| 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 |