[PATCH 8/9] winex11.drv: Advertise XInput2 version 2.1 support.
Rémi Bernon
rbernon at codeweavers.com
Wed Sep 25 04:35:44 CDT 2019
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.
However as soon as a mouse button is pressed, only the grabbing client
will receive the raw motion events.
By advertising the support of XInput2 version >= 2.1, where rawevents
are sent even during pointer grabs, we ensure to receive the RawMotion
events from the desktop window thread, even if a mouse grab is active.
It is also possible to simplify the code by listening to master device
events only and get rid of slave device id tracking.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/winex11.drv/mouse.c | 49 ++++++++-------------------------------
dlls/winex11.drv/x11drv.h | 3 ---
2 files changed, 10 insertions(+), 42 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index cedb488614d..2c68e68a992 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -304,12 +304,16 @@ static void enable_xinput2(void)
if (data->xi2_state == xi_unknown)
{
- int major = 2, minor = 0;
- if (!pXIQueryVersion( data->display, &major, &minor )) data->xi2_state = xi_disabled;
+ int major = 2, minor = 1;
+ if (!pXIQueryVersion( data->display, &major, &minor ) && major == 2 && minor > 0)
+ {
+ TRACE( "XInput2 v%d.%d available\n", major, minor );
+ data->xi2_state = xi_disabled;
+ }
else
{
data->xi2_state = xi_unavailable;
- WARN( "X Input 2 not available\n" );
+ WARN( "XInput v2.1 not available\n" );
}
}
if (data->xi2_state == xi_unavailable) return;
@@ -317,7 +321,7 @@ static void enable_xinput2(void)
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 );
@@ -329,16 +333,6 @@ static void enable_xinput2(void)
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;
#endif
}
@@ -359,15 +353,12 @@ 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_rel_valuator.number = -1;
data->y_rel_valuator.number = -1;
- data->xi2_devices = NULL;
data->xi2_core_pointer = 0;
- data->xi2_current_slave = 0;
#endif
}
@@ -1763,7 +1754,6 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
if (event->reason != XISlaveSwitch) return FALSE;
update_relative_valuators( event->classes, event->num_classes );
- data->xi2_current_slave = event->sourceid;
return TRUE;
}
@@ -1784,26 +1774,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.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->xi2_core_pointer) return FALSE;
x_rel = &thread_data->x_rel_valuator;
y_rel = &thread_data->y_rel_valuator;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index d4e476facb2..7dd8c158617 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -336,12 +336,9 @@ struct x11drv_thread_data
DWORD clip_reset; /* time when clipping was last reset */
HKL kbd_layout; /* active keyboard layout */
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;
struct x11drv_valuator_data x_rel_valuator;
struct x11drv_valuator_data y_rel_valuator;
int xi2_core_pointer; /* XInput2 core pointer id */
- int xi2_current_slave; /* Current slave driving the Core pointer */
};
extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
--
2.23.0
More information about the wine-devel
mailing list