[PATCH xserver] Convert server to masked input valuators

Chase Douglas chase.douglas at canonical.com
Tue Oct 5 13:07:56 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.

Note the minor version bump of the XInput ABI.

Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
 Xext/xtest.c                   |   10 +-
 dix/getevents.c                |  237 +++++++++++++++++++++------------------
 dix/inpututils.c               |   33 ++++++
 hw/dmx/input/dmxevents.c       |   52 +++++----
 hw/kdrive/src/kinput.c         |    5 +-
 hw/xfree86/common/xf86Module.h |    2 +-
 hw/xfree86/common/xf86Xinput.c |   94 +++++++++++++----
 hw/xfree86/common/xf86Xinput.h |    8 ++
 hw/xnest/Events.c              |   13 ++-
 hw/xquartz/darwinEvents.c      |   10 +-
 hw/xwin/winmouse.c             |    8 +-
 include/input.h                |   22 +++-
 mi/mipointer.c                 |    6 +-
 xkb/xkbActions.c               |   13 ++-
 14 files changed, 336 insertions(+), 177 deletions(-)

diff --git a/Xext/xtest.c b/Xext/xtest.c
index d7d254c..13d22bb 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -153,6 +153,7 @@ ProcXTestFakeInput(ClientPtr client)
     WindowPtr root;
     Bool extension = FALSE;
     deviceValuator *dv = NULL;
+    ValuatorMask mask;
     int valuators[MAX_VALUATORS] = {0};
     int numValuators = 0;
     int firstValuator = 0;
@@ -413,14 +414,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 e5134d3..552debb 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -184,34 +184,40 @@ 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, ValuatorMask *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 < mask->len; i++)
+    {
+        if (BitIsOn(mask->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, ValuatorMask *mask,
+              int *valuators)
 {
     int i;
 
-    for (i = first_valuator; i < first_valuator + num_valuators; i++)
+    for (i = 0; i < mask->len; 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->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 +530,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, ValuatorMask *mask,
+                    int *valuators)
 {
     char *buff = (char *) pDev->valuator->motion;
     ValuatorClassPtr v;
@@ -548,17 +554,19 @@ 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 < v->numAxes; i++)
         {
-            if (i >= v->numAxes)
-                break;
+            if (mask->len <= i || !BitIsOn(mask->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 +579,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 (mask->len <= i || !BitIsOn(mask->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 +647,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, ValuatorMask *mask, int *valuators)
 {
     int i;
 
-    for (i = 0; i < num_valuators; i++)
-        clipAxis(pDev, i + first_valuator, &(valuators[i]));
+    for (i = 0; i < mask->len; i++)
+        if (BitIsOn(mask->mask, i))
+            clipAxis(pDev, i, &(valuators[i]));
 }
 
 /**
@@ -680,36 +696,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)
+             ValuatorMask *mask, int *valuators)
 {
     int i;
 
 
-    if (num >= 1 && first == 0)
+    if (mask->len >= 1 && BitIsOn(mask->mask, 0))
         *x = *(valuators + 0);
     else
         *x = dev->last.valuators[0];
 
-    if (first <= 1 && num >= (2 - first))
-        *y = *(valuators + 1 - first);
+    if (mask->len >= 2 && BitIsOn(mask->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 < mask->len; i++)
     {
-        dev->last.valuators[i + first] = valuators[i];
-        clipAxis(dev, i, &dev->last.valuators[i + first]);
+        if (BitIsOn(mask->mask, i))
+        {
+            dev->last.valuators[i] = valuators[i];
+            clipAxis(dev, i, &dev->last.valuators[i]);
+        }
     }
 }
 
@@ -719,25 +736,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)
+             ValuatorMask *mask, int *valuators)
 {
     int i;
 
     *x = dev->last.valuators[0];
     *y = dev->last.valuators[1];
 
-    if (num >= 1 && first == 0)
+    if (mask->len >= 1 && BitIsOn(mask->mask, 0))
         *x += *(valuators +0);
 
-    if (first <= 1 && num >= (2 - first))
-        *y += *(valuators + 1 - first);
+    if (mask->len >= 2 && BitIsOn(mask->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 +764,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 < mask->len; 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->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 +886,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, ValuatorMask *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 +907,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);
+    ValuatorMask mask;
+
+    ValuatorRangeToMask(0, 0, &mask);
+    return GetKeyboardValuatorEvents(events, pDev, type, key_code, &mask, NULL);
 }
 
 
@@ -911,8 +932,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_in) {
+                          int key_code, ValuatorMask *mask, int *valuators_in) {
     int num_events = 0;
     CARD32 ms = 0;
     DeviceEvent *event;
@@ -924,9 +944,9 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
         return 0;
 
     if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
-        num_valuators > MAX_VALUATORS ||
        (type != KeyPress && type != KeyRelease) ||
-       (key_code < 8 || key_code > 255))
+       (key_code < 8 || key_code > 255) || !mask ||
+       (mask->len > 0 && !valuators_in))
         return 0;
 
     num_events = 1;
@@ -949,17 +969,15 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     events++;
     num_events++;
 
-    memcpy(valuators, valuators_in, num_valuators * sizeof(int));
+    if (valuators_in)
+        memcpy(valuators, valuators_in, MAX_VALUATORS * sizeof(int));
 
     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);
@@ -974,10 +992,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;
 }
@@ -1070,8 +1087,7 @@ 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_in) {
+                 int flags, ValuatorMask *mask, int *valuators_in) {
     int num_events = 1;
     CARD32 ms;
     DeviceEvent *event;
@@ -1088,13 +1104,15 @@ 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 > MAX_VALUATORS ||
-        ((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) || !mask ||
+        (mask->len > 0 && !valuators_in))
+        return 0;
+
+    if (type == MotionNotify &&
+        CountBits(mask->mask, mask->len) <= 0)
         return 0;
 
     events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
@@ -1103,54 +1121,60 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     events++;
     num_events++;
 
-    memcpy(valuators, valuators_in, num_valuators * sizeof(int));
+    if (valuators_in)
+        memcpy(valuators, valuators_in, MAX_VALUATORS * sizeof(int));
 
     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 (mask->len >= 1 && BitIsOn(mask->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 (mask->len >= 2 && BitIsOn(mask->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);
+            /* FIXME: Pointer acceleration only requires X and Y values. This
+             * should be converted to masked valuators. */
+            int vals[2];
+            vals[0] = (mask->len >= 1 && BitIsOn(mask->mask, 0)) ?
+                      valuators[0] : pDev->last.valuators[0];
+            vals[1] = (mask->len >= 2 && BitIsOn(mask->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 (mask->len >= 1 && BitIsOn(mask->mask, 0))
         valuators[0] = x;
-    if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-        valuators[1 - first_valuator] = y;
+    if (mask->len >= 2 && BitIsOn(mask->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);
@@ -1176,7 +1200,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;
 }
@@ -1191,7 +1215,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_in)
+                       ValuatorMask *mask, int *valuators_in)
 {
     int num_events = 1;
     DeviceEvent *event;
@@ -1202,18 +1226,14 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         return 0;
 
     /* Sanity checks. */
-    if (type != ProximityIn && type != ProximityOut)
+    if ((type != ProximityIn && type != ProximityOut) || !mask ||
+        (mask->len > 0 && !valuators_in))
         return 0;
     if (!pDev->valuator)
         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 > MAX_VALUATORS ||
-        (num_valuators + first_valuator) > pDev->valuator->numAxes)
-        return 0;
+        ValuatorRangeToMask(0, 0, mask);
 
     events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
@@ -1221,12 +1241,11 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
     init_event(pDev, event, GetTimeInMillis());
     event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
 
-    if (num_valuators) {
-        memcpy(valuators, valuators_in, num_valuators * sizeof(int));
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
-    }
+    if (valuators_in)
+        memcpy(valuators, valuators_in, MAX_VALUATORS * sizeof(int));
+    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 6693c67..5037f4c 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -418,3 +418,36 @@ FreeInputAttributes(InputAttributes *attrs)
     free(attrs);
 }
 
+void
+ValuatorRangeToMask(int first_valuator, int num_valuators, ValuatorMask *mask)
+{
+    int i;
+
+    memset(mask->mask, 0, bits_to_bytes(MAX_VALUATORS));
+
+    for (i = first_valuator; i < min(num_valuators, MAX_VALUATORS); i++)
+        SetBit(mask->mask, i);
+
+    mask->len = first_valuator + num_valuators;
+}
+
+void
+ValuatorMaskSetBit(ValuatorMask *mask, int bit)
+{
+    SetBit(mask->mask, bit);
+    if (bit >= mask->len)
+        mask->len = bit + 1;
+}
+
+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..f56d649 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -178,12 +178,15 @@ 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? */
+    ValuatorMask mask;
     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 +295,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
     int                    count;
     EventListPtr           events;
     int                    nevents;
+    ValuatorMask           mask;
 
     memset(xE, 0, sizeof(xE));
 
@@ -370,9 +374,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);
+    nevents = GetPointerEvents(events, pDevice, MotionNotify, 0,
+                               POINTER_ABSOLUTE, &mask, v);
     for (i = 0; i < nevents; i++)
         mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -388,13 +393,14 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     XDeviceKeyEvent        *ke     = (XDeviceKeyEvent *)e;
     XDeviceMotionEvent     *me     = (XDeviceMotionEvent *)e;
     DeviceIntPtr           pDevice = dmxLocal->pDevice;
-    int                    valuators[6];
+    int                    valuators[MAX_VALUATORS];
     EventListPtr           events;
     int                    nevents, i;
+    ValuatorMask           mask;
 
     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
@@ -432,23 +438,24 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     }
 
 #define EXTRACT_VALUATORS(ke, valuators) \
-        valuators[0]       = ke->axis_data[0]; \
-        valuators[1]       = ke->axis_data[1]; \
-        valuators[2]       = ke->axis_data[2]; \
-        valuators[3]       = ke->axis_data[3]; \
-        valuators[4]       = ke->axis_data[4]; \
-        valuators[5]       = ke->axis_data[5]; \
+        valuators[ke->first_axis + 0] = ke->axis_data[0]; \
+        valuators[ke->first_axis + 1] = ke->axis_data[1]; \
+        valuators[ke->first_axis + 2] = ke->axis_data[2]; \
+        valuators[ke->first_axis + 3] = ke->axis_data[3]; \
+        valuators[ke->first_axis + 4] = ke->axis_data[4]; \
+        valuators[ke->first_axis + 5] = ke->axis_data[5]; \
 
     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);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -457,13 +464,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);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -472,13 +480,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);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -664,6 +672,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
     DeviceIntPtr p = dmxLocal->pDevice;
     int i, nevents, valuators[3];
     EventListPtr events;
+    ValuatorMask mask;
 
     DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail);
 
@@ -687,11 +696,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 +707,13 @@ 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..25f9694 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 };
+    ValuatorMask mask;
 
     /* 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/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 7a8f62f..4f88440 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -83,7 +83,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(9, 0)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(11, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(11, 1)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(4, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 877eb03..8fe56f1 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1004,6 +1004,20 @@ xf86PostMotionEventP(DeviceIntPtr	device,
                     int			num_valuators,
                     int			*valuators)
 {
+    ValuatorMask mask;
+
+    XI_VERIFY_VALUATORS(num_valuators);
+
+    ValuatorRangeToMask(first_valuator, num_valuators, &mask);
+    xf86PostMotionEventM(device, is_absolute, &mask, valuators);
+}
+
+void
+xf86PostMotionEventM(DeviceIntPtr	device,
+                     int		is_absolute,
+                     ValuatorMask	*mask,
+                     int		*valuators)
+{
     int i = 0, nevents = 0;
     Bool drag = xf86SendDragEvents(device);
     DeviceEvent *event;
@@ -1014,8 +1028,6 @@ xf86PostMotionEventP(DeviceIntPtr	device,
     int dx = 0, dy = 0;
 #endif
 
-    XI_VERIFY_VALUATORS(num_valuators);
-
     if (is_absolute)
         flags = POINTER_ABSOLUTE;
     else
@@ -1023,19 +1035,20 @@ xf86PostMotionEventP(DeviceIntPtr	device,
 
 #if XFreeXDGA
     /* The evdev driver may not always send all axes across. */
-    if (num_valuators >= 1 && first_valuator <= 1) {
+    if ((mask->len >= 1 && BitIsOn(mask->mask, 0)) ||
+        (mask->len >= 2 && BitIsOn(mask->mask, 1)))
         if (miPointerGetScreen(device)) {
             index = miPointerGetScreen(device)->myNum;
-            if (first_valuator == 0)
+            if (BitIsOn(mask->mask, 0))
             {
                 dx = valuators[0];
                 if (is_absolute)
                     dx -= device->last.valuators[0];
             }
 
-            if (first_valuator == 1 || num_valuators >= 2)
+            if (mask->len >= 2 && BitIsOn(mask->mask, 1))
             {
-                dy = valuators[1 - first_valuator];
+                dy = valuators[1];
                 if (is_absolute)
                     dy -= device->last.valuators[1];
             }
@@ -1043,12 +1056,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);
@@ -1091,13 +1102,25 @@ xf86PostProximityEventP(DeviceIntPtr	device,
                         int		num_valuators,
                         int		*valuators)
 {
-    int i, nevents;
+    ValuatorMask mask;
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    ValuatorRangeToMask(first_valuator, num_valuators, &mask);
+    xf86PostProximityEventM(device, is_in, &mask, valuators);
+}
+
+void
+xf86PostProximityEventM(DeviceIntPtr	device,
+                        int		is_in,
+                        ValuatorMask	*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));
 
@@ -1137,6 +1160,23 @@ xf86PostButtonEventP(DeviceIntPtr	device,
                      int		num_valuators,
                      int		*valuators)
 {
+    ValuatorMask mask;
+
+    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,
+                     ValuatorMask	*mask,
+                     int		*valuators)
+{
     int i = 0, nevents = 0;
     int flags = 0;
 
@@ -1144,8 +1184,6 @@ xf86PostButtonEventP(DeviceIntPtr	device,
     int index;
 #endif
 
-    XI_VERIFY_VALUATORS(num_valuators);
-
     if (is_absolute)
         flags = POINTER_ABSOLUTE;
     else
@@ -1161,7 +1199,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));
@@ -1202,15 +1240,28 @@ xf86PostKeyEventP(DeviceIntPtr	device,
                   int		num_valuators,
                   int		*valuators)
 {
-    int i = 0, nevents = 0;
+    ValuatorMask mask;
 
     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,
+                  ValuatorMask	*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,
@@ -1227,7 +1278,10 @@ xf86PostKeyboardEvent(DeviceIntPtr      device,
                       unsigned int      key_code,
                       int               is_down)
 {
-    xf86PostKeyEventP(device, key_code, is_down, 0, 0, 0, NULL);
+    ValuatorMask mask;
+
+    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 7b60cdf..732f7f8 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -164,19 +164,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,
+			 ValuatorMask *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,
+			 ValuatorMask *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, ValuatorMask *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, ValuatorMask *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..87bfb5c 100644
--- a/hw/xnest/Events.c
+++ b/hw/xnest/Events.c
@@ -117,6 +117,7 @@ xnestCollectEvents(void)
 {
   XEvent X;
   int i, n, valuators[2];
+  ValuatorMask mask;
   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 74fadf4..9ce55bd 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -414,6 +414,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;
+    ValuatorMask mask;
     ScreenPtr screen;
     int valuators[5];
 	
@@ -464,8 +465,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();
@@ -491,6 +493,7 @@ void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) {
     ScreenPtr screen;
     DeviceIntPtr pDev = darwinTabletCurrent;
     int valuators[5];
+    ValuatorMask mask;
 
 	DEBUG_LOG("DarwinSendProximityEvents(%d, %f, %f)\n", ev_type, pointer_x, pointer_y);
 
@@ -507,8 +510,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..5e16852 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;
+  ValuatorMask mask;
 
 #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];
+  ValuatorMask mask;
   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 ffb1c33..8a1f41c 100644
--- a/include/input.h
+++ b/include/input.h
@@ -157,6 +157,11 @@ typedef struct _DeviceRec {
     Bool	on;			/* used by DDX to keep state */
 } DeviceRec, *DevicePtr;
 
+typedef struct _ValuatorMask {
+    uint8_t	len;
+    uint8_t	mask[(MAX_VALUATORS + 7) / 8];
+} ValuatorMask;
+
 typedef struct {
     int			click, bell, bell_pitch, bell_duration;
     Bool		autoRepeat;
@@ -451,8 +456,7 @@ extern _X_EXPORT int GetPointerEvents(
     int type,
     int buttons,
     int flags,
-    int first_valuator,
-    int num_valuators,
+    ValuatorMask *mask,
     int *valuators);
 
 extern _X_EXPORT int GetKeyboardEvents(
@@ -466,16 +470,14 @@ extern int GetKeyboardValuatorEvents(
     DeviceIntPtr pDev,
     int type,
     int key_code,
-    int first_valuator,
-    int num_valuator,
+    ValuatorMask *mask,
     int *valuators);
 
 extern int GetProximityEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
-    int first_valuator,
-    int num_valuators,
+    ValuatorMask *mask,
     int *valuators);
 
 extern void PostSyntheticMotion(
@@ -560,4 +562,12 @@ 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,
+    ValuatorMask *mask);
+
+extern _X_EXPORT void ValuatorMaskSetBit(ValuatorMask *mask, int bit);
+
+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..88b6beb 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];
+    ValuatorMask mask;
 
     miPointerMoveNoEvent(pDev, pScreen, x, y);
 
@@ -571,7 +572,10 @@ 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
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index c020444..d8d8568 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1354,7 +1354,7 @@ xkbStateNotify	sn;
  * First one on drinking island wins!
  */
 static void
-InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int num_valuators, int *valuators)
+InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask, int *valuators)
 {
     ScreenPtr           pScreen;
     EventListPtr        events;
@@ -1376,8 +1376,8 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int nu
     OsBlockSignals();
     pScreen = miPointerGetScreen(ptr);
     saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
-    nevents = GetPointerEvents(events, ptr, type, button, flags, 0,
-                               num_valuators, valuators);
+    nevents = GetPointerEvents(events, ptr, type, button, flags, mask,
+                               valuators);
     if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
         UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, &nevents);
     miPointerSetWaitForUpdate(pScreen, saveWait);
@@ -1393,6 +1393,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int nu
 static void
 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
 {
+    ValuatorMask        mask;
     int                 gpe_flags = 0;
 
     /* ignore attached SDs */
@@ -1404,7 +1405,9 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
     else
         gpe_flags = POINTER_RELATIVE;
 
-    InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, 2, (int[]){x, y});
+    ValuatorRangeToMask(0, 2, &mask);
+
+    InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask, (int[]){x, y});
 }
 
 void
@@ -1434,5 +1437,5 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
         return;
 
     InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
-                           button, 0, 0, NULL);
+                           button, 0, NULL, NULL);
 }
-- 
1.7.1



More information about the xorg-devel mailing list