Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / events / ozone / evdev / event_factory_evdev.cc
index cf9a607..47b46b4 100644 (file)
 #include "base/debug/trace_event.h"
 #include "base/stl_util.h"
 #include "base/task_runner.h"
+#include "ui/events/ozone/device/device_event.h"
+#include "ui/events/ozone/device/device_manager.h"
 #include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
-#include "ui/events/ozone/evdev/device_manager_evdev.h"
 #include "ui/events/ozone/evdev/event_device_info.h"
 #include "ui/events/ozone/evdev/key_event_converter_evdev.h"
 #include "ui/events/ozone/evdev/touch_event_converter_evdev.h"
 
-#if defined(USE_UDEV)
-#include "ui/events/ozone/evdev/device_manager_udev.h"
+#if defined(USE_EVDEV_GESTURES)
+#include "ui/events/ozone/evdev/libgestures_glue/event_reader_libevdev_cros.h"
+#include "ui/events/ozone/evdev/libgestures_glue/gesture_interpreter_libevdev_cros.h"
 #endif
 
 #ifndef EVIOCSCLOCKID
@@ -28,16 +30,49 @@ namespace ui {
 
 namespace {
 
-bool IsTouchPad(const EventDeviceInfo& devinfo) {
-  if (!devinfo.HasEventType(EV_ABS))
-    return false;
+#if defined(USE_EVDEV_GESTURES)
+bool UseGesturesLibraryForDevice(const EventDeviceInfo& devinfo) {
+  if (devinfo.HasAbsXY() && !devinfo.IsMappedToScreen())
+    return true;  // touchpad
 
-  return devinfo.HasKeyEvent(BTN_LEFT) || devinfo.HasKeyEvent(BTN_MIDDLE) ||
-         devinfo.HasKeyEvent(BTN_RIGHT) || devinfo.HasKeyEvent(BTN_TOOL_FINGER);
+  if (devinfo.HasRelXY())
+    return true;  // mouse
+
+  return false;
 }
+#endif
+
+scoped_ptr<EventConverterEvdev> CreateConverter(
+    int fd,
+    const base::FilePath& path,
+    const EventDeviceInfo& devinfo,
+    const EventDispatchCallback& dispatch,
+    EventModifiersEvdev* modifiers,
+    CursorDelegateEvdev* cursor) {
+#if defined(USE_EVDEV_GESTURES)
+  // Touchpad or mouse: use gestures library.
+  // EventReaderLibevdevCros -> GestureInterpreterLibevdevCros -> DispatchEvent
+  if (UseGesturesLibraryForDevice(devinfo)) {
+    scoped_ptr<GestureInterpreterLibevdevCros> gesture_interp = make_scoped_ptr(
+        new GestureInterpreterLibevdevCros(modifiers, cursor, dispatch));
+    scoped_ptr<EventReaderLibevdevCros> libevdev_reader =
+        make_scoped_ptr(new EventReaderLibevdevCros(
+            fd,
+            path,
+            gesture_interp.PassAs<EventReaderLibevdevCros::Delegate>()));
+    return libevdev_reader.PassAs<EventConverterEvdev>();
+  }
+#endif
 
-bool IsTouchScreen(const EventDeviceInfo& devinfo) {
-  return devinfo.HasEventType(EV_ABS) && !IsTouchPad(devinfo);
+  // Touchscreen: use TouchEventConverterEvdev.
+  scoped_ptr<EventConverterEvdev> converter;
+  if (devinfo.HasAbsXY())
+    return make_scoped_ptr<EventConverterEvdev>(
+        new TouchEventConverterEvdev(fd, path, devinfo, dispatch));
+
+  // Everything else: use KeyEventConverterEvdev.
+  return make_scoped_ptr<EventConverterEvdev>(
+      new KeyEventConverterEvdev(fd, path, modifiers, dispatch));
 }
 
 // Open an input device. Opening may put the calling thread to sleep, and
@@ -51,6 +86,7 @@ void OpenInputDevice(
     EventModifiersEvdev* modifiers,
     CursorDelegateEvdev* cursor,
     scoped_refptr<base::TaskRunner> reply_runner,
+    const EventDispatchCallback& dispatch,
     base::Callback<void(scoped_ptr<EventConverterEvdev>)> reply_callback) {
   TRACE_EVENT1("ozone", "OpenInputDevice", "path", path.value());
 
@@ -74,26 +110,12 @@ void OpenInputDevice(
     return;
   }
 
-  if (IsTouchPad(devinfo)) {
-    LOG(WARNING) << "touchpad device not supported: " << path.value();
-    close(fd);
-    return;
-  }
-
-  // TODO(spang) Add more device types.
-  scoped_ptr<EventConverterEvdev> converter;
-  if (IsTouchScreen(devinfo))
-    converter.reset(new TouchEventConverterEvdev(fd, path, devinfo));
-  else if (devinfo.HasEventType(EV_KEY))
-    converter.reset(new KeyEventConverterEvdev(fd, path, modifiers));
+  scoped_ptr<EventConverterEvdev> converter =
+      CreateConverter(fd, path, devinfo, dispatch, modifiers, cursor);
 
-  if (converter) {
-    // Reply with the constructed converter.
-    reply_runner->PostTask(
-        FROM_HERE, base::Bind(reply_callback, base::Passed(&converter)));
-  } else {
-    close(fd);
-  }
+  // Reply with the constructed converter.
+  reply_runner->PostTask(FROM_HERE,
+                         base::Bind(reply_callback, base::Passed(&converter)));
 }
 
 // Close an input device. Closing may put the calling thread to sleep, and
@@ -108,19 +130,35 @@ void CloseInputDevice(const base::FilePath& path,
 }  // namespace
 
 EventFactoryEvdev::EventFactoryEvdev()
-    : ui_task_runner_(base::MessageLoopProxy::current()),
+    : device_manager_(NULL),
+      has_started_processing_events_(false),
+      ui_task_runner_(base::MessageLoopProxy::current()),
       file_task_runner_(base::MessageLoopProxy::current()),
       cursor_(NULL),
+      dispatch_callback_(
+          base::Bind(base::IgnoreResult(&EventFactoryEvdev::DispatchUiEvent),
+                     base::Unretained(this))),
       weak_ptr_factory_(this) {}
 
-EventFactoryEvdev::EventFactoryEvdev(CursorDelegateEvdev* cursor)
-    : ui_task_runner_(base::MessageLoopProxy::current()),
+EventFactoryEvdev::EventFactoryEvdev(
+    CursorDelegateEvdev* cursor,
+    DeviceManager* device_manager)
+    : device_manager_(device_manager),
+      has_started_processing_events_(false),
+      ui_task_runner_(base::MessageLoopProxy::current()),
       file_task_runner_(base::MessageLoopProxy::current()),
       cursor_(cursor),
+      dispatch_callback_(
+          base::Bind(base::IgnoreResult(&EventFactoryEvdev::DispatchUiEvent),
+                     base::Unretained(this))),
       weak_ptr_factory_(this) {}
 
 EventFactoryEvdev::~EventFactoryEvdev() { STLDeleteValues(&converters_); }
 
+void EventFactoryEvdev::DispatchUiEvent(Event* event) {
+  EventFactoryOzone::DispatchEvent(event);
+}
+
 void EventFactoryEvdev::AttachInputDevice(
     const base::FilePath& path,
     scoped_ptr<EventConverterEvdev> converter) {
@@ -137,20 +175,35 @@ void EventFactoryEvdev::AttachInputDevice(
   converters_[path]->Start();
 }
 
-void EventFactoryEvdev::OnDeviceAdded(const base::FilePath& path) {
-  TRACE_EVENT1("ozone", "OnDeviceAdded", "path", path.value());
-
-  // Dispatch task to open on FILE thread, since open may block.
-  file_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&OpenInputDevice,
-                 path,
-                 &modifiers_,
-                 cursor_,
-                 ui_task_runner_,
-                 base::Bind(&EventFactoryEvdev::AttachInputDevice,
-                            weak_ptr_factory_.GetWeakPtr(),
-                            path)));
+void EventFactoryEvdev::OnDeviceEvent(const DeviceEvent& event) {
+  if (event.device_type() != DeviceEvent::INPUT)
+    return;
+
+  switch (event.action_type()) {
+    case DeviceEvent::ADD:
+    case DeviceEvent::CHANGE: {
+      TRACE_EVENT1("ozone", "OnDeviceAdded", "path", event.path().value());
+
+      // Dispatch task to open on FILE thread, since open may block.
+      file_task_runner_->PostTask(
+          FROM_HERE,
+          base::Bind(&OpenInputDevice,
+                     event.path(),
+                     &modifiers_,
+                     cursor_,
+                     ui_task_runner_,
+                     dispatch_callback_,
+                     base::Bind(&EventFactoryEvdev::AttachInputDevice,
+                                weak_ptr_factory_.GetWeakPtr(),
+                                event.path())));
+    }
+      break;
+    case DeviceEvent::REMOVE: {
+      TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", event.path().value());
+      DetachInputDevice(event.path());
+    }
+      break;
+  }
 }
 
 void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) {
@@ -173,26 +226,15 @@ void EventFactoryEvdev::DetachInputDevice(const base::FilePath& path) {
   }
 }
 
-void EventFactoryEvdev::OnDeviceRemoved(const base::FilePath& path) {
-  TRACE_EVENT1("ozone", "OnDeviceRemoved", "path", path.value());
-  DetachInputDevice(path);
-}
-
 void EventFactoryEvdev::StartProcessingEvents() {
   CHECK(ui_task_runner_->RunsTasksOnCurrentThread());
 
-#if defined(USE_UDEV)
-  // Scan for input devices using udev.
-  device_manager_ = CreateDeviceManagerUdev();
-#else
-  // No udev support. Scan devices manually in /dev/input.
-  device_manager_ = CreateDeviceManagerManual();
-#endif
-
-  // Scan & monitor devices.
-  device_manager_->ScanAndStartMonitoring(
-      base::Bind(&EventFactoryEvdev::OnDeviceAdded, base::Unretained(this)),
-      base::Bind(&EventFactoryEvdev::OnDeviceRemoved, base::Unretained(this)));
+  if (device_manager_ && !has_started_processing_events_) {
+    has_started_processing_events_ = true;
+    // Scan & monitor devices.
+    device_manager_->AddObserver(this);
+    device_manager_->ScanDevices(this);
+  }
 }
 
 void EventFactoryEvdev::SetFileTaskRunner(
@@ -204,12 +246,12 @@ void EventFactoryEvdev::WarpCursorTo(gfx::AcceleratedWidget widget,
                                      const gfx::PointF& location) {
   if (cursor_) {
     cursor_->MoveCursorTo(widget, location);
-    scoped_ptr<Event> ev(new MouseEvent(ET_MOUSE_MOVED,
-                                      cursor_->location(),
-                                      cursor_->location(),
-                                      modifiers_.GetModifierFlags(),
-                                      /* changed_button_flags */ 0));
-    DispatchEvent(ev.Pass());
+    MouseEvent mouse_event(ET_MOUSE_MOVED,
+                           cursor_->location(),
+                           cursor_->location(),
+                           modifiers_.GetModifierFlags(),
+                           /* changed_button_flags */ 0);
+    DispatchEvent(&mouse_event);
   }
 }