Annotation of researchv9/X11/src/X.V11R1/lib/X/XKeyBind.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.