> > I do fear that with some devices your patch will collapse too many
> > events and make it harder to follow small radius curves. 
>
> Right, I did not consider this case.  If this is a problem, perhaps
> the code could be changed to only collapse a pair of DELTA_X and
> DELTA_Y events, but never more than that.  This way it might still
> incorrectly merge two independent motions along the axes into one
> diagonal motion, but I would expect that to be rare, and the deltas
> to be so small that it has very little impact on anything.

Here's a diff that does just that.  If ws receives more than one
delta along an axis, it will not sum these; each will go in a separate
event.  But if it gets an X delta followed by an Y delta (or vice versa),
these will be combined into a single event.

Index: xenocara/driver/xf86-input-ws/src/ws.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-input-ws/src/ws.c,v
retrieving revision 1.57
diff -u -p -r1.57 ws.c
--- xenocara/driver/xf86-input-ws/src/ws.c      8 Jul 2012 14:22:03 -0000       
1.57
+++ xenocara/driver/xf86-input-ws/src/ws.c      8 Jul 2013 17:12:27 -0000
@@ -474,7 +474,7 @@ wsReadInput(InputInfoPtr pInfo)
 {
        WSDevicePtr priv = (WSDevicePtr)pInfo->private;
        static struct wscons_event eventList[NUMEVENTS];
-       int n, c;
+       int n, c, dx, dy;
        struct wscons_event *event = eventList;
        unsigned char *pBuf;
 
@@ -488,10 +488,11 @@ wsReadInput(InputInfoPtr pInfo)
        if (n == 0)
                return;
 
+       dx = dy = 0;
        n /= sizeof(struct wscons_event);
        while (n--) {
                int buttons = priv->lastButtons;
-               int dx = 0, dy = 0, dz = 0, dw = 0, ax = 0, ay = 0;
+               int newdx = 0, newdy = 0, dz = 0, dw = 0, ax = 0, ay = 0;
                int zbutton = 0, wbutton = 0;
 
                switch (event->type) {
@@ -506,11 +507,17 @@ wsReadInput(InputInfoPtr pInfo)
                            buttons));
                        break;
                case WSCONS_EVENT_MOUSE_DELTA_X:
-                       dx = event->value;
+                       if (!dx)
+                               dx = event->value;
+                       else
+                               newdx = event->value;
                        DBG(4, ErrorF("Relative X %d\n", event->value));
                        break;
                case WSCONS_EVENT_MOUSE_DELTA_Y:
-                       dy = -event->value;
+                       if (!dy)
+                               dy = -event->value;
+                       else
+                               newdy = -event->value;
                        DBG(4, ErrorF("Relative Y %d\n", event->value));
                        break;
                case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
@@ -548,14 +555,20 @@ wsReadInput(InputInfoPtr pInfo)
                }
                ++event;
 
-               if (dx || dy) {
-                       if (wsWheelEmuFilterMotion(pInfo, dx, dy))
+               if ((newdx || newdy) || ((dx || dy) &&
+                   event->type != WSCONS_EVENT_MOUSE_DELTA_X &&
+                   event->type != WSCONS_EVENT_MOUSE_DELTA_Y)) {
+                       int tmpx = dx, tmpy = dy;
+                       dx = newdx;
+                       dy = newdy;
+
+                       if (wsWheelEmuFilterMotion(pInfo, tmpx, tmpy))
                                continue;
 
                        /* relative motion event */
                        DBG(3, ErrorF("postMotionEvent dX %d dY %d\n",
-                           dx, dy));
-                       xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
+                           tmpx, tmpy));
+                       xf86PostMotionEvent(pInfo->dev, 0, 0, 2, tmpx, tmpy);
                }
                if (dz && priv->Z.negative != WS_NOMAP
                    && priv->Z.positive != WS_NOMAP) {
@@ -583,9 +596,9 @@ wsReadInput(InputInfoPtr pInfo)
                        ay = tmp;
                }
                if (ax) {
-                       dx = ax - priv->old_ax;
+                       int xdelta = ax - priv->old_ax;
                        priv->old_ax = ax;
-                       if (wsWheelEmuFilterMotion(pInfo, dx, 0))
+                       if (wsWheelEmuFilterMotion(pInfo, xdelta, 0))
                                continue;
 
                        /* absolute position event */
@@ -593,15 +606,24 @@ wsReadInput(InputInfoPtr pInfo)
                        xf86PostMotionEvent(pInfo->dev, 1, 0, 1, ax);
                }
                if (ay) {
-                       dy = ay - priv->old_ay;
+                       int ydelta = ay - priv->old_ay;
                        priv->old_ay = ay;
-                       if (wsWheelEmuFilterMotion(pInfo, 0, dy))
+                       if (wsWheelEmuFilterMotion(pInfo, 0, ydelta))
                                continue;
 
                        /* absolute position event */
                        DBG(3, ErrorF("postMotionEvent y %d\n", ay));
                        xf86PostMotionEvent(pInfo->dev, 1, 1, 1, ay);
                }
+       }
+       if (dx || dy) {
+               if (wsWheelEmuFilterMotion(pInfo, dx, dy))
+                       return;
+
+               /* relative motion event */
+               DBG(3, ErrorF("postMotionEvent dX %d dY %d\n",
+                   dx, dy));
+               xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
        }
        return;
 }

Reply via email to