Module: wine
Branch: master
Commit: 1a757a0146ef9cb7d7b1e6b6a4345d4c592a46b8
URL: https://gitlab.winehq.org/wine/wine/-/commit/1a757a0146ef9cb7d7b1e6b6a4345d…
Author: Rémi Bernon <rbernon(a)codeweavers.com>
Date: Sun Jan 28 18:28:24 2024 +0100
winex11: Advertise XInput2 version 2.2 support.
This is the required version for XInput2 touch events. It also allows
to greatly simplify the code by listening to master device events only
and get rid of device id tracking:
Under XInput2 protocol version < 2.1, RawEvents are not supposed to be
sent if a pointer grab is active. However slave device events are still
received regardless of this specification and Wine implemented a
workaround to receive RawEvents during pointer grabs by listening to
these slave device events.
By advertising the support of XInput2 version >= 2.1, where RawEvents
are sent even during pointer grabs, we ensure to receive the RawMotion
even if a mouse grab is active.
---
dlls/winex11.drv/mouse.c | 50 ++++++++---------------------------------------
dlls/winex11.drv/x11drv.h | 5 +----
2 files changed, 9 insertions(+), 46 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 612fff9995c..f02ca5355c5 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -268,7 +268,7 @@ static void enable_xinput2(void)
if (data->xi2_state == xi_unknown)
{
- int major = 2, minor = 0;
+ int major = 2, minor = 2;
if (!pXIQueryVersion( data->display, &major, &minor )) data->xi2_state = xi_disabled;
else
{
@@ -277,11 +277,11 @@ static void enable_xinput2(void)
}
}
if (data->xi2_state == xi_unavailable) return;
- if (!pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return;
+ if (!pXIGetClientPointer( data->display, None, &data->xinput2_pointer )) return;
mask.mask = mask_bits;
mask.mask_len = sizeof(mask_bits);
- mask.deviceid = XIAllDevices;
+ mask.deviceid = XIAllMasterDevices;
memset( mask_bits, 0, sizeof(mask_bits) );
XISetMask( mask_bits, XI_DeviceChanged );
XISetMask( mask_bits, XI_RawMotion );
@@ -289,20 +289,10 @@ static void enable_xinput2(void)
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
- pointer_info = pXIQueryDevice( data->display, data->xi2_core_pointer, &count );
+ pointer_info = pXIQueryDevice( data->display, data->xinput2_pointer, &count );
update_relative_valuators( pointer_info->classes, pointer_info->num_classes );
pXIFreeDeviceInfo( pointer_info );
- /* This device info list is only used to find the initial current slave if
- * no XI_DeviceChanged events happened. If any hierarchy change occurred that
- * might be relevant here (eg. user switching mice after (un)plugging), a
- * XI_DeviceChanged event will point us to the right slave. So this list is
- * safe to be obtained statically at enable_xinput2() time.
- */
- if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
- data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
- data->xi2_current_slave = 0;
-
data->xi2_state = xi_enabled;
}
@@ -324,17 +314,14 @@ static void disable_xinput2(void)
mask.mask = NULL;
mask.mask_len = 0;
- mask.deviceid = XIAllDevices;
+ mask.deviceid = XIAllMasterDevices;
pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
- pXIFreeDeviceInfo( data->xi2_devices );
data->x_valuator.number = -1;
data->y_valuator.number = -1;
data->x_valuator.value = 0;
data->y_valuator.value = 0;
- data->xi2_devices = NULL;
- data->xi2_core_pointer = 0;
- data->xi2_current_slave = 0;
+ data->xinput2_pointer = 0;
#endif
}
@@ -1643,11 +1630,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
XIDeviceChangedEvent *event = xev->data;
struct x11drv_thread_data *data = x11drv_thread_data();
- if (event->deviceid != data->xi2_core_pointer) return FALSE;
- if (event->reason != XISlaveSwitch) return FALSE;
-
+ if (event->deviceid != data->xinput2_pointer) return FALSE;
update_relative_valuators( event->classes, event->num_classes );
- data->xi2_current_slave = event->sourceid;
return TRUE;
}
@@ -1663,25 +1647,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
if (x->number < 0 || y->number < 0) return FALSE;
if (!event->valuators.mask_len) return FALSE;
if (thread_data->xi2_state != xi_enabled) return FALSE;
-
- /* If there is no slave currently detected, no previous motion nor device
- * change events were received. Look it up now on the device list in this
- * case.
- */
- if (!thread_data->xi2_current_slave)
- {
- XIDeviceInfo *devices = thread_data->xi2_devices;
-
- for (i = 0; i < thread_data->xi2_device_count; i++)
- {
- if (devices[i].use != XISlavePointer) continue;
- if (devices[i].deviceid != event->deviceid) continue;
- if (devices[i].attachment != thread_data->xi2_core_pointer) continue;
- thread_data->xi2_current_slave = event->deviceid;
- break;
- }
- }
- if (event->deviceid != thread_data->xi2_current_slave) return FALSE;
+ if (event->deviceid != thread_data->xinput2_pointer) return FALSE;
virtual_rect = NtUserGetVirtualScreenRect();
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index d5edb9ba377..dbf7d07e3d4 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -394,12 +394,9 @@ struct x11drv_thread_data
BOOL clipping_cursor; /* whether thread is currently clipping the cursor */
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
- void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */
- int xi2_device_count;
XIValuatorClassInfo x_valuator;
XIValuatorClassInfo y_valuator;
- int xi2_core_pointer; /* XInput2 core pointer id */
- int xi2_current_slave; /* Current slave driving the Core pointer */
+ int xinput2_pointer; /* XInput2 master pointer device id */
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
};