Compare commits

...

7 Commits

Author SHA1 Message Date
Peter Hutterer
7b2dbdc224 xf86-input-libinput 0.3.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-24 17:43:23 +10:00
Peter Hutterer
eddc8cb1b2 Don't process events from devices that got removed already
If the driver doesn't have a pInfo reference anymore for a libinput device,
don't bother processing events, the device was already removed. This was
triggered by the libevdev test suite which adds/removes devices very quickly.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-24 11:50:48 +10:00
Peter Hutterer
95597d8070 Drop double empty lines
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-24 11:50:48 +10:00
Peter Hutterer
a323e221a7 Use the button conversion helper for normal button events too
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-24 11:01:25 +10:00
Peter Hutterer
6385974e4d Add support for changing the button-scrolling button
This currently exposes the libinput button name, which isn't ideal. Needs to
be switched to X button numbers.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-24 11:01:25 +10:00
Peter Hutterer
439a244ae7 Add support for switching scroll methods
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-24 11:00:44 +10:00
Peter Hutterer
4a049ad6f8 Add support for left-handed button orientation
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2014-11-24 10:50:24 +10:00
3 changed files with 333 additions and 15 deletions

View File

@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-libinput],
[0.2.0],
[0.3.0],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
[xf86-input-libinput])
AC_CONFIG_SRCDIR([Makefile.am])

View File

@@ -53,9 +53,29 @@ 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 \*qLeftHanded\*q \*q" bool \*q
Enables left-handed button orientation, i.e. swapping left and right buttons.
.TP 7
.BI "Option \*qNaturalScrolling\*q \*q" bool \*q
Enables or disables natural scrolling behavior.
.TP 7
.BI "Option \*qScrollButton\*q \*q" int \*q
Designates a button as scroll button. If the
.BI ScrollMethod
is
.BI button
and the button is logically held down, x/y axis movement is converted into
scroll events.
.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
Sets the send events mode to disabled, enabled, or "disable when an external
mouse is connected".

View File

@@ -86,12 +86,50 @@ struct xf86libinput {
struct {
BOOL tapping;
BOOL natural_scrolling;
BOOL left_handed;
CARD32 sendevents;
CARD32 scroll_button; /* xorg button number */
float speed;
float matrix[9];
enum libinput_config_scroll_method scroll_method;
} options;
};
static inline unsigned int
btn_linux2xorg(unsigned int b)
{
unsigned int button;
switch(b) {
case 0: button = 0; break;
case BTN_LEFT: button = 1; break;
case BTN_MIDDLE: button = 2; break;
case BTN_RIGHT: button = 3; break;
default:
button = 8 + b - BTN_SIDE;
break;
}
return button;
}
static inline unsigned int
btn_xorg2linux(unsigned int b)
{
unsigned int button;
switch(b) {
case 0: button = 0; break;
case 1: button = BTN_LEFT; break;
case 2: button = BTN_MIDDLE; break;
case 3: button = BTN_RIGHT; break;
default:
button = b - 8 + BTN_SIDE;
break;
}
return button;
}
static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly);
@@ -143,6 +181,36 @@ LibinputApplyConfig(DeviceIntPtr dev)
driver_data->options.matrix[4], driver_data->options.matrix[5],
driver_data->options.matrix[6], driver_data->options.matrix[7],
driver_data->options.matrix[8]);
if (libinput_device_config_buttons_set_left_handed(device,
driver_data->options.left_handed) != LIBINPUT_CONFIG_STATUS_SUCCESS)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set LeftHanded to %d\n",
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);
}
if (libinput_device_config_scroll_set_button(device,
btn_xorg2linux(driver_data->options.scroll_button)) != LIBINPUT_CONFIG_STATUS_SUCCESS)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set ScrollButton to %d\n",
driver_data->options.scroll_button);
}
static int
@@ -199,7 +267,6 @@ xf86libinput_ptr_ctl(DeviceIntPtr dev, PtrCtrl *ctl)
{
}
static void
init_button_map(unsigned char *btnmap, size_t size)
{
@@ -263,7 +330,6 @@ xf86libinput_init_pointer(InputInfoPtr pInfo)
init_button_labels(btnlabels, ARRAY_SIZE(btnlabels));
init_axis_labels(axislabels, ARRAY_SIZE(axislabels));
InitPointerDeviceStruct((DevicePtr)dev, btnmap,
nbuttons,
btnlabels,
@@ -447,13 +513,7 @@ xf86libinput_handle_button(InputInfoPtr pInfo, struct libinput_event_pointer *ev
int button;
int is_press;
switch(libinput_event_pointer_get_button(event)) {
case BTN_LEFT: button = 1; break;
case BTN_MIDDLE: button = 2; break;
case BTN_RIGHT: button = 3; break;
default: /* no touchpad actually has those buttons */
return;
}
button = btn_linux2xorg(libinput_event_pointer_get_button(event));
is_press = (libinput_event_pointer_get_button_state(event) == LIBINPUT_BUTTON_STATE_PRESSED);
xf86PostButtonEvent(dev, Relative, button, is_press, 0, 0);
}
@@ -550,7 +610,7 @@ xf86libinput_handle_event(struct libinput_event *event)
device = libinput_event_get_device(event);
pInfo = libinput_device_get_user_data(device);
if (pInfo && !pInfo->dev->public.on)
if (!pInfo || !pInfo->dev->public.on)
return;
switch (libinput_event_get_type(event)) {
@@ -591,7 +651,6 @@ xf86libinput_handle_event(struct libinput_event *event)
}
}
static void
xf86libinput_read_input(InputInfoPtr pInfo)
{
@@ -679,6 +738,7 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
struct libinput *libinput = NULL;
struct libinput_device *device;
char *path;
uint32_t scroll_methods;
pInfo->fd = -1;
pInfo->type_name = 0;
@@ -848,6 +908,68 @@ static int xf86libinput_pre_init(InputDriverPtr drv,
}
}
if (libinput_device_config_buttons_has_left_handed(device)) {
BOOL left_handed = xf86SetBoolOption(pInfo->options,
"LeftHanded",
libinput_device_config_buttons_get_left_handed(device));
if (libinput_device_config_buttons_set_left_handed(device,
left_handed) !=
LIBINPUT_CONFIG_STATUS_SUCCESS) {
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set LeftHanded to %d\n",
left_handed);
left_handed = libinput_device_config_buttons_get_left_handed(device);
}
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);
}
if (libinput_device_config_scroll_get_methods(device) &
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) {
unsigned int b = btn_linux2xorg(libinput_device_config_scroll_get_button(device));
CARD32 scroll_button = xf86SetIntOption(pInfo->options,
"ScrollButton",
b);
b = btn_xorg2linux(scroll_button);
if (libinput_device_config_scroll_set_button(device,
b) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set ScrollButton to %d\n",
scroll_button);
scroll_button = btn_linux2xorg(libinput_device_config_scroll_get_button(device));
}
driver_data->options.scroll_button = scroll_button;
}
/* now pick an actual type */
if (libinput_device_config_tap_get_finger_count(device) > 0)
pInfo->type_name = XI_TOUCHPAD;
@@ -918,8 +1040,6 @@ _X_EXPORT XF86ModuleData libinputModuleData = {
.teardown = NULL
};
/* Property support */
/* Tapping enabled/disabled: BOOL, 1 value */
@@ -932,6 +1052,13 @@ _X_EXPORT XF86ModuleData libinputModuleData = {
#define PROP_NATURAL_SCROLL "libinput Natural Scrolling Enabled"
/* Send-events mode: 32-bit int, 1 value */
#define PROP_SENDEVENTS "libinput Send Events Mode"
/* Left-handed enabled/disabled: BOOL, 1 value */
#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"
/* Scroll button for button scrolling: 32-bit int, 1 value */
#define PROP_SCROLL_BUTTON "libinput Button Scrolling Button"
/* libinput-specific properties */
static Atom prop_tap;
@@ -939,6 +1066,9 @@ static Atom prop_calibration;
static Atom prop_accel;
static Atom prop_natural_scroll;
static Atom prop_sendevents;
static Atom prop_left_handed;
static Atom prop_scroll_methods;
static Atom prop_scroll_button;
/* general properties */
static Atom prop_float;
@@ -1097,6 +1227,104 @@ LibinputSetPropertySendEvents(DeviceIntPtr dev,
return Success;
}
static inline int
LibinputSetPropertyLeftHanded(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;
if (val->format != 8 || val->size != 1 || val->type != XA_INTEGER)
return BadMatch;
data = (BOOL*)val->data;
if (checkonly) {
int supported = libinput_device_config_buttons_has_left_handed(device);
int left_handed = *data;
if (!supported && left_handed)
return BadValue;
} else {
driver_data->options.left_handed = *data;
}
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 inline int
LibinputSetPropertyScrollButton(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;
CARD32* data;
if (val->format != 32 || val->size != 1 || val->type != XA_CARDINAL)
return BadMatch;
data = (CARD32*)val->data;
if (checkonly) {
uint32_t button = *data;
uint32_t supported = libinput_device_has_button(device,
btn_xorg2linux(button));
if (button && !supported)
return BadValue;
} else {
driver_data->options.scroll_button = *data;
}
return Success;
}
static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly)
@@ -1114,6 +1342,12 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
rc = LibinputSetPropertyNaturalScroll(dev, atom, val, checkonly);
else if (atom == prop_sendevents)
rc = LibinputSetPropertySendEvents(dev, atom, val, checkonly);
else if (atom == prop_left_handed)
rc = LibinputSetPropertyLeftHanded(dev, atom, val, checkonly);
else if (atom == prop_scroll_methods)
rc = LibinputSetPropertyScrollMethods(dev, atom, val, checkonly);
else if (atom == prop_scroll_button)
rc = LibinputSetPropertyScrollButton(dev, atom, val, checkonly);
else if (atom == prop_device || atom == prop_product_id)
return BadAccess; /* read-only */
else
@@ -1133,6 +1367,7 @@ LibinputInitProperty(DeviceIntPtr dev)
struct libinput_device *device = driver_data->device;
const char *device_node;
CARD32 product[2];
uint32_t scroll_methods;
int rc;
prop_float = XIGetKnownProperty("FLOAT");
@@ -1209,6 +1444,70 @@ LibinputInitProperty(DeviceIntPtr dev)
}
if (libinput_device_config_buttons_has_left_handed(device)) {
BOOL left_handed = driver_data->options.left_handed;
prop_left_handed = MakeAtom(PROP_LEFT_HANDED,
strlen(PROP_LEFT_HANDED),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_left_handed,
XA_INTEGER, 8,
PropModeReplace, 1, &left_handed, FALSE);
if (rc != Success)
return;
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);
}
if (libinput_device_config_scroll_get_methods(device) &
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) {
CARD32 scroll_button = driver_data->options.scroll_button;
prop_scroll_button = MakeAtom(PROP_SCROLL_BUTTON,
strlen(PROP_SCROLL_BUTTON),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_scroll_button,
XA_CARDINAL, 32,
PropModeReplace, 1,
&scroll_button, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_scroll_button, FALSE);
}
/* Device node property, read-only */
device_node = driver_data->path;
prop_device = MakeAtom(XI_PROP_DEVICE_NODE,
@@ -1223,7 +1522,6 @@ LibinputInitProperty(DeviceIntPtr dev)
XISetDevicePropertyDeletable(dev, prop_device, FALSE);
prop_product_id = MakeAtom(XI_PROP_PRODUCT_ID,
strlen(XI_PROP_PRODUCT_ID),
TRUE);