From e237de0dea9fe24e1c4efc78523bfdd86ed73876 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Wed, 20 Aug 2008 18:16:40 -0700 Subject: Add timeout support for mouse wheel emulation Support the EmulateWheelTimeout option as the mouse driver does. Signed-off-by: Dan Nicholson Signed-off-by: Peter Hutterer --- 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..ed24e47 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 */ -- cgit v1.2.3