Retrofit event timestamps to all device events based on the frame

As we now buffer device frames we can apply the timestamp of the frame
event to all currently pending events.
This commit is contained in:
Peter Hutterer 2022-05-17 15:27:14 +10:00
parent 48bf74a5b9
commit b4da6738d3
7 changed files with 101 additions and 8 deletions

View file

@ -426,7 +426,19 @@ ei_event_touch_get_y(struct ei_event *event)
_public_ uint64_t
ei_event_get_time(struct ei_event *event)
{
require_event_type(event, 0, EI_EVENT_FRAME);
require_event_type(event, 0,
EI_EVENT_POINTER_MOTION,
EI_EVENT_POINTER_MOTION_ABSOLUTE,
EI_EVENT_POINTER_BUTTON,
EI_EVENT_POINTER_SCROLL,
EI_EVENT_POINTER_SCROLL_STOP,
EI_EVENT_POINTER_SCROLL_CANCEL,
EI_EVENT_POINTER_SCROLL_DISCRETE,
EI_EVENT_KEYBOARD_KEY,
EI_EVENT_TOUCH_DOWN,
EI_EVENT_TOUCH_UP,
EI_EVENT_TOUCH_MOTION,
EI_EVENT_FRAME);
return event->timestamp;
}

View file

@ -198,6 +198,37 @@ ei_dispatch(struct ei *ei)
sink_dispatch(ei->sink);
}
static void
update_event_timestamp(struct ei_event *event, uint64_t time)
{
switch (event->type) {
case EI_EVENT_POINTER_MOTION:
case EI_EVENT_POINTER_MOTION_ABSOLUTE:
case EI_EVENT_POINTER_BUTTON:
case EI_EVENT_POINTER_SCROLL:
case EI_EVENT_POINTER_SCROLL_STOP:
case EI_EVENT_POINTER_SCROLL_CANCEL:
case EI_EVENT_POINTER_SCROLL_DISCRETE:
case EI_EVENT_KEYBOARD_KEY:
case EI_EVENT_TOUCH_DOWN:
case EI_EVENT_TOUCH_UP:
case EI_EVENT_TOUCH_MOTION:
if (event->timestamp != 0) {
log_bug(ei_event_get_context(event),
"Unexpected timestamp for event of type: %s\n",
ei_event_type_to_string(event->type));
return;
}
event->timestamp = time;
break;
default:
log_bug(ei_event_get_context(event),
"Unexpected event %s in pending queue event\n",
ei_event_type_to_string(event->type));
return;
}
}
static void
queue_event(struct ei *ei, struct ei_event *event)
{
@ -227,6 +258,7 @@ queue_event(struct ei *ei, struct ei_event *event)
struct ei_event *pending;
list_for_each_safe(pending, &device->pending_event_queue, link) {
update_event_timestamp(pending, event->timestamp);
list_remove(&pending->link);
list_append(&ei->event_queue, &pending->link);
}

View file

@ -764,9 +764,9 @@ ei_event_get_device(struct ei_event *event);
/**
* Return the time for the event of type @ref EI_EVENT_FRAME in microseconds.
*
* @note: This function is currently only implemented for events of type @ref
* EI_EVENT_FRAME. In the future, it may become available to other event types
* too.
* @note: Only events of type @ref EI_EVENT_FRAME carry a timestamp. For
* convenience, the timestamp for other device events is retrofitted by this
* library.
*
* @return the event time in microseconds
*/

View file

@ -175,7 +175,19 @@ check_event_type(struct eis_event *event,
_public_ uint64_t
eis_event_get_time(struct eis_event *event)
{
require_event_type(event, 0, EIS_EVENT_FRAME);
require_event_type(event, 0,
EIS_EVENT_POINTER_MOTION,
EIS_EVENT_POINTER_MOTION_ABSOLUTE,
EIS_EVENT_POINTER_BUTTON,
EIS_EVENT_POINTER_SCROLL,
EIS_EVENT_POINTER_SCROLL_STOP,
EIS_EVENT_POINTER_SCROLL_CANCEL,
EIS_EVENT_POINTER_SCROLL_DISCRETE,
EIS_EVENT_KEYBOARD_KEY,
EIS_EVENT_TOUCH_DOWN,
EIS_EVENT_TOUCH_UP,
EIS_EVENT_TOUCH_MOTION,
EIS_EVENT_FRAME);
return event->timestamp;
}

View file

@ -135,6 +135,37 @@ eis_event_type_to_string(enum eis_event_type type)
assert(!"Unhandled event type");
}
static void
update_event_timestamp(struct eis_event *event, uint64_t time)
{
switch (event->type) {
case EIS_EVENT_POINTER_MOTION:
case EIS_EVENT_POINTER_MOTION_ABSOLUTE:
case EIS_EVENT_POINTER_BUTTON:
case EIS_EVENT_POINTER_SCROLL:
case EIS_EVENT_POINTER_SCROLL_STOP:
case EIS_EVENT_POINTER_SCROLL_CANCEL:
case EIS_EVENT_POINTER_SCROLL_DISCRETE:
case EIS_EVENT_KEYBOARD_KEY:
case EIS_EVENT_TOUCH_DOWN:
case EIS_EVENT_TOUCH_UP:
case EIS_EVENT_TOUCH_MOTION:
if (event->timestamp != 0) {
log_bug(eis_event_get_context(event),
"Unexpected timestamp for event of type: %s\n",
eis_event_type_to_string(event->type));
return;
}
event->timestamp = time;
break;
default:
log_bug(eis_event_get_context(event),
"Unexpected event %s in pending queue event\n",
eis_event_type_to_string(event->type));
return;
}
}
static void
eis_queue_event(struct eis_event *event)
{
@ -165,9 +196,11 @@ eis_queue_event(struct eis_event *event)
struct eis_event *pending;
list_for_each_safe(pending, &device->pending_event_queue, link) {
update_event_timestamp(pending, event->timestamp);
list_remove(&pending->link);
list_append(&eis->event_queue, &pending->link);
}
break;
}
default:

View file

@ -1047,9 +1047,9 @@ eis_event_get_device(struct eis_event *event);
/**
* Return the time for the event of type @ref EIS_EVENT_FRAME in microseconds.
*
* @note: This function is currently only implemented for events of type @ref
* EIS_EVENT_FRAME. In the future, it may become available to other event types
* too.
* @note: Only events of type @ref EIS_EVENT_FRAME carry a timestamp. For
* convenience, the timestamp for other device events is retrofitted by this
* library.
*
* @return the event time in microseconds
*/

View file

@ -1190,9 +1190,11 @@ MUNIT_TEST(test_ei_frame_timestamp)
uint64_t timestamp = eis_event_get_time(frame1);
munit_assert_uint64(timestamp, ==, ts1);
munit_assert_uint64(timestamp, ==, eis_event_get_time(kbd1));
timestamp = eis_event_get_time(frame2);
munit_assert_uint64(timestamp, ==, ts2);
munit_assert_uint64(timestamp, ==, eis_event_get_time(kbd2));
peck_assert_no_eis_events(eis);
}
@ -2156,9 +2158,11 @@ MUNIT_TEST(test_passive_ei_frame_timestamp)
uint64_t timestamp = ei_event_get_time(frame1);
munit_assert_uint64(timestamp, ==, ts1);
munit_assert_uint64(timestamp, ==, ei_event_get_time(kbd1));
timestamp = ei_event_get_time(frame2);
munit_assert_uint64(timestamp, ==, ts2);
munit_assert_uint64(timestamp, ==, ei_event_get_time(kbd2));
peck_assert_no_ei_events(ei);
}