|
|
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: * from: @(#)ite.c 7.6 (Berkeley) 5/16/91 ! 41: * ite.c,v 1.1.1.1 1993/07/05 19:19:44 mw Exp ! 42: */ ! 43: ! 44: /* ! 45: * Bit-mapped display terminal emulator machine independent code. ! 46: * This is a very rudimentary. Much more can be abstracted out of ! 47: * the hardware dependent routines. ! 48: */ ! 49: #include "ite.h" ! 50: #if NITE > 0 ! 51: ! 52: #include "grf.h" ! 53: ! 54: #undef NITE ! 55: #define NITE NGRF ! 56: ! 57: #include "param.h" ! 58: #include "conf.h" ! 59: #include "proc.h" ! 60: #include "ioctl.h" ! 61: #include "tty.h" ! 62: #include "systm.h" ! 63: #include "malloc.h" ! 64: ! 65: #include "itevar.h" ! 66: #include "iteioctl.h" ! 67: #include "kbdmap.h" ! 68: ! 69: #include "machine/cpu.h" ! 70: ! 71: #ifdef __STDC__ ! 72: /* automatically generated, as you might guess:-) */ ! 73: ! 74: struct consdev; ! 75: struct itesw; ! 76: ! 77: extern int iteon (dev_t dev, int flag); ! 78: extern int iteinit (dev_t dev); ! 79: extern int iteoff (dev_t dev, int flag); ! 80: extern int iteopen (dev_t dev, int mode, int devtype, struct proc *p); ! 81: extern int iteclose (dev_t dev, int flag, int mode, struct proc *p); ! 82: extern int iteread (dev_t dev, struct uio *uio, int flag); ! 83: extern int itewrite (dev_t dev, struct uio *uio, int flag); ! 84: extern int iteioctl (dev_t dev, int cmd, caddr_t addr, int flag); ! 85: extern int itestart (register struct tty *tp); ! 86: extern int itefilter (register u_char c, enum caller caller); ! 87: extern int iteputchar (register int c, dev_t dev); ! 88: extern int itecheckwrap (register struct ite_softc *ip, register struct itesw *sp); ! 89: extern int itecnprobe (struct consdev *cp); ! 90: extern int itecninit (struct consdev *cp); ! 91: extern int itecngetc (dev_t dev); ! 92: extern int itecnputc (dev_t dev, int c); ! 93: static void repeat_handler (int a0, int a1); ! 94: static void ite_dnchar (struct ite_softc *ip, struct itesw *sp, int n); ! 95: static void ite_inchar (struct ite_softc *ip, struct itesw *sp, int n); ! 96: static void ite_clrtoeol (struct ite_softc *ip, struct itesw *sp, int y, int x); ! 97: static void ite_clrtobol (struct ite_softc *ip, struct itesw *sp, int y, int x); ! 98: static void ite_clrline (struct ite_softc *ip, struct itesw *sp, int y, int x); ! 99: static void ite_clrtoeos (struct ite_softc *ip, struct itesw *sp); ! 100: static void ite_clrtobos (struct ite_softc *ip, struct itesw *sp); ! 101: static void ite_clrscreen (struct ite_softc *ip, struct itesw *sp); ! 102: static void ite_dnline (struct ite_softc *ip, struct itesw *sp, int n); ! 103: static void ite_inline (struct ite_softc *ip, struct itesw *sp, int n); ! 104: static void ite_lf (struct ite_softc *ip, struct itesw *sp); ! 105: static void ite_crlf (struct ite_softc *ip, struct itesw *sp); ! 106: static void ite_cr (struct ite_softc *ip, struct itesw *sp); ! 107: static void ite_rlf (struct ite_softc *ip, struct itesw *sp); ! 108: static int atoi (const char *cp); ! 109: static char *index (const char *cp, char ch); ! 110: static int ite_argnum (struct ite_softc *ip); ! 111: static int ite_zargnum (struct ite_softc *ip); ! 112: static void ite_sendstr (struct ite_softc *ip, char *str); ! 113: static int strncmp (const char *a, const char *b, int l); ! 114: #endif ! 115: ! 116: ! 117: #define set_attr(ip, attr) ((ip)->attribute |= (attr)) ! 118: #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr)) ! 119: ! 120: extern int nodev(); ! 121: ! 122: int customc_scroll(), customc_init(), customc_deinit(); ! 123: int customc_clear(), customc_putc(), customc_cursor(); ! 124: ! 125: int tiga_scroll(), tiga_init(), tiga_deinit(); ! 126: int tiga_clear(), tiga_putc(), tiga_cursor(); ! 127: ! 128: ! 129: struct itesw itesw[] = ! 130: { ! 131: customc_init, customc_deinit, customc_clear, ! 132: customc_putc, customc_cursor, customc_scroll, ! 133: ! 134: tiga_init, tiga_deinit, tiga_clear, ! 135: tiga_putc, tiga_cursor, tiga_scroll, ! 136: }; ! 137: ! 138: /* ! 139: * # of chars are output in a single itestart() call. ! 140: * If this is too big, user processes will be blocked out for ! 141: * long periods of time while we are emptying the queue in itestart(). ! 142: * If it is too small, console output will be very ragged. ! 143: */ ! 144: int iteburst = 64; ! 145: ! 146: int nite = NITE; ! 147: struct tty *kbd_tty = NULL; ! 148: struct tty ite_cons; ! 149: struct tty *ite_tty[NITE] = { &ite_cons }; ! 150: struct ite_softc ite_softc[NITE]; ! 151: ! 152: int itestart(); ! 153: extern int ttrstrt(); ! 154: extern struct tty *constty; ! 155: ! 156: /* These are (later..) settable via an ioctl */ ! 157: int start_repeat_timo = 30; /* /100: initial timeout till pressed key repeats */ ! 158: int next_repeat_timo = 5; /* /100: timeout when repeating for next char */ ! 159: ! 160: /* ! 161: * Primary attribute buffer to be used by the first bitmapped console ! 162: * found. Secondary displays alloc the attribute buffer as needed. ! 163: * Size is based on a 68x128 display, which is currently our largest. ! 164: */ ! 165: u_char console_attributes[0x2200]; ! 166: ! 167: /* ! 168: * Perform functions necessary to setup device as a terminal emulator. ! 169: */ ! 170: iteon(dev, flag) ! 171: dev_t dev; ! 172: { ! 173: int unit = UNIT(dev); ! 174: struct tty *tp = ite_tty[unit]; ! 175: struct ite_softc *ip = &ite_softc[unit]; ! 176: ! 177: if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0) ! 178: return(ENXIO); ! 179: /* force ite active, overriding graphics mode */ ! 180: if (flag & 1) { ! 181: ip->flags |= ITE_ACTIVE; ! 182: ip->flags &= ~(ITE_INGRF|ITE_INITED); ! 183: } ! 184: /* leave graphics mode */ ! 185: if (flag & 2) { ! 186: ip->flags &= ~ITE_INGRF; ! 187: if ((ip->flags & ITE_ACTIVE) == 0) ! 188: return(0); ! 189: } ! 190: ip->flags |= ITE_ACTIVE; ! 191: if (ip->flags & ITE_INGRF) ! 192: return(0); ! 193: if (kbd_tty == NULL || kbd_tty == tp) { ! 194: kbd_tty = tp; ! 195: kbdenable(); ! 196: } ! 197: iteinit(dev); ! 198: return(0); ! 199: } ! 200: ! 201: /* used by the grf layer to reinitialize ite after changing fb parameters */ ! 202: itereinit(dev) ! 203: dev_t dev; ! 204: { ! 205: int unit = UNIT(dev); ! 206: struct ite_softc *ip = &ite_softc[unit]; ! 207: ! 208: ip->flags &= ~ITE_INITED; ! 209: iteinit (dev); ! 210: } ! 211: ! 212: iteinit(dev) ! 213: dev_t dev; ! 214: { ! 215: int unit = UNIT(dev); ! 216: struct ite_softc *ip = &ite_softc[unit]; ! 217: ! 218: if (ip->flags & ITE_INITED) ! 219: return; ! 220: ! 221: ip->curx = 0; ! 222: ip->cury = 0; ! 223: ip->cursorx = 0; ! 224: ip->cursory = 0; ! 225: ip->save_curx = 0; ! 226: ip->save_cury = 0; ! 227: ip->ap = ip->argbuf; ! 228: ip->emul_level = EMUL_VT300_7; ! 229: ip->eightbit_C1 = 0; ! 230: ip->inside_margins = 0; ! 231: ip->linefeed_newline = 0; ! 232: ! 233: (*itesw[ip->type].ite_init)(ip); ! 234: (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR); ! 235: ! 236: /* ip->rows initialized by ite_init above */ ! 237: ip->top_margin = 0; ip->bottom_margin = ip->rows - 1; ! 238: ! 239: ip->attribute = 0; ! 240: if (ip->attrbuf == NULL) ! 241: ip->attrbuf = (u_char *) ! 242: malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK); ! 243: bzero(ip->attrbuf, (ip->rows * ip->cols)); ! 244: ! 245: ip->imode = 0; ! 246: ip->flags |= ITE_INITED; ! 247: } ! 248: ! 249: /* ! 250: * "Shut down" device as terminal emulator. ! 251: * Note that we do not deinit the console device unless forced. ! 252: * Deinit'ing the console every time leads to a very active ! 253: * screen when processing /etc/rc. ! 254: */ ! 255: iteoff(dev, flag) ! 256: dev_t dev; ! 257: { ! 258: register struct ite_softc *ip = &ite_softc[UNIT(dev)]; ! 259: ! 260: if (flag & 2) ! 261: ip->flags |= ITE_INGRF; ! 262: if ((ip->flags & ITE_ACTIVE) == 0) ! 263: return; ! 264: if ((flag & 1) || ! 265: (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) ! 266: (*itesw[ip->type].ite_deinit)(ip); ! 267: if ((flag & 2) == 0) ! 268: ip->flags &= ~ITE_ACTIVE; ! 269: } ! 270: ! 271: /* ARGSUSED */ ! 272: #ifdef __STDC__ ! 273: iteopen(dev_t dev, int mode, int devtype, struct proc *p) ! 274: #else ! 275: iteopen(dev, mode, devtype, p) ! 276: dev_t dev; ! 277: int mode, devtype; ! 278: struct proc *p; ! 279: #endif ! 280: { ! 281: int unit = UNIT(dev); ! 282: register struct tty *tp; ! 283: register struct ite_softc *ip = &ite_softc[unit]; ! 284: register int error; ! 285: int first = 0; ! 286: ! 287: if(!ite_tty[unit]) { ! 288: MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK); ! 289: bzero(tp, sizeof(struct tty)); ! 290: ite_tty[unit] = tp; ! 291: } else ! 292: tp = ite_tty[unit]; ! 293: ! 294: if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE) ! 295: && p->p_ucred->cr_uid != 0) ! 296: return (EBUSY); ! 297: if ((ip->flags & ITE_ACTIVE) == 0) { ! 298: error = iteon(dev, 0); ! 299: if (error) ! 300: return (error); ! 301: first = 1; ! 302: } ! 303: tp->t_oproc = itestart; ! 304: tp->t_param = NULL; ! 305: tp->t_dev = dev; ! 306: if ((tp->t_state&TS_ISOPEN) == 0) { ! 307: ttychars(tp); ! 308: tp->t_iflag = TTYDEF_IFLAG; ! 309: tp->t_oflag = TTYDEF_OFLAG; ! 310: tp->t_cflag = CS8|CREAD; ! 311: tp->t_lflag = TTYDEF_LFLAG; ! 312: tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; ! 313: /* don't set TS_ISOPEN here, or the tty queues won't ! 314: be initialized in ttyopen()! */ ! 315: tp->t_state = TS_CARR_ON; ! 316: ttsetwater(tp); ! 317: } ! 318: error = (*linesw[tp->t_line].l_open)(dev, tp); ! 319: if (error == 0) { ! 320: tp->t_winsize.ws_row = ip->rows; ! 321: tp->t_winsize.ws_col = ip->cols; ! 322: } else if (first) ! 323: iteoff(dev, 0); ! 324: return (error); ! 325: } ! 326: ! 327: /*ARGSUSED*/ ! 328: iteclose(dev, flag, mode, p) ! 329: dev_t dev; ! 330: int flag, mode; ! 331: struct proc *p; ! 332: { ! 333: register struct tty *tp = ite_tty[UNIT(dev)]; ! 334: ! 335: (*linesw[tp->t_line].l_close)(tp, flag); ! 336: ttyclose(tp); ! 337: iteoff(dev, 0); ! 338: if (tp != &ite_cons) ! 339: { ! 340: FREE(tp, M_TTYS); ! 341: ite_tty[UNIT(dev)] = (struct tty *)NULL; ! 342: } ! 343: return(0); ! 344: } ! 345: ! 346: iteread(dev, uio, flag) ! 347: dev_t dev; ! 348: struct uio *uio; ! 349: { ! 350: register struct tty *tp = ite_tty[UNIT(dev)]; ! 351: int rc; ! 352: ! 353: rc = ((*linesw[tp->t_line].l_read)(tp, uio, flag)); ! 354: return rc; ! 355: } ! 356: ! 357: itewrite(dev, uio, flag) ! 358: dev_t dev; ! 359: struct uio *uio; ! 360: { ! 361: int unit = UNIT(dev); ! 362: register struct tty *tp = ite_tty[unit]; ! 363: ! 364: if ((ite_softc[unit].flags & ITE_ISCONS) && constty && ! 365: (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) ! 366: tp = constty; ! 367: return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); ! 368: } ! 369: ! 370: iteioctl(dev, cmd, addr, flag) ! 371: dev_t dev; ! 372: caddr_t addr; ! 373: { ! 374: register struct tty *tp = ite_tty[UNIT(dev)]; ! 375: int error; ! 376: ! 377: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag); ! 378: if (error >= 0) ! 379: return (error); ! 380: error = ttioctl(tp, cmd, addr, flag); ! 381: if (error >= 0) ! 382: return (error); ! 383: return (ENOTTY); ! 384: } ! 385: ! 386: itestart(tp) ! 387: register struct tty *tp; ! 388: { ! 389: register int cc, s; ! 390: int hiwat = 0; ! 391: ! 392: s = spltty(); ! 393: if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { ! 394: splx(s); ! 395: return; ! 396: } ! 397: tp->t_state |= TS_BUSY; ! 398: cc = RB_LEN (&tp->t_out); ! 399: if (cc <= tp->t_lowat) { ! 400: if (tp->t_state & TS_ASLEEP) { ! 401: tp->t_state &= ~TS_ASLEEP; ! 402: wakeup(&tp->t_out); ! 403: } ! 404: selwakeup(&tp->t_wsel); ! 405: } ! 406: /* ! 407: * Limit the amount of output we do in one burst ! 408: * to prevent hogging the CPU. ! 409: */ ! 410: if (cc > iteburst) { ! 411: hiwat++; ! 412: cc = iteburst; ! 413: } ! 414: while (--cc >= 0) { ! 415: register int c; ! 416: ! 417: c = rbgetc(&tp->t_out); ! 418: /* ! 419: * iteputchar() may take a long time and we don't want to ! 420: * block all interrupts for long periods of time. Since ! 421: * there is no need to stay at high priority while outputing ! 422: * the character (since we don't have to worry about ! 423: * interrupts), we don't. We just need to make sure that ! 424: * we don't reenter iteputchar, which is guarenteed by the ! 425: * earlier setting of TS_BUSY. ! 426: */ ! 427: splx(s); ! 428: iteputchar(c, tp->t_dev); ! 429: spltty(); ! 430: } ! 431: if (hiwat) { ! 432: tp->t_state |= TS_TIMEOUT; ! 433: timeout(ttrstrt, tp, 1); ! 434: } ! 435: tp->t_state &= ~TS_BUSY; ! 436: splx(s); ! 437: } ! 438: ! 439: /* these are used to implement repeating keys.. */ ! 440: static u_char last_char = 0; ! 441: static u_char tout_pending = 0; ! 442: ! 443: static void ! 444: repeat_handler (a0, a1) ! 445: int a0, a1; ! 446: { ! 447: tout_pending = 0; ! 448: /* leave it up to itefilter() to possible install a new callout entry ! 449: to reinvoke repeat_handler() */ ! 450: itefilter (last_char, ITEFILT_REPEATER); ! 451: } ! 452: ! 453: ! 454: int ! 455: itefilter(c, caller) ! 456: register u_char c; ! 457: enum caller caller; ! 458: { ! 459: static u_char mod = 0; ! 460: static u_char last_dead = 0; ! 461: register char code, *str; ! 462: u_char up, mask, i; ! 463: struct key key; ! 464: ! 465: if (caller != ITEFILT_CONSOLE && kbd_tty == NULL) ! 466: return; ! 467: ! 468: up = c & 0x80 ? 1 : 0; ! 469: c &= 0x7f; ! 470: code = 0; ! 471: ! 472: mask = 0; ! 473: if (c >= KBD_LEFT_SHIFT) ! 474: { ! 475: switch (c) ! 476: { ! 477: case KBD_LEFT_SHIFT: ! 478: mask = KBD_MOD_LSHIFT; ! 479: break; ! 480: ! 481: case KBD_RIGHT_SHIFT: ! 482: mask = KBD_MOD_RSHIFT; ! 483: break; ! 484: ! 485: case KBD_LEFT_ALT: ! 486: mask = KBD_MOD_LALT; ! 487: break; ! 488: ! 489: case KBD_RIGHT_ALT: ! 490: mask = KBD_MOD_RALT; ! 491: break; ! 492: ! 493: case KBD_LEFT_META: ! 494: mask = KBD_MOD_LMETA; ! 495: break; ! 496: ! 497: case KBD_RIGHT_META: ! 498: mask = KBD_MOD_RMETA; ! 499: break; ! 500: ! 501: case KBD_CAPS_LOCK: ! 502: /* capslock already behaves `right', don't need to keep track of the ! 503: state in here. */ ! 504: mask = KBD_MOD_CAPS; ! 505: break; ! 506: ! 507: case KBD_CTRL: ! 508: mask = KBD_MOD_CTRL; ! 509: break; ! 510: } ! 511: ! 512: if (mask) ! 513: { ! 514: if (up) ! 515: mod &= ~mask; ! 516: else ! 517: mod |= mask; ! 518: } ! 519: ! 520: /* these keys should not repeat, so it's the Right Thing dealing with ! 521: repeaters only after this block. */ ! 522: ! 523: /* return even if it wasn't a modifier key, the other codes up here ! 524: are either special (like reset warning), or not yet defined */ ! 525: return -1; ! 526: } ! 527: ! 528: /* no matter which character we're repeating, stop it if we get a key-up ! 529: event. I think this is the same thing amigados does. */ ! 530: if (up) ! 531: { ! 532: if (tout_pending) ! 533: { ! 534: untimeout (repeat_handler, 0); ! 535: tout_pending = 0; ! 536: } ! 537: return -1; ! 538: } ! 539: ! 540: ! 541: switch (mod & (KBD_MOD_ALT | KBD_MOD_SHIFT)) ! 542: { ! 543: case 0: ! 544: key = kbdmap.keys[c]; ! 545: if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS)) ! 546: break; ! 547: /* FALL INTO */ ! 548: ! 549: case KBD_MOD_LSHIFT: ! 550: case KBD_MOD_RSHIFT: ! 551: case KBD_MOD_SHIFT: ! 552: key = kbdmap.shift_keys[c]; ! 553: break; ! 554: ! 555: case KBD_MOD_LALT: ! 556: case KBD_MOD_RALT: ! 557: case KBD_MOD_ALT: ! 558: key = kbdmap.alt_keys[c]; ! 559: if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS)) ! 560: break; ! 561: /* FALL INTO */ ! 562: ! 563: case KBD_MOD_LALT|KBD_MOD_LSHIFT: ! 564: case KBD_MOD_LALT|KBD_MOD_RSHIFT: ! 565: case KBD_MOD_LALT|KBD_MOD_SHIFT: ! 566: case KBD_MOD_RALT|KBD_MOD_RSHIFT: ! 567: case KBD_MOD_RALT|KBD_MOD_SHIFT: ! 568: case KBD_MOD_ALT|KBD_MOD_RSHIFT: ! 569: key = kbdmap.alt_shift_keys[c]; ! 570: break; ! 571: } ! 572: ! 573: code = key.code; ! 574: ! 575: /* arrange to repeat the keystroke. By doing this at the level of scan-codes, ! 576: we can have function keys, and keys that send strings, repeat too. This ! 577: also entitles an additional overhead, since we have to do the conversion ! 578: each time, but I guess that's ok. */ ! 579: if (!tout_pending && caller == ITEFILT_TTY) ! 580: { ! 581: tout_pending = 1; ! 582: last_char = c; ! 583: timeout (repeat_handler, 0, start_repeat_timo); ! 584: } ! 585: else if (!tout_pending && caller == ITEFILT_REPEATER) ! 586: { ! 587: tout_pending = 1; ! 588: last_char = c; ! 589: timeout (repeat_handler, 0, next_repeat_timo); ! 590: } ! 591: ! 592: /* handle dead keys */ ! 593: if (key.mode & KBD_MODE_DEAD) ! 594: { ! 595: /* if entered twice, send accent itself */ ! 596: if (last_dead == key.mode & KBD_MODE_ACCMASK) ! 597: last_dead = 0; ! 598: else ! 599: { ! 600: last_dead = key.mode & KBD_MODE_ACCMASK; ! 601: return -1; ! 602: } ! 603: } ! 604: if (last_dead) ! 605: { ! 606: /* can't apply dead flag to string-keys */ ! 607: if (! (key.mode & KBD_MODE_STRING) && code >= '@' && code < 0x7f) ! 608: code = acctable[KBD_MODE_ACCENT (last_dead)][code - '@']; ! 609: ! 610: last_dead = 0; ! 611: } ! 612: ! 613: /* if not string, apply META and CTRL modifiers */ ! 614: if (! (key.mode & KBD_MODE_STRING)) ! 615: { ! 616: if (mod & KBD_MOD_CTRL) ! 617: code &= 0x1f; ! 618: ! 619: if (mod & KBD_MOD_META) ! 620: code |= 0x80; ! 621: } ! 622: else ! 623: { ! 624: /* strings are only supported in normal tty mode, not in console mode */ ! 625: if (caller != ITEFILT_CONSOLE) ! 626: { ! 627: str = kbdmap.strings + code; ! 628: /* using a length-byte instead of 0-termination allows to embed \0 into ! 629: strings, although this is not used in the default keymap */ ! 630: for (i = *str++; i; i--) ! 631: (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); ! 632: } ! 633: return -1; ! 634: } ! 635: ! 636: if (caller == ITEFILT_CONSOLE) ! 637: return code; ! 638: else ! 639: (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); ! 640: ! 641: return -1; ! 642: } ! 643: ! 644: ! 645: /* helper functions, makes the code below more readable */ ! 646: static void inline ! 647: ite_dnchar(ip, sp, n) ! 648: struct ite_softc *ip; ! 649: struct itesw *sp; ! 650: int n; ! 651: { ! 652: (*sp->ite_scroll)(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT); ! 653: attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx, ! 654: 1, ip->cols - ip->curx - n); ! 655: attrclr(ip, ip->cury, ip->cols - n, 1, n); ! 656: while (n--) ! 657: (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR); ! 658: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 659: } ! 660: ! 661: static void inline ! 662: ite_inchar(ip, sp, n) ! 663: struct ite_softc *ip; ! 664: struct itesw *sp; ! 665: int n; ! 666: { ! 667: (*sp->ite_scroll)(ip, ip->cury, ip->curx, n, SCROLL_RIGHT); ! 668: attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n, ! 669: 1, ip->cols - ip->curx - n); ! 670: attrclr(ip, ip->cury, ip->curx, 1, n); ! 671: while (n--) ! 672: (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR); ! 673: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 674: } ! 675: ! 676: static void inline ! 677: ite_clrtoeol(ip, sp, y, x) ! 678: struct ite_softc *ip; ! 679: struct itesw *sp; ! 680: int y, x; ! 681: { ! 682: (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); ! 683: attrclr(ip, y, x, 1, ip->cols - x); ! 684: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 685: } ! 686: ! 687: static void inline ! 688: ite_clrtobol(ip, sp, y, x) ! 689: struct ite_softc *ip; ! 690: struct itesw *sp; ! 691: int y, x; ! 692: { ! 693: (*sp->ite_clear)(ip, y, 0, 1, x); ! 694: attrclr(ip, y, 0, 1, x); ! 695: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 696: } ! 697: ! 698: static void inline ! 699: ite_clrline(ip, sp, y, x) ! 700: struct ite_softc *ip; ! 701: struct itesw *sp; ! 702: int y, x; ! 703: { ! 704: (*sp->ite_clear)(ip, y, 0, 1, ip->cols); ! 705: attrclr(ip, y, 0, 1, ip->cols); ! 706: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 707: } ! 708: ! 709: ! 710: ! 711: static void inline ! 712: ite_clrtoeos(ip, sp) ! 713: struct ite_softc *ip; ! 714: struct itesw *sp; ! 715: { ! 716: (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); ! 717: attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); ! 718: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 719: } ! 720: ! 721: static void inline ! 722: ite_clrtobos(ip, sp) ! 723: struct ite_softc *ip; ! 724: struct itesw *sp; ! 725: { ! 726: (*sp->ite_clear)(ip, 0, 0, ip->cury, ip->cols); ! 727: attrclr(ip, 0, 0, ip->cury, ip->cols); ! 728: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 729: } ! 730: ! 731: static void inline ! 732: ite_clrscreen(ip, sp) ! 733: struct ite_softc *ip; ! 734: struct itesw *sp; ! 735: { ! 736: (*sp->ite_clear)(ip, 0, 0, ip->rows, ip->cols); ! 737: attrclr(ip, 0, 0, ip->rows, ip->cols); ! 738: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 739: } ! 740: ! 741: ! 742: ! 743: static void inline ! 744: ite_dnline(ip, sp, n) ! 745: struct ite_softc *ip; ! 746: struct itesw *sp; ! 747: int n; ! 748: { ! 749: (*sp->ite_scroll)(ip, ip->cury + n, 0, n, SCROLL_UP); ! 750: attrmov(ip, ip->cury + n, 0, ip->cury, 0, ! 751: ip->bottom_margin + 1 - ip->cury - n, ip->cols); ! 752: (*sp->ite_clear)(ip, ip->bottom_margin - n + 1, 0, n, ip->cols); ! 753: attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols); ! 754: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 755: } ! 756: ! 757: static void inline ! 758: ite_inline(ip, sp, n) ! 759: struct ite_softc *ip; ! 760: struct itesw *sp; ! 761: int n; ! 762: { ! 763: (*sp->ite_scroll)(ip, ip->cury, 0, n, SCROLL_DOWN); ! 764: attrmov(ip, ip->cury, 0, ip->cury + n, 0, ! 765: ip->bottom_margin + 1 - ip->cury - n, ip->cols); ! 766: (*sp->ite_clear)(ip, ip->cury, 0, n, ip->cols); ! 767: attrclr(ip, ip->cury, 0, n, ip->cols); ! 768: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 769: } ! 770: ! 771: static void inline ! 772: ite_lf (ip, sp) ! 773: struct ite_softc *ip; ! 774: struct itesw *sp; ! 775: { ! 776: #if 0 ! 777: if (ip->inside_margins) ! 778: { ! 779: #endif ! 780: if (++ip->cury >= ip->bottom_margin + 1) ! 781: { ! 782: ip->cury = ip->bottom_margin; ! 783: (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); ! 784: ite_clrtoeol(ip, sp, ip->cury, 0); ! 785: } ! 786: else ! 787: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 788: #if 0 ! 789: } ! 790: else ! 791: { ! 792: if (++ip->cury == ip->rows) ! 793: { ! 794: --ip->cury; ! 795: (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); ! 796: ite_clrtoeol(ip, sp, ip->cury, 0); ! 797: } ! 798: else ! 799: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 800: } ! 801: #endif ! 802: clr_attr(ip, ATTR_INV); ! 803: } ! 804: ! 805: static void inline ! 806: ite_crlf (ip, sp) ! 807: struct ite_softc *ip; ! 808: struct itesw *sp; ! 809: { ! 810: ip->curx = 0; ! 811: ite_lf (ip, sp); ! 812: } ! 813: ! 814: static void inline ! 815: ite_cr (ip, sp) ! 816: struct ite_softc *ip; ! 817: struct itesw *sp; ! 818: { ! 819: if (ip->curx) ! 820: { ! 821: ip->curx = 0; ! 822: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 823: } ! 824: } ! 825: ! 826: static void inline ! 827: ite_rlf (ip, sp) ! 828: struct ite_softc *ip; ! 829: struct itesw *sp; ! 830: { ! 831: if (ip->cury > 0) ! 832: { ! 833: ip->cury--; ! 834: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 835: } ! 836: else ! 837: ite_inline (ip, sp, 1); ! 838: clr_attr(ip, ATTR_INV); ! 839: } ! 840: ! 841: static int inline ! 842: atoi (cp) ! 843: const char *cp; ! 844: { ! 845: int n; ! 846: ! 847: for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++) ! 848: n = n * 10 + *cp - '0'; ! 849: ! 850: return n; ! 851: } ! 852: ! 853: static char * ! 854: index (cp, ch) ! 855: const char *cp; ! 856: char ch; ! 857: { ! 858: while (*cp && *cp != ch) cp++; ! 859: return *cp ? cp : 0; ! 860: } ! 861: ! 862: ! 863: ! 864: static int inline ! 865: ite_argnum (ip) ! 866: struct ite_softc *ip; ! 867: { ! 868: char ch; ! 869: int n; ! 870: ! 871: /* convert argument string into number */ ! 872: if (ip->ap == ip->argbuf) ! 873: return 1; ! 874: ch = *ip->ap; ! 875: *ip->ap = 0; ! 876: n = atoi (ip->argbuf); ! 877: *ip->ap = ch; ! 878: ! 879: return n; ! 880: } ! 881: ! 882: static int inline ! 883: ite_zargnum (ip) ! 884: struct ite_softc *ip; ! 885: { ! 886: char ch, *cp; ! 887: int n; ! 888: ! 889: /* convert argument string into number */ ! 890: if (ip->ap == ip->argbuf) ! 891: return 0; ! 892: ch = *ip->ap; ! 893: *ip->ap = 0; ! 894: n = atoi (ip->argbuf); ! 895: *ip->ap = ch; ! 896: ! 897: return n; ! 898: } ! 899: ! 900: static void inline ! 901: ite_sendstr (ip, str) ! 902: struct ite_softc *ip; ! 903: char *str; ! 904: { ! 905: while (*str) ! 906: (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); ! 907: } ! 908: ! 909: static int inline ! 910: strncmp (a, b, l) ! 911: const char *a, *b; ! 912: int l; ! 913: { ! 914: for (;l--; a++, b++) ! 915: if (*a != *b) ! 916: return *a - *b; ! 917: return 0; ! 918: } ! 919: ! 920: static void inline ! 921: ite_reinit(ip) ! 922: struct ite_softc *ip; ! 923: { ! 924: ip->curx = 0; ! 925: ip->cury = 0; ! 926: ip->cursorx = 0; ! 927: ip->cursory = 0; ! 928: ip->save_curx = 0; ! 929: ip->save_cury = 0; ! 930: ip->ap = ip->argbuf; ! 931: ip->emul_level = EMUL_VT300_7; ! 932: ip->eightbit_C1 = 0; ! 933: ip->top_margin = 0; ip->bottom_margin = 23; ! 934: ip->inside_margins = 0; ! 935: ip->linefeed_newline = 0; ! 936: ! 937: (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR); ! 938: ! 939: ip->attribute = 0; ! 940: bzero(ip->attrbuf, (ip->rows * ip->cols)); ! 941: ! 942: ip->imode = 0; ! 943: } ! 944: ! 945: ! 946: ! 947: iteputchar(c, dev) ! 948: register int c; ! 949: dev_t dev; ! 950: { ! 951: int unit = UNIT(dev); ! 952: register struct ite_softc *ip = &ite_softc[unit]; ! 953: register struct itesw *sp = &itesw[ip->type]; ! 954: register int n; ! 955: int x, y; ! 956: char *cp; ! 957: ! 958: if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) ! 959: return; ! 960: ! 961: if ((ite_tty[unit]->t_cflag & CSIZE) == CS7 ! 962: || (ite_tty[unit]->t_cflag & PARENB)) ! 963: c &= 0x7f; ! 964: ! 965: if (ip->escape) ! 966: { ! 967: doesc: ! 968: switch (ip->escape) ! 969: { ! 970: case ESC: ! 971: switch (c) ! 972: { ! 973: /* first 7bit equivalents for the 8bit control characters */ ! 974: ! 975: case 'D': ! 976: c = IND; ! 977: ip->escape = 0; ! 978: break; ! 979: ! 980: case 'E': ! 981: c = NEL; ! 982: ip->escape = 0; ! 983: break; ! 984: ! 985: case 'H': ! 986: c = HTS; ! 987: ip->escape = 0; ! 988: break; ! 989: ! 990: case 'M': ! 991: c = RI; ! 992: ip->escape = 0; ! 993: break; ! 994: ! 995: case 'N': ! 996: c = SS2; ! 997: ip->escape = 0; ! 998: break; ! 999: ! 1000: case 'O': ! 1001: c = SS3; ! 1002: ip->escape = 0; ! 1003: break; ! 1004: ! 1005: case 'P': ! 1006: c = DCS; ! 1007: ip->escape = 0; ! 1008: break; ! 1009: ! 1010: case '[': ! 1011: c = CSI; ! 1012: ip->escape = 0; ! 1013: break; ! 1014: ! 1015: case '\\': ! 1016: c = ST; ! 1017: ip->escape = 0; ! 1018: break; ! 1019: ! 1020: case ']': ! 1021: c = OSC; ! 1022: ip->escape = 0; ! 1023: break; ! 1024: ! 1025: case '^': ! 1026: c = PM; ! 1027: ip->escape = 0; ! 1028: break; ! 1029: ! 1030: case '_': ! 1031: c = APC; ! 1032: ip->escape = 0; ! 1033: break; ! 1034: ! 1035: ! 1036: /* introduces 7/8bit control */ ! 1037: case ' ': ! 1038: /* can be followed by either F or G */ ! 1039: ip->escape = ' '; ! 1040: break; ! 1041: ! 1042: ! 1043: /* a lot of character set selections, not yet used... ! 1044: 94-character sets: */ ! 1045: case '(': /* G0 */ ! 1046: case ')': /* G1 */ ! 1047: case '*': /* G2 */ ! 1048: case '+': /* G3 */ ! 1049: case 'B': /* ASCII */ ! 1050: case 'A': /* ISO latin 1 */ ! 1051: case '<': /* user preferred suplemental */ ! 1052: case '0': /* dec special graphics */ ! 1053: ! 1054: /* 96-character sets: */ ! 1055: case '-': /* G1 */ ! 1056: case '.': /* G2 */ ! 1057: case '/': /* G3 */ ! 1058: ! 1059: /* national character sets: */ ! 1060: case '4': /* dutch */ ! 1061: case '5': ! 1062: case 'C': /* finnish */ ! 1063: case 'R': /* french */ ! 1064: case 'Q': /* french canadian */ ! 1065: case 'K': /* german */ ! 1066: case 'Y': /* italian */ ! 1067: case '6': /* norwegian/danish */ ! 1068: case 'Z': /* spanish */ ! 1069: case '=': /* swiss */ ! 1070: /* note: %5 and %6 are not supported (two chars..) */ ! 1071: ! 1072: ip->escape = 0; ! 1073: /* just ignore for now */ ! 1074: return -1; ! 1075: ! 1076: ! 1077: /* locking shift modes (as you might guess, not yet supported..) */ ! 1078: case '`': ! 1079: ip->GR = ip->G1; ! 1080: ip->escape = 0; ! 1081: return -1; ! 1082: ! 1083: case 'n': ! 1084: ip->GL = ip->G2; ! 1085: ip->escape = 0; ! 1086: return -1; ! 1087: ! 1088: case '}': ! 1089: ip->GR = ip->G2; ! 1090: ip->escape = 0; ! 1091: return -1; ! 1092: ! 1093: case 'o': ! 1094: ip->GL = ip->G3; ! 1095: ip->escape = 0; ! 1096: return -1; ! 1097: ! 1098: case '|': ! 1099: ip->GR = ip->G3; ! 1100: ip->escape = 0; ! 1101: return -1; ! 1102: ! 1103: ! 1104: /* font width/height control */ ! 1105: case '#': ! 1106: ip->escape = '#'; ! 1107: return -1; ! 1108: ! 1109: ! 1110: /* hard terminal reset .. */ ! 1111: case 'c': ! 1112: ite_reinit (ip); ! 1113: ip->escape = 0; ! 1114: return -1; ! 1115: ! 1116: ! 1117: case '7': ! 1118: ip->save_curx = ip->curx; ! 1119: ip->save_cury = ip->cury; ! 1120: ip->escape = 0; ! 1121: return -1; ! 1122: ! 1123: case '8': ! 1124: ip->curx = ip->save_curx; ! 1125: ip->cury = ip->save_cury; ! 1126: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1127: ip->escape = 0; ! 1128: return -1; ! 1129: ! 1130: ! 1131: /* default catch all for not recognized ESC sequences */ ! 1132: default: ! 1133: ip->escape = 0; ! 1134: return -1; ! 1135: } ! 1136: break; ! 1137: ! 1138: ! 1139: case ' ': ! 1140: switch (c) ! 1141: { ! 1142: case 'F': ! 1143: ip->eightbit_C1 = 0; ! 1144: ip->escape = 0; ! 1145: return -1; ! 1146: ! 1147: case 'G': ! 1148: ip->eightbit_C1 = 1; ! 1149: ip->escape = 0; ! 1150: return -1; ! 1151: ! 1152: default: ! 1153: /* not supported */ ! 1154: ip->escape = 0; ! 1155: return -1; ! 1156: } ! 1157: break; ! 1158: ! 1159: ! 1160: case '#': ! 1161: switch (c) ! 1162: { ! 1163: case '5': ! 1164: /* single height, single width */ ! 1165: ip->escape = 0; ! 1166: return -1; ! 1167: ! 1168: case '6': ! 1169: /* double width, single height */ ! 1170: ip->escape = 0; ! 1171: return -1; ! 1172: ! 1173: case '3': ! 1174: /* top half */ ! 1175: ip->escape = 0; ! 1176: return -1; ! 1177: ! 1178: case '4': ! 1179: /* bottom half */ ! 1180: ip->escape = 0; ! 1181: return -1; ! 1182: ! 1183: case '8': ! 1184: /* screen alignment pattern... */ ! 1185: ip->escape = 0; ! 1186: return -1; ! 1187: ! 1188: default: ! 1189: ip->escape = 0; ! 1190: return -1; ! 1191: } ! 1192: break; ! 1193: ! 1194: ! 1195: ! 1196: #if 0 ! 1197: case DCS: ! 1198: case PM: ! 1199: case APC: ! 1200: case OSC: ! 1201: switch (c) ! 1202: { ! 1203: case ST: ! 1204: ip->escape = 0; ! 1205: return -1; ! 1206: ! 1207: default: ! 1208: return -1; ! 1209: } ! 1210: break; ! 1211: #endif ! 1212: ! 1213: ! 1214: case CSI: ! 1215: /* the biggie... */ ! 1216: switch (c) ! 1217: { ! 1218: case '0': case '1': case '2': case '3': case '4': ! 1219: case '5': case '6': case '7': case '8': case '9': ! 1220: case ';': case '\"': case '$': case '>': ! 1221: if (ip->ap < ip->argbuf + ARGBUF_SIZE) ! 1222: *ip->ap++ = c; ! 1223: return -1; ! 1224: ! 1225: case CAN: ! 1226: ip->escape = 0; ! 1227: return -1; ! 1228: ! 1229: ! 1230: case 'p': ! 1231: *ip->ap = 0; ! 1232: if (! strncmp (ip->argbuf, "61\"", 3)) ! 1233: ip->emul_level = EMUL_VT100; ! 1234: else if (! strncmp (ip->argbuf, "63;1\"", 5) ! 1235: || ! strncmp (ip->argbuf, "62;1\"", 5)) ! 1236: ip->emul_level = EMUL_VT300_7; ! 1237: else ! 1238: ip->emul_level = EMUL_VT300_8; ! 1239: ip->escape = 0; ! 1240: return -1; ! 1241: ! 1242: ! 1243: case '?': ! 1244: *ip->ap = 0; ! 1245: ip->escape = '?'; ! 1246: ip->ap = ip->argbuf; ! 1247: return -1; ! 1248: ! 1249: ! 1250: case 'c': ! 1251: *ip->ap = 0; ! 1252: if (ip->ap == ip->argbuf ! 1253: || (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '0')) ! 1254: { ! 1255: /* primary DA request, send primary DA response */ ! 1256: if (ip->emul_level == EMUL_VT100) ! 1257: ite_sendstr (ip, "\033[61;0c"); ! 1258: else ! 1259: ite_sendstr (ip, "\033[63;0c"); ! 1260: } ! 1261: ! 1262: else if ((ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '>') ! 1263: || (ip->ap == &ip->argbuf[2] ! 1264: && !strncmp (ip->argbuf, ">0", 2))) ! 1265: { ! 1266: ite_sendstr (ip, "\033[>24;0;0;0c"); ! 1267: } ! 1268: ! 1269: ip->escape = 0; ! 1270: return -1; ! 1271: ! 1272: ! 1273: case 'n': ! 1274: *ip->ap = 0; ! 1275: if (ip->ap == &ip->argbuf[1]) ! 1276: { ! 1277: if (ip->argbuf[0] == '5') ! 1278: ite_sendstr (ip, "\033[0n"); /* no malfunction */ ! 1279: ! 1280: else if (ip->argbuf[0] == '6') ! 1281: { ! 1282: sprintf (ip->argbuf, "\033[%d;%dR", ! 1283: ip->cury + 1, ip->curx + 1); ! 1284: /* cursor position report */ ! 1285: ite_sendstr (ip, ip->argbuf); ! 1286: } ! 1287: ! 1288: } ! 1289: ip->escape = 0; ! 1290: return -1; ! 1291: ! 1292: ! 1293: case 'h': case 'l': ! 1294: *ip->ap = 0; ! 1295: if (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '4') ! 1296: ip->imode = (c == 'h'); /* insert/replace mode */ ! 1297: ! 1298: else if (ip->ap == &ip->argbuf[2] ! 1299: && !strncmp (ip->argbuf, "20", 2)) ! 1300: ip->linefeed_newline = (c == 'h'); ! 1301: ! 1302: ! 1303: /* various not supported commands */ ! 1304: ip->escape = 0; ! 1305: return -1; ! 1306: ! 1307: ! 1308: case 'M': ! 1309: *ip->ap = 0; ! 1310: ite_dnline (ip, sp, ite_argnum (ip)); ! 1311: ip->escape = 0; ! 1312: return -1; ! 1313: ! 1314: ! 1315: case 'L': ! 1316: *ip->ap = 0; ! 1317: ite_inline (ip, sp, ite_argnum (ip)); ! 1318: ip->escape = 0; ! 1319: return -1; ! 1320: ! 1321: ! 1322: case 'P': ! 1323: *ip->ap = 0; ! 1324: ite_dnchar (ip, sp, ite_argnum (ip)); ! 1325: ip->escape = 0; ! 1326: return -1; ! 1327: ! 1328: ! 1329: case '@': ! 1330: *ip->ap = 0; ! 1331: ite_inchar (ip, sp, ite_argnum (ip)); ! 1332: ip->escape = 0; ! 1333: return -1; ! 1334: ! 1335: ! 1336: case 'H': ! 1337: case 'f': ! 1338: *ip->ap = 0; ! 1339: y = atoi (ip->argbuf); ! 1340: x = 0; ! 1341: cp = index (ip->argbuf, ';'); ! 1342: if (cp) ! 1343: x = atoi (cp + 1); ! 1344: if (x) x--; ! 1345: if (y) y--; ! 1346: if (ip->inside_margins) ! 1347: { ! 1348: y += ip->top_margin; ! 1349: ip->cury = MIN(y, ip->bottom_margin); ! 1350: } ! 1351: else ! 1352: { ! 1353: ip->cury = MIN(y, ip->rows - 1); ! 1354: } ! 1355: ip->curx = MIN(x, ip->cols - 1); ! 1356: ip->escape = 0; ! 1357: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1358: clr_attr (ip, ATTR_INV); ! 1359: return -1; ! 1360: ! 1361: case 'A': ! 1362: *ip->ap = 0; ! 1363: n = ip->cury - ite_argnum (ip); ! 1364: ip->cury = n >= 0 ? n : 0; ! 1365: ip->escape = 0; ! 1366: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1367: clr_attr (ip, ATTR_INV); ! 1368: return -1; ! 1369: ! 1370: case 'B': ! 1371: *ip->ap = 0; ! 1372: n = ite_argnum (ip) + ip->cury; ! 1373: ip->cury = MIN(n, ip->rows - 1); ! 1374: ip->escape = 0; ! 1375: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1376: clr_attr (ip, ATTR_INV); ! 1377: return -1; ! 1378: ! 1379: case 'C': ! 1380: *ip->ap = 0; ! 1381: n = ite_argnum (ip) + ip->curx; ! 1382: ip->curx = MIN(n, ip->cols - 1); ! 1383: ip->escape = 0; ! 1384: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1385: clr_attr (ip, ATTR_INV); ! 1386: return -1; ! 1387: ! 1388: case 'D': ! 1389: *ip->ap = 0; ! 1390: n = ip->curx - ite_argnum (ip); ! 1391: ip->curx = n >= 0 ? n : 0; ! 1392: ip->escape = 0; ! 1393: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1394: clr_attr (ip, ATTR_INV); ! 1395: return -1; ! 1396: ! 1397: ! 1398: ! 1399: ! 1400: case 'J': ! 1401: *ip->ap = 0; ! 1402: n = ite_zargnum (ip); ! 1403: if (n == 0) ! 1404: ite_clrtoeos(ip, sp); ! 1405: else if (n == 1) ! 1406: ite_clrtobos(ip, sp); ! 1407: else if (n == 2) ! 1408: ite_clrscreen(ip, sp); ! 1409: ip->escape = 0; ! 1410: return -1; ! 1411: ! 1412: ! 1413: case 'K': ! 1414: *ip->ap = 0; ! 1415: n = ite_zargnum (ip); ! 1416: if (n == 0) ! 1417: ite_clrtoeol(ip, sp, ip->cury, ip->curx); ! 1418: else if (n == 1) ! 1419: ite_clrtobol(ip, sp, ip->cury, ip->curx); ! 1420: else if (n == 2) ! 1421: ite_clrline(ip, sp, ip->cury, ip->curx); ! 1422: ip->escape = 0; ! 1423: return -1; ! 1424: ! 1425: ! 1426: case 'X': ! 1427: *ip->ap = 0; ! 1428: for (n = ite_argnum (ip); n > 0; n--) ! 1429: { ! 1430: attrclr(ip, ip->cury, ip->curx + n - 1, 1, 1); ! 1431: (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n - 1, ATTR_NOR); ! 1432: } ! 1433: ip->escape = 0; ! 1434: return -1; ! 1435: ! 1436: ! 1437: case '}': case '`': ! 1438: /* status line control */ ! 1439: ip->escape = 0; ! 1440: return -1; ! 1441: ! 1442: ! 1443: case 'r': ! 1444: *ip->ap = 0; ! 1445: x = atoi (ip->argbuf); ! 1446: y = 0; ! 1447: cp = index (ip->argbuf, ';'); ! 1448: if (cp) ! 1449: y = atoi (cp + 1); ! 1450: if (x) x--; ! 1451: if (y) y--; ! 1452: ip->top_margin = MIN(x, ip->rows - 1); ! 1453: ip->bottom_margin = MIN(y, ip->rows - 1); ! 1454: ip->escape = 0; ! 1455: return -1; ! 1456: ! 1457: ! 1458: case 'm': ! 1459: /* big attribute setter/resetter */ ! 1460: { ! 1461: char *cp; ! 1462: *ip->ap = 0; ! 1463: for (cp = ip->argbuf; cp < ip->ap; ) ! 1464: { ! 1465: switch (*cp) ! 1466: { ! 1467: case '0': ! 1468: clr_attr (ip, ATTR_ALL); ! 1469: cp++; ! 1470: break; ! 1471: ! 1472: case '1': ! 1473: set_attr (ip, ATTR_BOLD); ! 1474: cp++; ! 1475: break; ! 1476: ! 1477: case '2': ! 1478: switch (cp[1]) ! 1479: { ! 1480: case '2': ! 1481: clr_attr (ip, ATTR_BOLD); ! 1482: cp += 2; ! 1483: break; ! 1484: ! 1485: case '4': ! 1486: clr_attr (ip, ATTR_UL); ! 1487: cp += 2; ! 1488: break; ! 1489: ! 1490: case '5': ! 1491: clr_attr (ip, ATTR_BLINK); ! 1492: cp += 2; ! 1493: break; ! 1494: ! 1495: case '7': ! 1496: clr_attr (ip, ATTR_INV); ! 1497: cp += 2; ! 1498: break; ! 1499: ! 1500: default: ! 1501: cp++; ! 1502: break; ! 1503: } ! 1504: break; ! 1505: ! 1506: case '4': ! 1507: set_attr (ip, ATTR_UL); ! 1508: cp++; ! 1509: break; ! 1510: ! 1511: case '5': ! 1512: set_attr (ip, ATTR_BLINK); ! 1513: cp++; ! 1514: break; ! 1515: ! 1516: case '7': ! 1517: set_attr (ip, ATTR_INV); ! 1518: cp++; ! 1519: break; ! 1520: ! 1521: default: ! 1522: cp++; ! 1523: break; ! 1524: } ! 1525: } ! 1526: ! 1527: } ! 1528: ip->escape = 0; ! 1529: return -1; ! 1530: ! 1531: ! 1532: case 'u': ! 1533: /* DECRQTSR */ ! 1534: ite_sendstr (ip, "\033P\033\\"); ! 1535: ip->escape = 0; ! 1536: return -1; ! 1537: ! 1538: ! 1539: ! 1540: default: ! 1541: ip->escape = 0; ! 1542: return -1; ! 1543: } ! 1544: break; ! 1545: ! 1546: ! 1547: ! 1548: case '?': /* CSI ? */ ! 1549: switch (c) ! 1550: { ! 1551: case '0': case '1': case '2': case '3': case '4': ! 1552: case '5': case '6': case '7': case '8': case '9': ! 1553: case ';': case '\"': case '$': ! 1554: if (ip->ap < ip->argbuf + ARGBUF_SIZE) ! 1555: *ip->ap++ = c; ! 1556: return -1; ! 1557: ! 1558: ! 1559: case CAN: ! 1560: ip->escape = 0; ! 1561: return -1; ! 1562: ! 1563: ! 1564: case 'n': ! 1565: *ip->ap = 0; ! 1566: if (ip->ap == &ip->argbuf[2]) ! 1567: { ! 1568: if (! strncmp (ip->argbuf, "15", 2)) ! 1569: /* printer status: no printer */ ! 1570: ite_sendstr (ip, "\033[13n"); ! 1571: ! 1572: else if (! strncmp (ip->argbuf, "25", 2)) ! 1573: /* udk status */ ! 1574: ite_sendstr (ip, "\033[20n"); ! 1575: ! 1576: else if (! strncmp (ip->argbuf, "26", 2)) ! 1577: /* keyboard dialect: US */ ! 1578: ite_sendstr (ip, "\033[27;1n"); ! 1579: } ! 1580: ip->escape = 0; ! 1581: return -1; ! 1582: ! 1583: ! 1584: case 'h': case 'l': ! 1585: *ip->ap = 0; ! 1586: if (ip->ap[0] == '6') ! 1587: ip->inside_margins = (c == 'h'); ! 1588: ! 1589: else if (! strncmp (ip->ap, "25", 2)) ! 1590: (*itesw[ip->type].ite_cursor)(ip, ! 1591: (c == 'h') ? DRAW_CURSOR : ERASE_CURSOR); ! 1592: ! 1593: /* others.. */ ! 1594: ! 1595: default: ! 1596: ip->escape = 0; ! 1597: return -1; ! 1598: } ! 1599: break; ! 1600: ! 1601: ! 1602: default: ! 1603: ip->escape = 0; ! 1604: return -1; ! 1605: } ! 1606: } ! 1607: ! 1608: ! 1609: switch (c) { ! 1610: ! 1611: case VT: /* VT is treated like LF */ ! 1612: case FF: /* so is FF */ ! 1613: case LF: ! 1614: if (ip->linefeed_newline) ! 1615: ite_crlf (ip, sp); ! 1616: else ! 1617: ite_lf (ip, sp); ! 1618: break; ! 1619: ! 1620: case CR: ! 1621: ite_cr (ip, sp); ! 1622: break; ! 1623: ! 1624: case BS: ! 1625: if (--ip->curx < 0) ! 1626: ip->curx = 0; ! 1627: else ! 1628: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1629: break; ! 1630: ! 1631: case HT: ! 1632: if (ip->curx < TABEND(unit)) { ! 1633: n = TABSIZE - (ip->curx & (TABSIZE - 1)); ! 1634: ip->curx += n; ! 1635: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1636: } else ! 1637: itecheckwrap(ip, sp); ! 1638: break; ! 1639: ! 1640: case BEL: ! 1641: if (ite_tty[unit] == kbd_tty) ! 1642: kbdbell(); ! 1643: break; ! 1644: ! 1645: case SO: ! 1646: ip->GL = ip->G1; ! 1647: break; ! 1648: ! 1649: case SI: ! 1650: ip->GL = ip->G0; ! 1651: break; ! 1652: ! 1653: case ENQ: ! 1654: /* send answer-back message !! */ ! 1655: break; ! 1656: ! 1657: case CAN: ! 1658: ip->escape = 0; /* cancel any escape sequence in progress */ ! 1659: break; ! 1660: ! 1661: case SUB: ! 1662: ip->escape = 0; /* dito, but see below */ ! 1663: /* should also display a reverse question mark!! */ ! 1664: break; ! 1665: ! 1666: case ESC: ! 1667: ip->escape = ESC; ! 1668: break; ! 1669: ! 1670: ! 1671: /* now it gets weird.. 8bit control sequences.. */ ! 1672: case IND: /* index: move cursor down, scroll */ ! 1673: ite_lf (ip, sp); ! 1674: break; ! 1675: ! 1676: case NEL: /* next line. next line, first pos. */ ! 1677: ite_crlf (ip, sp); ! 1678: break; ! 1679: ! 1680: case HTS: /* set horizontal tab */ ! 1681: /* not yet supported */ ! 1682: break; ! 1683: ! 1684: case RI: /* reverse index */ ! 1685: ite_rlf (ip, sp); ! 1686: break; ! 1687: ! 1688: case SS2: /* go into G2 for one character */ ! 1689: /* not yet supported */ ! 1690: break; ! 1691: ! 1692: case SS3: /* go into G3 for one character */ ! 1693: break; ! 1694: ! 1695: case DCS: /* device control string introducer */ ! 1696: ip->escape = DCS; ! 1697: ip->ap = ip->argbuf; ! 1698: break; ! 1699: ! 1700: case CSI: /* control sequence introducer */ ! 1701: ip->escape = CSI; ! 1702: ip->ap = ip->argbuf; ! 1703: break; ! 1704: ! 1705: case ST: /* string terminator */ ! 1706: /* ignore, if not used as terminator */ ! 1707: break; ! 1708: ! 1709: case OSC: /* introduces OS command. Ignore everything upto ST */ ! 1710: ip->escape = OSC; ! 1711: break; ! 1712: ! 1713: case PM: /* privacy message, ignore everything upto ST */ ! 1714: ip->escape = PM; ! 1715: break; ! 1716: ! 1717: case APC: /* application program command, ignore everything upto ST */ ! 1718: ip->escape = APC; ! 1719: break; ! 1720: ! 1721: default: ! 1722: if (c < ' ' || c == DEL) ! 1723: break; ! 1724: if (ip->imode) ! 1725: ite_inchar(ip, sp, 1); ! 1726: if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { ! 1727: attrset(ip, ATTR_INV); ! 1728: (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); ! 1729: } ! 1730: else ! 1731: (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); ! 1732: (*sp->ite_cursor)(ip, DRAW_CURSOR); ! 1733: itecheckwrap(ip, sp); ! 1734: break; ! 1735: } ! 1736: } ! 1737: ! 1738: itecheckwrap(ip, sp) ! 1739: register struct ite_softc *ip; ! 1740: register struct itesw *sp; ! 1741: { ! 1742: if (++ip->curx == ip->cols) { ! 1743: ip->curx = 0; ! 1744: clr_attr(ip, ATTR_INV); ! 1745: if (++ip->cury >= ip->bottom_margin + 1) { ! 1746: ip->cury = ip->bottom_margin; ! 1747: (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP); ! 1748: ite_clrtoeol(ip, sp, ip->cury, 0); ! 1749: return; ! 1750: } ! 1751: } ! 1752: (*sp->ite_cursor)(ip, MOVE_CURSOR); ! 1753: } ! 1754: ! 1755: /* ! 1756: * Console functions ! 1757: */ ! 1758: #include "../amiga/cons.h" ! 1759: #include "grfioctl.h" ! 1760: #include "grfvar.h" ! 1761: ! 1762: #ifdef DEBUG ! 1763: /* ! 1764: * Minimum ITE number at which to start looking for a console. ! 1765: * Setting to 0 will do normal search, 1 will skip first ITE device, ! 1766: * NITE will skip ITEs and use serial port. ! 1767: */ ! 1768: int whichconsole = 0; ! 1769: #endif ! 1770: ! 1771: itecnprobe(cp) ! 1772: struct consdev *cp; ! 1773: { ! 1774: register struct ite_softc *ip; ! 1775: int i, maj, unit, pri; ! 1776: ! 1777: /* locate the major number */ ! 1778: for (maj = 0; maj < nchrdev; maj++) ! 1779: if (cdevsw[maj].d_open == iteopen) ! 1780: break; ! 1781: ! 1782: /* urk! */ ! 1783: grfconfig(); ! 1784: ! 1785: /* check all the individual displays and find the best */ ! 1786: unit = -1; ! 1787: pri = CN_DEAD; ! 1788: for (i = 0; i < NITE; i++) { ! 1789: struct grf_softc *gp = &grf_softc[i]; ! 1790: ! 1791: ip = &ite_softc[i]; ! 1792: if ((gp->g_flags & GF_ALIVE) == 0) ! 1793: continue; ! 1794: ip->flags = (ITE_ALIVE|ITE_CONSOLE); ! 1795: ! 1796: /* XXX - we need to do something about mapping these */ ! 1797: switch (gp->g_type) { ! 1798: case GT_CUSTOMCHIPS: ! 1799: ip->type = ITE_CUSTOMCHIPS; ! 1800: break; ! 1801: ! 1802: case GT_TIGA_A2410: ! 1803: ip->type = ITE_TIGA_A2410; ! 1804: break; ! 1805: } ! 1806: #ifdef DEBUG ! 1807: if (i < whichconsole) ! 1808: continue; ! 1809: #endif ! 1810: if ((int)gp->g_type == GT_CUSTOMCHIPS) { ! 1811: pri = CN_INTERNAL; ! 1812: unit = i; ! 1813: } else if (unit < 0) { ! 1814: pri = CN_NORMAL; ! 1815: unit = i; ! 1816: } ! 1817: } ! 1818: ! 1819: /* initialize required fields */ ! 1820: cp->cn_dev = makedev(maj, unit); ! 1821: cp->cn_tp = ite_tty[unit]; ! 1822: cp->cn_pri = pri; ! 1823: } ! 1824: ! 1825: itecninit(cp) ! 1826: struct consdev *cp; ! 1827: { ! 1828: int unit = UNIT(cp->cn_dev); ! 1829: struct ite_softc *ip = &ite_softc[unit]; ! 1830: ip->attrbuf = console_attributes; ! 1831: iteinit(cp->cn_dev); ! 1832: ip->flags |= (ITE_ACTIVE|ITE_ISCONS); ! 1833: kbd_tty = ite_tty[unit]; ! 1834: kbdenable(); ! 1835: } ! 1836: ! 1837: /*ARGSUSED*/ ! 1838: itecngetc(dev) ! 1839: dev_t dev; ! 1840: { ! 1841: register int c; ! 1842: ! 1843: do ! 1844: { ! 1845: c = kbdgetcn (); ! 1846: c = itefilter (c, ITEFILT_CONSOLE); ! 1847: } ! 1848: while (c == -1); ! 1849: ! 1850: return(c); ! 1851: } ! 1852: ! 1853: itecnputc(dev, c) ! 1854: dev_t dev; ! 1855: int c; ! 1856: { ! 1857: static int paniced = 0; ! 1858: struct ite_softc *ip = &ite_softc[UNIT(dev)]; ! 1859: extern char *panicstr; ! 1860: ! 1861: if (panicstr && !paniced && ! 1862: (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { ! 1863: (void) iteon(dev, 3); ! 1864: paniced = 1; ! 1865: } ! 1866: iteputchar(c, dev); ! 1867: } ! 1868: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.