Annotation of 43BSD/contrib/X/Xlib/XKeyBind.c, revision 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.