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 |