Add initial implementation of libevdev to program

This commit is contained in:
Phireh 2024-12-11 19:19:18 +01:00
commit e66bccce6b
3 changed files with 95 additions and 7 deletions

View file

@ -1,6 +1,6 @@
INTERFACEDIR:=$(shell pkg-config --variable=pkgdatadir wayland-protocols) INTERFACEDIR:=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
CFLAGS=-Wall -Wextra -Og -ggdb3 -Wno-unused-but-set-variable -Wno-unused-parameter 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 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 gcc $(CFLAGS) $(LIBS) wayland.c xdg-shell-protocol.c xdg-decoration-unstable-v1.c zwp-text-input-unstable-v3-client-protocol.c -o wayland

View file

@ -7,6 +7,7 @@ typedef enum {
MODULE_KEYBOARD = 1 << 1, MODULE_KEYBOARD = 1 << 1,
MODULE_MOUSE = 1 << 2, MODULE_MOUSE = 1 << 2,
MODULE_WAYLAND = 1 << 3, MODULE_WAYLAND = 1 << 3,
MODULE_CONTROLLER = 1 << 4,
MODULE_ALL = ~0 MODULE_ALL = ~0
} console_verbosity_t; } console_verbosity_t;

View file

@ -15,6 +15,10 @@
// linux // linux
#include <sys/mman.h> #include <sys/mman.h>
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
#include <fcntl.h>
#include <errno.h>
// libevdev
#include <libevdev-1.0/libevdev/libevdev.h>
// generated header using wayland-scanner // generated header using wayland-scanner
#include "xdg-shell-client-protocol.h" #include "xdg-shell-client-protocol.h"
#include "zwp-text-input-unstable-v3-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_state *xkb_state = NULL;
struct xkb_keymap *xkb_keymap = NULL; struct xkb_keymap *xkb_keymap = NULL;
/* libevdev */
struct libevdev *libevdev;
/* Misc. global state */ /* Misc. global state */
EGLBoolean errcode = 0; EGLBoolean errcode = 0;
bool running = true; bool running = true;
input_t user_input = {}; input_t user_input = {};
arena_t main_arena = {}; 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 }; error_level_t error_verbosity = { ERROR_LEVEL_DEBUG };
char *egl_s(int code) char *egl_s(int code)
@ -384,6 +391,64 @@ void pointer_axis_relative_direction_callback(void *data, struct wl_pointer *poi
int main() int main()
{ {
console_log("Starting platform layer...\n"); 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); main_arena = arena_create(1*GB);
if (!main_arena.begin) if (!main_arena.begin)
console_err("Could not reserve memory for main arena!\n"); console_err("Could not reserve memory for main arena!\n");
@ -667,6 +732,28 @@ int main()
while (running) while (running)
{ {
wl_display_dispatch_pending(display); 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); //console_debug_ss(MODULE_WAYLAND, "Frame %d\n", framecount);
glClearColor(0.5, 0.3, 0.0, 1.0); glClearColor(0.5, 0.3, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);