evdev: retrieve udev tags
authorBenjamin Tissoires <benjamin.tissoires@gmail.com>
Mon, 2 Feb 2015 18:37:14 +0000 (13:37 -0500)
committerPeter Hutterer <peter.hutterer@who-t.net>
Sun, 8 Feb 2015 22:36:52 +0000 (08:36 +1000)
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 joystick or a pointer.

For now we tread INPUT_ID_KEY and INPUT_ID_KEYBOARD as equivalent. It may
become necessary to separate them later.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
src/evdev.c

index 6024d38..dad6616 100644 (file)
@@ -49,6 +49,37 @@ enum evdev_key_type {
        EVDEV_KEY_TYPE_BUTTON,
 };
 
+enum evdev_device_udev_tags {
+        EVDEV_UDEV_TAG_INPUT = (1 << 0),
+        EVDEV_UDEV_TAG_KEYBOARD = (1 << 1),
+        EVDEV_UDEV_TAG_MOUSE = (1 << 2),
+        EVDEV_UDEV_TAG_TOUCHPAD = (1 << 3),
+        EVDEV_UDEV_TAG_TOUCHSCREEN = (1 << 4),
+        EVDEV_UDEV_TAG_TABLET = (1 << 5),
+        EVDEV_UDEV_TAG_JOYSTICK = (1 << 6),
+        EVDEV_UDEV_TAG_ACCELEROMETER = (1 << 7),
+};
+
+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",                    EVDEV_UDEV_TAG_INPUT},
+       {"ID_INPUT_KEYBOARD",           EVDEV_UDEV_TAG_KEYBOARD},
+       {"ID_INPUT_KEY",                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)
 {
@@ -1319,6 +1350,25 @@ evdev_fix_abs_resolution(struct libevdev *evdev,
        }
 }
 
+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;
+}
+
 static int
 evdev_configure_device(struct evdev_device *device)
 {
@@ -1333,6 +1383,9 @@ evdev_configure_device(struct evdev_device *device)
        int slot;
        unsigned int i;
        const char *devnode = udev_device_get_devnode(device->udev_device);
+       enum evdev_device_udev_tags udev_tags;
+
+       udev_tags = evdev_device_get_udev_tags(device, device->udev_device);
 
        has_rel = 0;
        has_abs = 0;
@@ -1342,6 +1395,18 @@ evdev_configure_device(struct evdev_device *device)
        has_keyboard = 0;
        has_touch = 0;
 
+       if (udev_tags)
+               log_info(libinput,
+                        "input device '%s', %s is tagged by udev as:%s%s%s%s%s%s\n",
+                        device->devname, devnode,
+                        udev_tags & EVDEV_UDEV_TAG_KEYBOARD ? " Keyboard" : "",
+                        udev_tags & EVDEV_UDEV_TAG_MOUSE ? " Mouse" : "",
+                        udev_tags & EVDEV_UDEV_TAG_TOUCHPAD ? " Touchpad" : "",
+                        udev_tags & EVDEV_UDEV_TAG_TOUCHSCREEN ? " Touchscreen" : "",
+                        udev_tags & EVDEV_UDEV_TAG_TABLET ? " Tablet" : "",
+                        udev_tags & EVDEV_UDEV_TAG_JOYSTICK ? " Joystick" : "",
+                        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;