Use LIBINPUT_DEVICE_GROUP from udev as group identifier
authorBenjamin Tissoires <benjamin.tissoires@gmail.com>
Mon, 9 Feb 2015 23:45:45 +0000 (18:45 -0500)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 18 Feb 2015 00:08:35 +0000 (10:08 +1000)
Store it as identifier in the device group, any two devices that have a
the same non-NULL identifier share the group.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
doc/device-configuration-via-udev.dox
src/evdev.c
src/libinput-private.h
src/libinput.c
src/libinput.h

index bee3659..68a45af 100644 (file)
@@ -12,6 +12,11 @@ The following udev properties are supported:
 <dd>Sets the calibration matrix, see
 libinput_device_config_calibration_get_default_matrix(). If unset,
 defaults to the identity matrix.</dd>
+<dt>LIBINPUT_DEVICE_GROUP</dt>
+<dd>A string identifying the @ref libinput_device_group for this device. Two
+devices with the same property value are grouped into the same device group,
+the value itself is irrelevant otherwise.
+</dd>
 <dt>ID_SEAT</dt>
 <dd>Assigns the physical seat for this device. See
 libinput_seat_get_physical_name(). Defaults to "seat0".</dd>
index 525d5d7..11fa89b 100644 (file)
@@ -1579,6 +1579,42 @@ out:
        return rc;
 }
 
+static int
+evdev_set_device_group(struct evdev_device *device,
+                      struct udev_device *udev_device)
+{
+       struct libinput_device_group *group = NULL;
+       const char *udev_group;
+
+       udev_group = udev_device_get_property_value(udev_device,
+                                                   "LIBINPUT_DEVICE_GROUP");
+       if (udev_group) {
+               struct libinput_device *d;
+
+               list_for_each(d, &device->base.seat->devices_list, link) {
+                       const char *identifier = d->group->identifier;
+
+                       if (identifier &&
+                           strcmp(identifier, udev_group) == 0) {
+                               group = d->group;
+                               break;
+                       }
+               }
+       }
+
+       if (!group) {
+               group = libinput_device_group_create(udev_group);
+               if (!group)
+                       return 1;
+               libinput_device_set_device_group(&device->base, group);
+               libinput_device_group_unref(group);
+       } else {
+               libinput_device_set_device_group(&device->base, group);
+       }
+
+       return 0;
+}
+
 struct evdev_device *
 evdev_device_create(struct libinput_seat *seat,
                    struct udev_device *udev_device)
@@ -1589,7 +1625,6 @@ evdev_device_create(struct libinput_seat *seat,
        int fd;
        int unhandled_device = 0;
        const char *devnode = udev_device_get_devnode(udev_device);
-       struct libinput_device_group *group;
 
        /* Use non-blocking mode so that we can loop on read on
         * evdev_device_data() until all events on the fd are
@@ -1660,11 +1695,8 @@ evdev_device_create(struct libinput_seat *seat,
        if (!device->source)
                goto err;
 
-       group = libinput_device_group_create();
-       if (!group)
+       if (evdev_set_device_group(device, udev_device))
                goto err;
-       libinput_device_set_device_group(&device->base, group);
-       libinput_device_group_unref(group);
 
        list_insert(seat->devices_list.prev, &device->base.link);
 
index 23f66e4..14f5d67 100644 (file)
@@ -168,6 +168,7 @@ struct libinput_device_config {
 struct libinput_device_group {
        int refcount;
        void *user_data;
+       char *identifier; /* unique identifier or NULL for singletons */
 };
 
 struct libinput_device {
@@ -247,7 +248,7 @@ libinput_device_init(struct libinput_device *device,
                     struct libinput_seat *seat);
 
 struct libinput_device_group *
-libinput_device_group_create(void);
+libinput_device_group_create(const char *identifier);
 
 void
 libinput_device_set_device_group(struct libinput_device *device,
index b903caa..bb0595e 100644 (file)
@@ -1407,13 +1407,23 @@ libinput_device_group_ref(struct libinput_device_group *group)
 }
 
 struct libinput_device_group *
-libinput_device_group_create(void)
+libinput_device_group_create(const char *identifier)
 {
        struct libinput_device_group *group;
 
        group = zalloc(sizeof *group);
-       if (group)
-               group->refcount = 1;
+       if (!group)
+               return NULL;
+
+       group->refcount = 1;
+       if (identifier) {
+               group->identifier = strdup(identifier);
+               if (!group->identifier) {
+                       free(group);
+                       group = NULL;
+               }
+       }
+
        return group;
 }
 
@@ -1428,6 +1438,7 @@ libinput_device_set_device_group(struct libinput_device *device,
 static void
 libinput_device_group_destroy(struct libinput_device_group *group)
 {
+       free(group->identifier);
        free(group);
 }
 
index 0fdca7b..09503a2 100644 (file)
@@ -1471,6 +1471,9 @@ libinput_device_get_context(struct libinput_device *device);
  * libinput_device_group_unref() to continue using the handle outside of the
  * immediate scope.
  *
+ * Device groups are assigned based on the <b>LIBINPUT_DEVICE_GROUP</b> udev
+ * property, see @ref udev_config.
+ *
  * @return The device group this device belongs to
  */
 struct libinput_device_group *