feat: Initial usage of xkb.
This commit is contained in:
@@ -28,6 +28,12 @@ Build programs:
|
|||||||
cmake --build ./build
|
cmake --build ./build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Run tests:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ctest --test-dir build
|
||||||
|
```
|
||||||
|
|
||||||
Run program:
|
Run program:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ project(wlgol
|
|||||||
DESCRIPTION "Wayland Game Of Life"
|
DESCRIPTION "Wayland Game Of Life"
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(XKBCOMMON REQUIRED xkbcommon)
|
||||||
|
|
||||||
# Download xdg-shell.xml
|
# Download xdg-shell.xml
|
||||||
# file(DOWNLOAD "https://cgit.freedesktop.org/wayland/wayland-protocols/plain/stable/xdg-shell/xdg-shell.xml" "${CMAKE_CURRENT_BINARY_DIR}/xdg-shell.xml")
|
# file(DOWNLOAD "https://cgit.freedesktop.org/wayland/wayland-protocols/plain/stable/xdg-shell/xdg-shell.xml" "${CMAKE_CURRENT_BINARY_DIR}/xdg-shell.xml")
|
||||||
|
|
||||||
@@ -37,11 +40,17 @@ add_executable(wlgol wlgol.c ${SOURCES} ${GENHEADERS})
|
|||||||
target_include_directories(wlgol
|
target_include_directories(wlgol
|
||||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include
|
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include
|
||||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
PUBLIC ${XKBCOMMON_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(wlgol
|
target_link_libraries(wlgol
|
||||||
wayland-client
|
wayland-client
|
||||||
wayland-cursor
|
wayland-cursor
|
||||||
|
${XKBCOMMON_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(wlgol PRIVATE
|
||||||
|
${XKBCOMMON_CFLAGS_OTHER}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -52,10 +61,15 @@ add_executable(test_hashtable tests/test_hashtable.c
|
|||||||
target_link_libraries(test_hashtable
|
target_link_libraries(test_hashtable
|
||||||
wayland-client
|
wayland-client
|
||||||
wayland-cursor
|
wayland-cursor
|
||||||
|
${XKBCOMMON_LIBRARIES}
|
||||||
)
|
)
|
||||||
target_include_directories(test_hashtable
|
target_include_directories(test_hashtable
|
||||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include
|
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include
|
||||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
PUBLIC ${XKBCOMMON_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
target_compile_options(test_hashtable PRIVATE
|
||||||
|
${XKBCOMMON_CFLAGS_OTHER}
|
||||||
)
|
)
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
#ifndef TKEYBOARD_H
|
#ifndef TKEYBOARD_H
|
||||||
#define TKEYBOARD_H
|
#define TKEYBOARD_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
|
typedef void (*keyboard_key_handler_t)(uint32_t key, uint32_t state, xkb_keysym_t sym, void *user_data);
|
||||||
|
|
||||||
struct keyboard_data {
|
struct keyboard_data {
|
||||||
struct wl_keyboard *keyboard;
|
struct wl_keyboard *keyboard;
|
||||||
|
struct xkb_context *xkb_context;
|
||||||
|
struct xkb_keymap *xkb_keymap;
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
|
||||||
|
keyboard_key_handler_t handler;
|
||||||
|
void *user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct wl_keyboard_listener keyboard_listener;
|
extern const struct wl_keyboard_listener keyboard_listener;
|
||||||
|
|
||||||
|
void keyboard_set_handler(struct keyboard_data *kbd, keyboard_key_handler_t handler, void *user_data);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+61
-8
@@ -1,33 +1,82 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include <tkeyboard.h>
|
#include <tkeyboard.h>
|
||||||
|
|
||||||
static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size)
|
static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size)
|
||||||
{
|
{
|
||||||
// not implemented
|
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)
|
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");
|
printf("keyboard_enter\n");
|
||||||
// not implemented
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface)
|
static void keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface)
|
||||||
{
|
{
|
||||||
printf("keyboard_leave\n");
|
printf("keyboard_leave\n");
|
||||||
// not implemented
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
static void keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
||||||
{
|
{
|
||||||
printf("keyboard_key: %d %d\n", key, state);
|
struct keyboard_data *kbd = data;
|
||||||
// not implemented
|
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)
|
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)
|
||||||
{
|
{
|
||||||
// not implemented
|
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)
|
static void keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay)
|
||||||
@@ -41,6 +90,10 @@ const struct wl_keyboard_listener keyboard_listener = {
|
|||||||
.leave = keyboard_leave,
|
.leave = keyboard_leave,
|
||||||
.key = keyboard_key,
|
.key = keyboard_key,
|
||||||
.modifiers = keyboard_modifiers,
|
.modifiers = keyboard_modifiers,
|
||||||
.repeat_info = keyboard_repeat_info
|
.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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <xdg-shell.h>
|
#include <xdg-shell.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||||
|
|
||||||
#include <tkeyboard.h>
|
#include <tkeyboard.h>
|
||||||
#include <tpointer.h>
|
#include <tpointer.h>
|
||||||
@@ -142,6 +144,18 @@ const struct wl_buffer_listener wl_buffer_listener = {
|
|||||||
|
|
||||||
void redraw(); // forward declaration
|
void redraw(); // forward declaration
|
||||||
|
|
||||||
|
static void handle_key(uint32_t key, uint32_t state, xkb_keysym_t sym, void *user_data)
|
||||||
|
{
|
||||||
|
(void)key;
|
||||||
|
(void)user_data;
|
||||||
|
|
||||||
|
if (state == WL_KEYBOARD_KEY_STATE_PRESSED && sym == XKB_KEY_Escape)
|
||||||
|
{
|
||||||
|
printf("Escape pressed, exiting.\n");
|
||||||
|
running = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wl_callack_done(void *data, struct wl_callback *callback, uint32_t time)
|
void wl_callack_done(void *data, struct wl_callback *callback, uint32_t time)
|
||||||
{
|
{
|
||||||
if (canvas.frame)
|
if (canvas.frame)
|
||||||
@@ -187,6 +201,7 @@ int main(void)
|
|||||||
wl_surface_commit(canvas.surface);
|
wl_surface_commit(canvas.surface);
|
||||||
|
|
||||||
keyboard_data.keyboard = wl_seat_get_keyboard(wl_seat);
|
keyboard_data.keyboard = wl_seat_get_keyboard(wl_seat);
|
||||||
|
keyboard_set_handler(&keyboard_data, handle_key, NULL);
|
||||||
wl_keyboard_add_listener(keyboard_data.keyboard, &keyboard_listener, &keyboard_data);
|
wl_keyboard_add_listener(keyboard_data.keyboard, &keyboard_listener, &keyboard_data);
|
||||||
|
|
||||||
pointer_init_cursor(&pointer_data, compositor, shm);
|
pointer_init_cursor(&pointer_data, compositor, shm);
|
||||||
@@ -230,6 +245,19 @@ int main(void)
|
|||||||
xdg_surface_destroy(xdg_surface);
|
xdg_surface_destroy(xdg_surface);
|
||||||
wl_surface_destroy(canvas.surface);
|
wl_surface_destroy(canvas.surface);
|
||||||
wl_shm_pool_destroy(pool);
|
wl_shm_pool_destroy(pool);
|
||||||
|
wl_keyboard_destroy(keyboard_data.keyboard);
|
||||||
|
if (keyboard_data.xkb_state != NULL)
|
||||||
|
{
|
||||||
|
xkb_state_unref(keyboard_data.xkb_state);
|
||||||
|
}
|
||||||
|
if (keyboard_data.xkb_keymap != NULL)
|
||||||
|
{
|
||||||
|
xkb_keymap_unref(keyboard_data.xkb_keymap);
|
||||||
|
}
|
||||||
|
if (keyboard_data.xkb_context != NULL)
|
||||||
|
{
|
||||||
|
xkb_context_unref(keyboard_data.xkb_context);
|
||||||
|
}
|
||||||
wl_registry_destroy(registry);
|
wl_registry_destroy(registry);
|
||||||
wl_display_disconnect(display);
|
wl_display_disconnect(display);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user