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