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
dev
Kristian Høgsberg 11 years ago
parent 1a26f1baba
commit 2fce4808dd
  1. 1
      src/compositor.h
  2. 31
      src/evdev.c
  3. 2
      src/evdev.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;
};

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

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

Loading…
Cancel
Save