[PATCH libinput 2/2] Hook up event processing to libevdev
Peter Hutterer
peter.hutterer at who-t.net
Mon Feb 17 22:09:10 PST 2014
This gives us the ability to handle SYN_DROPPED transparently to the caller.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/evdev.c | 90 +++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 58 insertions(+), 32 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index ba28fc6..836d0af 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -29,7 +29,7 @@
#include <linux/input.h>
#include <unistd.h>
#include <fcntl.h>
-#include <mtdev.h>
+#include <mtdev-plumbing.h>
#include <assert.h>
#include "libinput.h"
@@ -436,56 +436,82 @@ fallback_dispatch_create(void)
return dispatch;
}
-static void
-evdev_process_events(struct evdev_device *device,
- struct input_event *ev, int count)
+static inline void
+evdev_process_event(struct evdev_device *device, struct input_event *e)
{
struct evdev_dispatch *dispatch = device->dispatch;
- struct input_event *e, *end;
- uint32_t time = 0;
+ uint32_t time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
- e = ev;
- end = e + count;
- for (e = ev; e < end; e++) {
- time = e->time.tv_sec * 1000 + e->time.tv_usec / 1000;
+ dispatch->interface->process(dispatch, device, e, time);
+}
- dispatch->interface->process(dispatch, device, e, time);
+static inline void
+evdev_device_dispatch_one(struct evdev_device *device,
+ struct input_event *ev)
+{
+ if (!device->mtdev) {
+ evdev_process_event(device, ev);
+ } else {
+ mtdev_put_event(device->mtdev, ev);
+ if (libevdev_event_is_code(ev, EV_SYN, SYN_REPORT)) {
+ while(!mtdev_empty(device->mtdev)) {
+ struct input_event e;
+ mtdev_get_event(device->mtdev, &e);
+ evdev_process_event(device, &e);
+ }
+ }
}
}
+static int
+evdev_sync_device(struct evdev_device *device)
+{
+ struct input_event ev;
+ int rc;
+
+ do {
+ rc = libevdev_next_event(device->evdev,
+ LIBEVDEV_READ_FLAG_SYNC, &ev);
+ if (rc < 0)
+ break;
+ evdev_device_dispatch_one(device, &ev);
+ } while (rc == LIBEVDEV_READ_STATUS_SYNC);
+
+ return rc == -EAGAIN ? 0 : rc;
+}
+
static void
evdev_device_dispatch(void *data)
{
struct evdev_device *device = data;
struct libinput *libinput = device->base.seat->libinput;
- int fd = device->fd;
- struct input_event ev[32];
- int len;
+ struct input_event ev;
+ int rc;
/* If the compositor is repainting, this function is called only once
* per frame and we have to process all the events available on the
* fd, otherwise there will be input lag. */
do {
- if (device->mtdev)
- len = mtdev_get(device->mtdev, fd, ev,
- ARRAY_LENGTH(ev)) *
- sizeof (struct input_event);
- else
- len = read(fd, &ev, sizeof ev);
+ rc = libevdev_next_event(device->evdev,
+ LIBEVDEV_READ_FLAG_NORMAL, &ev);
+ if (rc == LIBEVDEV_READ_STATUS_SYNC) {
+ /* send one more sync event so we handle all
+ currently pending events before we sync up
+ to the current state */
+ ev.code = SYN_REPORT;
+ evdev_device_dispatch_one(device, &ev);
- if (len < 0 || len % sizeof ev[0] != 0) {
- if (len < 0 && errno != EAGAIN && errno != EINTR) {
- libinput_remove_source(libinput,
- device->source);
- device->source = NULL;
- }
+ rc = evdev_sync_device(device);
+ if (rc == 0)
+ rc = LIBEVDEV_READ_STATUS_SUCCESS;
+ } else if (rc == LIBEVDEV_READ_STATUS_SUCCESS)
+ evdev_device_dispatch_one(device, &ev);
+ } while (rc == LIBEVDEV_READ_STATUS_SUCCESS);
- return;
- }
-
- evdev_process_events(device, ev, len / sizeof ev[0]);
-
- } while (len > 0);
+ if (rc != -EAGAIN && rc != -EINTR) {
+ libinput_remove_source(libinput, device->source);
+ device->source = NULL;
+ }
}
static int
--
1.8.4.2
More information about the wayland-devel
mailing list