Removed unused icon resources from app_list.
[chromium-blink-merge.git] / ash / touch / touch_transformer_controller.cc
blobc70ea850a312560cb479485bdd7d51974ff442dc
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(unsigned 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 ui::TouchscreenDevice& touchscreen,
68 const gfx::Size& framebuffer_size) const {
69 gfx::SizeF current_size = display.bounds_in_native().size();
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
78 gfx::Transform ctm;
80 if (current_size.IsEmpty() || native_size.IsEmpty() || touch_area.IsEmpty() ||
81 touchscreen.id == ui::InputDevice::kInvalidId)
82 return ctm;
84 #if defined(USE_OZONE)
85 // Translate the touch so that it falls within the display bounds.
86 ctm.Translate(display.bounds_in_native().x(),
87 display.bounds_in_native().y());
88 #endif
90 // Take care of panel fitting only if supported.
91 // If panel fitting is enabled then the aspect ratio is preserved and the
92 // display is scaled acordingly. In this case blank regions would be present
93 // in order to center the displayed area.
94 if (display.is_aspect_preserving_scaling()) {
95 float native_ar = native_size.width() / native_size.height();
96 float current_ar = current_size.width() / current_size.height();
98 if (current_ar > native_ar) { // Letterboxing
99 ctm.Translate(
100 0, (1 - current_ar / native_ar) * 0.5 * current_size.height());
101 ctm.Scale(1, current_ar / native_ar);
102 } else if (native_ar > current_ar) { // Pillarboxing
103 ctm.Translate(
104 (1 - native_ar / current_ar) * 0.5 * current_size.width(), 0);
105 ctm.Scale(native_ar / current_ar, 1);
109 // Take care of scaling between touchscreen area and display resolution.
110 ctm.Scale(current_size.width() / touch_area.width(),
111 current_size.height() / touch_area.height());
112 return ctm;
115 TouchTransformerController::TouchTransformerController() {
116 Shell::GetInstance()->display_controller()->AddObserver(this);
119 TouchTransformerController::~TouchTransformerController() {
120 Shell::GetInstance()->display_controller()->RemoveObserver(this);
123 void TouchTransformerController::UpdateTouchTransformer() const {
124 ui::DeviceDataManager* device_manager = ui::DeviceDataManager::GetInstance();
125 device_manager->ClearTouchTransformerRecord();
127 // Display IDs and DisplayInfo for mirror or extended mode.
128 int64 display1_id = gfx::Display::kInvalidDisplayID;
129 int64 display2_id = gfx::Display::kInvalidDisplayID;
130 DisplayInfo display1;
131 DisplayInfo display2;
132 // Display ID and DisplayInfo for single display mode.
133 int64 single_display_id = gfx::Display::kInvalidDisplayID;
134 DisplayInfo single_display;
136 DisplayController* display_controller =
137 Shell::GetInstance()->display_controller();
138 ui::MultipleDisplayState display_state =
139 Shell::GetInstance()->display_configurator()->display_state();
140 if (display_state == ui::MULTIPLE_DISPLAY_STATE_INVALID ||
141 display_state == ui::MULTIPLE_DISPLAY_STATE_HEADLESS) {
142 return;
143 } else if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR ||
144 display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
145 DisplayIdPair id_pair = GetDisplayManager()->GetCurrentDisplayIdPair();
146 display1_id = id_pair.first;
147 display2_id = id_pair.second;
148 DCHECK(display1_id != gfx::Display::kInvalidDisplayID &&
149 display2_id != gfx::Display::kInvalidDisplayID);
150 display1 = GetDisplayManager()->GetDisplayInfo(display1_id);
151 display2 = GetDisplayManager()->GetDisplayInfo(display2_id);
152 device_manager->UpdateTouchRadiusScale(
153 display1.touch_device_id(),
154 GetTouchResolutionScale(
155 display1,
156 FindTouchscreenById(display1.touch_device_id())));
157 device_manager->UpdateTouchRadiusScale(
158 display2.touch_device_id(),
159 GetTouchResolutionScale(
160 display2,
161 FindTouchscreenById(display2.touch_device_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 device_manager->UpdateTouchRadiusScale(
167 single_display.touch_device_id(),
168 GetTouchResolutionScale(
169 single_display,
170 FindTouchscreenById(single_display.touch_device_id())));
173 gfx::Size fb_size =
174 Shell::GetInstance()->display_configurator()->framebuffer_size();
176 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) {
177 // In mirror mode, both displays share the same root window so
178 // both display ids are associated with the root window.
179 aura::Window* root = display_controller->GetPrimaryRootWindow();
180 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
181 display1_id, display2_id);
182 device_manager->UpdateTouchInfoForDisplay(
183 display1_id,
184 display1.touch_device_id(),
185 GetTouchTransform(display1,
186 FindTouchscreenById(display1.touch_device_id()),
187 fb_size));
188 device_manager->UpdateTouchInfoForDisplay(
189 display2_id,
190 display2.touch_device_id(),
191 GetTouchTransform(display2,
192 FindTouchscreenById(display2.touch_device_id()),
193 fb_size));
194 return;
197 if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
198 // In extended but software mirroring mode, ther is only one X root window
199 // that associates with both displays.
200 if (GetDisplayManager()->software_mirroring_enabled()) {
201 aura::Window* root = display_controller->GetPrimaryRootWindow();
202 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
203 display1_id, display2_id);
204 DisplayInfo source_display =
205 gfx::Display::InternalDisplayId() == display1_id ?
206 display1 : display2;
207 // Mapping from framebuffer size to the source display's native
208 // resolution.
209 device_manager->UpdateTouchInfoForDisplay(
210 display1_id,
211 display1.touch_device_id(),
212 GetTouchTransform(source_display,
213 FindTouchscreenById(display1.touch_device_id()),
214 fb_size));
215 device_manager->UpdateTouchInfoForDisplay(
216 display2_id,
217 display2.touch_device_id(),
218 GetTouchTransform(source_display,
219 FindTouchscreenById(display2.touch_device_id()),
220 fb_size));
221 } else {
222 // In actual extended mode, each display is associated with one root
223 // window.
224 aura::Window* root1 =
225 display_controller->GetRootWindowForDisplayId(display1_id);
226 aura::Window* root2 =
227 display_controller->GetRootWindowForDisplayId(display2_id);
228 RootWindowController::ForWindow(root1)->ash_host()->UpdateDisplayID(
229 display1_id, gfx::Display::kInvalidDisplayID);
230 RootWindowController::ForWindow(root2)->ash_host()->UpdateDisplayID(
231 display2_id, gfx::Display::kInvalidDisplayID);
232 // Mapping from framebuffer size to each display's native resolution.
233 device_manager->UpdateTouchInfoForDisplay(
234 display1_id,
235 display1.touch_device_id(),
236 GetTouchTransform(display1,
237 FindTouchscreenById(display1.touch_device_id()),
238 fb_size));
239 device_manager->UpdateTouchInfoForDisplay(
240 display2_id,
241 display2.touch_device_id(),
242 GetTouchTransform(display2,
243 FindTouchscreenById(display2.touch_device_id()),
244 fb_size));
246 return;
249 // Single display mode. The root window has one associated display id.
250 aura::Window* root =
251 display_controller->GetRootWindowForDisplayId(single_display.id());
252 RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
253 single_display.id(), gfx::Display::kInvalidDisplayID);
254 device_manager->UpdateTouchInfoForDisplay(
255 single_display_id,
256 single_display.touch_device_id(),
257 GetTouchTransform(single_display,
258 FindTouchscreenById(single_display.touch_device_id()),
259 fb_size));
262 void TouchTransformerController::OnDisplaysInitialized() {
263 UpdateTouchTransformer();
266 void TouchTransformerController::OnDisplayConfigurationChanged() {
267 UpdateTouchTransformer();
270 } // namespace ash