[PATCH libevdev 3/4] Guess the device node based on the sysfs path
Peter Hutterer
peter.hutterer at who-t.net
Wed Aug 14 21:12:39 PDT 2013
The sysfs path contains a eventN file, that corresponds to our
/dev/input/eventN number. Use it so clients can quickly get the device
node, without a libudev dependency.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
libevdev/libevdev-uinput-int.h | 1 +
libevdev/libevdev-uinput.c | 45 ++++++++++++++++++++++++++++++++++++++----
libevdev/libevdev-uinput.h | 15 ++++++++++++++
3 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/libevdev/libevdev-uinput-int.h b/libevdev/libevdev-uinput-int.h
index f443984..fbc1c29 100644
--- a/libevdev/libevdev-uinput-int.h
+++ b/libevdev/libevdev-uinput-int.h
@@ -26,5 +26,6 @@ struct libevdev_uinput {
int fd_is_managed; /**< do we need to close it? */
char *name; /**< device name */
char *syspath; /**< /sys path */
+ char *devnode; /**< device node */
time_t ctime[2]; /**< before/after UI_DEV_CREATE */
};
diff --git a/libevdev/libevdev-uinput.c b/libevdev/libevdev-uinput.c
index 830d681..2cb9121 100644
--- a/libevdev/libevdev-uinput.c
+++ b/libevdev/libevdev-uinput.c
@@ -220,6 +220,7 @@ void libevdev_uinput_destroy(struct libevdev_uinput *uinput_dev)
if (uinput_dev->fd_is_managed)
close(uinput_dev->fd);
free(uinput_dev->syspath);
+ free(uinput_dev->devnode);
free(uinput_dev->name);
free(uinput_dev);
}
@@ -229,19 +230,41 @@ int libevdev_uinput_get_fd(const struct libevdev_uinput *uinput_dev)
return uinput_dev->fd;
}
-const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
+static char *
+fetch_device_node(const char *path)
{
DIR *dir;
struct dirent *dent;
+ char *devnode = NULL;
- if (uinput_dev->syspath != NULL)
- return uinput_dev->syspath;
+ dir = opendir(path);
+ if (!dir)
+ return NULL;
+
+ while ((dent = readdir(dir))) {
+ if (strncmp("event", dent->d_name, 5) != 0)
+ continue;
+
+ asprintf(&devnode, "/dev/input/%s", dent->d_name);
+ break;
+ }
+
+ closedir(dir);
+
+ return devnode;
+}
+
+static void
+fetch_syspath_and_devnode(struct libevdev_uinput *uinput_dev)
+{
+ DIR *dir;
+ struct dirent *dent;
/* FIXME: use new ioctl() here once kernel supports it */
dir = opendir(SYS_INPUT_DIR);
if (!dir)
- return NULL;
+ return;
while((dent = readdir(dir))) {
struct stat st;
@@ -277,6 +300,7 @@ const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
strcpy(path, SYS_INPUT_DIR);
strcat(path, dent->d_name);
uinput_dev->syspath = strdup(path);
+ uinput_dev->devnode = fetch_device_node(path);
close(fd);
break;
}
@@ -286,10 +310,23 @@ const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
}
closedir(dir);
+}
+
+const char* libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev)
+{
+ if (!uinput_dev->syspath)
+ fetch_syspath_and_devnode(uinput_dev);
return uinput_dev->syspath;
}
+const char* libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev)
+{
+ if (!uinput_dev->devnode)
+ fetch_syspath_and_devnode(uinput_dev);
+ return uinput_dev->devnode;
+}
+
int libevdev_uinput_write_event(const struct libevdev_uinput *uinput_dev,
unsigned int type,
unsigned int code,
diff --git a/libevdev/libevdev-uinput.h b/libevdev/libevdev-uinput.h
index c22c013..edcecb8 100644
--- a/libevdev/libevdev-uinput.h
+++ b/libevdev/libevdev-uinput.h
@@ -222,6 +222,21 @@ const char*libevdev_uinput_get_syspath(struct libevdev_uinput *uinput_dev);
/**
* @ingroup uinput
*
+ * Return the device node representing this uinput device.
+ *
+ * This relies on libevdev_uinput_get_syspath() to provide a valid syspath.
+ * See libevdev_uinput_get_syspath() for more details.
+ *
+ * @note This function may return NULL. libevdev currently has to guess the
+ * syspath and the device node. See libevdev_uinput_get_syspath() for details.
+ * @param uinput_dev A previously created uinput device.
+ * @return The device node for this device, in the form of /dev/input/eventN
+ */
+const char* libevdev_uinput_get_devnode(struct libevdev_uinput *uinput_dev);
+
+/**
+ * @ingroup uinput
+ *
* Post an event through the uinput device. It is the caller's responsibility
* that any event sequence is terminated with an EV_SYN/SYN_REPORT/0 event.
* Otherwise, listeners on the device node will not see the events until the
--
1.8.2.1
More information about the Input-tools
mailing list