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