Annotation of 43BSDTahoe/new/X/xterm/Xlib/XKeyBind.c, revision 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.