evdev: use mtdev for multitouch devices
authorTiago Vignatti <tiago.vignatti@intel.com>
Fri, 16 Mar 2012 20:33:03 +0000 (17:33 -0300)
committerJonas Ådahl <jadahl@gmail.com>
Sun, 10 Nov 2013 16:51:27 +0000 (17:51 +0100)
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@intel.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
src/evdev.c

index 530eb6b..9b8d756 100644 (file)
@@ -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);