Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Unified Diff: ui/ozone/platform/dri/touch_converter.cc

Issue 611423002: [WIP][Ozone] Support external touchscreens (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ozone-touchscreen
Patch Set: . Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/ozone/platform/dri/touch_converter.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/ozone/platform/dri/touch_converter.cc
diff --git a/ui/ozone/platform/dri/touch_converter.cc b/ui/ozone/platform/dri/touch_converter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d5ec8f2aaa5d5884b7ed5132443dcd8f2f867930
--- /dev/null
+++ b/ui/ozone/platform/dri/touch_converter.cc
@@ -0,0 +1,150 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/dri/touch_converter.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "ui/display/types/display_snapshot.h"
+#include "ui/events/device_data_manager.h"
+#include "ui/events/event.h"
+#include "ui/events/event_switches.h"
+#include "ui/gfx/display.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/ozone/platform/dri/display_manager.h"
+#include "ui/ozone/platform/dri/dri_window.h"
+
+namespace ui {
+
+namespace {
+
+TouchscreenDevice FindTouchscreenDevice(int64_t id) {
+ const std::vector<TouchscreenDevice>& touchscreens =
+ DeviceDataManager::GetInstance()->touchscreen_devices();
+ for (size_t i = 0; i < touchscreens.size(); ++i)
+ if (touchscreens[i].id == id)
+ return touchscreens[i];
+
+ NOTREACHED();
+ return TouchscreenDevice(TouchscreenDevice::kInvalidId, gfx::Size(), false);
+}
+
+} // namespace
+
+TouchConverter::TouchConverter(DriWindow* window,
+ DisplayManager* display_manager)
+ : window_(window), display_manager_(display_manager) {
+ GetTouchCalibration();
+}
+
+TouchConverter::~TouchConverter() {
+}
+
+bool TouchConverter::CanHandleEvent(const TouchEvent& event) {
+ int64_t touch_display_id =
+ DeviceDataManager::GetInstance()->GetDisplayForTouchDevice(
+ event.source_device_id());
+
+ DisplaySnapshot* display = display_manager_->GetDisplay(touch_display_id);
+ // Suppress touch events that don't have a display associated with them.
+ if (!display || !display->current_mode())
+ return false;
+
+ // Touchscreens are associated with a specific display. Since windows can
+ // move between displays we want to make sure that the window is on the
+ // correct display.
+ gfx::Rect display_bounds(display->origin(), display->current_mode()->size());
+ return display_bounds == window_->GetBounds();
+}
+
+void TouchConverter::RewriteTouchEvent(TouchEvent* event) {
+ if (cached_touchscreen_id_ != event->source_device_id()) {
+ cached_touchscreen_id_ = event->source_device_id();
+ UpdateTransform();
+ }
+
+ gfx::Point3F location(event->location_f());
+ transform_.TransformPoint(&location);
+
+ event->set_location(location.AsPointF());
+ event->set_root_location(location.AsPointF());
+
+ event->set_radius_x(event->radius_x() * scale_factor_);
+ event->set_radius_y(event->radius_y() * scale_factor_);
+}
+
+void TouchConverter::UpdateTransform() {
+ if (cached_touchscreen_id_ == TouchscreenDevice::kInvalidId)
+ return;
+
+ TouchscreenDevice touchscreen =
+ FindTouchscreenDevice(cached_touchscreen_id_);
+ DisplaySnapshot* display = display_manager_->GetDisplay(
+ DeviceDataManager::GetInstance()->GetDisplayForTouchDevice(
+ cached_touchscreen_id_));
+
+ if (touchscreen.id == TouchscreenDevice::kInvalidId ||
+ !display || !display->native_mode())
+ return;
+
+ transform_.MakeIdentity();
+
+ gfx::SizeF current_size = window_->GetBounds().size();
+ gfx::SizeF native_size = display->native_mode()->size();
+ gfx::SizeF touch_area = touchscreen.size;
+
+ // For now only the internal display has bezel configuration support.
+ if (display->display_id() == gfx::Display::InternalDisplayId()) {
+ touch_area.Enlarge(
+ -touch_calibration_.bezel_left - touch_calibration_.bezel_right,
+ -touch_calibration_.bezel_top - touch_calibration_.bezel_bottom);
+
+ transform_.Translate(-touch_calibration_.bezel_left,
+ -touch_calibration_.bezel_top);
+ }
+
+ float scale_x = 1;
+ float scale_y = 1;
+ // Take care of panel fitting only if supported.
+ 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
+ transform_.Translate(
+ 0, (1 - current_ar / native_ar) * 0.5 * current_size.height());
+ scale_y = current_ar / native_ar;
+ } else if (native_ar > current_ar) { // Pillarboxing
+ transform_.Translate(
+ (1 - native_ar / current_ar) * 0.5 * current_size.width(), 0);
+ scale_x = native_ar / current_ar;
+ }
+ }
+
+ // Take care of scaling between touchscreen area and display resolution.
+ scale_x *= current_size.width() / touch_area.width();
+ scale_y *= current_size.height() / touch_area.height();
+ transform_.Scale(scale_x, scale_y);
+ scale_factor_ = std::sqrt(scale_x * scale_y);
+}
+
+void TouchConverter::GetTouchCalibration() {
+ std::vector<std::string> parts;
+ if (Tokenize(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kTouchCalibration),
+ ",",
+ &parts) >= 4) {
+ if (!base::StringToInt(parts[0], &touch_calibration_.bezel_left))
+ DLOG(ERROR) << "Incorrect left border calibration value passed.";
+ if (!base::StringToInt(parts[1], &touch_calibration_.bezel_right))
+ DLOG(ERROR) << "Incorrect right border calibration value passed.";
+ if (!base::StringToInt(parts[2], &touch_calibration_.bezel_top))
+ DLOG(ERROR) << "Incorrect top border calibration value passed.";
+ if (!base::StringToInt(parts[3], &touch_calibration_.bezel_bottom))
+ DLOG(ERROR) << "Incorrect bottom border calibration value passed.";
+ }
+}
+
+} // namespace ui
« no previous file with comments | « ui/ozone/platform/dri/touch_converter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698