summaryrefslogtreecommitdiffstats
path: root/chromeos/display/output_configurator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromeos/display/output_configurator.cc')
-rw-r--r--chromeos/display/output_configurator.cc158
1 files changed, 39 insertions, 119 deletions
diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc
index 553bb1a..3bf0791 100644
--- a/chromeos/display/output_configurator.cc
+++ b/chromeos/display/output_configurator.cc
@@ -6,7 +6,6 @@
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
-#include <X11/extensions/XInput2.h>
#include "base/bind.h"
#include "base/logging.h"
@@ -150,26 +149,6 @@ OutputConfigurator::OutputSnapshot::OutputSnapshot()
OutputConfigurator::OutputSnapshot::~OutputSnapshot() {}
-void OutputConfigurator::TestApi::SendScreenChangeEvent() {
- XRRScreenChangeNotifyEvent event = {0};
- event.type = xrandr_event_base_ + RRScreenChangeNotify;
- configurator_->Dispatch(reinterpret_cast<const base::NativeEvent>(&event));
-}
-
-void OutputConfigurator::TestApi::SendOutputChangeEvent(RROutput output,
- RRCrtc crtc,
- RRMode mode,
- bool connected) {
- XRROutputChangeNotifyEvent event = {0};
- event.type = xrandr_event_base_ + RRNotify;
- event.subtype = RRNotify_OutputChange;
- event.output = output;
- event.crtc = crtc;
- event.mode = mode;
- event.connection = connected ? RR_Connected : RR_Disconnected;
- configurator_->Dispatch(reinterpret_cast<const base::NativeEvent>(&event));
-}
-
bool OutputConfigurator::TestApi::TriggerConfigureTimeout() {
if (configurator_->configure_timer_.get() &&
configurator_->configure_timer_->IsRunning()) {
@@ -236,21 +215,28 @@ OutputConfigurator::OutputConfigurator()
mirroring_controller_(NULL),
is_panel_fitting_enabled_(false),
configure_display_(base::SysInfo::IsRunningOnChromeOS()),
- xrandr_event_base_(0),
output_state_(ui::OUTPUT_STATE_INVALID),
power_state_(DISPLAY_POWER_ALL_ON),
next_output_protection_client_id_(1) {}
-OutputConfigurator::~OutputConfigurator() {}
+OutputConfigurator::~OutputConfigurator() {
+ if (native_display_delegate_)
+ native_display_delegate_->RemoveObserver(this);
+}
void OutputConfigurator::SetNativeDisplayDelegateForTesting(
scoped_ptr<NativeDisplayDelegate> delegate) {
+ DCHECK(!native_display_delegate_);
+
native_display_delegate_ = delegate.Pass();
+ native_display_delegate_->AddObserver(this);
configure_display_ = true;
}
void OutputConfigurator::SetTouchscreenDelegateForTesting(
scoped_ptr<TouchscreenDelegate> delegate) {
+ DCHECK(!touchscreen_delegate_);
+
touchscreen_delegate_ = delegate.Pass();
}
@@ -264,8 +250,10 @@ void OutputConfigurator::Init(bool is_panel_fitting_enabled) {
if (!configure_display_)
return;
- if (!native_display_delegate_)
+ if (!native_display_delegate_) {
native_display_delegate_.reset(new NativeDisplayDelegateX11());
+ native_display_delegate_->AddObserver(this);
+ }
if (!touchscreen_delegate_)
touchscreen_delegate_.reset(new TouchscreenDelegateX11());
@@ -276,7 +264,7 @@ void OutputConfigurator::Start(uint32 background_color_argb) {
return;
native_display_delegate_->GrabServer();
- native_display_delegate_->InitXRandRExtension(&xrandr_event_base_);
+ native_display_delegate_->Initialize();
UpdateCachedOutputs();
if (cached_outputs_.size() > 1 && background_color_argb)
@@ -295,7 +283,6 @@ void OutputConfigurator::Start(uint32 background_color_argb) {
bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) {
for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin();
it != cached_outputs_.end(); ++it) {
- RROutput this_id = it->output;
uint32_t all_desired = 0;
DisplayProtections::const_iterator request_it = requests.find(
it->display_id);
@@ -312,7 +299,7 @@ bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) {
(all_desired & ui::OUTPUT_PROTECTION_METHOD_HDCP)
? ui::HDCP_STATE_DESIRED
: ui::HDCP_STATE_UNDESIRED;
- if (!native_display_delegate_->SetHDCPState(this_id, new_desired_state))
+ if (!native_display_delegate_->SetHDCPState(*it, new_desired_state))
return false;
break;
}
@@ -369,7 +356,6 @@ bool OutputConfigurator::QueryOutputProtectionStatus(
*link_mask = 0;
for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin();
it != cached_outputs_.end(); ++it) {
- RROutput this_id = it->output;
if (it->display_id != display_id)
continue;
*link_mask |= it->type;
@@ -381,7 +367,7 @@ bool OutputConfigurator::QueryOutputProtectionStatus(
case ui::OUTPUT_TYPE_DVI:
case ui::OUTPUT_TYPE_HDMI: {
ui::HDCPState state;
- if (!native_display_delegate_->GetHDCPState(this_id, &state))
+ if (!native_display_delegate_->GetHDCPState(*it, &state))
return false;
if (state == ui::HDCP_STATE_ENABLED)
enabled |= ui::OUTPUT_PROTECTION_METHOD_HDCP;
@@ -453,6 +439,13 @@ bool OutputConfigurator::EnableOutputProtection(
void OutputConfigurator::Stop() {
configure_display_ = false;
+
+ // Since we need to stop processing configuration updates, we can just destroy
+ // the display delegate.
+ if (native_display_delegate_) {
+ native_display_delegate_->RemoveObserver(this);
+ native_display_delegate_.reset();
+ }
}
bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state,
@@ -520,78 +513,19 @@ bool OutputConfigurator::SetDisplayMode(ui::OutputState new_state) {
return success;
}
-uint32_t OutputConfigurator::Dispatch(const base::NativeEvent& event) {
- if (!configure_display_)
- return POST_DISPATCH_PERFORM_DEFAULT;
-
- if (event->type - xrandr_event_base_ == RRScreenChangeNotify) {
- VLOG(1) << "Received RRScreenChangeNotify event";
- native_display_delegate_->UpdateXRandRConfiguration(event);
- return POST_DISPATCH_PERFORM_DEFAULT;
- }
-
- // Bail out early for everything except RRNotify_OutputChange events
- // about an output getting connected or disconnected.
- if (event->type - xrandr_event_base_ != RRNotify)
- return POST_DISPATCH_PERFORM_DEFAULT;
- const XRRNotifyEvent* notify_event = reinterpret_cast<XRRNotifyEvent*>(event);
- if (notify_event->subtype != RRNotify_OutputChange)
- return POST_DISPATCH_PERFORM_DEFAULT;
- const XRROutputChangeNotifyEvent* output_change_event =
- reinterpret_cast<XRROutputChangeNotifyEvent*>(event);
- const int action = output_change_event->connection;
- if (action != RR_Connected && action != RR_Disconnected)
- return POST_DISPATCH_PERFORM_DEFAULT;
-
- const bool connected = (action == RR_Connected);
- VLOG(1) << "Received RRNotify_OutputChange event:"
- << " output=" << output_change_event->output
- << " crtc=" << output_change_event->crtc
- << " mode=" << output_change_event->mode
- << " action=" << (connected ? "connected" : "disconnected");
-
- bool found_changed_output = false;
- for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin();
- it != cached_outputs_.end(); ++it) {
- if (it->output == output_change_event->output) {
- if (connected && it->crtc == output_change_event->crtc &&
- it->current_mode == output_change_event->mode) {
- VLOG(1) << "Ignoring event describing already-cached state";
- return POST_DISPATCH_PERFORM_DEFAULT;
- }
- found_changed_output = true;
- break;
- }
- }
-
- if (!connected && !found_changed_output) {
- VLOG(1) << "Ignoring event describing already-disconnected output";
- return POST_DISPATCH_PERFORM_DEFAULT;
- }
-
- // Connecting/disconnecting a display may generate multiple events. Defer
- // configuring outputs to avoid grabbing X and configuring displays
- // multiple times.
- ScheduleConfigureOutputs();
- return POST_DISPATCH_PERFORM_DEFAULT;
-}
-
-base::EventStatus OutputConfigurator::WillProcessEvent(
- const base::NativeEvent& event) {
- // XI_HierarchyChanged events are special. There is no window associated with
- // these events. So process them directly from here.
- if (configure_display_ && event->type == GenericEvent &&
- event->xgeneric.evtype == XI_HierarchyChanged) {
- VLOG(1) << "Received XI_HierarchyChanged event";
- // Defer configuring outputs to not stall event processing.
- // This also takes care of same event being received twice.
- ScheduleConfigureOutputs();
+void OutputConfigurator::OnConfigurationChanged() {
+ // Configure outputs with |kConfigureDelayMs| delay,
+ // so that time-consuming ConfigureOutputs() won't be called multiple times.
+ if (configure_timer_.get()) {
+ configure_timer_->Reset();
+ } else {
+ configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>());
+ configure_timer_->Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
+ this,
+ &OutputConfigurator::ConfigureOutputs);
}
-
- return base::EVENT_CONTINUE;
-}
-
-void OutputConfigurator::DidProcessEvent(const base::NativeEvent& event) {
}
void OutputConfigurator::AddObserver(Observer* observer) {
@@ -625,19 +559,6 @@ void OutputConfigurator::ResumeDisplays() {
SetDisplayPower(power_state_, kSetDisplayPowerForceProbe);
}
-void OutputConfigurator::ScheduleConfigureOutputs() {
- if (configure_timer_.get()) {
- configure_timer_->Reset();
- } else {
- configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>());
- configure_timer_->Start(
- FROM_HERE,
- base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
- this,
- &OutputConfigurator::ConfigureOutputs);
- }
-}
-
void OutputConfigurator::UpdateCachedOutputs() {
cached_outputs_ = native_display_delegate_->GetOutputs();
touchscreen_delegate_->AssociateTouchscreens(&cached_outputs_);
@@ -750,7 +671,7 @@ bool OutputConfigurator::FindMirrorMode(OutputSnapshot* internal_output,
!external_info.interlaced;
if (can_fit) {
RRMode mode = external_it->first;
- native_display_delegate_->AddOutputMode(internal_output->output, mode);
+ native_display_delegate_->AddMode(*internal_output, mode);
internal_output->mode_infos.insert(std::make_pair(mode, external_info));
internal_output->mirror_mode = mode;
external_output->mirror_mode = mode;
@@ -944,11 +865,10 @@ bool OutputConfigurator::EnterState(ui::OutputState output_state,
bool configure_succeeded =false;
while (true) {
- if (native_display_delegate_->ConfigureCrtc(output.crtc,
- output.current_mode,
- output.output,
- output.x,
- output.y)) {
+ if (native_display_delegate_->Configure(output,
+ output.current_mode,
+ output.x,
+ output.y)) {
configure_succeeded = true;
break;
}