[clutter/clutter-1.16] evdev: allow hooking directly into libxkbcommon



commit 8c358f18b1be3a10430be6abb164494cf1591ed0
Author: Giovanni Campagna <gcampagn redhat com>
Date:   Fri Aug 9 17:06:39 2013 +0200

    evdev: allow hooking directly into libxkbcommon
    
    A wayland compositor needs to have more keyboard state than
    ClutterModifierState exposes, so it makes sense for it to use
    xkb_state directly. Also, it makes sense for it to provide
    it's own keymap, to ensure a consistent view between the compositor
    and the wayland clients.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=705710

 clutter/evdev/clutter-device-manager-evdev.c |   74 ++++++++++++++++++++++++++
 clutter/evdev/clutter-evdev.h                |    5 ++
 2 files changed, 79 insertions(+), 0 deletions(-)
---
diff --git a/clutter/evdev/clutter-device-manager-evdev.c b/clutter/evdev/clutter-device-manager-evdev.c
index 48b34e9..0e7f7c2 100644
--- a/clutter/evdev/clutter-device-manager-evdev.c
+++ b/clutter/evdev/clutter-device-manager-evdev.c
@@ -75,6 +75,7 @@ struct _ClutterDeviceManagerEvdevPrivate
   guint stage_added_handler;
   guint stage_removed_handler;
 
+  GArray *keys;
   struct xkb_state *xkb;              /* XKB state object */
   uint32_t button_state;
 };
@@ -158,6 +159,29 @@ queue_event (ClutterEvent *event)
 }
 
 static void
+add_key (GArray  *keys,
+        guint32  key)
+{
+  g_array_append_val (keys, key);
+}
+
+static void
+remove_key (GArray  *keys,
+           guint32  key)
+{
+  unsigned int i;
+
+  for (i = 0; i < keys->len; i++)
+    {
+      if (g_array_index (keys, guint32, i) == key)
+       {
+         g_array_remove_index_fast (keys, i);
+         return;
+       }
+    }
+}
+
+static void
 notify_key (ClutterEventSource *source,
             guint32             time_,
             guint32             key,
@@ -188,6 +212,11 @@ notify_key (ClutterEventSource *source,
                                           time_, key, state);
       xkb_state_update_key (manager_evdev->priv->xkb, event->key.hardware_keycode, state ? XKB_KEY_DOWN : 
XKB_KEY_UP);
 
+      if (state)
+       add_key (manager_evdev->priv->keys, event->key.hardware_keycode);
+      else
+       remove_key (manager_evdev->priv->keys, event->key.hardware_keycode);
+
       queue_event (event);
     }
 }
@@ -874,6 +903,7 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
   _clutter_device_manager_add_device (CLUTTER_DEVICE_MANAGER (manager_evdev), device);
   priv->core_keyboard = device;
 
+  priv->keys = g_array_new (FALSE, FALSE, sizeof (guint32));
   priv->xkb = _clutter_xkb_state_new (NULL,
                                      option_xkb_layout,
                                      option_xkb_variant,
@@ -1186,3 +1216,47 @@ clutter_evdev_set_open_callback (ClutterOpenDeviceCallback callback,
   open_callback = callback;
   open_callback_data = user_data;
 }
+
+/**
+ * clutter_evdev_get_keyboard_state: (skip)
+ * @evdev: the #ClutterDeviceManager created by the evdev backend
+ *
+ * Returns the xkb state tracking object for keyboard devices.
+ * The object must be treated as read only, and should be used only
+ * for reading out the detailed group and modifier state.
+ */
+struct xkb_state *
+clutter_evdev_get_keyboard_state (ClutterDeviceManager *evdev)
+{
+  g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev), NULL);
+
+  return (CLUTTER_DEVICE_MANAGER_EVDEV (evdev))->priv->xkb;
+}
+
+/**
+ * clutter_evdev_set_keyboard_map: (skip)
+ * @evdev: the #ClutterDeviceManager created by the evdev backend
+ * @keymap: the new keymap
+ *
+ * Instructs @evdev to use the speficied keyboard map. This will cause
+ * the backend to drop the state and create a new one with the new map.
+ */
+void
+clutter_evdev_set_keyboard_map (ClutterDeviceManager *evdev,
+                               struct xkb_keymap    *keymap)
+{
+  ClutterDeviceManagerEvdev *manager_evdev;
+  ClutterDeviceManagerEvdevPrivate *priv;
+  unsigned int i;
+
+  g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
+
+  manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
+  priv = manager_evdev->priv;
+
+  xkb_state_unref (priv->xkb);
+  priv->xkb = xkb_state_new (keymap);
+
+  for (i = 0; i < priv->keys->len; i++)
+    xkb_state_update_key (priv->xkb, g_array_index (priv->keys, guint32, i), XKB_KEY_DOWN);
+}
diff --git a/clutter/evdev/clutter-evdev.h b/clutter/evdev/clutter-evdev.h
index 2b72951..fea26cb 100644
--- a/clutter/evdev/clutter-evdev.h
+++ b/clutter/evdev/clutter-evdev.h
@@ -26,6 +26,7 @@
 
 #include <glib.h>
 #include <glib-object.h>
+#include <xkbcommon/xkbcommon.h>
 #include <clutter/clutter.h>
 
 G_BEGIN_DECLS
@@ -50,6 +51,10 @@ void  clutter_evdev_set_open_callback (ClutterOpenDeviceCallback callback,
 void  clutter_evdev_release_devices (void);
 void  clutter_evdev_reclaim_devices (void);
 
+struct xkb_state * clutter_evdev_get_keyboard_state (ClutterDeviceManager *evdev);
+void               clutter_evdev_set_keyboard_map   (ClutterDeviceManager *evdev,
+                                                    struct xkb_keymap    *keymap);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_EVDEV_H__ */


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