OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/touch/touch_transformer_controller.h" | 5 #include "ash/touch/touch_transformer_controller.h" |
6 | 6 |
7 #include "ash/display/display_controller.h" | 7 #include "ash/display/display_controller.h" |
8 #include "ash/display/display_manager.h" | 8 #include "ash/display/display_manager.h" |
9 #include "ash/host/ash_window_tree_host.h" | 9 #include "ash/host/ash_window_tree_host.h" |
10 #include "ash/root_window_controller.h" | 10 #include "ash/root_window_controller.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 double touch_area = touch_device.size.GetArea(); | 55 double touch_area = touch_device.size.GetArea(); |
56 double ratio = std::sqrt(display_area / touch_area); | 56 double ratio = std::sqrt(display_area / touch_area); |
57 | 57 |
58 VLOG(2) << "Display size: " | 58 VLOG(2) << "Display size: " |
59 << touch_display.bounds_in_native().size().ToString() | 59 << touch_display.bounds_in_native().size().ToString() |
60 << ", Touchscreen size: " << touch_device.size.ToString() | 60 << ", Touchscreen size: " << touch_device.size.ToString() |
61 << ", Touch radius scale ratio: " << ratio; | 61 << ", Touch radius scale ratio: " << ratio; |
62 return ratio; | 62 return ratio; |
63 } | 63 } |
64 | 64 |
65 // This function computes the extended mode TouchTransformer for | 65 gfx::Transform TouchTransformerController::GetTouchTransform( |
66 // |touch_display|. The TouchTransformer maps the touch event position | 66 const DisplayInfo& display, |
67 // from framebuffer size to the display size. | 67 const ui::TouchscreenDevice& touchscreen, |
68 gfx::Transform | 68 const gfx::Size& framebuffer_size) const { |
69 TouchTransformerController::GetExtendedModeTouchTransformer( | 69 gfx::SizeF current_size = display.bounds_in_native().size(); |
70 const DisplayInfo& touch_display, const gfx::Size& fb_size) const { | 70 gfx::SizeF native_size = display.GetNativeModeSize(); |
| 71 #if defined(USE_OZONE) |
| 72 gfx::SizeF touch_area = touchscreen.size; |
| 73 #elif defined(USE_X11) |
| 74 // On X11 touches are reported in the framebuffer coordinate space. |
| 75 gfx::SizeF touch_area = framebuffer_size; |
| 76 #endif |
| 77 |
71 gfx::Transform ctm; | 78 gfx::Transform ctm; |
72 if (touch_display.touch_device_id() == 0u || fb_size.width() == 0.0 || | 79 |
73 fb_size.height() == 0.0) | 80 if (current_size.IsEmpty() || native_size.IsEmpty() || touch_area.IsEmpty() || |
| 81 touchscreen.id == ui::InputDevice::kInvalidId) |
74 return ctm; | 82 return ctm; |
75 float width = touch_display.bounds_in_native().width(); | 83 |
76 float height = touch_display.bounds_in_native().height(); | 84 // Take care of panel fitting only if supported. |
77 ctm.Scale(width / fb_size.width(), height / fb_size.height()); | 85 // If panel fitting is enabled then the aspect ratio is preserved and the |
| 86 // display is scaled acordingly. In this case blank regions would be present |
| 87 // in order to center the displayed area. |
| 88 if (display.is_aspect_preserving_scaling()) { |
| 89 float native_ar = native_size.width() / native_size.height(); |
| 90 float current_ar = current_size.width() / current_size.height(); |
| 91 |
| 92 if (current_ar > native_ar) { // Letterboxing |
| 93 ctm.Translate( |
| 94 0, (1 - current_ar / native_ar) * 0.5 * current_size.height()); |
| 95 ctm.Scale(1, current_ar / native_ar); |
| 96 } else if (native_ar > current_ar) { // Pillarboxing |
| 97 ctm.Translate( |
| 98 (1 - native_ar / current_ar) * 0.5 * current_size.width(), 0); |
| 99 ctm.Scale(native_ar / current_ar, 1); |
| 100 } |
| 101 } |
| 102 |
| 103 // Take care of scaling between touchscreen area and display resolution. |
| 104 ctm.Scale(current_size.width() / touch_area.width(), |
| 105 current_size.height() / touch_area.height()); |
78 return ctm; | 106 return ctm; |
79 } | 107 } |
80 | 108 |
81 bool TouchTransformerController::ShouldComputeMirrorModeTouchTransformer( | 109 TouchTransformerController::TouchTransformerController() { |
82 const DisplayInfo& touch_display) const { | |
83 if (force_compute_mirror_mode_touch_transformer_) | |
84 return true; | |
85 | |
86 if (touch_display.touch_device_id() == 0u) | |
87 return false; | |
88 | |
89 if (touch_display.size_in_pixel() == touch_display.GetNativeModeSize() || | |
90 !touch_display.is_aspect_preserving_scaling()) { | |
91 return false; | |
92 } | |
93 | |
94 return true; | |
95 } | |
96 | |
97 // This function computes the mirror mode TouchTransformer for |touch_display|. | |
98 // When internal monitor is applied a resolution that does not have | |
99 // the same aspect ratio as its native resolution, there would be | |
100 // blank regions in the letterboxing/pillarboxing mode. | |
101 // The TouchTransformer will make sure the touch events on the blank region | |
102 // have negative coordinates and touch events within the chrome region | |
103 // have the correct positive coordinates. | |
104 gfx::Transform TouchTransformerController::GetMirrorModeTouchTransformer( | |
105 const DisplayInfo& touch_display) const { | |
106 gfx::Transform ctm; | |
107 if (!ShouldComputeMirrorModeTouchTransformer(touch_display)) | |
108 return ctm; | |
109 | |
110 float mirror_width = touch_display.bounds_in_native().width(); | |
111 float mirror_height = touch_display.bounds_in_native().height(); | |
112 gfx::Size native_mode_size = touch_display.GetNativeModeSize(); | |
113 float native_width = native_mode_size.width(); | |
114 float native_height = native_mode_size.height(); | |
115 | |
116 if (native_height == 0.0 || mirror_height == 0.0 || | |
117 native_width == 0.0 || mirror_width == 0.0) | |
118 return ctm; | |
119 | |
120 float native_ar = native_width / native_height; | |
121 float mirror_ar = mirror_width / mirror_height; | |
122 | |
123 if (mirror_ar > native_ar) { // Letterboxing | |
124 // Translate before scale. | |
125 ctm.Translate(0.0, (1.0 - mirror_ar / native_ar) * 0.5 * mirror_height); | |
126 ctm.Scale(1.0, mirror_ar / native_ar); | |
127 return ctm; | |
128 } | |
129 | |
130 if (native_ar > mirror_ar) { // Pillarboxing | |
131 // Translate before scale. | |
132 ctm.Translate((1.0 - native_ar / mirror_ar) * 0.5 * mirror_width, 0.0); | |
133 ctm.Scale(native_ar / mirror_ar, 1.0); | |
134 return ctm; | |
135 } | |
136 | |
137 return ctm; // Same aspect ratio - return identity | |
138 } | |
139 | |
140 TouchTransformerController::TouchTransformerController() : | |
141 force_compute_mirror_mode_touch_transformer_ (false) { | |
142 Shell::GetInstance()->display_controller()->AddObserver(this); | 110 Shell::GetInstance()->display_controller()->AddObserver(this); |
143 } | 111 } |
144 | 112 |
145 TouchTransformerController::~TouchTransformerController() { | 113 TouchTransformerController::~TouchTransformerController() { |
146 Shell::GetInstance()->display_controller()->RemoveObserver(this); | 114 Shell::GetInstance()->display_controller()->RemoveObserver(this); |
147 } | 115 } |
148 | 116 |
149 void TouchTransformerController::UpdateTouchTransformer() const { | 117 void TouchTransformerController::UpdateTouchTransformer() const { |
150 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); | 118 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance(); |
151 device_manager->ClearTouchTransformerRecord(); | 119 device_manager->ClearTouchTransformerRecord(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 single_display_id = GetDisplayManager()->first_display_id(); | 157 single_display_id = GetDisplayManager()->first_display_id(); |
190 DCHECK(single_display_id != gfx::Display::kInvalidDisplayID); | 158 DCHECK(single_display_id != gfx::Display::kInvalidDisplayID); |
191 single_display = GetDisplayManager()->GetDisplayInfo(single_display_id); | 159 single_display = GetDisplayManager()->GetDisplayInfo(single_display_id); |
192 device_manager->UpdateTouchRadiusScale( | 160 device_manager->UpdateTouchRadiusScale( |
193 single_display.touch_device_id(), | 161 single_display.touch_device_id(), |
194 GetTouchResolutionScale( | 162 GetTouchResolutionScale( |
195 single_display, | 163 single_display, |
196 FindTouchscreenById(single_display.touch_device_id()))); | 164 FindTouchscreenById(single_display.touch_device_id()))); |
197 } | 165 } |
198 | 166 |
| 167 gfx::Size fb_size = |
| 168 Shell::GetInstance()->display_configurator()->framebuffer_size(); |
| 169 |
199 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) { | 170 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) { |
200 // In mirror mode, both displays share the same root window so | 171 // In mirror mode, both displays share the same root window so |
201 // both display ids are associated with the root window. | 172 // both display ids are associated with the root window. |
202 aura::Window* root = display_controller->GetPrimaryRootWindow(); | 173 aura::Window* root = display_controller->GetPrimaryRootWindow(); |
203 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( | 174 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( |
204 display1_id, display2_id); | 175 display1_id, display2_id); |
205 device_manager->UpdateTouchInfoForDisplay( | 176 device_manager->UpdateTouchInfoForDisplay( |
206 display1_id, | 177 display1_id, |
207 display1.touch_device_id(), | 178 display1.touch_device_id(), |
208 GetMirrorModeTouchTransformer(display1)); | 179 GetTouchTransform(display1, |
| 180 FindTouchscreenById(display1.touch_device_id()), |
| 181 fb_size)); |
209 device_manager->UpdateTouchInfoForDisplay( | 182 device_manager->UpdateTouchInfoForDisplay( |
210 display2_id, | 183 display2_id, |
211 display2.touch_device_id(), | 184 display2.touch_device_id(), |
212 GetMirrorModeTouchTransformer(display2)); | 185 GetTouchTransform(display2, |
| 186 FindTouchscreenById(display2.touch_device_id()), |
| 187 fb_size)); |
213 return; | 188 return; |
214 } | 189 } |
215 | 190 |
216 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) { | 191 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) { |
217 gfx::Size fb_size = | |
218 Shell::GetInstance()->display_configurator()->framebuffer_size(); | |
219 // In extended but software mirroring mode, ther is only one X root window | 192 // In extended but software mirroring mode, ther is only one X root window |
220 // that associates with both displays. | 193 // that associates with both displays. |
221 if (GetDisplayManager()->software_mirroring_enabled()) { | 194 if (GetDisplayManager()->software_mirroring_enabled()) { |
222 aura::Window* root = display_controller->GetPrimaryRootWindow(); | 195 aura::Window* root = display_controller->GetPrimaryRootWindow(); |
223 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( | 196 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( |
224 display1_id, display2_id); | 197 display1_id, display2_id); |
225 DisplayInfo source_display = | 198 DisplayInfo source_display = |
226 gfx::Display::InternalDisplayId() == display1_id ? | 199 gfx::Display::InternalDisplayId() == display1_id ? |
227 display1 : display2; | 200 display1 : display2; |
228 // Mapping from framebuffer size to the source display's native | 201 // Mapping from framebuffer size to the source display's native |
229 // resolution. | 202 // resolution. |
230 device_manager->UpdateTouchInfoForDisplay( | 203 device_manager->UpdateTouchInfoForDisplay( |
231 display1_id, | 204 display1_id, |
232 display1.touch_device_id(), | 205 display1.touch_device_id(), |
233 GetExtendedModeTouchTransformer(source_display, fb_size)); | 206 GetTouchTransform(source_display, |
| 207 FindTouchscreenById(display1.touch_device_id()), |
| 208 fb_size)); |
234 device_manager->UpdateTouchInfoForDisplay( | 209 device_manager->UpdateTouchInfoForDisplay( |
235 display2_id, | 210 display2_id, |
236 display2.touch_device_id(), | 211 display2.touch_device_id(), |
237 GetExtendedModeTouchTransformer(source_display, fb_size)); | 212 GetTouchTransform(source_display, |
| 213 FindTouchscreenById(display2.touch_device_id()), |
| 214 fb_size)); |
238 } else { | 215 } else { |
239 // In actual extended mode, each display is associated with one root | 216 // In actual extended mode, each display is associated with one root |
240 // window. | 217 // window. |
241 aura::Window* root1 = | 218 aura::Window* root1 = |
242 display_controller->GetRootWindowForDisplayId(display1_id); | 219 display_controller->GetRootWindowForDisplayId(display1_id); |
243 aura::Window* root2 = | 220 aura::Window* root2 = |
244 display_controller->GetRootWindowForDisplayId(display2_id); | 221 display_controller->GetRootWindowForDisplayId(display2_id); |
245 RootWindowController::ForWindow(root1)->ash_host()->UpdateDisplayID( | 222 RootWindowController::ForWindow(root1)->ash_host()->UpdateDisplayID( |
246 display1_id, gfx::Display::kInvalidDisplayID); | 223 display1_id, gfx::Display::kInvalidDisplayID); |
247 RootWindowController::ForWindow(root2)->ash_host()->UpdateDisplayID( | 224 RootWindowController::ForWindow(root2)->ash_host()->UpdateDisplayID( |
248 display2_id, gfx::Display::kInvalidDisplayID); | 225 display2_id, gfx::Display::kInvalidDisplayID); |
249 // Mapping from framebuffer size to each display's native resolution. | 226 // Mapping from framebuffer size to each display's native resolution. |
250 device_manager->UpdateTouchInfoForDisplay( | 227 device_manager->UpdateTouchInfoForDisplay( |
251 display1_id, | 228 display1_id, |
252 display1.touch_device_id(), | 229 display1.touch_device_id(), |
253 GetExtendedModeTouchTransformer(display1, fb_size)); | 230 GetTouchTransform(display1, |
| 231 FindTouchscreenById(display1.touch_device_id()), |
| 232 fb_size)); |
254 device_manager->UpdateTouchInfoForDisplay( | 233 device_manager->UpdateTouchInfoForDisplay( |
255 display2_id, | 234 display2_id, |
256 display2.touch_device_id(), | 235 display2.touch_device_id(), |
257 GetExtendedModeTouchTransformer(display2, fb_size)); | 236 GetTouchTransform(display2, |
| 237 FindTouchscreenById(display2.touch_device_id()), |
| 238 fb_size)); |
258 } | 239 } |
259 return; | 240 return; |
260 } | 241 } |
261 | 242 |
262 // Single display mode. The root window has one associated display id. | 243 // Single display mode. The root window has one associated display id. |
263 aura::Window* root = | 244 aura::Window* root = |
264 display_controller->GetRootWindowForDisplayId(single_display.id()); | 245 display_controller->GetRootWindowForDisplayId(single_display.id()); |
265 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( | 246 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID( |
266 single_display.id(), gfx::Display::kInvalidDisplayID); | 247 single_display.id(), gfx::Display::kInvalidDisplayID); |
267 device_manager->UpdateTouchInfoForDisplay(single_display_id, | 248 device_manager->UpdateTouchInfoForDisplay( |
268 single_display.touch_device_id(), | 249 single_display_id, |
269 gfx::Transform()); | 250 single_display.touch_device_id(), |
| 251 GetTouchTransform(single_display, |
| 252 FindTouchscreenById(single_display.touch_device_id()), |
| 253 fb_size)); |
270 } | 254 } |
271 | 255 |
272 void TouchTransformerController::OnDisplaysInitialized() { | 256 void TouchTransformerController::OnDisplaysInitialized() { |
273 UpdateTouchTransformer(); | 257 UpdateTouchTransformer(); |
274 } | 258 } |
275 | 259 |
276 void TouchTransformerController::OnDisplayConfigurationChanged() { | 260 void TouchTransformerController::OnDisplayConfigurationChanged() { |
277 UpdateTouchTransformer(); | 261 UpdateTouchTransformer(); |
278 } | 262 } |
279 | 263 |
280 } // namespace ash | 264 } // namespace ash |
OLD | NEW |