Keyboard.c (8171B)
1 /* 2 3 Copyright 1993 by Davor Matic 4 5 Permission to use, copy, modify, distribute, and sell this software 6 and its documentation for any purpose is hereby granted without fee, 7 provided that the above copyright notice appear in all copies and that 8 both that copyright notice and this permission notice appear in 9 supporting documentation. Davor Matic makes no representations about 10 the suitability of this software for any purpose. It is provided "as 11 is" without express or implied warranty. 12 13 */ 14 15 #ifdef HAVE_XNEST_CONFIG_H 16 #include <xnest-config.h> 17 #endif 18 19 #ifdef WIN32 20 #include <X11/Xwindows.h> 21 #endif 22 23 #include <X11/X.h> 24 #include <X11/Xproto.h> 25 #include <X11/keysym.h> 26 #include "screenint.h" 27 #include "inputstr.h" 28 #include "misc.h" 29 #include "scrnintstr.h" 30 #include "servermd.h" 31 32 #include "Xnest.h" 33 34 #include "Display.h" 35 #include "Screen.h" 36 #include "Keyboard.h" 37 #include "Args.h" 38 #include "Events.h" 39 40 #include <X11/extensions/XKB.h> 41 #include "xkbsrv.h" 42 #include <X11/extensions/XKBconfig.h> 43 44 extern Bool 45 XkbQueryExtension(Display * /* dpy */ , 46 int * /* opcodeReturn */ , 47 int * /* eventBaseReturn */ , 48 int * /* errorBaseReturn */ , 49 int * /* majorRtrn */ , 50 int * /* minorRtrn */ 51 ); 52 53 extern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ , 54 unsigned int /* which */ , 55 unsigned int /* deviceSpec */ 56 ); 57 58 extern Status XkbGetControls(Display * /* dpy */ , 59 unsigned long /* which */ , 60 XkbDescPtr /* desc */ 61 ); 62 63 DeviceIntPtr xnestKeyboardDevice = NULL; 64 65 void 66 xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls) 67 { 68 XBell(xnestDisplay, volume); 69 } 70 71 void 72 DDXRingBell(int volume, int pitch, int duration) 73 { 74 XBell(xnestDisplay, volume); 75 } 76 77 void 78 xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl * ctrl) 79 { 80 #if 0 81 unsigned long value_mask; 82 XKeyboardControl values; 83 int i; 84 85 value_mask = KBKeyClickPercent | 86 KBBellPercent | KBBellPitch | KBBellDuration | KBAutoRepeatMode; 87 88 values.key_click_percent = ctrl->click; 89 values.bell_percent = ctrl->bell; 90 values.bell_pitch = ctrl->bell_pitch; 91 values.bell_duration = ctrl->bell_duration; 92 values.auto_repeat_mode = ctrl->autoRepeat ? 93 AutoRepeatModeOn : AutoRepeatModeOff; 94 95 XChangeKeyboardControl(xnestDisplay, value_mask, &values); 96 97 /* 98 value_mask = KBKey | KBAutoRepeatMode; 99 At this point, we need to walk through the vector and compare it 100 to the current server vector. If there are differences, report them. 101 */ 102 103 value_mask = KBLed | KBLedMode; 104 for (i = 1; i <= 32; i++) { 105 values.led = i; 106 values.led_mode = 107 (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff; 108 XChangeKeyboardControl(xnestDisplay, value_mask, &values); 109 } 110 #endif 111 } 112 113 int 114 xnestKeyboardProc(DeviceIntPtr pDev, int onoff) 115 { 116 XModifierKeymap *modifier_keymap; 117 KeySym *keymap; 118 int mapWidth; 119 int min_keycode, max_keycode; 120 KeySymsRec keySyms; 121 CARD8 modmap[MAP_LENGTH]; 122 int i, j; 123 XKeyboardState values; 124 XkbDescPtr xkb; 125 int op, event, error, major, minor; 126 127 switch (onoff) { 128 case DEVICE_INIT: 129 XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); 130 #ifdef _XSERVER64 131 { 132 KeySym64 *keymap64; 133 int len; 134 135 keymap64 = XGetKeyboardMapping(xnestDisplay, 136 min_keycode, 137 max_keycode - min_keycode + 1, 138 &mapWidth); 139 len = (max_keycode - min_keycode + 1) * mapWidth; 140 keymap = xallocarray(len, sizeof(KeySym)); 141 for (i = 0; i < len; ++i) 142 keymap[i] = keymap64[i]; 143 XFree(keymap64); 144 } 145 #else 146 keymap = XGetKeyboardMapping(xnestDisplay, 147 min_keycode, 148 max_keycode - min_keycode + 1, &mapWidth); 149 #endif 150 151 memset(modmap, 0, sizeof(modmap)); 152 modifier_keymap = XGetModifierMapping(xnestDisplay); 153 for (j = 0; j < 8; j++) 154 for (i = 0; i < modifier_keymap->max_keypermod; i++) { 155 CARD8 keycode; 156 157 if ((keycode = 158 modifier_keymap->modifiermap[j * 159 modifier_keymap-> 160 max_keypermod + i])) 161 modmap[keycode] |= 1 << j; 162 } 163 XFreeModifiermap(modifier_keymap); 164 165 keySyms.minKeyCode = min_keycode; 166 keySyms.maxKeyCode = max_keycode; 167 keySyms.mapWidth = mapWidth; 168 keySyms.map = keymap; 169 170 if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) 171 == 0) { 172 ErrorF("Unable to initialize XKEYBOARD extension.\n"); 173 goto XkbError; 174 } 175 xkb = 176 XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, 177 XkbUseCoreKbd); 178 if (xkb == NULL || xkb->geom == NULL) { 179 ErrorF("Couldn't get keyboard.\n"); 180 goto XkbError; 181 } 182 XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); 183 184 InitKeyboardDeviceStruct(pDev, NULL, 185 xnestBell, xnestChangeKeyboardControl); 186 187 XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode, 188 keySyms.maxKeyCode - keySyms.minKeyCode + 1, 189 modmap, serverClient); 190 191 XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); 192 XkbFreeKeyboard(xkb, 0, False); 193 free(keymap); 194 break; 195 case DEVICE_ON: 196 xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; 197 for (i = 0; i < xnestNumScreens; i++) 198 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 199 break; 200 case DEVICE_OFF: 201 xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; 202 for (i = 0; i < xnestNumScreens; i++) 203 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 204 break; 205 case DEVICE_CLOSE: 206 break; 207 } 208 return Success; 209 210 XkbError: 211 XGetKeyboardControl(xnestDisplay, &values); 212 memmove((char *) defaultKeyboardControl.autoRepeats, 213 (char *) values.auto_repeats, sizeof(values.auto_repeats)); 214 215 InitKeyboardDeviceStruct(pDev, NULL, xnestBell, xnestChangeKeyboardControl); 216 free(keymap); 217 return Success; 218 } 219 220 void 221 xnestUpdateModifierState(unsigned int state) 222 { 223 DeviceIntPtr pDev = xnestKeyboardDevice; 224 KeyClassPtr keyc = pDev->key; 225 int i; 226 CARD8 mask; 227 int xkb_state; 228 229 if (!pDev) 230 return; 231 232 xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 233 state = state & 0xff; 234 235 if (xkb_state == state) 236 return; 237 238 for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 239 int key; 240 241 /* Modifier is down, but shouldn't be */ 242 if ((xkb_state & mask) && !(state & mask)) { 243 int count = keyc->modifierKeyCount[i]; 244 245 for (key = 0; key < MAP_LENGTH; key++) 246 if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 247 if (mask == LockMask) { 248 xnestQueueKeyEvent(KeyPress, key); 249 xnestQueueKeyEvent(KeyRelease, key); 250 } 251 else if (key_is_down(pDev, key, KEY_PROCESSED)) 252 xnestQueueKeyEvent(KeyRelease, key); 253 254 if (--count == 0) 255 break; 256 } 257 } 258 259 /* Modifier should be down, but isn't */ 260 if (!(xkb_state & mask) && (state & mask)) 261 for (key = 0; key < MAP_LENGTH; key++) 262 if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 263 xnestQueueKeyEvent(KeyPress, key); 264 if (mask == LockMask) 265 xnestQueueKeyEvent(KeyRelease, key); 266 break; 267 } 268 } 269 }