xserver: Branch 'mpx' - 10 commits

Peter Hutterer whot at kemper.freedesktop.org
Fri May 23 02:59:54 PDT 2008


 Xext/xtest.c                   |    8 -
 Xi/exevents.c                  |  110 ++++++-------------
 Xi/warpdevp.c                  |    4 
 dix/devices.c                  |   10 +
 dix/getevents.c                |  226 ++++++++++++++++++++++-------------------
 hw/xfree86/common/xf86Xinput.c |   10 -
 include/input.h                |    2 
 include/inputstr.h             |   11 +
 8 files changed, 190 insertions(+), 191 deletions(-)

New commits:
commit 3ae0f4fc832462444d03024c5fbb867f19d5e960
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri May 23 15:02:43 2008 +0930

    dix: update valuators > 2 as well.
    
    master->last.valuator[x] for x > 2 is undefined. For all other devices, it's
    the respective device's last valuators.
    
    If the lastSlave did not have a valuator that is to be updated now, it is
    reset to 0.

diff --git a/dix/getevents.c b/dix/getevents.c
index 23ec6c4..7c7c63f 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -191,18 +191,39 @@ static void
 updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
 {
     ScreenPtr scr = miPointerGetScreen(pDev);
+    int i;
+    DeviceIntPtr lastSlave;
 
     /* master->last.valuators[0]/[1] is in screen coords and the actual
      * position of the pointer */
     pDev->last.valuators[0] = master->last.valuators[0];
     pDev->last.valuators[1] = master->last.valuators[1];
 
+    if (!pDev->valuator)
+        return;
+
     /* scale back to device coordinates */
     if(pDev->valuator->numAxes > 0)
         pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL, pDev->valuator->axes + 0, scr->width);
     if(pDev->valuator->numAxes > 1)
         pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL, pDev->valuator->axes + 1, scr->height);
-    /*TODO calculate the other axis as well based on info from the old slave-device */
+
+    /* calculate the other axis as well based on info from the old
+     * slave-device. If the old slave had less axes than this one,
+     * last.valuators is reset to 0.
+     */
+    if ((lastSlave = master->u.lastSlave) && lastSlave->valuator) {
+        for (i = 2; i < pDev->valuator->numAxes; i++) {
+            if (i >= lastSlave->valuator->numAxes)
+                pDev->last.valuators[i] = 0;
+            else
+                pDev->last.valuators[i] =
+                    rescaleValuatorAxis(pDev->last.valuators[i],
+                            lastSlave->valuator->axes + i,
+                            pDev->valuator->axes + i, 0);
+        }
+    }
+
 }
 
 /**
@@ -540,13 +561,9 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     if (master && master->u.lastSlave != pDev)
     {
         CreateClassesChangedEvent(events, master, pDev);
-
-        if (master->valuator && pDev->valuator)
-        {
-            pDev->last.valuators[0] = master->last.valuators[0];
-            pDev->last.valuators[1] = master->last.valuators[1];
-        }
+        updateSlaveDeviceCoords(master, pDev);
         master->u.lastSlave = pDev;
+        master->last.numValuators = pDev->last.numValuators;
         numEvents++;
         events++;
     }
@@ -713,6 +730,8 @@ FreeEventList(EventListPtr list, int num_events)
  *
  * last.valuators[x] of the device is always in absolute device coords.
  * last.valuators[x] of the master device is in absolute screen coords.
+ *
+ * master->last.valuators[x] for x > 2 is undefined.
  */
 _X_EXPORT int
 GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
@@ -726,6 +745,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         cx, cy; /* only screen coordinates */
     ScreenPtr scr = miPointerGetScreen(pDev);
     int *v0 = NULL, *v1 = NULL;
+    int i;
 
     /* Sanity checks. */
     if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
@@ -760,6 +780,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         CreateClassesChangedEvent(events, master, pDev);
         updateSlaveDeviceCoords(master, pDev);
         master->u.lastSlave = pDev;
+        master->last.numValuators = pDev->last.numValuators;
         num_events++;
         events++;
     }
@@ -777,12 +798,17 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     if (flags & POINTER_ABSOLUTE) {
         if(v0) x = *v0;
         if(v1) y = *v1;
-        /*TODO: Update the rest of the valuators */
 
         /* Clip both x and y to the defined limits (usually co-ord space limit). */
         clipAxis(pDev, 0, &x);
         clipAxis(pDev, 1, &y);
-        /*TODO: Clip the rest of the valuators */
+
+        i = (first_valuator > 2) ? 0 : 2;
+        for (; i < num_valuators; i++)
+        {
+            pDev->last.valuators[i + first_valuator] = valuators[i];
+            clipAxis(pDev, i, &pDev->last.valuators[i + first_valuator]);
+        }
     }
     else {
         if (flags & POINTER_ACCELERATE)
@@ -791,7 +817,6 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
         if(v0) x += *v0;
         if(v1) y += *v1;
-        /*TODO: Update the rest of the valuators */
 
         /* if attached, clip both x and y to the defined limits (usually
          * co-ord space limit). If it is attached, we need x/y to go over the
@@ -800,7 +825,15 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
             clipAxis(pDev, 0, &x);
             clipAxis(pDev, 1, &y);
         }
-        /*TODO: Clip the rest of the valuators (Yes, here. Only x&y get special treatment) */
+
+        /* calc other axes, clip, drop back into valuators */
+        i = (first_valuator > 2) ? 0 : 2;
+        for (; i < num_valuators; i++)
+        {
+            pDev->last.valuators[i + first_valuator] += valuators[i];
+            clipAxis(pDev, i, &pDev->last.valuators[i + first_valuator]);
+            valuators[i] = pDev->last.valuators[i + first_valuator];
+        }
     }
 
     /* scale x&y to screen */
@@ -836,7 +869,6 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     /* Update the valuators with the true value sent to the client*/
     if(v0) *v0 = x;
     if(v1) *v1 = y;
-    /* TODO: other axes */
 
     /* dropy x/y (device coordinates) back into valuators for next event */
     pDev->last.valuators[0] = x;
@@ -914,6 +946,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         CreateClassesChangedEvent(events, master, pDev);
         updateSlaveDeviceCoords(master, pDev);
         master->u.lastSlave = pDev;
+        master->last.numValuators = pDev->last.numValuators;
         num_events++;
         events++;
     }
commit 0d1b41ace38bc918e2cc2a0a6ad107c76346fd00
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri May 23 13:32:33 2008 +0930

    Xi: update device valuators based on the event.
    
    Event is always absolute, update the device's valuators (always absolute too),
    and then change the deviceValuator event to reflect the device's reporting
    mode.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 42b77c1..f477a73 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -831,90 +831,50 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
 		FatalError("Bad valuators reported for device %s\n",
 			   device->name);
 	    if (v && v->axisVal) {
-                /* The device always stores values in absolute. Only the
+                /* v->axisVal is always in absolute coordinates. Only the
                  * delivery mode changes.
-                 * If device is mode Absolute, and event is Relative
-                 *     dev += event
-                 *     event = dev
-                 * If device is mode Absolute, and event is Absolute
+                 * If device is mode Absolute
                  *     dev = event
-                 * If device is mode Relative, and event is Absolute
+                 * If device is mode Relative
                  *      swap = (event - device)
                  *      dev = event
                  *      event = delta
-                 * If device is mode Relative, and event is Relative
-                 *      dev += event
                  *
                  * XXX: axis clipping for relative events?
                  */
 		axisvals = v->axisVal;
-                if (xV->sequenceNumber & Absolute) {
-                    int delta;
-                    if (v->mode == Relative) /* device reports relative */
-                    {
-                        change = TRUE;
-                        xV->sequenceNumber &= ~Absolute;
-                    }
-
-                    switch (xV->num_valuators) {
-                        case 6:
-                            if (change) delta = xV->valuator5 - *(axisvals + first + 5);
-                            *(axisvals + first + 5) = xV->valuator5;
-                            if (change) xV->valuator5 = delta;
-                        case 5:
-                            if (change) delta = xV->valuator4 - *(axisvals + first + 4);
-                            *(axisvals + first + 4) = xV->valuator4;
-                            if (change) xV->valuator4 = delta;
-                        case 4:
-                            if (change) delta = xV->valuator3 - *(axisvals + first + 3);
-                            *(axisvals + first + 3) = xV->valuator3;
-                            if (change) xV->valuator3 = delta;
-                        case 3:
-                            if (change) delta = xV->valuator2 - *(axisvals + first + 2);
-                            *(axisvals + first + 2) = xV->valuator2;
-                            if (change) xV->valuator2 = delta;
-                        case 2:
-                            if (change) delta = xV->valuator1 - *(axisvals + first + 1);
-                            *(axisvals + first + 1) = xV->valuator1;
-                            if (change) xV->valuator1 = delta;
-                        case 1:
-                            if (change) delta = xV->valuator0 - *(axisvals + first);
-                            *(axisvals + first) = xV->valuator0;
-                            if (change) xV->valuator0 = delta;
-                        case 0:
-                        default:
-                            break;
-                    }
-		} else { /* event is relative */
-                    if (v->mode == Absolute) /* device reports absolute */
-                    {
-                        change = TRUE;
-                        xV->sequenceNumber |= Absolute;
-                    }
-
-                    switch (xV->num_valuators) {
-                        case 6:
-                            *(axisvals + first + 5) += xV->valuator5;
-                            if (change) xV->valuator5 = *(axisvals + first + 5);
-                        case 5:
-                            *(axisvals + first + 4) += xV->valuator4;
-                            if (change) xV->valuator4 = *(axisvals + first + 4);
-                        case 4:
-                            *(axisvals + first + 3) += xV->valuator3;
-                            if (change) xV->valuator3 = *(axisvals + first + 3);
-                        case 3:
-                            *(axisvals + first + 2) += xV->valuator2;
-                            if (change) xV->valuator2 = *(axisvals + first + 2);
-                        case 2:
-                            *(axisvals + first + 1) += xV->valuator1;
-                            if (change) xV->valuator1 = *(axisvals + first + 1);
-                        case 1:
-                            *(axisvals + first) += xV->valuator0;
-                            if (change) xV->valuator0 = *(axisvals + first);
-                        case 0:
-                        default:
-                            break;
-                    }
+                int delta;
+                if (v->mode == Relative) /* device reports relative */
+                    change = TRUE;
+
+                switch (xV->num_valuators) {
+                    case 6:
+                        if (change) delta = xV->valuator5 - *(axisvals + first + 5);
+                        *(axisvals + first + 5) = xV->valuator5;
+                        if (change) xV->valuator5 = delta;
+                    case 5:
+                        if (change) delta = xV->valuator4 - *(axisvals + first + 4);
+                        *(axisvals + first + 4) = xV->valuator4;
+                        if (change) xV->valuator4 = delta;
+                    case 4:
+                        if (change) delta = xV->valuator3 - *(axisvals + first + 3);
+                        *(axisvals + first + 3) = xV->valuator3;
+                        if (change) xV->valuator3 = delta;
+                    case 3:
+                        if (change) delta = xV->valuator2 - *(axisvals + first + 2);
+                        *(axisvals + first + 2) = xV->valuator2;
+                        if (change) xV->valuator2 = delta;
+                    case 2:
+                        if (change) delta = xV->valuator1 - *(axisvals + first + 1);
+                        *(axisvals + first + 1) = xV->valuator1;
+                        if (change) xV->valuator1 = delta;
+                    case 1:
+                        if (change) delta = xV->valuator0 - *(axisvals + first);
+                        *(axisvals + first) = xV->valuator0;
+                        if (change) xV->valuator0 = delta;
+                    case 0:
+                    default:
+                        break;
                 }
 	    }
 	}
commit 7eec1c23a34591064ea64499acb24f22ada08dfa
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri May 23 13:23:02 2008 +0930

    dix: don't allow relative data in deviceValuators.
    
    In GPE, we don't care about the device mode. Let's put the absolute values
    into the deviceValuator event and worry about relative valuators on the other
    side of the EQ.

diff --git a/dix/getevents.c b/dix/getevents.c
index 48aa0e8..23ec6c4 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -833,23 +833,10 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
 
-
-    /* update the valuators based on the mode of the InputDevice */
-    if(pDev->valuator->mode == Absolute) {
-        /* Update the valuators with the true value sent to the client*/
-        if(v0) *v0 = x;
-        if(v1) *v1 = y;
-        /*TODO Ensure that valuator 2 and onward also are absolute */
-    } else {/* Relative mode */
-        /* If driver reported in absolute, calculate the relative valuator
-         * values as a delta from the old absolute values of the valuator
-         * values. If relative report, keep it as-is.*/
-        if (flags & POINTER_ABSOLUTE) {
-            int i;
-            for (i = 0; i < num_valuators && i < pDev->last.numValuators; i++)
-                valuators[i] = valuators[i] - pDev->last.valuators[i + first_valuator];
-        }
-    }
+    /* Update the valuators with the true value sent to the client*/
+    if(v0) *v0 = x;
+    if(v1) *v1 = y;
+    /* TODO: other axes */
 
     /* dropy x/y (device coordinates) back into valuators for next event */
     pDev->last.valuators[0] = x;
commit 75551a2ef949c2cfb53fdc4b97f3964a5e2f45f5
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri May 23 12:55:50 2008 +0930

    Revert "dix: Correct values in the device axisVal are calculated in GPE"
    
    We can't rely on GPE to update device->valuators->axisVal. If a SIGIO occurs
    during event processing this may have incoherent results.
    
    This reverts commit f6645ddbf754c80e9a8b1672519534a887622270.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index da6cf8d..42b77c1 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -818,8 +818,107 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
         bit = 1 << (key & 7);
     }
 
-    /* Device axis are calculated in GetPointerEvents and need
-     * no more processing */
+    /* Update device axis */
+    for (i = 1; i < count; i++) {
+	if ((++xV)->type == DeviceValuator) {
+	    int *axisvals;
+            int first = xV->first_valuator;
+            BOOL change = FALSE;
+
+	    if (xV->num_valuators &&
+                (!v || (xV->num_valuators &&
+                      (first + xV->num_valuators > v->numAxes))))
+		FatalError("Bad valuators reported for device %s\n",
+			   device->name);
+	    if (v && v->axisVal) {
+                /* The device always stores values in absolute. Only the
+                 * delivery mode changes.
+                 * If device is mode Absolute, and event is Relative
+                 *     dev += event
+                 *     event = dev
+                 * If device is mode Absolute, and event is Absolute
+                 *     dev = event
+                 * If device is mode Relative, and event is Absolute
+                 *      swap = (event - device)
+                 *      dev = event
+                 *      event = delta
+                 * If device is mode Relative, and event is Relative
+                 *      dev += event
+                 *
+                 * XXX: axis clipping for relative events?
+                 */
+		axisvals = v->axisVal;
+                if (xV->sequenceNumber & Absolute) {
+                    int delta;
+                    if (v->mode == Relative) /* device reports relative */
+                    {
+                        change = TRUE;
+                        xV->sequenceNumber &= ~Absolute;
+                    }
+
+                    switch (xV->num_valuators) {
+                        case 6:
+                            if (change) delta = xV->valuator5 - *(axisvals + first + 5);
+                            *(axisvals + first + 5) = xV->valuator5;
+                            if (change) xV->valuator5 = delta;
+                        case 5:
+                            if (change) delta = xV->valuator4 - *(axisvals + first + 4);
+                            *(axisvals + first + 4) = xV->valuator4;
+                            if (change) xV->valuator4 = delta;
+                        case 4:
+                            if (change) delta = xV->valuator3 - *(axisvals + first + 3);
+                            *(axisvals + first + 3) = xV->valuator3;
+                            if (change) xV->valuator3 = delta;
+                        case 3:
+                            if (change) delta = xV->valuator2 - *(axisvals + first + 2);
+                            *(axisvals + first + 2) = xV->valuator2;
+                            if (change) xV->valuator2 = delta;
+                        case 2:
+                            if (change) delta = xV->valuator1 - *(axisvals + first + 1);
+                            *(axisvals + first + 1) = xV->valuator1;
+                            if (change) xV->valuator1 = delta;
+                        case 1:
+                            if (change) delta = xV->valuator0 - *(axisvals + first);
+                            *(axisvals + first) = xV->valuator0;
+                            if (change) xV->valuator0 = delta;
+                        case 0:
+                        default:
+                            break;
+                    }
+		} else { /* event is relative */
+                    if (v->mode == Absolute) /* device reports absolute */
+                    {
+                        change = TRUE;
+                        xV->sequenceNumber |= Absolute;
+                    }
+
+                    switch (xV->num_valuators) {
+                        case 6:
+                            *(axisvals + first + 5) += xV->valuator5;
+                            if (change) xV->valuator5 = *(axisvals + first + 5);
+                        case 5:
+                            *(axisvals + first + 4) += xV->valuator4;
+                            if (change) xV->valuator4 = *(axisvals + first + 4);
+                        case 4:
+                            *(axisvals + first + 3) += xV->valuator3;
+                            if (change) xV->valuator3 = *(axisvals + first + 3);
+                        case 3:
+                            *(axisvals + first + 2) += xV->valuator2;
+                            if (change) xV->valuator2 = *(axisvals + first + 2);
+                        case 2:
+                            *(axisvals + first + 1) += xV->valuator1;
+                            if (change) xV->valuator1 = *(axisvals + first + 1);
+                        case 1:
+                            *(axisvals + first) += xV->valuator0;
+                            if (change) xV->valuator0 = *(axisvals + first);
+                        case 0:
+                        default:
+                            break;
+                    }
+                }
+	    }
+	}
+    }
 
     if (xE->u.u.type == DeviceKeyPress) {
         if (!k)
commit fe59b1a62b2c7f467d20132db4913317bbf308eb
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri May 23 12:51:52 2008 +0930

    dix: more device scaling insanity.
    
    Assuming master->last.valuators is in screen coords, SD's are always in device
    coordinates.
    
    1. If an event comes in, scale masters->last to the device, drop into device's
    last->valuators.
    2. Apply motion from the actual event
    3. Scale back to screen coords, check if we may need to cross screens
    4. Drop screen coords into master->last
    5. Rescale to device coords, drop into deviceValuator event and SD->last
    6. Drop screen coords into ev->root_x/y
    
    Whoopee...

diff --git a/dix/getevents.c b/dix/getevents.c
index 300dae5..48aa0e8 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -183,24 +183,25 @@ rescaleValuatorAxis(int coord, AxisInfoPtr from, AxisInfoPtr to,
  * Update all coordinates when changing to a different SD
  * to ensure that relative reporting will work as expected
  * without loss of precision.
+ *
+ * pDev->last.valuators will be in absolute device coordinates after this
+ * function.
  */
 static void
 updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
 {
     ScreenPtr scr = miPointerGetScreen(pDev);
 
-    /* last.valuators[0]/[1] is in screen coords and the actual position
-     * of the pointer */
+    /* master->last.valuators[0]/[1] is in screen coords and the actual
+     * position of the pointer */
     pDev->last.valuators[0] = master->last.valuators[0];
     pDev->last.valuators[1] = master->last.valuators[1];
-    /* the valuator axis is in device coords and holds the
-     * position of the pointer, but in device coords. */
+
+    /* scale back to device coordinates */
     if(pDev->valuator->numAxes > 0)
-        pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL,
-                                            pDev->valuator->axes + 0, scr->width);
+        pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL, pDev->valuator->axes + 0, scr->width);
     if(pDev->valuator->numAxes > 1)
-        pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL,
-                                            pDev->valuator->axes + 1, scr->height);
+        pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL, pDev->valuator->axes + 1, scr->height);
     /*TODO calculate the other axis as well based on info from the old slave-device */
 }
 
@@ -709,8 +710,9 @@ FreeEventList(EventListPtr list, int num_events)
  *
  * In the generated events rootX/Y will be in absolute screen coords and
  * the valuator information in the absolute or relative device coords.
- * last.valuators[0]/[1] of the device is always in absolute screen coords
- * while the device valuator struct contain the absolute device coords.
+ *
+ * last.valuators[x] of the device is always in absolute device coords.
+ * last.valuators[x] of the master device is in absolute screen coords.
  */
 _X_EXPORT int
 GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
@@ -720,7 +722,8 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     CARD32 ms;
     deviceKeyButtonPointer *kbp = NULL;
     DeviceIntPtr master;
-    int x, y, cx, cy;
+    int x, y, /* switches between device and screen coords */
+        cx, cy; /* only screen coordinates */
     ScreenPtr scr = miPointerGetScreen(pDev);
     int *v0 = NULL, *v1 = NULL;
 
@@ -769,8 +772,8 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     /* Set x and y based on whether this is absolute or relative, and
      * accelerate if we need to. */
-    x = pDev->valuator->axisVal[0];
-    y = pDev->valuator->axisVal[1];
+    x = pDev->last.valuators[0];
+    y = pDev->last.valuators[1];
     if (flags & POINTER_ABSOLUTE) {
         if(v0) x = *v0;
         if(v1) y = *v1;
@@ -811,20 +814,25 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
      * so we don't set this for both the device and core.*/
     miPointerSetPosition(pDev, &pDev->last.valuators[0], &pDev->last.valuators[1], ms);
 
-    scr = miPointerGetScreen(pDev);
+    if (master) {
+        master->last.valuators[0] = pDev->last.valuators[0];
+        master->last.valuators[1] = pDev->last.valuators[1];
+    }
+
     if(cx != pDev->last.valuators[0])
-        x = rescaleValuatorAxis(pDev->last.valuators[0], NULL,
-                                pDev->valuator->axes + 0, scr->width);
+        cx = pDev->last.valuators[0];
     if(cy != pDev->last.valuators[1])
-        y = rescaleValuatorAxis(pDev->last.valuators[1], NULL,
-                                pDev->valuator->axes + 1, scr->height);
+        cy = pDev->last.valuators[1];
+
+    /* scale x/y back to device coordinates */
+    scr = miPointerGetScreen(pDev);
+    x = rescaleValuatorAxis(pDev->last.valuators[0], NULL,
+                        pDev->valuator->axes + 0, scr->width);
+    y = rescaleValuatorAxis(pDev->last.valuators[1], NULL,
+                        pDev->valuator->axes + 1, scr->height);
 
     updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
 
-    if (master) {
-        master->last.valuators[0] = pDev->last.valuators[0];
-        master->last.valuators[1] = pDev->last.valuators[1];
-    }
 
     /* update the valuators based on the mode of the InputDevice */
     if(pDev->valuator->mode == Absolute) {
@@ -838,14 +846,14 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
          * values. If relative report, keep it as-is.*/
         if (flags & POINTER_ABSOLUTE) {
             int i;
-            for (i = 0; i < num_valuators; i++)
-                valuators[i] = valuators[i] - pDev->valuator->axisVal[i + first_valuator];
+            for (i = 0; i < num_valuators && i < pDev->last.numValuators; i++)
+                valuators[i] = valuators[i] - pDev->last.valuators[i + first_valuator];
         }
     }
-    /* Save the last calculated device axis value in the device
-     * valuator for next event */
-    pDev->valuator->axisVal[0] = x;
-    pDev->valuator->axisVal[1] = y;
+
+    /* dropy x/y (device coordinates) back into valuators for next event */
+    pDev->last.valuators[0] = x;
+    pDev->last.valuators[1] = y;
 
     kbp = (deviceKeyButtonPointer *) events->event;
     kbp->time = ms;
@@ -862,8 +870,8 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         kbp->detail = pDev->button->map[buttons];
     }
 
-    kbp->root_x = pDev->last.valuators[0];
-    kbp->root_y = pDev->last.valuators[1];
+    kbp->root_x = cx; /* root_x/y always in screen coords */
+    kbp->root_y = cy;
 
     events++;
     if (num_valuators) {
diff --git a/include/inputstr.h b/include/inputstr.h
index d1cc448..d26eb13 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -422,6 +422,8 @@ typedef struct _DeviceIntRec {
     } u;
 
     /* last valuator values recorded, not posted to client;
+     * for slave devices, valuators is in device coordinates
+     * for master devices, valuators is in screen coordinates
      * see dix/getevents.c */
     struct {
         int             valuators[MAX_VALUATORS];
commit 6c9e9f8a40e20fb1761440acd2755f5fd31f4d44
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri May 23 11:51:53 2008 +0930

    input: instead of lastx/y, use a last.valuators[] array on the device.
    
    During GetPointerEvents (and others), we need to access the last coordinates
    posted for this device from the driver (not as posted to the client!). Lastx/y
    is ok if we only have two axes, but with more complex devices we also need to
    transition between all other axes.
    
    ABI break, recompile your input drivers.

diff --git a/Xext/xtest.c b/Xext/xtest.c
index a42faa7..58e20ef 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -470,16 +470,16 @@ ProcXTestFakeInput(client)
                      ev->u.keyButtonPointer.rootX,
                      ev->u.keyButtonPointer.rootY, FALSE);
             }
-            dev->lastx = ev->u.keyButtonPointer.rootX;
-            dev->lasty = ev->u.keyButtonPointer.rootY;
+            dev->last.valuators[0] = ev->u.keyButtonPointer.rootX;
+            dev->last.valuators[1] = ev->u.keyButtonPointer.rootY;
             break;
         case ButtonPress:
         case ButtonRelease:
             if (!extension)
                 dev = PickPointer(client);
 
-            ev->u.keyButtonPointer.rootX = dev->lastx;
-            ev->u.keyButtonPointer.rootY = dev->lasty;
+            ev->u.keyButtonPointer.rootX = dev->last.valuators[0];
+            ev->u.keyButtonPointer.rootY = dev->last.valuators[1];
             if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
             {
                 client->errorValue = ev->u.u.detail;
diff --git a/Xi/warpdevp.c b/Xi/warpdevp.c
index 3720441..502cab4 100644
--- a/Xi/warpdevp.c
+++ b/Xi/warpdevp.c
@@ -166,8 +166,8 @@ ProcXWarpDevicePointer(ClientPtr client)
     }
 
     /* if we don't update the device, we get a jump next time it moves */
-    pDev->lastx = x;
-    pDev->lasty = x;
+    pDev->last.valuators[0] = x;
+    pDev->last.valuators[1] = x;
     miPointerUpdateSprite(pDev);
 
     /* FIXME: XWarpPointer is supposed to generate an event. It doesn't do it
diff --git a/dix/devices.c b/dix/devices.c
index 1b71a42..2521186 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -168,6 +168,10 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     dev->spriteInfo->sprite = NULL;
     dev->spriteInfo->spriteOwner = FALSE;
 
+    /* last valuators */
+    memset(dev->last.valuators, 0, sizeof(dev->last.valuators));
+    dev->last.numValuators = 0;
+
     /*  security creation/labeling check
      */
     if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
@@ -491,9 +495,9 @@ CorePointerProc(DeviceIntPtr pDev, int what)
                                 GetMotionHistory, (PtrCtrlProcPtr)NoopDDA,
                                 GetMotionHistorySize(), 2);
         pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
-        pDev->lastx = pDev->valuator->axisVal[0];
+        pDev->last.valuators[0] = pDev->valuator->axisVal[0];
         pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
-        pDev->lasty = pDev->valuator->axisVal[1];
+        pDev->last.valuators[1] = pDev->valuator->axisVal[1];
         break;
 
     case DEVICE_CLOSE:
@@ -1192,6 +1196,8 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
                                0, 0, 0);
 	valc->axisVal[i]=0;
     }
+
+    dev->last.numValuators = numAxes;
     return TRUE;
 }
 
diff --git a/dix/getevents.c b/dix/getevents.c
index fea5285..300dae5 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -189,17 +189,17 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
 {
     ScreenPtr scr = miPointerGetScreen(pDev);
 
-    /* lastx/y is in screen coords and the actual position
+    /* last.valuators[0]/[1] is in screen coords and the actual position
      * of the pointer */
-    pDev->lastx = master->lastx;
-    pDev->lasty = master->lasty;
+    pDev->last.valuators[0] = master->last.valuators[0];
+    pDev->last.valuators[1] = master->last.valuators[1];
     /* the valuator axis is in device coords and holds the
      * position of the pointer, but in device coords. */
     if(pDev->valuator->numAxes > 0)
-        pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->lastx, NULL,
+        pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->last.valuators[0], NULL,
                                             pDev->valuator->axes + 0, scr->width);
     if(pDev->valuator->numAxes > 1)
-        pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->lasty, NULL,
+        pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->last.valuators[1], NULL,
                                             pDev->valuator->axes + 1, scr->height);
     /*TODO calculate the other axis as well based on info from the old slave-device */
 }
@@ -542,8 +542,8 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 
         if (master->valuator && pDev->valuator)
         {
-            pDev->lastx = master->lastx;
-            pDev->lasty = master->lasty;
+            pDev->last.valuators[0] = master->last.valuators[0];
+            pDev->last.valuators[1] = master->last.valuators[1];
         }
         master->u.lastSlave = pDev;
         numEvents++;
@@ -709,8 +709,8 @@ FreeEventList(EventListPtr list, int num_events)
  *
  * In the generated events rootX/Y will be in absolute screen coords and
  * the valuator information in the absolute or relative device coords.
- * lastx/y of the device is always in absolute screen coords while the
- * device valuator struct contain the absolute device coords.
+ * last.valuators[0]/[1] of the device is always in absolute screen coords
+ * while the device valuator struct contain the absolute device coords.
  */
 _X_EXPORT int
 GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
@@ -801,29 +801,29 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     }
 
     /* scale x&y to screen */
-    pDev->lastx = cx = rescaleValuatorAxis(x, pDev->valuator->axes + 0,
+    pDev->last.valuators[0] = cx = rescaleValuatorAxis(x, pDev->valuator->axes + 0,
                                            NULL, scr->width);
-    pDev->lasty = cy = rescaleValuatorAxis(y, pDev->valuator->axes + 1,
+    pDev->last.valuators[1] = cy = rescaleValuatorAxis(y, pDev->valuator->axes + 1,
                                            NULL, scr->height);
 
     /* This takes care of crossing screens for us, as well as clipping
      * to the current screen.  Right now, we only have one history buffer,
      * so we don't set this for both the device and core.*/
-    miPointerSetPosition(pDev, &pDev->lastx, &pDev->lasty, ms);
+    miPointerSetPosition(pDev, &pDev->last.valuators[0], &pDev->last.valuators[1], ms);
 
     scr = miPointerGetScreen(pDev);
-    if(cx != pDev->lastx)
-        x = rescaleValuatorAxis(pDev->lastx, NULL,
+    if(cx != pDev->last.valuators[0])
+        x = rescaleValuatorAxis(pDev->last.valuators[0], NULL,
                                 pDev->valuator->axes + 0, scr->width);
-    if(cy != pDev->lasty)
-        y = rescaleValuatorAxis(pDev->lasty, NULL,
+    if(cy != pDev->last.valuators[1])
+        y = rescaleValuatorAxis(pDev->last.valuators[1], NULL,
                                 pDev->valuator->axes + 1, scr->height);
 
     updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
 
     if (master) {
-        master->lastx = pDev->lastx;
-        master->lasty = pDev->lasty;
+        master->last.valuators[0] = pDev->last.valuators[0];
+        master->last.valuators[1] = pDev->last.valuators[1];
     }
 
     /* update the valuators based on the mode of the InputDevice */
@@ -862,13 +862,14 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         kbp->detail = pDev->button->map[buttons];
     }
 
-    kbp->root_x = pDev->lastx;
-    kbp->root_y = pDev->lasty;
+    kbp->root_x = pDev->last.valuators[0];
+    kbp->root_y = pDev->last.valuators[1];
 
     events++;
     if (num_valuators) {
         kbp->deviceid |= MORE_EVENTS;
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
+        if (flags & POINTER_ABSOLUTE)
+            clipValuators(pDev, first_valuator, num_valuators, valuators);
         events = getValuatorEvents(events, pDev, first_valuator,
                                    num_valuators, valuators);
     }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 9961624..2ae4630 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -505,8 +505,6 @@ DeleteInputDeviceRequest(DeviceIntPtr pDev)
  * convenient functions to post events
  */
 
-#define MAX_VALUATORS 36 /* XXX from comment in dix/getevents.c */
-
 _X_EXPORT void
 xf86PostMotionEvent(DeviceIntPtr	device,
                     int			is_absolute,
@@ -566,14 +564,14 @@ xf86PostMotionEventP(DeviceIntPtr	device,
             {
                 dx = valuators[0];
                 if (is_absolute)
-                    dx -= device->lastx;
+                    dx -= device->last.valuators[0];
             }
 
             if (first_valuator == 1 || num_valuators >= 2)
             {
                 dy = valuators[1 - first_valuator];
                 if (is_absolute)
-                    dy -= device->lasty;
+                    dy -= device->last.valuators[1];
             }
 
             if (DGAStealMotionEvent(device, index, dx, dy))
@@ -833,11 +831,11 @@ xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
 {
     if (axnum == 0) {
 	dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
-        dev->lastx = dev->valuator->axisVal[0];
+        dev->last.valuators[0] = dev->valuator->axisVal[0];
     }
     else if (axnum == 1) {
 	dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
-        dev->lasty = dev->valuator->axisVal[1];
+        dev->last.valuators[1] = dev->valuator->axisVal[1];
     }
 }
 
diff --git a/include/input.h b/include/input.h
index 13902d7..9b92ea3 100644
--- a/include/input.h
+++ b/include/input.h
@@ -63,6 +63,8 @@ SOFTWARE.
 #define POINTER_ABSOLUTE (1 << 2)
 #define POINTER_ACCELERATE (1 << 3)
 
+#define MAX_VALUATORS 36 /* XXX from comment in dix/getevents.c */
+
 #define NO_AXIS_LIMITS -1
 
 #define MAP_LENGTH	256
diff --git a/include/inputstr.h b/include/inputstr.h
index d117e55..d1cc448 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -420,8 +420,13 @@ typedef struct _DeviceIntRec {
     DeviceIntPtr        master;       /* master device */
     DeviceIntPtr        lastSlave;    /* last slave device used */
     } u;
-    int                 lastx, lasty; /* last event recorded, not posted to
-                                       * client; see dix/devices.c */
+
+    /* last valuator values recorded, not posted to client;
+     * see dix/getevents.c */
+    struct {
+        int             valuators[MAX_VALUATORS];
+        int             numValuators;
+    } last;
 } DeviceIntRec;
 
 typedef struct {
commit fb146cbb0f28e4e480e5d16d61476ac46b5d00ce
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri May 23 12:00:13 2008 +0930

    dix: coreEvents doesn't have meaning here, use master instead.
    
    We mustn't clip x/y if we are attached, otherwise we can't change screens.

diff --git a/dix/getevents.c b/dix/getevents.c
index 0caa764..fea5285 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -790,9 +790,10 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         if(v1) y += *v1;
         /*TODO: Update the rest of the valuators */
 
-        /* if not core -> clip both x and y to the defined limits (usually
-         * co-ord space limit). */
-        if(!pDev->coreEvents) {
+        /* if attached, clip both x and y to the defined limits (usually
+         * co-ord space limit). If it is attached, we need x/y to go over the
+         * limits to be able to change screens. */
+        if(master) {
             clipAxis(pDev, 0, &x);
             clipAxis(pDev, 1, &y);
         }
commit fc1cc0adcb91fdfa4c547bf379a85f9558c959ff
Author: Magnus Vigerlöf <Magnus.Vigerlof at ipbo.se>
Date:   Fri May 23 00:33:18 2008 +0200

    dix: Cleanup of GetPointerEvents
    
    Changed all the checks for x&y valuator so the more complex
    calculation is only made once.
    Added TODOs for valuator/axis 2 and above for future correct
    handling of relative reporting of these.
    
    Signed-off-by: Peter Hutterer <peter at cs.unisa.edu.au>

diff --git a/dix/getevents.c b/dix/getevents.c
index 26add12..0caa764 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -159,20 +159,22 @@ CreateClassesChangedEvent(EventList* event,
  * Rescale the coord between the two axis ranges.
  */
 static int
-rescaleValuatorAxis(int coord, int fmin, int fmax,
-                    int tmin, int tmax, int smax)
+rescaleValuatorAxis(int coord, AxisInfoPtr from, AxisInfoPtr to,
+                    int defmax)
 {
-    if(fmin >= fmax) {
-        fmin = 0;
-        fmax = smax;
+    int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax;
+
+    if(from && from->min_value < from->max_value) {
+        fmin = from->min_value;
+        fmax = from->max_value;
     }
-    if(tmin >= tmax) {
-        tmin = 0;
-        tmax = smax;
+    if(to && to->min_value < to->max_value) {
+        tmin = to->min_value;
+        tmax = to->max_value;
     }
+
     if(fmin == tmin && fmax == tmax)
         return coord;
-
     return (int)(((float)(coord - fmin)) * (tmax - tmin + 1) /
                  (fmax - fmin + 1)) + tmin;
 }
@@ -194,13 +196,11 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
     /* the valuator axis is in device coords and holds the
      * position of the pointer, but in device coords. */
     if(pDev->valuator->numAxes > 0)
-        pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->lastx, 0, scr->width,
-                                            pDev->valuator->axes[0].min_value,
-                                            pDev->valuator->axes[0].max_value, scr->width);
+        pDev->valuator->axisVal[0] = rescaleValuatorAxis(pDev->lastx, NULL,
+                                            pDev->valuator->axes + 0, scr->width);
     if(pDev->valuator->numAxes > 1)
-        pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->lasty, 0, scr->height,
-                                            pDev->valuator->axes[1].min_value,
-                                            pDev->valuator->axes[1].max_value, scr->height);
+        pDev->valuator->axisVal[1] = rescaleValuatorAxis(pDev->lasty, NULL,
+                                            pDev->valuator->axes + 1, scr->height);
     /*TODO calculate the other axis as well based on info from the old slave-device */
 }
 
@@ -707,17 +707,22 @@ FreeEventList(EventListPtr list, int num_events)
  * The DDX is responsible for allocating the event structure in the first
  * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
  *
+ * In the generated events rootX/Y will be in absolute screen coords and
+ * the valuator information in the absolute or relative device coords.
+ * lastx/y of the device is always in absolute screen coords while the
+ * device valuator struct contain the absolute device coords.
  */
 _X_EXPORT int
 GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
                  int flags, int first_valuator, int num_valuators,
                  int *valuators) {
     int num_events = 1;
-    CARD32 ms = 0;
+    CARD32 ms;
     deviceKeyButtonPointer *kbp = NULL;
     DeviceIntPtr master;
     int x, y, cx, cy;
     ScreenPtr scr = miPointerGetScreen(pDev);
+    int *v0 = NULL, *v1 = NULL;
 
     /* Sanity checks. */
     if (type != MotionNotify && type != ButtonPress && type != ButtonRelease)
@@ -756,29 +761,34 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         events++;
     }
 
+    /* Fetch pointers into the valuator array for more easy to read code */
+    if (num_valuators >= 1 && first_valuator == 0)
+        v0 = valuators + 0;
+    if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
+        v1 = valuators + 1 - first_valuator;
+
     /* Set x and y based on whether this is absolute or relative, and
      * accelerate if we need to. */
     x = pDev->valuator->axisVal[0];
     y = pDev->valuator->axisVal[1];
     if (flags & POINTER_ABSOLUTE) {
-        if (num_valuators >= 1 && first_valuator == 0)
-            x = valuators[0];
-        if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-            y = valuators[1 - first_valuator];
+        if(v0) x = *v0;
+        if(v1) y = *v1;
+        /*TODO: Update the rest of the valuators */
 
         /* Clip both x and y to the defined limits (usually co-ord space limit). */
         clipAxis(pDev, 0, &x);
         clipAxis(pDev, 1, &y);
+        /*TODO: Clip the rest of the valuators */
     }
     else {
         if (flags & POINTER_ACCELERATE)
             acceleratePointer(pDev, first_valuator, num_valuators,
                               valuators);
 
-        if (first_valuator == 0 && num_valuators >= 1)
-            x += valuators[0];
-        if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-            y += valuators[1 - first_valuator];
+        if(v0) x += *v0;
+        if(v1) y += *v1;
+        /*TODO: Update the rest of the valuators */
 
         /* if not core -> clip both x and y to the defined limits (usually
          * co-ord space limit). */
@@ -786,15 +796,14 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
             clipAxis(pDev, 0, &x);
             clipAxis(pDev, 1, &y);
         }
+        /*TODO: Clip the rest of the valuators (Yes, here. Only x&y get special treatment) */
     }
 
     /* scale x&y to screen */
-    pDev->lastx = cx = rescaleValuatorAxis(x, pDev->valuator->axes[0].min_value,
-                                           pDev->valuator->axes[0].max_value,
-                                           0, scr->width, scr->width);
-    pDev->lasty = cy = rescaleValuatorAxis(y, pDev->valuator->axes[1].min_value,
-                                           pDev->valuator->axes[1].max_value,
-                                           0, scr->height, scr->height);
+    pDev->lastx = cx = rescaleValuatorAxis(x, pDev->valuator->axes + 0,
+                                           NULL, scr->width);
+    pDev->lasty = cy = rescaleValuatorAxis(y, pDev->valuator->axes + 1,
+                                           NULL, scr->height);
 
     /* This takes care of crossing screens for us, as well as clipping
      * to the current screen.  Right now, we only have one history buffer,
@@ -803,15 +812,11 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     scr = miPointerGetScreen(pDev);
     if(cx != pDev->lastx)
-        x = rescaleValuatorAxis(pDev->lastx, 0, scr->width,
-                                pDev->valuator->axes[0].min_value,
-                                pDev->valuator->axes[0].max_value,
-                                scr->width);
+        x = rescaleValuatorAxis(pDev->lastx, NULL,
+                                pDev->valuator->axes + 0, scr->width);
     if(cy != pDev->lasty)
-        y = rescaleValuatorAxis(pDev->lasty, 0, scr->height,
-                                pDev->valuator->axes[1].min_value,
-                                pDev->valuator->axes[1].max_value,
-                                scr->height);
+        y = rescaleValuatorAxis(pDev->lasty, NULL,
+                                pDev->valuator->axes + 1, scr->height);
 
     updateMotionHistory(pDev, ms, first_valuator, num_valuators, valuators);
 
@@ -823,19 +828,17 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     /* update the valuators based on the mode of the InputDevice */
     if(pDev->valuator->mode == Absolute) {
         /* Update the valuators with the true value sent to the client*/
-        if (first_valuator == 0 && num_valuators >= 1)
-            valuators[0] = x;
-        if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-            valuators[1] = y;
+        if(v0) *v0 = x;
+        if(v1) *v1 = y;
+        /*TODO Ensure that valuator 2 and onward also are absolute */
     } else {/* Relative mode */
         /* If driver reported in absolute, calculate the relative valuator
          * values as a delta from the old absolute values of the valuator
          * values. If relative report, keep it as-is.*/
         if (flags & POINTER_ABSOLUTE) {
             int i;
-            for (i = first_valuator; i < num_valuators; i++)
-                valuators[i] = valuators[i] - pDev->valuator->axisVal[i];
-
+            for (i = 0; i < num_valuators; i++)
+                valuators[i] = valuators[i] - pDev->valuator->axisVal[i + first_valuator];
         }
     }
     /* Save the last calculated device axis value in the device
commit a0241d5380bb5d8b10865f8ea81a9a011de4aaf1
Author: Magnus Vigerlöf <Magnus.Vigerlof at ipbo.se>
Date:   Fri May 23 00:36:11 2008 +0200

    dix: Correct clipAxis so it can handle devices with value ranges properly
    
    Signed-off-by: Peter Hutterer <peter at cs.unisa.edu.au>

diff --git a/dix/getevents.c b/dix/getevents.c
index fafb632..26add12 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -406,22 +406,15 @@ static void
 clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
 {
     AxisInfoPtr axis = pDev->valuator->axes + axisNum;
-
     /* InitValuatoraAxisStruct ensures that (min < max). */
 
-
-    /* FIXME: drivers need to be updated, evdev e.g. inits axes as min = 0 and
-     * max = -1. Leave this extra check until the drivers have been updated.
-     */
-    if (axis->max_value < axis->min_value)
+    /* If a value range is defined, clip. If not, do nothing */
+    if (axis->max_value <= axis->min_value)
         return;
 
-    if (axis->min_value != NO_AXIS_LIMITS &&
-            *val < axis->min_value)
+    if (*val < axis->min_value)
         *val = axis->min_value;
-
-    if (axis->max_value != NO_AXIS_LIMITS &&
-            *val > axis->max_value)
+    if (*val > axis->max_value)
         *val = axis->max_value;
 }
 
commit f6645ddbf754c80e9a8b1672519534a887622270
Author: Magnus Vigerlöf <Magnus.Vigerlof at ipbo.se>
Date:   Thu May 22 23:33:45 2008 +0200

    dix: Correct values in the device axisVal are calculated in GPE
    
    Signed-off-by: Peter Hutterer <peter at cs.unisa.edu.au>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 42b77c1..da6cf8d 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -818,107 +818,8 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
         bit = 1 << (key & 7);
     }
 
-    /* Update device axis */
-    for (i = 1; i < count; i++) {
-	if ((++xV)->type == DeviceValuator) {
-	    int *axisvals;
-            int first = xV->first_valuator;
-            BOOL change = FALSE;
-
-	    if (xV->num_valuators &&
-                (!v || (xV->num_valuators &&
-                      (first + xV->num_valuators > v->numAxes))))
-		FatalError("Bad valuators reported for device %s\n",
-			   device->name);
-	    if (v && v->axisVal) {
-                /* The device always stores values in absolute. Only the
-                 * delivery mode changes.
-                 * If device is mode Absolute, and event is Relative
-                 *     dev += event
-                 *     event = dev
-                 * If device is mode Absolute, and event is Absolute
-                 *     dev = event
-                 * If device is mode Relative, and event is Absolute
-                 *      swap = (event - device)
-                 *      dev = event
-                 *      event = delta
-                 * If device is mode Relative, and event is Relative
-                 *      dev += event
-                 *
-                 * XXX: axis clipping for relative events?
-                 */
-		axisvals = v->axisVal;
-                if (xV->sequenceNumber & Absolute) {
-                    int delta;
-                    if (v->mode == Relative) /* device reports relative */
-                    {
-                        change = TRUE;
-                        xV->sequenceNumber &= ~Absolute;
-                    }
-
-                    switch (xV->num_valuators) {
-                        case 6:
-                            if (change) delta = xV->valuator5 - *(axisvals + first + 5);
-                            *(axisvals + first + 5) = xV->valuator5;
-                            if (change) xV->valuator5 = delta;
-                        case 5:
-                            if (change) delta = xV->valuator4 - *(axisvals + first + 4);
-                            *(axisvals + first + 4) = xV->valuator4;
-                            if (change) xV->valuator4 = delta;
-                        case 4:
-                            if (change) delta = xV->valuator3 - *(axisvals + first + 3);
-                            *(axisvals + first + 3) = xV->valuator3;
-                            if (change) xV->valuator3 = delta;
-                        case 3:
-                            if (change) delta = xV->valuator2 - *(axisvals + first + 2);
-                            *(axisvals + first + 2) = xV->valuator2;
-                            if (change) xV->valuator2 = delta;
-                        case 2:
-                            if (change) delta = xV->valuator1 - *(axisvals + first + 1);
-                            *(axisvals + first + 1) = xV->valuator1;
-                            if (change) xV->valuator1 = delta;
-                        case 1:
-                            if (change) delta = xV->valuator0 - *(axisvals + first);
-                            *(axisvals + first) = xV->valuator0;
-                            if (change) xV->valuator0 = delta;
-                        case 0:
-                        default:
-                            break;
-                    }
-		} else { /* event is relative */
-                    if (v->mode == Absolute) /* device reports absolute */
-                    {
-                        change = TRUE;
-                        xV->sequenceNumber |= Absolute;
-                    }
-
-                    switch (xV->num_valuators) {
-                        case 6:
-                            *(axisvals + first + 5) += xV->valuator5;
-                            if (change) xV->valuator5 = *(axisvals + first + 5);
-                        case 5:
-                            *(axisvals + first + 4) += xV->valuator4;
-                            if (change) xV->valuator4 = *(axisvals + first + 4);
-                        case 4:
-                            *(axisvals + first + 3) += xV->valuator3;
-                            if (change) xV->valuator3 = *(axisvals + first + 3);
-                        case 3:
-                            *(axisvals + first + 2) += xV->valuator2;
-                            if (change) xV->valuator2 = *(axisvals + first + 2);
-                        case 2:
-                            *(axisvals + first + 1) += xV->valuator1;
-                            if (change) xV->valuator1 = *(axisvals + first + 1);
-                        case 1:
-                            *(axisvals + first) += xV->valuator0;
-                            if (change) xV->valuator0 = *(axisvals + first);
-                        case 0:
-                        default:
-                            break;
-                    }
-                }
-	    }
-	}
-    }
+    /* Device axis are calculated in GetPointerEvents and need
+     * no more processing */
 
     if (xE->u.u.type == DeviceKeyPress) {
         if (!k)


More information about the xorg-commit mailing list