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

Unified Diff: ui/base/linux/touch_event_from_evdev_converter.cc

Issue 13886018: Add a factory and defines for native Linux surfaces. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Get {base,ui,aura}_unittests working with native linux surface Created 7 years, 8 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
Index: ui/base/linux/touch_event_from_evdev_converter.cc
diff --git a/ui/base/linux/touch_event_from_evdev_converter.cc b/ui/base/linux/touch_event_from_evdev_converter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9f147fec7dc7ff1a8ecec12fb50d628c28a995d3
--- /dev/null
+++ b/ui/base/linux/touch_event_from_evdev_converter.cc
@@ -0,0 +1,189 @@
+// Copyright (c) 2013 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/base/linux/touch_event_from_evdev_converter.h"
+
+#include <cmath>
+
+#include <fcntl.h>
+#include <linux/input.h>
+#include <poll.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/message_pump_linux.h"
+#include "ui/base/events/event_constants.h"
+#include "ui/base/events/event.h"
+
+
+namespace {
+
+// Number is determined empirically.
+// TODO(rjkroege): Configure this per device.
+const float kFingerWidth = 25.f;
+
+void DispatchEventHelper(ui::TouchEvent* tev) {
+ base::MessagePumpLinux::Current()->Dispatch(tev);
+}
+
+} // namespace
+
+namespace ui {
+
+TouchEventFromEvdevConverter::TouchEventFromEvdevConverter(int fd, int id)
+ : pressure_min_(0),
+ pressure_max_(0),
+ x_scale_(1.),
+ y_scale_(1.),
+ current_slot_(0),
+ fd_(fd),
+ id_(id) {
+ Init();
+}
+
+TouchEventFromEvdevConverter::~TouchEventFromEvdevConverter() {
+ if (close(fd_) < 0)
+ DLOG(WARNING) << "failed close on /dev/input/event" << id_;
+}
+
+void TouchEventFromEvdevConverter::Init() {
+ input_absinfo abs = {};
+ if (ioctl(fd_, EVIOCGABS(ABS_MT_SLOT), &abs) != -1) {
+ CHECK_GE(abs.maximum, abs.minimum);
+ CHECK_GE(abs.minimum, 0);
+ } else {
+ DLOG(WARNING) << "failed ioctl EVIOCGABS ABS_MT_SLOT event" << id_;
+ }
+ if (ioctl(fd_, EVIOCGABS(ABS_MT_PRESSURE), &abs) != -1) {
+ pressure_min_ = abs.minimum;
+ pressure_max_ = abs.maximum;
+ } else {
+ DLOG(WARNING) << "failed ioctl EVIOCGABS ABS_MT_PRESSURE event" << id_;
+ }
+ int x_min = 0, x_max = 0;
+ if (ioctl(fd_, EVIOCGABS(ABS_MT_POSITION_X), &abs) != -1) {
+ x_min = abs.minimum;
+ x_max = abs.maximum;
+ } else {
+ LOG(WARNING) << "failed ioctl EVIOCGABS ABS_X event" << id_;
+ }
+ int y_min = 0, y_max = 0;
+ if (ioctl(fd_, EVIOCGABS(ABS_MT_POSITION_Y), &abs) != -1) {
+ y_min = abs.minimum;
+ y_max = abs.maximum;
+ } else {
+ LOG(WARNING) << "failed ioctl EVIOCGABS ABS_Y event" << id_;
+ }
+ const char *display = getenv("ASH_DISPLAY_SPEC");
+ if (x_max && y_max && display) {
+ int screen_width, screen_height;
+ sscanf(display, "%dx%d", &screen_width, &screen_height);
+ x_scale_ = (double)screen_width / (x_max - x_min);
+ y_scale_ = (double)screen_height / (y_max - y_min);
+ LOG(INFO) << "touch input x_scale=" << x_scale_ << " y_scale=" << y_scale_;
+ }
+}
+
+void TouchEventFromEvdevConverter::OnFileCanWriteWithoutBlocking(int /* fd */) {
+ // Read-only file-descriptors.
+ NOTREACHED();
+}
+
+void TouchEventFromEvdevConverter::OnFileCanReadWithoutBlocking(int fd) {
+ input_event inputs[MAX_FINGERS * 6 + 1];
+ ssize_t read_size = read(fd, inputs, sizeof(inputs));
+ if (read_size <= 0)
+ return;
+
+ for (unsigned i = 0; i < read_size / sizeof(*inputs); i++) {
+ const input_event& input = inputs[i];
+ if (input.type == EV_ABS) {
+ switch (input.code) {
+ case ABS_MT_TOUCH_MAJOR:
+ altered_slots_.set(current_slot_);
+ events_[current_slot_].major_ = input.value;
+ break;
+ case ABS_X:
+ case ABS_MT_POSITION_X:
+ altered_slots_.set(current_slot_);
+ events_[current_slot_].x_ = roundf(input.value * x_scale_);
+ break;
+ case ABS_Y:
+ case ABS_MT_POSITION_Y:
+ altered_slots_.set(current_slot_);
+ events_[current_slot_].y_ = roundf(input.value * y_scale_);
+ break;
+ case ABS_MT_TRACKING_ID:
+ altered_slots_.set(current_slot_);
+ if (input.value < 0) {
+ events_[current_slot_].type_ = ET_TOUCH_RELEASED;
+ } else {
+ events_[current_slot_].finger_ = input.value;
+ events_[current_slot_].type_ = ET_TOUCH_PRESSED;
+ }
+ break;
+ case ABS_MT_PRESSURE:
+ case ABS_PRESSURE:
+ altered_slots_.set(current_slot_);
+ events_[current_slot_].pressure_ = input.value - pressure_min_;
+ events_[current_slot_].pressure_ /= pressure_max_ -
+ pressure_min_;
+ break;
+ case ABS_MT_SLOT:
+ current_slot_ = input.value;
+ altered_slots_.set(current_slot_);
+ break;
+ default:
+ NOTREACHED();
+ }
+ } else if (input.type == EV_SYN) {
+ switch (input.code) {
+ case SYN_REPORT:
+ for (int j = 0; j < MAX_FINGERS; j++) {
+ if (altered_slots_[j]) {
+ // TODO(rjkroege): Support elliptical finger regions.
+ TouchEvent* tev = new TouchEvent(events_[j].type_,
+ gfx::Point(events_[j].x_,
+ events_[j].y_),
+ /* flags */ 0,
+ /* touch_id */ j,
+ base::TimeDelta::FromMicroseconds(
+ input.time.tv_sec * 1000000 +
+ input.time.tv_usec),
+ events_[j].pressure_ *
+ kFingerWidth,
+ events_[j].pressure_ *
+ kFingerWidth,
+ /* angle */ 0.,
+ events_[j].pressure_);
+ events_[j].type_ = ET_TOUCH_MOVED;
+ DispatchEvent(tev);
+ }
+ }
+ altered_slots_.reset();
+ break;
+ case SYN_MT_REPORT:
+ case SYN_CONFIG:
+ case SYN_DROPPED:
+ NOTREACHED() << "Nexus Galaxy doesn't generate SYN_MT events.";
+ break;
+ }
+ } else {
+ NOTREACHED();
+ }
+ }
+}
+
+
+void TouchEventFromEvdevConverter::DispatchEvent(TouchEvent* tev) {
+ base::Callback<void()> event_cb = base::Bind(&DispatchEventHelper,
+ base::Owned(tev));
+ MessageLoop::current()->PostTask(FROM_HERE, event_cb);
+}
+
+} // namespace ui

Powered by Google App Engine
This is Rietveld 408576698