| 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, | 192 memset(&key_state_, 0, sizeof(key_state_)); |
| 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 } | 193 } |
| 203 | 194 |
| 204 KeyEventConverterEvdev::~KeyEventConverterEvdev() { | 195 KeyboardEvdev::~KeyboardEvdev() { |
| 205 Stop(); | |
| 206 close(fd_); | |
| 207 } | 196 } |
| 208 | 197 |
| 209 void KeyEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) { | 198 void KeyboardEvdev::OnKeyChange(unsigned int key, bool down) { |
| 210 input_event inputs[4]; | 199 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; | 200 return; |
| 201 |
| 202 if (down != EvdevBitIsSet(key_state_, key)) { |
| 203 // State transition: !(down) -> (down) |
| 204 if (down) |
| 205 EvdevSetBit(key_state_, key); |
| 206 else |
| 207 EvdevClearBit(key_state_, key); |
| 208 |
| 209 UpdateModifier(key, down); |
| 219 } | 210 } |
| 220 | 211 |
| 221 DCHECK_EQ(read_size % sizeof(*inputs), 0u); | 212 DispatchKey(key, down); |
| 222 ProcessEvents(inputs, read_size / sizeof(*inputs)); | |
| 223 } | 213 } |
| 224 | 214 |
| 225 void KeyEventConverterEvdev::ProcessEvents(const input_event* inputs, | 215 void KeyboardEvdev::UpdateModifier(unsigned int key, bool down) { |
| 226 int count) { | 216 int modifier = ModifierFromEvdevKey(key); |
| 227 for (int i = 0; i < count; ++i) { | 217 int locking = IsModifierLockKeyFromEvdevKey(key); |
| 228 const input_event& input = inputs[i]; | 218 |
| 229 if (input.type == EV_KEY) { | 219 if (modifier == EVDEV_MODIFIER_NONE) |
| 230 ConvertKeyEvent(input.code, input.value); | 220 return; |
| 231 } else if (input.type == EV_SYN) { | 221 |
| 232 // TODO(sadrul): Handle this case appropriately. | 222 if (locking) |
| 233 } | 223 modifiers_->UpdateModifierLock(modifier, down); |
| 234 } | 224 else |
| 225 modifiers_->UpdateModifier(modifier, down); |
| 235 } | 226 } |
| 236 | 227 |
| 237 void KeyEventConverterEvdev::ConvertKeyEvent(int key, int value) { | 228 void KeyboardEvdev::DispatchKey(unsigned int key, bool down) { |
| 238 int down = (value != 0); | 229 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(); | 230 int flags = modifiers_->GetModifierFlags(); |
| 254 | 231 |
| 255 KeyEvent key_event( | 232 KeyEvent key_event( |
| 256 down ? ET_KEY_PRESSED : ET_KEY_RELEASED, | 233 down ? ET_KEY_PRESSED : ET_KEY_RELEASED, |
| 257 code, | 234 code, |
| 258 KeycodeConverter::NativeKeycodeToCode(key + kXkbKeycodeOffset), | 235 KeycodeConverter::NativeKeycodeToCode(key + kXkbKeycodeOffset), |
| 259 flags); | 236 flags); |
| 260 callback_.Run(&key_event); | 237 callback_.Run(&key_event); |
| 261 } | 238 } |
| 262 | 239 |
| 263 } // namespace ui | 240 } // namespace ui |
| OLD | NEW |