From 41e988c99ed3d083e8f9e81672e75ff521742fd3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 5 Jun 2025 13:28:23 +1000 Subject: [PATCH] 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: --- meson.build | 1 + src/evdev-frame.h | 265 +++++++++++++++++++++++++++++++++++++---- src/evdev.c | 58 +++++---- src/util-input-event.h | 2 + test/test-utils.c | 92 ++++---------- 5 files changed, 299 insertions(+), 119 deletions(-) diff --git a/meson.build b/meson.build index afe7018b..16020204 100644 --- a/meson.build +++ b/meson.build @@ -303,6 +303,7 @@ foreach h: util_headers executable('test-build-@0@'.format(h), testfile, include_directories : [includes_src, includes_include], + dependencies: [dep_libevdev], install : false) endforeach diff --git a/src/evdev-frame.h b/src/evdev-frame.h index a0871416..82b3fedf 100644 --- a/src/evdev-frame.h +++ b/src/evdev-frame.h @@ -28,10 +28,223 @@ #include "util-mem.h" #include "util-input-event.h" +#include "util-newtype.h" #include #include +#define _evbit(t_, c_) ((t_) << 16 | (c_)) + +/** + * This is an enum to have the compiler help us a bit. + * The enum doesn't need to contain all event codes, only + * the ones we use in libinput - add to here as required. + * + * The order doesn't matter either since each enum value + * is just the type | code value anyway, keep it in somewhat + * logical groups where possible. + */ +enum evdev_usage { + EVDEV_SYN_REPORT = _evbit(EV_SYN, SYN_REPORT), + + EVDEV_KEY_RESERVED = _evbit(EV_KEY, KEY_RESERVED), + EVDEV_KEY_ESC= _evbit(EV_KEY, KEY_ESC), + EVDEV_KEY_MICMUTE = _evbit(EV_KEY, KEY_MICMUTE), + EVDEV_KEY_OK = _evbit(EV_KEY, KEY_OK), + EVDEV_KEY_LIGHTS_TOGGLE = _evbit(EV_KEY, KEY_LIGHTS_TOGGLE), + EVDEV_KEY_ALS_TOGGLE = _evbit(EV_KEY, KEY_ALS_TOGGLE), + EVDEV_KEY_MAX = _evbit(EV_KEY, KEY_MAX), + + EVDEV_BTN_LEFT = _evbit(EV_KEY, BTN_LEFT), + EVDEV_BTN_RIGHT = _evbit(EV_KEY, BTN_RIGHT), + EVDEV_BTN_MIDDLE = _evbit(EV_KEY, BTN_MIDDLE), + EVDEV_BTN_SIDE = _evbit(EV_KEY, BTN_SIDE), + EVDEV_BTN_EXTRA = _evbit(EV_KEY, BTN_EXTRA), + EVDEV_BTN_FORWARD = _evbit(EV_KEY, BTN_FORWARD), + EVDEV_BTN_BACK = _evbit(EV_KEY, BTN_BACK), + EVDEV_BTN_TASK = _evbit(EV_KEY, BTN_TASK), + + EVDEV_BTN_JOYSTICK = _evbit(EV_KEY, BTN_JOYSTICK), + + EVDEV_BTN_0 = _evbit(EV_KEY, BTN_0), + EVDEV_BTN_1 = _evbit(EV_KEY, BTN_1), + EVDEV_BTN_2 = _evbit(EV_KEY, BTN_2), + + EVDEV_BTN_STYLUS = _evbit(EV_KEY, BTN_STYLUS), + EVDEV_BTN_STYLUS2 = _evbit(EV_KEY, BTN_STYLUS2), + EVDEV_BTN_STYLUS3 = _evbit(EV_KEY, BTN_STYLUS3), + + EVDEV_BTN_TOUCH = _evbit(EV_KEY, BTN_TOUCH), + EVDEV_BTN_TOOL_PEN = _evbit(EV_KEY, BTN_TOOL_PEN), + EVDEV_BTN_TOOL_RUBBER = _evbit(EV_KEY, BTN_TOOL_RUBBER), + EVDEV_BTN_TOOL_BRUSH = _evbit(EV_KEY, BTN_TOOL_BRUSH), + EVDEV_BTN_TOOL_PENCIL = _evbit(EV_KEY, BTN_TOOL_PENCIL), + EVDEV_BTN_TOOL_AIRBRUSH = _evbit(EV_KEY, BTN_TOOL_AIRBRUSH), + EVDEV_BTN_TOOL_MOUSE = _evbit(EV_KEY, BTN_TOOL_MOUSE), + EVDEV_BTN_TOOL_LENS = _evbit(EV_KEY, BTN_TOOL_LENS), + EVDEV_BTN_TOOL_QUINTTAP = _evbit(EV_KEY, BTN_TOOL_QUINTTAP), + EVDEV_BTN_TOOL_DOUBLETAP = _evbit(EV_KEY, BTN_TOOL_DOUBLETAP), + EVDEV_BTN_TOOL_TRIPLETAP = _evbit(EV_KEY, BTN_TOOL_TRIPLETAP), + EVDEV_BTN_TOOL_QUADTAP = _evbit(EV_KEY, BTN_TOOL_QUADTAP), + EVDEV_BTN_TOOL_FINGER = _evbit(EV_KEY, BTN_TOOL_FINGER), + EVDEV_BTN_MISC = _evbit(EV_KEY, BTN_MISC), + EVDEV_BTN_GEAR_UP = _evbit(EV_KEY, BTN_GEAR_UP), + EVDEV_BTN_DPAD_UP = _evbit(EV_KEY, BTN_DPAD_UP), + EVDEV_BTN_DPAD_RIGHT = _evbit(EV_KEY, BTN_DPAD_RIGHT), + EVDEV_BTN_TRIGGER_HAPPY = _evbit(EV_KEY, BTN_TRIGGER_HAPPY), + EVDEV_BTN_TRIGGER_HAPPY40 = _evbit(EV_KEY, BTN_TRIGGER_HAPPY40), + + EVDEV_REL_X = _evbit(EV_REL, REL_X), + EVDEV_REL_Y = _evbit(EV_REL, REL_Y), + EVDEV_REL_WHEEL = _evbit(EV_REL, REL_WHEEL), + EVDEV_REL_WHEEL_HI_RES = _evbit(EV_REL, REL_WHEEL_HI_RES), + EVDEV_REL_HWHEEL = _evbit(EV_REL, REL_HWHEEL), + EVDEV_REL_HWHEEL_HI_RES = _evbit(EV_REL, REL_HWHEEL_HI_RES), + EVDEV_REL_DIAL = _evbit(EV_REL, REL_DIAL), + EVDEV_REL_MAX = _evbit(EV_REL, REL_MAX), + + EVDEV_ABS_X = _evbit(EV_ABS, ABS_X), + EVDEV_ABS_Y = _evbit(EV_ABS, ABS_Y), + EVDEV_ABS_Z = _evbit(EV_ABS, ABS_Z), + EVDEV_ABS_RX = _evbit(EV_ABS, ABS_RX), + EVDEV_ABS_RY = _evbit(EV_ABS, ABS_RY), + EVDEV_ABS_RZ = _evbit(EV_ABS, ABS_RZ), + EVDEV_ABS_PRESSURE = _evbit(EV_ABS, ABS_PRESSURE), + EVDEV_ABS_DISTANCE = _evbit(EV_ABS, ABS_DISTANCE), + EVDEV_ABS_THROTTLE = _evbit(EV_ABS, ABS_THROTTLE), + EVDEV_ABS_RUDDER = _evbit(EV_ABS, ABS_RUDDER), + EVDEV_ABS_WHEEL = _evbit(EV_ABS, ABS_WHEEL), + EVDEV_ABS_MISC = _evbit(EV_ABS, ABS_MISC), + EVDEV_ABS_TILT_X = _evbit(EV_ABS, ABS_TILT_X), + EVDEV_ABS_TILT_Y = _evbit(EV_ABS, ABS_TILT_Y), + + EVDEV_ABS_MT_SLOT = _evbit(EV_ABS, ABS_MT_SLOT), + EVDEV_ABS_MT_POSITION_X = _evbit(EV_ABS, ABS_MT_POSITION_X), + EVDEV_ABS_MT_POSITION_Y = _evbit(EV_ABS, ABS_MT_POSITION_Y), + EVDEV_ABS_MT_TOOL_TYPE = _evbit(EV_ABS, ABS_MT_TOOL_TYPE), + EVDEV_ABS_MT_TRACKING_ID = _evbit(EV_ABS, ABS_MT_TRACKING_ID), + EVDEV_ABS_MT_TOUCH_MAJOR = _evbit(EV_ABS, ABS_MT_TOUCH_MAJOR), + EVDEV_ABS_MT_TOUCH_MINOR = _evbit(EV_ABS, ABS_MT_TOUCH_MINOR), + EVDEV_ABS_MT_ORIENTATION = _evbit(EV_ABS, ABS_MT_ORIENTATION), + EVDEV_ABS_MT_PRESSURE = _evbit(EV_ABS, ABS_MT_PRESSURE), + EVDEV_ABS_MT_DISTANCE = _evbit(EV_ABS, ABS_MT_DISTANCE), + EVDEV_ABS_MAX = _evbit(EV_ABS, ABS_MAX), + + EVDEV_SW_LID = _evbit(EV_SW, SW_LID), + EVDEV_SW_TABLET_MODE = _evbit(EV_SW, SW_TABLET_MODE), + EVDEV_SW_MAX = _evbit(EV_SW, SW_MAX), + + EVDEV_MSC_SCAN = _evbit(EV_MSC, MSC_SCAN), + EVDEV_MSC_SERIAL = _evbit(EV_MSC, MSC_SERIAL), + EVDEV_MSC_TIMESTAMP = _evbit(EV_MSC, MSC_TIMESTAMP), +}; + +/** + * Declares evdev_usage_t as uint32_t wrapper that we + * use for passing event codes around. + * + * This way we can't accidentally mix up a code vs + * type or a random integer with what needs to be a usage. + */ +DECLARE_NEWTYPE(evdev_usage, uint32_t); + +static inline evdev_usage_t +evdev_usage_from(enum evdev_usage usage) +{ + return evdev_usage_from_uint32_t((uint32_t)usage); +} + +static inline enum evdev_usage +evdev_usage_enum(evdev_usage_t usage) +{ + return (enum evdev_usage)evdev_usage_as_uint32_t(usage); +} + +static inline evdev_usage_t +evdev_usage_from_code(unsigned int type, unsigned int code) +{ + return evdev_usage_from_uint32_t(_evbit(type, code)); +} + +static inline uint16_t +evdev_usage_type(evdev_usage_t usage) +{ + return evdev_usage_as_uint32_t(usage) >> 16; +} + +static inline uint16_t +evdev_usage_code(evdev_usage_t usage) +{ + return evdev_usage_as_uint32_t(usage) & 0xFFFF; +} + +static inline const char * +evdev_usage_code_name(evdev_usage_t usage) +{ + return libevdev_event_code_get_name(evdev_usage_type(usage), + evdev_usage_code(usage)); +} + +static inline const char * +evdev_usage_type_name(evdev_usage_t usage) +{ + return libevdev_event_type_get_name(evdev_usage_type(usage)); +} + +struct evdev_event { + /* this may be a value outside the known usages above but it's just an int */ + evdev_usage_t usage; + int32_t value; +}; + +static inline uint16_t +evdev_event_type(const struct evdev_event *e) +{ + return evdev_usage_type(e->usage); +} + +static inline uint16_t +evdev_event_code(const struct evdev_event *e) +{ + return evdev_usage_code(e->usage); +} + +static inline const char * +evdev_event_get_type_name(const struct evdev_event *e) +{ + return evdev_usage_type_name(e->usage); +} + +static inline const char * +evdev_event_get_code_name(const struct evdev_event *e) +{ + return evdev_usage_code_name(e->usage); +} + +static inline struct input_event +evdev_event_to_input_event(const struct evdev_event *e, uint64_t time) +{ + struct timeval tv = us2tv(time); + return (struct input_event) { + .type = evdev_event_type(e), + .code = evdev_event_code(e), + .value = e->value, + .input_event_sec = tv.tv_sec, + .input_event_usec = tv.tv_usec, + }; +} + +static inline struct evdev_event +evdev_event_from_input_event(const struct input_event *e, uint64_t *time) +{ + if (time) + *time = input_event_time(e); + return (struct evdev_event) { + .usage = evdev_usage_from_code(e->type, e->code), + .value = e->value, + }; +} + /** * A wrapper around a SYN_REPORT-terminated set of input events. * @@ -49,7 +262,8 @@ struct evdev_frame { int refcount; size_t max_size; size_t count; - struct input_event events[]; + uint64_t time; + struct evdev_event events[]; }; static inline struct evdev_frame * @@ -88,7 +302,7 @@ evdev_frame_get_count(const struct evdev_frame *frame) return frame->count; } -static inline struct input_event * +static inline struct evdev_event * evdev_frame_get_events(struct evdev_frame *frame, size_t *nevents) { if (nevents) @@ -103,24 +317,19 @@ evdev_frame_get_events(struct evdev_frame *frame, size_t *nevents) static inline void evdev_frame_set_time(struct evdev_frame *frame, uint64_t time) { - assert(frame->count > 0); - - for (size_t i = 0; i < frame->count; i++) - input_event_set_time(&frame->events[i], time); + frame->time = time; } static inline uint64_t evdev_frame_get_time(const struct evdev_frame *frame) { - assert(frame->count > 0); - - return input_event_time(&frame->events[frame->count - 1]); + return frame->time; } static inline int evdev_frame_reset(struct evdev_frame *frame) { - memset(frame->events, 0, frame->max_size * sizeof(struct input_event)); + memset(frame->events, 0, frame->max_size * sizeof(*frame->events)); frame->count = 1; /* SYN_REPORT is always there */ return 0; @@ -129,7 +338,7 @@ evdev_frame_reset(struct evdev_frame *frame) static inline struct evdev_frame * evdev_frame_new(size_t max_size) { - struct evdev_frame *frame = zalloc(max_size * sizeof(struct input_event) + sizeof(*frame)); + struct evdev_frame *frame = zalloc(max_size * sizeof(sizeof(*frame->events)) + sizeof(*frame)); frame->refcount = 1; frame->max_size = max_size; @@ -142,12 +351,12 @@ static inline struct evdev_frame * evdev_frame_new_on_stack(size_t max_size) { assert(max_size <= 64); - struct evdev_frame *frame = alloca(max_size * sizeof(struct input_event) + sizeof(*frame)); + struct evdev_frame *frame = alloca(max_size * sizeof(*frame->events) + sizeof(*frame)); frame->refcount = 1; frame->max_size = max_size; frame->count = 1; /* SYN_REPORT is always there */ - memset(frame->events, 0, max_size * sizeof(struct input_event)); + memset(frame->events, 0, max_size * sizeof(*frame->events)); return frame; } @@ -178,35 +387,41 @@ evdev_frame_new_on_stack(size_t max_size) */ static inline int evdev_frame_append(struct evdev_frame *frame, - const struct input_event *events, + const struct evdev_event *events, size_t nevents) { assert(nevents > 0); - uint64_t time = 0; - for (size_t i = 0; i < nevents; i++) { - if (events[i].type == EV_SYN && events[i].code == SYN_REPORT) { + if (evdev_usage_eq(events[i].usage, EVDEV_SYN_REPORT)) { nevents = i; - time = input_event_time(&events[i]); break; } - time = max(time, input_event_time(&events[i])); } if (nevents > 0) { if (frame->count + nevents > frame->max_size) return -ENOMEM; - memcpy(frame->events + frame->count - 1, events, nevents * sizeof(struct input_event)); + memcpy(frame->events + frame->count - 1, events, nevents * sizeof(*events)); frame->count += nevents; } - if (time) - evdev_frame_set_time(frame, time); return 0; } +static inline int +evdev_frame_append_input_event(struct evdev_frame *frame, + const struct input_event *event) +{ + struct evdev_event e = evdev_event_from_input_event(event, NULL); + if (evdev_usage_as_uint32_t(e.usage) == EVDEV_SYN_REPORT) { + uint64_t time = input_event_time(event); + evdev_frame_set_time(frame, time); + } + return evdev_frame_append(frame, &e, 1); +} + /** * Behaves like evdev_frame_append() but resets the frame before appending. * @@ -216,7 +431,7 @@ evdev_frame_append(struct evdev_frame *frame, */ static inline int evdev_frame_set(struct evdev_frame *frame, - const struct input_event *events, + const struct evdev_event *events, size_t nevents) { assert(nevents > 0); @@ -224,7 +439,7 @@ evdev_frame_set(struct evdev_frame *frame, size_t count = nevents; for (size_t i = 0; i < nevents; i++) { - if (events[i].type == EV_SYN && events[i].code == SYN_REPORT) { + if (evdev_usage_as_uint32_t(events[i].usage) == EVDEV_SYN_REPORT) { count = i; break; } @@ -241,7 +456,7 @@ static inline struct evdev_frame * evdev_frame_clone(struct evdev_frame *frame) { size_t nevents; - struct input_event *events = evdev_frame_get_events(frame, &nevents); + struct evdev_event *events = evdev_frame_get_events(frame, &nevents); struct evdev_frame *clone = evdev_frame_new(nevents); evdev_frame_append(clone, events, nevents); diff --git a/src/evdev.c b/src/evdev.c index eeb16533..77e9d409 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1027,11 +1027,12 @@ evdev_read_switch_reliability_prop(struct evdev_device *device) _unused_ static inline void evdev_print_event(struct evdev_device *device, - const struct input_event *e) + const struct evdev_event *e, + uint64_t time_in_us) { static uint32_t offset = 0; static uint32_t last_time = 0; - uint32_t time = us2ms(input_event_time(e)); + uint32_t time = us2ms(time_in_us); if (offset == 0) { offset = time; @@ -1040,7 +1041,8 @@ evdev_print_event(struct evdev_device *device, time -= offset; - if (libevdev_event_is_code(e, EV_SYN, SYN_REPORT)) { + switch (evdev_usage_enum(e->usage)) { + case EVDEV_SYN_REPORT: evdev_log_debug(device, "%u.%03u ----------------- EV_SYN ----------------- +%ums\n", time / 1000, @@ -1048,53 +1050,63 @@ evdev_print_event(struct evdev_device *device, time - last_time); last_time = time; - } else if (libevdev_event_is_code(e, EV_MSC, MSC_SERIAL)) { + break; + case EVDEV_MSC_SERIAL: evdev_log_debug(device, "%u.%03u %-16s %-16s %#010x\n", time / 1000, time % 1000, - libevdev_event_type_get_name(e->type), - libevdev_event_code_get_name(e->type, e->code), + evdev_event_get_type_name(e), + evdev_event_get_code_name(e), e->value); - } else { + break; + default: evdev_log_debug(device, "%u.%03u %-16s %-20s %4d\n", time / 1000, time % 1000, - libevdev_event_type_get_name(e->type), - libevdev_event_code_get_name(e->type, e->code), + 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 input_event *e) +evdev_process_event(struct evdev_device *device, + struct evdev_event *e, + uint64_t time) { struct evdev_dispatch *dispatch = device->dispatch; - uint64_t time = input_event_time(e); #if EVENT_DEBUGGING - evdev_print_event(device, e); + evdev_print_event(device, e, time); #endif libinput_timer_flush(evdev_libinput_context(device), time); - dispatch->interface->process(dispatch, device, e, time); + struct input_event ev = evdev_event_to_input_event(e, time); + dispatch->interface->process(dispatch, device, &ev, time); } static inline void evdev_device_dispatch_one(struct evdev_device *device, - struct input_event *ev) + struct evdev_event *ev, + uint64_t time) { if (!device->mtdev) { - evdev_process_event(device, ev); + evdev_process_event(device, ev, time); } else { - mtdev_put_event(device->mtdev, ev); - if (libevdev_event_is_code(ev, EV_SYN, SYN_REPORT)) { + 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); - evdev_process_event(device, &e); + + uint64_t time; + struct evdev_event ev = evdev_event_from_input_event(&e, &time); + evdev_process_event(device, &ev, time); } } } @@ -1105,10 +1117,10 @@ evdev_device_dispatch_frame(struct evdev_device *device, struct evdev_frame *frame) { size_t nevents; - struct input_event *events = evdev_frame_get_events(frame, &nevents); + struct evdev_event *events = evdev_frame_get_events(frame, &nevents); for (size_t i = 0; i < nevents; i++) { - evdev_device_dispatch_one(device, &events[i]); + evdev_device_dispatch_one(device, &events[i], evdev_frame_get_time(frame)); } } @@ -1127,7 +1139,7 @@ evdev_sync_device(struct evdev_device *device) break; /* No ENOMEM check here because >maxevents really should never happen */ - evdev_frame_append(frame, &ev, 1); + evdev_frame_append_input_event(frame, &ev); } while (rc == LIBEVDEV_READ_STATUS_SYNC); evdev_device_dispatch_frame(device, frame); @@ -1188,7 +1200,7 @@ evdev_device_dispatch(void *data) to the current state */ ev.code = SYN_REPORT; - if (evdev_frame_append(frame, &ev, 1) == -ENOMEM) { + if (evdev_frame_append_input_event(frame, &ev) == -ENOMEM) { evdev_log_bug_libinput(device, "event frame overflow, discarding events.\n"); } @@ -1204,7 +1216,7 @@ evdev_device_dispatch(void *data) once = true; } - if (evdev_frame_append(frame, &ev, 1) == -ENOMEM) { + if (evdev_frame_append_input_event(frame, &ev) == -ENOMEM) { evdev_log_bug_libinput(device, "event frame overflow, discarding events.\n"); } diff --git a/src/util-input-event.h b/src/util-input-event.h index b53ba208..9713b98c 100644 --- a/src/util-input-event.h +++ b/src/util-input-event.h @@ -27,9 +27,11 @@ #include "util-time.h" #include "util-mem.h" +#include "util-newtype.h" #include #include #include +#include static inline struct input_event input_event_init(uint64_t time, diff --git a/test/test-utils.c b/test/test-utils.c index e647b616..6400960b 100644 --- a/test/test-utils.c +++ b/test/test-utils.c @@ -2562,6 +2562,7 @@ END_TEST START_TEST(evdev_frames) { +#define U(u_) evdev_usage_from_uint32_t(u_) { evdev_frame_unref(NULL); /* unref on NULL is permitted */ } @@ -2574,21 +2575,21 @@ START_TEST(evdev_frames) } { _unref_(evdev_frame) *frame = evdev_frame_new(3); - struct input_event toobig[] = { - { .type = EV_ABS, .code = ABS_X, .value = 1, }, - { .type = EV_ABS, .code = ABS_Y, .value = 2, }, - { .type = EV_ABS, .code = ABS_Z, .value = 3, }, - { .type = EV_SYN, .code = SYN_REPORT, .value = 0, }, + struct evdev_event toobig[] = { + { .usage = U(EVDEV_ABS_X), .value = 1, }, + { .usage = U(EVDEV_ABS_Y), .value = 2, }, + { .usage = U(EVDEV_ABS_Z), .value = 3, }, + { .usage = U(EVDEV_SYN_REPORT), .value = 0, }, }; int rc = evdev_frame_set(frame, toobig, ARRAY_LENGTH(toobig)); litest_assert_int_eq(rc, -ENOMEM); } { - struct input_event events[] = { - { .type = EV_ABS, .code = ABS_X, .value = 1, }, - { .type = EV_ABS, .code = ABS_Y, .value = 2, }, - { .type = EV_SYN, .code = SYN_REPORT, .value = 0, }, + struct evdev_event events[] = { + { .usage = U(EVDEV_ABS_X), .value = 1, }, + { .usage = U(EVDEV_ABS_Y), .value = 2, }, + { .usage = U(EVDEV_SYN_REPORT), .value = 0, }, }; _unref_(evdev_frame) *frame = evdev_frame_new(3); @@ -2607,10 +2608,10 @@ START_TEST(evdev_frames) litest_assert_int_eq(rc, -ENOMEM); } { - struct input_event events[] = { - { .type = EV_ABS, .code = ABS_X, .value = 1, }, - { .type = EV_ABS, .code = ABS_Y, .value = 2, }, - { .type = EV_SYN, .code = SYN_REPORT, .value = 0, }, + struct evdev_event events[] = { + { .usage = U(EVDEV_ABS_X), .value = 1, }, + { .usage = U(EVDEV_ABS_Y), .value = 2, }, + { .usage = U(EVDEV_SYN_REPORT), .value = 0, }, }; _unref_(evdev_frame) *frame = evdev_frame_new(3); @@ -2625,13 +2626,13 @@ START_TEST(evdev_frames) litest_assert_int_eq(evdev_frame_get_count(frame), 3U); /* SYN_REPORT already there */ } { - struct input_event interrupted[] = { - { .type = EV_ABS, .code = ABS_X, .value = 1, }, - { .type = EV_ABS, .code = ABS_Y, .value = 2, }, - { .type = EV_SYN, .code = SYN_REPORT, .value = 0, }, - { .type = EV_ABS, .code = ABS_RX, .value = 1, }, - { .type = EV_ABS, .code = ABS_RY, .value = 2, }, - { .type = EV_SYN, .code = SYN_REPORT, .value = 0, }, + struct evdev_event interrupted[] = { + { .usage = U(EVDEV_ABS_X), .value = 1, }, + { .usage = U(EVDEV_ABS_Y), .value = 2, }, + { .usage = U(EVDEV_SYN_REPORT), .value = 0, }, + { .usage = U(EVDEV_ABS_RX), .value = 1, }, + { .usage = U(EVDEV_ABS_RY), .value = 2, }, + { .usage = U(EVDEV_SYN_REPORT), .value = 0, }, }; _unref_(evdev_frame) *frame = evdev_frame_new(5); @@ -2650,57 +2651,6 @@ START_TEST(evdev_frames) /* We never appended a timestamp */ litest_assert_int_eq(evdev_frame_get_time(frame), 0U); } - { - struct input_event e = { - .type = EV_ABS, - .code = ABS_X, - .value = 1, - .input_event_sec = 1234, - .input_event_usec = 567, - - }; - - _unref_(evdev_frame) *frame = evdev_frame_new(3); - litest_assert_int_eq(evdev_frame_get_time(frame), 0U); - - evdev_frame_append(frame, &e, 1); - litest_assert_int_eq(evdev_frame_get_time(frame), 1234000567U); - evdev_frame_append(frame, &e, 1); - litest_assert_int_eq(evdev_frame_get_time(frame), 1234000567U); - - struct input_event syn = { - .type = EV_SYN, - .code = SYN_REPORT, - .value = 0, - .input_event_sec = 111, - .input_event_usec = 333, - - }; - - litest_assert_neg_errno_success(evdev_frame_append(frame, &syn, 1)); - litest_assert_int_eq(evdev_frame_get_time(frame), 111000333U); - - /* SYN_REPORT overwrites lower timestamp */ - syn.input_event_usec = 111; - litest_assert_neg_errno_success(evdev_frame_append(frame, &syn, 1)); - litest_assert_int_eq(evdev_frame_get_time(frame), 111000111U); - } - { - /* Expect highest timestamp */ - _unref_(evdev_frame) *frame = evdev_frame_new(4); - struct input_event mixed_times[] = { - { .type = EV_ABS, .code = ABS_X, .value = 1, .input_event_sec = 12, .input_event_usec = 700, }, - { .type = EV_ABS, .code = ABS_Y, .value = 2, .input_event_sec = 56, .input_event_usec = 800, }, - { .type = EV_ABS, .code = ABS_Z, .value = 3, .input_event_sec = 34, .input_event_usec = 900, }, - { .type = EV_SYN, .code = SYN_REPORT, .value = 0, .input_event_sec = 0, .input_event_usec = 1, }, - }; - evdev_frame_set(frame, mixed_times, 3); - litest_assert_int_eq(evdev_frame_get_time(frame), 56000800U); - - /* but SYN_REPORT overwrites any other timestamp */ - evdev_frame_set(frame, mixed_times, 4); - litest_assert_int_eq(evdev_frame_get_time(frame), 1U); - } } END_TEST