summaryrefslogtreecommitdiff
path: root/udev
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2015-02-10 14:23:32 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2015-02-18 10:08:29 +1000
commit2b2a1b0eb9f4e3bc835401e1436731fcf4b2163b (patch)
tree9ec67c6fb2a07d41cc0feb607a4d0a66dc4baf58 /udev
parentf0d7eaf11e40e54fe3ace5c50718168c66d45c7a (diff)
Add udev bits to assign LIBINPUT_DEVICE_GROUP
The easiest way to get a device group is by looking at the phys path of the input device (which looks like usb-0000:00:14.0-1/input1) and dropping the /inputX bit. The rest is the same for devices that belong together (except on the Cintiq 22HD Touch). Ideally we could just take ATTRS{phys} but we can't select substrings to drop into ENV so we need to do it ourselves. This patch adds a callout that takes a syspath and prints the mangled path, to be used in LIBINPUT_DEVICE_GROUP. The rule triggers on any device that has a non-zero phys attribute, this groups devices like tablets together but also devices like mice with multiple interfaces. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Diffstat (limited to 'udev')
-rw-r--r--udev/.gitignore1
-rw-r--r--udev/80-libinput-device-groups.rules8
-rw-r--r--udev/Makefile.am9
-rw-r--r--udev/libinput-device-group.c77
4 files changed, 95 insertions, 0 deletions
diff --git a/udev/.gitignore b/udev/.gitignore
new file mode 100644
index 00000000..d8e1456b
--- /dev/null
+++ b/udev/.gitignore
@@ -0,0 +1 @@
+libinput-device-group
diff --git a/udev/80-libinput-device-groups.rules b/udev/80-libinput-device-groups.rules
new file mode 100644
index 00000000..f826bec6
--- /dev/null
+++ b/udev/80-libinput-device-groups.rules
@@ -0,0 +1,8 @@
+ACTION!="add|change", GOTO="libinput_device_group_end"
+KERNEL!="event[0-9]*", GOTO="libinput_device_group_end"
+
+ATTRS{phys}=="?*", \
+ PROGRAM="libinput-device-group %S%p", \
+ ENV{LIBINPUT_DEVICE_GROUP}="%c"
+
+LABEL="libinput_device_group_end"
diff --git a/udev/Makefile.am b/udev/Makefile.am
new file mode 100644
index 00000000..3691172c
--- /dev/null
+++ b/udev/Makefile.am
@@ -0,0 +1,9 @@
+udevdir=$(UDEV_DIR)
+udev_PROGRAMS = libinput-device-group
+
+libinput_device_group_SOURCES = libinput-device-group.c
+libinput_device_group_CFLAGS = $(LIBUDEV_CFLAGS) $(GCC_CFLAGS)
+libinput_device_group_LDADD = $(LIBUDEV_LIBS)
+
+udev_rulesdir=$(UDEV_DIR)/rules.d
+dist_udev_rules_DATA = 80-libinput-device-groups.rules
diff --git a/udev/libinput-device-group.c b/udev/libinput-device-group.c
new file mode 100644
index 00000000..50bfbe02
--- /dev/null
+++ b/udev/libinput-device-group.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libudev.h>
+
+int main(int argc, char **argv)
+{
+ int rc = 1;
+ struct udev *udev = NULL;
+ struct udev_device *device = NULL;
+ const char *syspath,
+ *phys = NULL;
+ char *group,
+ *str;
+
+ if (argc != 2)
+ return 1;
+
+ syspath = argv[1];
+
+ udev = udev_new();
+ if (!udev)
+ goto out;
+
+ device = udev_device_new_from_syspath(udev, syspath);
+ if (!device)
+ goto out;
+
+ /* Find the first parent with ATTRS{phys} set. For tablets that
+ * value looks like usb-0000:00:14.0-1/input1. Drop the /input1
+ * bit and use the remainder as device group identifier */
+ while (device != NULL) {
+ struct udev_device *parent;
+
+ phys = udev_device_get_sysattr_value(device, "phys");
+ if (phys)
+ break;
+
+ parent = udev_device_get_parent(device);
+ udev_device_ref(parent);
+ udev_device_unref(device);
+ device = parent;
+ }
+
+ if (!phys)
+ goto out;
+
+ group = strdup(phys);
+ if (!group)
+ goto out;
+
+ str = strstr(group, "/input");
+ if (str)
+ *str = '\0';
+
+ /* Cintiq 22HD Touch has
+ usb-0000:00:14.0-6.3.1/input0 for the touch
+ usb-0000:00:14.0-6.3.0/input0 for the pen
+ Check if there's a . after the last -, if so, cut off the string
+ there.
+ */
+ str = strrchr(group, '.');
+ if (str && str > strrchr(group, '-'))
+ *str = '\0';
+
+ printf("%s\n", group);
+ free(group);
+
+ rc = 0;
+out:
+ if (device)
+ udev_device_unref(device);
+ if (udev)
+ udev_unref(udev);
+
+ return rc;
+}