105b261ecSmrg/* 205b261ecSmrg 305b261ecSmrgCopyright 1993 by Davor Matic 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software 605b261ecSmrgand its documentation for any purpose is hereby granted without fee, 705b261ecSmrgprovided that the above copyright notice appear in all copies and that 805b261ecSmrgboth that copyright notice and this permission notice appear in 905b261ecSmrgsupporting documentation. Davor Matic makes no representations about 1005b261ecSmrgthe suitability of this software for any purpose. It is provided "as 1105b261ecSmrgis" without express or implied warranty. 1205b261ecSmrg 1305b261ecSmrg*/ 1405b261ecSmrg 1505b261ecSmrg#ifdef HAVE_XNEST_CONFIG_H 1605b261ecSmrg#include <xnest-config.h> 1705b261ecSmrg#endif 1805b261ecSmrg 1935c4bbdfSmrg#ifdef WIN32 2035c4bbdfSmrg#include <X11/Xwindows.h> 2135c4bbdfSmrg#endif 2235c4bbdfSmrg 2305b261ecSmrg#include <X11/X.h> 2405b261ecSmrg#include <X11/Xproto.h> 2505b261ecSmrg#include <X11/keysym.h> 2605b261ecSmrg#include "screenint.h" 2705b261ecSmrg#include "inputstr.h" 2805b261ecSmrg#include "misc.h" 2905b261ecSmrg#include "scrnintstr.h" 3005b261ecSmrg#include "servermd.h" 3105b261ecSmrg 3205b261ecSmrg#include "Xnest.h" 3305b261ecSmrg 3405b261ecSmrg#include "Display.h" 3505b261ecSmrg#include "Screen.h" 3605b261ecSmrg#include "Keyboard.h" 3705b261ecSmrg#include "Args.h" 3805b261ecSmrg#include "Events.h" 3905b261ecSmrg 4005b261ecSmrg#include <X11/extensions/XKB.h> 416747b715Smrg#include "xkbsrv.h" 4205b261ecSmrg#include <X11/extensions/XKBconfig.h> 4305b261ecSmrg 4405b261ecSmrgextern Bool 4535c4bbdfSmrg XkbQueryExtension(Display * /* dpy */ , 4635c4bbdfSmrg int * /* opcodeReturn */ , 4735c4bbdfSmrg int * /* eventBaseReturn */ , 4835c4bbdfSmrg int * /* errorBaseReturn */ , 4935c4bbdfSmrg int * /* majorRtrn */ , 5035c4bbdfSmrg int * /* minorRtrn */ 5135c4bbdfSmrg ); 5235c4bbdfSmrg 5335c4bbdfSmrgextern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ , 5435c4bbdfSmrg unsigned int /* which */ , 5535c4bbdfSmrg unsigned int /* deviceSpec */ 5635c4bbdfSmrg ); 5735c4bbdfSmrg 5835c4bbdfSmrgextern Status XkbGetControls(Display * /* dpy */ , 5935c4bbdfSmrg unsigned long /* which */ , 6035c4bbdfSmrg XkbDescPtr /* desc */ 6135c4bbdfSmrg ); 6205b261ecSmrg 6305b261ecSmrgDeviceIntPtr xnestKeyboardDevice = NULL; 6405b261ecSmrg 6505b261ecSmrgvoid 6635c4bbdfSmrgxnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls) 6705b261ecSmrg{ 6835c4bbdfSmrg XBell(xnestDisplay, volume); 6905b261ecSmrg} 7005b261ecSmrg 7105b261ecSmrgvoid 7205b261ecSmrgDDXRingBell(int volume, int pitch, int duration) 7305b261ecSmrg{ 7435c4bbdfSmrg XBell(xnestDisplay, volume); 7505b261ecSmrg} 7605b261ecSmrg 7705b261ecSmrgvoid 7835c4bbdfSmrgxnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl) 7905b261ecSmrg{ 8005b261ecSmrg#if 0 8135c4bbdfSmrg unsigned long value_mask; 8235c4bbdfSmrg XKeyboardControl values; 8335c4bbdfSmrg int i; 8435c4bbdfSmrg 8535c4bbdfSmrg value_mask = KBKeyClickPercent | 8635c4bbdfSmrg KBBellPercent | KBBellPitch | KBBellDuration | KBAutoRepeatMode; 8735c4bbdfSmrg 8835c4bbdfSmrg values.key_click_percent = ctrl->click; 8935c4bbdfSmrg values.bell_percent = ctrl->bell; 9035c4bbdfSmrg values.bell_pitch = ctrl->bell_pitch; 9135c4bbdfSmrg values.bell_duration = ctrl->bell_duration; 9235c4bbdfSmrg values.auto_repeat_mode = ctrl->autoRepeat ? 9335c4bbdfSmrg AutoRepeatModeOn : AutoRepeatModeOff; 9435c4bbdfSmrg 9505b261ecSmrg XChangeKeyboardControl(xnestDisplay, value_mask, &values); 9635c4bbdfSmrg 9735c4bbdfSmrg /* 9835c4bbdfSmrg value_mask = KBKey | KBAutoRepeatMode; 9935c4bbdfSmrg At this point, we need to walk through the vector and compare it 10035c4bbdfSmrg to the current server vector. If there are differences, report them. 10135c4bbdfSmrg */ 10235c4bbdfSmrg 10335c4bbdfSmrg value_mask = KBLed | KBLedMode; 10435c4bbdfSmrg for (i = 1; i <= 32; i++) { 10535c4bbdfSmrg values.led = i; 10635c4bbdfSmrg values.led_mode = 10735c4bbdfSmrg (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff; 10835c4bbdfSmrg XChangeKeyboardControl(xnestDisplay, value_mask, &values); 10935c4bbdfSmrg } 11005b261ecSmrg#endif 11105b261ecSmrg} 11205b261ecSmrg 11305b261ecSmrgint 11405b261ecSmrgxnestKeyboardProc(DeviceIntPtr pDev, int onoff) 11505b261ecSmrg{ 11635c4bbdfSmrg XModifierKeymap *modifier_keymap; 11735c4bbdfSmrg KeySym *keymap; 11835c4bbdfSmrg int mapWidth; 11935c4bbdfSmrg int min_keycode, max_keycode; 12035c4bbdfSmrg KeySymsRec keySyms; 12135c4bbdfSmrg CARD8 modmap[MAP_LENGTH]; 12235c4bbdfSmrg int i, j; 12335c4bbdfSmrg XKeyboardState values; 12435c4bbdfSmrg XkbDescPtr xkb; 12535c4bbdfSmrg int op, event, error, major, minor; 12635c4bbdfSmrg 12735c4bbdfSmrg switch (onoff) { 12835c4bbdfSmrg case DEVICE_INIT: 12935c4bbdfSmrg XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); 13005b261ecSmrg#ifdef _XSERVER64 13135c4bbdfSmrg { 13235c4bbdfSmrg KeySym64 *keymap64; 13335c4bbdfSmrg int len; 13435c4bbdfSmrg 13535c4bbdfSmrg keymap64 = XGetKeyboardMapping(xnestDisplay, 13635c4bbdfSmrg min_keycode, 13735c4bbdfSmrg max_keycode - min_keycode + 1, 13835c4bbdfSmrg &mapWidth); 13935c4bbdfSmrg len = (max_keycode - min_keycode + 1) * mapWidth; 14035c4bbdfSmrg keymap = xallocarray(len, sizeof(KeySym)); 14135c4bbdfSmrg for (i = 0; i < len; ++i) 14235c4bbdfSmrg keymap[i] = keymap64[i]; 14335c4bbdfSmrg XFree(keymap64); 14435c4bbdfSmrg } 14505b261ecSmrg#else 14635c4bbdfSmrg keymap = XGetKeyboardMapping(xnestDisplay, 14735c4bbdfSmrg min_keycode, 14835c4bbdfSmrg max_keycode - min_keycode + 1, &mapWidth); 14905b261ecSmrg#endif 150475c125cSmrg 15135c4bbdfSmrg memset(modmap, 0, sizeof(modmap)); 15235c4bbdfSmrg modifier_keymap = XGetModifierMapping(xnestDisplay); 15335c4bbdfSmrg for (j = 0; j < 8; j++) 15435c4bbdfSmrg for (i = 0; i < modifier_keymap->max_keypermod; i++) { 15535c4bbdfSmrg CARD8 keycode; 15635c4bbdfSmrg 15735c4bbdfSmrg if ((keycode = 15835c4bbdfSmrg modifier_keymap->modifiermap[j * 15935c4bbdfSmrg modifier_keymap-> 16035c4bbdfSmrg max_keypermod + i])) 16135c4bbdfSmrg modmap[keycode] |= 1 << j; 16235c4bbdfSmrg } 16335c4bbdfSmrg XFreeModifiermap(modifier_keymap); 16435c4bbdfSmrg 16535c4bbdfSmrg keySyms.minKeyCode = min_keycode; 16635c4bbdfSmrg keySyms.maxKeyCode = max_keycode; 16735c4bbdfSmrg keySyms.mapWidth = mapWidth; 16835c4bbdfSmrg keySyms.map = keymap; 16935c4bbdfSmrg 17035c4bbdfSmrg if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) 17135c4bbdfSmrg == 0) { 17235c4bbdfSmrg ErrorF("Unable to initialize XKEYBOARD extension.\n"); 17335c4bbdfSmrg goto XkbError; 17435c4bbdfSmrg } 17535c4bbdfSmrg xkb = 17635c4bbdfSmrg XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, 17735c4bbdfSmrg XkbUseCoreKbd); 17835c4bbdfSmrg if (xkb == NULL || xkb->geom == NULL) { 17935c4bbdfSmrg ErrorF("Couldn't get keyboard.\n"); 18035c4bbdfSmrg goto XkbError; 18135c4bbdfSmrg } 18235c4bbdfSmrg XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); 18335c4bbdfSmrg 18435c4bbdfSmrg InitKeyboardDeviceStruct(pDev, NULL, 18535c4bbdfSmrg xnestBell, xnestChangeKeyboardControl); 18635c4bbdfSmrg 18735c4bbdfSmrg XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode, 18835c4bbdfSmrg keySyms.maxKeyCode - keySyms.minKeyCode + 1, 18935c4bbdfSmrg modmap, serverClient); 19035c4bbdfSmrg 19135c4bbdfSmrg XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); 19235c4bbdfSmrg XkbFreeKeyboard(xkb, 0, False); 19335c4bbdfSmrg free(keymap); 19435c4bbdfSmrg break; 19535c4bbdfSmrg case DEVICE_ON: 19635c4bbdfSmrg xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; 19735c4bbdfSmrg for (i = 0; i < xnestNumScreens; i++) 19835c4bbdfSmrg XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 19935c4bbdfSmrg break; 20035c4bbdfSmrg case DEVICE_OFF: 20135c4bbdfSmrg xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; 20235c4bbdfSmrg for (i = 0; i < xnestNumScreens; i++) 20335c4bbdfSmrg XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 20435c4bbdfSmrg break; 20535c4bbdfSmrg case DEVICE_CLOSE: 20635c4bbdfSmrg break; 20705b261ecSmrg } 20835c4bbdfSmrg return Success; 20935c4bbdfSmrg 21035c4bbdfSmrg XkbError: 21135c4bbdfSmrg XGetKeyboardControl(xnestDisplay, &values); 21235c4bbdfSmrg memmove((char *) defaultKeyboardControl.autoRepeats, 21335c4bbdfSmrg (char *) values.auto_repeats, sizeof(values.auto_repeats)); 21435c4bbdfSmrg 21535c4bbdfSmrg InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl); 21635c4bbdfSmrg free(keymap); 21735c4bbdfSmrg return Success; 21805b261ecSmrg} 21905b261ecSmrg 22005b261ecSmrgvoid 22105b261ecSmrgxnestUpdateModifierState(unsigned int state) 22205b261ecSmrg{ 22335c4bbdfSmrg DeviceIntPtr pDev = xnestKeyboardDevice; 22435c4bbdfSmrg KeyClassPtr keyc = pDev->key; 22535c4bbdfSmrg int i; 22635c4bbdfSmrg CARD8 mask; 22735c4bbdfSmrg int xkb_state; 22835c4bbdfSmrg 22935c4bbdfSmrg if (!pDev) 23035c4bbdfSmrg return; 23135c4bbdfSmrg 23235c4bbdfSmrg xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 23335c4bbdfSmrg state = state & 0xff; 23435c4bbdfSmrg 23535c4bbdfSmrg if (xkb_state == state) 23635c4bbdfSmrg return; 23735c4bbdfSmrg 23835c4bbdfSmrg for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 23935c4bbdfSmrg int key; 24035c4bbdfSmrg 241ed6184dfSmrg /* Modifier is down, but shouldn't be */ 24235c4bbdfSmrg if ((xkb_state & mask) && !(state & mask)) { 24335c4bbdfSmrg int count = keyc->modifierKeyCount[i]; 24435c4bbdfSmrg 24535c4bbdfSmrg for (key = 0; key < MAP_LENGTH; key++) 24635c4bbdfSmrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 24735c4bbdfSmrg if (mask == LockMask) { 24835c4bbdfSmrg xnestQueueKeyEvent(KeyPress, key); 24935c4bbdfSmrg xnestQueueKeyEvent(KeyRelease, key); 25035c4bbdfSmrg } 25135c4bbdfSmrg else if (key_is_down(pDev, key, KEY_PROCESSED)) 25235c4bbdfSmrg xnestQueueKeyEvent(KeyRelease, key); 25335c4bbdfSmrg 25435c4bbdfSmrg if (--count == 0) 25535c4bbdfSmrg break; 25635c4bbdfSmrg } 25735c4bbdfSmrg } 25835c4bbdfSmrg 259ed6184dfSmrg /* Modifier should be down, but isn't */ 26035c4bbdfSmrg if (!(xkb_state & mask) && (state & mask)) 26135c4bbdfSmrg for (key = 0; key < MAP_LENGTH; key++) 26235c4bbdfSmrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 26335c4bbdfSmrg xnestQueueKeyEvent(KeyPress, key); 26435c4bbdfSmrg if (mask == LockMask) 26535c4bbdfSmrg xnestQueueKeyEvent(KeyRelease, key); 26635c4bbdfSmrg break; 26735c4bbdfSmrg } 26805b261ecSmrg } 26905b261ecSmrg} 270