Keyboard.c revision 6747b715
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#include <X11/X.h> 20#include <X11/Xproto.h> 21#include <X11/keysym.h> 22#include "screenint.h" 23#include "inputstr.h" 24#include "misc.h" 25#include "scrnintstr.h" 26#include "servermd.h" 27 28#include "Xnest.h" 29 30#include "Display.h" 31#include "Screen.h" 32#include "Keyboard.h" 33#include "Args.h" 34#include "Events.h" 35 36#include <X11/extensions/XKB.h> 37#include "xkbsrv.h" 38#include <X11/extensions/XKBconfig.h> 39 40extern Bool 41XkbQueryExtension( 42 Display * /* dpy */, 43 int * /* opcodeReturn */, 44 int * /* eventBaseReturn */, 45 int * /* errorBaseReturn */, 46 int * /* majorRtrn */, 47 int * /* minorRtrn */ 48); 49 50extern XkbDescPtr XkbGetKeyboard( 51 Display * /* dpy */, 52 unsigned int /* which */, 53 unsigned int /* deviceSpec */ 54); 55 56extern Status XkbGetControls( 57 Display * /* dpy */, 58 unsigned long /* which */, 59 XkbDescPtr /* desc */ 60); 61 62DeviceIntPtr xnestKeyboardDevice = NULL; 63 64void 65xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls) 66{ 67 XBell(xnestDisplay, volume); 68} 69 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 KeySym *keymap; 118 int mapWidth; 119 int min_keycode, max_keycode; 120 KeySymsRec keySyms; 121 int i; 122 XKeyboardState values; 123 XkbDescPtr xkb; 124 int op, event, error, major, minor; 125 126 switch (onoff) 127 { 128 case DEVICE_INIT: 129 XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode); 130#ifdef _XSERVER64 131 { 132 KeySym64 *keymap64; 133 int i, len; 134 keymap64 = XGetKeyboardMapping(xnestDisplay, 135 min_keycode, 136 max_keycode - min_keycode + 1, 137 &mapWidth); 138 len = (max_keycode - min_keycode + 1) * mapWidth; 139 keymap = (KeySym *)malloc(len * sizeof(KeySym)); 140 for(i = 0; i < len; ++i) 141 keymap[i] = keymap64[i]; 142 XFree(keymap64); 143 } 144#else 145 keymap = XGetKeyboardMapping(xnestDisplay, 146 min_keycode, 147 max_keycode - min_keycode + 1, 148 &mapWidth); 149#endif 150 151 keySyms.minKeyCode = min_keycode; 152 keySyms.maxKeyCode = max_keycode; 153 keySyms.mapWidth = mapWidth; 154 keySyms.map = keymap; 155 156 if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) { 157 ErrorF("Unable to initialize XKEYBOARD extension.\n"); 158 goto XkbError; 159 } 160 xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd); 161 if (xkb == NULL || xkb->geom == NULL) { 162 ErrorF("Couldn't get keyboard.\n"); 163 goto XkbError; 164 } 165 XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb); 166 167 InitKeyboardDeviceStruct(pDev, NULL, 168 xnestBell, xnestChangeKeyboardControl); 169 XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls); 170 XkbFreeKeyboard(xkb, 0, False); 171 free(keymap); 172 break; 173 case DEVICE_ON: 174 xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK; 175 for (i = 0; i < xnestNumScreens; i++) 176 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 177 break; 178 case DEVICE_OFF: 179 xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK; 180 for (i = 0; i < xnestNumScreens; i++) 181 XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask); 182 break; 183 case DEVICE_CLOSE: 184 break; 185 } 186 return Success; 187 188XkbError: 189 XGetKeyboardControl(xnestDisplay, &values); 190 memmove((char *)defaultKeyboardControl.autoRepeats, 191 (char *)values.auto_repeats, 192 sizeof(values.auto_repeats)); 193 194 InitKeyboardDeviceStruct(pDev, NULL, 195 xnestBell, xnestChangeKeyboardControl); 196 free(keymap); 197 return Success; 198} 199 200Bool 201LegalModifier(unsigned int key, DeviceIntPtr pDev) 202{ 203 return TRUE; 204} 205 206void 207xnestUpdateModifierState(unsigned int state) 208{ 209 DeviceIntPtr pDev = xnestKeyboardDevice; 210 KeyClassPtr keyc = pDev->key; 211 int i; 212 CARD8 mask; 213 int xkb_state; 214 215 if (!pDev) 216 return; 217 218 xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); 219 state = state & 0xff; 220 221 if (xkb_state == state) 222 return; 223 224 for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { 225 int key; 226 227 /* Modifier is down, but shouldn't be 228 */ 229 if ((xkb_state & mask) && !(state & mask)) { 230 int count = keyc->modifierKeyCount[i]; 231 232 for (key = 0; key < MAP_LENGTH; key++) 233 if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 234 if (key_is_down(pDev, key, KEY_PROCESSED)) 235 xnestQueueKeyEvent(KeyRelease, key); 236 237 if (--count == 0) 238 break; 239 } 240 } 241 242 /* Modifier shoud be down, but isn't 243 */ 244 if (!(xkb_state & mask) && (state & mask)) 245 for (key = 0; key < MAP_LENGTH; key++) 246 if (keyc->xkbInfo->desc->map->modmap[key] & mask) { 247 xnestQueueKeyEvent(KeyPress, key); 248 break; 249 } 250 } 251} 252