/****************************************************************************** KEYCOMP.C (C) Copyright 1986 Marc Adler All Rights Reserved Reads a file (arg1) whose line are of the form key=func Key can be a decimal number, 'char', ^char (control char), F# (normal func key), AF# (ALT func key), SF# (shift func key), CF# (CTRL func key), @char (ALT key) Func can be a decimal number or a character of the form 'c' or c. This program will generate a 256 byte "compiled" keystroke file called KEYTABLE.ME. Byte n will contain the translated char that will be read by ngetc() when key n is pressed. ******************************************************************************/ #include #include #include #include "keys.h" /*** BASE VALUES FOR FUNCTION KEY 0 ***/ #define NORM_FUNC 186 #define SHIFT_FUNC 211 #define CTRL_FUNC 221 #define ALT_FUNC 231 typedef struct keymap { struct keymap *nextmap; int prefix; unsigned char keytable[256]; } KEYMAP; struct _alts { char *altchars; int altbase; } alts[5] = { "QWERTYUIOP", 144, "ASDFGHJKL", 158, "ZXCVBNM", 172, "12345678", 248, "90-+", 128 }; KEYMAP *alloc_keymap(), *find_keymap(); KEYMAP *MainKeyMap; int NumMaps = 0; main(argc, argv) int argc; char **argv; { char *fgets(); FILE *f, *fopen(); unsigned char buf[100], c; char *s, *t, *strrchr(); char *kp; int i, k, outf; KEYMAP *kmap, *lastmap; long magic; int debug = 1; if (argc < 2) f = stdin; else if ((f = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "Can't open input file %s\n", argv[1]); exit(1); } /* init the table with byte[n] = n */ MainKeyMap = kmap = lastmap = alloc_keymap(0); for (kp = MainKeyMap->keytable, i = 0; i < 256; *kp++ = i++) ; while (fgets(buf, 100, f)) { /* skip any comments and blank lines */ if (*buf == '#' || isspace(*buf)) continue; /* convert left half to all upper case (if not in quotes) */ for (t = buf; *t && *t != '\''; t++) *t = toupper(*t); if (!strncmp(buf, "PREFIX", 6)) { for (s = buf+6; *s && isspace(*s); s++) ; k = decode_key(s); MainKeyMap->keytable[k] = KEYPREFIX; kmap = alloc_keymap(k); lastmap->nextmap = kmap; lastmap = kmap; continue; } /* Separate left and right hand sides */ if ((s = strrchr(buf, '=')) == NULL) continue; else *s = '\0'; if ((k = decode_key(buf)) >= 0) /* fill in the entry */ { kmap->keytable[k] = c = decode_key(s+1); if (isalpha(k) && /* Upper & lower case entries should be same */ kmap != MainKeyMap) /* in prefix commands (ie ^KD == ^Kd). */ kmap->keytable[toupper(k)] = c; } } /* Write out the keymaps */ if ((outf = open("keytable.me", O_CREAT|O_TRUNC|O_WRONLY|O_RAW, 0)) >= 0) { magic = KEYMAGIC; write(outf, &magic, sizeof(magic)); write(outf, &NumMaps, sizeof(NumMaps)); for (kmap = MainKeyMap; kmap; kmap = kmap->nextmap) { write(outf, &kmap->prefix, sizeof(kmap->prefix)); write(outf, kmap->keytable, sizeof(char) * 256); } } } decode_key(buf) char *buf; { int c, k; if (isdigit(c = buf[0])) /* numerical key */ k = atoi(buf); else if (c == '@') /* ALT keystroke */ k = find_alt(buf[1]); else if (c == '\'') /* quoted char */ k = buf[1]; else if (c == '^') /* control char */ k = buf[1] & 0x1F; else if (c == 'F') /* regular function key */ k = NORM_FUNC + atoi(buf+1); else if (buf[1] == 'F') { if (c == 'A') /* AF = ALT func key */ k = ALT_FUNC; else if (c == 'S') /* SF = SHIFT func key */ k = SHIFT_FUNC; else if (c == 'C') /* CF - CTRL func key */ k = CTRL_FUNC; k += atoi(buf+2); /* should be '1' - '10' */ } else k = c; if (isalpha(k) && k < 127) k = tolower(k); return(k); } /* find_alt - takes care translating of '@char' sequence */ find_alt(c) char c; { int i; char *s, *strchr(); /* search the string in alt[i] for the char - if it's in, return */ /* the base value plus its position in the string. */ for (i = 0; i < 5; i++) if ((s = strchr(alts[i].altchars, c)) != NULL) return (int) (alts[i].altbase + (s - alts[i].altchars)); return 0; } KEYMAP *alloc_keymap(prefix) unsigned prefix; { KEYMAP *k; char *calloc(); k = (KEYMAP *) calloc(sizeof(KEYMAP), 1); k->nextmap = NULL; k->prefix = prefix; NumMaps++; return(k); }