Hook up keyboard input callbacks
This commit is contained in:
parent
1ed83da395
commit
d053e7daff
2 changed files with 87 additions and 8 deletions
2
Makefile
2
Makefile
|
|
@ -1,5 +1,5 @@
|
||||||
INTERFACEDIR:=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
|
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
|
LIBS=-lwayland-client -lwayland-egl -lEGL -lOpenGL
|
||||||
wayland: wayland.c xdg-shell-protocol.c xdg-shell-client-protocol.h
|
wayland: wayland.c xdg-shell-protocol.c xdg-shell-client-protocol.h
|
||||||
gcc $(CFLAGS) $(LIBS) wayland.c xdg-shell-protocol.c -o wayland
|
gcc $(CFLAGS) $(LIBS) wayland.c xdg-shell-protocol.c -o wayland
|
||||||
|
|
|
||||||
93
wayland.c
93
wayland.c
|
|
@ -5,6 +5,7 @@
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
// Generated header using wayland-scanner
|
// Generated header using wayland-scanner
|
||||||
#include "xdg-shell-client-protocol.h"
|
#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_surface *xdg_surface = NULL;
|
||||||
struct xdg_toplevel *xdg_toplevel = NULL;
|
struct xdg_toplevel *xdg_toplevel = NULL;
|
||||||
struct wl_egl_window *window = 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;
|
EGLBoolean errcode = 0;
|
||||||
|
|
||||||
|
/* Misc. global state */
|
||||||
|
bool running = true;
|
||||||
|
|
||||||
char *egl_s(int code)
|
char *egl_s(int code)
|
||||||
{
|
{
|
||||||
switch (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)
|
uint32_t name, const char *interface, uint32_t version)
|
||||||
{
|
{
|
||||||
fprintf(stdout, "Wayland interface: '%s', version: %d, name: %d\n",
|
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");
|
fprintf(stdout, "Registering XDG WM base interface...\n");
|
||||||
wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
|
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,
|
void registry_handle_global_remove(void *data, struct wl_registry *registry,
|
||||||
[[maybe_unused]]uint32_t name)
|
uint32_t name)
|
||||||
{
|
{
|
||||||
// This space deliberately left blank
|
// This space deliberately left blank
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +81,7 @@ registry_listener = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Window size change callbacks */
|
/* 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)
|
if (!width || !height)
|
||||||
return; // compositor is deferring to us
|
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);
|
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()
|
int main()
|
||||||
{
|
{
|
||||||
fprintf(stdout, "Starting platform layer...\n");
|
fprintf(stdout, "Starting platform layer...\n");
|
||||||
|
|
@ -110,10 +166,33 @@ int main()
|
||||||
xdg_toplevel_set_title(xdg_toplevel, "Hi");
|
xdg_toplevel_set_title(xdg_toplevel, "Hi");
|
||||||
|
|
||||||
const struct xdg_toplevel_listener xdg_toplevel_listener = {
|
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))
|
if (xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL))
|
||||||
fprintf(stderr, "Could not set XDG toplevel listener\n");
|
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 */
|
/* WL EGL initialization */
|
||||||
window = wl_egl_window_create(surface, 480, 460);
|
window = wl_egl_window_create(surface, 480, 460);
|
||||||
|
|
@ -159,7 +238,7 @@ int main()
|
||||||
int attr;
|
int attr;
|
||||||
#define PRINT_ATTR(attr_name) \
|
#define PRINT_ATTR(attr_name) \
|
||||||
errcode = eglGetConfigAttrib(egl_display, configs[i], attr_name, &attr); \
|
errcode = eglGetConfigAttrib(egl_display, configs[i], attr_name, &attr); \
|
||||||
[[maybe_unused]] int attr_##attr_name = -1; \
|
int attr_##attr_name = -1; \
|
||||||
do { \
|
do { \
|
||||||
if (errcode == EGL_TRUE) { \
|
if (errcode == EGL_TRUE) { \
|
||||||
fprintf(stdout, "\t\t" #attr_name ": %d (%#0x)\n", attr, attr); \
|
fprintf(stdout, "\t\t" #attr_name ": %d (%#0x)\n", attr, attr); \
|
||||||
|
|
@ -263,7 +342,7 @@ int main()
|
||||||
|
|
||||||
// Main event loop
|
// Main event loop
|
||||||
int framecount = 0;
|
int framecount = 0;
|
||||||
while (1)
|
while (running)
|
||||||
{
|
{
|
||||||
wl_display_dispatch_pending(display);
|
wl_display_dispatch_pending(display);
|
||||||
//fprintf(stdout, "Frame %d\n", framecount);
|
//fprintf(stdout, "Frame %d\n", framecount);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue