Add timestamps to input events

master
Raheman Vaiya 4 years ago
parent 51a16dc085
commit 0ec11fb4b0
  1. 1
      src/config.c
  2. 48
      src/daemon.c
  3. 6
      src/evloop.c
  4. 32
      src/keyboard.c
  5. 10
      src/keyboard.h
  6. 2
      src/keyd.h
  7. 24
      src/monitor.c

@ -426,7 +426,6 @@ int parse_macro_expression(const char *s, struct macro *macro)
macro->sz++; \ macro->sz++; \
} while(0) } while(0)
char *tok;
size_t len = strlen(s); size_t len = strlen(s);
char buf[1024]; char buf[1024];

@ -403,25 +403,36 @@ static void add_device(struct device *dev)
static int event_handler(struct event *ev) static int event_handler(struct event *ev)
{ {
int timeout; static int last_time = 0;
static struct keyboard *last_kbd = NULL; static int timeout = 0;
static struct keyboard *timeout_kbd = NULL;
struct key_event kev;
timeout -= ev->timestamp - last_time;
last_time = ev->timestamp;
timeout = timeout < 0 ? 0 : timeout;
switch (ev->type) { switch (ev->type) {
case EV_TIMEOUT: case EV_TIMEOUT:
if (!last_kbd) if (!timeout_kbd)
return 0; return 0;
return kbd_process_key_event(last_kbd, 0, 0); kev.code = 0;
case EV_DEV_EVENT: kev.timestamp = ev->timestamp;
timeout = ev->timeleft;
timeout = kbd_process_events(timeout_kbd, &kev, 1);
break;
case EV_DEV_EVENT:
if (ev->dev->data) { if (ev->dev->data) {
last_kbd = ev->dev->data; timeout_kbd = ev->dev->data;
switch (ev->devev->type) { switch (ev->devev->type) {
case DEV_KEY: case DEV_KEY:
timeout = kbd_process_key_event(ev->dev->data, ev->devev->code, kev.code = ev->devev->code;
ev->devev->pressed); kev.pressed = ev->devev->pressed;
kev.timestamp = ev->timestamp;
timeout = kbd_process_events(ev->dev->data, &kev, 1);
break; break;
case DEV_MOUSE_MOVE: case DEV_MOUSE_MOVE:
vkbd_mouse_move(vkbd, ev->devev->x, ev->devev->y); vkbd_mouse_move(vkbd, ev->devev->x, ev->devev->y);
@ -436,11 +447,15 @@ static int event_handler(struct event *ev)
* Treat scroll events as mouse buttons so oneshot and the like get * Treat scroll events as mouse buttons so oneshot and the like get
* cleared. * cleared.
*/ */
if (last_kbd) { if (timeout_kbd) {
kbd_process_key_event(last_kbd, kev.code = KEYD_EXTERNAL_MOUSE_BUTTON;
KEYD_EXTERNAL_MOUSE_BUTTON, 1); kev.pressed = 1;
kbd_process_key_event(last_kbd, kev.timestamp = ev->timestamp;
KEYD_EXTERNAL_MOUSE_BUTTON, 0);
kbd_process_events(ev->dev->data, &kev, 1);
kev.pressed = 0;
timeout = kbd_process_events(ev->dev->data, &kev, 1);
} }
vkbd_mouse_scroll(vkbd, ev->devev->x, ev->devev->y); vkbd_mouse_scroll(vkbd, ev->devev->x, ev->devev->y);
@ -448,7 +463,6 @@ static int event_handler(struct event *ev)
} }
} }
return timeout;
break; break;
case EV_DEV_ADD: case EV_DEV_ADD:
if (strcmp(ev->dev->name, VKBD_NAME)) if (strcmp(ev->dev->name, VKBD_NAME))
@ -472,7 +486,7 @@ static int event_handler(struct event *ev)
break; break;
} }
return 0; return timeout;
} }
int run_daemon(int argc, char *argv[]) int run_daemon(int argc, char *argv[])

@ -74,16 +74,14 @@ int evloop(int (*event_handler) (struct event *ev))
start_time = get_time_ms(); start_time = get_time_ms();
poll(pfds, ndevs+nr_aux_fds+1, timeout > 0 ? timeout : -1); poll(pfds, ndevs+nr_aux_fds+1, timeout > 0 ? timeout : -1);
elapsed = get_time_ms() - start_time; ev.timestamp = get_time_ms();
elapsed = ev.timestamp - start_time;
ev.timeleft = timeout;
if (timeout > 0 && elapsed >= timeout) { if (timeout > 0 && elapsed >= timeout) {
ev.type = EV_TIMEOUT; ev.type = EV_TIMEOUT;
ev.timeleft = 0;
timeout = event_handler(&ev); timeout = event_handler(&ev);
} else { } else {
timeout -= elapsed; timeout -= elapsed;
ev.timeleft = timeout;
} }
for (i = 0; i < ndevs; i++) { for (i = 0; i < ndevs; i++) {

@ -606,12 +606,14 @@ struct keyboard *new_keyboard(struct config *config,
* of kbd_process_key_event must take place. A return value of 0 permits the * of kbd_process_key_event must take place. A return value of 0 permits the
* main loop to call at liberty. * main loop to call at liberty.
*/ */
long kbd_process_key_event(struct keyboard *kbd, static long process_event(struct keyboard *kbd, uint8_t code, int pressed, int timestamp)
uint8_t code, int pressed)
{ {
int dl = -1; int dl = -1;
struct descriptor d; struct descriptor d;
int timeleft = kbd->timeout - (timestamp - kbd->last_event_ts);
kbd->last_event_ts = timestamp;
/* timeout */ /* timeout */
if (!code) { if (!code) {
if (kbd->active_macro) { if (kbd->active_macro) {
@ -669,7 +671,31 @@ long kbd_process_key_event(struct keyboard *kbd,
cache_set(kbd, code, NULL, -1); cache_set(kbd, code, NULL, -1);
} }
return process_descriptor(kbd, code, &d, dl, pressed); kbd->timeout = process_descriptor(kbd, code, &d, dl, pressed);
return kbd->timeout;
}
long kbd_process_events(struct keyboard *kbd, const struct key_event *events, size_t n)
{
size_t i = 0;
int timeout = 0;
int timeout_ts = 0;
while (i != n) {
const struct key_event *ev = &events[i];
if (timeout && timeout_ts < ev->timestamp) {
timeout = process_event(kbd, 0, 0, timeout_ts);
} else {
timeout = process_event(kbd, ev->code, ev->pressed, ev->timestamp);
i++;
}
timeout_ts = ev->timestamp + timeout;
}
return timeout;
} }
int kbd_eval(struct keyboard *kbd, const char *exp) int kbd_eval(struct keyboard *kbd, const char *exp)

@ -20,6 +20,12 @@ struct cache_entry {
int dl; int dl;
}; };
struct key_event {
uint8_t code;
uint8_t pressed;
int timestamp;
};
/* May correspond to more than one physical input device. */ /* May correspond to more than one physical input device. */
struct keyboard { struct keyboard {
const struct config *original_config; const struct config *original_config;
@ -43,6 +49,8 @@ struct keyboard {
int active_macro_layer; int active_macro_layer;
long macro_repeat_timeout; long macro_repeat_timeout;
int timeout;
int last_event_ts;
struct { struct {
long activation_time; long activation_time;
@ -72,7 +80,7 @@ struct keyboard *new_keyboard(struct config *config,
void (*sink) (uint8_t code, uint8_t pressed), void (*sink) (uint8_t code, uint8_t pressed),
void (*layer_observer)(struct keyboard *kbd, const char *name, int state)); void (*layer_observer)(struct keyboard *kbd, const char *name, int state));
long kbd_process_key_event(struct keyboard *kbd, uint8_t code, int pressed); long kbd_process_events(struct keyboard *kbd, const struct key_event *events, size_t n);
int kbd_eval(struct keyboard *kbd, const char *exp); int kbd_eval(struct keyboard *kbd, const char *exp);
void kbd_reset(struct keyboard *kbd); void kbd_reset(struct keyboard *kbd);

@ -62,7 +62,7 @@ struct event {
enum event_type type; enum event_type type;
struct device *dev; struct device *dev;
struct device_event *devev; struct device_event *devev;
int timeleft; int timestamp;
int fd; int fd;
}; };

@ -30,17 +30,9 @@ static void cleanup()
set_tflags(ICANON|ECHO, 1); set_tflags(ICANON|ECHO, 1);
} }
static long get_time_ms()
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1E3 + ts.tv_nsec / 1E6;
}
int event_handler(struct event *ev) int event_handler(struct event *ev)
{ {
static long last_time; static long last_time;
long ctime = get_time_ms();
switch (ev->type) { switch (ev->type) {
const char *name; const char *name;
@ -56,17 +48,23 @@ int event_handler(struct event *ev)
ev->dev->name, ev->dev->path); ev->dev->name, ev->dev->path);
break; break;
case EV_DEV_EVENT: case EV_DEV_EVENT:
if (ev->devev->type == DEV_KEY) { switch (ev->devev->type) {
case DEV_KEY:
name = keycode_table[ev->devev->code].name; name = keycode_table[ev->devev->code].name;
if (time_flag) if (time_flag)
printf("+%ld ms\t", ctime - last_time); printf("+%ld ms\t", ev->timestamp - last_time);
printf("%s\t%04x:%04x\t%s %s\n", printf("%s\t%04x:%04x\t%s %s\n",
ev->dev->name, ev->dev->name,
ev->dev->vendor_id, ev->dev->vendor_id,
ev->dev->product_id, name, ev->devev->pressed ? "down" : "up"); ev->dev->product_id, name,
} ev->devev->pressed ? "down" : "up");
break;
default:
break;
}
break; break;
case EV_FD_ERR: case EV_FD_ERR:
exit(0); exit(0);
@ -78,7 +76,7 @@ int event_handler(struct event *ev)
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
last_time = ctime; last_time = ev->timestamp;
return 0; return 0;
} }

Loading…
Cancel
Save