mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-01-08 17:30:16 +01:00
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>
This commit is contained in:
parent
5698e3c12f
commit
83222a0798
4 changed files with 78 additions and 0 deletions
12
src/evdev.c
12
src/evdev.c
|
|
@ -1136,6 +1136,16 @@ evdev_device_dispatch_frame(struct libinput *libinput,
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
libinput_device_dispatch_frame(struct libinput_device *device,
|
||||
struct evdev_frame *frame)
|
||||
{
|
||||
struct libinput *libinput = libinput_device_get_context(device);
|
||||
struct evdev_device *dev = evdev_device(device);
|
||||
|
||||
evdev_device_dispatch_frame(libinput, dev, frame);
|
||||
}
|
||||
|
||||
static int
|
||||
evdev_sync_device(struct libinput *libinput,
|
||||
struct evdev_device *device)
|
||||
|
|
@ -2563,6 +2573,8 @@ evdev_device_create(struct libinput_seat *seat,
|
|||
|
||||
list_insert(seat->devices_list.prev, &device->base.link);
|
||||
|
||||
device->base.inject_evdev_frame = libinput_device_dispatch_frame;
|
||||
|
||||
evdev_notify_added_device(device);
|
||||
|
||||
return device;
|
||||
|
|
|
|||
|
|
@ -242,6 +242,15 @@ libinput_plugin_prepend_evdev_frame(struct libinput_plugin *plugin,
|
|||
frame);
|
||||
}
|
||||
|
||||
void
|
||||
libinput_plugin_inject_evdev_frame(struct libinput_plugin *plugin,
|
||||
struct libinput_device *device,
|
||||
struct evdev_frame *frame)
|
||||
{
|
||||
if (device->inject_evdev_frame)
|
||||
device->inject_evdev_frame(device, frame);
|
||||
}
|
||||
|
||||
void
|
||||
libinput_plugin_run(struct libinput_plugin *plugin)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -146,6 +146,60 @@ libinput_plugin_unref(struct libinput_plugin *plugin);
|
|||
DEFINE_UNREF_CLEANUP_FUNC(libinput_plugin);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Inject a new event frame from the given plugin. This
|
||||
* frame is treated as if it was just sent by the kernel's
|
||||
* event node and is processed immediately, interrupting
|
||||
* any other processing from this device.
|
||||
*
|
||||
* This function can be called any time but unlike
|
||||
* libinput_plugin_append_evdev_frame() and
|
||||
* libinput_plugin_prepend_evdev_frame() it starts
|
||||
* processing the frame at the bottom of the plugin
|
||||
* stack.
|
||||
*
|
||||
* The injected event will also be sent to
|
||||
* the current plugin, a guard needs to be in
|
||||
* place to prevent recursion.
|
||||
*
|
||||
* Injecting events may cause other plugins to
|
||||
* behave unexpectedly (see below). In almost all cases
|
||||
* it is better to use libinput_plugin_append_evdev_frame()
|
||||
* or libinput_plugin_prepend_evdev_frame() to only
|
||||
* affect the plugins logically *after* this
|
||||
* plugin.
|
||||
*
|
||||
* Assuming several plugins P1, P2, and P3 and
|
||||
* an event frame E, and P2 calling this function
|
||||
* with an injected event I:
|
||||
* - P1: receives E, optionally modifies E
|
||||
* - P2: receives E, injects I
|
||||
* - P1: receives I, optionally modifies I
|
||||
* - P2: receives I, optionally modifies I
|
||||
* - P3: receives I, optionally modifies I
|
||||
* - P2: continues processing E, optionally modifies E
|
||||
* - P3: receives E, optionally modifies E
|
||||
*
|
||||
* For P1 the injected event I is received after E,
|
||||
* for P3 the injected event I is received before E.
|
||||
*
|
||||
* An example for event injection being harmful:
|
||||
* A plugin may monitor tablet proximity state and prepent
|
||||
* proximity-in events if the tablet does not send proximity-in
|
||||
* events. This plugin stops monitoring events once it sees correct
|
||||
* proximity-in events.
|
||||
* If another plugin were to inject a proximity event (e.g. to fake a
|
||||
* different tool coming into proximity), the plugin would stop
|
||||
* monitoring. Future proximity events from the tablet will then
|
||||
* have the wrong proximity.
|
||||
* This can be avoided by appending or prepending the events instead
|
||||
* of injecting them.
|
||||
*/
|
||||
void
|
||||
libinput_plugin_inject_evdev_frame(struct libinput_plugin *libinput,
|
||||
struct libinput_device *device,
|
||||
struct evdev_frame *frame);
|
||||
|
||||
/**
|
||||
* Queue an event frame for the next plugin in sequence, after
|
||||
* the current event frame being processed.
|
||||
|
|
|
|||
|
|
@ -494,6 +494,9 @@ struct libinput_device {
|
|||
void *user_data;
|
||||
int refcount;
|
||||
struct libinput_device_config config;
|
||||
|
||||
void (*inject_evdev_frame)(struct libinput_device *device,
|
||||
struct evdev_frame *frame);
|
||||
};
|
||||
|
||||
enum libinput_tablet_tool_axis {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue