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:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define LIBRATBAG_UTIL_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <libudev.h>
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ extern "C" {
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <libudev.h>
|
||||
|
||||
#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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user