Hi. I modified the evdev driver to allow mousewheel emulation to work
on touchscreen devices. Previously this wasn't possible since
touchscreens report absolute, instead of relative positions, and the
wheel emulation code hooked into the relative position reporting code.

The bulk is in the first patch; the second patch is not strictly
necessary. I have tested the code on the one touchscreen device I have
(openmoko freerunner) and it seems to work. If I get the thumbs up, I
will modify the non-evdev versions of this code (the "mouse" driver is
the only one, right?) Thanks.

Dima
>From 4db8b697d2cf4c06b8b1d0384eab9bdc9b638335 Mon Sep 17 00:00:00 2001
From: Dima Kogan <[email protected]>
Date: Sun, 29 Nov 2009 18:00:08 -0800
Subject: [PATCH 1/2] allow wheel emulation to work even with absolute-position devices

Signed-off-by: Dima Kogan <[email protected]>
---
 src/emuWheel.c |   22 +++++-----------------
 src/evdev.c    |   23 ++++++++++++++++++++---
 src/evdev.h    |    2 +-
 3 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/src/emuWheel.c b/src/emuWheel.c
index e7b2f98..734b11a 100644
--- a/src/emuWheel.c
+++ b/src/emuWheel.c
@@ -95,11 +95,10 @@ EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value)
 
 /* Filter mouse wheel events */
 BOOL
-EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
+EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, BOOL isX, int delta)
 {
     EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
     WheelAxisPtr pAxis = NULL, pOtherAxis = NULL;
-    int value = pEv->value;
 
     /* Has wheel emulation been configured to be enabled? */
     if (!pEvdev->emulateWheel.enabled)
@@ -117,20 +116,12 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
                 return TRUE;
         }
 
-	/* We don't want to intercept real mouse wheel events */
-	switch(pEv->code) {
-	case REL_X:
+	if (isX) {
 	    pAxis = &(pEvdev->emulateWheel.X);
 	    pOtherAxis = &(pEvdev->emulateWheel.Y);
-	    break;
-
-	case REL_Y:
+	} else {
 	    pAxis = &(pEvdev->emulateWheel.Y);
 	    pOtherAxis = &(pEvdev->emulateWheel.X);
-	    break;
-
-	default:
-	    break;
 	}
 
 	/* If we found REL_X or REL_Y, emulate a mouse wheel.
@@ -138,11 +129,8 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
            to avoid the buildup of erroneous scroll events if the user
            doesn't move in a perfectly straight line.
          */
-	if (pAxis)
-	{
-	    if (EvdevWheelEmuInertia(pInfo, pAxis, value))
-		pOtherAxis->traveled_distance = 0;
-	}
+	if (EvdevWheelEmuInertia(pInfo, pAxis, delta))
+	    pOtherAxis->traveled_distance = 0;
 
 	/* Eat motion events while emulateWheel button pressed. */
 	return TRUE;
diff --git a/src/evdev.c b/src/evdev.c
index 81a0bd5..28358c6 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -497,8 +497,11 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
                 return;
 
             /* Handle mouse wheel emulation */
-            if (EvdevWheelEmuFilterMotion(pInfo, ev))
-                return;
+            if (ev->code == REL_X || ev->code == REL_Y)
+                if (EvdevWheelEmuFilterMotion(pInfo,
+                                              ev->code == REL_X,
+                                              ev->value))
+                    return;
 
             pEvdev->delta[ev->code] += value;
             break;
@@ -511,7 +514,7 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
 static void
 EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
 {
-    static int value;
+    static int value, oldValue;
     EvdevPtr pEvdev = pInfo->private;
 
     /* Get the signed value, earlier kernels had this as unsigned */
@@ -524,7 +527,21 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
     if (ev->code > ABS_MAX)
         return;
 
+    oldValue = pEvdev->vals[pEvdev->axis_map[ev->code]];
     pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
+
+    /* Handle mouse wheel emulation */
+    /* If wheel emulation is active, I set pEvdev->vals[], but not
+       ev->code. This keeps track of the position so that the delta is
+       computed correctly, but does not update the cursor position in
+       the X-server */
+    if (ev->code == ABS_X || ev->code == ABS_Y) {
+        if(EvdevWheelEmuFilterMotion(pInfo,
+                                     ev->code == ABS_X,
+                                     value - oldValue))
+            return;
+    }
+
     if (ev->code == ABS_X)
         pEvdev->abs |= ABS_X_VALUE;
     else if (ev->code == ABS_Y)
diff --git a/src/evdev.h b/src/evdev.h
index 38adeaf..8799693 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -204,7 +204,7 @@ void EvdevMBEmuEnable(InputInfoPtr, BOOL);
 /* Mouse Wheel emulation */
 void EvdevWheelEmuPreInit(InputInfoPtr pInfo);
 BOOL EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value);
-BOOL EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv);
+BOOL EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, BOOL isX, int delta);
 
 /* Draglock code */
 void EvdevDragLockPreInit(InputInfoPtr pInfo);
-- 
1.6.5.2

>From 60fdec2223ce25c1d184cf91b6f173f728ee1395 Mon Sep 17 00:00:00 2001
From: Dima Kogan <[email protected]>
Date: Sun, 29 Nov 2009 18:49:49 -0800
Subject: [PATCH 2/2] removed unnecessary static declaration

Signed-off-by: Dima Kogan <[email protected]>
---
 src/evdev.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index 28358c6..80f24f2 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -514,7 +514,7 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
 static void
 EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
 {
-    static int value, oldValue;
+    int value, oldValue;
     EvdevPtr pEvdev = pInfo->private;
 
     /* Get the signed value, earlier kernels had this as unsigned */
-- 
1.6.5.2

_______________________________________________
xorg-devel mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to