[PATCH libevdev 3/6] test: switch udev backend over to new libevdev-uinput bits
Peter Hutterer
peter.hutterer at who-t.net
Tue Aug 13 03:39:52 PDT 2013
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
configure.ac | 9 +-
test/Makefile.am | 2 +-
test/test-common-uinput.c | 265 ++++++++++------------------------------------
test/test-common-uinput.h | 2 +
4 files changed, 66 insertions(+), 212 deletions(-)
diff --git a/configure.ac b/configure.ac
index 68df538..7e17291 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,10 +34,13 @@ LT_INIT
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES(CHECK, [check], [HAVE_CHECK="yes"], [HAVE_CHECK="no"])
-if test "x$HAVE_CHECK" != "xyes"; then
- AC_MSG_WARN([check not found - skipping building unit tests])
+PKG_CHECK_MODULES(LIBUDEV, [libudev], [HAVE_LIBUDEV="yes"], [HAVE_LIBUDEV="no"])
+if test "x$HAVE_CHECK" != "xyes" -o "x$HAVE_LIBUDEV" != "xyes"; then
+ AC_MSG_WARN([check or libudev not found - skipping building unit tests])
fi
-AM_CONDITIONAL(BUILD_TESTS, [test "x$HAVE_CHECK" = "xyes"])
+AM_CONDITIONAL(BUILD_TESTS, [test "x$HAVE_CHECK" = "xyes" -a "x$HAVE_LIBUDEV" = "xyes"])
+
+
if test "x$GCC" = "xyes"; then
GCC_CFLAGS="-Wall -Wextra -Wno-unused-parameter -g -Wstrict-prototypes -Wmissing-prototypes -fvisibility=hidden"
diff --git a/test/Makefile.am b/test/Makefile.am
index cabd1bf..3ba2e7f 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -29,7 +29,7 @@ test_libevdev_SOURCES = \
test-uinput.c \
$(common_sources)
-test_libevdev_LDADD = $(CHECK_LIBS) $(GCOV_LDFLAGS)
+test_libevdev_LDADD = $(CHECK_LIBS) $(GCOV_LDFLAGS) $(LIBUDEV_LIBS)
if GCOV_ENABLED
diff --git a/test/test-common-uinput.c b/test/test-common-uinput.c
index b99bfa8..fe1bfb0 100644
--- a/test/test-common-uinput.c
+++ b/test/test-common-uinput.c
@@ -30,10 +30,13 @@
#include <errno.h>
#include <linux/uinput.h>
#include <sys/inotify.h>
+#include <libudev.h>
+#include <dirent.h>
#include <libevdev/libevdev.h>
#include <libevdev/libevdev-int.h>
#include <libevdev/libevdev-util.h>
+#include <libevdev/libevdev-uinput.h>
#include "test-common-uinput.h"
@@ -42,9 +45,11 @@
struct uinput_device
{
- struct libevdev d; /* lazy, it has all the accessors */
+ struct libevdev *d; /* lazy, it has all the accessors */
+ struct libevdev_uinput *uidev;
char *devnode; /* path after creation */
int dev_fd; /* open fd to the devnode */
+ int uinput_fd;
};
struct uinput_device*
@@ -56,11 +61,12 @@ uinput_device_new(const char *name)
if (!dev)
return NULL;
- dev->d.fd = -1;
+ dev->d = libevdev_new();
dev->dev_fd = -1;
+ dev->uinput_fd = -1;
if (name)
- dev->d.name = strdup(name);
+ libevdev_set_name(dev->d, name);
return dev;
}
@@ -110,14 +116,13 @@ uinput_device_free(struct uinput_device *dev)
if (!dev)
return;
- if (dev->d.fd != -1) {
- ioctl(dev->d.fd, UI_DEV_DESTROY, NULL);
- close(dev->d.fd);
+ if (dev->uinput_fd != -1) {
+ ioctl(dev->uinput_fd, UI_DEV_DESTROY, NULL);
+ close(dev->uinput_fd);
}
if (dev->dev_fd != -1)
close(dev->dev_fd);
- free(dev->d.name);
- free(dev->devnode);
+ libevdev_free(dev->d);
free(dev);
}
@@ -127,155 +132,52 @@ uinput_device_get_fd(const struct uinput_device *dev)
return dev->dev_fd;
}
-
-static char*
-wait_for_inotify(int fd)
+char* uinput_devnode_from_syspath(const char *syspath)
{
+ DIR *dir;
+ struct dirent *dp;
+ struct udev *udev;
+ struct udev_device *udev_device;
char *devnode = NULL;
- int found = 0;
- char buf[1024];
- size_t bufidx = 0;
- struct pollfd pfd;
- pfd.fd = fd;
- pfd.events = POLLIN;
+ udev = udev_new();
+ dir = opendir(syspath);
+ while ((dp = readdir(dir)) && devnode == NULL) {
+ char *path;
- while (!found && poll(&pfd, 1, 2000) > 0) {
- struct inotify_event *e;
- ssize_t r;
+ if (strncmp(dp->d_name, "event", 5) != 0)
+ continue;
- r = read(fd, buf + bufidx, sizeof(buf) - bufidx);
- if (r == -1 && errno != EAGAIN)
- return NULL;
-
- bufidx += r;
-
- e = (struct inotify_event*)buf;
-
- while (bufidx > sizeof(*e) && bufidx >= sizeof(*e) + e->len) {
- if (strncmp(e->name, "event", 5) == 0) {
- asprintf(&devnode, "%s%s", DEV_INPUT_DIR, e->name);
- found = 1;
- break;
- }
-
- /* this packet didn't contain what we're looking for */
- int len = sizeof(*e) + e->len;
- memmove(buf, buf + len, bufidx - len);
- bufidx -= len;
- }
+ asprintf(&path, "%s/%s", syspath, dp->d_name);
+ udev_device = udev_device_new_from_syspath(udev, path);
+ devnode = strdup(udev_device_get_devnode(udev_device));
+ udev_device_unref(udev_device);
+ free(path);
}
+ closedir(dir);
+ udev_unref(udev);
+
return devnode;
}
-static int
-inotify_setup()
-{
- int ifd = inotify_init1(IN_NONBLOCK);
- if (ifd == -1 || inotify_add_watch(ifd, DEV_INPUT_DIR, IN_CREATE) == -1) {
- if (ifd != -1)
- close(ifd);
- ifd = -1;
- }
-
- return ifd;
-}
-
int
uinput_device_create(struct uinput_device* d)
{
- int type, code, prop;
- struct uinput_user_dev dev;
int rc;
int fd;
- int ifd = -1; /* inotify fd */
fd = open("/dev/uinput", O_RDWR);
if (fd < 0)
goto error;
- d->d.fd = fd;
+ d->uinput_fd = fd;
- memset(&dev, 0, sizeof(dev));
- if (d->d.name)
- strncpy(dev.name, d->d.name, UINPUT_MAX_NAME_SIZE - 1);
- dev.id = d->d.ids;
-
- for (type = 0; type < EV_MAX; type++) {
- int max;
- int uinput_bit;
- const unsigned long *mask;
-
- if (!bit_is_set(d->d.bits, type))
- continue;
-
- rc = ioctl(fd, UI_SET_EVBIT, type);
- if (rc == -1)
- goto error;
-
- max = type_to_mask_const(&d->d, type, &mask);
- if (max == -1)
- continue;
-
- switch(type) {
- case EV_KEY: uinput_bit = UI_SET_KEYBIT; break;
- case EV_REL: uinput_bit = UI_SET_RELBIT; break;
- case EV_ABS: uinput_bit = UI_SET_ABSBIT; break;
- case EV_MSC: uinput_bit = UI_SET_MSCBIT; break;
- case EV_LED: uinput_bit = UI_SET_LEDBIT; break;
- case EV_SND: uinput_bit = UI_SET_SNDBIT; break;
- case EV_FF: uinput_bit = UI_SET_FFBIT; break;
- case EV_SW: uinput_bit = UI_SET_SWBIT; break;
- default:
- errno = EINVAL;
- goto error;
- }
-
- for (code = 0; code < max; code++) {
- if (!bit_is_set(mask, code))
- continue;
-
- rc = ioctl(fd, uinput_bit, code);
- if (rc == -1)
- goto error;
-
- if (type == EV_ABS) {
- dev.absmin[code] = d->d.abs_info[code].minimum;
- dev.absmax[code] = d->d.abs_info[code].maximum;
- dev.absfuzz[code] = d->d.abs_info[code].fuzz;
- dev.absflat[code] = d->d.abs_info[code].flat;
- /* uinput has no resolution in the device struct, we use
- * EVIOCSABS below */
- }
- }
-
- }
-
- for (prop = 0; prop < INPUT_PROP_MAX; prop++) {
- if (!bit_is_set(d->d.props, prop))
- continue;
-
- rc = ioctl(fd, UI_SET_PROPBIT, prop);
- if (rc == -1)
- goto error;
- }
-
- rc = write(fd, &dev, sizeof(dev));
- if (rc < 0)
- goto error;
- else if (rc < sizeof(dev)) {
- errno = EINVAL;
- goto error;
- }
-
- ifd = inotify_setup();
-
- rc = ioctl(fd, UI_DEV_CREATE, NULL);
- if (rc == -1)
+ rc = libevdev_uinput_create_from_device(d->d, fd, &d->uidev);
+ if (rc != 0)
goto error;
- d->devnode = wait_for_inotify(ifd);
+ d->devnode = uinput_devnode_from_syspath(libevdev_uinput_get_syspath(d->uidev));
if (d->devnode == NULL)
goto error;
@@ -284,18 +186,19 @@ uinput_device_create(struct uinput_device* d)
goto error;
/* write abs resolution now */
- if (bit_is_set(d->d.bits, EV_ABS)) {
- for (code = 0; code < ABS_MAX; code++ ) {
- struct input_absinfo *abs;
+ if (libevdev_has_event_type(d->d, EV_ABS)) {
+ int code;
+ for (code = 0; code < ABS_MAX; code++) {
+ const struct input_absinfo *abs;
/* can't change slots */
if (code == ABS_MT_SLOT)
continue;
- if (!bit_is_set(d->d.abs_bits, code))
+ abs = libevdev_get_abs_info(d->d, code);
+ if (!abs)
continue;
- abs = &d->d.abs_info[code];
rc = ioctl(d->dev_fd, EVIOCSABS(code), abs);
if (rc < 0) {
printf("error %s for code %d\n", strerror(-rc), code);
@@ -307,73 +210,45 @@ uinput_device_create(struct uinput_device* d)
return 0;
error:
- if (ifd != -1)
- close(ifd);
- if (d->d.fd != -1)
- close(fd);
+ if (d->dev_fd != -1)
+ close(d->dev_fd);
+ if (d->uinput_fd != -1)
+ close(d->uinput_fd);
return -errno;
}
int uinput_device_set_name(struct uinput_device *dev, const char *name)
{
- if (dev->d.name)
- free(dev->d.name);
- if (name)
- dev->d.name = strdup(name);
+ libevdev_set_name(dev->d, name);
return 0;
}
int uinput_device_set_ids(struct uinput_device *dev, const struct input_id *ids)
{
- dev->d.ids = *ids;
+ libevdev_set_id_product(dev->d, ids->product);
+ libevdev_set_id_vendor(dev->d, ids->vendor);
+ libevdev_set_id_bustype(dev->d, ids->bustype);
+ libevdev_set_id_version(dev->d, ids->version);
return 0;
}
int
uinput_device_set_bit(struct uinput_device* dev, unsigned int bit)
{
- if (!dev)
- return -EINVAL;
-
- if (bit > EV_MAX)
- return -EINVAL;
-
- set_bit(dev->d.bits, bit);
- return 0;
+ return libevdev_enable_event_type(dev->d, bit);
}
int
uinput_device_set_prop(struct uinput_device *dev, unsigned int prop)
{
- if (!dev)
- return -EINVAL;
-
- if (prop > INPUT_PROP_MAX)
- return -EINVAL;
-
- set_bit(dev->d.props, prop);
- return 0;
+ return libevdev_enable_property(dev->d, prop);
}
int
uinput_device_set_event_bit(struct uinput_device* dev, unsigned int type, unsigned int code)
{
- int max;
- unsigned long *mask;
-
- if (uinput_device_set_bit(dev, type) < 0)
- return -EINVAL;
-
- if (type == EV_SYN)
- return 0;
-
- max = type_to_mask(&dev->d, type, &mask);
- if (max == -1 || code > max)
- return -EINVAL;
-
- set_bit(mask, code);
- return 0;
+ return libevdev_enable_event_code(dev->d, type, code, NULL);
}
int
@@ -389,7 +264,7 @@ uinput_device_set_event_bits_v(struct uinput_device *dev, va_list args)
code = va_arg(args, int);
if (code == -1)
break;
- rc = uinput_device_set_event_bit(dev, type, code);
+ rc = libevdev_enable_event_code(dev->d, type, code, NULL);
} while (rc == 0);
return rc;
@@ -410,39 +285,13 @@ uinput_device_set_event_bits(struct uinput_device *dev, ...)
int
uinput_device_set_abs_bit(struct uinput_device* dev, unsigned int code, const struct input_absinfo *absinfo)
{
- if (uinput_device_set_event_bit(dev, EV_ABS, code) < 0)
- return -EINVAL;
-
- dev->d.abs_info[code] = *absinfo;
- return 0;
+ return libevdev_enable_event_code(dev->d, EV_ABS, code, absinfo);
}
int
uinput_device_event(const struct uinput_device *dev, unsigned int type, unsigned int code, int value)
{
- int max;
- int rc;
- const unsigned long *mask;
- struct input_event ev;
-
- if (type > EV_MAX)
- return -EINVAL;
-
- if (type != EV_SYN) {
- max = type_to_mask_const(&dev->d, type, &mask);
- if (max == -1 || code > max)
- return -EINVAL;
- }
-
- ev.type = type;
- ev.code = code;
- ev.value = value;
- ev.time.tv_sec = 0;
- ev.time.tv_usec = 0;
-
- rc = write(dev->d.fd, &ev, sizeof(ev));
-
- return (rc == -1) ? -errno : 0;
+ return libevdev_uinput_write_event(dev->uidev, type, code, value);
}
int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args)
diff --git a/test/test-common-uinput.h b/test/test-common-uinput.h
index b50155c..c1cd5a0 100644
--- a/test/test-common-uinput.h
+++ b/test/test-common-uinput.h
@@ -44,3 +44,5 @@ int uinput_device_event(const struct uinput_device* dev, unsigned int type, unsi
int uinput_device_event_multiple(const struct uinput_device* dev, ...);
int uinput_device_event_multiple_v(const struct uinput_device* dev, va_list args);
int uinput_device_get_fd(const struct uinput_device *dev);
+
+char *uinput_devnode_from_syspath(const char *syspath);
--
1.8.2.1
More information about the Input-tools
mailing list