[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