#include "ui/aura/window_tree_host.h"
#include "ui/display/chromeos/display_configurator.h"
#include "ui/display/types/display_snapshot.h"
-#include "ui/events/device_data_manager.h"
-#include "ui/events/x/device_data_manager_x11.h"
+#include "ui/events/devices/device_data_manager.h"
namespace ash {
return Shell::GetInstance()->display_manager();
}
+ui::TouchscreenDevice FindTouchscreenById(unsigned int id) {
+ const std::vector<ui::TouchscreenDevice>& touchscreens =
+ ui::DeviceDataManager::GetInstance()->touchscreen_devices();
+ for (auto touchscreen : touchscreens) {
+ if (touchscreen.id == id)
+ return touchscreen;
+ }
+
+ return ui::TouchscreenDevice();
+}
+
} // namespace
// This is to compute the scale ratio for the TouchEvent's radius. The
// resolution. We compute the scale as
// sqrt of (display_area / touchscreen_area)
double TouchTransformerController::GetTouchResolutionScale(
- const DisplayInfo& touch_display) const {
- if (touch_display.touch_device_id() == 0)
- return 1.0;
-
- double min_x, max_x;
- double min_y, max_y;
- if (!ui::DeviceDataManagerX11::GetInstance()->GetDataRange(
- touch_display.touch_device_id(),
- ui::DeviceDataManagerX11::DT_TOUCH_POSITION_X,
- &min_x, &max_x) ||
- !ui::DeviceDataManagerX11::GetInstance()->GetDataRange(
- touch_display.touch_device_id(),
- ui::DeviceDataManagerX11::DT_TOUCH_POSITION_Y,
- &min_y, &max_y)) {
- return 1.0;
- }
-
- double width = touch_display.bounds_in_native().width();
- double height = touch_display.bounds_in_native().height();
-
- if (max_x == 0.0 || max_y == 0.0 || width == 0.0 || height == 0.0)
+ const DisplayInfo& touch_display,
+ const ui::TouchscreenDevice& touch_device) const {
+ if (touch_device.id == ui::InputDevice::kInvalidId ||
+ touch_device.size.IsEmpty() ||
+ touch_display.bounds_in_native().size().IsEmpty())
return 1.0;
- // [0, max_x] -> touchscreen width = max_x + 1
- // [0, max_y] -> touchscreen height = max_y + 1
- max_x += 1.0;
- max_y += 1.0;
+ double display_area = touch_display.bounds_in_native().size().GetArea();
+ double touch_area = touch_device.size.GetArea();
+ double ratio = std::sqrt(display_area / touch_area);
- double ratio = std::sqrt((width * height) / (max_x * max_y));
-
- VLOG(2) << "Screen width/height: " << width << "/" << height
- << ", Touchscreen width/height: " << max_x << "/" << max_y
+ VLOG(2) << "Display size: "
+ << touch_display.bounds_in_native().size().ToString()
+ << ", Touchscreen size: " << touch_device.size.ToString()
<< ", Touch radius scale ratio: " << ratio;
return ratio;
}
-// This function computes the extended mode TouchTransformer for
-// |touch_display|. The TouchTransformer maps the touch event position
-// from framebuffer size to the display size.
-gfx::Transform
-TouchTransformerController::GetExtendedModeTouchTransformer(
- const DisplayInfo& touch_display, const gfx::Size& fb_size) const {
- gfx::Transform ctm;
- if (touch_display.touch_device_id() == 0 ||
- fb_size.width() == 0.0 ||
- fb_size.height() == 0.0)
- return ctm;
- float width = touch_display.bounds_in_native().width();
- float height = touch_display.bounds_in_native().height();
- ctm.Scale(width / fb_size.width(), height / fb_size.height());
- return ctm;
-}
-
-bool TouchTransformerController::ShouldComputeMirrorModeTouchTransformer(
- const DisplayInfo& touch_display) const {
- if (force_compute_mirror_mode_touch_transformer_)
- return true;
-
- if (touch_display.touch_device_id() == 0)
- return false;
-
- DisplayManager* display_manager = Shell::GetInstance()->display_manager();
- const std::vector<gfx::Display>& displays = display_manager->displays();
- const DisplayInfo* info = NULL;
- for (size_t i = 0; i < displays.size(); i++) {
- const DisplayInfo& current_info =
- display_manager->GetDisplayInfo(displays[i].id());
- if (current_info.touch_device_id() == touch_display.touch_device_id()) {
- info = ¤t_info;
- break;
- }
- }
+gfx::Transform TouchTransformerController::GetTouchTransform(
+ const DisplayInfo& display,
+ const ui::TouchscreenDevice& touchscreen,
+ const gfx::Size& framebuffer_size) const {
+ gfx::SizeF current_size = display.bounds_in_native().size();
+ gfx::SizeF native_size = display.GetNativeModeSize();
+#if defined(USE_OZONE)
+ gfx::SizeF touch_area = touchscreen.size;
+#elif defined(USE_X11)
+ // On X11 touches are reported in the framebuffer coordinate space.
+ gfx::SizeF touch_area = framebuffer_size;
+#endif
- if (!info || info->size_in_pixel() == info->GetNativeModeSize() ||
- !info->is_aspect_preserving_scaling()) {
- return false;
- }
- return true;
-}
-
-// This function computes the mirror mode TouchTransformer for |touch_display|.
-// When internal monitor is applied a resolution that does not have
-// the same aspect ratio as its native resolution, there would be
-// blank regions in the letterboxing/pillarboxing mode.
-// The TouchTransformer will make sure the touch events on the blank region
-// have negative coordinates and touch events within the chrome region
-// have the correct positive coordinates.
-gfx::Transform TouchTransformerController::GetMirrorModeTouchTransformer(
- const DisplayInfo& touch_display) const {
gfx::Transform ctm;
- if (!ShouldComputeMirrorModeTouchTransformer(touch_display))
- return ctm;
-
- float mirror_width = touch_display.bounds_in_native().width();
- float mirror_height = touch_display.bounds_in_native().height();
- float native_width = 0;
- float native_height = 0;
- std::vector<DisplayMode> modes = touch_display.display_modes();
- for (size_t i = 0; i < modes.size(); i++) {
- if (modes[i].native) {
- native_width = modes[i].size.width();
- native_height = modes[i].size.height();
- break;
- }
- }
-
- if (native_height == 0.0 || mirror_height == 0.0 ||
- native_width == 0.0 || mirror_width == 0.0)
+ if (current_size.IsEmpty() || native_size.IsEmpty() || touch_area.IsEmpty() ||
+ touchscreen.id == ui::InputDevice::kInvalidId)
return ctm;
- float native_ar = static_cast<float>(native_width) /
- static_cast<float>(native_height);
- float mirror_ar = static_cast<float>(mirror_width) /
- static_cast<float>(mirror_height);
-
- if (mirror_ar > native_ar) { // Letterboxing
- // Translate before scale.
- ctm.Translate(0.0, (1.0 - mirror_ar / native_ar) * 0.5 * mirror_height);
- ctm.Scale(1.0, mirror_ar / native_ar);
- return ctm;
- }
-
- if (native_ar > mirror_ar) { // Pillarboxing
- // Translate before scale.
- ctm.Translate((1.0 - native_ar / mirror_ar) * 0.5 * mirror_width, 0.0);
- ctm.Scale(native_ar / mirror_ar, 1.0);
- return ctm;
+ // Take care of panel fitting only if supported.
+ // If panel fitting is enabled then the aspect ratio is preserved and the
+ // display is scaled acordingly. In this case blank regions would be present
+ // in order to center the displayed area.
+ if (display.is_aspect_preserving_scaling()) {
+ float native_ar = native_size.width() / native_size.height();
+ float current_ar = current_size.width() / current_size.height();
+
+ if (current_ar > native_ar) { // Letterboxing
+ ctm.Translate(
+ 0, (1 - current_ar / native_ar) * 0.5 * current_size.height());
+ ctm.Scale(1, current_ar / native_ar);
+ } else if (native_ar > current_ar) { // Pillarboxing
+ ctm.Translate(
+ (1 - native_ar / current_ar) * 0.5 * current_size.width(), 0);
+ ctm.Scale(native_ar / current_ar, 1);
+ }
}
- return ctm; // Same aspect ratio - return identity
+ // Take care of scaling between touchscreen area and display resolution.
+ ctm.Scale(current_size.width() / touch_area.width(),
+ current_size.height() / touch_area.height());
+ return ctm;
}
-TouchTransformerController::TouchTransformerController() :
- force_compute_mirror_mode_touch_transformer_ (false) {
+TouchTransformerController::TouchTransformerController() {
Shell::GetInstance()->display_controller()->AddObserver(this);
}
display2_id != gfx::Display::kInvalidDisplayID);
display1 = GetDisplayManager()->GetDisplayInfo(display1_id);
display2 = GetDisplayManager()->GetDisplayInfo(display2_id);
- device_manager->UpdateTouchRadiusScale(display1.touch_device_id(),
- GetTouchResolutionScale(display1));
- device_manager->UpdateTouchRadiusScale(display2.touch_device_id(),
- GetTouchResolutionScale(display2));
+ device_manager->UpdateTouchRadiusScale(
+ display1.touch_device_id(),
+ GetTouchResolutionScale(
+ display1,
+ FindTouchscreenById(display1.touch_device_id())));
+ device_manager->UpdateTouchRadiusScale(
+ display2.touch_device_id(),
+ GetTouchResolutionScale(
+ display2,
+ FindTouchscreenById(display2.touch_device_id())));
} else {
single_display_id = GetDisplayManager()->first_display_id();
DCHECK(single_display_id != gfx::Display::kInvalidDisplayID);
single_display = GetDisplayManager()->GetDisplayInfo(single_display_id);
device_manager->UpdateTouchRadiusScale(
single_display.touch_device_id(),
- GetTouchResolutionScale(single_display));
+ GetTouchResolutionScale(
+ single_display,
+ FindTouchscreenById(single_display.touch_device_id())));
}
+ gfx::Size fb_size =
+ Shell::GetInstance()->display_configurator()->framebuffer_size();
+
if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR) {
// In mirror mode, both displays share the same root window so
// both display ids are associated with the root window.
device_manager->UpdateTouchInfoForDisplay(
display1_id,
display1.touch_device_id(),
- GetMirrorModeTouchTransformer(display1));
+ GetTouchTransform(display1,
+ FindTouchscreenById(display1.touch_device_id()),
+ fb_size));
device_manager->UpdateTouchInfoForDisplay(
display2_id,
display2.touch_device_id(),
- GetMirrorModeTouchTransformer(display2));
+ GetTouchTransform(display2,
+ FindTouchscreenById(display2.touch_device_id()),
+ fb_size));
return;
}
if (display_state == ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED) {
- gfx::Size fb_size =
- Shell::GetInstance()->display_configurator()->framebuffer_size();
// In extended but software mirroring mode, ther is only one X root window
// that associates with both displays.
if (GetDisplayManager()->software_mirroring_enabled()) {
device_manager->UpdateTouchInfoForDisplay(
display1_id,
display1.touch_device_id(),
- GetExtendedModeTouchTransformer(source_display, fb_size));
+ GetTouchTransform(source_display,
+ FindTouchscreenById(display1.touch_device_id()),
+ fb_size));
device_manager->UpdateTouchInfoForDisplay(
display2_id,
display2.touch_device_id(),
- GetExtendedModeTouchTransformer(source_display, fb_size));
+ GetTouchTransform(source_display,
+ FindTouchscreenById(display2.touch_device_id()),
+ fb_size));
} else {
// In actual extended mode, each display is associated with one root
// window.
device_manager->UpdateTouchInfoForDisplay(
display1_id,
display1.touch_device_id(),
- GetExtendedModeTouchTransformer(display1, fb_size));
+ GetTouchTransform(display1,
+ FindTouchscreenById(display1.touch_device_id()),
+ fb_size));
device_manager->UpdateTouchInfoForDisplay(
display2_id,
display2.touch_device_id(),
- GetExtendedModeTouchTransformer(display2, fb_size));
+ GetTouchTransform(display2,
+ FindTouchscreenById(display2.touch_device_id()),
+ fb_size));
}
return;
}
display_controller->GetRootWindowForDisplayId(single_display.id());
RootWindowController::ForWindow(root)->ash_host()->UpdateDisplayID(
single_display.id(), gfx::Display::kInvalidDisplayID);
- device_manager->UpdateTouchInfoForDisplay(single_display_id,
- single_display.touch_device_id(),
- gfx::Transform());
+ device_manager->UpdateTouchInfoForDisplay(
+ single_display_id,
+ single_display.touch_device_id(),
+ GetTouchTransform(single_display,
+ FindTouchscreenById(single_display.touch_device_id()),
+ fb_size));
}
void TouchTransformerController::OnDisplaysInitialized() {