[PATCH v2] evdev: use mtdev for multitouch devices

Tiago Vignatti tiago.vignatti at intel.com
Fri Mar 16 13:33:03 PDT 2012


mtdev library translates all multitouch based devices to the slotted evdev
protocol. It provides an uniform interface for Weston, which eases mt
implementation when dealing with a big variety of devices.

Weston on drm now directly depends on such library.

Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
---
since v1:
- merged both patches concerning mtdev
- addressed anderco concerns, adding a commentary about the reason of
  O_NONBLOCK

 configure.ac |    2 +-
 src/evdev.c  |   23 ++++++++++++++++++++---
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 9467ff7..f60b208 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 530eb6b..9b8d756 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -26,6 +26,7 @@
 #include <linux/input.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <mtdev.h>
 
 #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);
-- 
1.7.5.4



More information about the wayland-devel mailing list