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>
This commit is contained in:
Peter Hutterer 2015-02-10 14:23:32 +10:00
parent f0d7eaf11e
commit 2b2a1b0eb9
6 changed files with 112 additions and 3 deletions

View file

@ -1,4 +1,4 @@
SUBDIRS = src doc test tools
SUBDIRS = src doc test tools udev
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}

View file

@ -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}

1
udev/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
libinput-device-group

View file

@ -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"

9
udev/Makefile.am Normal file
View file

@ -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

View file

@ -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;
}