Annotation of coherent/d/PS2_KERNEL/tools/kbmain.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * driver routine for loadable keyboard tables.
                      3:  *
                      4:  * prior to firing off the ioctl() which loads the new keyboard tables,
                      5:  * permform some simple validity checks on the table.
                      6:  * if errors are found, bail out without setting the new table.
                      7:  *
                      8:  * this version removes all references to stdio since we need to put over
                      9:  * a dozen cooked keyboard tables on the boot disk - space is at a premium.
                     10:  *
                     11:  * Version 1.1, 6/25/91
                     12:  */
                     13: 
                     14: #include <sgtty.h>
                     15: #include <sys/kb.h>
                     16: #include <sys/kbscan.h>
                     17: #include <errno.h>
                     18: #include <sys/mdata.h>
                     19: 
                     20: #define        VERSION "1.1"
                     21: #define        FALSE   (0 != 0)
                     22: #define        TRUE    (0 == 0)
                     23: #define NULL ((char *)0)
                     24: #define putchar(c) { char b = c; write(1, &b, 1); }
                     25: 
                     26: /*
                     27:  * globals
                     28:  */
                     29: char   *argv0;                         /* name of this executable */
                     30: int    errors;                         /* for exit status */
                     31: char   verbose;                        /* step-by-step details */
                     32: char   debug;                          /* print out cooked table & exit */
                     33: KBTBL  table[MAX_KEYS];                /* cooked table for ioctl() */
                     34: FNKEY  *arena;                         /* function key arena */
                     35: unsigned char  fnbuffer[(sizeof(FNKEY) + MAX_FCHAR)]; /* function key area */
                     36: 
                     37: /*
                     38:  * The following table maps the specified key number to
                     39:  * a scan code set 3 value.
                     40:  * Note that K_14, K_65 through K_74 and K_107
                     41:  * are provided for compatibility with
                     42:  * the old XT layout AT keyboards.
                     43:  */
                     44: unsigned char  keyval[] = {            /* code set 3 mapped value */
                     45: none, K_1, K_2, K_3, K_4, K_5, K_6, K_7,
                     46: K_8, K_9, K_10, K_11, K_12, K_13, K_14, K_15,
                     47: K_16, K_17, K_18, K_19, K_20, K_21, K_22, K_23,
                     48: K_24, K_25, K_26, K_27, K_28, K_29, K_30, K_31,
                     49: K_32, K_33, K_34, K_35, K_36, K_37, K_38, K_39,
                     50: K_40, K_41, K_42, K_43, K_44, K_45, K_46, K_47,
                     51: K_48, K_49, K_50, K_51, K_52, K_53, K_54, K_55,
                     52: none, K_57, K_58, none, K_60, K_61, K_62, none,
                     53: K_64, K_65, K_66, K_67, K_68, K_69, K_70, K_71,
                     54: K_72, K_73, K_74, K_75, K_76, none, none, K_79,
                     55: K_80, K_81, none, K_83, K_84, K_85, K_86, none,
                     56: none, K_89, K_90, K_91, K_92, K_93, none, K_95,
                     57: K_96, K_97, K_98, K_99, K_100, K_101, K_102, K_103,
                     58: K_104, K_105, K_106, K_107, K_108, none, K_110, none,
                     59: K_112, K_113, K_114, K_115, K_116, K_117, K_118, K_119,
                     60: K_120, K_121, K_122, K_123, K_124, K_125, K_126, none
                     61: };
                     62: 
                     63: /*
                     64:  * externs from user-defined keyboard table
                     65:  */
                     66: extern KBTBL   kbtbl[];                        /* actual table */
                     67: extern char    tbl_name[];                     /* name of table as text */
                     68: extern unsigned char *funkey[];                /* function key definitions */
                     69: extern int     numfun;                         /* # of function keys in tbl */
                     70: extern int     numkey;                         /* number of keys in kbtbl[] */
                     71: 
                     72: main(argc, argv)
                     73: char *argv[];
                     74: {
                     75:        unsigned char *cp, *ncp;
                     76:        int i, j;
                     77:        int fd;                                 /* console file descriptor */
                     78: 
                     79:        argv0 = argv[0];
                     80:        arena = (FNKEY *) fnbuffer;
                     81: 
                     82:        if (argc > 1) {
                     83:                if (strcmp(argv[1], "-V") == 0)
                     84:                        printf("Version %s\n", VERSION);
                     85:                else if (strcmp(argv[1], "-D") == 0)
                     86:                        ++debug;
                     87:                else
                     88:                        usage();
                     89:        }
                     90: 
                     91:        if ((fd = open("/dev/console", 2)) < 0) {
                     92:                err("unable to access console");
                     93:                exit(errors);
                     94:        }
                     95: 
                     96:        /*
                     97:         * loop through the user's keyboard table validating each entry.
                     98:         * if the entry is good, copy it to the destination table.
                     99:         */
                    100:        for (i = 0; i < numkey; ++i) {          /* loop thru user's keys */
                    101:                if (ok_entry(i)) {
                    102:                        j = kbtbl[i].k_key;             /* map key */
                    103:                        table[j] = kbtbl[i];            /* copy entry */
                    104:                } else
                    105:                        ++errors;
                    106:        }
                    107: 
                    108:        if (errors)
                    109:                exit(errors);
                    110:        /*
                    111:         * build a function key arena consisting of the user defined
                    112:         * special and function keys.
                    113:         */
                    114:        ncp = arena->k_fnval;
                    115:        for (i = 0; i < numfun; ++i) {
                    116:                cp = funkey[i];
                    117:                do {
                    118:                        if (ncp >= &arena->k_fnval[MAX_FCHAR]) {
                    119:                                err("function key table overflow");
                    120:                                exit(errors);
                    121:                        }
                    122:                        *ncp++ = *cp;
                    123:                } while (*cp++ != DELIM);
                    124:        }
                    125:        arena->k_nfkeys = numfun;
                    126: 
                    127:        if (debug) {
                    128:                dump();                         /* print out cooked table */
                    129:                exit(0);
                    130:        }
                    131: 
                    132:        /*
                    133:         * load the cooked keyboard table into the driver via a
                    134:         * special ioctl() call.
                    135:         */
                    136:        ioctl(fd, TIOCSETKBT, table);
                    137:        if (errno) {
                    138:                err("keyboard table ioctl() failed, errno=%d", errno);
                    139:                exit(errors);
                    140:        }
                    141: 
                    142:        /*
                    143:         * load the cooked function key table into the driver via a
                    144:         * special ioctl() call.
                    145:         */
                    146:        ioctl(fd, TIOCSETF, arena);
                    147:        if (errno) {
                    148:                err("function key ioctl() failed, errno=%d", errno);
                    149:                exit(errors);
                    150:        }
                    151: 
                    152:        printf("Loaded %s\n", tbl_name);
                    153:        close(fd);
                    154:        exit(errors);
                    155: }
                    156: 
                    157: /*
                    158:  * validate a table entry
                    159:  */
                    160: ok_entry(n)
                    161: register int n;
                    162: {
                    163:        int i;
                    164:        int key = lookup(kbtbl[n].k_key);
                    165:        unsigned char kval;
                    166: 
                    167:        if (!key) {
                    168:                err("invalid key #0x%x in kbtbl[%d]", kbtbl[n].k_key, n);
                    169:                return FALSE;
                    170:        }
                    171:        if ((kbtbl[n].k_flags & (S|F)) == (S|F)) {
                    172:                err("invalid flag field for key K_%d", key);
                    173:                return FALSE;
                    174:        }
                    175:        if (kbtbl[n].k_flags & S) {
                    176:                for (i = BASE; i <= ALT_GR; ++i) {
                    177:                        kval = kbtbl[n].k_val[i];
                    178:                        if (kval != kbtbl[n].k_val[BASE]) {
                    179:                                err("inconsistent shift key entry for K_%d",
                    180:                                    key);
                    181:                                return FALSE;
                    182:                        }
                    183:                        if (kval < scroll || kval > altgr) {
                    184:                                err("bad shift key entry for K_%d",
                    185:                                    key);
                    186:                                return FALSE;
                    187:                        }
                    188:                } /* for */
                    189:        } else if (kbtbl[n].k_flags & F) {
                    190:                for (i = BASE; i <= ALT_GR; ++i) {
                    191:                        kval = kbtbl[n].k_val[i];
                    192:                        if (kval != none)
                    193:                                if (kval >= numfun && !VTKEY(kval)) {
                    194:                                        printf("val=%d\n", kval);
                    195:                                        err("bad function key entry K_%d",
                    196:                                            key);
                    197:                                        return FALSE;
                    198:                                }
                    199:                } /* for */
                    200:        } /* flag key */
                    201: 
                    202:        if (table[kbtbl[n].k_key].k_key != 0) {
                    203:                err("multiple entries for K_%d", key);
                    204:                return FALSE;
                    205:        }
                    206:        return TRUE;
                    207: }
                    208: 
                    209: /*
                    210:  * lookup the physical key number associated with a given
                    211:  * code set 3 scan code.
                    212:  *
                    213:  * return 0 if not found.
                    214:  */
                    215: lookup(sc)
                    216: unsigned sc;
                    217: {
                    218:        register int i;
                    219: 
                    220:        if (sc == none)
                    221:                return 0;
                    222:        for (i = 0; i < sizeof(keyval)/sizeof(keyval[0]); ++i)
                    223:                if (keyval[i] == (unsigned char)sc)
                    224:                        return (i);
                    225:        return 0;
                    226: }
                    227: 
                    228: usage()
                    229: {
                    230:        printf("usage:\t%s [-V]\n", argv0);
                    231:        exit(1);
                    232: }
                    233: 
                    234: err(msg)
                    235: char *msg;
                    236: {
                    237:        printf("%s: ERROR: %r\n", argv0, &msg);
                    238:        ++errors;
                    239: }
                    240: 
                    241: /*
                    242:  * dump the cooked keyboard table to stdout
                    243:  */
                    244: dump()
                    245: {
                    246:        int i, j;
                    247: 
                    248:        for (i = 0; i < MAX_KEYS; ++i) {
                    249:                printf("%02x: %02x ", i, table[i].k_key);
                    250:                for (j = 0; j < 9; ++j)
                    251:                        printf("%02x ", table[i].k_val[j]);
                    252:                printf("(%02x)\n", table[i].k_flags);
                    253:        }
                    254: }
                    255: 
                    256: 
                    257: /*
                    258:  * Simple standard output printf() using single character writes to stdout.
                    259:  *
                    260:  * Non-portable things:
                    261:  * 1) alignment of arguments is assumed to be completely contiguous.
                    262:  * 2) the smallest number is assumed to negate to itself.
                    263:  *    be held in an exact number of ints.
                    264:  */
                    265: union  alltypes {
                    266:        char    c;
                    267:        int     i;
                    268:        unsigned u;
                    269:        char    *s;
                    270: };
                    271: 
                    272: #define        bump(p,s)       (p+=sizeof(s)/sizeof(int))
                    273: 
                    274: char   *printi();
                    275: 
                    276: static char    null[] = "{NULL}";
                    277: 
                    278: printf(args)
                    279: union alltypes args;
                    280: {
                    281:        xprintf(&args);
                    282: }
                    283: xprintf(argp)
                    284: union alltypes *argp;
                    285: {
                    286:        register char *cbp;
                    287:        int *iap;
                    288:        register c;
                    289:        char *s;
                    290:        char *cbs;
                    291:        char adj, pad;
                    292:        int prec;
                    293:        int fwidth;
                    294:        int pwidth;
                    295:        register char *fmt;
                    296:        union alltypes elem;
                    297:        char cbuf[64];
                    298: 
                    299:        iap = (int *)argp;
                    300:        fmt = *(char **)iap;
                    301:        bump(iap, char*);
                    302:        for (;;) {
                    303:                while((c = *fmt++) != '%') {
                    304:                        if(c == '\0') {
                    305:                                return;
                    306:                        }
                    307:                        putchar(c);
                    308:                }
                    309:                pad = ' ';
                    310:                fwidth = -1;
                    311:                prec = -1;
                    312:                c = *fmt++;
                    313:                if (c == '-') {
                    314:                        adj = 1;
                    315:                        c = *fmt++;
                    316:                } else
                    317:                        adj = 0;
                    318:                if (c == '0') {
                    319:                        pad = '0';
                    320:                        c = *fmt++;
                    321:                }
                    322:                if (c == '*') {
                    323:                        fwidth = *iap++;
                    324:                        c = *fmt++;
                    325:                } else
                    326:                        for (fwidth = 0; c>='0' && c<='9'; c = *fmt++)
                    327:                                fwidth = fwidth*10 + c-'0';
                    328:                if (c == '.') {
                    329:                        c = *fmt++;
                    330:                        if (c == '*') {
                    331:                                prec = *iap++;
                    332:                                c = *fmt++;
                    333:                        } else
                    334:                                for (prec=0; c >= '0' && c <= '9'; c = *fmt++)
                    335:                                        prec = prec*10 + c-'0';
                    336:                }
                    337:                cbp = cbs = cbuf;
                    338:                switch (c) {
                    339: 
                    340:                case 'd':
                    341:                        elem.i = *iap++;
                    342:                        if (elem.i < 0) {
                    343:                                elem.i = -elem.i;
                    344:                                *cbp++ = '-';
                    345:                        }
                    346:                        cbp = printi(cbp, elem.i, 10);
                    347:                        break;
                    348: 
                    349:                case 'u':
                    350:                        cbp = printi(cbp, *iap++, 10);
                    351:                        break;
                    352:        
                    353:                case 'o':
                    354:                        cbp = printi(cbp, *iap++, 8);
                    355:                        break;
                    356: 
                    357:                case 'x':
                    358:                        cbp = printi(cbp, *iap++, 16);
                    359:                        break;
                    360: 
                    361:                case 's':
                    362:                        if ((s = *(char **)iap) == NULL)
                    363:                                s = null;
                    364:                        bump(iap, char*);
                    365:                        /*
                    366:                         * Do %s specially so it can be longer.
                    367:                         */
                    368:                        cbp = cbs = s;
                    369:                        while (*cbp++ != '\0')
                    370:                                if (prec>=0 && cbp-s>prec)
                    371:                                        break;
                    372:                        cbp--;
                    373:                        break;
                    374:        
                    375:                case 'c':
                    376:                        elem.c = *iap++;
                    377:                        *cbp++ = elem.c;
                    378:                        break;
                    379:        
                    380:                case 'r':
                    381:                        xprintf(*(char ***)iap);
                    382:                        bump(iap, char**);
                    383:                        break;
                    384:        
                    385:                default:
                    386:                        putchar(c);
                    387:                        continue;
                    388:                }
                    389:                if ((pwidth = fwidth + cbs-cbp) < 0)
                    390:                        pwidth = 0;
                    391:                if (!adj)
                    392:                        while (pwidth-- != 0)
                    393:                                putchar(pad);
                    394:                while (cbs < cbp)
                    395:                        putchar(*cbs++);
                    396:                if (adj)
                    397:                        while (pwidth-- != 0)
                    398:                                putchar(pad);
                    399:        }
                    400: }
                    401: 
                    402: static char    digits[] = {
                    403:        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                    404:        'A', 'B', 'C', 'D', 'E', 'F'
                    405: };
                    406: 
                    407: /*
                    408:  * Print an unsigned integer in base b.
                    409:  */
                    410: static
                    411: char *
                    412: printi(cp, n, b)
                    413: char *cp;
                    414: register unsigned n;
                    415: {
                    416:        register a;
                    417:        register char *ep;
                    418:        char pbuf[10];
                    419: 
                    420:        ep = &pbuf[10];
                    421:        *--ep = 0;
                    422:        for ( ; a = n/b; n=a)
                    423:                *--ep = digits[n%b];
                    424:        *--ep = digits[n];
                    425:        while (*ep)
                    426:                *cp++ = *ep++;
                    427:        return (cp);
                    428: }
                    429: 
                    430: /* end of kbmain.c */

unix.superglobalmegacorp.com

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