Index: chromeos/display/output_configurator.cc |
diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc |
index a07a9de356b618ebdb1e1329d59afef57d763223..45564428255afc387b5d77fce42c8b99c48f0d90 100644 |
--- a/chromeos/display/output_configurator.cc |
+++ b/chromeos/display/output_configurator.cc |
@@ -12,8 +12,6 @@ |
#include "base/logging.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/time.h" |
-#include "chromeos/dbus/dbus_thread_manager.h" |
-#include "chromeos/dbus/power_manager_client.h" |
#include "chromeos/display/real_output_configurator_delegate.h" |
namespace chromeos { |
@@ -28,15 +26,6 @@ const char kInternal_eDP[] = "eDP"; |
// in |Dispatch()|. |
const int64 kConfigureDelayMs = 500; |
-// Gap between screens so cursor at bottom of active display doesn't partially |
-// appear on top of inactive display. Higher numbers guard against larger |
-// cursors, but also waste more memory. |
-// For simplicity, this is hard-coded to 60 to avoid the complexity of always |
-// determining the DPI of the screen and rationalizing which screen we need to |
-// use for the DPI calculation. |
-// See crbug.com/130188 for initial discussion. |
-const int kVerticalGap = 60; |
- |
// Returns a string describing |state|. |
std::string DisplayPowerStateToString(DisplayPowerState state) { |
switch (state) { |
@@ -95,7 +84,8 @@ OutputState InferCurrentState( |
(secondary_mode == None); |
if (primary_native && secondary_native) { |
// Just check the relative locations. |
- int secondary_offset = outputs[0].height + kVerticalGap; |
+ int secondary_offset = outputs[0].height + |
+ OutputConfigurator::kVerticalGap; |
if (outputs[0].y == 0 && outputs[1].y == secondary_offset) { |
state = STATE_DUAL_EXTENDED; |
} else { |
@@ -166,6 +156,30 @@ OutputConfigurator::CrtcConfig::CrtcConfig(RRCrtc crtc, |
mode(mode), |
output(output) {} |
+bool OutputConfigurator::TestApi::SendOutputChangeEvents(bool connected) { |
+ XRRScreenChangeNotifyEvent screen_event; |
+ memset(&screen_event, 0, sizeof(screen_event)); |
+ screen_event.type = xrandr_event_base_ + RRScreenChangeNotify; |
+ configurator_->Dispatch( |
+ reinterpret_cast<const base::NativeEvent>(&screen_event)); |
+ |
+ XRROutputChangeNotifyEvent notify_event; |
+ memset(¬ify_event, 0, sizeof(notify_event)); |
+ notify_event.type = xrandr_event_base_ + RRNotify; |
+ notify_event.subtype = RRNotify_OutputChange; |
+ notify_event.connection = connected ? RR_Connected : RR_Disconnected; |
+ configurator_->Dispatch( |
+ reinterpret_cast<const base::NativeEvent>(¬ify_event)); |
+ |
+ if (!configurator_->configure_timer_->IsRunning()) { |
+ LOG(ERROR) << "ConfigureOutputs() timer not running"; |
+ return false; |
+ } |
+ |
+ configurator_->ConfigureOutputs(); |
+ return true; |
+} |
+ |
// static |
bool OutputConfigurator::IsInternalOutputName(const std::string& name) { |
return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; |
@@ -173,7 +187,6 @@ bool OutputConfigurator::IsInternalOutputName(const std::string& name) { |
OutputConfigurator::OutputConfigurator() |
: state_controller_(NULL), |
- delegate_(new RealOutputConfiguratorDelegate()), |
configure_display_(base::chromeos::IsRunningOnChromeOS()), |
connected_output_count_(0), |
xrandr_event_base_(0), |
@@ -183,11 +196,20 @@ OutputConfigurator::OutputConfigurator() |
OutputConfigurator::~OutputConfigurator() {} |
+void OutputConfigurator::SetDelegateForTesting( |
+ scoped_ptr<Delegate> delegate) { |
+ delegate_ = delegate.Pass(); |
+ configure_display_ = true; |
+} |
+ |
void OutputConfigurator::Init(bool is_panel_fitting_enabled, |
uint32 background_color_argb) { |
if (!configure_display_) |
return; |
+ if (!delegate_) |
+ delegate_.reset(new RealOutputConfiguratorDelegate()); |
+ |
// Cache the initial output state. |
delegate_->SetPanelFittingEnabled(is_panel_fitting_enabled); |
delegate_->GrabServer(); |
@@ -198,8 +220,10 @@ void OutputConfigurator::Init(bool is_panel_fitting_enabled, |
} |
void OutputConfigurator::Start() { |
+ if (!configure_display_) |
+ return; |
+ |
delegate_->GrabServer(); |
- // Detect our initial state. |
std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); |
connected_output_count_ = outputs.size(); |
@@ -218,12 +242,8 @@ void OutputConfigurator::Start() { |
// Force the DPMS on chrome startup as the driver doesn't always detect |
// that all displays are on when signing out. |
delegate_->ForceDPMSOn(); |
- |
- // Relinquish X resources. |
delegate_->UngrabServer(); |
- |
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> |
- SetIsProjecting(is_projecting); |
+ delegate_->SendProjectingStateToPowerManager(is_projecting); |
} |
void OutputConfigurator::Stop() { |
@@ -232,11 +252,11 @@ void OutputConfigurator::Stop() { |
bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, |
int flags) { |
- VLOG(1) << "SetDisplayPower: power_state=" |
- << DisplayPowerStateToString(power_state) << " flags=" << flags; |
- |
if (!configure_display_) |
return false; |
+ |
+ VLOG(1) << "SetDisplayPower: power_state=" |
+ << DisplayPowerStateToString(power_state) << " flags=" << flags; |
if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe)) |
return true; |
@@ -262,6 +282,9 @@ bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, |
} |
bool OutputConfigurator::SetDisplayMode(OutputState new_state) { |
+ if (!configure_display_) |
+ return false; |
+ |
if (output_state_ == STATE_INVALID || |
output_state_ == STATE_HEADLESS || |
output_state_ == STATE_SINGLE) |
@@ -287,14 +310,17 @@ bool OutputConfigurator::SetDisplayMode(OutputState new_state) { |
} |
bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { |
- if (event->type - xrandr_event_base_ == RRScreenChangeNotify) |
+ if (!configure_display_) |
+ return true; |
+ |
+ if (event->type - xrandr_event_base_ == RRScreenChangeNotify) { |
delegate_->UpdateXRandRConfiguration(event); |
- // Ignore this event if the Xrandr extension isn't supported, or |
- // the device is being shutdown. |
- if (!configure_display_ || |
- (event->type - xrandr_event_base_ != RRNotify)) { |
return true; |
} |
+ |
+ if (event->type - xrandr_event_base_ != RRNotify) |
+ return true; |
+ |
XEvent* xevent = static_cast<XEvent*>(event); |
XRRNotifyEvent* notify_event = |
reinterpret_cast<XRRNotifyEvent*>(xevent); |
@@ -319,38 +345,9 @@ bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { |
} |
} |
- // Ignore the case of RR_UnknownConnection. |
return true; |
} |
-void OutputConfigurator::ConfigureOutputs() { |
- configure_timer_.reset(); |
- |
- delegate_->GrabServer(); |
- std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); |
- int new_output_count = outputs.size(); |
- // Don't skip even if the output counts didn't change because |
- // a display might have been swapped during the suspend. |
- connected_output_count_ = new_output_count; |
- OutputState new_state = GetNextState(outputs); |
- // When a display was swapped, the state moves from |
- // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED, so don't rely on |
- // the state chagne to tell if it was successful. |
- bool success = EnterState(new_state, power_state_, outputs); |
- bool is_projecting = IsProjecting(outputs); |
- delegate_->UngrabServer(); |
- |
- if (success) { |
- output_state_ = new_state; |
- NotifyOnDisplayChanged(); |
- } else { |
- FOR_EACH_OBSERVER( |
- Observer, observers_, OnDisplayModeChangeFailed(new_state)); |
- } |
- chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> |
- SetIsProjecting(is_projecting); |
-} |
- |
void OutputConfigurator::AddObserver(Observer* observer) { |
observers_.AddObserver(observer); |
} |
@@ -382,6 +379,33 @@ void OutputConfigurator::ResumeDisplays() { |
SetDisplayPower(power_state_, kSetDisplayPowerForceProbe); |
} |
+void OutputConfigurator::ConfigureOutputs() { |
+ configure_timer_.reset(); |
+ |
+ delegate_->GrabServer(); |
+ std::vector<OutputSnapshot> outputs = delegate_->GetOutputs(); |
+ int new_output_count = outputs.size(); |
+ // Don't skip even if the output counts didn't change because |
+ // a display might have been swapped during the suspend. |
+ connected_output_count_ = new_output_count; |
+ OutputState new_state = GetNextState(outputs); |
+ // When a display was swapped, the state moves from |
+ // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED, so don't rely on |
+ // the state chagne to tell if it was successful. |
+ bool success = EnterState(new_state, power_state_, outputs); |
+ bool is_projecting = IsProjecting(outputs); |
+ delegate_->UngrabServer(); |
+ |
+ if (success) { |
+ output_state_ = new_state; |
+ NotifyOnDisplayChanged(); |
+ } else { |
+ FOR_EACH_OBSERVER( |
+ Observer, observers_, OnDisplayModeChangeFailed(new_state)); |
+ } |
+ delegate_->SendProjectingStateToPowerManager(is_projecting); |
+} |
+ |
void OutputConfigurator::NotifyOnDisplayChanged() { |
FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); |
} |
@@ -471,7 +495,7 @@ bool OutputConfigurator::EnterState( |
} |
configs[i] = CrtcConfig( |
- outputs[i].crtc, 0, height, |
+ outputs[i].crtc, 0, (height ? height + kVerticalGap : 0), |
output_power[i] ? outputs[i].native_mode : None, |
outputs[i].output); |