Compare commits

...

20 Commits

Author SHA1 Message Date
Peter Hutterer
18cc042e68 xf86-input-libinput 0.27.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-04-10 09:19:52 +10:00
Evangelos Foutras
0db82219bb Fix "left handed" property not set on all pointers
Remove conditional that prevents the LIBINPUT_PROP_LEFT_HANDED{,DEFAULT}
properties from being set on all pointer devices (only the first got it).
This appears to be a debugging left-over accidentally merged in
6d3bd4544a.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-22 10:59:01 +10:00
Peter Hutterer
f93bc148d4 xf86-input-libinput 0.27.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-20 11:23:57 +10:00
Peter Hutterer
0d4b50fd6e man: note that we don't do /dev/input/by-id or /dev/input/by-path
For logind-setups we need to match the path libinput wants to open with the
Option Device path that the device has so we know when to return the
server-fd. This doesn't work for by-id or by-path because libinput resolves
those (through udev) to the actual eventX node so our paths look different
when they are the same device.

This could be fixed but since this is easy enough to work around with a
InputClass section and rather a niche case, it's not really worth the effort.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2018-03-20 10:48:04 +10:00
Peter Hutterer
9d9f59fd4c Apply the capabilities checks on subdevices when applying the config
Properties are initialized on the correct devices only but on resume we'd just
blindly apply the config from our device. Depending on the resume order, this
would mean we'd apply a previously set config with a default config.

Example:
* pointer device with keyboard subdevice
* pointer device exports natural scrolling, keyboard device does not and
  remains at default (off)
* client enables natural scrolling on the pointer device
* VT switch away, VT switch back
* pointer device gets enabled first, enables natural scrolling on the
  libinput device
* keyboard device gets enabled second, resets to the default value

Reported-by: Yuxuan Shui <yshuiv7@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Tested-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-02-21 09:53:12 +10:00
Peter Hutterer
7353481490 Split LibinputDeviceApplyConfig into helper functions
No functional changes
2018-02-02 14:25:44 +10:00
Peter Hutterer
6d3bd4544a Move the subdevice capabilities check into the properties
87f9fe3a6fafe60134c6's intention was to not create properties that a subdevice
doesn't have configuration options for (i.e. if you have a pointer+keyboard
device, don't expose tapping configuration on the keyboard subdevice).

The result was messy, the checker function had a confusing triple-negation and
some properties weren't checked - e.g. left-handed was allowed for touch/tablet
but not for pointer, dwt was allowed for any device.

Fix this by moving the check into the property init function directly and
inverting the helper function to be easier to read.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-02-02 14:25:31 +10:00
Peter Hutterer
2be6487de4 xf86-input-libinput 0.26.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-09-15 11:26:54 +10:00
Peter Hutterer
6ce3d0249d Post a motion event before a tablet button down
Not all clients update the pointer position correctly from the button events
(for historical reasons) so we need to send a motion event before the button
event that represents a tip state change.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-08-17 15:20:29 +10:00
Peter Hutterer
87f9fe3a6f Only initialize properties that match capabilities on a subdevice
If a device is split into multiple subdevices, usually pointer+keyboard, we
initialized properties matching the libinput device on both devices. This
results in the keyboard having e.g. a Accel Speed or Left Handed settings even
though it cannot send any events of that type.

Filter by capabilities on the subdevice so we only get those properties that
match the subdevice's capabilities.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-29 08:15:20 +10:00
Peter Hutterer
0c657e0dcf Update copyright years
because why not

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-18 14:03:06 +10:00
Niklas Haas
ac3574958f man: add missing documentation for Accel Profile
This seems to have been simply missing from 0163482e.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-15 11:41:46 +10:00
Martin Kepplinger
8772a593b4 Fix config comment description to match the config
Since the config matches on tablets too, update the describing comment
accordingly.

Signed-off-by: Martin Kepplinger <martin.kepplinger@ginzinger.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-08 10:33:58 +10:00
Peter Hutterer
a80773a488 xf86-input-libinput 0.25.1
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-05-05 13:43:23 +10:00
Peter Hutterer
8bc694595d Post a motion event after proximity events
This patch splits the meat of xf86libinput_handle_tablet_axis into a helper
function xf86libinput_post_tablet_motion(), to be called right after we send
the proximity in event.

Clients that don't handle proximity (e.g. all XI2 clients) don't see the
coordinates we send along with the proximity events. And, for historical
reasons, they may not look at the coordinates in button events. So a device
that comes into proximity and immediately sends a tip down button event
doesn't send a motion event, causing the client to think the tip down was at
whatever the last known position was (before previous prox-out).

The practical effect is that when a user tries to draw a few dots, they end up
being connected to each other.

https://bugzilla.redhat.com/show_bug.cgi?id=1433755

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-03-22 11:14:15 +10:00
Peter Hutterer
153a7fc62f xf86-input-libinput 0.25.0
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-03-09 15:58:39 +10:00
Peter Hutterer
72fb6d304e test: fix a test failure on ppc64(le) and aarch64
Caused by different results in -O0 vs -O2. The resulting array differs only
slightly but the initial sequence has one extra zero. That triggers our
assert, no other compiler flag seem to be affecting this.

Compiled with -O0:
Breakpoint 1, test_nonzero_x_linear () at test-bezier.c:157
157			assert(bezier[x] > bezier[x-1]);
(gdb) p bezier
$6 = {0 <repeats 409 times>, 1, 2, 4, 5, 7, 9, 10, 12, 14, 15, 17, 19, 21, 22,

Compiled with -O2:
(gdb) p bezier
$1 = {0 <repeats 410 times>, 1, 3, 5, 7, 9, 10, 12, 14, 15, 17, 19, 20, 22,

Printing of the temporary numbers in the decasteljau function shows that a few
of them are off by one, e.g.
    408.530612/0.836735 with O0, but
    409.510204/0.836735 with O2
Note: these are not rounding errors caused by the code, the cast to int
happens afterwards.

Hack around this by allowing for one extra zero before we check that the rest
of the curve is ascending again.

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

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-02-28 15:27:33 +10:00
Peter Hutterer
aae2c8ad9a Open sysfs files directly instead of going through the server
Only use-case here are pad mode LEDs that now live in /sys/class/leds. Asking
the server to open them is pointless, the server only knows how to open Option
"Device". And since the LEDs are in sysfs we should have access to them
anyway, so no need for jumping through or hula-ing hoops.

xf86CloseSerial() works as intended as it's a slim wrapper around close(), so
we only have to worry about the open() path here.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-02-27 09:34:36 +10:00
Peter Hutterer
dafc296f2d Add streq() macro, replace strcmp instances with it
And why isn't this a thing in glibc yet

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
2017-02-27 09:34:36 +10:00
Peter Hutterer
7c90f06d56 Update pad modes in a workproc, not during the input thread
Updating the property directly causes us to send events from the input thread
which has some "interesting" side effects like messing up the reply order or
just crashing the server.

Schedule a work proc instead and update it whenever the server is back in the
main thread.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2017-02-27 09:34:36 +10:00
5 changed files with 327 additions and 43 deletions

View File

@@ -1,4 +1,4 @@
# Match on all types of devices but tablet devices and joysticks
# Match on all types of devices but joysticks
Section "InputClass"
Identifier "libinput pointer catchall"
MatchIsPointer "on"

View File

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

View File

@@ -203,6 +203,14 @@ on the device. The following properties are provided by the
.B libinput
driver.
.TP 7
.BI "libinput Accel Profiles Available"
2 boolean values (8 bit, 0 or 1), in order "adaptive", "flat".
Indicates which acceleration profiles are available on this device.
.TP 7
.BI "libinput Accel Profile Enabled"
2 boolean values (8 bit, 0 or 1), in order "adaptive", "flat".
Indicates which acceleration profile is currently enabled on this device.
.TP 7
.BI "libinput Accel Speed"
1 32-bit float value, defines the pointer speed. Value range -1, 1
.TP 7
@@ -373,6 +381,12 @@ it takes left-handed-ness into account.
.TP
This feature is provided by this driver, not by libinput.
.SH BUGS
This driver does not work with \fBOption \*qDevice\*q\fR set to an event
node in \fI/dev/input/by-id\fR and \fI/dev/input/by-path\fR. This can be
usually be worked by using \fBSection \*qInputClass\*q\fR with an
appropriate \fBMatch*\fR statement in the __xconfigfile__(__filemansuffix__).
.SH AUTHORS
Peter Hutterer
.SH "SEE ALSO"

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2013-2015 Red Hat, Inc.
* Copyright © 2013-2017 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
@@ -65,6 +65,9 @@
#define TOUCH_MAX_SLOTS 15
#define XORG_KEYCODE_OFFSET 8
#define streq(a, b) (strcmp(a, b) == 0)
#define strneq(a, b, n) (strncmp(a, b, n) == 0)
/*
libinput does not provide axis information for absolute devices, instead
it scales into the screen dimensions provided. So we set up the axes with
@@ -209,6 +212,10 @@ update_mode_prop(InputInfoPtr pInfo,
static enum event_handling
xf86libinput_handle_event(struct libinput_event *event);
static void
xf86libinput_post_tablet_motion(InputInfoPtr pInfo,
struct libinput_event_tablet_tool *event);
static inline int
use_server_fd(const InputInfoPtr pInfo) {
return pInfo->fd > -1 && (pInfo->flags & XI86_SERVER_FD);
@@ -259,7 +266,7 @@ xf86libinput_is_subdevice(InputInfoPtr pInfo)
BOOL is_subdevice;
source = xf86SetStrOption(pInfo->options, "_source", "");
is_subdevice = strcmp(source, "_driver/libinput") == 0;
is_subdevice = streq(source, "_driver/libinput");
free(source);
return is_subdevice;
@@ -454,19 +461,34 @@ xf86libinput_set_area_ratio(struct xf86libinput *driver_data,
}
}
/**
* returns true if the device has one or more of the given capabilities or
* if the device isn't a subdevice
*/
static inline bool
subdevice_has_capabilities(DeviceIntPtr dev, uint32_t capabilities)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
if (!xf86libinput_is_subdevice(pInfo))
return true;
return !!(driver_data->capabilities & capabilities);
}
static int
LibinputSetProperty(DeviceIntPtr dev, Atom atom, XIPropertyValuePtr val,
BOOL checkonly);
static void
LibinputInitProperty(DeviceIntPtr dev);
static inline void
LibinputApplyConfig(DeviceIntPtr dev)
static void
LibinputApplyConfigSendEvents(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
struct libinput_device *device = driver_data->shared_device->device;
unsigned int scroll_button;
if (libinput_device_config_send_events_get_modes(device) != LIBINPUT_CONFIG_SEND_EVENTS_ENABLED &&
libinput_device_config_send_events_set_mode(device,
@@ -474,6 +496,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set SendEventsMode %u\n",
driver_data->options.sendevents);
}
static void
LibinputApplyConfigNaturalScroll(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_scroll_has_natural_scroll(device) &&
libinput_device_config_scroll_set_natural_scroll_enabled(device,
@@ -481,6 +514,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set NaturalScrolling to %d\n",
driver_data->options.natural_scrolling);
}
static void
LibinputApplyConfigAccel(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_accel_is_available(device) &&
libinput_device_config_accel_set_speed(device,
@@ -509,6 +553,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
}
xf86IDrvMsg(pInfo, X_ERROR, "Failed to set profile %s\n", profile);
}
}
static inline void
LibinputApplyConfigTap(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_tap_get_finger_count(device) > 0 &&
libinput_device_config_tap_set_enabled(device,
@@ -545,6 +600,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set Tapping Drag to %d\n",
driver_data->options.tap_drag);
}
static void
LibinputApplyConfigCalibration(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_TOUCH|CAP_TABLET))
return;
if (libinput_device_config_calibration_has_matrix(device) &&
libinput_device_config_calibration_set_matrix(device,
@@ -557,6 +623,17 @@ 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]);
}
static void
LibinputApplyConfigLeftHanded(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER|CAP_TABLET))
return;
if (libinput_device_config_left_handed_is_available(device) &&
libinput_device_config_left_handed_set(device,
@@ -564,6 +641,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set LeftHanded to %d\n",
driver_data->options.left_handed);
}
static void
LibinputApplyConfigScrollMethod(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_scroll_set_method(device,
driver_data->options.scroll_method) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
@@ -584,12 +672,25 @@ LibinputApplyConfig(DeviceIntPtr dev)
}
if (libinput_device_config_scroll_get_methods(device) & LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN) {
unsigned int scroll_button;
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 %u\n",
driver_data->options.scroll_button);
}
}
static void
LibinputApplyConfigClickMethod(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_click_set_method(device,
driver_data->options.click_method) != LIBINPUT_CONFIG_STATUS_SUCCESS) {
@@ -607,6 +708,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
"Failed to set click method to %s\n",
method);
}
}
static void
LibinputApplyConfigMiddleEmulation(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_middle_emulation_is_available(device) &&
libinput_device_config_middle_emulation_set_enabled(device,
@@ -614,6 +726,17 @@ LibinputApplyConfig(DeviceIntPtr dev)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set MiddleEmulation to %d\n",
driver_data->options.middle_emulation);
}
static void
LibinputApplyConfigDisableWhileTyping(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_dwt_is_available(device) &&
libinput_device_config_dwt_set_enabled(device,
@@ -621,13 +744,43 @@ LibinputApplyConfig(DeviceIntPtr dev)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set DisableWhileTyping to %d\n",
driver_data->options.disable_while_typing);
}
static void
LibinputApplyConfigRotation(DeviceIntPtr dev,
struct xf86libinput *driver_data,
struct libinput_device *device)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_rotation_is_available(device) &&
libinput_device_config_rotation_set_angle(device, driver_data->options.rotation_angle) != LIBINPUT_CONFIG_STATUS_SUCCESS)
xf86IDrvMsg(pInfo, X_ERROR,
"Failed to set RotationAngle to %.2f\n",
driver_data->options.rotation_angle);
}
static inline void
LibinputApplyConfig(DeviceIntPtr dev)
{
InputInfoPtr pInfo = dev->public.devicePrivate;
struct xf86libinput *driver_data = pInfo->private;
struct libinput_device *device = driver_data->shared_device->device;
LibinputApplyConfigSendEvents(dev, driver_data, device);
LibinputApplyConfigNaturalScroll(dev, driver_data, device);
LibinputApplyConfigAccel(dev, driver_data, device);
LibinputApplyConfigTap(dev, driver_data, device);
LibinputApplyConfigCalibration(dev, driver_data, device);
LibinputApplyConfigLeftHanded(dev, driver_data, device);
LibinputApplyConfigScrollMethod(dev, driver_data, device);
LibinputApplyConfigClickMethod(dev, driver_data, device);
LibinputApplyConfigMiddleEmulation(dev, driver_data, device);
LibinputApplyConfigDisableWhileTyping(dev, driver_data, device);
LibinputApplyConfigRotation(dev, driver_data, device);
}
static int
@@ -1213,7 +1366,7 @@ is_libinput_device(InputInfoPtr pInfo)
BOOL rc;
driver = xf86CheckStrOption(pInfo->options, "driver", "");
rc = strcmp(driver, "libinput") == 0;
rc = streq(driver, "libinput");
free(driver);
return rc;
@@ -1713,12 +1866,15 @@ static enum event_handling
xf86libinput_handle_tablet_tip(InputInfoPtr pInfo,
struct libinput_event_tablet_tool *event)
{
DeviceIntPtr pDev = pInfo->dev;
enum libinput_tablet_tool_tip_state state;
const BOOL is_absolute = TRUE;
if (xf86libinput_tool_queue_event(event))
return EVENT_QUEUED;
xf86libinput_post_tablet_motion(pDev->public.devicePrivate, event);
state = libinput_event_tablet_tool_get_tip_state(event);
xf86PostButtonEventP(pInfo->dev,
@@ -1773,8 +1929,8 @@ xf86libinput_apply_area(InputInfoPtr pInfo, double *x, double *y)
*y = sy;
}
static enum event_handling
xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
static void
xf86libinput_post_tablet_motion(InputInfoPtr pInfo,
struct libinput_event_tablet_tool *event)
{
DeviceIntPtr dev = pInfo->dev;
@@ -1784,9 +1940,6 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
double value;
double x, y;
if (xf86libinput_tool_queue_event(event))
return EVENT_QUEUED;
x = libinput_event_tablet_tool_get_x_transformed(event,
TABLET_AXIS_MAX);
y = libinput_event_tablet_tool_get_y_transformed(event,
@@ -1836,13 +1989,23 @@ xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
default:
xf86IDrvMsg(pInfo, X_ERROR,
"Invalid rotation axis on tool\n");
return EVENT_HANDLED;
return;
}
valuator_mask_set_double(mask, valuator, value);
}
xf86PostMotionEventM(dev, Absolute, mask);
}
static enum event_handling
xf86libinput_handle_tablet_axis(InputInfoPtr pInfo,
struct libinput_event_tablet_tool *event)
{
if (xf86libinput_tool_queue_event(event))
return EVENT_QUEUED;
xf86libinput_post_tablet_motion(pInfo, event);
return EVENT_HANDLED;
}
@@ -1974,6 +2137,13 @@ xf86libinput_handle_tablet_proximity(InputInfoPtr pInfo,
xf86PostProximityEventM(pDev, in_prox, mask);
/* We have to send an extra motion event after proximity to make
* sure the client got the updated x/y coordinates, especially if
* they don't handle proximity events (XI2).
*/
if (in_prox)
xf86libinput_post_tablet_motion(pDev->public.devicePrivate, event);
return EVENT_HANDLED;
}
@@ -2184,10 +2354,16 @@ open_restricted(const char *path, int flags, void *data)
InputInfoPtr pInfo;
int fd = -1;
/* Special handling for sysfs files (used for pad LEDs) */
if (strneq(path, "/sys/", 5)) {
fd = open(path, flags);
return fd < 0 ? -errno : fd;
}
nt_list_for_each_entry(pInfo, xf86FirstLocalDevice(), next) {
char *device = xf86CheckStrOption(pInfo->options, "Device", NULL);
if (device != NULL && strcmp(path, device) == 0) {
if (device != NULL && streq(path, device)) {
free(device);
break;
}
@@ -2353,9 +2529,9 @@ xf86libinput_parse_tap_buttonmap_option(InputInfoPtr pInfo,
"TappingButtonMap",
NULL);
if (str) {
if (strcmp(str, "lmr") == 0)
if (streq(str, "lmr"))
map = LIBINPUT_CONFIG_TAP_MAP_LMR;
else if (strcmp(str, "lrm") == 0)
else if (streq(str, "lrm"))
map = LIBINPUT_CONFIG_TAP_MAP_LRM;
else
xf86IDrvMsg(pInfo, X_ERROR,
@@ -2468,11 +2644,11 @@ xf86libinput_parse_sendevents_option(InputInfoPtr pInfo,
"SendEventsMode",
NULL);
if (modestr) {
if (strcmp(modestr, "enabled") == 0)
if (streq(modestr, "enabled"))
mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
else if (strcmp(modestr, "disabled") == 0)
else if (streq(modestr, "disabled"))
mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
else if (strcmp(modestr, "disabled-on-external-mouse") == 0)
else if (streq(modestr, "disabled-on-external-mouse"))
mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
else
xf86IDrvMsg(pInfo, X_ERROR,
@@ -2866,7 +3042,7 @@ xf86libinput_parse_tablet_area_option(InputInfoPtr pInfo,
str = xf86SetStrOption(pInfo->options,
"TabletToolAreaRatio",
NULL);
if (!str || strcmp(str, "default") == 0)
if (!str || streq(str, "default"))
goto out;
rc = sscanf(str, "%d:%d", &area.x, &area.y);
@@ -3386,17 +3562,43 @@ static Atom prop_float;
static Atom prop_device;
static Atom prop_product_id;
static inline void
update_mode_prop(InputInfoPtr pInfo,
struct libinput_event_tablet_pad *event)
{
struct xf86libinput *driver_data = pInfo->private;
struct mode_prop_state {
int deviceid;
InputInfoPtr pInfo;
struct libinput_tablet_pad_mode_group *group;
unsigned int mode;
unsigned int idx;
};
static Bool
update_mode_prop_cb(ClientPtr client, pointer closure)
{
struct mode_prop_state *state = closure;
InputInfoPtr pInfo = state->pInfo, tmp;
struct xf86libinput *driver_data = pInfo->private;
BOOL found = FALSE;
XIPropertyValuePtr val;
int rc;
unsigned char groups[4] = {0};
struct libinput_tablet_pad_mode_group *group = state->group;
unsigned int mode = state->mode;
unsigned int idx = state->idx;
if (idx >= ARRAY_SIZE(groups))
goto out;
/* The device may have gotten removed before the WorkProc was
* scheduled. X reuses deviceids, but if the pointer value and
* device ID are what we had before, we're good */
nt_list_for_each_entry(tmp, xf86FirstLocalDevice(), next) {
if (tmp->dev->id == state->deviceid && tmp == pInfo) {
found = TRUE;
break;
}
}
if (!found)
goto out;
rc = XIGetDeviceProperty(pInfo->dev,
prop_mode_groups,
@@ -3404,18 +3606,12 @@ update_mode_prop(InputInfoPtr pInfo,
if (rc != Success ||
val->format != 8 ||
val->size <= 0)
return;
goto out;
memcpy(groups, (unsigned char*)val->data, val->size);
group = libinput_event_tablet_pad_get_mode_group(event);
mode = libinput_event_tablet_pad_get_mode(event);
idx = libinput_tablet_pad_mode_group_get_index(group);
if (idx >= ARRAY_SIZE(groups))
return;
if (groups[idx] == mode)
return;
goto out;
groups[idx] = mode;
@@ -3428,8 +3624,36 @@ update_mode_prop(InputInfoPtr pInfo,
groups,
TRUE);
driver_data->allow_mode_group_updates = false;
if (rc != Success)
out:
libinput_tablet_pad_mode_group_unref(group);
free(state);
return TRUE;
}
static inline void
update_mode_prop(InputInfoPtr pInfo,
struct libinput_event_tablet_pad *event)
{
struct libinput_tablet_pad_mode_group *group;
struct mode_prop_state *state;
state = calloc(1, sizeof(*state));
if (!state)
return;
state->deviceid = pInfo->dev->id;
state->pInfo = pInfo;
group = libinput_event_tablet_pad_get_mode_group(event);
state->group = libinput_tablet_pad_mode_group_ref(group);
state->mode = libinput_event_tablet_pad_get_mode(event);
state->idx = libinput_tablet_pad_mode_group_get_index(group);
/* Schedule a WorkProc so we don't update from within the input
thread */
QueueWorkProc(update_mode_prop_cb, serverClient, state);
}
static inline BOOL
@@ -4351,6 +4575,9 @@ LibinputInitTapProperty(DeviceIntPtr dev,
{
BOOL tap = driver_data->options.tapping;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_tap_get_finger_count(device) == 0)
return;
@@ -4377,6 +4604,9 @@ LibinputInitTapDragProperty(DeviceIntPtr dev,
{
BOOL drag = driver_data->options.tap_drag;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_tap_get_finger_count(device) == 0)
return;
@@ -4401,6 +4631,9 @@ LibinputInitTapDragLockProperty(DeviceIntPtr dev,
{
BOOL drag_lock = driver_data->options.tap_drag_lock;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (libinput_device_config_tap_get_finger_count(device) == 0)
return;
@@ -4426,6 +4659,9 @@ LibinputInitTapButtonmapProperty(DeviceIntPtr dev,
enum libinput_config_tap_button_map map;
BOOL data[2] = {0};
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
map = driver_data->options.tap_button_map;
if (libinput_device_config_tap_get_finger_count(device) == 0)
@@ -4476,6 +4712,9 @@ LibinputInitCalibrationProperty(DeviceIntPtr dev,
{
float calibration[9];
if (!subdevice_has_capabilities(dev, CAP_POINTER|CAP_TOUCH|CAP_TABLET))
return;
if (!libinput_device_config_calibration_has_matrix(device))
return;
@@ -4513,6 +4752,9 @@ LibinputInitAccelProperty(DeviceIntPtr dev,
enum libinput_config_accel_profile profile;
BOOL profiles[2] = {FALSE};
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (!libinput_device_config_accel_is_available(device) ||
driver_data->capabilities & CAP_TABLET)
return;
@@ -4600,6 +4842,9 @@ LibinputInitNaturalScrollProperty(DeviceIntPtr dev,
{
BOOL natural_scroll = driver_data->options.natural_scrolling;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (!libinput_device_config_scroll_has_natural_scroll(device))
return;
@@ -4682,6 +4927,9 @@ LibinputInitLeftHandedProperty(DeviceIntPtr dev,
{
BOOL left_handed = driver_data->options.left_handed;
if (!subdevice_has_capabilities(dev, CAP_POINTER|CAP_TABLET))
return;
if (!libinput_device_config_left_handed_is_available(device) ||
driver_data->capabilities & CAP_TABLET)
return;
@@ -4709,6 +4957,9 @@ LibinputInitScrollMethodsProperty(DeviceIntPtr dev,
enum libinput_config_scroll_method method;
BOOL methods[3] = {FALSE};
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
scroll_methods = libinput_device_config_scroll_get_methods(device);
if (scroll_methods == LIBINPUT_CONFIG_SCROLL_NO_SCROLL)
return;
@@ -4796,6 +5047,9 @@ LibinputInitClickMethodsProperty(DeviceIntPtr dev,
enum libinput_config_click_method method;
BOOL methods[2] = {FALSE};
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
click_methods = libinput_device_config_click_get_methods(device);
if (click_methods == LIBINPUT_CONFIG_CLICK_METHOD_NONE)
return;
@@ -4864,6 +5118,9 @@ LibinputInitMiddleEmulationProperty(DeviceIntPtr dev,
{
BOOL middle = driver_data->options.middle_emulation;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (!libinput_device_config_middle_emulation_is_available(device))
return;
@@ -4890,6 +5147,9 @@ LibinputInitDisableWhileTypingProperty(DeviceIntPtr dev,
{
BOOL dwt = driver_data->options.disable_while_typing;
if (!subdevice_has_capabilities(dev, CAP_POINTER))
return;
if (!libinput_device_config_dwt_is_available(device))
return;
@@ -4922,6 +5182,9 @@ LibinputInitModeGroupProperties(DeviceIntPtr dev,
associations[MAX_BUTTONS] = {0};
int g, b, r, s;
if (!subdevice_has_capabilities(dev, CAP_TABLET_PAD))
return;
if (!libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TABLET_PAD))
return;
@@ -5176,17 +5439,17 @@ LibinputInitProperty(DeviceIntPtr dev)
LibinputInitTapDragProperty(dev, driver_data, device);
LibinputInitTapDragLockProperty(dev, driver_data, device);
LibinputInitTapButtonmapProperty(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);
LibinputInitDisableWhileTypingProperty(dev, driver_data, device);
LibinputInitScrollMethodsProperty(dev, driver_data, device);
LibinputInitClickMethodsProperty(dev, driver_data, device);
LibinputInitMiddleEmulationProperty(dev, driver_data, device);
LibinputInitDisableWhileTypingProperty(dev, driver_data, device);
LibinputInitModeGroupProperties(dev, driver_data, device);
LibinputInitRotationAngleProperty(dev, driver_data, device);
LibinputInitAccelProperty(dev, driver_data, device);
LibinputInitCalibrationProperty(dev, driver_data, device);
LibinputInitLeftHandedProperty(dev, driver_data, device);
LibinputInitModeGroupProperties(dev, driver_data, device);
LibinputInitSendEventsProperty(dev, driver_data, device);
/* Device node property, read-only */
device_node = driver_data->path;

View File

@@ -153,6 +153,13 @@ test_nonzero_x_linear(void)
assert(bezier[x] == 0);
} while (++x < size * 0.2 - 1);
/* ppc64le, ppc64, aarch64 have different math results at -O2,
resulting in one extra zero at the beginning of the array.
some other numbers are different too but within the error
margin (#99992) */
if (bezier[x] == 0)
x++;
do {
assert(bezier[x] > bezier[x-1]);
} while (++x < size * 0.8 - 1);