Add evdev_frame_append_one()

This is the most common usage, let's add a helper.

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1245>
This commit is contained in:
Peter Hutterer 2025-06-23 14:53:20 +10:00 committed by Marge Bot
parent af6f53d55c
commit 8141159beb
5 changed files with 78 additions and 37 deletions

View file

@ -476,6 +476,21 @@ evdev_frame_append(struct evdev_frame *frame,
return 0;
}
static inline int
evdev_frame_append_one(struct evdev_frame *frame, evdev_usage_t usage, int32_t value)
{
if (evdev_usage_eq(usage, EVDEV_SYN_REPORT))
return 0;
if (frame->count >= frame->max_size)
return -ENOMEM;
struct evdev_event *e = &frame->events[frame->count - 1];
*e = (struct evdev_event){ .usage = usage, .value = value };
frame->count++;
return 0;
}
static inline int
evdev_frame_append_input_event(struct evdev_frame *frame,
const struct input_event *event)

View file

@ -122,18 +122,14 @@ double_tool_plugin_filter_frame(struct libinput_plugin *plugin,
}
if (filter & (PEN_IN_PROX | PEN_OUT_OF_PROX)) {
struct evdev_event event = {
.usage = evdev_usage_from(EVDEV_BTN_TOOL_PEN),
.value = (filter & PEN_IN_PROX) ? 1 : 0,
};
evdev_frame_append(frame_out, &event, 1);
evdev_frame_append_one(frame_out,
evdev_usage_from(EVDEV_BTN_TOOL_PEN),
(filter & PEN_IN_PROX) ? 1 : 0);
}
if (filter & (ERASER_IN_PROX | ERASER_OUT_OF_PROX)) {
struct evdev_event event = {
.usage = evdev_usage_from(EVDEV_BTN_TOOL_RUBBER),
.value = (filter & ERASER_IN_PROX) ? 1 : 0,
};
evdev_frame_append(frame_out, &event, 1);
evdev_frame_append_one(frame_out,
evdev_usage_from(EVDEV_BTN_TOOL_RUBBER),
(filter & ERASER_IN_PROX) ? 1 : 0);
}
return frame_out;

View file

@ -209,26 +209,20 @@ eraser_button_insert_frame(struct plugin_device *device,
}
if (filter & (PEN_IN_PROX | PEN_OUT_OF_PROX)) {
struct evdev_event event = {
.usage = evdev_usage_from(EVDEV_BTN_TOOL_PEN),
.value = (filter & PEN_IN_PROX) ? 1 : 0,
};
evdev_frame_append(frame_out, &event, 1);
evdev_frame_append_one(frame_out,
evdev_usage_from(EVDEV_BTN_TOOL_PEN),
(filter & PEN_IN_PROX) ? 1 : 0);
}
if (filter & (ERASER_IN_PROX | ERASER_OUT_OF_PROX)) {
struct evdev_event event = {
.usage = evdev_usage_from(EVDEV_BTN_TOOL_RUBBER),
.value = (filter & ERASER_IN_PROX) ? 1 : 0,
};
evdev_frame_append(frame_out, &event, 1);
evdev_frame_append_one(frame_out,
evdev_usage_from(EVDEV_BTN_TOOL_RUBBER),
(filter & ERASER_IN_PROX) ? 1 : 0);
}
if (filter & (BUTTON_UP | BUTTON_DOWN)) {
assert(button != NULL);
struct evdev_event event = {
.usage = *button,
.value = (filter & BUTTON_DOWN) ? 1 : 0,
};
evdev_frame_append(frame_out, &event, 1);
evdev_frame_append_one(frame_out,
*button,
(filter & BUTTON_DOWN) ? 1 : 0);
}
evdev_frame_set_time(frame_out, evdev_frame_get_time(frame_in));

View file

@ -115,13 +115,9 @@ tablet_proximity_out_quirk_timer_func(struct libinput_plugin *plugin,
plugin_log_debug(device->parent->plugin,
"%s: forcing proximity out after timeout\n",
libinput_device_get_name(device->device));
const struct evdev_event prox_out_event = {
.usage = evdev_usage_from(EVDEV_BTN_TOOL_PEN),
.value = 0,
};
_unref_(evdev_frame) *prox_out_frame = evdev_frame_new(2);
evdev_frame_append(prox_out_frame, &prox_out_event, 1);
evdev_frame_append_one(prox_out_frame, evdev_usage_from(EVDEV_BTN_TOOL_PEN), 0);
evdev_frame_set_time(prox_out_frame, now);
libinput_plugin_prepend_evdev_frame(device->parent->plugin,
@ -215,16 +211,10 @@ proximity_timer_plugin_device_handle_frame(struct libinput_plugin *libinput_plug
return;
}
} else if (device->proximity_out_forced) {
struct evdev_event pen_in_event = {
.usage = evdev_usage_from(EVDEV_BTN_TOOL_PEN),
.value = 1,
};
plugin_log_debug(libinput_plugin,
"%s: forcing proximity in\n",
libinput_device_get_name(device->device));
evdev_frame_append(frame,
&pen_in_event,
1); /* libinput's event frame will have space */
evdev_frame_append_one(frame, evdev_usage_from(EVDEV_BTN_TOOL_PEN), 1);
device->proximity_out_forced = false;
proximity_timer_plugin_set_timer(device, time);
}

View file

@ -3005,6 +3005,52 @@ START_TEST(evdev_frames)
/* We never appended a timestamp */
litest_assert_int_eq(evdev_frame_get_time(frame), 0U);
}
{
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);
int rc = evdev_frame_append_one(frame, U(EVDEV_ABS_X), 1);
litest_assert_neg_errno_success(rc);
rc = evdev_frame_append_one(frame, U(EVDEV_ABS_Y), 2);
litest_assert_neg_errno_success(rc);
rc = evdev_frame_append_one(frame, U(EV_SYN), 0);
litest_assert_neg_errno_success(rc);
litest_assert_int_eq(evdev_frame_get_count(frame),
ARRAY_LENGTH(events));
litest_assert_int_eq(frame->max_size, ARRAY_LENGTH(events));
size_t nevents;
rc = memcmp(evdev_frame_get_events(frame, &nevents),
events,
sizeof(events));
litest_assert_int_eq(rc, 0);
litest_assert_int_eq(nevents, ARRAY_LENGTH(events));
/* Already full, can't append */
rc = evdev_frame_append_one(frame, U(EVDEV_ABS_Z), 1);
litest_assert_int_eq(rc, -ENOMEM);
/* Appending SYN_REPORT is a noop */
rc = evdev_frame_append_one(frame, U(EVDEV_SYN_REPORT), 0);
litest_assert_neg_errno_success(rc);
litest_assert_int_eq(evdev_frame_get_count(frame),
ARRAY_LENGTH(events));
litest_assert_int_eq(frame->max_size, ARRAY_LENGTH(events));
}
}
END_TEST