|
|
1.1 ! root 1: /* ! 2: * Keyboard/display driver for French keyboard. ! 3: * Coherent, IBM PC/XT/AT (286 and 386). ! 4: */ ! 5: #include <sys/coherent.h> ! 6: #ifdef _I386 ! 7: #include <sys/reg.h> ! 8: #else ! 9: #include <sys/i8086.h> ! 10: #endif ! 11: #include <sys/con.h> ! 12: #include <sys/devices.h> ! 13: #include <errno.h> ! 14: #include <sys/stat.h> ! 15: #include <sys/tty.h> ! 16: #include <signal.h> ! 17: #include <sys/sched.h> ! 18: #include <sys/silo.h> ! 19: ! 20: #define SPC 0376 /* Special encoding */ ! 21: #define XXX 0377 /* Non-character */ ! 22: #define KBDATA 0x60 /* Keyboard data */ ! 23: #define KBCTRL 0x61 /* Keyboard control */ ! 24: #define KBFLAG 0x80 /* Keyboard reset flag */ ! 25: #define LEDCMD 0xED /* status indicator command */ ! 26: #define KBACK 0xFA /* status indicator acknowledge */ ! 27: #define EXTENDED0 0xE0 /* extended key seq initiator */ ! 28: #define EXTENDED1 0xE1 /* extended key seq initiator */ ! 29: ! 30: #define KEYUP 0x80 /* Key up change */ ! 31: #define KEYSC 0x7F /* Key scan code mask */ ! 32: #define LSHIFT 0x2A-1 /* Left shift key */ ! 33: #define LSHIFTA 0x2B-1 /* Alternate left-shift key */ ! 34: #define RSHIFT 0x36-1 /* Right shift key */ ! 35: #define CTRL 0x1D-1 /* Control key */ ! 36: /*-- #define CAPLOCK 0x1D-1 --*/ /* Control key */ ! 37: #define ALT 0x38-1 /* Alt key or ALT GR */ ! 38: #define CAPLOCK 0x3A-1 /* Caps lock key */ ! 39: /*-- #define CTRL 0x3A-1 --*/ /* Caps lock key */ ! 40: #define NUMLOCK 0x45-1 /* Numeric lock key */ ! 41: #define DELETE 0x53-1 /* Del, as in CTRL-ALT-DEL */ ! 42: #define BACKSP 0x0E-1 /* Back space */ ! 43: #define SCRLOCK 0x46-1 /* Scroll lock */ ! 44: ! 45: /* Shift flags */ ! 46: #define SRS 0x01 /* Right shift key on */ ! 47: #define SLS 0x02 /* Left shift key on */ ! 48: #define CTS 0x04 /* Ctrl key on */ ! 49: #define ALS 0x08 /* Alt key on */ ! 50: #define CPLS 0x10 /* Caps lock on */ ! 51: #define NMLS 0x20 /* Num lock on */ ! 52: #define AKPS 0x40 /* Alternate keypad shift */ ! 53: #define SHFT 0x80 /* Shift key flag */ ! 54: #define AGS 0x100 /* Alt Graphics on */ ! 55: ! 56: /* Function key information */ ! 57: #define NFKEY 20 /* Number of settable functions */ ! 58: #define NFCHAR 150 /* Number of characters settable */ ! 59: #define NFBUF (NFKEY*2+NFCHAR+1) /* Size of buffer */ ! 60: ! 61: /* ! 62: * Functions. ! 63: */ ! 64: int isrint(); ! 65: int istime(); ! 66: void isbatch(); ! 67: int mmstart(); ! 68: int isopen(); ! 69: int isclose(); ! 70: int isread(); ! 71: int mmwrite(); ! 72: int isioctl(); ! 73: void mmwatch(); ! 74: int isload(); ! 75: int isuload(); ! 76: int ispoll(); ! 77: int nulldev(); ! 78: int nonedev(); ! 79: ! 80: /* ! 81: * Configuration table. ! 82: */ ! 83: CON iscon ={ ! 84: DFCHR|DFPOL, /* Flags */ ! 85: KB_MAJOR, /* Major index */ ! 86: isopen, /* Open */ ! 87: isclose, /* Close */ ! 88: nulldev, /* Block */ ! 89: isread, /* Read */ ! 90: mmwrite, /* Write */ ! 91: isioctl, /* Ioctl */ ! 92: nulldev, /* Powerfail */ ! 93: mmwatch, /* Timeout */ ! 94: isload, /* Load */ ! 95: isuload, /* Unload */ ! 96: ispoll /* Poll */ ! 97: }; ! 98: ! 99: /* ! 100: * Flag indicating turbo machine. ! 101: */ ! 102: int isturbo = 0; ! 103: ! 104: /* ! 105: * Terminal structure. ! 106: */ ! 107: TTY istty = { ! 108: {0}, {0}, 0, mmstart, NULL, 0, 0 ! 109: }; ! 110: ! 111: static silo_t in_silo; ! 112: ! 113: /* ! 114: * State variables. ! 115: */ ! 116: int islock; /* Keyboard locked flag */ ! 117: int isbusy; /* Raw input conversion busy */ ! 118: static short shift; /* Overall shift state */ ! 119: static char scroll; /* Scroll lock state */ ! 120: static char lshift = LSHIFT; /* Left shift alternate state */ ! 121: static char isfbuf[NFBUF]; /* Function key values */ ! 122: static char *isfval[NFKEY]; /* Function key string pointers */ ! 123: static int ledcmd; /* LED update command flag */ ! 124: static int extended; /* extended key scan count */ ! 125: static char extmode; /* use extended mode for this key */ ! 126: static char ext0seen; /* 0xE0 prefix seen */ ! 127: ! 128: /* ! 129: * Tables for converting key code to ASCII. ! 130: * lmaptab specifies unshifted conversion, ! 131: * umaptab specifies shifted conversion, ! 132: * smaptab specifies the shift states which are active. ! 133: * An entry of XXX says the key is dead. ! 134: * An entry of SPC requires further processing. ! 135: * ! 136: * Key codes: ! 137: * ESC .. <- == 1 .. 14 ! 138: * -> .. \n == 15 .. 28 ! 139: * CTRL .. ` == 29 .. 41 ! 140: * ^Shift .. PrtSc == 42 .. 55 ! 141: * ALT .. CapsLock == 56 .. 58 ! 142: * F1 .. F10 == 59 .. 68 ! 143: * NumLock .. Del == 69 .. 83 ! 144: * ISO, F11, F12 == 86 .. 88 ! 145: */ ! 146: unsigned char agmaptab[] ={ /* Alt Gr */ ! 147: XXX, XXX, '~', '#', '{', '[', '|', /* 1 - 7 */ ! 148: '`', '\\', '^', '@', ']', '}', XXX, XXX, /* 8 - 15 */ ! 149: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 16 - 23 */ ! 150: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 24 - 31 */ ! 151: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 32 - 39 */ ! 152: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 40 - 47 */ ! 153: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 48 - 55 */ ! 154: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 56 - 63 */ ! 155: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 64 - 71 */ ! 156: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 72 - 79 */ ! 157: XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, /* 80 - 87 */ ! 158: XXX /* 88 */ ! 159: }; ! 160: ! 161: static unsigned char lmaptab[] ={ ! 162: '\33', '&','\202', '"', '\'', '(', '-', /* 1 - 7 */ ! 163: '\212','_','\207','\205',')', '=', '\b', '\t', /* 8 - 15 */ ! 164: 'a', 'z', 'e', 'r', 't', 'y', 'u', 'i', /* 16 - 23 */ ! 165: 'o', 'p','\260', '$', '\r', XXX, 'q', 's', /* 24 - 31 */ ! 166: 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', /* 32 - 39 */ ! 167: '\227','\375',XXX,'*', 'w', 'x', 'c', 'v', /* 40 - 47 */ ! 168: 'b', 'n', ',', ';', ':', SPC, XXX, SPC, /* 48 - 55 */ ! 169: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ ! 170: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ ! 171: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ ! 172: SPC, SPC, SPC, SPC, XXX, XXX, '<', XXX, /* 80 - 87 */ ! 173: XXX /* 88 */ ! 174: }; ! 175: ! 176: static unsigned char umaptab[] ={ ! 177: '\33', '1', '2', '3', '4', '5', '6', /* 1 - 7 */ ! 178: '7', '8', '9', '0','\370', '+', '\b', SPC, /* 8 - 15 */ ! 179: 'A', 'Z', 'E', 'R', 'T', 'Y', 'U', 'I', /* 16 - 23 */ ! 180: 'O', 'P','\261','\234','\r', XXX, 'Q', 'S', /* 24 - 31 */ ! 181: 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', /* 32 - 39 */ ! 182: '%','\300',XXX,'\346', 'W', 'X', 'C', 'V', /* 40 - 47 */ ! 183: 'B', 'N', '?', '.', '/', SPC, XXX, SPC, /* 48 - 55 */ ! 184: XXX, ' ', XXX, SPC, SPC, SPC, SPC, SPC, /* 56 - 63 */ ! 185: SPC, SPC, SPC, SPC, SPC, SPC, SPC, SPC, /* 64 - 71 */ ! 186: SPC, SPC, '-', SPC, SPC, SPC, '+', SPC, /* 72 - 79 */ ! 187: SPC, SPC, SPC, SPC, XXX, XXX, '>', XXX, /* 80 - 87 */ ! 188: XXX /* 88 */ ! 189: }; ! 190: ! 191: #define SS0 0 /* No shift */ ! 192: #define SS1 (SLS|SRS|CTS) /* Shift, Ctrl */ ! 193: #define SES (SLS|SRS) /* Shift */ ! 194: #define LET (SLS|SRS|CPLS|CTS) /* Shift, Caps, Ctrl */ ! 195: #define KEY (SLS|SRS|NMLS|AKPS) /* Shift, Num, Alt keypad */ ! 196: ! 197: static unsigned char smaptab[] ={ ! 198: SS0, SES, SS1, SES, SES, SES, SS1, /* 1 - 7 */ ! 199: SES, SES, SES, SES, SS1, SES, CTS, SES, /* 8 - 15 */ ! 200: LET, LET, LET, LET, LET, LET, LET, LET, /* 16 - 23 */ ! 201: LET, LET, SS1, SS1, CTS, SHFT, LET, LET, /* 24 - 31 */ ! 202: LET, LET, LET, LET, LET, LET, LET, SES, /* 32 - 39 */ ! 203: SES, SS1, SHFT, SS1, LET, LET, LET, LET, /* 40 - 47 */ ! 204: LET, LET, LET, SES, SES, SES, SHFT, SES, /* 48 - 55 */ ! 205: SHFT, SS1, SHFT, SS0, SS0, SS0, SS0, SS0, /* 56 - 63 */ ! 206: SS0, SS0, SS0, SS0, SS0, SHFT, KEY, KEY, /* 64 - 71 */ ! 207: KEY, KEY, SS0, KEY, KEY, KEY, SS0, KEY, /* 72 - 79 */ ! 208: KEY, KEY, KEY, KEY, SS0, SS0, SES, SS0, /* 80 - 87 */ ! 209: SS0 ! 210: }; ! 211: ! 212: /* ! 213: * Load entry point. ! 214: * Do reset the keyboard because it gets terribly munged ! 215: * if you type during the boot. ! 216: */ ! 217: isload() ! 218: { ! 219: register short i;/* was: int i .. the loop below is hardly portable */ ! 220: ! 221: /* ! 222: * Reset keyboard if NOT an XT turbo. ! 223: */ ! 224: if ( ! isturbo ) { ! 225: outb(KBCTRL, 0x0C); /* Clock low */ ! 226: for (i = 10582; --i >= 0; ); /* For 20ms */ ! 227: outb(KBCTRL, 0xCC); /* Clock high */ ! 228: for (i = 0; --i != 0; ) ! 229: ; ! 230: i = inb(KBDATA); ! 231: outb(KBCTRL, 0xCC); /* Clear keyboard */ ! 232: outb(KBCTRL, 0x4D); /* Enable keyboard */ ! 233: } ! 234: ! 235: /* ! 236: * Enable mmwatch() invocation every second. ! 237: */ ! 238: drvl[KB_MAJOR].d_time = 1; ! 239: ! 240: /* ! 241: * Seize keyboard interrupt. ! 242: */ ! 243: setivec(1, isrint); ! 244: ! 245: /* ! 246: * Initialize video display. ! 247: */ ! 248: mmstart( &istty ); ! 249: } ! 250: ! 251: /* ! 252: * Unload entry point. ! 253: */ ! 254: isuload() ! 255: { ! 256: clrivec(1); ! 257: } ! 258: ! 259: /* ! 260: * Default function key strings (terminated by -1 [\377]) ! 261: */ ! 262: static char *deffuncs[] = { ! 263: "\33[1x\377", /* F1 */ ! 264: "\33[2x\377", /* F2 */ ! 265: "\33[3x\377", /* F3 */ ! 266: "\33[4x\377", /* F4 */ ! 267: "\33[5x\377", /* F5 */ ! 268: "\33[6x\377", /* F6 */ ! 269: "\33[7x\377", /* F7 */ ! 270: "\33[8x\377", /* F8 */ ! 271: "\33[9x\377", /* F9 */ ! 272: "\33[0x\377", /* F10 - historical value */ ! 273: "\33[1y\377", /* F11 */ ! 274: "\33[2y\377", /* F12 */ ! 275: "\33[3y\377", /* F13 */ ! 276: "\33[4y\377", /* F14 */ ! 277: "\33[5y\377", /* F15 */ ! 278: "\33[6y\377", /* F16 */ ! 279: "\33[7y\377", /* F17 */ ! 280: "\33[8y\377", /* F18 */ ! 281: "\33[9y\377", /* F19 */ ! 282: "\33[0y\377" /* F20 */ ! 283: }; ! 284: ! 285: /* ! 286: * Open routine. ! 287: */ ! 288: isopen(dev, mode) ! 289: dev_t dev; ! 290: unsigned int mode; ! 291: { ! 292: register int s; ! 293: ! 294: if (minor(dev) != 0) { ! 295: u.u_error = ENXIO; ! 296: return; ! 297: } ! 298: if ((istty.t_flags&T_EXCL)!=0 && super()==0) { ! 299: u.u_error = ENODEV; ! 300: return; ! 301: } ! 302: ttsetgrp(&istty, dev, mode); ! 303: ! 304: s = sphi(); ! 305: if (istty.t_open++ == 0) ! 306: { initkeys(); /* init function keys */ ! 307: istty.t_flags = T_CARR; /* indicate "carrier" */ ! 308: ttopen(&istty); ! 309: } ! 310: spl(s); ! 311: updleds(); /* update keyboard status LEDS */ ! 312: } ! 313: ! 314: /* Init function keys */ ! 315: initkeys() ! 316: { register int i; ! 317: register char *cp1, *cp2; ! 318: ! 319: for (i=0; i<NFKEY; i++) ! 320: isfval[i] = 0; /* clear function key buffer */ ! 321: cp2 = isfbuf; /* pointer to key buffer */ ! 322: for (i=0; i<NFKEY; i++) ! 323: { isfval[i] = cp2; /* save pointer to key string */ ! 324: cp1 = deffuncs[i]; /* get init string pointer */ ! 325: while ((*cp2++ = *cp1++) != -1) /* copy key data */ ! 326: if (cp2 >= &isfbuf[NFBUF-3]) /* overflow? */ ! 327: return; ! 328: } ! 329: } ! 330: ! 331: /* ! 332: * Close a tty. ! 333: */ ! 334: isclose(dev) ! 335: { ! 336: register int s; ! 337: ! 338: s = sphi(); ! 339: if (--istty.t_open == 0) ! 340: { s = sphi(); ! 341: ttclose(&istty); ! 342: spl(s); ! 343: } ! 344: } ! 345: ! 346: /* ! 347: * Read routine. ! 348: */ ! 349: isread(dev, iop) ! 350: dev_t dev; ! 351: IO *iop; ! 352: { ! 353: ttread(&istty, iop, 0); ! 354: if (istty.t_oq.cq_cc) ! 355: mmtime(&istty); ! 356: } ! 357: ! 358: /* ! 359: * Ioctl routine. ! 360: */ ! 361: isioctl(dev, com, vec) ! 362: dev_t dev; ! 363: struct sgttyb *vec; ! 364: { ! 365: register int s; ! 366: ! 367: switch(com) { ! 368: case TIOCSETF: ! 369: case TIOCGETF: ! 370: isfunction(com, (char *)vec); ! 371: goto ioc_done;; ! 372: case TIOCSHIFT: /* switch left-SHIFT and "\" */ ! 373: lshift = LSHIFTA; /* alternate values */ ! 374: lmaptab[41] = '\\'; ! 375: lmaptab[42] = XXX; ! 376: umaptab[41] = '|'; ! 377: umaptab[42] = XXX; ! 378: smaptab[41] = SS1; ! 379: smaptab[42] = SHFT; ! 380: goto ioc_done;; ! 381: case TIOCCSHIFT: /* normal (default) left-SHIFT and "\" */ ! 382: lshift = LSHIFT; /* normal values */ ! 383: lmaptab[41] = XXX; ! 384: lmaptab[42] = '\\'; ! 385: umaptab[41] = XXX; ! 386: umaptab[42] = '|'; ! 387: smaptab[41] = SHFT; ! 388: smaptab[42] = SS1; ! 389: goto ioc_done;; ! 390: } ! 391: s = sphi(); ! 392: ttioctl(&istty, com, vec); ! 393: spl(s); ! 394: ! 395: ioc_done: ! 396: return; ! 397: } ! 398: ! 399: /* ! 400: * Set and receive the function keys. ! 401: */ ! 402: isfunction(c, v) ! 403: int c; ! 404: char *v; ! 405: { ! 406: register char *cp; ! 407: register int i; ! 408: ! 409: if (c == TIOCGETF) { ! 410: for (cp = isfbuf; cp < &isfbuf[NFBUF]; cp++) ! 411: putubd(v++, *cp); ! 412: } else { ! 413: for (i=0; i<NFKEY; i++) /* zap current settings */ ! 414: isfval[i] = 0; ! 415: cp = isfbuf; /* pointer to key buffer */ ! 416: for (i=0; i<NFKEY; i++) { ! 417: isfval[i] = cp; /* save pointer to key string */ ! 418: while ((*cp++ = getubd(v++)) != -1) /* copy key data */ ! 419: if (cp >= &isfbuf[NFBUF-3]) /* overflow? */ ! 420: return; ! 421: } ! 422: } ! 423: } ! 424: ! 425: ! 426: /* ! 427: * Poll routine. ! 428: */ ! 429: ispoll( dev, ev, msec ) ! 430: dev_t dev; ! 431: int ev; ! 432: int msec; ! 433: { ! 434: return ttpoll(&istty, ev, msec); ! 435: } ! 436: ! 437: /* ! 438: * Receive interrupt. ! 439: */ ! 440: isrint() ! 441: { ! 442: register int c; ! 443: register int s; ! 444: register int r; ! 445: int savests; ! 446: int update_leds = 0; ! 447: ! 448: /* ! 449: * Schedule raw input handler if not already active. ! 450: */ ! 451: if ( isbusy == 0 ) { ! 452: isbusy = 1; ! 453: defer( isbatch, &istty ); ! 454: } ! 455: ! 456: /* ! 457: * Pull character from the data ! 458: * port. Pulse the KBFLAG in the control ! 459: * port to reset the data buffer. ! 460: */ ! 461: r = inb(KBDATA) & 0xFF; ! 462: c = inb(KBCTRL); ! 463: outb(KBCTRL, c|KBFLAG); ! 464: outb(KBCTRL, c); ! 465: #if KBDEBUG ! 466: printf("kbd: %d\n", r); /* print scan code/direction */ ! 467: #endif ! 468: if (ledcmd) { ! 469: ledcmd = 0; ! 470: if (r == KBACK) { /* output to status LEDS */ ! 471: c = scroll & 1; ! 472: if (shift & NMLS) ! 473: c |= 2; ! 474: if (shift & CPLS) ! 475: c |= 4; ! 476: outb(KBDATA, c); ! 477: } ! 478: return; ! 479: } ! 480: if (extended > 0) { /* if multi-character seq, */ ! 481: --extended; /* ... ignore this char */ ! 482: return; ! 483: } ! 484: switch (r) { ! 485: case EXTENDED0: /* 0xE0 prefix found */ ! 486: ext0seen = 1; ! 487: return; ! 488: case EXTENDED1: /* ignore extended sequences */ ! 489: extended = 5; ! 490: return; ! 491: case 0xFF: /* Overrun */ ! 492: return; ! 493: } ! 494: ! 495: if (ext0seen) { ! 496: ext0seen = 0; ! 497: extmode = 1; ! 498: } else ! 499: extmode = 0; ! 500: ! 501: c = (r & KEYSC) - 1; ! 502: /* ! 503: * Check for reset. ! 504: */ ! 505: if ((r&KEYUP) == 0 && c == DELETE && (shift&(CTS|ALS)) == (CTS|ALS)) ! 506: boot(); ! 507: ! 508: /* ! 509: * Track "shift" keys. ! 510: */ ! 511: s = smaptab[c]; ! 512: if (s&SHFT) { ! 513: if (r&KEYUP) { /* "shift" released */ ! 514: if (c == RSHIFT) ! 515: shift &= ~SRS; ! 516: else if (c == lshift) ! 517: shift &= ~SLS; ! 518: else if (c == CTRL) ! 519: shift &= ~CTS; ! 520: else if (c == ALT) ! 521: shift &= extmode ? ~AGS : ~ALS; ! 522: } else { /* "shift" pressed */ ! 523: if (c == lshift) ! 524: shift |= SLS; ! 525: else if (c == RSHIFT) ! 526: shift |= SRS; ! 527: else if (c == CTRL) ! 528: shift |= CTS; ! 529: else if (c == ALT) ! 530: shift |= extmode ? AGS : ALS; ! 531: else if (c == CAPLOCK) { ! 532: shift ^= CPLS; /* toggle cap lock */ ! 533: updleds(); ! 534: } else if (c == NUMLOCK) { ! 535: shift ^= NMLS; /* toggle num lock */ ! 536: updleds(); ! 537: } ! 538: } ! 539: return; ! 540: } ! 541: ! 542: /* ! 543: * No other key up codes of interest. ! 544: */ ! 545: if (r&KEYUP) ! 546: return; ! 547: ! 548: /* ! 549: * If the tty is not open the character is ! 550: * just tossed away. ! 551: */ ! 552: if (istty.t_open == 0) ! 553: return; ! 554: ! 555: /* ! 556: * Map character, based on the ! 557: * current state of the shift, control, alt graphics, ! 558: * meta (ALT) and lock flags. ! 559: */ ! 560: if (shift & AGS) /* Alt Graphics ? */ ! 561: c = agmaptab[c]; ! 562: else if (shift & CTS) { ! 563: if (s == CTS) /* Map Ctrl (BS | NL) */ ! 564: c = (c == BACKSP) ? 0x7F : 0x0A; ! 565: else if (s==SS1 || s==LET) /* Normal Ctrl map */ ! 566: c = umaptab[c]&0x1F; /* Clear bits 5-6 */ ! 567: else ! 568: return; /* Ignore this char */ ! 569: } else if (s &= shift) { ! 570: if (shift & SES) { /* if shift on */ ! 571: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 572: c = lmaptab[c]; /* use unshifted */ ! 573: else ! 574: c = umaptab[c]; /* use shifted */ ! 575: } else { /* if shift not on */ ! 576: if (s & (CPLS|NMLS)) /* if caps/num lock */ ! 577: c = umaptab[c]; /* use shifted */ ! 578: else ! 579: c = lmaptab[c]; /* use unshifted */ ! 580: } ! 581: } else ! 582: c = lmaptab[c]; /* use unshifted */ ! 583: ! 584: /* ! 585: * Act on character. ! 586: */ ! 587: if (c == XXX) ! 588: return; /* char to ignore */ ! 589: ! 590: if (c != SPC) { /* not special char? */ ! 591: if (shift & ALS) /* ALT (meta bit)? */ ! 592: c |= 0x80; /* set meta */ ! 593: isin(c); /* send the char */ ! 594: } else ! 595: update_leds += isspecial(r); /* special chars */ ! 596: if (update_leds) { ! 597: savests = sphi(); ! 598: outb(KBDATA, LEDCMD); ! 599: ledcmd = 1; ! 600: spl(savests); ! 601: } ! 602: } ! 603: ! 604: /* ! 605: * Handle special input sequences. ! 606: * The character passed is the key number. ! 607: * ! 608: * The keypad is translated by the following table, ! 609: * the first entry is the normal sequence, the second the shifted, ! 610: * and the third the alternate keypad sequence. ! 611: */ ! 612: static char *keypad[][3] = { ! 613: { "\33[H", "7", "\33?w" }, /* 71 */ ! 614: { "\33[A", "8", "\33?x" }, /* 72 */ ! 615: { "\33[V", "9", "\33?y" }, /* 73 */ ! 616: { "\33[D", "4", "\33?t" }, /* 75 */ ! 617: { "\0337", "5", "\33?u" }, /* 76 */ ! 618: { "\33[C", "6", "\33?v" }, /* 77 */ ! 619: { "\33[24H","1", "\33?q" }, /* 79 */ ! 620: { "\33[B", "2", "\33?r" }, /* 80 */ ! 621: { "\33[U", "3", "\33?s" }, /* 81 */ ! 622: { "\33[@", "0", "\33?p" }, /* 82 */ ! 623: { "\33[P", ".", "\33?n" } /* 83 */ ! 624: }; ! 625: ! 626: isspecial(c) ! 627: int c; ! 628: { ! 629: register char *cp; ! 630: register int s; ! 631: int update_leds = 0; ! 632: ! 633: cp = 0; ! 634: ! 635: switch (c) { ! 636: case 15: /* cursor back tab */ ! 637: cp = "\033[Z"; ! 638: break; ! 639: case 53: ! 640: if (extmode) ! 641: cp = "/"; ! 642: else if (shift & SES) ! 643: cp = "\025"; ! 644: else ! 645: cp = "!"; ! 646: break; ! 647: case 55: /* ignore PrtScr */ ! 648: if (!extmode) ! 649: cp = "*"; ! 650: break; ! 651: case 59: case 60: case 61: case 62: case 63: /* Function keys */ ! 652: case 64: case 65: case 66: case 67: case 68: ! 653: /* offset to function string */ ! 654: if ( shift & ALS ) ! 655: cp = isfval[c-49]; ! 656: else ! 657: cp = isfval[c-59]; ! 658: break; ! 659: ! 660: case 70: /* Scroll Lock -- stop/start output */ ! 661: { ! 662: static char cbuf[2]; ! 663: ! 664: cp = &cbuf[0]; /* working buffer */ ! 665: if (!(istty.t_sgttyb.sg_flags&RAWIN)) { /* not if in RAW mode */ ! 666: ++update_leds; ! 667: if (istty.t_flags & T_STOP) { /* output stopped? */ ! 668: cbuf[0] = istty.t_tchars.t_startc; /* start it */ ! 669: scroll = 0; ! 670: } else { ! 671: cbuf[0] = istty.t_tchars.t_stopc; /* stop output */ ! 672: scroll = 1; ! 673: } ! 674: } ! 675: break; ! 676: } ! 677: ! 678: case 79: /* 1/End */ ! 679: case 80: /* 2/DOWN */ ! 680: case 81: /* 3/PgDn */ ! 681: case 82: /* 0/Ins */ ! 682: case 83: /* ./Del */ ! 683: --c; /* adjust code */ ! 684: case 75: /* 4/LEFT */ ! 685: case 76: /* 5 */ ! 686: case 77: /* 6/RIGHT */ ! 687: --c; /* adjust code */ ! 688: case 71: /* 7/Home/Clear */ ! 689: case 72: /* 8/UP */ ! 690: case 73: /* 9/PgUp */ ! 691: s = 0; /* start off with normal keypad */ ! 692: if (shift & NMLS) /* num lock? */ ! 693: s = 1; /* set shift pad */ ! 694: if (shift & SES) /* shift? */ ! 695: s ^= 1; /* toggle shift pad */ ! 696: if (shift & AKPS) /* alternate pad? */ ! 697: s = 2; /* set alternate pad */ ! 698: if (extmode) /* not from keypad? */ ! 699: s = 0; /* force normal sequence */ ! 700: cp = keypad[c-71][s]; /* get keypad value */ ! 701: break; ! 702: } ! 703: if (cp) /* send string */ ! 704: while ((*cp != 0) && (*cp != -1)) ! 705: isin( *cp++ & 0377 ); ! 706: return update_leds; ! 707: } ! 708: ! 709: /** ! 710: * ! 711: * void ! 712: * ismmfunc( c ) -- process keyboard related output escape sequences ! 713: * char c; ! 714: */ ! 715: void ! 716: ismmfunc(c) ! 717: register int c; ! 718: { ! 719: switch (c) { ! 720: case 't': /* Enter numlock */ ! 721: shift |= NMLS; ! 722: updleds(); /* update LED status */ ! 723: break; ! 724: case 'u': /* Leave numlock */ ! 725: shift &= ~NMLS; ! 726: updleds(); /* update LED status */ ! 727: break; ! 728: case '=': /* Enter alternate keypad */ ! 729: shift |= AKPS; ! 730: break; ! 731: case '>': /* Exit alternate keypad */ ! 732: shift &= ~AKPS; ! 733: break; ! 734: case 'c': /* Reset terminal */ ! 735: islock = 0; ! 736: shift = 0; ! 737: initkeys(); ! 738: updleds(); /* update LED status */ ! 739: break; ! 740: } ! 741: } ! 742: ! 743: /** ! 744: * ! 745: * void ! 746: * isin( c ) -- append character to raw input silo ! 747: * char c; ! 748: */ ! 749: static ! 750: isin( c ) ! 751: register int c; ! 752: { ! 753: int cache_it = 1; ! 754: TTY * tp = &istty; ! 755: ! 756: /* ! 757: * If using software incoming flow control, process and ! 758: * discard t_stopc and t_startc. ! 759: */ ! 760: if (ISIXON) { ! 761: #if _I386 ! 762: if (ISSTART || (ISIXANY && ISXSTOP)) { ! 763: tp->t_flags &= ~(T_STOP | T_XSTOP); ! 764: ttstart(tp); ! 765: cache_it = 0; ! 766: } else if (ISSTOP) { ! 767: if ((tp->t_flags&T_STOP) == 0) ! 768: tp->t_flags |= (T_STOP | T_XSTOP); ! 769: cache_it = 0; ! 770: } ! 771: #else ! 772: if (ISSTOP) { ! 773: if ((tp->t_flags&T_STOP) == 0) ! 774: tp->t_flags |= T_STOP; ! 775: cache_it = 0; ! 776: } ! 777: if (ISSTART) { ! 778: tp->t_flags &= ~T_STOP; ! 779: ttstart(tp); ! 780: cache_it = 0; ! 781: } ! 782: #endif ! 783: } ! 784: ! 785: /* ! 786: * Cache received character. ! 787: */ ! 788: if (cache_it) { ! 789: in_silo.si_buf[ in_silo.si_ix ] = c; ! 790: ! 791: if ( ++in_silo.si_ix >= sizeof(in_silo.si_buf) ) ! 792: in_silo.si_ix = 0; ! 793: } ! 794: } ! 795: ! 796: /** ! 797: * ! 798: * void ! 799: * isbatch() -- raw input conversion routine ! 800: * ! 801: * Action: Enable the video display. ! 802: * Canonize the raw input silo. ! 803: * ! 804: * Notes: isbatch() was scheduled as a deferred process by isrint(). ! 805: */ ! 806: static void ! 807: isbatch( tp ) ! 808: register TTY * tp; ! 809: { ! 810: register int c; ! 811: static int lastc; ! 812: ! 813: /* ! 814: * Ensure video display is enabled. ! 815: */ ! 816: mm_von(); ! 817: ! 818: isbusy = 0; ! 819: ! 820: /* ! 821: * Process all cached characters. ! 822: */ ! 823: while ( in_silo.si_ix != in_silo.si_ox ) { ! 824: ! 825: /* ! 826: * Get next cached char. ! 827: */ ! 828: c = in_silo.si_buf[ in_silo.si_ox ]; ! 829: ! 830: if ( in_silo.si_ox >= sizeof(in_silo.si_buf) - 1 ) ! 831: in_silo.si_ox = 0; ! 832: else ! 833: in_silo.si_ox++; ! 834: ! 835: if ( (islock == 0) || ISINTR || ISQUIT ) { ! 836: ttin( tp, c ); ! 837: } ! 838: ! 839: else if ( (c == 'b') && (lastc == '\033') ) { ! 840: islock = 0; ! 841: ttin( tp, lastc ); ! 842: ttin( tp, c ); ! 843: } ! 844: ! 845: else if ( (c == 'c') && (lastc == '\033') ) { ! 846: ttin( tp, lastc ); ! 847: ttin( tp, c ); ! 848: } ! 849: ! 850: else ! 851: putchar('\007'); ! 852: ! 853: lastc = c; ! 854: } ! 855: } ! 856: ! 857: /* ! 858: * update the keyboard status LEDS ! 859: */ ! 860: updleds() ! 861: { ! 862: int s; ! 863: ! 864: s = sphi(); ! 865: outb(KBDATA, LEDCMD); ! 866: ledcmd = 1; ! 867: spl(s); ! 868: } ! 869: ! 870: /* ! 871: * unlock the scroll in case an interrupt character is received ! 872: */ ! 873: kbunscroll() ! 874: { ! 875: scroll = 0; ! 876: updleds(); ! 877: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.