OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/event_executor.h" | 5 #include "remoting/host/event_executor.h" |
6 | 6 |
7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
8 #include <X11/XF86keysym.h> | 8 #include <X11/XF86keysym.h> |
9 #include <X11/keysym.h> | 9 #include <X11/keysym.h> |
10 #include <X11/extensions/XTest.h> | 10 #include <X11/extensions/XTest.h> |
(...skipping 18 matching lines...) Expand all Loading... | |
29 public: | 29 public: |
30 EventExecutorLinux(MessageLoop* message_loop, Capturer* capturer); | 30 EventExecutorLinux(MessageLoop* message_loop, Capturer* capturer); |
31 virtual ~EventExecutorLinux() {}; | 31 virtual ~EventExecutorLinux() {}; |
32 | 32 |
33 bool Init(); | 33 bool Init(); |
34 | 34 |
35 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; | 35 virtual void InjectKeyEvent(const KeyEvent& event) OVERRIDE; |
36 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; | 36 virtual void InjectMouseEvent(const MouseEvent& event) OVERRIDE; |
37 | 37 |
38 private: | 38 private: |
39 void InjectScrollWheelClicks(int button, int count); | |
40 | |
39 MessageLoop* message_loop_; | 41 MessageLoop* message_loop_; |
40 Capturer* capturer_; | 42 Capturer* capturer_; |
41 | 43 |
42 // X11 graphics context. | 44 // X11 graphics context. |
43 Display* display_; | 45 Display* display_; |
44 Window root_window_; | 46 Window root_window_; |
45 int width_; | 47 int width_; |
46 int height_; | 48 int height_; |
47 | 49 |
48 int test_event_base_; | 50 int test_event_base_; |
(...skipping 12 matching lines...) Expand all Loading... | |
61 | 63 |
62 case MouseEvent::BUTTON_MIDDLE: | 64 case MouseEvent::BUTTON_MIDDLE: |
63 return 2; | 65 return 2; |
64 | 66 |
65 case MouseEvent::BUTTON_UNDEFINED: | 67 case MouseEvent::BUTTON_UNDEFINED: |
66 default: | 68 default: |
67 return -1; | 69 return -1; |
68 } | 70 } |
69 } | 71 } |
70 | 72 |
73 int ScrollWheelToX11ButtonNumber(int dx, int dy) { | |
Wez
2011/10/14 21:42:54
Split this into two separate functions for clarity
| |
74 // Horizontal scroll wheel. | |
75 if (dx != 0) | |
76 return (dx > 0 ? 6 : 7); | |
77 | |
78 // Positive y-values are wheel scroll-up events (button 4), negative y-values | |
79 // are wheel scroll-down events (button 5). | |
80 return (dy > 0 ? 4 : 5); | |
81 } | |
82 | |
71 // Hard-coded mapping from Virtual Key codes to X11 KeySyms. | 83 // Hard-coded mapping from Virtual Key codes to X11 KeySyms. |
72 // This mapping is only valid if both client and host are using a | 84 // This mapping is only valid if both client and host are using a |
73 // US English keyboard layout. | 85 // US English keyboard layout. |
74 // Because we're passing VK codes on the wire, with no Scancode, | 86 // Because we're passing VK codes on the wire, with no Scancode, |
75 // "extended" flag, etc, things like distinguishing left & right | 87 // "extended" flag, etc, things like distinguishing left & right |
76 // Shift keys doesn't work. | 88 // Shift keys doesn't work. |
77 // | 89 // |
78 // TODO(wez): Replace this with something more closely tied to what | 90 // TODO(wez): Replace this with something more closely tied to what |
79 // WebInputEventFactory does on Linux/GTK, and which respects the | 91 // WebInputEventFactory does on Linux/GTK, and which respects the |
80 // host's keyboard layout (see http://crbug.com/74550 ). | 92 // host's keyboard layout (see http://crbug.com/74550 ). |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 return; | 314 return; |
303 } | 315 } |
304 | 316 |
305 VLOG(3) << "Got pepper key: " << event.keycode() | 317 VLOG(3) << "Got pepper key: " << event.keycode() |
306 << " sending keysym: " << keysym | 318 << " sending keysym: " << keysym |
307 << " to keycode: " << keycode; | 319 << " to keycode: " << keycode; |
308 XTestFakeKeyEvent(display_, keycode, event.pressed(), CurrentTime); | 320 XTestFakeKeyEvent(display_, keycode, event.pressed(), CurrentTime); |
309 XFlush(display_); | 321 XFlush(display_); |
310 } | 322 } |
311 | 323 |
324 void EventExecutorLinux::InjectScrollWheelClicks(int button, int count) { | |
325 for (int i = 0; i < count; i++) { | |
326 // Generate a button-down and a button-up to simulate a wheel click. | |
327 XTestFakeButtonEvent(display_, button, true, CurrentTime); | |
328 XTestFakeButtonEvent(display_, button, false, CurrentTime); | |
329 } | |
330 XFlush(display_); | |
331 } | |
332 | |
312 void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) { | 333 void EventExecutorLinux::InjectMouseEvent(const MouseEvent& event) { |
313 if (MessageLoop::current() != message_loop_) { | 334 if (MessageLoop::current() != message_loop_) { |
314 message_loop_->PostTask( | 335 message_loop_->PostTask( |
315 FROM_HERE, | 336 FROM_HERE, |
316 base::Bind(&EventExecutorLinux::InjectMouseEvent, | 337 base::Bind(&EventExecutorLinux::InjectMouseEvent, |
317 base::Unretained(this), event)); | 338 base::Unretained(this), event)); |
318 return; | 339 return; |
319 } | 340 } |
320 | 341 |
321 if (event.has_x() && event.has_y()) { | 342 if (event.has_x() && event.has_y()) { |
(...skipping 10 matching lines...) Expand all Loading... | |
332 XTestFakeMotionEvent(display_, DefaultScreen(display_), | 353 XTestFakeMotionEvent(display_, DefaultScreen(display_), |
333 event.x(), event.y(), | 354 event.x(), event.y(), |
334 CurrentTime); | 355 CurrentTime); |
335 XFlush(display_); | 356 XFlush(display_); |
336 } | 357 } |
337 | 358 |
338 if (event.has_button() && event.has_button_down()) { | 359 if (event.has_button() && event.has_button_down()) { |
339 int button_number = MouseButtonToX11ButtonNumber(event.button()); | 360 int button_number = MouseButtonToX11ButtonNumber(event.button()); |
340 | 361 |
341 if (button_number < 0) { | 362 if (button_number < 0) { |
342 LOG(WARNING) << "Ignoring unknown button type: " | 363 LOG(WARNING) << "Ignoring unknown button type: " << event.button(); |
343 << event.button(); | |
344 return; | 364 return; |
345 } | 365 } |
346 | 366 |
347 VLOG(3) << "Button " << event.button() | 367 VLOG(3) << "Button " << event.button() |
348 << " received, sending " | 368 << " received, sending " |
349 << (event.button_down() ? "down " : "up ") | 369 << (event.button_down() ? "down " : "up ") |
350 << button_number; | 370 << button_number; |
351 XTestFakeButtonEvent(display_, button_number, event.button_down(), | 371 XTestFakeButtonEvent(display_, button_number, event.button_down(), |
352 CurrentTime); | 372 CurrentTime); |
353 XFlush(display_); | 373 XFlush(display_); |
354 } | 374 } |
355 | 375 |
356 if (event.has_wheel_offset_x() && event.has_wheel_offset_y()) { | 376 if (event.has_wheel_offset_y() && event.wheel_offset_y() != 0) { |
357 NOTIMPLEMENTED() << "No scroll wheel support yet."; | 377 int dy = event.wheel_offset_y(); |
378 InjectScrollWheelClicks(ScrollWheelToX11ButtonNumber(0, dy), | |
379 (dy > 0) ? dy : -dy); | |
Lambros
2011/10/14 21:00:25
Optional nit: Maybe use abs() from <stdlib.h> or <
| |
380 } | |
381 if (event.has_wheel_offset_x() && event.wheel_offset_x() != 0) { | |
382 int dx = event.wheel_offset_x(); | |
383 InjectScrollWheelClicks(ScrollWheelToX11ButtonNumber(dx, 0), | |
384 (dx > 0) ? dx : -dx); | |
358 } | 385 } |
359 } | 386 } |
360 | 387 |
361 } // namespace | 388 } // namespace |
362 | 389 |
363 EventExecutor* EventExecutor::Create(MessageLoop* message_loop, | 390 EventExecutor* EventExecutor::Create(MessageLoop* message_loop, |
364 Capturer* capturer) { | 391 Capturer* capturer) { |
365 EventExecutorLinux* executor = new EventExecutorLinux(message_loop, capturer); | 392 EventExecutorLinux* executor = new EventExecutorLinux(message_loop, capturer); |
366 if (!executor->Init()) { | 393 if (!executor->Init()) { |
367 delete executor; | 394 delete executor; |
368 executor = NULL; | 395 executor = NULL; |
369 } | 396 } |
370 return executor; | 397 return executor; |
371 } | 398 } |
372 | 399 |
373 } // namespace remoting | 400 } // namespace remoting |
OLD | NEW |