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 220void 221xnestUpdateModifierState(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} 270