summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2008-08-07 16:53:51 +0930
committerPeter Hutterer <peter.hutterer@redhat.com>2008-08-08 15:50:55 +0930
commit9793de81373bb78b9ddbb2487e0af5d2ddd0b246 (patch)
treec63725b844be32413bd5280184b2e963e8cc3ea2
parenta9d72b40fbe178fa4fbb9d0e7c02dc6c5250969a (diff)
Expose wheel emulation through device properties.
Don't enable wheel emulation with 0 inertia - bad things happen.
-rw-r--r--src/emuWheel.c231
-rw-r--r--src/evdev.c5
-rw-r--r--src/evdev.h9
3 files changed, 245 insertions, 0 deletions
diff --git a/src/emuWheel.c b/src/emuWheel.c
index e6c7f6e..b82ba79 100644
--- a/src/emuWheel.c
+++ b/src/emuWheel.c
@@ -33,11 +33,22 @@
#include "config.h"
#endif
+#include <X11/Xatom.h>
+#include <xf86.h>
+#include <xf86Xinput.h>
+#include <exevents.h>
+
#include "evdev.h"
#define MSE_MAXBUTTONS 32
#define WHEEL_NOT_CONFIGURED 0
+static Atom prop_wheel_emu;
+static Atom prop_wheel_xmap;
+static Atom prop_wheel_ymap;
+static Atom prop_wheel_inertia;
+static Atom prop_wheel_button;
+
/* Local Funciton Prototypes */
static BOOL EvdevWheelEmuHandleButtonMap(InputInfoPtr pInfo, WheelAxisPtr pAxis, char *axis_name);
static void EvdevWheelEmuInertia(InputInfoPtr pInfo, WheelAxisPtr axis, int value);
@@ -188,6 +199,8 @@ void
EvdevWheelEmuPreInit(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = (EvdevPtr)pInfo->private;
+ int val[2];
+
pEvdev->emulateWheel.enabled = FALSE;
if (xf86SetBoolOption(pInfo->options, "EmulateWheel", FALSE)) {
@@ -252,6 +265,224 @@ EvdevWheelEmuPreInit(InputInfoPtr pInfo)
xf86Msg(X_CONFIG, "%s: EmulateWheelButton: %d, EmulateWheelInertia: %d\n",
pInfo->name, pEvdev->emulateWheel.button, inertia);
+
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
+ XIChangeDeviceProperty(pInfo->dev, prop_wheel_emu, XA_INTEGER, 8,
+ PropModeReplace, 1, &pEvdev->emulateWheel.enabled,
+ TRUE, FALSE, FALSE);
+ XIChangeDeviceProperty(pInfo->dev, prop_wheel_button, XA_INTEGER, 8,
+ PropModeReplace, 1,
+ &pEvdev->emulateWheel.button,
+ TRUE, FALSE, FALSE);
+ XIChangeDeviceProperty(pInfo->dev, prop_wheel_inertia, XA_INTEGER, 8,
+ PropModeReplace, 1,
+ &pEvdev->emulateWheel.inertia,
+ TRUE, FALSE, FALSE);
+
+ val[0] = pEvdev->emulateWheel.X.up_button;
+ val[1] = pEvdev->emulateWheel.X.down_button;
+ XIChangeDeviceProperty(pInfo->dev, prop_wheel_xmap, XA_INTEGER, 8,
+ PropModeReplace, 2, val,
+ TRUE, FALSE, FALSE);
+
+ val[0] = pEvdev->emulateWheel.Y.up_button;
+ val[1] = pEvdev->emulateWheel.Y.down_button;
+ XIChangeDeviceProperty(pInfo->dev, prop_wheel_ymap, XA_INTEGER, 8,
+ PropModeReplace, 2, val,
+ TRUE, FALSE, FALSE);
+
+#endif
}
}
+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3
+Atom
+EvdevWheelEmuInitProperty(DeviceIntPtr dev, char* name)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ EvdevPtr pEvdev = pInfo->private;
+ int rc = TRUE;
+ INT32 valid_vals[] = { TRUE, FALSE};
+
+ if (!dev->button) /* don't init prop for keyboards */
+ return 0;
+
+ prop_wheel_emu = MakeAtom(name, strlen(name), TRUE);
+ rc = XIChangeDeviceProperty(dev, prop_wheel_emu, XA_INTEGER, 8,
+ PropModeReplace, 1,
+ &pEvdev->emulateWheel.enabled,
+ FALSE, FALSE, FALSE);
+ if (rc != Success)
+ return 0;
+
+ rc = XIConfigureDeviceProperty(dev, prop_wheel_emu, FALSE, FALSE,
+ FALSE, 2, valid_vals);
+
+ if (rc != Success)
+ return 0;
+ return prop_wheel_emu;
+}
+
+Atom
+EvdevWheelEmuInitPropertyXMap(DeviceIntPtr dev, char* name)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ EvdevPtr pEvdev = pInfo->private;
+ int rc = TRUE;
+ int vals[2];
+
+ if (!dev->button) /* don't init prop for keyboards */
+ return 0;
+
+ vals[0] = pEvdev->emulateWheel.X.up_button;
+ vals[1] = pEvdev->emulateWheel.X.down_button;
+
+ prop_wheel_xmap = MakeAtom(name, strlen(name), TRUE);
+ rc = XIChangeDeviceProperty(dev, prop_wheel_xmap, XA_INTEGER, 8,
+ PropModeReplace, 2, vals,
+ FALSE, FALSE, FALSE);
+ if (rc != Success)
+ return 0;
+
+ rc = XIConfigureDeviceProperty(dev, prop_wheel_xmap, FALSE, FALSE,
+ FALSE, 0, NULL);
+
+ if (rc != Success)
+ return 0;
+ return prop_wheel_xmap;
+}
+
+Atom
+EvdevWheelEmuInitPropertyYMap(DeviceIntPtr dev, char* name)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ EvdevPtr pEvdev = pInfo->private;
+ int rc = TRUE;
+ int vals[2];
+
+ if (!dev->button) /* don't init prop for keyboards */
+ return 0;
+
+ vals[0] = pEvdev->emulateWheel.Y.up_button;
+ vals[1] = pEvdev->emulateWheel.Y.down_button;
+
+ prop_wheel_ymap = MakeAtom(name, strlen(name), TRUE);
+ rc = XIChangeDeviceProperty(dev, prop_wheel_ymap, XA_INTEGER, 8,
+ PropModeReplace, 2, vals,
+ FALSE, FALSE, FALSE);
+ if (rc != Success)
+ return 0;
+
+ rc = XIConfigureDeviceProperty(dev, prop_wheel_ymap, FALSE, FALSE,
+ FALSE, 0, NULL);
+
+ if (rc != Success)
+ return 0;
+ return prop_wheel_ymap;
+}
+
+Atom
+EvdevWheelEmuInitPropertyInertia(DeviceIntPtr dev, char* name)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ EvdevPtr pEvdev = pInfo->private;
+ int rc = TRUE;
+
+ if (!dev->button) /* don't init prop for keyboards */
+ return 0;
+
+ prop_wheel_inertia = MakeAtom(name, strlen(name), TRUE);
+ rc = XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER, 16,
+ PropModeReplace, 1,
+ &pEvdev->emulateWheel.inertia,
+ FALSE, FALSE, FALSE);
+ if (rc != Success)
+ return 0;
+
+ rc = XIConfigureDeviceProperty(dev, prop_wheel_inertia, FALSE, FALSE,
+ FALSE, 0, NULL);
+
+ if (rc != Success)
+ return 0;
+ return prop_wheel_inertia;
+}
+
+Atom
+EvdevWheelEmuInitPropertyButton(DeviceIntPtr dev, char* name)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ EvdevPtr pEvdev = pInfo->private;
+ int rc = TRUE;
+
+ if (!dev->button) /* don't init prop for keyboards */
+ return 0;
+
+ prop_wheel_button = MakeAtom(name, strlen(name), TRUE);
+ rc = XIChangeDeviceProperty(dev, prop_wheel_button, XA_INTEGER, 8,
+ PropModeReplace, 1,
+ &pEvdev->emulateWheel.button,
+ FALSE, FALSE, FALSE);
+ if (rc != Success)
+ return 0;
+
+ rc = XIConfigureDeviceProperty(dev, prop_wheel_button, FALSE, FALSE,
+ FALSE, 0, NULL);
+
+ if (rc != Success)
+ return 0;
+ return prop_wheel_button;
+}
+
+
+BOOL
+EvdevWheelEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ EvdevPtr pEvdev = pInfo->private;
+
+ if (atom == prop_wheel_emu)
+ {
+ pEvdev->emulateWheel.enabled = *((BOOL*)val->data);
+ /* Don't enable with zero inertia, otherwise we may get stuck in an
+ * infinite loop */
+ if (pEvdev->emulateWheel.inertia <= 0)
+ {
+ pEvdev->emulateWheel.inertia = 10;
+ XIChangeDeviceProperty(dev, prop_wheel_inertia, XA_INTEGER, 16,
+ PropModeReplace, 1,
+ &pEvdev->emulateWheel.inertia,
+ TRUE, FALSE, FALSE);
+ }
+ }
+ else if (atom == prop_wheel_button)
+ {
+ int bt = *((CARD8*)val->data);
+ if (bt < 0 || bt >= MSE_MAXBUTTONS)
+ return FALSE;
+ pEvdev->emulateWheel.button = bt;
+ } else if (atom == prop_wheel_xmap)
+ {
+ if (val->size != 2)
+ return FALSE;
+
+ pEvdev->emulateWheel.X.up_button = *((CARD8*)val->data);
+ pEvdev->emulateWheel.X.down_button = *(((CARD8*)val->data) + 1);
+ } else if (atom == prop_wheel_ymap)
+ {
+ if (val->size != 2)
+ return FALSE;
+
+ pEvdev->emulateWheel.Y.up_button = *((CARD8*)val->data);
+ pEvdev->emulateWheel.Y.down_button = *(((CARD8*)val->data) + 1);
+ } else if (atom == prop_wheel_inertia)
+ {
+ int inertia = *((CARD16*)val->data);
+ if (inertia < 0)
+ return FALSE;
+
+ pEvdev->emulateWheel.inertia = inertia;
+ }
+ return TRUE;
+}
+
+#endif
diff --git a/src/evdev.c b/src/evdev.c
index 5bc562a..540738c 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -106,6 +106,11 @@ typedef struct _PropTable {
static PropTable evdevPropTable[] = {
{ 0, "Middle Button Emulation", EvdevMBEmuInitProperty, EvdevMBEmuSetProperty },
{ 0, "Middle Button Timeout", EvdevMBEmuInitPropertyTimeout, EvdevMBEmuSetProperty},
+ { 0, "Wheel Emulation", EvdevWheelEmuInitProperty, EvdevWheelEmuSetProperty},
+ { 0, "Wheel Emulation X Axis", EvdevWheelEmuInitPropertyXMap, EvdevWheelEmuSetProperty},
+ { 0, "Wheel Emulation Y Axis", EvdevWheelEmuInitPropertyYMap, EvdevWheelEmuSetProperty},
+ { 0, "Wheel Emulation Inertia", EvdevWheelEmuInitPropertyInertia, EvdevWheelEmuSetProperty},
+ { 0, "Wheel Emulation Button", EvdevWheelEmuInitPropertyButton, EvdevWheelEmuSetProperty},
{ 0, NULL, NULL, NULL }
};
diff --git a/src/evdev.h b/src/evdev.h
index 83f03f4..0afa44c 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -102,6 +102,14 @@ unsigned int EvdevUtilButtonEventToButtonNumber(int code);
Atom EvdevMBEmuInitProperty(DeviceIntPtr, char*);
Atom EvdevMBEmuInitPropertyTimeout(DeviceIntPtr, char*);
BOOL EvdevMBEmuSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr);
+
+Atom EvdevWheelEmuInitProperty(DeviceIntPtr, char*);
+Atom EvdevWheelEmuInitPropertyXMap(DeviceIntPtr, char*);
+Atom EvdevWheelEmuInitPropertyYMap(DeviceIntPtr, char*);
+Atom EvdevWheelEmuInitPropertyInertia(DeviceIntPtr, char*);
+Atom EvdevWheelEmuInitPropertyButton(DeviceIntPtr, char*);
+
+BOOL EvdevWheelEmuSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr);
#endif
/* Mouse Wheel emulation */
@@ -109,4 +117,5 @@ void EvdevWheelEmuPreInit(InputInfoPtr pInfo);
BOOL EvdevWheelEmuFilterButton(InputInfoPtr pInfo, unsigned int button, int value);
BOOL EvdevWheelEmuFilterMotion(InputInfoPtr pInfo, struct input_event *pEv);
+
#endif