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

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

Issue 1287103004: Sync ui/events to chromium @ https://codereview.chromium.org/1210203002 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: rebased Created 5 years, 4 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
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/event_converter_evdev_impl.h"
6
7 #include <errno.h>
8 #include <linux/input.h>
9
10 #include "base/trace_event/trace_event.h"
11 #include "ui/events/event.h"
12 #include "ui/events/event_utils.h"
13 #include "ui/events/keycodes/dom/keycode_converter.h"
14 #include "ui/events/ozone/evdev/device_event_dispatcher_evdev.h"
15 #include "ui/events/ozone/evdev/keyboard_util_evdev.h"
16
17 namespace ui {
18
19 namespace {
20
21 // Values for EV_KEY.
22 const int kKeyReleaseValue = 0;
23 const int kKeyRepeatValue = 2;
24
25 } // namespace
26
27 EventConverterEvdevImpl::EventConverterEvdevImpl(
28 int fd,
29 base::FilePath path,
30 int id,
31 InputDeviceType type,
32 const EventDeviceInfo& devinfo,
33 CursorDelegateEvdev* cursor,
34 DeviceEventDispatcherEvdev* dispatcher)
35 : EventConverterEvdev(fd,
36 path,
37 id,
38 type,
39 devinfo.name(),
40 devinfo.vendor_id(),
41 devinfo.product_id()),
42 has_keyboard_(devinfo.HasKeyboard()),
43 has_touchpad_(devinfo.HasTouchpad()),
44 has_caps_lock_led_(devinfo.HasLedEvent(LED_CAPSL)),
45 cursor_(cursor),
46 dispatcher_(dispatcher) {
47 }
48
49 EventConverterEvdevImpl::~EventConverterEvdevImpl() {
50 DCHECK(!enabled_);
51 close(fd_);
52 }
53
54 void EventConverterEvdevImpl::OnFileCanReadWithoutBlocking(int fd) {
55 TRACE_EVENT1("evdev", "EventConverterEvdevImpl::OnFileCanReadWithoutBlocking",
56 "fd", fd);
57
58 input_event inputs[4];
59 ssize_t read_size = read(fd, inputs, sizeof(inputs));
60 if (read_size < 0) {
61 if (errno == EINTR || errno == EAGAIN)
62 return;
63 if (errno != ENODEV)
64 PLOG(ERROR) << "error reading device " << path_.value();
65 Stop();
66 return;
67 }
68
69 if (!enabled_)
70 return;
71
72 DCHECK_EQ(read_size % sizeof(*inputs), 0u);
73 ProcessEvents(inputs, read_size / sizeof(*inputs));
74 }
75
76 bool EventConverterEvdevImpl::HasKeyboard() const {
77 return has_keyboard_;
78 }
79
80 bool EventConverterEvdevImpl::HasTouchpad() const {
81 return has_touchpad_;
82 }
83
84 bool EventConverterEvdevImpl::HasCapsLockLed() const {
85 return has_caps_lock_led_;
86 }
87
88 void EventConverterEvdevImpl::SetKeyFilter(bool enable_filter,
89 std::vector<DomCode> allowed_keys) {
90 if (!enable_filter) {
91 blocked_keys_.reset();
92 return;
93 }
94
95 blocked_keys_.set();
96 for (const DomCode& it : allowed_keys) {
97 int evdev_code =
98 NativeCodeToEvdevCode(KeycodeConverter::DomCodeToNativeKeycode(it));
99 blocked_keys_.reset(evdev_code);
100 }
101
102 // Release any pressed blocked keys.
103 base::TimeDelta timestamp = ui::EventTimeForNow();
104 for (int key = 0; key < KEY_CNT; ++key) {
105 if (blocked_keys_.test(key))
106 OnKeyChange(key, false /* down */, timestamp);
107 }
108 }
109
110 void EventConverterEvdevImpl::OnDisabled() {
111 ReleaseKeys();
112 ReleaseMouseButtons();
113 }
114
115 void EventConverterEvdevImpl::ProcessEvents(const input_event* inputs,
116 int count) {
117 for (int i = 0; i < count; ++i) {
118 const input_event& input = inputs[i];
119 switch (input.type) {
120 case EV_KEY:
121 ConvertKeyEvent(input);
122 break;
123 case EV_REL:
124 ConvertMouseMoveEvent(input);
125 break;
126 case EV_SYN:
127 if (input.code == SYN_DROPPED)
128 OnLostSync();
129 else if (input.code == SYN_REPORT)
130 FlushEvents(input);
131 break;
132 }
133 }
134 }
135
136 void EventConverterEvdevImpl::ConvertKeyEvent(const input_event& input) {
137 // Ignore repeat events.
138 if (input.value == kKeyRepeatValue)
139 return;
140
141 // Mouse processing.
142 if (input.code >= BTN_MOUSE && input.code < BTN_JOYSTICK) {
143 DispatchMouseButton(input);
144 return;
145 }
146
147 // Keyboard processing.
148 OnKeyChange(input.code, input.value != kKeyReleaseValue,
149 TimeDeltaFromInputEvent(input));
150 }
151
152 void EventConverterEvdevImpl::ConvertMouseMoveEvent(const input_event& input) {
153 if (!cursor_)
154 return;
155 switch (input.code) {
156 case REL_X:
157 x_offset_ = input.value;
158 break;
159 case REL_Y:
160 y_offset_ = input.value;
161 break;
162 }
163 }
164
165 void EventConverterEvdevImpl::OnKeyChange(unsigned int key,
166 bool down,
167 const base::TimeDelta& timestamp) {
168 if (key > KEY_MAX)
169 return;
170
171 if (down == key_state_.test(key))
172 return;
173
174 // Apply key filter (releases for previously pressed keys are excepted).
175 if (down && blocked_keys_.test(key))
176 return;
177
178 // State transition: !(down) -> (down)
179 key_state_.set(key, down);
180
181 dispatcher_->DispatchKeyEvent(KeyEventParams(input_device_.id, key, down,
182 false /* suppress_auto_repeat */,
183 timestamp));
184 }
185
186 void EventConverterEvdevImpl::ReleaseKeys() {
187 base::TimeDelta timestamp = ui::EventTimeForNow();
188 for (int key = 0; key < KEY_CNT; ++key)
189 OnKeyChange(key, false /* down */, timestamp);
190 }
191
192 void EventConverterEvdevImpl::ReleaseMouseButtons() {
193 base::TimeDelta timestamp = ui::EventTimeForNow();
194 for (int code = BTN_MOUSE; code < BTN_JOYSTICK; ++code)
195 OnButtonChange(code, false /* down */, timestamp);
196 }
197
198 void EventConverterEvdevImpl::OnLostSync() {
199 LOG(WARNING) << "kernel dropped input events";
200
201 // We may have missed key releases. Release everything.
202 // TODO(spang): Use EVIOCGKEY to avoid releasing keys that are still held.
203 ReleaseKeys();
204 ReleaseMouseButtons();
205 }
206
207 void EventConverterEvdevImpl::DispatchMouseButton(const input_event& input) {
208 if (!cursor_)
209 return;
210
211 OnButtonChange(input.code, input.value, TimeDeltaFromInputEvent(input));
212 }
213
214 void EventConverterEvdevImpl::OnButtonChange(int code,
215 bool down,
216 const base::TimeDelta& timestamp) {
217 if (code == BTN_SIDE)
218 code = BTN_BACK;
219 else if (code == BTN_EXTRA)
220 code = BTN_FORWARD;
221
222 int button_offset = code - BTN_MOUSE;
223 if (mouse_button_state_.test(button_offset) == down)
224 return;
225
226 mouse_button_state_.set(button_offset, down);
227
228 dispatcher_->DispatchMouseButtonEvent(MouseButtonEventParams(
229 input_device_.id, cursor_->GetLocation(), code, down,
230 /* allow_remap */ true, timestamp));
231 }
232
233 void EventConverterEvdevImpl::FlushEvents(const input_event& input) {
234 if (!cursor_ || (x_offset_ == 0 && y_offset_ == 0))
235 return;
236
237 cursor_->MoveCursor(gfx::Vector2dF(x_offset_, y_offset_));
238
239 dispatcher_->DispatchMouseMoveEvent(
240 MouseMoveEventParams(input_device_.id, cursor_->GetLocation(),
241 TimeDeltaFromInputEvent(input)));
242
243 x_offset_ = 0;
244 y_offset_ = 0;
245 }
246
247 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/ozone/evdev/event_converter_evdev_impl.h ('k') | ui/events/ozone/evdev/event_converter_evdev_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698