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 |