Keyboard.c revision 6747b715
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{ 11705b261ecSmrg KeySym *keymap; 11805b261ecSmrg int mapWidth; 11905b261ecSmrg int min_keycode, max_keycode; 12005b261ecSmrg KeySymsRec keySyms; 1216747b715Smrg int i; 12205b261ecSmrg XKeyboardState values; 1236747b715Smrg XkbDescPtr xkb; 1246747b715Smrg int op, event, error, major, minor; 12505b261ecSmrg 12605b261ecSmrg switch (onoff) 12705b261ecSmrg { 12805b261ecSmrg case DEVICE_INIT: 12905b261ecSmrg XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); 13005b261ecSmrg#ifdef _XSERVER64 13105b261ecSmrg { 13205b261ecSmrg KeySym64 *keymap64; 13305b261ecSmrg int i, len; 13405b261ecSmrg keymap64 = XGetKeyboardMapping(xnestDisplay, 13505b261ecSmrg min_keycode, 13605b261ecSmrg max_keycode - min_keycode + 1, 13705b261ecSmrg &mapWidth); 13805b261ecSmrg len = (max_keycode - min_keycode + 1) * mapWidth; 1396747b715Smrg keymap = (KeySym *)malloc(len * sizeof(KeySym)); 14005b261ecSmrg for(i = 0; i < len; ++i) 14105b261ecSmrg keymap[i] = keymap64[i]; 14205b261ecSmrg XFree(keymap64); 14305b261ecSmrg } 14405b261ecSmrg#else 14505b261ecSmrg keymap = XGetKeyboardMapping(xnestDisplay, 14605b261ecSmrg min_keycode, 14705b261ecSmrg max_keycode - min_keycode + 1, 14805b261ecSmrg &mapWidth); 14905b261ecSmrg#endif 15005b261ecSmrg 15105b261ecSmrg keySyms.minKeyCode = min_keycode; 15205b261ecSmrg keySyms.maxKeyCode = max_keycode; 15305b261ecSmrg keySyms.mapWidth = mapWidth; 15405b261ecSmrg keySyms.map = keymap; 15505b261ecSmrg 1566747b715Smrg if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { 1576747b715Smrg ErrorF("Unable to initialize XKEYBOARD extension.\n"); 15805b261ecSmrg goto XkbError; 1596747b715Smrg } 1606747b715Smrg xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); 1616747b715Smrg if (xkb == NULL || xkb->geom == NULL) { 16205b261ecSmrg ErrorF("Couldn't get keyboard.\n"); 1636747b715Smrg goto XkbError; 16405b261ecSmrg } 1656747b715Smrg XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); 1666747b715Smrg 1676747b715Smrg InitKeyboardDeviceStruct(pDev, NULL, 1686747b715Smrg xnestBell, xnestChangeKeyboardControl); 1696747b715Smrg XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); 1706747b715Smrg XkbFreeKeyboard(xkb, 0, False); 1716747b715Smrg free(keymap); 17205b261ecSmrg break; 17305b261ecSmrg case DEVICE_ON: 17405b261ecSmrg xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; 17505b261ecSmrg for (i = 0; i < xnestNumScreens; i++) 17605b261ecSmrg XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 17705b261ecSmrg break; 17805b261ecSmrg case DEVICE_OFF: 17905b261ecSmrg xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; 18005b261ecSmrg for (i = 0; i < xnestNumScreens; i++) 18105b261ecSmrg XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 18205b261ecSmrg break; 18305b261ecSmrg case DEVICE_CLOSE: 18405b261ecSmrg break; 18505b261ecSmrg } 18605b261ecSmrg return Success; 1876747b715Smrg 1886747b715SmrgXkbError: 1896747b715Smrg XGetKeyboardControl(xnestDisplay, &values); 1906747b715Smrg memmove((char *)defaultKeyboardControl.autoRepeats, 1916747b715Smrg (char *)values.auto_repeats, 1926747b715Smrg sizeof(values.auto_repeats)); 1936747b715Smrg 1946747b715Smrg InitKeyboardDeviceStruct(pDev, NULL, 1956747b715Smrg xnestBell, xnestChangeKeyboardControl); 1966747b715Smrg free(keymap); 1976747b715Smrg return Success; 19805b261ecSmrg} 19905b261ecSmrg 20005b261ecSmrgBool 20105b261ecSmrgLegalModifier(unsigned int key, DeviceIntPtr pDev) 20205b261ecSmrg{ 20305b261ecSmrg return TRUE; 20405b261ecSmrg} 20505b261ecSmrg 20605b261ecSmrgvoid 20705b261ecSmrgxnestUpdateModifierState(unsigned int state) 20805b261ecSmrg{ 20905b261ecSmrg DeviceIntPtr pDev = xnestKeyboardDevice; 21005b261ecSmrg KeyClassPtr keyc = pDev->key; 21105b261ecSmrg int i; 21205b261ecSmrg CARD8 mask; 2136747b715Smrg int xkb_state; 2146747b715Smrg 2156747b715Smrg if (!pDev) 2166747b715Smrg return; 21705b261ecSmrg 2186747b715Smrg xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 21905b261ecSmrg state = state & 0xff; 22005b261ecSmrg 2216747b715Smrg if (xkb_state == state) 22205b261ecSmrg return; 22305b261ecSmrg 22405b261ecSmrg for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 22505b261ecSmrg int key; 22605b261ecSmrg 22705b261ecSmrg /* Modifier is down, but shouldn't be 22805b261ecSmrg */ 2296747b715Smrg if ((xkb_state & mask) && !(state & mask)) { 23005b261ecSmrg int count = keyc->modifierKeyCount[i]; 23105b261ecSmrg 23205b261ecSmrg for (key = 0; key < MAP_LENGTH; key++) 2336747b715Smrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 2346747b715Smrg if (key_is_down(pDev, key, KEY_PROCESSED)) 23505b261ecSmrg xnestQueueKeyEvent(KeyRelease, key); 23605b261ecSmrg 23705b261ecSmrg if (--count == 0) 23805b261ecSmrg break; 23905b261ecSmrg } 24005b261ecSmrg } 24105b261ecSmrg 24205b261ecSmrg /* Modifier shoud be down, but isn't 24305b261ecSmrg */ 2446747b715Smrg if (!(xkb_state & mask) && (state & mask)) 24505b261ecSmrg for (key = 0; key < MAP_LENGTH; key++) 2466747b715Smrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 24705b261ecSmrg xnestQueueKeyEvent(KeyPress, key); 24805b261ecSmrg break; 24905b261ecSmrg } 25005b261ecSmrg } 25105b261ecSmrg} 252