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 <X11/extensions/XInput.h> | 7 #include <X11/extensions/XInput.h> |
8 #include <X11/extensions/XTest.h> | 8 #include <X11/extensions/XTest.h> |
9 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
10 | 10 |
11 #include <set> | 11 #include <set> |
12 | 12 |
13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
14 #include "base/bind.h" | 14 #include "base/bind.h" |
15 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
16 #include "base/location.h" | 16 #include "base/location.h" |
17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
18 #include "remoting/base/logging.h" | 18 #include "remoting/base/logging.h" |
19 #include "remoting/host/clipboard.h" | 19 #include "remoting/host/clipboard.h" |
20 #include "remoting/proto/internal.pb.h" | 20 #include "remoting/proto/internal.pb.h" |
21 #include "third_party/skia/include/core/SkPoint.h" | 21 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" |
22 #include "ui/events/keycodes/dom4/keycode_converter.h" | 22 #include "ui/events/keycodes/dom4/keycode_converter.h" |
23 | 23 |
24 namespace remoting { | 24 namespace remoting { |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 using protocol::ClipboardEvent; | 28 using protocol::ClipboardEvent; |
29 using protocol::KeyEvent; | 29 using protocol::KeyEvent; |
30 using protocol::MouseEvent; | 30 using protocol::MouseEvent; |
31 | 31 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // Compensates for global button mappings and resets the XTest device | 92 // Compensates for global button mappings and resets the XTest device |
93 // mapping. | 93 // mapping. |
94 void InitMouseButtonMap(); | 94 void InitMouseButtonMap(); |
95 int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button); | 95 int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button); |
96 int HorizontalScrollWheelToX11ButtonNumber(int dx); | 96 int HorizontalScrollWheelToX11ButtonNumber(int dx); |
97 int VerticalScrollWheelToX11ButtonNumber(int dy); | 97 int VerticalScrollWheelToX11ButtonNumber(int dy); |
98 | 98 |
99 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 99 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
100 | 100 |
101 std::set<int> pressed_keys_; | 101 std::set<int> pressed_keys_; |
102 SkIPoint latest_mouse_position_; | 102 webrtc::DesktopVector latest_mouse_position_; |
103 float wheel_ticks_x_; | 103 float wheel_ticks_x_; |
104 float wheel_ticks_y_; | 104 float wheel_ticks_y_; |
105 | 105 |
106 // X11 graphics context. | 106 // X11 graphics context. |
107 Display* display_; | 107 Display* display_; |
108 Window root_window_; | 108 Window root_window_; |
109 | 109 |
110 int test_event_base_; | 110 int test_event_base_; |
111 int test_error_base_; | 111 int test_error_base_; |
112 | 112 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 153 } |
154 | 154 |
155 void InputInjectorLinux::Start( | 155 void InputInjectorLinux::Start( |
156 scoped_ptr<protocol::ClipboardStub> client_clipboard) { | 156 scoped_ptr<protocol::ClipboardStub> client_clipboard) { |
157 core_->Start(client_clipboard.Pass()); | 157 core_->Start(client_clipboard.Pass()); |
158 } | 158 } |
159 | 159 |
160 InputInjectorLinux::Core::Core( | 160 InputInjectorLinux::Core::Core( |
161 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 161 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
162 : task_runner_(task_runner), | 162 : task_runner_(task_runner), |
163 latest_mouse_position_(SkIPoint::Make(-1, -1)), | 163 latest_mouse_position_(-1, -1), |
164 wheel_ticks_x_(0.0f), | 164 wheel_ticks_x_(0.0f), |
165 wheel_ticks_y_(0.0f), | 165 wheel_ticks_y_(0.0f), |
166 display_(XOpenDisplay(NULL)), | 166 display_(XOpenDisplay(NULL)), |
167 root_window_(BadValue), | 167 root_window_(BadValue), |
168 saved_auto_repeat_enabled_(false) { | 168 saved_auto_repeat_enabled_(false) { |
169 } | 169 } |
170 | 170 |
171 bool InputInjectorLinux::Core::Init() { | 171 bool InputInjectorLinux::Core::Init() { |
172 CHECK(display_); | 172 CHECK(display_); |
173 | 173 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 void InputInjectorLinux::Core::InjectMouseEvent(const MouseEvent& event) { | 292 void InputInjectorLinux::Core::InjectMouseEvent(const MouseEvent& event) { |
293 if (!task_runner_->BelongsToCurrentThread()) { | 293 if (!task_runner_->BelongsToCurrentThread()) { |
294 task_runner_->PostTask(FROM_HERE, | 294 task_runner_->PostTask(FROM_HERE, |
295 base::Bind(&Core::InjectMouseEvent, this, event)); | 295 base::Bind(&Core::InjectMouseEvent, this, event)); |
296 return; | 296 return; |
297 } | 297 } |
298 | 298 |
299 if (event.has_delta_x() && | 299 if (event.has_delta_x() && |
300 event.has_delta_y() && | 300 event.has_delta_y() && |
301 (event.delta_x() != 0 || event.delta_y() != 0)) { | 301 (event.delta_x() != 0 || event.delta_y() != 0)) { |
302 latest_mouse_position_ = SkIPoint::Make(-1, -1); | 302 latest_mouse_position_.set(-1, -1); |
303 VLOG(3) << "Moving mouse by " << event.delta_x() << "," << event.delta_y(); | 303 VLOG(3) << "Moving mouse by " << event.delta_x() << "," << event.delta_y(); |
304 XTestFakeRelativeMotionEvent(display_, | 304 XTestFakeRelativeMotionEvent(display_, |
305 event.delta_x(), event.delta_y(), | 305 event.delta_x(), event.delta_y(), |
306 CurrentTime); | 306 CurrentTime); |
307 | 307 |
308 } else if (event.has_x() && event.has_y()) { | 308 } else if (event.has_x() && event.has_y()) { |
309 // Injecting a motion event immediately before a button release results in | 309 // Injecting a motion event immediately before a button release results in |
310 // a MotionNotify even if the mouse position hasn't changed, which confuses | 310 // a MotionNotify even if the mouse position hasn't changed, which confuses |
311 // apps which assume MotionNotify implies movement. See crbug.com/138075. | 311 // apps which assume MotionNotify implies movement. See crbug.com/138075. |
312 bool inject_motion = true; | 312 bool inject_motion = true; |
313 SkIPoint new_mouse_position(SkIPoint::Make(event.x(), event.y())); | 313 webrtc::DesktopVector new_mouse_position( |
| 314 webrtc::DesktopVector(event.x(), event.y())); |
314 if (event.has_button() && event.has_button_down() && !event.button_down()) { | 315 if (event.has_button() && event.has_button_down() && !event.button_down()) { |
315 if (new_mouse_position == latest_mouse_position_) | 316 if (new_mouse_position.equals(latest_mouse_position_)) |
316 inject_motion = false; | 317 inject_motion = false; |
317 } | 318 } |
318 | 319 |
319 if (inject_motion) { | 320 if (inject_motion) { |
320 latest_mouse_position_ = | 321 latest_mouse_position_.set(std::max(0, new_mouse_position.x()), |
321 SkIPoint::Make(std::max(0, new_mouse_position.x()), | 322 std::max(0, new_mouse_position.y())); |
322 std::max(0, new_mouse_position.y())); | |
323 | 323 |
324 VLOG(3) << "Moving mouse to " << latest_mouse_position_.x() | 324 VLOG(3) << "Moving mouse to " << latest_mouse_position_.x() |
325 << "," << latest_mouse_position_.y(); | 325 << "," << latest_mouse_position_.y(); |
326 XTestFakeMotionEvent(display_, DefaultScreen(display_), | 326 XTestFakeMotionEvent(display_, DefaultScreen(display_), |
327 latest_mouse_position_.x(), | 327 latest_mouse_position_.x(), |
328 latest_mouse_position_.y(), | 328 latest_mouse_position_.y(), |
329 CurrentTime); | 329 CurrentTime); |
330 } | 330 } |
331 } | 331 } |
332 | 332 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 513 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |
514 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 514 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { |
515 scoped_ptr<InputInjectorLinux> injector( | 515 scoped_ptr<InputInjectorLinux> injector( |
516 new InputInjectorLinux(main_task_runner)); | 516 new InputInjectorLinux(main_task_runner)); |
517 if (!injector->Init()) | 517 if (!injector->Init()) |
518 return scoped_ptr<InputInjector>(); | 518 return scoped_ptr<InputInjector>(); |
519 return injector.PassAs<InputInjector>(); | 519 return injector.PassAs<InputInjector>(); |
520 } | 520 } |
521 | 521 |
522 } // namespace remoting | 522 } // namespace remoting |
OLD | NEW |