From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/wayland_keyboard.c | 46 +++++++++++++++++++++++-- dlls/winewayland.drv/waylanddrv.h | 1 + 2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_keyboard.c b/dlls/winewayland.drv/wayland_keyboard.c index 29ddb4591c4..5566141e1cb 100644 --- a/dlls/winewayland.drv/wayland_keyboard.c +++ b/dlls/winewayland.drv/wayland_keyboard.c @@ -27,6 +27,7 @@
#include <linux/input.h> #undef SW_MAX /* Also defined in winuser.rh */ +#include <sys/mman.h> #include <unistd.h>
#include "waylanddrv.h" @@ -128,8 +129,39 @@ static WORD key2scan(UINT key) static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int fd, uint32_t size) { - FIXME("stub!\n"); + struct wayland_keyboard *keyboard = &process_wayland.keyboard; + struct xkb_keymap *xkb_keymap = NULL; + struct xkb_state *xkb_state; + char *keymap_str; + + TRACE("format=%d fd=%d size=%d\n", format, fd, size); + + if ((keymap_str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0)) != MAP_FAILED) + { + if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) + xkb_keymap = xkb_keymap_new_from_buffer(keyboard->xkb_context, keymap_str, size, + XKB_KEYMAP_FORMAT_TEXT_V1, 0); + else + FIXME("Unsupported keymap format %#x\n", format); + + munmap(keymap_str, size); + } + close(fd); + + if (!xkb_keymap) + { + ERR("Failed to load Xkb keymap\n"); + return; + } + + if ((xkb_state = xkb_state_new(xkb_keymap))) + { + xkb_state_unref(keyboard->xkb_state); + keyboard->xkb_state = xkb_state; + } + + xkb_keymap_unref(xkb_keymap); }
static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, @@ -196,8 +228,17 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar uint32_t mods_latched, uint32_t mods_locked, uint32_t xkb_group) { - FIXME("serial=%u mods_depressed=%#x mods_latched=%#x mods_locked=%#x xkb_group=%d stub!\n", + struct wayland_keyboard *keyboard = &process_wayland.keyboard; + + if (!keyboard->focused_hwnd) return; + + TRACE("serial=%u mods_depressed=%#x mods_latched=%#x mods_locked=%#x xkb_group=%d stub!\n", serial, mods_depressed, mods_latched, mods_locked, xkb_group); + + xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, + mods_locked, 0, 0, xkb_group); + + /* TODO: Sync wine modifier state with XKB modifier state. */ }
static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, @@ -253,6 +294,7 @@ void wayland_keyboard_deinit(struct wayland_keyboard *keyboard) if (keyboard->wl_keyboard) wl_keyboard_destroy(keyboard->wl_keyboard);
+ xkb_state_unref(keyboard->xkb_state); xkb_context_unref(keyboard->xkb_context); memset(keyboard, 0, sizeof(*keyboard)); } diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index de2167ddc49..2fdb9fe679e 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -70,6 +70,7 @@ struct wayland_keyboard { struct wl_keyboard *wl_keyboard; struct xkb_context *xkb_context; + struct xkb_state *xkb_state; HWND focused_hwnd; };