Annotation of 43BSDTahoe/new/X/xterm/Xlib/XKeyBind.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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