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

Side by Side 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, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/base/linux/touch_event_from_evdev_converter.h"
6
7 #include <cmath>
8
9 #include <fcntl.h>
10 #include <linux/input.h>
11 #include <poll.h>
12 #include <stdio.h>
13 #include <unistd.h>
14
15 #include "base/bind.h"
16 #include "base/callback.h"
17 #include "base/logging.h"
18 #include "base/message_loop.h"
19 #include "base/message_pump_linux.h"
20 #include "ui/base/events/event_constants.h"
21 #include "ui/base/events/event.h"
22
23
24 namespace {
25
26 // Number is determined empirically.
27 // TODO(rjkroege): Configure this per device.
28 const float kFingerWidth = 25.f;
29
30 void DispatchEventHelper(ui::TouchEvent* tev) {
31 base::MessagePumpLinux::Current()->Dispatch(tev);
32 }
33
34 } // namespace
35
36 namespace ui {
37
38 TouchEventFromEvdevConverter::TouchEventFromEvdevConverter(int fd, int id)
39 : pressure_min_(0),
40 pressure_max_(0),
41 x_scale_(1.),
42 y_scale_(1.),
43 current_slot_(0),
44 fd_(fd),
45 id_(id) {
46 Init();
47 }
48
49 TouchEventFromEvdevConverter::~TouchEventFromEvdevConverter() {
50 if (close(fd_) < 0)
51 DLOG(WARNING) << "failed close on /dev/input/event" << id_;
52 }
53
54 void TouchEventFromEvdevConverter::Init() {
55 input_absinfo abs = {};
56 if (ioctl(fd_, EVIOCGABS(ABS_MT_SLOT), &abs) != -1) {
57 CHECK_GE(abs.maximum, abs.minimum);
58 CHECK_GE(abs.minimum, 0);
59 } else {
60 DLOG(WARNING) << "failed ioctl EVIOCGABS ABS_MT_SLOT event" << id_;
61 }
62 if (ioctl(fd_, EVIOCGABS(ABS_MT_PRESSURE), &abs) != -1) {
63 pressure_min_ = abs.minimum;
64 pressure_max_ = abs.maximum;
65 } else {
66 DLOG(WARNING) << "failed ioctl EVIOCGABS ABS_MT_PRESSURE event" << id_;
67 }
68 int x_min = 0, x_max = 0;
69 if (ioctl(fd_, EVIOCGABS(ABS_MT_POSITION_X), &abs) != -1) {
70 x_min = abs.minimum;
71 x_max = abs.maximum;
72 } else {
73 LOG(WARNING) << "failed ioctl EVIOCGABS ABS_X event" << id_;
74 }
75 int y_min = 0, y_max = 0;
76 if (ioctl(fd_, EVIOCGABS(ABS_MT_POSITION_Y), &abs) != -1) {
77 y_min = abs.minimum;
78 y_max = abs.maximum;
79 } else {
80 LOG(WARNING) << "failed ioctl EVIOCGABS ABS_Y event" << id_;
81 }
82 const char *display = getenv("ASH_DISPLAY_SPEC");
83 if (x_max && y_max && display) {
84 int screen_width, screen_height;
85 sscanf(display, "%dx%d", &screen_width, &screen_height);
86 x_scale_ = (double)screen_width / (x_max - x_min);
87 y_scale_ = (double)screen_height / (y_max - y_min);
88 LOG(INFO) << "touch input x_scale=" << x_scale_ << " y_scale=" << y_scale_;
89 }
90 }
91
92 void TouchEventFromEvdevConverter::OnFileCanWriteWithoutBlocking(int /* fd */) {
93 // Read-only file-descriptors.
94 NOTREACHED();
95 }
96
97 void TouchEventFromEvdevConverter::OnFileCanReadWithoutBlocking(int fd) {
98 input_event inputs[MAX_FINGERS * 6 + 1];
99 ssize_t read_size = read(fd, inputs, sizeof(inputs));
100 if (read_size <= 0)
101 return;
102
103 for (unsigned i = 0; i < read_size / sizeof(*inputs); i++) {
104 const input_event& input = inputs[i];
105 if (input.type == EV_ABS) {
106 switch (input.code) {
107 case ABS_MT_TOUCH_MAJOR:
108 altered_slots_.set(current_slot_);
109 events_[current_slot_].major_ = input.value;
110 break;
111 case ABS_X:
112 case ABS_MT_POSITION_X:
113 altered_slots_.set(current_slot_);
114 events_[current_slot_].x_ = roundf(input.value * x_scale_);
115 break;
116 case ABS_Y:
117 case ABS_MT_POSITION_Y:
118 altered_slots_.set(current_slot_);
119 events_[current_slot_].y_ = roundf(input.value * y_scale_);
120 break;
121 case ABS_MT_TRACKING_ID:
122 altered_slots_.set(current_slot_);
123 if (input.value < 0) {
124 events_[current_slot_].type_ = ET_TOUCH_RELEASED;
125 } else {
126 events_[current_slot_].finger_ = input.value;
127 events_[current_slot_].type_ = ET_TOUCH_PRESSED;
128 }
129 break;
130 case ABS_MT_PRESSURE:
131 case ABS_PRESSURE:
132 altered_slots_.set(current_slot_);
133 events_[current_slot_].pressure_ = input.value - pressure_min_;
134 events_[current_slot_].pressure_ /= pressure_max_ -
135 pressure_min_;
136 break;
137 case ABS_MT_SLOT:
138 current_slot_ = input.value;
139 altered_slots_.set(current_slot_);
140 break;
141 default:
142 NOTREACHED();
143 }
144 } else if (input.type == EV_SYN) {
145 switch (input.code) {
146 case SYN_REPORT:
147 for (int j = 0; j < MAX_FINGERS; j++) {
148 if (altered_slots_[j]) {
149 // TODO(rjkroege): Support elliptical finger regions.
150 TouchEvent* tev = new TouchEvent(events_[j].type_,
151 gfx::Point(events_[j].x_,
152 events_[j].y_),
153 /* flags */ 0,
154 /* touch_id */ j,
155 base::TimeDelta::FromMicroseconds(
156 input.time.tv_sec * 1000000 +
157 input.time.tv_usec),
158 events_[j].pressure_ *
159 kFingerWidth,
160 events_[j].pressure_ *
161 kFingerWidth,
162 /* angle */ 0.,
163 events_[j].pressure_);
164 events_[j].type_ = ET_TOUCH_MOVED;
165 DispatchEvent(tev);
166 }
167 }
168 altered_slots_.reset();
169 break;
170 case SYN_MT_REPORT:
171 case SYN_CONFIG:
172 case SYN_DROPPED:
173 NOTREACHED() << "Nexus Galaxy doesn't generate SYN_MT events.";
174 break;
175 }
176 } else {
177 NOTREACHED();
178 }
179 }
180 }
181
182
183 void TouchEventFromEvdevConverter::DispatchEvent(TouchEvent* tev) {
184 base::Callback<void()> event_cb = base::Bind(&DispatchEventHelper,
185 base::Owned(tev));
186 MessageLoop::current()->PostTask(FROM_HERE, event_cb);
187 }
188
189 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698