[PATCH xf86-input-libinput 4/4] Add option "ButtonMapping" (#9206)

Peter Hutterer peter.hutterer at who-t.net
Tue Apr 28 16:51:29 PDT 2015


With a long entry in the man page to detail what this option does.
Specifically, it's the xorg.conf equivalent to XSetPointerMapping(3), it
doesn't do any physical button remappings, merely the logical ones. If the
physical button isn't mapped to the right logical button by default, that's
either a libiput bug or an xkcd 1172 issue.

X.Org Bug 9206 <http://bugs.freedesktop.org/show_bug.cgi?id=9206>

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 man/libinput.man | 38 +++++++++++++++++++++++++++++++++++++
 src/libinput.c   | 57 +++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/man/libinput.man b/man/libinput.man
index c5eaea5..3b2697e 100644
--- a/man/libinput.man
+++ b/man/libinput.man
@@ -50,6 +50,19 @@ The mapping from device node to hardware is system-dependent. Property:
 .BI "Option \*qAccelSpeed\*q \*q" float \*q
 Sets the pointer acceleration speed within the range [-1, 1]
 .TP 7
+.BI "Option \*qButtonMapping\*q \*q" string \*q
+Sets the logical button mapping for this device, see
+XSetPointerMapping(__libmansuffix__). The string must be a
+space-separated list of button mappings in the order of the
+logical buttons on the device, starting with button 1.
+The default mapping is "1 2 3 ... 32". A mapping of 0
+deactivates the button. Multiple buttons can have the same mapping.
+Invalid mapping strings are discarded and the default mapping
+is used for all buttons. Buttons not specified in the user's mapping use the
+default mapping. See section
+.B BUTTON MAPPING
+for more details.
+.TP 7
 .BI "Option \*qCalibrationMatrix\*q \*q" string \*q
 A string of 9 space-separated floating point numbers.
 Sets the calibration matrix to the 3x3 matrix where the first row is (abc),
@@ -167,6 +180,31 @@ The above properties have a
 .BI "libinput <property name> Default"
 equivalent that indicates the default value for this setting on this device.
 
+.SH BUTTON MAPPING
+X clients receive events with logical button numbers, where 1, 2, 3
+are usually interpreted as left, middle, right and logical buttons 4, 5, 6,
+7 are usually interpreted as scroll up, down, left, right. The fourth and
+fifth physical buttons on a device will thus send logical buttons 8 and 9.
+The
+.B ButtonMapping
+option adjusts the logical button mapping, it does not affect how a physical
+button is mapped to a logical button.
+.PP
+Traditionally, a device was set to left-handed button mode by applying a
+button mapping of
+.B "\*q3 2 1 ...\*q"
+On systems using the
+.B libinput
+__xservername__ input driver it is recommended to use the
+.B LeftHanded
+option instead. Adjusting the
+.PP
+The
+.B libinput
+__xservername__ input driver does not use the button mapping after setup.
+Use XSetPointerMapping(__libmansuffix__) to modify the button mapping at
+runtime.
+
 .SH AUTHORS
 Peter Hutterer
 .SH "SEE ALSO"
diff --git a/src/libinput.c b/src/libinput.c
index 2db62ba..c7ab18c 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -96,6 +96,8 @@ struct xf86libinput {
 		float matrix[9];
 		enum libinput_config_scroll_method scroll_method;
 		enum libinput_config_click_method click_method;
+
+		unsigned char btnmap[MAX_BUTTONS + 1];
 	} options;
 };
 
@@ -440,7 +442,6 @@ xf86libinput_init_pointer(InputInfoPtr pInfo)
 	int nbuttons = 7;
 	int i;
 
-	unsigned char btnmap[MAX_BUTTONS + 1];
 	Atom btnlabels[MAX_BUTTONS];
 	Atom axislabels[TOUCHPAD_NUM_AXES];
 
@@ -451,11 +452,11 @@ xf86libinput_init_pointer(InputInfoPtr pInfo)
 		}
 	}
 
-	init_button_map(btnmap, ARRAY_SIZE(btnmap));
 	init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
 	init_axis_labels(axislabels, ARRAY_SIZE(axislabels));
 
-	InitPointerDeviceStruct((DevicePtr)dev, btnmap,
+	InitPointerDeviceStruct((DevicePtr)dev,
+				driver_data->options.btnmap,
 				nbuttons,
 				btnlabels,
 				xf86libinput_ptr_ctl,
@@ -488,7 +489,6 @@ xf86libinput_init_pointer_absolute(InputInfoPtr pInfo)
 	int nbuttons = 7;
 	int i;
 
-	unsigned char btnmap[MAX_BUTTONS + 1];
 	Atom btnlabels[MAX_BUTTONS];
 	Atom axislabels[TOUCHPAD_NUM_AXES];
 
@@ -499,11 +499,11 @@ xf86libinput_init_pointer_absolute(InputInfoPtr pInfo)
 		}
 	}
 
-	init_button_map(btnmap, ARRAY_SIZE(btnmap));
 	init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
 	init_axis_labels(axislabels, ARRAY_SIZE(axislabels));
 
-	InitPointerDeviceStruct((DevicePtr)dev, btnmap,
+	InitPointerDeviceStruct((DevicePtr)dev,
+				driver_data->options.btnmap,
 				nbuttons,
 				btnlabels,
 				xf86libinput_ptr_ctl,
@@ -589,6 +589,7 @@ static void
 xf86libinput_init_touch(InputInfoPtr pInfo)
 {
 	DeviceIntPtr dev = pInfo->dev;
+	struct xf86libinput *driver_data = pInfo->private;
 	int min, max, res;
 	unsigned char btnmap[MAX_BUTTONS + 1];
 	Atom btnlabels[MAX_BUTTONS];
@@ -599,7 +600,8 @@ xf86libinput_init_touch(InputInfoPtr pInfo)
 	init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
 	init_axis_labels(axislabels, ARRAY_SIZE(axislabels));
 
-	InitPointerDeviceStruct((DevicePtr)dev, btnmap,
+	InitPointerDeviceStruct((DevicePtr)dev,
+				driver_data->options.btnmap,
 				nbuttons,
 				btnlabels,
 				xf86libinput_ptr_ctl,
@@ -1264,12 +1266,48 @@ xf86libinput_parse_middleemulation_option(InputInfoPtr pInfo,
 }
 
 static void
+xf86libinput_parse_buttonmap_option(InputInfoPtr pInfo,
+				    unsigned char *btnmap,
+				    size_t size)
+{
+	const int MAXBUTTONS = 32;
+	char *mapping, *map, *s = NULL;
+	int idx = 1;
+
+	init_button_map(btnmap, size);
+
+	mapping = xf86SetStrOption(pInfo->options, "ButtonMapping", NULL);
+	if (!mapping)
+		return;
+
+	map = mapping;
+	do
+	{
+		unsigned long int btn = strtoul(map, &s, 10);
+
+		if (s == map || btn > MAXBUTTONS)
+		{
+			xf86IDrvMsg(pInfo, X_ERROR,
+				    "... Invalid button mapping. Using defaults\n");
+			init_button_map(btnmap, size);
+			break;
+		}
+
+		btnmap[idx++] = btn;
+		map = s;
+	} while (s && *s != '\0' && idx < MAXBUTTONS);
+
+	free(mapping);
+}
+
+static void
 xf86libinput_parse_options(InputInfoPtr pInfo,
 			   struct xf86libinput *driver_data,
 			   struct libinput_device *device)
 {
 	struct options *options = &driver_data->options;
 
+	/* libinput options */
 	options->tapping = xf86libinput_parse_tap_option(pInfo, device);
 	options->speed = xf86libinput_parse_accel_option(pInfo, device);
 	options->natural_scrolling = xf86libinput_parse_natscroll_option(pInfo, device);
@@ -1280,6 +1318,11 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
 	options->click_method = xf86libinput_parse_clickmethod_option(pInfo, device);
 	options->middle_emulation = xf86libinput_parse_middleemulation_option(pInfo, device);
 	xf86libinput_parse_calibration_option(pInfo, device, driver_data->options.matrix);
+
+	/* non-libinput options */
+	xf86libinput_parse_buttonmap_option(pInfo,
+					    options->btnmap,
+					    sizeof(options->btnmap));
 }
 
 static int
-- 
2.3.5



More information about the xorg-devel mailing list