Rémi Bernon : winex11.drv: Accumulate mouse movement to avoid rounding losses.
Alexandre Julliard
julliard at winehq.org
Mon Oct 25 16:30:07 CDT 2021
Module: wine
Branch: master
Commit: f7ac9f309f2964e131c8e60c5ff3a878b67b2e32
URL: https://source.winehq.org/git/wine.git/?a=commit;h=f7ac9f309f2964e131c8e60c5ff3a878b67b2e32
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Mon Oct 25 11:51:55 2021 +0200
winex11.drv: Accumulate mouse movement to avoid rounding losses.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38420
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winex11.drv/mouse.c | 41 ++++++++++++++++++++++++++++++++---------
1 file changed, 32 insertions(+), 9 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 1ef7027e838..8cc30f0736d 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -22,6 +22,8 @@
#include "config.h"
#include "wine/port.h"
+#include <math.h>
+
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <stdarg.h>
@@ -270,6 +272,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
(!class->label && class->number == 1 && class->mode == XIModeRelative))
thread_data->y_valuator = *class;
}
+
+ thread_data->x_valuator.value = 0;
+ thread_data->y_valuator.value = 0;
}
#endif
@@ -351,6 +356,8 @@ static void disable_xinput2(void)
pXIFreeDeviceInfo( data->xi2_devices );
data->x_valuator.number = -1;
data->y_valuator.number = -1;
+ data->x_valuator.value = 0;
+ data->y_valuator.value = 0;
data->xi2_devices = NULL;
data->xi2_core_pointer = 0;
data->xi2_current_slave = 0;
@@ -626,8 +633,8 @@ 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;
+ double x_value = 0, y_value = 0, x_scale, y_scale;
const double *values = event->valuators.values;
- double dx = 0, dy = 0, val;
RECT virtual_rect;
int i;
@@ -656,25 +663,41 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input )
virtual_rect = get_virtual_screen_rect();
+ if (x->max <= x->min) x_scale = 1;
+ else x_scale = (virtual_rect.right - virtual_rect.left) / (x->max - x->min);
+ if (y->max <= y->min) y_scale = 1;
+ else y_scale = (virtual_rect.bottom - virtual_rect.top) / (y->max - y->min);
+
for (i = 0; i <= max( x->number, y->number ); i++)
{
if (!XIMaskIsSet( event->valuators.mask, i )) continue;
- val = *values++;
if (i == x->number)
{
- input->u.mi.dx = dx = val;
- if (x->min < x->max)
- input->u.mi.dx = val * (virtual_rect.right - virtual_rect.left) / (x->max - x->min);
+ x_value = *values;
+ x->value += x_value * x_scale;
}
if (i == y->number)
{
- input->u.mi.dy = dy = val;
- if (y->min < y->max)
- input->u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top) / (y->max - y->min);
+ y_value = *values;
+ y->value += y_value * y_scale;
}
+ values++;
+ }
+
+ input->u.mi.dx = round( x->value );
+ input->u.mi.dy = round( y->value );
+
+ TRACE( "event %f,%f value %f,%f input %d,%d\n", x_value, y_value, x->value, y->value, input->u.mi.dx, input->u.mi.dy );
+
+ x->value -= input->u.mi.dx;
+ y->value -= input->u.mi.dy;
+
+ if (!input->u.mi.dx && !input->u.mi.dy)
+ {
+ TRACE( "accumulating motion\n" );
+ return FALSE;
}
- TRACE( "pos %d,%d (event %f,%f)\n", input->u.mi.dx, input->u.mi.dy, dx, dy );
return TRUE;
}
More information about the wine-cvs
mailing list