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/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 #if defined(USE_EVDEV_GESTURES) | 81 #if defined(USE_EVDEV_GESTURES) |
82 // Touchpad or mouse: use gestures library. | 82 // Touchpad or mouse: use gestures library. |
83 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent | 83 // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent |
84 if (UseGesturesLibraryForDevice(devinfo)) { | 84 if (UseGesturesLibraryForDevice(devinfo)) { |
85 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = | 85 scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = |
86 make_scoped_ptr(new GestureInterpreterLibevdevCros( | 86 make_scoped_ptr(new GestureInterpreterLibevdevCros( |
87 params.id, params.modifiers, params.button_map, params.cursor, | 87 params.id, params.modifiers, params.button_map, params.cursor, |
88 params.keyboard, params.gesture_property_provider, | 88 params.keyboard, params.gesture_property_provider, |
89 params.dispatch_callback)); | 89 params.dispatch_callback)); |
90 return make_scoped_ptr(new EventReaderLibevdevCros( | 90 return make_scoped_ptr(new EventReaderLibevdevCros( |
91 fd, params.path, params.id, type, gesture_interp.Pass())); | 91 fd, params.path, params.id, type, devinfo, gesture_interp.Pass())); |
92 } | 92 } |
93 #endif | 93 #endif |
94 | 94 |
95 // Touchscreen: use TouchEventConverterEvdev. | 95 // Touchscreen: use TouchEventConverterEvdev. |
96 if (devinfo.HasMTAbsXY()) { | 96 if (devinfo.HasMTAbsXY()) { |
97 scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev( | 97 scoped_ptr<TouchEventConverterEvdev> converter(new TouchEventConverterEvdev( |
98 fd, params.path, params.id, type, params.dispatch_callback)); | 98 fd, params.path, params.id, type, params.dispatch_callback)); |
99 converter->Initialize(devinfo); | 99 converter->Initialize(devinfo); |
100 return converter.Pass(); | 100 return converter.Pass(); |
101 } | 101 } |
102 | 102 |
103 // Graphics tablet | 103 // Graphics tablet |
104 if (devinfo.HasAbsXY()) | 104 if (devinfo.HasAbsXY()) |
105 return make_scoped_ptr<EventConverterEvdev>(new TabletEventConverterEvdev( | 105 return make_scoped_ptr<EventConverterEvdev>(new TabletEventConverterEvdev( |
106 fd, params.path, params.id, type, params.modifiers, params.cursor, | 106 fd, params.path, params.id, type, params.modifiers, params.cursor, |
107 devinfo, params.dispatch_callback)); | 107 devinfo, params.dispatch_callback)); |
108 | 108 |
109 // Everything else: use EventConverterEvdevImpl. | 109 // Everything else: use EventConverterEvdevImpl. |
110 return make_scoped_ptr<EventConverterEvdevImpl>(new EventConverterEvdevImpl( | 110 return make_scoped_ptr<EventConverterEvdevImpl>(new EventConverterEvdevImpl( |
111 fd, params.path, params.id, type, params.modifiers, | 111 fd, params.path, params.id, type, devinfo, params.modifiers, |
112 params.button_map, params.cursor, params.keyboard, | 112 params.button_map, params.cursor, params.keyboard, |
113 params.dispatch_callback)); | 113 params.dispatch_callback)); |
114 } | 114 } |
115 | 115 |
116 // Open an input device. Opening may put the calling thread to sleep, and | 116 // Open an input device. Opening may put the calling thread to sleep, and |
117 // therefore should be run on a thread where latency is not critical. We | 117 // therefore should be run on a thread where latency is not critical. We |
118 // run it on a thread from the worker pool. | 118 // run it on a thread from the worker pool. |
119 // | 119 // |
120 // This takes a TaskRunner and runs the reply on that thread, so that we | 120 // This takes a TaskRunner and runs the reply on that thread, so that we |
121 // can hop threads if necessary (back to the UI thread). | 121 // can hop threads if necessary (back to the UI thread). |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 | 217 |
218 // If we have an existing device, detach it. We don't want two | 218 // If we have an existing device, detach it. We don't want two |
219 // devices with the same name open at the same time. | 219 // devices with the same name open at the same time. |
220 if (converters_[path]) | 220 if (converters_[path]) |
221 DetachInputDevice(path); | 221 DetachInputDevice(path); |
222 | 222 |
223 // Add initialized device to map. | 223 // Add initialized device to map. |
224 converters_[path] = converter.release(); | 224 converters_[path] = converter.release(); |
225 converters_[path]->Start(); | 225 converters_[path]->Start(); |
226 | 226 |
227 NotifyHotplugEventObserver(*converters_[path]); | 227 NotifyDeviceChange(*converters_[path]); |
228 } | 228 } |
229 | 229 |
230 void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) { | 230 void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) { |
231 if (event.device_type() != DeviceEvent::INPUT) | 231 if (event.device_type() != DeviceEvent::INPUT) |
232 return; | 232 return; |
233 | 233 |
234 switch (event.action_type()) { | 234 switch (event.action_type()) { |
235 case DeviceEvent::ADD: | 235 case DeviceEvent::ADD: |
236 case DeviceEvent::CHANGE: { | 236 case DeviceEvent::CHANGE: { |
237 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); | 237 TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 | 284 |
285 // Remove device from map. | 285 // Remove device from map. |
286 scoped_ptr<EventConverterEvdev> converter(converters_[path]); | 286 scoped_ptr<EventConverterEvdev> converter(converters_[path]); |
287 converters_.erase(path); | 287 converters_.erase(path); |
288 | 288 |
289 if (converter) { | 289 if (converter) { |
290 // Cancel libevent notifications from this converter. This part must be | 290 // Cancel libevent notifications from this converter. This part must be |
291 // on UI since the polling happens on UI. | 291 // on UI since the polling happens on UI. |
292 converter->Stop(); | 292 converter->Stop(); |
293 | 293 |
294 NotifyHotplugEventObserver(*converter); | 294 NotifyDeviceChange(*converter); |
295 | 295 |
296 // Dispatch task to close from the worker pool, since close may block. | 296 // Dispatch task to close from the worker pool, since close may block. |
297 base::WorkerPool::PostTask( | 297 base::WorkerPool::PostTask( |
298 FROM_HERE, | 298 FROM_HERE, |
299 base::Bind(&CloseInputDevice, path, base::Passed(&converter)), | 299 base::Bind(&CloseInputDevice, path, base::Passed(&converter)), |
300 true); | 300 true); |
301 } | 301 } |
302 } | 302 } |
303 | 303 |
304 void EventFactoryEvdev::WarpCursorTo(gfx::AcceleratedWidget widget, | 304 void EventFactoryEvdev::WarpCursorTo(gfx::AcceleratedWidget widget, |
305 const gfx::PointF& location) { | 305 const gfx::PointF& location) { |
306 if (cursor_) { | 306 if (cursor_) { |
307 cursor_->MoveCursorTo(widget, location); | 307 cursor_->MoveCursorTo(widget, location); |
308 PostUiEvent(make_scoped_ptr(new MouseEvent(ET_MOUSE_MOVED, | 308 PostUiEvent(make_scoped_ptr(new MouseEvent(ET_MOUSE_MOVED, |
309 cursor_->GetLocation(), | 309 cursor_->GetLocation(), |
310 cursor_->GetLocation(), | 310 cursor_->GetLocation(), |
311 modifiers_.GetModifierFlags(), | 311 modifiers_.GetModifierFlags(), |
312 /* changed_button_flags */ 0))); | 312 /* changed_button_flags */ 0))); |
313 } | 313 } |
314 } | 314 } |
315 | 315 |
316 void EventFactoryEvdev::NotifyHotplugEventObserver( | 316 void EventFactoryEvdev::NotifyDeviceChange( |
317 const EventConverterEvdev& converter) { | 317 const EventConverterEvdev& converter) { |
318 // For now the only information propagated is related to touchscreens. Ignore | 318 if (converter.HasTouchscreen()) |
319 // events for everything but touchscreens. | 319 NotifyTouchscreensUpdated(); |
320 if (!converter.HasTouchscreen()) | |
321 return; | |
322 | 320 |
| 321 if (converter.HasKeyboard()) |
| 322 NotifyKeyboardsUpdated(); |
| 323 } |
| 324 |
| 325 void EventFactoryEvdev::NotifyTouchscreensUpdated() { |
323 DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance(); | 326 DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance(); |
324 std::vector<TouchscreenDevice> touchscreens; | 327 std::vector<TouchscreenDevice> touchscreens; |
325 for (auto it = converters_.begin(); it != converters_.end(); ++it) { | 328 for (auto it = converters_.begin(); it != converters_.end(); ++it) { |
326 if (it->second->HasTouchscreen()) { | 329 if (it->second->HasTouchscreen()) { |
327 touchscreens.push_back( | 330 touchscreens.push_back(TouchscreenDevice( |
328 TouchscreenDevice(it->second->id(), | 331 it->second->id(), it->second->type(), std::string() /* Device name */, |
329 it->second->type(), | 332 it->second->GetTouchscreenSize())); |
330 std::string(), /* Device name */ | |
331 it->second->GetTouchscreenSize())); | |
332 } | 333 } |
333 } | 334 } |
334 | 335 |
335 observer->OnTouchscreenDevicesUpdated(touchscreens); | 336 observer->OnTouchscreenDevicesUpdated(touchscreens); |
336 } | 337 } |
337 | 338 |
| 339 void EventFactoryEvdev::NotifyKeyboardsUpdated() { |
| 340 DeviceHotplugEventObserver* observer = DeviceDataManager::GetInstance(); |
| 341 std::vector<KeyboardDevice> keyboards; |
| 342 for (auto it = converters_.begin(); it != converters_.end(); ++it) { |
| 343 if (it->second->HasKeyboard()) { |
| 344 keyboards.push_back(KeyboardDevice(it->second->id(), it->second->type(), |
| 345 std::string() /* Device name */)); |
| 346 } |
| 347 } |
| 348 |
| 349 observer->OnKeyboardDevicesUpdated(keyboards); |
| 350 } |
| 351 |
338 int EventFactoryEvdev::NextDeviceId() { | 352 int EventFactoryEvdev::NextDeviceId() { |
339 return ++last_device_id_; | 353 return ++last_device_id_; |
340 } | 354 } |
341 | 355 |
342 bool EventFactoryEvdev::GetDeviceIdsByType(const EventDeviceType type, | 356 bool EventFactoryEvdev::GetDeviceIdsByType(const EventDeviceType type, |
343 std::vector<int>* device_ids) { | 357 std::vector<int>* device_ids) { |
344 if (device_ids) | 358 if (device_ids) |
345 device_ids->clear(); | 359 device_ids->clear(); |
346 std::vector<int> ids; | 360 std::vector<int> ids; |
347 | 361 |
348 #if defined(USE_EVDEV_GESTURES) | 362 #if defined(USE_EVDEV_GESTURES) |
349 // Ask GesturePropertyProvider for matching devices. | 363 // Ask GesturePropertyProvider for matching devices. |
350 gesture_property_provider_->GetDeviceIdsByType(type, &ids); | 364 gesture_property_provider_->GetDeviceIdsByType(type, &ids); |
351 #endif | 365 #endif |
352 // In the future we can add other device matching logics here. | 366 // In the future we can add other device matching logics here. |
353 | 367 |
354 if (device_ids) | 368 if (device_ids) |
355 device_ids->assign(ids.begin(), ids.end()); | 369 device_ids->assign(ids.begin(), ids.end()); |
356 return !ids.empty(); | 370 return !ids.empty(); |
357 } | 371 } |
358 | 372 |
359 } // namespace ui | 373 } // namespace ui |
OLD | NEW |