diff options
Diffstat (limited to 'gdk/x11')
-rw-r--r-- | gdk/x11/gdkdevicemanager-x11.c | 2 | ||||
-rw-r--r-- | gdk/x11/gdkdevicemanager-xi2.c | 178 | ||||
-rw-r--r-- | gdk/x11/gdkdevicemanager-xi2.h | 1 | ||||
-rw-r--r-- | gdk/x11/gdkdisplay-x11.c | 2 | ||||
-rw-r--r-- | gdk/x11/gdkmain-x11.c | 2 | ||||
-rw-r--r-- | gdk/x11/gdkwindow-x11.h | 3 |
6 files changed, 149 insertions, 39 deletions
diff --git a/gdk/x11/gdkdevicemanager-x11.c b/gdk/x11/gdkdevicemanager-x11.c index a6bb50b7c3..4a6953d3be 100644 --- a/gdk/x11/gdkdevicemanager-x11.c +++ b/gdk/x11/gdkdevicemanager-x11.c @@ -48,7 +48,7 @@ _gdk_device_manager_new (GdkDisplay *display) major = 2; minor = 0; - if (_gdk_enable_multidevice && + if (!_gdk_disable_multidevice && XIQueryVersion (xdisplay, &major, &minor) != BadRequest) { GdkDeviceManagerXI2 *device_manager_xi2; diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c index 25d7a841a6..ee3461c3fe 100644 --- a/gdk/x11/gdkdevicemanager-xi2.c +++ b/gdk/x11/gdkdevicemanager-xi2.c @@ -263,15 +263,29 @@ add_device (GdkDeviceManagerXI2 *device_manager, if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard) device_manager->master_devices = g_list_append (device_manager->master_devices, device); - else if (dev->use == XISlavePointer || dev->use == XISlaveKeyboard) + else if (dev->use == XISlavePointer || dev->use == XISlaveKeyboard || dev->use == XIFloatingSlave) device_manager->slave_devices = g_list_append (device_manager->slave_devices, device); - else if (dev->use == XIFloatingSlave) - device_manager->floating_devices = g_list_append (device_manager->floating_devices, device); else g_warning ("Unhandled device: %s\n", gdk_device_get_name (device)); if (emit_signal) - g_signal_emit_by_name (device_manager, "device-added", device); + { + if (dev->use == XISlavePointer || dev->use == XISlaveKeyboard) + { + GdkDevice *master; + + /* The device manager is already constructed, then + * keep the hierarchy coherent for the added device. + */ + master = g_hash_table_lookup (device_manager->id_table, + GINT_TO_POINTER (dev->attachment)); + + _gdk_device_set_associated_device (device, master); + _gdk_device_add_slave (master, device); + } + + g_signal_emit_by_name (device_manager, "device-added", device); + } return device; } @@ -289,7 +303,6 @@ remove_device (GdkDeviceManagerXI2 *device_manager, { 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); @@ -301,7 +314,7 @@ remove_device (GdkDeviceManagerXI2 *device_manager, } static void -relate_devices (gpointer key, +relate_masters (gpointer key, gpointer value, gpointer user_data) { @@ -317,12 +330,28 @@ relate_devices (gpointer key, } static void +relate_slaves (gpointer key, + gpointer value, + gpointer user_data) +{ + GdkDeviceManagerXI2 *device_manager; + GdkDevice *slave, *master; + + device_manager = user_data; + slave = g_hash_table_lookup (device_manager->id_table, key); + master = g_hash_table_lookup (device_manager->id_table, value); + + _gdk_device_set_associated_device (slave, master); + _gdk_device_add_slave (master, slave); +} + +static void gdk_device_manager_xi2_constructed (GObject *object) { GdkDeviceManagerXI2 *device_manager_xi2; GdkDisplay *display; GdkScreen *screen; - GHashTable *relations; + GHashTable *masters, *slaves; Display *xdisplay; XIDeviceInfo *info, *dev; int ndevices, i; @@ -332,7 +361,9 @@ gdk_device_manager_xi2_constructed (GObject *object) device_manager_xi2 = GDK_DEVICE_MANAGER_XI2 (object); display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object)); xdisplay = GDK_DISPLAY_XDISPLAY (display); - relations = g_hash_table_new (NULL, NULL); + + masters = g_hash_table_new (NULL, NULL); + slaves = g_hash_table_new (NULL, NULL); info = XIQueryDevice(xdisplay, XIAllDevices, &ndevices); @@ -347,7 +378,14 @@ gdk_device_manager_xi2_constructed (GObject *object) if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard) { - g_hash_table_insert (relations, + g_hash_table_insert (masters, + GINT_TO_POINTER (dev->deviceid), + GINT_TO_POINTER (dev->attachment)); + } + else if (dev->use == XISlavePointer || + dev->use == XISlaveKeyboard) + { + g_hash_table_insert (slaves, GINT_TO_POINTER (dev->deviceid), GINT_TO_POINTER (dev->attachment)); } @@ -356,8 +394,11 @@ gdk_device_manager_xi2_constructed (GObject *object) XIFreeDeviceInfo(info); /* Stablish relationships between devices */ - g_hash_table_foreach (relations, relate_devices, object); - g_hash_table_destroy (relations); + g_hash_table_foreach (masters, relate_masters, object); + g_hash_table_destroy (masters); + + g_hash_table_foreach (slaves, relate_slaves, object); + g_hash_table_destroy (slaves); /* Connect to hierarchy change events */ screen = gdk_display_get_default_screen (display); @@ -388,10 +429,6 @@ gdk_device_manager_xi2_dispose (GObject *object) g_list_free (device_manager_xi2->slave_devices); device_manager_xi2->slave_devices = NULL; - g_list_foreach (device_manager_xi2->floating_devices, (GFunc) g_object_unref, NULL); - g_list_free (device_manager_xi2->floating_devices); - device_manager_xi2->floating_devices = NULL; - if (device_manager_xi2->id_table) { g_hash_table_destroy (device_manager_xi2->id_table); @@ -416,10 +453,21 @@ gdk_device_manager_xi2_list_devices (GdkDeviceManager *device_manager, list = device_manager_xi2->master_devices; break; case GDK_DEVICE_TYPE_SLAVE: - list = device_manager_xi2->slave_devices; - break; case GDK_DEVICE_TYPE_FLOATING: - list = device_manager_xi2->floating_devices; + { + GList *devs = device_manager_xi2->slave_devices; + + while (devs) + { + GdkDevice *dev; + + dev = devs->data; + devs = devs->next; + + if (type == gdk_device_get_device_type (dev)) + list = g_list_prepend (list, dev); + } + } break; default: g_assert_not_reached (); @@ -457,32 +505,61 @@ static void handle_hierarchy_changed (GdkDeviceManagerXI2 *device_manager, XIHierarchyEvent *ev) { + GdkDisplay *display; + Display *xdisplay; GdkDevice *device; + XIDeviceInfo *info; + int ndevices; gint i; - /* We only care about enabled devices */ - if (!(ev->flags & XIDeviceEnabled) && - !(ev->flags & XIDeviceDisabled)) - return; + display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (device_manager)); + xdisplay = GDK_DISPLAY_XDISPLAY (display); for (i = 0; i < ev->num_info; 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); + else if (ev->info[i].flags & XISlaveAttached || + ev->info[i].flags & XISlaveDetached) + { + GdkDevice *master, *slave; + + slave = g_hash_table_lookup (device_manager->id_table, + GINT_TO_POINTER (ev->info[i].deviceid)); + + /* Remove old master info */ + master = gdk_device_get_associated_device (slave); + + if (master) + { + _gdk_device_remove_slave (master, slave); + _gdk_device_set_associated_device (slave, NULL); + + g_signal_emit_by_name (device_manager, "device-changed", master); + } + + /* Add new master if it's an attachment event */ + if (ev->info[i].flags & XISlaveAttached) + { + info = XIQueryDevice(xdisplay, ev->info[i].deviceid, &ndevices); + + master = g_hash_table_lookup (device_manager->id_table, + GINT_TO_POINTER (info->attachment)); + + _gdk_device_set_associated_device (slave, master); + _gdk_device_add_slave (master, slave); + + g_signal_emit_by_name (device_manager, "device-changed", master); + } + + g_signal_emit_by_name (device_manager, "device-changed", slave); + } } } @@ -499,6 +576,8 @@ handle_device_changed (GdkDeviceManagerXI2 *device_manager, _gdk_device_reset_axes (device); translate_device_classes (display, device, ev->classes, ev->num_classes); + + g_signal_emit_by_name (G_OBJECT (device), "changed"); } static GdkCrossingMode @@ -641,6 +720,7 @@ translate_keyboard_string (GdkEventKey *event) static void generate_focus_event (GdkWindow *window, GdkDevice *device, + GdkDevice *source_device, gboolean in) { GdkEvent *event; @@ -650,6 +730,7 @@ generate_focus_event (GdkWindow *window, event->focus_change.send_event = FALSE; event->focus_change.in = in; gdk_event_set_device (event, device); + gdk_event_set_source_device (event, source_device); gdk_event_put (event); gdk_event_free (event); @@ -658,6 +739,7 @@ generate_focus_event (GdkWindow *window, static void handle_focus_change (GdkWindow *window, GdkDevice *device, + GdkDevice *source_device, gint detail, gint mode, gboolean in) @@ -717,7 +799,7 @@ handle_focus_change (GdkWindow *window, } if (HAS_FOCUS (toplevel) != had_focus) - generate_focus_event (window, device, (in) ? TRUE : FALSE); + generate_focus_event (window, device, source_device, (in) ? TRUE : FALSE); } static gdouble * @@ -916,7 +998,7 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, XIDeviceEvent *xev = (XIDeviceEvent *) ev; GdkKeymap *keymap = gdk_keymap_get_for_display (display); GdkModifierType consumed, state; - GdkDevice *device; + GdkDevice *device, *source_device; event->key.type = xev->evtype == XI_KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE; @@ -933,6 +1015,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, GUINT_TO_POINTER (xev->deviceid)); gdk_event_set_device (event, device); + source_device = g_hash_table_lookup (device_manager->id_table, + GUINT_TO_POINTER (xev->sourceid)); + gdk_event_set_source_device (event, source_device); + event->key.keyval = GDK_KEY_VoidSymbol; gdk_keymap_translate_keyboard_state (keymap, @@ -961,6 +1047,7 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, case XI_ButtonRelease: { XIDeviceEvent *xev = (XIDeviceEvent *) ev; + GdkDevice *source_device; switch (xev->detail) { @@ -989,6 +1076,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->scroll.device = g_hash_table_lookup (device_manager->id_table, GUINT_TO_POINTER (xev->deviceid)); + source_device = g_hash_table_lookup (device_manager->id_table, + GUINT_TO_POINTER (xev->sourceid)); + gdk_event_set_source_device (event, source_device); + event->scroll.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons); break; default: @@ -1004,6 +1095,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->button.device = g_hash_table_lookup (device_manager->id_table, GUINT_TO_POINTER (xev->deviceid)); + source_device = g_hash_table_lookup (device_manager->id_table, + GUINT_TO_POINTER (xev->sourceid)); + gdk_event_set_source_device (event, source_device); + event->button.axes = translate_axes (event->button.device, event->button.x, event->button.y, @@ -1036,6 +1131,7 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, case XI_Motion: { XIDeviceEvent *xev = (XIDeviceEvent *) ev; + GdkDevice *source_device; event->motion.type = GDK_MOTION_NOTIFY; @@ -1050,6 +1146,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->motion.device = g_hash_table_lookup (device_manager->id_table, GINT_TO_POINTER (xev->deviceid)); + source_device = g_hash_table_lookup (device_manager->id_table, + GUINT_TO_POINTER (xev->sourceid)); + gdk_event_set_source_device (event, source_device); + event->motion.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons); /* There doesn't seem to be motion hints in XI */ @@ -1075,7 +1175,7 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, case XI_Leave: { XIEnterEvent *xev = (XIEnterEvent *) ev; - GdkDevice *device; + GdkDevice *device, *source_device; event->crossing.type = (ev->evtype == XI_Enter) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY; @@ -1093,6 +1193,10 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, GINT_TO_POINTER (xev->deviceid)); gdk_event_set_device (event, device); + source_device = g_hash_table_lookup (device_manager->id_table, + GUINT_TO_POINTER (xev->sourceid)); + gdk_event_set_source_device (event, source_device); + event->crossing.mode = translate_crossing_mode (xev->mode); event->crossing.detail = translate_notify_type (xev->detail); event->crossing.state = gdk_device_xi2_translate_state (&xev->mods, &xev->buttons); @@ -1102,12 +1206,16 @@ gdk_device_manager_xi2_translate_event (GdkEventTranslator *translator, case XI_FocusOut: { XIEnterEvent *xev = (XIEnterEvent *) ev; - GdkDevice *device; + GdkDevice *device, *source_device; device = g_hash_table_lookup (device_manager->id_table, GINT_TO_POINTER (xev->deviceid)); - handle_focus_change (window, device, xev->detail, xev->mode, + source_device = g_hash_table_lookup (device_manager->id_table, + GUINT_TO_POINTER (xev->sourceid)); + + handle_focus_change (window, device, source_device, + xev->detail, xev->mode, (ev->evtype == XI_FocusIn) ? TRUE : FALSE); return_val = FALSE; diff --git a/gdk/x11/gdkdevicemanager-xi2.h b/gdk/x11/gdkdevicemanager-xi2.h index 20054c160c..e16a6f7bf8 100644 --- a/gdk/x11/gdkdevicemanager-xi2.h +++ b/gdk/x11/gdkdevicemanager-xi2.h @@ -43,7 +43,6 @@ struct _GdkDeviceManagerXI2 GList *master_devices; GList *slave_devices; - GList *floating_devices; GdkDevice *client_pointer; diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index bfcc358cce..27ef251919 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -1633,7 +1633,7 @@ device_ungrab_callback (GdkDisplay *display, { GdkDevice *device = data; - _gdk_display_device_grab_update (display, device, serial); + _gdk_display_device_grab_update (display, device, NULL, serial); } diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index f9df29592f..2ce5e34875 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -136,7 +136,7 @@ has_pointer_grab_callback (GdkDisplay *display, { GdkDevice *device = data; - _gdk_display_device_grab_update (display, device, serial); + _gdk_display_device_grab_update (display, device, NULL, serial); } GdkGrabStatus diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h index fd63e8b462..85d892b283 100644 --- a/gdk/x11/gdkwindow-x11.h +++ b/gdk/x11/gdkwindow-x11.h @@ -30,11 +30,14 @@ #include "gdk/x11/gdkprivate-x11.h" #include "gdk/gdkwindowimpl.h" +#include <X11/Xlib.h> + #ifdef HAVE_XDAMAGE #include <X11/extensions/Xdamage.h> #endif #ifdef HAVE_XSYNC +#include <X11/Xlib.h> #include <X11/extensions/sync.h> #endif |