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

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

Issue 10909133: Implement clipboard for Chromoting Linux hosts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix nits. Created 8 years, 2 months 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
« no previous file with comments | « remoting/host/clipboard_linux.cc ('k') | remoting/host/linux/x_server_clipboard.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/extensions/XTest.h> 8 #include <X11/extensions/XTest.h>
9 #include <X11/extensions/XInput.h> 9 #include <X11/extensions/XInput.h>
10 10
11 #include <set> 11 #include <set>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
16 #include "base/location.h" 16 #include "base/location.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/single_thread_task_runner.h" 18 #include "base/single_thread_task_runner.h"
19 #include "remoting/host/clipboard.h"
19 #include "remoting/proto/internal.pb.h" 20 #include "remoting/proto/internal.pb.h"
20 #include "third_party/skia/include/core/SkPoint.h" 21 #include "third_party/skia/include/core/SkPoint.h"
21 22
22 namespace remoting { 23 namespace remoting {
23 24
24 namespace { 25 namespace {
25 26
26 using protocol::ClipboardEvent; 27 using protocol::ClipboardEvent;
27 using protocol::KeyEvent; 28 using protocol::KeyEvent;
28 using protocol::MouseEvent; 29 using protocol::MouseEvent;
(...skipping 23 matching lines...) Expand all
52 // EventExecutor interface. 53 // EventExecutor interface.
53 virtual void Start( 54 virtual void Start(
54 scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE; 55 scoped_ptr<protocol::ClipboardStub> client_clipboard) OVERRIDE;
55 virtual void StopAndDelete() OVERRIDE; 56 virtual void StopAndDelete() OVERRIDE;
56 57
57 private: 58 private:
58 // Number of buttons we support. 59 // Number of buttons we support.
59 // Left, Right, Middle, VScroll Up/Down, HScroll Left/Right. 60 // Left, Right, Middle, VScroll Up/Down, HScroll Left/Right.
60 static const int kNumPointerButtons = 7; 61 static const int kNumPointerButtons = 7;
61 62
63 void InitClipboard();
64
62 // |mode| is one of the AutoRepeatModeOn, AutoRepeatModeOff, 65 // |mode| is one of the AutoRepeatModeOn, AutoRepeatModeOff,
63 // AutoRepeatModeDefault constants defined by the XChangeKeyboardControl() 66 // AutoRepeatModeDefault constants defined by the XChangeKeyboardControl()
64 // API. 67 // API.
65 void SetAutoRepeatForKey(int keycode, int mode); 68 void SetAutoRepeatForKey(int keycode, int mode);
66 void InjectScrollWheelClicks(int button, int count); 69 void InjectScrollWheelClicks(int button, int count);
67 // Compensates for global button mappings and resets the XTest device mapping. 70 // Compensates for global button mappings and resets the XTest device mapping.
68 void InitMouseButtonMap(); 71 void InitMouseButtonMap();
69 int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button); 72 int MouseButtonToX11ButtonNumber(MouseEvent::MouseButton button);
70 int HorizontalScrollWheelToX11ButtonNumber(int dx); 73 int HorizontalScrollWheelToX11ButtonNumber(int dx);
71 int VerticalScrollWheelToX11ButtonNumber(int dy); 74 int VerticalScrollWheelToX11ButtonNumber(int dy);
72 75
73 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 76 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
74 77
75 std::set<int> pressed_keys_; 78 std::set<int> pressed_keys_;
76 SkIPoint latest_mouse_position_; 79 SkIPoint latest_mouse_position_;
77 80
78 // X11 graphics context. 81 // X11 graphics context.
79 Display* display_; 82 Display* display_;
80 Window root_window_; 83 Window root_window_;
81 84
82 int test_event_base_; 85 int test_event_base_;
83 int test_error_base_; 86 int test_error_base_;
84 87
85 int pointer_button_map_[kNumPointerButtons]; 88 int pointer_button_map_[kNumPointerButtons];
89
90 scoped_ptr<Clipboard> clipboard_;
91
86 DISALLOW_COPY_AND_ASSIGN(EventExecutorLinux); 92 DISALLOW_COPY_AND_ASSIGN(EventExecutorLinux);
87 }; 93 };
88 94
89 EventExecutorLinux::EventExecutorLinux( 95 EventExecutorLinux::EventExecutorLinux(
90 scoped_refptr<base::SingleThreadTaskRunner> task_runner) 96 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
91 : task_runner_(task_runner), 97 : task_runner_(task_runner),
92 latest_mouse_position_(SkIPoint::Make(-1, -1)), 98 latest_mouse_position_(SkIPoint::Make(-1, -1)),
93 display_(XOpenDisplay(NULL)), 99 display_(XOpenDisplay(NULL)),
94 root_window_(BadValue) { 100 root_window_(BadValue) {
101 if (!task_runner_->BelongsToCurrentThread()) {
102 task_runner_->PostTask(
103 FROM_HERE,
104 base::Bind(&EventExecutorLinux::InitClipboard, base::Unretained(this)));
105 }
95 } 106 }
96 107
97 EventExecutorLinux::~EventExecutorLinux() { 108 EventExecutorLinux::~EventExecutorLinux() {
98 CHECK(pressed_keys_.empty()); 109 CHECK(pressed_keys_.empty());
99 } 110 }
100 111
101 bool EventExecutorLinux::Init() { 112 bool EventExecutorLinux::Init() {
102 CHECK(display_); 113 CHECK(display_);
103 114
104 root_window_ = RootWindow(display_, DefaultScreen(display_)); 115 root_window_ = RootWindow(display_, DefaultScreen(display_));
105 if (root_window_ == BadValue) { 116 if (root_window_ == BadValue) {
106 LOG(ERROR) << "Unable to get the root window"; 117 LOG(ERROR) << "Unable to get the root window";
107 return false; 118 return false;
108 } 119 }
109 120
110 // TODO(ajwong): Do we want to check the major/minor version at all for XTest? 121 // TODO(ajwong): Do we want to check the major/minor version at all for XTest?
111 int major = 0; 122 int major = 0;
112 int minor = 0; 123 int minor = 0;
113 if (!XTestQueryExtension(display_, &test_event_base_, &test_error_base_, 124 if (!XTestQueryExtension(display_, &test_event_base_, &test_error_base_,
114 &major, &minor)) { 125 &major, &minor)) {
115 LOG(ERROR) << "Server does not support XTest."; 126 LOG(ERROR) << "Server does not support XTest.";
116 return false; 127 return false;
117 } 128 }
118 InitMouseButtonMap(); 129 InitMouseButtonMap();
119 return true; 130 return true;
120 } 131 }
121 132
122 void EventExecutorLinux::InjectClipboardEvent(const ClipboardEvent& event) { 133 void EventExecutorLinux::InjectClipboardEvent(const ClipboardEvent& event) {
123 // TODO(simonmorris): Implement clipboard injection. 134 if (!task_runner_->BelongsToCurrentThread()) {
135 task_runner_->PostTask(
136 FROM_HERE,
137 base::Bind(&EventExecutorLinux::InjectClipboardEvent,
138 base::Unretained(this), event));
139 return;
140 }
141
142 clipboard_->InjectClipboardEvent(event);
124 } 143 }
125 144
126 void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) { 145 void EventExecutorLinux::InjectKeyEvent(const KeyEvent& event) {
127 // HostEventDispatcher should filter events missing the pressed field. 146 // HostEventDispatcher should filter events missing the pressed field.
128 DCHECK(event.has_pressed()); 147 DCHECK(event.has_pressed());
129 DCHECK(event.has_usb_keycode()); 148 DCHECK(event.has_usb_keycode());
130 149
131 if (!task_runner_->BelongsToCurrentThread()) { 150 if (!task_runner_->BelongsToCurrentThread()) {
132 task_runner_->PostTask( 151 task_runner_->PostTask(
133 FROM_HERE, 152 FROM_HERE,
(...skipping 29 matching lines...) Expand all
163 // case, this ensures that key-repeating will continue to work normally 182 // case, this ensures that key-repeating will continue to work normally
164 // for the local user of the host machine. "ModeDefault" is used instead 183 // for the local user of the host machine. "ModeDefault" is used instead
165 // of "ModeOn", since some keys (such as Shift) should not auto-repeat. 184 // of "ModeOn", since some keys (such as Shift) should not auto-repeat.
166 SetAutoRepeatForKey(keycode, AutoRepeatModeDefault); 185 SetAutoRepeatForKey(keycode, AutoRepeatModeDefault);
167 } 186 }
168 187
169 XTestFakeKeyEvent(display_, keycode, event.pressed(), CurrentTime); 188 XTestFakeKeyEvent(display_, keycode, event.pressed(), CurrentTime);
170 XFlush(display_); 189 XFlush(display_);
171 } 190 }
172 191
192 void EventExecutorLinux::InitClipboard() {
193 DCHECK(task_runner_->BelongsToCurrentThread());
194 clipboard_ = Clipboard::Create();
195 }
196
173 void EventExecutorLinux::SetAutoRepeatForKey(int keycode, int mode) { 197 void EventExecutorLinux::SetAutoRepeatForKey(int keycode, int mode) {
174 XKeyboardControl control; 198 XKeyboardControl control;
175 control.key = keycode; 199 control.key = keycode;
176 control.auto_repeat_mode = mode; 200 control.auto_repeat_mode = mode;
177 XChangeKeyboardControl(display_, KBKey | KBAutoRepeatMode, &control); 201 XChangeKeyboardControl(display_, KBKey | KBAutoRepeatMode, &control);
178 } 202 }
179 203
180 void EventExecutorLinux::InjectScrollWheelClicks(int button, int count) { 204 void EventExecutorLinux::InjectScrollWheelClicks(int button, int count) {
181 if (button < 0) { 205 if (button < 0) {
182 LOG(WARNING) << "Ignoring unmapped scroll wheel button"; 206 LOG(WARNING) << "Ignoring unmapped scroll wheel button";
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 void EventExecutorLinux::Start( 378 void EventExecutorLinux::Start(
355 scoped_ptr<protocol::ClipboardStub> client_clipboard) { 379 scoped_ptr<protocol::ClipboardStub> client_clipboard) {
356 if (!task_runner_->BelongsToCurrentThread()) { 380 if (!task_runner_->BelongsToCurrentThread()) {
357 task_runner_->PostTask( 381 task_runner_->PostTask(
358 FROM_HERE, 382 FROM_HERE,
359 base::Bind(&EventExecutorLinux::Start, 383 base::Bind(&EventExecutorLinux::Start,
360 base::Unretained(this), 384 base::Unretained(this),
361 base::Passed(&client_clipboard))); 385 base::Passed(&client_clipboard)));
362 return; 386 return;
363 } 387 }
388
364 InitMouseButtonMap(); 389 InitMouseButtonMap();
365 return; 390 clipboard_->Start(client_clipboard.Pass());
366 } 391 }
367 392
368 void EventExecutorLinux::StopAndDelete() { 393 void EventExecutorLinux::StopAndDelete() {
369 delete this; 394 delete this;
370 } 395 }
371 396
372 } // namespace 397 } // namespace
373 398
374 scoped_ptr<EventExecutor> EventExecutor::Create( 399 scoped_ptr<EventExecutor> EventExecutor::Create(
375 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 400 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
376 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { 401 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
377 scoped_ptr<EventExecutorLinux> executor( 402 scoped_ptr<EventExecutorLinux> executor(
378 new EventExecutorLinux(main_task_runner)); 403 new EventExecutorLinux(main_task_runner));
379 if (!executor->Init()) 404 if (!executor->Init())
380 return scoped_ptr<EventExecutor>(NULL); 405 return scoped_ptr<EventExecutor>(NULL);
381 return executor.PassAs<EventExecutor>(); 406 return executor.PassAs<EventExecutor>();
382 } 407 }
383 408
384 } // namespace remoting 409 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/clipboard_linux.cc ('k') | remoting/host/linux/x_server_clipboard.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698