From e66bccce6b9e00ab8869430d5a3ced6e9e61dc8d Mon Sep 17 00:00:00 2001 From: Phireh Date: Wed, 11 Dec 2024 19:19:18 +0100 Subject: [PATCH] Add initial implementation of libevdev to program --- Makefile | 2 +- debug.h | 11 +++---- wayland.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 95 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 21cbfbf..b2a0f07 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ INTERFACEDIR:=$(shell pkg-config --variable=pkgdatadir wayland-protocols) CFLAGS=-Wall -Wextra -Og -ggdb3 -Wno-unused-but-set-variable -Wno-unused-parameter -LIBS=-lwayland-client -lwayland-egl -lEGL -lOpenGL -lxkbcommon +LIBS=-lwayland-client -lwayland-egl -lEGL -lOpenGL -lxkbcommon -levdev wayland: wayland.c xdg-shell-protocol.c xdg-shell-client-protocol.h zwp-text-input-unstable-v3-client-protocol.c zwp-text-input-unstable-v3-protocol.h xdg-decoration-unstable-v1.c xdg-decoration-unstable-v1.h gcc $(CFLAGS) $(LIBS) wayland.c xdg-shell-protocol.c xdg-decoration-unstable-v1.c zwp-text-input-unstable-v3-client-protocol.c -o wayland diff --git a/debug.h b/debug.h index b6877f7..9aac243 100644 --- a/debug.h +++ b/debug.h @@ -3,11 +3,12 @@ // TODO: Maybe add a IME subsystem? typedef enum { - MODULE_EGL = 1 << 0, - MODULE_KEYBOARD = 1 << 1, - MODULE_MOUSE = 1 << 2, - MODULE_WAYLAND = 1 << 3, - MODULE_ALL = ~0 + MODULE_EGL = 1 << 0, + MODULE_KEYBOARD = 1 << 1, + MODULE_MOUSE = 1 << 2, + MODULE_WAYLAND = 1 << 3, + MODULE_CONTROLLER = 1 << 4, + MODULE_ALL = ~0 } console_verbosity_t; typedef enum { diff --git a/wayland.c b/wayland.c index 1b027b3..1bc92ad 100644 --- a/wayland.c +++ b/wayland.c @@ -15,6 +15,10 @@ // linux #include #include +#include +#include +// libevdev +#include // generated header using wayland-scanner #include "xdg-shell-client-protocol.h" #include "zwp-text-input-unstable-v3-protocol.h" @@ -50,12 +54,15 @@ struct xkb_context *xkb_context = NULL; struct xkb_state *xkb_state = NULL; struct xkb_keymap *xkb_keymap = NULL; +/* libevdev */ +struct libevdev *libevdev; + /* Misc. global state */ EGLBoolean errcode = 0; bool running = true; input_t user_input = {}; arena_t main_arena = {}; -console_verbosity_t console_verbosity = { MODULE_ALL }; +console_verbosity_t console_verbosity = { MODULE_CONTROLLER }; error_level_t error_verbosity = { ERROR_LEVEL_DEBUG }; char *egl_s(int code) @@ -384,6 +391,64 @@ void pointer_axis_relative_direction_callback(void *data, struct wl_pointer *poi int main() { console_log("Starting platform layer...\n"); + + libevdev = libevdev_new(); + if (!libevdev) + console_err_ss(MODULE_CONTROLLER, "Could not initialize libevdev...\n"); + + console_log_ss(MODULE_CONTROLLER, "Querying input devices...\n"); + int32_t i = 0; + int32_t controller_idx = 0; + do + { + char path[17+33] = "/dev/input/event"; + char idx[33] = {}; + // I'd like to use itoa, but it's not in stdlib.h ?? + sprintf(idx, "%d", i); + strcat(path, idx); + console_debug_ss(MODULE_CONTROLLER, "Opening %s\n", path); + int fd = open(path, O_RDONLY | O_NONBLOCK); + + if (fd == -1 && errno == EACCES) continue; + + if (libevdev_new_from_fd(fd, &libevdev)) + { + console_warn_ss(MODULE_CONTROLLER, "Could not open %s !\n", path); + break; + } + else + { + console_debug_ss(MODULE_CONTROLLER, "\tName: %s\n", libevdev_get_name(libevdev)); + console_debug_ss(MODULE_CONTROLLER, "\tPhysical location: %s\n", libevdev_get_phys(libevdev)); + console_debug_ss(MODULE_CONTROLLER, "\tUID: %s\n", libevdev_get_uniq(libevdev)); + console_debug_ss(MODULE_CONTROLLER, "\tVendor: %d\n", libevdev_get_id_vendor(libevdev)); + console_debug_ss(MODULE_CONTROLLER, "\tProduct: %d\n", libevdev_get_id_product(libevdev)); + console_debug_ss(MODULE_CONTROLLER, "\tBus type: %d\n", libevdev_get_id_bustype(libevdev)); + console_debug_ss(MODULE_CONTROLLER, "\tFirmware version: %d\n", libevdev_get_id_version(libevdev)); + console_debug_ss(MODULE_CONTROLLER, "\tDriver version: %d\n", libevdev_get_driver_version(libevdev)); + console_debug_ss(MODULE_CONTROLLER, "\tSupported event types:\n\t\t"); + for (int j = 0; j < EV_MAX; ++j) + if (libevdev_has_event_type(libevdev, j)) + console_debug_ss(MODULE_CONTROLLER, "%s ", libevdev_event_type_get_name(j)); + console_debug_ss(MODULE_CONTROLLER, "\n"); + if (libevdev_has_event_type(libevdev, EV_KEY && libevdev_has_event_code(libevdev, EV_KEY, BTN_NORTH)) && + libevdev_has_event_type(libevdev, EV_ABS)) + { + console_debug_ss(MODULE_CONTROLLER, "\tThis device looks like a controller!\n"); + controller_idx = i; + } + libevdev_free(libevdev); + close(fd); + } + } + while (++i); + + char controller_path[17+33] = "/dev/input/event"; + int controller_fd; + sprintf(controller_path, "/dev/input/event%d", controller_idx); + controller_fd = open(controller_path, O_RDONLY | O_NONBLOCK); + libevdev_new_from_fd(controller_fd, &libevdev); + main_arena = arena_create(1*GB); if (!main_arena.begin) console_err("Could not reserve memory for main arena!\n"); @@ -667,6 +732,28 @@ int main() while (running) { wl_display_dispatch_pending(display); + + /* Controller input handling */ + struct input_event iev; + int errcode = libevdev_next_event(libevdev, LIBEVDEV_READ_FLAG_NORMAL | LIBEVDEV_READ_FLAG_BLOCKING, &iev); + do { + if (errcode == LIBEVDEV_READ_STATUS_SYNC) + { + // TODO: Debug printing, deal with lost controller + while ((errcode = libevdev_next_event(libevdev, LIBEVDEV_READ_FLAG_SYNC, &iev)) == LIBEVDEV_READ_STATUS_SYNC); + } + else if (errcode == LIBEVDEV_READ_STATUS_SUCCESS) + { + // TODO: Debug printing + if (iev.type == EV_ABS || iev.type == EV_KEY) + console_debug_ss(MODULE_CONTROLLER, "Controller event\n\tTime: %ld.%06ld\n\tType: %s\n\tCode: %s\n\tValue: %d\n", iev.input_event_sec, iev.input_event_usec, libevdev_event_type_get_name(iev.type), libevdev_event_code_get_name(iev.type, iev.code), iev.value); + } + } while (errcode != LIBEVDEV_READ_STATUS_SYNC && errcode != LIBEVDEV_READ_STATUS_SUCCESS && errcode != -EAGAIN); + + if (errcode != LIBEVDEV_READ_STATUS_SUCCESS && errcode != -EAGAIN) + console_warn_ss(MODULE_CONTROLLER, "Failed to handle controller event: %s\n", strerror(-errcode)); + + //console_debug_ss(MODULE_WAYLAND, "Frame %d\n", framecount); glClearColor(0.5, 0.3, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT);