From d1818ef2066d7e526e0f64fffd41e06061ceb017 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 8 Jul 2008 16:37:42 +0930 Subject: Add support for device properties, currently MB emulation and timeout. --- src/emuMB.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/evdev.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/evdev.h | 5 +++++ 3 files changed, 143 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/emuMB.c b/src/emuMB.c index 99a09f2..c2f4327 100644 --- a/src/emuMB.c +++ b/src/emuMB.c @@ -34,7 +34,10 @@ #include "config.h" #endif +#include #include +#include +#include #include "evdev.h" @@ -44,6 +47,9 @@ enum { MBEMU_AUTO }; +static Atom prop_mbemu = 0; /* Middle button emulation on/off property */ +static Atom prop_mbtimeout = 0; /* Middle button timeout property */ + /* * Lets create a simple finite-state machine for 3 button emulation: * @@ -313,6 +319,12 @@ EvdevMBEmuPreInit(InputInfoPtr pInfo) EvdevMBEmuWakeupHandler, (pointer)pInfo); + XIChangeDeviceProperty(pInfo->dev, prop_mbemu, XA_INTEGER, 8, + PropModeReplace, 1, &pEvdev->emulateMB.enabled, + TRUE, FALSE, FALSE); + XIChangeDeviceProperty(pInfo->dev, prop_mbtimeout, XA_INTEGER, 16, + PropModeReplace, 1, &pEvdev->emulateMB.timeout, + TRUE, FALSE, FALSE); } void @@ -332,3 +344,63 @@ EvdevMBEmuEnable(InputInfoPtr pInfo, BOOL enable) if (pEvdev->emulateMB.enabled == MBEMU_AUTO) pEvdev->emulateMB.enabled = enable; } + + +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 +Atom +EvdevMBEmuInitProperty(DeviceIntPtr dev, char* name) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + EvdevPtr pEvdev = pInfo->private; + int rc = TRUE; + INT32 valid_vals[] = { MBEMU_DISABLED, MBEMU_ENABLED, MBEMU_AUTO }; + + if (!dev->button) /* don't init prop for keyboards */ + return 0; + + prop_mbemu = MakeAtom(name, strlen(name), TRUE); + rc = XIChangeDeviceProperty(dev, prop_mbemu, XA_INTEGER, 8, + PropModeReplace, 1, + &pEvdev->emulateMB.enabled, + FALSE, FALSE, FALSE); + if (rc != Success) + return 0; + + rc = XIConfigureDeviceProperty(dev, prop_mbemu, FALSE, FALSE, FALSE, 3, valid_vals); + + if (rc != Success) + return 0; + return prop_mbemu; +} + +Atom +EvdevMBEmuInitPropertyTimeout(DeviceIntPtr dev, char *name) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + EvdevPtr pEvdev = pInfo->private; + int rc = TRUE; + + prop_mbtimeout = MakeAtom(name, strlen(name), TRUE); + rc = XIChangeDeviceProperty(dev, prop_mbtimeout, XA_INTEGER, 16, PropModeReplace, 1, + &pEvdev->emulateMB.timeout, FALSE, FALSE, + FALSE); + + if (rc != Success) + return 0; + return prop_mbtimeout; +} + +BOOL +EvdevMBEmuSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + EvdevPtr pEvdev = pInfo->private; + + if (atom == prop_mbemu) + pEvdev->emulateMB.enabled = *((BOOL*)val->data); + else if (atom == prop_mbtimeout) + pEvdev->emulateMB.timeout = *((INT16*)val->data); + + return TRUE; +} +#endif diff --git a/src/evdev.c b/src/evdev.c index a51757e..311f678 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -87,7 +87,6 @@ #define MODEFLAG 8 #define COMPOSEFLAG 16 - static const char *evdevDefaults[] = { "XkbRules", "base", "XkbModel", "evdev", @@ -95,6 +94,22 @@ static const char *evdevDefaults[] = { NULL }; +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 +typedef struct _PropTable { + Atom prop; + char *prop_name; + Atom (*init)(DeviceIntPtr dev, char* name); + BOOL (*handler)(DeviceIntPtr dev, Atom prop, XIPropertyValuePtr val); +} PropTable, *PropTableEntryPtr; + +static PropTable evdevPropTable[] = { + { 0, "Middle Button Emulation", EvdevMBEmuInitProperty, EvdevMBEmuSetProperty }, + { 0, "Middle Button Timeout", EvdevMBEmuInitPropertyTimeout, EvdevMBEmuSetProperty}, + { 0, NULL, NULL, NULL } +}; + +#endif + static void SetXkbOption(InputInfoPtr pInfo, char *name, char **option) { @@ -143,6 +158,31 @@ PostKbdEvent(InputInfoPtr pInfo, struct input_event *ev, int value) xf86PostKeyboardEvent(pInfo->dev, ev->code + MIN_KEYCODE, value); } +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 +static Bool +EvdevSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr val) +{ + PropTableEntryPtr entry = evdevPropTable; + + while (entry && entry->prop_name) + { + if (entry->prop == property) + return entry->handler(dev, property, val); + entry++; + } + + /* property not handled, report success */ + return TRUE; +} + +static Bool EvdevGetProperty(DeviceIntPtr dev, + Atom property) +{ + /* XXX */ + return TRUE; +} +#endif + static void EvdevReadInput(InputInfoPtr pInfo) { @@ -786,6 +826,22 @@ EvdevAddButtonClass(DeviceIntPtr device) return Success; } +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 +static void +EvdevInitProperties(DeviceIntPtr device) +{ + PropTableEntryPtr entry; + + entry = evdevPropTable; + while(entry && entry->prop_name) + { + entry->prop = (*entry->init)(device, entry->prop_name); + entry++; + } + +} +#endif + static int EvdevInit(DeviceIntPtr device) { @@ -815,6 +871,14 @@ EvdevInit(DeviceIntPtr device) else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) EvdevAddAbsClass(device); +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 + /* We drop the return value, the only time we ever want the handlers to + * unregister is when the device dies. In which case we don't have to + * unregister anyway */ + XIRegisterPropertyHandler(device, EvdevSetProperty, EvdevGetProperty); + EvdevInitProperties(device); +#endif + return Success; } @@ -971,6 +1035,7 @@ EvdevProbe(InputInfoPtr pInfo) return 0; } + static InputInfoPtr EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags) { diff --git a/src/evdev.h b/src/evdev.h index c6a6e99..c415bd1 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -78,5 +78,10 @@ void EvdevMBEmuBlockHandler(pointer, struct timeval**, pointer); void EvdevMBEmuPreInit(InputInfoPtr); void EvdevMBEmuFinalize(InputInfoPtr); void EvdevMBEmuEnable(InputInfoPtr, BOOL); +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 +Atom EvdevMBEmuInitProperty(DeviceIntPtr, char*); +Atom EvdevMBEmuInitPropertyTimeout(DeviceIntPtr, char*); +BOOL EvdevMBEmuSetProperty(DeviceIntPtr, Atom, XIPropertyValuePtr); +#endif #endif -- cgit v1.2.3