[PATCH 1/2] Convert server to masked input valuators

Chase Douglas chase.douglas at canonical.com
Fri Jul 16 06:21:18 PDT 2010


XI2 allows for input event valuators to be masked. The current input
module API only allows for ranges to be specified. This fixes all
internal plumbing to use masks instead of ranges, and adds "M"
mask versions of xf86Post*Event() functions.

Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
 Xext/xtest.c                   |   10 +-
 dix/getevents.c                |  218 ++++++++++++++++++++++------------------
 dix/inpututils.c               |   23 ++++
 hw/dmx/input/dmxevents.c       |   34 ++++---
 hw/kdrive/src/kinput.c         |    5 +-
 hw/xfree86/common/xf86Xinput.c |   95 ++++++++++++++----
 hw/xfree86/common/xf86Xinput.h |    8 ++
 hw/xnest/Events.c              |   13 ++-
 hw/xquartz/darwinEvents.c      |   10 ++-
 hw/xwin/winmouse.c             |    8 +-
 include/input.h                |   15 ++-
 mi/mipointer.c                 |    4 +-
 12 files changed, 291 insertions(+), 152 deletions(-)

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 7268768..b9fd5e7 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -181,6 +181,7 @@ ProcXTestFakeInput(ClientPtr client)
     int base = 0;
     int flags = 0;
     int need_ptr_update = 1;
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
 
     nev = (stuff->length << 2) - sizeof(xReq);
     if ((nev % sizeof(xEvent)) || !nev)
@@ -433,14 +434,15 @@ ProcXTestFakeInput(ClientPtr client)
 
     switch(type) {
         case MotionNotify:
-            nevents = GetPointerEvents(xtest_evlist, dev, type, 0, flags,
-                            firstValuator, numValuators, valuators);
+            ValuatorRangeToMask(firstValuator, numValuators, mask);
+            nevents = GetPointerEvents(xtest_evlist, dev, type, 0, flags, mask,
+                                       valuators);
             break;
         case ButtonPress:
         case ButtonRelease:
+            ValuatorRangeToMask(firstValuator, numValuators, mask);
             nevents = GetPointerEvents(xtest_evlist, dev, type, ev->u.u.detail,
-                                       flags, firstValuator,
-                                       numValuators, valuators);
+                                       flags, mask, valuators);
             break;
         case KeyPress:
         case KeyRelease:
diff --git a/dix/getevents.c b/dix/getevents.c
index a9b6e82..20cc79b 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -184,34 +184,37 @@ init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
 }
 
 static void
-set_raw_valuators(RawDeviceEvent *event, int first, int num, int *valuators, int32_t* data)
+set_raw_valuators(RawDeviceEvent *event, uint8_t *mask, int *valuators, int32_t* data)
 {
     int i;
-    for (i = first; i < first + num; i++)
-        SetBit(event->valuators.mask, i);
 
-    memcpy(&data[first], valuators, num * sizeof(uint32_t));
+    for (i = 0; i < MAX_VALUATORS; i++)
+        if (BitIsOn(mask, i))
+        {
+            SetBit(event->valuators.mask, i);
+            data[i] = valuators[i];
+        }
 }
 
 
 static void
-set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
-              int num_valuators, int *valuators)
+set_valuators(DeviceIntPtr dev, DeviceEvent* event, uint8_t *mask,
+              int *valuators)
 {
     int i;
 
-    for (i = first_valuator; i < first_valuator + num_valuators; i++)
+    for (i = 0; i < MAX_VALUATORS; i++)
     {
-        SetBit(event->valuators.mask, i);
-        if (dev->valuator->mode == Absolute)
-            SetBit(event->valuators.mode, i);
-        event->valuators.data_frac[i] =
-            dev->last.remainder[i] * (1 << 16) * (1 << 16);
+        if (BitIsOn(mask, i))
+        {
+            SetBit(event->valuators.mask, i);
+            if (dev->valuator->mode == Absolute)
+                SetBit(event->valuators.mode, i);
+            event->valuators.data[i] = valuators[i];
+            event->valuators.data_frac[i] =
+                dev->last.remainder[i] * (1 << 16) * (1 << 16);
+        }
     }
-
-    memcpy(&event->valuators.data[first_valuator],
-           valuators, num_valuators * sizeof(uint32_t));
-
 }
 
 void
@@ -524,12 +527,12 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
  *   for SDs: [time] [val0] [val1] ... [valn]
  *   for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
  *
- * For events that have some valuators unset (first_valuator > 0):
+ * For events that have some valuators unset:
  *      min_val == max_val == val == 0.
  */
 static void
-updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
-                    int num_valuators, int *valuators)
+updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, uint8_t *mask,
+                    int *valuators)
 {
     char *buff = (char *) pDev->valuator->motion;
     ValuatorClassPtr v;
@@ -548,17 +551,21 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
         buff += sizeof(Time);
 
         memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
-        buff += 3 * sizeof(INT32) * first_valuator;
 
-        for (i = first_valuator; i < first_valuator + num_valuators; i++)
+        for (i = 0; i < MAX_VALUATORS; i++)
         {
             if (i >= v->numAxes)
                 break;
+            if (!BitIsOn(mask, i))
+            {
+                buff += 3 * sizeof(INT32);
+                continue;
+            }
             memcpy(buff, &v->axes[i].min_value, sizeof(INT32));
             buff += sizeof(INT32);
             memcpy(buff, &v->axes[i].max_value, sizeof(INT32));
             buff += sizeof(INT32);
-            memcpy(buff, &valuators[i - first_valuator], sizeof(INT32));
+            memcpy(buff, &valuators[i], sizeof(INT32));
             buff += sizeof(INT32);
         }
     } else
@@ -571,9 +578,17 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
         buff += sizeof(Time);
 
         memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
-        buff += sizeof(INT32) * first_valuator;
 
-        memcpy(buff, valuators, sizeof(INT32) * num_valuators);
+        for (i = 0; i < MAX_VALUATORS; i++)
+        {
+            if (!BitIsOn(mask, i))
+            {
+                buff += sizeof(INT32);
+                continue;
+            }
+            memcpy(buff, &valuators[i], sizeof(INT32));
+            buff += sizeof(INT32);
+        }
     }
 
     pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
@@ -631,13 +646,13 @@ clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
  * Clip every axis in the list of valuators to its bounds.
  */
 static void
-clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
-              int *valuators)
+clipValuators(DeviceIntPtr pDev, uint8_t *mask, int *valuators)
 {
     int i;
 
-    for (i = 0; i < num_valuators; i++)
-        clipAxis(pDev, i + first_valuator, &(valuators[i]));
+    for (i = 0; i < MAX_VALUATORS; i++)
+        if (BitIsOn(mask, i))
+            clipAxis(pDev, i, &(valuators[i]));
 }
 
 /**
@@ -680,36 +695,37 @@ updateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_event
  * @param dev The device which's pointer is to be moved.
  * @param x Returns the x position of the pointer after the move.
  * @param y Returns the y position of the pointer after the move.
- * @param first The first valuator in @valuators
- * @param num Total number of valuators in @valuators.
+ * @param mask Bit mask of valid valuators.
  * @param valuators Valuator data for each axis between @first and
  *        @first+ at num.
  */
 static void
 moveAbsolute(DeviceIntPtr dev, int *x, int *y,
-             int first, int num, int *valuators)
+             uint8_t *mask, int *valuators)
 {
     int i;
 
 
-    if (num >= 1 && first == 0)
+    if (BitIsOn(mask, 0))
         *x = *(valuators + 0);
     else
         *x = dev->last.valuators[0];
 
-    if (first <= 1 && num >= (2 - first))
-        *y = *(valuators + 1 - first);
+    if (BitIsOn(mask, 1))
+        *y = *(valuators + 1);
     else
         *y = dev->last.valuators[1];
 
     clipAxis(dev, 0, x);
     clipAxis(dev, 1, y);
 
-    i = (first > 2) ? 0 : 2;
-    for (; i < num; i++)
+    for (i = 2; i < MAX_VALUATORS; i++)
     {
-        dev->last.valuators[i + first] = valuators[i];
-        clipAxis(dev, i, &dev->last.valuators[i + first]);
+        if (BitIsOn(mask, i))
+        {
+            dev->last.valuators[i] = valuators[i];
+            clipAxis(dev, i, &dev->last.valuators[i]);
+        }
     }
 }
 
@@ -719,25 +735,24 @@ moveAbsolute(DeviceIntPtr dev, int *x, int *y,
  * @param dev The device which's pointer is to be moved.
  * @param x Returns the x position of the pointer after the move.
  * @param y Returns the y position of the pointer after the move.
- * @param first The first valuator in @valuators
- * @param num Total number of valuators in @valuators.
+ * @param mask Bit mask of valid valuators.
  * @param valuators Valuator data for each axis between @first and
  *        @first+ at num.
  */
 static void
 moveRelative(DeviceIntPtr dev, int *x, int *y,
-             int first, int num, int *valuators)
+             uint8_t *mask, int *valuators)
 {
     int i;
 
     *x = dev->last.valuators[0];
     *y = dev->last.valuators[1];
 
-    if (num >= 1 && first == 0)
+    if (BitIsOn(mask, 0))
         *x += *(valuators +0);
 
-    if (first <= 1 && num >= (2 - first))
-        *y += *(valuators + 1 - first);
+    if (BitIsOn(mask, 1))
+        *y += *(valuators + 1);
 
     /* 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
@@ -748,13 +763,15 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
     }
 
     /* calc other axes, clip, drop back into valuators */
-    i = (first > 2) ? 0 : 2;
-    for (; i < num; i++)
+    for (i = 2; i < MAX_VALUATORS; i++)
     {
-        dev->last.valuators[i + first] += valuators[i];
-        if (dev->valuator->mode == Absolute)
-            clipAxis(dev, i, &dev->last.valuators[i + first]);
-        valuators[i] = dev->last.valuators[i + first];
+        if (BitIsOn(mask, i))
+        {
+            dev->last.valuators[i] += valuators[i];
+            if (dev->valuator->mode == Absolute)
+                clipAxis(dev, i, &dev->last.valuators[i]);
+            valuators[i] = dev->last.valuators[i];
+        }
     }
 }
 
@@ -868,18 +885,18 @@ positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
  * Update the motion history for the device and (if appropriate) for its
  * master device.
  * @param dev Slave device to update.
- * @param first First valuator to append to history.
+ * @param mask Bit mask of valid valuators to append to history.
  * @param num Total number of valuators to append to history.
  * @param ms Current time
  */
 static void
-updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
+updateHistory(DeviceIntPtr dev, uint8_t *mask, CARD32 ms)
 {
-    updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]);
+    updateMotionHistory(dev, ms, mask, dev->last.valuators);
     if (dev->u.master)
     {
         DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
-        updateMotionHistory(master, ms, first, num, &dev->last.valuators[first]);
+        updateMotionHistory(master, ms, mask, dev->last.valuators);
     }
 }
 
@@ -889,7 +906,10 @@ updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
  */
 int
 GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) {
-    return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL);
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
+
+    ValuatorRangeToMask(0, 0, mask);
+    return GetKeyboardValuatorEvents(events, pDev, type, key_code, mask, NULL);
 }
 
 
@@ -911,8 +931,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code)
  */
 int
 GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
-                          int key_code, int first_valuator,
-                          int num_valuators, int *valuators) {
+                              int key_code, uint8_t *mask, int *valuators) {
     int num_events = 0;
     CARD32 ms = 0;
     DeviceEvent *event;
@@ -948,14 +967,11 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     num_events++;
 
     init_raw(pDev, raw, ms, type, key_code);
-    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-                      raw->valuators.data_raw);
+    set_raw_valuators(raw, mask, valuators, raw->valuators.data_raw);
 
-    if (num_valuators)
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
+    clipValuators(pDev, mask, valuators);
 
-    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-                      raw->valuators.data);
+    set_raw_valuators(raw, mask, valuators, raw->valuators.data);
 
     event = (DeviceEvent*) events->event;
     init_event(pDev, event, ms);
@@ -970,10 +986,9 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 	set_key_up(pDev, key_code, KEY_POSTED);
     }
 
-    if (num_valuators)
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
+    clipValuators(pDev, mask, valuators);
 
-    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+    set_valuators(pDev, event, mask, valuators);
 
     return num_events;
 }
@@ -1066,8 +1081,8 @@ transformAbsolute(DeviceIntPtr dev, int v[MAX_VALUATORS])
  */
 int
 GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
-                 int flags, int first_valuator, int num_valuators,
-                 int *valuators) {
+                     int flags, uint8_t *mask, int *valuators) {
+    int i;
     int num_events = 1;
     CARD32 ms;
     DeviceEvent *event;
@@ -1083,14 +1098,21 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     ms = GetTimeInMillis(); /* before pointer update to help precision */
 
-    if (!scr || !pDev->valuator || first_valuator < 0 ||
-        ((num_valuators + first_valuator) > pDev->valuator->numAxes) ||
+    if (!scr || !pDev->valuator ||
         (type != MotionNotify && type != ButtonPress && type != ButtonRelease) ||
         (type != MotionNotify && !pDev->button) ||
-        ((type == ButtonPress || type == ButtonRelease) && !buttons) ||
-        (type == MotionNotify && num_valuators <= 0))
+        ((type == ButtonPress || type == ButtonRelease) && !buttons))
         return 0;
 
+    if (type == MotionNotify)
+    {
+        for (i = 0; i < MAX_VALUATORS; i++)
+            if (BitIsOn(mask, i))
+                break;
+        if (i >= MAX_VALUATORS)
+            return 0;
+    }
+
     events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
     raw = (RawDeviceEvent*)events->event;
@@ -1098,51 +1120,55 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     num_events++;
 
     init_raw(pDev, raw, ms, type, buttons);
-    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-                      raw->valuators.data_raw);
+    set_raw_valuators(raw, mask, valuators, raw->valuators.data_raw);
 
     if (flags & POINTER_ABSOLUTE)
     {
         if (flags & POINTER_SCREEN) /* valuators are in screen coords */
         {
 
-            if (num_valuators >= 1 && first_valuator == 0)
+            if (BitIsOn(mask, 0))
                 valuators[0] = rescaleValuatorAxis(valuators[0], 0.0, &x_frac, NULL,
                         pDev->valuator->axes + 0,
                         scr->width);
-            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-                valuators[1 - first_valuator] = rescaleValuatorAxis(valuators[1 - first_valuator], 0.0, &y_frac, NULL,
+            if (BitIsOn(mask, 1))
+                valuators[1] = rescaleValuatorAxis(valuators[1], 0.0, &y_frac, NULL,
                         pDev->valuator->axes + 1,
                         scr->height);
         }
 
         transformAbsolute(pDev, valuators);
-        moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
+        moveAbsolute(pDev, &x, &y, mask, valuators);
     } else {
         if (flags & POINTER_ACCELERATE) {
-            accelPointer(pDev, first_valuator, num_valuators, valuators, ms);
+            /* Pointer acceleration only requires X and Y values, we cheat */
+            int vals[2];
+            vals[0] = (BitIsOn(mask, 0)) ? valuators[0] :
+                      pDev->last.valuators[0];
+            vals[1] = (BitIsOn(mask, 1)) ? valuators[1] :
+                      pDev->last.valuators[1];
+            accelPointer(pDev, 0, 2, vals, ms);
+
             /* The pointer acceleration code modifies the fractional part
              * in-place, so we need to extract this information first */
             x_frac = pDev->last.remainder[0];
             y_frac = pDev->last.remainder[1];
         }
-        moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);
+        moveRelative(pDev, &x, &y, mask, valuators);
     }
 
-    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-            raw->valuators.data);
+    set_raw_valuators(raw, mask, valuators, raw->valuators.data);
 
     positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
-    updateHistory(pDev, first_valuator, num_valuators, ms);
+    updateHistory(pDev, mask, ms);
 
     /* Update the valuators with the true value sent to the client*/
-    if (num_valuators >= 1 && first_valuator == 0)
+    if (BitIsOn(mask, 0))
         valuators[0] = x;
-    if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-        valuators[1 - first_valuator] = y;
+    if (BitIsOn(mask, 1))
+        valuators[1] = y;
 
-    if (num_valuators)
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
+    clipValuators(pDev, mask, valuators);
 
     event = (DeviceEvent*) events->event;
     init_event(pDev, event, ms);
@@ -1168,7 +1194,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     event->root_x_frac = cx_frac;
     event->root_y_frac = cy_frac;
 
-    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+    set_valuators(pDev, event, mask, valuators);
 
     return num_events;
 }
@@ -1183,7 +1209,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
  */
 int
 GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
-                   int first_valuator, int num_valuators, int *valuators)
+                       uint8_t *mask, int *valuators)
 {
     int num_events = 1;
     DeviceEvent *event;
@@ -1199,12 +1225,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         return 0;
     /* Do we need to send a DeviceValuator event? */
     if ((pDev->valuator->mode & 1) == Relative)
-        num_valuators = 0;
-
-    /* You fail. */
-    if (first_valuator < 0 ||
-        (num_valuators + first_valuator) > pDev->valuator->numAxes)
-        return 0;
+        memset(mask, 0, bits_to_bytes(MAX_VALUATORS));
 
     events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
@@ -1212,10 +1233,9 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
     init_event(pDev, event, GetTimeInMillis());
     event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
 
-    if (num_valuators)
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
+    clipValuators(pDev, mask, valuators);
 
-    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+    set_valuators(pDev, event, mask, valuators);
 
     return num_events;
 }
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 8ec80b5..b444968 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -416,3 +416,26 @@ FreeInputAttributes(InputAttributes *attrs)
     free(attrs);
 }
 
+void
+ValuatorRangeToMask(int first_valuator, int num_valuators, uint8_t *mask)
+{
+    int i;
+
+    memset(mask, 0, bits_to_bytes(MAX_VALUATORS));
+
+    for (i = first_valuator; i < min(num_valuators, MAX_VALUATORS); i++)
+        SetBit(mask, i);
+}
+
+int
+CountBits(uint8_t *mask, int len)
+{
+    int i;
+    int ret = 0;
+
+    for (i = 0; i < len; i++)
+        if (BitIsOn(mask, i))
+            ret++;
+
+    return ret;
+}
diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index dfa6bda..19c5330 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -178,12 +178,14 @@ static void enqueueMotion(DevicePtr pDev, int x, int y)
     int i, nevents, valuators[3];
     EventListPtr events;
     int detail = 0;  /* XXX should this be mask of pressed buttons? */
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
     valuators[0] = x;
     valuators[1] = y;
 
+    ValuatorRangeToMask(0, 2, mask);
     GetEventList(&events);
     nevents = GetPointerEvents(events, p, MotionNotify, detail,
-                               POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators);
+                               POINTER_ABSOLUTE | POINTER_SCREEN, mask, valuators);
     for (i = 0; i < nevents; i++)
        mieqEnqueue(p, (InternalEvent*)(events + i)->event);
     return;
@@ -292,6 +294,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
     int                    count;
     EventListPtr           events;
     int                    nevents;
+    uint8_t                mask[bits_to_bytes(MAX_VALUATORS)];
 
     memset(xE, 0, sizeof(xE));
 
@@ -370,9 +373,10 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
 
     if (block)
         dmxSigioBlock();
+    ValuatorRangeToMask(firstAxis, axesCount, mask);
     GetEventList(&events);
     nevents = GetPointerEvents(events, pDevice, MotionNotify, 0, POINTER_ABSOLUTE,
-                               firstAxis, axesCount, v);
+                               mask, v);
     for (i = 0; i < nevents; i++)
         mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -391,10 +395,11 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     int                    valuators[6];
     EventListPtr           events;
     int                    nevents, i;
+    uint8_t                mask[bits_to_bytes(MAX_VALUATORS)];
 
     if (!e)
         return -1;          /* No extended event passed, cannot handle */
-    
+
     if ((XID)dmxLocal->deviceId != ke->deviceid) {
                                 /* Search for the correct dmxLocal,
                                  * since backend and console events are
@@ -442,13 +447,14 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     switch (type) {
     case XI_DeviceKeyPress:
     case XI_DeviceKeyRelease:
+        ValuatorRangeToMask(ke->first_axis, ke->axes_count, mask);
         EXTRACT_VALUATORS(ke, valuators);
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
         nevents = GetKeyboardValuatorEvents(events, pDevice, event,
-                                            ke->keycode, ke->first_axis,
-                                            ke->axes_count, valuators);
+                                            ke->keycode, mask,
+                                            valuators - ke->first_axis);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -457,13 +463,14 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         break;
     case XI_DeviceButtonPress:
     case XI_DeviceButtonRelease:
+        ValuatorRangeToMask(ke->first_axis, ke->axes_count, mask);
         EXTRACT_VALUATORS(ke, valuators);
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
         nevents = GetPointerEvents(events, pDevice, event, ke->keycode,
-                                   POINTER_ABSOLUTE, ke->first_axis,
-                                   ke->axes_count, valuators);
+                                   POINTER_ABSOLUTE, mask,
+                                   valuators - ke->first_axis);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -472,13 +479,13 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         break;
     case XI_ProximityIn:
     case XI_ProximityOut:
+        ValuatorRangeToMask(ke->first_axis, ke->axes_count, mask);
         EXTRACT_VALUATORS(ke, valuators);
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
         nevents = GetProximityEvents(events, pDevice, event,
-                                     ke->first_axis, ke->axes_count,
-                                     valuators);
+                                     mask, valuators - ke->first_axis);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -664,6 +671,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
     DeviceIntPtr p = dmxLocal->pDevice;
     int i, nevents, valuators[3];
     EventListPtr events;
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
 
     DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail);
 
@@ -687,11 +695,10 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
     case ButtonPress:
     case ButtonRelease:
         detail = dmxGetButtonMapping(dmxLocal, detail);
+        ValuatorRangeToMask(0, 0, mask);
         GetEventList(&events);
         nevents = GetPointerEvents(events, p, type, detail,
-                                   POINTER_ABSOLUTE | POINTER_SCREEN,
-                                   0,   /* first_valuator = 0 */
-                                   0,   /* num_valuators = 0 */
+                                   POINTER_ABSOLUTE | POINTER_SCREEN, mask,
                                    valuators);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(p, (InternalEvent*)(events + i)->event);
@@ -699,11 +706,12 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
 
     case MotionNotify:
         GetEventList(&events);
+        ValuatorRangeToMask(0, 3, mask);
         valuators[0] = e->xmotion.x;
         valuators[1] = e->xmotion.y;
         valuators[2] = e->xmotion.state; /* FIXME: WTF?? */
         nevents = GetPointerEvents(events, p, type, detail, 
-                                   POINTER_ABSOLUTE | POINTER_SCREEN, 0, 3, valuators);
+                                   POINTER_ABSOLUTE | POINTER_SCREEN, mask, valuators);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(p, (InternalEvent*)(events + i)->event);
         return;
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 80a1458..9707a97 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -1975,14 +1975,17 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
 {
     int nEvents = 0, i = 0;
     int valuators[3] = { x, y, z };
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
 
     /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */
     if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel))
         return;
 
+    ValuatorRangeToMask(0, 3, mask);
+
     GetEventList(&kdEvents);
     nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel,
-                               0, 3, valuators);
+                               mask, valuators);
     for (i = 0; i < nEvents; i++)
         KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event));
 }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 76d2d00..7d0d2a3 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1006,6 +1006,20 @@ xf86PostMotionEventP(DeviceIntPtr	device,
                     int			num_valuators,
                     int			*valuators)
 {
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
+
+    XI_VERIFY_VALUATORS(num_valuators);
+
+    ValuatorRangeToMask(first_valuator, num_valuators, mask);
+    xf86PostMotionEventM(device, is_absolute, mask, valuators);
+}
+
+void
+xf86PostMotionEventM(DeviceIntPtr	device,
+                     int		is_absolute,
+                     uint8_t		*mask,
+                     int		*valuators)
+{
     int i = 0, nevents = 0;
     Bool drag = xf86SendDragEvents(device);
     DeviceEvent *event;
@@ -1016,8 +1030,6 @@ xf86PostMotionEventP(DeviceIntPtr	device,
     int dx = 0, dy = 0;
 #endif
 
-    XI_VERIFY_VALUATORS(num_valuators);
-
     if (is_absolute)
         flags = POINTER_ABSOLUTE;
     else
@@ -1025,19 +1037,19 @@ xf86PostMotionEventP(DeviceIntPtr	device,
 
 #if XFreeXDGA
     /* The evdev driver may not always send all axes across. */
-    if (num_valuators >= 1 && first_valuator <= 1) {
+    if (BitIsOn(mask, 0) || BitIsOn(mask, 1))
         if (miPointerGetScreen(device)) {
             index = miPointerGetScreen(device)->myNum;
-            if (first_valuator == 0)
+            if (BitIsOn(mask, 0))
             {
                 dx = valuators[0];
                 if (is_absolute)
                     dx -= device->last.valuators[0];
             }
 
-            if (first_valuator == 1 || num_valuators >= 2)
+            if (BitIsOn(mask, 1))
             {
-                dy = valuators[1 - first_valuator];
+                dy = valuators[1];
                 if (is_absolute)
                     dy -= device->last.valuators[1];
             }
@@ -1045,12 +1057,10 @@ xf86PostMotionEventP(DeviceIntPtr	device,
             if (DGAStealMotionEvent(device, index, dx, dy))
                 return;
         }
-    }
 #endif
 
-    nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0,
-                               flags, first_valuator, num_valuators,
-                               valuators);
+    nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags,
+                               mask, valuators);
 
     for (i = 0; i < nevents; i++) {
         event = (DeviceEvent*)((xf86Events + i)->event);
@@ -1094,12 +1104,26 @@ xf86PostProximityEventP(DeviceIntPtr	device,
                         int		*valuators)
 {
     int i, nevents;
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    ValuatorRangeToMask(first_valuator, num_valuators, mask);
+
+    xf86PostProximityEventM(device, is_in, mask, valuators);
+}
+
+void
+xf86PostProximityEventM(DeviceIntPtr	device,
+                        int		is_in,
+                        uint8_t		*mask,
+                        int		*valuators)
+{
+    int i, nevents;
+
     nevents = GetProximityEvents(xf86Events, device,
-                                 is_in ? ProximityIn : ProximityOut, 
-                                 first_valuator, num_valuators, valuators);
+                                 is_in ? ProximityIn : ProximityOut, mask,
+                                 valuators);
     for (i = 0; i < nevents; i++)
         mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
 
@@ -1139,6 +1163,24 @@ xf86PostButtonEventP(DeviceIntPtr	device,
                      int		num_valuators,
                      int		*valuators)
 {
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
+
+    XI_VERIFY_VALUATORS(num_valuators);
+
+    ValuatorRangeToMask(first_valuator, num_valuators, mask);
+
+    xf86PostButtonEventM(device, is_absolute, button, is_down, mask,
+                         valuators);
+}
+
+void
+xf86PostButtonEventM(DeviceIntPtr	device,
+                     int		is_absolute,
+                     int		button,
+                     int		is_down,
+                     uint8_t		*mask,
+                     int		*valuators)
+{
     int i = 0, nevents = 0;
     int flags = 0;
 
@@ -1146,8 +1188,6 @@ xf86PostButtonEventP(DeviceIntPtr	device,
     int index;
 #endif
 
-    XI_VERIFY_VALUATORS(num_valuators);
-
     if (is_absolute)
         flags = POINTER_ABSOLUTE;
     else
@@ -1163,7 +1203,7 @@ xf86PostButtonEventP(DeviceIntPtr	device,
 
     nevents = GetPointerEvents(xf86Events, device,
                                is_down ? ButtonPress : ButtonRelease, button,
-                               flags, first_valuator, num_valuators, valuators);
+                               flags, mask, valuators);
 
     for (i = 0; i < nevents; i++)
         mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
@@ -1204,15 +1244,29 @@ xf86PostKeyEventP(DeviceIntPtr	device,
                   int		num_valuators,
                   int		*valuators)
 {
-    int i = 0, nevents = 0;
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    ValuatorRangeToMask(first_valuator, num_valuators, mask);
+
+    xf86PostKeyEventM(device, key_code, is_down, is_absolute, mask, valuators);
+}
+
+void
+xf86PostKeyEventM(DeviceIntPtr	device,
+                  unsigned int	key_code,
+                  int		is_down,
+                  int		is_absolute,
+                  uint8_t	*mask,
+                  int		*valuators)
+{
+    int i = 0, nevents = 0;
+
     if (is_absolute) {
         nevents = GetKeyboardValuatorEvents(xf86Events, device,
                                             is_down ? KeyPress : KeyRelease,
-                                            key_code, first_valuator,
-                                            num_valuators, valuators);
+                                            key_code, mask, valuators);
     }
     else {
         nevents = GetKeyboardEvents(xf86Events, device,
@@ -1229,7 +1283,10 @@ xf86PostKeyboardEvent(DeviceIntPtr      device,
                       unsigned int      key_code,
                       int               is_down)
 {
-    xf86PostKeyEventP(device, key_code, is_down, 0, 0, 0, NULL);
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
+
+    ValuatorRangeToMask(0, 0, mask);
+    xf86PostKeyEventM(device, key_code, is_down, 0, mask, NULL);
 }
 
 LocalDevicePtr
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 20a3f1b..d6c115c 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -165,19 +165,27 @@ extern _X_EXPORT void xf86PostMotionEvent(DeviceIntPtr device, int is_absolute,
 			 int first_valuator, int num_valuators, ...);
 extern _X_EXPORT void xf86PostMotionEventP(DeviceIntPtr device, int is_absolute,
 			 int first_valuator, int num_valuators, int *valuators);
+extern _X_EXPORT void xf86PostMotionEventM(DeviceIntPtr device, int is_absolute,
+			 uint8_t *mask, int *valuators);
 extern _X_EXPORT void xf86PostProximityEvent(DeviceIntPtr device, int is_in,
 			    int first_valuator, int num_valuators, ...);
 extern _X_EXPORT void xf86PostProximityEventP(DeviceIntPtr device, int is_in, int first_valuator,
 			     int num_valuators, int *valuators);
+extern _X_EXPORT void xf86PostProximityEventM(DeviceIntPtr device, int is_in, uint8_t *mask,
+			     int *valuators);
 extern _X_EXPORT void xf86PostButtonEvent(DeviceIntPtr device, int is_absolute, int button,
 		    	 int is_down, int first_valuator, int num_valuators,
 			 ...);
 extern _X_EXPORT void xf86PostButtonEventP(DeviceIntPtr device, int is_absolute, int button,
 			  int is_down, int first_valuator, int num_valuators,
 			  int *valuators);
+extern _X_EXPORT void xf86PostButtonEventM(DeviceIntPtr device, int is_absolute, int button,
+			  int is_down, uint8_t *mask, int *valuators);
 extern _X_EXPORT void xf86PostKeyEvent(DeviceIntPtr device, unsigned int key_code, int is_down,
 		      int is_absolute, int first_valuator, int num_valuators,
 		      ...);
+extern _X_EXPORT void xf86PostKeyEventM(DeviceIntPtr device, unsigned int key_code, int is_down,
+		       int is_absolute, uint8_t *mask, int *valuators);
 extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device, unsigned int key_code, int is_down,
 		       int is_absolute, int first_valuator, int num_valuators,
 		       int *valuators);
diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c
index 62e17cb..8c5a029 100644
--- a/hw/xnest/Events.c
+++ b/hw/xnest/Events.c
@@ -117,6 +117,7 @@ xnestCollectEvents(void)
 {
   XEvent X;
   int i, n, valuators[2];
+  uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
   ScreenPtr pScreen;
   GetEventList(&xnestEvents);
 
@@ -133,19 +134,21 @@ xnestCollectEvents(void)
       break;
       
     case ButtonPress:
+      ValuatorRangeToMask(0, 0, mask);
       xnestUpdateModifierState(X.xkey.state);
       lastEventTime = GetTimeInMillis();
       n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
-                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
+                           X.xbutton.button, POINTER_RELATIVE, mask, NULL);
       for (i = 0; i < n; i++)
         mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
       break;
       
     case ButtonRelease:
+      ValuatorRangeToMask(0, 0, mask);
       xnestUpdateModifierState(X.xkey.state);
       lastEventTime = GetTimeInMillis();
       n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
-                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
+                           X.xbutton.button, POINTER_RELATIVE, mask, NULL);
       for (i = 0; i < n; i++)
         mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
       break;
@@ -153,9 +156,10 @@ xnestCollectEvents(void)
     case MotionNotify:
       valuators[0] = X.xmotion.x;
       valuators[1] = X.xmotion.y;
+      ValuatorRangeToMask(0, 2, mask);
       lastEventTime = GetTimeInMillis();
       n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
-                           0, POINTER_ABSOLUTE, 0, 2, valuators);
+                           0, POINTER_ABSOLUTE, mask, valuators);
       for (i = 0; i < n; i++)
         mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
       break;
@@ -186,9 +190,10 @@ xnestCollectEvents(void)
 	  NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x, X.xcrossing.y);
           valuators[0] = X.xcrossing.x;
           valuators[1] = X.xcrossing.y;
+          ValuatorRangeToMask(0, 2, mask);
           lastEventTime = GetTimeInMillis();
           n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
-                               0, POINTER_ABSOLUTE, 0, 2, valuators);
+                               0, POINTER_ABSOLUTE, mask, valuators);
           for (i = 0; i < n; i++)
             mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
 	  xnestDirectInstallColormaps(pScreen);
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 147b32a..4177b00 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -408,6 +408,7 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa
 			     float pressure, float tilt_x, float tilt_y) {
 	static int darwinFakeMouseButtonDown = 0;
 	int i, num_events;
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
     ScreenPtr screen;
     int valuators[5];
 	
@@ -458,8 +459,9 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa
 
     DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
     darwinEvents_lock(); {
+        ValuatorRangeToMask(0, (pDev == darwinTabletCurrent) ? 5 : 2, mask);
         num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button, 
-                                      POINTER_ABSOLUTE, 0, pDev==darwinTabletCurrent?5:2, valuators);
+                                      POINTER_ABSOLUTE, 0, mask, valuators);
         for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
         if(num_events > 0) DarwinPokeEQ();
     } darwinEvents_unlock();
@@ -485,6 +487,7 @@ void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) {
     ScreenPtr screen;
     DeviceIntPtr pDev = darwinTabletCurrent;
     int valuators[5];
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
 
 	DEBUG_LOG("DarwinSendProximityEvents(%d, %f, %f)\n", ev_type, pointer_x, pointer_y);
 
@@ -501,8 +504,9 @@ void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) {
 
     DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, 0.0f, 0.0f, 0.0f);
     darwinEvents_lock(); {
-        num_events = GetProximityEvents(darwinEvents, pDev, ev_type,
-                                        0, 5, valuators);
+        ValuatorRangeToMask(0, 5, mask);
+        num_events = GetProximityEvents(darwinEvents, pDev, ev_type, mask,
+                                        valuators);
         for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
         if(num_events > 0) DarwinPokeEQ();
     } darwinEvents_unlock();
diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c
index 342f20d..e2e949c 100644
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@ -240,15 +240,17 @@ winMouseButtonsSendEvent (int iEventType, int iButton)
 {
   EventListPtr events;
   int i, nevents;
+  uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
 
 #if defined(XFree86Server)
   if (g_winMouseButtonMap)
     iButton = g_winMouseButtonMap[iButton];
 #endif
 
+  ValuatorRangeToMask(0, 0, mask);
   GetEventList(&events);
   nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton,
-			     POINTER_RELATIVE, 0, 0, NULL);
+			     POINTER_RELATIVE, mask, NULL);
 
   for (i = 0; i < nevents; i++)
     mieqEnqueue(g_pwinPointer, events[i].event);
@@ -373,15 +375,17 @@ void winEnqueueMotion(int x, int y)
 {
   int i, nevents;
   int valuators[2];
+  uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
   EventListPtr events;
 
   miPointerSetPosition(g_pwinPointer, &x, &y);
   valuators[0] = x;
   valuators[1] = y;
 
+  ValuatorRangeToMask(0, 2, mask);
   GetEventList(&events);
   nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0,
-			     POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators);
+			     POINTER_ABSOLUTE | POINTER_SCREEN, mask, valuators);
 
   for (i = 0; i < nevents; i++)
     mieqEnqueue(g_pwinPointer, events[i].event);
diff --git a/include/input.h b/include/input.h
index 55b1537..d26850e 100644
--- a/include/input.h
+++ b/include/input.h
@@ -445,8 +445,7 @@ extern _X_EXPORT int GetPointerEvents(
     int type,
     int buttons,
     int flags,
-    int first_valuator,
-    int num_valuators,
+    uint8_t *mask,
     int *valuators);
 
 extern _X_EXPORT int GetKeyboardEvents(
@@ -460,16 +459,14 @@ extern int GetKeyboardValuatorEvents(
     DeviceIntPtr pDev,
     int type,
     int key_code,
-    int first_valuator,
-    int num_valuator,
+    uint8_t *mask,
     int *valuators);
 
 extern int GetProximityEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
-    int first_valuator,
-    int num_valuators,
+    uint8_t *mask,
     int *valuators);
 
 extern void PostSyntheticMotion(
@@ -554,4 +551,10 @@ extern _X_EXPORT void DDXRingBell(
    xfixes/cursor.c uses it to determine if the cursor is enabled */
 extern Bool EnableCursor;
 
+extern _X_EXPORT void ValuatorRangeToMask(int first_valuator,
+    int num_valuators,
+    uint8_t *mask);
+
+extern _X_EXPORT int CountBits(uint8_t *mask, int len);
+
 #endif /* INPUT_H */
diff --git a/mi/mipointer.c b/mi/mipointer.c
index d8aaf8c..e79cfb6 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -553,6 +553,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 {
     int i, nevents;
     int valuators[2];
+    uint8_t mask[bits_to_bytes(MAX_VALUATORS)];
 
     miPointerMoveNoEvent(pDev, pScreen, x, y);
 
@@ -571,7 +572,8 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
         }
     }
 
-    nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_SCREEN | POINTER_ABSOLUTE, 0, 2, valuators);
+    ValuatorRangeToMask(0, 2, mask);
+    nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_SCREEN | POINTER_ABSOLUTE, mask, valuators);
 
     OsBlockSignals();
 #ifdef XQUARTZ
-- 
1.7.0.4



More information about the xorg-devel mailing list