| 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> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 16 #include "base/task.h" | 16 #include "base/task.h" |
| 17 #include "media/base/callback.h" |
| 17 #include "remoting/proto/internal.pb.h" | 18 #include "remoting/proto/internal.pb.h" |
| 18 | 19 |
| 19 namespace remoting { | 20 namespace remoting { |
| 20 | 21 |
| 21 using protocol::MouseEvent; | 22 using protocol::MouseEvent; |
| 22 using protocol::KeyEvent; | 23 using protocol::KeyEvent; |
| 23 | 24 |
| 24 namespace { | 25 namespace { |
| 25 | 26 |
| 26 // A class to generate events on Linux. | 27 // A class to generate events on Linux. |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 LOG(ERROR) << "Unable to get window attributes"; | 271 LOG(ERROR) << "Unable to get window attributes"; |
| 271 return false; | 272 return false; |
| 272 } | 273 } |
| 273 | 274 |
| 274 width_ = root_attr.width; | 275 width_ = root_attr.width; |
| 275 height_ = root_attr.height; | 276 height_ = root_attr.height; |
| 276 return true; | 277 return true; |
| 277 } | 278 } |
| 278 | 279 |
| 279 void EventExecutorLinux::InjectKeyEvent(const KeyEvent* event, Task* done) { | 280 void EventExecutorLinux::InjectKeyEvent(const KeyEvent* event, Task* done) { |
| 280 base::ScopedTaskRunner done_runner(done); | 281 media::AutoTaskRunner done_runner(done); |
| 281 | 282 |
| 282 if (MessageLoop::current() != message_loop_) { | 283 if (MessageLoop::current() != message_loop_) { |
| 283 message_loop_->PostTask( | 284 message_loop_->PostTask( |
| 284 FROM_HERE, | 285 FROM_HERE, |
| 285 NewRunnableMethod(this, &EventExecutorLinux::InjectKeyEvent, | 286 NewRunnableMethod(this, &EventExecutorLinux::InjectKeyEvent, |
| 286 event, done_runner.Release())); | 287 event, done_runner.release())); |
| 287 return; | 288 return; |
| 288 } | 289 } |
| 289 | 290 |
| 290 // TODO(ajwong): This will only work for QWERTY keyboards. | 291 // TODO(ajwong): This will only work for QWERTY keyboards. |
| 291 int keysym = ChromotocolKeycodeToX11Keysym(event->keycode()); | 292 int keysym = ChromotocolKeycodeToX11Keysym(event->keycode()); |
| 292 | 293 |
| 293 if (keysym == -1) { | 294 if (keysym == -1) { |
| 294 LOG(WARNING) << "Ignoring unknown key: " << event->keycode(); | 295 LOG(WARNING) << "Ignoring unknown key: " << event->keycode(); |
| 295 return; | 296 return; |
| 296 } | 297 } |
| 297 | 298 |
| 298 // Translate the keysym into a keycode understandable by the X display. | 299 // Translate the keysym into a keycode understandable by the X display. |
| 299 int keycode = XKeysymToKeycode(display_, keysym); | 300 int keycode = XKeysymToKeycode(display_, keysym); |
| 300 if (keycode == 0) { | 301 if (keycode == 0) { |
| 301 LOG(WARNING) << "Ignoring undefined keysym: " << keysym | 302 LOG(WARNING) << "Ignoring undefined keysym: " << keysym |
| 302 << " for key: " << event->keycode(); | 303 << " for key: " << event->keycode(); |
| 303 return; | 304 return; |
| 304 } | 305 } |
| 305 | 306 |
| 306 VLOG(3) << "Got pepper key: " << event->keycode() | 307 VLOG(3) << "Got pepper key: " << event->keycode() |
| 307 << " sending keysym: " << keysym | 308 << " sending keysym: " << keysym |
| 308 << " to keycode: " << keycode; | 309 << " to keycode: " << keycode; |
| 309 XTestFakeKeyEvent(display_, keycode, event->pressed(), CurrentTime); | 310 XTestFakeKeyEvent(display_, keycode, event->pressed(), CurrentTime); |
| 310 XFlush(display_); | 311 XFlush(display_); |
| 311 } | 312 } |
| 312 | 313 |
| 313 void EventExecutorLinux::InjectMouseEvent(const MouseEvent* event, | 314 void EventExecutorLinux::InjectMouseEvent(const MouseEvent* event, |
| 314 Task* done) { | 315 Task* done) { |
| 315 base::ScopedTaskRunner done_runner(done); | 316 media::AutoTaskRunner done_runner(done); |
| 316 | 317 |
| 317 if (MessageLoop::current() != message_loop_) { | 318 if (MessageLoop::current() != message_loop_) { |
| 318 message_loop_->PostTask( | 319 message_loop_->PostTask( |
| 319 FROM_HERE, | 320 FROM_HERE, |
| 320 NewRunnableMethod(this, &EventExecutorLinux::InjectMouseEvent, | 321 NewRunnableMethod(this, &EventExecutorLinux::InjectMouseEvent, |
| 321 event, done_runner.Release())); | 322 event, done_runner.release())); |
| 322 return; | 323 return; |
| 323 } | 324 } |
| 324 | 325 |
| 325 if (event->has_x() && event->has_y()) { | 326 if (event->has_x() && event->has_y()) { |
| 326 if (event->x() < 0 || event->y() < 0 || | 327 if (event->x() < 0 || event->y() < 0 || |
| 327 event->x() > width_ || event->y() > height_) { | 328 event->x() > width_ || event->y() > height_) { |
| 328 // A misbehaving client may send these. Drop events that are out of range. | 329 // A misbehaving client may send these. Drop events that are out of range. |
| 329 // TODO(ajwong): How can we log this sanely? We don't want to DOS the | 330 // TODO(ajwong): How can we log this sanely? We don't want to DOS the |
| 330 // server with a misbehaving client by logging like crazy. | 331 // server with a misbehaving client by logging like crazy. |
| 331 return; | 332 return; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 } // namespace | 364 } // namespace |
| 364 | 365 |
| 365 EventExecutor* EventExecutor::Create(MessageLoop* message_loop, | 366 EventExecutor* EventExecutor::Create(MessageLoop* message_loop, |
| 366 Capturer* capturer) { | 367 Capturer* capturer) { |
| 367 return new EventExecutorLinux(message_loop, capturer); | 368 return new EventExecutorLinux(message_loop, capturer); |
| 368 } | 369 } |
| 369 | 370 |
| 370 } // namespace remoting | 371 } // namespace remoting |
| 371 | 372 |
| 372 DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::EventExecutorLinux); | 373 DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::EventExecutorLinux); |
| OLD | NEW |