[PATCH evdev] Only use mtdev for multitouch devices

Chase Douglas chase.douglas at canonical.com
Thu Jul 26 14:39:17 PDT 2012


On 07/24/2012 08:52 PM, Peter Hutterer wrote:
> mtdev uses a chunk of memory per device (~41kB), mainly for for its
> internal event buffers. The average box these days can easily have 10
> devices, but only few of those are multitouch. So check if we have
> ABS_MT_POSITION axes and only create an mtdev instance if we do.
>
> If a device has multitouch axes but not x/y, we will ignore events from this
> device now.
>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
>   src/evdev.c |   81 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
>   1 file changed, 71 insertions(+), 10 deletions(-)
>
> diff --git a/src/evdev.c b/src/evdev.c
> index f33b201..ee98a4a 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -774,6 +774,9 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
>       EvdevPtr pEvdev = pInfo->private;
>       int map;
>
> +    if (!pEvdev->mtdev)
> +        return;
> +
>       if (ev->code == ABS_MT_SLOT) {
>           EvdevProcessTouch(pInfo);
>           pEvdev->cur_slot = ev->value;
> @@ -1385,7 +1388,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
>       }
>
>   #ifdef MULTITOUCH
> -    if (num_mt_axes_total > 0)
> +    if (pEvdev->mtdev && num_mt_axes_total > 0)
>       {
>           int num_touches = 0;
>           int mode = pEvdev->flags & EVDEV_TOUCHPAD ?
> @@ -2326,6 +2329,68 @@ EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
>       }
>   }
>
> +#ifdef MULTITOUCH
> +/**
> + * Open an mtdev device for this device. mtdev is a bit too generous with
> + * memory usage, so only do so for devices with multitouch bits set.
> + *
> + * @return FALSE on error, TRUE if mtdev was initiated or the device doesn't
> + * need it
> + */
> +static Bool
> +EvdevOpenMTDev(InputInfoPtr pInfo)
> +{
> +    EvdevPtr pEvdev = pInfo->private;
> +    unsigned long bitmask[NLONGS(EV_CNT)]      = {0};
> +    unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0};
> +    int len;
> +
> +    if (pEvdev->mtdev) {
> +        pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
> +        return TRUE;
> +    }
> +
> +    if (pInfo->fd < 0) {
> +        xf86Msg(X_ERROR, "%s: Bug. fd < 0\n", pInfo->name);
> +        return FALSE;
> +    }
> +
> +    /* Use ioctl here, this may be called before EvdevCache */
> +    len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
> +    if (len < 0) {
> +        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
> +                    strerror(errno));
> +        return FALSE;
> +    }
> +
> +    if (!EvdevBitIsSet(bitmask, EV_ABS))
> +        return TRUE;
> +
> +    len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
> +    if (len < 0) {
> +        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
> +                    strerror(errno));
> +        return FALSE;
> +    }
> +
> +    if (!EvdevBitIsSet(abs_bitmask, ABS_MT_POSITION_X) ||
> +        !EvdevBitIsSet(abs_bitmask, ABS_MT_POSITION_Y))
> +        return TRUE;
> +
> +    xf86IDrvMsg(pInfo, X_INFO, "Using mtdev for this device\n");
> +    pEvdev->mtdev = mtdev_new_open(pInfo->fd);
> +    if (pEvdev->mtdev)
> +        pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
> +    else {
> +        xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
> +        EvdevCloseDevice(pInfo);
> +        return FALSE;
> +    }
> +
> +    return TRUE;
> +}
> +#endif
> +
>   static int
>   EvdevOpenDevice(InputInfoPtr pInfo)
>   {
> @@ -2366,18 +2431,14 @@ EvdevOpenDevice(InputInfoPtr pInfo)
>       }
>
>   #ifdef MULTITOUCH
> -    if (!pEvdev->mtdev) { /* after PreInit mtdev is still valid */
> -        pEvdev->mtdev = mtdev_new_open(pInfo->fd);
> -        if (!pEvdev->mtdev) {
> -            xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
> -            EvdevCloseDevice(pInfo);
> -            return FALSE;
> -        }
> +    if (!EvdevOpenMTDev(pInfo)) {
> +        xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
> +        EvdevCloseDevice(pInfo);
> +        return FALSE;
>       }
> -    if (pEvdev->mtdev)
> -        pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
>   #endif
>
> +

Did you really want another new line here ^^?

>       return Success;
>   }
>

Sounds like a good idea.

Reviewed-by: Chase Douglas <chase.douglas at canonical.com>


More information about the xorg-devel mailing list