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

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

Issue 2402593003: Use FileDescriptorWatcher in LocalInputMonitorX11. (Closed)
Patch Set: fix build error Created 4 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
« no previous file with comments | « no previous file | no next file » | 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 9
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #define XK_MISCELLANY 11 #define XK_MISCELLANY
12 #include <X11/keysymdef.h> 12 #include <X11/keysymdef.h>
13 13
14 #include "base/bind.h" 14 #include "base/bind.h"
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/compiler_specific.h" 16 #include "base/compiler_specific.h"
17 #include "base/files/file_descriptor_watcher_posix.h"
17 #include "base/location.h" 18 #include "base/location.h"
18 #include "base/logging.h" 19 #include "base/logging.h"
19 #include "base/macros.h" 20 #include "base/macros.h"
20 #include "base/message_loop/message_loop.h" 21 #include "base/message_loop/message_loop.h"
21 #include "base/message_loop/message_pump_libevent.h" 22 #include "base/message_loop/message_pump_libevent.h"
joedow 2016/10/11 16:56:12 message_pump_libevent.h can be removed now
fdoray 2016/10/11 17:07:31 Done.
22 #include "base/single_thread_task_runner.h" 23 #include "base/single_thread_task_runner.h"
23 #include "base/threading/non_thread_safe.h" 24 #include "base/threading/non_thread_safe.h"
24 #include "remoting/host/client_session_control.h" 25 #include "remoting/host/client_session_control.h"
25 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 26 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
26 27
27 // These includes need to be later than dictated by the style guide due to 28 // These includes need to be later than dictated by the style guide due to
28 // Xlib header pollution, specifically the min, max, and Status macros. 29 // Xlib header pollution, specifically the min, max, and Status macros.
29 #include <X11/XKBlib.h> 30 #include <X11/XKBlib.h>
30 #include <X11/Xlibint.h> 31 #include <X11/Xlibint.h>
31 #include <X11/extensions/record.h> 32 #include <X11/extensions/record.h>
32 33
33 namespace remoting { 34 namespace remoting {
34 35
35 namespace { 36 namespace {
36 37
37 class LocalInputMonitorX11 : public base::NonThreadSafe, 38 class LocalInputMonitorX11 : public base::NonThreadSafe,
38 public LocalInputMonitor { 39 public LocalInputMonitor {
39 public: 40 public:
40 LocalInputMonitorX11( 41 LocalInputMonitorX11(
41 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 42 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
42 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, 43 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
43 base::WeakPtr<ClientSessionControl> client_session_control); 44 base::WeakPtr<ClientSessionControl> client_session_control);
44 ~LocalInputMonitorX11() override; 45 ~LocalInputMonitorX11() override;
45 46
46 private: 47 private:
47 // The actual implementation resides in LocalInputMonitorX11::Core class. 48 // The actual implementation resides in LocalInputMonitorX11::Core class.
48 class Core 49 class Core : public base::RefCountedThreadSafe<Core> {
49 : public base::RefCountedThreadSafe<Core>,
50 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,
54 base::WeakPtr<ClientSessionControl> client_session_control); 53 base::WeakPtr<ClientSessionControl> client_session_control);
55 54
56 void Start(); 55 void Start();
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 ~Core() override; 60 ~Core();
62 61
63 void StartOnInputThread(); 62 void StartOnInputThread();
64 void StopOnInputThread(); 63 void StopOnInputThread();
65 64
66 // base::MessagePumpLibevent::Watcher interface. 65 // Called when there are pending X events.
67 void OnFileCanReadWithoutBlocking(int fd) override; 66 void OnPendingXEvents();
68 void OnFileCanWriteWithoutBlocking(int fd) override;
69 67
70 // Processes key and mouse events. 68 // Processes key and mouse events.
71 void ProcessXEvent(xEvent* event); 69 void ProcessXEvent(xEvent* event);
72 70
73 static void ProcessReply(XPointer self, XRecordInterceptData* data); 71 static void ProcessReply(XPointer self, XRecordInterceptData* data);
74 72
75 // Task runner on which public methods of this class must be called. 73 // Task runner on which public methods of this class must be called.
76 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; 74 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_;
77 75
78 // Task runner on which X Window events are received. 76 // Task runner on which X Window events are received.
79 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_; 77 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner_;
80 78
81 // Points to the object receiving mouse event notifications and session 79 // Points to the object receiving mouse event notifications and session
82 // disconnect requests. 80 // disconnect requests.
83 base::WeakPtr<ClientSessionControl> client_session_control_; 81 base::WeakPtr<ClientSessionControl> client_session_control_;
84 82
85 // Used to receive base::MessagePumpLibevent::Watcher events. 83 // Controls watching X events.
86 base::MessagePumpLibevent::FileDescriptorWatcher controller_; 84 std::unique_ptr<base::FileDescriptorWatcher::Controller> controller_;
87 85
88 // True when Alt is pressed. 86 // True when Alt is pressed.
89 bool alt_pressed_; 87 bool alt_pressed_;
90 88
91 // True when Ctrl is pressed. 89 // True when Ctrl is pressed.
92 bool ctrl_pressed_; 90 bool ctrl_pressed_;
93 91
94 Display* display_; 92 Display* display_;
95 Display* x_record_display_; 93 Display* x_record_display_;
96 XRecordRange* x_record_range_[2]; 94 XRecordRange* x_record_range_[2];
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 return; 203 return;
206 } 204 }
207 205
208 if (!XRecordEnableContextAsync(x_record_display_, x_record_context_, 206 if (!XRecordEnableContextAsync(x_record_display_, x_record_context_,
209 &Core::ProcessReply, 207 &Core::ProcessReply,
210 reinterpret_cast<XPointer>(this))) { 208 reinterpret_cast<XPointer>(this))) {
211 LOG(ERROR) << "XRecordEnableContextAsync failed."; 209 LOG(ERROR) << "XRecordEnableContextAsync failed.";
212 return; 210 return;
213 } 211 }
214 212
215 // Register OnFileCanReadWithoutBlocking() to be called every time there is 213 // Register OnPendingXEvents() to be called every time there is
216 // something to read from |x_record_display_|. 214 // something to read from |x_record_display_|.
217 base::MessageLoopForIO* message_loop = base::MessageLoopForIO::current(); 215 controller_ = base::FileDescriptorWatcher::WatchReadable(
218 int result = 216 ConnectionNumber(x_record_display_),
219 message_loop->WatchFileDescriptor(ConnectionNumber(x_record_display_), 217 base::Bind(&Core::OnPendingXEvents, base::Unretained(this)));
220 true,
221 base::MessageLoopForIO::WATCH_READ,
222 &controller_,
223 this);
224 if (!result) {
225 LOG(ERROR) << "Failed to create X record task.";
226 return;
227 }
228 218
229 // Fetch pending events if any. 219 // Fetch pending events if any.
230 while (XPending(x_record_display_)) { 220 while (XPending(x_record_display_)) {
231 XEvent ev; 221 XEvent ev;
232 XNextEvent(x_record_display_, &ev); 222 XNextEvent(x_record_display_, &ev);
233 } 223 }
234 } 224 }
235 225
236 void LocalInputMonitorX11::Core::StopOnInputThread() { 226 void LocalInputMonitorX11::Core::StopOnInputThread() {
237 DCHECK(input_task_runner_->BelongsToCurrentThread()); 227 DCHECK(input_task_runner_->BelongsToCurrentThread());
238 228
239 // Context must be disabled via the control channel because we can't send 229 // Context must be disabled via the control channel because we can't send
240 // any X protocol traffic over the data channel while it's recording. 230 // any X protocol traffic over the data channel while it's recording.
241 if (x_record_context_) { 231 if (x_record_context_) {
242 XRecordDisableContext(display_, x_record_context_); 232 XRecordDisableContext(display_, x_record_context_);
243 XFlush(display_); 233 XFlush(display_);
244 } 234 }
245 235
246 controller_.StopWatchingFileDescriptor(); 236 controller_.reset();
247 237
248 if (x_record_range_[0]) { 238 if (x_record_range_[0]) {
249 XFree(x_record_range_[0]); 239 XFree(x_record_range_[0]);
250 x_record_range_[0] = nullptr; 240 x_record_range_[0] = nullptr;
251 } 241 }
252 if (x_record_range_[1]) { 242 if (x_record_range_[1]) {
253 XFree(x_record_range_[1]); 243 XFree(x_record_range_[1]);
254 x_record_range_[1] = nullptr; 244 x_record_range_[1] = nullptr;
255 } 245 }
256 if (x_record_context_) { 246 if (x_record_context_) {
257 XRecordFreeContext(x_record_display_, x_record_context_); 247 XRecordFreeContext(x_record_display_, x_record_context_);
258 x_record_context_ = 0; 248 x_record_context_ = 0;
259 } 249 }
260 if (x_record_display_) { 250 if (x_record_display_) {
261 XCloseDisplay(x_record_display_); 251 XCloseDisplay(x_record_display_);
262 x_record_display_ = nullptr; 252 x_record_display_ = nullptr;
263 } 253 }
264 if (display_) { 254 if (display_) {
265 XCloseDisplay(display_); 255 XCloseDisplay(display_);
266 display_ = nullptr; 256 display_ = nullptr;
267 } 257 }
268 } 258 }
269 259
270 void LocalInputMonitorX11::Core::OnFileCanReadWithoutBlocking(int fd) { 260 void LocalInputMonitorX11::Core::OnPendingXEvents() {
271 DCHECK(input_task_runner_->BelongsToCurrentThread()); 261 DCHECK(input_task_runner_->BelongsToCurrentThread());
272 262
273 // Fetch pending events if any. 263 // Fetch pending events if any.
274 while (XPending(x_record_display_)) { 264 while (XPending(x_record_display_)) {
275 XEvent ev; 265 XEvent ev;
276 XNextEvent(x_record_display_, &ev); 266 XNextEvent(x_record_display_, &ev);
277 } 267 }
278 } 268 }
279 269
280 void LocalInputMonitorX11::Core::OnFileCanWriteWithoutBlocking(int fd) {
281 NOTREACHED();
282 }
283
284 void LocalInputMonitorX11::Core::ProcessXEvent(xEvent* event) { 270 void LocalInputMonitorX11::Core::ProcessXEvent(xEvent* event) {
285 DCHECK(input_task_runner_->BelongsToCurrentThread()); 271 DCHECK(input_task_runner_->BelongsToCurrentThread());
286 272
287 if (event->u.u.type == MotionNotify) { 273 if (event->u.u.type == MotionNotify) {
288 webrtc::DesktopVector position(event->u.keyButtonPointer.rootX, 274 webrtc::DesktopVector position(event->u.keyButtonPointer.rootX,
289 event->u.keyButtonPointer.rootY); 275 event->u.keyButtonPointer.rootY);
290 caller_task_runner_->PostTask( 276 caller_task_runner_->PostTask(
291 FROM_HERE, base::Bind(&ClientSessionControl::OnLocalMouseMoved, 277 FROM_HERE, base::Bind(&ClientSessionControl::OnLocalMouseMoved,
292 client_session_control_, 278 client_session_control_,
293 position)); 279 position));
(...skipping 28 matching lines...) Expand all
322 std::unique_ptr<LocalInputMonitor> LocalInputMonitor::Create( 308 std::unique_ptr<LocalInputMonitor> LocalInputMonitor::Create(
323 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, 309 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner,
324 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, 310 scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
325 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 311 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
326 base::WeakPtr<ClientSessionControl> client_session_control) { 312 base::WeakPtr<ClientSessionControl> client_session_control) {
327 return base::WrapUnique(new LocalInputMonitorX11( 313 return base::WrapUnique(new LocalInputMonitorX11(
328 caller_task_runner, input_task_runner, client_session_control)); 314 caller_task_runner, input_task_runner, client_session_control));
329 } 315 }
330 316
331 } // namespace remoting 317 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698