1
0
forked from drath/libratbag

Drop from_fd, replace with from_udev_device

We don't need the evdev fd, it's more flexible to start with a udev device.
This changes ratbag-command to take a /sys path as well, but for not it'll
do.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2015-08-18 15:40:48 +10:00
parent 5dad2e258d
commit fcda14df61
7 changed files with 76 additions and 37 deletions

View File

@@ -43,7 +43,6 @@ struct ratbag {
char *name; char *name;
struct udev_device *udev_device; struct udev_device *udev_device;
struct udev_device *udev_hidraw; struct udev_device *udev_hidraw;
int evdev_fd;
int hidraw_fd; int hidraw_fd;
int refcount; int refcount;
struct input_id ids; struct input_id ids;
@@ -103,8 +102,6 @@ struct ratbag_button {
enum ratbag_button_action_type action_type; enum ratbag_button_action_type action_type;
}; };
void ratbag_device_init(struct ratbag *rb, int fd);
static inline void static inline void
ratbag_set_drv_data(struct ratbag *ratbag, void *drv_data) ratbag_set_drv_data(struct ratbag *ratbag, void *drv_data)
{ {

View File

@@ -69,3 +69,19 @@ list_empty(const struct list *list)
{ {
return list->next == 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;
}

View File

@@ -25,6 +25,7 @@
#define LIBRATBAG_UTIL_H #define LIBRATBAG_UTIL_H
#include <unistd.h> #include <unistd.h>
#include <libudev.h>
/* /*
* This list data structure is a verbatim copy from wayland-util.h from the * 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); long_clear_bit(array, bit);
} }
const char *
udev_prop_value(struct udev_device *device,
const char *property_name);
#endif /* LIBRATBAG_UTIL_H */ #endif /* LIBRATBAG_UTIL_H */

View File

@@ -158,17 +158,12 @@ out:
} }
static int 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; struct udev_device *hidraw_udev;
int rc = -ENODEV; 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); ratbag->udev_device = udev_device_ref(udev_device);
hidraw_udev = udev_find_hidraw(libratbag, ratbag); hidraw_udev = udev_find_hidraw(libratbag, ratbag);
@@ -188,10 +183,9 @@ out:
return rc; return rc;
} }
void static void
ratbag_device_init(struct ratbag *rb, int fd) ratbag_device_init(struct ratbag *rb)
{ {
rb->evdev_fd = fd;
rb->hidraw_fd = -1; rb->hidraw_fd = -1;
rb->refcount = 1; rb->refcount = 1;
list_init(&rb->profiles); list_init(&rb->profiles);
@@ -243,13 +237,46 @@ ratbag_find_driver(struct libratbag *libratbag, struct ratbag *ratbag,
return NULL; 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* 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; int rc;
struct ratbag *ratbag = NULL; struct ratbag *ratbag = NULL;
struct ratbag_driver *driver; struct ratbag_driver *driver;
char buf[256];
if (!libratbag) { if (!libratbag) {
fprintf(stderr, "libratbag is NULL\n"); fprintf(stderr, "libratbag is NULL\n");
@@ -261,25 +288,17 @@ ratbag_new_from_fd(struct libratbag *libratbag, int fd)
return NULL; return NULL;
ratbag->libratbag = libratbag_ref(libratbag); ratbag->libratbag = libratbag_ref(libratbag);
if (get_product_id(device, &ratbag->ids) != 0)
rc = ioctl(fd, EVIOCGID, &ratbag->ids);
if (rc < 0)
goto out_err; 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); free(ratbag->name);
ratbag->name = strdup(buf); ratbag->name = get_device_name(device);
if (!ratbag->name) { if (!ratbag->name) {
errno = ENOMEM; errno = ENOMEM;
goto out_err; goto out_err;
} }
ratbag_device_init(ratbag, fd); ratbag_device_init(ratbag);
rc = ratbag_device_init_udev(libratbag, ratbag, fd); rc = ratbag_device_init_udev(libratbag, ratbag, device);
if (rc) if (rc)
goto out_err; goto out_err;

View File

@@ -30,6 +30,7 @@ extern "C" {
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <libudev.h>
#define LIBRATBAG_ATTRIBUTE_PRINTF(_format, _args) \ #define LIBRATBAG_ATTRIBUTE_PRINTF(_format, _args) \
__attribute__ ((format (printf, _format, _args))) __attribute__ ((format (printf, _format, _args)))
@@ -169,11 +170,11 @@ libratbag_unref(struct libratbag *libratbag);
/** /**
* @ingroup base * @ingroup base
* *
* Create a new ratbag context from the given fd. The file descriptor must * Create a new ratbag context from the given udev device.
* point to a /dev/input/eventX event node and be opened in O_RDWR.
*/ */
struct ratbag* 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 * @ingroup base

View File

@@ -14,7 +14,7 @@ global:
ratbag_get_num_buttons; ratbag_get_num_buttons;
ratbag_get_profile_by_index; ratbag_get_profile_by_index;
ratbag_has_capability; ratbag_has_capability;
ratbag_new_from_fd; ratbag_new_from_udev_device;
ratbag_set_active_profile; ratbag_set_active_profile;
ratbag_profile_ref; ratbag_profile_ref;
ratbag_profile_unref; ratbag_profile_unref;

View File

@@ -33,7 +33,7 @@
static void static void
list_ratbags_usage(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" "/path/to/device .... open the given device only\n"
"\n" "\n"
"Features:\n" "Features:\n"
@@ -52,9 +52,10 @@ main(int argc, char **argv)
struct ratbag_profile *profile; struct ratbag_profile *profile;
struct ratbag_button *button; struct ratbag_button *button;
char *path; char *path;
int fd;
int i; int i;
int retval = 0; int retval = 0;
struct udev *udev;
struct udev_device *udev_device;
if (argc < 2) { if (argc < 2) {
list_ratbags_usage(); list_ratbags_usage();
@@ -62,8 +63,9 @@ main(int argc, char **argv)
} }
path = argv[1]; path = argv[1];
fd = open(path, O_RDWR); udev = udev_new();
if (fd <= 0) { udev_device = udev_device_new_from_syspath(udev, path);
if (!udev_device) {
fprintf(stderr, "Can't open '%s': %s\n", path, strerror(errno)); fprintf(stderr, "Can't open '%s': %s\n", path, strerror(errno));
return 1; return 1;
} }
@@ -74,7 +76,7 @@ main(int argc, char **argv)
return 1; return 1;
} }
rb = ratbag_new_from_fd(libratbag, fd); rb = ratbag_new_from_udev_device(libratbag, udev_device);
if (!rb) { if (!rb) {
fprintf(stderr, "Looks like '%s' is not supported\n", path); fprintf(stderr, "Looks like '%s' is not supported\n", path);
@@ -98,6 +100,6 @@ main(int argc, char **argv)
out: out:
rb = ratbag_unref(rb); rb = ratbag_unref(rb);
libratbag_unref(libratbag); libratbag_unref(libratbag);
close(fd); udev_unref(udev);
return retval; return retval;
} }