Chromium Code Reviews| 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 |