mirror of
https://github.com/X11Libre/xf86-input-libinput.git
synced 2026-03-26 10:24:30 +00:00
Compare commits
7 Commits
xf86-input
...
xf86-input
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b2dbdc224 | ||
|
|
eddc8cb1b2 | ||
|
|
95597d8070 | ||
|
|
a323e221a7 | ||
|
|
6385974e4d | ||
|
|
439a244ae7 | ||
|
|
4a049ad6f8 |
@@ -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])
|
||||
|
||||
@@ -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".
|
||||
|
||||
326
src/libinput.c
326
src/libinput.c
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user