From 2d0eee125442524f2df009ebd6d4df166a74d6f9 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Tue, 13 Aug 2019 01:12:50 +0100 Subject: Wayland: Detect keyboard layout automatically --- src/imv.c | 5 +++++ src/keyboard.c | 12 ++++++++++-- src/keyboard.h | 3 +++ src/window.h | 2 ++ src/wl_window.c | 20 +++++++++++++++++--- src/x11_window.c | 5 +++++ 6 files changed, 42 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/imv.c b/src/imv.c index 7d660dd..d5c2c3c 100644 --- a/src/imv.c +++ b/src/imv.c @@ -1081,6 +1081,11 @@ static bool setup_window(struct imv *imv) { imv->keyboard = imv_keyboard_create(); assert(imv->keyboard); + + const char *keymap = imv_window_keymap(imv->window); + if (keymap) { + imv_keyboard_set_keymap(imv->keyboard, keymap); + } } { diff --git a/src/keyboard.c b/src/keyboard.c index 16b2c9d..af79006 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -22,9 +22,9 @@ struct imv_keyboard *imv_keyboard_create(void) struct xkb_rule_names names = { .rules = NULL, .model = NULL, - .layout = "gb", + .layout = NULL, .variant = NULL, - .options = "caps:escape,compose:ralt" + .options = NULL, }; keyboard->keymap = xkb_keymap_new_from_names(keyboard->context, &names, 0); assert(keyboard->keymap); @@ -116,3 +116,11 @@ size_t imv_keyboard_get_text(struct imv_keyboard *keyboard, int scancode, char * { return xkb_state_key_get_utf8(keyboard->state, scancode + scancode_offset, buf, buflen); } + +void imv_keyboard_set_keymap(struct imv_keyboard *keyboard, const char *keymap) +{ + xkb_keymap_unref(keyboard->keymap); + keyboard->keymap = xkb_keymap_new_from_string(keyboard->context, keymap, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); + xkb_state_unref(keyboard->state); + keyboard->state = xkb_state_new(keyboard->keymap); +} diff --git a/src/keyboard.h b/src/keyboard.h index 755bae2..7bbb202 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -24,4 +24,7 @@ char *imv_keyboard_describe_key(struct imv_keyboard *keyboard, int scancode); /* Write the null-terminated text generated by scancode being pressed into buf */ size_t imv_keyboard_get_text(struct imv_keyboard *keyboard, int scancode, char *buf, size_t buflen); +/* Initialise the keymap from a string containing the description */ +void imv_keyboard_set_keymap(struct imv_keyboard *keyboard, const char *keymap); + #endif diff --git a/src/window.h b/src/window.h index c185b6f..7db1125 100644 --- a/src/window.h +++ b/src/window.h @@ -73,4 +73,6 @@ typedef void (*imv_event_handler)(void *data, const struct imv_event *e); void imv_window_pump_events(struct imv_window *window, imv_event_handler handler, void *data); +const char *imv_window_keymap(struct imv_window *window); + #endif diff --git a/src/wl_window.c b/src/wl_window.c index a6b16ae..635fd4f 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,8 @@ struct imv_window { bool fullscreen; int scale; + char *keymap; + struct { struct { double last; @@ -92,11 +95,17 @@ static const struct xdg_wm_base_listener shell_listener_xdg = { static void keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) { - (void)data; (void)keyboard; (void)format; - (void)fd; - (void)size; + struct imv_window *window = data; + if (window->keymap) { + free(window->keymap); + } + window->keymap = malloc(size); + char *src = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + memcpy(window->keymap, src, size); + munmap(src, size); + close(fd); } static void keyboard_enter(void *data, struct wl_keyboard *keyboard, @@ -785,3 +794,8 @@ void imv_window_pump_events(struct imv_window *window, imv_event_handler handler } } } + +const char *imv_window_keymap(struct imv_window *window) +{ + return window->keymap; +} diff --git a/src/x11_window.c b/src/x11_window.c index 15042a4..7bf7d2b 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -332,3 +332,8 @@ void imv_window_pump_events(struct imv_window *window, imv_event_handler handler } } +const char *imv_window_keymap(struct imv_window *window) +{ + (void)window; + return NULL; +} -- cgit v1.2.3