[PATCH xf86-input-libinput] Add support for configurable tap button mapping

Peter Hutterer peter.hutterer at who-t.net
Mon Aug 15 23:58:58 UTC 2016


Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 include/libinput-properties.h |   7 ++
 man/libinput.man              |   8 +++
 src/xf86libinput.c            | 144 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 159 insertions(+)

diff --git a/include/libinput-properties.h b/include/libinput-properties.h
index 7335c3f..695f15d 100644
--- a/include/libinput-properties.h
+++ b/include/libinput-properties.h
@@ -42,6 +42,13 @@
 /* Tap drag lock default enabled/disabled: BOOL, 1 value, read-only */
 #define LIBINPUT_PROP_TAP_DRAG_LOCK_DEFAULT "libinput Tapping Drag Lock Enabled Default"
 
+/* Tap button order: BOOL, 2 values in order LRM, LMR, only one may be set
+   at any time */
+#define LIBINPUT_PROP_TAP_BUTTONMAP "libinput Tapping Button Mapping Enabled"
+
+/* Tap button default order: BOOL, 2 values in order LRM, LMR, read-only */
+#define LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT "libinput Tapping Button Mapping Default"
+
 /* Calibration matrix: FLOAT, 9 values of a 3x3 matrix, in rows */
 #define LIBINPUT_PROP_CALIBRATION "libinput Calibration Matrix"
 
diff --git a/man/libinput.man b/man/libinput.man
index a11e21f..72486a1 100644
--- a/man/libinput.man
+++ b/man/libinput.man
@@ -129,6 +129,10 @@ mouse is connected".
 .BI "Option \*qTapping\*q \*q" bool \*q
 Enables or disables tap-to-click behavior.
 .TP 7
+.BI "Option \*qTappingButtonMap\*q \*q" (lrm|lmr) \*q
+Set the button mapping for 1/2/3-finger taps to left/right/middle or
+left/middle/right, respectively.
+.TP 7
 .BI "Option \*qTappingDrag\*q \*q" bool \*q
 Enables or disables drag during tapping behavior ("tap-and-drag"). When
 enabled, a tap followed by a finger held down causes a single button down
@@ -184,6 +188,10 @@ driver.
 .BI "libinput Tapping Enabled"
 1 boolean value (8 bit, 0 or 1). 1 enables tapping
 .TP 7
+.BI "libinput Tapping Button Mapping Enabled"
+2 boolean value (8 bit, 0 or 1), in order "lrm" and "lmr". Indicates which
+button mapping is currently enabled on this device.
+.TP 7
 .BI "libinput Tapping Drag Lock Enabled"
 1 boolean value (8 bit, 0 or 1). 1 enables drag lock during tapping
 .TP 7
diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index 1ecbc41..64709fc 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -135,6 +135,7 @@ struct xf86libinput {
 		BOOL tapping;
 		BOOL tap_drag;
 		BOOL tap_drag_lock;
+		enum libinput_config_tap_button_map tap_button_map;
 		BOOL natural_scrolling;
 		BOOL left_handed;
 		BOOL middle_emulation;
@@ -432,6 +433,21 @@ LibinputApplyConfig(DeviceIntPtr dev)
 			    driver_data->options.tapping);
 
 	if (libinput_device_config_tap_get_finger_count(device) > 0 &&
+	    libinput_device_config_tap_set_button_map(device,
+						      driver_data->options.tap_button_map) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
+		const char *map;
+
+		switch(driver_data->options.tap_button_map) {
+		case LIBINPUT_CONFIG_TAP_MAP_LRM: map = "lrm"; break;
+		case LIBINPUT_CONFIG_TAP_MAP_LMR: map = "lmr"; break;
+		default: map = "unknown"; break;
+		}
+		xf86IDrvMsg(pInfo, X_ERROR,
+			    "Failed to set Tapping ButtonMap to %s\n",
+			    map);
+	}
+
+	if (libinput_device_config_tap_get_finger_count(device) > 0 &&
 	    libinput_device_config_tap_set_drag_lock_enabled(device,
 							     driver_data->options.tap_drag_lock) != LIBINPUT_CONFIG_STATUS_SUCCESS)
 		xf86IDrvMsg(pInfo, X_ERROR,
@@ -1933,6 +1949,43 @@ xf86libinput_parse_tap_drag_lock_option(InputInfoPtr pInfo,
 	return drag_lock;
 }
 
+static inline enum libinput_config_tap_button_map
+xf86libinput_parse_tap_buttonmap_option(InputInfoPtr pInfo,
+					struct libinput_device *device)
+{
+	enum libinput_config_tap_button_map map;
+	char *str;
+
+	if (libinput_device_config_tap_get_finger_count(device) == 0)
+		return FALSE;
+
+	map = libinput_device_config_tap_get_button_map(device);
+	str = xf86SetStrOption(pInfo->options,
+			       "TappingButtonMap",
+			       NULL);
+	if (str) {
+		if (strcmp(str, "lmr") == 0)
+			map = LIBINPUT_CONFIG_TAP_MAP_LMR;
+		else if (strcmp(str, "lrm") == 0)
+			map = LIBINPUT_CONFIG_TAP_MAP_LRM;
+		else
+			xf86IDrvMsg(pInfo, X_ERROR,
+				    "Invalid TapButtonMap: %s\n",
+				    str);
+		free(str);
+	}
+
+	if (libinput_device_config_send_events_set_mode(device, map) !=
+	    LIBINPUT_CONFIG_STATUS_SUCCESS) {
+		xf86IDrvMsg(pInfo, X_ERROR,
+			    "Failed to set Tapping Drag Lock to %d\n",
+			    map);
+		map = libinput_device_config_tap_get_button_map(device);
+	}
+
+	return map;
+}
+
 static inline double
 xf86libinput_parse_accel_option(InputInfoPtr pInfo,
 				struct libinput_device *device)
@@ -2318,6 +2371,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
 	options->tapping = xf86libinput_parse_tap_option(pInfo, device);
 	options->tap_drag = xf86libinput_parse_tap_drag_option(pInfo, device);
 	options->tap_drag_lock = xf86libinput_parse_tap_drag_lock_option(pInfo, device);
+	options->tap_button_map = xf86libinput_parse_tap_buttonmap_option(pInfo, device);
 	options->speed = xf86libinput_parse_accel_option(pInfo, device);
 	options->accel_profile = xf86libinput_parse_accel_profile_option(pInfo, device);
 	options->natural_scrolling = xf86libinput_parse_natscroll_option(pInfo, device);
@@ -2747,6 +2801,8 @@ static Atom prop_tap_drag;
 static Atom prop_tap_drag_default;
 static Atom prop_tap_drag_lock;
 static Atom prop_tap_drag_lock_default;
+static Atom prop_tap_buttonmap;
+static Atom prop_tap_buttonmap_default;
 static Atom prop_calibration;
 static Atom prop_calibration_default;
 static Atom prop_accel;
@@ -2948,6 +3004,39 @@ LibinputSetPropertyTapDragLock(DeviceIntPtr dev,
 }
 
 static inline int
+LibinputSetPropertyTapButtonmap(DeviceIntPtr dev,
+				Atom atom,
+				XIPropertyValuePtr val,
+				BOOL checkonly)
+{
+	InputInfoPtr pInfo = dev->public.devicePrivate;
+	struct xf86libinput *driver_data = pInfo->private;
+	BOOL* data;
+	enum libinput_config_tap_button_map map;
+
+	if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER)
+		return BadMatch;
+
+	data = (BOOL*)val->data;
+
+	if (checkonly &&
+	    ((data[0] && data[1]) || (!data[0] && !data[1])))
+		return BadValue;
+
+	if (data[0])
+		map = LIBINPUT_CONFIG_TAP_MAP_LRM;
+	else if (data[1])
+		map = LIBINPUT_CONFIG_TAP_MAP_LMR;
+	else
+		return BadValue;
+
+	if (!checkonly)
+		driver_data->options.tap_button_map = map;
+
+	return Success;
+}
+
+static inline int
 LibinputSetPropertyCalibration(DeviceIntPtr dev,
                                Atom atom,
                                XIPropertyValuePtr val,
@@ -3458,6 +3547,8 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
 		rc = LibinputSetPropertyTapDrag(dev, atom, val, checkonly);
 	else if (atom == prop_tap_drag_lock)
 		rc = LibinputSetPropertyTapDragLock(dev, atom, val, checkonly);
+	else if (atom == prop_tap_buttonmap)
+		rc = LibinputSetPropertyTapButtonmap(dev, atom, val, checkonly);
 	else if (atom == prop_calibration)
 		rc = LibinputSetPropertyCalibration(dev, atom, val,
 						    checkonly);
@@ -3498,6 +3589,7 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
 		 atom == prop_tap_default ||
 		 atom == prop_tap_drag_default ||
 		 atom == prop_tap_drag_lock_default ||
+		 atom == prop_tap_buttonmap_default ||
 		 atom == prop_calibration_default ||
 		 atom == prop_accel_default ||
 		 atom == prop_accel_profile_default ||
@@ -3623,6 +3715,57 @@ LibinputInitTapDragLockProperty(DeviceIntPtr dev,
 }
 
 static void
+LibinputInitTapButtonmapProperty(DeviceIntPtr dev,
+				 struct xf86libinput *driver_data,
+				 struct libinput_device *device)
+{
+	enum libinput_config_tap_button_map map;
+	BOOL data[2] = {0};
+
+	map = driver_data->options.tap_button_map;
+
+	if (libinput_device_config_tap_get_finger_count(device) == 0)
+		return;
+
+	switch (map) {
+	case LIBINPUT_CONFIG_TAP_MAP_LRM:
+		data[0] = 1;
+		break;
+	case LIBINPUT_CONFIG_TAP_MAP_LMR:
+		data[1] = 1;
+		break;
+	default:
+		break;
+	}
+
+	prop_tap_buttonmap = LibinputMakeProperty(dev,
+						  LIBINPUT_PROP_TAP_BUTTONMAP,
+						  XA_INTEGER, 8,
+						  2, data);
+	if (!prop_tap_buttonmap)
+		return;
+
+	map = libinput_device_config_tap_get_default_button_map(device);
+	memset(data, 0, sizeof(data));
+
+	switch (map) {
+	case LIBINPUT_CONFIG_TAP_MAP_LRM:
+		data[0] = 1;
+		break;
+	case LIBINPUT_CONFIG_TAP_MAP_LMR:
+		data[1] = 1;
+		break;
+	default:
+		break;
+	}
+
+	prop_tap_buttonmap_default = LibinputMakeProperty(dev,
+							  LIBINPUT_PROP_TAP_BUTTONMAP_DEFAULT,
+							  XA_INTEGER, 8,
+							  2, data);
+}
+
+static void
 LibinputInitCalibrationProperty(DeviceIntPtr dev,
 				struct xf86libinput *driver_data,
 				struct libinput_device *device)
@@ -4247,6 +4390,7 @@ LibinputInitProperty(DeviceIntPtr dev)
 	LibinputInitTapProperty(dev, driver_data, device);
 	LibinputInitTapDragProperty(dev, driver_data, device);
 	LibinputInitTapDragLockProperty(dev, driver_data, device);
+	LibinputInitTapButtonmapProperty(dev, driver_data, device);
 	LibinputInitCalibrationProperty(dev, driver_data, device);
 	LibinputInitAccelProperty(dev, driver_data, device);
 	LibinputInitNaturalScrollProperty(dev, driver_data, device);
-- 
2.7.4



More information about the xorg-devel mailing list