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 <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
| 10 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 643 XRRFreeScreenResources(screen); | 643 XRRFreeScreenResources(screen); |
| 644 XUngrabServer(display); | 644 XUngrabServer(display); |
| 645 | 645 |
| 646 if (did_change) | 646 if (did_change) |
| 647 NotifyOnDisplayChanged(); | 647 NotifyOnDisplayChanged(); |
| 648 else | 648 else |
| 649 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChangeFailed()); | 649 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChangeFailed()); |
| 650 return did_change; | 650 return did_change; |
| 651 } | 651 } |
| 652 | 652 |
| 653 bool OutputConfigurator::ScreenPowerSet(bool power_on, bool all_displays) { | 653 bool OutputConfigurator::SetDisplayPowerState(DisplayPowerState state) { |
| 654 TRACE_EVENT0("chromeos", "OutputConfigurator::ScreenPowerSet"); | 654 TRACE_EVENT0("chromeos", "OutputConfigurator::SetPowerState"); |
| 655 VLOG(1) << "OutputConfigurator::SetScreensOn " << power_on | 655 VLOG(1) << "OutputConfigurator::SetPowerState state " << state; |
| 656 << " all displays " << all_displays; | |
| 657 if (!is_running_on_chrome_os_) | 656 if (!is_running_on_chrome_os_) |
| 658 return false; | 657 return false; |
| 659 | 658 |
| 660 bool success = false; | |
| 661 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 659 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); |
| 662 CHECK(display != NULL); | 660 CHECK(display != NULL); |
| 663 XGrabServer(display); | 661 XGrabServer(display); |
| 664 Window window = DefaultRootWindow(display); | 662 Window window = DefaultRootWindow(display); |
| 665 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); | 663 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); |
| 666 CHECK(screen != NULL); | 664 CHECK(screen != NULL); |
| 667 | 665 |
| 668 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); | 666 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); |
| 669 connected_output_count_ = outputs.size(); | 667 connected_output_count_ = outputs.size(); |
| 670 | 668 |
| 671 if (all_displays && power_on) { | 669 if (state == DISPLAY_POWER_ALL_ON) { |
| 672 // Resume all displays using the current state. | 670 // Resume all displays using the current state. |
| 673 if (EnterState(display, screen, window, output_state_, outputs)) { | 671 if (EnterState(display, screen, window, output_state_, outputs)) { |
| 674 // Force the DPMS on since the driver doesn't always detect that it should | 672 // Force the DPMS on since the driver doesn't always detect that it should |
| 675 // turn on. This is needed when coming back from idle suspend. | 673 // turn on. This is needed when coming back from idle suspend. |
| 676 CHECK(DPMSEnable(display)); | 674 CHECK(DPMSEnable(display)); |
| 677 CHECK(DPMSForceLevel(display, DPMSModeOn)); | 675 CHECK(DPMSForceLevel(display, DPMSModeOn)); |
| 678 | 676 |
| 679 XRRFreeScreenResources(screen); | 677 XRRFreeScreenResources(screen); |
| 680 XUngrabServer(display); | 678 XUngrabServer(display); |
| 681 return true; | 679 return true; |
| 682 } | 680 } |
| 683 } | 681 } |
| 684 | 682 |
| 685 CrtcConfig config; | 683 CrtcConfig config; |
| 686 config.crtc = None; | 684 config.crtc = None; |
| 687 // Set the CRTCs based on whether we want to turn the power on or off and | 685 // Set the CRTCs based on whether we want to turn the power on or off and |
| 688 // select the outputs to operate on by name or all_displays. | 686 // select the outputs to operate on by name or all_displays. |
| 689 for (int i = 0; i < connected_output_count_; ++i) { | 687 for (int i = 0; i < connected_output_count_; ++i) { |
| 690 if (all_displays || outputs[i].is_internal || power_on) { | 688 config.x = 0; |
|
Daniel Erat
2013/02/28 01:48:53
I'm not sure how to test that this still works as
| |
| 691 config.x = 0; | 689 config.y = outputs[i].y; |
| 692 config.y = outputs[i].y; | 690 config.output = outputs[i].output; |
| 693 config.output = outputs[i].output; | 691 |
| 694 config.mode = None; | 692 // Workaround for crbug.com/148365: leave internal display in native |
| 695 if (power_on) { | 693 // mode so user can move cursor (and hence windows) onto internal |
| 694 // display even when it's off. | |
| 695 if (connected_output_count_ > 1 && outputs[i].is_internal) { | |
| 696 config.mode = outputs[i].native_mode; | |
| 697 } else { | |
| 698 if (state == DISPLAY_POWER_ALL_ON || | |
| 699 (state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && | |
| 700 !outputs[i].is_internal)) { | |
| 696 config.mode = (output_state_ == STATE_DUAL_MIRROR) ? | 701 config.mode = (output_state_ == STATE_DUAL_MIRROR) ? |
| 697 outputs[i].mirror_mode : outputs[i].native_mode; | 702 outputs[i].mirror_mode : outputs[i].native_mode; |
| 698 } else if (connected_output_count_ > 1 && !all_displays && | 703 } else { |
| 699 outputs[i].is_internal) { | 704 config.mode = None; |
| 700 // Workaround for crbug.com/148365: leave internal display in native | |
| 701 // mode so user can move cursor (and hence windows) onto internal | |
| 702 // display even when dimmed | |
| 703 config.mode = outputs[i].native_mode; | |
| 704 } | 705 } |
| 705 config.crtc = GetNextCrtcAfter(display, screen, config.output, | 706 } |
| 706 config.crtc); | |
| 707 | 707 |
| 708 ConfigureCrtc(display, screen, &config); | 708 config.crtc = GetNextCrtcAfter(display, screen, config.output, config.crtc); |
| 709 success = true; | 709 ConfigureCrtc(display, screen, &config); |
| 710 } | |
| 711 } | 710 } |
| 712 | 711 |
| 713 // Force the DPMS on since the driver doesn't always detect that it should | 712 // Force the DPMS on since the driver doesn't always detect that it should |
| 714 // turn on. This is needed when coming back from idle suspend. | 713 // turn on. This is needed when coming back from idle suspend. |
| 715 if (power_on) { | 714 if (state == DISPLAY_POWER_ALL_ON || |
| 715 state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON) { | |
| 716 CHECK(DPMSEnable(display)); | 716 CHECK(DPMSEnable(display)); |
| 717 CHECK(DPMSForceLevel(display, DPMSModeOn)); | 717 CHECK(DPMSForceLevel(display, DPMSModeOn)); |
| 718 } | 718 } |
| 719 | 719 |
| 720 XRRFreeScreenResources(screen); | 720 XRRFreeScreenResources(screen); |
| 721 XUngrabServer(display); | 721 XUngrabServer(display); |
| 722 | 722 |
| 723 return success; | 723 return true; |
| 724 } | 724 } |
| 725 | 725 |
| 726 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { | 726 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { |
| 727 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayMode"); | 727 TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayMode"); |
| 728 if (output_state_ == STATE_INVALID || | 728 if (output_state_ == STATE_INVALID || |
| 729 output_state_ == STATE_HEADLESS || | 729 output_state_ == STATE_HEADLESS || |
| 730 output_state_ == STATE_SINGLE) | 730 output_state_ == STATE_SINGLE) |
| 731 return false; | 731 return false; |
| 732 | 732 |
| 733 if (output_state_ == new_state) | 733 if (output_state_ == new_state) |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 836 | 836 |
| 837 // static | 837 // static |
| 838 bool OutputConfigurator::IsInternalOutputName(const std::string& name) { | 838 bool OutputConfigurator::IsInternalOutputName(const std::string& name) { |
| 839 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; | 839 return name.find(kInternal_LVDS) == 0 || name.find(kInternal_eDP) == 0; |
| 840 } | 840 } |
| 841 | 841 |
| 842 void OutputConfigurator::SuspendDisplays() { | 842 void OutputConfigurator::SuspendDisplays() { |
| 843 // Turn displays on before suspend. At this point, the backlight is off, | 843 // Turn displays on before suspend. At this point, the backlight is off, |
| 844 // so we turn on the internal display so that we can resume directly into | 844 // so we turn on the internal display so that we can resume directly into |
| 845 // "on" state. This greatly reduces resume times. | 845 // "on" state. This greatly reduces resume times. |
| 846 ScreenPowerSet(true, true); | 846 SetDisplayPowerState(DISPLAY_POWER_ALL_ON); |
| 847 // We need to make sure that the monitor configuration we just did actually | 847 // We need to make sure that the monitor configuration we just did actually |
| 848 // completes before we return, because otherwise the X message could be | 848 // completes before we return, because otherwise the X message could be |
| 849 // racing with the HandleSuspendReadiness message. | 849 // racing with the HandleSuspendReadiness message. |
| 850 XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), 0); | 850 XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), 0); |
| 851 } | 851 } |
| 852 | 852 |
| 853 void OutputConfigurator::NotifyOnDisplayChanged() { | 853 void OutputConfigurator::NotifyOnDisplayChanged() { |
| 854 TRACE_EVENT0("chromeos", "OutputConfigurator::NotifyOnDisplayChanged"); | 854 TRACE_EVENT0("chromeos", "OutputConfigurator::NotifyOnDisplayChanged"); |
| 855 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); | 855 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged()); |
| 856 } | 856 } |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1337 // static | 1337 // static |
| 1338 RRMode OutputConfigurator::GetOutputNativeMode( | 1338 RRMode OutputConfigurator::GetOutputNativeMode( |
| 1339 const XRROutputInfo* output_info) { | 1339 const XRROutputInfo* output_info) { |
| 1340 if (output_info->nmode <= 0) | 1340 if (output_info->nmode <= 0) |
| 1341 return None; | 1341 return None; |
| 1342 | 1342 |
| 1343 return output_info->modes[0]; | 1343 return output_info->modes[0]; |
| 1344 } | 1344 } |
| 1345 | 1345 |
| 1346 } // namespace chromeos | 1346 } // namespace chromeos |
| OLD | NEW |