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