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