summaryrefslogtreecommitdiff
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
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>
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac18
-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
6 files changed, 112 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am
index 05698ba..fc6e6b7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = src doc test tools
+SUBDIRS = src doc test tools udev
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
diff --git a/configure.ac b/configure.ac
index 1e60e58..2ccd30d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -69,6 +69,19 @@ fi
AC_SUBST(GCC_CFLAGS)
AC_SUBST(GCC_CXXFLAGS)
+udev_dir_default="$libdir/udev"
+AC_ARG_WITH(udev-dir,
+ AS_HELP_STRING([--with-udev-dir=DIR],
+ [udev base directory [[default=$udev_dir_default]]]),
+ [],
+ [with_udev_dir="yes"])
+AS_CASE($with_udev_dir,
+ [no|""], [AC_MSG_ERROR([You must define a udev base directory])],
+ [yes], [udevdir="$udev_dir_default"],
+ [udevdir="$with_udev_dir"])
+UDEV_DIR=${udevdir}
+AC_SUBST(UDEV_DIR)
+
AC_ARG_ENABLE([documentation],
[AC_HELP_STRING([--enable-documentation],
[Enable building the documentation (default=auto)])],
@@ -163,14 +176,15 @@ AC_CONFIG_FILES([Makefile
src/libinput.pc
src/libinput-version.h
test/Makefile
- tools/Makefile])
+ tools/Makefile
+ udev/Makefile])
AC_CONFIG_FILES([test/symbols-leak-test],
[chmod +x test/symbols-leak-test])
-
AC_OUTPUT
AC_MSG_RESULT([
Prefix ${prefix}
+ udev base dir ${UDEV_DIR}
Build documentation ${build_documentation}
Build tests ${build_tests}
diff --git a/udev/.gitignore b/udev/.gitignore
new file mode 100644
index 0000000..d8e1456
--- /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 0000000..f826bec
--- /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 0000000..3691172
--- /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 0000000..50bfbe0
--- /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;
+}