diff --git a/man/libinput.man b/man/libinput.man index c5eaea5..df202a9 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 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. +.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, @@ -1263,6 +1265,41 @@ xf86libinput_parse_middleemulation_option(InputInfoPtr pInfo, return enabled; } +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, @@ -1270,6 +1307,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo, { 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