Updated user32-rawinput-mouse patchset

This update supersede user32-rawinput-mouse-experimental, removing.
This commit is contained in:
Alistair Leslie-Hughes
2024-03-09 10:46:02 +11:00
parent daf7cb4cb9
commit aa8b27c396
17 changed files with 588 additions and 1095 deletions

View File

@@ -0,0 +1,36 @@
From 22d786152100f510a69cf9a2153638c47af7f017 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 8 Mar 2024 10:48:31 +0100
Subject: [PATCH 1/7] server: Add support for absolute rawinput mouse messages.
---
server/queue.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index 0e8653bedf0..67c03c10b40 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1811,7 +1811,9 @@ static void rawmouse_init( struct rawinput *header, RAWMOUSE *rawmouse, int x, i
header->wparam = 0;
header->usage = MAKELONG(HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC);
- rawmouse->usFlags = MOUSE_MOVE_RELATIVE;
+ rawmouse->usFlags = 0;
+ if (flags & MOUSEEVENTF_ABSOLUTE) rawmouse->usFlags |= MOUSE_MOVE_ABSOLUTE;
+ if (flags & MOUSEEVENTF_VIRTUALDESK) rawmouse->usFlags |= MOUSE_VIRTUAL_DESKTOP;
rawmouse->usButtonFlags = 0;
rawmouse->usButtonData = 0;
for (i = 1; i < ARRAY_SIZE(button_flags); ++i)
@@ -2044,7 +2046,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
raw_msg.time = time;
raw_msg.message = WM_INPUT;
raw_msg.flags = flags;
- rawmouse_init( &raw_msg.rawinput, &raw_msg.data.mouse, x - desktop->cursor.x, y - desktop->cursor.y,
+ rawmouse_init( &raw_msg.rawinput, &raw_msg.data.mouse, input->mouse.x, input->mouse.y,
raw_msg.flags, input->mouse.data, input->mouse.info );
dispatch_rawinput_message( desktop, &raw_msg );
--
2.43.0

View File

@@ -0,0 +1,55 @@
From 7a0030874b52ffdb0324b8f114190e909ee572cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 8 Mar 2024 11:08:53 +0100
Subject: [PATCH 2/7] winex11: Clear the MOUSEEVENTF_MOVE flag when
accumulating motion.
---
dlls/winex11.drv/mouse.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 7293480b635..45619d4970d 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -1703,19 +1703,17 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
values++;
}
- input->mi.dx = round( x->value );
- input->mi.dy = round( y->value );
-
- TRACE( "event %f,%f value %f,%f input %d,%d\n", x_value, y_value, x->value, y->value,
- (int)input->mi.dx, (int)input->mi.dy );
-
- x->value -= input->mi.dx;
- y->value -= input->mi.dy;
-
- if (!input->mi.dx && !input->mi.dy)
+ if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value )))
{
- TRACE( "accumulating motion\n" );
- return FALSE;
+ TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value );
+ input->mi.dwFlags &= ~MOUSEEVENTF_MOVE;
+ }
+ else
+ {
+ TRACE( "event %f,%f value %f,%f, input %d,%d\n", x_value, y_value, x->value, y->value,
+ (int)input->mi.dx, (int)input->mi.dy );
+ x->value -= input->mi.dx;
+ y->value -= input->mi.dy;
}
return TRUE;
@@ -1743,6 +1741,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input.mi.dx = 0;
input.mi.dy = 0;
if (!map_raw_event_coords( event, &input )) return FALSE;
+ if (!(input.mi.dwFlags & MOUSEEVENTF_MOVE)) return FALSE;
NtUserSendHardwareInput( 0, 0, &input, 0 );
return TRUE;
--
2.43.0

View File

@@ -1,255 +0,0 @@
From e37bc9f0f5554b56861fd3971d1611e8f6db9448 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 23 Jan 2020 11:00:19 +0100
Subject: [PATCH] winex11.drv: Support XInput2 events for individual windows.
This will allow us to listen to the XInput version of several events,
which can bring additional information.
---
dlls/winex11.drv/desktop.c | 2 ++
dlls/winex11.drv/event.c | 7 +++++
dlls/winex11.drv/mouse.c | 59 +++++++++++++++++++++++++++-----------
dlls/winex11.drv/window.c | 3 ++
dlls/winex11.drv/x11drv.h | 12 +++++++-
5 files changed, 66 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c
index 687c0cf5a4c..01bd6a1b74a 100644
--- a/dlls/winex11.drv/desktop.c
+++ b/dlls/winex11.drv/desktop.c
@@ -86,6 +86,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height )
0, 0, width, height, 0, default_visual.depth, InputOutput,
default_visual.visual, CWEventMask | CWCursor | CWColormap, &win_attr );
if (!win) return FALSE;
+
+ x11drv_xinput_enable( display, win, win_attr.event_mask );
XFlush( display );
X11DRV_init_desktop( win, width, height );
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 97bec34b0ea..d2de3c53d79 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -235,6 +235,13 @@ static Bool filter_event( Display *display, XEvent *event, char *arg )
return (mask & QS_MOUSEBUTTON) != 0;
#ifdef GenericEvent
case GenericEvent:
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+ if (event->xcookie.extension == xinput2_opcode &&
+ (event->xcookie.evtype == XI_RawMotion ||
+ event->xcookie.evtype == XI_DeviceChanged))
+ return (mask & QS_MOUSEMOVE) != 0;
+#endif
+ return (mask & QS_SENDMESSAGE) != 0;
#endif
case MotionNotify:
case EnterNotify:
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 911e93d8de1..820126a2c48 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -280,20 +280,32 @@ void x11drv_xinput_init(void)
/***********************************************************************
- * enable_xinput2
+ * x11drv_xinput_enable
*/
-static void enable_xinput2(void)
+void x11drv_xinput_enable( Display *display, Window window, long event_mask )
{
struct x11drv_thread_data *data = x11drv_thread_data();
XIEventMask mask;
XIDeviceInfo *pointer_info;
unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)];
+ enum xi2_state xi2_state = data ? data->xi2_state : xi_unknown;
int count;
- TRACE( "state:%d\n", data->xi2_state );
- if (data->xi2_state != xi_disabled) return;
+ TRACE( "state:%d window:%lx event_mask:%lx\n", xi2_state, window, event_mask );
- if (!pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return;
+ if (xi2_state == xi_unavailable) return;
+
+ if (window != DefaultRootWindow( display ))
+ {
+ mask.mask = mask_bits;
+ mask.mask_len = sizeof(mask_bits);
+ mask.deviceid = XIAllMasterDevices;
+ memset( mask_bits, 0, sizeof(mask_bits) );
+
+ pXISelectEvents( display, window, &mask, 1 );
+ XSelectInput( display, window, event_mask );
+ return;
+ }
mask.mask = mask_bits;
mask.mask_len = sizeof(mask_bits);
@@ -303,8 +315,9 @@ static void enable_xinput2(void)
XISetMask( mask_bits, XI_RawMotion );
XISetMask( mask_bits, XI_ButtonPress );
- pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
+ pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 );
+ if (!data || !pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return;
pointer_info = pXIQueryDevice( data->display, data->xi2_core_pointer, &count );
update_relative_valuators( pointer_info->classes, pointer_info->num_classes );
pXIFreeDeviceInfo( pointer_info );
@@ -313,7 +326,7 @@ static void enable_xinput2(void)
* 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.
+ * safe to be obtained statically at x11drv_xinput_enable() time.
*/
if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices );
data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count );
@@ -325,24 +338,37 @@ static void enable_xinput2(void)
#endif
/***********************************************************************
- * disable_xinput2
+ * x11drv_xinput_disable
*/
-static void disable_xinput2(void)
+void x11drv_xinput_disable( Display *display, Window window, long event_mask )
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
struct x11drv_thread_data *data = x11drv_thread_data();
+ enum xi2_state xi2_state = data ? data->xi2_state : xi_unknown;
XIEventMask mask;
- TRACE( "state:%d\n", data->xi2_state );
- if (data->xi2_state != xi_enabled) return;
+ TRACE( "state:%d window:%lx event_mask:%lx\n", xi2_state, window, event_mask );
- data->xi2_state = xi_disabled;
+ if (xi2_state == xi_unavailable) return;
+
+ if (window != DefaultRootWindow( display ))
+ {
+ mask.mask = NULL;
+ mask.mask_len = 0;
+ mask.deviceid = XIAllMasterDevices;
+
+ pXISelectEvents( display, window, &mask, 1 );
+ XSelectInput( display, window, event_mask );
+ return;
+ }
mask.mask = NULL;
mask.mask_len = 0;
mask.deviceid = XIAllDevices;
- pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
+ pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 );
+
+ if (!data) return;
pXIFreeDeviceInfo( data->xi2_devices );
data->x_valuator.number = -1;
data->y_valuator.number = -1;
@@ -351,6 +377,7 @@ static void disable_xinput2(void)
data->xi2_devices = NULL;
data->xi2_core_pointer = 0;
data->xi2_current_slave = 0;
+ data->xi2_state = xi_disabled;
#endif
}
@@ -383,7 +410,7 @@ static BOOL grab_clipping_window( const RECT *clip )
}
/* enable XInput2 unless we are already clipping */
- if (!data->clipping_cursor) enable_xinput2();
+ if (!data->clipping_cursor) x11drv_xinput_enable( data->display, DefaultRootWindow( data->display ), PointerMotionMask );
if (data->xi2_state != xi_enabled)
{
@@ -423,7 +450,7 @@ static BOOL grab_clipping_window( const RECT *clip )
if (!clipping_cursor)
{
- disable_xinput2();
+ x11drv_xinput_disable( data->display, DefaultRootWindow( data->display ), PointerMotionMask );
return FALSE;
}
clip_rect = *clip;
@@ -452,7 +479,7 @@ void ungrab_clipping_window(void)
if (clipping_cursor) XUngrabPointer( data->display, CurrentTime );
clipping_cursor = FALSE;
data->clipping_cursor = FALSE;
- disable_xinput2();
+ x11drv_xinput_disable( data->display, DefaultRootWindow( data->display ), PointerMotionMask );
}
/***********************************************************************
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 53982bb8c3b..c2d7e850656 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -362,6 +362,7 @@ static void sync_window_style( struct x11drv_win_data *data )
int mask = get_window_attributes( data, &attr );
XChangeWindowAttributes( data->display, data->whole_window, mask, &attr );
+ x11drv_xinput_enable( data->display, data->whole_window, attr.event_mask );
}
}
@@ -1680,6 +1681,7 @@ static void create_whole_window( struct x11drv_win_data *data )
data->vis.visual, mask, &attr );
if (!data->whole_window) goto done;
+ x11drv_xinput_enable( data->display, data->whole_window, attr.event_mask );
set_initial_wm_hints( data->display, data->whole_window );
set_wm_hints( data );
@@ -2018,6 +2020,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd )
data->clip_window = XCreateWindow( data->display, root_window, 0, 0, 1, 1, 0, 0,
InputOnly, default_visual.visual,
CWOverrideRedirect | CWEventMask, &attr );
+ x11drv_xinput_enable( data->display, data->clip_window, attr.event_mask );
XFlush( data->display );
NtUserSetProp( hwnd, clip_window_prop, (HANDLE)data->clip_window );
X11DRV_DisplayDevices_RegisterEventHandlers();
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index fd69e55054c..1f96716b2ad 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -263,6 +263,8 @@ extern void X11DRV_ThreadDetach(void);
extern void X11DRV_Xcursor_Init(void);
extern void x11drv_xinput_load(void);
extern void x11drv_xinput_init(void);
+extern void x11drv_xinput_enable( Display *display, Window window, long event_mask );
+extern void x11drv_xinput_disable( Display *display, Window window, long event_mask );
extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
@@ -377,6 +379,14 @@ struct x11drv_escape_flush_gl_drawable
* X11 USER driver
*/
+enum xi2_state
+{
+ xi_unavailable = -1,
+ xi_unknown,
+ xi_disabled,
+ xi_enabled
+};
+
struct x11drv_thread_data
{
Display *display;
@@ -392,7 +402,7 @@ struct x11drv_thread_data
Window clip_window; /* window used for cursor clipping */
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 */
+ enum xi2_state xi2_state; /* XInput2 state */
void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */
int xi2_device_count;
XIValuatorClassInfo x_valuator;
--
2.42.0

View File

@@ -0,0 +1,93 @@
From 25e8368ac3671ab0407e66bac00c19106296d474 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 8 Mar 2024 11:15:57 +0100
Subject: [PATCH 3/7] winex11: Add support for absolute position in RawMotion
events.
---
dlls/winex11.drv/mouse.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 45619d4970d..87007b837bd 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -240,12 +240,18 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes
{
valuator = (XIValuatorClassInfo *)classes[num_classes];
if (classes[num_classes]->type != XIValuatorClass) continue;
- if (valuator->number == 0 && valuator->mode == XIModeRelative) thread_data->x_valuator = *valuator;
- if (valuator->number == 1 && valuator->mode == XIModeRelative) thread_data->y_valuator = *valuator;
+ if (valuator->number == 0) thread_data->x_valuator = *valuator;
+ if (valuator->number == 1) thread_data->y_valuator = *valuator;
}
if (thread_data->x_valuator.number < 0 || thread_data->y_valuator.number < 0)
WARN( "X/Y axis valuators not found, ignoring RawMotion events\n" );
+ else if (thread_data->x_valuator.mode != thread_data->y_valuator.mode)
+ {
+ WARN( "Relative/Absolute mismatch between X/Y axis, ignoring RawMotion events\n" );
+ thread_data->x_valuator.number = -1;
+ thread_data->y_valuator.number = -1;
+ }
thread_data->x_valuator.value = 0;
thread_data->y_valuator.value = 0;
@@ -1670,6 +1676,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
{
struct x11drv_thread_data *thread_data = x11drv_thread_data();
XIValuatorClassInfo *x = &thread_data->x_valuator, *y = &thread_data->y_valuator;
+ const UINT absolute_flags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;
double x_value = 0, y_value = 0, x_scale, y_scale;
const double *values = event->valuators.values;
RECT virtual_rect;
@@ -1680,7 +1687,15 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
if (!xinput2_available) return FALSE;
if (event->deviceid != thread_data->xinput2_pointer) return FALSE;
- virtual_rect = NtUserGetVirtualScreenRect();
+ if (x->mode == XIModeRelative && y->mode == XIModeRelative)
+ input->mi.dwFlags &= ~absolute_flags;
+ else if (x->mode == XIModeAbsolute && y->mode == XIModeAbsolute)
+ input->mi.dwFlags |= absolute_flags;
+ else
+ FIXME( "Unsupported relative/absolute X/Y axis mismatch\n." );
+
+ if (input->mi.dwFlags & MOUSEEVENTF_VIRTUALDESK) SetRect( &virtual_rect, 0, 0, UINT16_MAX, UINT16_MAX );
+ else virtual_rect = NtUserGetVirtualScreenRect();
if (x->max <= x->min) x_scale = 1;
else x_scale = (virtual_rect.right - virtual_rect.left) / (x->max - x->min);
@@ -1693,17 +1708,26 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
if (i == x->number)
{
x_value = *values;
- x->value += x_value * x_scale;
+ if (x->mode == XIModeRelative) x->value += x_value * x_scale;
+ else x->value = (x_value - x->min) * x_scale;
}
if (i == y->number)
{
y_value = *values;
- y->value += y_value * y_scale;
+ if (y->mode == XIModeRelative) y->value += y_value * y_scale;
+ else y->value = (y_value - y->min) * y_scale;
}
values++;
}
- if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value )))
+ if (input->mi.dwFlags & MOUSEEVENTF_ABSOLUTE)
+ {
+ input->mi.dx = round( x->value );
+ input->mi.dy = round( y->value );
+ TRACE( "event %f,%f value %f,%f absolute input %d,%d\n", x_value, y_value, x->value, y->value,
+ (int)input->mi.dx, (int)input->mi.dy );
+ }
+ else if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value )))
{
TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value );
input->mi.dwFlags &= ~MOUSEEVENTF_MOVE;
--
2.43.0

View File

@@ -0,0 +1,122 @@
From 5e9af0573526693cbc98ad8282b5f2023c6b5bf7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 26 Aug 2019 14:37:20 +0200
Subject: [PATCH 4/7] server: Add send_hardware_message flags for rawinput
translation.
---
include/ntuser.h | 4 ++++
server/protocol.def | 3 +--
server/queue.c | 16 ++++++++++------
3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/include/ntuser.h b/include/ntuser.h
index f947fec7fea..4ded432bd99 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -1423,6 +1423,10 @@ struct hid_packet
C_ASSERT(sizeof(struct hid_packet) == offsetof(struct hid_packet, data[0]));
+#define SEND_HWMSG_INJECTED 1
+#define SEND_HWMSG_NO_RAW 2
+#define SEND_HWMSG_NO_MSG 4
+
struct send_hardware_input_params
{
UINT flags;
diff --git a/server/protocol.def b/server/protocol.def
index 7b21aa16636..8e483bf3bbf 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2126,7 +2126,7 @@ enum message_type
@REQ(send_hardware_message)
user_handle_t win; /* window handle */
hw_input_t input; /* input data */
- unsigned int flags; /* flags (see below) */
+ unsigned int flags; /* flags (see ntuser.h) */
VARARG(report,bytes); /* HID report data */
@REPLY
int wait; /* do we need to wait for a reply? */
@@ -2135,7 +2135,6 @@ enum message_type
int new_x; /* new cursor position */
int new_y;
@END
-#define SEND_HWMSG_INJECTED 0x01
/* Get a message from the current queue */
diff --git a/server/queue.c b/server/queue.c
index 67c03c10b40..0687a7feac1 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1983,7 +1983,7 @@ static void dispatch_rawinput_message( struct desktop *desktop, struct rawinput_
/* queue a hardware message for a mouse event */
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
- unsigned int origin, struct msg_queue *sender )
+ unsigned int origin, struct msg_queue *sender, unsigned int send_flags )
{
const struct rawinput_device *device;
struct hardware_msg_data *msg_data;
@@ -2038,7 +2038,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
y = desktop->cursor.y;
}
- if ((foreground = get_foreground_thread( desktop, win )))
+ if (!(send_flags & SEND_HWMSG_NO_RAW) && (foreground = get_foreground_thread( desktop, win )))
{
memset( &raw_msg, 0, sizeof(raw_msg) );
raw_msg.foreground = foreground;
@@ -2060,6 +2060,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
return 0;
}
+ if (send_flags & SEND_HWMSG_NO_MSG) return 0;
+
for (i = 0; i < ARRAY_SIZE( messages ); i++)
{
if (!messages[i]) continue;
@@ -2091,7 +2093,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
/* queue a hardware message for a keyboard event */
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
- unsigned int origin, struct msg_queue *sender )
+ unsigned int origin, struct msg_queue *sender, unsigned int send_flags )
{
struct hw_msg_source source = { IMDT_KEYBOARD, origin };
const struct rawinput_device *device;
@@ -2168,7 +2170,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
break;
}
- if ((foreground = get_foreground_thread( desktop, win )))
+ if (!(send_flags & SEND_HWMSG_NO_RAW) && (foreground = get_foreground_thread( desktop, win )))
{
struct rawinput_message raw_msg = {0};
raw_msg.foreground = foreground;
@@ -2189,6 +2191,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
return 0;
}
+ if (send_flags & SEND_HWMSG_NO_MSG) return 0;
+
if (!(msg = alloc_hardware_message( input->kbd.info, source, time, 0 ))) return 0;
msg_data = msg->data;
@@ -2936,10 +2940,10 @@ DECL_HANDLER(send_hardware_message)
switch (req->input.type)
{
case INPUT_MOUSE:
- wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender );
+ wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags );
break;
case INPUT_KEYBOARD:
- wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender );
+ wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags );
break;
case INPUT_HARDWARE:
queue_custom_hardware_message( desktop, req->win, origin, &req->input );
--
2.43.0

View File

@@ -1,100 +0,0 @@
From 5afa48387aee90fcc968ae049a1d047271cf4ecc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 26 Aug 2019 14:37:20 +0200
Subject: [PATCH] server: Add send_hardware_message flags for rawinput
translation.
---
dlls/win32u/message.c | 2 ++
server/protocol.def | 1 +
server/queue.c | 12 ++++++------
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c
index d15f9af3f9f..5f7ac9189c3 100644
--- a/dlls/win32u/message.c
+++ b/dlls/win32u/message.c
@@ -3463,6 +3463,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.mouse.flags = input->mi.dwFlags;
req->input.mouse.time = input->mi.time;
req->input.mouse.info = input->mi.dwExtraInfo;
+ req->flags |= SEND_HWMSG_RAWINPUT;
affects_key_state = !!(input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP |
MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP |
MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP |
@@ -3474,6 +3475,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.kbd.flags = input->ki.dwFlags;
req->input.kbd.time = input->ki.time;
req->input.kbd.info = input->ki.dwExtraInfo;
+ req->flags |= SEND_HWMSG_RAWINPUT;
affects_key_state = TRUE;
break;
case INPUT_HARDWARE:
diff --git a/server/protocol.def b/server/protocol.def
index 919297c818c..416fdf020fd 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2143,6 +2143,7 @@ enum message_type
int new_y;
@END
#define SEND_HWMSG_INJECTED 0x01
+#define SEND_HWMSG_RAWINPUT 0x02
/* Get a message from the current queue */
diff --git a/server/queue.c b/server/queue.c
index fcc946ff0cb..f62593b096a 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1845,7 +1845,7 @@ done:
/* queue a hardware message for a mouse event */
static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
- unsigned int origin, struct msg_queue *sender )
+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
{
const struct rawinput_device *device;
struct hardware_msg_data *msg_data;
@@ -1900,7 +1900,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
y = desktop->cursor.y;
}
- if ((foreground = get_foreground_thread( desktop, win )))
+ if ((req_flags & SEND_HWMSG_RAWINPUT) && (foreground = get_foreground_thread( desktop, win )))
{
memset( &raw_msg, 0, sizeof(raw_msg) );
raw_msg.foreground = foreground;
@@ -1960,7 +1960,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
/* queue a hardware message for a keyboard event */
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input,
- unsigned int origin, struct msg_queue *sender )
+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags )
{
struct hw_msg_source source = { IMDT_KEYBOARD, origin };
const struct rawinput_device *device;
@@ -2038,7 +2038,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
break;
}
- if ((foreground = get_foreground_thread( desktop, win )))
+ if ((req_flags & SEND_HWMSG_RAWINPUT) && (foreground = get_foreground_thread( desktop, win )))
{
memset( &raw_msg, 0, sizeof(raw_msg) );
raw_msg.foreground = foreground;
@@ -2664,10 +2664,10 @@ DECL_HANDLER(send_hardware_message)
switch (req->input.type)
{
case INPUT_MOUSE:
- reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender );
+ reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags );
break;
case INPUT_KEYBOARD:
- reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender );
+ reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags );
break;
case INPUT_HARDWARE:
queue_custom_hardware_message( desktop, req->win, origin, &req->input );
--
2.40.1

View File

@@ -1,7 +1,7 @@
From 7fcbbbd139dc8504ca084e468afc436cfaee6ef1 Mon Sep 17 00:00:00 2001
From f1a3f71d4de4721ec1760236215a213088961594 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 19 Dec 2019 22:34:44 +0100
Subject: [PATCH] winex11.drv: Keep track of pointer and device button
Subject: [PATCH 5/7] winex11: Keep track of mouse device and pointer button
mappings.
We are going to receive raw button events and we will need to apply the
@@ -9,49 +9,69 @@ correct button mappings ourselves.
Original patch by Andrew Eikum <aeikum@codeweavers.com>.
---
dlls/winex11.drv/keyboard.c | 23 ++++++---
dlls/winex11.drv/mouse.c | 89 +++++++++++++++++++++++++++++++++-
configure.ac | 1 +
dlls/winex11.drv/keyboard.c | 24 +++++++--
dlls/winex11.drv/mouse.c | 93 +++++++++++++++++++++++++++++++++-
dlls/winex11.drv/x11drv.h | 1 +
dlls/winex11.drv/x11drv_main.c | 1 +
4 files changed, 106 insertions(+), 8 deletions(-)
5 files changed, 114 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index 2b16df17bb8..93f6d57e686 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1201,6 +1201,7 @@ then
dnl *** All of the following tests require X11/Xlib.h
AC_CHECK_HEADERS([X11/extensions/shape.h \
+ X11/extensions/XInput.h \
X11/extensions/XInput2.h \
X11/extensions/XShm.h \
X11/extensions/Xfixes.h \
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 5c7f6c37276..674d8d6db58 100644
index 23f07b851a7..130b7e516a2 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1848,13 +1848,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
@@ -1838,11 +1838,7 @@ BOOL X11DRV_ActivateKeyboardLayout(HKL hkl, UINT flags)
return TRUE;
}
-
-/***********************************************************************
- * X11DRV_MappingNotify
- */
-BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
+static BOOL X11DRV_KeyboardMappingNotify( HWND dummy, XEvent *event )
{
HWND hwnd;
- XRefreshKeyboardMapping(&event->xmapping);
- X11DRV_InitKeyboard( event->xmapping.display );
@@ -1856,6 +1852,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
return TRUE;
}
+/***********************************************************************
+ * X11DRV_MappingNotify
+ */
+BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event )
+{
+ switch (event->xmapping.request)
+ {
+ case MappingModifier:
+ case MappingKeyboard:
+ XRefreshKeyboardMapping( &event->xmapping );
+ X11DRV_InitKeyboard( event->xmapping.display );
+
+ hwnd = get_focus();
+ if (!hwnd) hwnd = get_active_window();
+ NtUserPostMessage( hwnd, WM_INPUTLANGCHANGEREQUEST,
+ 0 /*FIXME*/, (LPARAM)NtUserGetKeyboardLayout(0) );
+ break;
+
+ return X11DRV_KeyboardMappingNotify( dummy, event );
+ case MappingPointer:
+ X11DRV_InitMouse( event->xmapping.display );
+ break;
+ }
+
+ return TRUE;
+}
+
- hwnd = get_focus();
- if (!hwnd) hwnd = get_active_window();
- NtUserPostMessage( hwnd, WM_INPUTLANGCHANGEREQUEST,
- 0 /*FIXME*/, (LPARAM)NtUserGetKeyboardLayout(0) );
return TRUE;
}
/***********************************************************************
* VkKeyScanEx (X11DRV.@)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index ab89f32a8a2..75d961423ba 100644
index 87007b837bd..f10d3cfb2d6 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -30,6 +30,9 @@
@@ -79,7 +99,7 @@ index ab89f32a8a2..75d961423ba 100644
/***********************************************************************
* X11DRV_Xcursor_Init
*
@@ -224,6 +235,70 @@ void set_window_cursor( Window window, HCURSOR handle )
@@ -224,6 +235,75 @@ void set_window_cursor( Window window, HCURSOR handle )
XFlush( gdi_display );
}
@@ -93,6 +113,8 @@ index ab89f32a8a2..75d961423ba 100644
+static struct mouse_button_mapping *pointer_mapping;
+static struct mouse_button_mapping *device_mapping;
+
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
+
+static void update_pointer_mapping( Display *display )
+{
+ struct mouse_button_mapping *tmp;
@@ -106,14 +128,11 @@ index ab89f32a8a2..75d961423ba 100644
+ tmp->button_count = ARRAY_SIZE( tmp->buttons );
+ tmp->button_count = XGetPointerMapping( display, tmp->buttons, tmp->button_count );
+
+ tmp = InterlockedExchangePointer( (void**)&pointer_mapping, tmp );
+
+ free( tmp );
+ free( InterlockedExchangePointer( (void**)&pointer_mapping, tmp ) );
+}
+
+static void update_device_mapping( Display *display, int deviceid )
+{
+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H
+ struct mouse_button_mapping *tmp;
+ XDevice *device;
+
@@ -134,47 +153,47 @@ index ab89f32a8a2..75d961423ba 100644
+ tmp->button_count = ARRAY_SIZE( tmp->buttons );
+ tmp->button_count = pXGetDeviceButtonMapping( display, device, tmp->buttons, tmp->button_count );
+
+ tmp = InterlockedExchangePointer( (void**)&device_mapping, tmp );
+
+ free( tmp );
+ free( InterlockedExchangePointer( (void**)&device_mapping, tmp ) );
+
+ pXCloseDevice( display, device );
+#endif
+}
+
+void X11DRV_InitMouse( Display *display )
+{
+ update_pointer_mapping( display );
+}
+
+#else /* HAVE_X11_EXTENSIONS_XINPUT_H */
+
+void X11DRV_InitMouse( Display *display )
+{
+}
+
+#endif /* HAVE_X11_EXTENSIONS_XINPUT_H */
+
+
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
/***********************************************************************
* update_relative_valuators
@@ -1677,6 +1752,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
if (event->reason != XISlaveSwitch) return FALSE;
@@ -1669,6 +1749,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
if (event->deviceid != data->xinput2_pointer) return FALSE;
update_relative_valuators( event->classes, event->num_classes );
+ update_device_mapping( event->display, event->sourceid );
+
return TRUE;
}
@@ -1764,13 +1841,12 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
-
/***********************************************************************
* x11drv_xinput_load
@@ -1817,7 +1899,7 @@ static BOOL X11DRV_TouchEvent( HWND hwnd, XGenericEventCookie *xev )
*/
void x11drv_xinput_load(void)
void x11drv_xinput2_load(void)
{
-#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H)
+#if defined(SONAME_LIBXI)
int event, error;
void *libxi_handle = dlopen( SONAME_LIBXI, RTLD_NOW );
@@ -1786,11 +1862,20 @@ void x11drv_xinput_load(void)
@@ -1833,11 +1915,20 @@ void x11drv_xinput2_load(void)
return; \
}
@@ -196,10 +215,10 @@ index ab89f32a8a2..75d961423ba 100644
xinput2_available = XQueryExtension( gdi_display, "XInputExtension", &xinput2_opcode, &event, &error );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 4d94f042ee1..7ad685dfafb 100644
index 2f46522f59f..655c6847b92 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -692,6 +692,7 @@ extern void retry_grab_clipping_window(void);
@@ -684,6 +684,7 @@ extern void retry_grab_clipping_window(void);
extern void ungrab_clipping_window(void);
extern void move_resize_window( HWND hwnd, int dir );
extern void X11DRV_InitKeyboard( Display *display );
@@ -208,10 +227,10 @@ index 4d94f042ee1..7ad685dfafb 100644
extern HWND *build_hwnd_list(void);
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 573a41bbe96..0eb5a2e8d45 100644
index 0925fe54b9c..4b4d5563b60 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -704,6 +704,7 @@ static NTSTATUS x11drv_init( void *arg )
@@ -699,6 +699,7 @@ static NTSTATUS x11drv_init( void *arg )
XkbUseExtension( gdi_display, NULL, NULL );
X11DRV_InitKeyboard( gdi_display );
@@ -220,5 +239,5 @@ index 573a41bbe96..0eb5a2e8d45 100644
init_user_driver();
--
2.42.0
2.43.0

View File

@@ -1,244 +0,0 @@
From 1c5763ee8859e76c72b2247a846bdf9addf9b138 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 24 Mar 2021 23:29:28 +0100
Subject: [PATCH] user32: Set SEND_HWMSG_RAWINPUT flags only when RAWINPUT is
set.
So we can generate legacy messages only by calling __wine_send_input
with NULL rawinput, and generate WM_INPUT messages only by calling
__wine_send_input with INPUT_HARDWARE input type and a rawinput.
---
dlls/win32u/input.c | 3 ++-
dlls/win32u/message.c | 4 ++--
dlls/wineandroid.drv/keyboard.c | 3 ++-
dlls/wineandroid.drv/window.c | 5 +++--
dlls/winemac.drv/keyboard.c | 3 ++-
dlls/winemac.drv/mouse.c | 3 ++-
dlls/winex11.drv/keyboard.c | 3 ++-
dlls/winex11.drv/mouse.c | 11 +++++++----
8 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c
index 1f9e48423fc..dc8f44ee910 100644
--- a/dlls/win32u/input.c
+++ b/dlls/win32u/input.c
@@ -655,6 +655,7 @@ UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size )
{
UINT i;
NTSTATUS status = STATUS_SUCCESS;
+ RAWINPUT rawinput;
if (size != sizeof(INPUT))
{
@@ -684,7 +685,7 @@ UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size )
update_mouse_coords( &input );
/* fallthrough */
case INPUT_KEYBOARD:
- status = send_hardware_message( 0, &input, NULL, SEND_HWMSG_INJECTED );
+ status = send_hardware_message( 0, &input, &rawinput, SEND_HWMSG_INJECTED );
break;
case INPUT_HARDWARE:
RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED );
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c
index 5f7ac9189c3..b60afaad475 100644
--- a/dlls/win32u/message.c
+++ b/dlls/win32u/message.c
@@ -3463,7 +3463,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.mouse.flags = input->mi.dwFlags;
req->input.mouse.time = input->mi.time;
req->input.mouse.info = input->mi.dwExtraInfo;
- req->flags |= SEND_HWMSG_RAWINPUT;
+ if (rawinput) req->flags |= SEND_HWMSG_RAWINPUT;
affects_key_state = !!(input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP |
MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP |
MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP |
@@ -3475,7 +3475,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
req->input.kbd.flags = input->ki.dwFlags;
req->input.kbd.time = input->ki.time;
req->input.kbd.info = input->ki.dwExtraInfo;
- req->flags |= SEND_HWMSG_RAWINPUT;
+ if (rawinput) req->flags |= SEND_HWMSG_RAWINPUT;
affects_key_state = TRUE;
break;
case INPUT_HARDWARE:
diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c
index 9f369094949..1606afb3f86 100644
--- a/dlls/wineandroid.drv/keyboard.c
+++ b/dlls/wineandroid.drv/keyboard.c
@@ -671,6 +671,7 @@ static BOOL get_async_key_state( BYTE state[256] )
static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags )
{
+ RAWINPUT rawinput;
INPUT input;
input.type = INPUT_KEYBOARD;
@@ -680,7 +681,7 @@ static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags )
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
- __wine_send_input( hwnd, &input, NULL );
+ __wine_send_input( hwnd, &input, &rawinput );
}
/***********************************************************************
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c
index d62a2c53909..47a424b40b8 100644
--- a/dlls/wineandroid.drv/window.c
+++ b/dlls/wineandroid.drv/window.c
@@ -421,6 +421,7 @@ static int process_events( DWORD mask )
DPI_AWARENESS_CONTEXT context;
struct java_event *event, *next, *previous;
unsigned int count = 0;
+ RAWINPUT rawinput;
assert( GetCurrentThreadId() == desktop_tid );
@@ -514,7 +515,7 @@ static int process_events( DWORD mask )
}
SERVER_END_REQ;
}
- __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, NULL );
+ __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, &rawinput );
}
break;
@@ -528,7 +529,7 @@ static int process_events( DWORD mask )
event->data.kbd.input.ki.wVk, event->data.kbd.input.ki.wVk,
event->data.kbd.input.ki.wScan );
update_keyboard_lock_state( event->data.kbd.input.ki.wVk, event->data.kbd.lock_state );
- __wine_send_input( 0, &event->data.kbd.input, NULL );
+ __wine_send_input( 0, &event->data.kbd.input, &rawinput );
break;
default:
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c
index c1963daa56e..14f0010e37e 100644
--- a/dlls/winemac.drv/keyboard.c
+++ b/dlls/winemac.drv/keyboard.c
@@ -990,6 +990,7 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
*/
static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, unsigned int flags, unsigned int time)
{
+ RAWINPUT rawinput;
INPUT input;
TRACE_(key)("hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags);
@@ -1001,7 +1002,7 @@ static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, unsigned
input.ki.time = time;
input.ki.dwExtraInfo = 0;
- __wine_send_input(hwnd, &input, NULL);
+ __wine_send_input(hwnd, &input, &rawinput);
}
diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c
index 5c04c71e1dc..260831c44dc 100644
--- a/dlls/winemac.drv/mouse.c
+++ b/dlls/winemac.drv/mouse.c
@@ -129,6 +129,7 @@ static const CFStringRef cocoa_cursor_names[] =
static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, int x, int y,
DWORD mouse_data, BOOL drag, unsigned long time)
{
+ RAWINPUT rawinput;
INPUT input;
HWND top_level_hwnd;
@@ -158,7 +159,7 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags,
input.mi.time = time;
input.mi.dwExtraInfo = 0;
- __wine_send_input(top_level_hwnd, &input, NULL);
+ __wine_send_input(top_level_hwnd, &input, &rawinput);
}
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index b54ca795954..231af33fd48 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1121,6 +1121,7 @@ static WORD EVENT_event_to_vkey( XIC xic, XKeyEvent *e)
*/
static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, UINT flags, UINT time )
{
+ RAWINPUT rawinput;
INPUT input;
TRACE_(key)( "hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags );
@@ -1132,7 +1133,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, UINT fl
input.ki.time = time;
input.ki.dwExtraInfo = 0;
- __wine_send_input( hwnd, &input, NULL );
+ __wine_send_input( hwnd, &input, &rawinput );
}
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 33f6ac24af8..ca0092f21c1 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -626,6 +626,7 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x
static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input )
{
struct x11drv_win_data *data;
+ RAWINPUT rawinput;
input->type = INPUT_MOUSE;
@@ -633,7 +634,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
{
struct x11drv_thread_data *thread_data = x11drv_thread_data();
if (!thread_data->clipping_cursor || thread_data->clip_window != window) return;
- __wine_send_input( hwnd, input, NULL );
+ __wine_send_input( hwnd, input, &rawinput );
return;
}
@@ -660,7 +661,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
SERVER_END_REQ;
}
- __wine_send_input( hwnd, input, NULL );
+ __wine_send_input( hwnd, input, &rawinput );
}
#ifdef SONAME_LIBXCURSOR
@@ -1588,6 +1589,7 @@ void move_resize_window( HWND hwnd, int dir )
{
MSG msg;
INPUT input;
+ RAWINPUT rawinput;
int x, y, rootX, rootY;
if (!XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &x, &y, &xstate )) break;
@@ -1603,7 +1605,7 @@ void move_resize_window( HWND hwnd, int dir )
input.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
input.mi.time = NtGetTickCount();
input.mi.dwExtraInfo = 0;
- __wine_send_input( hwnd, &input, NULL );
+ __wine_send_input( hwnd, &input, &rawinput );
}
while (NtUserPeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
@@ -1816,6 +1818,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
{
XIRawEvent *event = xev->data;
+ RAWINPUT rawinput;
INPUT input;
if (broken_rawevents && is_old_motion_event( xev->serial ))
@@ -1833,7 +1836,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input.mi.dy = 0;
if (!map_raw_event_coords( event, &input )) return FALSE;
- __wine_send_input( 0, &input, NULL );
+ __wine_send_input( 0, &input, &rawinput );
return TRUE;
}
--
2.40.1

View File

@@ -0,0 +1,229 @@
From 1c3132e5307aead682883f5f7613d5811d38b53a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 25 Oct 2021 11:45:47 +0200
Subject: [PATCH 6/7] winex11: Listen to Raw(Motion|Button) events in the
desktop thread.
We still need to send "normal" input from the clipping window thread
to trigger low-level hooks callbacks when clipping cursor. This is for
instance used in our dinput implementation.
---
dlls/winex11.drv/event.c | 10 ++++--
dlls/winex11.drv/mouse.c | 73 ++++++++++++++++++++++++++++++++++++---
dlls/winex11.drv/window.c | 4 +++
dlls/winex11.drv/x11drv.h | 1 +
4 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 8b02361aaff..f4e290f8b8f 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -315,6 +315,10 @@ static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawE
*/
static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
{
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+#endif
+
switch (prev->type)
{
case ConfigureNotify:
@@ -346,19 +350,21 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
case GenericEvent:
if (next->xcookie.extension != xinput2_opcode) break;
if (next->xcookie.evtype != XI_RawMotion) break;
- if (x11drv_thread_data()->warp_serial) break;
+ if (thread_data->xinput2_rawinput) break;
+ if (thread_data->warp_serial) break;
return MERGE_KEEP;
}
break;
case GenericEvent:
if (prev->xcookie.extension != xinput2_opcode) break;
if (prev->xcookie.evtype != XI_RawMotion) break;
+ if (thread_data->xinput2_rawinput) break;
switch (next->type)
{
case GenericEvent:
if (next->xcookie.extension != xinput2_opcode) break;
if (next->xcookie.evtype != XI_RawMotion) break;
- if (x11drv_thread_data()->warp_serial) break;
+ if (thread_data->warp_serial) break;
return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data );
#endif
}
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index f10d3cfb2d6..6557331df22 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -343,6 +343,7 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes
*/
void x11drv_xinput2_enable( Display *display, Window window )
{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
XIEventMask mask;
unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)];
@@ -357,7 +358,13 @@ void x11drv_xinput2_enable( Display *display, Window window )
{
XISetMask( mask_bits, XI_DeviceChanged );
XISetMask( mask_bits, XI_RawMotion );
- XISetMask( mask_bits, XI_ButtonPress );
+ if (!thread_data->xinput2_rawinput)
+ XISetMask( mask_bits, XI_ButtonPress );
+ else
+ {
+ XISetMask( mask_bits, XI_RawButtonPress );
+ XISetMask( mask_bits, XI_RawButtonRelease );
+ }
}
else
{
@@ -375,10 +382,12 @@ void x11drv_xinput2_enable( Display *display, Window window )
*/
void x11drv_xinput2_disable( Display *display, Window window )
{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)];
XIEventMask mask;
if (!xinput2_available) return;
+ if (thread_data->xinput2_rawinput) return;
mask.mask = mask_bits;
mask.mask_len = sizeof(mask_bits);
@@ -632,7 +641,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
{
struct x11drv_thread_data *thread_data = x11drv_thread_data();
if (!thread_data->clipping_cursor || thread_data->clip_window != window) return;
- NtUserSendHardwareInput( hwnd, 0, input, 0 );
+ NtUserSendHardwareInput( hwnd, SEND_HWMSG_NO_RAW, input, 0 );
return;
}
@@ -659,7 +668,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
SERVER_END_REQ;
}
- NtUserSendHardwareInput( hwnd, 0, input, 0 );
+ NtUserSendHardwareInput( hwnd, SEND_HWMSG_NO_RAW, input, 0 );
}
#ifdef SONAME_LIBXCURSOR
@@ -1602,7 +1611,7 @@ void move_resize_window( HWND hwnd, int dir )
input.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
input.mi.time = NtGetTickCount();
input.mi.dwExtraInfo = 0;
- NtUserSendHardwareInput( hwnd, 0, &input, 0 );
+ NtUserSendHardwareInput( hwnd, SEND_HWMSG_NO_RAW, &input, 0 );
}
while (NtUserPeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
@@ -1830,6 +1839,8 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
*/
static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+ UINT flags = thread_data->xinput2_rawinput ? SEND_HWMSG_NO_MSG : SEND_HWMSG_NO_RAW;
XIRawEvent *event = xev->data;
INPUT input;
@@ -1849,7 +1860,55 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
if (!map_raw_event_coords( event, &input )) return FALSE;
if (!(input.mi.dwFlags & MOUSEEVENTF_MOVE)) return FALSE;
- NtUserSendHardwareInput( 0, 0, &input, 0 );
+ NtUserSendHardwareInput( 0, flags, &input, 0 );
+ return TRUE;
+}
+
+/***********************************************************************
+ * X11DRV_RawButtonEvent
+ */
+static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie )
+{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+ const UINT *button_data, *button_flags;
+ XIRawEvent *event = cookie->data;
+ int button = event->detail - 1;
+ INPUT input;
+
+ if (!thread_data->xinput2_rawinput) return FALSE;
+
+ if (!device_mapping || device_mapping->deviceid != event->sourceid)
+ update_device_mapping( event->display, event->sourceid );
+
+ if (button >= 0 && device_mapping) button = device_mapping->buttons[button] - 1;
+ if (button >= 0 && pointer_mapping) button = pointer_mapping->buttons[button] - 1;
+
+ if (button < 0 || button >= NB_BUTTONS) return FALSE;
+ if (event->deviceid != thread_data->xinput2_pointer) return FALSE;
+
+ TRACE( "raw button %u (raw: %u) %s\n", button, event->detail, event->evtype == XI_RawButtonRelease ? "up" : "down" );
+
+ if (event->evtype == XI_RawButtonRelease)
+ {
+ button_data = button_up_data;
+ button_flags = button_up_flags;
+ }
+ else
+ {
+ button_data = button_down_data;
+ button_flags = button_down_flags;
+ }
+
+ input.type = INPUT_MOUSE;
+ input.mi.mouseData = button_data[button];
+ input.mi.dwFlags = button_flags[button] | MOUSEEVENTF_MOVE;
+ input.mi.time = EVENT_x11_time_to_win32_time( event->time );
+ input.mi.dwExtraInfo = 0;
+ input.mi.dx = 0;
+ input.mi.dy = 0;
+ map_raw_event_coords( event, &input );
+
+ NtUserSendHardwareInput( 0, SEND_HWMSG_NO_MSG, &input, 0 );
return TRUE;
}
@@ -1964,6 +2023,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
case XI_RawMotion:
ret = X11DRV_RawMotion( event );
break;
+ case XI_RawButtonPress:
+ case XI_RawButtonRelease:
+ ret = X11DRV_RawButtonEvent( event );
+ break;
case XI_TouchBegin:
case XI_TouchUpdate:
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index cbe4fc197d1..03ad33060ae 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2040,6 +2040,10 @@ BOOL X11DRV_CreateWindow( HWND hwnd )
struct x11drv_thread_data *data = x11drv_init_thread_data();
XSetWindowAttributes attr;
+ /* listen to raw xinput event in the desktop window thread */
+ data->xinput2_rawinput = TRUE;
+ x11drv_xinput2_enable( data->display, DefaultRootWindow( data->display ) );
+
/* create the cursor clipping window */
attr.override_redirect = TRUE;
attr.event_mask = StructureNotifyMask | FocusChangeMask;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 655c6847b92..37bd1d9d91c 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -395,6 +395,7 @@ struct x11drv_thread_data
XIValuatorClassInfo x_valuator;
XIValuatorClassInfo y_valuator;
int xinput2_pointer; /* XInput2 master pointer device id */
+ int xinput2_rawinput; /* XInput2 rawinput-only thread */
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
};
--
2.43.0

View File

@@ -1,45 +0,0 @@
From 84e2d01ee1a616724d5a61ca95db13b309b752f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 25 Mar 2021 14:26:35 +0100
Subject: [PATCH] user32: Support sending RIM_TYPEMOUSE through
__wine_send_input.
---
dlls/win32u/message.c | 6 ++++++
server/queue.c | 3 +++
2 files changed, 9 insertions(+)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c
index 99bae5280f6..ff8f5bd6d87 100644
--- a/dlls/win32u/message.c
+++ b/dlls/win32u/message.c
@@ -3553,6 +3553,12 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r
case WM_INPUT_DEVICE_CHANGE:
switch (rawinput->header.dwType)
{
+ case RIM_TYPEMOUSE:
+ req->input.hw.mouse.x = rawinput->data.mouse.lLastX;
+ req->input.hw.mouse.y = rawinput->data.mouse.lLastY;
+ req->input.hw.mouse.data = rawinput->data.mouse.ulRawButtons;
+ req->input.hw.lparam = rawinput->data.mouse.usFlags;
+ break;
case RIM_TYPEHID:
req->input.hw.wparam = rawinput->header.wParam;
req->input.hw.hid.device = HandleToUlong( rawinput->header.hDevice );
diff --git a/server/queue.c b/server/queue.c
index e234b5e8af9..1aedda1ca71 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -2109,6 +2109,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
raw_msg.rawinput.kbd.vkey = vkey;
raw_msg.rawinput.kbd.scan = input->kbd.scan;
+ if (input->hw.msg == WM_INPUT && input->hw.rawinput.type == RIM_TYPEMOUSE)
+ msg_data->flags = input->hw.lparam;
+
enum_processes( queue_rawinput_message, &raw_msg );
release_object( foreground );
}
--
2.43.0

View File

@@ -0,0 +1,91 @@
From 63298efb1ad8f04f38f7e1bc518bec7786192d26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 8 Mar 2024 11:11:27 +0100
Subject: [PATCH 7/7] winex11: Send relative RawMotion events position
unprocessed.
This makes relative raw input independent from cursor speed, as it is
the case on Windows. Absolute raw input is already translated to
virtual desktop space, and cursor speed is meaningless in this case.
This does not support mixed relative/absolute X/Y axis.
---
dlls/winex11.drv/mouse.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 6557331df22..d26ed5d794b 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -1763,13 +1763,13 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
return TRUE;
}
-static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
+static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input, BOOL send_raw )
{
struct x11drv_thread_data *thread_data = x11drv_thread_data();
XIValuatorClassInfo *x = &thread_data->x_valuator, *y = &thread_data->y_valuator;
+ const double *values = event->valuators.values, *raw_values = event->raw_values;
const UINT absolute_flags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;
- double x_value = 0, y_value = 0, x_scale, y_scale;
- const double *values = event->valuators.values;
+ double x_raw = 0, y_raw = 0, x_value = 0, y_value = 0, x_scale, y_scale;
RECT virtual_rect;
int i;
@@ -1798,16 +1798,19 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
if (i == x->number)
{
+ x_raw = *raw_values;
x_value = *values;
if (x->mode == XIModeRelative) x->value += x_value * x_scale;
else x->value = (x_value - x->min) * x_scale;
}
if (i == y->number)
{
+ y_raw = *raw_values;
y_value = *values;
if (y->mode == XIModeRelative) y->value += y_value * y_scale;
else y->value = (y_value - y->min) * y_scale;
}
+ raw_values++;
values++;
}
@@ -1818,6 +1821,13 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
TRACE( "event %f,%f value %f,%f absolute input %d,%d\n", x_value, y_value, x->value, y->value,
(int)input->mi.dx, (int)input->mi.dy );
}
+ else if (send_raw)
+ {
+ input->mi.dx = round( x_raw );
+ input->mi.dy = round( y_raw );
+ TRACE( "event %f,%f raw value %f,%f, raw input %d,%d\n", x_value, y_value, x_raw, y_raw,
+ (int)input->mi.dx, (int)input->mi.dy );
+ }
else if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value )))
{
TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value );
@@ -1857,7 +1867,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input.mi.dwExtraInfo = 0;
input.mi.dx = 0;
input.mi.dy = 0;
- if (!map_raw_event_coords( event, &input )) return FALSE;
+ if (!map_raw_event_coords( event, &input, flags & SEND_HWMSG_NO_MSG )) return FALSE;
if (!(input.mi.dwFlags & MOUSEEVENTF_MOVE)) return FALSE;
NtUserSendHardwareInput( 0, flags, &input, 0 );
@@ -1906,7 +1916,7 @@ static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie )
input.mi.dwExtraInfo = 0;
input.mi.dx = 0;
input.mi.dy = 0;
- map_raw_event_coords( event, &input );
+ map_raw_event_coords( event, &input, TRUE );
NtUserSendHardwareInput( 0, SEND_HWMSG_NO_MSG, &input, 0 );
return TRUE;
--
2.43.0

View File

@@ -1,264 +0,0 @@
From 1bf08ef753b4f7fc43e72aa71c20c1b952b83bb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 25 Oct 2021 11:45:47 +0200
Subject: [PATCH] winex11.drv: Listen to RawMotion and RawButton* events in the
desktop thread.
We still need to send "normal" input from the clipping window thread
to trigger low-level hooks callbacks when clipping cursor. This is for
instance used in our dinput implementation.
---
dlls/winex11.drv/event.c | 10 +++-
dlls/winex11.drv/mouse.c | 105 +++++++++++++++++++++++++++++++++++---
dlls/winex11.drv/window.c | 4 ++
dlls/winex11.drv/x11drv.h | 1 +
4 files changed, 111 insertions(+), 9 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index f6d9041ca65..d11f75cf1a6 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -318,6 +318,10 @@ static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawE
*/
static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
{
+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+#endif
+
switch (prev->type)
{
case ConfigureNotify:
@@ -349,19 +353,21 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next )
case GenericEvent:
if (next->xcookie.extension != xinput2_opcode) break;
if (next->xcookie.evtype != XI_RawMotion) break;
- if (x11drv_thread_data()->warp_serial) break;
+ if (thread_data->xi2_rawinput_only) break;
+ if (thread_data->warp_serial) break;
return MERGE_KEEP;
}
break;
case GenericEvent:
if (prev->xcookie.extension != xinput2_opcode) break;
if (prev->xcookie.evtype != XI_RawMotion) break;
+ if (thread_data->xi2_rawinput_only) break;
switch (next->type)
{
case GenericEvent:
if (next->xcookie.extension != xinput2_opcode) break;
if (next->xcookie.evtype != XI_RawMotion) break;
- if (x11drv_thread_data()->warp_serial) break;
+ if (thread_data->warp_serial) break;
return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data );
#endif
}
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index ca0092f21c1..0a1ce16381c 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -388,7 +388,16 @@ void x11drv_xinput_enable( Display *display, Window window, long event_mask )
memset( mask_bits, 0, sizeof(mask_bits) );
XISetMask( mask_bits, XI_DeviceChanged );
XISetMask( mask_bits, XI_RawMotion );
- XISetMask( mask_bits, XI_ButtonPress );
+
+ if (data->xi2_rawinput_only)
+ {
+ XISetMask( mask_bits, XI_RawButtonPress );
+ XISetMask( mask_bits, XI_RawButtonRelease );
+ }
+ else
+ {
+ XISetMask( mask_bits, XI_ButtonPress );
+ }
pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 );
@@ -415,6 +424,7 @@ void x11drv_xinput_disable( Display *display, Window window, long event_mask )
TRACE( "state:%d window:%lx event_mask:%lx\n", xi2_state, window, event_mask );
if (xi2_state == xi_unavailable) return;
+ if (data->xi2_rawinput_only) return;
if (window != DefaultRootWindow( display ))
{
@@ -626,7 +636,6 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x
static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input )
{
struct x11drv_win_data *data;
- RAWINPUT rawinput;
input->type = INPUT_MOUSE;
@@ -634,7 +643,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
{
struct x11drv_thread_data *thread_data = x11drv_thread_data();
if (!thread_data->clipping_cursor || thread_data->clip_window != window) return;
- __wine_send_input( hwnd, input, &rawinput );
+ __wine_send_input( hwnd, input, NULL );
return;
}
@@ -661,7 +670,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
SERVER_END_REQ;
}
- __wine_send_input( hwnd, input, &rawinput );
+ __wine_send_input( hwnd, input, NULL );
}
#ifdef SONAME_LIBXCURSOR
@@ -1589,7 +1598,6 @@ void move_resize_window( HWND hwnd, int dir )
{
MSG msg;
INPUT input;
- RAWINPUT rawinput;
int x, y, rootX, rootY;
if (!XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &x, &y, &xstate )) break;
@@ -1605,7 +1613,7 @@ void move_resize_window( HWND hwnd, int dir )
input.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
input.mi.time = NtGetTickCount();
input.mi.dwExtraInfo = 0;
- __wine_send_input( hwnd, &input, &rawinput );
+ __wine_send_input( hwnd, &input, NULL );
}
while (NtUserPeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
@@ -1817,6 +1825,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
*/
static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
XIRawEvent *event = xev->data;
RAWINPUT rawinput;
INPUT input;
@@ -1836,7 +1845,85 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
input.mi.dy = 0;
if (!map_raw_event_coords( event, &input )) return FALSE;
- __wine_send_input( 0, &input, &rawinput );
+ if (!thread_data->xi2_rawinput_only)
+ __wine_send_input( 0, &input, NULL );
+ else
+ {
+ rawinput.header.dwType = RIM_TYPEMOUSE;
+ rawinput.header.dwSize = offsetof(RAWINPUT, data) + sizeof(RAWMOUSE);
+ rawinput.header.hDevice = ULongToHandle(1); /* WINE_MOUSE_HANDLE */
+ rawinput.header.wParam = RIM_INPUT;
+ rawinput.data.mouse.usFlags = input.mi.dwFlags;
+ rawinput.data.mouse.ulRawButtons = 0;
+ rawinput.data.mouse.usButtonData = 0;
+ rawinput.data.mouse.usButtonFlags = 0;
+ rawinput.data.mouse.lLastX = input.mi.dx;
+ rawinput.data.mouse.lLastY = input.mi.dy;
+ rawinput.data.mouse.ulExtraInformation = 0;
+
+ input.type = INPUT_HARDWARE;
+ input.hi.uMsg = WM_INPUT;
+ input.hi.wParamH = 0;
+ input.hi.wParamL = 0;
+ if (rawinput.data.mouse.lLastX || rawinput.data.mouse.lLastY)
+ __wine_send_input( 0, &input, &rawinput );
+ }
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * X11DRV_RawButtonEvent
+ */
+static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie )
+{
+ struct x11drv_thread_data *thread_data = x11drv_thread_data();
+ XIRawEvent *event = cookie->data;
+ int button = event->detail - 1;
+ RAWINPUT rawinput;
+ INPUT input;
+
+ if (!device_mapping || device_mapping->deviceid != event->sourceid)
+ update_device_mapping( event->display, event->sourceid );
+
+ if (button >= 0 && device_mapping)
+ button = device_mapping->buttons[button] - 1;
+
+ if (button >= 0 && pointer_mapping)
+ button = pointer_mapping->buttons[button] - 1;
+
+ if (button < 0 || button >= NB_BUTTONS) return FALSE;
+ if (thread_data->xi2_state != xi_enabled) return FALSE;
+ if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
+
+ TRACE( "raw button %u (raw: %u) %s\n", button, event->detail, event->evtype == XI_RawButtonRelease ? "up" : "down" );
+
+ rawinput.header.dwType = RIM_TYPEMOUSE;
+ rawinput.header.dwSize = offsetof(RAWINPUT, data) + sizeof(RAWMOUSE);
+ rawinput.header.hDevice = ULongToHandle(1); /* WINE_MOUSE_HANDLE */
+ rawinput.header.wParam = RIM_INPUT;
+ if (event->evtype == XI_RawButtonRelease)
+ {
+ rawinput.data.mouse.usFlags = button_up_flags[button];
+ rawinput.data.mouse.ulRawButtons = button_up_data[button];
+ }
+ else
+ {
+ rawinput.data.mouse.usFlags = button_down_flags[button];
+ rawinput.data.mouse.ulRawButtons = button_down_data[button];
+ }
+ rawinput.data.mouse.usButtonData = 0;
+ rawinput.data.mouse.usButtonFlags = 0;
+ rawinput.data.mouse.lLastX = 0;
+ rawinput.data.mouse.lLastY = 0;
+ rawinput.data.mouse.ulExtraInformation = 0;
+
+ input.type = INPUT_HARDWARE;
+ input.hi.uMsg = WM_INPUT;
+ input.hi.wParamH = 0;
+ input.hi.wParamL = 0;
+ if (rawinput.data.mouse.usFlags || rawinput.data.mouse.ulRawButtons)
+ __wine_send_input( 0, &input, &rawinput );
return TRUE;
}
@@ -1912,6 +1999,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
case XI_RawMotion:
ret = X11DRV_RawMotion( event );
break;
+ case XI_RawButtonPress:
+ case XI_RawButtonRelease:
+ ret = X11DRV_RawButtonEvent( event );
+ break;
default:
TRACE( "Unhandled event %#x\n", event->evtype );
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index f043e64047e..bf7afe0e8bf 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1999,6 +1999,10 @@ BOOL X11DRV_CreateWindow( HWND hwnd )
struct x11drv_thread_data *data = x11drv_init_thread_data();
XSetWindowAttributes attr;
+ /* listen to raw xinput event in the desktop window thread */
+ data->xi2_rawinput_only = TRUE;
+ x11drv_xinput_enable( data->display, DefaultRootWindow( data->display ), PointerMotionMask );
+
/* create the cursor clipping window */
attr.override_redirect = TRUE;
attr.event_mask = StructureNotifyMask | FocusChangeMask;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 8bbac23f88e..55b3049a7cc 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -405,6 +405,7 @@ struct x11drv_thread_data
XIValuatorClassInfo x_valuator;
XIValuatorClassInfo y_valuator;
int xi2_core_pointer; /* XInput2 core pointer id */
+ int xi2_rawinput_only;
#endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
};
--
2.40.1

View File

@@ -1,3 +1,2 @@
Fixes: [42631] Mouse drift, jump or don't react to small slow movements in Unity-engine games and Fallout 4 (partly fixed in Unity games, have walkaround in Fallout4 )
Fixes: [42675] Overwatch: Phantom mouse input / view pulled up to ceiling
Disabled: True