[PATCH v3 libinput 2/3] Add udev bits to assign LIBINPUT_DEVICE_GROUP
Peter Hutterer
peter.hutterer at who-t.net
Thu Feb 12 16:07:09 PST 2015
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 at who-t.net>
---
Changes to v2:
- add special handling for 22HD
Makefile.am | 2 +-
configure.ac | 17 +++++++-
udev/.gitignore | 1 +
udev/80-libinput-device-groups.rules | 8 ++++
udev/Makefile.am | 9 +++++
udev/libinput-device-group.c | 77 ++++++++++++++++++++++++++++++++++++
6 files changed, 112 insertions(+), 2 deletions(-)
create mode 100644 udev/.gitignore
create mode 100644 udev/80-libinput-device-groups.rules
create mode 100644 udev/Makefile.am
create mode 100644 udev/libinput-device-group.c
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 f47c5a4..490d1ee 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,11 +176,13 @@ AC_CONFIG_FILES([Makefile
src/libinput.pc
src/libinput-version.h
test/Makefile
- tools/Makefile])
+ tools/Makefile
+ udev/Makefile])
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;
+}
--
2.1.0
More information about the wayland-devel
mailing list