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
This commit is contained in:
Kristian Høgsberg 2014-01-08 16:21:24 -08:00
parent 1a26f1baba
commit 2fce4808dd
3 changed files with 23 additions and 11 deletions

View 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;
};

View 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;
}

View 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;