Keyboard.c revision 475c125c
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 1905b261ecSmrg#include <X11/X.h> 2005b261ecSmrg#include <X11/Xproto.h> 2105b261ecSmrg#include <X11/keysym.h> 2205b261ecSmrg#include "screenint.h" 2305b261ecSmrg#include "inputstr.h" 2405b261ecSmrg#include "misc.h" 2505b261ecSmrg#include "scrnintstr.h" 2605b261ecSmrg#include "servermd.h" 2705b261ecSmrg 2805b261ecSmrg#include "Xnest.h" 2905b261ecSmrg 3005b261ecSmrg#include "Display.h" 3105b261ecSmrg#include "Screen.h" 3205b261ecSmrg#include "Keyboard.h" 3305b261ecSmrg#include "Args.h" 3405b261ecSmrg#include "Events.h" 3505b261ecSmrg 3605b261ecSmrg#include <X11/extensions/XKB.h> 376747b715Smrg#include "xkbsrv.h" 3805b261ecSmrg#include <X11/extensions/XKBconfig.h> 3905b261ecSmrg 4005b261ecSmrgextern Bool 4105b261ecSmrgXkbQueryExtension( 4205b261ecSmrg Display * /* dpy */, 4305b261ecSmrg int * /* opcodeReturn */, 4405b261ecSmrg int * /* eventBaseReturn */, 4505b261ecSmrg int * /* errorBaseReturn */, 4605b261ecSmrg int * /* majorRtrn */, 4705b261ecSmrg int * /* minorRtrn */ 4805b261ecSmrg); 4905b261ecSmrg 5005b261ecSmrgextern XkbDescPtr XkbGetKeyboard( 5105b261ecSmrg Display * /* dpy */, 5205b261ecSmrg unsigned int /* which */, 5305b261ecSmrg unsigned int /* deviceSpec */ 5405b261ecSmrg); 5505b261ecSmrg 5605b261ecSmrgextern Status XkbGetControls( 5705b261ecSmrg Display * /* dpy */, 5805b261ecSmrg unsigned long /* which */, 5905b261ecSmrg XkbDescPtr /* desc */ 6005b261ecSmrg); 6105b261ecSmrg 6205b261ecSmrgDeviceIntPtr xnestKeyboardDevice = NULL; 6305b261ecSmrg 6405b261ecSmrgvoid 6505b261ecSmrgxnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls) 6605b261ecSmrg{ 6705b261ecSmrg XBell(xnestDisplay, volume); 6805b261ecSmrg} 6905b261ecSmrg 7005b261ecSmrgvoid 7105b261ecSmrgDDXRingBell(int volume, int pitch, int duration) 7205b261ecSmrg{ 7305b261ecSmrg XBell(xnestDisplay, volume); 7405b261ecSmrg} 7505b261ecSmrg 7605b261ecSmrgvoid 7705b261ecSmrgxnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl) 7805b261ecSmrg{ 7905b261ecSmrg#if 0 8005b261ecSmrg unsigned long value_mask; 8105b261ecSmrg XKeyboardControl values; 8205b261ecSmrg int i; 8305b261ecSmrg 8405b261ecSmrg value_mask = KBKeyClickPercent | 8505b261ecSmrg KBBellPercent | 8605b261ecSmrg KBBellPitch | 8705b261ecSmrg KBBellDuration | 8805b261ecSmrg KBAutoRepeatMode; 8905b261ecSmrg 9005b261ecSmrg values.key_click_percent = ctrl->click; 9105b261ecSmrg values.bell_percent = ctrl->bell; 9205b261ecSmrg values.bell_pitch = ctrl->bell_pitch; 9305b261ecSmrg values.bell_duration = ctrl->bell_duration; 9405b261ecSmrg values.auto_repeat_mode = ctrl->autoRepeat ? 9505b261ecSmrg AutoRepeatModeOn : AutoRepeatModeOff; 9605b261ecSmrg 9705b261ecSmrg XChangeKeyboardControl(xnestDisplay, value_mask, &values); 9805b261ecSmrg 9905b261ecSmrg /* 10005b261ecSmrg value_mask = KBKey | KBAutoRepeatMode; 10105b261ecSmrg At this point, we need to walk through the vector and compare it 10205b261ecSmrg to the current server vector. If there are differences, report them. 10305b261ecSmrg */ 10405b261ecSmrg 10505b261ecSmrg value_mask = KBLed | KBLedMode; 10605b261ecSmrg for (i = 1; i <= 32; i++) { 10705b261ecSmrg values.led = i; 10805b261ecSmrg values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff; 10905b261ecSmrg XChangeKeyboardControl(xnestDisplay, value_mask, &values); 11005b261ecSmrg } 11105b261ecSmrg#endif 11205b261ecSmrg} 11305b261ecSmrg 11405b261ecSmrgint 11505b261ecSmrgxnestKeyboardProc(DeviceIntPtr pDev, int onoff) 11605b261ecSmrg{ 117475c125cSmrg XModifierKeymap *modifier_keymap; 11805b261ecSmrg KeySym *keymap; 11905b261ecSmrg int mapWidth; 12005b261ecSmrg int min_keycode, max_keycode; 12105b261ecSmrg KeySymsRec keySyms; 122475c125cSmrg CARD8 modmap[MAP_LENGTH]; 123475c125cSmrg int i, j; 12405b261ecSmrg XKeyboardState values; 1256747b715Smrg XkbDescPtr xkb; 1266747b715Smrg int op, event, error, major, minor; 12705b261ecSmrg 12805b261ecSmrg switch (onoff) 12905b261ecSmrg { 13005b261ecSmrg case DEVICE_INIT: 13105b261ecSmrg XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); 13205b261ecSmrg#ifdef _XSERVER64 13305b261ecSmrg { 13405b261ecSmrg KeySym64 *keymap64; 135475c125cSmrg int len; 13605b261ecSmrg keymap64 = XGetKeyboardMapping(xnestDisplay, 13705b261ecSmrg min_keycode, 13805b261ecSmrg max_keycode - min_keycode + 1, 13905b261ecSmrg &mapWidth); 14005b261ecSmrg len = (max_keycode - min_keycode + 1) * mapWidth; 1416747b715Smrg keymap = (KeySym *)malloc(len * sizeof(KeySym)); 14205b261ecSmrg for(i = 0; i < len; ++i) 14305b261ecSmrg keymap[i] = keymap64[i]; 14405b261ecSmrg XFree(keymap64); 14505b261ecSmrg } 14605b261ecSmrg#else 14705b261ecSmrg keymap = XGetKeyboardMapping(xnestDisplay, 14805b261ecSmrg min_keycode, 14905b261ecSmrg max_keycode - min_keycode + 1, 15005b261ecSmrg &mapWidth); 15105b261ecSmrg#endif 152475c125cSmrg 153475c125cSmrg memset(modmap, 0, sizeof(modmap)); 154475c125cSmrg modifier_keymap = XGetModifierMapping(xnestDisplay); 155475c125cSmrg for (j = 0; j < 8; j++) 156475c125cSmrg for(i = 0; i < modifier_keymap->max_keypermod; i++) { 157475c125cSmrg CARD8 keycode; 158475c125cSmrg if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i])) 159475c125cSmrg modmap[keycode] |= 1<<j; 160475c125cSmrg } 161475c125cSmrg XFreeModifiermap(modifier_keymap); 162475c125cSmrg 16305b261ecSmrg keySyms.minKeyCode = min_keycode; 16405b261ecSmrg keySyms.maxKeyCode = max_keycode; 16505b261ecSmrg keySyms.mapWidth = mapWidth; 16605b261ecSmrg keySyms.map = keymap; 16705b261ecSmrg 1686747b715Smrg if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { 1696747b715Smrg ErrorF("Unable to initialize XKEYBOARD extension.\n"); 17005b261ecSmrg goto XkbError; 1716747b715Smrg } 1726747b715Smrg xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); 1736747b715Smrg if (xkb == NULL || xkb->geom == NULL) { 17405b261ecSmrg ErrorF("Couldn't get keyboard.\n"); 1756747b715Smrg goto XkbError; 17605b261ecSmrg } 1776747b715Smrg XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); 1786747b715Smrg 1796747b715Smrg InitKeyboardDeviceStruct(pDev, NULL, 180475c125cSmrg xnestBell, xnestChangeKeyboardControl); 181475c125cSmrg 182475c125cSmrg XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode, 183475c125cSmrg keySyms.maxKeyCode - keySyms.minKeyCode + 1, 184475c125cSmrg modmap, serverClient); 185475c125cSmrg 1866747b715Smrg XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); 1876747b715Smrg XkbFreeKeyboard(xkb, 0, False); 1886747b715Smrg free(keymap); 18905b261ecSmrg break; 19005b261ecSmrg case DEVICE_ON: 19105b261ecSmrg xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; 19205b261ecSmrg for (i = 0; i < xnestNumScreens; i++) 19305b261ecSmrg XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 19405b261ecSmrg break; 19505b261ecSmrg case DEVICE_OFF: 19605b261ecSmrg xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; 19705b261ecSmrg for (i = 0; i < xnestNumScreens; i++) 19805b261ecSmrg XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 19905b261ecSmrg break; 20005b261ecSmrg case DEVICE_CLOSE: 20105b261ecSmrg break; 20205b261ecSmrg } 20305b261ecSmrg return Success; 2046747b715Smrg 2056747b715SmrgXkbError: 2066747b715Smrg XGetKeyboardControl(xnestDisplay, &values); 2076747b715Smrg memmove((char *)defaultKeyboardControl.autoRepeats, 2086747b715Smrg (char *)values.auto_repeats, 2096747b715Smrg sizeof(values.auto_repeats)); 2106747b715Smrg 2116747b715Smrg InitKeyboardDeviceStruct(pDev, NULL, 2126747b715Smrg xnestBell, xnestChangeKeyboardControl); 2136747b715Smrg free(keymap); 2146747b715Smrg return Success; 21505b261ecSmrg} 21605b261ecSmrg 21705b261ecSmrgBool 21805b261ecSmrgLegalModifier(unsigned int key, DeviceIntPtr pDev) 21905b261ecSmrg{ 22005b261ecSmrg return TRUE; 22105b261ecSmrg} 22205b261ecSmrg 22305b261ecSmrgvoid 22405b261ecSmrgxnestUpdateModifierState(unsigned int state) 22505b261ecSmrg{ 22605b261ecSmrg DeviceIntPtr pDev = xnestKeyboardDevice; 22705b261ecSmrg KeyClassPtr keyc = pDev->key; 22805b261ecSmrg int i; 22905b261ecSmrg CARD8 mask; 2306747b715Smrg int xkb_state; 2316747b715Smrg 2326747b715Smrg if (!pDev) 2336747b715Smrg return; 23405b261ecSmrg 2356747b715Smrg xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 23605b261ecSmrg state = state & 0xff; 23705b261ecSmrg 2386747b715Smrg if (xkb_state == state) 23905b261ecSmrg return; 24005b261ecSmrg 24105b261ecSmrg for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 24205b261ecSmrg int key; 24305b261ecSmrg 24405b261ecSmrg /* Modifier is down, but shouldn't be 24505b261ecSmrg */ 2466747b715Smrg if ((xkb_state & mask) && !(state & mask)) { 24705b261ecSmrg int count = keyc->modifierKeyCount[i]; 24805b261ecSmrg 24905b261ecSmrg for (key = 0; key < MAP_LENGTH; key++) 2506747b715Smrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 2516747b715Smrg if (key_is_down(pDev, key, KEY_PROCESSED)) 25205b261ecSmrg xnestQueueKeyEvent(KeyRelease, key); 25305b261ecSmrg 25405b261ecSmrg if (--count == 0) 25505b261ecSmrg break; 25605b261ecSmrg } 25705b261ecSmrg } 25805b261ecSmrg 25905b261ecSmrg /* Modifier shoud be down, but isn't 26005b261ecSmrg */ 2616747b715Smrg if (!(xkb_state & mask) && (state & mask)) 26205b261ecSmrg for (key = 0; key < MAP_LENGTH; key++) 2636747b715Smrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 26405b261ecSmrg xnestQueueKeyEvent(KeyPress, key); 26505b261ecSmrg break; 26605b261ecSmrg } 26705b261ecSmrg } 26805b261ecSmrg} 269