| 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
|
|
|