wine-staging/patches/user32-rawinput-mouse-experimental/0004-winex11.drv-Accumulate-mouse-movement-to-avoid-round.patch
Alistair Leslie-Hughes 8218a78955 Updated rawinput patchsets
This is a completely updated rawinput patchsets from RĂ©mi Bernon,
replacing the current user32-rawinput.
2019-12-23 21:47:16 +11:00

122 lines
4.8 KiB
Diff

From cf8668ffad406a26dde59993b81619c966446975 Mon Sep 17 00:00:00 2001
From: Jordan Galby <gravemind2a+wine@gmail.com>
Date: Tue, 16 Jul 2019 00:34:38 -0400
Subject: [PATCH 4/4] winex11.drv: Accumulate mouse movement to avoid rounding
losses.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
From: Jordan Galby <gravemind2a+wine@gmail.com>
---
dlls/winex11.drv/mouse.c | 44 +++++++++++++++++++++++++++++++++-------
1 file changed, 37 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 49734ba195b..b5cba492d7e 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -376,6 +376,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
thread_data->x_pos_valuator.min = thread_data->x_pos_valuator.max = 0;
if (thread_data->y_pos_valuator.min >= thread_data->y_pos_valuator.max)
thread_data->y_pos_valuator.min = thread_data->y_pos_valuator.max = 0;
+
+ thread_data->x_pos_valuator.value = 0;
+ thread_data->y_pos_valuator.value = 0;
+ thread_data->wheel_valuator.value = 0;
}
#endif
@@ -1917,6 +1921,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
double dx = 0, dy = 0, dw = 0, val;
double raw_dx = 0, raw_dy = 0, raw_val;
double x_scale = 1, y_scale = 1;
+ double x_accum = 0, y_accum = 0, w_accum = 0;
struct x11drv_thread_data *thread_data = x11drv_thread_data();
XIValuatorClassInfo *x_pos, *y_pos, *wheel;
@@ -1929,6 +1934,10 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
y_pos = &thread_data->y_pos_valuator;
wheel = &thread_data->wheel_valuator;
+ x_accum = x_pos->value;
+ y_accum = y_pos->value;
+ w_accum = wheel->value;
+
input.type = INPUT_MOUSE;
input.u.mi.mouseData = 0;
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
@@ -1956,9 +1965,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
raw_dx = raw_val;
input.u.mi.dwFlags |= (x_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
if (x_pos->mode == XIModeAbsolute)
- input.u.mi.dx = (dx - x_pos->min) * x_scale;
+ x_accum = (dx - x_pos->min) * x_scale;
else
- input.u.mi.dx = dx * x_scale;
+ x_accum += dx * x_scale;
}
if (i == y_pos->number)
{
@@ -1966,24 +1975,38 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
raw_dy = raw_val;
input.u.mi.dwFlags |= (y_pos->mode == XIModeAbsolute ? MOUSEEVENTF_ABSOLUTE : 0);
if (y_pos->mode == XIModeAbsolute)
- input.u.mi.dy = (dy - y_pos->min) * y_scale;
+ y_accum = (dy - y_pos->min) * y_scale;
else
- input.u.mi.dy = dy * y_scale;
+ y_accum += dy * y_scale;
}
if (i == wheel->number)
{
dw = val;
input.u.mi.dwFlags |= MOUSEEVENTF_WHEEL;
- input.u.mi.mouseData = dw * thread_data->wheel_scale;
+ w_accum += dw * thread_data->wheel_scale;
}
}
+ /* Accumulate the fractional parts so they aren't lost after casting
+ * successive motion values to integral fields.
+ *
+ * Note: It looks like raw_dx, raw_dy and raw_dw are already
+ * integral values but that may be wrong.
+ */
+ input.u.mi.dx = (LONG)x_accum;
+ input.u.mi.dy = (LONG)y_accum;
+ input.u.mi.mouseData = (DWORD)w_accum;
+
if (broken_rawevents && is_old_motion_event( xev->serial ))
{
TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, xev->serial );
return FALSE;
}
+ x_pos->value = x_accum - input.u.mi.dx;
+ y_pos->value = y_accum - input.u.mi.dy;
+ wheel->value = w_accum - input.u.mi.mouseData;
+
if (x_pos->mode == XIModeAbsolute)
{
TRACE( "pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, dx, dy, dw );
@@ -1991,8 +2014,15 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
}
else if (!thread_data->xi2_rawinput_only)
{
- TRACE( "pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, dx, dy, dw );
- __wine_send_input( 0, &input, SEND_HWMSG_WINDOW );
+ if ((dy || dy || dw) && !(input.u.mi.dx || input.u.mi.dy || input.u.mi.mouseData))
+ {
+ TRACE( "accumulating raw motion (event %f,%f,%f accum %f,%f,%f)\n", dx, dy, dw, x_pos->value, y_pos->value, wheel->value );
+ }
+ else
+ {
+ TRACE( "pos %d,%d w:%d (event %f,%f,%f)\n", input.u.mi.dx, input.u.mi.dy, input.u.mi.mouseData, dx, dy, dw );
+ __wine_send_input( 0, &input, SEND_HWMSG_WINDOW );
+ }
}
else
{
--
2.24.1