2021-04-09 15:39:38 -07:00
|
|
|
From 8ec7d7199eb28051e8403867a16257f8974414f0 Mon Sep 17 00:00:00 2001
|
|
|
|
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
|
|
|
|
Date: Thu, 25 Mar 2021 14:40:26 +0100
|
2020-06-30 15:30:13 -07:00
|
|
|
Subject: [PATCH] winex11.drv: Accumulate mouse movement to avoid rounding
|
2019-12-23 01:03:44 -08:00
|
|
|
losses.
|
|
|
|
|
|
|
|
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=42631
|
|
|
|
From: Jordan Galby <gravemind2a+wine@gmail.com>
|
|
|
|
---
|
2019-12-23 13:17:06 -08:00
|
|
|
dlls/winex11.drv/mouse.c | 40 +++++++++++++++++++++++++++++++++-------
|
|
|
|
1 file changed, 33 insertions(+), 7 deletions(-)
|
2019-12-23 01:03:44 -08:00
|
|
|
|
|
|
|
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
|
2021-04-09 15:39:38 -07:00
|
|
|
index 44e9786cd9f..0e1559a88f3 100644
|
2019-12-23 01:03:44 -08:00
|
|
|
--- a/dlls/winex11.drv/mouse.c
|
|
|
|
+++ b/dlls/winex11.drv/mouse.c
|
2020-06-30 15:30:13 -07:00
|
|
|
@@ -365,6 +365,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
|
2019-12-23 01:03:44 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-04-09 15:39:38 -07:00
|
|
|
@@ -1961,6 +1964,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
2019-12-23 13:17:06 -08:00
|
|
|
double dx = 0, dy = 0, val;
|
2019-12-23 01:03:44 -08:00
|
|
|
double raw_dx = 0, raw_dy = 0, raw_val;
|
|
|
|
double x_scale = 1, y_scale = 1;
|
2019-12-23 13:17:06 -08:00
|
|
|
+ double x_accum = 0, y_accum = 0;
|
2019-12-23 01:03:44 -08:00
|
|
|
struct x11drv_thread_data *thread_data = x11drv_thread_data();
|
2019-12-23 13:17:06 -08:00
|
|
|
XIValuatorClassInfo *x_pos, *y_pos;
|
2019-12-23 01:03:44 -08:00
|
|
|
|
2021-04-09 15:39:38 -07:00
|
|
|
@@ -1972,6 +1976,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
2019-12-23 13:17:06 -08:00
|
|
|
x_pos = &thread_data->x_pos_valuator;
|
2019-12-23 01:03:44 -08:00
|
|
|
y_pos = &thread_data->y_pos_valuator;
|
|
|
|
|
|
|
|
+ x_accum = x_pos->value;
|
|
|
|
+ y_accum = y_pos->value;
|
|
|
|
+
|
|
|
|
input.type = INPUT_MOUSE;
|
|
|
|
input.u.mi.mouseData = 0;
|
|
|
|
input.u.mi.dwFlags = MOUSEEVENTF_MOVE;
|
2021-04-09 15:39:38 -07:00
|
|
|
@@ -1999,9 +2006,9 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
2019-12-23 01:03:44 -08:00
|
|
|
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)
|
|
|
|
{
|
2021-04-09 15:39:38 -07:00
|
|
|
@@ -2009,22 +2016,41 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
2019-12-23 01:03:44 -08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+ /* Accumulate the fractional parts so they aren't lost after casting
|
|
|
|
+ * successive motion values to integral fields.
|
|
|
|
+ *
|
2019-12-23 13:17:06 -08:00
|
|
|
+ * Note: It looks like raw_dx, raw_dy are already
|
2019-12-23 01:03:44 -08:00
|
|
|
+ * integral values but that may be wrong.
|
|
|
|
+ */
|
|
|
|
+ input.u.mi.dx = (LONG)x_accum;
|
|
|
|
+ input.u.mi.dy = (LONG)y_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;
|
|
|
|
+
|
2021-04-09 15:39:38 -07:00
|
|
|
if (!thread_data->xi2_rawinput_only)
|
2019-12-23 01:03:44 -08:00
|
|
|
{
|
2019-12-23 13:17:06 -08:00
|
|
|
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
2021-04-09 15:39:38 -07:00
|
|
|
- __wine_send_input( 0, &input, NULL );
|
2019-12-23 13:17:06 -08:00
|
|
|
+ if ((dy || dy) && !(input.u.mi.dx || input.u.mi.dy))
|
2019-12-23 01:03:44 -08:00
|
|
|
+ {
|
2019-12-23 13:17:06 -08:00
|
|
|
+ TRACE( "accumulating raw motion (event %f,%f accum %f,%f)\n", dx, dy, x_pos->value, y_pos->value );
|
2019-12-23 01:03:44 -08:00
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
2019-12-23 13:17:06 -08:00
|
|
|
+ TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
2021-04-09 15:39:38 -07:00
|
|
|
+ __wine_send_input( 0, &input, NULL );
|
2019-12-23 01:03:44 -08:00
|
|
|
+ }
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-04-09 15:39:38 -07:00
|
|
|
@@ -2034,7 +2060,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
|
|
|
|
input.u.mi.dy = raw_dy;
|
|
|
|
}
|
|
|
|
|
2019-12-23 13:17:06 -08:00
|
|
|
- TRACE( "raw pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
|
|
|
|
+ TRACE( "raw pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, raw_dx, raw_dy );
|
2021-04-09 15:39:38 -07:00
|
|
|
|
|
|
|
rawinput.header.dwType = RIM_TYPEMOUSE;
|
|
|
|
rawinput.header.dwSize = offsetof(RAWINPUT, data) + sizeof(RAWMOUSE);
|
2019-12-23 01:03:44 -08:00
|
|
|
--
|
2021-04-09 15:39:38 -07:00
|
|
|
2.30.2
|
2019-12-23 01:03:44 -08:00
|
|
|
|