#include #include #include #include #include #include #include #include static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) { 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); } 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) { 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); } } 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) { 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); } } 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, .repeat_info = keyboard_repeat_info}; void keyboard_set_handler(struct keyboard_data *kbd, keyboard_key_handler_t handler, void *user_data) { kbd->handler = handler; kbd->user_data = user_data; }