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