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

Peter Hutterer peter.hutterer at who-t.net
Mon Jul 26 16:54:59 PDT 2010


On Fri, Jul 16, 2010 at 09:21:18AM -0400, Chase Douglas wrote:
> 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++)

I think it'd be better to pass in a length argument for the mask as well
instead of assuming the length here. or a typedef, similar to e.g.
XIEventMask.

> +        if (BitIsOn(mask, i))
> +        {
> +            SetBit(event->valuators.mask, i);
> +            data[i] = valuators[i];
> +        }

not a big fan of skipping {} when the content of a block is more than one
line...

>  }
>  
>  
>  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;

shouldn't this be the loop condition now?

> +            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) {

indentation

>      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) {

indentation

> +    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;
> +    }

use CountBits() instead.

> +
>      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 */

Mark this with a FIXME, I'd like to see a follow-up patch for this in the
future.

> +            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)

indentation.

>  {
>      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);
> +}

given this is a server-internal utility function, I wonder if we should name
it with valuator_range_to_mask nomenclature. jury's out which one is
preferred here, we seem to mix both.

> +
> +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);

urgh, not a big fan of this tbh. just make valuators MAX_VALUATORS big.

>          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);

same here.

>          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

rest looks good.

Cheers,
  Peter


More information about the xorg-devel mailing list