Chromium Code Reviews| 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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 if (!configure_display_) | 206 if (!configure_display_) |
| 207 return; | 207 return; |
| 208 | 208 |
| 209 delegate_->GrabServer(); | 209 delegate_->GrabServer(); |
| 210 delegate_->InitXRandRExtension(&xrandr_event_base_); | 210 delegate_->InitXRandRExtension(&xrandr_event_base_); |
| 211 | 211 |
| 212 std::vector<OutputSnapshot> outputs = | 212 std::vector<OutputSnapshot> outputs = |
| 213 delegate_->GetOutputs(state_controller_); | 213 delegate_->GetOutputs(state_controller_); |
| 214 if (outputs.size() > 1 && background_color_argb) | 214 if (outputs.size() > 1 && background_color_argb) |
| 215 delegate_->SetBackgroundColor(background_color_argb); | 215 delegate_->SetBackgroundColor(background_color_argb); |
| 216 EnterStateOrFallBackToSoftwareMirroring( | 216 const OutputState new_state = GetOutputState(outputs, power_state_); |
| 217 GetOutputState(outputs, power_state_), power_state_, outputs); | 217 EnterStateOrFallBackToSoftwareMirroring(new_state, power_state_, outputs); |
| 218 | 218 |
| 219 // Force the DPMS on chrome startup as the driver doesn't always detect | 219 // Force the DPMS on chrome startup as the driver doesn't always detect |
| 220 // that all displays are on when signing out. | 220 // that all displays are on when signing out. |
| 221 delegate_->ForceDPMSOn(); | 221 delegate_->ForceDPMSOn(); |
| 222 delegate_->UngrabServer(); | 222 delegate_->UngrabServer(); |
| 223 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); | 223 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); |
| 224 NotifyOnDisplayChanged(); | 224 NotifyObservers(new_state); |
| 225 } | 225 } |
| 226 | 226 |
| 227 void OutputConfigurator::Stop() { | 227 void OutputConfigurator::Stop() { |
| 228 configure_display_ = false; | 228 configure_display_ = false; |
| 229 } | 229 } |
| 230 | 230 |
| 231 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, | 231 bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, |
| 232 int flags) { | 232 int flags) { |
| 233 if (!configure_display_) | 233 if (!configure_display_) |
| 234 return false; | 234 return false; |
| 235 | 235 |
| 236 VLOG(1) << "SetDisplayPower: power_state=" | 236 VLOG(1) << "SetDisplayPower: power_state=" |
| 237 << DisplayPowerStateToString(power_state) << " flags=" << flags; | 237 << DisplayPowerStateToString(power_state) << " flags=" << flags; |
| 238 if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe)) | 238 if (power_state == power_state_ && !(flags & kSetDisplayPowerForceProbe)) |
| 239 return true; | 239 return true; |
| 240 | 240 |
| 241 delegate_->GrabServer(); | 241 delegate_->GrabServer(); |
| 242 std::vector<OutputSnapshot> outputs = | 242 std::vector<OutputSnapshot> outputs = |
| 243 delegate_->GetOutputs(state_controller_); | 243 delegate_->GetOutputs(state_controller_); |
| 244 | 244 |
| 245 const OutputState new_state = GetOutputState(outputs, power_state); | |
| 246 bool attempted_change = false; | |
| 247 | |
| 245 bool only_if_single_internal_display = | 248 bool only_if_single_internal_display = |
| 246 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay; | 249 flags & kSetDisplayPowerOnlyIfSingleInternalDisplay; |
| 247 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal; | 250 bool single_internal_display = outputs.size() == 1 && outputs[0].is_internal; |
| 248 if ((single_internal_display || !only_if_single_internal_display) && | 251 if (single_internal_display || !only_if_single_internal_display) { |
| 249 EnterStateOrFallBackToSoftwareMirroring( | 252 if (EnterStateOrFallBackToSoftwareMirroring( |
| 250 GetOutputState(outputs, power_state), power_state, outputs)) { | 253 new_state, power_state, outputs)) { |
| 251 if (power_state != DISPLAY_POWER_ALL_OFF) { | |
| 252 // Force the DPMS on since the driver doesn't always detect that it | 254 // Force the DPMS on since the driver doesn't always detect that it |
| 253 // should turn on. This is needed when coming back from idle suspend. | 255 // should turn on. This is needed when coming back from idle suspend. |
| 254 delegate_->ForceDPMSOn(); | 256 if (power_state != DISPLAY_POWER_ALL_OFF) |
| 257 delegate_->ForceDPMSOn(); | |
| 255 } | 258 } |
| 259 attempted_change = true; | |
| 256 } | 260 } |
| 257 | 261 |
| 258 delegate_->UngrabServer(); | 262 delegate_->UngrabServer(); |
| 263 if (attempted_change) | |
| 264 NotifyObservers(new_state); | |
| 259 return true; | 265 return true; |
| 260 } | 266 } |
| 261 | 267 |
| 262 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { | 268 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { |
| 263 if (!configure_display_) | 269 if (!configure_display_) |
| 264 return false; | 270 return false; |
| 265 | 271 |
| 266 VLOG(1) << "SetDisplayMode: state=" << OutputStateToString(new_state); | 272 VLOG(1) << "SetDisplayMode: state=" << OutputStateToString(new_state); |
| 267 if (output_state_ == new_state) { | 273 if (output_state_ == new_state) { |
| 268 // Cancel software mirroring if the state is moving from | 274 // Cancel software mirroring if the state is moving from |
| 269 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED. | 275 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED. |
| 270 if (mirroring_controller_ && new_state == STATE_DUAL_EXTENDED) | 276 if (mirroring_controller_ && new_state == STATE_DUAL_EXTENDED) |
| 271 mirroring_controller_->SetSoftwareMirroring(false); | 277 mirroring_controller_->SetSoftwareMirroring(false); |
| 272 NotifyOnDisplayChanged(); | 278 NotifyObservers(new_state); |
| 273 return true; | 279 return true; |
| 274 } | 280 } |
| 275 | 281 |
| 276 delegate_->GrabServer(); | 282 delegate_->GrabServer(); |
| 277 std::vector<OutputSnapshot> outputs = | 283 std::vector<OutputSnapshot> outputs = |
| 278 delegate_->GetOutputs(state_controller_); | 284 delegate_->GetOutputs(state_controller_); |
| 279 bool success = EnterStateOrFallBackToSoftwareMirroring( | 285 bool success = EnterStateOrFallBackToSoftwareMirroring( |
| 280 new_state, power_state_, outputs); | 286 new_state, power_state_, outputs); |
|
oshima
2013/08/16 13:52:05
new_state and output_state_ can be different when
Daniel Erat
2013/08/16 15:52:31
Done. (We also need to pass the state so we can in
| |
| 281 delegate_->UngrabServer(); | 287 delegate_->UngrabServer(); |
| 282 | 288 |
| 283 if (success) { | 289 NotifyObservers(new_state); |
| 284 NotifyOnDisplayChanged(); | |
| 285 } else { | |
| 286 FOR_EACH_OBSERVER( | |
| 287 Observer, observers_, OnDisplayModeChangeFailed(new_state)); | |
| 288 } | |
| 289 return success; | 290 return success; |
| 290 } | 291 } |
| 291 | 292 |
| 292 bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { | 293 bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { |
| 293 if (!configure_display_) | 294 if (!configure_display_) |
| 294 return true; | 295 return true; |
| 295 | 296 |
| 296 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) { | 297 if (event->type - xrandr_event_base_ == RRScreenChangeNotify) { |
| 297 VLOG(1) << "Received RRScreenChangeNotify event"; | 298 VLOG(1) << "Received RRScreenChangeNotify event"; |
| 298 delegate_->UpdateXRandRConfiguration(event); | 299 delegate_->UpdateXRandRConfiguration(event); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 &OutputConfigurator::ConfigureOutputs); | 406 &OutputConfigurator::ConfigureOutputs); |
| 406 } | 407 } |
| 407 } | 408 } |
| 408 | 409 |
| 409 void OutputConfigurator::ConfigureOutputs() { | 410 void OutputConfigurator::ConfigureOutputs() { |
| 410 configure_timer_.reset(); | 411 configure_timer_.reset(); |
| 411 | 412 |
| 412 delegate_->GrabServer(); | 413 delegate_->GrabServer(); |
| 413 std::vector<OutputSnapshot> outputs = | 414 std::vector<OutputSnapshot> outputs = |
| 414 delegate_->GetOutputs(state_controller_); | 415 delegate_->GetOutputs(state_controller_); |
| 415 OutputState new_state = GetOutputState(outputs, power_state_); | 416 const OutputState new_state = GetOutputState(outputs, power_state_); |
| 416 bool success = EnterStateOrFallBackToSoftwareMirroring( | 417 EnterStateOrFallBackToSoftwareMirroring(new_state, power_state_, outputs); |
| 417 new_state, power_state_, outputs); | |
| 418 delegate_->UngrabServer(); | 418 delegate_->UngrabServer(); |
| 419 | 419 |
| 420 if (success) { | 420 NotifyObservers(new_state); |
| 421 NotifyOnDisplayChanged(); | |
| 422 } else { | |
| 423 FOR_EACH_OBSERVER( | |
| 424 Observer, observers_, OnDisplayModeChangeFailed(new_state)); | |
| 425 } | |
| 426 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); | 421 delegate_->SendProjectingStateToPowerManager(IsProjecting(outputs)); |
| 427 } | 422 } |
| 428 | 423 |
| 429 void OutputConfigurator::NotifyOnDisplayChanged() { | 424 void OutputConfigurator::NotifyObservers(OutputState attempted_state) { |
| 430 FOR_EACH_OBSERVER(Observer, observers_, | 425 if (output_state_ == attempted_state) { |
| 431 OnDisplayModeChanged(cached_outputs_)); | 426 FOR_EACH_OBSERVER(Observer, observers_, |
| 427 OnDisplayModeChanged(cached_outputs_)); | |
| 428 } else { | |
| 429 FOR_EACH_OBSERVER(Observer, observers_, | |
| 430 OnDisplayModeChangeFailed(attempted_state)); | |
| 431 } | |
| 432 } | 432 } |
| 433 | 433 |
| 434 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring( | 434 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring( |
| 435 OutputState output_state, | 435 OutputState output_state, |
| 436 DisplayPowerState power_state, | 436 DisplayPowerState power_state, |
| 437 const std::vector<OutputSnapshot>& outputs) { | 437 const std::vector<OutputSnapshot>& outputs) { |
| 438 bool success = EnterState(output_state, power_state, outputs); | 438 bool success = EnterState(output_state, power_state, outputs); |
| 439 if (mirroring_controller_) { | 439 if (mirroring_controller_) { |
| 440 bool enable_software_mirroring = false; | 440 bool enable_software_mirroring = false; |
| 441 if (!success && output_state == STATE_DUAL_MIRROR) { | 441 if (!success && output_state == STATE_DUAL_MIRROR) { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 686 float width_ratio = static_cast<float>(mirror_mode_info->width) / | 686 float width_ratio = static_cast<float>(mirror_mode_info->width) / |
| 687 static_cast<float>(native_mode_info->width); | 687 static_cast<float>(native_mode_info->width); |
| 688 float height_ratio = static_cast<float>(mirror_mode_info->height) / | 688 float height_ratio = static_cast<float>(mirror_mode_info->height) / |
| 689 static_cast<float>(native_mode_info->height); | 689 static_cast<float>(native_mode_info->height); |
| 690 | 690 |
| 691 area_ratio = width_ratio * height_ratio; | 691 area_ratio = width_ratio * height_ratio; |
| 692 return area_ratio; | 692 return area_ratio; |
| 693 } | 693 } |
| 694 | 694 |
| 695 } // namespace chromeos | 695 } // namespace chromeos |
| OLD | NEW |