Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: remoting/host/event_executor_linux.cc

Issue 4726003: Implement InputStub in the host side for chromoting (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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_linux.h" 5 #include "remoting/host/event_executor_linux.h"
6 6
7 #include <X11/Xlib.h> 7 #include <X11/Xlib.h>
8 #include <X11/keysym.h> 8 #include <X11/keysym.h>
9 #include <X11/extensions/XTest.h> 9 #include <X11/extensions/XTest.h>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop.h"
13 #include "base/task.h"
12 #include "remoting/proto/internal.pb.h" 14 #include "remoting/proto/internal.pb.h"
13 15
14 namespace remoting { 16 namespace remoting {
15 17
16 static int MouseButtonToX11ButtonNumber(MouseButton button) { 18 static int MouseButtonToX11ButtonNumber(MouseButton button) {
17 switch (button) { 19 switch (button) {
18 case MouseButtonLeft: 20 case MouseButtonLeft:
19 return 1; 21 return 1;
20 22
21 case MouseButtonRight: 23 case MouseButtonRight:
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 195
194 return kPepperToX11Keysym[keycode]; 196 return kPepperToX11Keysym[keycode];
195 } 197 }
196 198
197 class EventExecutorLinuxPimpl { 199 class EventExecutorLinuxPimpl {
198 public: 200 public:
199 explicit EventExecutorLinuxPimpl(EventExecutorLinux* executor); 201 explicit EventExecutorLinuxPimpl(EventExecutorLinux* executor);
200 ~EventExecutorLinuxPimpl(); 202 ~EventExecutorLinuxPimpl();
201 203
202 bool Init(); // TODO(ajwong): Do we really want this to be synchronous? 204 bool Init(); // TODO(ajwong): Do we really want this to be synchronous?
203 205 void HandleMouse(const MouseEvent* message);
204 void HandleInputEvent(ChromotingClientMessage* message); 206 void HandleKey(const KeyEvent* key_event);
205 207
206 private: 208 private:
207 void HandleMouseSetPosition(const MouseSetPositionEvent& position_event); 209 void HandleMouseSetPosition(const MouseSetPositionEvent& position_event);
208 void HandleMouseMove(const MouseMoveEvent& move_event); 210 void HandleMouseMove(const MouseMoveEvent& move_event);
209 void HandleMouseWheel(const MouseWheelEvent& wheel_event); 211 void HandleMouseWheel(const MouseWheelEvent& wheel_event);
210 void HandleMouseButtonDown(const MouseDownEvent& mouse_down_event); 212 void HandleMouseButtonDown(const MouseDownEvent& mouse_down_event);
211 void HandleMouseButtonUp(const MouseUpEvent& mouse_up_event); 213 void HandleMouseButtonUp(const MouseUpEvent& mouse_up_event);
212 void HandleKey(const KeyEvent& key_event);
213 void DeinitXlib(); 214 void DeinitXlib();
214 215
215 // Reference to containing class so we can access friend functions. 216 // Reference to containing class so we can access friend functions.
216 // Not owned. 217 // Not owned.
217 EventExecutorLinux* executor_; 218 EventExecutorLinux* executor_;
218 219
219 // X11 graphics context. 220 // X11 graphics context.
220 Display* display_; 221 Display* display_;
221 GC gc_; 222 GC gc_;
222 Window root_window_; 223 Window root_window_;
223 int width_; 224 int width_;
224 int height_; 225 int height_;
225 226
226 int test_event_base_; 227 int test_event_base_;
227 int test_error_base_; 228 int test_error_base_;
228 }; 229 };
229 230
230 EventExecutorLinux::EventExecutorLinux(Capturer* capturer)
231 : EventExecutor(capturer),
232 pimpl_(new EventExecutorLinuxPimpl(this)) {
233 CHECK(pimpl_->Init());
234 }
235
236 EventExecutorLinux::~EventExecutorLinux() {
237 }
238
239 void EventExecutorLinux::HandleInputEvent(ChromotingClientMessage* message) {
240 pimpl_->HandleInputEvent(message);
241 }
242
243 EventExecutorLinuxPimpl::EventExecutorLinuxPimpl(EventExecutorLinux* executor) 231 EventExecutorLinuxPimpl::EventExecutorLinuxPimpl(EventExecutorLinux* executor)
244 : executor_(executor), 232 : executor_(executor),
245 display_(NULL), 233 display_(NULL),
246 gc_(NULL), 234 gc_(NULL),
247 root_window_(BadValue), 235 root_window_(BadValue),
248 width_(0), 236 width_(0),
249 height_(0) { 237 height_(0) {
250 } 238 }
251 239
252 EventExecutorLinuxPimpl::~EventExecutorLinuxPimpl() { 240 EventExecutorLinuxPimpl::~EventExecutorLinuxPimpl() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 DeinitXlib(); 283 DeinitXlib();
296 return false; 284 return false;
297 } 285 }
298 286
299 width_ = root_attr.width; 287 width_ = root_attr.width;
300 height_ = root_attr.height; 288 height_ = root_attr.height;
301 289
302 return true; 290 return true;
303 } 291 }
304 292
305 void EventExecutorLinuxPimpl::HandleInputEvent( 293 void EventExecutorLinuxPimpl::HandleMouse(
306 ChromotingClientMessage* message) { 294 const MouseEvent* mouse_event) {
307 if (message->has_mouse_set_position_event()) { 295 if (mouse_event->has_set_position()) {
308 HandleMouseSetPosition(message->mouse_set_position_event()); 296 HandleMouseSetPosition(mouse_event->set_position());
309 } else if (message->has_mouse_move_event()) { 297 } else if (mouse_event->has_wheel()) {
310 HandleMouseMove(message->mouse_move_event()); 298 HandleMouseWheel(mouse_event->wheel());
311 } else if (message->has_mouse_wheel_event()) { 299 } else if (mouse_event->has_down()) {
312 HandleMouseWheel(message->mouse_wheel_event()); 300 HandleMouseButtonDown(mouse_event->down());
313 } else if (message->has_mouse_down_event()) { 301 } else if (mouse_event->has_up()) {
314 HandleMouseButtonDown(message->mouse_down_event()); 302 HandleMouseButtonUp(mouse_event->up());
315 } else if (message->has_mouse_up_event()) {
316 HandleMouseButtonUp(message->mouse_up_event());
317 } else if (message->has_key_event()) {
318 HandleKey(message->key_event());
319 } 303 }
320 delete message;
321 } 304 }
322 305
323 void EventExecutorLinuxPimpl::HandleMouseSetPosition( 306 void EventExecutorLinuxPimpl::HandleMouseSetPosition(
324 const MouseSetPositionEvent& position_event) { 307 const MouseSetPositionEvent& position_event) {
325 if (position_event.x() < 0 || position_event.y() < 0 || 308 if (position_event.x() < 0 || position_event.y() < 0 ||
326 position_event.x() > width_ || position_event.y() > height_) { 309 position_event.x() > width_ || position_event.y() > height_) {
327 // A misbehaving client may send these. Drop events that are out of range. 310 // A misbehaving client may send these. Drop events that are out of range.
328 // TODO(ajwong): How can we log this sanely? We don't want to DOS the server 311 // TODO(ajwong): How can we log this sanely? We don't want to DOS the server
329 // with a misbehaving client by logging like crazy. 312 // with a misbehaving client by logging like crazy.
330 return; 313 return;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 LOG(WARNING) << "Ignoring unknown button type: " 352 LOG(WARNING) << "Ignoring unknown button type: "
370 << mouse_up_event.button(); 353 << mouse_up_event.button();
371 return; 354 return;
372 } 355 }
373 356
374 VLOG(3) << "Button " << mouse_up_event.button() 357 VLOG(3) << "Button " << mouse_up_event.button()
375 << " received, sending up " << button_number; 358 << " received, sending up " << button_number;
376 XTestFakeButtonEvent(display_, button_number, False, CurrentTime); 359 XTestFakeButtonEvent(display_, button_number, False, CurrentTime);
377 } 360 }
378 361
379 void EventExecutorLinuxPimpl::HandleKey(const KeyEvent& key_event) { 362 void EventExecutorLinuxPimpl::HandleKey(const KeyEvent* key_event) {
380 // TODO(ajwong): This will only work for QWERTY keyboards. 363 // TODO(ajwong): This will only work for QWERTY keyboards.
381 int keysym = ChromotocolKeycodeToX11Keysym(key_event.key()); 364 int keysym = ChromotocolKeycodeToX11Keysym(key_event->key());
382 365
383 if (keysym == -1) { 366 if (keysym == -1) {
384 LOG(WARNING) << "Ignoring unknown key: " << key_event.key(); 367 LOG(WARNING) << "Ignoring unknown key: " << key_event->key();
385 return; 368 return;
386 } 369 }
387 370
388 // Translate the keysym into a keycode understandable by the X display. 371 // Translate the keysym into a keycode understandable by the X display.
389 int keycode = XKeysymToKeycode(display_, keysym); 372 int keycode = XKeysymToKeycode(display_, keysym);
390 if (keycode == 0) { 373 if (keycode == 0) {
391 LOG(WARNING) << "Ignoring undefined keysym: " << keysym 374 LOG(WARNING) << "Ignoring undefined keysym: " << keysym
392 << " for key: " << key_event.key(); 375 << " for key: " << key_event->key();
393 return; 376 return;
394 } 377 }
395 378
396 VLOG(3) << "Got pepper key: " << key_event.key() 379 VLOG(3) << "Got pepper key: " << key_event->key()
397 << " sending keysym: " << keysym 380 << " sending keysym: " << keysym
398 << " to keycode: " << keycode; 381 << " to keycode: " << keycode;
399 XTestFakeKeyEvent(display_, keycode, key_event.pressed(), CurrentTime); 382 XTestFakeKeyEvent(display_, keycode, key_event->pressed(), CurrentTime);
400 } 383 }
401 384
402 void EventExecutorLinuxPimpl::DeinitXlib() { 385 void EventExecutorLinuxPimpl::DeinitXlib() {
403 // TODO(ajwong): We should expose a "close" or "shutdown" method. 386 // TODO(ajwong): We should expose a "close" or "shutdown" method.
404 if (gc_) { 387 if (gc_) {
405 if (!XFreeGC(display_, gc_)) { 388 if (!XFreeGC(display_, gc_)) {
406 LOG(ERROR) << "Unable to free Xlib GC"; 389 LOG(ERROR) << "Unable to free Xlib GC";
407 } 390 }
408 gc_ = NULL; 391 gc_ = NULL;
409 } 392 }
410 393
411 if (display_) { 394 if (display_) {
412 if (!XCloseDisplay(display_)) { 395 if (!XCloseDisplay(display_)) {
413 LOG(ERROR) << "Unable to close the Xlib Display."; 396 LOG(ERROR) << "Unable to close the Xlib Display.";
414 } 397 }
415 display_ = NULL; 398 display_ = NULL;
416 } 399 }
417 } 400 }
418 401
402 EventExecutorLinux::EventExecutorLinux(
403 MessageLoop* message_loop, Capturer* capturer)
404 : message_loop_(message_loop),
405 capturer_(capturer),
406 pimpl_(new EventExecutorLinuxPimpl(this)) {
407 CHECK(pimpl_->Init());
408 }
409
410 EventExecutorLinux::~EventExecutorLinux() {
411 }
412
413 void EventExecutorLinux::InjectKeyEvent(const KeyEvent* event, Task* done) {
414 if (MessageLoop::current() != message_loop_) {
415 message_loop_->PostTask(
416 FROM_HERE,
417 NewRunnableMethod(this, &EventExecutorLinux::InjectKeyEvent,
418 event, done));
419 return;
420 }
421 pimpl_->HandleKey(event);
422 done->Run();
423 delete done;
424 }
425
426 void EventExecutorLinux::InjectMouseEvent(const MouseEvent* event,
427 Task* done) {
428 if (MessageLoop::current() != message_loop_) {
429 message_loop_->PostTask(
430 FROM_HERE,
431 NewRunnableMethod(this, &EventExecutorLinux::InjectMouseEvent,
432 event, done));
433 return;
434 }
435 pimpl_->HandleMouse(event);
436 done->Run();
437 delete done;
438 }
439
419 } // namespace remoting 440 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698