Commit 439a244a authored by Peter Hutterer's avatar Peter Hutterer

Add support for switching scroll methods

Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent 4a049ad6
...@@ -59,6 +59,15 @@ Enables left-handed button orientation, i.e. swapping left and right buttons. ...@@ -59,6 +59,15 @@ Enables left-handed button orientation, i.e. swapping left and right buttons.
.BI "Option \*qNaturalScrolling\*q \*q" bool \*q .BI "Option \*qNaturalScrolling\*q \*q" bool \*q
Enables or disables natural scrolling behavior. Enables or disables natural scrolling behavior.
.TP 7 .TP 7
.BI "Option \*qScrollMethod\*q \*q" string \*q
Enables a scroll method. Permitted values are
.BI none,
.BI twofinger,
.BI edge,
.BI button.
Not all devices support all options, if an option is unsupported, the
default scroll option for this device is used.
.TP 7
.BI "Option \*qSendEventsMode\*q \*q" (disabled|enabled|disabled-on-external-mouse) \*q .BI "Option \*qSendEventsMode\*q \*q" (disabled|enabled|disabled-on-external-mouse) \*q
Sets the send events mode to disabled, enabled, or "disable when an external Sets the send events mode to disabled, enabled, or "disable when an external
mouse is connected". mouse is connected".
......
...@@ -90,6 +90,7 @@ struct xf86libinput { ...@@ -90,6 +90,7 @@ struct xf86libinput {
CARD32 sendevents; CARD32 sendevents;
float speed; float speed;
float matrix[9]; float matrix[9];
enum libinput_config_scroll_method scroll_method;
} options; } options;
}; };
...@@ -150,6 +151,24 @@ LibinputApplyConfig(DeviceIntPtr dev) ...@@ -150,6 +151,24 @@ LibinputApplyConfig(DeviceIntPtr dev)
xf86IDrvMsg(pInfo, X_ERROR, xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set LeftHanded to %d\n", "Failed to set LeftHanded to %d\n",
driver_data->options.left_handed); driver_data->options.left_handed);
if (libinput_device_config_scroll_set_method(device,
driver_data->options.scroll_method) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
const char *method;
switch(driver_data->options.scroll_method) {
case LIBINPUT_CONFIG_SCROLL_NO_SCROLL: method = "none"; break;
case LIBINPUT_CONFIG_SCROLL_2FG: method = "twofinger"; break;
case LIBINPUT_CONFIG_SCROLL_EDGE: method = "edge"; break;
case LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN: method = "button"; break;
default:
method = "unknown"; break;
}
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set scroll to %s\n",
method);
}
} }
static int static int
...@@ -686,6 +705,7 @@ static int xf86libinput_pre_init(InputDriverPtr drv, ...@@ -686,6 +705,7 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
struct libinput *libinput = NULL; struct libinput *libinput = NULL;
struct libinput_device *device; struct libinput_device *device;
char *path; char *path;
uint32_t scroll_methods;
pInfo->fd = -1; pInfo->fd = -1;
pInfo->type_name = 0; pInfo->type_name = 0;
...@@ -870,6 +890,34 @@ static int xf86libinput_pre_init(InputDriverPtr drv, ...@@ -870,6 +890,34 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
driver_data->options.left_handed = left_handed; driver_data->options.left_handed = left_handed;
} }
scroll_methods = libinput_device_config_scroll_get_methods(device);
if (scroll_methods != LIBINPUT_CONFIG_SCROLL_NO_SCROLL) {
enum libinput_config_scroll_method m;
char *method = xf86SetStrOption(pInfo->options,
"ScrollMethod",
NULL);
if (!method)
m = libinput_device_config_scroll_get_method(device);
else if (strncasecmp(method, "twofinger", 9) == 0)
m = LIBINPUT_CONFIG_SCROLL_2FG;
else if (strncasecmp(method, "edge", 4) == 0)
m = LIBINPUT_CONFIG_SCROLL_EDGE;
else if (strncasecmp(method, "button", 6) == 0)
m = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
else if (strncasecmp(method, "none", 4) == 0)
m = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
else {
xf86IDrvMsg(pInfo, X_ERROR,
"Unknown scroll method '%s'. Using default.\n",
method);
m = libinput_device_config_scroll_get_method(device);
}
driver_data->options.scroll_method = m;
free(method);
}
/* now pick an actual type */ /* now pick an actual type */
if (libinput_device_config_tap_get_finger_count(device) > 0) if (libinput_device_config_tap_get_finger_count(device) > 0)
pInfo->type_name = XI_TOUCHPAD; pInfo->type_name = XI_TOUCHPAD;
...@@ -956,6 +1004,9 @@ _X_EXPORT XF86ModuleData libinputModuleData = { ...@@ -956,6 +1004,9 @@ _X_EXPORT XF86ModuleData libinputModuleData = {
#define PROP_SENDEVENTS "libinput Send Events Mode" #define PROP_SENDEVENTS "libinput Send Events Mode"
/* Left-handed enabled/disabled: BOOL, 1 value */ /* Left-handed enabled/disabled: BOOL, 1 value */
#define PROP_LEFT_HANDED "libinput Left Handed Enabled" #define PROP_LEFT_HANDED "libinput Left Handed Enabled"
/* Scroll method: BOOL, 3 values in order 2fg, edge, button
only one is enabled at a time at max */
#define PROP_SCROLL_METHODS "libinput Scroll Methods"
/* libinput-specific properties */ /* libinput-specific properties */
static Atom prop_tap; static Atom prop_tap;
...@@ -964,6 +1015,7 @@ static Atom prop_accel; ...@@ -964,6 +1015,7 @@ static Atom prop_accel;
static Atom prop_natural_scroll; static Atom prop_natural_scroll;
static Atom prop_sendevents; static Atom prop_sendevents;
static Atom prop_left_handed; static Atom prop_left_handed;
static Atom prop_scroll_methods;
/* general properties */ /* general properties */
static Atom prop_float; static Atom prop_float;
...@@ -1151,6 +1203,45 @@ LibinputSetPropertyLeftHanded(DeviceIntPtr dev, ...@@ -1151,6 +1203,45 @@ LibinputSetPropertyLeftHanded(DeviceIntPtr dev,
return Success; return Success;
} }
static inline int
LibinputSetPropertyScrollMethods(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 != 3 || val->type != XA_INTEGER)
return BadMatch;
data = (BOOL*)val->data;
if (data[0])
modes |= LIBINPUT_CONFIG_SCROLL_2FG;
if (data[1])
modes |= LIBINPUT_CONFIG_SCROLL_EDGE;
if (data[2])
modes |= LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
if (checkonly) {
uint32_t supported = libinput_device_config_scroll_get_methods(device);
if (__builtin_popcount(modes) > 1)
return BadValue;
if ((modes & supported) == 0)
return BadValue;
} else {
driver_data->options.scroll_method = modes;
}
return Success;
}
static int static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly) BOOL checkonly)
...@@ -1170,6 +1261,8 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val, ...@@ -1170,6 +1261,8 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
rc = LibinputSetPropertySendEvents(dev, atom, val, checkonly); rc = LibinputSetPropertySendEvents(dev, atom, val, checkonly);
else if (atom == prop_left_handed) else if (atom == prop_left_handed)
rc = LibinputSetPropertyLeftHanded(dev, atom, val, checkonly); rc = LibinputSetPropertyLeftHanded(dev, atom, val, checkonly);
else if (atom == prop_scroll_methods)
rc = LibinputSetPropertyScrollMethods(dev, atom, val, checkonly);
else if (atom == prop_device || atom == prop_product_id) else if (atom == prop_device || atom == prop_product_id)
return BadAccess; /* read-only */ return BadAccess; /* read-only */
else else
...@@ -1189,6 +1282,7 @@ LibinputInitProperty(DeviceIntPtr dev) ...@@ -1189,6 +1282,7 @@ LibinputInitProperty(DeviceIntPtr dev)
struct libinput_device *device = driver_data->device; struct libinput_device *device = driver_data->device;
const char *device_node; const char *device_node;
CARD32 product[2]; CARD32 product[2];
uint32_t scroll_methods;
int rc; int rc;
prop_float = XIGetKnownProperty("FLOAT"); prop_float = XIGetKnownProperty("FLOAT");
...@@ -1279,6 +1373,41 @@ LibinputInitProperty(DeviceIntPtr dev) ...@@ -1279,6 +1373,41 @@ LibinputInitProperty(DeviceIntPtr dev)
XISetDevicePropertyDeletable(dev, prop_left_handed, FALSE); XISetDevicePropertyDeletable(dev, prop_left_handed, FALSE);
} }
scroll_methods = libinput_device_config_scroll_get_methods(device);
if (scroll_methods != LIBINPUT_CONFIG_SCROLL_NO_SCROLL) {
enum libinput_config_scroll_method method;
BOOL methods[3] = {FALSE};
method = libinput_device_config_scroll_get_method(device);
switch(method) {
case LIBINPUT_CONFIG_SCROLL_2FG:
methods[0] = TRUE;
break;
case LIBINPUT_CONFIG_SCROLL_EDGE:
methods[1] = TRUE;
break;
case LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN:
methods[2] = TRUE;
break;
default:
break;
}
prop_scroll_methods = MakeAtom(PROP_SCROLL_METHODS,
strlen(PROP_SCROLL_METHODS),
TRUE);
rc = XIChangeDeviceProperty(dev,
prop_scroll_methods,
XA_INTEGER, 8,
PropModeReplace,
ARRAY_SIZE(methods),
&methods, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_scroll_methods, FALSE);
}
/* Device node property, read-only */ /* Device node property, read-only */
device_node = driver_data->path; device_node = driver_data->path;
prop_device = MakeAtom(XI_PROP_DEVICE_NODE, prop_device = MakeAtom(XI_PROP_DEVICE_NODE,
......
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