static Status EphyrKeyboardInit(KdKeyboardInfo * ki) { KeySymsRec keySyms; CARD8 modmap[MAP_LENGTH]; XkbControlsRec controls; ki->driverPrivate = (EphyrKbdPrivate *) calloc(sizeof(EphyrKbdPrivate), 1); if (hostx_load_keymap(&keySyms, modmap, &controls)) { XkbApplyMappingChange(ki->dixdev, &keySyms, keySyms.minKeyCode, keySyms.maxKeyCode - keySyms.minKeyCode + 1, modmap, serverClient); XkbDDXChangeControls(ki->dixdev, &controls, &controls); free(keySyms.map); } ki->minScanCode = keySyms.minKeyCode; ki->maxScanCode = keySyms.maxKeyCode; if (ki->name != NULL) { free(ki->name); } ki->name = strdup("Xephyr virtual keyboard"); ephyrKbd = ki; return Success; }
/* Actually change the modifier map, and send notifications. Cannot fail. */ static void do_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap) { XkbApplyMappingChange(dev, NULL, 0, 0, modmap, serverClient); }
int xnestKeyboardProc(DeviceIntPtr pDev, int onoff) { XModifierKeymap *modifier_keymap; KeySym *keymap; int mapWidth; int min_keycode, max_keycode; KeySymsRec keySyms; CARD8 modmap[MAP_LENGTH]; int i, j; XKeyboardState values; XkbDescPtr xkb; int op, event, error, major, minor; switch (onoff) { case DEVICE_INIT: XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); #ifdef _XSERVER64 { KeySym64 *keymap64; int len; keymap64 = XGetKeyboardMapping(xnestDisplay, min_keycode, max_keycode - min_keycode + 1, &mapWidth); len = (max_keycode - min_keycode + 1) * mapWidth; keymap = xallocarray(len, sizeof(KeySym)); for (i = 0; i < len; ++i) keymap[i] = keymap64[i]; XFree(keymap64); } #else keymap = XGetKeyboardMapping(xnestDisplay, min_keycode, max_keycode - min_keycode + 1, &mapWidth); #endif memset(modmap, 0, sizeof(modmap)); modifier_keymap = XGetModifierMapping(xnestDisplay); for (j = 0; j < 8; j++) for (i = 0; i < modifier_keymap->max_keypermod; i++) { CARD8 keycode; if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap-> max_keypermod + i])) modmap[keycode] |= 1 << j; } XFreeModifiermap(modifier_keymap); keySyms.minKeyCode = min_keycode; keySyms.maxKeyCode = max_keycode; keySyms.mapWidth = mapWidth; keySyms.map = keymap; if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { ErrorF("Unable to initialize XKEYBOARD extension.\n"); goto XkbError; } xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); if (xkb == NULL || xkb->geom == NULL) { ErrorF("Couldn't get keyboard.\n"); goto XkbError; } XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl); XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode, keySyms.maxKeyCode - keySyms.minKeyCode + 1, modmap, serverClient); XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); XkbFreeKeyboard(xkb, 0, False); free(keymap); break; case DEVICE_ON: xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; for (i = 0; i < xnestNumScreens; i++) XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); break; case DEVICE_OFF: xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; for (i = 0; i < xnestNumScreens; i++) XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); break; case DEVICE_CLOSE: break; } return Success; XkbError: XGetKeyboardControl(xnestDisplay, &values); memmove((char *) defaultKeyboardControl.autoRepeats, (char *) values.auto_repeats, sizeof(values.auto_repeats)); InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl); free(keymap); return Success; }