Expose wheel emulation through device properties.

Don't enable wheel emulation with 0 inertia - bad things happen.
This commit is contained in:
Peter Hutterer
2008-08-07 16:53:51 +09:30
committed by Peter Hutterer
parent a9d72b40fb
commit 9793de8137
3 changed files with 245 additions and 0 deletions

View File

@@ -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

View File

@@ -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 }
};

View File

@@ -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