OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "ui/events/ozone/evdev/event_factory_evdev.h" | 5 #include "ui/events/ozone/evdev/event_factory_evdev.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <linux/input.h> | 8 #include <linux/input.h> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 typedef base::Callback<void(scoped_ptr<EventConverterEvdev>)> | 42 typedef base::Callback<void(scoped_ptr<EventConverterEvdev>)> |
43 OpenInputDeviceReplyCallback; | 43 OpenInputDeviceReplyCallback; |
44 | 44 |
45 struct OpenInputDeviceParams { | 45 struct OpenInputDeviceParams { |
46 // Unique identifier for the new device. | 46 // Unique identifier for the new device. |
47 int id; | 47 int id; |
48 | 48 |
49 // Device path to open. | 49 // Device path to open. |
50 base::FilePath path; | 50 base::FilePath path; |
51 | 51 |
52 // Callback for dispatching events. Call on UI thread only. | 52 // Dispatcher for events. Call on UI thread only. |
53 KeyEventDispatchCallback key_callback; | 53 DeviceEventDispatcherEvdev* dispatcher; |
54 MouseMoveEventDispatchCallback mouse_move_callback; | |
55 MouseButtonEventDispatchCallback mouse_button_callback; | |
56 MouseWheelEventDispatchCallback mouse_wheel_callback; | |
57 ScrollEventDispatchCallback scroll_callback; | |
58 TouchEventDispatchCallback touch_callback; | |
59 | 54 |
60 // State shared between devices. Must not be dereferenced on worker thread. | 55 // State shared between devices. Must not be dereferenced on worker thread. |
61 CursorDelegateEvdev* cursor; | 56 CursorDelegateEvdev* cursor; |
62 #if defined(USE_EVDEV_GESTURES) | 57 #if defined(USE_EVDEV_GESTURES) |
63 GesturePropertyProvider* gesture_property_provider; | 58 GesturePropertyProvider* gesture_property_provider; |
64 #endif | 59 #endif |
65 }; | 60 }; |
66 | 61 |
67 #if defined(USE_EVDEV_GESTURES) | 62 #if defined(USE_EVDEV_GESTURES) |
68 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) { | 63 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) { |
(...skipping 12 matching lines...) Expand all Loading... |
81 int fd, | 76 int fd, |
82 InputDeviceType type, | 77 InputDeviceType type, |
83 const EventDeviceInfo& devinfo) { | 78 const EventDeviceInfo& devinfo) { |
84 #if defined(USE_EVDEV_GESTURES) | 79 #if defined(USE_EVDEV_GESTURES) |
85 // Touchpad or mouse: use gestures library. | 80 // Touchpad or mouse: use gestures library. |
86 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent | 81 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent |
87 if (UseGesturesLibraryForDevice(devinfo)) { | 82 if (UseGesturesLibraryForDevice(devinfo)) { |
88 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = | 83 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = |
89 make_scoped_ptr(new GestureInterpreterLibevdevCros( | 84 make_scoped_ptr(new GestureInterpreterLibevdevCros( |
90 params.id, params.cursor, params.gesture_property_provider, | 85 params.id, params.cursor, params.gesture_property_provider, |
91 params.key_callback, params.mouse_move_callback, | 86 params.dispatcher)); |
92 params.mouse_button_callback, params.mouse_wheel_callback, | |
93 params.scroll_callback)); | |
94 return make_scoped_ptr(new EventReaderLibevdevCros( | 87 return make_scoped_ptr(new EventReaderLibevdevCros( |
95 fd, params.path, params.id, type, devinfo, gesture_interp.Pass())); | 88 fd, params.path, params.id, type, devinfo, gesture_interp.Pass())); |
96 } | 89 } |
97 #endif | 90 #endif |
98 | 91 |
99 // Touchscreen: use TouchEventConverterEvdev. | 92 // Touchscreen: use TouchEventConverterEvdev. |
100 if (devinfo.HasMTAbsXY()) { | 93 if (devinfo.HasMTAbsXY()) { |
101 scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev( | 94 scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev( |
102 fd, params.path, params.id, type, params.touch_callback)); | 95 fd, params.path, params.id, type, params.dispatcher)); |
103 converter->Initialize(devinfo); | 96 converter->Initialize(devinfo); |
104 return converter.Pass(); | 97 return converter.Pass(); |
105 } | 98 } |
106 | 99 |
107 // Graphics tablet | 100 // Graphics tablet |
108 if (devinfo.HasAbsXY()) | 101 if (devinfo.HasAbsXY()) |
109 return make_scoped_ptr<EventConverterEvdev>(new TabletEventConverterEvdev( | 102 return make_scoped_ptr<EventConverterEvdev>(new TabletEventConverterEvdev( |
110 fd, params.path, params.id, type, params.cursor, devinfo, | 103 fd, params.path, params.id, type, params.cursor, devinfo, |
111 params.mouse_move_callback, params.mouse_button_callback)); | 104 params.dispatcher)); |
112 | 105 |
113 // Everything else: use EventConverterEvdevImpl. | 106 // Everything else: use EventConverterEvdevImpl. |
114 return make_scoped_ptr<EventConverterEvdevImpl>(new EventConverterEvdevImpl( | 107 return make_scoped_ptr<EventConverterEvdevImpl>( |
115 fd, params.path, params.id, type, devinfo, params.cursor, | 108 new EventConverterEvdevImpl(fd, params.path, params.id, type, devinfo, |
116 params.key_callback, params.mouse_move_callback, | 109 params.cursor, params.dispatcher)); |
117 params.mouse_button_callback)); | |
118 } | 110 } |
119 | 111 |
120 // Open an input device. Opening may put the calling thread to sleep, and | 112 // Open an input device. Opening may put the calling thread to sleep, and |
121 // therefore should be run on a thread where latency is not critical. We | 113 // therefore should be run on a thread where latency is not critical. We |
122 // run it on a thread from the worker pool. | 114 // run it on a thread from the worker pool. |
123 // | 115 // |
124 // This takes a TaskRunner and runs the reply on that thread, so that we | 116 // This takes a TaskRunner and runs the reply on that thread, so that we |
125 // can hop threads if necessary (back to the UI thread). | 117 // can hop threads if necessary (back to the UI thread). |
126 void OpenInputDevice(scoped_ptr<OpenInputDeviceParams> params, | 118 void OpenInputDevice(scoped_ptr<OpenInputDeviceParams> params, |
127 scoped_refptr<base::TaskRunner> reply_runner, | 119 scoped_refptr<base::TaskRunner> reply_runner, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 gesture_property_provider_(new GesturePropertyProvider), | 176 gesture_property_provider_(new GesturePropertyProvider), |
185 #endif | 177 #endif |
186 input_controller_(this, | 178 input_controller_(this, |
187 &keyboard_, | 179 &keyboard_, |
188 &button_map_ | 180 &button_map_ |
189 #if defined(USE_EVDEV_GESTURES) | 181 #if defined(USE_EVDEV_GESTURES) |
190 , | 182 , |
191 gesture_property_provider_.get() | 183 gesture_property_provider_.get() |
192 #endif | 184 #endif |
193 ), | 185 ), |
| 186 initialized_(false), |
194 weak_ptr_factory_(this) { | 187 weak_ptr_factory_(this) { |
195 DCHECK(device_manager_); | 188 DCHECK(device_manager_); |
196 } | 189 } |
197 | 190 |
198 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); } | 191 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); } |
199 | 192 |
| 193 void EventFactoryEvdev::Init() { |
| 194 DCHECK(!initialized_); |
| 195 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 196 |
| 197 // Scan & monitor devices. |
| 198 device_manager_->AddObserver(this); |
| 199 device_manager_->ScanDevices(this); |
| 200 |
| 201 initialized_ = true; |
| 202 } |
| 203 |
200 scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() { | 204 scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() { |
201 return make_scoped_ptr(new InputInjectorEvdev( | 205 return make_scoped_ptr(new InputInjectorEvdev( |
202 &modifiers_, cursor_, &keyboard_, dispatch_callback_)); | 206 &modifiers_, cursor_, &keyboard_, dispatch_callback_)); |
203 } | 207 } |
204 | 208 |
205 void EventFactoryEvdev::PostKeyEvent(const KeyEventParams& params) { | 209 void EventFactoryEvdev::DispatchKeyEvent(const KeyEventParams& params) { |
206 keyboard_.OnKeyChange(params.code, params.down); | 210 keyboard_.OnKeyChange(params.code, params.down); |
207 } | 211 } |
208 | 212 |
209 void EventFactoryEvdev::PostMouseMoveEvent(const MouseMoveEventParams& params) { | 213 void EventFactoryEvdev::DispatchMouseMoveEvent( |
| 214 const MouseMoveEventParams& params) { |
210 scoped_ptr<MouseEvent> event(new MouseEvent(ui::ET_MOUSE_MOVED, | 215 scoped_ptr<MouseEvent> event(new MouseEvent(ui::ET_MOUSE_MOVED, |
211 params.location, params.location, | 216 params.location, params.location, |
212 modifiers_.GetModifierFlags(), | 217 modifiers_.GetModifierFlags(), |
213 /* changed_button_flags */ 0)); | 218 /* changed_button_flags */ 0)); |
214 event->set_source_device_id(params.device_id); | 219 event->set_source_device_id(params.device_id); |
215 PostUiEvent(event.Pass()); | 220 PostUiEvent(event.Pass()); |
216 } | 221 } |
217 | 222 |
218 void EventFactoryEvdev::PostMouseButtonEvent( | 223 void EventFactoryEvdev::DispatchMouseButtonEvent( |
219 const MouseButtonEventParams& params) { | 224 const MouseButtonEventParams& params) { |
220 // Mouse buttons can be remapped, touchpad taps & clicks cannot. | 225 // Mouse buttons can be remapped, touchpad taps & clicks cannot. |
221 unsigned int button = params.button; | 226 unsigned int button = params.button; |
222 if (params.allow_remap) | 227 if (params.allow_remap) |
223 button = button_map_.GetMappedButton(button); | 228 button = button_map_.GetMappedButton(button); |
224 | 229 |
225 int modifier = EVDEV_MODIFIER_NONE; | 230 int modifier = EVDEV_MODIFIER_NONE; |
226 switch (button) { | 231 switch (button) { |
227 case BTN_LEFT: | 232 case BTN_LEFT: |
228 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; | 233 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; |
(...skipping 12 matching lines...) Expand all Loading... |
241 modifiers_.UpdateModifier(modifier, params.down); | 246 modifiers_.UpdateModifier(modifier, params.down); |
242 | 247 |
243 scoped_ptr<MouseEvent> event(new MouseEvent( | 248 scoped_ptr<MouseEvent> event(new MouseEvent( |
244 params.down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, | 249 params.down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, |
245 params.location, params.location, modifiers_.GetModifierFlags() | flag, | 250 params.location, params.location, modifiers_.GetModifierFlags() | flag, |
246 /* changed_button_flags */ flag)); | 251 /* changed_button_flags */ flag)); |
247 event->set_source_device_id(params.device_id); | 252 event->set_source_device_id(params.device_id); |
248 PostUiEvent(event.Pass()); | 253 PostUiEvent(event.Pass()); |
249 } | 254 } |
250 | 255 |
251 void EventFactoryEvdev::PostMouseWheelEvent( | 256 void EventFactoryEvdev::DispatchMouseWheelEvent( |
252 const MouseWheelEventParams& params) { | 257 const MouseWheelEventParams& params) { |
253 scoped_ptr<MouseWheelEvent> event(new MouseWheelEvent( | 258 scoped_ptr<MouseWheelEvent> event(new MouseWheelEvent( |
254 params.delta, params.location, params.location, | 259 params.delta, params.location, params.location, |
255 modifiers_.GetModifierFlags(), 0 /* changed_button_flags */)); | 260 modifiers_.GetModifierFlags(), 0 /* changed_button_flags */)); |
256 event->set_source_device_id(params.device_id); | 261 event->set_source_device_id(params.device_id); |
257 PostUiEvent(event.Pass()); | 262 PostUiEvent(event.Pass()); |
258 } | 263 } |
259 | 264 |
260 void EventFactoryEvdev::PostScrollEvent(const ScrollEventParams& params) { | 265 void EventFactoryEvdev::DispatchScrollEvent(const ScrollEventParams& params) { |
261 scoped_ptr<ScrollEvent> event(new ScrollEvent( | 266 scoped_ptr<ScrollEvent> event(new ScrollEvent( |
262 params.type, params.location, params.timestamp, | 267 params.type, params.location, params.timestamp, |
263 modifiers_.GetModifierFlags(), params.delta.x(), params.delta.y(), | 268 modifiers_.GetModifierFlags(), params.delta.x(), params.delta.y(), |
264 params.ordinal_delta.x(), params.ordinal_delta.y(), params.finger_count)); | 269 params.ordinal_delta.x(), params.ordinal_delta.y(), params.finger_count)); |
265 event->set_source_device_id(params.device_id); | 270 event->set_source_device_id(params.device_id); |
266 PostUiEvent(event.Pass()); | 271 PostUiEvent(event.Pass()); |
267 } | 272 } |
268 | 273 |
269 void EventFactoryEvdev::PostTouchEvent(const TouchEventParams& params) { | 274 void EventFactoryEvdev::DispatchTouchEvent(const TouchEventParams& params) { |
270 float x = params.location.x(); | 275 float x = params.location.x(); |
271 float y = params.location.y(); | 276 float y = params.location.y(); |
272 double radius_x = params.radii.x(); | 277 double radius_x = params.radii.x(); |
273 double radius_y = params.radii.y(); | 278 double radius_y = params.radii.y(); |
274 | 279 |
275 // Transform the event to align touches to the image based on display mode. | 280 // Transform the event to align touches to the image based on display mode. |
276 DeviceDataManager::GetInstance()->ApplyTouchTransformer(params.device_id, &x, | 281 DeviceDataManager::GetInstance()->ApplyTouchTransformer(params.device_id, &x, |
277 &y); | 282 &y); |
278 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id, | 283 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id, |
279 &radius_x); | 284 &radius_x); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 | 330 |
326 switch (event.action_type()) { | 331 switch (event.action_type()) { |
327 case DeviceEvent::ADD: | 332 case DeviceEvent::ADD: |
328 case DeviceEvent::CHANGE: { | 333 case DeviceEvent::CHANGE: { |
329 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); | 334 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); |
330 | 335 |
331 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); | 336 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); |
332 params->id = NextDeviceId(); | 337 params->id = NextDeviceId(); |
333 params->path = event.path(); | 338 params->path = event.path(); |
334 params->cursor = cursor_; | 339 params->cursor = cursor_; |
335 params->key_callback = base::Bind(&EventFactoryEvdev::PostKeyEvent, | 340 params->dispatcher = this; |
336 weak_ptr_factory_.GetWeakPtr()); | |
337 params->mouse_move_callback = | |
338 base::Bind(&EventFactoryEvdev::PostMouseMoveEvent, | |
339 weak_ptr_factory_.GetWeakPtr()); | |
340 params->mouse_button_callback = | |
341 base::Bind(&EventFactoryEvdev::PostMouseButtonEvent, | |
342 weak_ptr_factory_.GetWeakPtr()); | |
343 params->mouse_wheel_callback = | |
344 base::Bind(&EventFactoryEvdev::PostMouseWheelEvent, | |
345 weak_ptr_factory_.GetWeakPtr()); | |
346 params->scroll_callback = base::Bind(&EventFactoryEvdev::PostScrollEvent, | |
347 weak_ptr_factory_.GetWeakPtr()); | |
348 params->touch_callback = base::Bind(&EventFactoryEvdev::PostTouchEvent, | |
349 weak_ptr_factory_.GetWeakPtr()); | |
350 | 341 |
351 #if defined(USE_EVDEV_GESTURES) | 342 #if defined(USE_EVDEV_GESTURES) |
352 params->gesture_property_provider = gesture_property_provider_.get(); | 343 params->gesture_property_provider = gesture_property_provider_.get(); |
353 #endif | 344 #endif |
354 | 345 |
355 OpenInputDeviceReplyCallback reply_callback = | 346 OpenInputDeviceReplyCallback reply_callback = |
356 base::Bind(&EventFactoryEvdev::AttachInputDevice, | 347 base::Bind(&EventFactoryEvdev::AttachInputDevice, |
357 weak_ptr_factory_.GetWeakPtr()); | 348 weak_ptr_factory_.GetWeakPtr()); |
358 | 349 |
359 // Dispatch task to open from the worker pool, since open may block. | 350 // Dispatch task to open from the worker pool, since open may block. |
360 base::WorkerPool::PostTask(FROM_HERE, | 351 base::WorkerPool::PostTask(FROM_HERE, |
361 base::Bind(&OpenInputDevice, | 352 base::Bind(&OpenInputDevice, |
362 base::Passed(¶ms), | 353 base::Passed(¶ms), |
363 ui_task_runner_, | 354 ui_task_runner_, |
364 reply_callback), | 355 reply_callback), |
365 true /* task_is_slow */); | 356 true /* task_is_slow */); |
366 } | 357 } |
367 break; | 358 break; |
368 case DeviceEvent::REMOVE: { | 359 case DeviceEvent::REMOVE: { |
369 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value()); | 360 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value()); |
370 DetachInputDevice(event.path()); | 361 DetachInputDevice(event.path()); |
371 } | 362 } |
372 break; | 363 break; |
373 } | 364 } |
374 } | 365 } |
375 | 366 |
376 void EventFactoryEvdev::OnDispatcherListChanged() { | 367 void EventFactoryEvdev::OnDispatcherListChanged() { |
377 if (!ui_task_runner_.get()) { | 368 if (!initialized_) |
378 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 369 Init(); |
379 // Scan & monitor devices. | |
380 device_manager_->AddObserver(this); | |
381 device_manager_->ScanDevices(this); | |
382 } | |
383 } | 370 } |
384 | 371 |
385 void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) { | 372 void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) { |
386 TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value()); | 373 TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value()); |
387 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 374 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
388 | 375 |
389 // Remove device from map. | 376 // Remove device from map. |
390 scoped_ptr<EventConverterEvdev> converter(converters_[path]); | 377 scoped_ptr<EventConverterEvdev> converter(converters_[path]); |
391 converters_.erase(path); | 378 converters_.erase(path); |
392 | 379 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 gesture_property_provider_->GetDeviceIdsByType(type, &ids); | 501 gesture_property_provider_->GetDeviceIdsByType(type, &ids); |
515 #endif | 502 #endif |
516 // In the future we can add other device matching logics here. | 503 // In the future we can add other device matching logics here. |
517 | 504 |
518 if (device_ids) | 505 if (device_ids) |
519 device_ids->assign(ids.begin(), ids.end()); | 506 device_ids->assign(ids.begin(), ids.end()); |
520 return !ids.empty(); | 507 return !ids.empty(); |
521 } | 508 } |
522 | 509 |
523 } // namespace ui | 510 } // namespace ui |
OLD | NEW |