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

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

Issue 12594009: Converted LocalInputMonitor into a SessionController instance. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 7 years, 9 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/local_input_monitor.h ('k') | remoting/host/local_input_monitor_mac.mm » ('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/local_input_monitor.h" 5 #include "remoting/host/local_input_monitor.h"
6 6
7 #include <sys/select.h> 7 #include <sys/select.h>
8 #include <unistd.h> 8 #include <unistd.h>
9 #define XK_MISCELLANY 9 #define XK_MISCELLANY
10 #include <X11/keysymdef.h> 10 #include <X11/keysymdef.h>
11 11
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback.h" 14 #include "base/callback.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/message_loop.h" 18 #include "base/message_loop.h"
19 #include "base/message_pump_libevent.h" 19 #include "base/message_pump_libevent.h"
20 #include "base/posix/eintr_wrapper.h" 20 #include "base/posix/eintr_wrapper.h"
21 #include "base/single_thread_task_runner.h" 21 #include "base/single_thread_task_runner.h"
22 #include "remoting/host/mouse_move_observer.h" 22 #include "base/threading/non_thread_safe.h"
23 #include "remoting/host/client_session_control.h"
23 #include "third_party/skia/include/core/SkPoint.h" 24 #include "third_party/skia/include/core/SkPoint.h"
24 25
25 // These includes need to be later than dictated by the style guide due to 26 // These includes need to be later than dictated by the style guide due to
26 // Xlib header pollution, specifically the min, max, and Status macros. 27 // Xlib header pollution, specifically the min, max, and Status macros.
27 #include <X11/XKBlib.h> 28 #include <X11/XKBlib.h>
28 #include <X11/Xlibint.h> 29 #include <X11/Xlibint.h>
29 #include <X11/extensions/record.h> 30 #include <X11/extensions/record.h>
30 31
31 namespace remoting { 32 namespace remoting {
32 33
33 namespace { 34 namespace {
34 35
35 class LocalInputMonitorLinux : public LocalInputMonitor { 36 class LocalInputMonitorLinux : public base::NonThreadSafe,
37 public LocalInputMonitor {
36 public: 38 public:
37 LocalInputMonitorLinux( 39 LocalInputMonitorLinux(
38 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 40 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
39 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner); 41 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
42 base::WeakPtr<ClientSessionControl> client_session_control);
40 virtual ~LocalInputMonitorLinux(); 43 virtual ~LocalInputMonitorLinux();
41 44
42 virtual void Start(MouseMoveObserver* mouse_move_observer,
43 const base::Closure& disconnect_callback) OVERRIDE;
44 virtual void Stop() OVERRIDE;
45
46 private: 45 private:
47 // The actual implementation resides in LocalInputMonitorLinux::Core class. 46 // The actual implementation resides in LocalInputMonitorLinux::Core class.
48 class Core 47 class Core
49 : public base::RefCountedThreadSafe<Core>, 48 : public base::RefCountedThreadSafe<Core>,
50 public base::MessagePumpLibevent::Watcher { 49 public base::MessagePumpLibevent::Watcher {
51 public: 50 public:
52 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 51 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
53 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner); 52 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
53 base::WeakPtr<ClientSessionControl> client_session_control);
54 54
55 void Start(MouseMoveObserver* mouse_move_observer, 55 void Start();
56 const base::Closure& disconnect_callback);
57 void Stop(); 56 void Stop();
58 57
59 private: 58 private:
60 friend class base::RefCountedThreadSafe<Core>; 59 friend class base::RefCountedThreadSafe<Core>;
61 virtual ~Core(); 60 virtual ~Core();
62 61
63 void StartOnInputThread(); 62 void StartOnInputThread();
64 void StopOnInputThread(); 63 void StopOnInputThread();
65 64
66 // base::MessagePumpLibevent::Watcher interface. 65 // base::MessagePumpLibevent::Watcher interface.
67 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; 66 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
68 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; 67 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
69 68
70 // Posts OnLocalMouseMoved() notification to |mouse_move_observer_| on
71 // the |caller_task_runner_| thread.
72 void OnLocalMouseMoved(const SkIPoint& position);
73
74 // Posts |disconnect_callback_| on the |caller_task_runner_| thread.
75 void OnDisconnectShortcut();
76
77 // Processes key and mouse events. 69 // Processes key and mouse events.
78 void ProcessXEvent(xEvent* event); 70 void ProcessXEvent(xEvent* event);
79 71
80 static void ProcessReply(XPointer self, XRecordInterceptData* data); 72 static void ProcessReply(XPointer self, XRecordInterceptData* data);
81 73
82 // Task runner on which public methods of this class must be called. 74 // Task runner on which public methods of this class must be called.
83 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 75 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
84 76
85 // Task runner on which X Window events are received. 77 // Task runner on which X Window events are received.
86 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; 78 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
87 79
88 // Invoked in the |caller_task_runner_| thread to report local mouse events. 80 // Points to the object receiving mouse event notifications and session
89 MouseMoveObserver* mouse_move_observer_; 81 // disconnect requests.
90 82 base::WeakPtr<ClientSessionControl> client_session_control_;
91 // Posted to the |caller_task_runner_| thread every time the disconnect key
92 // combination is pressed.
93 base::Closure disconnect_callback_;
94 83
95 // Used to receive base::MessagePumpLibevent::Watcher events. 84 // Used to receive base::MessagePumpLibevent::Watcher events.
96 base::MessagePumpLibevent::FileDescriptorWatcher controller_; 85 base::MessagePumpLibevent::FileDescriptorWatcher controller_;
97 86
98 // True when Alt is pressed. 87 // True when Alt is pressed.
99 bool alt_pressed_; 88 bool alt_pressed_;
100 89
101 // True when Ctrl is pressed. 90 // True when Ctrl is pressed.
102 bool ctrl_pressed_; 91 bool ctrl_pressed_;
103 92
104 Display* display_; 93 Display* display_;
105 Display* x_record_display_; 94 Display* x_record_display_;
106 XRecordRange* x_record_range_[2]; 95 XRecordRange* x_record_range_[2];
107 XRecordContext x_record_context_; 96 XRecordContext x_record_context_;
108 97
109 DISALLOW_COPY_AND_ASSIGN(Core); 98 DISALLOW_COPY_AND_ASSIGN(Core);
110 }; 99 };
111 100
112 scoped_refptr<Core> core_; 101 scoped_refptr<Core> core_;
113 102
114 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorLinux); 103 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorLinux);
115 }; 104 };
116 105
117 LocalInputMonitorLinux::LocalInputMonitorLinux( 106 LocalInputMonitorLinux::LocalInputMonitorLinux(
118 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 107 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
119 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner) 108 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
120 : core_(new Core(caller_task_runner, input_task_runner)) { 109 base::WeakPtr<ClientSessionControl> client_session_control)
110 : core_(new Core(caller_task_runner,
111 input_task_runner,
112 client_session_control)) {
113 core_->Start();
121 } 114 }
122 115
123 LocalInputMonitorLinux::~LocalInputMonitorLinux() { 116 LocalInputMonitorLinux::~LocalInputMonitorLinux() {
124 }
125
126 void LocalInputMonitorLinux::Start(
127 MouseMoveObserver* mouse_move_observer,
128 const base::Closure& disconnect_callback) {
129 core_->Start(mouse_move_observer, disconnect_callback);
130 }
131
132 void LocalInputMonitorLinux::Stop() {
133 core_->Stop(); 117 core_->Stop();
134 } 118 }
135 119
136 LocalInputMonitorLinux::Core::Core( 120 LocalInputMonitorLinux::Core::Core(
137 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 121 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
138 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner) 122 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
123 base::WeakPtr<ClientSessionControl> client_session_control)
139 : caller_task_runner_(caller_task_runner), 124 : caller_task_runner_(caller_task_runner),
140 input_task_runner_(input_task_runner), 125 input_task_runner_(input_task_runner),
141 mouse_move_observer_(NULL), 126 client_session_control_(client_session_control),
142 alt_pressed_(false), 127 alt_pressed_(false),
143 ctrl_pressed_(false), 128 ctrl_pressed_(false),
144 display_(NULL), 129 display_(NULL),
145 x_record_display_(NULL), 130 x_record_display_(NULL),
146 x_record_context_(0) { 131 x_record_context_(0) {
147 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 132 DCHECK(caller_task_runner_->BelongsToCurrentThread());
133 DCHECK(client_session_control_);
148 134
149 x_record_range_[0] = NULL; 135 x_record_range_[0] = NULL;
150 x_record_range_[1] = NULL; 136 x_record_range_[1] = NULL;
151 } 137 }
152 138
153 void LocalInputMonitorLinux::Core::Start( 139 void LocalInputMonitorLinux::Core::Start() {
154 MouseMoveObserver* mouse_move_observer,
155 const base::Closure& disconnect_callback) {
156 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 140 DCHECK(caller_task_runner_->BelongsToCurrentThread());
157 DCHECK(disconnect_callback_.is_null());
158 DCHECK(!disconnect_callback.is_null());
159 DCHECK(!mouse_move_observer_);
160 DCHECK(mouse_move_observer);
161 141
162 disconnect_callback_ = disconnect_callback;
163 mouse_move_observer_ = mouse_move_observer;
164 input_task_runner_->PostTask(FROM_HERE, 142 input_task_runner_->PostTask(FROM_HERE,
165 base::Bind(&Core::StartOnInputThread, this)); 143 base::Bind(&Core::StartOnInputThread, this));
166 } 144 }
167 145
168 void LocalInputMonitorLinux::Core::Stop() { 146 void LocalInputMonitorLinux::Core::Stop() {
169 DCHECK(caller_task_runner_->BelongsToCurrentThread()); 147 DCHECK(caller_task_runner_->BelongsToCurrentThread());
170 148
171 disconnect_callback_.Reset();
172 mouse_move_observer_ = NULL;
173 input_task_runner_->PostTask(FROM_HERE, 149 input_task_runner_->PostTask(FROM_HERE,
174 base::Bind(&Core::StopOnInputThread, this)); 150 base::Bind(&Core::StopOnInputThread, this));
175 } 151 }
176 152
177 LocalInputMonitorLinux::Core::~Core() { 153 LocalInputMonitorLinux::Core::~Core() {
178 DCHECK(disconnect_callback_.is_null());
179 DCHECK(!mouse_move_observer_);
180 DCHECK(!display_); 154 DCHECK(!display_);
181 DCHECK(!x_record_display_); 155 DCHECK(!x_record_display_);
182 DCHECK(!x_record_range_[0]); 156 DCHECK(!x_record_range_[0]);
183 DCHECK(!x_record_range_[1]); 157 DCHECK(!x_record_range_[1]);
184 DCHECK(!x_record_context_); 158 DCHECK(!x_record_context_);
185 } 159 }
186 160
187 void LocalInputMonitorLinux::Core::StartOnInputThread() { 161 void LocalInputMonitorLinux::Core::StartOnInputThread() {
188 DCHECK(input_task_runner_->BelongsToCurrentThread()); 162 DCHECK(input_task_runner_->BelongsToCurrentThread());
189 DCHECK(!display_); 163 DCHECK(!display_);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 while (XPending(x_record_display_)) { 270 while (XPending(x_record_display_)) {
297 XEvent ev; 271 XEvent ev;
298 XNextEvent(x_record_display_, &ev); 272 XNextEvent(x_record_display_, &ev);
299 } 273 }
300 } 274 }
301 275
302 void LocalInputMonitorLinux::Core::OnFileCanWriteWithoutBlocking(int fd) { 276 void LocalInputMonitorLinux::Core::OnFileCanWriteWithoutBlocking(int fd) {
303 NOTREACHED(); 277 NOTREACHED();
304 } 278 }
305 279
306 void LocalInputMonitorLinux::Core::OnLocalMouseMoved(const SkIPoint& position) {
307 if (!caller_task_runner_->BelongsToCurrentThread()) {
308 caller_task_runner_->PostTask(
309 FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position));
310 return;
311 }
312
313 if (mouse_move_observer_)
314 mouse_move_observer_->OnLocalMouseMoved(position);
315 }
316
317 void LocalInputMonitorLinux::Core::OnDisconnectShortcut() {
318 if (!caller_task_runner_->BelongsToCurrentThread()) {
319 caller_task_runner_->PostTask(
320 FROM_HERE, base::Bind(&Core::OnDisconnectShortcut, this));
321 return;
322 }
323
324 if (!disconnect_callback_.is_null())
325 disconnect_callback_.Run();
326 }
327
328 void LocalInputMonitorLinux::Core::ProcessXEvent(xEvent* event) { 280 void LocalInputMonitorLinux::Core::ProcessXEvent(xEvent* event) {
329 DCHECK(input_task_runner_->BelongsToCurrentThread()); 281 DCHECK(input_task_runner_->BelongsToCurrentThread());
330 282
331 if (event->u.u.type == MotionNotify) { 283 if (event->u.u.type == MotionNotify) {
332 SkIPoint position(SkIPoint::Make(event->u.keyButtonPointer.rootX, 284 SkIPoint position(SkIPoint::Make(event->u.keyButtonPointer.rootX,
333 event->u.keyButtonPointer.rootY)); 285 event->u.keyButtonPointer.rootY));
334 OnLocalMouseMoved(position); 286 caller_task_runner_->PostTask(
287 FROM_HERE, base::Bind(&ClientSessionControl::OnLocalMouseMoved,
288 client_session_control_,
289 position));
335 } else { 290 } else {
336 int key_code = event->u.u.detail; 291 int key_code = event->u.u.detail;
337 bool down = event->u.u.type == KeyPress; 292 bool down = event->u.u.type == KeyPress;
338 KeySym key_sym = XkbKeycodeToKeysym(display_, key_code, 0, 0); 293 KeySym key_sym = XkbKeycodeToKeysym(display_, key_code, 0, 0);
339 if (key_sym == XK_Control_L || key_sym == XK_Control_R) { 294 if (key_sym == XK_Control_L || key_sym == XK_Control_R) {
340 ctrl_pressed_ = down; 295 ctrl_pressed_ = down;
341 } else if (key_sym == XK_Alt_L || key_sym == XK_Alt_R) { 296 } else if (key_sym == XK_Alt_L || key_sym == XK_Alt_R) {
342 alt_pressed_ = down; 297 alt_pressed_ = down;
343 } else if (key_sym == XK_Escape && down && alt_pressed_ && ctrl_pressed_) { 298 } else if (key_sym == XK_Escape && down && alt_pressed_ && ctrl_pressed_) {
344 OnDisconnectShortcut(); 299 caller_task_runner_->PostTask(
300 FROM_HERE, base::Bind(&ClientSessionControl::DisconnectSession,
301 client_session_control_));
345 } 302 }
346 } 303 }
347 } 304 }
348 305
349 // static 306 // static
350 void LocalInputMonitorLinux::Core::ProcessReply(XPointer self, 307 void LocalInputMonitorLinux::Core::ProcessReply(XPointer self,
351 XRecordInterceptData* data) { 308 XRecordInterceptData* data) {
352 if (data->category == XRecordFromServer) { 309 if (data->category == XRecordFromServer) {
353 xEvent* event = reinterpret_cast<xEvent*>(data->data); 310 xEvent* event = reinterpret_cast<xEvent*>(data->data);
354 reinterpret_cast<Core*>(self)->ProcessXEvent(event); 311 reinterpret_cast<Core*>(self)->ProcessXEvent(event);
355 } 312 }
356 XRecordFreeData(data); 313 XRecordFreeData(data);
357 } 314 }
358 315
359 } // namespace 316 } // namespace
360 317
361 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create( 318 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create(
362 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 319 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
363 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, 320 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
364 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { 321 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
322 base::WeakPtr<ClientSessionControl> client_session_control) {
365 return scoped_ptr<LocalInputMonitor>( 323 return scoped_ptr<LocalInputMonitor>(
366 new LocalInputMonitorLinux(caller_task_runner, input_task_runner)); 324 new LocalInputMonitorLinux(caller_task_runner,
325 input_task_runner,
326 client_session_control));
367 } 327 }
368 328
369 } // namespace remoting 329 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/local_input_monitor.h ('k') | remoting/host/local_input_monitor_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698