[PATCH evdev 3/5] Add the new valuators for multitouch

Peter Hutterer peter.hutterer at who-t.net
Thu Apr 8 22:44:11 PDT 2010


On Sun, Mar 28, 2010 at 01:58:11PM +0200, Benjamin Tissoires wrote:
> The step one in implementing multitouch in evdev is to report all the
> touches in different valuators.
> This patch just creates the extra valuators required for multitouch.
> 
> Note that I currently assume that all definitions above ABS_MT_TOUCH_MAJOR
> and below ABS_MAX are MT-related.
> 
> Signed-off-by: Benjamin Tissoires <tissoire at cena.fr>
> ---
>  src/evdev.c |   51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  src/evdev.h |    5 +++++
>  2 files changed, 55 insertions(+), 1 deletions(-)
> 
> diff --git a/src/evdev.c b/src/evdev.c
> index b84af7f..7e59601 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1156,7 +1156,7 @@ EvdevAddAbsClass(DeviceIntPtr device)
>  {
>      InputInfoPtr pInfo;
>      EvdevPtr pEvdev;
> -    int num_axes, axis, i = 0;
> +    int num_axes, axis, mt_first_valuator, i = 0, j = 0;
>      Atom *atoms;
>      const char *mode;
>  
> @@ -1167,8 +1167,35 @@ EvdevAddAbsClass(DeviceIntPtr device)
>              return !Success;
>  
>      num_axes = CountBits(pEvdev->abs_bitmask, NLONGS(ABS_MAX));
> +    pEvdev->mt_num_valuators = 0;
>      if (num_axes < 1)
>          return !Success;
> +
> +    if (pEvdev->flags & EVDEV_MULTITOUCH) {
> +        /* in case of multitouch devices, we force the axis Tracking ID if not reported by the kernel */
> +        if (!TestBit(ABS_MT_TRACKING_ID, pEvdev->abs_bitmask)) {
> +            num_axes++;
> +            pEvdev->mt_num_valuators++;
> +        }
> +
> +        /* count the number of valuators mt-related.
> +         * assume that mt values are in the range
> +         * ABS_MT_TOUCH_MAJOR..ABS_MAX */
> +        mt_first_valuator = 0;
> +        for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
> +            if (!TestBit(axis, pEvdev->abs_bitmask))
> +                continue;
> +            if (!mt_first_valuator)
> +                mt_first_valuator = axis;
> +            pEvdev->mt_num_valuators++;
> +        }
> +
> +        /* now add the extra axes to the count of reported axes
> +         * the -1 is due to the already registered collection of
> +         * multitouch events */
> +        num_axes += (EVDEV_MAX_TOUCHPOINTS - 1) * pEvdev->mt_num_valuators;
> +    }
> +

I'm worried about EvdevAddAbsClass getting a bit too messy with this. If I'm
not mistaken, you can quite trivially move this if (flags & MULTITOUCH)
condition into a EvdevMTCountValuators() and the loop to init all axes into a
EvdevMTInitValuators(). I think in the future MT will need some more special
handling so refacturing it out into a nice "namespace" might aid this.

Bonus point - you could easily add some documentation to those about the
approach evdev takes in handling multitouch events.

If you squash the preceding patch into this one, then that would be one nice
logic.

code-wise ACK so if you could just do that minor change and the comments,
then I'll push it.

Cheers,
  Peter

>      pEvdev->num_vals = num_axes;
>      memset(pEvdev->vals, 0, num_axes * sizeof(int));
>      memset(pEvdev->old_vals, -1, num_axes * sizeof(int));
> @@ -1182,6 +1209,9 @@ EvdevAddAbsClass(DeviceIntPtr device)
>          i++;
>      }
>  
> +    if (pEvdev->flags & EVDEV_MULTITOUCH)
> +        pEvdev->mt_first_axis = pEvdev->axis_map[mt_first_valuator];
> +
>      EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
>  
>      if (!InitValuatorClassDeviceStruct(device, num_axes,
> @@ -1209,6 +1239,25 @@ EvdevAddAbsClass(DeviceIntPtr device)
>          pEvdev->old_vals[axnum] = -1;
>      }
>  
> +    /* initialize the extra mt-axes */
> +    for (j = 1; j < EVDEV_MAX_TOUCHPOINTS; j++) {
> +        for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
> +            int axnum = pEvdev->axis_map[axis];
> +            int real_axnum = axnum + j * pEvdev->mt_num_valuators;
> +            if (axnum == -1)
> +                continue;
> +            xf86InitValuatorAxisStruct(device, real_axnum,
> +    #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
> +                                       atoms[axnum],
> +    #endif
> +                                       pEvdev->absinfo[axis].minimum,
> +                                       pEvdev->absinfo[axis].maximum,
> +                                       10000, 0, 10000);
> +            xf86InitValuatorDefaults(device, real_axnum);
> +            pEvdev->old_vals[real_axnum] = -1;
> +        }
> +    }
> +
>      xfree(atoms);
>  
>      if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
> diff --git a/src/evdev.h b/src/evdev.h
> index 0e115f3..383a904 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -80,6 +80,8 @@
>  #define MAX_VALUATORS 36
>  #endif
>  
> +/* the number of simultaneous touchpoints the driver can support */
> +#define EVDEV_MAX_TOUCHPOINTS 5 /* currently as MAX_VALUATORS == 36 */
>  
>  #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5
>  typedef struct {
> @@ -193,6 +195,9 @@ typedef struct {
>      /* Event queue used to defer keyboard/button events until EV_SYN time. */
>      int                     num_queue;
>      EventQueueRec           queue[EVDEV_MAXQUEUE];
> +
> +    unsigned int mt_first_axis;
> +    unsigned int mt_num_valuators;
>  } EvdevRec, *EvdevPtr;
>  
>  /* Event posting functions */
> -- 
> 1.6.6.1
> 


More information about the xorg-devel mailing list