Remove obsolete parameters from net-internals.
[chromium-blink-merge.git] / ash / touch / touch_transformer_controller.cc
blobd2582c027a3bf1980f3c10b3a990a4108b22de57
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.
5 #include "ash/touch/touch_transformer_controller.h"
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/display_snapshot.h"
15 #include "ui/events/devices/device_data_manager.h"
17 namespace ash {
19 namespace {
21 DisplayManager* GetDisplayManager() {
22 return Shell::GetInstance()->display_manager();
25 ui::TouchscreenDevice FindTouchscreenById(int id) {
26 const std::vector<ui::TouchscreenDevice>& touchscreens =
27 ui::DeviceDataManager::GetInstance()->touchscreen_devices();
28 for (const auto& touchscreen : touchscreens) {
29 if (touchscreen.id == id)
30 return touchscreen;
33 return ui::TouchscreenDevice();
36 } // namespace
38 // This is to compute the scale ratio for the TouchEvent's radius. The
39 // configured resolution of the display is not always the same as the touch
40 // screen's reporting resolution, e.g. the display could be set as
41 // 1920x1080 while the touchscreen is reporting touch position range at
42 // 32767x32767. Touch radius is reported in the units the same as touch position
43 // so we need to scale the touch radius to be compatible with the display's
44 // resolution. We compute the scale as
45 // sqrt of (display_area / touchscreen_area)
46 double TouchTransformerController::GetTouchResolutionScale(
47 const DisplayInfo& touch_display,
48 const ui::TouchscreenDevice& touch_device) const {
49 if (touch_device.id == ui::InputDevice::kInvalidId ||
50 touch_device.size.IsEmpty() ||
51 touch_display.bounds_in_native().size().IsEmpty())
52 return 1.0;
54 double display_area = touch_display.bounds_in_native().size().GetArea();
55 double touch_area = touch_device.size.GetArea();
56 double ratio = std::sqrt(display_area / touch_area);
58 VLOG(2) << "Display size: "
59 << touch_display.bounds_in_native().size().ToString()
60 << ", Touchscreen size: " << touch_device.size.ToString()
61 << ", Touch radius scale ratio: " << ratio;
62 return ratio;
65 gfx::Transform TouchTransformerController::GetTouchTransform(
66 const DisplayInfo& display,
67 const DisplayInfo& touch_display,
68 const ui::TouchscreenDevice& touchscreen,
69 const gfx::Size& framebuffer_size) const {
70 gfx::SizeF current_size = display.bounds_in_native().size();
71 gfx::SizeF touch_native_size = touch_display.GetNativeModeSize();
72 #if defined(USE_OZONE)
73 gfx::SizeF touch_area = touchscreen.size;
74 #elif defined(USE_X11)
75 // On X11 touches are reported in the framebuffer coordinate space.
76 gfx::SizeF touch_area = framebuffer_size;
77 #endif
79 gfx::Transform ctm;
81 if (current_size.IsEmpty() || touch_native_size.IsEmpty() ||
82 touch_area.IsEmpty() || touchscreen.id == ui::InputDevice::kInvalidId)
83 return ctm;
85 #if defined(USE_OZONE)
86 // Translate the touch so that it falls within the display bounds.
87 ctm.Translate(display.bounds_in_native().x(),
88 display.bounds_in_native().y());
89 #endif
91 // Take care of panel fitting only if supported. Panel fitting is emulated in
92 // software mirroring mode (display != touch_display).
93 // If panel fitting is enabled then the aspect ratio is preserved and the
94 // display is scaled acordingly. In this case blank regions would be present
95 // in order to center the displayed area.
96 if (display.is_aspect_preserving_scaling() ||
97 display.id() != touch_display.id()) {
98 float touch_native_ar =
99 touch_native_size.width() / touch_native_size.height();
100 float current_ar = current_size.width() / current_size.height();
102 if (current_ar > touch_native_ar) { // Letterboxing
103 ctm.Translate(
104 0, (1 - current_ar / touch_native_ar) * 0.5 * current_size.height());
105 ctm.Scale(1, current_ar / touch_native_ar);
106 } else if (touch_native_ar > current_ar) { // Pillarboxing
107 ctm.Translate(
108 (1 - touch_native_ar / current_ar) * 0.5 * current_size.width(), 0);
109 ctm.Scale(touch_native_ar / current_ar, 1);
113 // Take care of scaling between touchscreen area and display resolution.
114 ctm.Scale(current_size.width() / touch_area.width(),
115 current_size.height() / touch_area.height());
116 return ctm;
119 TouchTransformerController::TouchTransformerController() {
120 Shell::GetInstance()->display_controller()->AddObserver(this);
123 TouchTransformerController::~TouchTransformerController() {
124 Shell::GetInstance()->display_controller()->RemoveObserver(this);
127 void TouchTransformerController::UpdateTouchTransformer() const {
128 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
129 device_manager->ClearTouchDeviceAssociations();
131 // Display IDs and DisplayInfo for mirror or extended mode.
132 int64 display1_id = gfx::Display::kInvalidDisplayID;
133 int64 display2_id = gfx::Display::kInvalidDisplayID;
134 DisplayInfo display1;
135 DisplayInfo display2;
136 // Display ID and DisplayInfo for single display mode.
137 int64 single_display_id = gfx::Display::kInvalidDisplayID;
138 DisplayInfo single_display;
140 DisplayController* display_controller =
141 Shell::GetInstance()->display_controller();
142 DisplayManager* display_manager = GetDisplayManager();
143 if (display_manager->num_connected_displays() == 0) {
144 return;
145 } else if (display_manager->num_connected_displays() == 1) {
146 single_display_id = display_manager->first_display_id();
147 DCHECK(single_display_id != gfx::Display::kInvalidDisplayID);
148 single_display = display_manager->GetDisplayInfo(single_display_id);
149 device_manager->UpdateTouchRadiusScale(
150 single_display.touch_device_id(),
151 GetTouchResolutionScale(
152 single_display,
153 FindTouchscreenById(single_display.touch_device_id())));
154 } else {
155 DisplayIdPair id_pair = display_manager->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 = display_manager->GetDisplayInfo(display1_id);
161 display2 = display_manager->GetDisplayInfo(display2_id);
162 device_manager->UpdateTouchRadiusScale(
163 display1.touch_device_id(),
164 GetTouchResolutionScale(
165 display1,
166 FindTouchscreenById(display1.touch_device_id())));
167 device_manager->UpdateTouchRadiusScale(
168 display2.touch_device_id(),
169 GetTouchResolutionScale(
170 display2,
171 FindTouchscreenById(display2.touch_device_id())));
174 gfx::Size fb_size =
175 Shell::GetInstance()->display_configurator()->framebuffer_size();
177 if (display_manager->IsInMirrorMode()) {
178 if (GetDisplayManager()->software_mirroring_enabled()) {
179 // In extended but software mirroring mode, there is a WindowTreeHost for
180 // each display, but all touches are forwarded to the primary root
181 // window's WindowTreeHost.
182 DisplayInfo target_display =
183 display_controller->GetPrimaryDisplayId() == display1_id ? display1
184 : display2;
185 device_manager->UpdateTouchInfoForDisplay(
186 target_display.id(), display1.touch_device_id(),
187 GetTouchTransform(target_display, display1,
188 FindTouchscreenById(display1.touch_device_id()),
189 fb_size));
190 device_manager->UpdateTouchInfoForDisplay(
191 target_display.id(), display2.touch_device_id(),
192 GetTouchTransform(target_display, display2,
193 FindTouchscreenById(display2.touch_device_id()),
194 fb_size));
195 } else {
196 // In mirror mode, there is just one WindowTreeHost and two displays. Make
197 // the WindowTreeHost accept touch events from both displays.
198 int64 primary_display_id = display_controller->GetPrimaryDisplayId();
199 device_manager->UpdateTouchInfoForDisplay(
200 primary_display_id, display1.touch_device_id(),
201 GetTouchTransform(display1, display1,
202 FindTouchscreenById(display1.touch_device_id()),
203 fb_size));
204 device_manager->UpdateTouchInfoForDisplay(
205 primary_display_id, display2.touch_device_id(),
206 GetTouchTransform(display2, display2,
207 FindTouchscreenById(display2.touch_device_id()),
208 fb_size));
210 return;
213 if (display_manager->num_connected_displays() > 1) {
214 // In actual extended mode, each display is associated with one
215 // WindowTreeHost.
216 device_manager->UpdateTouchInfoForDisplay(
217 display1_id, display1.touch_device_id(),
218 GetTouchTransform(display1, display1,
219 FindTouchscreenById(display1.touch_device_id()),
220 fb_size));
221 device_manager->UpdateTouchInfoForDisplay(
222 display2_id, display2.touch_device_id(),
223 GetTouchTransform(display2, display2,
224 FindTouchscreenById(display2.touch_device_id()),
225 fb_size));
226 return;
229 // Single display mode. The WindowTreeHost has one associated display id.
230 device_manager->UpdateTouchInfoForDisplay(
231 single_display_id, single_display.touch_device_id(),
232 GetTouchTransform(single_display, single_display,
233 FindTouchscreenById(single_display.touch_device_id()),
234 fb_size));
237 void TouchTransformerController::OnDisplaysInitialized() {
238 UpdateTouchTransformer();
241 void TouchTransformerController::OnDisplayConfigurationChanged() {
242 UpdateTouchTransformer();
245 } // namespace ash