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;
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)
{

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}