[PATCH 1/2] Add timeout support for mouse wheel emulation

Dan Nicholson dbn.lists at gmail.com
Wed Aug 20 18:16:40 PDT 2008


Support the EmulateWheelTimeout option as the mouse driver does.

Signed-off-by: Dan Nicholson <dbn.lists at gmail.com>
---
 man/evdev.man  |    9 +++++++++
 src/emuWheel.c |   43 +++++++++++++++++++++++++++++++++++++++++--
 src/evdev.h    |    2 ++
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/man/evdev.man b/man/evdev.man
index 8b20acc..91894dd 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -99,6 +99,7 @@ behaviour with trackballs.  It can also be useful for mice with 4 or
 more buttons but no wheel.  See the description of the
 .BR EmulateWheelButton ,
 .BR EmulateWheelInertia ,
+.BR EmulateWheelTimeout ,
 .BR XAxisMapping ,
 and
 .B YAxisMapping
@@ -117,6 +118,14 @@ settings.  Default: 4.
 Specifies how far (in pixels) the pointer must move to generate button
 press/release events in wheel emulation mode.  Default: 10.
 .TP 7
+.BI "Option \*qEmulateWheelTimeout\*q \*q" integer \*q
+Specifies the time in milliseconds the
+.BR EmulateWheelButton
+must be pressed before wheel emulation is started. If the
+.BR EmulateWheelButton
+is released before this timeout, the original button press/release event
+is sent.  Default: 200.
+.TP 7
 .BI "Option \*qXAxisMapping\*q \*q" "N1 N2" \*q
 Specifies which buttons are mapped to motion in the X direction in wheel
 emulation mode.  Button number
diff --git a/src/emuWheel.c b/src/emuWheel.c
index 3c0b066..53fc3b4 100644
--- a/src/emuWheel.c
+++ b/src/emuWheel.c
@@ -64,6 +64,7 @@ BOOL
 EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value)
 {
     EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
+    int ms;
 
     /* Has wheel emulation been configured to be enabled? */
     if (!pEvdev->emulateWheel.enabled)
@@ -73,6 +74,22 @@ EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value)
     if (pEvdev->emulateWheel.button == button) {
 	pEvdev->emulateWheel.button_state = value;
 
+        if (value)
+            /* Start the timer when the button is pressed */
+            pEvdev->emulateWheel.expires = pEvdev->emulateWheel.timeout +
+                                           GetTimeInMillis();
+        else {
+            ms = pEvdev->emulateWheel.expires - GetTimeInMillis();
+            if (ms > 0) {
+                /*
+                 * If the button is released early enough emit the button
+                 * press/release events
+                 */
+                xf86PostButtonEvent(pInfo->dev, 0, button, 1, 0, 0);
+                xf86PostButtonEvent(pInfo->dev, 0, button, 0, 0, 0);
+            }
+        }
+
 	return TRUE;
     }
 
@@ -87,6 +104,7 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
     EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
     WheelAxisPtr pAxis = NULL;
     int value = pEv->value;
+    int ms;
 
     /* Has wheel emulation been configured to be enabled? */
     if (!pEvdev->emulateWheel.enabled)
@@ -94,6 +112,11 @@ EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv)
 
     /* Handle our motion events if the emuWheel button is pressed*/
     if (pEvdev->emulateWheel.button_state) {
+        /* Just return if the timeout hasn't expired yet */
+        ms = pEvdev->emulateWheel.expires - GetTimeInMillis();
+        if (ms > 0)
+            return TRUE;
+
 	/* We don't want to intercept real mouse wheel events */
 	switch(pEv->code) {
 	case REL_X:
@@ -212,6 +235,7 @@ EvdevWheelEmuPreInit(InputInfoPtr pInfo)
     if (xf86SetBoolOption(pInfo->options, "EmulateWheel", FALSE)) {
 	int wheelButton;
 	int inertia;
+	int timeout;
 
 	pEvdev->emulateWheel.enabled = TRUE;
 	wheelButton = xf86SetIntOption(pInfo->options,
@@ -241,6 +265,19 @@ EvdevWheelEmuPreInit(InputInfoPtr pInfo)
 
 	pEvdev->emulateWheel.inertia = inertia;
 
+    timeout = xf86SetIntOption(pInfo->options, "EmulateWheelTimeout", 200);
+
+    if (timeout < 0) {
+        xf86Msg(X_WARNING, "%s: Invalid EmulateWheelTimeout value: %d\n",
+            pInfo->name, timeout);
+        xf86Msg(X_WARNING, "%s: Using built-in timeout value.\n",
+            pInfo->name);
+
+        timeout = 200;
+    }
+
+    pEvdev->emulateWheel.timeout = timeout;
+
 	/* Configure the Y axis or default it */
 	if (!EvdevWheelEmuHandleButtonMap(pInfo, &(pEvdev->emulateWheel.Y),
 					  "YAxisMapping")) {
@@ -269,8 +306,10 @@ EvdevWheelEmuPreInit(InputInfoPtr pInfo)
 	pEvdev->emulateWheel.X.traveled_distance = 0;
 	pEvdev->emulateWheel.Y.traveled_distance = 0;
 
-	xf86Msg(X_CONFIG, "%s: EmulateWheelButton: %d, EmulateWheelInertia: %d\n",
-		pInfo->name, pEvdev->emulateWheel.button, inertia);
+	xf86Msg(X_CONFIG, "%s: EmulateWheelButton: %d, "
+		"EmulateWheelInertia: %d, "
+		"EmulateWheelTimeout: %d\n",
+		pInfo->name, pEvdev->emulateWheel.button, inertia, timeout);
 
 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
         XIChangeDeviceProperty(pInfo->dev, prop_wheel_emu, XA_INTEGER, 8,
diff --git a/src/evdev.h b/src/evdev.h
index 1f829f0..80756ac 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -90,6 +90,8 @@ typedef struct {
         int                 inertia;
         WheelAxis           X;
         WheelAxis           Y;
+        Time                expires;     /* time of expiry */
+        Time                timeout;
     } emulateWheel;
 
     unsigned char btnmap[32];           /* config-file specified button mapping */
-- 
1.5.5.1




More information about the xorg mailing list