[clutter/clutter-1.16] evdev: add a way for applications to tweak how devices are opened



commit 26b2852601620f5b042e2a43b6e7bfa5d07beeda
Author: Giovanni Campagna <gcampagn redhat com>
Date:   Mon Jul 15 18:24:35 2013 +0200

    evdev: add a way for applications to tweak how devices are opened
    
    In some cases, applications (or actually, wayland compositors)
    don't have the required permissions to access evdev directly, but
    can do so with an external helper like weston-launch.
    
    Allow them to do so with a custom callback that replaces the regular
    open() path.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=704269

 clutter/evdev/clutter-device-manager-evdev.c |   49 +++++++++++++++++++++++--
 clutter/evdev/clutter-evdev.h                |   17 +++++++++
 2 files changed, 62 insertions(+), 4 deletions(-)
---
diff --git a/clutter/evdev/clutter-device-manager-evdev.c b/clutter/evdev/clutter-device-manager-evdev.c
index bab4a82..6c8399c 100644
--- a/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/evdev/clutter-device-manager-evdev.c
@@ -73,6 +73,9 @@ G_DEFINE_TYPE_WITH_PRIVATE (ClutterDeviceManagerEvdev,
                             clutter_device_manager_evdev,
                             CLUTTER_TYPE_DEVICE_MANAGER)
 
+static ClutterOpenDeviceCallback open_callback;
+static gpointer                  open_callback_data;
+
 static const gchar *subsystems[] = { "input", NULL };
 
 /*
@@ -465,17 +468,33 @@ clutter_event_source_new (ClutterInputDeviceEvdev *input_device)
   ClutterInputDeviceType type;
   const gchar *node_path;
   gint fd;
+  GError *error;
 
   /* grab the udev input device node and open it */
   node_path = _clutter_input_device_evdev_get_device_path (input_device);
 
   CLUTTER_NOTE (EVENT, "Creating GSource for device %s", node_path);
 
-  fd = open (node_path, O_RDONLY | O_NONBLOCK);
-  if (fd < 0)
+  if (open_callback)
     {
-      g_warning ("Could not open device %s: %s", node_path, strerror (errno));
-      return NULL;
+      error = NULL;
+      fd = open_callback (node_path, O_RDONLY | O_NONBLOCK, open_callback_data, &error);
+
+      if (fd < 0)
+       {
+         g_warning ("Could not open device %s: %s", node_path, error->message);
+         g_error_free (error);
+         return NULL;
+       }
+    }
+  else
+    {
+      fd = open (node_path, O_RDONLY | O_NONBLOCK);
+      if (fd < 0)
+       {
+         g_warning ("Could not open device %s: %s", node_path, strerror (errno));
+         return NULL;
+       }
     }
 
   /* setup the source */
@@ -1119,3 +1138,25 @@ clutter_evdev_reclaim_devices (void)
   priv->released = FALSE;
   clutter_device_manager_evdev_probe_devices (evdev_manager);
 }
+
+/**
+ * clutter_evdev_set_open_callback: (skip)
+ * @callback: the user replacement for open()
+ * @user_data: user data for @callback
+ *
+ * Through this function, the application can set a custom callback
+ * to invoked when Clutter is about to open an evdev device. It can do
+ * so if special handling is needed, for example to circumvent permission
+ * problems.
+ *
+ * Setting @callback to %NULL will reset the default behavior.
+ *
+ * For reliable effects, this function must be called before clutter_init().
+ */
+void
+clutter_evdev_set_open_callback (ClutterOpenDeviceCallback callback,
+                                 gpointer                  user_data)
+{
+  open_callback = callback;
+  open_callback_data = user_data;
+}
diff --git a/clutter/evdev/clutter-evdev.h b/clutter/evdev/clutter-evdev.h
index cc5e18e..2b72951 100644
--- a/clutter/evdev/clutter-evdev.h
+++ b/clutter/evdev/clutter-evdev.h
@@ -30,6 +30,23 @@
 
 G_BEGIN_DECLS
 
+/**
+ * ClutterOpenDeviceCallback:
+ * @path: the device path
+ * @flags: flags to be passed to open
+ *
+ * This callback will be called when Clutter needs to access an input
+ * device. It should return an open file descriptor for the file at @path,
+ * or -1 if opening failed.
+ */
+typedef int (*ClutterOpenDeviceCallback) (const char  *path,
+                                         int          flags,
+                                         gpointer     user_data,
+                                         GError     **error);
+
+void  clutter_evdev_set_open_callback (ClutterOpenDeviceCallback callback,
+                                      gpointer                  user_data);
+
 void  clutter_evdev_release_devices (void);
 void  clutter_evdev_reclaim_devices (void);
 


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