From eb9554185229cf56771c874d56627fd6316c2f86 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 31 Aug 2009 10:29:11 +1000 Subject: [PATCH] input: provide "Button mapping" DIX property. This patch adds a new server-supported property: "Button Mapping". This property represents the current button mapping of the device, with each value representing the logical button for a given physical button. The values start with the mapping for button 1. The property is connected to the core protocol's SetPointerMapping and the XI's SetDeviceButtonMapping requests, changing the button through either of the requests changes the property as well. If the property is changed, a MappingNotify is sent. New control flow is: - RequestHandler -> ApplyPointerMapping -> XIChangeDeviceProperty -> Check values for validity -> ApplyButtonMap -> send mapping notify event Signed-off-by: Peter Hutterer --- Xi/xiproperty.c | 4 ++- dix/devices.c | 37 ++++++++++++++++++++++ dix/inpututils.c | 69 ++++++++++++++++++----------------------- include/input.h | 5 +++ include/xserver-properties.h | 5 +++ 5 files changed, 80 insertions(+), 40 deletions(-) diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c index 024dc44..742a0d5 100644 --- a/Xi/xiproperty.c +++ b/Xi/xiproperty.c @@ -166,7 +166,9 @@ static struct dev_properties {0, BTN_LABEL_PROP_BTN_TOOL_TRIPLETAP}, {0, BTN_LABEL_PROP_BTN_GEAR_DOWN}, - {0, BTN_LABEL_PROP_BTN_GEAR_UP} + {0, BTN_LABEL_PROP_BTN_GEAR_UP}, + + {0, XI_PROP_BUTTONMAPPING} }; static long XIPropHandlerID = 1; diff --git a/dix/devices.c b/dix/devices.c index 0be3d58..13f928f 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -122,6 +122,29 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, else if (!(*((CARD8*)prop->data)) && dev->enabled) DisableDevice(dev, TRUE); } + } else if (property == XIGetKnownProperty(XI_PROP_BUTTONMAPPING)) + { + CARD8 *mapping; + + if (prop->format != 8 || prop->type != XA_INTEGER) + return BadMatch; + /* we expect a zero-indexed map, even though the button 0 doesn't + * exist. hence numButtons + 1 */ + if (!dev->button || dev->button->numButtons != prop->size) + return BadValue; + + mapping = (CARD8*)prop->data; + + if (checkonly) { + int i; + + for (i = 0; i < prop->size; i++) { + if (dev->button->map[i + 1] != mapping[i] && + dev->button->down[i + 1]) + return BadAccess; + } + } else + ApplyButtonMap(dev, mapping, prop->size); } return Success; @@ -350,6 +373,20 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); + /* Properties only for pointer devices */ + if (dev->button) + { + int ret; + Atom prop; + + prop = XIGetKnownProperty(XI_PROP_BUTTONMAPPING); + ret = XIChangeDeviceProperty(dev, prop, XA_INTEGER, 8, PropModeReplace, + dev->button->numButtons, + &dev->button->map[1], + FALSE); + XISetDevicePropertyDeletable(dev, prop, FALSE); + } + SendDevicePresenceEvent(dev->id, DeviceEnabled); if (sendevent) { diff --git a/dix/inpututils.c b/dix/inpututils.c index 4848c1b..d88316d 100644 --- a/dix/inpututils.c +++ b/dix/inpututils.c @@ -35,46 +35,17 @@ #include "xace.h" #include "xkbsrv.h" #include "xkbstr.h" +#include "xserver-properties.h" +#include -/* Check if a button map change is okay with the device. - * Returns -1 for BadValue, as it collides with MappingBusy. */ -static int -check_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, CARD32 *errval_out, - ClientPtr client) -{ - int i, ret; - - if (!dev || !dev->button) - { - client->errorValue = (dev) ? dev->id : 0; - return BadDevice; - } - - ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); - if (ret != Success) - { - client->errorValue = dev->id; - return ret; - } - - for (i = 0; i < len; i++) { - if (dev->button->map[i + 1] != map[i] && dev->button->down[i + 1]) - return MappingBusy; - } - - return Success; -} - -static void -do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) +void +ApplyButtonMap(DeviceIntPtr dev, CARD8 *map, int len) { int i; xEvent core_mn; deviceMappingNotify xi_mn; - /* The map in ButtonClassRec refers to button numbers, whereas the - * protocol is zero-indexed. Sigh. */ - memcpy(&(dev->button->map[1]), map, len); + memcpy(&dev->button->map[1], map, len); core_mn.u.u.type = MappingNotify; core_mn.u.mappingNotify.request = MappingPointer; @@ -110,15 +81,35 @@ do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) int ApplyPointerMapping(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) { - int ret; + int ret = Success; + CARD8 buttonmap[MAP_LENGTH - 1]; - /* If we can't perform the change on the requested device, bail out. */ - ret = check_butmap_change(dev, map, len, &client->errorValue, client); + if (!dev || !dev->button) + { + client->errorValue = (dev) ? dev->id : 0; + return BadDevice; + } + + ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); if (ret != Success) + { + client->errorValue = dev->id; return ret; - do_butmap_change(dev, map, len, client); + } - return Success; + /* The map in ButtonClassRec refers to button numbers, whereas the + * protocol+property are zero-indexed */ + memcpy(buttonmap, &dev->button->map[1], sizeof(buttonmap)); + memcpy(buttonmap, map, len); + + ret = XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_BUTTONMAPPING), + XA_INTEGER, 8, PropModeReplace, + dev->button->numButtons, buttonmap, + TRUE); + if (ret == BadAccess) + ret = MappingBusy; + + return ret; } /* Check if a modifier map change is okay with the device. diff --git a/include/input.h b/include/input.h index 7ab5e9d..371527f 100644 --- a/include/input.h +++ b/include/input.h @@ -365,6 +365,11 @@ extern _X_EXPORT Bool InitKeyboardDeviceStruct( BellProcPtr /*bellProc*/, KbdCtrlProcPtr /*controlProc*/); +extern void ApplyButtonMap( + DeviceIntPtr /* dev */, + CARD8 * /* map */, + int /* len */); + extern int ApplyPointerMapping( DeviceIntPtr /* pDev */, CARD8 * /* map */, diff --git a/include/xserver-properties.h b/include/xserver-properties.h index 626d0ad..ef395f2 100644 --- a/include/xserver-properties.h +++ b/include/xserver-properties.h @@ -34,6 +34,11 @@ #define XI_PROP_ENABLED "Device Enabled" /* BOOL. If present, device is a virtual XTEST device */ #define XI_PROP_XTEST_DEVICE "XTEST Device" +/* Button mapping */ +/* CARD8. number of buttons on the device. 0 disables a button. + * BadValue if property is invalid. + * BadAccess if property cannot be changed right now. */ +#define XI_PROP_BUTTONMAPPING "Button Mapping" /* Pointer acceleration properties */ /* INTEGER of any format */ -- 1.6.3.rc1.2.g0164.dirty