OLD | NEW |
---|---|
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 "third_party/skia/include/core/SkPoint.h" | 23 #include "third_party/skia/include/core/SkPoint.h" |
24 | 24 |
25 // These includes need to be later than dictated by the style guide due to | 25 // 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. | 26 // Xlib header pollution, specifically the min, max, and Status macros. |
27 #include <X11/XKBlib.h> | 27 #include <X11/XKBlib.h> |
28 #include <X11/Xlibint.h> | 28 #include <X11/Xlibint.h> |
29 #include <X11/extensions/record.h> | 29 #include <X11/extensions/record.h> |
30 | 30 |
31 namespace remoting { | 31 namespace remoting { |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 class LocalInputMonitorLinux : public LocalInputMonitor { | 35 class LocalInputMonitorLinux : public base::NonThreadSafe, |
36 public LocalInputMonitor { | |
36 public: | 37 public: |
37 LocalInputMonitorLinux( | 38 LocalInputMonitorLinux( |
38 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 39 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
39 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner); | 40 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
41 SessionController::Delegate* delegate); | |
40 virtual ~LocalInputMonitorLinux(); | 42 virtual ~LocalInputMonitorLinux(); |
41 | 43 |
42 virtual void Start(MouseMoveObserver* mouse_move_observer, | |
43 const base::Closure& disconnect_callback) OVERRIDE; | |
44 virtual void Stop() OVERRIDE; | |
45 | |
46 private: | 44 private: |
47 // The actual implementation resides in LocalInputMonitorLinux::Core class. | 45 // The actual implementation resides in LocalInputMonitorLinux::Core class. |
48 class Core | 46 class Core |
49 : public base::RefCountedThreadSafe<Core>, | 47 : public base::RefCountedThreadSafe<Core>, |
50 public base::MessagePumpLibevent::Watcher { | 48 public base::MessagePumpLibevent::Watcher { |
51 public: | 49 public: |
52 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 50 Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
53 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner); | 51 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
52 SessionController::Delegate* delegate); | |
54 | 53 |
55 void Start(MouseMoveObserver* mouse_move_observer, | 54 void Start(); |
56 const base::Closure& disconnect_callback); | |
57 void Stop(); | 55 void Stop(); |
58 | 56 |
59 private: | 57 private: |
60 friend class base::RefCountedThreadSafe<Core>; | 58 friend class base::RefCountedThreadSafe<Core>; |
61 virtual ~Core(); | 59 virtual ~Core(); |
62 | 60 |
63 void StartOnInputThread(); | 61 void StartOnInputThread(); |
64 void StopOnInputThread(); | 62 void StopOnInputThread(); |
65 | 63 |
66 // base::MessagePumpLibevent::Watcher interface. | 64 // base::MessagePumpLibevent::Watcher interface. |
67 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; | 65 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; |
68 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; | 66 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; |
69 | 67 |
70 // Posts OnLocalMouseMoved() notification to |mouse_move_observer_| on | 68 // Posts OnLocalMouseMoved() notification to |delegate_| on |
71 // the |caller_task_runner_| thread. | 69 // the |caller_task_runner_| thread. |
72 void OnLocalMouseMoved(const SkIPoint& position); | 70 void OnLocalMouseMoved(const SkIPoint& position); |
73 | 71 |
74 // Posts |disconnect_callback_| on the |caller_task_runner_| thread. | 72 // Posts DisconnectSession() call to |delegate_ on the |caller_task_runner_| |
Sergey Ulanov
2013/03/20 06:31:06
nit: missing |
alexeypa (please no reviews)
2013/03/20 17:05:29
Done.
| |
73 // thread. | |
75 void OnDisconnectShortcut(); | 74 void OnDisconnectShortcut(); |
76 | 75 |
77 // Processes key and mouse events. | 76 // Processes key and mouse events. |
78 void ProcessXEvent(xEvent* event); | 77 void ProcessXEvent(xEvent* event); |
79 | 78 |
80 static void ProcessReply(XPointer self, XRecordInterceptData* data); | 79 static void ProcessReply(XPointer self, XRecordInterceptData* data); |
81 | 80 |
82 // Task runner on which public methods of this class must be called. | 81 // Task runner on which public methods of this class must be called. |
83 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; | 82 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; |
84 | 83 |
85 // Task runner on which X Window events are received. | 84 // Task runner on which X Window events are received. |
86 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; | 85 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; |
87 | 86 |
88 // Invoked in the |caller_task_runner_| thread to report local mouse events. | 87 // Points to the object receiving mouse event notifications and session |
89 MouseMoveObserver* mouse_move_observer_; | 88 // disconnect requests. |
90 | 89 SessionController::Delegate* delegate_; |
91 // Posted to the |caller_task_runner_| thread every time the disconnect key | |
92 // combination is pressed. | |
93 base::Closure disconnect_callback_; | |
94 | 90 |
95 // Used to receive base::MessagePumpLibevent::Watcher events. | 91 // Used to receive base::MessagePumpLibevent::Watcher events. |
96 base::MessagePumpLibevent::FileDescriptorWatcher controller_; | 92 base::MessagePumpLibevent::FileDescriptorWatcher controller_; |
97 | 93 |
98 // True when Alt is pressed. | 94 // True when Alt is pressed. |
99 bool alt_pressed_; | 95 bool alt_pressed_; |
100 | 96 |
101 // True when Ctrl is pressed. | 97 // True when Ctrl is pressed. |
102 bool ctrl_pressed_; | 98 bool ctrl_pressed_; |
103 | 99 |
104 Display* display_; | 100 Display* display_; |
105 Display* x_record_display_; | 101 Display* x_record_display_; |
106 XRecordRange* x_record_range_[2]; | 102 XRecordRange* x_record_range_[2]; |
107 XRecordContext x_record_context_; | 103 XRecordContext x_record_context_; |
108 | 104 |
109 DISALLOW_COPY_AND_ASSIGN(Core); | 105 DISALLOW_COPY_AND_ASSIGN(Core); |
110 }; | 106 }; |
111 | 107 |
112 scoped_refptr<Core> core_; | 108 scoped_refptr<Core> core_; |
113 | 109 |
114 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorLinux); | 110 DISALLOW_COPY_AND_ASSIGN(LocalInputMonitorLinux); |
115 }; | 111 }; |
116 | 112 |
117 LocalInputMonitorLinux::LocalInputMonitorLinux( | 113 LocalInputMonitorLinux::LocalInputMonitorLinux( |
118 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 114 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
119 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner) | 115 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
120 : core_(new Core(caller_task_runner, input_task_runner)) { | 116 SessionController::Delegate* delegate) |
117 : core_(new Core(caller_task_runner, input_task_runner, delegate)) { | |
118 core_->Start(); | |
121 } | 119 } |
122 | 120 |
123 LocalInputMonitorLinux::~LocalInputMonitorLinux() { | 121 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(); | 122 core_->Stop(); |
134 } | 123 } |
135 | 124 |
136 LocalInputMonitorLinux::Core::Core( | 125 LocalInputMonitorLinux::Core::Core( |
137 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 126 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
138 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner) | 127 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
128 SessionController::Delegate* delegate) | |
139 : caller_task_runner_(caller_task_runner), | 129 : caller_task_runner_(caller_task_runner), |
140 input_task_runner_(input_task_runner), | 130 input_task_runner_(input_task_runner), |
141 mouse_move_observer_(NULL), | 131 delegate_(delegate), |
142 alt_pressed_(false), | 132 alt_pressed_(false), |
143 ctrl_pressed_(false), | 133 ctrl_pressed_(false), |
144 display_(NULL), | 134 display_(NULL), |
145 x_record_display_(NULL), | 135 x_record_display_(NULL), |
146 x_record_context_(0) { | 136 x_record_context_(0) { |
147 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 137 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
138 DCHECK(delegate_); | |
148 | 139 |
149 x_record_range_[0] = NULL; | 140 x_record_range_[0] = NULL; |
150 x_record_range_[1] = NULL; | 141 x_record_range_[1] = NULL; |
151 } | 142 } |
152 | 143 |
153 void LocalInputMonitorLinux::Core::Start( | 144 void LocalInputMonitorLinux::Core::Start() { |
154 MouseMoveObserver* mouse_move_observer, | |
155 const base::Closure& disconnect_callback) { | |
156 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 145 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 | 146 |
162 disconnect_callback_ = disconnect_callback; | |
163 mouse_move_observer_ = mouse_move_observer; | |
164 input_task_runner_->PostTask(FROM_HERE, | 147 input_task_runner_->PostTask(FROM_HERE, |
165 base::Bind(&Core::StartOnInputThread, this)); | 148 base::Bind(&Core::StartOnInputThread, this)); |
166 } | 149 } |
167 | 150 |
168 void LocalInputMonitorLinux::Core::Stop() { | 151 void LocalInputMonitorLinux::Core::Stop() { |
169 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 152 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
170 | 153 |
171 disconnect_callback_.Reset(); | 154 delegate_ = NULL; |
172 mouse_move_observer_ = NULL; | |
173 input_task_runner_->PostTask(FROM_HERE, | 155 input_task_runner_->PostTask(FROM_HERE, |
174 base::Bind(&Core::StopOnInputThread, this)); | 156 base::Bind(&Core::StopOnInputThread, this)); |
175 } | 157 } |
176 | 158 |
177 LocalInputMonitorLinux::Core::~Core() { | 159 LocalInputMonitorLinux::Core::~Core() { |
178 DCHECK(disconnect_callback_.is_null()); | 160 DCHECK(!delegate_); |
179 DCHECK(!mouse_move_observer_); | |
180 DCHECK(!display_); | 161 DCHECK(!display_); |
181 DCHECK(!x_record_display_); | 162 DCHECK(!x_record_display_); |
182 DCHECK(!x_record_range_[0]); | 163 DCHECK(!x_record_range_[0]); |
183 DCHECK(!x_record_range_[1]); | 164 DCHECK(!x_record_range_[1]); |
184 DCHECK(!x_record_context_); | 165 DCHECK(!x_record_context_); |
185 } | 166 } |
186 | 167 |
187 void LocalInputMonitorLinux::Core::StartOnInputThread() { | 168 void LocalInputMonitorLinux::Core::StartOnInputThread() { |
188 DCHECK(input_task_runner_->BelongsToCurrentThread()); | 169 DCHECK(input_task_runner_->BelongsToCurrentThread()); |
189 DCHECK(!display_); | 170 DCHECK(!display_); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 NOTREACHED(); | 284 NOTREACHED(); |
304 } | 285 } |
305 | 286 |
306 void LocalInputMonitorLinux::Core::OnLocalMouseMoved(const SkIPoint& position) { | 287 void LocalInputMonitorLinux::Core::OnLocalMouseMoved(const SkIPoint& position) { |
307 if (!caller_task_runner_->BelongsToCurrentThread()) { | 288 if (!caller_task_runner_->BelongsToCurrentThread()) { |
308 caller_task_runner_->PostTask( | 289 caller_task_runner_->PostTask( |
309 FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position)); | 290 FROM_HERE, base::Bind(&Core::OnLocalMouseMoved, this, position)); |
310 return; | 291 return; |
311 } | 292 } |
312 | 293 |
313 if (mouse_move_observer_) | 294 if (delegate_) |
314 mouse_move_observer_->OnLocalMouseMoved(position); | 295 delegate_->OnLocalMouseMoved(position); |
315 } | 296 } |
316 | 297 |
317 void LocalInputMonitorLinux::Core::OnDisconnectShortcut() { | 298 void LocalInputMonitorLinux::Core::OnDisconnectShortcut() { |
318 if (!caller_task_runner_->BelongsToCurrentThread()) { | 299 if (!caller_task_runner_->BelongsToCurrentThread()) { |
319 caller_task_runner_->PostTask( | 300 caller_task_runner_->PostTask( |
320 FROM_HERE, base::Bind(&Core::OnDisconnectShortcut, this)); | 301 FROM_HERE, base::Bind(&Core::OnDisconnectShortcut, this)); |
321 return; | 302 return; |
322 } | 303 } |
323 | 304 |
324 if (!disconnect_callback_.is_null()) | 305 if (delegate_) |
325 disconnect_callback_.Run(); | 306 delegate_->DisconnectSession(); |
326 } | 307 } |
327 | 308 |
328 void LocalInputMonitorLinux::Core::ProcessXEvent(xEvent* event) { | 309 void LocalInputMonitorLinux::Core::ProcessXEvent(xEvent* event) { |
329 DCHECK(input_task_runner_->BelongsToCurrentThread()); | 310 DCHECK(input_task_runner_->BelongsToCurrentThread()); |
330 | 311 |
331 if (event->u.u.type == MotionNotify) { | 312 if (event->u.u.type == MotionNotify) { |
332 SkIPoint position(SkIPoint::Make(event->u.keyButtonPointer.rootX, | 313 SkIPoint position(SkIPoint::Make(event->u.keyButtonPointer.rootX, |
333 event->u.keyButtonPointer.rootY)); | 314 event->u.keyButtonPointer.rootY)); |
334 OnLocalMouseMoved(position); | 315 OnLocalMouseMoved(position); |
335 } else { | 316 } else { |
(...skipping 18 matching lines...) Expand all Loading... | |
354 reinterpret_cast<Core*>(self)->ProcessXEvent(event); | 335 reinterpret_cast<Core*>(self)->ProcessXEvent(event); |
355 } | 336 } |
356 XRecordFreeData(data); | 337 XRecordFreeData(data); |
357 } | 338 } |
358 | 339 |
359 } // namespace | 340 } // namespace |
360 | 341 |
361 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create( | 342 scoped_ptr<LocalInputMonitor> LocalInputMonitor::Create( |
362 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, | 343 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
363 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, | 344 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, |
364 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) { | 345 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
346 SessionController::Delegate* delegate) { | |
365 return scoped_ptr<LocalInputMonitor>( | 347 return scoped_ptr<LocalInputMonitor>( |
366 new LocalInputMonitorLinux(caller_task_runner, input_task_runner)); | 348 new LocalInputMonitorLinux(caller_task_runner, |
349 input_task_runner, | |
350 delegate)); | |
367 } | 351 } |
368 | 352 |
369 } // namespace remoting | 353 } // namespace remoting |
OLD | NEW |