Touchscreen support in Kdrive via evdev

Peter Hutterer peter.hutterer at who-t.net
Wed Apr 20 23:02:15 PDT 2011


On Wed, Apr 20, 2011 at 01:08:27PM +0400, Grigory Batalov wrote:
> Hello!
> 
> I'm trying to complete touchscreen support in Kdrive's evdev driver
> by sending events with absolute coordinates (see the attachment).
> 
> Also I've introduced minX/maxX/minY/maxY options to evdev driver
> to scale received coordinates properly.
> 
> Now I can move cursor (to right position) by touching the screen,
> but the touch doesn't send button event, although I call
> 
> KdEnqueuePointerEvent(pi, flags, 0, 0, 0);
> 
> with KD_BUTTON_1 set in flags .
> 
> Could you help me to find an error, please?

rough guess: you may be sending the touch event first, then moving the
pointer to the position. by that time an implicit grab is active already and
no other client will see the button event.

Cheers,
  Peter

> From bf7f0035ccfcfcd641ed330a3bc5fbcc0e0b2254 Mon Sep 17 00:00:00 2001
> From: Grigory Batalov <gbatalov at crystals.ru>
> Date: Wed, 20 Apr 2011 12:54:14 +0400
> Subject: [PATCH] Send events with absolute coordinates
> 
> Scale coordinates reported by a touchscreen
> by user-specified value limits (minX/maxX/minY/maxY)
> and actual screen dimensions.
> ---
>  hw/kdrive/linux/evdev.c |    5 +++++
>  hw/kdrive/src/kdrive.h  |    1 +
>  hw/kdrive/src/kinput.c  |   21 +++++++++++++++++++++
>  3 files changed, 27 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/kdrive/linux/evdev.c b/hw/kdrive/linux/evdev.c
> index 2eaa1e3..d357d60 100644
> --- a/hw/kdrive/linux/evdev.c
> +++ b/hw/kdrive/linux/evdev.c
> @@ -133,6 +133,11 @@ EvdevPtrMotion (KdPointerInfo    *pi, struct input_event *ev)
>              break;
>          }
>      
> +        flags = flags & ~KD_MOUSE_DELTA;
> +        KdEnqueuePointerEvent(pi, flags, ke->abs[0], ke->abs[1], 0);
> +        flags = flags | KD_MOUSE_DELTA | KD_BUTTON_1; 
> +        KdEnqueuePointerEvent(pi, flags, 0, 0, 0);
> + 
>      if (ev->code == REL_WHEEL) {           
>        for (i = 0; i < abs (ev->value); i++) 
>        {
> diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
> index 4e04b59..f541cb6 100644
> --- a/hw/kdrive/src/kdrive.h
> +++ b/hw/kdrive/src/kdrive.h
> @@ -255,6 +255,7 @@ struct _KdPointerInfo {
>      CARD8                 map[KD_MAX_BUTTON + 1];
>      int                   nButtons;
>      int                   nAxes;
> +    int			  minX, maxX, minY, maxY;
>  
>      Bool                  emulateMiddleButton;
>      unsigned long         emulationTimeout;
> diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
> index 9ba1166..935a197 100644
> --- a/hw/kdrive/src/kinput.c
> +++ b/hw/kdrive/src/kinput.c
> @@ -1275,6 +1275,14 @@ KdParsePointerOptions (KdPointerInfo *pi)
>              pi->transformCoordinates = FALSE;
>          else if (!strcasecmp (option->key, "device"))
>              pi->path = KdSaveString(option->value);
> +        else if (!strcasecmp (option->key, "minx"))
> +            pi->minX = atoi(option->value);
> +        else if (!strcasecmp (option->key, "maxx"))
> +            pi->maxX = atoi(option->value);
> +        else if (!strcasecmp (option->key, "miny"))
> +            pi->minY = atoi(option->value);
> +        else if (!strcasecmp (option->key, "maxy"))
> +            pi->maxY = atoi(option->value);
>          else
>              ErrorF("Pointer option key (%s) of value (%s) not assigned!\n", 
>                      option->key, option->value);
> @@ -1298,6 +1306,15 @@ KdParsePointer (char *arg)
>      pi->nButtons = 5; /* XXX should not be hardcoded */
>      pi->inputClass = KD_MOUSE;
>  
> +    /* default touchscreen margins */
> +    pi->minX = pi->minY = 0;
> +    if (screenInfo.numScreens > 0) {
> +	pi->maxX = screenInfo.screens[0]->width;
> +	pi->maxY = screenInfo.screens[0]->height;
> +    }
> +    else
> +	pi->maxX = pi->maxY = 65535;
> +
>      if (!arg)
>      {
>          ErrorF("mouse: no arg\n");
> @@ -2105,6 +2122,10 @@ KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry,
>  	    x = rx;
>  	    y = ry;
>  	}
> +        if (screenInfo.numScreens > 0 && pi->maxX > pi->minX && pi->maxY > pi->minY) {
> +            x = (x - pi->minX) * screenInfo.screens[0]->width / (pi->maxX - pi->minX);
> +	    y = (y - pi->minY) * screenInfo.screens[0]->height / (pi->maxY - pi->minY);
> +        }
>      }
>      z = rz;
>  
> -- 
> 1.7.4.2


More information about the xorg-devel mailing list