OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/display/output_configurator.h" | 5 #include "chromeos/display/output_configurator.h" |
6 | 6 |
7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
8 #include <X11/extensions/Xrandr.h> | 8 #include <X11/extensions/Xrandr.h> |
9 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
10 | 10 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
99 (state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && !internal) || | 99 (state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && !internal) || |
100 (state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && internal); | 100 (state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && internal); |
101 if (output_power) | 101 if (output_power) |
102 (*output_power)[i] = on; | 102 (*output_power)[i] = on; |
103 if (on) | 103 if (on) |
104 num_on_outputs++; | 104 num_on_outputs++; |
105 } | 105 } |
106 return num_on_outputs; | 106 return num_on_outputs; |
107 } | 107 } |
108 | 108 |
109 // Determine if there is an "internal" output and how many outputs are | |
110 // connected. | |
111 bool IsProjecting( | |
112 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { | |
113 bool has_internal_output = false; | |
114 int connected_output_count = outputs.size(); | |
115 for (size_t i = 0; i < outputs.size(); ++i) | |
116 has_internal_output |= outputs[i].type == OUTPUT_TYPE_INTERNAL; | |
117 | |
118 // "Projecting" is defined as having more than 1 output connected while at | |
119 // least one of them is an internal output. | |
120 return has_internal_output && (connected_output_count > 1); | |
121 } | |
122 | |
123 } // namespace | 109 } // namespace |
124 | 110 |
125 OutputConfigurator::ModeInfo::ModeInfo() | 111 OutputConfigurator::ModeInfo::ModeInfo() |
126 : width(0), | 112 : width(0), |
127 height(0), | 113 height(0), |
128 interlaced(false), | 114 interlaced(false), |
129 refresh_rate(0.0) {} | 115 refresh_rate(0.0) {} |
130 | 116 |
131 OutputConfigurator::ModeInfo::ModeInfo(int width, | 117 OutputConfigurator::ModeInfo::ModeInfo(int width, |
132 int height, | 118 int height, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 } | 231 } |
246 | 232 |
247 OutputConfigurator::OutputConfigurator() | 233 OutputConfigurator::OutputConfigurator() |
248 : state_controller_(NULL), | 234 : state_controller_(NULL), |
249 mirroring_controller_(NULL), | 235 mirroring_controller_(NULL), |
250 is_panel_fitting_enabled_(false), | 236 is_panel_fitting_enabled_(false), |
251 configure_display_(base::SysInfo::IsRunningOnChromeOS()), | 237 configure_display_(base::SysInfo::IsRunningOnChromeOS()), |
252 xrandr_event_base_(0), | 238 xrandr_event_base_(0), |
253 output_state_(STATE_INVALID), | 239 output_state_(STATE_INVALID), |
254 power_state_(DISPLAY_POWER_ALL_ON), | 240 power_state_(DISPLAY_POWER_ALL_ON), |
255 next_output_protection_client_id_(1) { | 241 next_output_protection_client_id_(1), |
242 casting_session_count_(0) { | |
256 } | 243 } |
257 | 244 |
258 OutputConfigurator::~OutputConfigurator() {} | 245 OutputConfigurator::~OutputConfigurator() {} |
259 | 246 |
260 void OutputConfigurator::SetDelegateForTesting(scoped_ptr<Delegate> delegate) { | 247 void OutputConfigurator::SetDelegateForTesting(scoped_ptr<Delegate> delegate) { |
261 delegate_ = delegate.Pass(); | 248 delegate_ = delegate.Pass(); |
262 configure_display_ = true; | 249 configure_display_ = true; |
263 } | 250 } |
264 | 251 |
265 void OutputConfigurator::SetInitialDisplayPower(DisplayPowerState power_state) { | 252 void OutputConfigurator::SetInitialDisplayPower(DisplayPowerState power_state) { |
(...skipping 21 matching lines...) Expand all Loading... | |
287 if (cached_outputs_.size() > 1 && background_color_argb) | 274 if (cached_outputs_.size() > 1 && background_color_argb) |
288 delegate_->SetBackgroundColor(background_color_argb); | 275 delegate_->SetBackgroundColor(background_color_argb); |
289 const OutputState new_state = ChooseOutputState(power_state_); | 276 const OutputState new_state = ChooseOutputState(power_state_); |
290 const bool success = EnterStateOrFallBackToSoftwareMirroring( | 277 const bool success = EnterStateOrFallBackToSoftwareMirroring( |
291 new_state, power_state_); | 278 new_state, power_state_); |
292 | 279 |
293 // Force the DPMS on chrome startup as the driver doesn't always detect | 280 // Force the DPMS on chrome startup as the driver doesn't always detect |
294 // that all displays are on when signing out. | 281 // that all displays are on when signing out. |
295 delegate_->ForceDPMSOn(); | 282 delegate_->ForceDPMSOn(); |
296 delegate_->UngrabServer(); | 283 delegate_->UngrabServer(); |
297 delegate_->SendProjectingStateToPowerManager(IsProjecting(cached_outputs_)); | 284 SendProjectingStateToPowerManager(); |
298 NotifyObservers(success, new_state); | 285 NotifyObservers(success, new_state); |
299 } | 286 } |
300 | 287 |
301 bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) { | 288 bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) { |
302 for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin(); | 289 for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin(); |
303 it != cached_outputs_.end(); ++it) { | 290 it != cached_outputs_.end(); ++it) { |
304 RROutput this_id = it->output; | 291 RROutput this_id = it->output; |
305 uint32_t all_desired = 0; | 292 uint32_t all_desired = 0; |
306 DisplayProtections::const_iterator request_it = requests.find( | 293 DisplayProtections::const_iterator request_it = requests.find( |
307 it->display_id); | 294 it->display_id); |
(...skipping 20 matching lines...) Expand all Loading... | |
328 break; | 315 break; |
329 case OUTPUT_TYPE_NONE: | 316 case OUTPUT_TYPE_NONE: |
330 NOTREACHED(); | 317 NOTREACHED(); |
331 break; | 318 break; |
332 } | 319 } |
333 } | 320 } |
334 | 321 |
335 return true; | 322 return true; |
336 } | 323 } |
337 | 324 |
325 void OutputConfigurator::SendProjectingStateToPowerManager() { | |
326 bool has_internal_output = false; | |
327 int connected_output_count = cached_outputs_.size() + casting_session_count_; | |
328 for (size_t i = 0; i < cached_outputs_.size(); ++i) { | |
329 if (cached_outputs_[i].type == OUTPUT_TYPE_INTERNAL) { | |
330 has_internal_output = true; | |
331 break; | |
332 } | |
333 } | |
334 | |
335 // "Projecting" is defined as having more than 1 output connected while at | |
336 // least one of them is an internal output. | |
337 bool is_projecting = has_internal_output && (connected_output_count > 1); | |
338 delegate_->SendProjectingStateToPowerManager(is_projecting); | |
339 } | |
340 | |
338 OutputConfigurator::OutputProtectionClientId | 341 OutputConfigurator::OutputProtectionClientId |
339 OutputConfigurator::RegisterOutputProtectionClient() { | 342 OutputConfigurator::RegisterOutputProtectionClient() { |
340 if (!configure_display_) | 343 if (!configure_display_) |
341 return kInvalidClientId; | 344 return kInvalidClientId; |
342 | 345 |
343 return next_output_protection_client_id_++; | 346 return next_output_protection_client_id_++; |
344 } | 347 } |
345 | 348 |
346 void OutputConfigurator::UnregisterOutputProtectionClient( | 349 void OutputConfigurator::UnregisterOutputProtectionClient( |
347 OutputProtectionClientId client_id) { | 350 OutputProtectionClientId client_id) { |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
592 // This also takes care of same event being received twice. | 595 // This also takes care of same event being received twice. |
593 ScheduleConfigureOutputs(); | 596 ScheduleConfigureOutputs(); |
594 } | 597 } |
595 | 598 |
596 return base::EVENT_CONTINUE; | 599 return base::EVENT_CONTINUE; |
597 } | 600 } |
598 | 601 |
599 void OutputConfigurator::DidProcessEvent(const base::NativeEvent& event) { | 602 void OutputConfigurator::DidProcessEvent(const base::NativeEvent& event) { |
600 } | 603 } |
601 | 604 |
605 void OutputConfigurator::OnCastingSessionStartedOrStopped(bool started) { | |
606 if (started) { | |
607 ++casting_session_count_; | |
608 } else { | |
609 DCHECK_GT(casting_session_count_, 0); | |
610 --casting_session_count_; | |
oshima
2014/01/17 20:57:36
nit: you may want to reset to 0 if it goes blow 0
hshi1
2014/01/17 21:01:37
Done.
| |
611 } | |
612 SendProjectingStateToPowerManager(); | |
613 } | |
614 | |
602 void OutputConfigurator::AddObserver(Observer* observer) { | 615 void OutputConfigurator::AddObserver(Observer* observer) { |
603 observers_.AddObserver(observer); | 616 observers_.AddObserver(observer); |
604 } | 617 } |
605 | 618 |
606 void OutputConfigurator::RemoveObserver(Observer* observer) { | 619 void OutputConfigurator::RemoveObserver(Observer* observer) { |
607 observers_.RemoveObserver(observer); | 620 observers_.RemoveObserver(observer); |
608 } | 621 } |
609 | 622 |
610 void OutputConfigurator::SuspendDisplays() { | 623 void OutputConfigurator::SuspendDisplays() { |
611 // If the display is off due to user inactivity and there's only a single | 624 // If the display is off due to user inactivity and there's only a single |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
770 configure_timer_.reset(); | 783 configure_timer_.reset(); |
771 | 784 |
772 delegate_->GrabServer(); | 785 delegate_->GrabServer(); |
773 UpdateCachedOutputs(); | 786 UpdateCachedOutputs(); |
774 const OutputState new_state = ChooseOutputState(power_state_); | 787 const OutputState new_state = ChooseOutputState(power_state_); |
775 const bool success = EnterStateOrFallBackToSoftwareMirroring( | 788 const bool success = EnterStateOrFallBackToSoftwareMirroring( |
776 new_state, power_state_); | 789 new_state, power_state_); |
777 delegate_->UngrabServer(); | 790 delegate_->UngrabServer(); |
778 | 791 |
779 NotifyObservers(success, new_state); | 792 NotifyObservers(success, new_state); |
780 delegate_->SendProjectingStateToPowerManager(IsProjecting(cached_outputs_)); | 793 SendProjectingStateToPowerManager(); |
781 } | 794 } |
782 | 795 |
783 void OutputConfigurator::NotifyObservers(bool success, | 796 void OutputConfigurator::NotifyObservers(bool success, |
784 OutputState attempted_state) { | 797 OutputState attempted_state) { |
785 if (success) { | 798 if (success) { |
786 FOR_EACH_OBSERVER(Observer, observers_, | 799 FOR_EACH_OBSERVER(Observer, observers_, |
787 OnDisplayModeChanged(cached_outputs_)); | 800 OnDisplayModeChanged(cached_outputs_)); |
788 } else { | 801 } else { |
789 FOR_EACH_OBSERVER(Observer, observers_, | 802 FOR_EACH_OBSERVER(Observer, observers_, |
790 OnDisplayModeChangeFailed(attempted_state)); | 803 OnDisplayModeChangeFailed(attempted_state)); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1130 float width_ratio = static_cast<float>(mirror_mode_info->width) / | 1143 float width_ratio = static_cast<float>(mirror_mode_info->width) / |
1131 static_cast<float>(native_mode_info->width); | 1144 static_cast<float>(native_mode_info->width); |
1132 float height_ratio = static_cast<float>(mirror_mode_info->height) / | 1145 float height_ratio = static_cast<float>(mirror_mode_info->height) / |
1133 static_cast<float>(native_mode_info->height); | 1146 static_cast<float>(native_mode_info->height); |
1134 | 1147 |
1135 area_ratio = width_ratio * height_ratio; | 1148 area_ratio = width_ratio * height_ratio; |
1136 return area_ratio; | 1149 return area_ratio; |
1137 } | 1150 } |
1138 | 1151 |
1139 } // namespace chromeos | 1152 } // namespace chromeos |
OLD | NEW |