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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
C23 auto is basically __auto_type so let's wrap it if our compiler
doesn't provide it (yet).
This lets us use `auto` as type specifier, e.g. compare
enum libinput_config_status status = libinput_device_config_set(...)
auto status = libinput_device_config_set(...)
Note that as of now meson will never detect this as it requires -std=c23
to be passed to the compiler. This flag is only supported by Clang 18
(released 2024) and we don't want to break things for older compilers
for what is a bit of a niche feature right now.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1181>
Before this patch, tp_filter_motion() was called twice in pointer motion
handler during 3fg drag, causing the pointer speed to be much faster
than during 1fg motion when the acceleration profile is adaptive.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1180>
Commit 48cd4c7287 ("tablet: track pressure ranges per tablet") added
tracking of pressure ranges per tablet by storing ranges for multiple
(up to 4) tablets in the tool. This doesn't scale well, had the
disadvantage of the range only being updated on out-of-proximity, and is
the wrong approach anyway.
Turns out we can update the pressure range on proximity in since we
haven't processed the pressure values yet at that stage. This gives us
better behavior when switching between tablet devices (including unplug)
as the pen will only lag behind once (when setting the range) instead
of once per new tablet.
However, since the offset (which is a tool issue) applies on top of the
pressure range (which is a tablet property) this requires that we now
track the offset as percent of the range.
So on proximity in we apply the new tablet range, then apply the e.g. 5%
pressure offset within this range.
This means we no longer have to track multiple tablets since it'll just
apply on the current tablet when in proximity.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1172>