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