[gtk+/xi2: 344/1239] Map device hierarchy changes to GdkDeviceManager::device-added/removed.



commit f396465d79252c06ccd26b4cd1e9c02c1ca2e5ce
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Jun 17 02:05:02 2009 +0200

    Map device hierarchy changes to GdkDeviceManager::device-added/removed.

 gdk/x11/gdkdevicemanager-xi2.c |  157 ++++++++++++++++++++++++++++++++++------
 gdk/x11/gdkdevicemanager-xi2.h |    2 +
 2 files changed, 136 insertions(+), 23 deletions(-)
---
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 704a859..0a33afa 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -23,6 +23,7 @@
 #include "gdkx.h"
 
 static void    gdk_device_manager_xi2_constructed (GObject *object);
+static void    gdk_device_manager_xi2_finalize    (GObject *object);
 
 static GList * gdk_device_manager_xi2_get_devices (GdkDeviceManager *device_manager,
                                                    GdkDeviceType     type);
@@ -50,6 +51,7 @@ gdk_device_manager_xi2_class_init (GdkDeviceManagerXI2Class *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->constructed = gdk_device_manager_xi2_constructed;
+  object_class->finalize = gdk_device_manager_xi2_finalize;
 
   device_manager_class->get_devices = gdk_device_manager_xi2_get_devices;
   device_manager_class->set_window_events = gdk_device_manager_xi2_set_window_events;
@@ -58,6 +60,10 @@ gdk_device_manager_xi2_class_init (GdkDeviceManagerXI2Class *klass)
 static void
 gdk_device_manager_xi2_init (GdkDeviceManagerXI2 *device_manager)
 {
+  device_manager->id_table = g_hash_table_new_full (g_direct_hash,
+                                                    g_direct_equal,
+                                                    NULL,
+                                                    (GDestroyNotify) g_object_unref);
 }
 
 static void
@@ -133,6 +139,76 @@ _gdk_device_manager_xi2_select_events (GdkDeviceManager *device_manager,
   XISelectEvents (xdisplay, xwindow, &event_mask, 1);
 }
 
+static GdkDevice *
+create_device (XIDeviceInfo *dev)
+{
+  GdkDevice *device;
+
+  device = g_object_new (GDK_TYPE_DEVICE, NULL);
+
+  device->name = g_strdup (dev->name);
+  device->source = GDK_SOURCE_MOUSE;
+
+  device->mode = (dev->use == XIMasterPointer) ? GDK_MODE_SCREEN : GDK_MODE_DISABLED;
+  device->has_cursor = (dev->use == XIMasterPointer);
+  device->num_axes = 0;
+  device->axes = NULL;
+  device->num_keys = 0;
+  device->keys = NULL;
+
+  return device;
+}
+
+static GdkDevice *
+add_device (GdkDeviceManagerXI2 *device_manager,
+            XIDeviceInfo        *dev,
+            gboolean             emit_signal)
+{
+  GdkDevice *device;
+
+  device = create_device (dev);
+
+  g_hash_table_replace (device_manager->id_table,
+                        GINT_TO_POINTER (dev->deviceid),
+                        device);
+
+  if (dev->use == XIMasterPointer)
+    device_manager->master_devices = g_list_prepend (device_manager->master_devices, device);
+  else if (dev->use == XISlavePointer)
+    device_manager->slave_devices = g_list_prepend (device_manager->slave_devices, device);
+  else if (dev->use == XIFloatingSlave)
+    device_manager->floating_devices = g_list_prepend (device_manager->floating_devices, device);
+  else
+    g_warning ("Unhandled device: %s\n", device->name);
+
+  if (emit_signal)
+    g_signal_emit_by_name (device_manager, "device-added", device);
+
+  return device;
+}
+
+static void
+remove_device (GdkDeviceManagerXI2 *device_manager,
+               int                  device_id)
+{
+  GdkDevice *device;
+
+  device = g_hash_table_lookup (device_manager->id_table,
+                                GINT_TO_POINTER (device_id));
+
+  if (device)
+    {
+      device_manager->master_devices = g_list_remove (device_manager->master_devices, device);
+      device_manager->slave_devices = g_list_remove (device_manager->slave_devices, device);
+      device_manager->floating_devices = g_list_remove (device_manager->floating_devices, device);
+
+      g_signal_emit_by_name (device_manager, "device-removed", device);
+
+      g_hash_table_remove (device_manager->id_table,
+                           GINT_TO_POINTER (device_id));
+    }
+}
+
 static void
 gdk_device_manager_xi2_constructed (GObject *object)
 {
@@ -157,31 +233,12 @@ gdk_device_manager_xi2_constructed (GObject *object)
       GdkDevicePrivate *private;
 
       dev = &info[i];
+      device = add_device (device_manager_xi2, dev, FALSE);
 
-      device = g_object_new (GDK_TYPE_DEVICE, NULL);
-      private = (GdkDevicePrivate *) device;
-
-      device->name = g_strdup (dev->name);
-      device->source = GDK_SOURCE_MOUSE;
-      device->mode = GDK_MODE_SCREEN;
-      device->has_cursor = TRUE;
-      device->num_axes = 0;
-      device->axes = NULL;
-      device->num_keys = 0;
-      device->keys = NULL;
-
-      private->display = display;
-
-      if (dev->use == XIMasterPointer)
-        device_manager_xi2->master_devices = g_list_prepend (device_manager_xi2->master_devices, device);
-      else if (dev->use == XISlavePointer)
-        device_manager_xi2->slave_devices = g_list_prepend (device_manager_xi2->slave_devices, device);
-      else if (dev->use == XIFloatingSlave)
-        device_manager_xi2->floating_devices = g_list_prepend (device_manager_xi2->floating_devices, device);
-      else
+      if (device)
         {
-          g_warning ("Unhandled device: %s\n", device->name);
-          g_object_unref (device);
+          private = (GdkDevicePrivate *) device;
+          private->display = display;
         }
     }
 
@@ -197,6 +254,22 @@ gdk_device_manager_xi2_constructed (GObject *object)
                                          mask);
 }
 
+static void
+gdk_device_manager_xi2_finalize (GObject *object)
+{
+  GdkDeviceManagerXI2 *device_manager_xi2;
+
+  device_manager_xi2 = GDK_DEVICE_MANAGER_XI2 (object);
+
+  g_list_free (device_manager_xi2->master_devices);
+  g_list_free (device_manager_xi2->slave_devices);
+  g_list_free (device_manager_xi2->floating_devices);
+
+  g_hash_table_destroy (device_manager_xi2->id_table);
+
+  G_OBJECT_CLASS (gdk_device_manager_xi2_parent_class)->finalize (object);
+}
+
 static GList *
 gdk_device_manager_xi2_get_devices (GdkDeviceManager *device_manager,
                                     GdkDeviceType     type)
@@ -244,6 +317,39 @@ gdk_device_manager_xi2_event_translator_init (GdkEventTranslatorIface *iface)
   iface->translate_event = gdk_device_manager_xi2_translate_event;
 }
 
+static void
+handle_hierarchy_changed (GdkDeviceManagerXI2 *device_manager,
+                          XIHierarchyEvent    *ev)
+{
+  GdkDevice *device;
+  gint i;
+
+  /* We only care about enabled devices */
+  if (!(ev->flags & XIDeviceEnabled) &&
+      !(ev->flags & XIDeviceDisabled))
+    return;
+
+  for (i = 0; i < ev->num_devices; i++)
+    {
+      if (ev->info[i].flags & XIDeviceEnabled)
+        {
+          GdkDisplay *display;
+          Display *xdisplay;
+          XIDeviceInfo *info;
+          int ndevices;
+
+          display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager));
+          xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+          info = XIQueryDevice(xdisplay, ev->info[i].deviceid, &ndevices);
+          device = add_device (device_manager, &info[0], TRUE);
+          XIFreeDeviceInfo(info);
+        }
+      else if (ev->info[i].flags & XIDeviceDisabled)
+        remove_device (device_manager, ev->info[i].deviceid);
+    }
+}
+
 static gboolean
 gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
                                         GdkDisplay         *display,
@@ -262,6 +368,11 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator,
 
   switch (ev->evtype)
     {
+    case XI_HierarchyChanged:
+      handle_hierarchy_changed (device_manager,
+                                (XIHierarchyEvent *) ev);
+      return_val = FALSE;
+      break;
     default:
       return_val = FALSE;
       break;
diff --git a/gdk/x11/gdkdevicemanager-xi2.h b/gdk/x11/gdkdevicemanager-xi2.h
index b033c65..d47bcdb 100644
--- a/gdk/x11/gdkdevicemanager-xi2.h
+++ b/gdk/x11/gdkdevicemanager-xi2.h
@@ -39,6 +39,8 @@ struct _GdkDeviceManagerXI2
 {
   GdkDeviceManager parent_object;
 
+  GHashTable *id_table;
+
   GList *master_devices;
   GList *slave_devices;
   GList *floating_devices;



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