[Xorg] [PATCH] allow EmulateWheel to generate normal clicks too
Andrew Pimlott
andrew at pimlott.net
Sun Aug 15 01:55:00 PDT 2004
I just got hooked on the EmulateWheel feature, for which I use
EmulateWheelButton 2. But I also like having a third button, and I
believe it's possible to have the best of both: If I press button 2 and
release it without moving the mouse, it's a button 2 press; otherwise,
it's an emulated wheel.
This doesn't work for everyone. It requires you to press and release a
button without moving the mouse, which may be hard with a normal mouse,
but easy with a trackball or trackpoint. And it requires you not to
press button 2 to scroll, then change your mind and release without
moving the mouse. But I have found I never do this anyway, so the
behavior I've implemented works great.
I have put this behavior under the option EmulateWheelClickToo, which
defaults to off.
The patch is fairly straightforward, except someone should check my
addition to the man page, because I just aped what I saw.
Andrew
--- hw/xfree86/os-support/xf86OSmouse.h.orig 2004-08-15 00:24:15.000000000 -0700
+++ hw/xfree86/os-support/xf86OSmouse.h 2004-08-15 01:02:04.000000000 -0700
@@ -150,6 +150,8 @@
Bool emulateWheel;
int wheelInertia;
int wheelButtonMask;
+ Bool wheelButtonClick;
+ Bool wheelButtonMoved;
int negativeX; /* Button values. Unlike the Z and */
int positiveX; /* W equivalents, these are button */
int negativeY; /* values rather than button masks. */
--- hw/xfree86/input/mouse/mouse.c.orig 2004-08-15 00:07:41.000000000 -0700
+++ hw/xfree86/input/mouse/mouse.c 2004-08-15 01:15:47.000000000 -0700
@@ -185,6 +185,7 @@
OPTION_RESOLUTION,
OPTION_EMULATE_WHEEL,
OPTION_EMU_WHEEL_BUTTON,
+ OPTION_EMU_WHEEL_CLICK,
OPTION_EMU_WHEEL_INERTIA,
OPTION_X_AXIS_MAPPING,
OPTION_Y_AXIS_MAPPING,
@@ -222,6 +223,7 @@
{ OPTION_RESOLUTION, "Resolution", OPTV_INTEGER, {0}, FALSE },
{ OPTION_EMULATE_WHEEL, "EmulateWheel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_EMU_WHEEL_BUTTON, "EmulateWheelButton", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_EMU_WHEEL_CLICK, "EmulateWheelClickToo", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_EMU_WHEEL_INERTIA, "EmulateWheelInertia", OPTV_INTEGER, {0}, FALSE },
{ OPTION_X_AXIS_MAPPING, "XAxisMapping", OPTV_STRING, {0}, FALSE },
{ OPTION_Y_AXIS_MAPPING, "YAxisMapping", OPTV_STRING, {0}, FALSE },
@@ -619,6 +621,9 @@
}
pMse->wheelButtonMask = 1 << (wheelButton - 1);
+ pMse->wheelButtonClick = xf86SetBoolOption(pInfo->options,
+ "EmulateWheelClickToo", FALSE);
+
pMse->wheelInertia = xf86SetIntOption(pInfo->options,
"EmulateWheelInertia", 10);
if (pMse->wheelInertia <= 0) {
@@ -689,8 +694,9 @@
pInfo->name, pMse->negativeY, pMse->positiveY);
}
xf86Msg(X_CONFIG, "%s: EmulateWheel, EmulateWheelButton: %d, "
- "EmulateWheelInertia: %d\n",
- pInfo->name, wheelButton, pMse->wheelInertia);
+ "EmulateWheelClickToo: %d, EmulateWheelInertia: %d\n",
+ pInfo->name, wheelButton, pMse->wheelInertia,
+ pMse->wheelButtonClick);
}
if (origButtons != pMse->buttons)
from = X_CONFIG;
@@ -1992,6 +1998,8 @@
/* Intercept wheel emulation. */
if (pMse->emulateWheel && (buttons & pMse->wheelButtonMask)) {
+ pMse->wheelButtonMoved = pMse->wheelButtonMoved || dx || dy;
+
/* Y axis movement */
if (pMse->negativeY != MSE_NOAXISMAP) {
pMse->wheelYDistance += dy;
@@ -2044,10 +2052,9 @@
}
}
- /* Absorb the mouse movement and the wheel button press. */
+ /* Absorb the mouse movement. */
dx = 0;
dy = 0;
- buttons &= ~pMse->wheelButtonMask;
}
if (dx || dy)
@@ -2060,6 +2067,31 @@
else
change = buttons ^ reverseBits(reverseMap, pMse->lastButtons);
+ /* We generally swallow wheelButtonMask events, except when a wheel
+ * button is released, and we haven't moved the mouse since a wheel
+ * button was pressed, and EmulateWheelClickToo is set. */
+
+ if (pMse->emulateWheel && change & pMse->wheelButtonMask) {
+ int wheelChange = change & pMse->wheelButtonMask;
+
+ while (wheelChange) {
+ id = ffs(wheelChange);
+ wheelChange &= ~(1 << (id - 1));
+ if (pMse->wheelButtonClick &&
+ ! (buttons & (1 << (id - 1))) && /* released */
+ ! pMse->wheelButtonMoved) {
+ xf86PostButtonEvent(pInfo->dev, 0, id, 1, 0, 0);
+ xf86PostButtonEvent(pInfo->dev, 0, id, 0, 0, 0);
+ }
+ }
+
+ if (! (buttons & pMse->wheelButtonMask))
+ pMse->wheelButtonMoved = 0;
+
+ buttons &= ~pMse->wheelButtonMask;
+ change &= ~pMse->wheelButtonMask;
+ }
+
/*
* adjust buttons state for drag locks!
* if there is drag locks
--- hw/xfree86/input/mouse/mouse.man.orig 2004-08-15 01:04:07.000000000 -0700
+++ hw/xfree86/input/mouse/mouse.man 2004-08-15 01:16:00.000000000 -0700
@@ -112,6 +112,12 @@
.B YAxisMapping
settings. Default: 4.
.TP 7
+.BI "Option \*qEmulateWheelClickToo\*q \*q" boolean \*q
+Causes
+.B EmulateWheelButton
+to generate normal clicks when the mouse isn't moved between press and
+release. Default: off
+.TP 7
.BI "Option \*qEmulateWheelInertia\*q \*q" integer \*q
Specifies how far (in pixels) the pointer must move to generate button
press/release events in wheel emulation mode. Default: 50.
More information about the xorg
mailing list