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/dpms.h> | 8 #include <X11/extensions/dpms.h> |
9 #include <X11/extensions/Xrandr.h> | 9 #include <X11/extensions/Xrandr.h> |
10 | 10 |
11 // Xlib defines Status as int which causes our include of dbus/bus.h to fail | 11 // Xlib defines Status as int which causes our include of dbus/bus.h to fail |
12 // when it tries to name an enum Status. Thus, we need to undefine it (note | 12 // when it tries to name an enum Status. Thus, we need to undefine it (note |
13 // that this will cause a problem if code needs to use the Status type). | 13 // that this will cause a problem if code needs to use the Status type). |
14 // RootWindow causes similar problems in that there is a Chromium type with that | 14 // RootWindow causes similar problems in that there is a Chromium type with that |
15 // name. | 15 // name. |
16 #undef Status | 16 #undef Status |
17 #undef RootWindow | 17 #undef RootWindow |
18 | 18 |
19 #include "base/bind.h" | |
19 #include "base/chromeos/chromeos_version.h" | 20 #include "base/chromeos/chromeos_version.h" |
20 #include "base/logging.h" | 21 #include "base/logging.h" |
21 #include "base/message_pump_aurax11.h" | 22 #include "base/message_pump_aurax11.h" |
22 #include "base/metrics/histogram.h" | 23 #include "base/metrics/histogram.h" |
23 #include "base/perftimer.h" | 24 #include "base/perftimer.h" |
24 #include "chromeos/dbus/dbus_thread_manager.h" | 25 #include "chromeos/dbus/dbus_thread_manager.h" |
25 #include "dbus/bus.h" | 26 #include "dbus/bus.h" |
26 #include "dbus/exported_object.h" | 27 #include "dbus/exported_object.h" |
27 #include "dbus/message.h" | 28 #include "dbus/message.h" |
28 #include "dbus/object_path.h" | 29 #include "dbus/object_path.h" |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
749 } | 750 } |
750 return success; | 751 return success; |
751 } | 752 } |
752 | 753 |
753 bool OutputConfigurator::SetDisplayMode(State new_state) { | 754 bool OutputConfigurator::SetDisplayMode(State new_state) { |
754 if (output_state_ == STATE_INVALID || | 755 if (output_state_ == STATE_INVALID || |
755 output_state_ == STATE_HEADLESS || | 756 output_state_ == STATE_HEADLESS || |
756 output_state_ == STATE_SINGLE) | 757 output_state_ == STATE_SINGLE) |
757 return false; | 758 return false; |
758 | 759 |
759 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 760 if (animation_delegate_.get()) { |
760 CHECK(display != NULL); | 761 animation_delegate_->WillDisplayModeChange( |
761 XGrabServer(display); | 762 base::Bind(&OutputConfigurator::SetDisplayModeInternal, |
762 Window window = DefaultRootWindow(display); | 763 base::Unretained(this), new_state)); |
oshima
2012/07/26 05:27:49
what happen if the display configuration changed d
Jun Mukai
2012/07/26 09:44:03
Added the output_state_ guards for STATE_INVALID/H
| |
763 XRRScreenResources* screen = XRRGetScreenResources(display, window); | 764 } else { |
764 CHECK(screen != NULL); | 765 SetDisplayModeInternal(new_state); |
765 | 766 } |
766 UpdateCacheAndXrandrToState(display, | |
767 screen, | |
768 window, | |
769 new_state); | |
770 XRRFreeScreenResources(screen); | |
771 XUngrabServer(display); | |
772 return true; | 767 return true; |
773 } | 768 } |
774 | 769 |
775 bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { | 770 bool OutputConfigurator::Dispatch(const base::NativeEvent& event) { |
776 // Ignore this event if the Xrandr extension isn't supported. | 771 // Ignore this event if the Xrandr extension isn't supported. |
777 if (is_running_on_chrome_os_ && | 772 if (is_running_on_chrome_os_ && |
778 (event->type - xrandr_event_base_ == RRNotify)) { | 773 (event->type - xrandr_event_base_ == RRNotify)) { |
779 XEvent* xevent = static_cast<XEvent*>(event); | 774 XEvent* xevent = static_cast<XEvent*>(event); |
780 XRRNotifyEvent* notify_event = | 775 XRRNotifyEvent* notify_event = |
781 reinterpret_cast<XRRNotifyEvent*>(xevent); | 776 reinterpret_cast<XRRNotifyEvent*>(xevent); |
782 if (notify_event->subtype == RRNotify_OutputChange) { | 777 if (notify_event->subtype == RRNotify_OutputChange) { |
783 XRROutputChangeNotifyEvent* output_change_event = | 778 XRROutputChangeNotifyEvent* output_change_event = |
784 reinterpret_cast<XRROutputChangeNotifyEvent*>(xevent); | 779 reinterpret_cast<XRROutputChangeNotifyEvent*>(xevent); |
785 if ((output_change_event->connection == RR_Connected) || | 780 if ((output_change_event->connection == RR_Connected) || |
786 (output_change_event->connection == RR_Disconnected)) { | 781 (output_change_event->connection == RR_Disconnected)) { |
787 RecacheAndUseDefaultState(); | 782 RecacheAndUseDefaultState(); |
788 CheckIsProjectingAndNotify(); | 783 CheckIsProjectingAndNotify(); |
789 } | 784 } |
790 // Ignore the case of RR_UnkownConnection. | 785 // Ignore the case of RR_UnkownConnection. |
791 } | 786 } |
792 } | 787 } |
793 return true; | 788 return true; |
794 } | 789 } |
795 | 790 |
791 void OutputConfigurator::SetDisplayModeInternal(State new_state) { | |
792 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); | |
793 CHECK(display != NULL); | |
794 XGrabServer(display); | |
795 Window window = DefaultRootWindow(display); | |
796 XRRScreenResources* screen = XRRGetScreenResources(display, window); | |
797 CHECK(screen != NULL); | |
798 | |
799 UpdateCacheAndXrandrToState(display, | |
800 screen, | |
801 window, | |
802 new_state); | |
803 XRRFreeScreenResources(screen); | |
804 XUngrabServer(display); | |
805 if (animation_delegate_.get()) { | |
806 MessageLoop::current()->PostTask( | |
807 FROM_HERE, base::Bind(&AnimationDelegate::OnDisplayModeChanged, | |
808 base::Unretained(animation_delegate_.get()))); | |
809 } | |
810 } | |
811 | |
796 void OutputConfigurator::CheckIsProjectingAndNotify() { | 812 void OutputConfigurator::CheckIsProjectingAndNotify() { |
797 // Determine if there is an "internal" output and how many outputs are | 813 // Determine if there is an "internal" output and how many outputs are |
798 // connected. | 814 // connected. |
799 bool has_internal_output = false; | 815 bool has_internal_output = false; |
800 int connected_output_count = 0; | 816 int connected_output_count = 0; |
801 for (int i = 0; i < output_count_; ++i) { | 817 for (int i = 0; i < output_count_; ++i) { |
802 if (output_cache_[i].is_connected) { | 818 if (output_cache_[i].is_connected) { |
803 connected_output_count += 1; | 819 connected_output_count += 1; |
804 has_internal_output |= output_cache_[i].is_internal; | 820 has_internal_output |= output_cache_[i].is_internal; |
805 } | 821 } |
(...skipping 12 matching lines...) Expand all Loading... | |
818 power_manager::kSetIsProjectingMethod); | 834 power_manager::kSetIsProjectingMethod); |
819 dbus::MessageWriter writer(&method_call); | 835 dbus::MessageWriter writer(&method_call); |
820 writer.AppendBool(is_projecting); | 836 writer.AppendBool(is_projecting); |
821 power_manager_proxy->CallMethod( | 837 power_manager_proxy->CallMethod( |
822 &method_call, | 838 &method_call, |
823 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 839 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
824 dbus::ObjectProxy::EmptyResponseCallback()); | 840 dbus::ObjectProxy::EmptyResponseCallback()); |
825 } | 841 } |
826 | 842 |
827 } // namespace chromeos | 843 } // namespace chromeos |
OLD | NEW |