[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