diff options
Diffstat (limited to '')
-rw-r--r-- | libgamepad_open_device.c | 98 |
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; +} |