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

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

Issue 191223007: Move touch CTM from X into Chrome (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: move CTM update code into a separate file ash/touch/touch_ctm_controller.cc Created 6 years, 9 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 (c) 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_ctm_controller.h"
6
7 #include "ash/display/display_controller.h"
8 #include "ash/display/display_manager.h"
9 #include "ash/shell.h"
10 #include "ui/aura/window_tree_host.h"
11 #include "ui/events/touch_ctm.h"
12
13 #if defined(OS_CHROMEOS) && defined(USE_X11)
oshima 2014/03/14 21:53:53 Since this make sense only on chromeos + x11, it's
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
14 #include "ui/events/x/device_data_manager.h"
15 #endif // defined(OS_CHROMEOS) && defined(USE_X11)
16
17 namespace ash {
18
19 namespace {
20
21 internal::DisplayManager* GetDisplayManager() {
22 return Shell::GetInstance()->display_manager();
23 }
24
25 #if defined(OS_CHROMEOS) && defined(USE_X11)
26 // This function computes the extended mode TouchCTM for |touch_display|.
27 // An example of how to calculate the extended CTM.
28 // Suppose we have 2 monitors, the first one has size 1366 x 768.
29 // The second one has size 2560 x 1600
30 // The total size of framebuffer is 2560 x 2428
31 // where 2428 = 768 + 60 (hidden gap) + 1600
32 // and the sceond monitor is translated to Point (0, 828) in the
sadrul 2014/03/15 19:32:51 second
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 comments removed.
33 // framebuffer.
34 // X will first map input event location to [0, 2560) x [0, 2428),
spang 2014/03/24 18:52:31 Is this really a half-open interval? AFAIK aura e
ynovikov 2014/03/24 19:02:41 No, but I think the numbers make more sense this w
spang 2014/03/24 19:05:31 No it's [0, 2560] x [0, 2428]. That's the point.
spang 2014/03/26 17:30:34 sadrul has fixed my understanding of the coordinat
35 // Then the TouchCTM should map touch events from framebuffer space
36 // to root window space.
37 // For monitor1, we have
38 // x_scale = (1366 - 1) / (2560 - 1)
39 // x_offset = 0
40 // y_scale = (768 - 1) / (2428 - 1)
41 // y_offset = 0
42 // For Monitor 2, we have
43 // x_scale = (2560 - 1) / (2560 - 1)
44 // x_offset = 0
45 // y_scale = (1600 - 1) / (2428 - 1)
46 // y_offset = 0
ynovikov 2014/03/27 23:35:53 This used to be: // y_offset = 828 / (2428 -1) Th
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
47 // See DisplayControllerTest.TouchCTMExtendedMode for the test.
48 ui::TouchCTM GetExtendedModeTouchCTM(
49 const internal::DisplayInfo& touch_display,
50 const internal::DisplayInfo& second_display) {
51 ui::TouchCTM ctm;
52 float width = touch_display.bounds_in_native().width();
53 float height = touch_display.bounds_in_native().height();
54 // float origin_x = touch_display.bounds_in_native().origin().x();
55 // float origin_y = touch_display.bounds_in_native().origin().y();
ynovikov 2014/03/27 23:35:53 This comment is misleading, please remove.
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
56 float framebuffer_width = std::max<int>(
57 width, second_display.bounds_in_native().width());
58 float framebuffer_height =
59 height + chromeos::OutputConfigurator::kVerticalGap +
60 second_display.bounds_in_native().height();
ynovikov 2014/03/27 23:35:53 I don't think this computation is appropriate here
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
61 ctm.x_scale = (width - 1) / (framebuffer_width - 1);
spang 2014/03/26 17:30:34 I think this should be: width / framebuffer_width
ynovikov 2014/03/27 23:35:53 No, as the comment states for Monitor 2, in case w
spang 2014/03/28 16:49:31 Agree completely. However note x/x == (x-1)/(x-1)
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 OK, changed to use width / framebuffer_width. The
62 ctm.x_offset = 0;
63 ctm.y_scale = (height -1) / (framebuffer_height - 1);
spang 2014/03/26 17:30:34 Same here.
ynovikov 2014/03/27 23:35:53 Nit, add space in (height -1)
64 ctm.y_offset = 0;
65 return ctm;
66 }
67
68 // This function computes the mirror mode TouchCTM for |touch_display|.
69 // When internal monitor is applied a resolution that does not have
70 // the same aspect ratio as its native resolution, there would be
71 // blank regions in the letterboxing/pillarboxing mode.
72 // The TouchCTM will make sure the touch events on the blank region
73 // have negative coordinates and touch events within the chrome region
74 // have the correct positive coordinates.
75 ui::TouchCTM GetMirrorModeTouchCTM(
76 const internal::DisplayInfo& touch_display) {
77 ui::TouchCTM ctm;
78 // For external monitor, assuming no letterboxing or pillarboxing
79 // and just use the default TouchCTM.
ynovikov 2014/03/27 23:35:53 Why? Double checking that aspect ratio hasn't chan
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
80 if (touch_display.id() != gfx::Display::InternalDisplayId())
81 return ctm;
82
83 float mirror_width = touch_display.bounds_in_native().width();
84 float mirror_height = touch_display.bounds_in_native().height();
85 float native_width = 0;
86 float native_height = 0;
87
88 internal::DisplayMode native_mode;
89 std::vector<internal::DisplayMode> modes = touch_display.display_modes();
90 for (size_t i = 0; i < modes.size(); i++) {
91 if (modes[i].native) {
92 native_width = modes[i].size.width();
93 native_height = modes[i].size.height();
94 break;
95 }
96 }
97
98 if (native_height == 0.0 || mirror_height == 0.0 ||
99 native_width == 0.0 || mirror_width == 0.0)
100 return ctm;
101
102 float native_ar = static_cast<float>(native_width) /
103 static_cast<float>(native_height);
104 float mirror_ar = static_cast<float>(mirror_width) /
105 static_cast<float>(mirror_height);
106
107 if (mirror_ar > native_ar) { // Letterboxing
108 ctm.x_scale = 1.0;
109 ctm.x_offset = 0.0;
110 ctm.y_scale = mirror_ar / native_ar;
111 ctm.y_offset = (1.0 / mirror_ar - 1.0 / native_ar) * 0.5 * mirror_width;
112 return ctm;
113 }
114
115 if (native_ar > mirror_ar) { // Pillarboxing
116 ctm.y_scale = 1.0;
117 ctm.y_offset = 0.0;
118 ctm.x_scale = native_ar / mirror_ar;
119 ctm.x_offset = (mirror_ar - native_ar) * 0.5 * mirror_height;
120 return ctm;
121 }
122
123 return ctm; // Same aspect ratio - return identity
124 }
125 #endif // defined(OS_CHROMEOS) && defined(USE_X11)
126
127 } // namespace
128
129 TouchCTMController::TouchCTMController() {
130 Shell::GetInstance()->display_controller()->AddObserver(this);
131 }
132
133 TouchCTMController::~TouchCTMController() {
134 Shell::GetInstance()->display_controller()->RemoveObserver(this);
135 }
136
137 void TouchCTMController::UpdateTouchCTM() {
138 #if defined(OS_CHROMEOS) && defined(USE_X11)
139 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
140 device_manager->ClearTouchCTM();
141 device_manager->ClearTouchDeviceToDisplayMap();
142
143 // Display IDs and DisplayInfo for mirror or extended mode.
144 int64 display1_id = gfx::Display::kInvalidDisplayID;
145 int64 display2_id = gfx::Display::kInvalidDisplayID;
146 internal::DisplayInfo display1;
147 internal::DisplayInfo display2;
148 // Display ID and DisplayInfo for single display mode.
149 int64 single_display_id = gfx::Display::kInvalidDisplayID;
150 internal::DisplayInfo single_display;
151
152 const std::map<int64, aura::Window*>& root_windows =
153 Shell::GetInstance()->display_controller()->root_windows();
154
155 ui::OutputState output_state =
156 Shell::GetInstance()->output_configurator()->output_state();
157 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR ||
158 output_state == ui::OUTPUT_STATE_DUAL_EXTENDED) {
159 DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair();
160 display1_id = id_pair.first;
161 display2_id = id_pair.second;
162 if (display1_id == gfx::Display::kInvalidDisplayID ||
163 display2_id == gfx::Display::kInvalidDisplayID)
164 return;
165 display1 = GetDisplayManager()->GetDisplayInfo(display1_id);
166 display2 = GetDisplayManager()->GetDisplayInfo(display2_id);
167 } else {
168 single_display_id = GetDisplayManager()->first_display_id();
169 if (single_display_id == gfx::Display::kInvalidDisplayID)
170 return;
171 single_display = GetDisplayManager()->GetDisplayInfo(single_display_id);
172 }
173
174 if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR) {
175 std::map<int64, aura::Window*>::const_iterator it = root_windows.begin();
sadrul 2014/03/15 19:32:51 In this case, is root_windows.size() == 1?
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 reworked, ptal.
176 // In mirror mode, both displays share the same root window so
177 // both display ids are associated with the root window.
178 for (; it != root_windows.end(); it++)
179 it->second->GetHost()->UpdateDisplayID(display1_id, display2_id);
180 // Update the associated display id and TouchCTM in device manager
181 // if the display is a touch device.
182 if (display1.touch_device_id() != 0) {
183 device_manager->MapTouchDeviceToDisplay(display1.touch_device_id(),
184 display1.id());
185 device_manager->SetTouchCTM(display1.touch_device_id(),
186 GetMirrorModeTouchCTM(display1));
187 }
sadrul 2014/03/15 19:32:51 This block of code should be in DeviceDataManager,
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 done.
188 if (display2.touch_device_id() != 0) {
189 device_manager->MapTouchDeviceToDisplay(display2.touch_device_id(),
190 display2.id());
191 device_manager->SetTouchCTM(display2.touch_device_id(),
192 GetMirrorModeTouchCTM(display2));
193 }
194 return;
195 }
196
197 if (output_state == ui::OUTPUT_STATE_DUAL_EXTENDED) {
198 std::map<int64, aura::Window*>::const_iterator it = root_windows.begin();
199 // In extended mode, each display has one associated root window.
200 for (; it != root_windows.end(); it++) {
201 if (it->first == display1_id) {
202 it->second->GetHost()->UpdateDisplayID(display1_id,
203 gfx::Display::kInvalidDisplayID);
204 } else if (it->first == display2_id) {
205 it->second->GetHost()->UpdateDisplayID(display2_id,
206 gfx::Display::kInvalidDisplayID);
207 }
208 }
209 // Update the associated display id and TouchCTM in device manager
210 // if the display is a touch device.
211 if (display1.touch_device_id() != 0) {
212 device_manager->MapTouchDeviceToDisplay(display1.touch_device_id(),
213 display1.id());
214 device_manager->SetTouchCTM(display1.touch_device_id(),
215 GetExtendedModeTouchCTM(display1, display2));
216 }
217 if (display2.touch_device_id() != 0) {
218 device_manager->MapTouchDeviceToDisplay(display2.touch_device_id(),
219 display2.id());
220 device_manager->SetTouchCTM(display2.touch_device_id(),
221 GetExtendedModeTouchCTM(display2, display1));
222 }
223 return;
224 }
225
226 // Single display mode. The root window has one associated display id.
227 std::map<int64, aura::Window*>::const_iterator it = root_windows.begin();
228 for (; it != root_windows.end(); it++) {
229 if (it->first == single_display.id()) {
230 it->second->GetHost()->UpdateDisplayID(single_display.id(),
231 gfx::Display::kInvalidDisplayID);
232 }
233 }
234 // If the display is a touch display, we add a deafult TouchCTM to the
ynovikov 2014/03/27 23:35:53 default
Yufeng Shen (Slow to review) 2014/04/29 20:34:18 Done.
235 // according root window.
236 if (single_display.touch_device_id() != 0) {
237 device_manager->MapTouchDeviceToDisplay(single_display.touch_device_id(),
238 single_display.id());
239 device_manager->SetTouchCTM(single_display.touch_device_id(),
240 ui::TouchCTM());
241 }
242 #endif
243 }
244
245 void TouchCTMController::OnDisplayConfigurationChanged() {
246 UpdateTouchCTM();
247 }
248
249 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698