diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | rules/60-evdev_id.rules | 10 | ||||
-rw-r--r-- | src/udev/udev-builtin-evdev_id.c | 78 | ||||
-rw-r--r-- | src/udev/udev-builtin.c | 1 | ||||
-rw-r--r-- | src/udev/udev.h | 2 |
5 files changed, 93 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 2d45a7b6c5..7f9dc26085 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3478,6 +3478,7 @@ dist_udevrules_DATA += \ rules/42-usb-hid-pm.rules \ rules/50-udev-default.rules \ rules/60-drm.rules \ + rules/60-evdev_id.rules \ rules/60-keyboard.rules \ rules/70-mouse.rules \ rules/60-persistent-storage-tape.rules \ @@ -3561,6 +3562,7 @@ libudev_core_la_SOURCES = \ src/udev/udev-builtin.c \ src/udev/udev-builtin-btrfs.c \ src/udev/udev-builtin-hwdb.c \ + src/udev/udev-builtin-evdev_id.c \ src/udev/udev-builtin-input_id.c \ src/udev/udev-builtin-keyboard.c \ src/udev/udev-builtin-net_id.c \ diff --git a/rules/60-evdev_id.rules b/rules/60-evdev_id.rules new file mode 100644 index 0000000000..4716a1034d --- /dev/null +++ b/rules/60-evdev_id.rules @@ -0,0 +1,10 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="add", GOTO="evdev_id_end" +SUBSYSTEM!="input", GOTO="evdev_id_end" +KERNEL!="event*", GOTO="evdev_id_end" + +ENV{ID_INPUT_TOUCHSCREEN}=="1", IMPORT{builtin}="evdev_id" +ENV{ID_INPUT_TABLET}=="1", IMPORT{builtin}="evdev_id" + +LABEL="evdev_id_end" diff --git a/src/udev/udev-builtin-evdev_id.c b/src/udev/udev-builtin-evdev_id.c new file mode 100644 index 0000000000..1b58bdda3d --- /dev/null +++ b/src/udev/udev-builtin-evdev_id.c @@ -0,0 +1,78 @@ +/* + * evdev_id - extracts miscellaneous information from evdev devices + * + * Copyright (C) 2014 Red Hat + * Author: + * Carlos Garnacho <carlosg@gnome.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with keymap; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <linux/input.h> +#include "udev.h" +#include "util.h" + +static inline int abs_size_mm(const struct input_absinfo *absinfo) { + /* Resolution is defined to be in units/mm for ABS_X/Y */ + return (absinfo->maximum - absinfo->minimum) / absinfo->resolution; +} + +static void extract_info(struct udev_device *dev, const char *devpath, bool test) { + char width[DECIMAL_STR_MAX(int)], height[DECIMAL_STR_MAX(int)]; + struct input_absinfo xabsinfo = {}, yabsinfo = {}; + _cleanup_close_ int fd = -1; + + fd = open(devpath, O_RDONLY|O_CLOEXEC); + if (fd < 0) + return; + + if (ioctl(fd, EVIOCGABS(ABS_X), &xabsinfo) < 0 || + ioctl(fd, EVIOCGABS(ABS_Y), &yabsinfo) < 0) + return; + + if (xabsinfo.resolution <= 0 || yabsinfo.resolution <= 0) + return; + + snprintf(width, sizeof(width), "%d", abs_size_mm(&xabsinfo)); + snprintf(height, sizeof(height), "%d", abs_size_mm(&yabsinfo)); + + udev_builtin_add_property(dev, test, "ID_INPUT_WIDTH_MM", width); + udev_builtin_add_property(dev, test, "ID_INPUT_HEIGHT_MM", height); +} + +static int builtin_evdev_id(struct udev_device *dev, int argc, char *argv[], bool test) { + const char *subsystem; + const char *devnode; + + subsystem = udev_device_get_subsystem(dev); + + if (!subsystem || !streq(subsystem, "input")) + return EXIT_SUCCESS; + + devnode = udev_device_get_devnode(dev); + /* not an evdev node */ + if (!devnode) + return EXIT_SUCCESS; + + extract_info(dev, devnode, test); + + return EXIT_SUCCESS; +} + +const struct udev_builtin udev_builtin_evdev_id = { + .name = "evdev_id", + .cmd = builtin_evdev_id, + .help = "evdev devices information", +}; diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index 1950ec23a1..9cfea5e03b 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -47,6 +47,7 @@ static const struct udev_builtin *builtins[] = { #ifdef HAVE_ACL [UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess, #endif + [UDEV_BUILTIN_EVDEV_ID] = &udev_builtin_evdev_id, }; void udev_builtin_init(struct udev *udev) { diff --git a/src/udev/udev.h b/src/udev/udev.h index dece6eccab..ce4188f881 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -164,6 +164,7 @@ enum udev_builtin_cmd { #ifdef HAVE_ACL UDEV_BUILTIN_UACCESS, #endif + UDEV_BUILTIN_EVDEV_ID, UDEV_BUILTIN_MAX }; struct udev_builtin { @@ -190,6 +191,7 @@ extern const struct udev_builtin udev_builtin_net_setup_link; extern const struct udev_builtin udev_builtin_path_id; extern const struct udev_builtin udev_builtin_usb_id; extern const struct udev_builtin udev_builtin_uaccess; +extern const struct udev_builtin udev_builtin_evdev_id; void udev_builtin_init(struct udev *udev); void udev_builtin_exit(struct udev *udev); enum udev_builtin_cmd udev_builtin_lookup(const char *command); |