From a86a9aedd6f6d556bb9f0b8c3856456036e535e6 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 23 Jun 2025 15:06:36 +1000 Subject: [PATCH] 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: --- src/evdev-fallback.c | 22 +++++-- src/evdev-mt-touchpad-buttons.c | 17 ++--- src/evdev-mt-touchpad.c | 34 ++++++---- src/evdev-plugin.c | 113 +++++++++++++++++++------------- src/evdev-tablet-pad.c | 22 +++++-- src/evdev-tablet.c | 22 +++++-- src/evdev-totem.c | 22 +++++-- src/evdev.h | 2 +- 8 files changed, 165 insertions(+), 89 deletions(-) diff --git a/src/evdev-fallback.c b/src/evdev-fallback.c index 223bb28b..13dcd8a9 100644 --- a/src/evdev-fallback.c +++ b/src/evdev-fallback.c @@ -1072,10 +1072,10 @@ fallback_handle_state(struct fallback_dispatch *dispatch, } static void -fallback_interface_process(struct evdev_dispatch *evdev_dispatch, - struct evdev_device *device, - struct evdev_event *event, - uint64_t time) +fallback_interface_process_event(struct evdev_dispatch *evdev_dispatch, + struct evdev_device *device, + struct evdev_event *event, + uint64_t time) { struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch); 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 cancel_touches(struct fallback_dispatch *dispatch, struct evdev_device *device, diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c index c53d8383..467fbf36 100644 --- a/src/evdev-mt-touchpad-buttons.c +++ b/src/evdev-mt-touchpad-buttons.c @@ -1188,24 +1188,15 @@ tp_notify_clickpadbutton(struct tp_dispatch *tp, /* If we've a trackpoint, send top buttons through the trackpoint */ if (tp->buttons.trackpoint) { if (is_topbutton) { + _unref_(evdev_frame) *frame = evdev_frame_new(2); struct evdev_dispatch *dispatch = tp->buttons.trackpoint->dispatch; int value = (state == LIBINPUT_BUTTON_STATE_PRESSED) ? 1 : 0; - struct evdev_event event = { - .usage = button, - .value = value, - }; - struct evdev_event syn_report = { - .usage = evdev_usage_from(EVDEV_SYN_REPORT), - .value = 0, - }; + evdev_frame_set_time(frame, time); + evdev_frame_append_one(frame, button, value); dispatch->interface->process(dispatch, tp->buttons.trackpoint, - &event, - time); - dispatch->interface->process(dispatch, - tp->buttons.trackpoint, - &syn_report, + frame, time); return 1; } diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 104bbfd2..f819a2ad 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -696,15 +696,11 @@ tp_process_trackpoint_button(struct tp_dispatch *tp, return; } - struct evdev_event event = { .usage = button, .value = e->value }; - struct evdev_event syn_report = { .usage = evdev_usage_from(EVDEV_SYN_REPORT), - .value = 0 }; + _unref_(evdev_frame) *frame = evdev_frame_new(2); + evdev_frame_append_one(frame, button, e->value); + evdev_frame_set_time(frame, time); - dispatch->interface->process(dispatch, tp->buttons.trackpoint, &event, time); - dispatch->interface->process(dispatch, - tp->buttons.trackpoint, - &syn_report, - time); + dispatch->interface->process(dispatch, tp->buttons.trackpoint, frame, time); } static void @@ -1854,10 +1850,10 @@ tp_debug_touch_state(struct tp_dispatch *tp, struct evdev_device *device) } static void -tp_interface_process(struct evdev_dispatch *dispatch, - struct evdev_device *device, - struct evdev_event *e, - uint64_t time) +tp_interface_process_event(struct evdev_dispatch *dispatch, + struct evdev_device *device, + struct evdev_event *e, + uint64_t time) { 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 tp_remove_sendevents(struct tp_dispatch *tp) { diff --git a/src/evdev-plugin.c b/src/evdev-plugin.c index 5d3e4e07..0a5ea831 100644 --- a/src/evdev-plugin.c +++ b/src/evdev-plugin.c @@ -25,14 +25,15 @@ #include +#include "util-macros.h" #include "util-mem.h" #include "evdev-plugin.h" #include "evdev.h" _unused_ static inline void -evdev_print_event(struct evdev_device *device, - const struct evdev_event *e, +evdev_print_frame(struct evdev_device *device, + struct evdev_frame *frame, uint64_t time_in_us) { static uint32_t offset = 0; @@ -46,50 +47,59 @@ evdev_print_event(struct evdev_device *device, time -= offset; - switch (evdev_usage_enum(e->usage)) { - case EVDEV_SYN_REPORT: - evdev_log_debug( - device, - "%u.%03u ----------------- EV_SYN ----------------- +%ums\n", - time / 1000, - time % 1000, - time - last_time); + size_t nevents; + struct evdev_event *events = evdev_frame_get_events(frame, &nevents); - last_time = time; - break; - case EVDEV_MSC_SERIAL: - evdev_log_debug(device, - "%u.%03u %-16s %-16s %#010x\n", + for (size_t i = 0; i < nevents; i++) { + struct evdev_event *e = &events[i]; + + switch (evdev_usage_enum(e->usage)) { + case EVDEV_SYN_REPORT: + evdev_log_debug( + device, + "%u.%03u ----------------- EV_SYN ----------------- +%ums\n", time / 1000, time % 1000, - evdev_event_get_type_name(e), - evdev_event_get_code_name(e), - e->value); - 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; + time - last_time); + + last_time = time; + break; + case EVDEV_MSC_SERIAL: + evdev_log_debug(device, + "%u.%03u %-16s %-16s %#010x\n", + time / 1000, + time % 1000, + evdev_event_get_type_name(e), + evdev_event_get_code_name(e), + e->value); + 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 -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; #if EVENT_DEBUGGING - evdev_print_event(device, e, time); + evdev_print_frame(device, frame, time); #endif 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 @@ -100,27 +110,36 @@ evdev_device_dispatch_frame(struct libinput_plugin *plugin, struct evdev_device *device = evdev_device(libinput_device); uint64_t time = evdev_frame_get_time(frame); - size_t nevents; - struct evdev_event *events = evdev_frame_get_events(frame, &nevents); - for (size_t i = 0; i < nevents; i++) { - struct evdev_event *ev = &events[i]; - if (!device->mtdev) { - evdev_process_event(device, ev, time); - } else { + if (!device->mtdev) { + evdev_process_frame(device, frame, time); + } else { + size_t nevents; + struct evdev_event *events = evdev_frame_get_events(frame, &nevents); + for (size_t i = 0; i < nevents; i++) { + struct evdev_event *ev = &events[i]; struct input_event e = evdev_event_to_input_event(ev, time); 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; - struct evdev_event ev = - evdev_event_from_input_event(&e, &time); - evdev_process_event(device, &ev, time); + mtdev_get_event(device->mtdev, &e); + evdev_frame_append_input_event(mtdev_frame, &e); + if (e.type == EV_SYN && e.code == SYN_REPORT) { + 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)); } } diff --git a/src/evdev-tablet-pad.c b/src/evdev-tablet-pad.c index 85036335..c1e387c5 100644 --- a/src/evdev-tablet-pad.c +++ b/src/evdev-tablet-pad.c @@ -573,10 +573,10 @@ pad_flush(struct pad_dispatch *pad, struct evdev_device *device, uint64_t time) } static void -pad_process(struct evdev_dispatch *dispatch, - struct evdev_device *device, - struct evdev_event *e, - uint64_t time) +pad_process_event(struct evdev_dispatch *dispatch, + struct evdev_device *device, + struct evdev_event *e, + uint64_t time) { 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 pad_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device) { diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index fc2480f2..a04a5b2d 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -2349,10 +2349,10 @@ tablet_reset_state(struct tablet_dispatch *tablet) } static void -tablet_process(struct evdev_dispatch *dispatch, - struct evdev_device *device, - struct evdev_event *e, - uint64_t time) +tablet_process_event(struct evdev_dispatch *dispatch, + struct evdev_device *device, + struct evdev_event *e, + uint64_t time) { 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 tablet_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device) { diff --git a/src/evdev-totem.c b/src/evdev-totem.c index 399a76e3..0e800a9e 100644 --- a/src/evdev-totem.c +++ b/src/evdev-totem.c @@ -511,10 +511,10 @@ totem_handle_state(struct totem_dispatch *totem, uint64_t time) } static void -totem_interface_process(struct evdev_dispatch *dispatch, - struct evdev_device *device, - struct evdev_event *e, - uint64_t time) +totem_process_event(struct evdev_dispatch *dispatch, + struct evdev_device *device, + struct evdev_event *e, + uint64_t time) { struct totem_dispatch *totem = totem_dispatch(dispatch); 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 totem_interface_suspend(struct evdev_dispatch *dispatch, struct evdev_device *device) { diff --git a/src/evdev.h b/src/evdev.h index 9f128f2c..d3aa7f0f 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -296,7 +296,7 @@ struct evdev_dispatch_interface { /* Process an evdev input event. */ void (*process)(struct evdev_dispatch *dispatch, struct evdev_device *device, - struct evdev_event *event, + struct evdev_frame *frame, uint64_t time); /* Device is being suspended */