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