diff --git a/src/libratbag-private.h b/src/libratbag-private.h index 437fa6c4..9c859643 100644 --- a/src/libratbag-private.h +++ b/src/libratbag-private.h @@ -43,7 +43,6 @@ struct ratbag { char *name; struct udev_device *udev_device; struct udev_device *udev_hidraw; - int evdev_fd; int hidraw_fd; int refcount; struct input_id ids; @@ -103,8 +102,6 @@ struct ratbag_button { enum ratbag_button_action_type action_type; }; -void ratbag_device_init(struct ratbag *rb, int fd); - static inline void ratbag_set_drv_data(struct ratbag *ratbag, void *drv_data) { diff --git a/src/libratbag-util.c b/src/libratbag-util.c index 507eae23..0d77cef3 100644 --- a/src/libratbag-util.c +++ b/src/libratbag-util.c @@ -69,3 +69,19 @@ list_empty(const struct list *list) { return list->next == list; } + +const char * +udev_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; +} diff --git a/src/libratbag-util.h b/src/libratbag-util.h index 7fa16341..abf699fd 100644 --- a/src/libratbag-util.h +++ b/src/libratbag-util.h @@ -25,6 +25,7 @@ #define LIBRATBAG_UTIL_H #include +#include /* * This list data structure is a verbatim copy from wayland-util.h from the @@ -117,4 +118,7 @@ long_set_bit_state(unsigned long *array, int bit, int state) long_clear_bit(array, bit); } +const char * +udev_prop_value(struct udev_device *device, + const char *property_name); #endif /* LIBRATBAG_UTIL_H */ diff --git a/src/libratbag.c b/src/libratbag.c index 94257367..4247dd01 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -158,17 +158,12 @@ out: } static int -ratbag_device_init_udev(struct libratbag *libratbag, struct ratbag *ratbag, int fd) +ratbag_device_init_udev(struct libratbag *libratbag, struct ratbag *ratbag, + struct udev_device *udev_device) { - struct udev_device *udev_device; struct udev_device *hidraw_udev; int rc = -ENODEV; - udev_device = udev_device_from_devnode(libratbag, ratbag, fd); - if (!udev_device) { - log_bug_client(libratbag, "Invalid path %s\n", fd); - return -ENODEV; - } ratbag->udev_device = udev_device_ref(udev_device); hidraw_udev = udev_find_hidraw(libratbag, ratbag); @@ -188,10 +183,9 @@ out: return rc; } -void -ratbag_device_init(struct ratbag *rb, int fd) +static void +ratbag_device_init(struct ratbag *rb) { - rb->evdev_fd = fd; rb->hidraw_fd = -1; rb->refcount = 1; list_init(&rb->profiles); @@ -243,13 +237,46 @@ ratbag_find_driver(struct libratbag *libratbag, struct ratbag *ratbag, return NULL; } +static inline char* +get_device_name(struct udev_device *device) +{ + const char *prop; + + prop = udev_prop_value(device, "NAME"); + if (!prop) + return NULL; + + /* udev name is inclosed by " */ + return strndup(&prop[1], strlen(prop) - 2); +} + +static inline int +get_product_id(struct udev_device *device, struct input_id *id) +{ + const char *product; + struct input_id ids; + int rc; + + product = udev_prop_value(device, "PRODUCT"); + if (!product) + return -1; + + rc = sscanf(product, "%hx/%hx/%hx/%hx", &ids.bustype, + &ids.vendor, &ids.product, &ids.version); + if (rc != 4) + return -1; + + *id = ids; + return 0; +} + LIBRATBAG_EXPORT struct ratbag* -ratbag_new_from_fd(struct libratbag *libratbag, int fd) +ratbag_new_from_udev_device(struct libratbag *libratbag, + struct udev_device *device) { int rc; struct ratbag *ratbag = NULL; struct ratbag_driver *driver; - char buf[256]; if (!libratbag) { fprintf(stderr, "libratbag is NULL\n"); @@ -261,25 +288,17 @@ ratbag_new_from_fd(struct libratbag *libratbag, int fd) return NULL; ratbag->libratbag = libratbag_ref(libratbag); - - rc = ioctl(fd, EVIOCGID, &ratbag->ids); - if (rc < 0) + if (get_product_id(device, &ratbag->ids) != 0) goto out_err; - - memset(buf, 0, sizeof(buf)); - rc = ioctl(fd, EVIOCGNAME(sizeof(buf) - 1), buf); - if (rc < 0) - goto out_err; - free(ratbag->name); - ratbag->name = strdup(buf); + ratbag->name = get_device_name(device); if (!ratbag->name) { errno = ENOMEM; goto out_err; } - ratbag_device_init(ratbag, fd); - rc = ratbag_device_init_udev(libratbag, ratbag, fd); + ratbag_device_init(ratbag); + rc = ratbag_device_init_udev(libratbag, ratbag, device); if (rc) goto out_err; diff --git a/src/libratbag.h b/src/libratbag.h index 5cfc31f0..e7215a30 100644 --- a/src/libratbag.h +++ b/src/libratbag.h @@ -30,6 +30,7 @@ extern "C" { #include #include +#include #define LIBRATBAG_ATTRIBUTE_PRINTF(_format, _args) \ __attribute__ ((format (printf, _format, _args))) @@ -169,11 +170,11 @@ libratbag_unref(struct libratbag *libratbag); /** * @ingroup base * - * Create a new ratbag context from the given fd. The file descriptor must - * point to a /dev/input/eventX event node and be opened in O_RDWR. + * Create a new ratbag context from the given udev device. */ struct ratbag* -ratbag_new_from_fd(struct libratbag *libratbag, int fd); +ratbag_new_from_udev_device(struct libratbag *libratbag, + struct udev_device *device); /** * @ingroup base diff --git a/src/libratbag.sym b/src/libratbag.sym index 3d92cd06..357bef9b 100644 --- a/src/libratbag.sym +++ b/src/libratbag.sym @@ -14,7 +14,7 @@ global: ratbag_get_num_buttons; ratbag_get_profile_by_index; ratbag_has_capability; - ratbag_new_from_fd; + ratbag_new_from_udev_device; ratbag_set_active_profile; ratbag_profile_ref; ratbag_profile_unref; diff --git a/tools/ratbag-command.c b/tools/ratbag-command.c index 83d1914a..37b46a1a 100644 --- a/tools/ratbag-command.c +++ b/tools/ratbag-command.c @@ -33,7 +33,7 @@ static void list_ratbags_usage(void) { - printf("Usage: %s [options] /dev/input/eventX\n" + printf("Usage: %s [options] /sys/class/input/eventX\n" "/path/to/device .... open the given device only\n" "\n" "Features:\n" @@ -52,9 +52,10 @@ main(int argc, char **argv) struct ratbag_profile *profile; struct ratbag_button *button; char *path; - int fd; int i; int retval = 0; + struct udev *udev; + struct udev_device *udev_device; if (argc < 2) { list_ratbags_usage(); @@ -62,8 +63,9 @@ main(int argc, char **argv) } path = argv[1]; - fd = open(path, O_RDWR); - if (fd <= 0) { + udev = udev_new(); + udev_device = udev_device_new_from_syspath(udev, path); + if (!udev_device) { fprintf(stderr, "Can't open '%s': %s\n", path, strerror(errno)); return 1; } @@ -74,7 +76,7 @@ main(int argc, char **argv) return 1; } - rb = ratbag_new_from_fd(libratbag, fd); + rb = ratbag_new_from_udev_device(libratbag, udev_device); if (!rb) { fprintf(stderr, "Looks like '%s' is not supported\n", path); @@ -98,6 +100,6 @@ main(int argc, char **argv) out: rb = ratbag_unref(rb); libratbag_unref(libratbag); - close(fd); + udev_unref(udev); return retval; }