[PATCH] evdev: allow mouse wheel emulation to work even with absolute-position devices (like touchscreens)

Peter Hutterer peter.hutterer at who-t.net
Sun Dec 6 17:56:36 PST 2009


On Sat, Dec 05, 2009 at 02:14:21PM -0800, Dima Kogan wrote:
> Here's the new patch. Let me know when you get a chance to try it out.
> Thanks.

thanks again, getting there, one more small change please. :) 
see the comment below.

> From 4b62891ad4297cc5e842efc378fa36e58ecdd28f Mon Sep 17 00:00:00 2001
> From: Dima Kogan <dkogan at cds.caltech.edu>
> Date: Sat, 5 Dec 2009 02:05:19 -0800
> Subject: [PATCH 1/2] allow wheel emulation to work with absolute-position devices
> 
> Signed-off-by: Dima Kogan <dkogan at cds.caltech.edu>
> ---
>  src/emuWheel.c |   61 +++++++++++++++++++++++++++++++++++++++----------------
>  src/evdev.c    |    3 ++
>  2 files changed, 46 insertions(+), 18 deletions(-)
> 
> diff --git a/src/emuWheel.c b/src/emuWheel.c
> index e7b2f98..3105522 100644
> --- a/src/emuWheel.c
> +++ b/src/emuWheel.c
> @@ -100,6 +100,7 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
>      EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
>      WheelAxisPtr pAxis = NULL, pOtherAxis = NULL;
>      int value = pEv->value;
> +    int oldValue;
>  
>      /* Has wheel emulation been configured to be enabled? */
>      if (!pEvdev->emulateWheel.enabled)
> @@ -118,25 +119,49 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
>          }
>  
>  	/* We don't want to intercept real mouse wheel events */
> -	switch(pEv->code) {
> -	case REL_X:
> -	    pAxis = &(pEvdev->emulateWheel.X);
> -	    pOtherAxis = &(pEvdev->emulateWheel.Y);
> -	    break;
> -
> -	case REL_Y:
> -	    pAxis = &(pEvdev->emulateWheel.Y);
> -	    pOtherAxis = &(pEvdev->emulateWheel.X);
> -	    break;
> -
> -	default:
> -	    break;
> -	}
> +        /* REL_X and ABS_X have the same values, so we need a switch inside
> +           an if, instead of a single switch */
> +        if(pEv->type == EV_REL) {
> +            switch(pEv->code) {
> +            case REL_X:
> +                pAxis = &(pEvdev->emulateWheel.X);
> +                pOtherAxis = &(pEvdev->emulateWheel.Y);
> +                break;
> +
> +            case REL_Y:
> +                pAxis = &(pEvdev->emulateWheel.Y);
> +                pOtherAxis = &(pEvdev->emulateWheel.X);
> +                break;
> +
> +            default:
> +                break;
> +            }
> +        } else if(pEv->type == EV_ABS) {
> +            oldValue = pEvdev->vals[pEvdev->axis_map[pEv->code]];
> +            pEvdev->vals[pEvdev->axis_map[pEv->code]] = value;
> +            value -= oldValue; // make value into a differential measurement
> +
> +            switch(pEv->code) {
> +            case ABS_X:
> +                pAxis = &(pEvdev->emulateWheel.X);
> +                pOtherAxis = &(pEvdev->emulateWheel.Y);
> +                break;
> +
> +            case ABS_Y:
> +                pAxis = &(pEvdev->emulateWheel.Y);
> +                pOtherAxis = &(pEvdev->emulateWheel.X);
> +                break;
> +
> +            default:
> +                break;
> +            }
> +
> +        }

how about something like this? (badly copied from the diff, so may not
apply)

+        if(pEv->type == EV_ABS) {
+            oldValue = pEvdev->vals[pEvdev->axis_map[pEv->code]];
+            pEvdev->vals[pEvdev->axis_map[pEv->code]] = value;
+            value -= oldValue; // make value into a differential measurement
+        }
+
+        switch(pEv->code) {
+            case REL_X: /* applies for ABS_X too */
+                pAxis = &(pEvdev->emulateWheel.X);
+                pOtherAxis = &(pEvdev->emulateWheel.Y);
+                break;
+
+            case REL_Y: /* applies for ABS_Y too */
+                pAxis = &(pEvdev->emulateWheel.Y);
+                pOtherAxis = &(pEvdev->emulateWheel.X);
+                break;
+
+            default:
+                break;
+         }

>  
> -	/* If we found REL_X or REL_Y, emulate a mouse wheel.
> -           Reset the inertia of the other axis when a scroll event was sent
> -           to avoid the buildup of erroneous scroll events if the user
> -           doesn't move in a perfectly straight line.
> +	/* If we found REL_X, REL_Y, ABS_X or ABS_Y then emulate a mouse
> +           wheel.  Reset the inertia of the other axis when a scroll event
> +           was sent to avoid the buildup of erroneous scroll events if the
> +           user doesn't move in a perfectly straight line.
>           */
>  	if (pAxis)
>  	{
> diff --git a/src/evdev.c b/src/evdev.c
> index 81a0bd5..1e0f9e2 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -524,6 +524,9 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>      if (ev->code > ABS_MAX)
>          return;
>  
> +    if (EvdevWheelEmuFilterMotion(pInfo, ev))
> +        return;
> +
>      pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
>      if (ev->code == ABS_X)
>          pEvdev->abs |= ABS_X_VALUE;
> -- 
> 1.6.5.2

with that change it looks good. if you can re-send the patch I'll apply,
test and push.

> From fc20a64818a124d536c4a91d791319a1d191b4c6 Mon Sep 17 00:00:00 2001
> From: Dima Kogan <dkogan at cds.caltech.edu>
> Date: Sat, 5 Dec 2009 02:08:32 -0800
> Subject: [PATCH 2/2] removed unnecessary static declarations
> 
> Signed-off-by: Dima Kogan <dkogan at cds.caltech.edu>
> ---
>  src/evdev.c |    6 +++---
>  1 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/src/evdev.c b/src/evdev.c
> index 1e0f9e2..ed77b0f 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -466,7 +466,7 @@ EvdevProcessButtonEvent(InputInfoPtr pInfo, struct input_event *ev)
>  static void
>  EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>  {
> -    static int value;
> +    int value;
>      EvdevPtr pEvdev = pInfo->private;
>  
>      /* Get the signed value, earlier kernels had this as unsigned */
> @@ -511,7 +511,7 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>  static void
>  EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>  {
> -    static int value;
> +    int value;
>      EvdevPtr pEvdev = pInfo->private;
>  
>      /* Get the signed value, earlier kernels had this as unsigned */
> @@ -542,7 +542,7 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
>  static void
>  EvdevProcessKeyEvent(InputInfoPtr pInfo, struct input_event *ev)
>  {
> -    static int value;
> +    int value;
>      EvdevPtr pEvdev = pInfo->private;
>  
>      /* Get the signed value, earlier kernels had this as unsigned */
> -- 
> 1.6.5.2

Applied, thanks.

Cheers,
  Peter


More information about the xorg-devel mailing list