Keyboard.c revision 475c125c
18c9fbc29Smrg/* 28c9fbc29Smrg 38c9fbc29SmrgCopyright 1993 by Davor Matic 48c9fbc29Smrg 58c9fbc29SmrgPermission to use, copy, modify, distribute, and sell this software 68c9fbc29Smrgand its documentation for any purpose is hereby granted without fee, 78c9fbc29Smrgprovided that the above copyright notice appear in all copies and that 88c9fbc29Smrgboth that copyright notice and this permission notice appear in 94cd6a3aeSmrgsupporting documentation. Davor Matic makes no representations about 104cd6a3aeSmrgthe suitability of this software for any purpose. It is provided "as 118c9fbc29Smrgis" without express or implied warranty. 124cd6a3aeSmrg 138c9fbc29Smrg*/ 148c9fbc29Smrg 154cd6a3aeSmrg#ifdef HAVE_XNEST_CONFIG_H 164cd6a3aeSmrg#include <xnest-config.h> 174cd6a3aeSmrg#endif 188c9fbc29Smrg 194cd6a3aeSmrg#include <X11/X.h> 204cd6a3aeSmrg#include <X11/Xproto.h> 214cd6a3aeSmrg#include <X11/keysym.h> 228c9fbc29Smrg#include "screenint.h" 238c9fbc29Smrg#include "inputstr.h" 248c9fbc29Smrg#include "misc.h" 258c9fbc29Smrg#include "scrnintstr.h" 268c9fbc29Smrg#include "servermd.h" 278c9fbc29Smrg 288c9fbc29Smrg#include "Xnest.h" 298c9fbc29Smrg 308c9fbc29Smrg#include "Display.h" 318c9fbc29Smrg#include "Screen.h" 328c9fbc29Smrg#include "Keyboard.h" 338c9fbc29Smrg#include "Args.h" 348c9fbc29Smrg#include "Events.h" 358c9fbc29Smrg 368c9fbc29Smrg#include <X11/extensions/XKB.h> 378c9fbc29Smrg#include "xkbsrv.h" 388c9fbc29Smrg#include <X11/extensions/XKBconfig.h> 398c9fbc29Smrg 408c9fbc29Smrgextern Bool 418c9fbc29SmrgXkbQueryExtension( 428c9fbc29Smrg Display * /* dpy */, 438c9fbc29Smrg int * /* opcodeReturn */, 448c9fbc29Smrg int * /* eventBaseReturn */, 458c9fbc29Smrg int * /* errorBaseReturn */, 468c9fbc29Smrg int * /* majorRtrn */, 478c9fbc29Smrg int * /* minorRtrn */ 488c9fbc29Smrg); 498c9fbc29Smrg 508c9fbc29Smrgextern XkbDescPtr XkbGetKeyboard( 518c9fbc29Smrg Display * /* dpy */, 528c9fbc29Smrg unsigned int /* which */, 538c9fbc29Smrg unsigned int /* deviceSpec */ 548c9fbc29Smrg); 558c9fbc29Smrg 568c9fbc29Smrgextern Status XkbGetControls( 578c9fbc29Smrg Display * /* dpy */, 588c9fbc29Smrg unsigned long /* which */, 598c9fbc29Smrg XkbDescPtr /* desc */ 608c9fbc29Smrg); 618c9fbc29Smrg 628c9fbc29SmrgDeviceIntPtr xnestKeyboardDevice = NULL; 638c9fbc29Smrg 648c9fbc29Smrgvoid 658c9fbc29SmrgxnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls) 668c9fbc29Smrg{ 678c9fbc29Smrg XBell(xnestDisplay, volume); 688c9fbc29Smrg} 698c9fbc29Smrg 70void 71DDXRingBell(int volume, int pitch, int duration) 72{ 73 XBell(xnestDisplay, volume); 74} 75 76void 77xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl) 78{ 79#if 0 80 unsigned long value_mask; 81 XKeyboardControl values; 82 int i; 83 84 value_mask = KBKeyClickPercent | 85 KBBellPercent | 86 KBBellPitch | 87 KBBellDuration | 88 KBAutoRepeatMode; 89 90 values.key_click_percent = ctrl->click; 91 values.bell_percent = ctrl->bell; 92 values.bell_pitch = ctrl->bell_pitch; 93 values.bell_duration = ctrl->bell_duration; 94 values.auto_repeat_mode = ctrl->autoRepeat ? 95 AutoRepeatModeOn : AutoRepeatModeOff; 96 97 XChangeKeyboardControl(xnestDisplay, value_mask, &values); 98 99 /* 100 value_mask = KBKey | KBAutoRepeatMode; 101 At this point, we need to walk through the vector and compare it 102 to the current server vector. If there are differences, report them. 103 */ 104 105 value_mask = KBLed | KBLedMode; 106 for (i = 1; i <= 32; i++) { 107 values.led = i; 108 values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff; 109 XChangeKeyboardControl(xnestDisplay, value_mask, &values); 110 } 111#endif 112} 113 114int 115xnestKeyboardProc(DeviceIntPtr pDev, int onoff) 116{ 117 XModifierKeymap *modifier_keymap; 118 KeySym *keymap; 119 int mapWidth; 120 int min_keycode, max_keycode; 121 KeySymsRec keySyms; 122 CARD8 modmap[MAP_LENGTH]; 123 int i, j; 124 XKeyboardState values; 125 XkbDescPtr xkb; 126 int op, event, error, major, minor; 127 128 switch (onoff) 129 { 130 case DEVICE_INIT: 131 XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); 132#ifdef _XSERVER64 133 { 134 KeySym64 *keymap64; 135 int len; 136 keymap64 = XGetKeyboardMapping(xnestDisplay, 137 min_keycode, 138 max_keycode - min_keycode + 1, 139 &mapWidth); 140 len = (max_keycode - min_keycode + 1) * mapWidth; 141 keymap = (KeySym *)malloc(len * sizeof(KeySym)); 142 for(i = 0; i < len; ++i) 143 keymap[i] = keymap64[i]; 144 XFree(keymap64); 145 } 146#else 147 keymap = XGetKeyboardMapping(xnestDisplay, 148 min_keycode, 149 max_keycode - min_keycode + 1, 150 &mapWidth); 151#endif 152 153 memset(modmap, 0, sizeof(modmap)); 154 modifier_keymap = XGetModifierMapping(xnestDisplay); 155 for (j = 0; j < 8; j++) 156 for(i = 0; i < modifier_keymap->max_keypermod; i++) { 157 CARD8 keycode; 158 if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i])) 159 modmap[keycode] |= 1<<j; 160 } 161 XFreeModifiermap(modifier_keymap); 162 163 keySyms.minKeyCode = min_keycode; 164 keySyms.maxKeyCode = max_keycode; 165 keySyms.mapWidth = mapWidth; 166 keySyms.map = keymap; 167 168 if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { 169 ErrorF("Unable to initialize XKEYBOARD extension.\n"); 170 goto XkbError; 171 } 172 xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); 173 if (xkb == NULL || xkb->geom == NULL) { 174 ErrorF("Couldn't get keyboard.\n"); 175 goto XkbError; 176 } 177 XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); 178 179 InitKeyboardDeviceStruct(pDev, NULL, 180 xnestBell, xnestChangeKeyboardControl); 181 182 XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode, 183 keySyms.maxKeyCode - keySyms.minKeyCode + 1, 184 modmap, serverClient); 185 186 XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); 187 XkbFreeKeyboard(xkb, 0, False); 188 free(keymap); 189 break; 190 case DEVICE_ON: 191 xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; 192 for (i = 0; i < xnestNumScreens; i++) 193 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 194 break; 195 case DEVICE_OFF: 196 xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; 197 for (i = 0; i < xnestNumScreens; i++) 198 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 199 break; 200 case DEVICE_CLOSE: 201 break; 202 } 203 return Success; 204 205XkbError: 206 XGetKeyboardControl(xnestDisplay, &values); 207 memmove((char *)defaultKeyboardControl.autoRepeats, 208 (char *)values.auto_repeats, 209 sizeof(values.auto_repeats)); 210 211 InitKeyboardDeviceStruct(pDev, NULL, 212 xnestBell, xnestChangeKeyboardControl); 213 free(keymap); 214 return Success; 215} 216 217Bool 218LegalModifier(unsigned int key, DeviceIntPtr pDev) 219{ 220 return TRUE; 221} 222 223void 224xnestUpdateModifierState(unsigned int state) 225{ 226 DeviceIntPtr pDev = xnestKeyboardDevice; 227 KeyClassPtr keyc = pDev->key; 228 int i; 229 CARD8 mask; 230 int xkb_state; 231 232 if (!pDev) 233 return; 234 235 xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 236 state = state & 0xff; 237 238 if (xkb_state == state) 239 return; 240 241 for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 242 int key; 243 244 /* Modifier is down, but shouldn't be 245 */ 246 if ((xkb_state & mask) && !(state & mask)) { 247 int count = keyc->modifierKeyCount[i]; 248 249 for (key = 0; key < MAP_LENGTH; key++) 250 if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 251 if (key_is_down(pDev, key, KEY_PROCESSED)) 252 xnestQueueKeyEvent(KeyRelease, key); 253 254 if (--count == 0) 255 break; 256 } 257 } 258 259 /* Modifier shoud be down, but isn't 260 */ 261 if (!(xkb_state & mask) && (state & mask)) 262 for (key = 0; key < MAP_LENGTH; key++) 263 if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 264 xnestQueueKeyEvent(KeyPress, key); 265 break; 266 } 267 } 268} 269