Keyboard.c revision 35c4bbdf
1/* 2 3Copyright 1993 by Davor Matic 4 5Permission to use, copy, modify, distribute, and sell this software 6and its documentation for any purpose is hereby granted without fee, 7provided that the above copyright notice appear in all copies and that 8both that copyright notice and this permission notice appear in 9supporting documentation. Davor Matic makes no representations about 10the suitability of this software for any purpose. It is provided "as 11is" 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 44extern Bool 45 XkbQueryExtension(Display * /* dpy */ , 46 int * /* opcodeReturn */ , 47 int * /* eventBaseReturn */ , 48 int * /* errorBaseReturn */ , 49 int * /* majorRtrn */ , 50 int * /* minorRtrn */ 51 ); 52 53extern XkbDescPtr XkbGetKeyboard(Display * /* dpy */ , 54 unsigned int /* which */ , 55 unsigned int /* deviceSpec */ 56 ); 57 58extern Status XkbGetControls(Display * /* dpy */ , 59 unsigned long /* which */ , 60 XkbDescPtr /* desc */ 61 ); 62 63DeviceIntPtr xnestKeyboardDevice = NULL; 64 65void 66xnestBell(int volume, DeviceIntPtr pDev, void *ctrl, int cls) 67{ 68 XBell(xnestDisplay, volume); 69} 70 71void 72DDXRingBell(int volume, int pitch, int duration) 73{ 74 XBell(xnestDisplay, volume); 75} 76 77void 78xnestChangeKeyboardControl(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 113int 114xnestKeyboardProc(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 220Bool 221LegalModifier(unsigned int key, DeviceIntPtr pDev) 222{ 223 return TRUE; 224} 225 226void 227xnestUpdateModifierState(unsigned int state) 228{ 229 DeviceIntPtr pDev = xnestKeyboardDevice; 230 KeyClassPtr keyc = pDev->key; 231 int i; 232 CARD8 mask; 233 int xkb_state; 234 235 if (!pDev) 236 return; 237 238 xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 239 state = state & 0xff; 240 241 if (xkb_state == state) 242 return; 243 244 for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 245 int key; 246 247 /* Modifier is down, but shouldn't be 248 */ 249 if ((xkb_state & mask) && !(state & mask)) { 250 int count = keyc->modifierKeyCount[i]; 251 252 for (key = 0; key < MAP_LENGTH; key++) 253 if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 254 if (mask == LockMask) { 255 xnestQueueKeyEvent(KeyPress, key); 256 xnestQueueKeyEvent(KeyRelease, key); 257 } 258 else if (key_is_down(pDev, key, KEY_PROCESSED)) 259 xnestQueueKeyEvent(KeyRelease, key); 260 261 if (--count == 0) 262 break; 263 } 264 } 265 266 /* Modifier shoud be down, but isn't 267 */ 268 if (!(xkb_state & mask) && (state & mask)) 269 for (key = 0; key < MAP_LENGTH; key++) 270 if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 271 xnestQueueKeyEvent(KeyPress, key); 272 if (mask == LockMask) 273 xnestQueueKeyEvent(KeyRelease, key); 274 break; 275 } 276 } 277} 278