[mutter/wip/garnacho/virtual-input-device: 102/107] ClutterVirtualInputDeviceEvdev: Forward button and key presses



commit c2ce0e67956f2308912253d9cd897804331f6f13
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed Jun 22 17:56:44 2016 +0800

    ClutterVirtualInputDeviceEvdev: Forward button and key presses
    
    https://bugzilla.gnome.org/show_bug.cgi?id=765009

 .../evdev/clutter-virtual-input-device-evdev.c     |  145 ++++++++++++++++++++
 1 files changed, 145 insertions(+), 0 deletions(-)
---
diff --git a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c 
b/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c
index d6517d5..b4925e1 100644
--- a/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c
+++ b/clutter/clutter/evdev/clutter-virtual-input-device-evdev.c
@@ -26,6 +26,7 @@
 #endif
 
 #include <glib-object.h>
+#include <linux/input.h>
 
 #include "clutter-private.h"
 #include "clutter-virtual-input-device.h"
@@ -50,12 +51,107 @@ struct _ClutterVirtualInputDeviceEvdev
 
   ClutterInputDevice *device;
   ClutterSeatEvdev *seat;
+  int button_count[KEY_CNT];
 };
 
 G_DEFINE_TYPE (ClutterVirtualInputDeviceEvdev,
                clutter_virtual_input_device_evdev,
                CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE)
 
+typedef enum _EvdevButtonType
+{
+  EVDEV_BUTTON_TYPE_NONE,
+  EVDEV_BUTTON_TYPE_KEY,
+  EVDEV_BUTTON_TYPE_BUTTON,
+} EvdevButtonType;
+
+static int
+update_button_count (ClutterVirtualInputDeviceEvdev *virtual_evdev,
+                     uint32_t                        button,
+                     uint32_t                        state)
+{
+  if (state)
+    {
+      return ++virtual_evdev->button_count[button];
+    }
+  else
+    {
+      /* Handle cases where we newer saw the initial pressed event. */
+      if (virtual_evdev->button_count[button] == 0)
+        return 0;
+
+      return --virtual_evdev->button_count[button];
+    }
+}
+
+static EvdevButtonType
+get_button_type (uint16_t code)
+{
+  switch (code)
+    {
+    case BTN_TOOL_PEN:
+    case BTN_TOOL_RUBBER:
+    case BTN_TOOL_BRUSH:
+    case BTN_TOOL_PENCIL:
+    case BTN_TOOL_AIRBRUSH:
+    case BTN_TOOL_MOUSE:
+    case BTN_TOOL_LENS:
+    case BTN_TOOL_QUINTTAP:
+    case BTN_TOOL_DOUBLETAP:
+    case BTN_TOOL_TRIPLETAP:
+    case BTN_TOOL_QUADTAP:
+    case BTN_TOOL_FINGER:
+    case BTN_TOUCH:
+      return EVDEV_BUTTON_TYPE_NONE;
+    }
+
+  if (code >= KEY_ESC && code <= KEY_MICMUTE)
+    return EVDEV_BUTTON_TYPE_KEY;
+  if (code >= BTN_MISC && code <= BTN_GEAR_UP)
+    return EVDEV_BUTTON_TYPE_BUTTON;
+  if (code >= KEY_OK && code <= KEY_LIGHTS_TOGGLE)
+    return EVDEV_BUTTON_TYPE_KEY;
+  if (code >= BTN_DPAD_UP && code <= BTN_DPAD_RIGHT)
+    return EVDEV_BUTTON_TYPE_BUTTON;
+  if (code >= KEY_ALS_TOGGLE && code <= KEY_KBDINPUTASSIST_CANCEL)
+    return EVDEV_BUTTON_TYPE_KEY;
+  if (code >= BTN_TRIGGER_HAPPY && code <= BTN_TRIGGER_HAPPY40)
+    return EVDEV_BUTTON_TYPE_BUTTON;
+  return EVDEV_BUTTON_TYPE_NONE;
+}
+
+static void
+release_pressed_buttons (ClutterVirtualInputDevice *virtual_device)
+{
+  ClutterVirtualInputDeviceEvdev *virtual_evdev =
+    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
+  int code;
+  uint64_t time_us;
+
+  time_us = g_get_monotonic_time ();
+
+  for (code = 0; code < G_N_ELEMENTS (virtual_evdev->button_count); code++)
+    {
+      switch (get_button_type (code))
+        {
+        case EVDEV_BUTTON_TYPE_KEY:
+          clutter_virtual_input_device_notify_key (virtual_device,
+                                                   time_us,
+                                                   code,
+                                                   CLUTTER_KEY_STATE_RELEASED);
+          break;
+        case EVDEV_BUTTON_TYPE_BUTTON:
+          clutter_virtual_input_device_notify_button (virtual_device,
+                                                      time_us,
+                                                      code,
+                                                      CLUTTER_BUTTON_STATE_RELEASED);
+          break;
+        case EVDEV_BUTTON_TYPE_NONE:
+          g_assert_not_reached ();
+        }
+    }
+}
+
 static void
 clutter_virtual_input_device_evdev_notify_relative_motion (ClutterVirtualInputDevice *virtual_device,
                                                            uint64_t                   time_us,
@@ -94,6 +190,30 @@ clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *vir
                                                   uint32_t                   button,
                                                   ClutterButtonState         button_state)
 {
+  ClutterVirtualInputDeviceEvdev *virtual_evdev =
+    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
+  int button_count;
+
+  if (get_button_type (button) != EVDEV_BUTTON_TYPE_BUTTON)
+    {
+      g_warning ("Unknown/invalid virtual device button 0x%x pressed",
+                 button);
+      return;
+    }
+
+  button_count = update_button_count (virtual_evdev, button, button_state);
+  if (button_count > 1)
+    {
+      g_warning ("Received multiple virtual 0x%x button presses (ignoring)",
+                 button);
+      return;
+    }
+
+  clutter_seat_evdev_notify_button (virtual_evdev->seat,
+                                    virtual_evdev->device,
+                                    time_us,
+                                    button,
+                                    button_state);
 }
 
 static void
@@ -102,6 +222,30 @@ clutter_virtual_input_device_evdev_notify_key (ClutterVirtualInputDevice *virtua
                                                uint32_t                   key,
                                                ClutterKeyState            key_state)
 {
+  ClutterVirtualInputDeviceEvdev *virtual_evdev =
+    CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
+  int key_count;
+
+  if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY)
+    {
+      g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", key);
+      return;
+    }
+
+  key_count = update_button_count (virtual_evdev, key, key_state);
+  if (key_count > 1)
+    {
+      g_warning ("Received multiple virtual 0x%x key presses (ignoring)",
+                 key);
+      return;
+    }
+
+  clutter_seat_evdev_notify_key (virtual_evdev->seat,
+                                 virtual_evdev->device,
+                                 time_us,
+                                 key,
+                                 key_state,
+                                 TRUE);
 }
 
 static void
@@ -176,6 +320,7 @@ clutter_virtual_input_device_evdev_finalize (GObject *object)
     CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (object);
   GObjectClass *object_class;
 
+  release_pressed_buttons (virtual_device);
   g_clear_object (&virtual_evdev->device);
 
   object_class =


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]