Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: ash/touch/touch_transformer_controller.cc

Issue 191223007: Move touch CTM from X into Chrome (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: fix all the unittests Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "ash/touch/touch_transformer_controller.h"
6
7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_manager.h"
9 #include "ash/host/ash_window_tree_host.h"
10 #include "ash/root_window_controller.h"
11 #include "ash/shell.h"
12 #include "ui/aura/window_tree_host.h"
13 #include "ui/display/chromeos/display_configurator.h"
14 #include "ui/display/types/chromeos/display_snapshot.h"
15 #include "ui/events/x/device_data_manager.h"
16
17 namespace ash {
18
19 namespace {
20
21 DisplayManager* GetDisplayManager() {
22 return Shell::GetInstance()->display_manager();
23 }
24
25 } // namespace
26
27 // This function computes the extended mode TouchTransformer for
28 // |touch_display|. The TouchTransformer maps the touch event position
29 // from framebuffer size to the display size.
30 ui::TouchTransformer
31 TouchTransformerController::GetExtendedModeTouchTransformer(
32 const DisplayInfo& touch_display, const gfx::Size& fb_size) const {
33 ui::TouchTransformer ctm;
34 if (touch_display.touch_device_id() == 0 ||
35 fb_size.width() == 0.0 ||
36 fb_size.height() == 0.0)
37 return ctm;
38 float width = touch_display.bounds_in_native().width();
39 float height = touch_display.bounds_in_native().height();
40 ctm.x_scale = width / fb_size.width();
41 ctm.x_offset = 0;
42 ctm.y_scale = height / fb_size.height();
43 ctm.y_offset = 0;
44 return ctm;
45 }
46
47 bool TouchTransformerController::ShouldComputeMirrorModeTouchTransformer(
48 const DisplayInfo& touch_display) const {
49 if (force_compute_mirror_mode_touch_transformer_)
50 return true;
51
52 if (touch_display.touch_device_id() == 0)
53 return false;
54
55 const ui::DisplayConfigurator::DisplayState* state = NULL;
56 const std::vector<ui::DisplayConfigurator::DisplayState>& cached_displays =
57 Shell::GetInstance()->display_configurator()->cached_displays();
58 for (size_t i = 0; i < cached_displays.size(); i++) {
59 if (cached_displays[i].touch_device_id == touch_display.touch_device_id()) {
60 state = &cached_displays[i];
61 break;
62 }
63 }
64
65 if (!state || state->mirror_mode == state->display->native_mode() ||
66 !state->display->is_aspect_preserving_scaling()) {
67 return false;
68 }
69 return true;
70 }
71
72 // This function computes the mirror mode TouchTransformer for |touch_display|.
73 // When internal monitor is applied a resolution that does not have
74 // the same aspect ratio as its native resolution, there would be
75 // blank regions in the letterboxing/pillarboxing mode.
76 // The TouchTransformer will make sure the touch events on the blank region
77 // have negative coordinates and touch events within the chrome region
78 // have the correct positive coordinates.
79 ui::TouchTransformer TouchTransformerController::GetMirrorModeTouchTransformer(
80 const DisplayInfo& touch_display) const {
81 ui::TouchTransformer ctm;
82 if (!ShouldComputeMirrorModeTouchTransformer(touch_display))
83 return ctm;
84
85 float mirror_width = touch_display.bounds_in_native().width();
86 float mirror_height = touch_display.bounds_in_native().height();
87 float native_width = 0;
88 float native_height = 0;
89
90 std::vector<DisplayMode> modes = touch_display.display_modes();
91 for (size_t i = 0; i < modes.size(); i++) {
92 if (modes[i].native) {
93 native_width = modes[i].size.width();
94 native_height = modes[i].size.height();
95 break;
96 }
97 }
98
99 if (native_height == 0.0 || mirror_height == 0.0 ||
100 native_width == 0.0 || mirror_width == 0.0)
101 return ctm;
102
103 float native_ar = static_cast<float>(native_width) /
104 static_cast<float>(native_height);
105 float mirror_ar = static_cast<float>(mirror_width) /
106 static_cast<float>(mirror_height);
107
108 if (mirror_ar > native_ar) { // Letterboxing
109 ctm.y_scale = mirror_ar / native_ar;
110 ctm.y_offset = (1.0 - mirror_ar / native_ar) * 0.5 * mirror_height;
111 return ctm;
112 }
113
114 if (native_ar > mirror_ar) { // Pillarboxing
115 ctm.x_scale = native_ar / mirror_ar;
116 ctm.x_offset = (1.0 - native_ar / mirror_ar) * 0.5 * mirror_width;
117 return ctm;
118 }
119
120 return ctm; // Same aspect ratio - return identity
121 }
122
123 TouchTransformerController::TouchTransformerController() :
124 force_compute_mirror_mode_touch_transformer_ (false) {
125 Shell::GetInstance()->display_controller()->AddObserver(this);
126 }
127
128 TouchTransformerController::~TouchTransformerController() {
129 Shell::GetInstance()->display_controller()->RemoveObserver(this);
130 }
131
132 void TouchTransformerController::UpdateTouchTransformer() const {
133 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
134 device_manager->ClearTouchTransformerRecord();
135
136 // Display IDs and DisplayInfo for mirror or extended mode.
137 int64 display1_id = gfx::Display::kInvalidDisplayID;
138 int64 display2_id = gfx::Display::kInvalidDisplayID;
139 DisplayInfo display1;
140 DisplayInfo display2;
141 // Display ID and DisplayInfo for single display mode.
142 int64 single_display_id = gfx::Display::kInvalidDisplayID;
143 DisplayInfo single_display;
144
145 DisplayController* display_controller =
146 Shell::GetInstance()->display_controller();
147 ui::MultipleDisplayState display_state =
148 Shell::GetInstance()->display_configurator()->display_state();
149 if (display_state == ui::MULTIPLE_DISPLAY_STATE_INVALID ||
150 display_state == ui::MULTIPLE_DISPLAY_STATE_HEADLESS) {
151 return;
152 } else if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR ||
153 display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
154 // TODO(miletus) : Handle DUAL_EXTENDED with software mirroring.
155 DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair();
156 display1_id = id_pair.first;
157 display2_id = id_pair.second;
158 DCHECK(display1_id != gfx::Display::kInvalidDisplayID &&
159 display2_id != gfx::Display::kInvalidDisplayID);
160 display1 = GetDisplayManager()->GetDisplayInfo(display1_id);
161 display2 = GetDisplayManager()->GetDisplayInfo(display2_id);
162 } else {
163 single_display_id = GetDisplayManager()->first_display_id();
164 DCHECK(single_display_id != gfx::Display::kInvalidDisplayID);
165 single_display = GetDisplayManager()->GetDisplayInfo(single_display_id);
166 }
167
168 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) {
169 // In mirror mode, both displays share the same root window so
170 // both display ids are associated with the root window.
171 aura::Window* root = display_controller->GetPrimaryRootWindow();
172 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
173 display1_id, display2_id);
174 device_manager->UpdateTouchInfoForDisplay(
175 display1_id,
176 display1.touch_device_id(),
177 GetMirrorModeTouchTransformer(display1));
178 device_manager->UpdateTouchInfoForDisplay(
179 display2_id,
180 display2.touch_device_id(),
181 GetMirrorModeTouchTransformer(display2));
182 return;
183 }
184
185 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
186 // In extended mode, each display is associated with one root window.
187 aura::Window* root1 =
188 display_controller->GetRootWindowForDisplayId(display1_id);
189 aura::Window* root2 =
190 display_controller->GetRootWindowForDisplayId(display2_id);
191 RootWindowController::ForWindow(root1)->ash_host()->UpdateDisplayID(
192 display1_id, gfx::Display::kInvalidDisplayID);
193 RootWindowController::ForWindow(root2)->ash_host()->UpdateDisplayID(
194 display2_id, gfx::Display::kInvalidDisplayID);
195 gfx::Size fb_size =
196 Shell::GetInstance()->display_configurator()->framebuffer_size();
197 device_manager->UpdateTouchInfoForDisplay(
198 display1_id,
199 display1.touch_device_id(),
200 GetExtendedModeTouchTransformer(display1, fb_size));
201 device_manager->UpdateTouchInfoForDisplay(
202 display2_id,
203 display2.touch_device_id(),
204 GetExtendedModeTouchTransformer(display2, fb_size));
205 return;
206 }
207
208 // Single display mode. The root window has one associated display id.
209 aura::Window* root =
210 display_controller->GetRootWindowForDisplayId(single_display.id());
211 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
212 single_display.id(), gfx::Display::kInvalidDisplayID);
213 device_manager->UpdateTouchInfoForDisplay(single_display_id,
214 single_display.touch_device_id(),
215 ui::TouchTransformer());
216 }
217
218 void TouchTransformerController::OnDisplaysInitialized() {
219 UpdateTouchTransformer();
220 }
221
222 void TouchTransformerController::OnDisplayConfigurationChanged() {
223 UpdateTouchTransformer();
224 }
225
226 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698