|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 University of Utah. ! 3: * Copyright (c) 1990 The Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * This code is derived from software contributed to Berkeley by ! 7: * the Systems Programming Group of the University of Utah Computer ! 8: * Science Department. ! 9: * ! 10: * Redistribution and use in source and binary forms, with or without ! 11: * modification, are permitted provided that the following conditions ! 12: * are met: ! 13: * 1. Redistributions of source code must retain the above copyright ! 14: * notice, this list of conditions and the following disclaimer. ! 15: * 2. Redistributions in binary form must reproduce the above copyright ! 16: * notice, this list of conditions and the following disclaimer in the ! 17: * documentation and/or other materials provided with the distribution. ! 18: * 3. All advertising materials mentioning features or use of this software ! 19: * must display the following acknowledgement: ! 20: * This product includes software developed by the University of ! 21: * California, Berkeley and its contributors. ! 22: * 4. Neither the name of the University nor the names of its contributors ! 23: * may be used to endorse or promote products derived from this software ! 24: * without specific prior written permission. ! 25: * ! 26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 36: * SUCH DAMAGE. ! 37: * ! 38: * from: Utah $Hdr: ite.c 1.1 90/07/09$ ! 39: * ! 40: * @(#)ite.c 7.6 (Berkeley) 5/16/91 ! 41: */ ! 42: ! 43: /* ! 44: * Bit-mapped display terminal emulator machine independent code. ! 45: * This is a very rudimentary. Much more can be abstracted out of ! 46: * the hardware dependent routines. ! 47: */ ! 48: #include "ite.h" ! 49: #if NITE > 0 ! 50: ! 51: #include "grf.h" ! 52: ! 53: #undef NITE ! 54: #define NITE NGRF ! 55: ! 56: #include "param.h" ! 57: #include "conf.h" ! 58: #include "proc.h" ! 59: #include "ioctl.h" ! 60: #include "tty.h" ! 61: #include "systm.h" ! 62: #include "malloc.h" ! 63: ! 64: #include "itevar.h" ! 65: #include "iteioctl.h" ! 66: #include "kbdmap.h" ! 67: ! 68: #include "machine/cpu.h" ! 69: ! 70: #define set_attr(ip, attr) ((ip)->attribute |= (attr)) ! 71: #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr)) ! 72: ! 73: extern int nodev(); ! 74: ! 75: int topcat_scroll(), topcat_init(), topcat_deinit(); ! 76: int topcat_clear(), topcat_putc(), topcat_cursor(); ! 77: int gatorbox_scroll(), gatorbox_init(), gatorbox_deinit(); ! 78: int gatorbox_clear(), gatorbox_putc(), gatorbox_cursor(); ! 79: int rbox_scroll(), rbox_init(), rbox_deinit(); ! 80: int rbox_clear(), rbox_putc(), rbox_cursor(); ! 81: int dvbox_scroll(), dvbox_init(), dvbox_deinit(); ! 82: int dvbox_clear(), dvbox_putc(), dvbox_cursor(); ! 83: ! 84: struct itesw itesw[] = ! 85: { ! 86: topcat_init, topcat_deinit, topcat_clear, ! 87: topcat_putc, topcat_cursor, topcat_scroll, ! 88: ! 89: gatorbox_init, gatorbox_deinit, gatorbox_clear, ! 90: gatorbox_putc, gatorbox_cursor, gatorbox_scroll, ! 91: ! 92: rbox_init, rbox_deinit, rbox_clear, ! 93: rbox_putc, rbox_cursor, rbox_scroll, ! 94: ! 95: dvbox_init, dvbox_deinit, dvbox_clear, ! 96: dvbox_putc, dvbox_cursor, dvbox_scroll, ! 97: }; ! 98: ! 99: /* ! 100: * # of chars are output in a single itestart() call. ! 101: * If this is too big, user processes will be blocked out for ! 102: * long periods of time while we are emptying the queue in itestart(). ! 103: * If it is too small, console output will be very ragged. ! 104: */ ! 105: int iteburst = 64; ! 106: ! 107: int nite = NITE; ! 108: struct tty *kbd_tty = NULL; ! 109: struct tty ite_tty[NITE]; ! 110: struct ite_softc ite_softc[NITE]; ! 111: ! 112: int itestart(); ! 113: extern int ttrstrt(); ! 114: extern struct tty *constty; ! 115: ! 116: /* ! 117: * Primary attribute buffer to be used by the first bitmapped console ! 118: * found. Secondary displays alloc the attribute buffer as needed. ! 119: * Size is based on a 68x128 display, which is currently our largest. ! 120: */ ! 121: u_char console_attributes[0x2200]; ! 122: ! 123: /* ! 124: * Perform functions necessary to setup device as a terminal emulator. ! 125: */ ! 126: iteon(dev, flag) ! 127: dev_t dev; ! 128: { ! 129: int unit = UNIT(dev); ! 130: struct tty *tp = &ite_tty[unit]; ! 131: struct ite_softc *ip = &ite_softc[unit]; ! 132: ! 133: if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0) ! 134: return(ENXIO); ! 135: /* force ite active, overriding graphics mode */ ! 136: if (flag & 1) { ! 137: ip->flags |= ITE_ACTIVE; ! 138: ip->flags &= ~(ITE_INGRF|ITE_INITED); ! 139: } ! 140: /* leave graphics mode */ ! 141: if (flag & 2) { ! 142: ip->flags &= ~ITE_INGRF; ! 143: if ((ip->flags & ITE_ACTIVE) == 0) ! 144: return(0); ! 145: } ! 146: ip->flags |= ITE_ACTIVE; ! 147: if (ip->flags & ITE_INGRF) ! 148: return(0); ! 149: if (kbd_tty == NULL || kbd_tty == tp) { ! 150: kbd_tty = tp; ! 151: kbdenable(); ! 152: } ! 153: iteinit(dev); ! 154: return(0); ! 155: } ! 156: ! 157: iteinit(dev) ! 158: dev_t dev; ! 159: { ! 160: int unit = UNIT(dev); ! 161: struct ite_softc *ip = &ite_softc[unit]; ! 162: ! 163: if (ip->flags & ITE_INITED) ! 164: return; ! 165: ! 166: ip->curx = 0; ! 167: ip->cury = 0; ! 168: ip->cursorx = 0; ! 169: ip->cursory = 0; ! 170: ! 171: (*itesw[ip->type].ite_init)(ip); ! 172: (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR); ! 173: ! 174: ip->attribute = 0; ! 175: if (ip->attrbuf == NULL) ! 176: ip->attrbuf = (u_char *) ! 177: malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK); ! 178: bzero(ip->attrbuf, (ip->rows * ip->cols)); ! 179: ! 180: ip->imode = 0; ! 181: ip->flags |= ITE_INITED; ! 182: } ! 183: ! 184: /* ! 185: * "Shut down" device as terminal emulator. ! 186: * Note that we do not deinit the console device unless forced. ! 187: * Deinit'ing the console every time leads to a very active ! 188: * screen when processing /etc/rc. ! 189: */ ! 190: iteoff(dev, flag) ! 191: dev_t dev; ! 192: { ! 193: register struct ite_softc *ip = &ite_softc[UNIT(dev)]; ! 194: ! 195: if (flag & 2) ! 196: ip->flags |= ITE_INGRF; ! 197: if ((ip->flags & ITE_ACTIVE) == 0) ! 198: return; ! 199: if ((flag & 1) || ! 200: (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) ! 201: (*itesw[ip->type].ite_deinit)(ip); ! 202: if ((flag & 2) == 0) ! 203: ip->flags &= ~ITE_ACTIVE; ! 204: } ! 205: ! 206: /* ARGSUSED */ ! 207: #ifdef __STDC__ ! 208: iteopen(dev_t dev, int mode, int devtype, struct proc *p) ! 209: #else ! 210: iteopen(dev, mode, devtype, p) ! 211: dev_t dev; ! 212: int mode, devtype; ! 213: struct proc *p; ! 214: #endif ! 215: { ! 216: int unit = UNIT(dev); ! 217: register struct tty *tp = &ite_tty[unit]; ! 218: register struct ite_softc *ip = &ite_softc[unit]; ! 219: register int error; ! 220: int first = 0; ! 221: ! 222: if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE) ! 223: && p->p_ucred->cr_uid != 0) ! 224: return (EBUSY); ! 225: if ((ip->flags & ITE_ACTIVE) == 0) { ! 226: error = iteon(dev, 0); ! 227: if (error) ! 228: return (error); ! 229: first = 1; ! 230: } ! 231: tp->t_oproc = itestart; ! 232: tp->t_param = NULL; ! 233: tp->t_dev = dev; ! 234: if ((tp->t_state&TS_ISOPEN) == 0) { ! 235: ttychars(tp); ! 236: tp->t_iflag = TTYDEF_IFLAG; ! 237: tp->t_oflag = TTYDEF_OFLAG; ! 238: tp->t_cflag = CS8|CREAD; ! 239: tp->t_lflag = TTYDEF_LFLAG; ! 240: tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; ! 241: tp->t_state = TS_ISOPEN|TS_CARR_ON; ! 242: ttsetwater(tp); ! 243: } ! 244: error = (*linesw[tp->t_line].l_open)(dev, tp); ! 245: if (error == 0) { ! 246: tp->t_winsize.ws_row = ip->rows; ! 247: tp->t_winsize.ws_col = ip->cols; ! 248: } else if (first) ! 249: iteoff(dev, 0); ! 250: return (error); ! 251: } ! 252: ! 253: /*ARGSUSED*/ ! 254: iteclose(dev, flag, mode, p) ! 255: dev_t dev; ! 256: int flag, mode; ! 257: struct proc *p; ! 258: { ! 259: register struct tty *tp = &ite_tty[UNIT(dev)]; ! 260: ! 261: (*linesw[tp->t_line].l_close)(tp, flag); ! 262: ttyclose(tp); ! 263: iteoff(dev, 0); ! 264: return(0); ! 265: } ! 266: ! 267: iteread(dev, uio, flag) ! 268: dev_t dev; ! 269: struct uio *uio; ! 270: { ! 271: register struct tty *tp = &ite_tty[UNIT(dev)]; ! 272: ! 273: return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); ! 274: } ! 275: ! 276: itewrite(dev, uio, flag) ! 277: dev_t dev; ! 278: struct uio *uio; ! 279: { ! 280: int unit = UNIT(dev); ! 281: register struct tty *tp = &ite_tty[unit]; ! 282: ! 283: if ((ite_softc[unit].flags & ITE_ISCONS) && constty && ! 284: (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) ! 285: tp = constty; ! 286: return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); ! 287: } ! 288: ! 289: iteioctl(dev, cmd, addr, flag) ! 290: dev_t dev; ! 291: caddr_t addr; ! 292: { ! 293: register struct tty *tp = &ite_tty[UNIT(dev)]; ! 294: int error; ! 295: ! 296: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag); ! 297: if (error >= 0) ! 298: return (error); ! 299: error = ttioctl(tp, cmd, addr, flag); ! 300: if (error >= 0) ! 301: return (error); ! 302: return (ENOTTY); ! 303: } ! 304: ! 305: itestart(tp) ! 306: register struct tty *tp; ! 307: { ! 308: register int cc, s; ! 309: int hiwat = 0; ! 310: ! 311: s = spltty(); ! 312: if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { ! 313: splx(s); ! 314: return; ! 315: } ! 316: tp->t_state |= TS_BUSY; ! 317: cc = tp->t_outq.c_cc; ! 318: if (cc <= tp->t_lowat) { ! 319: if (tp->t_state & TS_ASLEEP) { ! 320: tp->t_state &= ~TS_ASLEEP; ! 321: wakeup(&tp->t_outq); ! 322: } ! 323: if (tp->t_wsel) { ! 324: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); ! 325: tp->t_wsel = 0; ! 326: tp->t_state &= ~TS_WCOLL; ! 327: } ! 328: } ! 329: /* ! 330: * Limit the amount of output we do in one burst ! 331: * to prevent hogging the CPU. ! 332: */ ! 333: if (cc > iteburst) { ! 334: hiwat++; ! 335: cc = iteburst; ! 336: } ! 337: while (--cc >= 0) { ! 338: register int c; ! 339: ! 340: c = getc(&tp->t_outq); ! 341: /* ! 342: * iteputchar() may take a long time and we don't want to ! 343: * block all interrupts for long periods of time. Since ! 344: * there is no need to stay at high priority while outputing ! 345: * the character (since we don't have to worry about ! 346: * interrupts), we don't. We just need to make sure that ! 347: * we don't reenter iteputchar, which is guarenteed by the ! 348: * earlier setting of TS_BUSY. ! 349: */ ! 350: splx(s); ! 351: iteputchar(c, tp->t_dev); ! 352: spltty(); ! 353: } ! 354: if (hiwat) { ! 355: tp->t_state |= TS_TIMEOUT; ! 356: timeout(ttrstrt, tp, 1); ! 357: } ! 358: tp->t_state &= ~TS_BUSY; ! 359: splx(s); ! 360: } ! 361: ! 362: itefilter(stat, c) ! 363: register char stat, c; ! 364: { ! 365: static int capsmode = 0; ! 366: static int metamode = 0; ! 367: register char code, *str; ! 368: ! 369: if (kbd_tty == NULL) ! 370: return; ! 371: ! 372: switch (c & 0xFF) { ! 373: case KBD_CAPSLOCK: ! 374: capsmode = !capsmode; ! 375: return; ! 376: ! 377: case KBD_EXT_LEFT_DOWN: ! 378: case KBD_EXT_RIGHT_DOWN: ! 379: metamode = 1; ! 380: return; ! 381: ! 382: case KBD_EXT_LEFT_UP: ! 383: case KBD_EXT_RIGHT_UP: ! 384: metamode = 0; ! 385: return; ! 386: } ! 387: ! 388: c &= KBD_CHARMASK; ! 389: switch ((stat>>KBD_SSHIFT) & KBD_SMASK) { ! 390: ! 391: case KBD_KEY: ! 392: if (!capsmode) { ! 393: code = kbd_keymap[c]; ! 394: break; ! 395: } ! 396: /* fall into... */ ! 397: ! 398: case KBD_SHIFT: ! 399: code = kbd_shiftmap[c]; ! 400: break; ! 401: ! 402: case KBD_CTRL: ! 403: code = kbd_ctrlmap[c]; ! 404: break; ! 405: ! 406: case KBD_CTRLSHIFT: ! 407: code = kbd_ctrlshiftmap[c]; ! 408: break; ! 409: } ! 410: ! 411: if (code == NULL && (str = kbd_stringmap[c]) != NULL) { ! 412: while (*str) ! 413: (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); ! 414: } else { ! 415: if (metamode) ! 416: code |= 0x80; ! 417: (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); ! 418: } ! 419: } ! 420: ! 421: iteputchar(c, dev) ! 422: register int c; ! 423: dev_t dev; ! 424: { ! 425: int unit = UNIT(dev); ! 426: register struct ite_softc *ip = &ite_softc[unit]; ! 427: register struct itesw *sp = &itesw[ip->type]; ! 428: register int n; ! 429: ! 430: if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) ! 431: return; ! 432: ! 433: if (ip->escape) { ! 434: doesc: ! 435: switch (ip->escape) { ! 436: ! 437: case '&': /* Next can be a,d, or s */ ! 438: if (ip->fpd++) { ! 439: ip->escape = c; ! 440: ip->fpd = 0; ! 441: } ! 442: return; ! 443: ! 444: case 'a': /* cursor change */ ! 445: switch (c) { ! 446: ! 447: case 'Y': /* Only y coord. */ ! 448: ip->cury = MIN(ip->pos, ip->rows-1); ! 449: ip->pos = 0; ! 450: ip->escape = 0; ! 451: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 452: clr_attr(ip, ATTR_INV); ! 453: break; ! 454: ! 455: case 'y': /* y coord first */ ! 456: ip->cury = MIN(ip->pos, ip->rows-1); ! 457: ip->pos = 0; ! 458: ip->fpd = 0; ! 459: break; ! 460: ! 461: case 'C': /* x coord */ ! 462: ip->curx = MIN(ip->pos, ip->cols-1); ! 463: ip->pos = 0; ! 464: ip->escape = 0; ! 465: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 466: clr_attr(ip, ATTR_INV); ! 467: break; ! 468: ! 469: default: /* Possibly a 3 digit number. */ ! 470: if (c >= '0' && c <= '9' && ip->fpd < 3) { ! 471: ip->pos = ip->pos * 10 + (c - '0'); ! 472: ip->fpd++; ! 473: } else { ! 474: ip->pos = 0; ! 475: ip->escape = 0; ! 476: } ! 477: break; ! 478: } ! 479: return; ! 480: ! 481: case 'd': /* attribute change */ ! 482: switch (c) { ! 483: ! 484: case 'B': ! 485: set_attr(ip, ATTR_INV); ! 486: break; ! 487: case 'D': ! 488: /* XXX: we don't do anything for underline */ ! 489: set_attr(ip, ATTR_UL); ! 490: break; ! 491: case '@': ! 492: clr_attr(ip, ATTR_ALL); ! 493: break; ! 494: } ! 495: ip->escape = 0; ! 496: return; ! 497: ! 498: case 's': /* keypad control */ ! 499: switch (ip->fpd) { ! 500: ! 501: case 0: ! 502: ip->hold = c; ! 503: ip->fpd++; ! 504: return; ! 505: ! 506: case 1: ! 507: if (c == 'A') { ! 508: switch (ip->hold) { ! 509: ! 510: case '0': ! 511: clr_attr(ip, ATTR_KPAD); ! 512: break; ! 513: case '1': ! 514: set_attr(ip, ATTR_KPAD); ! 515: break; ! 516: } ! 517: } ! 518: ip->hold = 0; ! 519: } ! 520: ip->escape = 0; ! 521: return; ! 522: ! 523: case 'i': /* back tab */ ! 524: if (ip->curx > TABSIZE) { ! 525: n = ip->curx - (ip->curx & (TABSIZE - 1)); ! 526: ip->curx -= n; ! 527: } else ! 528: ip->curx = 0; ! 529: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 530: ip->escape = 0; ! 531: return; ! 532: ! 533: case '3': /* clear all tabs */ ! 534: goto ignore; ! 535: ! 536: case 'K': /* clear_eol */ ! 537: ite_clrtoeol(ip, sp, ip->cury, ip->curx); ! 538: ip->escape = 0; ! 539: return; ! 540: ! 541: case 'J': /* clear_eos */ ! 542: ite_clrtoeos(ip, sp); ! 543: ip->escape = 0; ! 544: return; ! 545: ! 546: case 'B': /* cursor down 1 line */ ! 547: if (++ip->cury == ip->rows) { ! 548: --ip->cury; ! 549: (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); ! 550: ite_clrtoeol(ip, sp, ip->cury, 0); ! 551: } ! 552: else ! 553: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 554: clr_attr(ip, ATTR_INV); ! 555: ip->escape = 0; ! 556: return; ! 557: ! 558: case 'C': /* cursor forward 1 char */ ! 559: ip->escape = 0; ! 560: itecheckwrap(ip, sp); ! 561: return; ! 562: ! 563: case 'A': /* cursor up 1 line */ ! 564: if (ip->cury > 0) { ! 565: ip->cury--; ! 566: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 567: } ! 568: ip->escape = 0; ! 569: clr_attr(ip, ATTR_INV); ! 570: return; ! 571: ! 572: case 'P': /* delete character */ ! 573: ite_dchar(ip, sp); ! 574: ip->escape = 0; ! 575: return; ! 576: ! 577: case 'M': /* delete line */ ! 578: ite_dline(ip, sp); ! 579: ip->escape = 0; ! 580: return; ! 581: ! 582: case 'Q': /* enter insert mode */ ! 583: ip->imode = 1; ! 584: ip->escape = 0; ! 585: return; ! 586: ! 587: case 'R': /* exit insert mode */ ! 588: ip->imode = 0; ! 589: ip->escape = 0; ! 590: return; ! 591: ! 592: case 'L': /* insert blank line */ ! 593: ite_iline(ip, sp); ! 594: ip->escape = 0; ! 595: return; ! 596: ! 597: case 'h': /* home key */ ! 598: ip->cury = ip->curx = 0; ! 599: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 600: ip->escape = 0; ! 601: return; ! 602: ! 603: case 'D': /* left arrow key */ ! 604: if (ip->curx > 0) { ! 605: ip->curx--; ! 606: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 607: } ! 608: ip->escape = 0; ! 609: return; ! 610: ! 611: case '1': /* set tab in all rows */ ! 612: goto ignore; ! 613: ! 614: case ESC: ! 615: if ((ip->escape = c) == ESC) ! 616: break; ! 617: ip->fpd = 0; ! 618: goto doesc; ! 619: ! 620: default: ! 621: ignore: ! 622: ip->escape = 0; ! 623: return; ! 624: ! 625: } ! 626: } ! 627: ! 628: switch (c &= 0x7F) { ! 629: ! 630: case '\n': ! 631: ! 632: if (++ip->cury == ip->rows) { ! 633: --ip->cury; ! 634: (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); ! 635: ite_clrtoeol(ip, sp, ip->cury, 0); ! 636: } ! 637: else ! 638: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 639: clr_attr(ip, ATTR_INV); ! 640: break; ! 641: ! 642: case '\r': ! 643: if (ip->curx) { ! 644: ip->curx = 0; ! 645: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 646: } ! 647: break; ! 648: ! 649: case '\b': ! 650: if (--ip->curx < 0) ! 651: ip->curx = 0; ! 652: else ! 653: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 654: break; ! 655: ! 656: case '\t': ! 657: if (ip->curx < TABEND(unit)) { ! 658: n = TABSIZE - (ip->curx & (TABSIZE - 1)); ! 659: ip->curx += n; ! 660: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 661: } else ! 662: itecheckwrap(ip, sp); ! 663: break; ! 664: ! 665: case CTRL('G'): ! 666: if (&ite_tty[unit] == kbd_tty) ! 667: kbdbell(); ! 668: break; ! 669: ! 670: case ESC: ! 671: ip->escape = ESC; ! 672: break; ! 673: ! 674: default: ! 675: if (c < ' ' || c == DEL) ! 676: break; ! 677: if (ip->imode) ! 678: ite_ichar(ip, sp); ! 679: if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { ! 680: attrset(ip, ATTR_INV); ! 681: (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); ! 682: } ! 683: else ! 684: (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); ! 685: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 686: itecheckwrap(ip, sp); ! 687: break; ! 688: } ! 689: } ! 690: ! 691: itecheckwrap(ip, sp) ! 692: register struct ite_softc *ip; ! 693: register struct itesw *sp; ! 694: { ! 695: if (++ip->curx == ip->cols) { ! 696: ip->curx = 0; ! 697: clr_attr(ip, ATTR_INV); ! 698: if (++ip->cury == ip->rows) { ! 699: --ip->cury; ! 700: (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); ! 701: ite_clrtoeol(ip, sp, ip->cury, 0); ! 702: return; ! 703: } ! 704: } ! 705: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 706: } ! 707: ! 708: ite_dchar(ip, sp) ! 709: register struct ite_softc *ip; ! 710: register struct itesw *sp; ! 711: { ! 712: (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT); ! 713: attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx, ! 714: 1, ip->cols - ip->curx - 1); ! 715: attrclr(ip, ip->cury, ip->cols - 1, 1, 1); ! 716: (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR); ! 717: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 718: } ! 719: ! 720: ite_ichar(ip, sp) ! 721: register struct ite_softc *ip; ! 722: register struct itesw *sp; ! 723: { ! 724: (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT); ! 725: attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1, ! 726: 1, ip->cols - ip->curx - 1); ! 727: attrclr(ip, ip->cury, ip->curx, 1, 1); ! 728: (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR); ! 729: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 730: } ! 731: ! 732: ite_dline(ip, sp) ! 733: register struct ite_softc *ip; ! 734: register struct itesw *sp; ! 735: { ! 736: (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP); ! 737: attrmov(ip, ip->cury + 1, 0, ip->cury, 0, ! 738: ip->rows - ip->cury - 1, ip->cols); ! 739: ite_clrtoeol(ip, sp, ip->rows - 1, 0); ! 740: } ! 741: ! 742: ite_iline(ip, sp) ! 743: register struct ite_softc *ip; ! 744: register struct itesw *sp; ! 745: { ! 746: (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN); ! 747: attrmov(ip, ip->cury, 0, ip->cury + 1, 0, ! 748: ip->rows - ip->cury - 1, ip->cols); ! 749: ite_clrtoeol(ip, sp, ip->cury, 0); ! 750: } ! 751: ! 752: ite_clrtoeol(ip, sp, y, x) ! 753: register struct ite_softc *ip; ! 754: register struct itesw *sp; ! 755: register int y, x; ! 756: { ! 757: (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); ! 758: attrclr(ip, y, x, 1, ip->cols - x); ! 759: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 760: } ! 761: ! 762: ite_clrtoeos(ip, sp) ! 763: register struct ite_softc *ip; ! 764: register struct itesw *sp; ! 765: { ! 766: (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); ! 767: attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); ! 768: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 769: } ! 770: ! 771: /* ! 772: * Console functions ! 773: */ ! 774: #include "../hp300/cons.h" ! 775: #include "grfioctl.h" ! 776: #include "grfvar.h" ! 777: ! 778: #ifdef DEBUG ! 779: /* ! 780: * Minimum ITE number at which to start looking for a console. ! 781: * Setting to 0 will do normal search, 1 will skip first ITE device, ! 782: * NITE will skip ITEs and use serial port. ! 783: */ ! 784: int whichconsole = 0; ! 785: #endif ! 786: ! 787: itecnprobe(cp) ! 788: struct consdev *cp; ! 789: { ! 790: register struct ite_softc *ip; ! 791: int i, maj, unit, pri; ! 792: ! 793: /* locate the major number */ ! 794: for (maj = 0; maj < nchrdev; maj++) ! 795: if (cdevsw[maj].d_open == iteopen) ! 796: break; ! 797: ! 798: /* urk! */ ! 799: grfconfig(); ! 800: ! 801: /* check all the individual displays and find the best */ ! 802: unit = -1; ! 803: pri = CN_DEAD; ! 804: for (i = 0; i < NITE; i++) { ! 805: struct grf_softc *gp = &grf_softc[i]; ! 806: ! 807: ip = &ite_softc[i]; ! 808: if ((gp->g_flags & GF_ALIVE) == 0) ! 809: continue; ! 810: ip->flags = (ITE_ALIVE|ITE_CONSOLE); ! 811: ! 812: /* XXX - we need to do something about mapping these */ ! 813: switch (gp->g_type) { ! 814: ! 815: case GT_TOPCAT: ! 816: case GT_LRCATSEYE: ! 817: case GT_HRCCATSEYE: ! 818: case GT_HRMCATSEYE: ! 819: ip->type = ITE_TOPCAT; ! 820: break; ! 821: case GT_GATORBOX: ! 822: ip->type = ITE_GATORBOX; ! 823: break; ! 824: case GT_RENAISSANCE: ! 825: ip->type = ITE_RENAISSANCE; ! 826: break; ! 827: case GT_DAVINCI: ! 828: ip->type = ITE_DAVINCI; ! 829: break; ! 830: } ! 831: #ifdef DEBUG ! 832: if (i < whichconsole) ! 833: continue; ! 834: #endif ! 835: if ((int)gp->g_display.gd_regaddr == GRFIADDR) { ! 836: pri = CN_INTERNAL; ! 837: unit = i; ! 838: } else if (unit < 0) { ! 839: pri = CN_NORMAL; ! 840: unit = i; ! 841: } ! 842: } ! 843: ! 844: /* initialize required fields */ ! 845: cp->cn_dev = makedev(maj, unit); ! 846: cp->cn_tp = &ite_tty[unit]; ! 847: cp->cn_pri = pri; ! 848: } ! 849: ! 850: itecninit(cp) ! 851: struct consdev *cp; ! 852: { ! 853: int unit = UNIT(cp->cn_dev); ! 854: struct ite_softc *ip = &ite_softc[unit]; ! 855: ! 856: ip->attrbuf = console_attributes; ! 857: iteinit(cp->cn_dev); ! 858: ip->flags |= (ITE_ACTIVE|ITE_ISCONS); ! 859: kbd_tty = &ite_tty[unit]; ! 860: } ! 861: ! 862: /*ARGSUSED*/ ! 863: itecngetc(dev) ! 864: dev_t dev; ! 865: { ! 866: register int c; ! 867: int stat; ! 868: ! 869: c = kbdgetc(&stat); ! 870: switch ((stat >> KBD_SSHIFT) & KBD_SMASK) { ! 871: case KBD_SHIFT: ! 872: c = kbd_shiftmap[c & KBD_CHARMASK]; ! 873: break; ! 874: case KBD_CTRL: ! 875: c = kbd_ctrlmap[c & KBD_CHARMASK]; ! 876: break; ! 877: case KBD_KEY: ! 878: c = kbd_keymap[c & KBD_CHARMASK]; ! 879: break; ! 880: default: ! 881: c = 0; ! 882: break; ! 883: } ! 884: return(c); ! 885: } ! 886: ! 887: itecnputc(dev, c) ! 888: dev_t dev; ! 889: int c; ! 890: { ! 891: static int paniced = 0; ! 892: struct ite_softc *ip = &ite_softc[UNIT(dev)]; ! 893: extern char *panicstr; ! 894: ! 895: if (panicstr && !paniced && ! 896: (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { ! 897: (void) iteon(dev, 3); ! 898: paniced = 1; ! 899: } ! 900: iteputchar(c, dev); ! 901: } ! 902: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.