diff --git a/configure.ac b/configure.ac index 9467ff7d5..f60b20860 100644 --- a/configure.ac +++ b/configure.ac @@ -73,7 +73,7 @@ AC_ARG_ENABLE(drm-compositor, [ --enable-drm-compositor],, AM_CONDITIONAL(ENABLE_DRM_COMPOSITOR, test x$enable_drm_compositor = xyes) if test x$enable_drm_compositor = xyes; then AC_DEFINE([BUILD_DRM_COMPOSITOR], [1], [Build the DRM compositor]) - PKG_CHECK_MODULES(DRM_COMPOSITOR, [libudev >= 136 libdrm >= 2.4.30 gbm]) + PKG_CHECK_MODULES(DRM_COMPOSITOR, [libudev >= 136 libdrm >= 2.4.30 gbm mtdev]) fi diff --git a/src/evdev.c b/src/evdev.c index 530eb6b66..9b8d756af 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "compositor.h" #include "evdev.h" @@ -57,6 +58,7 @@ struct evdev_input_device { int32_t x[MAX_SLOTS]; int32_t y[MAX_SLOTS]; } mt; + struct mtdev *mtdev; struct { int dx, dy; @@ -320,13 +322,14 @@ evdev_flush_motion(struct evdev_input_device *device, uint32_t time) device->type &= ~EVDEV_ABSOLUTE_MOTION; } } +#define NUM_EVENTS 8 static int evdev_input_device_data(int fd, uint32_t mask, void *data) { struct weston_compositor *ec; struct evdev_input_device *device = data; - struct input_event ev[8], *e, *end; + struct input_event ev[NUM_EVENTS], *e, *end; int len; uint32_t time = 0; @@ -334,7 +337,11 @@ evdev_input_device_data(int fd, uint32_t mask, void *data) if (!ec->focus) return 1; - len = read(fd, &ev, sizeof ev); + if (device->mtdev) + len = mtdev_get(device->mtdev, fd, ev, NUM_EVENTS) * + sizeof (struct input_event); + else + len = read(fd, &ev, sizeof ev); if (len < 0 || len % sizeof e[0] != 0) { /* FIXME: call device_removed when errno is ENODEV. */; return 1; @@ -450,18 +457,26 @@ evdev_input_device_create(struct evdev_input *master, device->master = master; device->is_touchpad = 0; device->is_mt = 0; + device->mtdev = NULL; device->devnode = strdup(path); device->mt.slot = -1; device->rel.dx = 0; device->rel.dy = 0; - device->fd = open(path, O_RDONLY); + /* if O_NONBLOCK is not set, mtdev_get() blocks */ + device->fd = open(path, O_RDONLY | O_NONBLOCK); if (device->fd < 0) goto err0; if (evdev_configure_device(device) == -1) goto err1; + if (device->is_mt) { + device->mtdev = mtdev_new_open(device->fd); + if (!device->mtdev) + fprintf(stderr, "mtdev failed to open for %s\n", path); + } + device->source = wl_event_loop_add_fd(ec->input_loop, device->fd, WL_EVENT_READABLE, evdev_input_device_data, device); @@ -511,6 +526,8 @@ device_removed(struct udev_device *udev_device, struct evdev_input *master) if (!strcmp(device->devnode, devnode)) { wl_event_source_remove(device->source); wl_list_remove(&device->link); + if (device->mtdev) + mtdev_close_delete(device->mtdev); close(device->fd); free(device->devnode); free(device);