Hook up keyboard input callbacks

This commit is contained in:
Phireh 2024-11-24 13:44:55 +01:00
commit d053e7daff
2 changed files with 87 additions and 8 deletions

View file

@ -1,5 +1,5 @@
INTERFACEDIR:=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
CFLAGS=-Wall -Wextra -Og -ggdb3
CFLAGS=-Wall -Wextra -Og -ggdb3 -Wno-unused-but-set-variable -Wno-unused-parameter
LIBS=-lwayland-client -lwayland-egl -lEGL -lOpenGL
wayland: wayland.c xdg-shell-protocol.c xdg-shell-client-protocol.h
gcc $(CFLAGS) $(LIBS) wayland.c xdg-shell-protocol.c -o wayland

View file

@ -5,6 +5,7 @@
#include <GL/gl.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
// Generated header using wayland-scanner
#include "xdg-shell-client-protocol.h"
@ -15,8 +16,15 @@ struct xdg_wm_base *wm_base = NULL;
struct xdg_surface *xdg_surface = NULL;
struct xdg_toplevel *xdg_toplevel = NULL;
struct wl_egl_window *window = NULL;
/* Input API */
struct wl_seat *wl_seat = NULL;
struct wl_keyboard *wl_keyboard = NULL;
struct wl_pointer *wl_pointer = NULL;
EGLBoolean errcode = 0;
/* Misc. global state */
bool running = true;
char *egl_s(int code)
{
switch (code)
@ -37,7 +45,7 @@ char *egl_s(int code)
}
}
void registry_handle_global([[maybe_unused]] void *data, struct wl_registry *registry,
void registry_handle_global( void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version)
{
fprintf(stdout, "Wayland interface: '%s', version: %d, name: %d\n",
@ -52,11 +60,16 @@ void registry_handle_global([[maybe_unused]] void *data, struct wl_registry *reg
fprintf(stdout, "Registering XDG WM base interface...\n");
wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
}
if (!strcmp(interface, wl_seat_interface.name))
{
fprintf(stdout, "Registering WL seat interface...\n");
wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, 1);
}
}
void registry_handle_global_remove([[maybe_unused]]void *data, [[maybe_unused]]struct wl_registry *registry,
[[maybe_unused]]uint32_t name)
void registry_handle_global_remove(void *data, struct wl_registry *registry,
uint32_t name)
{
// This space deliberately left blank
}
@ -68,7 +81,7 @@ registry_listener = {
};
/* Window size change callbacks */
static void xdg_toplevel_configure([[maybe_unused]] void *data, [[maybe_unused]] struct xdg_toplevel *t, int32_t width, int32_t height, [[maybe_unused]] struct wl_array *states)
void xdg_toplevel_configure(void *data, struct xdg_toplevel *t, int32_t width, int32_t height, struct wl_array *states)
{
if (!width || !height)
return; // compositor is deferring to us
@ -78,6 +91,49 @@ static void xdg_toplevel_configure([[maybe_unused]] void *data, [[maybe_unused]]
glViewport(0, 0, width, height);
}
/* Window close callback */
void xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
{
running = false;
}
/* Basic wayland method to check if our program is responsive still */
void wayland_ping(void *data, struct xdg_wm_base *base, uint32_t serial)
{
xdg_wm_base_pong(base, serial);
}
void keymap_callback(void *data, struct wl_keyboard *kb, uint format, int fd, uint size)
{
// TODO: Check for XKB compatibility and use xkbcommon to extract
fprintf(stdout, "KBMAP of size %d detected\n", size);
}
void enter_callback(void *data, struct wl_keyboard* kb, uint serial, struct wl_surface* surface, struct wl_array *keys)
{
fprintf(stdout, "KBMAP with serial %d entered surface\n", serial);
}
void leave_callback(void *data, struct wl_keyboard* kb, uint serial, struct wl_surface* surface)
{
fprintf(stdout, "KBMAP with serial %d left surface\n", serial);
}
void key_callback(void *data, struct wl_keyboard *kb, uint serial, uint time, uint key, uint state)
{
fprintf(stdout, "Pressed key %d\n", key);
}
void modifier_callback(void *data, struct wl_keyboard *kb, uint serial, uint mods_depressed, uint mods_latched, uint mods_locked, uint group)
{
fprintf(stdout, "Keyboard modifier keys changed\n");
}
void repeat_info_callback(void *data, struct wl_keyboard *kb, int rate, int delay)
{
fprintf(stdout, "Keyboard repeat/delay rate changed\n");
}
int main()
{
fprintf(stdout, "Starting platform layer...\n");
@ -110,10 +166,33 @@ int main()
xdg_toplevel_set_title(xdg_toplevel, "Hi");
const struct xdg_toplevel_listener xdg_toplevel_listener = {
.configure = xdg_toplevel_configure
.configure = xdg_toplevel_configure,
.close = xdg_toplevel_close
};
const struct xdg_wm_base_listener xdg_wm_base_listener = {
.ping = wayland_ping
};
if (xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL))
fprintf(stderr, "Could not set XDG toplevel listener\n");
if (xdg_wm_base_add_listener(wm_base, &xdg_wm_base_listener, NULL))
fprintf(stderr, "Could not set XDG WM base listener\n");
if (!(wl_keyboard = wl_seat_get_keyboard(wl_seat)))
fprintf(stderr, "Could not get XKB keyboard\n");
if (!(wl_pointer = wl_seat_get_pointer(wl_seat)))
fprintf(stderr, "Could not get WL pointer\n");
/* NOTE: We have to define all available callbacks for the keyboard listener even if we are not interested in them:
https://gitlab.freedesktop.org/wayland/wayland/-/issues/160 */
const struct wl_keyboard_listener wl_keyboard_listener = {
.keymap = keymap_callback,
.enter = enter_callback,
.leave = leave_callback,
.key = key_callback,
.modifiers = modifier_callback,
.repeat_info = repeat_info_callback,
};
wl_keyboard_add_listener(wl_keyboard, &wl_keyboard_listener, NULL);
/* WL EGL initialization */
window = wl_egl_window_create(surface, 480, 460);
@ -159,7 +238,7 @@ int main()
int attr;
#define PRINT_ATTR(attr_name) \
errcode = eglGetConfigAttrib(egl_display, configs[i], attr_name, &attr); \
[[maybe_unused]] int attr_##attr_name = -1; \
int attr_##attr_name = -1; \
do { \
if (errcode == EGL_TRUE) { \
fprintf(stdout, "\t\t" #attr_name ": %d (%#0x)\n", attr, attr); \
@ -263,7 +342,7 @@ int main()
// Main event loop
int framecount = 0;
while (1)
while (running)
{
wl_display_dispatch_pending(display);
//fprintf(stdout, "Frame %d\n", framecount);