OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CHROMEOS_MONITOR_OUTPUT_CONFIGURATOR_H_ | |
6 #define CHROMEOS_MONITOR_OUTPUT_CONFIGURATOR_H_ | |
7 #pragma once | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/event_types.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/message_loop.h" | |
13 #include "chromeos/chromeos_export.h" | |
14 | |
15 // Forward declarations for Xlib and Xrandr. | |
16 // This is so unused X definitions don't pollute the namespace. | |
17 typedef unsigned long XID; | |
18 typedef XID Window; | |
19 typedef XID RROutput; | |
20 typedef XID RRCrtc; | |
21 typedef XID RRMode; | |
22 | |
23 struct _XRRScreenResources; | |
24 typedef _XRRScreenResources XRRScreenResources; | |
25 | |
26 namespace chromeos { | |
27 | |
28 // The information we need to cache from an output to implement operations such | |
29 // as power state but also to eliminate duplicate operations within a given | |
30 // action (determining which CRTC to use for a given output, for example). | |
31 struct CachedOutputDescription { | |
32 RROutput output; | |
33 RRCrtc crtc; | |
34 RRMode mirror_mode; | |
35 RRMode ideal_mode; | |
36 int x; | |
37 int y; | |
38 bool is_connected; | |
39 bool is_powered_on; | |
40 bool is_internal; | |
41 unsigned long mm_width; | |
42 unsigned long mm_height; | |
43 }; | |
44 | |
45 // Used to describe the state of a multi-monitor configuration. | |
46 enum State { | |
47 STATE_INVALID, | |
48 STATE_HEADLESS, | |
49 STATE_SINGLE, | |
50 STATE_DUAL_MIRROR, | |
51 STATE_DUAL_PRIMARY_ONLY, | |
52 STATE_DUAL_SECONDARY_ONLY, | |
53 }; | |
54 | |
55 // This class interacts directly with the underlying Xrandr API to manipulate | |
56 // CTRCs and Outputs. It will likely grow more state, over time, or expose | |
57 // Output info in other ways as more of the Chrome display code grows up around | |
58 // it. | |
59 class CHROMEOS_EXPORT OutputConfigurator : public MessageLoop::Dispatcher { | |
60 public: | |
61 OutputConfigurator(); | |
62 virtual ~OutputConfigurator(); | |
63 | |
64 State output_state() const { return output_state_; } | |
65 | |
66 // Called when the user hits ctrl-F4 to request a display mode change. | |
67 // This method should only return false if it was called in a single-head or | |
68 // headless mode. | |
69 bool CycleDisplayMode(); | |
70 | |
71 // Called when powerd notifies us that some set of displays should be turned | |
72 // on or off. This requires enabling or disabling the CRTC associated with | |
73 // the display(s) in question so that the low power state is engaged. | |
74 bool ScreenPowerSet(bool power_on, bool all_displays); | |
75 | |
76 // Force switching the display mode to |new_state|. This method is used when | |
77 // the user explicitly changes the display mode in the options UI. Returns | |
78 // false if it was called in a single-head or headless mode. | |
79 bool SetDisplayMode(State new_state); | |
80 | |
81 // Called when an RRNotify event is received. The implementation is | |
82 // interested in the cases of RRNotify events which correspond to output | |
83 // add/remove events. Note that Output add/remove events are sent in response | |
84 // to our own reconfiguration operations so spurious events are common. | |
85 // Spurious events will have no effect. | |
86 virtual bool Dispatch(const base::NativeEvent& event) OVERRIDE; | |
87 | |
88 private: | |
89 // Updates |output_count_|, |output_cache_|, |mirror_supported_|, | |
90 // |primary_output_index_|, and |secondary_output_index_| with new data. | |
91 // Returns true if the update succeeded or false if it was skipped since no | |
92 // actual change was observed. | |
93 // Note that |output_state_| is not updated by this call. | |
94 bool TryRecacheOutputs(Display* display, XRRScreenResources* screen); | |
95 | |
96 // Uses the data stored in |output_cache_| and the given |new_state| to | |
97 // configure the Xrandr interface and then updates |output_state_| to reflect | |
98 // the new state. | |
99 void UpdateCacheAndXrandrToState(Display* display, | |
100 XRRScreenResources* screen, | |
101 Window window, | |
102 State new_state); | |
103 | |
104 // A helper to re-cache instance variable state and transition into the | |
105 // appropriate default state for the observed displays. | |
106 bool RecacheAndUseDefaultState(); | |
107 | |
108 // Checks the |primary_output_index_|, |secondary_output_index_|, and | |
109 // |mirror_supported_| to see how many displays are currently connected and | |
110 // returns the state which is most appropriate as a default state for those | |
111 // displays. | |
112 State GetDefaultState() const; | |
113 | |
114 // Called during start-up to determine what the current state of the displays | |
115 // appears to be, by investigating how the outputs compare to the data stored | |
116 // in |output_cache_|. Returns STATE_INVALID if the current display state | |
117 // doesn't match any supported state. |output_cache_| must be up-to-date with | |
118 // regards to the state of X or this method may return incorrect results. | |
119 State InferCurrentState(Display* display, XRRScreenResources* screen) const; | |
120 | |
121 // Scans the |output_cache_| to determine whether or not we are in a | |
122 // "projecting" state and then calls the DBus kSetIsProjectingMethod on powerd | |
123 // with the result. | |
124 void CheckIsProjectingAndNotify(); | |
125 | |
126 // This is detected by the constructor to determine whether or not we should | |
127 // be enabled. If we aren't running on ChromeOS, we can't assume that the | |
128 // Xrandr X11 extension is supported. | |
129 // If this flag is set to false, any attempts to change the output | |
130 // configuration to immediately fail without changing the state. | |
131 bool is_running_on_chrome_os_; | |
132 | |
133 // The number of outputs in the output_cache_ array. | |
134 int output_count_; | |
135 | |
136 // The list of cached output descriptions (|output_count_| elements long). | |
137 scoped_array<CachedOutputDescription> output_cache_; | |
138 | |
139 // True if |output_cache_| describes a permutation of outputs which support a | |
140 // mirrored device mode. | |
141 bool mirror_supported_; | |
142 | |
143 // The index of the primary connected output in |output_cache_|. -1 if there | |
144 // is no primary output. This implies the machine currently has no outputs. | |
145 int primary_output_index_; | |
146 | |
147 // The index of the secondary connected output in |output_cache_|. -1 if | |
148 // there is no secondary output. This implies the machine currently has one | |
149 // output. | |
150 int secondary_output_index_; | |
151 | |
152 // The base of the event numbers used to represent XRandr events used in | |
153 // decoding events regarding output add/remove. | |
154 int xrandr_event_base_; | |
155 | |
156 // The display state as derived from the outputs observed in |output_cache_|. | |
157 // This is used for rotating display modes. | |
158 State output_state_; | |
159 | |
160 DISALLOW_COPY_AND_ASSIGN(OutputConfigurator); | |
161 }; | |
162 | |
163 } // namespace chromeos | |
164 | |
165 #endif // CHROMEOS_MONITOR_OUTPUT_CONFIGURATOR_H_ | |
OLD | NEW |