Commit fb6506f5 authored by Peter Hutterer's avatar Peter Hutterer

Add properties to change the click method (#89332)

X.Org Bug 89332 <http://bugs.freedesktop.org/show_bug.cgi?id=89332>
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
parent 275c7128
......@@ -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_ */
......@@ -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
......
......@@ -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
......@@ -1883,6 +1975,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)
{
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment