input: Remap touch point IDs from multiple touch screens to not overlap
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 9 Jan 2014 00:21:24 +0000 (16:21 -0800)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 9 Jan 2014 00:21:24 +0000 (16:21 -0800)
With multiple touch screens on one seat, the touch points IDs from the
different evdev devices may overlap.  We have to remap the IDs we forward
to core weston so that the touch points all have unique IDs within the seat.

Closes: https://bugs.freedesktop.org/show_bug.cgi?id=73003

src/compositor.h
src/evdev.c
src/evdev.h

index 2b9bb6e..9da1e3c 100644 (file)
@@ -509,6 +509,7 @@ struct weston_seat {
 
        void (*led_update)(struct weston_seat *ws, enum weston_led leds);
 
+       uint32_t slot_map;
        struct input_method *input_method;
        char *seat_name;
 };
index 1802bbf..3b21afc 100644 (file)
@@ -90,10 +90,9 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
        struct weston_seat *master = device->seat;
        wl_fixed_t x, y;
        int32_t cx, cy;
-       int slot;
+       int slot, seat_slot;
 
        slot = device->mt.slot;
-
        switch (device->pending_event) {
        case EVDEV_NONE:
                return;
@@ -107,20 +106,24 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
                                                   wl_fixed_from_int(device->mt.slots[slot].x),
                                                   wl_fixed_from_int(device->mt.slots[slot].y),
                                                   &x, &y);
-               notify_touch(master, time,
-                            slot, x, y, WL_TOUCH_DOWN);
+               seat_slot = ffs(~master->slot_map) - 1;
+               device->mt.slots[slot].seat_slot = seat_slot;
+               master->slot_map |= 1 << seat_slot;
+
+               notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN);
                goto handled;
        case EVDEV_ABSOLUTE_MT_MOTION:
                weston_output_transform_coordinate(device->output,
                                                   wl_fixed_from_int(device->mt.slots[slot].x),
                                                   wl_fixed_from_int(device->mt.slots[slot].y),
                                                   &x, &y);
-               notify_touch(master, time,
-                            slot, x, y, WL_TOUCH_MOTION);
+               seat_slot = device->mt.slots[slot].seat_slot;
+               notify_touch(master, time, seat_slot, x, y, WL_TOUCH_MOTION);
                goto handled;
        case EVDEV_ABSOLUTE_MT_UP:
-               notify_touch(master, time, slot, 0, 0,
-                            WL_TOUCH_UP);
+               seat_slot = device->mt.slots[slot].seat_slot;
+               master->slot_map &= ~(1 << seat_slot);
+               notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP);
                goto handled;
        case EVDEV_ABSOLUTE_TOUCH_DOWN:
                transform_absolute(device, &cx, &cy);
@@ -128,7 +131,10 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
                                                   wl_fixed_from_int(cx),
                                                   wl_fixed_from_int(cy),
                                                   &x, &y);
-               notify_touch(master, time, 0, x, y, WL_TOUCH_DOWN);
+               seat_slot = ffs(~master->slot_map) - 1;
+               device->abs.seat_slot = seat_slot;
+               master->slot_map |= 1 << seat_slot;
+               notify_touch(master, time, seat_slot, x, y, WL_TOUCH_DOWN);
                goto handled;
        case EVDEV_ABSOLUTE_MOTION:
                transform_absolute(device, &cx, &cy);
@@ -138,12 +144,15 @@ evdev_flush_pending_event(struct evdev_device *device, uint32_t time)
                                                   &x, &y);
 
                if (device->seat_caps & EVDEV_SEAT_TOUCH)
-                       notify_touch(master, time, 0, x, y, WL_TOUCH_MOTION);
+                       notify_touch(master, time, device->abs.seat_slot,
+                                    x, y, WL_TOUCH_MOTION);
                else if (device->seat_caps & EVDEV_SEAT_POINTER)
                        notify_motion_absolute(master, time, x, y);
                goto handled;
        case EVDEV_ABSOLUTE_TOUCH_UP:
-               notify_touch(master, time, 0, 0, 0, WL_TOUCH_UP);
+               seat_slot = device->abs.seat_slot;
+               master->slot_map &= ~(1 << seat_slot);
+               notify_touch(master, time, seat_slot, 0, 0, WL_TOUCH_UP);
                goto handled;
        }
 
index eef4f3b..25b3631 100644 (file)
@@ -58,6 +58,7 @@ struct evdev_device {
        int fd;
        struct {
                int min_x, max_x, min_y, max_y;
+               uint32_t seat_slot;
                int32_t x, y;
 
                int apply_calibration;
@@ -68,6 +69,7 @@ struct evdev_device {
                int slot;
                struct {
                        int32_t x, y;
+                       uint32_t seat_slot;
                } slots[MAX_SLOTS];
        } mt;
        struct mtdev *mtdev;