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