Keyboard.c revision 4642e01f
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#define NEED_EVENTS 16#ifdef HAVE_XNEST_CONFIG_H 17#include <xnest-config.h> 18#endif 19 20#include <X11/X.h> 21#include <X11/Xproto.h> 22#include <X11/keysym.h> 23#include "screenint.h" 24#include "inputstr.h" 25#include "misc.h" 26#include "scrnintstr.h" 27#include "servermd.h" 28 29#include "Xnest.h" 30 31#include "Display.h" 32#include "Screen.h" 33#include "Keyboard.h" 34#include "Args.h" 35#include "Events.h" 36 37#ifdef XKB 38#include <X11/extensions/XKB.h> 39#include <xkbsrv.h> 40#include <X11/extensions/XKBconfig.h> 41 42extern Bool 43XkbQueryExtension( 44 Display * /* dpy */, 45 int * /* opcodeReturn */, 46 int * /* eventBaseReturn */, 47 int * /* errorBaseReturn */, 48 int * /* majorRtrn */, 49 int * /* minorRtrn */ 50); 51 52extern XkbDescPtr XkbGetKeyboard( 53 Display * /* dpy */, 54 unsigned int /* which */, 55 unsigned int /* deviceSpec */ 56); 57 58extern Status XkbGetControls( 59 Display * /* dpy */, 60 unsigned long /* which */, 61 XkbDescPtr /* desc */ 62); 63 64#ifndef XKB_BASE_DIRECTORY 65#define XKB_BASE_DIRECTORY "/usr/X11R6/lib/X11/xkb/" 66#endif 67#ifndef XKB_CONFIG_FILE 68#define XKB_CONFIG_FILE "X0-config.keyboard" 69#endif 70#ifndef XKB_DFLT_RULES_FILE 71#define XKB_DFLT_RULES_FILE __XKBDEFRULES__ 72#endif 73#ifndef XKB_DFLT_KB_LAYOUT 74#define XKB_DFLT_KB_LAYOUT "us" 75#endif 76#ifndef XKB_DFLT_KB_MODEL 77#define XKB_DFLT_KB_MODEL "pc101" 78#endif 79#ifndef XKB_DFLT_KB_VARIANT 80#define XKB_DFLT_KB_VARIANT NULL 81#endif 82#ifndef XKB_DFLT_KB_OPTIONS 83#define XKB_DFLT_KB_OPTIONS NULL 84#endif 85 86#endif 87 88DeviceIntPtr xnestKeyboardDevice = NULL; 89 90void 91xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls) 92{ 93 XBell(xnestDisplay, volume); 94} 95 96void 97DDXRingBell(int volume, int pitch, int duration) 98{ 99 XBell(xnestDisplay, volume); 100} 101 102void 103xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl) 104{ 105#if 0 106 unsigned long value_mask; 107 XKeyboardControl values; 108 int i; 109 110 value_mask = KBKeyClickPercent | 111 KBBellPercent | 112 KBBellPitch | 113 KBBellDuration | 114 KBAutoRepeatMode; 115 116 values.key_click_percent = ctrl->click; 117 values.bell_percent = ctrl->bell; 118 values.bell_pitch = ctrl->bell_pitch; 119 values.bell_duration = ctrl->bell_duration; 120 values.auto_repeat_mode = ctrl->autoRepeat ? 121 AutoRepeatModeOn : AutoRepeatModeOff; 122 123 XChangeKeyboardControl(xnestDisplay, value_mask, &values); 124 125 /* 126 value_mask = KBKey | KBAutoRepeatMode; 127 At this point, we need to walk through the vector and compare it 128 to the current server vector. If there are differences, report them. 129 */ 130 131 value_mask = KBLed | KBLedMode; 132 for (i = 1; i <= 32; i++) { 133 values.led = i; 134 values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff; 135 XChangeKeyboardControl(xnestDisplay, value_mask, &values); 136 } 137#endif 138} 139 140int 141xnestKeyboardProc(DeviceIntPtr pDev, int onoff) 142{ 143 XModifierKeymap *modifier_keymap; 144 KeySym *keymap; 145 int mapWidth; 146 int min_keycode, max_keycode; 147 KeySymsRec keySyms; 148 CARD8 modmap[MAP_LENGTH]; 149 int i, j; 150 XKeyboardState values; 151 152 switch (onoff) 153 { 154 case DEVICE_INIT: 155 modifier_keymap = XGetModifierMapping(xnestDisplay); 156 XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); 157#ifdef _XSERVER64 158 { 159 KeySym64 *keymap64; 160 int i, len; 161 keymap64 = XGetKeyboardMapping(xnestDisplay, 162 min_keycode, 163 max_keycode - min_keycode + 1, 164 &mapWidth); 165 len = (max_keycode - min_keycode + 1) * mapWidth; 166 keymap = (KeySym *)xalloc(len * sizeof(KeySym)); 167 for(i = 0; i < len; ++i) 168 keymap[i] = keymap64[i]; 169 XFree(keymap64); 170 } 171#else 172 keymap = XGetKeyboardMapping(xnestDisplay, 173 min_keycode, 174 max_keycode - min_keycode + 1, 175 &mapWidth); 176#endif 177 178 for (i = 0; i < MAP_LENGTH; i++) 179 modmap[i] = 0; 180 for (j = 0; j < 8; j++) 181 for(i = 0; i < modifier_keymap->max_keypermod; i++) { 182 CARD8 keycode; 183 if ((keycode = 184 modifier_keymap-> 185 modifiermap[j * modifier_keymap->max_keypermod + i])) 186 modmap[keycode] |= 1<<j; 187 } 188 XFreeModifiermap(modifier_keymap); 189 190 keySyms.minKeyCode = min_keycode; 191 keySyms.maxKeyCode = max_keycode; 192 keySyms.mapWidth = mapWidth; 193 keySyms.map = keymap; 194 195#ifdef XKB 196 if (noXkbExtension) { 197XkbError: 198#endif 199 XGetKeyboardControl(xnestDisplay, &values); 200 201 memmove((char *) defaultKeyboardControl.autoRepeats, 202 (char *) values.auto_repeats, sizeof(values.auto_repeats)); 203 204 InitKeyboardDeviceStruct(&pDev->public, &keySyms, modmap, 205 xnestBell, xnestChangeKeyboardControl); 206#ifdef XKB 207 } else { 208 XkbComponentNamesRec names; 209 char *rules, *model, *layout, *variants, *options; 210 211 XkbDescPtr xkb; 212 int op, event, error, major, minor; 213 214 if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { 215 ErrorF("Unable to initialize XKEYBOARD extension.\n"); 216 goto XkbError; 217 } 218 xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); 219 if (xkb == NULL || xkb->geom == NULL) { 220 ErrorF("Couldn't get keyboard.\n"); 221 goto XkbError; 222 } 223 XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); 224 225 memset(&names, 0, sizeof(XkbComponentNamesRec)); 226 rules = XKB_DFLT_RULES_FILE; 227 model = XKB_DFLT_KB_MODEL; 228 layout = XKB_DFLT_KB_LAYOUT; 229 variants = XKB_DFLT_KB_VARIANT; 230 options = XKB_DFLT_KB_OPTIONS; 231 232 XkbSetRulesDflts(rules, model, layout, variants, options); 233 XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modmap, 234 xnestBell, xnestChangeKeyboardControl); 235 XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); 236 XkbFreeKeyboard(xkb, 0, False); 237 } 238#endif 239 xfree(keymap); 240 break; 241 case DEVICE_ON: 242 xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; 243 for (i = 0; i < xnestNumScreens; i++) 244 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 245 break; 246 case DEVICE_OFF: 247 xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; 248 for (i = 0; i < xnestNumScreens; i++) 249 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 250 break; 251 case DEVICE_CLOSE: 252 break; 253 } 254 return Success; 255} 256 257Bool 258LegalModifier(unsigned int key, DeviceIntPtr pDev) 259{ 260 return TRUE; 261} 262 263void 264xnestUpdateModifierState(unsigned int state) 265{ 266 DeviceIntPtr pDev = xnestKeyboardDevice; 267 KeyClassPtr keyc = pDev->key; 268 int i; 269 CARD8 mask; 270 271 state = state & 0xff; 272 273 if (keyc->state == state) 274 return; 275 276 for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 277 int key; 278 279 /* Modifier is down, but shouldn't be 280 */ 281 if ((keyc->state & mask) && !(state & mask)) { 282 int count = keyc->modifierKeyCount[i]; 283 284 for (key = 0; key < MAP_LENGTH; key++) 285 if (keyc->modifierMap[key] & mask) { 286 int bit; 287 BYTE *kptr; 288 289 kptr = &keyc->down[key >> 3]; 290 bit = 1 << (key & 7); 291 292 if (*kptr & bit) 293 xnestQueueKeyEvent(KeyRelease, key); 294 295 if (--count == 0) 296 break; 297 } 298 } 299 300 /* Modifier shoud be down, but isn't 301 */ 302 if (!(keyc->state & mask) && (state & mask)) 303 for (key = 0; key < MAP_LENGTH; key++) 304 if (keyc->modifierMap[key] & mask) { 305 xnestQueueKeyEvent(KeyPress, key); 306 break; 307 } 308 } 309} 310