Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / ui / display / chromeos / output_configurator.h
1 // Copyright 2014 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 UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_
6 #define UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_
7
8 #include <stdint.h>
9
10 #include <map>
11 #include <string>
12 #include <vector>
13
14 #include "base/event_types.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/timer/timer.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
19 #include "ui/display/chromeos/native_display_observer.h"
20 #include "ui/display/display_constants.h"
21 #include "ui/display/display_export.h"
22
23 namespace gfx {
24 class Point;
25 class Size;
26 }
27
28 namespace ui {
29 class DisplayMode;
30 class DisplaySnapshot;
31 class NativeDisplayDelegate;
32
33 // This class interacts directly with the system display configurator.
34 class DISPLAY_EXPORT OutputConfigurator : public NativeDisplayObserver {
35  public:
36   typedef uint64_t OutputProtectionClientId;
37   static const OutputProtectionClientId kInvalidClientId = 0;
38
39   struct CoordinateTransformation {
40     // Initialized to the identity transformation.
41     CoordinateTransformation();
42
43     float x_scale;
44     float x_offset;
45     float y_scale;
46     float y_offset;
47   };
48
49   struct DisplayState {
50     DisplayState();
51
52     DisplaySnapshot* display;  // Not owned.
53
54     // XInput device ID or 0 if this output isn't a touchscreen.
55     int touch_device_id;
56
57     CoordinateTransformation transform;
58
59     // User-selected mode for the output.
60     const DisplayMode* selected_mode;
61
62     // Mode used when displaying the same desktop on multiple outputs.
63     const DisplayMode* mirror_mode;
64   };
65
66   typedef std::vector<DisplayState> DisplayStateList;
67
68   class Observer {
69    public:
70     virtual ~Observer() {}
71
72     // Called after the display mode has been changed. |output| contains the
73     // just-applied configuration. Note that the X server is no longer grabbed
74     // when this method is called, so the actual configuration could've changed
75     // already.
76     virtual void OnDisplayModeChanged(
77         const std::vector<DisplayState>& outputs) {}
78
79     // Called after a display mode change attempt failed. |failed_new_state| is
80     // the new state which the system failed to enter.
81     virtual void OnDisplayModeChangeFailed(OutputState failed_new_state) {}
82   };
83
84   // Interface for classes that make decisions about which output state
85   // should be used.
86   class StateController {
87    public:
88     virtual ~StateController() {}
89
90     // Called when displays are detected.
91     virtual OutputState GetStateForDisplayIds(
92         const std::vector<int64_t>& display_ids) const = 0;
93
94     // Queries the resolution (|size|) in pixels to select output mode for the
95     // given display id.
96     virtual bool GetResolutionForDisplayId(int64_t display_id,
97                                            gfx::Size* size) const = 0;
98   };
99
100   // Interface for classes that implement software based mirroring.
101   class SoftwareMirroringController {
102    public:
103     virtual ~SoftwareMirroringController() {}
104
105     // Called when the hardware mirroring failed.
106     virtual void SetSoftwareMirroring(bool enabled) = 0;
107   };
108
109   class TouchscreenDelegate {
110    public:
111     virtual ~TouchscreenDelegate() {}
112
113     // Searches for touchscreens among input devices,
114     // and tries to match them up to screens in |outputs|.
115     // |outputs| is an array of detected screens.
116     // If a touchscreen with same resolution as an output's native mode
117     // is detected, its id will be stored in this output.
118     virtual void AssociateTouchscreens(std::vector<DisplayState>* outputs) = 0;
119
120     // Configures XInput's Coordinate Transformation Matrix property.
121     // |touch_device_id| the ID of the touchscreen device to configure.
122     // |ctm| contains the desired transformation parameters.  The offsets
123     // in it should be normalized so that 1 corresponds to the X or Y axis
124     // size for the corresponding offset.
125     virtual void ConfigureCTM(int touch_device_id,
126                               const CoordinateTransformation& ctm) = 0;
127   };
128
129   // Helper class used by tests.
130   class TestApi {
131    public:
132     TestApi(OutputConfigurator* configurator) : configurator_(configurator) {}
133     ~TestApi() {}
134
135     // If |configure_timer_| is started, stops the timer, runs
136     // ConfigureOutputs(), and returns true; returns false otherwise.
137     bool TriggerConfigureTimeout();
138
139    private:
140     OutputConfigurator* configurator_;  // not owned
141
142     DISALLOW_COPY_AND_ASSIGN(TestApi);
143   };
144
145   // Flags that can be passed to SetDisplayPower().
146   static const int kSetDisplayPowerNoFlags = 0;
147   // Configure displays even if the passed-in state matches |power_state_|.
148   static const int kSetDisplayPowerForceProbe = 1 << 0;
149   // Do not change the state if multiple displays are connected or if the
150   // only connected display is external.
151   static const int kSetDisplayPowerOnlyIfSingleInternalDisplay = 1 << 1;
152
153   // Gap between screens so cursor at bottom of active display doesn't
154   // partially appear on top of inactive display. Higher numbers guard
155   // against larger cursors, but also waste more memory.
156   // For simplicity, this is hard-coded to avoid the complexity of always
157   // determining the DPI of the screen and rationalizing which screen we
158   // need to use for the DPI calculation.
159   // See crbug.com/130188 for initial discussion.
160   static const int kVerticalGap = 60;
161
162   // Returns the mode within |output| that matches the given size with highest
163   // refresh rate. Returns None if no matching output was found.
164   static const DisplayMode* FindDisplayModeMatchingSize(
165       const DisplaySnapshot& output,
166       const gfx::Size& size);
167
168   OutputConfigurator();
169   virtual ~OutputConfigurator();
170
171   OutputState output_state() const { return output_state_; }
172   chromeos::DisplayPowerState power_state() const { return power_state_; }
173   const std::vector<DisplayState>& cached_outputs() const {
174     return cached_outputs_;
175   }
176
177   void set_state_controller(StateController* controller) {
178     state_controller_ = controller;
179   }
180   void set_mirroring_controller(SoftwareMirroringController* controller) {
181     mirroring_controller_ = controller;
182   }
183
184   // Replaces |native_display_delegate_| with |delegate| and sets
185   // |configure_display_| to true.  Should be called before Init().
186   void SetNativeDisplayDelegateForTesting(
187       scoped_ptr<NativeDisplayDelegate> delegate);
188
189   void SetTouchscreenDelegateForTesting(
190       scoped_ptr<TouchscreenDelegate> delegate);
191
192   // Sets the initial value of |power_state_|.  Must be called before Start().
193   void SetInitialDisplayPower(chromeos::DisplayPowerState power_state);
194
195   // Initialization, must be called right after constructor.
196   // |is_panel_fitting_enabled| indicates hardware panel fitting support.
197   void Init(bool is_panel_fitting_enabled);
198
199   // Does initial configuration of displays during startup.
200   // If |background_color_argb| is non zero and there are multiple displays,
201   // OutputConfigurator sets the background color of X's RootWindow to this
202   // color.
203   void ForceInitialConfigure(uint32_t background_color_argb);
204
205   // Stop handling display configuration events/requests.
206   void PrepareForExit();
207
208   // Called when powerd notifies us that some set of displays should be turned
209   // on or off.  This requires enabling or disabling the CRTC associated with
210   // the display(s) in question so that the low power state is engaged.
211   // |flags| contains bitwise-or-ed kSetDisplayPower* values.
212   bool SetDisplayPower(chromeos::DisplayPowerState power_state, int flags);
213
214   // Force switching the display mode to |new_state|. Returns false if
215   // switching failed (possibly because |new_state| is invalid for the
216   // current set of connected outputs).
217   bool SetDisplayMode(OutputState new_state);
218
219   // NativeDisplayDelegate::Observer overrides:
220   virtual void OnConfigurationChanged() OVERRIDE;
221
222   void AddObserver(Observer* observer);
223   void RemoveObserver(Observer* observer);
224
225   // Sets all the displays into pre-suspend mode; usually this means
226   // configure them for their resume state. This allows faster resume on
227   // machines where display configuration is slow.
228   void SuspendDisplays();
229
230   // Reprobes displays to handle changes made while the system was
231   // suspended.
232   void ResumeDisplays();
233
234   const std::map<int, float>& GetMirroredDisplayAreaRatioMap() {
235     return mirrored_display_area_ratio_map_;
236   }
237
238   // Registers a client for output protection and requests a client id. Returns
239   // 0 if requesting failed.
240   OutputProtectionClientId RegisterOutputProtectionClient();
241
242   // Unregisters the client.
243   void UnregisterOutputProtectionClient(OutputProtectionClientId client_id);
244
245   // Queries link status and protection status.
246   // |link_mask| is the type of connected output links, which is a bitmask of
247   // OutputType values. |protection_mask| is the desired protection methods,
248   // which is a bitmask of the OutputProtectionMethod values.
249   // Returns true on success.
250   bool QueryOutputProtectionStatus(OutputProtectionClientId client_id,
251                                    int64_t display_id,
252                                    uint32_t* link_mask,
253                                    uint32_t* protection_mask);
254
255   // Requests the desired protection methods.
256   // |protection_mask| is the desired protection methods, which is a bitmask
257   // of the OutputProtectionMethod values.
258   // Returns true when the protection request has been made.
259   bool EnableOutputProtection(OutputProtectionClientId client_id,
260                               int64_t display_id,
261                               uint32_t desired_protection_mask);
262
263   // Checks the available color profiles for |display_id| and fills the result
264   // into |profiles|.
265   std::vector<ui::ColorCalibrationProfile> GetAvailableColorCalibrationProfiles(
266       int64_t display_id);
267
268   // Updates the color calibration to |new_profile|.
269   bool SetColorCalibrationProfile(
270       int64_t display_id,
271       ui::ColorCalibrationProfile new_profile);
272
273  private:
274   // Mapping a display_id to a protection request bitmask.
275   typedef std::map<int64_t, uint32_t> DisplayProtections;
276   // Mapping a client to its protection request.
277   typedef std::map<OutputProtectionClientId, DisplayProtections>
278       ProtectionRequests;
279
280   // Updates |cached_outputs_| to contain currently-connected outputs. Calls
281   // |delegate_->GetOutputs()| and then does additional work, like finding the
282   // mirror mode and setting user-preferred modes. Note that the server must be
283   // grabbed via |delegate_->GrabServer()| first.
284   void UpdateCachedOutputs();
285
286   // Helper method for UpdateCachedOutputs() that initializes the passed-in
287   // outputs' |mirror_mode| fields by looking for a mode in |internal_output|
288   // and |external_output| having the same resolution. Returns false if a shared
289   // mode wasn't found or created.
290   //
291   // |try_panel_fitting| allows creating a panel-fitting mode for
292   // |internal_output| instead of only searching for a matching mode (note that
293   // it may lead to a crash if |internal_info| is not capable of panel fitting).
294   //
295   // |preserve_aspect| limits the search/creation only to the modes having the
296   // native aspect ratio of |external_output|.
297   bool FindMirrorMode(DisplayState* internal_output,
298                       DisplayState* external_output,
299                       bool try_panel_fitting,
300                       bool preserve_aspect);
301
302   // Configures outputs.
303   void ConfigureOutputs();
304
305   // Notifies observers about an attempted state change.
306   void NotifyObservers(bool success, OutputState attempted_state);
307
308   // Switches to the state specified in |output_state| and |power_state|.
309   // If the hardware mirroring failed and |mirroring_controller_| is set,
310   // it switches to |STATE_DUAL_EXTENDED| and calls |SetSoftwareMirroring()|
311   // to enable software based mirroring.
312   // On success, updates |output_state_|, |power_state_|, and |cached_outputs_|
313   // and returns true.
314   bool EnterStateOrFallBackToSoftwareMirroring(
315       OutputState output_state,
316       chromeos::DisplayPowerState power_state);
317
318   // Switches to the state specified in |output_state| and |power_state|.
319   // On success, updates |output_state_|, |power_state_|, and
320   // |cached_outputs_| and returns true.
321   bool EnterState(OutputState output_state,
322                   chromeos::DisplayPowerState power_state);
323
324   // Returns the output state that should be used with |cached_outputs_| while
325   // in |power_state|.
326   OutputState ChooseOutputState(chromeos::DisplayPowerState power_state) const;
327
328   // Computes the relevant transformation for mirror mode.
329   // |output| is the output on which mirror mode is being applied.
330   // Returns the transformation or identity if computations fail.
331   CoordinateTransformation GetMirrorModeCTM(const DisplayState& output);
332
333   // Computes the relevant transformation for extended mode. |output| is the
334   // output on which extended mode is being applied. |new_origin| is the
335   // position of the output on the framebuffer. |framebuffer_size| is the
336   // size of the combined framebuffer.
337   // Returns the transformation or identity if computations fail.
338   CoordinateTransformation GetExtendedModeCTM(
339       const DisplayState& output,
340       const gfx::Point& new_origin,
341       const gfx::Size& framebuffer_size);
342
343   // Returns the ratio between mirrored mode area and native mode area:
344   // (mirror_mode_width * mirrow_mode_height) / (native_width * native_height)
345   float GetMirroredDisplayAreaRatio(const DisplayState& output);
346
347   // Applies output protections according to requests.
348   bool ApplyProtections(const DisplayProtections& requests);
349
350   StateController* state_controller_;
351   SoftwareMirroringController* mirroring_controller_;
352   scoped_ptr<NativeDisplayDelegate> native_display_delegate_;
353   scoped_ptr<TouchscreenDelegate> touchscreen_delegate_;
354
355   // Used to enable modes which rely on panel fitting.
356   bool is_panel_fitting_enabled_;
357
358   // Key of the map is the touch display's id, and the value of the map is the
359   // touch display's area ratio in mirror mode defined as :
360   // mirror_mode_area / native_mode_area.
361   // This is used for scaling touch event's radius when the touch display is in
362   // mirror mode :
363   // new_touch_radius = sqrt(area_ratio) * old_touch_radius
364   std::map<int, float> mirrored_display_area_ratio_map_;
365
366   // This is detected by the constructor to determine whether or not we should
367   // be enabled.  If we aren't running on ChromeOS, we can't assume that the
368   // Xrandr X11 extension is supported.
369   // If this flag is set to false, any attempts to change the output
370   // configuration to immediately fail without changing the state.
371   bool configure_display_;
372
373   // The current display state.
374   OutputState output_state_;
375
376   // The current power state.
377   chromeos::DisplayPowerState power_state_;
378
379   // Most-recently-used output configuration. Note that the actual
380   // configuration changes asynchronously.
381   DisplayStateList cached_outputs_;
382
383   ObserverList<Observer> observers_;
384
385   // The timer to delay configuring outputs. See also the comments in
386   // Dispatch().
387   scoped_ptr<base::OneShotTimer<OutputConfigurator> > configure_timer_;
388
389   // Id for next output protection client.
390   OutputProtectionClientId next_output_protection_client_id_;
391
392   // Output protection requests of each client.
393   ProtectionRequests client_protection_requests_;
394
395   DISALLOW_COPY_AND_ASSIGN(OutputConfigurator);
396 };
397
398 }  // namespace ui
399
400 #endif  // UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_