[PATCH xserver] Convert server to masked input valuators

Peter Hutterer peter.hutterer at who-t.net
Wed Oct 13 20:31:23 PDT 2010


On Tue, Oct 05, 2010 at 04:07:56PM -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.
> 
> Note the minor version bump of the XInput ABI.

thanks, finally got to review it. a couple of comments, but nothing
world-changing.

fwiw, I'm planning for this to be the last patch for the input ABI 12
patchset, so the minor version bump won't be needed here.

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

if BitIsOn() returns 1 for the bit, then mask->len must be >= 1, so we can
cut out the first bit here.

Generally it'd be good to do some sanity checking in the xf86Post* events to
verify that the ValuatorMask supplied is actually valid. This one here would
just fail quietly.

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

shouldn't this use len or so instead of MAX_VALUATORS?

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

the !mask/mask->len check is there often enough to warrant a mask_is_empty()
macro/inline.


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


indentation


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

there should still be a check to warn in the log if a device sends more
valuators than possible.

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

why not go the full step and add the int *valuators to this struct as well?
Call it ValuatorData, with the mask plus the actual data in one struct.
Makes for simpler passing and I think the changes elsewhere would still be
reasonably small.

Without a comment, I also don't know what len stands for? Shouldn't that be
implicit by the number of bits set in mask?
Also, making mask explicit of MAX_VALUATORS means MAX_VALUATORS becomes ABI,
which may not be the best of all things. Split it up into a uint8_t
mask_len, a uint8_t *mask and the int* valuators to be arbitrary (that's
also what we use for the protocol).

In regards to the use of the valuator array: I think it's better (if more
complicated) to just pass the actual values around. Right now, if you update
axis 32 only, you still have to pass in an array size 32 because the axis
maps to the position in the array. It seems better

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

SetBit/BitIsOn/ClearBit are defined in inputstr.h, might be better to move
CountBits there too.

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

Cheers,
  Peter


More information about the xorg-devel mailing list