summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2021-03-26 13:40:21 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2021-03-30 09:02:31 +1000
commit33b30d463137db6549e0e3208cbd1ce66a492bd3 (patch)
tree43e9b36aadeb6f395c8255a198f5ec31d5adb741
parentbacf4e5a62d3a243f23b91c18a4cc0816ceeab51 (diff)
downloadlibinput-33b30d463137db6549e0e3208cbd1ce66a492bd3.tar.gz
tools/record: rework the event printing
For historical (but not very good) reasons, libinput record printed events from the first device to the output file (or stdout) and buffered everything else. On ctrl+c, the other devices' descriptions and the buffered events were appended to the output file. This makes the printing code rather complex. Simplify it by giving each device a separate FILE* - the first device points to the real output file, the others to a tempfile. On Ctrl+C we just append those tempfiles to the real output file one-by-one and done. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--tools/libinput-record.c966
1 files changed, 407 insertions, 559 deletions
diff --git a/tools/libinput-record.c b/tools/libinput-record.c
index d1472fe0..45fb02d7 100644
--- a/tools/libinput-record.c
+++ b/tools/libinput-record.c
@@ -74,32 +74,8 @@ enum indent {
I_EVENT = 6, /* event data */
};
-
-/* libinput is not designed to keep events past immediate use so we need to
- * cache our events. Simplest way to do this is to just cache the printf
- * output */
-struct li_event {
- char msg[256];
-};
-
-enum event_type {
- NONE,
- EVDEV,
- LIBINPUT,
- COMMENT,
-};
-
-struct event {
- enum event_type type;
- uint64_t time;
- union {
- struct input_event evdev;
- struct li_event libinput;
- char comment[200];
- } u;
-};
-
struct record_device {
+ struct record_context *ctx;
struct list link;
char *devnode; /* device node of the source device */
struct libevdev *evdev;
@@ -107,15 +83,13 @@ struct record_device {
deltas */
struct libinput_device *device;
- struct event *events;
- size_t nevents;
- size_t events_sz;
-
struct {
bool is_touch_device;
uint16_t slot_state;
uint16_t last_slot_state;
} touch;
+
+ FILE *fp;
};
struct record_context {
@@ -133,10 +107,8 @@ struct record_context {
struct {
char *name; /* file name given on cmdline */
char *name_with_suffix; /* full file name with suffix */
- FILE *fp;
} output_file;
-
struct libinput *libinput;
int epoll_fd;
@@ -160,14 +132,6 @@ struct record_context {
(sz_) = new_size; \
}
-static struct event *
-next_event(struct record_device *d)
-{
- if (d->nevents == d->events_sz)
- resize(d->events, d->events_sz);
- return &d->events[d->nevents++];
-}
-
typedef void (*source_dispatch_t)(struct record_context *ctx,
int fd,
void *user_data);
@@ -205,7 +169,7 @@ obfuscate_keycode(struct input_event *ev)
*/
LIBINPUT_ATTRIBUTE_PRINTF(3, 4)
static void
-iprintf(const struct record_context *ctx,
+iprintf(FILE *fp,
enum indent indent,
const char *format, ...)
{
@@ -229,7 +193,7 @@ iprintf(const struct record_context *ctx,
snprintf(fmt, sizeof(fmt), "%s%s", &space[len - indent - 1], format);
va_start(args, format);
- rc = vfprintf(ctx->output_file.fp, fmt, args);
+ rc = vfprintf(fp, fmt, args);
va_end(args);
assert(rc != -1 && (unsigned int)rc > indent);
@@ -242,19 +206,18 @@ time_offset(struct record_context *ctx, uint64_t time)
}
static void
-print_evdev_event(struct record_context *ctx,
- struct record_device *dev,
+print_evdev_event(struct record_device *dev,
struct input_event *ev)
{
const char *tname, *cname;
bool was_modified = false;
char desc[1024];
- uint64_t time = input_event_time(ev) - ctx->offset;
+ uint64_t time = input_event_time(ev) - dev->ctx->offset;
input_event_set_time(ev, time);
/* Don't leak passwords unless the user wants to */
- if (!ctx->show_keycodes)
+ if (!dev->ctx->show_keycodes)
was_modified = obfuscate_keycode(ev);
tname = libevdev_event_type_get_name(ev->type);
@@ -370,7 +333,7 @@ print_evdev_event(struct record_context *ctx,
was_modified ? " (obfuscated)" : "");
}
- iprintf(ctx,
+ iprintf(dev->fp,
I_EVENT,
"- [%3lu, %6u, %3d, %3d, %7d] # %s\n",
ev->input_event_sec,
@@ -381,30 +344,25 @@ print_evdev_event(struct record_context *ctx,
desc);
}
-static size_t
-handle_evdev_frame(struct record_context *ctx, struct record_device *d)
+static bool
+handle_evdev_frame(struct record_device *d)
{
struct libevdev *evdev = d->evdev;
struct input_event e;
- size_t count = 0;
- uint32_t last_time = 0;
- struct event *event;
- while (libevdev_next_event(evdev,
- LIBEVDEV_READ_FLAG_NORMAL,
- &e) == LIBEVDEV_READ_STATUS_SUCCESS) {
- uint64_t time = input_event_time(&e);
+ if (libevdev_next_event(evdev, LIBEVDEV_READ_FLAG_NORMAL, &e) !=
+ LIBEVDEV_READ_STATUS_SUCCESS)
+ return false;
- if (ctx->offset == 0)
- ctx->offset = time;
- else
- time = time_offset(ctx, time);
+ iprintf(d->fp, I_EVENTTYPE, "- evdev:\n");
+ do {
- event = next_event(d);
- event->type = EVDEV;
- event->time = time;
- event->u.evdev = e;
- count++;
+ if (d->ctx->offset == 0) {
+ uint64_t time = input_event_time(&e);
+ d->ctx->offset = time;
+ }
+
+ print_evdev_event(d, &e);
if (d->touch.is_touch_device &&
e.type == EV_ABS &&
@@ -418,35 +376,29 @@ handle_evdev_frame(struct record_context *ctx, struct record_device *d)
d->touch.slot_state &= ~(1 << slot);
}
- last_time = event->time;
-
if (e.type == EV_SYN && e.code == SYN_REPORT)
break;
- }
+ } while (libevdev_next_event(evdev,
+ LIBEVDEV_READ_FLAG_NORMAL,
+ &e) == LIBEVDEV_READ_STATUS_SUCCESS);
if (d->touch.slot_state != d->touch.last_slot_state) {
d->touch.last_slot_state = d->touch.slot_state;
if (d->touch.slot_state == 0) {
- event = next_event(d);
- event->type = COMMENT;
- event->time = last_time;
- snprintf(event->u.comment,
- sizeof(event->u.comment),
+ iprintf(d->fp,
+ I_EVENT,
" # Touch device in neutral state\n");
- count++;
}
}
- return count;
+ return true;
}
static void
-buffer_device_notify(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_device_notify(struct record_device *dev, struct libinput_event *e)
{
- struct libinput_device *dev = libinput_event_get_device(e);
- struct libinput_seat *seat = libinput_device_get_seat(dev);
+ struct libinput_device *d = libinput_event_get_device(e);
+ struct libinput_seat *seat = libinput_device_get_seat(d);
const char *type = NULL;
switch(libinput_event_get_type(e)) {
@@ -460,19 +412,16 @@ buffer_device_notify(struct record_context *ctx,
abort();
}
- event->time = 0;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{type: %s, seat: %5s, logical_seat: %7s}",
- type,
- libinput_seat_get_physical_name(seat),
- libinput_seat_get_logical_name(seat));
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {type: %s, seat: %5s, logical_seat: %7s}\n",
+ type,
+ libinput_seat_get_physical_name(seat),
+ libinput_seat_get_logical_name(seat));
}
static void
-buffer_key_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_key_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_keyboard *k = libinput_event_get_keyboard_event(e);
enum libinput_key_state state;
@@ -488,29 +437,26 @@ buffer_key_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_keyboard_get_time_usec(k));
+ time = time_offset(dev->ctx, libinput_event_keyboard_get_time_usec(k));
state = libinput_event_keyboard_get_key_state(k);
key = libinput_event_keyboard_get_key(k);
- if (!ctx->show_keycodes &&
+ if (!dev->ctx->show_keycodes &&
(key >= KEY_ESC && key < KEY_ZENKAKUHANKAKU))
key = -1;
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, key: %d, state: %s}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- key,
- state == LIBINPUT_KEY_STATE_PRESSED ? "pressed" : "released");
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, key: %d, state: %s}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ key,
+ state == LIBINPUT_KEY_STATE_PRESSED ? "pressed" : "released");
}
static void
-buffer_motion_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_motion_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_pointer *p = libinput_event_get_pointer_event(e);
double x = libinput_event_pointer_get_dx(p),
@@ -528,22 +474,19 @@ buffer_motion_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_pointer_get_time_usec(p));
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, delta: [%6.2f, %6.2f], unaccel: [%6.2f, %6.2f]}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- x, y,
- uax, uay);
+ time = time_offset(dev->ctx, libinput_event_pointer_get_time_usec(p));
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, delta: [%6.2f, %6.2f], unaccel: [%6.2f, %6.2f]}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ x, y,
+ uax, uay);
}
static void
-buffer_absmotion_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_absmotion_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_pointer *p = libinput_event_get_pointer_event(e);
double x = libinput_event_pointer_get_absolute_x(p),
@@ -561,23 +504,20 @@ buffer_absmotion_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_pointer_get_time_usec(p));
+ time = time_offset(dev->ctx, libinput_event_pointer_get_time_usec(p));
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, point: [%6.2f, %6.2f], transformed: [%6.2f, %6.2f]}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- x, y,
- tx, ty);
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, point: [%6.2f, %6.2f], transformed: [%6.2f, %6.2f]}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ x, y,
+ tx, ty);
}
static void
-buffer_pointer_button_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_pointer_button_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_pointer *p = libinput_event_get_pointer_event(e);
enum libinput_button_state state;
@@ -593,26 +533,23 @@ buffer_pointer_button_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_pointer_get_time_usec(p));
+ time = time_offset(dev->ctx, libinput_event_pointer_get_time_usec(p));
button = libinput_event_pointer_get_button(p);
state = libinput_event_pointer_get_button_state(p);
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, button: %d, state: %s, seat_count: %u}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- button,
- state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released",
- libinput_event_pointer_get_seat_button_count(p));
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, button: %d, state: %s, seat_count: %u}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ button,
+ state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released",
+ libinput_event_pointer_get_seat_button_count(p));
}
static void
-buffer_pointer_axis_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_pointer_axis_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_pointer *p = libinput_event_get_pointer_event(e);
uint64_t time;
@@ -628,7 +565,7 @@ buffer_pointer_axis_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_pointer_get_time_usec(p));
+ time = time_offset(dev->ctx, libinput_event_pointer_get_time_usec(p));
if (libinput_event_pointer_has_axis(p,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL)) {
h = libinput_event_pointer_get_axis_value(p,
@@ -653,22 +590,19 @@ buffer_pointer_axis_event(struct record_context *ctx,
break;
}
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, axes: [%2.2f, %2.2f], discrete: [%d, %d], source: %s}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- h, v,
- hd, vd,
- source);
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, axes: [%2.2f, %2.2f], discrete: [%d, %d], source: %s}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ h, v,
+ hd, vd,
+ source);
}
static void
-buffer_touch_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_touch_event(struct record_device *dev, struct libinput_event *e)
{
enum libinput_event_type etype = libinput_event_get_type(e);
struct libinput_event_touch *t = libinput_event_get_touch_event(e);
@@ -698,22 +632,21 @@ buffer_touch_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_touch_get_time_usec(t));
+ time = time_offset(dev->ctx, libinput_event_touch_get_time_usec(t));
if (etype != LIBINPUT_EVENT_TOUCH_FRAME) {
slot = libinput_event_touch_get_slot(t);
seat_slot = libinput_event_touch_get_seat_slot(t);
}
- event->time = time;
switch (etype) {
case LIBINPUT_EVENT_TOUCH_FRAME:
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type);
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type);
break;
case LIBINPUT_EVENT_TOUCH_DOWN:
case LIBINPUT_EVENT_TOUCH_MOTION:
@@ -721,27 +654,28 @@ buffer_touch_event(struct record_context *ctx,
y = libinput_event_touch_get_y(t);
tx = libinput_event_touch_get_x_transformed(t, 100);
ty = libinput_event_touch_get_y_transformed(t, 100);
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, slot: %d, seat_slot: %d, point: [%6.2f, %6.2f], transformed: [%6.2f, %6.2f]}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- slot,
- seat_slot,
- x, y,
- tx, ty);
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, slot: %d, seat_slot: %d, "
+ "point: [%6.2f, %6.2f], transformed: [%6.2f, %6.2f]}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ slot,
+ seat_slot,
+ x, y,
+ tx, ty);
break;
case LIBINPUT_EVENT_TOUCH_UP:
case LIBINPUT_EVENT_TOUCH_CANCEL:
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, slot: %d, seat_slot: %d}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- slot,
- seat_slot);
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, slot: %d, seat_slot: %d}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ slot,
+ seat_slot);
break;
default:
abort();
@@ -749,9 +683,7 @@ buffer_touch_event(struct record_context *ctx,
}
static void
-buffer_gesture_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_gesture_event(struct record_device *dev, struct libinput_event *e)
{
enum libinput_event_type etype = libinput_event_get_type(e);
struct libinput_event_gesture *g = libinput_event_get_gesture_event(e);
@@ -781,46 +713,45 @@ buffer_gesture_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_gesture_get_time_usec(g));
- event->time = time;
+ time = time_offset(dev->ctx, libinput_event_gesture_get_time_usec(g));
switch (etype) {
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
case LIBINPUT_EVENT_GESTURE_PINCH_END:
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, nfingers: %d, "
- "delta: [%6.2f, %6.2f], unaccel: [%6.2f, %6.2f], "
- "angle_delta: %6.2f, scale: %6.2f}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- libinput_event_gesture_get_finger_count(g),
- libinput_event_gesture_get_dx(g),
- libinput_event_gesture_get_dy(g),
- libinput_event_gesture_get_dx_unaccelerated(g),
- libinput_event_gesture_get_dy_unaccelerated(g),
- libinput_event_gesture_get_angle_delta(g),
- libinput_event_gesture_get_scale(g)
- );
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, nfingers: %d, "
+ "delta: [%6.2f, %6.2f], unaccel: [%6.2f, %6.2f], "
+ "angle_delta: %6.2f, scale: %6.2f}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ libinput_event_gesture_get_finger_count(g),
+ libinput_event_gesture_get_dx(g),
+ libinput_event_gesture_get_dy(g),
+ libinput_event_gesture_get_dx_unaccelerated(g),
+ libinput_event_gesture_get_dy_unaccelerated(g),
+ libinput_event_gesture_get_angle_delta(g),
+ libinput_event_gesture_get_scale(g)
+ );
break;
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, nfingers: %d, "
- "delta: [%6.2f, %6.2f], unaccel: [%6.2f, %6.2f]}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- libinput_event_gesture_get_finger_count(g),
- libinput_event_gesture_get_dx(g),
- libinput_event_gesture_get_dy(g),
- libinput_event_gesture_get_dx_unaccelerated(g),
- libinput_event_gesture_get_dy_unaccelerated(g)
- );
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, nfingers: %d, "
+ "delta: [%6.2f, %6.2f], unaccel: [%6.2f, %6.2f]}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ libinput_event_gesture_get_finger_count(g),
+ libinput_event_gesture_get_dx(g),
+ libinput_event_gesture_get_dy(g),
+ libinput_event_gesture_get_dx_unaccelerated(g),
+ libinput_event_gesture_get_dy_unaccelerated(g)
+ );
break;
default:
abort();
@@ -913,9 +844,7 @@ out:
}
static void
-buffer_tablet_tool_proximity_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_tablet_tool_proximity_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_tablet_tool *t =
libinput_event_get_tablet_tool_event(e);
@@ -964,7 +893,7 @@ buffer_tablet_tool_proximity_event(struct record_context *ctx,
}
prox = libinput_event_tablet_tool_get_proximity_state(t);
- time = time_offset(ctx, libinput_event_tablet_tool_get_time_usec(t));
+ time = time_offset(dev->ctx, libinput_event_tablet_tool_get_time_usec(t));
axes = buffer_tablet_axes(t);
idx = 0;
@@ -982,25 +911,23 @@ buffer_tablet_tool_proximity_event(struct record_context *ctx,
caps[idx++] = 'w';
assert(idx <= ARRAY_LENGTH(caps));
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, proximity: %s, tool-type: %s, serial: %" PRIu64 ", axes: %s, %s}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- prox ? "in" : "out",
- tool_type,
- libinput_tablet_tool_get_serial(tool),
- caps,
- axes);
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, proximity: %s, tool-type: %s, serial: %" PRIu64 ", axes: %s, %s}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ prox ? "in" : "out",
+ tool_type,
+ libinput_tablet_tool_get_serial(tool),
+ caps,
+ axes);
free(axes);
}
static void
-buffer_tablet_tool_button_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_tablet_tool_button_event(struct record_device *dev,
+ struct libinput_event *e)
{
struct libinput_event_tablet_tool *t =
libinput_event_get_tablet_tool_event(e);
@@ -1020,23 +947,20 @@ buffer_tablet_tool_button_event(struct record_context *ctx,
button = libinput_event_tablet_tool_get_button(t);
state = libinput_event_tablet_tool_get_button_state(t);
- time = time_offset(ctx, libinput_event_tablet_tool_get_time_usec(t));
+ time = time_offset(dev->ctx, libinput_event_tablet_tool_get_time_usec(t));
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, button: %d, state: %s}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- button,
- state ? "pressed" : "released");
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, button: %d, state: %s}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ button,
+ state ? "pressed" : "released");
}
static void
-buffer_tablet_tool_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_tablet_tool_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_tablet_tool *t =
libinput_event_get_tablet_tool_event(e);
@@ -1073,26 +997,24 @@ buffer_tablet_tool_event(struct record_context *ctx,
}
tip = libinput_event_tablet_tool_get_tip_state(t);
- time = time_offset(ctx, libinput_event_tablet_tool_get_time_usec(t));
+ time = time_offset(dev->ctx, libinput_event_tablet_tool_get_time_usec(t));
axes = buffer_tablet_axes(t);
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s%s, tip: %s, %s}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- btn_buffer, /* may be empty string */
- tip ? "down" : "up",
- axes);
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s%s, tip: %s, %s}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ btn_buffer, /* may be empty string */
+ tip ? "down" : "up",
+ axes);
free(axes);
}
static void
-buffer_tablet_pad_button_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_tablet_pad_button_event(struct record_device *dev,
+ struct libinput_event *e)
{
struct libinput_event_tablet_pad *p =
libinput_event_get_tablet_pad_event(e);
@@ -1110,32 +1032,29 @@ buffer_tablet_pad_button_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_tablet_pad_get_time_usec(p));
+ time = time_offset(dev->ctx, libinput_event_tablet_pad_get_time_usec(p));
button = libinput_event_tablet_pad_get_button_number(p),
state = libinput_event_tablet_pad_get_button_state(p);
mode = libinput_event_tablet_pad_get_mode(p);
group = libinput_event_tablet_pad_get_mode_group(p);
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, button: %d, state: %s, mode: %d, is-toggle: %s}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- button,
- state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released",
- mode,
- libinput_tablet_pad_mode_group_button_is_toggle(group, button) ? "true" : "false"
- );
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, button: %d, state: %s, mode: %d, is-toggle: %s}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ button,
+ state == LIBINPUT_BUTTON_STATE_PRESSED ? "pressed" : "released",
+ mode,
+ libinput_tablet_pad_mode_group_button_is_toggle(group, button) ? "true" : "false"
+ );
}
static void
-buffer_tablet_pad_ringstrip_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_tablet_pad_ringstrip_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_tablet_pad *p =
libinput_event_get_tablet_pad_event(e);
@@ -1178,26 +1097,23 @@ buffer_tablet_pad_ringstrip_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_tablet_pad_get_time_usec(p));
+ time = time_offset(dev->ctx, libinput_event_tablet_pad_get_time_usec(p));
mode = libinput_event_tablet_pad_get_mode(p);
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, number: %d, position: %.2f, source: %s, mode: %d}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- number,
- pos,
- source,
- mode);
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, number: %d, position: %.2f, source: %s, mode: %d}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ number,
+ pos,
+ source,
+ mode);
}
static void
-buffer_switch_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_switch_event(struct record_device *dev, struct libinput_event *e)
{
struct libinput_event_switch *s = libinput_event_get_switch_event(e);
enum libinput_switch_state state;
@@ -1213,54 +1129,51 @@ buffer_switch_event(struct record_context *ctx,
abort();
}
- time = time_offset(ctx, libinput_event_switch_get_time_usec(s));
+ time = time_offset(dev->ctx, libinput_event_switch_get_time_usec(s));
sw = libinput_event_switch_get_switch(s);
state = libinput_event_switch_get_switch_state(s);
- event->time = time;
- snprintf(event->u.libinput.msg,
- sizeof(event->u.libinput.msg),
- "{time: %ld.%06ld, type: %s, switch: %d, state: %s}",
- (long)(time / (int)1e6),
- (long)(time % (int)1e6),
- type,
- sw,
- state == LIBINPUT_SWITCH_STATE_ON ? "on" : "off");
+ iprintf(dev->fp,
+ I_EVENT,
+ "- {time: %ld.%06ld, type: %s, switch: %d, state: %s}\n",
+ (long)(time / (int)1e6),
+ (long)(time % (int)1e6),
+ type,
+ sw,
+ state == LIBINPUT_SWITCH_STATE_ON ? "on" : "off");
}
static void
-buffer_libinput_event(struct record_context *ctx,
- struct libinput_event *e,
- struct event *event)
+print_libinput_event(struct record_device *dev, struct libinput_event *e)
{
switch (libinput_event_get_type(e)) {
case LIBINPUT_EVENT_NONE:
abort();
case LIBINPUT_EVENT_DEVICE_ADDED:
case LIBINPUT_EVENT_DEVICE_REMOVED:
- buffer_device_notify(ctx, e, event);
+ print_device_notify(dev, e);
break;
case LIBINPUT_EVENT_KEYBOARD_KEY:
- buffer_key_event(ctx, e, event);
+ print_key_event(dev, e);
break;
case LIBINPUT_EVENT_POINTER_MOTION:
- buffer_motion_event(ctx, e, event);
+ print_motion_event(dev, e);
break;
case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
- buffer_absmotion_event(ctx, e, event);
+ print_absmotion_event(dev, e);
break;
case LIBINPUT_EVENT_POINTER_BUTTON:
- buffer_pointer_button_event(ctx, e, event);
+ print_pointer_button_event(dev, e);
break;
case LIBINPUT_EVENT_POINTER_AXIS:
- buffer_pointer_axis_event(ctx, e, event);
+ print_pointer_axis_event(dev, e);
break;
case LIBINPUT_EVENT_TOUCH_DOWN:
case LIBINPUT_EVENT_TOUCH_UP:
case LIBINPUT_EVENT_TOUCH_MOTION:
case LIBINPUT_EVENT_TOUCH_CANCEL:
case LIBINPUT_EVENT_TOUCH_FRAME:
- buffer_touch_event(ctx, e, event);
+ print_touch_event(dev, e);
break;
case LIBINPUT_EVENT_GESTURE_PINCH_BEGIN:
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
@@ -1268,119 +1181,49 @@ buffer_libinput_event(struct record_context *ctx,
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
case LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE:
case LIBINPUT_EVENT_GESTURE_SWIPE_END:
- buffer_gesture_event(ctx, e, event);
+ print_gesture_event(dev, e);
break;
case LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY:
- buffer_tablet_tool_proximity_event(ctx, e, event);
+ print_tablet_tool_proximity_event(dev, e);
break;
case LIBINPUT_EVENT_TABLET_TOOL_AXIS:
case LIBINPUT_EVENT_TABLET_TOOL_TIP:
- buffer_tablet_tool_event(ctx, e, event);
+ print_tablet_tool_event(dev, e);
break;
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
- buffer_tablet_tool_button_event(ctx, e, event);
+ print_tablet_tool_button_event(dev, e);
break;
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
- buffer_tablet_pad_button_event(ctx, e, event);
+ print_tablet_pad_button_event(dev, e);
break;
case LIBINPUT_EVENT_TABLET_PAD_RING:
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
- buffer_tablet_pad_ringstrip_event(ctx, e, event);
+ print_tablet_pad_ringstrip_event(dev, e);
break;
case LIBINPUT_EVENT_SWITCH_TOGGLE:
- buffer_switch_event(ctx, e, event);
+ print_switch_event(dev, e);
break;
default:
break;
}
}
-static void
-print_cached_events(struct record_context *ctx,
- struct record_device *d,
- unsigned int offset,
- int len)
-{
- unsigned int idx;
- enum event_type last_type;
- uint64_t last_time;
-
- if (len == -1)
- len = d->nevents - offset;
- assert(offset + len <= d->nevents);
-
- if (offset == 0) {
- last_type = NONE;
- last_time = 0;
- } else {
- last_type = d->events[offset - 1].type;
- last_time = d->events[offset - 1].time;
- }
-
- idx = offset;
- while (idx < offset + len) {
- struct event *e;
-
- e = &d->events[idx++];
- if (e->type != last_type || e->time != last_time) {
- bool new_frame = false;
-
- if (last_time == 0 || e->time != last_time)
- new_frame = true;
-
- switch(e->type) {
- case EVDEV:
- if (new_frame)
- iprintf(ctx, I_EVENTTYPE, "- evdev:\n");
- else
- iprintf(ctx, I_EVENTTYPE, "evdev:\n");
- break;
- case LIBINPUT:
- if (new_frame)
- iprintf(ctx, I_EVENTTYPE, "- libinput:\n");
- else
- iprintf(ctx, I_EVENTTYPE, "libinput:\n");
- break;
- case COMMENT:
- break;
- default:
- abort();
- }
-
- last_type = e->type;
- }
-
- switch (e->type) {
- case EVDEV:
- print_evdev_event(ctx, d, &e->u.evdev);
- break;
- case LIBINPUT:
- iprintf(ctx, I_EVENT, "- %s\n", e->u.libinput.msg);
- break;
- case COMMENT:
- iprintf(ctx, I_EVENT, "%s", e->u.comment);
- break;
- default:
- abort();
- }
-
- last_time = e->time;
- }
-}
-
-static size_t
+static bool
handle_libinput_events(struct record_context *ctx,
- struct record_device *d)
+ struct record_device *d,
+ bool start_frame)
{
struct libinput_event *e;
- size_t count = 0;
struct record_device *current = d;
libinput_dispatch(ctx->libinput);
+ e = libinput_get_event(ctx->libinput);
+ if (!e)
+ return false;
- while ((e = libinput_get_event(ctx->libinput)) != NULL) {
+ iprintf(d->fp, I_EVENTTYPE, "%slibinput:\n", start_frame ? "- " : "");
+ do {
struct libinput_device *device = libinput_event_get_device(e);
- struct event *event;
if (device != current->device) {
struct record_device *tmp;
@@ -1395,59 +1238,49 @@ handle_libinput_events(struct record_context *ctx,
assert(found);
}
- event = next_event(current);
- event->type = LIBINPUT;
- buffer_libinput_event(ctx, e, event);
-
- if (current == d)
- count++;
+ print_libinput_event(current, e);
libinput_event_destroy(e);
- }
- return count;
+ } while ((e = libinput_get_event(ctx->libinput)) != NULL);
+
+ return true;
}
static void
-handle_events(struct record_context *ctx, struct record_device *d, bool print)
+handle_events(struct record_context *ctx, struct record_device *d)
{
- while(true) {
- size_t first_idx = d->nevents;
- size_t evcount = 0,
- licount = 0;
+ bool has_events = true;
- evcount = handle_evdev_frame(ctx, d);
+ while (has_events) {
+ has_events = handle_evdev_frame(d);
if (ctx->libinput)
- licount = handle_libinput_events(ctx, d);
-
- if (evcount == 0 && licount == 0)
- break;
-
- if (!print)
- continue;
-
- print_cached_events(ctx, d, first_idx, evcount + licount);
+ has_events |= handle_libinput_events(ctx,
+ d,
+ !has_events);
}
+
+ fflush(d->fp);
}
static void
-print_libinput_header(struct record_context *ctx)
+print_libinput_header(FILE *fp, int timeout)
{
- iprintf(ctx, I_TOPLEVEL, "libinput:\n");
- iprintf(ctx, I_LIBINPUT, "version: \"%s\"\n", LIBINPUT_VERSION);
- iprintf(ctx, I_LIBINPUT, "git: \"%s\"\n", LIBINPUT_GIT_VERSION);
- if (ctx->timeout > 0)
- iprintf(ctx, I_LIBINPUT, "autorestart: %d\n", ctx->timeout);
+ iprintf(fp, I_TOPLEVEL, "libinput:\n");
+ iprintf(fp, I_LIBINPUT, "version: \"%s\"\n", LIBINPUT_VERSION);
+ iprintf(fp, I_LIBINPUT, "git: \"%s\"\n", LIBINPUT_GIT_VERSION);
+ if (timeout > 0)
+ iprintf(fp, I_LIBINPUT, "autorestart: %d\n", timeout);
}
static void
-print_system_header(struct record_context *ctx)
+print_system_header(FILE *fp)
{
struct utsname u;
const char *kernel = "unknown";
FILE *dmi, *osrelease;
char dmistr[2048] = "unknown";
- iprintf(ctx, I_TOPLEVEL, "system:\n");
+ iprintf(fp, I_TOPLEVEL, "system:\n");
/* /etc/os-release version and distribution name */
osrelease = fopen("/etc/os-release", "r");
@@ -1466,7 +1299,7 @@ print_system_header(struct record_context *ctx)
version = strstrip(&osrstr[11], "\"'");
if (distro && version) {
- iprintf(ctx,
+ iprintf(fp,
I_SYSTEM,
"os: \"%s:%s\"\n",
distro,
@@ -1482,7 +1315,7 @@ print_system_header(struct record_context *ctx)
/* kernel version */
if (uname(&u) != -1)
kernel = u.release;
- iprintf(ctx, I_SYSTEM, "kernel: \"%s\"\n", kernel);
+ iprintf(fp, I_SYSTEM, "kernel: \"%s\"\n", kernel);
/* dmi modalias */
dmi = fopen("/sys/class/dmi/id/modalias", "r");
@@ -1494,21 +1327,21 @@ print_system_header(struct record_context *ctx)
}
fclose(dmi);
}
- iprintf(ctx, I_SYSTEM, "dmi: \"%s\"\n", dmistr);
+ iprintf(fp, I_SYSTEM, "dmi: \"%s\"\n", dmistr);
}
static void
-print_header(struct record_context *ctx)
+print_header(FILE *fp, struct record_context *ctx)
{
- iprintf(ctx, I_TOPLEVEL, "# libinput record\n");
- iprintf(ctx, I_TOPLEVEL, "version: %d\n", FILE_VERSION_NUMBER);
- iprintf(ctx, I_TOPLEVEL, "ndevices: %d\n", ctx->ndevices);
- print_libinput_header(ctx);
- print_system_header(ctx);
+ iprintf(fp, I_TOPLEVEL, "# libinput record\n");
+ iprintf(fp, I_TOPLEVEL, "version: %d\n", FILE_VERSION_NUMBER);
+ iprintf(fp, I_TOPLEVEL, "ndevices: %d\n", ctx->ndevices);
+ print_libinput_header(fp, ctx->timeout);
+ print_system_header(fp);
}
static void
-print_description_abs(struct record_context *ctx,
+print_description_abs(FILE *fp,
struct libevdev *dev,
unsigned int code)
{
@@ -1517,26 +1350,26 @@ print_description_abs(struct record_context *ctx,
abs = libevdev_get_abs_info(dev, code);
assert(abs);
- iprintf(ctx, I_EVDEV, "# Value %6d\n", abs->value);
- iprintf(ctx, I_EVDEV, "# Min %6d\n", abs->minimum);
- iprintf(ctx, I_EVDEV, "# Max %6d\n", abs->maximum);
- iprintf(ctx, I_EVDEV, "# Fuzz %6d\n", abs->fuzz);
- iprintf(ctx, I_EVDEV, "# Flat %6d\n", abs->flat);
- iprintf(ctx, I_EVDEV, "# Resolution %6d\n", abs->resolution);
+ iprintf(fp, I_EVDEV, "# Value %6d\n", abs->value);
+ iprintf(fp, I_EVDEV, "# Min %6d\n", abs->minimum);
+ iprintf(fp, I_EVDEV, "# Max %6d\n", abs->maximum);
+ iprintf(fp, I_EVDEV, "# Fuzz %6d\n", abs->fuzz);
+ iprintf(fp, I_EVDEV, "# Flat %6d\n", abs->flat);
+ iprintf(fp, I_EVDEV, "# Resolution %6d\n", abs->resolution);
}
static void
-print_description_state(struct record_context *ctx,
+print_description_state(FILE *fp,
struct libevdev *dev,
unsigned int type,
unsigned int code)
{
int state = libevdev_get_event_value(dev, type, code);
- iprintf(ctx, I_EVDEV, "# State %d\n", state);
+ iprintf(fp, I_EVDEV, "# State %d\n", state);
}
static void
-print_description_codes(struct record_context *ctx,
+print_description_codes(FILE *fp,
struct libevdev *dev,
unsigned int type)
{
@@ -1546,7 +1379,7 @@ print_description_codes(struct record_context *ctx,
if (max == -1)
return;
- iprintf(ctx,
+ iprintf(fp,
I_EVDEV,
"# Event type %d (%s)\n",
type,
@@ -1559,7 +1392,7 @@ print_description_codes(struct record_context *ctx,
if (!libevdev_has_event_code(dev, type, code))
continue;
- iprintf(ctx,
+ iprintf(fp,
I_EVDEV,
"# Event code %d (%s)\n",
code,
@@ -1568,23 +1401,23 @@ print_description_codes(struct record_context *ctx,
switch (type) {
case EV_ABS:
- print_description_abs(ctx, dev, code);
+ print_description_abs(fp, dev, code);
break;
case EV_LED:
case EV_SW:
- print_description_state(ctx, dev, type, code);
+ print_description_state(fp, dev, type, code);
break;
}
}
}
static void
-print_description(struct record_context *ctx, struct libevdev *dev)
+print_description(FILE *fp, struct libevdev *dev)
{
const struct input_absinfo *x, *y;
- iprintf(ctx, I_EVDEV, "# Name: %s\n", libevdev_get_name(dev));
- iprintf(ctx,
+ iprintf(fp, I_EVDEV, "# Name: %s\n", libevdev_get_name(dev));
+ iprintf(fp,
I_EVDEV,
"# ID: bus %#02x vendor %#02x product %#02x version %#02x\n",
libevdev_get_id_bustype(dev),
@@ -1600,28 +1433,28 @@ print_description(struct record_context *ctx, struct libevdev *dev)
w = (x->maximum - x->minimum)/x->resolution;
h = (y->maximum - y->minimum)/y->resolution;
- iprintf(ctx, I_EVDEV, "# Size in mm: %dx%d\n", w, h);
+ iprintf(fp, I_EVDEV, "# Size in mm: %dx%d\n", w, h);
} else {
- iprintf(ctx,
+ iprintf(fp,
I_EVDEV,
"# Size in mm: unknown, missing resolution\n");
}
}
- iprintf(ctx, I_EVDEV, "# Supported Events:\n");
+ iprintf(fp, I_EVDEV, "# Supported Events:\n");
for (unsigned int type = 0; type < EV_CNT; type++) {
if (!libevdev_has_event_type(dev, type))
continue;
- print_description_codes(ctx, dev, type);
+ print_description_codes(fp, dev, type);
}
- iprintf(ctx, I_EVDEV, "# Properties:\n");
+ iprintf(fp, I_EVDEV, "# Properties:\n");
for (unsigned int prop = 0; prop < INPUT_PROP_CNT; prop++) {
if (libevdev_has_property(dev, prop)) {
- iprintf(ctx,
+ iprintf(fp,
I_EVDEV,
"# Property %d (%s)\n",
prop,
@@ -1631,10 +1464,10 @@ print_description(struct record_context *ctx, struct libevdev *dev)
}
static void
-print_bits_info(struct record_context *ctx, struct libevdev *dev)
+print_bits_info(FILE *fp, struct libevdev *dev)
{
- iprintf(ctx, I_EVDEV, "name: \"%s\"\n", libevdev_get_name(dev));
- iprintf(ctx,
+ iprintf(fp, I_EVDEV, "name: \"%s\"\n", libevdev_get_name(dev));
+ iprintf(fp,
I_EVDEV,
"id: [%d, %d, %d, %d]\n",
libevdev_get_id_bustype(dev),
@@ -1644,20 +1477,20 @@ print_bits_info(struct record_context *ctx, struct libevdev *dev)
}
static void
-print_bits_absinfo(struct record_context *ctx, struct libevdev *dev)
+print_bits_absinfo(FILE *fp, struct libevdev *dev)
{
const struct input_absinfo *abs;
if (!libevdev_has_event_type(dev, EV_ABS))
return;
- iprintf(ctx, I_EVDEV, "absinfo:\n");
+ iprintf(fp, I_EVDEV, "absinfo:\n");
for (unsigned int code = 0; code < ABS_CNT; code++) {
abs = libevdev_get_abs_info(dev, code);
if (!abs)
continue;
- iprintf(ctx,
+ iprintf(fp,
I_EVDEV_DATA,
"%d: [%d, %d, %d, %d, %d]\n",
code,
@@ -1670,9 +1503,7 @@ print_bits_absinfo(struct record_context *ctx, struct libevdev *dev)
}
static void
-print_bits_codes(struct record_context *ctx,
- struct libevdev *dev,
- unsigned int type)
+print_bits_codes(FILE *fp, struct libevdev *dev, unsigned int type)
{
int max;
const char *sep = "";
@@ -1681,62 +1512,61 @@ print_bits_codes(struct record_context *ctx,
if (max == -1)
return;
- iprintf(ctx, I_EVDEV_DATA, "%d: [", type);
+ iprintf(fp, I_EVDEV_DATA, "%d: [", type);
for (unsigned int code = 0; code <= (unsigned int)max; code++) {
if (!libevdev_has_event_code(dev, type, code))
continue;
- iprintf(ctx, I_NONE, "%s%d", sep, code);
+ iprintf(fp, I_NONE, "%s%d", sep, code);
sep = ", ";
}
- iprintf(ctx, I_NONE, "] # %s\n", libevdev_event_type_get_name(type));
+ iprintf(fp, I_NONE, "] # %s\n", libevdev_event_type_get_name(type));
}
static void
-print_bits_types(struct record_context *ctx, struct libevdev *dev)
+print_bits_types(FILE *fp, struct libevdev *dev)
{
- iprintf(ctx, I_EVDEV, "codes:\n");
+ iprintf(fp, I_EVDEV, "codes:\n");
for (unsigned int type = 0; type < EV_CNT; type++) {
if (!libevdev_has_event_type(dev, type))
continue;
- print_bits_codes(ctx, dev, type);
+ print_bits_codes(fp, dev, type);
}
}
static void
-print_bits_props(struct record_context *ctx, struct libevdev *dev)
+print_bits_props(FILE *fp, struct libevdev *dev)
{
const char *sep = "";
- iprintf(ctx, I_EVDEV, "properties: [");
+ iprintf(fp, I_EVDEV, "properties: [");
for (unsigned int prop = 0; prop < INPUT_PROP_CNT; prop++) {
if (libevdev_has_property(dev, prop)) {
- iprintf(ctx, I_NONE, "%s%d", sep, prop);
+ iprintf(fp, I_NONE, "%s%d", sep, prop);
sep = ", ";
}
}
- iprintf(ctx, I_NONE, "]\n"); /* last entry, no comma */
+ iprintf(fp, I_NONE, "]\n"); /* last entry, no comma */
}
static void
-print_evdev_description(struct record_context *ctx, struct record_device *dev)
+print_evdev_description(struct record_device *dev)
{
struct libevdev *evdev = dev->evdev;
- iprintf(ctx, I_DEVICE, "evdev:\n");
+ iprintf(dev->fp, I_DEVICE, "evdev:\n");
- print_description(ctx, evdev);
- print_bits_info(ctx, evdev);
- print_bits_types(ctx, evdev);
- print_bits_absinfo(ctx, evdev);
- print_bits_props(ctx, evdev);
+ print_description(dev->fp, evdev);
+ print_bits_info(dev->fp, evdev);
+ print_bits_types(dev->fp, evdev);
+ print_bits_absinfo(dev->fp, evdev);
+ print_bits_props(dev->fp, evdev);
}
static void
-print_hid_report_descriptor(struct record_context *ctx,
- struct record_device *dev)
+print_hid_report_descriptor(struct record_device *dev)
{
const char *prefix = "/dev/input/event";
char syspath[PATH_MAX];
@@ -1763,22 +1593,22 @@ print_hid_report_descriptor(struct record_context *ctx,
if (fd == -1)
return;
- iprintf(ctx, I_DEVICE, "hid: [");
+ iprintf(dev->fp, I_DEVICE, "hid: [");
while ((len = read(fd, buf, sizeof(buf))) > 0) {
for (int i = 0; i < len; i++) {
/* YAML requires decimal */
- iprintf(ctx, I_NONE, "%s%u", sep, buf[i]);
+ iprintf(dev->fp, I_NONE, "%s%u", sep, buf[i]);
sep = ", ";
}
}
- iprintf(ctx, I_NONE, "]\n");
+ iprintf(dev->fp, I_NONE, "]\n");
close(fd);
}
static void
-print_udev_properties(struct record_context *ctx, struct record_device *dev)
+print_udev_properties(struct record_device *dev)
{
struct udev *udev = NULL;
struct udev_device *udev_device = NULL;
@@ -1796,9 +1626,9 @@ print_udev_properties(struct record_context *ctx, struct record_device *dev)
if (!udev_device)
goto out;
- iprintf(ctx, I_DEVICE, "udev:\n");
+ iprintf(dev->fp, I_DEVICE, "udev:\n");
- iprintf(ctx, I_UDEV, "properties:\n");
+ iprintf(dev->fp, I_UDEV, "properties:\n");
entry = udev_device_get_properties_list_entry(udev_device);
while (entry) {
@@ -1812,7 +1642,7 @@ print_udev_properties(struct record_context *ctx, struct record_device *dev)
strneq(key, "MOUSE_DPI", 9) ||
strneq(key, "POINTINGSTICK_", 14)) {
value = udev_list_entry_get_value(entry);
- iprintf(ctx, I_UDEV_DATA, "- %s=%s\n", key, value);
+ iprintf(dev->fp, I_UDEV_DATA, "- %s=%s\n", key, value);
}
entry = udev_list_entry_get_next(entry);
@@ -1834,13 +1664,13 @@ quirks_log_handler(struct libinput *this_is_null,
static void
list_print(void *userdata, const char *val)
{
- struct record_context *ctx = userdata;
+ FILE *fp = userdata;
- iprintf(ctx, I_QUIRKS, "- %s\n", val);
+ iprintf(fp, I_QUIRKS, "- %s\n", val);
}
static void
-print_device_quirks(struct record_context *ctx, struct record_device *dev)
+print_device_quirks(struct record_device *dev)
{
struct udev *udev = NULL;
struct udev_device *udev_device = NULL;
@@ -1882,8 +1712,8 @@ print_device_quirks(struct record_context *ctx, struct record_device *dev)
if (!udev_device)
goto out;
- iprintf(ctx, I_DEVICE, "quirks:\n");
- tools_list_device_quirks(quirks, udev_device, list_print, ctx);
+ iprintf(dev->fp, I_DEVICE, "quirks:\n");
+ tools_list_device_quirks(quirks, udev_device, list_print, dev->fp);
out:
udev_device_unref(udev_device);
udev_unref(udev);
@@ -1891,8 +1721,7 @@ out:
}
static void
-print_libinput_description(struct record_context *ctx,
- struct record_device *dev)
+print_libinput_description(struct record_device *dev)
{
struct libinput_device *device = dev->device;
double w, h;
@@ -1914,18 +1743,18 @@ print_libinput_description(struct record_context *ctx,
if (!device)
return;
- iprintf(ctx, I_DEVICE, "libinput:\n");
+ iprintf(dev->fp, I_DEVICE, "libinput:\n");
if (libinput_device_get_size(device, &w, &h) == 0)
- iprintf(ctx, I_LIBINPUTDEV, "size: [%.f, %.f]\n", w, h);
+ iprintf(dev->fp, I_LIBINPUTDEV, "size: [%.f, %.f]\n", w, h);
- iprintf(ctx, I_LIBINPUTDEV, "capabilities: [");
+ iprintf(dev->fp, I_LIBINPUTDEV, "capabilities: [");
ARRAY_FOR_EACH(caps, cap) {
if (!libinput_device_has_capability(device, cap->cap))
continue;
- iprintf(ctx, I_NONE, "%s%s", sep, cap->name);
+ iprintf(dev->fp, I_NONE, "%s%s", sep, cap->name);
sep = ", ";
}
- iprintf(ctx, I_NONE, "]\n");
+ iprintf(dev->fp, I_NONE, "]\n");
/* Configuration options should be printed here, but since they
* don't reflect the user-configured ones their usefulness is
@@ -1935,15 +1764,15 @@ print_libinput_description(struct record_context *ctx,
}
static void
-print_device_description(struct record_context *ctx, struct record_device *dev)
+print_device_description(struct record_device *dev)
{
- iprintf(ctx, I_DEVICE, "- node: %s\n", dev->devnode);
+ iprintf(dev->fp, I_DEVICE, "- node: %s\n", dev->devnode);
- print_evdev_description(ctx, dev);
- print_hid_report_descriptor(ctx, dev);
- print_udev_properties(ctx, dev);
- print_device_quirks(ctx, dev);
- print_libinput_description(ctx, dev);
+ print_evdev_description(dev);
+ print_hid_report_descriptor(dev);
+ print_udev_properties(dev);
+ print_device_quirks(dev);
+ print_libinput_description(dev);
}
static int is_event_node(const struct dirent *dir) {
@@ -2082,9 +1911,10 @@ init_output_file(const char *file, bool is_prefix)
}
static bool
-open_output_file(struct record_context *ctx, bool is_prefix)
+open_output_files(struct record_context *ctx, bool is_prefix)
{
FILE *out_file;
+ struct record_device *d;
if (ctx->output_file.name) {
char *fname = init_output_file(ctx->output_file.name, is_prefix);
@@ -2097,7 +1927,13 @@ open_output_file(struct record_context *ctx, bool is_prefix)
out_file = stdout;
}
- ctx->output_file.fp = out_file;
+ ctx->first_device->fp = out_file;
+
+ list_for_each(d, &ctx->devices, link) {
+ if (d->fp)
+ continue;
+ d->fp = tmpfile();
+ }
return true;
}
@@ -2120,12 +1956,17 @@ print_wall_time(struct record_context *ctx)
{
time_t t = time(NULL);
struct tm tm;
+ struct record_device *d;
localtime_r(&t, &tm);
- iprintf(ctx,
- I_NONE,
- "# Current time is %02d:%02d:%02d\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ list_for_each(d, &ctx->devices, link) {
+ iprintf(d->fp,
+ I_DEVICE,
+ "# Current time is %02d:%02d:%02d\n",
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ fflush(d->fp);
+ }
}
static void
@@ -2220,26 +2061,17 @@ evdev_dispatch(struct record_context *ctx, int fd, void *data)
ctx->had_events = true;
ctx->timestamps.had_events_since_last_time = true;
- handle_events(ctx, this_device, this_device == ctx->first_device);
+ handle_events(ctx, this_device);
}
static void
libinput_ctx_dispatch(struct record_context *ctx, int fd, void *data)
{
- size_t count, offset;
-
/* This function should only handle events caused by internal
* timeouts etc. The real input events caused by the evdev devices
* are already processed in handle_events */
libinput_dispatch(ctx->libinput);
- offset = ctx->first_device->nevents;
- count = handle_libinput_events(ctx, ctx->first_device);
- if (count) {
- print_cached_events(ctx,
- ctx->first_device,
- offset,
- count);
- }
+ handle_libinput_events(ctx, ctx->first_device, true);
}
static int
@@ -2313,7 +2145,9 @@ mainloop(struct record_context *ctx)
}
do {
- if (!open_output_file(ctx, autorestart)) {
+ struct record_device *d;
+
+ if (!open_output_files(ctx, autorestart)) {
fprintf(stderr,
"Failed to open '%s'\n",
ctx->output_file.name_with_suffix);
@@ -2325,27 +2159,26 @@ mainloop(struct record_context *ctx)
ctx->had_events = false;
- print_header(ctx);
+ print_header(ctx->first_device->fp, ctx);
if (autorestart)
- iprintf(ctx,
+ iprintf(ctx->first_device->fp,
I_NONE,
"# Autorestart timeout: %d\n",
ctx->timeout);
- iprintf(ctx, I_TOPLEVEL, "devices:\n");
+ iprintf(ctx->first_device->fp, I_TOPLEVEL, "devices:\n");
/* we only print the first device's description, the
* rest is assembled after CTRL+C */
- print_device_description(ctx, ctx->first_device);
-
+ list_for_each(d, &ctx->devices, link) {
+ print_device_description(d);
+ iprintf(d->fp, I_DEVICE, "events:\n");
+ }
print_wall_time(ctx);
- iprintf(ctx, I_DEVICE, "events:\n");
if (ctx->libinput) {
- size_t count;
libinput_dispatch(ctx->libinput);
- count = handle_libinput_events(ctx, ctx->first_device);
- print_cached_events(ctx, ctx->first_device, 0, count);
+ handle_libinput_events(ctx, ctx->first_device, true);
}
while (true) {
@@ -2368,31 +2201,45 @@ mainloop(struct record_context *ctx)
}
- if (ctx->output_file.fp != stdout)
+ if (ctx->first_device->fp != stdout)
print_progress_bar();
}
if (autorestart) {
- iprintf(ctx,
- I_NONE,
- "# Closing after %ds inactivity",
- ctx->timeout/1000);
+ list_for_each(d, &ctx->devices, link) {
+ iprintf(d->fp,
+ I_NONE,
+ "# Closing after %ds inactivity",
+ ctx->timeout/1000);
+ }
}
/* First device is printed, now append all the data from the
* other devices, if any */
list_for_each(d, &ctx->devices, link) {
- if (d == list_first_entry(&ctx->devices, d, link))
+ char buf[4096];
+ size_t n;
+
+ if (d == ctx->first_device)
continue;
- print_device_description(ctx, d);
- iprintf(ctx, I_DEVICE, "events:\n");
- print_cached_events(ctx, d, 0, -1);
+ rewind(d->fp);
+ do {
+
+ n = fread(buf, 1, sizeof(buf), d->fp);
+ if (n > 0)
+ fwrite(buf, 1, n, ctx->first_device->fp);
+ } while (n == sizeof(buf));
+
+ fclose(d->fp);
+ d->fp = NULL;
}
/* If we didn't have events, delete the file. */
- if (!isatty(fileno(ctx->output_file.fp))) {
+ if (!isatty(fileno(ctx->first_device->fp))) {
+ struct record_device *d;
+
if (!ctx->had_events && ctx->output_file.name_with_suffix) {
fprintf(stderr,
"No events recorded, deleting '%s'\n",
@@ -2400,8 +2247,12 @@ mainloop(struct record_context *ctx)
unlink(ctx->output_file.name_with_suffix);
}
- fclose(ctx->output_file.fp);
- ctx->output_file.fp = NULL;
+ list_for_each(d, &ctx->devices, link) {
+ if (d->fp && d->fp != stdout) {
+ fclose(d->fp);
+ d->fp = NULL;
+ }
+ }
}
free(ctx->output_file.name_with_suffix);
ctx->output_file.name_with_suffix = NULL;
@@ -2424,10 +2275,8 @@ init_device(struct record_context *ctx, const char *path, bool grab)
int fd, rc;
d = zalloc(sizeof(*d));
+ d->ctx = ctx;
d->devnode = safe_strdup(path);
- d->nevents = 0;
- d->events_sz = 5000;
- d->events = zalloc(d->events_sz * sizeof(*d->events));
fd = open(d->devnode, O_RDONLY|O_NONBLOCK);
if (fd < 0) {
@@ -2794,7 +2643,6 @@ out:
list_for_each_safe(d, &ctx.devices, link) {
if (d->device)
libinput_device_unref(d->device);
- free(d->events);
free(d->devnode);
libevdev_free(d->evdev);
}