|
|
1.1 ! root 1: #include "copyright.h" ! 2: ! 3: /* $Header: XKeyBind.c,v 11.35 87/09/08 20:17:55 toddb Exp $ */ ! 4: /* Copyright 1985, 1987, Massachusetts Institute of Technology */ ! 5: ! 6: /* Beware, here be monsters (still under construction... - JG */ ! 7: ! 8: #define NEED_EVENTS ! 9: #include "Xlib.h" ! 10: #include "Xlibint.h" ! 11: #include "Xutil.h" ! 12: #include "keysym.h" ! 13: #include <stdio.h> ! 14: ! 15: #define HAS_CTRL(c) ((c) >= '@' && (c) <= '\177') ! 16: ! 17: struct XKeytrans { ! 18: struct XKeytrans *next;/* next on list */ ! 19: char *string; /* string to return when the time comes */ ! 20: int len; /* length of string (since NULL is legit)*/ ! 21: KeySym key; /* keysym rebound */ ! 22: unsigned int state; /* modifier state */ ! 23: KeySym *modifiers; /* modifier keysyms you want */ ! 24: int mlen; /* length of modifier list */ ! 25: }; ! 26: ! 27: static struct XKeytrans *trans = NULL; ! 28: ! 29: static KeySym KeyCodetoKeySym(dpy, keycode, col) ! 30: register Display *dpy; ! 31: int keycode; ! 32: int col; ! 33: { ! 34: int ind; ! 35: /* ! 36: * if keycode not defined in set, this should really be impossible. ! 37: * in any case, if sanity check fails, return NoSymbol. ! 38: */ ! 39: if (col < 0 || col > dpy->keysyms_per_keycode) return (NoSymbol); ! 40: if (keycode < dpy->min_keycode || keycode > dpy->max_keycode) ! 41: return(NoSymbol); ! 42: ! 43: ind = (keycode - dpy->min_keycode) * dpy->keysyms_per_keycode + col; ! 44: return (dpy->keysyms[ind]); ! 45: } ! 46: ! 47: KeySym XKeycodeToKeysym(dpy, kc, col) ! 48: Display *dpy; ! 49: KeyCode kc; ! 50: int col; ! 51: { ! 52: if (dpy->keysyms == NULL) ! 53: Initialize(dpy); ! 54: return (KeyCodetoKeySym(dpy, kc, col)); ! 55: } ! 56: ! 57: KeyCode XKeysymToKeycode(dpy, ks) ! 58: Display *dpy; ! 59: KeySym ks; ! 60: { ! 61: int i; ! 62: ! 63: if (dpy->keysyms == NULL) ! 64: Initialize(dpy); ! 65: for (i = dpy->min_keycode; i <= dpy->max_keycode; i++) { ! 66: int j; ! 67: ! 68: for (j = 0; j < dpy->keysyms_per_keycode; j++) { ! 69: int ind = (i - dpy->min_keycode) * dpy->keysyms_per_keycode + j; ! 70: ! 71: if (ks == dpy->keysyms[ind]) ! 72: return (i); ! 73: } ! 74: } ! 75: return (0); ! 76: } ! 77: ! 78: KeySym XLookupKeysym(event, col) ! 79: register XKeyEvent *event; ! 80: int col; ! 81: { ! 82: if (event->display->keysyms == NULL) ! 83: Initialize(event->display); ! 84: return (XKeycodeToKeysym(event->display, event->keycode, col)); ! 85: } ! 86: ! 87: XRefreshKeyboardMapping(event) ! 88: register XMappingEvent *event; ! 89: { ! 90: LockDisplay(event->display); ! 91: /* XXX should really only refresh what is necessary, for now, make ! 92: initialize test fail */ ! 93: if(event->request == MappingKeyboard) ! 94: if (event->display->keysyms != NULL) { ! 95: Xfree ((char *)event->display->keysyms); ! 96: event->display->keysyms = NULL; ! 97: } ! 98: if(event->request == MappingModifier) { ! 99: XFreeModifiermap(event->display->modifiermap); ! 100: event->display->keysyms = NULL;/* XXX - looks like astorage leak */ ! 101: } ! 102: UnlockDisplay(event->display); ! 103: } ! 104: static InitTranslationList() ! 105: { ! 106: /* not yet implemented */ ! 107: /* should read keymap file and initialize list */ ! 108: } ! 109: ! 110: /*ARGSUSED*/ ! 111: int XUseKeymap(filename) ! 112: char *filename; ! 113: { ! 114: /* not yet implemented */ ! 115: } ! 116: ! 117: /* XXX not sure locking is race free here */ ! 118: static Initialize(dpy) ! 119: Display *dpy; ! 120: { ! 121: register KeySym *bd; ! 122: int nbd; ! 123: ! 124: if (trans == NULL) InitTranslationList(); ! 125: /* ! 126: * lets go get the keysyms from the server. ! 127: */ ! 128: if (dpy->keysyms == NULL) { ! 129: dpy->keysyms = XGetKeyboardMapping (dpy, dpy->min_keycode, ! 130: dpy->max_keycode - dpy->min_keycode + 1, &dpy->keysyms_per_keycode); ! 131: LockDisplay(dpy); ! 132: nbd = (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode; ! 133: for (bd = dpy->keysyms; bd < (dpy->keysyms + nbd); bd += 2) { ! 134: if ((*(bd + 1) == NoSymbol) && (*bd >= XK_A) && (*bd <= XK_Z)) { ! 135: *(bd + 1) = *bd; ! 136: *bd += 0x20; ! 137: } ! 138: } ! 139: UnlockDisplay(dpy); ! 140: } ! 141: if (dpy->modifiermap == NULL) { ! 142: dpy->modifiermap = XGetModifierMapping(dpy); ! 143: } ! 144: } ! 145: ! 146: static int KeySymRebound(event, buf, symbol) ! 147: XKeyEvent *event; ! 148: char *buf; ! 149: KeySym symbol; ! 150: { ! 151: register struct XKeytrans *p; ! 152: ! 153: p = trans; ! 154: while (p != NULL) { ! 155: if (MatchEvent(event, symbol, p)) { ! 156: bcopy (p->string, buf, p->len); ! 157: return p->len; ! 158: } ! 159: p = p->next; ! 160: } ! 161: return -1; ! 162: } ! 163: ! 164: Bool MatchEvent(event, symbol, p) ! 165: XKeyEvent *event; ! 166: KeySym symbol; ! 167: register struct XKeytrans *p; ! 168: { ! 169: if ((event->state == p->state) && (symbol == p->key)) return True; ! 170: return False; ! 171: } ! 172: ! 173: int XLookupString (event, buffer, nbytes, keysym, status) ! 174: XKeyEvent *event; ! 175: char *buffer; /* buffer */ ! 176: int nbytes; /* space in buffer for characters */ ! 177: KeySym *keysym; ! 178: XComposeStatus *status; ! 179: { ! 180: register KeySym symbol, lsymbol, usymbol; ! 181: int length = 0; ! 182: char buf[BUFSIZ]; ! 183: unsigned char byte3, byte4; ! 184: ! 185: if (event->display->keysyms == NULL) ! 186: Initialize(event->display); ! 187: ! 188: lsymbol = XKeycodeToKeysym(event->display, event->keycode, 0); ! 189: usymbol = XKeycodeToKeysym(event->display, event->keycode, 1); ! 190: /* ! 191: * we have to find out what kind of lock we are dealing with, if any. ! 192: * if caps lock, only shift caps. ! 193: */ ! 194: symbol = lsymbol; ! 195: if (event->state & LockMask) { ! 196: XModifierKeymap *m = event->display->modifiermap; ! 197: int i; ! 198: ! 199: if (usymbol != NoSymbol) ! 200: symbol = usymbol; ! 201: for (i = m->max_keypermod; i < 2*m->max_keypermod; i++) { ! 202: /* ! 203: * Run through all the keys setting LOCK and, if ! 204: * ANY of them are CAPS_LOCK, do Caps Lock. ! 205: * This is kind of bogus, but what else to do? ! 206: * Supposing we have CAPS_LOCK, but on the shifted ! 207: * part of the key? ! 208: */ ! 209: if (XKeycodeToKeysym(event->display, m->modifiermap[i], 0) ! 210: == XK_Caps_Lock) { ! 211: if (usymbol >= XK_A && usymbol <= XK_Z) ! 212: symbol = usymbol; ! 213: else ! 214: symbol = lsymbol; ! 215: break; ! 216: } ! 217: } ! 218: } ! 219: if ((event->state & ShiftMask) && usymbol != NoSymbol) ! 220: symbol = usymbol; ! 221: ! 222: if (keysym != NULL) *keysym = symbol; ! 223: ! 224: byte4 = symbol & 0xFF; ! 225: byte3 = (symbol >> 8 ) & 0xFF; ! 226: ! 227: /* ! 228: * see if symbol rebound, if so, return that string. ! 229: * if any of high order 16 bits set, can only do ascii. ! 230: * (reserved for future use, and for vendors). ! 231: */ ! 232: if ((length = KeySymRebound(event, buf, symbol)) == -1) { ! 233: if ( IsModifierKey(symbol) || IsCursorKey(symbol) ! 234: || IsPFKey (symbol) || IsFunctionKey(symbol) ! 235: || IsMiscFunctionKey(symbol) ! 236: || (symbol == XK_Multi_key) || (symbol == XK_Kanji)) return 0; ! 237: buf[0] = byte4; ! 238: /* if X keysym, convert to ascii by grabbing low 7 bits */ ! 239: if (byte3 == 0xFF) buf[0] &= 0x7F; ! 240: /* only apply Control key if it makes sense, else ignore it */ ! 241: if ((event->state & ControlMask) && HAS_CTRL(buf[0])) ! 242: buf[0] = buf[0] & 0x1F; ! 243: length = 1; ! 244: } ! 245: if (length > nbytes) length = nbytes; ! 246: bcopy (buf, buffer, length); ! 247: return (length); ! 248: } ! 249: ! 250: XRebindKeysym (dpy, keysym, mlist, nm, str, nbytes) ! 251: Display *dpy; ! 252: KeySym keysym; ! 253: KeySym *mlist; ! 254: int nm; /* number of modifiers in mlist */ ! 255: unsigned char *str; ! 256: int nbytes; ! 257: { ! 258: register struct XKeytrans *tmp, *p; ! 259: int nb; ! 260: ! 261: if (dpy->keysyms == NULL) ! 262: Initialize(dpy); ! 263: LockDisplay(dpy); ! 264: tmp = trans; ! 265: trans = p = (struct XKeytrans *)Xmalloc(sizeof(struct XKeytrans)); ! 266: p->next = tmp; /* chain onto list */ ! 267: p->string = (char *) Xmalloc(nbytes); ! 268: bcopy (str, p->string, nbytes); ! 269: p->len = nbytes; ! 270: nb = sizeof (KeySym) * nm; ! 271: p->modifiers = (KeySym *) Xmalloc(nb); ! 272: bcopy (mlist, p->modifiers, nb); ! 273: p->key = keysym; ! 274: p->mlen = nm; ! 275: ComputeMaskFromKeytrans(dpy, p); ! 276: UnlockDisplay(dpy); ! 277: return; ! 278: } ! 279: ! 280: /* ! 281: * given a KeySym, returns the first keycode found after the index value ! 282: * in the table. (Hopefully, can be found quickly). ! 283: */ ! 284: static CARD8 FindKeyCode(dpy, ind, code) ! 285: register Display *dpy; ! 286: int ind; ! 287: register int code; ! 288: { ! 289: ! 290: register KeySym *kmax = dpy->keysyms + ! 291: (dpy->max_keycode - dpy->min_keycode + 1) * dpy->keysyms_per_keycode; ! 292: register KeySym *k = dpy->keysyms; /* XXX not yet dealing with ind */ ! 293: if ((ind < dpy->min_keycode) || (ind > dpy->max_keycode)) return 0; ! 294: while (k < kmax) { ! 295: if (*k == code) ! 296: return(((k - dpy->keysyms) ! 297: / dpy->keysyms_per_keycode) + dpy->min_keycode); ! 298: k += 1; ! 299: } ! 300: return 0; ! 301: } ! 302: ! 303: ! 304: /* ! 305: * given a list of modifiers, computes the mask necessary for later matching. ! 306: * This routine must lookup the key in the Keymap and then search to see ! 307: * what modifier it is bound to, if any. ! 308: */ ! 309: static ComputeMaskFromKeytrans(dpy, p) ! 310: Display *dpy; ! 311: register struct XKeytrans *p; ! 312: { ! 313: register int i; ! 314: register CARD8 code; ! 315: register XModifierKeymap *m = dpy->modifiermap; ! 316: ! 317: p->state = 0; ! 318: for (i = 0; i < p->mlen; i++) { ! 319: /* if not found, then not on current keyboard */ ! 320: if ((code = FindKeyCode(dpy, dpy->min_keycode, p->modifiers[i])) == 0) ! 321: continue; ! 322: /* code is now the keycode for the modifier you want */ ! 323: { ! 324: register int j; ! 325: ! 326: for (j = 0; j < (m->max_keypermod<<3); j++) { ! 327: if (m->modifiermap[j] && code == m->modifiermap[j]) ! 328: p->state |= (1<<(j/m->max_keypermod)); ! 329: } ! 330: } ! 331: } ! 332: return; ! 333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.