[RFC XI 2.1 - xf86-input-evdev 3/3] Use MTDev for multitouch devices

Peter Hutterer peter.hutterer at who-t.net
Thu Nov 18 22:38:29 PST 2010


On Fri, Nov 12, 2010 at 05:35:13PM -0500, Chase Douglas wrote:
> From: Chase Douglas <chase.douglas at ubuntu.com>
> 
> MTDev translates all multitouch devices to the slotted evdev protocol.
> This provides a clean and uniform interface and reduces message handling
> inside the input module and X.
> 
> Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
> ---
>  configure.ac    |    3 +++
>  src/Makefile.am |    2 +-
>  src/evdev.c     |   44 ++++++++++++++++++++++++++++++++++++++++----
>  src/evdev.h     |    7 +++++++
>  4 files changed, 51 insertions(+), 5 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index cc9e721..ed87352 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -56,6 +56,9 @@ AC_ARG_ENABLE(multitouch,
>  
>  if test "x$MULTITOUCH" = xyes; then
>          AC_DEFINE(MULTITOUCH, 1, [Enable experimental multitouch code])
> +
> +        # Obtain compiler/linker options for mtdev
> +        PKG_CHECK_MODULES(MTDEV, mtdev)
>  fi
>  
>  # Define a configure option for an alternate input module directory
> diff --git a/src/Makefile.am b/src/Makefile.am
> index a5c89ac..89137bc 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -29,7 +29,7 @@ AM_CFLAGS = $(XORG_CFLAGS) $(CWARNFLAGS)
>  AM_CPPFLAGS =-I$(top_srcdir)/include
>  
>  @DRIVER_NAME at _drv_la_LTLIBRARIES = @DRIVER_NAME at _drv.la
> - at DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version
> + at DRIVER_NAME@_drv_la_LDFLAGS = -module -avoid-version $(MTDEV_LIBS)
>  @DRIVER_NAME at _drv_ladir = @inputdir@

I think we should use LDADD for this?

>  @DRIVER_NAME at _drv_la_SOURCES = @DRIVER_NAME at .c \
> diff --git a/src/evdev.c b/src/evdev.c
> index 8b13e9f..a83d4e4 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1065,7 +1065,17 @@ EvdevReadInput(InputInfoPtr pInfo)
>  
>      while (len == sizeof(ev))
>      {
> -        len = read(pInfo->fd, &ev, sizeof(ev));
> +#ifdef MULTITOUCH
> +        EvdevPtr pEvdev = pInfo->private;
> +
> +        if (pEvdev->mtdev)
> +            len = mtdev_get(pEvdev->mtdev, pInfo->fd, ev, NUM_EVENTS) *
> +                sizeof(struct input_event);
> +        else
> +            len = read(pInfo->fd, &ev, sizeof(ev));
> +#else
> +            len = read(pInfo->fd, &ev, sizeof(ev));
> +#endif
>          if (len <= 0)
>          {
>              if (errno == ENODEV) /* May happen after resume */
> @@ -1496,6 +1506,9 @@ EvdevAddAbsClass(DeviceIntPtr device)
>  #ifdef HAVE_MASKED_VALUATORS
>      num_axes = CountBits((uint8_t *)pEvdev->abs_bitmask, ABS_MT_SLOT);
>      num_mt_axes = CountBits((uint8_t *)pEvdev->abs_bitmask, ABS_MAX) - num_axes;
> +
> +    if (num_mt_axes > 0 && !TestBit(ABS_MT_TRACKING_ID, pEvdev->abs_bitmask))
> +        num_mt_axes++;
>  #else
>      num_axes = EvdevCountBits(pEvdev->abs_bitmask, NLONGS(ABS_MAX));
>      num_mt_axes = 0;
> @@ -1540,7 +1553,8 @@ EvdevAddAbsClass(DeviceIntPtr device)
>  
>      for (axis = ABS_X; i < MAX_VALUATORS && axis <= ABS_MAX; axis++) {
>          pEvdev->axis_map[axis] = -1;
> -        if (!TestBit(axis, pEvdev->abs_bitmask) || axis == ABS_MT_SLOT)
> +        if ((!TestBit(axis, pEvdev->abs_bitmask) || axis == ABS_MT_SLOT) &&
> +            axis != ABS_MT_TRACKING_ID)
>              continue;
>          pEvdev->axis_map[axis] = i;
>          i++;
> @@ -1565,8 +1579,8 @@ EvdevAddAbsClass(DeviceIntPtr device)
>          int mode = pEvdev->flags & EVDEV_TOUCHPAD ?
>              XIDependentTouch : XIDirectTouch;
>  
> -        if (pEvdev->absinfo[ABS_MT_SLOT].maximum > 0)
> -            num_touches = pEvdev->absinfo[ABS_MT_SLOT].maximum;
> +        if (pEvdev->mtdev->caps.slot.maximum > 0)
> +            num_touches = pEvdev->mtdev->caps.slot.maximum;
>  
>          pEvdev->mt_slot_map = malloc(num_touches * sizeof(int));
>          if (!pEvdev->mt_slot_map)
> @@ -2061,6 +2075,8 @@ EvdevProc(DeviceIntPtr device, int what)
>  #ifdef MULTITOUCH
>          free(pEvdev->mt_slot_map);
>          free(pEvdev->mtMask);
> +        if (pEvdev->mtdev)
> +            mtdev_close(pEvdev->mtdev);
>  #endif
>          EvdevRemoveDevice(pInfo);
>          pEvdev->min_maj = 0;
> @@ -2489,6 +2505,16 @@ EvdevOpenDevice(InputInfoPtr pInfo)
>  
>          pEvdev->device = device;
>          xf86Msg(X_CONFIG, "%s: Device: \"%s\"\n", pInfo->name, device);
> +
> +#ifdef MULTITOUCH
> +        pEvdev->mtdev = malloc(sizeof(struct mtdev));
> +        if (!pEvdev->mtdev)
> +        {
> +            xf86Msg(X_ERROR, "%s: Couldn't allocate mtdev structure\n",
> +                    pInfo->name);
> +            return BadAlloc;
> +        }
> +#endif
>      }
>  
>      if (pInfo->fd < 0)
> @@ -2503,6 +2529,16 @@ EvdevOpenDevice(InputInfoPtr pInfo)
>          }
>      }
>  
> +#ifdef MULTITOUCH
> +    if (mtdev_open(pEvdev->mtdev, pInfo->fd) == 0)
> +        pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
> +    else {
> +        free(pEvdev->mtdev);
> +        pEvdev->mtdev = NULL;
> +        xf86Msg(X_INFO, "%s: Couldn't open mtdev device\n", pInfo->name);

return FALSE here?

Cheers,
  Peter

> +    }
> +#endif
> +
>      /* Check major/minor of device node to avoid adding duplicate devices. */
>      pEvdev->min_maj = EvdevGetMajorMinor(pInfo);
>      if (EvdevIsDuplicate(pInfo))
> diff --git a/src/evdev.h b/src/evdev.h
> index 63c75a3..6bd8fe3 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -39,6 +39,10 @@
>  #include <xf86_OSproc.h>
>  #include <xkbstr.h>
>  
> +#ifdef MULTITOUCH
> +#include <mtdev.h>
> +#endif
> +
>  #ifndef EV_CNT /* linux 2.6.23 kernels and earlier lack _CNT defines */
>  #define EV_CNT (EV_MAX+1)
>  #endif
> @@ -210,6 +214,9 @@ typedef struct {
>      /* Event queue used to defer keyboard/button events until EV_SYN time. */
>      int                     num_queue;
>      EventQueueRec           queue[EVDEV_MAXQUEUE];
> +#ifdef MULTITOUCH
> +    struct mtdev            *mtdev;
> +#endif
>  } EvdevRec, *EvdevPtr;
>  
>  /* Event posting functions */
> -- 
> 1.7.1
> 


More information about the xorg-devel mailing list