Commit graph

2534 commits

Author SHA1 Message Date
Peter Hutterer
8974a15178 util: add a bitmask_t type for bit masks
Previously we used uint32_t for bitmasks but having a custom type means
we're less likely to confuse an int value with a mask type.

Two types of API here, the u32 api for passing in masks and a bit API
for passing in single bits.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1218>
2025-06-18 19:38:14 +10:00
Peter Hutterer
905b4c6a4c evdev: implement our evdev device dispatch as plugin
This makes event handling easier where plugins queue other event frames
per frame. Our initialization guarantees that our evdev code is alway
the last plugin in the series so in the no-plugin case we just pass on
to that.

The effective event flow is now:
    evdev.c -> plugin1 -> plugin2 -> evdev-plugin.c -> evdev.c
except that no plugins exist yet.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1217>
2025-06-18 06:18:54 +00:00
Peter Hutterer
83222a0798 plugins: Add the ability for a plugin to inject evdev frames
This adds a callback for plugins (and lua plugins) to inject an evdev
frame into the event stream. Unlike the prepend/append functions
this one injects the event at the bottom of the plugin stack as if
the device had sent the frame right then and there.

There's a drawback though: the event frame isn't marked as synthetic
so it cannot be identified without having a guard in the plugin so
the same frame is not reprocessed.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1217>
2025-06-18 06:18:54 +00:00
Peter Hutterer
5698e3c12f plugin: wrap timers for use by plugins
Wrapping timers means plugins we can set up the event queue for a plugin
when the timer triggers, allowing plugins to queue events during the
timer func.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1217>
2025-06-18 06:18:54 +00:00
Peter Hutterer
e69c0b9bfb plugin: allow a prefix during event frame printing
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1217>
2025-06-18 06:18:54 +00:00
Peter Hutterer
7137eb9702 plugin: add ability to queue more events in the evdev_frame callback
This adds a event queue pointer to each plugin that is set when the
plugin's evdev_frame() callback is invoked. If the plugin calls
libinput_plugin_queue_event_frame() during the callback the given
event frame is appended to an event frame list (starting with the
current frame). Once the callback completes, that frame list is
passed to the next plugin and each frame is replayed on the next plugin.

In the case of multiple plugins queueing events this effectively builds
a tree of frames which each level of the tree representing one plugin.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1217>
2025-06-18 06:18:53 +00:00
Peter Hutterer
38d92a96b9 evdev: don't notify plugins about devices we will never add
We require ID_INPUT on any device we want to handle so let's filter any
device that is missing that property before we notify the plugins.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1217>
2025-06-18 06:18:53 +00:00
Peter Hutterer
3958ba44c2 Add an internal plugin system to libinput
This adds the scaffolding for an internal plugin architecture. No such
plugin currently exists and any plugin implemented against this
architecture merely is plugin-like in the event flow, not actually
external to libinput.

The goal of this architecture is to have more segmented processing
of the event stream from devices to modify that stream before libinput
ever sees it. Right now libinput looks at e.g. a tablet packet and then
determines whether the tool was correctly in proximity, etc.
With this architecture we can have a plugin that modifies the event
stream that the tool is *always* correctly in proximity and the tablet
backend itself merely needs to handle the correct case.

The event flow will thus logically change from:
   evdev device -> backend dispatch
to
   evdev device -> plugin1 -> plugin2 -> backend dispatch

The plugin API is more expansive than we will use immediately, it is the
result of several different implementation branches that all require
different functionality.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1217>
2025-06-18 06:18:53 +00:00
Peter Hutterer
7516dddeb3 util: fix a memleak for the dwtp string
Was assigned to dwt and any device with both dwt and dwtp would leak
that string.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1227>
2025-06-18 12:22:21 +10:00
Peter Hutterer
2dcfda2ebc util: add ANSI escape codes for rgb and background rgb
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1226>
2025-06-17 13:50:58 +10:00
Peter Hutterer
1850ea18f4 util: add safe_atou64 for 64-bit values
Copy/paste from safe_atou

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1226>
2025-06-17 13:50:58 +10:00
Peter Hutterer
76f88deb24 touchpad: remove a workaround for an old libevdev bug
Require libevdev 1.9, released in 2020.

Reverts commit 1e1b9c0e60 ("touchpad: never reduce the slot count to 0")

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1224>
2025-06-16 17:11:14 +10:00
Peter Hutterer
5d23794d53 tablet: disable smoothing for uinput devices
When a tablet was created via uinput we trust that the
tablet's events are preprocessed to the point where we
no longer need to apply smoothing to the axes.

Closes #1120

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1219>
2025-06-12 09:49:15 +00:00
Peter Hutterer
c4d0d2c09d Switch some uint32_t usage loops to use evdev_usage_next
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
1c5715fedf Use a newtype for the keycode, button code and pad button
This provides both some type-safety but also better readability of what
the integer we're passing around is supposed to be. In particular the
pad buttons are numeric buttons while the normal buttons are evdev
codes.

Future extension of this could be to also check for (or against) the
valid BTN_* ranges for a button code or keycode.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
c821bbd8e4 Drop struct input-event from dispatch->interface->process
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
28ee82b6f1 Switch the tablet pad backend to use struct evdev_event
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
4eb8ccb10d Switch the totem backend to struct evdev_event
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
56bad53f29 Switch the tablet backend to use struct evdev_event
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
4be243d0e7 Switch the fallback and touchpad backends to use struct evdev_event
These two use enough shared functions that they cannot be switched
separatly.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
41e988c99e Introduce our own evdev_event struct
In addition to the evdev_frame this struct is what contains our actual
events instead of a struct input_event. The goal of this is twofold:
slightly better memory usage per frame since we can skip the timestamp
and refer to the evdev frame's timestamp only. This also improves
handling a frame since we no longer need to care about updating
all events when the timestamp changes during appending events.

Secondly it merges the evdev type + code into a single "usage"
(term obviously and shamelessly stolen from HID). Those usages
are the same as the code names but with an extra EVDEV_ prepended,
i.e.  EV_SYN / SYN_REPORT becomes EVDEV_SYN_REPORT.

And they are wrapped in a newtype so passing it around provides
some typesafety.

This only switches one part of the processing over, the dispatch
interfaces still use a struct input_event

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
540605f8e4 evdev: use frame-based dispatching of events
Accumulate evdev events until we get a SYN_REPORT, then dispatch all
of those as a single event frame. This currently has little functional
change because we then just loop through the events anyway so it's just
an extra layer of indirection.

The size of the frame is hardcoded because we should never get anywhere
near than 64 events within any one evdev frame anyway (even 5 fingers
down with 10 properties for each touch point only get up to ~60 events
within one frame (5 * 10 + ~10 for the single-touch bits).

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Peter Hutterer
9f00f77bc4 Add an evdev_frame wrapper struct
The kernel only ever gives us a frame of events in one go (it flushes on
SYN_REPORT). We then need to look at that frame as a single state change
(keyboards excepted for historical reasons) so let's push this into a
proper struct we can pass around.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1215>
2025-06-12 18:20:40 +10:00
Ryan Hendrickson
8a95c0e3c8 wheel: add and use ignore_small_hi_res_movements
ignore_small_hi_res_movements is set to true if the underlying device is
not virtual.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1213>
2025-06-08 23:55:10 +00:00
Ryan Hendrickson
efb4b6a3be evdev: detect virtual devices
The quirk AttrIsVirtual takes precedence, if present. If not, use the
syspath of the event device to detect if it is virtual, as long as we
aren't running the test suite. (Test suite devices are all virtual, but
we should test them as if they aren't.)

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1213>
2025-06-08 23:55:10 +00:00
Peter Hutterer
49eb6cb8ab Move the log #defines and declarations to a separate header
Makes them easier to re-use as API

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1216>
2025-06-06 13:11:34 +10:00
Peter Hutterer
d9d4d92ff0 Move libinput_now() to our timer.c helper functions
This is just general cleanup so libinput_now() is easier to use without
needing to include libinput-private.h (which itself opens up most of
libinput's internals).

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1216>
2025-06-06 13:11:32 +10:00
Peter Hutterer
5774463dde tablet: shut up deprecated declarations warnings
No need to see those every time, #1137 now tracks this

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1214>
2025-06-06 11:00:04 +10:00
Peter Hutterer
46950de903 util: return early when listing files from a NULL directory list
For consistency with "no matching file found" return a single-null-entry
array.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1212>
2025-06-05 00:49:57 +00:00
Peter Hutterer
ec9c39da18 util: add a number of list helpers
The list_debug function is ifdef'd out, it'll be useful to debug
whenever we have some list corruption.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1209>
2025-06-03 09:10:15 +00:00
Peter Hutterer
57a0a219b0 evdev: Handle MSC_SERIAL better in the event log print
Print it as hex and align it better in the output

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1208>
2025-06-03 08:55:24 +00:00
Peter Hutterer
e91e1c3111 util: add a tmpdir helper
With the __attribute__(cleanup) helper this makes it simple
enough to provide a tempdir inside a function that is (recursively)
automatically deleted when the variable is deleted.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1204>
2025-05-26 05:22:33 +00:00
Peter Hutterer
91d4f9e58e util: add an rmdir_r helper function
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1204>
2025-05-26 05:22:33 +00:00
Peter Hutterer
efea8463fe util: add a helper to find files in a set of directories
Returns a number of paths for files with a given suffix in a
priority-sorted list of directories.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1204>
2025-05-26 05:22:33 +00:00
Peter Hutterer
95a417cefa util: add a helper to find substrings in a strv
Returns true and optionally the first index of any string in strv that
contains the given substring.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1204>
2025-05-26 05:22:33 +00:00
Peter Hutterer
6f28664854 util: move zalloc to util-mem.h
zalloc pre-dates util-mem.h but let's move it there, it makes more sense
than including util-strings.h.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1204>
2025-05-26 05:22:33 +00:00
Peter Hutterer
f653ce0a22 Fix links to point to the current doc pages
The underscored page names date back to doxygen and have been obsolete
for many years now.

Closes #1123

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1202>
2025-05-16 05:45:51 +00:00
Peter Hutterer
0e67cdc4ed gestures: rewrite the gesture state transition debugging code
Fixes a spurious compiler error in release builds:

cc -Ilibinput-plugin-test-suite.p -I. -I.. -I../src -I../include -I/usr/include/libevdev-1.0 -I/usr/include/libwacom-1.0 -I/usr/include/gudev-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/sysprof-6 -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu99 -O3 -Wno-unused-parameter -Wmissing-prototypes -Wstrict-prototypes -Wundef -Wlogical-op -Wpointer-arith -Wuninitialized -Winit-self -Wstrict-prototypes -Wimplicit-fallthrough -Wredundant-decls -Wincompatible-pointer-types -Wformat=2 -Wno-missing-field-initializers -Wmissing-declarations -fvisibility=hidden -Werror -pthread -MD -MQ libinput-plugin-test-suite.p/src_evdev-mt-touchpad-gestures.c.o -MF libinput-plugin-test-suite.p/src_evdev-mt-touchpad-gestures.c.o.d -o libinput-plugin-test-suite.p/src_evdev-mt-touchpad-gestures.c.o -c ../src/evdev-mt-touchpad-gestures.c
../src/evdev-mt-touchpad-gestures.c: In function ‘tp_gesture_handle_state’:
../src/evdev-mt-touchpad-gestures.c:1814:69: error: ‘%s’ directive argument is null [-Werror=format-truncation=]
 1814 |                         int n = snprintf(&buf[slen], remaining, " → %s", gesture_state_to_str(*s));
      |                                                                     ^~

Apparently because gesture_state_to_str() may return null (this cannot
happen in our code) it fails with an error here. So let's rewrite it to
use our strv helpers.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1201>
2025-05-11 23:51:10 +00:00
Peter Hutterer
04975b4618 Constify libinput_config_accel_set_points()
We copy the contents of the double array so let's constify this.

Fixes: 5324f425a1 ("Introduce custom acceleration profile")

Closes #1114

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1195>
2025-05-06 04:34:46 +00:00
Peter Hutterer
d400b17bee util: add the macros required for magic vararg expansion
A set of macros that expand to different things depending on the
number of arguments passed into the macro. Can be used for anything
but in the test case we use it to differ between stringifying the single
argument or taking a custom string for that same argument.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1188>
2025-04-28 10:05:52 +10:00
Peter Hutterer
6563b66a92 utils: add strv_find()
Finds and optionally returns the index of a string in a strv

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1193>
2025-04-24 17:34:06 +10:00
Peter Hutterer
b481170918 evdev: use autofree for the sysname
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1193>
2025-04-24 15:31:19 +10:00
Peter Hutterer
a19671d0da Use _unref_ for the udev handling in path and udev seat implementations
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
2025-04-16 17:04:58 +10:00
Peter Hutterer
cefab21e42 util: add an _unused_ macro and replace LIBINPUT_UNUSED
For annotating intentionally used variables it needs to be a bit
shorter, so let's replace the current one which was aimed at functions.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
2025-04-16 17:04:58 +10:00
Peter Hutterer
fbc8eb8cb7 quirks: use __attribute__(cleanup)
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
2025-04-16 17:04:58 +10:00
Peter Hutterer
d5e2bb1267 util: use cleanup in the event printing helpers
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
2025-04-16 17:04:58 +10:00
Peter Hutterer
bbbe757a26 Define a set of cleanup helpers
These are all data structs that are used in libinput and the tests,
let's declare them in a shared header so we can use them everywhere.

For udev and libevdev let's use an ifdef check for a known #define
so we don't have to add those deps everywhere.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
2025-04-16 17:04:58 +10:00
Peter Hutterer
ae423bc3fe util: define a cleanup for stringbuf
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
2025-04-16 17:04:58 +10:00
Peter Hutterer
829aec8055 util: add a list helper for handing a pointer to a list
Effectively a combination of list_append() and steal.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
2025-04-16 17:04:58 +10:00
Peter Hutterer
76c87d2486 util: add various helper functions to use __attribute__(cleanup)
Taken from libei, with slight modifications. The general approach is:
basic data types use _autofoo_ to call the maching foo function on
cleanup. Struct types use _unref_, _destory_, _free_, whichever applies
to that struct.

Notably: attribute syntax depends on where it's declared [1] so in the
following examles only a, b, and d have the autofree attribute:
   _autofree_ char *a, *b;
   char *c, _autofree *d;

Simplest way to ensure it's all correct to keep the declarations one per
line.

[1] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1184>
2025-04-16 17:04:58 +10:00