2024-06-02 19:29:26 +02:00
|
|
|
#include <stdio.h>
|
2026-06-13 10:22:08 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
|
|
|
|
|
#include <wayland-client.h>
|
|
|
|
|
#include <xkbcommon/xkbcommon.h>
|
2024-06-02 19:29:26 +02:00
|
|
|
|
|
|
|
|
#include <tkeyboard.h>
|
|
|
|
|
|
|
|
|
|
static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size)
|
|
|
|
|
{
|
2026-06-13 10:22:08 +02:00
|
|
|
struct keyboard_data *kbd = data;
|
|
|
|
|
|
|
|
|
|
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
|
|
|
|
|
{
|
|
|
|
|
close(fd);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *map_str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
|
|
|
if (map_str == MAP_FAILED)
|
|
|
|
|
{
|
|
|
|
|
close(fd);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kbd->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
|
|
|
|
kbd->xkb_keymap = xkb_keymap_new_from_string(
|
|
|
|
|
kbd->xkb_context, map_str,
|
|
|
|
|
XKB_KEYMAP_FORMAT_TEXT_V1,
|
|
|
|
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
|
|
|
|
kbd->xkb_state = xkb_state_new(kbd->xkb_keymap);
|
|
|
|
|
|
|
|
|
|
munmap(map_str, size);
|
|
|
|
|
close(fd);
|
2024-06-02 19:29:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void keyboard_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys)
|
|
|
|
|
{
|
|
|
|
|
printf("keyboard_enter\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface)
|
|
|
|
|
{
|
|
|
|
|
printf("keyboard_leave\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
|
|
|
|
{
|
2026-06-13 10:22:08 +02:00
|
|
|
struct keyboard_data *kbd = data;
|
|
|
|
|
xkb_keysym_t sym = XKB_KEY_NoSymbol;
|
|
|
|
|
|
|
|
|
|
if (kbd->xkb_state != NULL)
|
|
|
|
|
{
|
|
|
|
|
// Wayland keycodes are Linux evdev scancodes;
|
|
|
|
|
// xkbcommon expects keycodes offset by 8.
|
|
|
|
|
sym = xkb_state_key_get_one_sym(kbd->xkb_state, key + 8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf("keyboard_key: scancode=%d state=%d keysym=%u\n", key, state, sym);
|
|
|
|
|
|
|
|
|
|
if (kbd->handler != NULL)
|
|
|
|
|
{
|
|
|
|
|
kbd->handler(key, state, sym, kbd->user_data);
|
|
|
|
|
}
|
2024-06-02 19:29:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
|
|
|
|
|
{
|
2026-06-13 10:22:08 +02:00
|
|
|
struct keyboard_data *kbd = data;
|
|
|
|
|
|
|
|
|
|
if (kbd->xkb_state != NULL)
|
|
|
|
|
{
|
|
|
|
|
xkb_state_update_mask(kbd->xkb_state,
|
|
|
|
|
mods_depressed, mods_latched, mods_locked,
|
|
|
|
|
0, 0, group);
|
|
|
|
|
}
|
2024-06-02 19:29:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay)
|
|
|
|
|
{
|
|
|
|
|
// not implemented
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct wl_keyboard_listener keyboard_listener = {
|
|
|
|
|
.keymap = keyboard_keymap,
|
|
|
|
|
.enter = keyboard_enter,
|
|
|
|
|
.leave = keyboard_leave,
|
|
|
|
|
.key = keyboard_key,
|
|
|
|
|
.modifiers = keyboard_modifiers,
|
2026-06-13 10:22:08 +02:00
|
|
|
.repeat_info = keyboard_repeat_info};
|
2024-06-02 19:29:26 +02:00
|
|
|
|
2026-06-13 10:22:08 +02:00
|
|
|
void keyboard_set_handler(struct keyboard_data *kbd, keyboard_key_handler_t handler, void *user_data)
|
|
|
|
|
{
|
|
|
|
|
kbd->handler = handler;
|
|
|
|
|
kbd->user_data = user_data;
|
|
|
|
|
}
|