summaryrefslogtreecommitdiff
path: root/gdk/x11
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/x11')
-rw-r--r--gdk/x11/gdkdevicemanager-x11.c2
-rw-r--r--gdk/x11/gdkdevicemanager-xi2.c178
-rw-r--r--gdk/x11/gdkdevicemanager-xi2.h1
-rw-r--r--gdk/x11/gdkdisplay-x11.c2
-rw-r--r--gdk/x11/gdkmain-x11.c2
-rw-r--r--gdk/x11/gdkwindow-x11.h3
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