From d43a01c9cb622ea7300614dce3d0752e21ca180a Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Mon, 21 Oct 2013 14:41:54 +0200 Subject: [PATCH 39/39] xwayland: Handle keymap changes --- hw/xfree86/xwayland/xwayland-input.c | 39 +++++++++++++++++++++++++++++++++--- include/input.h | 2 +- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c index d031b34..ebf1af1 100644 --- a/hw/xfree86/xwayland/xwayland-input.c +++ b/hw/xfree86/xwayland/xwayland-input.c @@ -143,7 +143,10 @@ xwl_keyboard_proc(DeviceIntPtr device, int what) switch (what) { case DEVICE_INIT: device->public.on = FALSE; - len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size); + if (xwl_seat->keymap) + len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size); + else + len = 0; if (!InitKeyboardDeviceStructFromString(device, xwl_seat->keymap, len, NULL, xwl_keyboard_control)) @@ -453,12 +456,42 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) { struct xwl_seat *xwl_seat = data; + DeviceIntPtr master; + XkbDescPtr xkb; + XkbChangesRec changes = { 0 }; + + if (xwl_seat->keymap) + munmap(xwl_seat->keymap, xwl_seat->keymap_size); xwl_seat->keymap_size = size; xwl_seat->keymap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - if (xwl_seat->keymap == MAP_FAILED) - ; /* wah wah */ + if (xwl_seat->keymap == MAP_FAILED) { + xwl_seat->keymap_size = 0; + xwl_seat->keymap = NULL; + goto out; + } + + if (!xwl_seat->keyboard) + goto out; + + xkb = XkbCompileKeymapFromString(xwl_seat->keyboard, xwl_seat->keymap, + strnlen(xwl_seat->keymap, xwl_seat->keymap_size)); + if (!xkb) + goto out; + + XkbUpdateDescActions(xkb, xkb->min_key_code, XkbNumKeys(xkb), &changes); + /* Keep the current controls */ + XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc); + + XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb); + + master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD); + if (master && master->lastSlave == xwl_seat->keyboard) + XkbDeviceApplyKeymap(master, xkb); + + XkbFreeKeyboard(xkb, XkbAllComponentsMask, TRUE); + out: close(fd); } diff --git a/include/input.h b/include/input.h index 6573a3a..1edcedc 100644 --- a/include/input.h +++ b/include/input.h @@ -508,7 +508,7 @@ extern int AttachDevice(ClientPtr client, DeviceIntPtr slave, DeviceIntPtr master); extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd); -extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type); +extern _X_EXPORT DeviceIntPtr GetMaster(DeviceIntPtr dev, int type); extern _X_EXPORT int AllocDevicePair(ClientPtr client, const char *name, -- 1.8.3.1