Annotation of 43BSD/contrib/X/Xlib/XKeyBind.c, revision 1.1.1.1

1.1       root        1: #include <X/mit-copyright.h>
                      2: 
                      3: /* $Header: XKeyBind.c,v 10.8 86/02/01 15:35:46 tony Rel $ */
                      4: /* Copyright 1985, Massachusetts Institute of Technology */
                      5: 
                      6: #include "XlibInternal.h"
                      7: #include <sys/file.h>
                      8: #include <sys/stat.h>
                      9: #include "Xkeymap.h"
                     10: #include "Xkeyboard.h"
                     11: #include <stdio.h>
                     12: #include <strings.h>
                     13: 
                     14: #define EMPTY_ENTRY LeftMask 
                     15:    /* if the "metabits" field of a runtime table entry contains this,
                     16:     it's an empty entry */
                     17: 
                     18: static KeyMapElt *keymap = NULL;
                     19: static Bool inited = FALSE;
                     20: 
                     21: static ExtensionHeader *ext_begin, *ext_end;
                     22: 
                     23: /* Runtime table: contains multiple-byte character bindings defined
                     24:   at runtime with XRebindCode */
                     25: 
                     26: typedef struct {
                     27:     unsigned char keycode;
                     28:     unsigned char metabits;
                     29:     short length;
                     30:     char *value;
                     31:     } RuntimeTableEntry;
                     32: 
                     33: static RuntimeTableEntry
                     34:    *rt_begin,  /* first entry of runtime table */
                     35:    *rt_end,    /* this and all succeeding entries are empty */
                     36:    *rt_buf_end;/* points beyond end of allocated storage for table */
                     37: 
                     38: #define RT_INITIAL_SIZE 100  /* initial size of runtime table */
                     39: #define RT_INCREMENT 40  /* size to grow by if expanded */
                     40: 
                     41: static Initialize() {
                     42:     int file = -1;
                     43:     int filesize;
                     44:     unsigned char magic;
                     45:     struct stat filestat;
                     46:     char *getenv();
                     47:     char *filename;
                     48:     char *home = getenv ("HOME");
                     49:     inited = TRUE;
                     50:     if (home) {
                     51:        int homelen = strlen (home);
                     52:        char *keymapstr = "/.Xkeymap";
                     53:        int keymapstrlen = strlen (keymapstr);
                     54:        filename = malloc (homelen + keymapstrlen + 1);
                     55:        strncpy (filename, home, homelen+1);
                     56:        strncat (filename, keymapstr, keymapstrlen);
                     57:        file = open (filename, O_RDONLY, 0);
                     58:        }
                     59:     if (file < 0) {
                     60:        free (filename);
                     61:        return;     /* no keymap file found */
                     62:        }
                     63:     fstat (file, &filestat);
                     64:     filesize = filestat.st_size - 1; /* first byte is magic number */
                     65:     if (filesize < 256*sizeof(KeyMapElt)) {
                     66:        fprintf (stderr, "Keymap file %s is too small\n", filename);
                     67:        close (file);
                     68:        free (filename);
                     69:        return;
                     70:        }
                     71:     read (file, &magic, 1);
                     72:     if (magic != X_KEYMAP_MAGIC) {
                     73:        fprintf (stderr, 
                     74:          "Keymap file %s doesn't begin with the proper magic number\n",
                     75:          filename);
                     76:         close (file);
                     77:        free (filename);
                     78:        return;
                     79:        }
                     80:     keymap = (KeyMapElt *) malloc (filesize);
                     81:     if (!keymap) {
                     82:        close (file);
                     83:        free (filename);
                     84:        return;  /* couldn't malloc; just act like there isn't a keymap */
                     85:        }
                     86:     read (file, (char *) keymap, filesize);
                     87:     ext_begin = (ExtensionHeader *) (keymap + 256);
                     88:     ext_end = (ExtensionHeader *) (((char *) keymap) + filesize);
                     89:     rt_begin = (RuntimeTableEntry *) malloc (RT_INITIAL_SIZE*sizeof(RuntimeTableEntry));
                     90:     if (!rt_begin)
                     91:        _XIOError (_XlibCurrentDisplay);
                     92:     rt_end = rt_begin;
                     93:     rt_buf_end = rt_begin + RT_INITIAL_SIZE;
                     94:     free (filename);
                     95:     close (file);
                     96:     }
                     97: 
                     98: /* this routine is used when initialization failed to find a
                     99:    valid keymap file */
                    100: static char *BackstopLookupMapping (event, nbytes)
                    101:     XKeyPressedEvent *event;
                    102:     int *nbytes;
                    103:     {
                    104:     int detail = event->detail;
                    105:     register int keycode = detail & ValueMask;
                    106:     extern KeyMapEntry StdMap[];
                    107:     static char c;
                    108:     short s;  /* needed to distinguish a real character (e.g. \0377) from -1 */
                    109:     s = StdMap [keycode] [KeyState(detail)];
                    110:     c = s;
                    111:     if ((detail & ShiftLockMask) && (c >= 'a') && (c <= 'z'))
                    112:        c += ('A' - 'a');
                    113:     if (IsTypewriterKey(keycode)
                    114:       || keycode == KC_ESC || keycode == KC_BS || keycode == KC_LF)
                    115:        *nbytes = (s == -1 ? 0 : 1);
                    116:     else
                    117:        *nbytes = 0;
                    118:     return (&c);
                    119:     }
                    120: 
                    121: char *XLookupMapping (event, nbytes)
                    122:     XKeyPressedEvent *event;
                    123:     int *nbytes;
                    124:     {
                    125:     int detail = event->detail;
                    126:     unsigned int metabits = FullKeyState (detail);
                    127:     unsigned int key = detail & ValueMask;
                    128:     register unsigned char *the_char;
                    129: 
                    130:     if (!inited)
                    131:        Initialize();
                    132:     if (!keymap)
                    133:        return (BackstopLookupMapping (event, nbytes));
                    134: 
                    135:     the_char = &keymap [key] [metabits];
                    136: 
                    137:     switch (*the_char) {
                    138: 
                    139:        case UNBOUND: {
                    140:            *nbytes = 0;
                    141:            return (NULL);
                    142:            }
                    143: 
                    144:        case EXTENSION_BOUND: {
                    145:            register ExtensionHeader *this;
                    146:            for (this = ext_begin; this < ext_end; NextExtension(this))
                    147:                if ((key == this->keycode)
                    148:                && ((metabits == this->metabits) || (this->metabits == DontCareMetaBits))) {
                    149:                    *nbytes = this->length;
                    150:                    return ((char *)this + ExtensionHeaderSize);
                    151:                    }
                    152:            /* if we get here, no match was found in the table extension */
                    153:            *nbytes = 0;
                    154:            return (NULL);
                    155:            }
                    156: 
                    157:         case RUNTIME_TABLE_BOUND: {
                    158:            register RuntimeTableEntry *entry;
                    159:            for (entry = rt_begin; entry < rt_end; entry++)
                    160:                if ((key == entry->keycode)
                    161:                && ((metabits == entry->metabits) || (entry->metabits == DontCareMetaBits))) {
                    162:                    *nbytes = entry->length;
                    163:                    return (entry->value);
                    164:                    }
                    165: 
                    166:            /* if we get here, no match was found in the runtime table */
                    167:            *nbytes = 0;
                    168:            return (NULL);
                    169:            }
                    170: 
                    171:        default: {
                    172:            *nbytes = 1;
                    173:            return ((char *)the_char);
                    174:            }
                    175:        }
                    176: 
                    177:     }
                    178: 
                    179: 
                    180: XRebindCode (keycode, metabits, str, nbytes)
                    181:     unsigned int keycode, metabits;
                    182:     char *str;
                    183:     int nbytes;
                    184:     {
                    185:     unsigned char *table_char;
                    186:     metabits = FullKeyState (metabits);  /* shift meta bits to rightmost four bits */
                    187:     if (!inited)
                    188:        Initialize();
                    189:     if (!keymap)
                    190:        return;  /* no keymap file; what else can I do? */
                    191:     table_char = &keymap [keycode] [metabits];
                    192:     if (nbytes == 0) {
                    193:        if (*table_char == RUNTIME_TABLE_BOUND)
                    194:            Unbind (keycode, metabits);
                    195:        *table_char = UNBOUND;
                    196:        return;
                    197:        }
                    198:     if ((nbytes == 1) && SingleCharBound (*str)) {
                    199:        if (*table_char == RUNTIME_TABLE_BOUND)
                    200:            Unbind (keycode, metabits);
                    201:        *table_char = *str;
                    202:        return;
                    203:        }
                    204:     
                    205:     /* the new binding is either multi-character, or one of the
                    206:        three reserved special characters */
                    207: 
                    208:     if (*table_char == RUNTIME_TABLE_BOUND) {
                    209:        /* entry is already in table; just change its binding */
                    210:        register RuntimeTableEntry *entry;
                    211:        for (entry = rt_begin; entry < rt_end; entry++)
                    212:            if (keycode == entry->keycode && metabits == entry->metabits) {
                    213:                entry->value = str;
                    214:                entry->length = nbytes;
                    215:                return;
                    216:                }
                    217:        /* if we get here, entry wasn't found in table; shouldn't
                    218:         * ever happen!  Not much to do but fall through to 
                    219:         * the following code.  */
                    220:        }
                    221: 
                    222:     /* new binding must go in a new entry in the table */
                    223:     *table_char = RUNTIME_TABLE_BOUND;
                    224:     if (rt_end < rt_buf_end) {
                    225:        rt_end->keycode = keycode;
                    226:        rt_end->metabits = metabits;
                    227:        rt_end->value = str;
                    228:        rt_end++->length = nbytes;
                    229:        return;
                    230:        }
                    231: 
                    232:     /* no room at end of table; look for holes in middle */
                    233:     {
                    234:     register RuntimeTableEntry *entry;
                    235:     for (entry = rt_begin; entry < rt_end; entry++)
                    236:        if (entry->metabits == EMPTY_ENTRY) {
                    237:            entry->keycode = keycode;
                    238:            entry->metabits = metabits;
                    239:            entry->value = str;
                    240:            entry->length = nbytes;
                    241:            return;
                    242:            }
                    243:     }
                    244: 
                    245:     /* no room in table at all.  Must expand it. */
                    246:     {
                    247:     int rt_length = rt_end - rt_begin;
                    248:     realloc (&rt_begin, (rt_length+RT_INCREMENT)*sizeof (RuntimeTableEntry));
                    249:     rt_end = rt_begin + rt_length;
                    250:     rt_buf_end = rt_end + RT_INCREMENT;
                    251:     rt_end->keycode = keycode;
                    252:     rt_end->metabits = metabits;
                    253:     rt_end->value = str;
                    254:     rt_end++->length = nbytes;
                    255:     }
                    256:     }
                    257:     
                    258: 
                    259: static Unbind (keycode, metabits)
                    260:     unsigned int keycode, metabits;
                    261:     {
                    262:     register RuntimeTableEntry *entry;
                    263:     for (entry = rt_begin; entry < rt_end; entry++)
                    264:        if (keycode == entry->keycode && metabits == entry->metabits) {
                    265:            entry->metabits = EMPTY_ENTRY;
                    266:            return;
                    267:            }
                    268:     }

unix.superglobalmegacorp.com

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