| 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> |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 // Clipboard stub interface. | 122 // Clipboard stub interface. |
| 123 void InjectClipboardEvent(const ClipboardEvent& event) override; | 123 void InjectClipboardEvent(const ClipboardEvent& event) override; |
| 124 | 124 |
| 125 // InputStub interface. | 125 // InputStub interface. |
| 126 void InjectKeyEvent(const KeyEvent& event) override; | 126 void InjectKeyEvent(const KeyEvent& event) override; |
| 127 void InjectTextEvent(const TextEvent& event) override; | 127 void InjectTextEvent(const TextEvent& event) override; |
| 128 void InjectMouseEvent(const MouseEvent& event) override; | 128 void InjectMouseEvent(const MouseEvent& event) override; |
| 129 void InjectTouchEvent(const TouchEvent& event) override; | 129 void InjectTouchEvent(const TouchEvent& event) override; |
| 130 | 130 |
| 131 // InputInjector interface. | 131 // InputInjector interface. |
| 132 void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard) override; | 132 void Start( |
| 133 std::unique_ptr<protocol::ClipboardStub> client_clipboard) override; |
| 133 | 134 |
| 134 private: | 135 private: |
| 135 // The actual implementation resides in InputInjectorX11::Core class. | 136 // The actual implementation resides in InputInjectorX11::Core class. |
| 136 class Core : public base::RefCountedThreadSafe<Core> { | 137 class Core : public base::RefCountedThreadSafe<Core> { |
| 137 public: | 138 public: |
| 138 explicit Core(scoped_refptr<base::SingleThreadTaskRunner> task_runner); | 139 explicit Core(scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| 139 | 140 |
| 140 bool Init(); | 141 bool Init(); |
| 141 | 142 |
| 142 // Mirrors the ClipboardStub interface. | 143 // Mirrors the ClipboardStub interface. |
| 143 void InjectClipboardEvent(const ClipboardEvent& event); | 144 void InjectClipboardEvent(const ClipboardEvent& event); |
| 144 | 145 |
| 145 // Mirrors the InputStub interface. | 146 // Mirrors the InputStub interface. |
| 146 void InjectKeyEvent(const KeyEvent& event); | 147 void InjectKeyEvent(const KeyEvent& event); |
| 147 void InjectTextEvent(const TextEvent& event); | 148 void InjectTextEvent(const TextEvent& event); |
| 148 void InjectMouseEvent(const MouseEvent& event); | 149 void InjectMouseEvent(const MouseEvent& event); |
| 149 | 150 |
| 150 // Mirrors the InputInjector interface. | 151 // Mirrors the InputInjector interface. |
| 151 void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard); | 152 void Start(std::unique_ptr<protocol::ClipboardStub> client_clipboard); |
| 152 | 153 |
| 153 void Stop(); | 154 void Stop(); |
| 154 | 155 |
| 155 private: | 156 private: |
| 156 friend class base::RefCountedThreadSafe<Core>; | 157 friend class base::RefCountedThreadSafe<Core>; |
| 157 virtual ~Core(); | 158 virtual ~Core(); |
| 158 | 159 |
| 159 void InitClipboard(); | 160 void InitClipboard(); |
| 160 | 161 |
| 161 // Queries whether keyboard auto-repeat is globally enabled. This is used | 162 // Queries whether keyboard auto-repeat is globally enabled. This is used |
| (...skipping 27 matching lines...) Expand all Loading... |
| 189 // Number of buttons we support. | 190 // Number of buttons we support. |
| 190 // Left, Right, Middle, VScroll Up/Down, HScroll Left/Right. | 191 // Left, Right, Middle, VScroll Up/Down, HScroll Left/Right. |
| 191 static const int kNumPointerButtons = 7; | 192 static const int kNumPointerButtons = 7; |
| 192 | 193 |
| 193 int pointer_button_map_[kNumPointerButtons]; | 194 int pointer_button_map_[kNumPointerButtons]; |
| 194 | 195 |
| 195 #if defined(OS_CHROMEOS) | 196 #if defined(OS_CHROMEOS) |
| 196 PointTransformer point_transformer_; | 197 PointTransformer point_transformer_; |
| 197 #endif | 198 #endif |
| 198 | 199 |
| 199 scoped_ptr<Clipboard> clipboard_; | 200 std::unique_ptr<Clipboard> clipboard_; |
| 200 | 201 |
| 201 bool saved_auto_repeat_enabled_; | 202 bool saved_auto_repeat_enabled_; |
| 202 | 203 |
| 203 DISALLOW_COPY_AND_ASSIGN(Core); | 204 DISALLOW_COPY_AND_ASSIGN(Core); |
| 204 }; | 205 }; |
| 205 | 206 |
| 206 scoped_refptr<Core> core_; | 207 scoped_refptr<Core> core_; |
| 207 | 208 |
| 208 DISALLOW_COPY_AND_ASSIGN(InputInjectorX11); | 209 DISALLOW_COPY_AND_ASSIGN(InputInjectorX11); |
| 209 }; | 210 }; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 235 | 236 |
| 236 void InputInjectorX11::InjectMouseEvent(const MouseEvent& event) { | 237 void InputInjectorX11::InjectMouseEvent(const MouseEvent& event) { |
| 237 core_->InjectMouseEvent(event); | 238 core_->InjectMouseEvent(event); |
| 238 } | 239 } |
| 239 | 240 |
| 240 void InputInjectorX11::InjectTouchEvent(const TouchEvent& event) { | 241 void InputInjectorX11::InjectTouchEvent(const TouchEvent& event) { |
| 241 NOTIMPLEMENTED() << "Raw touch event injection not implemented for X11."; | 242 NOTIMPLEMENTED() << "Raw touch event injection not implemented for X11."; |
| 242 } | 243 } |
| 243 | 244 |
| 244 void InputInjectorX11::Start( | 245 void InputInjectorX11::Start( |
| 245 scoped_ptr<protocol::ClipboardStub> client_clipboard) { | 246 std::unique_ptr<protocol::ClipboardStub> client_clipboard) { |
| 246 core_->Start(std::move(client_clipboard)); | 247 core_->Start(std::move(client_clipboard)); |
| 247 } | 248 } |
| 248 | 249 |
| 249 InputInjectorX11::Core::Core( | 250 InputInjectorX11::Core::Core( |
| 250 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 251 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| 251 : task_runner_(task_runner), | 252 : task_runner_(task_runner), |
| 252 latest_mouse_position_(-1, -1), | 253 latest_mouse_position_(-1, -1), |
| 253 wheel_ticks_x_(0.0f), | 254 wheel_ticks_x_(0.0f), |
| 254 wheel_ticks_y_(0.0f), | 255 wheel_ticks_y_(0.0f), |
| 255 display_(XOpenDisplay(nullptr)), | 256 display_(XOpenDisplay(nullptr)), |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 } | 516 } |
| 516 | 517 |
| 517 void InputInjectorX11::Core::InitMouseButtonMap() { | 518 void InputInjectorX11::Core::InitMouseButtonMap() { |
| 518 // TODO(rmsousa): Run this on global/device mapping change events. | 519 // TODO(rmsousa): Run this on global/device mapping change events. |
| 519 | 520 |
| 520 // Do not touch global pointer mapping, since this may affect the local user. | 521 // Do not touch global pointer mapping, since this may affect the local user. |
| 521 // Instead, try to work around it by reversing the mapping. | 522 // Instead, try to work around it by reversing the mapping. |
| 522 // Note that if a user has a global mapping that completely disables a button | 523 // Note that if a user has a global mapping that completely disables a button |
| 523 // (by assigning 0 to it), we won't be able to inject it. | 524 // (by assigning 0 to it), we won't be able to inject it. |
| 524 int num_buttons = XGetPointerMapping(display_, nullptr, 0); | 525 int num_buttons = XGetPointerMapping(display_, nullptr, 0); |
| 525 scoped_ptr<unsigned char[]> pointer_mapping(new unsigned char[num_buttons]); | 526 std::unique_ptr<unsigned char[]> pointer_mapping( |
| 527 new unsigned char[num_buttons]); |
| 526 num_buttons = XGetPointerMapping(display_, pointer_mapping.get(), | 528 num_buttons = XGetPointerMapping(display_, pointer_mapping.get(), |
| 527 num_buttons); | 529 num_buttons); |
| 528 for (int i = 0; i < kNumPointerButtons; i++) { | 530 for (int i = 0; i < kNumPointerButtons; i++) { |
| 529 pointer_button_map_[i] = -1; | 531 pointer_button_map_[i] = -1; |
| 530 } | 532 } |
| 531 for (int i = 0; i < num_buttons; i++) { | 533 for (int i = 0; i < num_buttons; i++) { |
| 532 // Reverse the mapping. | 534 // Reverse the mapping. |
| 533 if (pointer_mapping[i] > 0 && pointer_mapping[i] <= kNumPointerButtons) | 535 if (pointer_mapping[i] > 0 && pointer_mapping[i] <= kNumPointerButtons) |
| 534 pointer_button_map_[pointer_mapping[i] - 1] = i + 1; | 536 pointer_button_map_[pointer_mapping[i] - 1] = i + 1; |
| 535 } | 537 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 } | 574 } |
| 573 | 575 |
| 574 XDevice* device = XOpenDevice(display_, device_id); | 576 XDevice* device = XOpenDevice(display_, device_id); |
| 575 if (!device) { | 577 if (!device) { |
| 576 LOG(ERROR) << "Cannot open XTest device."; | 578 LOG(ERROR) << "Cannot open XTest device."; |
| 577 return; | 579 return; |
| 578 } | 580 } |
| 579 | 581 |
| 580 int num_device_buttons = | 582 int num_device_buttons = |
| 581 XGetDeviceButtonMapping(display_, device, nullptr, 0); | 583 XGetDeviceButtonMapping(display_, device, nullptr, 0); |
| 582 scoped_ptr<unsigned char[]> button_mapping(new unsigned char[num_buttons]); | 584 std::unique_ptr<unsigned char[]> button_mapping( |
| 585 new unsigned char[num_buttons]); |
| 583 for (int i = 0; i < num_device_buttons; i++) { | 586 for (int i = 0; i < num_device_buttons; i++) { |
| 584 button_mapping[i] = i + 1; | 587 button_mapping[i] = i + 1; |
| 585 } | 588 } |
| 586 error = XSetDeviceButtonMapping(display_, device, button_mapping.get(), | 589 error = XSetDeviceButtonMapping(display_, device, button_mapping.get(), |
| 587 num_device_buttons); | 590 num_device_buttons); |
| 588 if (error != Success) | 591 if (error != Success) |
| 589 LOG(ERROR) << "Failed to set XTest device button mapping: " << error; | 592 LOG(ERROR) << "Failed to set XTest device button mapping: " << error; |
| 590 | 593 |
| 591 XCloseDevice(display_, device); | 594 XCloseDevice(display_, device); |
| 592 } | 595 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 613 return (dx > 0 ? pointer_button_map_[5] : pointer_button_map_[6]); | 616 return (dx > 0 ? pointer_button_map_[5] : pointer_button_map_[6]); |
| 614 } | 617 } |
| 615 | 618 |
| 616 int InputInjectorX11::Core::VerticalScrollWheelToX11ButtonNumber(int dy) { | 619 int InputInjectorX11::Core::VerticalScrollWheelToX11ButtonNumber(int dy) { |
| 617 // Positive y-values are wheel scroll-up events (button 4), negative y-values | 620 // Positive y-values are wheel scroll-up events (button 4), negative y-values |
| 618 // are wheel scroll-down events (button 5). | 621 // are wheel scroll-down events (button 5). |
| 619 return (dy > 0 ? pointer_button_map_[3] : pointer_button_map_[4]); | 622 return (dy > 0 ? pointer_button_map_[3] : pointer_button_map_[4]); |
| 620 } | 623 } |
| 621 | 624 |
| 622 void InputInjectorX11::Core::Start( | 625 void InputInjectorX11::Core::Start( |
| 623 scoped_ptr<protocol::ClipboardStub> client_clipboard) { | 626 std::unique_ptr<protocol::ClipboardStub> client_clipboard) { |
| 624 if (!task_runner_->BelongsToCurrentThread()) { | 627 if (!task_runner_->BelongsToCurrentThread()) { |
| 625 task_runner_->PostTask( | 628 task_runner_->PostTask( |
| 626 FROM_HERE, | 629 FROM_HERE, |
| 627 base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); | 630 base::Bind(&Core::Start, this, base::Passed(&client_clipboard))); |
| 628 return; | 631 return; |
| 629 } | 632 } |
| 630 | 633 |
| 631 InitMouseButtonMap(); | 634 InitMouseButtonMap(); |
| 632 | 635 |
| 633 clipboard_->Start(std::move(client_clipboard)); | 636 clipboard_->Start(std::move(client_clipboard)); |
| 634 } | 637 } |
| 635 | 638 |
| 636 void InputInjectorX11::Core::Stop() { | 639 void InputInjectorX11::Core::Stop() { |
| 637 if (!task_runner_->BelongsToCurrentThread()) { | 640 if (!task_runner_->BelongsToCurrentThread()) { |
| 638 task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this)); | 641 task_runner_->PostTask(FROM_HERE, base::Bind(&Core::Stop, this)); |
| 639 return; | 642 return; |
| 640 } | 643 } |
| 641 | 644 |
| 642 clipboard_.reset(); | 645 clipboard_.reset(); |
| 643 } | 646 } |
| 644 | 647 |
| 645 } // namespace | 648 } // namespace |
| 646 | 649 |
| 647 // static | 650 // static |
| 648 scoped_ptr<InputInjector> InputInjector::Create( | 651 std::unique_ptr<InputInjector> InputInjector::Create( |
| 649 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 652 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
| 650 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 653 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
| 651 scoped_ptr<InputInjectorX11> injector( | 654 std::unique_ptr<InputInjectorX11> injector( |
| 652 new InputInjectorX11(main_task_runner)); | 655 new InputInjectorX11(main_task_runner)); |
| 653 if (!injector->Init()) | 656 if (!injector->Init()) |
| 654 return nullptr; | 657 return nullptr; |
| 655 return std::move(injector); | 658 return std::move(injector); |
| 656 } | 659 } |
| 657 | 660 |
| 658 // static | 661 // static |
| 659 bool InputInjector::SupportsTouchEvents() { | 662 bool InputInjector::SupportsTouchEvents() { |
| 660 return false; | 663 return false; |
| 661 } | 664 } |
| 662 | 665 |
| 663 } // namespace remoting | 666 } // namespace remoting |
| OLD | NEW |