Switch our internal dispatch interface to take an evdev frame

No functional changes, all the actual interfaces now simply loop through
the frame instead of expecting the dispatcher to do so.

The mtdev code changed slightly since we can shortcut in the non-mtdev
case.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1245>
This commit is contained in:
Peter Hutterer 2025-06-23 15:06:36 +10:00 committed by Marge Bot
parent 8141159beb
commit a86a9aedd6
8 changed files with 165 additions and 89 deletions

View file

@ -1072,10 +1072,10 @@ fallback_handle_state(struct fallback_dispatch *dispatch,
} }
static void static void
fallback_interface_process(struct evdev_dispatch *evdev_dispatch, fallback_interface_process_event(struct evdev_dispatch *evdev_dispatch,
struct evdev_device *device, struct evdev_device *device,
struct evdev_event *event, struct evdev_event *event,
uint64_t time) uint64_t time)
{ {
struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch); struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch);
static bool warned = false; static bool warned = false;
@ -1111,6 +1111,20 @@ fallback_interface_process(struct evdev_dispatch *evdev_dispatch,
} }
} }
static void
fallback_interface_process(struct evdev_dispatch *dispatch,
struct evdev_device *device,
struct evdev_frame *frame,
uint64_t time)
{
size_t nevents;
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
for (size_t i = 0; i < nevents; i++) {
fallback_interface_process_event(dispatch, device, &events[i], time);
}
}
static void static void
cancel_touches(struct fallback_dispatch *dispatch, cancel_touches(struct fallback_dispatch *dispatch,
struct evdev_device *device, struct evdev_device *device,

View file

@ -1188,24 +1188,15 @@ tp_notify_clickpadbutton(struct tp_dispatch *tp,
/* If we've a trackpoint, send top buttons through the trackpoint */ /* If we've a trackpoint, send top buttons through the trackpoint */
if (tp->buttons.trackpoint) { if (tp->buttons.trackpoint) {
if (is_topbutton) { if (is_topbutton) {
_unref_(evdev_frame) *frame = evdev_frame_new(2);
struct evdev_dispatch *dispatch = struct evdev_dispatch *dispatch =
tp->buttons.trackpoint->dispatch; tp->buttons.trackpoint->dispatch;
int value = (state == LIBINPUT_BUTTON_STATE_PRESSED) ? 1 : 0; int value = (state == LIBINPUT_BUTTON_STATE_PRESSED) ? 1 : 0;
struct evdev_event event = { evdev_frame_set_time(frame, time);
.usage = button, evdev_frame_append_one(frame, button, value);
.value = value,
};
struct evdev_event syn_report = {
.usage = evdev_usage_from(EVDEV_SYN_REPORT),
.value = 0,
};
dispatch->interface->process(dispatch, dispatch->interface->process(dispatch,
tp->buttons.trackpoint, tp->buttons.trackpoint,
&event, frame,
time);
dispatch->interface->process(dispatch,
tp->buttons.trackpoint,
&syn_report,
time); time);
return 1; return 1;
} }

View file

@ -696,15 +696,11 @@ tp_process_trackpoint_button(struct tp_dispatch *tp,
return; return;
} }
struct evdev_event event = { .usage = button, .value = e->value }; _unref_(evdev_frame) *frame = evdev_frame_new(2);
struct evdev_event syn_report = { .usage = evdev_usage_from(EVDEV_SYN_REPORT), evdev_frame_append_one(frame, button, e->value);
.value = 0 }; evdev_frame_set_time(frame, time);
dispatch->interface->process(dispatch, tp->buttons.trackpoint, &event, time); dispatch->interface->process(dispatch, tp->buttons.trackpoint, frame, time);
dispatch->interface->process(dispatch,
tp->buttons.trackpoint,
&syn_report,
time);
} }
static void static void
@ -1854,10 +1850,10 @@ tp_debug_touch_state(struct tp_dispatch *tp, struct evdev_device *device)
} }
static void static void
tp_interface_process(struct evdev_dispatch *dispatch, tp_interface_process_event(struct evdev_dispatch *dispatch,
struct evdev_device *device, struct evdev_device *device,
struct evdev_event *e, struct evdev_event *e,
uint64_t time) uint64_t time)
{ {
struct tp_dispatch *tp = tp_dispatch(dispatch); struct tp_dispatch *tp = tp_dispatch(dispatch);
@ -1884,6 +1880,20 @@ tp_interface_process(struct evdev_dispatch *dispatch,
} }
} }
static void
tp_interface_process(struct evdev_dispatch *dispatch,
struct evdev_device *device,
struct evdev_frame *frame,
uint64_t time)
{
size_t nevents;
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
for (size_t i = 0; i < nevents; i++) {
tp_interface_process_event(dispatch, device, &events[i], time);
}
}
static void static void
tp_remove_sendevents(struct tp_dispatch *tp) tp_remove_sendevents(struct tp_dispatch *tp)
{ {

View file

@ -25,14 +25,15 @@
#include <mtdev-plumbing.h> #include <mtdev-plumbing.h>
#include "util-macros.h"
#include "util-mem.h" #include "util-mem.h"
#include "evdev-plugin.h" #include "evdev-plugin.h"
#include "evdev.h" #include "evdev.h"
_unused_ static inline void _unused_ static inline void
evdev_print_event(struct evdev_device *device, evdev_print_frame(struct evdev_device *device,
const struct evdev_event *e, struct evdev_frame *frame,
uint64_t time_in_us) uint64_t time_in_us)
{ {
static uint32_t offset = 0; static uint32_t offset = 0;
@ -46,50 +47,59 @@ evdev_print_event(struct evdev_device *device,
time -= offset; time -= offset;
switch (evdev_usage_enum(e->usage)) { size_t nevents;
case EVDEV_SYN_REPORT: struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
evdev_log_debug(
device,
"%u.%03u ----------------- EV_SYN ----------------- +%ums\n",
time / 1000,
time % 1000,
time - last_time);
last_time = time; for (size_t i = 0; i < nevents; i++) {
break; struct evdev_event *e = &events[i];
case EVDEV_MSC_SERIAL:
evdev_log_debug(device, switch (evdev_usage_enum(e->usage)) {
"%u.%03u %-16s %-16s %#010x\n", case EVDEV_SYN_REPORT:
evdev_log_debug(
device,
"%u.%03u ----------------- EV_SYN ----------------- +%ums\n",
time / 1000, time / 1000,
time % 1000, time % 1000,
evdev_event_get_type_name(e), time - last_time);
evdev_event_get_code_name(e),
e->value); last_time = time;
break; break;
default: case EVDEV_MSC_SERIAL:
evdev_log_debug(device, evdev_log_debug(device,
"%u.%03u %-16s %-20s %4d\n", "%u.%03u %-16s %-16s %#010x\n",
time / 1000, time / 1000,
time % 1000, time % 1000,
evdev_event_get_type_name(e), evdev_event_get_type_name(e),
evdev_event_get_code_name(e), evdev_event_get_code_name(e),
e->value); e->value);
break; break;
default:
evdev_log_debug(device,
"%u.%03u %-16s %-20s %4d\n",
time / 1000,
time % 1000,
evdev_event_get_type_name(e),
evdev_event_get_code_name(e),
e->value);
break;
}
} }
} }
static inline void static inline void
evdev_process_event(struct evdev_device *device, struct evdev_event *e, uint64_t time) evdev_process_frame(struct evdev_device *device,
struct evdev_frame *frame,
uint64_t time)
{ {
struct evdev_dispatch *dispatch = device->dispatch; struct evdev_dispatch *dispatch = device->dispatch;
#if EVENT_DEBUGGING #if EVENT_DEBUGGING
evdev_print_event(device, e, time); evdev_print_frame(device, frame, time);
#endif #endif
libinput_timer_flush(evdev_libinput_context(device), time); libinput_timer_flush(evdev_libinput_context(device), time);
dispatch->interface->process(dispatch, device, e, time); dispatch->interface->process(dispatch, device, frame, time);
} }
static inline void static inline void
@ -100,27 +110,36 @@ evdev_device_dispatch_frame(struct libinput_plugin *plugin,
struct evdev_device *device = evdev_device(libinput_device); struct evdev_device *device = evdev_device(libinput_device);
uint64_t time = evdev_frame_get_time(frame); uint64_t time = evdev_frame_get_time(frame);
size_t nevents; if (!device->mtdev) {
struct evdev_event *events = evdev_frame_get_events(frame, &nevents); evdev_process_frame(device, frame, time);
for (size_t i = 0; i < nevents; i++) { } else {
struct evdev_event *ev = &events[i]; size_t nevents;
if (!device->mtdev) { struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
evdev_process_event(device, ev, time); for (size_t i = 0; i < nevents; i++) {
} else { struct evdev_event *ev = &events[i];
struct input_event e = evdev_event_to_input_event(ev, time); struct input_event e = evdev_event_to_input_event(ev, time);
mtdev_put_event(device->mtdev, &e); mtdev_put_event(device->mtdev, &e);
if (evdev_usage_eq(ev->usage, EVDEV_SYN_REPORT)) { }
while (!mtdev_empty(device->mtdev)) {
struct input_event e;
mtdev_get_event(device->mtdev, &e); if (!mtdev_empty(device->mtdev)) {
_unref_(evdev_frame) *mtdev_frame = evdev_frame_new(256);
do {
struct input_event e;
uint64_t time; mtdev_get_event(device->mtdev, &e);
struct evdev_event ev = evdev_frame_append_input_event(mtdev_frame, &e);
evdev_event_from_input_event(&e, &time); if (e.type == EV_SYN && e.code == SYN_REPORT) {
evdev_process_event(device, &ev, time); evdev_frame_set_time(mtdev_frame,
input_event_time(&e));
evdev_process_frame(
device,
mtdev_frame,
evdev_frame_get_time(mtdev_frame));
/* mtdev can theoretically produce multiple
* frames */
mtdev_frame = evdev_frame_unref(mtdev_frame);
} }
} } while (!mtdev_empty(device->mtdev));
} }
} }

View file

@ -573,10 +573,10 @@ pad_flush(struct pad_dispatch *pad, struct evdev_device *device, uint64_t time)
} }
static void static void
pad_process(struct evdev_dispatch *dispatch, pad_process_event(struct evdev_dispatch *dispatch,
struct evdev_device *device, struct evdev_device *device,
struct evdev_event *e, struct evdev_event *e,
uint64_t time) uint64_t time)
{ {
struct pad_dispatch *pad = pad_dispatch(dispatch); struct pad_dispatch *pad = pad_dispatch(dispatch);
@ -607,6 +607,20 @@ pad_process(struct evdev_dispatch *dispatch,
} }
} }
static void
pad_process(struct evdev_dispatch *dispatch,
struct evdev_device *device,
struct evdev_frame *frame,
uint64_t time)
{
size_t nevents;
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
for (size_t i = 0; i < nevents; i++) {
pad_process_event(dispatch, device, &events[i], time);
}
}
static void static void
pad_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device) pad_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device)
{ {

View file

@ -2349,10 +2349,10 @@ tablet_reset_state(struct tablet_dispatch *tablet)
} }
static void static void
tablet_process(struct evdev_dispatch *dispatch, tablet_process_event(struct evdev_dispatch *dispatch,
struct evdev_device *device, struct evdev_device *device,
struct evdev_event *e, struct evdev_event *e,
uint64_t time) uint64_t time)
{ {
struct tablet_dispatch *tablet = tablet_dispatch(dispatch); struct tablet_dispatch *tablet = tablet_dispatch(dispatch);
@ -2384,6 +2384,20 @@ tablet_process(struct evdev_dispatch *dispatch,
} }
} }
static void
tablet_process(struct evdev_dispatch *dispatch,
struct evdev_device *device,
struct evdev_frame *frame,
uint64_t time)
{
size_t nevents;
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
for (size_t i = 0; i < nevents; i++) {
tablet_process_event(dispatch, device, &events[i], time);
}
}
static void static void
tablet_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device) tablet_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device)
{ {

View file

@ -511,10 +511,10 @@ totem_handle_state(struct totem_dispatch *totem, uint64_t time)
} }
static void static void
totem_interface_process(struct evdev_dispatch *dispatch, totem_process_event(struct evdev_dispatch *dispatch,
struct evdev_device *device, struct evdev_device *device,
struct evdev_event *e, struct evdev_event *e,
uint64_t time) uint64_t time)
{ {
struct totem_dispatch *totem = totem_dispatch(dispatch); struct totem_dispatch *totem = totem_dispatch(dispatch);
enum totem_slot_state global_state; enum totem_slot_state global_state;
@ -545,6 +545,20 @@ totem_interface_process(struct evdev_dispatch *dispatch,
} }
} }
static void
totem_interface_process(struct evdev_dispatch *dispatch,
struct evdev_device *device,
struct evdev_frame *frame,
uint64_t time)
{
size_t nevents;
struct evdev_event *events = evdev_frame_get_events(frame, &nevents);
for (size_t i = 0; i < nevents; i++) {
totem_process_event(dispatch, device, &events[i], time);
}
}
static void static void
totem_interface_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device) totem_interface_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device)
{ {

View file

@ -296,7 +296,7 @@ struct evdev_dispatch_interface {
/* Process an evdev input event. */ /* Process an evdev input event. */
void (*process)(struct evdev_dispatch *dispatch, void (*process)(struct evdev_dispatch *dispatch,
struct evdev_device *device, struct evdev_device *device,
struct evdev_event *event, struct evdev_frame *frame,
uint64_t time); uint64_t time);
/* Device is being suspended */ /* Device is being suspended */