[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