From 2fce4808dd90bb59689c56ddbe322496ca653182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 8 Jan 2014 16:21:24 -0800 Subject: [PATCH] input: Remap touch point IDs from multiple touch screens to not overlap 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 | 1 + src/evdev.c | 31 ++++++++++++++++++++----------- src/evdev.h | 2 ++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/compositor.h b/src/compositor.h index 2b9bb6e1..9da1e3c8 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -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; }; diff --git a/src/evdev.c b/src/evdev.c index 1802bbf9..3b21afc6 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -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; } diff --git a/src/evdev.h b/src/evdev.h index eef4f3b7..25b36315 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -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;