[PATCH libinput] evdev: allow weird multitouch device without slots
Peter Hutterer
peter.hutterer at who-t.net
Tue Aug 19 00:02:35 PDT 2014
On Tue, Aug 19, 2014 at 06:29:40AM +0300, Leonid Borisenko wrote:
> HID device 'USB HID v1.11 Mouse' provided by Microsoft Wireless Optical
> Desktop® 2.20 (connected to USB and identified as vendor 0x45e, product
> 0xe3, version 0x111) is reported as supporting EV_ABS event with ABS_MT_SLOT
> code, but nevertheless libevdev_get_num_slots returns -1.
yeah, that's intentional. libevdev detects those devices (through guesswork,
but still...) and returns -1 as slot number.
> Furthermore, all connected devices (mouse and keyboard) don't produce any
> EV_ABS events for that HID Mouse device in tests with evtest.
>
> Before this fix mouse didn't work in Weston (but worked in X.Org).
>
> As partially explained by LKML message [1] (Message-Id [2]):
>
> The root of the problem comes from hid-input, which maps unknown axis
> to ABS_MISC. However, when an event code is already in use, hid-input
> uses the one after, leading to uses of ABS_MISC + N, where N is the
> number of unknown axis.
>
> We are encountering a problem with the multitouch protocol here because
> if a device has more than 7 unknown axis (which is the case for the PS3
> Sixaxis controller), then the unknown axis get maps to ABS_MT_SLOT and
> beyond.
>
> [1] https://lkml.org/lkml/2013/11/20/515
> [2] 1384983141-31019-1-git-send-email-benjamin.tissoires at redhat.com
>
> Signed-off-by: Leonid Borisenko <leo.borisenko at gmail.com>
> ---
> src/evdev.c | 16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/src/evdev.c b/src/evdev.c
> index a125510..d6a14b7 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -144,7 +144,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
> pointer_notify_motion(base, time, motion.dx, motion.dy);
> break;
> case EVDEV_ABSOLUTE_MT_DOWN:
> - if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
> + if (slot == -1 || !(device->seat_caps & EVDEV_DEVICE_TOUCH))
> break;
>
> if (device->mt.slots[slot].seat_slot != -1) {
> @@ -167,7 +167,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
> touch_notify_touch_down(base, time, slot, seat_slot, x, y);
> break;
> case EVDEV_ABSOLUTE_MT_MOTION:
> - if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
> + if (slot == -1 || !(device->seat_caps & EVDEV_DEVICE_TOUCH))
> break;
>
> seat_slot = device->mt.slots[slot].seat_slot;
> @@ -180,7 +180,7 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
> touch_notify_touch_motion(base, time, slot, seat_slot, x, y);
> break;
> case EVDEV_ABSOLUTE_MT_UP:
> - if (!(device->seat_caps & EVDEV_DEVICE_TOUCH))
> + if (slot == -1 || !(device->seat_caps & EVDEV_DEVICE_TOUCH))
> break;
>
> seat_slot = device->mt.slots[slot].seat_slot;
> @@ -680,6 +680,16 @@ evdev_configure_device(struct evdev_device *device)
> active_slot = libevdev_get_current_slot(evdev);
> }
>
> + if (num_slots <= 0) {
> + log_bug_kernel(libinput,
> + "multitouch input device %s "
> + "has %s slots\n",
> + device->devnode,
> + num_slots == 0 ? "0" : "no");
> + num_slots = 0;
> + active_slot = -1;
> + }
> +
so, as I said above the libevdev behaviour is intentional and our indicator
that this isn't a MT device after all. We should integrate that knowledge
better so that we don't label a device as touch device when it isn't, and so
that we process events from those axes as normal ABS events instead of MT
events.
Cheers,
Peter
> slots = calloc(num_slots, sizeof(struct mt_slot));
> if (!slots)
> return -1;
> --
> 2.1.0.rc1
More information about the wayland-devel
mailing list