| 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/key_event_converter_evdev.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <linux/input.h> | 8 #include <linux/input.h> |
| 9 | 9 |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "ui/events/event.h" | 11 #include "ui/events/event.h" |
| 12 #include "ui/events/keycodes/dom4/keycode_converter.h" | 12 #include "ui/events/keycodes/dom4/keycode_converter.h" |
| 13 #include "ui/events/keycodes/keyboard_codes.h" | 13 #include "ui/events/keycodes/keyboard_codes.h" |
| 14 #include "ui/events/ozone/evdev/event_modifiers_evdev.h" | 14 #include "ui/events/ozone/evdev/event_modifiers_evdev.h" |
| 15 | 15 |
| 16 namespace ui { | 16 namespace ui { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 const int kXkbKeycodeOffset = 8; | |
| 21 | |
| 22 ui::KeyboardCode KeyboardCodeFromButton(unsigned int code) { | |
| 23 static const ui::KeyboardCode kLinuxBaseKeyMap[] = { | |
| 24 ui::VKEY_UNKNOWN, // KEY_RESERVED | |
| 25 ui::VKEY_ESCAPE, // KEY_ESC | |
| 26 ui::VKEY_1, // KEY_1 | |
| 27 ui::VKEY_2, // KEY_2 | |
| 28 ui::VKEY_3, // KEY_3 | |
| 29 ui::VKEY_4, // KEY_4 | |
| 30 ui::VKEY_5, // KEY_5 | |
| 31 ui::VKEY_6, // KEY_6 | |
| 32 ui::VKEY_7, // KEY_7 | |
| 33 ui::VKEY_8, // KEY_8 | |
| 34 ui::VKEY_9, // KEY_9 | |
| 35 ui::VKEY_0, // KEY_0 | |
| 36 ui::VKEY_OEM_MINUS, // KEY_MINUS | |
| 37 ui::VKEY_OEM_PLUS, // KEY_EQUAL | |
| 38 ui::VKEY_BACK, // KEY_BACKSPACE | |
| 39 ui::VKEY_TAB, // KEY_TAB | |
| 40 ui::VKEY_Q, // KEY_Q | |
| 41 ui::VKEY_W, // KEY_W | |
| 42 ui::VKEY_E, // KEY_E | |
| 43 ui::VKEY_R, // KEY_R | |
| 44 ui::VKEY_T, // KEY_T | |
| 45 ui::VKEY_Y, // KEY_Y | |
| 46 ui::VKEY_U, // KEY_U | |
| 47 ui::VKEY_I, // KEY_I | |
| 48 ui::VKEY_O, // KEY_O | |
| 49 ui::VKEY_P, // KEY_P | |
| 50 ui::VKEY_OEM_4, // KEY_LEFTBRACE | |
| 51 ui::VKEY_OEM_6, // KEY_RIGHTBRACE | |
| 52 ui::VKEY_RETURN, // KEY_ENTER | |
| 53 ui::VKEY_CONTROL, // KEY_LEFTCTRL | |
| 54 ui::VKEY_A, // KEY_A | |
| 55 ui::VKEY_S, // KEY_S | |
| 56 ui::VKEY_D, // KEY_D | |
| 57 ui::VKEY_F, // KEY_F | |
| 58 ui::VKEY_G, // KEY_G | |
| 59 ui::VKEY_H, // KEY_H | |
| 60 ui::VKEY_J, // KEY_J | |
| 61 ui::VKEY_K, // KEY_K | |
| 62 ui::VKEY_L, // KEY_L | |
| 63 ui::VKEY_OEM_1, // KEY_SEMICOLON | |
| 64 ui::VKEY_OEM_7, // KEY_APOSTROPHE | |
| 65 ui::VKEY_OEM_3, // KEY_GRAVE | |
| 66 ui::VKEY_SHIFT, // KEY_LEFTSHIFT | |
| 67 ui::VKEY_OEM_5, // KEY_BACKSLASH | |
| 68 ui::VKEY_Z, // KEY_Z | |
| 69 ui::VKEY_X, // KEY_X | |
| 70 ui::VKEY_C, // KEY_C | |
| 71 ui::VKEY_V, // KEY_V | |
| 72 ui::VKEY_B, // KEY_B | |
| 73 ui::VKEY_N, // KEY_N | |
| 74 ui::VKEY_M, // KEY_M | |
| 75 ui::VKEY_OEM_COMMA, // KEY_COMMA | |
| 76 ui::VKEY_OEM_PERIOD, // KEY_DOT | |
| 77 ui::VKEY_OEM_2, // KEY_SLASH | |
| 78 ui::VKEY_SHIFT, // KEY_RIGHTSHIFT | |
| 79 ui::VKEY_MULTIPLY, // KEY_KPASTERISK | |
| 80 ui::VKEY_MENU, // KEY_LEFTALT | |
| 81 ui::VKEY_SPACE, // KEY_SPACE | |
| 82 ui::VKEY_CAPITAL, // KEY_CAPSLOCK | |
| 83 ui::VKEY_F1, // KEY_F1 | |
| 84 ui::VKEY_F2, // KEY_F2 | |
| 85 ui::VKEY_F3, // KEY_F3 | |
| 86 ui::VKEY_F4, // KEY_F4 | |
| 87 ui::VKEY_F5, // KEY_F5 | |
| 88 ui::VKEY_F6, // KEY_F6 | |
| 89 ui::VKEY_F7, // KEY_F7 | |
| 90 ui::VKEY_F8, // KEY_F8 | |
| 91 ui::VKEY_F9, // KEY_F9 | |
| 92 ui::VKEY_F10, // KEY_F10 | |
| 93 ui::VKEY_NUMLOCK, // KEY_NUMLOCK | |
| 94 ui::VKEY_SCROLL, // KEY_SCROLLLOCK | |
| 95 ui::VKEY_NUMPAD7, // KEY_KP7 | |
| 96 ui::VKEY_NUMPAD8, // KEY_KP8 | |
| 97 ui::VKEY_NUMPAD9, // KEY_KP9 | |
| 98 ui::VKEY_SUBTRACT, // KEY_KPMINUS | |
| 99 ui::VKEY_NUMPAD4, // KEY_KP4 | |
| 100 ui::VKEY_NUMPAD5, // KEY_KP5 | |
| 101 ui::VKEY_NUMPAD6, // KEY_KP6 | |
| 102 ui::VKEY_ADD, // KEY_KPPLUS | |
| 103 ui::VKEY_NUMPAD1, // KEY_KP1 | |
| 104 ui::VKEY_NUMPAD2, // KEY_KP2 | |
| 105 ui::VKEY_NUMPAD3, // KEY_KP3 | |
| 106 ui::VKEY_NUMPAD0, // KEY_KP0 | |
| 107 ui::VKEY_DECIMAL, // KEY_KPDOT | |
| 108 ui::VKEY_UNKNOWN, // (unassigned) | |
| 109 ui::VKEY_DBE_DBCSCHAR, // KEY_ZENKAKUHANKAKU | |
| 110 ui::VKEY_OEM_102, // KEY_102ND | |
| 111 ui::VKEY_F11, // KEY_F11 | |
| 112 ui::VKEY_F12, // KEY_F12 | |
| 113 ui::VKEY_UNKNOWN, // KEY_RO | |
| 114 ui::VKEY_UNKNOWN, // KEY_KATAKANA | |
| 115 ui::VKEY_UNKNOWN, // KEY_HIRAGANA | |
| 116 ui::VKEY_CONVERT, // KEY_HENKAN | |
| 117 ui::VKEY_UNKNOWN, // KEY_KATAKANAHIRAGANA | |
| 118 ui::VKEY_NONCONVERT, // KEY_MUHENKAN | |
| 119 ui::VKEY_UNKNOWN, // KEY_KPJPCOMMA | |
| 120 ui::VKEY_RETURN, // KEY_KPENTER | |
| 121 ui::VKEY_CONTROL, // KEY_RIGHTCTRL | |
| 122 ui::VKEY_DIVIDE, // KEY_KPSLASH | |
| 123 ui::VKEY_PRINT, // KEY_SYSRQ | |
| 124 ui::VKEY_MENU, // KEY_RIGHTALT | |
| 125 ui::VKEY_RETURN, // KEY_LINEFEED | |
| 126 ui::VKEY_HOME, // KEY_HOME | |
| 127 ui::VKEY_UP, // KEY_UP | |
| 128 ui::VKEY_PRIOR, // KEY_PAGEUP | |
| 129 ui::VKEY_LEFT, // KEY_LEFT | |
| 130 ui::VKEY_RIGHT, // KEY_RIGHT | |
| 131 ui::VKEY_END, // KEY_END | |
| 132 ui::VKEY_DOWN, // KEY_DOWN | |
| 133 ui::VKEY_NEXT, // KEY_PAGEDOWN | |
| 134 ui::VKEY_INSERT, // KEY_INSERT | |
| 135 ui::VKEY_DELETE, // KEY_DELETE | |
| 136 ui::VKEY_UNKNOWN, // KEY_MACRO | |
| 137 ui::VKEY_VOLUME_MUTE, // KEY_MUTE | |
| 138 ui::VKEY_VOLUME_DOWN, // KEY_VOLUMEDOWN | |
| 139 ui::VKEY_VOLUME_UP, // KEY_VOLUMEUP | |
| 140 ui::VKEY_POWER, // KEY_POWER | |
| 141 ui::VKEY_OEM_PLUS, // KEY_KPEQUAL | |
| 142 ui::VKEY_UNKNOWN, // KEY_KPPLUSMINUS | |
| 143 ui::VKEY_PAUSE, // KEY_PAUSE | |
| 144 ui::VKEY_MEDIA_LAUNCH_APP1, // KEY_SCALE | |
| 145 ui::VKEY_DECIMAL, // KEY_KPCOMMA | |
| 146 ui::VKEY_HANGUL, // KEY_HANGEUL | |
| 147 ui::VKEY_HANJA, // KEY_HANJA | |
| 148 ui::VKEY_UNKNOWN, // KEY_YEN | |
| 149 ui::VKEY_LWIN, // KEY_LEFTMETA | |
| 150 ui::VKEY_RWIN, // KEY_RIGHTMETA | |
| 151 ui::VKEY_APPS, // KEY_COMPOSE | |
| 152 }; | |
| 153 | |
| 154 if (code < arraysize(kLinuxBaseKeyMap)) | |
| 155 return kLinuxBaseKeyMap[code]; | |
| 156 | |
| 157 LOG(ERROR) << "Unknown key code: " << code; | |
| 158 return ui::VKEY_UNKNOWN; | |
| 159 } | |
| 160 | |
| 161 int ModifierFromButton(unsigned int code) { | |
| 162 switch (code) { | |
| 163 case KEY_CAPSLOCK: | |
| 164 return EVDEV_MODIFIER_CAPS_LOCK; | |
| 165 case KEY_LEFTSHIFT: | |
| 166 case KEY_RIGHTSHIFT: | |
| 167 return EVDEV_MODIFIER_SHIFT; | |
| 168 case KEY_LEFTCTRL: | |
| 169 case KEY_RIGHTCTRL: | |
| 170 return EVDEV_MODIFIER_CONTROL; | |
| 171 case KEY_LEFTALT: | |
| 172 case KEY_RIGHTALT: | |
| 173 return EVDEV_MODIFIER_ALT; | |
| 174 case BTN_LEFT: | |
| 175 return EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; | |
| 176 case BTN_MIDDLE: | |
| 177 return EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON; | |
| 178 case BTN_RIGHT: | |
| 179 return EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON; | |
| 180 case KEY_LEFTMETA: | |
| 181 case KEY_RIGHTMETA: | |
| 182 return EVDEV_MODIFIER_COMMAND; | |
| 183 default: | |
| 184 return EVDEV_MODIFIER_NONE; | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 bool IsLockButton(unsigned int code) { return code == KEY_CAPSLOCK; } | |
| 189 | |
| 190 } // namespace | 20 } // namespace |
| 191 | 21 |
| 192 KeyEventConverterEvdev::KeyEventConverterEvdev( | 22 KeyEventConverterEvdev::KeyEventConverterEvdev(int fd, |
| 193 int fd, | 23 base::FilePath path, |
| 194 base::FilePath path, | 24 int id, |
| 195 int id, | 25 KeyboardEvdev* keyboard) |
| 196 EventModifiersEvdev* modifiers, | 26 : EventConverterEvdev(fd, path, id), keyboard_(keyboard) { |
| 197 const EventDispatchCallback& callback) | |
| 198 : EventConverterEvdev(fd, path, id), | |
| 199 callback_(callback), | |
| 200 modifiers_(modifiers) { | |
| 201 // TODO(spang): Initialize modifiers using EVIOCGKEY. | |
| 202 } | 27 } |
| 203 | 28 |
| 204 KeyEventConverterEvdev::~KeyEventConverterEvdev() { | 29 KeyEventConverterEvdev::~KeyEventConverterEvdev() { |
| 205 Stop(); | 30 Stop(); |
| 206 close(fd_); | 31 close(fd_); |
| 207 } | 32 } |
| 208 | 33 |
| 209 void KeyEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { | 34 void KeyEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { |
| 210 input_event inputs[4]; | 35 input_event inputs[4]; |
| 211 ssize_t read_size = read(fd, inputs, sizeof(inputs)); | 36 ssize_t read_size = read(fd, inputs, sizeof(inputs)); |
| 212 if (read_size < 0) { | 37 if (read_size < 0) { |
| 213 if (errno == EINTR || errno == EAGAIN) | 38 if (errno == EINTR || errno == EAGAIN) |
| 214 return; | 39 return; |
| 215 if (errno != ENODEV) | 40 if (errno != ENODEV) |
| 216 PLOG(ERROR) << "error reading device " << path_.value(); | 41 PLOG(ERROR) << "error reading device " << path_.value(); |
| 217 Stop(); | 42 Stop(); |
| 218 return; | 43 return; |
| 219 } | 44 } |
| 220 | 45 |
| 221 DCHECK_EQ(read_size % sizeof(*inputs), 0u); | 46 DCHECK_EQ(read_size % sizeof(*inputs), 0u); |
| 222 ProcessEvents(inputs, read_size / sizeof(*inputs)); | 47 ProcessEvents(inputs, read_size / sizeof(*inputs)); |
| 223 } | 48 } |
| 224 | 49 |
| 225 void KeyEventConverterEvdev::ProcessEvents(const input_event* inputs, | 50 void KeyEventConverterEvdev::ProcessEvents(const input_event* inputs, |
| 226 int count) { | 51 int count) { |
| 227 for (int i = 0; i < count; ++i) { | 52 for (int i = 0; i < count; ++i) { |
| 228 const input_event& input = inputs[i]; | 53 const input_event& input = inputs[i]; |
| 229 if (input.type == EV_KEY) { | 54 if (input.type == EV_KEY) { |
| 230 ConvertKeyEvent(input.code, input.value); | 55 keyboard_->OnKeyChange(input.code, input.value != 0); |
| 231 } else if (input.type == EV_SYN) { | 56 } else if (input.type == EV_SYN) { |
| 232 // TODO(sadrul): Handle this case appropriately. | 57 // TODO(sadrul): Handle this case appropriately. |
| 233 } | 58 } |
| 234 } | 59 } |
| 235 } | 60 } |
| 236 | 61 |
| 237 void KeyEventConverterEvdev::ConvertKeyEvent(int key, int value) { | |
| 238 int down = (value != 0); | |
| 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(); | |
| 254 | |
| 255 KeyEvent key_event( | |
| 256 down ? ET_KEY_PRESSED : ET_KEY_RELEASED, | |
| 257 code, | |
| 258 KeycodeConverter::NativeKeycodeToCode(key + kXkbKeycodeOffset), | |
| 259 flags); | |
| 260 callback_.Run(&key_event); | |
| 261 } | |
| 262 | |
| 263 } // namespace ui | 62 } // namespace ui |
| OLD | NEW |