summaryrefslogtreecommitdiffstats
path: root/chromeos/display/output_configurator.cc
diff options
context:
space:
mode:
authordnicoara@chromium.org <dnicoara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-26 23:39:18 +0000
committerdnicoara@chromium.org <dnicoara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-26 23:39:18 +0000
commit3d1cd60ccb3f7176fc206268300cca16115bf0c8 (patch)
treecf020f2374da11c83796683637558fa66804813c /chromeos/display/output_configurator.cc
parent1763a9bf43129c9f103145350d1c0abf04921182 (diff)
downloadchromium_src-3d1cd60ccb3f7176fc206268300cca16115bf0c8.zip
chromium_src-3d1cd60ccb3f7176fc206268300cca16115bf0c8.tar.gz
chromium_src-3d1cd60ccb3f7176fc206268300cca16115bf0c8.tar.bz2
Extract NativeDisplayDelegate and move display event handling to NativeDisplayDelegate
Display configuration events are platform specific, thus move display event processing to NativeDisplayDelegate. OutputConfigurator will then register itself as an observer of NativeDisplayDelegate which will notify observers when display configuration changes occur. The NativeDisplayDelegate interface has also been modified to take in OutputSnapshot objects as a first step to abstracting display state. In a future CL NativeDisplayDelegate and OutputSnapshot will be updated such that X11 specific state will not be present in the interface. BUG=333413 Review URL: https://codereview.chromium.org/173713003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253631 0039d316-1c4b-4281-b951-d872f2087c98
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;
}