Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "remoting/host/input_injector.h" | 5 #include "remoting/host/input_injector.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <X11/extensions/XInput.h> | 9 #include <X11/extensions/XInput.h> |
| 10 #include <X11/extensions/XTest.h> | 10 #include <X11/extensions/XTest.h> |
| 11 #include <X11/Xlib.h> | 11 #include <X11/Xlib.h> |
| 12 #include <X11/XKBlib.h> | 12 #include <X11/XKBlib.h> |
| 13 #include <X11/keysym.h> | |
| 13 #undef Status // Xlib.h #defines this, which breaks protobuf headers. | 14 #undef Status // Xlib.h #defines this, which breaks protobuf headers. |
| 14 | 15 |
| 15 #include <set> | 16 #include <set> |
| 16 #include <utility> | 17 #include <utility> |
| 17 | 18 |
| 18 #include "base/bind.h" | 19 #include "base/bind.h" |
| 19 #include "base/compiler_specific.h" | 20 #include "base/compiler_specific.h" |
| 20 #include "base/location.h" | 21 #include "base/location.h" |
| 21 #include "base/macros.h" | 22 #include "base/macros.h" |
| 22 #include "base/memory/ptr_util.h" | 23 #include "base/memory/ptr_util.h" |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 | 115 |
| 115 // Queries whether keyboard auto-repeat is globally enabled. This is used | 116 // Queries whether keyboard auto-repeat is globally enabled. This is used |
| 116 // to decide whether to temporarily disable then restore this setting. If | 117 // to decide whether to temporarily disable then restore this setting. If |
| 117 // auto-repeat has already been disabled, this class should leave it | 118 // auto-repeat has already been disabled, this class should leave it |
| 118 // untouched. | 119 // untouched. |
| 119 bool IsAutoRepeatEnabled(); | 120 bool IsAutoRepeatEnabled(); |
| 120 | 121 |
| 121 // Enables or disables keyboard auto-repeat globally. | 122 // Enables or disables keyboard auto-repeat globally. |
| 122 void SetAutoRepeatEnabled(bool enabled); | 123 void SetAutoRepeatEnabled(bool enabled); |
| 123 | 124 |
| 125 // Sets the keyboard lock states to those provided. | |
| 126 void SetLockStates(uint32_t states); | |
| 127 | |
| 124 void InjectScrollWheelClicks(int button, int count); | 128 void InjectScrollWheelClicks(int button, int count); |
| 125 // Compensates for global button mappings and resets the XTest device | 129 // Compensates for global button mappings and resets the XTest device |
| 126 // mapping. | 130 // mapping. |
| 127 void InitMouseButtonMap(); | 131 void InitMouseButtonMap(); |
| 128 int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button); | 132 int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button); |
| 129 int HorizontalScrollWheelToX11ButtonNumber(int dx); | 133 int HorizontalScrollWheelToX11ButtonNumber(int dx); |
| 130 int VerticalScrollWheelToX11ButtonNumber(int dy); | 134 int VerticalScrollWheelToX11ButtonNumber(int dy); |
| 131 | 135 |
| 132 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 136 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 133 | 137 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 if (event.pressed()) { | 273 if (event.pressed()) { |
| 270 if (pressed_keys_.find(keycode) != pressed_keys_.end()) { | 274 if (pressed_keys_.find(keycode) != pressed_keys_.end()) { |
| 271 // Ignore repeats for modifier keys. | 275 // Ignore repeats for modifier keys. |
| 272 if (IsModifierKey(static_cast<ui::DomCode>(event.usb_keycode()))) | 276 if (IsModifierKey(static_cast<ui::DomCode>(event.usb_keycode()))) |
| 273 return; | 277 return; |
| 274 // Key is already held down, so lift the key up to ensure this repeated | 278 // Key is already held down, so lift the key up to ensure this repeated |
| 275 // press takes effect. | 279 // press takes effect. |
| 276 XTestFakeKeyEvent(display_, keycode, False, CurrentTime); | 280 XTestFakeKeyEvent(display_, keycode, False, CurrentTime); |
| 277 } | 281 } |
| 278 | 282 |
| 283 if (event.has_lock_states()) { | |
| 284 SetLockStates(event.lock_states()); | |
| 285 } | |
| 286 | |
| 279 if (pressed_keys_.empty()) { | 287 if (pressed_keys_.empty()) { |
| 280 // Disable auto-repeat, if necessary, to avoid triggering auto-repeat | 288 // Disable auto-repeat, if necessary, to avoid triggering auto-repeat |
| 281 // if network congestion delays the key-up event from the client. | 289 // if network congestion delays the key-up event from the client. |
| 282 saved_auto_repeat_enabled_ = IsAutoRepeatEnabled(); | 290 saved_auto_repeat_enabled_ = IsAutoRepeatEnabled(); |
| 283 if (saved_auto_repeat_enabled_) | 291 if (saved_auto_repeat_enabled_) |
| 284 SetAutoRepeatEnabled(false); | 292 SetAutoRepeatEnabled(false); |
| 285 } | 293 } |
| 286 pressed_keys_.insert(keycode); | 294 pressed_keys_.insert(keycode); |
| 287 } else { | 295 } else { |
| 288 pressed_keys_.erase(keycode); | 296 pressed_keys_.erase(keycode); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 } | 348 } |
| 341 return state.global_auto_repeat == AutoRepeatModeOn; | 349 return state.global_auto_repeat == AutoRepeatModeOn; |
| 342 } | 350 } |
| 343 | 351 |
| 344 void InputInjectorX11::Core::SetAutoRepeatEnabled(bool mode) { | 352 void InputInjectorX11::Core::SetAutoRepeatEnabled(bool mode) { |
| 345 XKeyboardControl control; | 353 XKeyboardControl control; |
| 346 control.auto_repeat_mode = mode ? AutoRepeatModeOn : AutoRepeatModeOff; | 354 control.auto_repeat_mode = mode ? AutoRepeatModeOn : AutoRepeatModeOff; |
| 347 XChangeKeyboardControl(display_, KBAutoRepeatMode, &control); | 355 XChangeKeyboardControl(display_, KBAutoRepeatMode, &control); |
| 348 } | 356 } |
| 349 | 357 |
| 358 void InputInjectorX11::Core::SetLockStates(uint32_t states) { | |
| 359 unsigned int caps_lock_mask = XkbKeysymToModifiers(display_, XK_Caps_Lock); | |
| 360 unsigned int num_lock_mask = XkbKeysymToModifiers(display_, XK_Num_Lock); | |
| 361 unsigned int lock_values = 0; | |
| 362 if (states & protocol::KeyEvent::LOCK_STATES_CAPSLOCK) { | |
| 363 lock_values |= caps_lock_mask; | |
| 364 } | |
| 365 if (states & protocol::KeyEvent::LOCK_STATES_NUMLOCK) { | |
| 366 lock_values |= num_lock_mask; | |
| 367 } | |
| 368 XkbLockModifiers(display_, XkbUseCoreKbd, caps_lock_mask | num_lock_mask, | |
| 369 lock_values); | |
|
rkjnsn
2017/04/25 19:25:03
We could check the existing states first instead o
Jamie
2017/04/25 20:15:57
I think this is fine. The documentation suggests t
| |
| 370 } | |
| 371 | |
| 350 void InputInjectorX11::Core::InjectScrollWheelClicks(int button, int count) { | 372 void InputInjectorX11::Core::InjectScrollWheelClicks(int button, int count) { |
| 351 if (button < 0) { | 373 if (button < 0) { |
| 352 LOG(WARNING) << "Ignoring unmapped scroll wheel button"; | 374 LOG(WARNING) << "Ignoring unmapped scroll wheel button"; |
| 353 return; | 375 return; |
| 354 } | 376 } |
| 355 for (int i = 0; i < count; i++) { | 377 for (int i = 0; i < count; i++) { |
| 356 // Generate a button-down and a button-up to simulate a wheel click. | 378 // Generate a button-down and a button-up to simulate a wheel click. |
| 357 XTestFakeButtonEvent(display_, button, true, CurrentTime); | 379 XTestFakeButtonEvent(display_, button, true, CurrentTime); |
| 358 XTestFakeButtonEvent(display_, button, false, CurrentTime); | 380 XTestFakeButtonEvent(display_, button, false, CurrentTime); |
| 359 } | 381 } |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 return nullptr; | 625 return nullptr; |
| 604 return std::move(injector); | 626 return std::move(injector); |
| 605 } | 627 } |
| 606 | 628 |
| 607 // static | 629 // static |
| 608 bool InputInjector::SupportsTouchEvents() { | 630 bool InputInjector::SupportsTouchEvents() { |
| 609 return false; | 631 return false; |
| 610 } | 632 } |
| 611 | 633 |
| 612 } // namespace remoting | 634 } // namespace remoting |
| OLD | NEW |