OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "ui/ozone/platform/dri/touch_converter.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/string_util.h" |
| 10 #include "ui/display/types/display_snapshot.h" |
| 11 #include "ui/events/device_data_manager.h" |
| 12 #include "ui/events/event.h" |
| 13 #include "ui/events/event_switches.h" |
| 14 #include "ui/gfx/display.h" |
| 15 #include "ui/gfx/geometry/point3_f.h" |
| 16 #include "ui/ozone/platform/dri/display_manager.h" |
| 17 #include "ui/ozone/platform/dri/dri_window.h" |
| 18 |
| 19 namespace ui { |
| 20 |
| 21 namespace { |
| 22 |
| 23 TouchscreenDevice FindTouchscreenDevice(int64_t id) { |
| 24 const std::vector<TouchscreenDevice>& touchscreens = |
| 25 DeviceDataManager::GetInstance()->touchscreen_devices(); |
| 26 for (size_t i = 0; i < touchscreens.size(); ++i) |
| 27 if (touchscreens[i].id == id) |
| 28 return touchscreens[i]; |
| 29 |
| 30 NOTREACHED(); |
| 31 return TouchscreenDevice(TouchscreenDevice::kInvalidId, gfx::Size(), false); |
| 32 } |
| 33 |
| 34 } // namespace |
| 35 |
| 36 TouchConverter::TouchConverter(DriWindow* window, |
| 37 DisplayManager* display_manager) |
| 38 : window_(window), display_manager_(display_manager) { |
| 39 GetTouchCalibration(); |
| 40 } |
| 41 |
| 42 TouchConverter::~TouchConverter() { |
| 43 } |
| 44 |
| 45 bool TouchConverter::CanHandleEvent(const TouchEvent& event) { |
| 46 int64_t touch_display_id = |
| 47 DeviceDataManager::GetInstance()->GetDisplayForTouchDevice( |
| 48 event.source_device_id()); |
| 49 |
| 50 DisplaySnapshot* display = display_manager_->GetDisplay(touch_display_id); |
| 51 // Suppress touch events that don't have a display associated with them. |
| 52 if (!display || !display->current_mode()) |
| 53 return false; |
| 54 |
| 55 // Touchscreens are associated with a specific display. Since windows can |
| 56 // move between displays we want to make sure that the window is on the |
| 57 // correct display. |
| 58 gfx::Rect display_bounds(display->origin(), display->current_mode()->size()); |
| 59 return display_bounds == window_->GetBounds(); |
| 60 } |
| 61 |
| 62 void TouchConverter::RewriteTouchEvent(TouchEvent* event) { |
| 63 if (cached_touchscreen_id_ != event->source_device_id()) { |
| 64 cached_touchscreen_id_ = event->source_device_id(); |
| 65 UpdateTransform(); |
| 66 } |
| 67 |
| 68 gfx::Point3F location(event->location_f()); |
| 69 transform_.TransformPoint(&location); |
| 70 |
| 71 event->set_location(location.AsPointF()); |
| 72 event->set_root_location(location.AsPointF()); |
| 73 |
| 74 event->set_radius_x(event->radius_x() * scale_factor_); |
| 75 event->set_radius_y(event->radius_y() * scale_factor_); |
| 76 } |
| 77 |
| 78 void TouchConverter::UpdateTransform() { |
| 79 if (cached_touchscreen_id_ == TouchscreenDevice::kInvalidId) |
| 80 return; |
| 81 |
| 82 TouchscreenDevice touchscreen = |
| 83 FindTouchscreenDevice(cached_touchscreen_id_); |
| 84 DisplaySnapshot* display = display_manager_->GetDisplay( |
| 85 DeviceDataManager::GetInstance()->GetDisplayForTouchDevice( |
| 86 cached_touchscreen_id_)); |
| 87 |
| 88 if (touchscreen.id == TouchscreenDevice::kInvalidId || |
| 89 !display || !display->native_mode()) |
| 90 return; |
| 91 |
| 92 transform_.MakeIdentity(); |
| 93 |
| 94 gfx::SizeF current_size = window_->GetBounds().size(); |
| 95 gfx::SizeF native_size = display->native_mode()->size(); |
| 96 gfx::SizeF touch_area = touchscreen.size; |
| 97 |
| 98 // For now only the internal display has bezel configuration support. |
| 99 if (display->display_id() == gfx::Display::InternalDisplayId()) { |
| 100 touch_area.Enlarge( |
| 101 -touch_calibration_.bezel_left - touch_calibration_.bezel_right, |
| 102 -touch_calibration_.bezel_top - touch_calibration_.bezel_bottom); |
| 103 |
| 104 transform_.Translate(-touch_calibration_.bezel_left, |
| 105 -touch_calibration_.bezel_top); |
| 106 } |
| 107 |
| 108 float scale_x = 1; |
| 109 float scale_y = 1; |
| 110 // Take care of panel fitting only if supported. |
| 111 if (display->is_aspect_preserving_scaling()) { |
| 112 float native_ar = native_size.width() / native_size.height(); |
| 113 float current_ar = current_size.width() / current_size.height(); |
| 114 |
| 115 if (current_ar > native_ar) { // Letterboxing |
| 116 transform_.Translate( |
| 117 0, (1 - current_ar / native_ar) * 0.5 * current_size.height()); |
| 118 scale_y = current_ar / native_ar; |
| 119 } else if (native_ar > current_ar) { // Pillarboxing |
| 120 transform_.Translate( |
| 121 (1 - native_ar / current_ar) * 0.5 * current_size.width(), 0); |
| 122 scale_x = native_ar / current_ar; |
| 123 } |
| 124 } |
| 125 |
| 126 // Take care of scaling between touchscreen area and display resolution. |
| 127 scale_x *= current_size.width() / touch_area.width(); |
| 128 scale_y *= current_size.height() / touch_area.height(); |
| 129 transform_.Scale(scale_x, scale_y); |
| 130 scale_factor_ = std::sqrt(scale_x * scale_y); |
| 131 } |
| 132 |
| 133 void TouchConverter::GetTouchCalibration() { |
| 134 std::vector<std::string> parts; |
| 135 if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 136 switches::kTouchCalibration), |
| 137 ",", |
| 138 &parts) >= 4) { |
| 139 if (!base::StringToInt(parts[0], &touch_calibration_.bezel_left)) |
| 140 DLOG(ERROR) << "Incorrect left border calibration value passed."; |
| 141 if (!base::StringToInt(parts[1], &touch_calibration_.bezel_right)) |
| 142 DLOG(ERROR) << "Incorrect right border calibration value passed."; |
| 143 if (!base::StringToInt(parts[2], &touch_calibration_.bezel_top)) |
| 144 DLOG(ERROR) << "Incorrect top border calibration value passed."; |
| 145 if (!base::StringToInt(parts[3], &touch_calibration_.bezel_bottom)) |
| 146 DLOG(ERROR) << "Incorrect bottom border calibration value passed."; |
| 147 } |
| 148 } |
| 149 |
| 150 } // namespace ui |
OLD | NEW |