[RFC XI 2.1 - xf86-input-evdev 1/3] Add support for masked valuators

Peter Hutterer peter.hutterer at who-t.net
Tue Nov 16 22:04:55 PST 2010


On Fri, Nov 12, 2010 at 05:35:11PM -0500, Chase Douglas wrote:
> From: Chase Douglas <chase.douglas at ubuntu.com>
> 
> With the X server now supporting masked valuators for XI2, enable
> support in X evdev.
> 
> Note that this leaves around a lot of cruft that should be removed, but
> the code allows for backwards compatibility with X servers < 1.10.
> 
> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
> ---

ack in spirit, nack in this form. this leaves too much code duplication
for my liking, so I'd say we just bite the bullet and remove pre-ABI 12
support.

evdev has a whole bunch of fixes on master right now which can probably be
tagged as 2.6.0. then we can go on with the 2.7 work that drops servers
pre-1.10 and just backport patches as needed.

so I'm not merging this patch as-is but I can see the benefits of exposing
the valuator mask api. let me get master into shape first for branching,
then we can re-do this one without the ifdefs.

Cheers,
  Peter

>  src/emuWheel.c |    6 ++
>  src/evdev.c    |  203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  src/evdev.h    |   12 +++-
>  3 files changed, 215 insertions(+), 6 deletions(-)
> 
> diff --git a/src/emuWheel.c b/src/emuWheel.c
> index 9a53211..7dc4ba8 100644
> --- a/src/emuWheel.c
> +++ b/src/emuWheel.c
> @@ -120,8 +120,14 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
>  
>  	/* We don't want to intercept real mouse wheel events */
>  	if(pEv->type == EV_ABS) {
> +	    int axis = pEvdev->axis_map[pEv->code];
> +#ifdef HAVE_MASKED_VALUATORS
> +	    oldValue = valuator_mask_get(pEvdev->mask, axis);
> +	    valuator_mask_set(pEvdev->mask, axis, value);
> +#else
>  	    oldValue = pEvdev->vals[pEvdev->axis_map[pEv->code]];
>  	    pEvdev->vals[pEvdev->axis_map[pEv->code]] = value;
> +#endif
>  	    value -= oldValue; /* make value into a differential measurement */
>  	}
>  
> diff --git a/src/evdev.c b/src/evdev.c
> index 040cfdc..4984019 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -368,6 +368,108 @@ EvdevQueueButtonClicks(InputInfoPtr pInfo, int button, int count)
>      }
>  }
>  
> +#ifdef HAVE_MASKED_VALUATORS
> +/**
> + * Take the valuators and process them accordingly
> + */
> +static void
> +EvdevProcessValuators(InputInfoPtr pInfo)
> +{
> +    int tmp;
> +    EvdevPtr pEvdev = pInfo->private;
> +
> +    /* convert to relative motion for touchpads */
> +    if (pEvdev->abs_queued && (pEvdev->flags & EVDEV_RELATIVE_MODE)) {
> +        if (pEvdev->proximity) {
> +            if (valuator_mask_isset(pEvdev->mask, 0) &&
> +                valuator_mask_isset(pEvdev->oldMask, 0))
> +                pEvdev->delta[REL_X] = valuator_mask_get(pEvdev->mask, 0) -
> +                                       valuator_mask_get(pEvdev->oldMask, 0);
> +            if (valuator_mask_isset(pEvdev->mask, 1) &&
> +                valuator_mask_isset(pEvdev->oldMask, 1))
> +                pEvdev->delta[REL_Y] = valuator_mask_get(pEvdev->mask, 1) -
> +                                       valuator_mask_get(pEvdev->oldMask, 1);
> +            if (valuator_mask_isset(pEvdev->mask, 0))
> +                valuator_mask_set(pEvdev->oldMask, 0,
> +                                  valuator_mask_get(pEvdev->mask, 0));
> +            if (valuator_mask_isset(pEvdev->mask, 1))
> +                valuator_mask_set(pEvdev->oldMask, 1,
> +                                  valuator_mask_get(pEvdev->mask, 1));
> +        } else {
> +            valuator_mask_zero(pEvdev->oldMask);
> +        }
> +        valuator_mask_zero(pEvdev->mask);
> +        pEvdev->abs_queued = 0;
> +        pEvdev->rel_queued = 1;
> +    }
> +
> +    if (pEvdev->rel_queued) {
> +        int i;
> +
> +        if (pEvdev->swap_axes) {
> +            tmp = pEvdev->delta[REL_X];
> +            pEvdev->delta[REL_X] = pEvdev->delta[REL_Y];
> +            pEvdev->delta[REL_Y] = tmp;
> +        }
> +        if (pEvdev->invert_x)
> +            pEvdev->delta[REL_X] *= -1;
> +        if (pEvdev->invert_y)
> +            pEvdev->delta[REL_Y] *= -1;
> +
> +        for (i = 0; i < REL_CNT; i++)
> +        {
> +            int map = pEvdev->axis_map[i];
> +            if (pEvdev->delta[i] && map != -1)
> +                valuator_mask_set(pEvdev->mask, map, pEvdev->delta[i]);
> +        }
> +    }
> +    /*
> +     * Some devices only generate valid abs coords when BTN_TOOL_PEN is
> +     * pressed.  On wacom tablets, this means that the pen is in
> +     * proximity of the tablet.  After the pen is removed, BTN_TOOL_PEN is
> +     * released, and a (0, 0) absolute event is generated.  Checking
> +     * pEvdev->proximity here lets us ignore that event.  pEvdev is
> +     * initialized to 1 so devices that doesn't use this scheme still
> +     * just works.
> +     */
> +    else if (pEvdev->abs_queued && pEvdev->proximity) {
> +        int unswapped_x = valuator_mask_get(pEvdev->mask, 0);
> +        int unswapped_y = valuator_mask_get(pEvdev->mask, 1);
> +        int i;
> +
> +        for (i = 0; i <= 1; i++) {
> +            int val;
> +
> +            if (!valuator_mask_isset(pEvdev->mask, i))
> +                continue;
> +
> +            val = valuator_mask_get(pEvdev->mask, i);
> +
> +            if (pEvdev->swap_axes)
> +                val = xf86ScaleAxis((i == 0 ? unswapped_y : unswapped_x),
> +                                    pEvdev->absinfo[i].maximum,
> +                                    pEvdev->absinfo[i].minimum,
> +                                    pEvdev->absinfo[1 - i].maximum,
> +                                    pEvdev->absinfo[1 - i].minimum);
> +
> +            if (pEvdev->flags & EVDEV_CALIBRATED)
> +                val = xf86ScaleAxis(val, pEvdev->absinfo[i].maximum,
> +                                    pEvdev->absinfo[i].minimum,
> +                                    (i == 0 ? pEvdev->calibration.max_x :
> +                                     pEvdev->calibration.max_y),
> +                                    (i == 0 ? pEvdev->calibration.min_x :
> +                                     pEvdev->calibration.min_y));
> +
> +            if ((i == 0 && pEvdev->invert_x) || (i == 1 && pEvdev->invert_y))
> +                val = (pEvdev->absinfo[i].maximum - val +
> +                       pEvdev->absinfo[i].minimum);
> +
> +            valuator_mask_set(pEvdev->mask, i, val);
> +        }
> +    }
> +}
> +
> +#else
>  #define ABS_X_VALUE 0x1
>  #define ABS_Y_VALUE 0x2
>  #define ABS_VALUE   0x4
> @@ -480,6 +582,7 @@ EvdevProcessValuators(InputInfoPtr pInfo, int v[MAX_VALUATORS], int *num_v,
>          *first_v = 0;
>      }
>  }
> +#endif
>  
>  static void
>  EvdevProcessProximityEvent(InputInfoPtr pInfo, struct input_event *ev)
> @@ -516,7 +619,11 @@ EvdevProcessProximityState(InputInfoPtr pInfo)
>      if (!pEvdev->prox_queued)
>      {
>          if (pEvdev->abs_queued && !pEvdev->proximity)
> +#ifdef HAVE_MASKED_VALUATORS
> +            valuator_mask_copy(pEvdev->proxMask, pEvdev->mask);
> +#else
>              pEvdev->abs_prox = pEvdev->abs_queued;
> +#endif
>          return 0;
>      }
>  
> @@ -534,11 +641,20 @@ EvdevProcessProximityState(InputInfoPtr pInfo)
>      {
>          /* We're about to go into/out of proximity but have no abs events
>           * within the EV_SYN. Use the last coordinates we have. */
> +#ifdef HAVE_MASKED_VALUATORS
> +        if (!pEvdev->abs_queued &&
> +            valuator_mask_num_valuators(pEvdev->proxMask) > 0)
> +        {
> +            valuator_mask_copy(pEvdev->mask, pEvdev->proxMask);
> +            valuator_mask_zero(pEvdev->proxMask);
> +        }
> +#else
>          if (!pEvdev->abs_queued && pEvdev->abs_prox)
>          {
>              pEvdev->abs_queued = pEvdev->abs_prox;
>              pEvdev->abs_prox = 0;
>          }
> +#endif
>      }
>  
>      pEvdev->proximity = prox_state;
> @@ -584,6 +700,9 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>  {
>      int value;
>      EvdevPtr pEvdev = pInfo->private;
> +#ifdef HAVE_MASKED_VALUATORS
> +    int map;
> +#endif
>  
>      /* Get the signed value, earlier kernels had this as unsigned */
>      value = ev->value;
> @@ -616,6 +735,10 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>  
>              pEvdev->rel_queued = 1;
>              pEvdev->delta[ev->code] += value;
> +#ifdef HAVE_MASKED_VALUATORS
> +            map = pEvdev->axis_map[ev->code];
> +            valuator_mask_set(pEvdev->mask, map, value);
> +#endif
>              break;
>      }
>  }
> @@ -628,6 +751,7 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>  {
>      int value;
>      EvdevPtr pEvdev = pInfo->private;
> +    int map;
>  
>      /* Get the signed value, earlier kernels had this as unsigned */
>      value = ev->value;
> @@ -642,13 +766,19 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>      if (EvdevWheelEmuFilterMotion(pInfo, ev))
>          return;
>  
> -    pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
> +    map = pEvdev->axis_map[ev->code];
> +#ifdef HAVE_MASKED_VALUATORS
> +    valuator_mask_set(pEvdev->mask, map, value);
> +    pEvdev->abs_queued = 1;
> +#else
> +    pEvdev->vals[map] = value;
>      if (ev->code == ABS_X)
>          pEvdev->abs_queued |= ABS_X_VALUE;
>      else if (ev->code == ABS_Y)
>          pEvdev->abs_queued |= ABS_Y_VALUE;
>      else
>          pEvdev->abs_queued |= ABS_VALUE;
> +#endif
>  }
>  
>  /**
> @@ -702,7 +832,11 @@ EvdevPostRelativeMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
>      EvdevPtr pEvdev = pInfo->private;
>  
>      if (pEvdev->rel_queued) {
> +#ifdef HAVE_MASKED_VALUATORS
> +        xf86PostMotionEventM(pInfo->dev, FALSE, pEvdev->mask);
> +#else
>          xf86PostMotionEventP(pInfo->dev, FALSE, first_v, num_v, v + first_v);
> +#endif
>      }
>  }
>  
> @@ -725,7 +859,11 @@ EvdevPostAbsoluteMotionEvents(InputInfoPtr pInfo, int num_v, int first_v,
>       * just work.
>       */
>      if (pEvdev->abs_queued && pEvdev->proximity) {
> +#ifdef HAVE_MASKED_VALUATORS
> +        xf86PostMotionEventM(pInfo->dev, TRUE, pEvdev->mask);
> +#else
>          xf86PostMotionEventP(pInfo->dev, TRUE, first_v, num_v, v + first_v);
> +#endif
>      }
>  }
>  
> @@ -796,7 +934,11 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
>  
>      EvdevProcessProximityState(pInfo);
>  
> +#ifdef HAVE_MASKED_VALUATORS
> +    EvdevProcessValuators(pInfo);
> +#else
>      EvdevProcessValuators(pInfo, v, &num_v, &first_v);
> +#endif
>  
>      EvdevPostProximityEvents(pInfo, TRUE, num_v, first_v, v);
>      EvdevPostRelativeMotionEvents(pInfo, num_v, first_v, v);
> @@ -806,6 +948,10 @@ EvdevProcessSyncEvent(InputInfoPtr pInfo, struct input_event *ev)
>  
>      memset(pEvdev->delta, 0, sizeof(pEvdev->delta));
>      memset(pEvdev->queue, 0, sizeof(pEvdev->queue));
> +#ifdef HAVE_MASKED_VALUATORS
> +    if (pEvdev->mask)
> +        valuator_mask_zero(pEvdev->mask);
> +#endif
>      pEvdev->num_queue = 0;
>      pEvdev->abs_queued = 0;
>      pEvdev->rel_queued = 0;
> @@ -1289,8 +1435,19 @@ EvdevAddAbsClass(DeviceIntPtr device)
>      }
>  
>      pEvdev->num_vals = num_axes;
> +#ifdef HAVE_MASKED_VALUATORS
> +    if (num_axes > 0) {
> +        pEvdev->mask = valuator_mask_new(num_axes);
> +        if (!pEvdev->mask)
> +            return !Success;
> +        pEvdev->oldMask = valuator_mask_new(num_axes);
> +        if (!pEvdev->oldMask)
> +            goto out;
> +    }
> +#else
>      memset(pEvdev->vals, 0, num_axes * sizeof(int));
>      memset(pEvdev->old_vals, -1, num_axes * sizeof(int));
> +#endif
>      atoms = malloc(pEvdev->num_vals * sizeof(Atom));
>  
>      for (axis = ABS_X; i < MAX_VALUATORS && axis <= ABS_MAX; axis++) {
> @@ -1311,7 +1468,7 @@ EvdevAddAbsClass(DeviceIntPtr device)
>                                         GetMotionHistory,
>  #endif
>                                         GetMotionHistorySize(), Absolute))
> -        return !Success;
> +        goto out;
>  
>      for (axis = ABS_X; axis <= ABS_MAX; axis++) {
>          int axnum = pEvdev->axis_map[axis];
> @@ -1338,7 +1495,9 @@ EvdevAddAbsClass(DeviceIntPtr device)
>  #endif
>                                     );
>          xf86InitValuatorDefaults(device, axnum);
> +#ifndef HAVE_MASKED_VALUATORS
>          pEvdev->old_vals[axnum] = -1;
> +#endif
>      }
>  
>      free(atoms);
> @@ -1348,12 +1507,15 @@ EvdevAddAbsClass(DeviceIntPtr device)
>          if (TestBit(proximity_bits[i], pEvdev->key_bitmask))
>          {
>              InitProximityClassDeviceStruct(device);
> +            pEvdev->proxMask = valuator_mask_new(num_axes);
> +            if (!pEvdev->proxMask)
> +                goto out;
>              break;
>          }
>      }
>  
>      if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
> -        return !Success;
> +        goto out;
>  
>      if (pEvdev->flags & EVDEV_TOUCHPAD)
>          pEvdev->flags |= EVDEV_RELATIVE_MODE;
> @@ -1374,6 +1536,17 @@ EvdevAddAbsClass(DeviceIntPtr device)
>      }
>  
>      return Success;
> +
> +out:
> +#ifdef HAVE_MASKED_VALUATORS
> +    free(pEvdev->mask);
> +    pEvdev->mask = NULL;
> +    free(pEvdev->oldMask);
> +    pEvdev->oldMask = NULL;
> +    free(pEvdev->proxMask);
> +    pEvdev->proxMask = NULL;
> +#endif
> +    return !Success;
>  }
>  
>  static int
> @@ -1412,7 +1585,15 @@ EvdevAddRelClass(DeviceIntPtr device)
>      }
>  
>      pEvdev->num_vals = num_axes;
> +#ifdef HAVE_MASKED_VALUATORS
> +    if (num_axes > 0) {
> +        pEvdev->mask = valuator_mask_new(num_axes);
> +        if (!pEvdev->mask)
> +            return !Success;
> +    }
> +#else
>      memset(pEvdev->vals, 0, num_axes * sizeof(int));
> +#endif
>      atoms = malloc(pEvdev->num_vals * sizeof(Atom));
>  
>      for (axis = REL_X; i < MAX_VALUATORS && axis <= REL_MAX; axis++)
> @@ -1437,10 +1618,10 @@ EvdevAddRelClass(DeviceIntPtr device)
>                                         GetMotionHistory,
>  #endif
>                                         GetMotionHistorySize(), Relative))
> -        return !Success;
> +        goto out;
>  
>      if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
> -        return !Success;
> +        goto out;
>  
>      for (axis = REL_X; axis <= REL_MAX; axis++)
>      {
> @@ -1463,6 +1644,13 @@ EvdevAddRelClass(DeviceIntPtr device)
>      free(atoms);
>  
>      return Success;
> +
> +out:
> +#ifdef HAVE_MASKED_VALUATORS
> +    free(pEvdev->mask);
> +    pEvdev->mask = NULL;
> +#endif
> +    return !Success;
>  }
>  
>  static int
> @@ -1732,6 +1920,9 @@ EvdevProc(DeviceIntPtr device, int what)
>              close(pInfo->fd);
>              pInfo->fd = -1;
>          }
> +        free(pEvdev->mask);
> +        free(pEvdev->oldMask);
> +        free(pEvdev->proxMask);
>          EvdevRemoveDevice(pInfo);
>          pEvdev->min_maj = 0;
>  	break;
> @@ -2038,7 +2229,9 @@ EvdevProbe(InputInfoPtr pInfo)
>                  if (has_lmr || TestBit(BTN_TOOL_FINGER, pEvdev->key_bitmask)) {
>                      xf86Msg(X_PROBED, "%s: Found absolute touchpad.\n", pInfo->name);
>                      pEvdev->flags |= EVDEV_TOUCHPAD;
> +#ifndef HAVE_MASKED_VALUATORS
>                      memset(pEvdev->old_vals, -1, sizeof(int) * pEvdev->num_vals);
> +#endif
>                  } else {
>                      xf86Msg(X_PROBED, "%s: Found absolute touchscreen\n", pInfo->name);
>                      pEvdev->flags |= EVDEV_TOUCHSCREEN;
> diff --git a/src/evdev.h b/src/evdev.h
> index 7c17ca4..bd5cb16 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -76,6 +76,10 @@
>  #define HAVE_PROPERTIES 1
>  #endif
>  
> +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 12
> +#define HAVE_MASKED_VALUATORS 1
> +#endif
> +
>  #ifndef MAX_VALUATORS
>  #define MAX_VALUATORS 36
>  #endif
> @@ -121,8 +125,15 @@ typedef struct {
>  
>      int num_vals;           /* number of valuators */
>      int axis_map[max(ABS_CNT, REL_CNT)]; /* Map evdev <axis> to index */
> +#ifdef HAVE_MASKED_VALUATORS
> +    ValuatorMask *mask;
> +    ValuatorMask *oldMask;
> +    ValuatorMask *proxMask;
> +#else
>      int vals[MAX_VALUATORS];
>      int old_vals[MAX_VALUATORS]; /* Translate absolute inputs to relative */
> +    unsigned int abs_prox;  /* valuators posted while out of prox? */
> +#endif
>  
>      int flags;
>      int proximity;
> @@ -133,7 +144,6 @@ typedef struct {
>  
>      int delta[REL_CNT];
>      unsigned int abs_queued, rel_queued, prox_queued;
> -    unsigned int abs_prox;  /* valuators posted while out of prox? */
>  
>      /* XKB stuff has to be per-device rather than per-driver */
>  #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5
> -- 
> 1.7.1
> 


More information about the xorg-devel mailing list