[PATCH libinput] evdev: retrieve udev tags
Peter Hutterer
peter.hutterer at who-t.net
Mon Feb 2 21:06:27 PST 2015
On Mon, Feb 02, 2015 at 01:43:48PM -0500, Benjamin Tissoires wrote:
> Udev already tags the devices by opening each of them and analyzing their
> features. We are basically re-doing this in libinput.
>
> The advantage of udev tags over the plain heuristic from libinput is that
> users (or driver writers) can force some tags that are not detected by
> common rules. For instance, the pad part of the Wacom tablets is difficult
> to discriminate from a joystlick or a pointer.
>
> This patch adds a udev_tags field in struct evdev_device and populates
> it accroding to the current known udev built in tags.
there are a few typos in the commit message, please re-read through it.
Generally this looks like a good approach, though it means we have to audit
the code we have at the moment to ensure we can deal with devices that are
badly labelled. e.g. a keyboard with ID_INPUT_MOUSE still sends key events -
do we handle those correctly?
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
> ---
>
> Hi,
>
> I had to rely on the udev tags when working on the tablet branch.
> I think master could benefit from it as well, given one of the recent patches
> Hans sent.
>
> Cheers,
> Benjamin
>
>
> src/evdev.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
> src/evdev.h | 11 +++++++++++
> 2 files changed, 62 insertions(+)
>
> diff --git a/src/evdev.c b/src/evdev.c
> index 24d30e0..838a5e5 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -49,6 +49,24 @@ enum evdev_key_type {
> EVDEV_KEY_TYPE_BUTTON,
> };
>
> +struct evdev_udev_tag_match {
> + const char *name;
> + enum evdev_device_udev_tags tag;
> +};
> +
> +static const struct evdev_udev_tag_match evdev_udev_tag_matches[] = {
> + {"ID_INPUT_KEYBOARD", EVDEV_UDEV_TAG_KEYBOARD},
> + {"ID_INPUT_MOUSE", EVDEV_UDEV_TAG_MOUSE},
> + {"ID_INPUT_TOUCHPAD", EVDEV_UDEV_TAG_TOUCHPAD},
> + {"ID_INPUT_TOUCHSCREEN", EVDEV_UDEV_TAG_TOUCHSCREEN},
> + {"ID_INPUT_TABLET", EVDEV_UDEV_TAG_TABLET},
> + {"ID_INPUT_JOYSTICK", EVDEV_UDEV_TAG_JOYSTICK},
> + {"ID_INPUT_ACCELEROMETER", EVDEV_UDEV_TAG_ACCELEROMETER},
> +
> + /* sentinel value */
> + { 0 },
> +};
> +
> static void
> hw_set_key_down(struct evdev_device *device, int code, int pressed)
> {
> @@ -1340,6 +1358,18 @@ evdev_configure_device(struct evdev_device *device)
> has_keyboard = 0;
> has_touch = 0;
>
> + if (device->udev_tags)
in the tablet/buttonset branch - are you using the tags elsewhere? If not,
you can keep the lot local to evdev_configure_device.
Cheers,
Peter
> + log_info(libinput,
> + "input device '%s', %s is tagged by udev as:%s%s%s%s%s%s\n",
> + device->devname, devnode,
> + device->udev_tags & EVDEV_UDEV_TAG_KEYBOARD ? " Keyboard" : "",
> + device->udev_tags & EVDEV_UDEV_TAG_MOUSE ? " Mouse" : "",
> + device->udev_tags & EVDEV_UDEV_TAG_TOUCHPAD ? " Touchpad" : "",
> + device->udev_tags & EVDEV_UDEV_TAG_TOUCHSCREEN ? " Touchscreen" : "",
> + device->udev_tags & EVDEV_UDEV_TAG_TABLET ? " Tablet" : "",
> + device->udev_tags & EVDEV_UDEV_TAG_JOYSTICK ? " Joystick" : "",
> + device->udev_tags & EVDEV_UDEV_TAG_ACCELEROMETER ? " Accelerometer" : "");
> +
> for (i = BTN_JOYSTICK; i <= BTN_PINKIE; i++)
> if (libevdev_has_event_code(evdev, EV_KEY, i))
> has_joystick_button = 1;
> @@ -1559,6 +1589,25 @@ out:
> return rc;
> }
>
> +static enum evdev_device_udev_tags
> +evdev_device_get_udev_tags(struct evdev_device *device,
> + struct udev_device *udev_device)
> +{
> + const char *prop;
> + enum evdev_device_udev_tags tags = 0;
> + const struct evdev_udev_tag_match *match = evdev_udev_tag_matches;
> +
> + while (match->name) {
> + prop = udev_device_get_property_value(device->udev_device,
> + match->name);
> + if (prop)
> + tags |= match->tag;
> +
> + match++;
> + }
> + return tags;
> +}
> +
> struct evdev_device *
> evdev_device_create(struct libinput_seat *seat,
> struct udev_device *udev_device)
> @@ -1620,6 +1669,8 @@ evdev_device_create(struct libinput_seat *seat,
> matrix_init_identity(&device->abs.usermatrix);
> matrix_init_identity(&device->abs.default_calibration);
>
> + device->udev_tags = evdev_device_get_udev_tags(device, udev_device);
> +
> if (evdev_configure_device(device) == -1)
> goto err;
>
> diff --git a/src/evdev.h b/src/evdev.h
> index fc70a28..91c8624 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -57,6 +57,16 @@ enum evdev_device_tags {
> EVDEV_TAG_TOUCHPAD_TRACKPOINT = (1 << 3),
> };
>
> +enum evdev_device_udev_tags {
> + EVDEV_UDEV_TAG_KEYBOARD = (1 << 0),
> + EVDEV_UDEV_TAG_MOUSE = (1 << 1),
> + EVDEV_UDEV_TAG_TOUCHPAD = (1 << 2),
> + EVDEV_UDEV_TAG_TOUCHSCREEN = (1 << 3),
> + EVDEV_UDEV_TAG_TABLET = (1 << 4),
> + EVDEV_UDEV_TAG_JOYSTICK = (1 << 5),
> + EVDEV_UDEV_TAG_ACCELEROMETER = (1 << 6),
> +};
> +
> struct mt_slot {
> int32_t seat_slot;
> int32_t x, y;
> @@ -128,6 +138,7 @@ struct evdev_device {
> enum evdev_event_type pending_event;
> enum evdev_device_seat_capability seat_caps;
> enum evdev_device_tags tags;
> + enum evdev_device_udev_tags udev_tags;
>
> int is_mt;
> int suspended;
> --
> 2.1.0
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
More information about the wayland-devel
mailing list