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

Hans de Goede hdegoede at redhat.com
Tue Aug 16 08:48:40 UTC 2016


Hi,

On 16-08-16 01:58, Peter Hutterer wrote:
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

Patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede at redhat.com>

Regards,

Hans


> ---
>  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);
>


More information about the xorg-devel mailing list