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