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