Annotation of coherent/d/kernel/USRSRC/i8086/drv/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: 
                    166:        if (!key) {
                    167:                err("invalid key #0x%x in kbtbl[%d]", kbtbl[n].k_key, n);
                    168:                return FALSE;
                    169:        }
                    170:        if ((kbtbl[n].k_flags & (S|F)) == (S|F)) {
                    171:                err("invalid flag field for key K_%d", key);
                    172:                return FALSE;
                    173:        }
                    174:        if (kbtbl[n].k_flags & S) {
                    175:                for (i = BASE; i <= ALT_GR; ++i) {
                    176:                        if (kbtbl[n].k_val[i] != kbtbl[n].k_val[BASE]) {
                    177:                                err("inconsistent shift key entry for K_%d",
                    178:                                    key);
                    179:                                return FALSE;
                    180:                        }
                    181:                        if (kbtbl[n].k_val[i] < scroll
                    182:                           || kbtbl[n].k_val[i] > altgr) {
                    183:                                err("bad shift key entry for K_%d",
                    184:                                    key);
                    185:                                return FALSE;
                    186:                        }
                    187:                } /* for */
                    188:        } else if (kbtbl[n].k_flags & F) {
                    189:                for (i = BASE; i <= ALT_GR; ++i) {
                    190:                        if (kbtbl[n].k_val[i] != none)
                    191:                                if (kbtbl[n].k_val[i] >= numfun) {
                    192:                                        err("bad function key entry for K_%d",
                    193:                                            key);
                    194:                                        return FALSE;
                    195:                                }
                    196:                } /* for */
                    197:        } /* flag key */
                    198: 
                    199:        key = kbtbl[n].k_key;
                    200:        if (table[key].k_key != 0) {
                    201:                err("multiple entries for K_%d", key);
                    202:                return FALSE;
                    203:        }
                    204:        return TRUE;
                    205: }
                    206: 
                    207: /*
                    208:  * lookup the physical key number associated with a given
                    209:  * code set 3 scan code.
                    210:  *
                    211:  * return 0 if not found.
                    212:  */
                    213: lookup(sc)
                    214: unsigned sc;
                    215: {
                    216:        register int i;
                    217: 
                    218:        if (sc == none)
                    219:                return 0;
                    220:        for (i = 0; i < sizeof(keyval)/sizeof(keyval[0]); ++i)
                    221:                if (keyval[i] == (unsigned char)sc)
                    222:                        return (i);
                    223:        return 0;
                    224: }
                    225: 
                    226: usage()
                    227: {
                    228:        printf("usage:\t%s [-V]\n", argv0);
                    229:        exit(1);
                    230: }
                    231: 
                    232: err(msg)
                    233: char *msg;
                    234: {
                    235:        printf("%s: ERROR: %r\n", argv0, &msg);
                    236:        ++errors;
                    237: }
                    238: 
                    239: /*
                    240:  * dump the cooked keyboard table to stdout
                    241:  */
                    242: dump()
                    243: {
                    244:        int i, j;
                    245: 
                    246:        for (i = 0; i < MAX_KEYS; ++i) {
                    247:                printf("%02x: %02x ", i, table[i].k_key);
                    248:                for (j = 0; j < 9; ++j)
                    249:                        printf("%02x ", table[i].k_val[j]);
                    250:                printf("(%02x)\n", table[i].k_flags);
                    251:        }
                    252: }
                    253: 
                    254: 
                    255: /*
                    256:  * Simple standard output printf() using single character writes to stdout.
                    257:  *
                    258:  * Non-portable things:
                    259:  * 1) alignment of arguments is assumed to be completely contiguous.
                    260:  * 2) the smallest number is assumed to negate to itself.
                    261:  *    be held in an exact number of ints.
                    262:  */
                    263: union  alltypes {
                    264:        char    c;
                    265:        int     i;
                    266:        unsigned u;
                    267:        char    *s;
                    268: };
                    269: 
                    270: #define        bump(p,s)       (p+=sizeof(s)/sizeof(int))
                    271: 
                    272: char   *printi();
                    273: 
                    274: static char    null[] = "{NULL}";
                    275: 
                    276: printf(args)
                    277: union alltypes args;
                    278: {
                    279:        xprintf(&args);
                    280: }
                    281: xprintf(argp)
                    282: union alltypes *argp;
                    283: {
                    284:        register char *cbp;
                    285:        int *iap;
                    286:        register c;
                    287:        char *s;
                    288:        char *cbs;
                    289:        char adj, pad;
                    290:        int prec;
                    291:        int fwidth;
                    292:        int pwidth;
                    293:        register char *fmt;
                    294:        union alltypes elem;
                    295:        char cbuf[64];
                    296: 
                    297:        iap = (int *)argp;
                    298:        fmt = *(char **)iap;
                    299:        bump(iap, char*);
                    300:        for (;;) {
                    301:                while((c = *fmt++) != '%') {
                    302:                        if(c == '\0') {
                    303:                                return;
                    304:                        }
                    305:                        putchar(c);
                    306:                }
                    307:                pad = ' ';
                    308:                fwidth = -1;
                    309:                prec = -1;
                    310:                c = *fmt++;
                    311:                if (c == '-') {
                    312:                        adj = 1;
                    313:                        c = *fmt++;
                    314:                } else
                    315:                        adj = 0;
                    316:                if (c == '0') {
                    317:                        pad = '0';
                    318:                        c = *fmt++;
                    319:                }
                    320:                if (c == '*') {
                    321:                        fwidth = *iap++;
                    322:                        c = *fmt++;
                    323:                } else
                    324:                        for (fwidth = 0; c>='0' && c<='9'; c = *fmt++)
                    325:                                fwidth = fwidth*10 + c-'0';
                    326:                if (c == '.') {
                    327:                        c = *fmt++;
                    328:                        if (c == '*') {
                    329:                                prec = *iap++;
                    330:                                c = *fmt++;
                    331:                        } else
                    332:                                for (prec=0; c >= '0' && c <= '9'; c = *fmt++)
                    333:                                        prec = prec*10 + c-'0';
                    334:                }
                    335:                cbp = cbs = cbuf;
                    336:                switch (c) {
                    337: 
                    338:                case 'd':
                    339:                        elem.i = *iap++;
                    340:                        if (elem.i < 0) {
                    341:                                elem.i = -elem.i;
                    342:                                *cbp++ = '-';
                    343:                        }
                    344:                        cbp = printi(cbp, elem.i, 10);
                    345:                        break;
                    346: 
                    347:                case 'u':
                    348:                        cbp = printi(cbp, *iap++, 10);
                    349:                        break;
                    350:        
                    351:                case 'o':
                    352:                        cbp = printi(cbp, *iap++, 8);
                    353:                        break;
                    354: 
                    355:                case 'x':
                    356:                        cbp = printi(cbp, *iap++, 16);
                    357:                        break;
                    358: 
                    359:                case 's':
                    360:                        if ((s = *(char **)iap) == NULL)
                    361:                                s = null;
                    362:                        bump(iap, char*);
                    363:                        /*
                    364:                         * Do %s specially so it can be longer.
                    365:                         */
                    366:                        cbp = cbs = s;
                    367:                        while (*cbp++ != '\0')
                    368:                                if (prec>=0 && cbp-s>prec)
                    369:                                        break;
                    370:                        cbp--;
                    371:                        break;
                    372:        
                    373:                case 'c':
                    374:                        elem.c = *iap++;
                    375:                        *cbp++ = elem.c;
                    376:                        break;
                    377:        
                    378:                case 'r':
                    379:                        xprintf(*(char ***)iap);
                    380:                        bump(iap, char**);
                    381:                        break;
                    382:        
                    383:                default:
                    384:                        putchar(c);
                    385:                        continue;
                    386:                }
                    387:                if ((pwidth = fwidth + cbs-cbp) < 0)
                    388:                        pwidth = 0;
                    389:                if (!adj)
                    390:                        while (pwidth-- != 0)
                    391:                                putchar(pad);
                    392:                while (cbs < cbp)
                    393:                        putchar(*cbs++);
                    394:                if (adj)
                    395:                        while (pwidth-- != 0)
                    396:                                putchar(pad);
                    397:        }
                    398: }
                    399: 
                    400: static char    digits[] = {
                    401:        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                    402:        'A', 'B', 'C', 'D', 'E', 'F'
                    403: };
                    404: 
                    405: /*
                    406:  * Print an unsigned integer in base b.
                    407:  */
                    408: static
                    409: char *
                    410: printi(cp, n, b)
                    411: char *cp;
                    412: register unsigned n;
                    413: {
                    414:        register a;
                    415:        register char *ep;
                    416:        char pbuf[10];
                    417: 
                    418:        ep = &pbuf[10];
                    419:        *--ep = 0;
                    420:        for ( ; a = n/b; n=a)
                    421:                *--ep = digits[n%b];
                    422:        *--ep = digits[n];
                    423:        while (*ep)
                    424:                *cp++ = *ep++;
                    425:        return (cp);
                    426: }
                    427: 
                    428: /* 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.