From 53e7525744cd7c47707c7339f0b771f59f99b97c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 21 Jul 2008 18:15:35 +0930 Subject: Add support for ButtonMapping option. --- man/evdev.man | 11 ++++++++++ src/evdev.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ src/evdev.h | 2 ++ 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/man/evdev.man b/man/evdev.man index f438f78..0a4b71a 100644 --- a/man/evdev.man +++ b/man/evdev.man @@ -67,6 +67,17 @@ button event is registered. Sets the timeout (in milliseconds) that the driver waits before deciding if two buttons where pressed "simultaneously" when 3 button emulation is enabled. Default: 50. +.TP 7 +.BI "Option \*qButtonMapping\*q \*q" string \*q +Sets the button mapping for this device. The mapping is a space-separated list +of button mappings that correspond in order to the physical buttons on the +device (i.e. the first number is the mapping for button 1, etc.). The default +mapping is "1 2 3 ... 32". A mapping of 0 deactivates the button. Multiple +buttons can have the same mapping. +For example, a left-handed mouse with deactivated scroll-wheel would use a +mapping of "3 2 1 0 0". Invalid mappings are ignored and the default mapping +is used. Buttons not specified in the user's mapping use the default mapping. + .SH AUTHORS Kristian Høgsberg. .SH "SEE ALSO" diff --git a/src/evdev.c b/src/evdev.c index 5c236b0..f831081 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -811,22 +811,72 @@ EvdevAddRelClass(DeviceIntPtr device) static int EvdevAddButtonClass(DeviceIntPtr device) { - CARD8 map[32]; InputInfoPtr pInfo; - int i; + EvdevPtr pEvdev; pInfo = device->public.devicePrivate; + pEvdev = pInfo->private; /* FIXME: count number of actual buttons */ - for (i = 0; i < ArrayLength(map); i++) - map[i] = i; - - if (!InitButtonClassDeviceStruct(device, ArrayLength(map), map)) + if (!InitButtonClassDeviceStruct(device, ArrayLength(pEvdev->btnmap), + pEvdev->btnmap)) return !Success; return Success; } +/** + * Init the button mapping for the device. By default, this is a 1:1 mapping, + * i.e. Button 1 maps to Button 1, Button 2 to 2, etc. + * + * If a mapping has been specified, the mapping is the default, with the + * user-defined ones overwriting the defaults. + * i.e. a user-defined mapping of "3 2 1" results in a mapping of 3 2 1 4 5 6 ... + * + * Invalid button mappings revert to the default. + * + * Note that index 0 is unused, button 0 does not exist. + * This mapping is initialised for all devices, but only applied if the device + * has buttons (in EvdevAddButtonClass). + */ +static void +EvdevInitButtonMapping(InputInfoPtr pInfo) +{ + int i, nbuttons = 1; + char *mapping = NULL; + EvdevPtr pEvdev = pInfo->private; + + /* Check for user-defined button mapping */ + if ((mapping = xf86CheckStrOption(pInfo->options, "ButtonMapping", NULL))) + { + char *s = " "; + int btn = 0; + + xf86Msg(X_CONFIG, "%s: ButtonMapping '%s'\n", pInfo->name, mapping); + while (s && *s != '\0' && nbuttons < 32) + { + btn = strtol(mapping, &s, 10); + + if (s == mapping || btn < 0 || btn > 32) + { + xf86Msg(X_ERROR, + "%s: ... Invalid button mapping. Using defaults\n", + pInfo->name); + nbuttons = 1; /* ensure defaults start at 1 */ + break; + } + + pEvdev->btnmap[nbuttons++] = btn; + mapping = s; + } + } + + for (i = nbuttons; i < ArrayLength(pEvdev->btnmap); i++) + pEvdev->btnmap[i] = i; + +} + + #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 3 static void EvdevInitProperties(DeviceIntPtr device) @@ -1104,6 +1154,8 @@ EvdevPreInit(InputDriverPtr drv, IDevPtr dev, int flags) return NULL; } + EvdevInitButtonMapping(pInfo); + pEvdev->noXkb = noXkbExtension; /* parse the XKB options during kbd setup */ diff --git a/src/evdev.h b/src/evdev.h index c415bd1..bc79287 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -68,6 +68,8 @@ typedef struct { Time expires; /* time of expiry */ Time timeout; } emulateMB; + + unsigned char btnmap[32]; /* config-file specified button mapping */ } EvdevRec, *EvdevPtr; /* Middle Button emulation */ -- cgit v1.2.3