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

Side by Side Diff: media/base/user_input_monitor_linux.cc

Issue 23702008: Adds the UserInputMonitor implementation for Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 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 | « media/base/user_input_monitor.cc ('k') | media/base/user_input_monitor_mac.cc » ('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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "media/base/user_input_monitor.h" 5 #include "media/base/user_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/memory/weak_ptr.h"
18 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
19 #include "base/message_loop/message_pump_libevent.h" 20 #include "base/message_loop/message_pump_libevent.h"
21 #include "base/observer_list_threadsafe.h"
20 #include "base/posix/eintr_wrapper.h" 22 #include "base/posix/eintr_wrapper.h"
21 #include "base/single_thread_task_runner.h" 23 #include "base/single_thread_task_runner.h"
24 #include "base/synchronization/lock.h"
22 #include "media/base/keyboard_event_counter.h" 25 #include "media/base/keyboard_event_counter.h"
23 #include "third_party/skia/include/core/SkPoint.h" 26 #include "third_party/skia/include/core/SkPoint.h"
24 #include "ui/base/keycodes/keyboard_code_conversion_x.h" 27 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
25 28
26 // These includes need to be later than dictated by the style guide due to 29 // These includes need to be later than dictated by the style guide due to
27 // Xlib header pollution, specifically the min, max, and Status macros. 30 // Xlib header pollution, specifically the min, max, and Status macros.
28 #include <X11/XKBlib.h> 31 #include <X11/XKBlib.h>
29 #include <X11/Xlibint.h> 32 #include <X11/Xlibint.h>
30 #include <X11/extensions/record.h> 33 #include <X11/extensions/record.h>
31 34
32 namespace media { 35 namespace media {
33 namespace { 36 namespace {
34 37
35 class UserInputMonitorLinux : public UserInputMonitor , 38 // This is the actual implementation of event monitoring. It's separated from
36 public base::MessagePumpLibevent::Watcher { 39 // UserInputMonitorLinux since it needs to be deleted on the IO thread.
40 class UserInputMonitorLinuxCore : public base::MessagePumpLibevent::Watcher {
37 public: 41 public:
38 explicit UserInputMonitorLinux(
39 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
40 virtual ~UserInputMonitorLinux();
41
42 virtual size_t GetKeyPressCount() const OVERRIDE;
43
44 private:
45 enum EventType { 42 enum EventType {
46 MOUSE_EVENT, 43 MOUSE_EVENT,
47 KEYBOARD_EVENT 44 KEYBOARD_EVENT
48 }; 45 };
49 46
50 virtual void StartMouseMonitoring() OVERRIDE; 47 explicit UserInputMonitorLinuxCore(
51 virtual void StopMouseMonitoring() OVERRIDE; 48 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
52 virtual void StartKeyboardMonitoring() OVERRIDE; 49 virtual ~UserInputMonitorLinuxCore();
53 virtual void StopKeyboardMonitoring() OVERRIDE;
54 50
55 // 51 void AddMouseListener(UserInputMonitor::MouseEventListener* listener);
56 // The following methods must be called on the IO thread. 52 void RemoveMouseListener(UserInputMonitor::MouseEventListener* listener);
57 // 53 size_t GetKeyPressCount() const;
58 void StartMonitor(EventType type); 54 void StartMonitor(EventType type);
59 void StopMonitor(EventType type); 55 void StopMonitor(EventType type);
60 56
57 base::WeakPtr<UserInputMonitorLinuxCore> GetWeakPtr() {
58 return weak_factory_.GetWeakPtr();
Wez 2013/09/11 08:03:42 You can avoid this ugly WeakPtr getter by keeping
jiayl 2013/09/11 16:57:10 To reiterate why PostTask to IO thread from UserIn
Wez 2013/09/13 10:01:27 You could add the listener from UserInputMonitor,
59 }
60
61 private:
62 void OnMouseListenerAdded();
63 void OnMouseListenerRemoved();
61 // base::MessagePumpLibevent::Watcher interface. 64 // base::MessagePumpLibevent::Watcher interface.
62 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; 65 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
63 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; 66 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
64 67
65 // Processes key and mouse events. 68 // Processes key and mouse events.
66 void ProcessXEvent(xEvent* event); 69 void ProcessXEvent(xEvent* event);
67 static void ProcessReply(XPointer self, XRecordInterceptData* data); 70 static void ProcessReply(XPointer self, XRecordInterceptData* data);
68 71
69 // Task runner on which X Window events are received.
70 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; 72 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
73 scoped_refptr<ObserverListThreadSafe<UserInputMonitor::MouseEventListener> >
74 mouse_listeners_;
71 75
72 // 76 //
73 // The following members should only be accessed on the IO thread. 77 // The following members should only be accessed on the IO thread.
74 // 78 //
79 size_t mouse_listeners_count_;
75 base::MessagePumpLibevent::FileDescriptorWatcher controller_; 80 base::MessagePumpLibevent::FileDescriptorWatcher controller_;
76 Display* display_; 81 Display* x_control_display_;
77 Display* x_record_display_; 82 Display* x_record_display_;
78 XRecordRange* x_record_range_[2]; 83 XRecordRange* x_record_range_[2];
79 XRecordContext x_record_context_; 84 XRecordContext x_record_context_;
80 KeyboardEventCounter counter_; 85 KeyboardEventCounter counter_;
86 base::WeakPtrFactory<UserInputMonitorLinuxCore> weak_factory_;
87
88 DISALLOW_COPY_AND_ASSIGN(UserInputMonitorLinuxCore);
89 };
90
91 class UserInputMonitorLinux : public UserInputMonitor {
92 public:
93 explicit UserInputMonitorLinux(
94 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
95 virtual ~UserInputMonitorLinux();
96
97 // Public UserInputMonitor overrides.
98 virtual void AddMouseListener(MouseEventListener* listener) OVERRIDE;
99 virtual void RemoveMouseListener(MouseEventListener* listener) OVERRIDE;
100 virtual size_t GetKeyPressCount() const OVERRIDE;
101
102 private:
103 // Private UserInputMonitor overrides.
104 virtual void StartKeyboardMonitoring() OVERRIDE;
105 virtual void StopKeyboardMonitoring() OVERRIDE;
106
107 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
108 UserInputMonitorLinuxCore* core_;
81 109
82 DISALLOW_COPY_AND_ASSIGN(UserInputMonitorLinux); 110 DISALLOW_COPY_AND_ASSIGN(UserInputMonitorLinux);
83 }; 111 };
84 112
85 UserInputMonitorLinux::UserInputMonitorLinux( 113 UserInputMonitorLinuxCore::UserInputMonitorLinuxCore(
86 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) 114 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
87 : io_task_runner_(io_task_runner), 115 : io_task_runner_(io_task_runner),
88 display_(NULL), 116 mouse_listeners_(
117 new ObserverListThreadSafe<UserInputMonitor::MouseEventListener>()),
118 mouse_listeners_count_(0),
119 x_control_display_(NULL),
89 x_record_display_(NULL), 120 x_record_display_(NULL),
90 x_record_context_(0) { 121 x_record_context_(0),
122 weak_factory_(this) {
91 x_record_range_[0] = NULL; 123 x_record_range_[0] = NULL;
92 x_record_range_[1] = NULL; 124 x_record_range_[1] = NULL;
93 } 125 }
94 126
95 UserInputMonitorLinux::~UserInputMonitorLinux() { 127 UserInputMonitorLinuxCore::~UserInputMonitorLinuxCore() {
96 DCHECK(!display_); 128 DCHECK_EQ(0u, mouse_listeners_count_);
129 mouse_listeners_->AssertEmpty();
130 DCHECK(!x_control_display_);
97 DCHECK(!x_record_display_); 131 DCHECK(!x_record_display_);
98 DCHECK(!x_record_range_[0]); 132 DCHECK(!x_record_range_[0]);
99 DCHECK(!x_record_range_[1]); 133 DCHECK(!x_record_range_[1]);
100 DCHECK(!x_record_context_); 134 DCHECK(!x_record_context_);
101 } 135 }
102 136
103 size_t UserInputMonitorLinux::GetKeyPressCount() const { 137 void UserInputMonitorLinuxCore::AddMouseListener(
138 UserInputMonitor::MouseEventListener* listener) {
139 mouse_listeners_->AddObserver(listener);
140 io_task_runner_->PostTask(
141 FROM_HERE,
142 base::Bind(&UserInputMonitorLinuxCore::OnMouseListenerAdded,
143 weak_factory_.GetWeakPtr()));
144 }
145
146 void UserInputMonitorLinuxCore::RemoveMouseListener(
147 UserInputMonitor::MouseEventListener* listener) {
148 mouse_listeners_->RemoveObserver(listener);
149 io_task_runner_->PostTask(
150 FROM_HERE,
151 base::Bind(&UserInputMonitorLinuxCore::OnMouseListenerRemoved,
152 weak_factory_.GetWeakPtr()));
153 }
154
155 size_t UserInputMonitorLinuxCore::GetKeyPressCount() const {
104 return counter_.GetKeyPressCount(); 156 return counter_.GetKeyPressCount();
105 } 157 }
106 158
107 void UserInputMonitorLinux::StartMouseMonitoring() { 159 void UserInputMonitorLinuxCore::StartMonitor(EventType type) {
108 if (!io_task_runner_->BelongsToCurrentThread()) {
109 io_task_runner_->PostTask(
110 FROM_HERE,
111 base::Bind(&UserInputMonitorLinux::StartMonitor,
112 base::Unretained(this),
113 MOUSE_EVENT));
114 return;
115 }
116 StartMonitor(MOUSE_EVENT);
117 }
118
119 void UserInputMonitorLinux::StopMouseMonitoring() {
120 if (!io_task_runner_->BelongsToCurrentThread()) {
121 io_task_runner_->PostTask(
122 FROM_HERE,
123 base::Bind(&UserInputMonitorLinux::StopMonitor,
124 base::Unretained(this),
125 MOUSE_EVENT));
126 return;
127 }
128 StopMonitor(MOUSE_EVENT);
129 }
130
131 void UserInputMonitorLinux::StartKeyboardMonitoring() {
132 if (!io_task_runner_->BelongsToCurrentThread()) {
133 io_task_runner_->PostTask(
134 FROM_HERE,
135 base::Bind(&UserInputMonitorLinux::StartMonitor,
136 base::Unretained(this),
137 KEYBOARD_EVENT));
138 return;
139 }
140 StartMonitor(KEYBOARD_EVENT);
141 }
142
143 void UserInputMonitorLinux::StopKeyboardMonitoring() {
144 if (!io_task_runner_->BelongsToCurrentThread()) {
145 io_task_runner_->PostTask(
146 FROM_HERE,
147 base::Bind(&UserInputMonitorLinux::StopMonitor,
148 base::Unretained(this),
149 KEYBOARD_EVENT));
150 return;
151 }
152 StopMonitor(KEYBOARD_EVENT);
153 }
154
155 void UserInputMonitorLinux::StartMonitor(EventType type) {
156 DCHECK(io_task_runner_->BelongsToCurrentThread()); 160 DCHECK(io_task_runner_->BelongsToCurrentThread());
157 161
158 if (type == KEYBOARD_EVENT) 162 if (type == KEYBOARD_EVENT)
159 counter_.Reset(); 163 counter_.Reset();
160 164
161 // TODO(jamiewalch): We should pass the display in. At that point, since 165 // TODO(jamiewalch): We should pass the display in. At that point, since
162 // XRecord needs a private connection to the X Server for its data channel 166 // XRecord needs a private connection to the X Server for its data channel
163 // and both channels are used from a separate thread, we'll need to duplicate 167 // and both channels are used from a separate thread, we'll need to duplicate
164 // them with something like the following: 168 // them with something like the following:
165 // XOpenDisplay(DisplayString(display)); 169 // XOpenDisplay(DisplayString(display));
166 if (!display_) 170 if (!x_control_display_)
167 display_ = XOpenDisplay(NULL); 171 x_control_display_ = XOpenDisplay(NULL);
168 172
169 if (!x_record_display_) 173 if (!x_record_display_)
170 x_record_display_ = XOpenDisplay(NULL); 174 x_record_display_ = XOpenDisplay(NULL);
171 175
172 if (!display_ || !x_record_display_) { 176 if (!x_control_display_ || !x_record_display_) {
173 LOG(ERROR) << "Couldn't open X display"; 177 LOG(ERROR) << "Couldn't open X display";
174 return; 178 return;
175 } 179 }
176 180
177 int xr_opcode, xr_event, xr_error; 181 int xr_opcode, xr_event, xr_error;
178 if (!XQueryExtension(display_, "RECORD", &xr_opcode, &xr_event, &xr_error)) { 182 if (!XQueryExtension(
183 x_control_display_, "RECORD", &xr_opcode, &xr_event, &xr_error)) {
179 LOG(ERROR) << "X Record extension not available."; 184 LOG(ERROR) << "X Record extension not available.";
180 return; 185 return;
181 } 186 }
182 187
183 if (!x_record_range_[type]) 188 if (!x_record_range_[type])
184 x_record_range_[type] = XRecordAllocRange(); 189 x_record_range_[type] = XRecordAllocRange();
185 190
186 if (!x_record_range_[type]) { 191 if (!x_record_range_[type]) {
187 LOG(ERROR) << "XRecordAllocRange failed."; 192 LOG(ERROR) << "XRecordAllocRange failed.";
188 return; 193 return;
189 } 194 }
190 195
191 if (type == MOUSE_EVENT) { 196 if (type == MOUSE_EVENT) {
192 x_record_range_[type]->device_events.first = MotionNotify; 197 x_record_range_[type]->device_events.first = MotionNotify;
193 x_record_range_[type]->device_events.last = MotionNotify; 198 x_record_range_[type]->device_events.last = MotionNotify;
194 } else { 199 } else {
195 DCHECK_EQ(KEYBOARD_EVENT, type); 200 DCHECK_EQ(KEYBOARD_EVENT, type);
196 x_record_range_[type]->device_events.first = KeyPress; 201 x_record_range_[type]->device_events.first = KeyPress;
197 x_record_range_[type]->device_events.last = KeyRelease; 202 x_record_range_[type]->device_events.last = KeyRelease;
198 } 203 }
199 204
200 if (x_record_context_) { 205 if (x_record_context_) {
201 XRecordDisableContext(display_, x_record_context_); 206 XRecordDisableContext(x_control_display_, x_record_context_);
202 XFlush(display_); 207 XFlush(x_control_display_);
203 XRecordFreeContext(x_record_display_, x_record_context_); 208 XRecordFreeContext(x_record_display_, x_record_context_);
204 x_record_context_ = 0; 209 x_record_context_ = 0;
205 } 210 }
206 XRecordRange** record_range_to_use = 211 XRecordRange** record_range_to_use =
207 (x_record_range_[0] && x_record_range_[1]) ? x_record_range_ 212 (x_record_range_[0] && x_record_range_[1]) ? x_record_range_
208 : &x_record_range_[type]; 213 : &x_record_range_[type];
209 int number_of_ranges = (x_record_range_[0] && x_record_range_[1]) ? 2 : 1; 214 int number_of_ranges = (x_record_range_[0] && x_record_range_[1]) ? 2 : 1;
210 215
211 XRecordClientSpec client_spec = XRecordAllClients; 216 XRecordClientSpec client_spec = XRecordAllClients;
212 x_record_context_ = XRecordCreateContext(x_record_display_, 217 x_record_context_ = XRecordCreateContext(x_record_display_,
213 0, 218 0,
214 &client_spec, 219 &client_spec,
215 1, 220 1,
216 record_range_to_use, 221 record_range_to_use,
217 number_of_ranges); 222 number_of_ranges);
218 if (!x_record_context_) { 223 if (!x_record_context_) {
219 LOG(ERROR) << "XRecordCreateContext failed."; 224 LOG(ERROR) << "XRecordCreateContext failed.";
220 return; 225 return;
221 } 226 }
222 227
223 if (!XRecordEnableContextAsync(x_record_display_, 228 if (!XRecordEnableContextAsync(x_record_display_,
224 x_record_context_, 229 x_record_context_,
225 &UserInputMonitorLinux::ProcessReply, 230 &UserInputMonitorLinuxCore::ProcessReply,
226 reinterpret_cast<XPointer>(this))) { 231 reinterpret_cast<XPointer>(this))) {
227 LOG(ERROR) << "XRecordEnableContextAsync failed."; 232 LOG(ERROR) << "XRecordEnableContextAsync failed.";
228 return; 233 return;
229 } 234 }
230 235
231 if (!x_record_range_[0] || !x_record_range_[1]) { 236 if (!x_record_range_[0] || !x_record_range_[1]) {
232 // Register OnFileCanReadWithoutBlocking() to be called every time there is 237 // Register OnFileCanReadWithoutBlocking() to be called every time there is
233 // something to read from |x_record_display_|. 238 // something to read from |x_record_display_|.
234 base::MessageLoopForIO* message_loop = base::MessageLoopForIO::current(); 239 base::MessageLoopForIO* message_loop = base::MessageLoopForIO::current();
235 int result = 240 int result =
236 message_loop->WatchFileDescriptor(ConnectionNumber(x_record_display_), 241 message_loop->WatchFileDescriptor(ConnectionNumber(x_record_display_),
237 true, 242 true,
238 base::MessageLoopForIO::WATCH_READ, 243 base::MessageLoopForIO::WATCH_READ,
239 &controller_, 244 &controller_,
240 this); 245 this);
241 if (!result) { 246 if (!result) {
242 LOG(ERROR) << "Failed to create X record task."; 247 LOG(ERROR) << "Failed to create X record task.";
243 return; 248 return;
244 } 249 }
245 } 250 }
246 251
247 // Fetch pending events if any. 252 // Fetch pending events if any.
248 OnFileCanReadWithoutBlocking(ConnectionNumber(x_record_display_)); 253 OnFileCanReadWithoutBlocking(ConnectionNumber(x_record_display_));
249 } 254 }
250 255
251 void UserInputMonitorLinux::StopMonitor(EventType type) { 256 void UserInputMonitorLinuxCore::StopMonitor(EventType type) {
252 DCHECK(io_task_runner_->BelongsToCurrentThread()); 257 DCHECK(io_task_runner_->BelongsToCurrentThread());
253 258
254 if (x_record_range_[type]) { 259 if (x_record_range_[type]) {
255 XFree(x_record_range_[type]); 260 XFree(x_record_range_[type]);
256 x_record_range_[type] = NULL; 261 x_record_range_[type] = NULL;
257 } 262 }
258 if (x_record_range_[0] || x_record_range_[1]) 263 if (x_record_range_[0] || x_record_range_[1])
259 return; 264 return;
260 265
261 // Context must be disabled via the control channel because we can't send 266 // Context must be disabled via the control channel because we can't send
262 // any X protocol traffic over the data channel while it's recording. 267 // any X protocol traffic over the data channel while it's recording.
263 if (x_record_context_) { 268 if (x_record_context_) {
264 XRecordDisableContext(display_, x_record_context_); 269 XRecordDisableContext(x_control_display_, x_record_context_);
265 XFlush(display_); 270 XFlush(x_control_display_);
266 XRecordFreeContext(x_record_display_, x_record_context_); 271 XRecordFreeContext(x_record_display_, x_record_context_);
267 x_record_context_ = 0; 272 x_record_context_ = 0;
268 273
269 controller_.StopWatchingFileDescriptor(); 274 controller_.StopWatchingFileDescriptor();
270 if (x_record_display_) { 275 if (x_record_display_) {
271 XCloseDisplay(x_record_display_); 276 XCloseDisplay(x_record_display_);
272 x_record_display_ = NULL; 277 x_record_display_ = NULL;
273 } 278 }
274 if (display_) { 279 if (x_control_display_) {
275 XCloseDisplay(display_); 280 XCloseDisplay(x_control_display_);
276 display_ = NULL; 281 x_control_display_ = NULL;
277 } 282 }
278 } 283 }
279 } 284 }
280 285
281 void UserInputMonitorLinux::OnFileCanReadWithoutBlocking(int fd) { 286 void UserInputMonitorLinuxCore::OnMouseListenerAdded() {
287 DCHECK(io_task_runner_->BelongsToCurrentThread());
288 mouse_listeners_count_++;
289 if (mouse_listeners_count_ == 1) {
290 StartMonitor(MOUSE_EVENT);
291 DVLOG(2) << "Started mouse monitoring.";
292 }
293 }
294
295 void UserInputMonitorLinuxCore::OnMouseListenerRemoved() {
296 DCHECK(io_task_runner_->BelongsToCurrentThread());
297 mouse_listeners_count_--;
298 if (mouse_listeners_count_ == 0) {
299 StopMonitor(MOUSE_EVENT);
300 DVLOG(2) << "Stopped mouse monitoring.";
301 }
302 }
303
304 void UserInputMonitorLinuxCore::OnFileCanReadWithoutBlocking(int fd) {
282 DCHECK(io_task_runner_->BelongsToCurrentThread()); 305 DCHECK(io_task_runner_->BelongsToCurrentThread());
283 XEvent event; 306 XEvent event;
284 // Fetch pending events if any. 307 // Fetch pending events if any.
285 while (XPending(x_record_display_)) { 308 while (XPending(x_record_display_)) {
286 XNextEvent(x_record_display_, &event); 309 XNextEvent(x_record_display_, &event);
287 } 310 }
288 } 311 }
289 312
290 void UserInputMonitorLinux::OnFileCanWriteWithoutBlocking(int fd) { 313 void UserInputMonitorLinuxCore::OnFileCanWriteWithoutBlocking(int fd) {
291 NOTREACHED(); 314 NOTREACHED();
292 } 315 }
293 316
294 void UserInputMonitorLinux::ProcessXEvent(xEvent* event) { 317 void UserInputMonitorLinuxCore::ProcessXEvent(xEvent* event) {
295 DCHECK(io_task_runner_->BelongsToCurrentThread()); 318 DCHECK(io_task_runner_->BelongsToCurrentThread());
296 if (event->u.u.type == MotionNotify) { 319 if (event->u.u.type == MotionNotify) {
297 SkIPoint position(SkIPoint::Make(event->u.keyButtonPointer.rootX, 320 SkIPoint position(SkIPoint::Make(event->u.keyButtonPointer.rootX,
298 event->u.keyButtonPointer.rootY)); 321 event->u.keyButtonPointer.rootY));
299 OnMouseEvent(position); 322 mouse_listeners_->Notify(
323 &UserInputMonitor::MouseEventListener::OnMouseMoved, position);
300 } else { 324 } else {
301 ui::EventType type; 325 ui::EventType type;
302 if (event->u.u.type == KeyPress) { 326 if (event->u.u.type == KeyPress) {
303 type = ui::ET_KEY_PRESSED; 327 type = ui::ET_KEY_PRESSED;
304 } else if (event->u.u.type == KeyRelease) { 328 } else if (event->u.u.type == KeyRelease) {
305 type = ui::ET_KEY_RELEASED; 329 type = ui::ET_KEY_RELEASED;
306 } else { 330 } else {
307 NOTREACHED(); 331 NOTREACHED();
308 return; 332 return;
309 } 333 }
310 334
311 KeySym key_sym = XkbKeycodeToKeysym(display_, event->u.u.detail, 0, 0); 335 KeySym key_sym =
336 XkbKeycodeToKeysym(x_control_display_, event->u.u.detail, 0, 0);
312 ui::KeyboardCode key_code = ui::KeyboardCodeFromXKeysym(key_sym); 337 ui::KeyboardCode key_code = ui::KeyboardCodeFromXKeysym(key_sym);
313 counter_.OnKeyboardEvent(type, key_code); 338 counter_.OnKeyboardEvent(type, key_code);
314 } 339 }
315 } 340 }
316 341
317 // static 342 // static
318 void UserInputMonitorLinux::ProcessReply(XPointer self, 343 void UserInputMonitorLinuxCore::ProcessReply(XPointer self,
319 XRecordInterceptData* data) { 344 XRecordInterceptData* data) {
320 if (data->category == XRecordFromServer) { 345 if (data->category == XRecordFromServer) {
321 xEvent* event = reinterpret_cast<xEvent*>(data->data); 346 xEvent* event = reinterpret_cast<xEvent*>(data->data);
322 reinterpret_cast<UserInputMonitorLinux*>(self)->ProcessXEvent(event); 347 reinterpret_cast<UserInputMonitorLinuxCore*>(self)->ProcessXEvent(event);
323 } 348 }
324 XRecordFreeData(data); 349 XRecordFreeData(data);
325 } 350 }
326 351
352 //
353 // Implementation of UserInputMonitorLinux.
354 //
355
356 UserInputMonitorLinux::UserInputMonitorLinux(
357 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
358 : io_task_runner_(io_task_runner),
359 core_(new UserInputMonitorLinuxCore(io_task_runner)) {}
360
361 UserInputMonitorLinux::~UserInputMonitorLinux() {
362 if (!io_task_runner_->DeleteSoon(FROM_HERE, core_))
363 delete core_;
364 }
365
366 void UserInputMonitorLinux::AddMouseListener(MouseEventListener* listener) {
367 core_->AddMouseListener(listener);
368 }
369
370 void UserInputMonitorLinux::RemoveMouseListener(MouseEventListener* listener) {
371 core_->RemoveMouseListener(listener);
372 }
373
374 size_t UserInputMonitorLinux::GetKeyPressCount() const {
375 return core_->GetKeyPressCount();
376 }
377
378 void UserInputMonitorLinux::StartKeyboardMonitoring() {
379 io_task_runner_->PostTask(
380 FROM_HERE,
381 base::Bind(&UserInputMonitorLinuxCore::StartMonitor,
382 core_->GetWeakPtr(),
383 UserInputMonitorLinuxCore::KEYBOARD_EVENT));
384 }
385
386 void UserInputMonitorLinux::StopKeyboardMonitoring() {
387 io_task_runner_->PostTask(
388 FROM_HERE,
389 base::Bind(&UserInputMonitorLinuxCore::StopMonitor,
390 core_->GetWeakPtr(),
391 UserInputMonitorLinuxCore::KEYBOARD_EVENT));
392 }
393
327 } // namespace 394 } // namespace
328 395
329 scoped_ptr<UserInputMonitor> UserInputMonitor::Create( 396 scoped_ptr<UserInputMonitor> UserInputMonitor::Create(
330 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 397 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
331 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) { 398 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner) {
332 return scoped_ptr<UserInputMonitor>( 399 return scoped_ptr<UserInputMonitor>(
333 new UserInputMonitorLinux(io_task_runner)); 400 new UserInputMonitorLinux(io_task_runner));
334 } 401 }
335 402
336 } // namespace media 403 } // namespace media
OLDNEW
« no previous file with comments | « media/base/user_input_monitor.cc ('k') | media/base/user_input_monitor_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698