winex11: Always use the Virtual Core Pointer for raw events

Carlos Garnacho carlosg at gnome.org
Sat Nov 12 10:14:19 CST 2016


Detection of the master pointer Wine listens to for raw events
is busted. First, it's trying to do so based on the capabilities of
the master pointer (looking for rel x/y axes), whereas master devices
always get their capabilities updated to reflect those of the device
that was last interacted by the user. This means that if the user
interacts with a device not having relative axes (eg. a touchscreen)
right before Wine tries to enable XI2, the check will fail despite
the master pointer having attached HW devices with relative axes.

Second, in the unlikely case that Wine managed to detect a master
pointer other than the VCP (this requires user intervention, creating
a second pointer/keyboard pair and assigning HW devices to it) This
second pointer would be unaffected by the core X calls performed by
Wine (eg. grabs,cursor). This could eg. result in Wine grabbing/confining
one pointer, while listening to raw events from another, which is
otherwise unaffected by the grab.

The Virtual Core Pointer is a given, it always has ID=2, it's created
by default, it can't be removed, it's the one getting HW devices attached
to by default, and it will be the device implicitly used by the other
X core calls. It's the device Wine wants to listen to despite its initial
state.

The main purpose of this patch is fixing master device detection over
Xwayland, which is affected by the relative axes check. Xwayland will
most usually emit pointer events as coming from a device with absolute
axes, only switching to emitting relative motion when a very specific
set of conditions are met (thought out for gaming basically). But most
usually these conditions don't apply yet when XI2 is enabled, so the
VCP is skipped and it ends up with xi2_core_pointer=0, thus ignoring
the relative motion that is later sent.

But again, this is not Xwayland specific, it could happen as well with
the right conditions on traditional X servers.

Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
---
 dlls/winex11.drv/mouse.c | 24 ++----------------------
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index a120fae..f799f8b 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -129,6 +129,7 @@ static RECT clip_rect;
 static Cursor create_cursor( HANDLE handle );
 
 #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+#define VIRTUAL_CORE_POINTER 2 /* Virtual Core Pointer has always deviceid=2 */
 static BOOL xinput2_available;
 static BOOL broken_rawevents;
 #define MAKE_FUNCPTR(f) static typeof(f) * p##f
@@ -273,28 +274,7 @@ static void enable_xinput2(void)
 
     if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
     data->xi2_devices = devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
-    for (i = 0; i < data->xi2_device_count; ++i)
-    {
-        if (devices[i].use != XIMasterPointer) continue;
-        for (j = count = 0; j < devices[i].num_classes; j++)
-        {
-            XIValuatorClassInfo *class = (XIValuatorClassInfo *)devices[i].classes[j];
-
-            if (devices[i].classes[j]->type != XIValuatorClass) continue;
-            TRACE( "Device %u (%s) num %u %f,%f res %u mode %u label %s\n",
-                   devices[i].deviceid, debugstr_a(devices[i].name),
-                   class->number, class->min, class->max, class->resolution, class->mode,
-                   XGetAtomName( data->display, class->label ));
-            if (class->label == x11drv_atom( Rel_X ) || class->label == x11drv_atom( Rel_Y )) count++;
-            /* workaround for drivers that don't provide labels */
-            if (!class->label && class->number <= 1 && class->mode == XIModeRelative) count++;
-        }
-        if (count < 2) continue;
-        TRACE( "Using %u (%s) as core pointer\n",
-               devices[i].deviceid, debugstr_a(devices[i].name) );
-        data->xi2_core_pointer = devices[i].deviceid;
-        break;
-    }
+    data->xi2_core_pointer = VIRTUAL_CORE_POINTER;
 
     mask.mask     = mask_bits;
     mask.mask_len = sizeof(mask_bits);
-- 
2.9.3




More information about the wine-patches mailing list