1706f2543Smrg/* 2706f2543Smrg 3706f2543SmrgCopyright 1993 by Davor Matic 4706f2543Smrg 5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software 6706f2543Smrgand its documentation for any purpose is hereby granted without fee, 7706f2543Smrgprovided that the above copyright notice appear in all copies and that 8706f2543Smrgboth that copyright notice and this permission notice appear in 9706f2543Smrgsupporting documentation. Davor Matic makes no representations about 10706f2543Smrgthe suitability of this software for any purpose. It is provided "as 11706f2543Smrgis" without express or implied warranty. 12706f2543Smrg 13706f2543Smrg*/ 14706f2543Smrg 15706f2543Smrg#ifdef HAVE_XNEST_CONFIG_H 16706f2543Smrg#include <xnest-config.h> 17706f2543Smrg#endif 18706f2543Smrg 19706f2543Smrg#include <X11/X.h> 20706f2543Smrg#include <X11/Xproto.h> 21706f2543Smrg#include <X11/keysym.h> 22706f2543Smrg#include "screenint.h" 23706f2543Smrg#include "inputstr.h" 24706f2543Smrg#include "misc.h" 25706f2543Smrg#include "scrnintstr.h" 26706f2543Smrg#include "servermd.h" 27706f2543Smrg 28706f2543Smrg#include "Xnest.h" 29706f2543Smrg 30706f2543Smrg#include "Display.h" 31706f2543Smrg#include "Screen.h" 32706f2543Smrg#include "Keyboard.h" 33706f2543Smrg#include "Args.h" 34706f2543Smrg#include "Events.h" 35706f2543Smrg 36706f2543Smrg#include <X11/extensions/XKB.h> 37706f2543Smrg#include "xkbsrv.h" 38706f2543Smrg#include <X11/extensions/XKBconfig.h> 39706f2543Smrg 40706f2543Smrgextern Bool 41706f2543SmrgXkbQueryExtension( 42706f2543Smrg Display * /* dpy */, 43706f2543Smrg int * /* opcodeReturn */, 44706f2543Smrg int * /* eventBaseReturn */, 45706f2543Smrg int * /* errorBaseReturn */, 46706f2543Smrg int * /* majorRtrn */, 47706f2543Smrg int * /* minorRtrn */ 48706f2543Smrg); 49706f2543Smrg 50706f2543Smrgextern XkbDescPtr XkbGetKeyboard( 51706f2543Smrg Display * /* dpy */, 52706f2543Smrg unsigned int /* which */, 53706f2543Smrg unsigned int /* deviceSpec */ 54706f2543Smrg); 55706f2543Smrg 56706f2543Smrgextern Status XkbGetControls( 57706f2543Smrg Display * /* dpy */, 58706f2543Smrg unsigned long /* which */, 59706f2543Smrg XkbDescPtr /* desc */ 60706f2543Smrg); 61706f2543Smrg 62706f2543SmrgDeviceIntPtr xnestKeyboardDevice = NULL; 63706f2543Smrg 64706f2543Smrgvoid 65706f2543SmrgxnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls) 66706f2543Smrg{ 67706f2543Smrg XBell(xnestDisplay, volume); 68706f2543Smrg} 69706f2543Smrg 70706f2543Smrgvoid 71706f2543SmrgDDXRingBell(int volume, int pitch, int duration) 72706f2543Smrg{ 73706f2543Smrg XBell(xnestDisplay, volume); 74706f2543Smrg} 75706f2543Smrg 76706f2543Smrgvoid 77706f2543SmrgxnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl) 78706f2543Smrg{ 79706f2543Smrg#if 0 80706f2543Smrg unsigned long value_mask; 81706f2543Smrg XKeyboardControl values; 82706f2543Smrg int i; 83706f2543Smrg 84706f2543Smrg value_mask = KBKeyClickPercent | 85706f2543Smrg KBBellPercent | 86706f2543Smrg KBBellPitch | 87706f2543Smrg KBBellDuration | 88706f2543Smrg KBAutoRepeatMode; 89706f2543Smrg 90706f2543Smrg values.key_click_percent = ctrl->click; 91706f2543Smrg values.bell_percent = ctrl->bell; 92706f2543Smrg values.bell_pitch = ctrl->bell_pitch; 93706f2543Smrg values.bell_duration = ctrl->bell_duration; 94706f2543Smrg values.auto_repeat_mode = ctrl->autoRepeat ? 95706f2543Smrg AutoRepeatModeOn : AutoRepeatModeOff; 96706f2543Smrg 97706f2543Smrg XChangeKeyboardControl(xnestDisplay, value_mask, &values); 98706f2543Smrg 99706f2543Smrg /* 100706f2543Smrg value_mask = KBKey | KBAutoRepeatMode; 101706f2543Smrg At this point, we need to walk through the vector and compare it 102706f2543Smrg to the current server vector. If there are differences, report them. 103706f2543Smrg */ 104706f2543Smrg 105706f2543Smrg value_mask = KBLed | KBLedMode; 106706f2543Smrg for (i = 1; i <= 32; i++) { 107706f2543Smrg values.led = i; 108706f2543Smrg values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff; 109706f2543Smrg XChangeKeyboardControl(xnestDisplay, value_mask, &values); 110706f2543Smrg } 111706f2543Smrg#endif 112706f2543Smrg} 113706f2543Smrg 114706f2543Smrgint 115706f2543SmrgxnestKeyboardProc(DeviceIntPtr pDev, int onoff) 116706f2543Smrg{ 117706f2543Smrg XModifierKeymap *modifier_keymap; 118706f2543Smrg KeySym *keymap; 119706f2543Smrg int mapWidth; 120706f2543Smrg int min_keycode, max_keycode; 121706f2543Smrg KeySymsRec keySyms; 122706f2543Smrg CARD8 modmap[MAP_LENGTH]; 123706f2543Smrg int i, j; 124706f2543Smrg XKeyboardState values; 125706f2543Smrg XkbDescPtr xkb; 126706f2543Smrg int op, event, error, major, minor; 127706f2543Smrg 128706f2543Smrg switch (onoff) 129706f2543Smrg { 130706f2543Smrg case DEVICE_INIT: 131706f2543Smrg XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); 132706f2543Smrg#ifdef _XSERVER64 133706f2543Smrg { 134706f2543Smrg KeySym64 *keymap64; 135706f2543Smrg int len; 136706f2543Smrg keymap64 = XGetKeyboardMapping(xnestDisplay, 137706f2543Smrg min_keycode, 138706f2543Smrg max_keycode - min_keycode + 1, 139706f2543Smrg &mapWidth); 140706f2543Smrg len = (max_keycode - min_keycode + 1) * mapWidth; 141706f2543Smrg keymap = (KeySym *)malloc(len * sizeof(KeySym)); 142706f2543Smrg for(i = 0; i < len; ++i) 143706f2543Smrg keymap[i] = keymap64[i]; 144706f2543Smrg XFree(keymap64); 145706f2543Smrg } 146706f2543Smrg#else 147706f2543Smrg keymap = XGetKeyboardMapping(xnestDisplay, 148706f2543Smrg min_keycode, 149706f2543Smrg max_keycode - min_keycode + 1, 150706f2543Smrg &mapWidth); 151706f2543Smrg#endif 152706f2543Smrg 153706f2543Smrg memset(modmap, 0, sizeof(modmap)); 154706f2543Smrg modifier_keymap = XGetModifierMapping(xnestDisplay); 155706f2543Smrg for (j = 0; j < 8; j++) 156706f2543Smrg for(i = 0; i < modifier_keymap->max_keypermod; i++) { 157706f2543Smrg CARD8 keycode; 158706f2543Smrg if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i])) 159706f2543Smrg modmap[keycode] |= 1<<j; 160706f2543Smrg } 161706f2543Smrg XFreeModifiermap(modifier_keymap); 162706f2543Smrg 163706f2543Smrg keySyms.minKeyCode = min_keycode; 164706f2543Smrg keySyms.maxKeyCode = max_keycode; 165706f2543Smrg keySyms.mapWidth = mapWidth; 166706f2543Smrg keySyms.map = keymap; 167706f2543Smrg 168706f2543Smrg if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { 169706f2543Smrg ErrorF("Unable to initialize XKEYBOARD extension.\n"); 170706f2543Smrg goto XkbError; 171706f2543Smrg } 172706f2543Smrg xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); 173706f2543Smrg if (xkb == NULL || xkb->geom == NULL) { 174706f2543Smrg ErrorF("Couldn't get keyboard.\n"); 175706f2543Smrg goto XkbError; 176706f2543Smrg } 177706f2543Smrg XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); 178706f2543Smrg 179706f2543Smrg InitKeyboardDeviceStruct(pDev, NULL, 180706f2543Smrg xnestBell, xnestChangeKeyboardControl); 181706f2543Smrg 182706f2543Smrg XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode, 183706f2543Smrg keySyms.maxKeyCode - keySyms.minKeyCode + 1, 184706f2543Smrg modmap, serverClient); 185706f2543Smrg 186706f2543Smrg XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); 187706f2543Smrg XkbFreeKeyboard(xkb, 0, False); 188706f2543Smrg free(keymap); 189706f2543Smrg break; 190706f2543Smrg case DEVICE_ON: 191706f2543Smrg xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; 192706f2543Smrg for (i = 0; i < xnestNumScreens; i++) 193706f2543Smrg XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 194706f2543Smrg break; 195706f2543Smrg case DEVICE_OFF: 196706f2543Smrg xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; 197706f2543Smrg for (i = 0; i < xnestNumScreens; i++) 198706f2543Smrg XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 199706f2543Smrg break; 200706f2543Smrg case DEVICE_CLOSE: 201706f2543Smrg break; 202706f2543Smrg } 203706f2543Smrg return Success; 204706f2543Smrg 205706f2543SmrgXkbError: 206706f2543Smrg XGetKeyboardControl(xnestDisplay, &values); 207706f2543Smrg memmove((char *)defaultKeyboardControl.autoRepeats, 208706f2543Smrg (char *)values.auto_repeats, 209706f2543Smrg sizeof(values.auto_repeats)); 210706f2543Smrg 211706f2543Smrg InitKeyboardDeviceStruct(pDev, NULL, 212706f2543Smrg xnestBell, xnestChangeKeyboardControl); 213706f2543Smrg free(keymap); 214706f2543Smrg return Success; 215706f2543Smrg} 216706f2543Smrg 217706f2543SmrgBool 218706f2543SmrgLegalModifier(unsigned int key, DeviceIntPtr pDev) 219706f2543Smrg{ 220706f2543Smrg return TRUE; 221706f2543Smrg} 222706f2543Smrg 223706f2543Smrgvoid 224706f2543SmrgxnestUpdateModifierState(unsigned int state) 225706f2543Smrg{ 226706f2543Smrg DeviceIntPtr pDev = xnestKeyboardDevice; 227706f2543Smrg KeyClassPtr keyc = pDev->key; 228706f2543Smrg int i; 229706f2543Smrg CARD8 mask; 230706f2543Smrg int xkb_state; 231706f2543Smrg 232706f2543Smrg if (!pDev) 233706f2543Smrg return; 234706f2543Smrg 235706f2543Smrg xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 236706f2543Smrg state = state & 0xff; 237706f2543Smrg 238706f2543Smrg if (xkb_state == state) 239706f2543Smrg return; 240706f2543Smrg 241706f2543Smrg for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 242706f2543Smrg int key; 243706f2543Smrg 244706f2543Smrg /* Modifier is down, but shouldn't be 245706f2543Smrg */ 246706f2543Smrg if ((xkb_state & mask) && !(state & mask)) { 247706f2543Smrg int count = keyc->modifierKeyCount[i]; 248706f2543Smrg 249706f2543Smrg for (key = 0; key < MAP_LENGTH; key++) 250706f2543Smrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 251706f2543Smrg if (key_is_down(pDev, key, KEY_PROCESSED)) 252706f2543Smrg xnestQueueKeyEvent(KeyRelease, key); 253706f2543Smrg 254706f2543Smrg if (--count == 0) 255706f2543Smrg break; 256706f2543Smrg } 257706f2543Smrg } 258706f2543Smrg 259706f2543Smrg /* Modifier shoud be down, but isn't 260706f2543Smrg */ 261706f2543Smrg if (!(xkb_state & mask) && (state & mask)) 262706f2543Smrg for (key = 0; key < MAP_LENGTH; key++) 263706f2543Smrg if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 264706f2543Smrg xnestQueueKeyEvent(KeyPress, key); 265706f2543Smrg break; 266706f2543Smrg } 267706f2543Smrg } 268706f2543Smrg} 269