summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/evdev.man11
-rw-r--r--src/evdev.c64
-rw-r--r--src/evdev.h2
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 */