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

Dima Kogan dkogan at cds.caltech.edu
Sun Dec 6 18:23:28 PST 2009


Hi Peter.

I specifically didn't do it that way because I didn't want to assume
that REL_X == ABS_X and REL_Y == ABS_Y. I don't know how set in stone
those definitions are. I'd like you to confirm that this assumption will
hold for the foreseeable future, and if so, I will redo the patch. Let
me know. Thanks.

Dima

On Mon, 7 Dec 2009 11:56:36 +1000
Peter Hutterer <peter.hutterer at who-t.net> wrote:

> 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