Compare commits

...

16 Commits

Author SHA1 Message Date
Peter Hutterer
446401bea9 xf86-input-libinput 0.9.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-04-23 12:23:01 +10:00
Peter Hutterer
8d4e03570c Add "libinput something Default" properties
A client or xorg.conf setting may change the property but once changed it
cannot be reset by a client to the original state without knowledge about the
device.

Export the various libinput_...get_default() functions as properties.

https://bugs.freedesktop.org/show_bug.cgi?id=89574

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-03-18 09:15:40 +10:00
Peter Hutterer
0c5620a29c Add a helper function for making properties
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-03-18 09:15:40 +10:00
Peter Hutterer
fb50cef700 man: update the property list in the man page
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-03-18 09:15:40 +10:00
Peter Hutterer
64a0f870e0 Fix a couple of -Wformat warnings
unsigned int vs int

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-03-18 09:15:40 +10:00
Peter Hutterer
e362e4dc4c cosmetic: drop duplicate empty lines
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-03-16 10:38:07 +10:00
Peter Hutterer
7b3b04b518 xf86-input-libinput 0.8.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-03-06 15:32:58 +10:00
Boyan Ding
4ac531bdf6 Initialize variable 'path' to NULL to silence warning
CC       libinput.lo
libinput.c: In function 'xf86libinput_pre_init':
libinput.c:1222:2: warning: 'path' may be used uninitialized in this
function [-Wmaybe-uninitialized]
  free(path);
  ^

Signed-off-by: Boyan Ding <boyan.j.ding@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-03-06 14:50:38 +10:00
Peter Hutterer
7ec0bf7ae2 Up the scroll dist value for touchpads
For source FINGER and CONTINUOUS, the axis value is the same as relative
motion - but scrolling in X usually doesn't have the same speed as finger
movement, it's a lot coarser.

We don't know ahead of time where we'll get the scroll events from. Set a
default scroll distance of 15 and multiply any wheel clicks we get by this
value.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-03-05 19:07:28 +10:00
Peter Hutterer
2ffd8d14be Apply the configuration before initalizing the property
Otherwise the property contains the device defaults, rather than the xorg.conf
options.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-03-02 10:43:07 +10:00
Peter Hutterer
e9a0ee69cb Don't unref the device until we're done with it in DEVICE_INIT
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-03-02 10:42:03 +10:00
Peter Hutterer
fb6506f5ee 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 <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-02-26 17:06:10 +10:00
Peter Hutterer
275c712866 Split out property init into helper functions
Makes the code less messy. Only functional change is that if one property
fails to initialize we'll now continue with the others. Previously the first
failed property would prevent any other property init.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2015-02-26 16:54:54 +10:00
Peter Hutterer
2455f0d03b Use the new libinput_device_pointer_has_button
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-02-26 16:09:50 +10:00
Olivier Fourdan
98ae01b9ae Ignore property changes if the device is disabled
If the device is present but disabled, the server will still call into
SetProperty. We don't have a libinput device to back it up in this case,
causing a null-pointer dereference.

This is a bug specific to this driver that cannot easily be fixed. All
other drivers can handle property changes even if no device is present,
here we rely on libinput to make the final call. But without a device
path/fd we don't have a libinput reference.

The protocol doesn't mention this case, so let's pick BadMatch as the
least wrong error code. And put a warning in the log, this needs a
workaround in the client.

Also, if we get here and the device is on, then that's definitely a bug,
warn about that.

https://bugs.freedesktop.org/show_bug.cgi?id=89296

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-02-26 08:10:24 +10:00
Peter Hutterer
2600a4a352 Fix off-by-one error in buttonmap initialization (#89300)
X.Org Bug 89300 <http://bugs.freedesktop.org/show_bug.cgi?id=89300>

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2015-02-25 07:50:45 +10:00
4 changed files with 654 additions and 224 deletions

View File

@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-libinput],
[0.7.0],
[0.9.0],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
[xf86-input-libinput])
AC_CONFIG_SRCDIR([Makefile.am])
@@ -45,7 +45,7 @@ XORG_DEFAULT_OPTIONS
# Obtain compiler/linker options from server and required extensions
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.10] xproto [inputproto >= 2.2])
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 0.8.0])
PKG_CHECK_MODULES(LIBINPUT, [libinput >= 0.11.0])
# Define a configure option for an alternate input module directory
AC_ARG_WITH(xorg-module-dir,

View File

@@ -27,15 +27,27 @@
/* Tapping enabled/disabled: BOOL, 1 value */
#define LIBINPUT_PROP_TAP "libinput Tapping Enabled"
/* Tapping default enabled/disabled: BOOL, 1 value, read-only */
#define LIBINPUT_PROP_TAP_DEFAULT "libinput Tapping Enabled Default"
/* Calibration matrix: FLOAT, 9 values of a 3x3 matrix, in rows */
#define LIBINPUT_PROP_CALIBRATION "libinput Calibration Matrix"
/* Calibration matrix: FLOAT, 9 values of a 3x3 matrix, in rows, read-only*/
#define LIBINPUT_PROP_CALIBRATION_DEFAULT "libinput Calibration Matrix Default"
/* Pointer accel speed: FLOAT, 1 value, 32 bit */
#define LIBINPUT_PROP_ACCEL "libinput Accel Speed"
/* Pointer accel speed: FLOAT, 1 value, 32 bit, read-only*/
#define LIBINPUT_PROP_ACCEL_DEFAULT "libinput Accel Speed Default"
/* Natural scrolling: BOOL, 1 value */
#define LIBINPUT_PROP_NATURAL_SCROLL "libinput Natural Scrolling Enabled"
/* Natural scrolling: BOOL, 1 value, read-only */
#define LIBINPUT_PROP_NATURAL_SCROLL_DEFAULT "libinput Natural Scrolling Enabled Default"
/* Send-events mode: BOOL read-only, 2 values in order disabled,
disabled-on-external-mouse */
#define LIBINPUT_PROP_SENDEVENTS_AVAILABLE "libinput Send Events Modes Available"
@@ -44,9 +56,16 @@
disabled-on-external-mouse */
#define LIBINPUT_PROP_SENDEVENTS_ENABLED "libinput Send Events Mode Enabled"
/* Send-events mode: BOOL, 2 values in order disabled,
disabled-on-external-mouse, read-only */
#define LIBINPUT_PROP_SENDEVENTS_ENABLED_DEFAULT "libinput Send Events Mode Enabled Default"
/* Left-handed enabled/disabled: BOOL, 1 value */
#define LIBINPUT_PROP_LEFT_HANDED "libinput Left Handed Enabled"
/* Left-handed enabled/disabled: BOOL, 1 value, read-only */
#define LIBINPUT_PROP_LEFT_HANDED_DEFAULT "libinput Left Handed Enabled Default"
/* Scroll method: BOOL read-only, 3 values in order 2fg, edge, button.
shows available scroll methods */
#define LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE "libinput Scroll Methods Available"
@@ -55,7 +74,25 @@
only one is enabled at a time at max */
#define LIBINPUT_PROP_SCROLL_METHOD_ENABLED "libinput Scroll Method Enabled"
/* Scroll method: BOOL, 3 values in order 2fg, edge, button
only one is enabled at a time at max, read-only */
#define LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT "libinput Scroll Method Enabled Default"
/* Scroll button for button scrolling: 32-bit int, 1 value */
#define LIBINPUT_PROP_SCROLL_BUTTON "libinput Button Scrolling Button"
/* Scroll button for button scrolling: 32-bit int, 1 value, read-only */
#define LIBINPUT_PROP_SCROLL_BUTTON_DEFAULT "libinput Button Scrolling Button Default"
/* 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"
/* Click method: BOOL, 2 values in order buttonareas, clickfinger
only one enabled at a time at max, read-only */
#define LIBINPUT_PROP_CLICK_METHOD_ENABLED_DEFAULT "libinput Click Method Enabled Default"
#endif /* _LIBINPUT_PROPERTIES_H_ */

View File

@@ -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
@@ -88,7 +96,11 @@ configuration option. For all options, the default value is the one used by
libinput. On configuration failure, the default value is applied.
.SH SUPPORTED PROPERTIES
The following properties are provided by the
.B libinput
exports runtime-configurable options as properties. If a property listed
below is not available, the matching configuration option is not available
on the device. This however does not imply that the feature is not available
on the device. The following properties are provided by the
.B libinput
driver.
.TP 7
@@ -105,9 +117,44 @@ driver.
.BI "libinput Natural Scrolling Enabled"
1 boolean value (8 bit, 0 or 1). 1 enables natural scrolling
.TP 7
.BI "libinput Send Events Mode"
1 32-bit value, defines the sendevent mode. See the libinput documentation
for the allowed values.
.BI "libinput Send Events Modes Available"
2 boolean values (8 bit, 0 or 1), in order "disabled" and
"disabled-on-external-mouse". Indicates which send-event modes are available
on this device.
.TP 7
.BI "libinput Send Events Mode Enabled"
2 boolean values (8 bit, 0 or 1), in order "disabled" and
"disabled-on-external-mouse". Indicates which send-event modes is currently
enabled on this device.
.TP 7
.BI "libinput Left Handed Enabled"
1 boolean value (8 bit, 0 or 1). Indicates if left-handed mode is enabled or
disabled.
.TP 7
.BI "libinput Scroll Methods Available"
3 boolean values (8 bit, 0 or 1), in order "two-finger", "edge", "button".
Indicates which scroll methods are available on this device.
.TP 7
.BI "libinput Scroll Method Enabled"
3 boolean values (8 bit, 0 or 1), in order "two-finger", "edge", "button".
Indicates which scroll method is currently enabled on this device.
.TP 7
.BI "libinput Button Scrolling Button"
1 32-bit value. Sets the button number to use for button scrolling. This
setting is independent of the scroll method, to enable button scrolling the
method must be set to button-scrolling and a valid button must be set.
.TP 7
.BI "libinput Click Methods Available"
2 boolean values (8 bit, 0 or 1), in order "buttonareas", "clickfinger".
Indicates which click methods are available on this device.
.TP 7
.BI "libinput Click Methods Enabled"
2 boolean values (8 bit, 0 or 1), in order "buttonareas", "clickfinger".
Indicates which click methods are enabled on this device.
.PP
The above properties have a
.BI "libinput <property name> Default"
equivalent that indicates the default value for this setting on this device.
.SH AUTHORS
Peter Hutterer

View File

@@ -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;
};
@@ -224,7 +225,7 @@ LibinputApplyConfig(DeviceIntPtr dev)
libinput_device_config_send_events_set_mode(device,
driver_data->options.sendevents) != LIBINPUT_CONFIG_STATUS_SUCCESS)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set SendEventsMode %d\n",
"Failed to set SendEventsMode %u\n",
driver_data->options.sendevents);
if (libinput_device_config_scroll_has_natural_scroll(device) &&
@@ -288,9 +289,26 @@ LibinputApplyConfig(DeviceIntPtr dev)
scroll_button = btn_xorg2linux(driver_data->options.scroll_button);
if (libinput_device_config_scroll_set_button(device, scroll_button) != LIBINPUT_CONFIG_STATUS_SUCCESS)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set ScrollButton to %d\n",
"Failed to set ScrollButton to %u\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
@@ -372,7 +390,7 @@ init_button_map(unsigned char *btnmap, size_t size)
int i;
memset(btnmap, 0, size);
for (i = 0; i <= size; i++)
for (i = 0; i < size; i++)
btnmap[i] = i;
}
@@ -419,7 +437,7 @@ xf86libinput_init_pointer(InputInfoPtr pInfo)
Atom axislabels[TOUCHPAD_NUM_AXES];
for (i = BTN_BACK; i >= BTN_SIDE; i--) {
if (libinput_device_has_button(driver_data->device, i)) {
if (libinput_device_pointer_has_button(driver_data->device, i)) {
nbuttons += i - BTN_SIDE + 1;
break;
}
@@ -467,7 +485,7 @@ xf86libinput_init_pointer_absolute(InputInfoPtr pInfo)
Atom axislabels[TOUCHPAD_NUM_AXES];
for (i = BTN_BACK; i >= BTN_SIDE; i--) {
if (libinput_device_has_button(driver_data->device, i)) {
if (libinput_device_pointer_has_button(driver_data->device, i)) {
nbuttons += i - BTN_SIDE + 1;
break;
}
@@ -614,13 +632,14 @@ xf86libinput_init(DeviceIntPtr dev)
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH))
xf86libinput_init_touch(pInfo);
LibinputApplyConfig(dev);
LibinputInitProperty(dev);
XIRegisterPropertyHandler(dev, LibinputSetProperty, NULL, NULL);
/* unref the device now, because we'll get a new ref during
DEVICE_ON */
libinput_device_unref(device);
LibinputInitProperty(dev);
XIRegisterPropertyHandler(dev, LibinputSetProperty, NULL, NULL);
return 0;
}
@@ -737,18 +756,22 @@ xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *even
axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
if (libinput_event_pointer_has_axis(event, axis)) {
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
value = libinput_event_pointer_get_axis_value_discrete(event, axis);
else
value *= driver_data->scroll_vdist;
} else {
value = libinput_event_pointer_get_axis_value(event, axis);
}
valuator_mask_set_double(mask, 3, value);
}
axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
if (libinput_event_pointer_has_axis(event, axis)) {
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
value = libinput_event_pointer_get_axis_value_discrete(event, axis);
else
value *= driver_data->scroll_hdist;
} else {
value = libinput_event_pointer_get_axis_value(event, axis);
}
valuator_mask_set_double(mask, 2, value);
}
@@ -948,6 +971,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,
@@ -1017,7 +1041,7 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
if (libinput_device_config_send_events_set_mode(device, mode) !=
LIBINPUT_CONFIG_STATUS_SUCCESS) {
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set SendEventsMode %d\n", mode);
"Failed to set SendEventsMode %u\n", mode);
mode = libinput_device_config_send_events_get_mode(device);
}
driver_data->options.sendevents = mode;
@@ -1111,13 +1135,38 @@ xf86libinput_parse_options(InputInfoPtr pInfo,
if (libinput_device_config_scroll_set_button(device,
b) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set ScrollButton to %d\n",
"Failed to set ScrollButton to %u\n",
scroll_button);
scroll_button = btn_linux2xorg(libinput_device_config_scroll_get_button(device));
}
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
@@ -1128,7 +1177,7 @@ xf86libinput_pre_init(InputDriverPtr drv,
struct xf86libinput *driver_data = NULL;
struct libinput *libinput = NULL;
struct libinput_device *device;
char *path;
char *path = NULL;
pInfo->type_name = 0;
pInfo->device_control = xf86libinput_device_control;
@@ -1144,8 +1193,8 @@ xf86libinput_pre_init(InputDriverPtr drv,
if (!driver_data->valuators)
goto fail;
driver_data->scroll_vdist = 1;
driver_data->scroll_hdist = 1;
driver_data->scroll_vdist = 15;
driver_data->scroll_hdist = 15;
path = xf86SetStrOption(pInfo->options, "Device", NULL);
if (!path)
@@ -1278,21 +1327,52 @@ _X_EXPORT XF86ModuleData libinputModuleData = {
/* libinput-specific properties */
static Atom prop_tap;
static Atom prop_tap_default;
static Atom prop_calibration;
static Atom prop_calibration_default;
static Atom prop_accel;
static Atom prop_accel_default;
static Atom prop_natural_scroll;
static Atom prop_natural_scroll_default;
static Atom prop_sendevents_available;
static Atom prop_sendevents_enabled;
static Atom prop_sendevents_default;
static Atom prop_left_handed;
static Atom prop_left_handed_default;
static Atom prop_scroll_methods_available;
static Atom prop_scroll_method_enabled;
static Atom prop_scroll_method_default;
static Atom prop_scroll_button;
static Atom prop_scroll_button_default;
static Atom prop_click_methods_available;
static Atom prop_click_method_enabled;
static Atom prop_click_method_default;
/* general properties */
static Atom prop_float;
static Atom prop_device;
static Atom prop_product_id;
static inline BOOL
xf86libinput_check_device (DeviceIntPtr dev,
Atom atom)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
struct libinput_device *device = driver_data->device;
if (device == NULL) {
BUG_WARN(dev->public.on);
xf86IDrvMsg(pInfo, X_INFO,
"SetProperty on %u called but device is disabled.\n"
"This driver cannot change properties on a disabled device\n",
atom);
return FALSE;
}
return TRUE;
}
static inline int
LibinputSetPropertyTap(DeviceIntPtr dev,
Atom atom,
@@ -1312,6 +1392,9 @@ LibinputSetPropertyTap(DeviceIntPtr dev,
if (*data != 0 && *data != 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
return BadMatch;
if (libinput_device_config_tap_get_finger_count(device) == 0)
return BadMatch;
} else {
@@ -1343,6 +1426,9 @@ LibinputSetPropertyCalibration(DeviceIntPtr dev,
data[8] != 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
return BadMatch;
if (!libinput_device_config_calibration_has_matrix(device))
return BadMatch;
} else {
@@ -1374,6 +1460,9 @@ LibinputSetPropertyAccel(DeviceIntPtr dev,
if (*data < -1 || *data > 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
return BadMatch;
if (libinput_device_config_accel_is_available(device) == 0)
return BadMatch;
} else {
@@ -1403,6 +1492,9 @@ LibinputSetPropertyNaturalScroll(DeviceIntPtr dev,
if (*data != 0 && *data != 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
return BadMatch;
if (libinput_device_config_scroll_has_natural_scroll(device) == 0)
return BadMatch;
} else {
@@ -1435,9 +1527,12 @@ LibinputSetPropertySendEvents(DeviceIntPtr dev,
modes |= LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
if (checkonly) {
uint32_t supported =
libinput_device_config_send_events_get_modes(device);
uint32_t supported;
if (!xf86libinput_check_device (dev, atom))
return BadMatch;
supported = libinput_device_config_send_events_get_modes(device);
if ((modes | supported) != supported)
return BadValue;
@@ -1465,9 +1560,13 @@ LibinputSetPropertyLeftHanded(DeviceIntPtr dev,
data = (BOOL*)val->data;
if (checkonly) {
int supported = libinput_device_config_left_handed_is_available(device);
int supported;
int left_handed = *data;
if (!xf86libinput_check_device (dev, atom))
return BadMatch;
supported = libinput_device_config_left_handed_is_available(device);
if (!supported && left_handed)
return BadValue;
} else {
@@ -1502,11 +1601,15 @@ LibinputSetPropertyScrollMethods(DeviceIntPtr dev,
modes |= LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
if (checkonly) {
uint32_t supported = libinput_device_config_scroll_get_methods(device);
uint32_t supported;
if (__builtin_popcount(modes) > 1)
return BadValue;
if (!xf86libinput_check_device (dev, atom))
return BadMatch;
supported = libinput_device_config_scroll_get_methods(device);
if (modes && (modes & supported) == 0)
return BadValue;
} else {
@@ -1534,9 +1637,13 @@ LibinputSetPropertyScrollButton(DeviceIntPtr dev,
if (checkonly) {
uint32_t button = *data;
uint32_t supported = libinput_device_has_button(device,
btn_xorg2linux(button));
uint32_t supported;
if (!xf86libinput_check_device (dev, atom))
return BadMatch;
supported = libinput_device_pointer_has_button(device,
btn_xorg2linux(button));
if (button && !supported)
return BadValue;
} else {
@@ -1546,6 +1653,47 @@ 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)
@@ -1573,7 +1721,20 @@ 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_device || atom == prop_product_id)
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 ||
atom == prop_tap_default ||
atom == prop_calibration_default ||
atom == prop_accel_default ||
atom == prop_natural_scroll_default ||
atom == prop_sendevents_default ||
atom == prop_left_handed_default ||
atom == prop_scroll_method_default ||
atom == prop_scroll_button_default ||
atom == prop_click_method_default)
return BadAccess; /* read-only */
else
return Success;
@@ -1584,6 +1745,377 @@ LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
return rc;
}
static Atom
LibinputMakeProperty(DeviceIntPtr dev,
const char *prop_name,
Atom type,
int format,
int len,
void *data)
{
int rc;
Atom prop = MakeAtom(prop_name, strlen(prop_name), TRUE);
rc = XIChangeDeviceProperty(dev, prop, type, format,
PropModeReplace,
len, data, FALSE);
if (rc != Success)
return None;
XISetDevicePropertyDeletable(dev, prop, FALSE);
return prop;
}
static void
LibinputInitTapProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
BOOL tap = driver_data->options.tapping;
if (libinput_device_config_tap_get_finger_count(device) == 0)
return;
prop_tap = LibinputMakeProperty(dev,
LIBINPUT_PROP_TAP,
XA_INTEGER,
8,
1,
&tap);
if (!prop_tap)
return;
tap = libinput_device_config_tap_get_default_enabled(device);
prop_tap_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_TAP_DEFAULT,
XA_INTEGER, 8,
1, &tap);
}
static void
LibinputInitCalibrationProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
float calibration[9];
if (!libinput_device_config_calibration_has_matrix(device))
return;
/* We use a 9-element matrix just to be closer to the X server's
transformation matrix which also has the full matrix */
libinput_device_config_calibration_get_matrix(device, calibration);
calibration[6] = 0;
calibration[7] = 0;
calibration[8] = 1;
prop_calibration = LibinputMakeProperty(dev,
LIBINPUT_PROP_CALIBRATION,
prop_float, 32,
9, calibration);
if (!prop_calibration)
return;
libinput_device_config_calibration_get_default_matrix(device,
calibration);
prop_calibration_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_CALIBRATION_DEFAULT,
prop_float, 32,
9, calibration);
}
static void
LibinputInitAccelProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
float speed = driver_data->options.speed;
if (!libinput_device_config_accel_is_available(device))
return;
prop_accel = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL,
prop_float, 32,
1, &speed);
if (!prop_accel)
return;
speed = libinput_device_config_accel_get_default_speed(device);
prop_accel_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_ACCEL_DEFAULT,
prop_float, 32,
1, &speed);
}
static void
LibinputInitNaturalScrollProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
BOOL natural_scroll = driver_data->options.natural_scrolling;
if (!libinput_device_config_scroll_has_natural_scroll(device))
return;
prop_natural_scroll = LibinputMakeProperty(dev,
LIBINPUT_PROP_NATURAL_SCROLL,
XA_INTEGER, 8,
1, &natural_scroll);
if (!prop_natural_scroll)
return;
natural_scroll = libinput_device_config_scroll_get_default_natural_scroll_enabled(device);
prop_natural_scroll_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_NATURAL_SCROLL_DEFAULT,
XA_INTEGER, 8,
1, &natural_scroll);
}
static void
LibinputInitSendEventsProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
uint32_t sendevent_modes;
uint32_t sendevents;
BOOL modes[2] = {FALSE};
sendevent_modes = libinput_device_config_send_events_get_modes(device);
if (sendevent_modes == LIBINPUT_CONFIG_SEND_EVENTS_ENABLED)
return;
if (sendevent_modes & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED)
modes[0] = TRUE;
if (sendevent_modes & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
modes[1] = TRUE;
prop_sendevents_available = LibinputMakeProperty(dev,
LIBINPUT_PROP_SENDEVENTS_AVAILABLE,
XA_INTEGER, 8,
2, modes);
if (!prop_sendevents_available)
return;
memset(modes, 0, sizeof(modes));
sendevents = driver_data->options.sendevents;
switch(sendevents) {
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
modes[0] = TRUE;
break;
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
modes[1] = TRUE;
break;
}
prop_sendevents_enabled = LibinputMakeProperty(dev,
LIBINPUT_PROP_SENDEVENTS_ENABLED,
XA_INTEGER, 8,
2, modes);
if (!prop_sendevents_enabled)
return;
memset(modes, 0, sizeof(modes));
sendevent_modes = libinput_device_config_send_events_get_default_mode(device);
if (sendevent_modes & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED)
modes[0] = TRUE;
if (sendevent_modes & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
modes[1] = TRUE;
prop_sendevents_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_SENDEVENTS_ENABLED_DEFAULT,
XA_INTEGER, 8,
2, modes);
}
static void
LibinputInitLeftHandedProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
BOOL left_handed = driver_data->options.left_handed;
if (!libinput_device_config_left_handed_is_available(device))
return;
prop_left_handed = LibinputMakeProperty(dev,
LIBINPUT_PROP_LEFT_HANDED,
XA_INTEGER, 8,
1, &left_handed);
if (!prop_left_handed)
return;
left_handed = libinput_device_config_left_handed_get_default(device);
prop_left_handed_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_LEFT_HANDED_DEFAULT,
XA_INTEGER, 8,
1, &left_handed);
}
static void
LibinputInitScrollMethodsProperty(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
uint32_t scroll_methods;
enum libinput_config_scroll_method method;
BOOL methods[3] = {FALSE};
scroll_methods = libinput_device_config_scroll_get_methods(device);
if (scroll_methods == LIBINPUT_CONFIG_SCROLL_NO_SCROLL)
return;
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_2FG)
methods[0] = TRUE;
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_EDGE)
methods[1] = TRUE;
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)
methods[2] = TRUE;
prop_scroll_methods_available = LibinputMakeProperty(dev,
LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE,
XA_INTEGER, 8,
ARRAY_SIZE(methods),
&methods);
if (!prop_scroll_methods_available)
return;
memset(methods, 0, sizeof(methods));
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_method_enabled = LibinputMakeProperty(dev,
LIBINPUT_PROP_SCROLL_METHOD_ENABLED,
XA_INTEGER, 8,
ARRAY_SIZE(methods),
&methods);
if (!prop_scroll_method_enabled)
return;
scroll_methods = libinput_device_config_scroll_get_default_method(device);
if (scroll_methods == LIBINPUT_CONFIG_SCROLL_NO_SCROLL)
return;
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_2FG)
methods[0] = TRUE;
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_EDGE)
methods[1] = TRUE;
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)
methods[2] = TRUE;
prop_scroll_method_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_SCROLL_METHOD_ENABLED_DEFAULT,
XA_INTEGER, 8,
ARRAY_SIZE(methods),
&methods);
/* Scroll button */
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 = LibinputMakeProperty(dev,
LIBINPUT_PROP_SCROLL_BUTTON,
XA_CARDINAL, 32,
1, &scroll_button);
if (!prop_scroll_button)
return;
scroll_button = libinput_device_config_scroll_get_default_button(device);
prop_scroll_button_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_SCROLL_BUTTON_DEFAULT,
XA_CARDINAL, 32,
1, &scroll_button);
}
}
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};
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 = LibinputMakeProperty(dev,
LIBINPUT_PROP_CLICK_METHODS_AVAILABLE,
XA_INTEGER, 8,
ARRAY_SIZE(methods),
&methods);
if (!prop_click_methods_available)
return;
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 = LibinputMakeProperty(dev,
LIBINPUT_PROP_CLICK_METHOD_ENABLED,
XA_INTEGER, 8,
ARRAY_SIZE(methods),
&methods);
if (!prop_click_method_enabled)
return;
memset(methods, 0, sizeof(methods));
method = libinput_device_config_click_get_default_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_default = LibinputMakeProperty(dev,
LIBINPUT_PROP_CLICK_METHOD_ENABLED_DEFAULT,
XA_INTEGER, 8,
ARRAY_SIZE(methods),
&methods);
}
static void
LibinputInitProperty(DeviceIntPtr dev)
{
@@ -1592,204 +2124,18 @@ LibinputInitProperty(DeviceIntPtr dev)
struct libinput_device *device = driver_data->device;
const char *device_node;
CARD32 product[2];
uint32_t scroll_methods;
uint32_t sendevent_modes;
int rc;
prop_float = XIGetKnownProperty("FLOAT");
if (libinput_device_config_tap_get_finger_count(device) > 0) {
BOOL tap = driver_data->options.tapping;
prop_tap = MakeAtom(LIBINPUT_PROP_TAP, strlen(LIBINPUT_PROP_TAP), TRUE);
rc = XIChangeDeviceProperty(dev, prop_tap, XA_INTEGER, 8,
PropModeReplace, 1, &tap, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_tap, FALSE);
}
/* We use a 9-element matrix just to be closer to the X server's
transformation matrix which also has the full matrix */
if (libinput_device_config_calibration_has_matrix(device)) {
float calibration[9];
libinput_device_config_calibration_get_matrix(device, calibration);
calibration[6] = 0;
calibration[7] = 0;
calibration[8] = 1;
prop_calibration = MakeAtom(LIBINPUT_PROP_CALIBRATION,
strlen(LIBINPUT_PROP_CALIBRATION),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_calibration, prop_float, 32,
PropModeReplace, 9, calibration, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_calibration, FALSE);
}
if (libinput_device_config_accel_is_available(device)) {
float speed = driver_data->options.speed;
prop_accel = MakeAtom(LIBINPUT_PROP_ACCEL, strlen(LIBINPUT_PROP_ACCEL), TRUE);
rc = XIChangeDeviceProperty(dev, prop_accel, prop_float, 32,
PropModeReplace, 1, &speed, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_accel, FALSE);
}
if (libinput_device_config_scroll_has_natural_scroll(device)) {
BOOL natural_scroll = driver_data->options.natural_scrolling;
prop_natural_scroll = MakeAtom(LIBINPUT_PROP_NATURAL_SCROLL,
strlen(LIBINPUT_PROP_NATURAL_SCROLL),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_natural_scroll, XA_INTEGER, 8,
PropModeReplace, 1, &natural_scroll, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_natural_scroll, FALSE);
}
sendevent_modes = libinput_device_config_send_events_get_modes(device);
if (sendevent_modes != LIBINPUT_CONFIG_SEND_EVENTS_ENABLED) {
uint32_t sendevents;
BOOL modes[2] = {FALSE};
if (sendevent_modes & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED)
modes[0] = TRUE;
if (sendevent_modes & LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE)
modes[1] = TRUE;
prop_sendevents_available = MakeAtom(LIBINPUT_PROP_SENDEVENTS_AVAILABLE,
strlen(LIBINPUT_PROP_SENDEVENTS_AVAILABLE),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_sendevents_available,
XA_INTEGER, 8,
PropModeReplace, 2, modes, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_sendevents_available, FALSE);
memset(modes, 0, sizeof(modes));
sendevents = driver_data->options.sendevents;
switch(sendevents) {
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
modes[0] = TRUE;
break;
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
modes[1] = TRUE;
break;
}
prop_sendevents_enabled = MakeAtom(LIBINPUT_PROP_SENDEVENTS_ENABLED,
strlen(LIBINPUT_PROP_SENDEVENTS_ENABLED),
TRUE);
rc = XIChangeDeviceProperty(dev, prop_sendevents_enabled,
XA_INTEGER, 8,
PropModeReplace, 2, modes, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev, prop_sendevents_enabled, FALSE);
}
if (libinput_device_config_left_handed_is_available(device)) {
BOOL left_handed = driver_data->options.left_handed;
prop_left_handed = MakeAtom(LIBINPUT_PROP_LEFT_HANDED,
strlen(LIBINPUT_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};
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_2FG)
methods[0] = TRUE;
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_EDGE)
methods[1] = TRUE;
if (scroll_methods & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN)
methods[2] = TRUE;
prop_scroll_methods_available =
MakeAtom(LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE,
strlen(LIBINPUT_PROP_SCROLL_METHODS_AVAILABLE),
TRUE);
rc = XIChangeDeviceProperty(dev,
prop_scroll_methods_available,
XA_INTEGER, 8,
PropModeReplace,
ARRAY_SIZE(methods),
&methods, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev,
prop_scroll_methods_available,
FALSE);
memset(methods, 0, sizeof(methods));
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_method_enabled =
MakeAtom(LIBINPUT_PROP_SCROLL_METHOD_ENABLED,
strlen(LIBINPUT_PROP_SCROLL_METHOD_ENABLED),
TRUE);
rc = XIChangeDeviceProperty(dev,
prop_scroll_method_enabled,
XA_INTEGER, 8,
PropModeReplace,
ARRAY_SIZE(methods),
&methods, FALSE);
if (rc != Success)
return;
XISetDevicePropertyDeletable(dev,
prop_scroll_method_enabled,
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(LIBINPUT_PROP_SCROLL_BUTTON,
strlen(LIBINPUT_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);
}
LibinputInitTapProperty(dev, driver_data, device);
LibinputInitCalibrationProperty(dev, driver_data, device);
LibinputInitAccelProperty(dev, driver_data, device);
LibinputInitNaturalScrollProperty(dev, driver_data, device);
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;