| 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(int device_id, | 209 void EventFactoryEvdev::DispatchKeyEvent(int device_id, |
| 206 unsigned int code, | 210 unsigned int code, |
| 207 bool down) { | 211 bool down) { |
| 208 keyboard_.OnKeyChange(code, down); | 212 keyboard_.OnKeyChange(code, down); |
| 209 } | 213 } |
| 210 | 214 |
| 211 void EventFactoryEvdev::PostMouseMoveEvent(int device_id, | 215 void EventFactoryEvdev::DispatchMouseMoveEvent(int device_id, |
| 212 const gfx::PointF& location) { | 216 const gfx::PointF& location) { |
| 213 scoped_ptr<MouseEvent> event(new MouseEvent( | 217 scoped_ptr<MouseEvent> event(new MouseEvent( |
| 214 ui::ET_MOUSE_MOVED, location, location, modifiers_.GetModifierFlags(), | 218 ui::ET_MOUSE_MOVED, location, location, modifiers_.GetModifierFlags(), |
| 215 /* changed_button_flags */ 0)); | 219 /* changed_button_flags */ 0)); |
| 216 event->set_source_device_id(device_id); | 220 event->set_source_device_id(device_id); |
| 217 PostUiEvent(event.Pass()); | 221 PostUiEvent(event.Pass()); |
| 218 } | 222 } |
| 219 | 223 |
| 220 void EventFactoryEvdev::PostMouseButtonEvent(int device_id, | 224 void EventFactoryEvdev::DispatchMouseButtonEvent(int device_id, |
| 221 const gfx::PointF& location, | 225 const gfx::PointF& location, |
| 222 unsigned int button, | 226 unsigned int button, |
| 223 bool down, | 227 bool down, |
| 224 bool allow_remap) { | 228 bool allow_remap) { |
| 225 // Mouse buttons can be remapped, touchpad taps & clicks cannot. | 229 // Mouse buttons can be remapped, touchpad taps & clicks cannot. |
| 226 if (allow_remap) | 230 if (allow_remap) |
| 227 button = button_map_.GetMappedButton(button); | 231 button = button_map_.GetMappedButton(button); |
| 228 | 232 |
| 229 int modifier = EVDEV_MODIFIER_NONE; | 233 int modifier = EVDEV_MODIFIER_NONE; |
| 230 switch (button) { | 234 switch (button) { |
| 231 case BTN_LEFT: | 235 case BTN_LEFT: |
| 232 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; | 236 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; |
| 233 break; | 237 break; |
| 234 case BTN_RIGHT: | 238 case BTN_RIGHT: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 245 modifiers_.UpdateModifier(modifier, down); | 249 modifiers_.UpdateModifier(modifier, down); |
| 246 | 250 |
| 247 scoped_ptr<MouseEvent> event( | 251 scoped_ptr<MouseEvent> event( |
| 248 new MouseEvent(down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, | 252 new MouseEvent(down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, |
| 249 location, location, modifiers_.GetModifierFlags() | flag, | 253 location, location, modifiers_.GetModifierFlags() | flag, |
| 250 /* changed_button_flags */ flag)); | 254 /* changed_button_flags */ flag)); |
| 251 event->set_source_device_id(device_id); | 255 event->set_source_device_id(device_id); |
| 252 PostUiEvent(event.Pass()); | 256 PostUiEvent(event.Pass()); |
| 253 } | 257 } |
| 254 | 258 |
| 255 void EventFactoryEvdev::PostMouseWheelEvent(int device_id, | 259 void EventFactoryEvdev::DispatchMouseWheelEvent(int device_id, |
| 256 const gfx::PointF& location, | 260 const gfx::PointF& location, |
| 257 const gfx::Vector2d& delta) { | 261 const gfx::Vector2d& delta) { |
| 258 scoped_ptr<MouseWheelEvent> event(new MouseWheelEvent( | 262 scoped_ptr<MouseWheelEvent> event(new MouseWheelEvent( |
| 259 delta, location, location, modifiers_.GetModifierFlags(), | 263 delta, location, location, modifiers_.GetModifierFlags(), |
| 260 0 /* changed_button_flags */)); | 264 0 /* changed_button_flags */)); |
| 261 event->set_source_device_id(device_id); | 265 event->set_source_device_id(device_id); |
| 262 PostUiEvent(event.Pass()); | 266 PostUiEvent(event.Pass()); |
| 263 } | 267 } |
| 264 | 268 |
| 265 void EventFactoryEvdev::PostScrollEvent(const ScrollEventParams& params) { | 269 void EventFactoryEvdev::DispatchScrollEvent(const ScrollEventParams& params) { |
| 266 scoped_ptr<ScrollEvent> event(new ScrollEvent( | 270 scoped_ptr<ScrollEvent> event(new ScrollEvent( |
| 267 params.type, params.location, params.timestamp, | 271 params.type, params.location, params.timestamp, |
| 268 modifiers_.GetModifierFlags(), params.delta.x(), params.delta.y(), | 272 modifiers_.GetModifierFlags(), params.delta.x(), params.delta.y(), |
| 269 params.ordinal_delta.x(), params.ordinal_delta.y(), params.finger_count)); | 273 params.ordinal_delta.x(), params.ordinal_delta.y(), params.finger_count)); |
| 270 event->set_source_device_id(params.device_id); | 274 event->set_source_device_id(params.device_id); |
| 271 PostUiEvent(event.Pass()); | 275 PostUiEvent(event.Pass()); |
| 272 } | 276 } |
| 273 | 277 |
| 274 void EventFactoryEvdev::PostTouchEvent(const TouchEventParams& params) { | 278 void EventFactoryEvdev::DispatchTouchEvent(const TouchEventParams& params) { |
| 275 float x = params.location.x(); | 279 float x = params.location.x(); |
| 276 float y = params.location.y(); | 280 float y = params.location.y(); |
| 277 double radius_x = params.radii.x(); | 281 double radius_x = params.radii.x(); |
| 278 double radius_y = params.radii.y(); | 282 double radius_y = params.radii.y(); |
| 279 | 283 |
| 280 // Transform the event according (this is used to align touches | 284 // Transform the event according (this is used to align touches |
| 281 // to the image based on display mode). | 285 // to the image based on display mode). |
| 282 DeviceDataManager::GetInstance()->ApplyTouchTransformer(params.device_id, &x, | 286 DeviceDataManager::GetInstance()->ApplyTouchTransformer(params.device_id, &x, |
| 283 &y); | 287 &y); |
| 284 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id, | 288 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 | 335 |
| 332 switch (event.action_type()) { | 336 switch (event.action_type()) { |
| 333 case DeviceEvent::ADD: | 337 case DeviceEvent::ADD: |
| 334 case DeviceEvent::CHANGE: { | 338 case DeviceEvent::CHANGE: { |
| 335 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); | 339 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); |
| 336 | 340 |
| 337 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); | 341 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); |
| 338 params->id = NextDeviceId(); | 342 params->id = NextDeviceId(); |
| 339 params->path = event.path(); | 343 params->path = event.path(); |
| 340 params->cursor = cursor_; | 344 params->cursor = cursor_; |
| 341 params->key_callback = base::Bind(&EventFactoryEvdev::PostKeyEvent, | 345 params->dispatcher = this; |
| 342 weak_ptr_factory_.GetWeakPtr()); | |
| 343 params->mouse_move_callback = | |
| 344 base::Bind(&EventFactoryEvdev::PostMouseMoveEvent, | |
| 345 weak_ptr_factory_.GetWeakPtr()); | |
| 346 params->mouse_button_callback = | |
| 347 base::Bind(&EventFactoryEvdev::PostMouseButtonEvent, | |
| 348 weak_ptr_factory_.GetWeakPtr()); | |
| 349 params->mouse_wheel_callback = | |
| 350 base::Bind(&EventFactoryEvdev::PostMouseWheelEvent, | |
| 351 weak_ptr_factory_.GetWeakPtr()); | |
| 352 params->scroll_callback = base::Bind(&EventFactoryEvdev::PostScrollEvent, | |
| 353 weak_ptr_factory_.GetWeakPtr()); | |
| 354 params->touch_callback = base::Bind(&EventFactoryEvdev::PostTouchEvent, | |
| 355 weak_ptr_factory_.GetWeakPtr()); | |
| 356 | 346 |
| 357 #if defined(USE_EVDEV_GESTURES) | 347 #if defined(USE_EVDEV_GESTURES) |
| 358 params->gesture_property_provider = gesture_property_provider_.get(); | 348 params->gesture_property_provider = gesture_property_provider_.get(); |
| 359 #endif | 349 #endif |
| 360 | 350 |
| 361 OpenInputDeviceReplyCallback reply_callback = | 351 OpenInputDeviceReplyCallback reply_callback = |
| 362 base::Bind(&EventFactoryEvdev::AttachInputDevice, | 352 base::Bind(&EventFactoryEvdev::AttachInputDevice, |
| 363 weak_ptr_factory_.GetWeakPtr()); | 353 weak_ptr_factory_.GetWeakPtr()); |
| 364 | 354 |
| 365 // Dispatch task to open from the worker pool, since open may block. | 355 // Dispatch task to open from the worker pool, since open may block. |
| 366 base::WorkerPool::PostTask(FROM_HERE, | 356 base::WorkerPool::PostTask(FROM_HERE, |
| 367 base::Bind(&OpenInputDevice, | 357 base::Bind(&OpenInputDevice, |
| 368 base::Passed(¶ms), | 358 base::Passed(¶ms), |
| 369 ui_task_runner_, | 359 ui_task_runner_, |
| 370 reply_callback), | 360 reply_callback), |
| 371 true /* task_is_slow */); | 361 true /* task_is_slow */); |
| 372 } | 362 } |
| 373 break; | 363 break; |
| 374 case DeviceEvent::REMOVE: { | 364 case DeviceEvent::REMOVE: { |
| 375 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value()); | 365 TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value()); |
| 376 DetachInputDevice(event.path()); | 366 DetachInputDevice(event.path()); |
| 377 } | 367 } |
| 378 break; | 368 break; |
| 379 } | 369 } |
| 380 } | 370 } |
| 381 | 371 |
| 382 void EventFactoryEvdev::OnDispatcherListChanged() { | 372 void EventFactoryEvdev::OnDispatcherListChanged() { |
| 383 if (!ui_task_runner_.get()) { | 373 if (!initialized_) |
| 384 ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 374 Init(); |
| 385 // Scan & monitor devices. | |
| 386 device_manager_->AddObserver(this); | |
| 387 device_manager_->ScanDevices(this); | |
| 388 } | |
| 389 } | 375 } |
| 390 | 376 |
| 391 void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) { | 377 void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) { |
| 392 TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value()); | 378 TRACE_EVENT1("ozone", "DetachInputDevice", "path", path.value()); |
| 393 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); | 379 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); |
| 394 | 380 |
| 395 // Remove device from map. | 381 // Remove device from map. |
| 396 scoped_ptr<EventConverterEvdev> converter(converters_[path]); | 382 scoped_ptr<EventConverterEvdev> converter(converters_[path]); |
| 397 converters_.erase(path); | 383 converters_.erase(path); |
| 398 | 384 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 gesture_property_provider_->GetDeviceIdsByType(type, &ids); | 506 gesture_property_provider_->GetDeviceIdsByType(type, &ids); |
| 521 #endif | 507 #endif |
| 522 // In the future we can add other device matching logics here. | 508 // In the future we can add other device matching logics here. |
| 523 | 509 |
| 524 if (device_ids) | 510 if (device_ids) |
| 525 device_ids->assign(ids.begin(), ids.end()); | 511 device_ids->assign(ids.begin(), ids.end()); |
| 526 return !ids.empty(); | 512 return !ids.empty(); |
| 527 } | 513 } |
| 528 | 514 |
| 529 } // namespace ui | 515 } // namespace ui |
| OLD | NEW |