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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 // Callback for dispatching events. Call on UI thread only. |
53 EventDispatchCallback dispatch_callback; | 53 EventDispatchCallback dispatch_callback; |
54 KeyEventDispatchCallback key_callback; | 54 KeyEventDispatchCallback key_callback; |
| 55 MouseMoveEventDispatchCallback mouse_move_callback; |
| 56 MouseButtonEventDispatchCallback mouse_button_callback; |
55 TouchEventDispatchCallback touch_callback; | 57 TouchEventDispatchCallback touch_callback; |
56 | 58 |
57 // State shared between devices. Must not be dereferenced on worker thread. | 59 // State shared between devices. Must not be dereferenced on worker thread. |
58 EventModifiersEvdev* modifiers; | 60 EventModifiersEvdev* modifiers; |
59 MouseButtonMapEvdev* button_map; | |
60 CursorDelegateEvdev* cursor; | 61 CursorDelegateEvdev* cursor; |
61 #if defined(USE_EVDEV_GESTURES) | 62 #if defined(USE_EVDEV_GESTURES) |
62 GesturePropertyProvider* gesture_property_provider; | 63 GesturePropertyProvider* gesture_property_provider; |
63 #endif | 64 #endif |
64 }; | 65 }; |
65 | 66 |
66 #if defined(USE_EVDEV_GESTURES) | 67 #if defined(USE_EVDEV_GESTURES) |
67 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) { | 68 bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) { |
68 if (devinfo.HasTouchpad()) | 69 if (devinfo.HasTouchpad()) |
69 return true; | 70 return true; |
70 | 71 |
71 if (devinfo.HasRelXY()) | 72 if (devinfo.HasRelXY()) |
72 return true; // mouse | 73 return true; // mouse |
73 | 74 |
74 return false; | 75 return false; |
75 } | 76 } |
76 #endif | 77 #endif |
77 | 78 |
78 scoped_ptr<EventConverterEvdev> CreateConverter( | 79 scoped_ptr<EventConverterEvdev> CreateConverter( |
79 const OpenInputDeviceParams& params, | 80 const OpenInputDeviceParams& params, |
80 int fd, | 81 int fd, |
81 InputDeviceType type, | 82 InputDeviceType type, |
82 const EventDeviceInfo& devinfo) { | 83 const EventDeviceInfo& devinfo) { |
83 #if defined(USE_EVDEV_GESTURES) | 84 #if defined(USE_EVDEV_GESTURES) |
84 // Touchpad or mouse: use gestures library. | 85 // Touchpad or mouse: use gestures library. |
85 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent | 86 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent |
86 if (UseGesturesLibraryForDevice(devinfo)) { | 87 if (UseGesturesLibraryForDevice(devinfo)) { |
87 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = | 88 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = |
88 make_scoped_ptr(new GestureInterpreterLibevdevCros( | 89 make_scoped_ptr(new GestureInterpreterLibevdevCros( |
89 params.id, params.modifiers, params.button_map, params.cursor, | 90 params.id, params.modifiers, params.cursor, |
90 params.gesture_property_provider, params.key_callback, | 91 params.gesture_property_provider, params.key_callback, |
| 92 params.mouse_move_callback, params.mouse_button_callback, |
91 params.dispatch_callback)); | 93 params.dispatch_callback)); |
92 return make_scoped_ptr(new EventReaderLibevdevCros( | 94 return make_scoped_ptr(new EventReaderLibevdevCros( |
93 fd, params.path, params.id, type, devinfo, gesture_interp.Pass())); | 95 fd, params.path, params.id, type, devinfo, gesture_interp.Pass())); |
94 } | 96 } |
95 #endif | 97 #endif |
96 | 98 |
97 // Touchscreen: use TouchEventConverterEvdev. | 99 // Touchscreen: use TouchEventConverterEvdev. |
98 if (devinfo.HasMTAbsXY()) { | 100 if (devinfo.HasMTAbsXY()) { |
99 scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev( | 101 scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev( |
100 fd, params.path, params.id, type, params.touch_callback)); | 102 fd, params.path, params.id, type, params.touch_callback)); |
101 converter->Initialize(devinfo); | 103 converter->Initialize(devinfo); |
102 return converter.Pass(); | 104 return converter.Pass(); |
103 } | 105 } |
104 | 106 |
105 // Graphics tablet | 107 // Graphics tablet |
106 if (devinfo.HasAbsXY()) | 108 if (devinfo.HasAbsXY()) |
107 return make_scoped_ptr<EventConverterEvdev>(new TabletEventConverterEvdev( | 109 return make_scoped_ptr<EventConverterEvdev>(new TabletEventConverterEvdev( |
108 fd, params.path, params.id, type, params.modifiers, params.cursor, | 110 fd, params.path, params.id, type, params.modifiers, params.cursor, |
109 devinfo, params.dispatch_callback)); | 111 devinfo, params.dispatch_callback)); |
110 | 112 |
111 // Everything else: use EventConverterEvdevImpl. | 113 // Everything else: use EventConverterEvdevImpl. |
112 return make_scoped_ptr<EventConverterEvdevImpl>(new EventConverterEvdevImpl( | 114 return make_scoped_ptr<EventConverterEvdevImpl>(new EventConverterEvdevImpl( |
113 fd, params.path, params.id, type, devinfo, params.modifiers, | 115 fd, params.path, params.id, type, devinfo, params.modifiers, |
114 params.button_map, params.cursor, params.key_callback, | 116 params.cursor, params.key_callback, params.mouse_move_callback, |
115 params.dispatch_callback)); | 117 params.mouse_button_callback)); |
116 } | 118 } |
117 | 119 |
118 // Open an input device. Opening may put the calling thread to sleep, and | 120 // Open an input device. Opening may put the calling thread to sleep, and |
119 // therefore should be run on a thread where latency is not critical. We | 121 // therefore should be run on a thread where latency is not critical. We |
120 // run it on a thread from the worker pool. | 122 // run it on a thread from the worker pool. |
121 // | 123 // |
122 // This takes a TaskRunner and runs the reply on that thread, so that we | 124 // This takes a TaskRunner and runs the reply on that thread, so that we |
123 // can hop threads if necessary (back to the UI thread). | 125 // can hop threads if necessary (back to the UI thread). |
124 void OpenInputDevice(scoped_ptr<OpenInputDeviceParams> params, | 126 void OpenInputDevice(scoped_ptr<OpenInputDeviceParams> params, |
125 scoped_refptr<base::TaskRunner> reply_runner, | 127 scoped_refptr<base::TaskRunner> reply_runner, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 | 199 |
198 scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() { | 200 scoped_ptr<SystemInputInjector> EventFactoryEvdev::CreateSystemInputInjector() { |
199 return make_scoped_ptr(new InputInjectorEvdev( | 201 return make_scoped_ptr(new InputInjectorEvdev( |
200 &modifiers_, cursor_, &keyboard_, dispatch_callback_)); | 202 &modifiers_, cursor_, &keyboard_, dispatch_callback_)); |
201 } | 203 } |
202 | 204 |
203 void EventFactoryEvdev::PostKeyEvent(const KeyEventParams& params) { | 205 void EventFactoryEvdev::PostKeyEvent(const KeyEventParams& params) { |
204 keyboard_.OnKeyChange(params.code, params.down); | 206 keyboard_.OnKeyChange(params.code, params.down); |
205 } | 207 } |
206 | 208 |
| 209 void EventFactoryEvdev::PostMouseMoveEvent(const MouseMoveEventParams& params) { |
| 210 scoped_ptr<MouseEvent> event(new MouseEvent(ui::ET_MOUSE_MOVED, |
| 211 params.location, params.location, |
| 212 modifiers_.GetModifierFlags(), |
| 213 /* changed_button_flags */ 0)); |
| 214 event->set_source_device_id(params.device_id); |
| 215 PostUiEvent(event.Pass()); |
| 216 } |
| 217 |
| 218 void EventFactoryEvdev::PostMouseButtonEvent( |
| 219 const MouseButtonEventParams& params) { |
| 220 // Mouse buttons can be remapped, touchpad taps & clicks cannot. |
| 221 unsigned int button = params.button; |
| 222 if (params.allow_remap) |
| 223 button = button_map_.GetMappedButton(button); |
| 224 |
| 225 int modifier = EVDEV_MODIFIER_NONE; |
| 226 switch (button) { |
| 227 case BTN_LEFT: |
| 228 modifier = EVDEV_MODIFIER_LEFT_MOUSE_BUTTON; |
| 229 break; |
| 230 case BTN_RIGHT: |
| 231 modifier = EVDEV_MODIFIER_RIGHT_MOUSE_BUTTON; |
| 232 break; |
| 233 case BTN_MIDDLE: |
| 234 modifier = EVDEV_MODIFIER_MIDDLE_MOUSE_BUTTON; |
| 235 break; |
| 236 default: |
| 237 return; |
| 238 } |
| 239 |
| 240 int flag = modifiers_.GetEventFlagFromModifier(modifier); |
| 241 modifiers_.UpdateModifier(modifier, params.down); |
| 242 |
| 243 scoped_ptr<MouseEvent> event(new MouseEvent( |
| 244 params.down ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, |
| 245 params.location, params.location, modifiers_.GetModifierFlags() | flag, |
| 246 /* changed_button_flags */ flag)); |
| 247 event->set_source_device_id(params.device_id); |
| 248 PostUiEvent(event.Pass()); |
| 249 } |
| 250 |
207 void EventFactoryEvdev::PostTouchEvent(const TouchEventParams& params) { | 251 void EventFactoryEvdev::PostTouchEvent(const TouchEventParams& params) { |
208 float x = params.location.x(); | 252 float x = params.location.x(); |
209 float y = params.location.y(); | 253 float y = params.location.y(); |
210 double radius_x = params.radii.x(); | 254 double radius_x = params.radii.x(); |
211 double radius_y = params.radii.y(); | 255 double radius_y = params.radii.y(); |
212 | 256 |
213 // Transform the event to align touches to the image based on display mode. | 257 // Transform the event to align touches to the image based on display mode. |
214 DeviceDataManager::GetInstance()->ApplyTouchTransformer(params.device_id, &x, | 258 DeviceDataManager::GetInstance()->ApplyTouchTransformer(params.device_id, &x, |
215 &y); | 259 &y); |
216 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id, | 260 DeviceDataManager::GetInstance()->ApplyTouchRadiusScale(params.device_id, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 switch (event.action_type()) { | 308 switch (event.action_type()) { |
265 case DeviceEvent::ADD: | 309 case DeviceEvent::ADD: |
266 case DeviceEvent::CHANGE: { | 310 case DeviceEvent::CHANGE: { |
267 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); | 311 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); |
268 | 312 |
269 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); | 313 scoped_ptr<OpenInputDeviceParams> params(new OpenInputDeviceParams); |
270 params->id = NextDeviceId(); | 314 params->id = NextDeviceId(); |
271 params->path = event.path(); | 315 params->path = event.path(); |
272 params->dispatch_callback = dispatch_callback_; | 316 params->dispatch_callback = dispatch_callback_; |
273 params->modifiers = &modifiers_; | 317 params->modifiers = &modifiers_; |
274 params->button_map = &button_map_; | |
275 params->cursor = cursor_; | 318 params->cursor = cursor_; |
276 params->key_callback = base::Bind(&EventFactoryEvdev::PostKeyEvent, | 319 params->key_callback = base::Bind(&EventFactoryEvdev::PostKeyEvent, |
277 weak_ptr_factory_.GetWeakPtr()); | 320 weak_ptr_factory_.GetWeakPtr()); |
| 321 params->mouse_move_callback = |
| 322 base::Bind(&EventFactoryEvdev::PostMouseMoveEvent, |
| 323 weak_ptr_factory_.GetWeakPtr()); |
| 324 params->mouse_button_callback = |
| 325 base::Bind(&EventFactoryEvdev::PostMouseButtonEvent, |
| 326 weak_ptr_factory_.GetWeakPtr()); |
278 params->touch_callback = base::Bind(&EventFactoryEvdev::PostTouchEvent, | 327 params->touch_callback = base::Bind(&EventFactoryEvdev::PostTouchEvent, |
279 weak_ptr_factory_.GetWeakPtr()); | 328 weak_ptr_factory_.GetWeakPtr()); |
280 | 329 |
281 #if defined(USE_EVDEV_GESTURES) | 330 #if defined(USE_EVDEV_GESTURES) |
282 params->gesture_property_provider = gesture_property_provider_.get(); | 331 params->gesture_property_provider = gesture_property_provider_.get(); |
283 #endif | 332 #endif |
284 | 333 |
285 OpenInputDeviceReplyCallback reply_callback = | 334 OpenInputDeviceReplyCallback reply_callback = |
286 base::Bind(&EventFactoryEvdev::AttachInputDevice, | 335 base::Bind(&EventFactoryEvdev::AttachInputDevice, |
287 weak_ptr_factory_.GetWeakPtr()); | 336 weak_ptr_factory_.GetWeakPtr()); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 gesture_property_provider_->GetDeviceIdsByType(type, &ids); | 493 gesture_property_provider_->GetDeviceIdsByType(type, &ids); |
445 #endif | 494 #endif |
446 // In the future we can add other device matching logics here. | 495 // In the future we can add other device matching logics here. |
447 | 496 |
448 if (device_ids) | 497 if (device_ids) |
449 device_ids->assign(ids.begin(), ids.end()); | 498 device_ids->assign(ids.begin(), ids.end()); |
450 return !ids.empty(); | 499 return !ids.empty(); |
451 } | 500 } |
452 | 501 |
453 } // namespace ui | 502 } // namespace ui |
OLD | NEW |