aboutsummaryrefslogtreecommitdiffstats
path: root/libgamepad_open_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgamepad_open_device.c')
-rw-r--r--libgamepad_open_device.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/libgamepad_open_device.c b/libgamepad_open_device.c
new file mode 100644
index 0000000..5b32658
--- /dev/null
+++ b/libgamepad_open_device.c
@@ -0,0 +1,98 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libgamepad_open_device(struct libgamepad_device *devicep, int dirfd, const char *path, int mode)
+{
+ int err;
+ unsigned int i;
+ uint16_t n;
+
+ devicep->fd = dirfd;
+ devicep->close_fd = 0;
+ devicep->require_sync = 0;
+ devicep->dev = NULL;
+ devicep->buttons = NULL;
+ devicep->absolute_axes = NULL;
+ devicep->relative_axes = NULL;
+
+ if (path && *path) {
+ devicep->fd = openat(dirfd, path, mode);
+ if (devicep->fd < 0)
+ return -1;
+ devicep->close_fd = 1;
+ }
+
+ err = -libevdev_new_from_fd(devicep->fd, &devicep->dev);
+ if (err > 0) {
+ if (devicep->close_fd) {
+ close(devicep->fd);
+ devicep->close_fd = 0;
+ }
+ errno = err;
+ return -1;
+ }
+
+ devicep->name = libevdev_get_name(devicep->dev);
+ devicep->unique_id = libevdev_get_uniq(devicep->dev);
+ devicep->physical_location = libevdev_get_phys(devicep->dev);
+ devicep->bus_type = libevdev_get_id_bustype(devicep->dev);
+ devicep->vendor = libevdev_get_id_vendor(devicep->dev);
+ devicep->product = libevdev_get_id_product(devicep->dev);
+ devicep->version = libevdev_get_id_version(devicep->dev);
+
+ devicep->nbuttons = 0;
+ for (i = 0; i < KEY_CNT; i++) {
+ devicep->button_map[i] = -1;
+ if (libevdev_has_event_code(devicep->dev, EV_KEY, i))
+ devicep->button_map[i] = (int16_t)devicep->nbuttons++;
+ }
+
+ devicep->nabsolute_axes = 0;
+ for (i = 0; i < ABS_CNT; i++) {
+ devicep->absolute_axis_map[i] = -1;
+ if (libevdev_has_event_code(devicep->dev, EV_ABS, i))
+ devicep->absolute_axis_map[i] = (int16_t)devicep->nabsolute_axes++;
+ }
+
+ devicep->nrelative_axes = 0;
+ for (i = 0; i < REL_CNT; i++) {
+ devicep->relative_axis_map[i] = -1;
+ if (libevdev_has_event_code(devicep->dev, EV_REL, i))
+ devicep->relative_axis_map[i] = (int16_t)devicep->nrelative_axes++;
+ }
+
+ if (devicep->nbuttons) {
+ devicep->buttons = calloc(devicep->nbuttons, sizeof(*devicep->buttons));
+ if (!devicep->buttons)
+ goto fail;
+ for (i = 0, n = 0; i < KEY_CNT; i++)
+ if (devicep->button_map[i] >= 0)
+ devicep->buttons[n++] = (uint16_t)i;
+ }
+
+ if (devicep->nabsolute_axes) {
+ devicep->absolute_axes = calloc(devicep->nabsolute_axes, sizeof(*devicep->absolute_axes));
+ if (!devicep->absolute_axes)
+ goto fail;
+ for (i = 0, n = 0; i < ABS_CNT; i++)
+ if (devicep->absolute_axis_map[i] >= 0)
+ devicep->absolute_axes[n++] = (uint16_t)i;
+ }
+
+ if (devicep->nrelative_axes) {
+ devicep->relative_axes = calloc(devicep->nrelative_axes, sizeof(*devicep->relative_axes));
+ if (!devicep->relative_axes)
+ goto fail;
+ for (i = 0, n = 0; i < REL_CNT; i++)
+ if (devicep->relative_axis_map[i] >= 0)
+ devicep->relative_axes[n++] = (uint16_t)i;
+ }
+
+ return 0;
+
+fail:
+ libgamepad_close_device(devicep);
+ return -1;
+}