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

Side by Side Diff: ui/events/ozone/evdev/tablet_event_converter_evdev.cc

Issue 721823002: ozone: Interpret absolute events for graphics tablets (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@o
Patch Set: Add missing initialisers for class members on TabletEventConverterEvdev Created 6 years, 1 month 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
OLDNEW
(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/events/ozone/evdev/tablet_event_converter_evdev.h"
6
7 #include <errno.h>
8 #include <linux/input.h>
9
10 #include "base/message_loop/message_loop.h"
11 #include "ui/events/event.h"
12
13 namespace ui {
14
15 TabletEventConverterEvdev::TabletEventConverterEvdev(
16 int fd,
17 base::FilePath path,
18 int id,
19 EventModifiersEvdev* modifiers,
20 CursorDelegateEvdev* cursor,
21 const EventDeviceInfo& info,
22 const EventDispatchCallback& callback)
23 : EventConverterEvdev(fd, path, id),
24 cursor_(cursor),
25 modifiers_(modifiers),
26 callback_(callback),
27 stylus_(0),
28 abs_value_dirty_(false) {
29 x_abs_min_ = info.GetAbsMinimum(ABS_X);
30 x_abs_range_ = info.GetAbsMaximum(ABS_X) - x_abs_min_ + 1;
31 y_abs_min_ = info.GetAbsMinimum(ABS_Y);
32 y_abs_range_ = info.GetAbsMaximum(ABS_Y) - y_abs_min_ + 1;
33 }
34
35 TabletEventConverterEvdev::~TabletEventConverterEvdev() {
36 Stop();
37 close(fd_);
38 }
39
40 void TabletEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
41 input_event inputs[4];
42 ssize_t read_size = read(fd, inputs, sizeof(inputs));
43 if (read_size < 0) {
44 if (errno == EINTR || errno == EAGAIN)
45 return;
46 if (errno != ENODEV)
47 PLOG(ERROR) << "error reading device " << path_.value();
48 Stop();
49 return;
50 }
51
52 DCHECK_EQ(read_size % sizeof(*inputs), 0u);
53 ProcessEvents(inputs, read_size / sizeof(*inputs));
54 }
55
56 void TabletEventConverterEvdev::ProcessEvents(const input_event* inputs,
57 int count) {
58 for (int i = 0; i < count; ++i) {
59 const input_event& input = inputs[i];
60 switch (input.type) {
61 case EV_KEY:
62 ConvertKeyEvent(input);
63 break;
64 case EV_ABS:
65 ConvertAbsEvent(input);
66 break;
67 case EV_SYN:
68 FlushEvents();
69 break;
70 }
71 }
72 }
73
74 void TabletEventConverterEvdev::ConvertKeyEvent(const input_event& input) {
75 // Only handle other events if we have a stylus in proximity
76 if (input.code >= BTN_TOOL_PEN && input.code <= BTN_TOOL_LENS) {
77 if (input.value == 1)
78 stylus_ = input.code;
79 else if (input.value == 0)
80 stylus_ = 0;
81 else
82 LOG(WARNING) << "Unexpected value: " << input.value
83 << " for code: " << input.code;
84 }
85
86 if (input.code >= BTN_TOUCH && input.code <= BTN_STYLUS2) {
87 DispatchMouseButton(input);
88 return;
89 }
90 }
91
92 void TabletEventConverterEvdev::ConvertAbsEvent(const input_event& input) {
93 if (!cursor_)
94 return;
95
96 switch (input.code) {
97 case ABS_X:
98 x_abs_location_ = input.value;
99 abs_value_dirty_ = true;
100 break;
101 case ABS_Y:
102 y_abs_location_ = input.value;
103 abs_value_dirty_ = true;
104 break;
105 }
106 }
107
108 void TabletEventConverterEvdev::UpdateCursor() {
109 int width = cursor_->GetCursorDisplayBounds().width();
110 int height = cursor_->GetCursorDisplayBounds().height();
111 int x = ((x_abs_location_ - x_abs_min_) * width) / x_abs_range_;
112 int y = ((y_abs_location_ - y_abs_min_) * height) / y_abs_range_;
113
114 cursor_->MoveCursorTo(gfx::PointF(x, y));
115 }
116
117 void TabletEventConverterEvdev::DispatchMouseButton(const input_event& input) {
118 if (!cursor_)
119 return;
120
121 unsigned int modifier;
122 // These are the same as X11 behaviour
123 if (input.code == BTN_TOUCH)
124 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON;
125 else if (input.code == BTN_STYLUS2)
126 modifier = EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON;
127 else if (input.code == BTN_STYLUS)
128 modifier = EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON;
129 else
130 return;
131
132 if (abs_value_dirty_) {
133 UpdateCursor();
134 abs_value_dirty_ = false;
135 }
136
137 int flag = modifiers_->GetEventFlagFromModifier(modifier);
138 modifiers_->UpdateModifier(modifier, input.value);
139 callback_.Run(make_scoped_ptr(new MouseEvent(
140 input.value ? ET_MOUSE_PRESSED : ET_MOUSE_RELEASED, cursor_->location(),
141 cursor_->location(), modifiers_->GetModifierFlags() | flag, flag)));
142 }
143
144 void TabletEventConverterEvdev::FlushEvents() {
145 if (!cursor_)
146 return;
147
148 // Prevent propagation of invalid data on stylus lift off
149 if (stylus_ == 0) {
150 abs_value_dirty_ = false;
151 return;
152 }
153
154 if (!abs_value_dirty_)
155 return;
156
157 UpdateCursor();
158
159 callback_.Run(make_scoped_ptr(
160 new MouseEvent(ui::ET_MOUSE_MOVED, cursor_->location(),
161 cursor_->location(), modifiers_->GetModifierFlags(),
162 /* changed_button_flags */ 0)));
163
164 abs_value_dirty_ = false;
165 }
166
167 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/tablet_event_converter_evdev.h ('k') | ui/events/ozone/evdev/tablet_event_converter_evdev_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698