OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/events/ozone/evdev/key_event_converter_evdev.h" | 5 #include "ui/events/ozone/evdev/keyboard_evdev.h" |
6 | 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" | 7 #include "ui/events/event.h" |
12 #include "ui/events/keycodes/dom4/keycode_converter.h" | 8 #include "ui/events/keycodes/dom4/keycode_converter.h" |
13 #include "ui/events/keycodes/keyboard_codes.h" | |
14 #include "ui/events/ozone/evdev/event_modifiers_evdev.h" | 9 #include "ui/events/ozone/evdev/event_modifiers_evdev.h" |
15 | 10 |
16 namespace ui { | 11 namespace ui { |
17 | 12 |
18 namespace { | 13 namespace { |
19 | 14 |
20 const int kXkbKeycodeOffset = 8; | 15 const int kXkbKeycodeOffset = 8; |
21 | 16 |
22 ui::KeyboardCode KeyboardCodeFromButton(unsigned int code) { | 17 ui::KeyboardCode KeyboardCodeFromEvdevKey(unsigned int code) { |
23 static const ui::KeyboardCode kLinuxBaseKeyMap[] = { | 18 static const ui::KeyboardCode kLinuxBaseKeyMap[] = { |
24 ui::VKEY_UNKNOWN, // KEY_RESERVED | 19 ui::VKEY_UNKNOWN, // KEY_RESERVED |
25 ui::VKEY_ESCAPE, // KEY_ESC | 20 ui::VKEY_ESCAPE, // KEY_ESC |
26 ui::VKEY_1, // KEY_1 | 21 ui::VKEY_1, // KEY_1 |
27 ui::VKEY_2, // KEY_2 | 22 ui::VKEY_2, // KEY_2 |
28 ui::VKEY_3, // KEY_3 | 23 ui::VKEY_3, // KEY_3 |
29 ui::VKEY_4, // KEY_4 | 24 ui::VKEY_4, // KEY_4 |
30 ui::VKEY_5, // KEY_5 | 25 ui::VKEY_5, // KEY_5 |
31 ui::VKEY_6, // KEY_6 | 26 ui::VKEY_6, // KEY_6 |
32 ui::VKEY_7, // KEY_7 | 27 ui::VKEY_7, // KEY_7 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 ui::VKEY_APPS, // KEY_COMPOSE | 146 ui::VKEY_APPS, // KEY_COMPOSE |
152 }; | 147 }; |
153 | 148 |
154 if (code < arraysize(kLinuxBaseKeyMap)) | 149 if (code < arraysize(kLinuxBaseKeyMap)) |
155 return kLinuxBaseKeyMap[code]; | 150 return kLinuxBaseKeyMap[code]; |
156 | 151 |
157 LOG(ERROR) << "Unknown key code: " << code; | 152 LOG(ERROR) << "Unknown key code: " << code; |
158 return ui::VKEY_UNKNOWN; | 153 return ui::VKEY_UNKNOWN; |
159 } | 154 } |
160 | 155 |
161 int ModifierFromButton(unsigned int code) { | 156 int ModifierFromEvdevKey(unsigned int code) { |
162 switch (code) { | 157 switch (code) { |
163 case KEY_CAPSLOCK: | 158 case KEY_CAPSLOCK: |
164 return EVDEV_MODIFIER_CAPS_LOCK; | 159 return EVDEV_MODIFIER_CAPS_LOCK; |
165 case KEY_LEFTSHIFT: | 160 case KEY_LEFTSHIFT: |
166 case KEY_RIGHTSHIFT: | 161 case KEY_RIGHTSHIFT: |
167 return EVDEV_MODIFIER_SHIFT; | 162 return EVDEV_MODIFIER_SHIFT; |
168 case KEY_LEFTCTRL: | 163 case KEY_LEFTCTRL: |
169 case KEY_RIGHTCTRL: | 164 case KEY_RIGHTCTRL: |
170 return EVDEV_MODIFIER_CONTROL; | 165 return EVDEV_MODIFIER_CONTROL; |
171 case KEY_LEFTALT: | 166 case KEY_LEFTALT: |
172 case KEY_RIGHTALT: | 167 case KEY_RIGHTALT: |
173 return EVDEV_MODIFIER_ALT; | 168 return EVDEV_MODIFIER_ALT; |
174 case BTN_LEFT: | 169 case BTN_LEFT: |
175 return EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; | 170 return EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; |
176 case BTN_MIDDLE: | 171 case BTN_MIDDLE: |
177 return EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON; | 172 return EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON; |
178 case BTN_RIGHT: | 173 case BTN_RIGHT: |
179 return EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON; | 174 return EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON; |
180 case KEY_LEFTMETA: | 175 case KEY_LEFTMETA: |
181 case KEY_RIGHTMETA: | 176 case KEY_RIGHTMETA: |
182 return EVDEV_MODIFIER_COMMAND; | 177 return EVDEV_MODIFIER_COMMAND; |
183 default: | 178 default: |
184 return EVDEV_MODIFIER_NONE; | 179 return EVDEV_MODIFIER_NONE; |
185 } | 180 } |
186 } | 181 } |
187 | 182 |
188 bool IsLockButton(unsigned int code) { return code == KEY_CAPSLOCK; } | 183 bool IsModifierLockKeyFromEvdevKey(unsigned int code) { |
| 184 return code == KEY_CAPSLOCK; |
| 185 } |
189 | 186 |
190 } // namespace | 187 } // namespace |
191 | 188 |
192 KeyEventConverterEvdev::KeyEventConverterEvdev( | 189 KeyboardEvdev::KeyboardEvdev(EventModifiersEvdev* modifiers, |
193 int fd, | 190 const EventDispatchCallback& callback) |
194 base::FilePath path, | 191 : callback_(callback), modifiers_(modifiers) { |
195 int id, | |
196 EventModifiersEvdev* modifiers, | |
197 const EventDispatchCallback& callback) | |
198 : EventConverterEvdev(fd, path, id), | |
199 callback_(callback), | |
200 modifiers_(modifiers) { | |
201 // TODO(spang): Initialize modifiers using EVIOCGKEY. | |
202 } | 192 } |
203 | 193 |
204 KeyEventConverterEvdev::~KeyEventConverterEvdev() { | 194 KeyboardEvdev::~KeyboardEvdev() { |
205 Stop(); | |
206 close(fd_); | |
207 } | 195 } |
208 | 196 |
209 void KeyEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { | 197 void KeyboardEvdev::OnKeyChange(unsigned int key, bool down) { |
210 input_event inputs[4]; | 198 if (key > KEY_MAX) |
211 ssize_t read_size = read(fd, inputs, sizeof(inputs)); | |
212 if (read_size < 0) { | |
213 if (errno == EINTR || errno == EAGAIN) | |
214 return; | |
215 if (errno != ENODEV) | |
216 PLOG(ERROR) << "error reading device " << path_.value(); | |
217 Stop(); | |
218 return; | 199 return; |
| 200 |
| 201 if (down != key_state_.test(key)) { |
| 202 // State transition: !(down) -> (down) |
| 203 if (down) |
| 204 key_state_.set(key); |
| 205 else |
| 206 key_state_.reset(key); |
| 207 |
| 208 UpdateModifier(key, down); |
219 } | 209 } |
220 | 210 |
221 DCHECK_EQ(read_size % sizeof(*inputs), 0u); | 211 DispatchKey(key, down); |
222 ProcessEvents(inputs, read_size / sizeof(*inputs)); | |
223 } | 212 } |
224 | 213 |
225 void KeyEventConverterEvdev::ProcessEvents(const input_event* inputs, | 214 void KeyboardEvdev::UpdateModifier(unsigned int key, bool down) { |
226 int count) { | 215 int modifier = ModifierFromEvdevKey(key); |
227 for (int i = 0; i < count; ++i) { | 216 int locking = IsModifierLockKeyFromEvdevKey(key); |
228 const input_event& input = inputs[i]; | 217 |
229 if (input.type == EV_KEY) { | 218 if (modifier == EVDEV_MODIFIER_NONE) |
230 ConvertKeyEvent(input.code, input.value); | 219 return; |
231 } else if (input.type == EV_SYN) { | 220 |
232 // TODO(sadrul): Handle this case appropriately. | 221 if (locking) |
233 } | 222 modifiers_->UpdateModifierLock(modifier, down); |
234 } | 223 else |
| 224 modifiers_->UpdateModifier(modifier, down); |
235 } | 225 } |
236 | 226 |
237 void KeyEventConverterEvdev::ConvertKeyEvent(int key, int value) { | 227 void KeyboardEvdev::DispatchKey(unsigned int key, bool down) { |
238 int down = (value != 0); | 228 ui::KeyboardCode code = KeyboardCodeFromEvdevKey(key); |
239 int repeat = (value == 2); | |
240 int modifier = ModifierFromButton(key); | |
241 ui::KeyboardCode code = KeyboardCodeFromButton(key); | |
242 | |
243 if (!repeat && (modifier != EVDEV_MODIFIER_NONE)) { | |
244 if (IsLockButton(key)) { | |
245 // Locking modifier keys: CapsLock. | |
246 modifiers_->UpdateModifierLock(modifier, down); | |
247 } else { | |
248 // Regular modifier keys: Shift, Ctrl, Alt, etc. | |
249 modifiers_->UpdateModifier(modifier, down); | |
250 } | |
251 } | |
252 | |
253 int flags = modifiers_->GetModifierFlags(); | 229 int flags = modifiers_->GetModifierFlags(); |
254 | 230 |
255 KeyEvent key_event( | 231 KeyEvent key_event( |
256 down ? ET_KEY_PRESSED : ET_KEY_RELEASED, | 232 down ? ET_KEY_PRESSED : ET_KEY_RELEASED, |
257 code, | 233 code, |
258 KeycodeConverter::NativeKeycodeToCode(key + kXkbKeycodeOffset), | 234 KeycodeConverter::NativeKeycodeToCode(key + kXkbKeycodeOffset), |
259 flags); | 235 flags); |
260 callback_.Run(&key_event); | 236 callback_.Run(&key_event); |
261 } | 237 } |
262 | 238 |
263 } // namespace ui | 239 } // namespace ui |
OLD | NEW |