| 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 |