X.Org Bug 89332 <http://bugs.freedesktop.org/show_bug.cgi?id=89332>
Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> --- include/libinput-properties.h | 8 +++ man/libinput.man | 8 +++ src/libinput.c | 160 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) diff --git a/include/libinput-properties.h b/include/libinput-properties.h index bbc85d0..1d7b416 100644 --- a/include/libinput-properties.h +++ b/include/libinput-properties.h @@ -58,4 +58,12 @@ /* Scroll button for button scrolling: 32-bit int, 1 value */ #define LIBINPUT_PROP_SCROLL_BUTTON "libinput Button Scrolling Button" +/* Click method: BOOL read-only, 2 values in order buttonareas, clickfinger + shows available click methods */ +#define LIBINPUT_PROP_CLICK_METHODS_AVAILABLE "libinput Click Methods Available" + +/* Click method: BOOL, 2 values in order buttonareas, clickfinger + only one enabled at a time at max */ +#define LIBINPUT_PROP_CLICK_METHOD_ENABLED "libinput Click Method Enabled" + #endif /* _LIBINPUT_PROPERTIES_H_ */ diff --git a/man/libinput.man b/man/libinput.man index 692d56a..f4e9bed 100644 --- a/man/libinput.man +++ b/man/libinput.man @@ -53,6 +53,14 @@ A string of 9 space-separated floating point numbers. Sets the calibration matrix to the 3x3 matrix where the first row is (abc), the second row is (def) and the third row is (ghi). .TP 7 +.BI "Option \*qClickMethod\*q \*q" string \*q +Enables a click method. Permitted values are +.BI none, +.BI buttonareas, +.BI clickfinger. +Not all devices support all methods, if an option is unsupported, the +default click method for this device is used. +.TP 7 .BI "Option \*qLeftHanded\*q \*q" bool \*q Enables left-handed button orientation, i.e. swapping left and right buttons. .TP 7 diff --git a/src/libinput.c b/src/libinput.c index 9be17b4..5bcb995 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -94,6 +94,7 @@ struct xf86libinput { float speed; float matrix[9]; enum libinput_config_scroll_method scroll_method; + enum libinput_config_click_method click_method; } options; }; @@ -291,6 +292,23 @@ LibinputApplyConfig(DeviceIntPtr dev) "Failed to set ScrollButton to %d\n", driver_data->options.scroll_button); } + + if (libinput_device_config_click_set_method(device, + driver_data->options.click_method) != LIBINPUT_CONFIG_STATUS_SUCCESS) { + const char *method; + + switch (driver_data->options.click_method) { + case LIBINPUT_CONFIG_CLICK_METHOD_NONE: method = "none"; break; + case LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS: method = "buttonareas"; break; + case LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER: method = "clickfinger"; break; + default: + method = "unknown"; break; + } + + xf86IDrvMsg(pInfo, X_ERROR, + "Failed to set click method to %s\n", + method); + } } static int @@ -948,6 +966,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo, struct libinput_device *device) { uint32_t scroll_methods; + uint32_t click_methods; if (libinput_device_config_tap_get_finger_count(device) > 0) { BOOL tap = xf86SetBoolOption(pInfo->options, @@ -1118,6 +1137,31 @@ xf86libinput_parse_options(InputInfoPtr pInfo, driver_data->options.scroll_button = scroll_button; } + click_methods = libinput_device_config_click_get_methods(device); + if (click_methods != LIBINPUT_CONFIG_CLICK_METHOD_NONE) { + enum libinput_config_click_method m; + char *method = xf86SetStrOption(pInfo->options, + "ClickMethod", + NULL); + + if (!method) + m = libinput_device_config_click_get_method(device); + else if (strncasecmp(method, "buttonareas", 11) == 0) + m = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; + else if (strncasecmp(method, "clickfinger", 11) == 0) + m = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; + else if (strncasecmp(method, "none", 4) == 0) + m = LIBINPUT_CONFIG_CLICK_METHOD_NONE; + else { + xf86IDrvMsg(pInfo, X_ERROR, + "Unknown click method '%s'. Using default.\n", + method); + m = libinput_device_config_click_get_method(device); + } + + driver_data->options.click_method = m; + free(method); + } } static int @@ -1287,6 +1331,8 @@ static Atom prop_left_handed; static Atom prop_scroll_methods_available; static Atom prop_scroll_method_enabled; static Atom prop_scroll_button; +static Atom prop_click_methods_available; +static Atom prop_click_method_enabled; /* general properties */ static Atom prop_float; @@ -1593,6 +1639,48 @@ LibinputSetPropertyScrollButton(DeviceIntPtr dev, return Success; } +static inline int +LibinputSetPropertyClickMethod(DeviceIntPtr dev, + Atom atom, + XIPropertyValuePtr val, + BOOL checkonly) +{ + InputInfoPtr pInfo = dev->public.devicePrivate; + struct xf86libinput *driver_data = pInfo->private; + struct libinput_device *device = driver_data->device; + BOOL* data; + uint32_t modes = 0; + + if (val->format != 8 || val->size != 2 || val->type != XA_INTEGER) + return BadMatch; + + data = (BOOL*)val->data; + + if (data[0]) + modes |= LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; + if (data[1]) + modes |= LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; + + if (checkonly) { + uint32_t supported; + + if (__builtin_popcount(modes) > 1) + return BadValue; + + if (!xf86libinput_check_device(dev, atom)) + return BadMatch; + + supported = libinput_device_config_click_get_methods(device); + if (modes && (modes & supported) == 0) + return BadValue; + } else { + driver_data->options.click_method = modes; + } + + return Success; +} + + static int LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, BOOL checkonly) @@ -1620,6 +1708,10 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, rc = LibinputSetPropertyScrollMethods(dev, atom, val, checkonly); else if (atom == prop_scroll_button) rc = LibinputSetPropertyScrollButton(dev, atom, val, checkonly); + else if (atom == prop_click_methods_available) + return BadAccess; /* read-only */ + else if (atom == prop_click_method_enabled) + rc = LibinputSetPropertyClickMethod(dev, atom, val, checkonly); else if (atom == prop_device || atom == prop_product_id) return BadAccess; /* read-only */ else @@ -1884,6 +1976,73 @@ LibinputInitScrollMethodsProperty(DeviceIntPtr dev, } static void +LibinputInitClickMethodsProperty(DeviceIntPtr dev, + struct xf86libinput *driver_data, + struct libinput_device *device) +{ + uint32_t click_methods; + enum libinput_config_click_method method; + BOOL methods[2] = {FALSE}; + int rc; + + click_methods = libinput_device_config_click_get_methods(device); + if (click_methods == LIBINPUT_CONFIG_CLICK_METHOD_NONE) + return; + + if (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS) + methods[0] = TRUE; + if (click_methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER) + methods[1] = TRUE; + + prop_click_methods_available = + MakeAtom(LIBINPUT_PROP_CLICK_METHODS_AVAILABLE, + strlen(LIBINPUT_PROP_CLICK_METHODS_AVAILABLE), + TRUE); + rc = XIChangeDeviceProperty(dev, + prop_click_methods_available, + XA_INTEGER, 8, + PropModeReplace, + ARRAY_SIZE(methods), + &methods, FALSE); + if (rc != Success) + return; + XISetDevicePropertyDeletable(dev, + prop_click_methods_available, + FALSE); + + memset(methods, 0, sizeof(methods)); + + method = libinput_device_config_click_get_method(device); + switch(method) { + case LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS: + methods[0] = TRUE; + break; + case LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER: + methods[1] = TRUE; + break; + default: + break; + } + + prop_click_method_enabled = + MakeAtom(LIBINPUT_PROP_CLICK_METHOD_ENABLED, + strlen(LIBINPUT_PROP_CLICK_METHOD_ENABLED), + TRUE); + rc = XIChangeDeviceProperty(dev, + prop_click_method_enabled, + XA_INTEGER, 8, + PropModeReplace, + ARRAY_SIZE(methods), + &methods, FALSE); + if (rc != Success) + return; + + XISetDevicePropertyDeletable(dev, + prop_click_method_enabled, + FALSE); +} + +static void LibinputInitProperty(DeviceIntPtr dev) { InputInfoPtr pInfo = dev->public.devicePrivate; @@ -1902,6 +2061,7 @@ LibinputInitProperty(DeviceIntPtr dev) LibinputInitSendEventsProperty(dev, driver_data, device); LibinputInitLeftHandedProperty(dev, driver_data, device); LibinputInitScrollMethodsProperty(dev, driver_data, device); + LibinputInitClickMethodsProperty(dev, driver_data, device); /* Device node property, read-only */ device_node = driver_data->path; -- 2.1.0 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel