diff --git a/udev/.gitignore b/udev/.gitignore index 72c77a0f..2fdaedcf 100644 --- a/udev/.gitignore +++ b/udev/.gitignore @@ -1,2 +1,3 @@ libinput-device-group +libinput-model-quirks *.rules diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-quirks.hwdb index cf57e9c9..fd9efa81 100644 --- a/udev/90-libinput-model-quirks.hwdb +++ b/udev/90-libinput-model-quirks.hwdb @@ -11,7 +11,7 @@ # Match string formats: # libinput: # libinput:name::dmi: - +# libinput:name::fwversion: # # Sort by brand, model diff --git a/udev/90-libinput-model-quirks.rules.in b/udev/90-libinput-model-quirks.rules.in index 43674f55..d8341558 100644 --- a/udev/90-libinput-model-quirks.rules.in +++ b/udev/90-libinput-model-quirks.rules.in @@ -11,6 +11,20 @@ ACTION!="add|change", GOTO="libinput_model_quirks_end" KERNEL!="event*", GOTO="libinput_model_quirks_end" +# Touchpad firmware detection, two-stage process. +# First, run the program and import the LIBINPUT_MODEL_FIRMWARE_VERSION +# environment (if any) +KERNELS=="*input*", \ + ENV{ID_INPUT_TOUCHPAD}=="1", \ + IMPORT{program}="@UDEV_TEST_PATH@libinput-model-quirks %S%p" + +# Second, match on anything with that env set and import from the hwdb +KERNELS=="*input*", \ + ENV{ID_INPUT_TOUCHPAD}=="1", \ + ENV{LIBINPUT_MODEL_FIRMWARE_VERSION}!="", \ + IMPORT{builtin}="hwdb 'libinput:name:$attr{name}:fwversion:$env{LIBINPUT_MODEL_FIRMWARE_VERSION}'" +# End of touchpad firmware detection + # Matches below are exclusive, if one matches we skip the rest # hwdb matches: # diff --git a/udev/Makefile.am b/udev/Makefile.am index e5cf95c4..e850e09c 100644 --- a/udev/Makefile.am +++ b/udev/Makefile.am @@ -1,5 +1,6 @@ udevdir=$(UDEV_DIR) -udev_PROGRAMS = libinput-device-group +udev_PROGRAMS = libinput-device-group \ + libinput-model-quirks litest_rules = 80-libinput-device-groups-litest.rules \ 90-libinput-model-quirks-litest.rules @@ -9,6 +10,13 @@ libinput_device_group_SOURCES = libinput-device-group.c libinput_device_group_CFLAGS = $(LIBUDEV_CFLAGS) $(GCC_CFLAGS) libinput_device_group_LDADD = $(LIBUDEV_LIBS) +libinput_model_quirks_SOURCES = libinput-model-quirks.c +libinput_model_quirks_CFLAGS = \ + -I$(top_srcdir)/src \ + $(LIBUDEV_CFLAGS) \ + $(GCC_CFLAGS) +libinput_model_quirks_LDADD = $(LIBUDEV_LIBS) + udev_rulesdir=$(UDEV_DIR)/rules.d dist_udev_rules_DATA = \ 80-libinput-device-groups.rules \ diff --git a/udev/libinput-model-quirks.c b/udev/libinput-model-quirks.c new file mode 100644 index 00000000..3c51a378 --- /dev/null +++ b/udev/libinput-model-quirks.c @@ -0,0 +1,90 @@ +/* + * Copyright © 2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libinput-util.h" + +static inline const char * +prop_value(struct udev_device *device, + const char *prop_name) +{ + struct udev_device *parent; + const char *prop_value = NULL; + + parent = device; + while (parent && !prop_value) { + prop_value = udev_device_get_property_value(parent, prop_name); + parent = udev_device_get_parent(parent); + } + + return prop_value; +} + +static void +handle_touchpad(struct udev_device *device) +{ +} + +int main(int argc, char **argv) +{ + int rc = 1; + struct udev *udev = NULL; + struct udev_device *device = NULL; + const char *syspath; + + 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; + + if (udev_device_get_property_value(device, "ID_INPUT_TOUCHPAD")) + handle_touchpad(device); + + rc = 0; + +out: + if (device) + udev_device_unref(device); + if (udev) + udev_unref(udev); + + return rc; +}