[clutter/clutter-1.20] evdev: Add evdev specific event filter function



commit 91ee1ceca452176667708ad898cd59196712a76d
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Apr 25 19:54:35 2014 +0200

    evdev: Add evdev specific event filter function
    
    This function can be used to intercept or translate events
    that are unmanaged by clutter itself.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728967

 clutter/evdev/clutter-device-manager-evdev.c |  132 ++++++++++++++++++++++++++
 clutter/evdev/clutter-evdev.h                |   11 ++
 2 files changed, 143 insertions(+), 0 deletions(-)
---
diff --git a/clutter/evdev/clutter-device-manager-evdev.c b/clutter/evdev/clutter-device-manager-evdev.c
index 30f39f3..aa4dc23 100644
--- a/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/evdev/clutter-device-manager-evdev.c
@@ -62,6 +62,8 @@
 #define INITIAL_POINTER_X 16
 #define INITIAL_POINTER_Y 16
 
+typedef struct _ClutterEventFilter ClutterEventFilter;
+
 struct _ClutterSeatEvdev
 {
   struct libinput_seat *libinput_seat;
@@ -88,6 +90,13 @@ struct _ClutterSeatEvdev
   ClutterInputDevice *repeat_device;
 };
 
+struct _ClutterEventFilter
+{
+  ClutterEvdevFilterFunc func;
+  gpointer data;
+  GDestroyNotify destroy_notify;
+};
+
 typedef struct _ClutterEventSource  ClutterEventSource;
 
 struct _ClutterDeviceManagerEvdevPrivate
@@ -111,6 +120,8 @@ struct _ClutterDeviceManagerEvdevPrivate
   ClutterStageManager *stage_manager;
   guint stage_added_handler;
   guint stage_removed_handler;
+
+  GSList *event_filters;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (ClutterDeviceManagerEvdev,
@@ -1098,10 +1109,40 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
   return handled;
 }
 
+static gboolean
+filter_event (ClutterDeviceManagerEvdev *manager_evdev,
+              struct libinput_event     *event)
+{
+  gboolean retval = CLUTTER_EVENT_PROPAGATE;
+  ClutterEventFilter *filter;
+  GSList *tmp_list;
+
+  tmp_list = manager_evdev->priv->event_filters;
+
+  while (tmp_list)
+    {
+      filter = tmp_list->data;
+      retval = filter->func (event, filter->data);
+      tmp_list = tmp_list->next;
+
+      if (retval != CLUTTER_EVENT_PROPAGATE)
+        break;
+    }
+
+  return retval;
+}
+
 static void
 process_event (ClutterDeviceManagerEvdev *manager_evdev,
                struct libinput_event *event)
 {
+  gboolean retval;
+
+  retval = filter_event (manager_evdev, event);
+
+  if (retval != CLUTTER_EVENT_PROPAGATE)
+    return;
+
   if (process_base_event (manager_evdev, event))
     return;
   if (process_device_event (manager_evdev, event))
@@ -1639,3 +1680,94 @@ clutter_evdev_set_keyboard_repeat (ClutterDeviceManager *evdev,
   seat->repeat_delay = delay;
   seat->repeat_interval = interval;
 }
+
+/**
+ * clutter_evdev_add_filter: (skip)
+ * @func: (closure data): a filter function
+ * @data: (allow-none): user data to be passed to the filter function, or %NULL
+ * @destroy_notify: (allow-none): function to call on @data when the filter is removed, or %NULL
+ *
+ * Adds an event filter function.
+ *
+ * Since: 1.20
+ * Stability: unstable
+ */
+void
+clutter_evdev_add_filter (ClutterEvdevFilterFunc func,
+                          gpointer               data,
+                          GDestroyNotify         destroy_notify)
+{
+  ClutterDeviceManagerEvdev *manager_evdev;
+  ClutterDeviceManager *manager;
+  ClutterEventFilter *filter;
+
+  g_return_if_fail (func != NULL);
+
+  manager = clutter_device_manager_get_default ();
+
+  if (!CLUTTER_IS_DEVICE_MANAGER_EVDEV (manager))
+    {
+      g_critical ("The Clutter input backend is not a evdev backend");
+      return;
+    }
+
+  manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
+
+  filter = g_new0 (ClutterEventFilter, 1);
+  filter->func = func;
+  filter->data = data;
+  filter->destroy_notify = destroy_notify;
+
+  manager_evdev->priv->event_filters =
+    g_slist_append (manager_evdev->priv->event_filters, filter);
+}
+
+/**
+ * clutter_evdev_remove_filter: (skip)
+ * @func: a filter function
+ * @data: (allow-none): user data to be passed to the filter function, or %NULL
+ *
+ * Removes the given filter function.
+ *
+ * Since: 1.20
+ * Stability: unstable
+ */
+void
+clutter_evdev_remove_filter (ClutterEvdevFilterFunc func,
+                             gpointer               data)
+{
+  ClutterDeviceManagerEvdev *manager_evdev;
+  ClutterDeviceManager *manager;
+  ClutterEventFilter *filter;
+  GSList *tmp_list;
+
+  g_return_if_fail (func != NULL);
+
+  manager = clutter_device_manager_get_default ();
+
+  if (!CLUTTER_IS_DEVICE_MANAGER_EVDEV (manager))
+    {
+      g_critical ("The Clutter input backend is not a evdev backend");
+      return;
+    }
+
+  manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
+  tmp_list = manager_evdev->priv->event_filters;
+
+  while (tmp_list)
+    {
+      filter = tmp_list->data;
+
+      if (filter->func == func && filter->data == data)
+        {
+          if (filter->destroy_notify)
+            filter->destroy_notify (filter->data);
+          g_free (filter);
+          manager_evdev->priv->event_filters =
+            g_slist_delete_link (manager_evdev->priv->event_filters, tmp_list);
+          return;
+        }
+
+      tmp_list = tmp_list->next;
+    }
+}
diff --git a/clutter/evdev/clutter-evdev.h b/clutter/evdev/clutter-evdev.h
index f97a3f5..f85127f 100644
--- a/clutter/evdev/clutter-evdev.h
+++ b/clutter/evdev/clutter-evdev.h
@@ -102,6 +102,17 @@ void clutter_evdev_set_keyboard_repeat (ClutterDeviceManager *evdev,
                                         guint32               delay,
                                         guint32               interval);
 
+typedef gboolean (* ClutterEvdevFilterFunc) (struct libinput_event *event,
+                                             gpointer               data);
+
+CLUTTER_AVAILABLE_IN_1_20
+void clutter_evdev_add_filter    (ClutterEvdevFilterFunc func,
+                                  gpointer               data,
+                                  GDestroyNotify         destroy_notify);
+CLUTTER_AVAILABLE_IN_1_20
+void clutter_evdev_remove_filter (ClutterEvdevFilterFunc func,
+                                  gpointer               data);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_EVDEV_H__ */


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