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

@ -1,27 +0,0 @@
From 021af6dcf439d70df46b9fc839c2cc0877b8e43c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 28 Oct 2021 09:11:02 +0200
Subject: [PATCH] server: Clear the MOUSEEVENTF_(ABSOLUTE|VIRTUALDESK) flags.
For rawinput messages, as user32 is currently only expecting relative
motion.
---
server/queue.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/queue.c b/server/queue.c
index 1aedda1ca71..87b25820cfe 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1967,7 +1967,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
raw_msg.message = WM_INPUT;
raw_msg.info = input->mouse.info;
- raw_msg.flags = flags;
+ raw_msg.flags = flags & ~(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK);
raw_msg.rawinput.type = RIM_TYPEMOUSE;
raw_msg.rawinput.mouse.x = x - desktop->cursor.x;
raw_msg.rawinput.mouse.y = y - desktop->cursor.y;
--
2.43.0

View File

@ -1,26 +0,0 @@
From 0a849a6fcdab538be01d2eb3b0bb9c1dd42e9d6a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 25 Oct 2021 11:26:43 +0200
Subject: [PATCH] user32: Add support for absolute rawinput messages.
---
dlls/win32u/rawinput.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c
index 81403771c4a..186bd1e52b1 100644
--- a/dlls/win32u/rawinput.c
+++ b/dlls/win32u/rawinput.c
@@ -96,7 +96,8 @@ static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct har
rawinput->header.hDevice = WINE_MOUSE_HANDLE;
rawinput->header.wParam = 0;
- rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE;
+ rawinput->data.mouse.usFlags = msg_data->flags & MOUSEEVENTF_ABSOLUTE ? MOUSE_MOVE_ABSOLUTE : MOUSE_MOVE_RELATIVE;
+ if (msg_data->flags & MOUSEEVENTF_VIRTUALDESK) rawinput->data.mouse.usFlags |= MOUSE_VIRTUAL_DESKTOP;
rawinput->data.mouse.usButtonFlags = 0;
rawinput->data.mouse.usButtonData = 0;
for (i = 1; i < ARRAY_SIZE(button_flags); ++i)
--
2.35.1

View File

@ -1,30 +0,0 @@
From 7ab586e1da370ab17f5cc64dc97449a436f2fa5e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 25 Oct 2021 11:22:04 +0200
Subject: [PATCH] server: Stop enforcing relative rawinput mouse positions.
---
server/queue.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/server/queue.c b/server/queue.c
index 87b25820cfe..a94bdf53939 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1967,10 +1967,10 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
raw_msg.message = WM_INPUT;
raw_msg.info = input->mouse.info;
- raw_msg.flags = flags & ~(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK);
+ raw_msg.flags = flags;
raw_msg.rawinput.type = RIM_TYPEMOUSE;
- raw_msg.rawinput.mouse.x = x - desktop->cursor.x;
- raw_msg.rawinput.mouse.y = y - desktop->cursor.y;
+ raw_msg.rawinput.mouse.x = (flags & MOUSEEVENTF_MOVE) ? input->mouse.x : 0;
+ raw_msg.rawinput.mouse.y = (flags & MOUSEEVENTF_MOVE) ? input->mouse.y : 0;
raw_msg.rawinput.mouse.data = input->mouse.data;
enum_processes( queue_rawinput_message, &raw_msg );
--
2.43.0

View File

@ -1,3 +0,0 @@
Fixes: [45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games).
Depends: user32-rawinput-mouse
Disabled: True

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

@ -1,17 +1,18 @@
From eef4aa97b1271118a95419cbca2870c0bfa6fbcd Mon Sep 17 00:00:00 2001
From 25e8368ac3671ab0407e66bac00c19106296d474 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 28 Oct 2021 09:18:37 +0200
Subject: [PATCH] winex11.drv: Add support for absolute RawMotion events.
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 | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
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 ec12c8b1917..f10745a1ad0 100644
index 45619d4970d..87007b837bd 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -315,12 +315,18 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes
@@ -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;
@ -32,24 +33,32 @@ index ec12c8b1917..f10745a1ad0 100644
thread_data->x_valuator.value = 0;
thread_data->y_valuator.value = 0;
@@ -1778,7 +1784,15 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
if (thread_data->xi2_state != xi_enabled) return FALSE;
if (event->deviceid != thread_data->xi2_core_pointer) return FALSE;
@@ -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 &= ~(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK);
+ input->mi.dwFlags &= ~absolute_flags;
+ else if (x->mode == XIModeAbsolute && y->mode == XIModeAbsolute)
+ input->mi.dwFlags |= MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;
+ 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, 65535, 65535 );
+ 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);
@@ -1791,12 +1805,14 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
@@ -1693,17 +1708,26 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
if (i == x->number)
{
x_value = *values;
@ -66,6 +75,19 @@ index ec12c8b1917..f10745a1ad0 100644
}
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.40.1
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

@ -1,7 +1,8 @@
From d45e910803dd78f892ddece1743849943d7c67f3 Mon Sep 17 00:00:00 2001
From 63298efb1ad8f04f38f7e1bc518bec7786192d26 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 25 Oct 2021 11:48:00 +0200
Subject: [PATCH] winex11.drv: Send relative RawMotion events unprocessed.
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
@ -9,30 +10,31 @@ 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 | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
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 4a42b3c85b6..e58ee125c95 100644
index 6557331df22..d26ed5d794b 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -1770,12 +1770,12 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev )
@@ -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, RAWINPUT *rawinput )
+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;
+ const double *values = event->valuators.values, *raw_values = event->raw_values;
+ double x_raw = 0, y_raw = 0, x_value = 0, y_value = 0, x_scale, y_scale;
RECT virtual_rect;
int i;
@@ -1804,22 +1804,30 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
@@ -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)
{
@ -52,35 +54,38 @@ index 4a42b3c85b6..e58ee125c95 100644
values++;
}
input->mi.dx = round( x->value );
input->mi.dy = round( y->value );
+ if (x->mode != XIModeAbsolute) rawinput->data.mouse.lLastX = x_raw;
+ else rawinput->data.mouse.lLastX = input->mi.dx;
+ if (y->mode != XIModeAbsolute) rawinput->data.mouse.lLastY = y_raw;
+ else rawinput->data.mouse.lLastY = input->mi.dy;
+
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 );
@@ -1858,7 +1866,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
@@ -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, &rawinput )) return FALSE;
+ if (!map_raw_event_coords( event, &input, flags & SEND_HWMSG_NO_MSG )) return FALSE;
if (!(input.mi.dwFlags & MOUSEEVENTF_MOVE)) return FALSE;
if (!thread_data->xi2_rawinput_only)
__wine_send_input( 0, &input, NULL );
@@ -1872,8 +1880,6 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
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;
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 );
input.type = INPUT_HARDWARE;
NtUserSendHardwareInput( 0, SEND_HWMSG_NO_MSG, &input, 0 );
return TRUE;
--
2.40.1
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