Home | History | Annotate | Line # | Download | only in dev
ite.c revision 1.70
      1  1.70   tsutsui /*	$NetBSD: ite.c,v 1.70 2022/06/25 05:01:31 tsutsui Exp $	*/
      2   1.1       oki 
      3   1.1       oki /*
      4  1.58     rmind  * Copyright (c) 1988 University of Utah.
      5   1.1       oki  * Copyright (c) 1990 The Regents of the University of California.
      6   1.1       oki  * All rights reserved.
      7   1.1       oki  *
      8   1.1       oki  * This code is derived from software contributed to Berkeley by
      9   1.1       oki  * the Systems Programming Group of the University of Utah Computer
     10   1.1       oki  * Science Department.
     11   1.1       oki  *
     12   1.1       oki  * Redistribution and use in source and binary forms, with or without
     13   1.1       oki  * modification, are permitted provided that the following conditions
     14   1.1       oki  * are met:
     15   1.1       oki  * 1. Redistributions of source code must retain the above copyright
     16   1.1       oki  *    notice, this list of conditions and the following disclaimer.
     17   1.1       oki  * 2. Redistributions in binary form must reproduce the above copyright
     18   1.1       oki  *    notice, this list of conditions and the following disclaimer in the
     19   1.1       oki  *    documentation and/or other materials provided with the distribution.
     20  1.35       agc  * 3. Neither the name of the University nor the names of its contributors
     21  1.35       agc  *    may be used to endorse or promote products derived from this software
     22  1.35       agc  *    without specific prior written permission.
     23  1.35       agc  *
     24  1.35       agc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  1.35       agc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  1.35       agc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  1.35       agc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  1.35       agc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  1.35       agc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  1.35       agc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  1.35       agc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  1.35       agc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  1.35       agc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  1.35       agc  * SUCH DAMAGE.
     35  1.35       agc  *
     36  1.35       agc  * from: Utah $Hdr: ite.c 1.1 90/07/09$
     37  1.35       agc  *
     38  1.35       agc  *	@(#)ite.c	7.6 (Berkeley) 5/16/91
     39  1.35       agc  */
     40   1.1       oki 
     41   1.1       oki /*
     42   1.1       oki  * ite - bitmaped terminal.
     43   1.1       oki  * Supports VT200, a few terminal features will be unavailable until
     44   1.1       oki  * the system actually probes the device (i.e. not after consinit())
     45   1.1       oki  */
     46  1.34     lukem 
     47  1.34     lukem #include <sys/cdefs.h>
     48  1.70   tsutsui __KERNEL_RCSID(0, "$NetBSD: ite.c,v 1.70 2022/06/25 05:01:31 tsutsui Exp $");
     49   1.1       oki 
     50   1.1       oki #include "ite.h"
     51   1.1       oki #if NITE > 0
     52   1.1       oki 
     53   1.1       oki #include "bell.h"
     54  1.14   minoura #include "kbd.h"
     55  1.17   minoura 
     56  1.17   minoura #include "opt_ite.h"
     57   1.1       oki 
     58   1.1       oki #include <sys/param.h>
     59   1.1       oki #include <sys/conf.h>
     60   1.1       oki #include <sys/proc.h>
     61   1.1       oki #include <sys/ioctl.h>
     62   1.1       oki #include <sys/tty.h>
     63   1.1       oki #include <sys/systm.h>
     64   1.1       oki #include <sys/device.h>
     65   1.1       oki #include <sys/malloc.h>
     66  1.45      elad #include <sys/kauth.h>
     67  1.65  riastrad #include <sys/device_impl.h>	/* XXX autoconf abuse */
     68  1.14   minoura 
     69  1.16   minoura #include <machine/cpu.h>
     70   1.1       oki #include <machine/kbio.h>
     71  1.14   minoura #include <machine/bus.h>
     72  1.56     isaki #include <machine/autoconf.h>
     73  1.14   minoura #include <machine/grfioctl.h>
     74  1.13   minoura #include <machine/iteioctl.h>
     75   1.1       oki 
     76  1.14   minoura #include <arch/x68k/dev/grfvar.h>
     77  1.14   minoura #include <arch/x68k/dev/itevar.h>
     78  1.14   minoura #include <arch/x68k/dev/kbdmap.h>
     79  1.14   minoura #include <arch/x68k/dev/mfp.h>
     80  1.66   tsutsui 
     81  1.66   tsutsui #include "ioconf.h"
     82  1.66   tsutsui 
     83  1.16   minoura #if NBELL > 0
     84  1.38       chs void opm_bell(void);
     85  1.16   minoura #endif
     86   1.1       oki 
     87   1.1       oki #define SUBR_INIT(ip)		ip->isw->ite_init(ip)
     88   1.1       oki #define SUBR_DEINIT(ip)		ip->isw->ite_deinit(ip)
     89   1.1       oki #define SUBR_PUTC(ip,c,dy,dx,m)	ip->isw->ite_putc(ip,c,dy,dx,m)
     90   1.1       oki #define SUBR_CURSOR(ip,flg)	ip->isw->ite_cursor(ip,flg)
     91   1.1       oki #define SUBR_CLEAR(ip,sy,sx,h,w)	ip->isw->ite_clear(ip,sy,sx,h,w)
     92   1.1       oki #define SUBR_SCROLL(ip,sy,sx,count,dir)	\
     93   1.1       oki     ip->isw->ite_scroll(ip,sy,sx,count,dir)
     94   1.1       oki 
     95   1.1       oki struct consdev;
     96   1.1       oki 
     97  1.69   tsutsui static inline void itesendch(int);
     98  1.69   tsutsui static inline void alignment_display(struct ite_softc *);
     99  1.69   tsutsui static inline void snap_cury(struct ite_softc *);
    100  1.69   tsutsui static inline void ite_dnchar(struct ite_softc *, int);
    101  1.38       chs static void ite_inchar(struct ite_softc *,	int);
    102  1.69   tsutsui static inline void ite_clrtoeol(struct ite_softc *);
    103  1.69   tsutsui static inline void ite_clrtobol(struct ite_softc *);
    104  1.69   tsutsui static inline void ite_clrline(struct ite_softc *);
    105  1.69   tsutsui static inline void ite_clrtoeos(struct ite_softc *);
    106  1.69   tsutsui static inline void ite_clrtobos(struct ite_softc *);
    107  1.69   tsutsui static inline void ite_clrscreen(struct ite_softc *);
    108  1.69   tsutsui static inline void ite_dnline(struct ite_softc *, int);
    109  1.69   tsutsui static inline void ite_inline(struct ite_softc *, int);
    110  1.69   tsutsui static inline void ite_index(struct ite_softc *);
    111  1.69   tsutsui static inline void ite_lf(struct ite_softc *);
    112  1.69   tsutsui static inline void ite_crlf(struct ite_softc *);
    113  1.69   tsutsui static inline void ite_cr(struct ite_softc *);
    114  1.69   tsutsui static inline void ite_rlf(struct ite_softc *);
    115  1.38       chs static void iteprecheckwrap(struct ite_softc *);
    116  1.38       chs static void itecheckwrap(struct ite_softc *);
    117  1.38       chs static int ite_argnum(struct ite_softc *);
    118  1.38       chs static int ite_zargnum(struct ite_softc *);
    119  1.40        he static void ite_sendstr(struct ite_softc *, const char *);
    120  1.69   tsutsui static inline int atoi(const char *);
    121  1.69   tsutsui static struct ite_softc *getitesp(dev_t);
    122   1.1       oki 
    123  1.69   tsutsui static struct itesw itesw[] = {
    124  1.16   minoura 	{0,	tv_init,	tv_deinit,	0,
    125  1.16   minoura 	 0,	0,		0}
    126   1.1       oki };
    127   1.1       oki 
    128   1.1       oki /*
    129   1.1       oki  * # of chars are output in a single itestart() call.
    130   1.1       oki  * If this is too big, user processes will be blocked out for
    131   1.1       oki  * long periods of time while we are emptying the queue in itestart().
    132   1.1       oki  * If it is too small, console output will be very ragged.
    133   1.1       oki  */
    134   1.1       oki #define ITEBURST 64
    135   1.1       oki 
    136   1.1       oki struct	tty *ite_tty[NITE];
    137   1.1       oki 
    138  1.69   tsutsui static struct ite_softc *kbd_ite = NULL;
    139  1.69   tsutsui static struct ite_softc con_itesoftc;
    140  1.69   tsutsui static struct device con_itedev;
    141   1.1       oki 
    142  1.69   tsutsui static struct tty *kbd_tty = NULL;
    143   1.1       oki 
    144  1.69   tsutsui static int start_repeat_timeo = 20;	/* /100: initial timeout till pressed
    145  1.69   tsutsui 						 key repeats */
    146  1.69   tsutsui static int next_repeat_timeo  = 3;	/* /100: timeout when repeating for
    147  1.69   tsutsui 						 next char */
    148   1.1       oki 
    149  1.69   tsutsui static u_char cons_tabs[MAX_TABS];
    150   1.1       oki 
    151  1.69   tsutsui static void itestart(struct tty *);
    152   1.1       oki 
    153  1.69   tsutsui static void iteputchar(int, struct ite_softc *);
    154  1.69   tsutsui static void ite_putstr(const u_char *, int, dev_t);
    155  1.69   tsutsui 
    156  1.69   tsutsui static int itematch(device_t, cfdata_t, void *);
    157  1.69   tsutsui static void iteattach(device_t, device_t, void *);
    158   1.1       oki 
    159  1.57     isaki CFATTACH_DECL_NEW(ite, sizeof(struct ite_softc),
    160  1.32   thorpej     itematch, iteattach, NULL, NULL);
    161   1.1       oki 
    162  1.69   tsutsui static dev_type_open(iteopen);
    163  1.69   tsutsui static dev_type_close(iteclose);
    164  1.69   tsutsui static dev_type_read(iteread);
    165  1.69   tsutsui static dev_type_write(itewrite);
    166  1.69   tsutsui static dev_type_ioctl(iteioctl);
    167  1.69   tsutsui static dev_type_tty(itetty);
    168  1.69   tsutsui static dev_type_poll(itepoll);
    169  1.29   gehenna 
    170  1.29   gehenna const struct cdevsw ite_cdevsw = {
    171  1.61  dholland 	.d_open = iteopen,
    172  1.61  dholland 	.d_close = iteclose,
    173  1.61  dholland 	.d_read = iteread,
    174  1.61  dholland 	.d_write = itewrite,
    175  1.61  dholland 	.d_ioctl = iteioctl,
    176  1.61  dholland 	.d_stop = nostop,
    177  1.61  dholland 	.d_tty = itetty,
    178  1.61  dholland 	.d_poll = itepoll,
    179  1.61  dholland 	.d_mmap = nommap,
    180  1.61  dholland 	.d_kqfilter = ttykqfilter,
    181  1.63  dholland 	.d_discard = nodiscard,
    182  1.61  dholland 	.d_flag = D_TTY
    183  1.29   gehenna };
    184  1.29   gehenna 
    185  1.69   tsutsui static int
    186  1.60   tsutsui itematch(device_t parent, cfdata_t cf, void *aux)
    187   1.1       oki {
    188   1.1       oki 	struct grf_softc *gp;
    189   1.1       oki 
    190  1.60   tsutsui 	gp = aux;
    191  1.60   tsutsui 	if (cf->cf_loc[GRFCF_GRFADDR] != gp->g_cfaddr)
    192  1.39       chs 		return 0;
    193   1.1       oki 
    194  1.39       chs 	return 1;
    195   1.1       oki }
    196   1.1       oki 
    197  1.50     isaki /*
    198   1.1       oki  * iteinit() is the standard entry point for initialization of
    199   1.1       oki  * an ite device, it is also called from ite_cninit().
    200   1.1       oki  */
    201  1.69   tsutsui static void
    202  1.60   tsutsui iteattach(device_t parent, device_t self, void *aux)
    203   1.1       oki {
    204   1.1       oki 	struct ite_softc *ip;
    205   1.1       oki 	struct grf_softc *gp;
    206   1.1       oki 
    207  1.60   tsutsui 	gp = aux;
    208  1.60   tsutsui 	ip = device_private(self);
    209  1.60   tsutsui 	ip->device = self;
    210  1.56     isaki 	if(con_itesoftc.grf != NULL
    211  1.56     isaki 		/*&& con_itesoftc.grf->g_unit == gp->g_unit*/) {
    212  1.56     isaki 		/*
    213  1.56     isaki 		 * console reinit copy params over.
    214  1.56     isaki 		 * and console always gets keyboard
    215  1.56     isaki 		 */
    216  1.56     isaki 		memcpy(&ip->grf, &con_itesoftc.grf,
    217  1.56     isaki 		    (char *)&ip[1] - (char *)&ip->grf);
    218  1.56     isaki 		con_itesoftc.grf = NULL;
    219  1.56     isaki 		kbd_ite = ip;
    220  1.56     isaki 	}
    221  1.56     isaki 	ip->grf = gp;
    222  1.60   tsutsui 	iteinit(device_unit(self)); /* XXX */
    223  1.57     isaki 	aprint_normal(": rows %d cols %d", ip->rows, ip->cols);
    224  1.56     isaki 	if (kbd_ite == NULL)
    225  1.56     isaki 		kbd_ite = ip;
    226  1.57     isaki 	aprint_normal("\n");
    227   1.1       oki }
    228   1.1       oki 
    229  1.69   tsutsui static struct ite_softc *
    230  1.38       chs getitesp(dev_t dev)
    231   1.1       oki {
    232   1.1       oki 
    233   1.1       oki 	if (x68k_realconfig && con_itesoftc.grf == NULL)
    234  1.55    cegger 		return device_lookup_private(&ite_cd, UNIT(dev));
    235   1.1       oki 
    236   1.1       oki 	if (con_itesoftc.grf == NULL)
    237   1.1       oki 		panic("no ite_softc for console");
    238  1.69   tsutsui 	return &con_itesoftc;
    239   1.1       oki }
    240   1.1       oki 
    241  1.49     isaki void
    242  1.38       chs iteinit(dev_t dev)
    243   1.1       oki {
    244   1.1       oki 	struct ite_softc *ip;
    245   1.1       oki 
    246   1.1       oki 	ip = getitesp(dev);
    247   1.1       oki 
    248   1.1       oki 	if (ip->flags & ITE_INITED)
    249   1.1       oki 		return;
    250  1.27       wiz 	memcpy(&kbdmap, &ascii_kbdmap, sizeof(struct kbdmap));
    251   1.1       oki 
    252   1.1       oki 	ip->curx = 0;
    253   1.1       oki 	ip->cury = 0;
    254   1.1       oki 	ip->cursorx = 0;
    255   1.1       oki 	ip->cursory = 0;
    256   1.1       oki 
    257  1.60   tsutsui 	ip->isw = &itesw[device_unit(ip->device)]; /* XXX */
    258   1.1       oki 	SUBR_INIT(ip);
    259   1.1       oki 	SUBR_CURSOR(ip, DRAW_CURSOR);
    260  1.69   tsutsui 	if (ip->tabs == NULL)
    261  1.69   tsutsui 		ip->tabs = malloc(MAX_TABS * sizeof(u_char),
    262  1.69   tsutsui 		    M_DEVBUF, M_WAITOK);
    263   1.1       oki 	ite_reset(ip);
    264   1.1       oki 	ip->flags |= ITE_INITED;
    265   1.1       oki }
    266   1.1       oki 
    267  1.56     isaki void
    268  1.56     isaki ite_config_console(void)
    269  1.56     isaki {
    270  1.56     isaki 	struct grf_softc *gp = &congrf;
    271  1.56     isaki 
    272  1.56     isaki 	if (con_itesoftc.grf != NULL)
    273  1.56     isaki 		return;
    274  1.56     isaki 	con_itesoftc.grf = gp;
    275  1.56     isaki 	con_itesoftc.tabs = cons_tabs;
    276  1.60   tsutsui 	con_itesoftc.device = &con_itedev;
    277  1.56     isaki }
    278  1.56     isaki 
    279   1.1       oki /*
    280   1.1       oki  * Perform functions necessary to setup device as a terminal emulator.
    281   1.1       oki  */
    282  1.49     isaki int
    283  1.38       chs iteon(dev_t dev, int flag)
    284   1.1       oki {
    285   1.1       oki 	int unit = UNIT(dev);
    286  1.12   minoura 	struct ite_softc *ip;
    287   1.1       oki 
    288  1.12   minoura 	if (unit < 0 || unit >= ite_cd.cd_ndevs ||
    289  1.69   tsutsui 	    (ip = getitesp(dev)) == NULL || (ip->flags & ITE_ALIVE) == 0)
    290  1.69   tsutsui 		return ENXIO;
    291   1.1       oki 	/* force ite active, overriding graphics mode */
    292  1.69   tsutsui 	if ((flag & 1) != 0) {
    293   1.1       oki 		ip->flags |= ITE_ACTIVE;
    294   1.1       oki 		ip->flags &= ~(ITE_INGRF|ITE_INITED);
    295   1.1       oki 	}
    296   1.1       oki 	/* leave graphics mode */
    297  1.69   tsutsui 	if ((flag & 2) != 0) {
    298   1.1       oki 		ip->flags &= ~ITE_INGRF;
    299   1.1       oki 		if ((ip->flags & ITE_ACTIVE) == 0)
    300  1.69   tsutsui 			return 0;
    301   1.1       oki 	}
    302   1.1       oki 	ip->flags |= ITE_ACTIVE;
    303  1.69   tsutsui 	if ((ip->flags & ITE_INGRF) != 0)
    304  1.69   tsutsui 		return 0;
    305   1.1       oki 	iteinit(dev);
    306  1.69   tsutsui 	if ((flag & 2) != 0)
    307  1.20   minoura 		ite_reset(ip);
    308  1.14   minoura #if NKBD > 0
    309  1.49     isaki 	mfp_send_usart(0x49);	/* XXX */
    310  1.14   minoura #endif
    311  1.69   tsutsui 	return 0;
    312   1.1       oki }
    313   1.1       oki 
    314   1.1       oki /*
    315   1.1       oki  * "Shut down" device as terminal emulator.
    316   1.1       oki  * Note that we do not deinit the console device unless forced.
    317   1.1       oki  * Deinit'ing the console every time leads to a very active
    318   1.1       oki  * screen when processing /etc/rc.
    319   1.1       oki  */
    320  1.49     isaki void
    321  1.38       chs iteoff(dev_t dev, int flag)
    322   1.1       oki {
    323   1.4       oki 	int unit = UNIT(dev);
    324  1.38       chs 	struct ite_softc *ip;
    325   1.1       oki 
    326   1.4       oki 	/* XXX check whether when call from grf.c */
    327  1.12   minoura 	if (unit < 0 || unit >= ite_cd.cd_ndevs ||
    328  1.69   tsutsui 	    (ip = getitesp(dev)) == NULL || (ip->flags & ITE_ALIVE) == 0)
    329   1.4       oki 		return;
    330  1.69   tsutsui 	if ((flag & 2) != 0)
    331   1.1       oki 		ip->flags |= ITE_INGRF;
    332   1.1       oki 
    333   1.1       oki 	if ((ip->flags & ITE_ACTIVE) == 0)
    334   1.1       oki 		return;
    335  1.69   tsutsui 	if ((flag & 1) != 0 ||
    336  1.69   tsutsui 	    (ip->flags & (ITE_INGRF | ITE_ISCONS | ITE_INITED)) == ITE_INITED)
    337   1.1       oki 		SUBR_DEINIT(ip);
    338   1.1       oki 
    339   1.1       oki 	/*
    340   1.1       oki 	 * XXX When the system is rebooted with "reboot", init(8)
    341   1.1       oki 	 * kills the last process to have the console open.
    342  1.37    simonb 	 * If we don't revent the ITE_ACTIVE bit from being
    343   1.1       oki 	 * cleared, we will never see messages printed during
    344   1.1       oki 	 * the process of rebooting.
    345   1.1       oki 	 */
    346  1.14   minoura 	if ((flag & 2) == 0 && (ip->flags & ITE_ISCONS) == 0) {
    347   1.1       oki 		ip->flags &= ~ITE_ACTIVE;
    348  1.14   minoura #if NKBD > 0
    349  1.49     isaki 		mfp_send_usart(0x48);	/* XXX */
    350  1.14   minoura #endif
    351  1.14   minoura 	}
    352   1.1       oki }
    353   1.1       oki 
    354   1.1       oki /*
    355   1.1       oki  * standard entry points to the device.
    356   1.1       oki  */
    357   1.1       oki 
    358   1.1       oki /* ARGSUSED */
    359  1.69   tsutsui static int
    360  1.42  christos iteopen(dev_t dev, int mode, int devtype, struct lwp *l)
    361   1.1       oki {
    362   1.1       oki 	int unit = UNIT(dev);
    363  1.38       chs 	struct tty *tp;
    364  1.38       chs 	struct ite_softc *ip;
    365  1.38       chs 	int error;
    366   1.1       oki 	int first = 0;
    367   1.1       oki 
    368  1.15   minoura 	if (unit >= ite_cd.cd_ndevs || (ip = getitesp(dev)) == NULL)
    369  1.69   tsutsui 		return ENXIO;
    370  1.69   tsutsui 	if (ite_tty[unit] == NULL) {
    371  1.59     rmind 		tp = ite_tty[unit] = tty_alloc();
    372   1.3       oki 		tty_attach(tp);
    373   1.3       oki 	} else
    374   1.1       oki 		tp = ite_tty[unit];
    375  1.47      elad 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
    376  1.69   tsutsui 		return EBUSY;
    377   1.1       oki 	if ((ip->flags & ITE_ACTIVE) == 0) {
    378   1.1       oki 		error = iteon(dev, 0);
    379   1.1       oki 		if (error)
    380  1.69   tsutsui 			return error;
    381   1.1       oki 		first = 1;
    382   1.1       oki 	}
    383   1.1       oki 	tp->t_oproc = itestart;
    384   1.1       oki 	tp->t_param = NULL;
    385   1.1       oki 	tp->t_dev = dev;
    386   1.1       oki 	if ((tp->t_state&TS_ISOPEN) == 0) {
    387   1.1       oki 		ttychars(tp);
    388   1.1       oki 		tp->t_iflag = TTYDEF_IFLAG;
    389   1.1       oki 		tp->t_oflag = TTYDEF_OFLAG;
    390   1.1       oki 		tp->t_cflag = TTYDEF_CFLAG;
    391   1.1       oki 		tp->t_lflag = TTYDEF_LFLAG;
    392   1.1       oki 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
    393   1.1       oki 		tp->t_state = TS_ISOPEN|TS_CARR_ON;
    394   1.1       oki 		ttsetwater(tp);
    395   1.1       oki 	}
    396  1.23       eeh 	error = (*tp->t_linesw->l_open)(dev, tp);
    397   1.1       oki 	if (error == 0) {
    398   1.1       oki 		tp->t_winsize.ws_row = ip->rows;
    399   1.1       oki 		tp->t_winsize.ws_col = ip->cols;
    400   1.1       oki 	} else if (first)
    401   1.1       oki 		iteoff(dev, 0);
    402  1.69   tsutsui 	return error;
    403   1.1       oki }
    404   1.1       oki 
    405   1.1       oki /*ARGSUSED*/
    406  1.69   tsutsui static int
    407  1.42  christos iteclose(dev_t dev, int flag, int mode, struct lwp *l)
    408   1.1       oki {
    409  1.38       chs 	struct tty *tp = ite_tty[UNIT(dev)];
    410   1.1       oki 
    411  1.23       eeh 	(*tp->t_linesw->l_close)(tp, flag);
    412   1.1       oki 	ttyclose(tp);
    413   1.1       oki 	iteoff(dev, 0);
    414   1.1       oki #if 0
    415  1.59     rmind 	tty_free(tp);
    416  1.69   tsutsui 	ite_tty[UNIT(dev)] = NULL;
    417   1.1       oki #endif
    418  1.69   tsutsui 	return 0;
    419   1.1       oki }
    420   1.1       oki 
    421  1.69   tsutsui static int
    422  1.38       chs iteread(dev_t dev, struct uio *uio, int flag)
    423   1.1       oki {
    424  1.38       chs 	struct tty *tp = ite_tty[UNIT(dev)];
    425   1.1       oki 
    426  1.69   tsutsui 	return (*tp->t_linesw->l_read)(tp, uio, flag);
    427   1.1       oki }
    428   1.1       oki 
    429  1.69   tsutsui static int
    430  1.38       chs itewrite(dev_t dev, struct uio *uio, int flag)
    431   1.1       oki {
    432  1.38       chs 	struct tty *tp = ite_tty[UNIT(dev)];
    433   1.1       oki 
    434  1.69   tsutsui 	return (*tp->t_linesw->l_write)(tp, uio, flag);
    435  1.25       scw }
    436  1.25       scw 
    437  1.69   tsutsui static int
    438  1.42  christos itepoll(dev_t dev, int events, struct lwp *l)
    439  1.25       scw {
    440  1.38       chs 	struct tty *tp = ite_tty[UNIT(dev)];
    441  1.50     isaki 
    442  1.69   tsutsui 	return (*tp->t_linesw->l_poll)(tp, events, l);
    443   1.1       oki }
    444   1.1       oki 
    445  1.69   tsutsui static struct tty *
    446  1.38       chs itetty(dev_t dev)
    447   1.1       oki {
    448   1.1       oki 
    449  1.69   tsutsui 	return ite_tty[UNIT(dev)];
    450   1.1       oki }
    451   1.1       oki 
    452  1.69   tsutsui static int
    453  1.48  christos iteioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
    454   1.1       oki {
    455   1.1       oki 	struct iterepeat *irp;
    456  1.38       chs 	struct tty *tp = ite_tty[UNIT(dev)];
    457   1.1       oki 	int error;
    458   1.1       oki 
    459  1.42  christos 	error = (*tp->t_linesw->l_ioctl)(tp, cmd, addr, flag, l);
    460  1.28    atatat 	if (error != EPASSTHROUGH)
    461  1.69   tsutsui 		return error;
    462  1.28    atatat 
    463  1.42  christos 	error = ttioctl(tp, cmd, addr, flag, l);
    464  1.28    atatat 	if (error != EPASSTHROUGH)
    465  1.69   tsutsui 		return error;
    466   1.1       oki 
    467   1.1       oki 	switch (cmd) {
    468   1.1       oki 	case ITEIOCSKMAP:
    469  1.69   tsutsui 		if (addr == NULL)
    470  1.69   tsutsui 			return EFAULT;
    471  1.27       wiz 		memcpy(&kbdmap, addr, sizeof(struct kbdmap));
    472  1.69   tsutsui 		return 0;
    473   1.1       oki 
    474   1.1       oki 	case ITEIOCGKMAP:
    475   1.1       oki 		if (addr == NULL)
    476  1.69   tsutsui 			return EFAULT;
    477  1.27       wiz 		memcpy(addr, &kbdmap, sizeof(struct kbdmap));
    478  1.69   tsutsui 		return 0;
    479   1.1       oki 
    480   1.1       oki 	case ITEIOCGREPT:
    481   1.1       oki 		irp = (struct iterepeat *)addr;
    482   1.1       oki 		irp->start = start_repeat_timeo;
    483   1.1       oki 		irp->next = next_repeat_timeo;
    484   1.1       oki 
    485   1.1       oki 	case ITEIOCSREPT:
    486   1.1       oki 		irp = (struct iterepeat *)addr;
    487   1.1       oki 		if (irp->start < ITEMINREPEAT && irp->next < ITEMINREPEAT)
    488   1.1       oki 			return(EINVAL);
    489   1.1       oki 		start_repeat_timeo = irp->start;
    490   1.1       oki 		next_repeat_timeo = irp->next;
    491   1.1       oki #if x68k
    492   1.1       oki 	case ITELOADFONT:
    493  1.69   tsutsui 		if (addr != NULL) {
    494  1.49     isaki 			memcpy(kern_font, addr, 4096 /*sizeof(kernel_font)*/);
    495  1.26     isaki 			ite_set_glyph();
    496   1.1       oki 			return 0;
    497   1.1       oki 		} else
    498   1.1       oki 			return EFAULT;
    499   1.1       oki 
    500   1.1       oki 	case ITETVCTRL:
    501  1.69   tsutsui 		if (addr != NULL && *(uint8_t *)addr < 0x40) {
    502  1.69   tsutsui 			return mfp_send_usart(*(uint8_t *)addr);
    503  1.14   minoura 		} else {
    504   1.1       oki 			return EFAULT;
    505  1.14   minoura 		}
    506   1.1       oki #endif
    507   1.1       oki 	}
    508  1.69   tsutsui 	return EPASSTHROUGH;
    509   1.1       oki }
    510   1.1       oki 
    511  1.69   tsutsui static void
    512  1.38       chs itestart(struct tty *tp)
    513   1.1       oki {
    514   1.1       oki 	struct clist *rbp;
    515  1.69   tsutsui 	uint8_t buf[ITEBURST];
    516  1.16   minoura 	int s, len;
    517   1.1       oki 
    518  1.62  christos 	getitesp(tp->t_dev);
    519   1.1       oki 	/*
    520   1.1       oki 	 * (Potentially) lower priority.  We only need to protect ourselves
    521   1.1       oki 	 * from keyboard interrupts since that is all that can affect the
    522   1.6  christos 	 * state of our tty (kernel printf doesn't go through this routine).
    523   1.1       oki 	 */
    524   1.1       oki 	s = spltty();
    525  1.69   tsutsui 	if ((tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) != 0)
    526   1.1       oki 		goto out;
    527   1.1       oki 	tp->t_state |= TS_BUSY;
    528   1.1       oki 	rbp = &tp->t_outq;
    529   1.1       oki 	len = q_to_b(rbp, buf, ITEBURST);
    530   1.1       oki 	/*splx(s);*/
    531   1.1       oki 
    532   1.1       oki 	/* Here is a really good place to implement pre/jumpscroll() */
    533   1.1       oki 	ite_putstr(buf, len, tp->t_dev);
    534   1.1       oki 
    535   1.1       oki 	/*s = spltty();*/
    536   1.1       oki 	tp->t_state &= ~TS_BUSY;
    537   1.1       oki 	/* we have characters remaining. */
    538  1.53        ad 	if (ttypull(tp)) {
    539   1.1       oki 		tp->t_state |= TS_TIMEOUT;
    540  1.52     joerg 		callout_schedule(&tp->t_rstrt_ch, 1);
    541   1.1       oki 	}
    542  1.69   tsutsui  out:
    543   1.1       oki 	splx(s);
    544   1.1       oki }
    545   1.1       oki 
    546   1.1       oki /* XXX called after changes made in underlying grf layer. */
    547   1.1       oki /* I want to nuke this */
    548  1.49     isaki void
    549  1.38       chs ite_reinit(dev_t dev)
    550   1.1       oki {
    551   1.1       oki 	struct ite_softc *ip;
    552   1.4       oki 	int unit = UNIT(dev);
    553   1.4       oki 
    554   1.4       oki 	/* XXX check whether when call from grf.c */
    555  1.12   minoura 	if (unit < 0 || unit >= ite_cd.cd_ndevs ||
    556  1.60   tsutsui 	    (ip = getitesp(dev)) == NULL)
    557   1.4       oki 		return;
    558   1.1       oki 
    559   1.1       oki 	ip->flags &= ~ITE_INITED;
    560   1.1       oki 	iteinit(dev);
    561   1.1       oki }
    562   1.1       oki 
    563  1.49     isaki void
    564  1.38       chs ite_reset(struct ite_softc *ip)
    565   1.1       oki {
    566   1.1       oki 	int i;
    567   1.1       oki 
    568   1.1       oki 	ip->curx = 0;
    569   1.1       oki 	ip->cury = 0;
    570   1.1       oki 	ip->attribute = 0;
    571   1.1       oki 	ip->save_curx = 0;
    572   1.1       oki 	ip->save_cury = 0;
    573   1.1       oki 	ip->save_attribute = 0;
    574   1.1       oki 	ip->ap = ip->argbuf;
    575   1.1       oki 	ip->emul_level = EMUL_VT300_8;
    576   1.1       oki 	ip->eightbit_C1 = 0;
    577   1.1       oki 	ip->top_margin = 0;
    578   1.1       oki 	ip->bottom_margin = ip->rows - 1;
    579   1.1       oki 	ip->inside_margins = 0; /* origin mode == absolute */
    580   1.1       oki 	ip->linefeed_newline = 0;
    581   1.1       oki 	ip->auto_wrap = 1;
    582   1.1       oki 	ip->cursor_appmode = 0;
    583   1.1       oki 	ip->keypad_appmode = 0;
    584   1.1       oki 	ip->imode = 0;
    585   1.1       oki 	ip->key_repeat = 1;
    586   1.1       oki 	ip->G0 = CSET_ASCII;
    587   1.1       oki 	ip->G1 = CSET_JIS1983;
    588   1.1       oki 	ip->G2 = CSET_JISKANA;
    589   1.1       oki 	ip->G3 = CSET_JIS1990;
    590   1.1       oki 	ip->GL = &ip->G0;
    591   1.1       oki 	ip->GR = &ip->G1;
    592   1.1       oki 	ip->save_GL = 0;
    593   1.1       oki 	ip->save_char = 0;
    594   1.1       oki 	ip->fgcolor = 7;
    595   1.1       oki 	ip->bgcolor = 0;
    596   1.1       oki 	for (i = 0; i < ip->cols; i++)
    597   1.1       oki 		ip->tabs[i] = ((i & 7) == 0);
    598   1.1       oki 	/* XXX clear screen */
    599   1.1       oki 	SUBR_CLEAR(ip, 0, 0, ip->rows, ip->cols);
    600   1.1       oki 	attrclr(ip, 0, 0, ip->rows, ip->cols);
    601   1.1       oki }
    602   1.1       oki 
    603   1.1       oki /* Used in console at startup only */
    604   1.1       oki int
    605  1.49     isaki ite_cnfilter(u_char c)
    606   1.1       oki {
    607   1.1       oki 	static u_char mod = 0;
    608   1.1       oki 	struct key key;
    609  1.69   tsutsui 	uint8_t code, up, mask;
    610  1.16   minoura 	int s;
    611   1.1       oki 
    612   1.1       oki 	up = c & 0x80 ? 1 : 0;
    613   1.1       oki 	c &= 0x7f;
    614   1.1       oki 	code = 0;
    615   1.1       oki 
    616   1.1       oki 	s = spltty();
    617   1.1       oki 
    618   1.1       oki 	mask = 0;
    619  1.69   tsutsui 	if (c >= KBD_LEFT_ALT &&
    620  1.69   tsutsui 	    !(c >= 0x63 && c <= 0x6c)) {	/* 0x63: F1, 0x6c:F10 */
    621   1.1       oki 		switch (c) {
    622   1.1       oki 		case KBD_LEFT_SHIFT:
    623   1.1       oki 			mask = KBD_MOD_SHIFT;
    624   1.1       oki 			break;
    625   1.1       oki 
    626   1.1       oki 		case KBD_LEFT_ALT:
    627   1.1       oki 			mask = KBD_MOD_LALT;
    628   1.1       oki 			break;
    629   1.1       oki 
    630   1.1       oki 		case KBD_RIGHT_ALT:
    631   1.1       oki 			mask = KBD_MOD_RALT;
    632   1.1       oki 			break;
    633   1.1       oki 
    634   1.1       oki 		case KBD_LEFT_META:
    635   1.1       oki 			mask = KBD_MOD_LMETA;
    636   1.1       oki 			break;
    637   1.1       oki 
    638   1.1       oki 		case KBD_RIGHT_META:
    639   1.1       oki 			mask = KBD_MOD_RMETA;
    640   1.1       oki 			break;
    641   1.1       oki 
    642  1.49     isaki 		case KBD_CAPS_LOCK:
    643   1.1       oki 			/*
    644   1.1       oki 			 * capslock already behaves `right', don't need to
    645   1.1       oki 			 * keep track of the state in here.
    646   1.1       oki 			 */
    647   1.1       oki 			mask = KBD_MOD_CAPS;
    648   1.1       oki 			break;
    649   1.1       oki 
    650   1.1       oki 		case KBD_CTRL:
    651   1.1       oki 			mask = KBD_MOD_CTRL;
    652   1.1       oki 			break;
    653   1.1       oki 
    654   1.1       oki 		case KBD_RECONNECT:
    655   1.1       oki 			/* ite got 0xff */
    656   1.1       oki 			if (up)
    657   1.1       oki 				kbd_setLED();
    658   1.1       oki 			break;
    659   1.1       oki 		}
    660   1.1       oki 		if (mask & KBD_MOD_CAPS) {
    661   1.1       oki 			if (!up) {
    662   1.1       oki 				mod ^= KBD_MOD_CAPS;
    663   1.1       oki 				kbdled ^= LED_CAPS_LOCK;
    664   1.1       oki 				kbd_setLED();
    665   1.1       oki 			}
    666   1.1       oki 		} else if (up)
    667   1.1       oki 			mod &= ~mask;
    668  1.69   tsutsui 		else
    669  1.69   tsutsui 			mod |= mask;
    670  1.49     isaki 		splx(s);
    671   1.1       oki 		return -1;
    672   1.1       oki 	}
    673   1.1       oki 
    674   1.1       oki 	if (up) {
    675   1.1       oki 		splx(s);
    676   1.1       oki 		return -1;
    677   1.1       oki 	}
    678   1.1       oki 
    679   1.1       oki 	/* translate modifiers */
    680  1.69   tsutsui 	if ((mod & KBD_MOD_SHIFT) != 0) {
    681  1.69   tsutsui 		if ((mod & KBD_MOD_ALT) != 0)
    682   1.1       oki 			key = kbdmap.alt_shift_keys[c];
    683  1.50     isaki 		else
    684   1.1       oki 			key = kbdmap.shift_keys[c];
    685  1.69   tsutsui 	} else if ((mod & KBD_MOD_ALT) != 0)
    686   1.1       oki 		key = kbdmap.alt_keys[c];
    687   1.1       oki 	else {
    688   1.1       oki 		key = kbdmap.keys[c];
    689   1.1       oki 		/* if CAPS and key is CAPable (no pun intended) */
    690  1.69   tsutsui 		if ((mod & KBD_MOD_CAPS) != 0 &&
    691  1.69   tsutsui 		    (key.mode & KBD_MODE_CAPS) != 0)
    692   1.1       oki 			key = kbdmap.shift_keys[c];
    693   1.1       oki 	}
    694   1.1       oki 	code = key.code;
    695   1.1       oki 
    696   1.1       oki 	/* if string return */
    697  1.69   tsutsui 	if ((key.mode & (KBD_MODE_STRING | KBD_MODE_KPAD)) != 0) {
    698   1.1       oki 		splx(s);
    699   1.1       oki 		return -1;
    700   1.1       oki 	}
    701   1.1       oki 	/* handle dead keys */
    702  1.69   tsutsui 	if ((key.mode & KBD_MODE_DEAD) != 0) {
    703   1.1       oki 		splx(s);
    704   1.1       oki 		return -1;
    705   1.1       oki 	}
    706  1.69   tsutsui 	if ((mod & KBD_MOD_CTRL) != 0)
    707   1.1       oki 		code &= 0x1f;
    708  1.69   tsutsui 	if ((mod & KBD_MOD_META) != 0)
    709   1.1       oki 		code |= 0x80;
    710   1.1       oki 
    711   1.1       oki 	/* do console mapping. */
    712   1.1       oki 	code = code == '\r' ? '\n' : code;
    713   1.1       oki 
    714   1.1       oki 	splx(s);
    715  1.69   tsutsui 	return code;
    716   1.1       oki }
    717   1.1       oki 
    718   1.1       oki /* And now the old stuff. */
    719  1.69   tsutsui static inline void
    720  1.38       chs itesendch(int ch)
    721   1.1       oki {
    722  1.69   tsutsui 
    723  1.24   minoura 	(*kbd_tty->t_linesw->l_rint)(ch, kbd_tty);
    724   1.1       oki }
    725   1.1       oki 
    726   1.1       oki void
    727  1.49     isaki ite_filter(u_char c)
    728   1.1       oki {
    729  1.69   tsutsui 	static uint16_t mod = 0;
    730  1.69   tsutsui 	uint8_t code, *str;
    731  1.69   tsutsui 	uint16_t up, mask;
    732   1.1       oki 	struct key key;
    733   1.1       oki 	int s, i;
    734   1.1       oki 
    735  1.69   tsutsui 	if (kbd_ite == NULL ||
    736  1.69   tsutsui 	    (kbd_tty = ite_tty[device_unit(kbd_ite->device)]) == NULL)
    737   1.1       oki 		return;
    738   1.1       oki 
    739   1.1       oki 	/* have to make sure we're at spltty in here */
    740  1.49     isaki 	s = spltty();
    741   1.1       oki 
    742   1.1       oki 	up = c & 0x80 ? 1 : 0;
    743   1.1       oki 	c &= 0x7f;
    744   1.1       oki 	code = 0;
    745  1.50     isaki 
    746   1.1       oki 	mask = 0;
    747   1.1       oki 	if (c >= KBD_LEFT_ALT &&
    748   1.1       oki 	    !(c >= 0x63 && c <= 0x6c)) {	/* 0x63: F1, 0x6c:F10 */
    749   1.1       oki 		switch (c) {
    750   1.1       oki 		case KBD_LEFT_SHIFT:
    751   1.1       oki 			mask = KBD_MOD_SHIFT;
    752   1.1       oki 			break;
    753   1.1       oki 
    754   1.1       oki 		case KBD_LEFT_ALT:
    755   1.1       oki 			mask = KBD_MOD_LALT;
    756   1.1       oki 			break;
    757  1.49     isaki 
    758   1.1       oki 		case KBD_RIGHT_ALT:
    759   1.1       oki 			mask = KBD_MOD_RALT;
    760   1.1       oki 			break;
    761  1.49     isaki 
    762   1.1       oki 		case KBD_LEFT_META:
    763   1.1       oki 			mask = KBD_MOD_LMETA;
    764   1.1       oki 			break;
    765   1.1       oki 
    766   1.1       oki 		case KBD_RIGHT_META:
    767   1.1       oki 			mask = KBD_MOD_RMETA;
    768   1.1       oki 			break;
    769   1.1       oki 
    770   1.1       oki 		case KBD_CAPS_LOCK:
    771   1.1       oki 			/*
    772   1.1       oki 			 * capslock already behaves `right', don't need to keep
    773   1.1       oki 			 * track of the state in here.
    774   1.1       oki 			 */
    775   1.1       oki 			mask = KBD_MOD_CAPS;
    776   1.1       oki 			break;
    777   1.1       oki 
    778   1.1       oki 		case KBD_CTRL:
    779   1.1       oki 			mask = KBD_MOD_CTRL;
    780   1.1       oki 			break;
    781   1.1       oki 
    782   1.1       oki 		case KBD_OPT1:
    783   1.1       oki 			mask = KBD_MOD_OPT1;
    784   1.1       oki 			break;
    785   1.1       oki 
    786   1.1       oki 		case KBD_OPT2:
    787   1.1       oki 			mask = KBD_MOD_OPT2;
    788   1.1       oki 			break;
    789   1.1       oki 
    790   1.1       oki 		case KBD_RECONNECT:
    791   1.1       oki 			if (up) { /* ite got 0xff */
    792   1.1       oki 				kbd_setLED();
    793   1.1       oki 			}
    794   1.1       oki 			break;
    795   1.1       oki 		}
    796   1.1       oki 
    797  1.69   tsutsui 		if ((mask & KBD_MOD_CAPS) != 0) {
    798   1.1       oki 			if (!up) {
    799   1.1       oki 				mod ^= KBD_MOD_CAPS;
    800   1.1       oki 				kbdled ^= LED_CAPS_LOCK;
    801   1.1       oki 				kbd_setLED();
    802   1.1       oki 			}
    803   1.1       oki 		} else if (up) {
    804   1.1       oki 			mod &= ~mask;
    805  1.69   tsutsui 		} else
    806  1.69   tsutsui 			mod |= mask;
    807   1.1       oki 
    808   1.1       oki 		/*
    809   1.1       oki 		 * return even if it wasn't a modifier key, the other
    810   1.1       oki 		 * codes up here are either special (like reset warning),
    811   1.1       oki 		 * or not yet defined
    812   1.1       oki 		 */
    813  1.49     isaki 		splx(s);
    814   1.1       oki 		return;
    815   1.1       oki 	}
    816   1.1       oki 
    817   1.1       oki 	if (up) {
    818  1.49     isaki 		splx(s);
    819   1.1       oki 		return;
    820   1.1       oki 	}
    821   1.1       oki 
    822   1.1       oki 	/*
    823   1.1       oki 	 * intercept LAlt-LMeta-F1 here to switch back to original ascii-keymap.
    824   1.1       oki 	 * this should probably be configurable..
    825   1.1       oki 	 */
    826  1.16   minoura 	if (mod == (KBD_MOD_LALT|KBD_MOD_LMETA) && c == 0x63) {
    827  1.27       wiz 		memcpy(&kbdmap, &ascii_kbdmap, sizeof(struct kbdmap));
    828  1.49     isaki 		splx(s);
    829   1.1       oki 		return;
    830   1.1       oki 	}
    831   1.1       oki 
    832   1.1       oki 	/* translate modifiers */
    833  1.69   tsutsui 	if ((mod & KBD_MOD_SHIFT) != 0) {
    834  1.69   tsutsui 		if ((mod & KBD_MOD_ALT) != 0)
    835   1.1       oki 			key = kbdmap.alt_shift_keys[c];
    836  1.50     isaki 		else
    837   1.1       oki 			key = kbdmap.shift_keys[c];
    838  1.69   tsutsui 	} else if ((mod & KBD_MOD_ALT) != 0)
    839   1.1       oki 		key = kbdmap.alt_keys[c];
    840   1.1       oki 	else {
    841   1.1       oki 		key = kbdmap.keys[c];
    842   1.1       oki 		/* if CAPS and key is CAPable (no pun intended) */
    843  1.69   tsutsui 		if ((mod & KBD_MOD_CAPS) != 0 &&
    844  1.69   tsutsui 		    (key.mode & KBD_MODE_CAPS) != 0)
    845   1.1       oki 			key = kbdmap.shift_keys[c];
    846  1.69   tsutsui 		else if ((mod & KBD_MOD_OPT2) != 0 &&
    847  1.69   tsutsui 		    	 (key.mode & KBD_MODE_KPAD) != 0)
    848   1.1       oki 			key = kbdmap.shift_keys[c];
    849   1.1       oki 	}
    850   1.1       oki 	code = key.code;
    851  1.50     isaki 
    852   1.1       oki 	/* handle dead keys */
    853  1.69   tsutsui 	if ((key.mode & KBD_MODE_DEAD) != 0) {
    854  1.49     isaki 		splx(s);
    855   1.1       oki 		return;
    856   1.1       oki 	}
    857  1.50     isaki 	/* if not string, apply META and CTRL modifiers */
    858  1.69   tsutsui 	if ((key.mode & KBD_MODE_STRING) == 0 &&
    859  1.69   tsutsui 	    ((key.mode & KBD_MODE_KPAD) == 0 ||
    860  1.69   tsutsui 	     (kbd_ite != NULL && kbd_ite->keypad_appmode == 0))) {
    861  1.69   tsutsui 		if ((mod & KBD_MOD_CTRL) != 0 &&
    862   1.1       oki 		    (code == ' ' || (code >= '@' && code <= 'z')))
    863   1.1       oki 			code &= 0x1f;
    864  1.69   tsutsui 		if ((mod & KBD_MOD_META) != 0)
    865   1.1       oki 			code |= 0x80;
    866  1.69   tsutsui 	} else if ((key.mode & KBD_MODE_KPAD) != 0 &&
    867  1.69   tsutsui 	       (kbd_ite != NULL && kbd_ite->keypad_appmode != 0)) {
    868  1.36  jdolecek 		static const char * const in = "0123456789-+.\r()/*";
    869  1.36  jdolecek 		static const char * const out = "pqrstuvwxymlnMPQRS";
    870  1.36  jdolecek 		char *cp = strchr(in, code);
    871   1.1       oki 
    872  1.50     isaki 		/*
    873   1.1       oki 		 * keypad-appmode sends SS3 followed by the above
    874   1.1       oki 		 * translated character
    875   1.1       oki 		 */
    876  1.49     isaki 		(*kbd_tty->t_linesw->l_rint)(27, kbd_tty);
    877  1.49     isaki 		(*kbd_tty->t_linesw->l_rint)('O', kbd_tty);
    878  1.49     isaki 		(*kbd_tty->t_linesw->l_rint)(out[cp - in], kbd_tty);
    879   1.1       oki 		splx(s);
    880   1.1       oki 		return;
    881   1.1       oki 	} else {
    882   1.1       oki 		/* *NO* I don't like this.... */
    883  1.69   tsutsui 		static u_char app_cursor[] = {
    884   1.1       oki 		  3, 27, 'O', 'A',
    885   1.1       oki 		  3, 27, 'O', 'B',
    886   1.1       oki 		  3, 27, 'O', 'C',
    887  1.69   tsutsui 		  3, 27, 'O', 'D'
    888  1.69   tsutsui 		};
    889   1.1       oki 
    890   1.1       oki 		str = kbdmap.strings + code;
    891  1.50     isaki 		/*
    892   1.1       oki 		 * if this is a cursor key, AND it has the default
    893   1.1       oki 		 * keymap setting, AND we're in app-cursor mode, switch
    894   1.1       oki 		 * to the above table. This is *nasty* !
    895   1.1       oki 		 */
    896  1.69   tsutsui 		if (c >= 0x3b && c <= 0x3e && kbd_ite->cursor_appmode != 0 &&
    897  1.69   tsutsui 		    memcmp(str, "\x03\x1b[", 3) == 0 &&
    898  1.69   tsutsui 		    strchr("ABCD", str[3]) != 0)
    899   1.1       oki 			str = app_cursor + 4 * (str[3] - 'A');
    900   1.1       oki 
    901  1.50     isaki 		/*
    902   1.1       oki 		 * using a length-byte instead of 0-termination allows
    903   1.1       oki 		 * to embed \0 into strings, although this is not used
    904   1.1       oki 		 * in the default keymap
    905   1.1       oki 		 */
    906   1.1       oki 		for (i = *str++; i; i--)
    907  1.49     isaki 			(*kbd_tty->t_linesw->l_rint)(*str++, kbd_tty);
    908   1.1       oki 		splx(s);
    909   1.1       oki 		return;
    910   1.1       oki 	}
    911  1.24   minoura 	(*kbd_tty->t_linesw->l_rint)(code, kbd_tty);
    912   1.1       oki 
    913   1.1       oki 	splx(s);
    914   1.1       oki 	return;
    915   1.1       oki }
    916   1.1       oki 
    917   1.1       oki /* helper functions, makes the code below more readable */
    918  1.69   tsutsui static inline void
    919  1.40        he ite_sendstr(struct ite_softc *ip, const char *str)
    920   1.1       oki {
    921  1.69   tsutsui 
    922  1.69   tsutsui 	while (*str != 0)
    923  1.49     isaki 		itesendch(*str++);
    924   1.1       oki }
    925   1.1       oki 
    926  1.69   tsutsui static inline void
    927  1.38       chs alignment_display(struct ite_softc *ip)
    928   1.1       oki {
    929   1.1       oki 	int i, j;
    930   1.1       oki 
    931   1.1       oki 	for (j = 0; j < ip->rows; j++)
    932   1.1       oki 		for (i = 0; i < ip->cols; i++)
    933   1.1       oki 			SUBR_PUTC(ip, 'E', j, i, ATTR_NOR);
    934   1.1       oki 	attrclr(ip, 0, 0, ip->rows, ip->cols);
    935   1.1       oki }
    936   1.1       oki 
    937  1.69   tsutsui static inline void
    938  1.38       chs snap_cury(struct ite_softc *ip)
    939   1.1       oki {
    940  1.69   tsutsui 
    941  1.69   tsutsui 	if (ip->inside_margins != 0) {
    942   1.1       oki 		if (ip->cury < ip->top_margin)
    943   1.1       oki 			ip->cury = ip->top_margin;
    944   1.1       oki 		if (ip->cury > ip->bottom_margin)
    945   1.1       oki 			ip->cury = ip->bottom_margin;
    946   1.1       oki 	}
    947   1.1       oki }
    948   1.1       oki 
    949  1.69   tsutsui static inline void
    950  1.38       chs ite_dnchar(struct ite_softc *ip, int n)
    951   1.1       oki {
    952  1.69   tsutsui 
    953  1.64  riastrad 	n = uimin(n, ip->cols - ip->curx);
    954   1.1       oki 	if (n < ip->cols - ip->curx) {
    955   1.1       oki 		SUBR_SCROLL(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT);
    956   1.1       oki 		attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx,
    957  1.69   tsutsui 		    1, ip->cols - ip->curx - n);
    958   1.1       oki 		attrclr(ip, ip->cury, ip->cols - n, 1, n);
    959   1.1       oki 	}
    960   1.1       oki 	while (n-- > 0)
    961   1.1       oki 		SUBR_PUTC(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR);
    962   1.1       oki }
    963   1.1       oki 
    964  1.49     isaki static void
    965  1.38       chs ite_inchar(struct ite_softc *ip, int n)
    966   1.1       oki {
    967   1.1       oki 	int c = ip->save_char;
    968  1.69   tsutsui 
    969   1.1       oki 	ip->save_char = 0;
    970  1.64  riastrad 	n = uimin(n, ip->cols - ip->curx);
    971   1.1       oki 	if (n < ip->cols - ip->curx) {
    972   1.1       oki 		SUBR_SCROLL(ip, ip->cury, ip->curx, n, SCROLL_RIGHT);
    973   1.1       oki 		attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n,
    974  1.69   tsutsui 		    1, ip->cols - ip->curx - n);
    975   1.1       oki 		attrclr(ip, ip->cury, ip->curx, 1, n);
    976   1.1       oki 	}
    977  1.69   tsutsui 	while (n-- != 0)
    978   1.1       oki 		SUBR_PUTC(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
    979   1.1       oki 	ip->save_char = c;
    980   1.1       oki }
    981   1.1       oki 
    982  1.69   tsutsui static inline void
    983  1.38       chs ite_clrtoeol(struct ite_softc *ip)
    984   1.1       oki {
    985   1.1       oki 	int y = ip->cury, x = ip->curx;
    986  1.69   tsutsui 
    987   1.1       oki 	if (ip->cols - x > 0) {
    988   1.1       oki 		SUBR_CLEAR(ip, y, x, 1, ip->cols - x);
    989   1.1       oki 		attrclr(ip, y, x, 1, ip->cols - x);
    990   1.1       oki 	}
    991   1.1       oki }
    992   1.1       oki 
    993  1.69   tsutsui static inline void
    994  1.38       chs ite_clrtobol(struct ite_softc *ip)
    995   1.1       oki {
    996  1.64  riastrad 	int y = ip->cury, x = uimin(ip->curx + 1, ip->cols);
    997  1.69   tsutsui 
    998   1.1       oki 	SUBR_CLEAR(ip, y, 0, 1, x);
    999   1.1       oki 	attrclr(ip, y, 0, 1, x);
   1000   1.1       oki }
   1001   1.1       oki 
   1002  1.69   tsutsui static inline void
   1003  1.38       chs ite_clrline(struct ite_softc *ip)
   1004   1.1       oki {
   1005   1.1       oki 	int y = ip->cury;
   1006  1.69   tsutsui 
   1007   1.1       oki 	SUBR_CLEAR(ip, y, 0, 1, ip->cols);
   1008   1.1       oki 	attrclr(ip, y, 0, 1, ip->cols);
   1009   1.1       oki }
   1010   1.1       oki 
   1011  1.69   tsutsui static inline void
   1012  1.38       chs ite_clrtoeos(struct ite_softc *ip)
   1013   1.1       oki {
   1014  1.69   tsutsui 
   1015   1.1       oki 	ite_clrtoeol(ip);
   1016   1.1       oki 	if (ip->cury < ip->rows - 1) {
   1017  1.69   tsutsui 		SUBR_CLEAR(ip, ip->cury + 1, 0,
   1018  1.69   tsutsui 		    ip->rows - 1 - ip->cury, ip->cols);
   1019   1.1       oki 		attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
   1020   1.1       oki 	}
   1021   1.1       oki }
   1022   1.1       oki 
   1023  1.69   tsutsui static inline void
   1024  1.38       chs ite_clrtobos(struct ite_softc *ip)
   1025   1.1       oki {
   1026  1.69   tsutsui 
   1027   1.1       oki 	ite_clrtobol(ip);
   1028   1.1       oki 	if (ip->cury > 0) {
   1029   1.1       oki 		SUBR_CLEAR(ip, 0, 0, ip->cury, ip->cols);
   1030   1.1       oki 		attrclr(ip, 0, 0, ip->cury, ip->cols);
   1031   1.1       oki 	}
   1032   1.1       oki }
   1033   1.1       oki 
   1034  1.69   tsutsui static inline void
   1035  1.38       chs ite_clrscreen(struct ite_softc *ip)
   1036   1.1       oki {
   1037  1.69   tsutsui 
   1038   1.1       oki 	SUBR_CLEAR(ip, 0, 0, ip->rows, ip->cols);
   1039   1.1       oki 	attrclr(ip, 0, 0, ip->rows, ip->cols);
   1040   1.1       oki }
   1041   1.1       oki 
   1042  1.69   tsutsui static inline void
   1043  1.38       chs ite_dnline(struct ite_softc *ip, int n)
   1044   1.1       oki {
   1045  1.69   tsutsui 
   1046   1.1       oki 	/*
   1047   1.1       oki 	 * interesting.. if the cursor is outside the scrolling
   1048   1.1       oki 	 * region, this command is simply ignored..
   1049   1.1       oki 	 */
   1050   1.1       oki 	if (ip->cury < ip->top_margin || ip->cury > ip->bottom_margin)
   1051   1.1       oki 		return;
   1052   1.1       oki 
   1053  1.64  riastrad 	n = uimin(n, ip->bottom_margin + 1 - ip->cury);
   1054   1.1       oki 	if (n <= ip->bottom_margin - ip->cury) {
   1055   1.1       oki 		SUBR_SCROLL(ip, ip->cury + n, 0, n, SCROLL_UP);
   1056   1.1       oki 		attrmov(ip, ip->cury + n, 0, ip->cury, 0,
   1057  1.69   tsutsui 		    ip->bottom_margin + 1 - ip->cury - n, ip->cols);
   1058   1.1       oki 	}
   1059   1.1       oki 	SUBR_CLEAR(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
   1060   1.1       oki 	attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
   1061   1.1       oki }
   1062   1.1       oki 
   1063  1.69   tsutsui static inline void
   1064  1.38       chs ite_inline(struct ite_softc *ip, int n)
   1065   1.1       oki {
   1066  1.69   tsutsui 
   1067   1.1       oki 	/*
   1068   1.1       oki 	 * interesting.. if the cursor is outside the scrolling
   1069   1.1       oki 	 * region, this command is simply ignored..
   1070   1.1       oki 	 */
   1071   1.1       oki 	if (ip->cury < ip->top_margin || ip->cury > ip->bottom_margin)
   1072   1.1       oki 		return;
   1073   1.1       oki 
   1074   1.1       oki 	if (n <= 0)
   1075   1.1       oki 		n = 1;
   1076  1.69   tsutsui 	else
   1077  1.69   tsutsui 		n = uimin(n, ip->bottom_margin + 1 - ip->cury);
   1078   1.1       oki 	if (n <= ip->bottom_margin  - ip->cury) {
   1079   1.1       oki 		SUBR_SCROLL(ip, ip->cury, 0, n, SCROLL_DOWN);
   1080   1.1       oki 		attrmov(ip, ip->cury, 0, ip->cury + n, 0,
   1081  1.69   tsutsui 		    ip->bottom_margin + 1 - ip->cury - n, ip->cols);
   1082   1.1       oki 	}
   1083   1.1       oki 	SUBR_CLEAR(ip, ip->cury, 0, n, ip->cols);
   1084   1.1       oki 	attrclr(ip, ip->cury, 0, n, ip->cols);
   1085   1.1       oki 	ip->curx = 0;
   1086   1.1       oki }
   1087   1.1       oki 
   1088  1.69   tsutsui static inline void
   1089  1.38       chs ite_index(struct ite_softc *ip)
   1090   1.1       oki {
   1091  1.69   tsutsui 
   1092   1.1       oki 	++ip->cury;
   1093   1.1       oki 	if ((ip->cury == ip->bottom_margin+1) || (ip->cury == ip->rows)) {
   1094   1.1       oki 		ip->cury--;
   1095   1.1       oki 		SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
   1096   1.1       oki 		ite_clrline(ip);
   1097   1.1       oki 	}
   1098   1.1       oki 	/*clr_attr(ip, ATTR_INV);*/
   1099   1.1       oki }
   1100   1.1       oki 
   1101  1.69   tsutsui static inline void
   1102  1.38       chs ite_lf(struct ite_softc *ip)
   1103   1.1       oki {
   1104  1.69   tsutsui 
   1105   1.1       oki 	++ip->cury;
   1106   1.1       oki 	if (ip->cury > ip->bottom_margin) {
   1107   1.1       oki 		ip->cury--;
   1108   1.1       oki 		SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
   1109   1.1       oki 		ite_clrline(ip);
   1110   1.1       oki 	}
   1111  1.69   tsutsui 	/*SUBR_CURSOR(ip, MOVE_CURSOR);*/
   1112   1.1       oki 	/*clr_attr(ip, ATTR_INV);*/
   1113   1.1       oki 	/* reset character set ... thanks for mohta. */
   1114   1.1       oki 	ip->G0 = CSET_ASCII;
   1115   1.1       oki 	ip->G1 = CSET_JIS1983;
   1116   1.1       oki 	ip->G2 = CSET_JISKANA;
   1117   1.1       oki 	ip->G3 = CSET_JIS1990;
   1118   1.1       oki 	ip->GL = &ip->G0;
   1119   1.1       oki 	ip->GR = &ip->G1;
   1120   1.1       oki 	ip->save_GL = 0;
   1121   1.1       oki 	ip->save_char = 0;
   1122   1.1       oki }
   1123   1.1       oki 
   1124  1.69   tsutsui static inline void
   1125  1.38       chs ite_crlf(struct ite_softc *ip)
   1126   1.1       oki {
   1127  1.69   tsutsui 
   1128   1.1       oki 	ip->curx = 0;
   1129  1.69   tsutsui 	ite_lf(ip);
   1130   1.1       oki }
   1131   1.1       oki 
   1132  1.69   tsutsui static inline void
   1133  1.38       chs ite_cr(struct ite_softc *ip)
   1134   1.1       oki {
   1135  1.69   tsutsui 
   1136  1.69   tsutsui 	if (ip->curx != 0) {
   1137   1.1       oki 		ip->curx = 0;
   1138   1.1       oki 	}
   1139   1.1       oki }
   1140   1.1       oki 
   1141  1.69   tsutsui static inline void
   1142  1.38       chs ite_rlf(struct ite_softc *ip)
   1143   1.1       oki {
   1144  1.69   tsutsui 
   1145   1.1       oki 	ip->cury--;
   1146   1.1       oki 	if ((ip->cury < 0) || (ip->cury == ip->top_margin - 1)) {
   1147   1.1       oki 		ip->cury++;
   1148   1.1       oki 		SUBR_SCROLL(ip, ip->top_margin, 0, 1, SCROLL_DOWN);
   1149   1.1       oki 		ite_clrline(ip);
   1150   1.1       oki 	}
   1151   1.1       oki 	clr_attr(ip, ATTR_INV);
   1152   1.1       oki }
   1153   1.1       oki 
   1154  1.69   tsutsui static inline int
   1155  1.38       chs atoi(const char *cp)
   1156   1.1       oki {
   1157   1.1       oki 	int n;
   1158   1.1       oki 
   1159   1.1       oki 	for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++)
   1160   1.1       oki 		n = n * 10 + *cp - '0';
   1161   1.1       oki 	return n;
   1162   1.1       oki }
   1163   1.1       oki 
   1164  1.69   tsutsui static inline int
   1165  1.38       chs ite_argnum(struct ite_softc *ip)
   1166   1.1       oki {
   1167   1.1       oki 	char ch;
   1168   1.1       oki 	int n;
   1169   1.1       oki 
   1170   1.1       oki 	/* convert argument string into number */
   1171   1.1       oki 	if (ip->ap == ip->argbuf)
   1172   1.1       oki 		return 1;
   1173   1.1       oki 	ch = *ip->ap;
   1174   1.1       oki 	*ip->ap = 0;
   1175  1.49     isaki 	n = atoi(ip->argbuf);
   1176   1.1       oki 	*ip->ap = ch;
   1177   1.1       oki 
   1178   1.1       oki 	return n;
   1179   1.1       oki }
   1180   1.1       oki 
   1181  1.69   tsutsui static inline int
   1182  1.38       chs ite_zargnum(struct ite_softc *ip)
   1183   1.1       oki {
   1184   1.1       oki 	char ch;
   1185   1.1       oki 	int n;
   1186   1.1       oki 
   1187   1.1       oki 	/* convert argument string into number */
   1188   1.1       oki 	if (ip->ap == ip->argbuf)
   1189   1.1       oki 		return 0;
   1190   1.1       oki 	ch = *ip->ap;
   1191   1.1       oki 	*ip->ap = 0;	/* terminate string */
   1192  1.49     isaki 	n = atoi(ip->argbuf);
   1193   1.1       oki 	*ip->ap = ch;
   1194  1.50     isaki 
   1195   1.1       oki 	return n;	/* don't "n ? n : 1" here, <CSI>0m != <CSI>1m ! */
   1196   1.1       oki }
   1197   1.1       oki 
   1198  1.69   tsutsui static void
   1199  1.49     isaki ite_putstr(const u_char *s, int len, dev_t dev)
   1200   1.1       oki {
   1201   1.1       oki 	struct ite_softc *ip;
   1202   1.1       oki 	int i;
   1203   1.1       oki 
   1204   1.1       oki 	ip = getitesp(dev);
   1205   1.1       oki 
   1206   1.1       oki 	/* XXX avoid problems */
   1207   1.1       oki 	if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
   1208   1.1       oki 	  	return;
   1209   1.1       oki 
   1210   1.1       oki 	SUBR_CURSOR(ip, START_CURSOROPT);
   1211   1.1       oki 	for (i = 0; i < len; i++)
   1212  1.69   tsutsui 		if (s[i] != 0)
   1213   1.1       oki 			iteputchar(s[i], ip);
   1214   1.1       oki 	SUBR_CURSOR(ip, END_CURSOROPT);
   1215   1.1       oki }
   1216   1.1       oki 
   1217  1.69   tsutsui static void
   1218  1.38       chs iteputchar(int c, struct ite_softc *ip)
   1219   1.1       oki {
   1220   1.1       oki 	int n, x, y;
   1221   1.1       oki 	char *cp;
   1222   1.1       oki 
   1223  1.69   tsutsui 	if (c >= 0x20 && ip->escape != 0) {
   1224   1.1       oki 		switch (ip->escape) {
   1225   1.1       oki 
   1226   1.1       oki 		case ESC:
   1227   1.1       oki 			switch (c) {
   1228  1.69   tsutsui 			/*
   1229  1.69   tsutsui 			 * first 7bit equivalents for the 8bit control
   1230  1.69   tsutsui 			 * characters
   1231  1.69   tsutsui 			 */
   1232  1.50     isaki 
   1233   1.1       oki 			case 'D':
   1234   1.1       oki 				c = IND;
   1235   1.1       oki 				ip->escape = 0;
   1236  1.69   tsutsui 				break;
   1237  1.69   tsutsui 				/*
   1238  1.69   tsutsui 				 * and fall into the next switch below
   1239  1.69   tsutsui 				 * (same for all `break')
   1240  1.69   tsutsui 				 */
   1241   1.1       oki 
   1242   1.1       oki 			case 'E':
   1243   1.1       oki 				/* next line */
   1244   1.1       oki 				c = NEL;
   1245   1.1       oki 				ip->escape = 0;
   1246   1.1       oki 				break;
   1247   1.1       oki 
   1248   1.1       oki 			case 'H':
   1249   1.1       oki 				/* set TAB at current col */
   1250   1.1       oki 				c = HTS;
   1251   1.1       oki 				ip->escape = 0;
   1252   1.1       oki 				break;
   1253   1.1       oki 
   1254   1.1       oki 			case 'M':
   1255   1.1       oki 				/* reverse index */
   1256   1.1       oki 				c = RI;
   1257   1.1       oki 				ip->escape = 0;
   1258   1.1       oki 				break;
   1259   1.1       oki 
   1260   1.1       oki 			case 'N':
   1261   1.1       oki 				/* single shift G2 */
   1262   1.1       oki 				c = SS2;
   1263   1.1       oki 				ip->escape = 0;
   1264   1.1       oki 				break;
   1265   1.1       oki 
   1266   1.1       oki 			case 'O':
   1267   1.1       oki 				/* single shift G3 */
   1268   1.1       oki 				c = SS3;
   1269   1.1       oki 				ip->escape = 0;
   1270   1.1       oki 				break;
   1271   1.1       oki 
   1272   1.1       oki 			case 'P':
   1273   1.1       oki 				/* DCS detected */
   1274   1.1       oki 				c = DCS;
   1275   1.1       oki 				ip->escape = 0;
   1276   1.1       oki 				break;
   1277   1.1       oki 
   1278   1.1       oki 			case '[':
   1279   1.1       oki 				c = CSI;
   1280   1.1       oki 				ip->escape = 0;
   1281   1.1       oki 				break;
   1282   1.1       oki 
   1283   1.1       oki 			case '\\':
   1284   1.1       oki 				/* String Terminator */
   1285   1.1       oki 				c = ST;
   1286   1.1       oki 				ip->escape = 0;
   1287   1.1       oki 				break;
   1288   1.1       oki 
   1289   1.1       oki 			case ']':
   1290   1.1       oki 				c = OSC;
   1291   1.1       oki 				ip->escape = 0;
   1292   1.1       oki 				break;
   1293   1.1       oki 
   1294   1.1       oki 			case '^':
   1295   1.1       oki 				c = PM;
   1296   1.1       oki 				ip->escape = 0;
   1297   1.1       oki 				break;
   1298   1.1       oki 
   1299   1.1       oki 			case '_':
   1300   1.1       oki 				c = APC;
   1301   1.1       oki 				ip->escape = 0;
   1302   1.1       oki 				break;
   1303   1.1       oki 
   1304   1.1       oki 			/* introduces 7/8bit control */
   1305   1.1       oki 			case ' ':
   1306   1.1       oki 				/* can be followed by either F or G */
   1307   1.1       oki 				ip->escape = ' ';
   1308   1.1       oki 				break;
   1309   1.1       oki 
   1310  1.69   tsutsui 			/* a lot of character set selections, not yet used... */
   1311  1.69   tsutsui 			/* 94-character sets: */
   1312   1.1       oki 			case '(':	/* G0 */
   1313   1.1       oki 			case ')':	/* G1 */
   1314   1.1       oki 				ip->escape = c;
   1315   1.1       oki 				return;
   1316   1.1       oki 
   1317   1.1       oki 			case '*':	/* G2 */
   1318   1.1       oki 			case '+':	/* G3 */
   1319   1.1       oki 			case 'B':	/* ASCII */
   1320   1.1       oki 			case 'A':	/* ISO latin 1 */
   1321   1.1       oki 			case '<':	/* user preferred suplemental */
   1322  1.70   tsutsui 			case '0':	/* DEC special graphics */
   1323   1.1       oki 
   1324   1.1       oki 			/* 96-character sets: */
   1325   1.1       oki 			case '-':	/* G1 */
   1326   1.1       oki 			case '.':	/* G2 */
   1327   1.1       oki 			case '/':	/* G3 */
   1328   1.1       oki 
   1329   1.1       oki 			/* national character sets: */
   1330   1.1       oki 			case '4':	/* dutch */
   1331   1.1       oki 			case '5':
   1332   1.1       oki 			case 'C':	/* finnish */
   1333   1.1       oki 			case 'R':	/* french */
   1334   1.1       oki 			case 'Q':	/* french canadian */
   1335   1.1       oki 			case 'K':	/* german */
   1336   1.1       oki 			case 'Y':	/* italian */
   1337   1.1       oki 			case '6':	/* norwegian/danish */
   1338   1.1       oki 			/* note: %5 and %6 are not supported (two chars..) */
   1339   1.1       oki 
   1340   1.1       oki 				ip->escape = 0;
   1341   1.1       oki 				/* just ignore for now */
   1342   1.1       oki 				return;
   1343   1.1       oki 
   1344   1.1       oki 			/* 94-multibyte character sets designate */
   1345   1.1       oki 			case '$':
   1346   1.1       oki 				ip->escape = '$';
   1347   1.1       oki 				return;
   1348   1.1       oki 
   1349   1.1       oki 			/* locking shift modes */
   1350   1.1       oki 			case '`':
   1351   1.1       oki 				ip->GR = &ip->G1;
   1352   1.1       oki 				ip->escape = 0;
   1353   1.1       oki 				return;
   1354   1.1       oki 
   1355   1.1       oki 			case 'n':
   1356   1.1       oki 				ip->GL = &ip->G2;
   1357   1.1       oki 				ip->escape = 0;
   1358   1.1       oki 				return;
   1359   1.1       oki 
   1360   1.1       oki 			case '}':
   1361   1.1       oki 				ip->GR = &ip->G2;
   1362   1.1       oki 				ip->escape = 0;
   1363   1.1       oki 				return;
   1364   1.1       oki 
   1365   1.1       oki 			case 'o':
   1366   1.1       oki 				ip->GL = &ip->G3;
   1367   1.1       oki 				ip->escape = 0;
   1368   1.1       oki 				return;
   1369   1.1       oki 
   1370   1.1       oki 			case '|':
   1371   1.1       oki 				ip->GR = &ip->G3;
   1372   1.1       oki 				ip->escape = 0;
   1373   1.1       oki 				return;
   1374   1.1       oki 
   1375   1.1       oki 			case '~':
   1376   1.1       oki 				ip->GR = &ip->G1;
   1377   1.1       oki 				ip->escape = 0;
   1378   1.1       oki 				return;
   1379   1.1       oki 
   1380   1.1       oki 			/* font width/height control */
   1381   1.1       oki 			case '#':
   1382   1.1       oki 				ip->escape = '#';
   1383   1.1       oki 				return;
   1384   1.1       oki 
   1385   1.1       oki 			case 'c':
   1386   1.1       oki 				/* hard terminal reset .. */
   1387  1.49     isaki 				ite_reset(ip);
   1388   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1389   1.1       oki 				ip->escape = 0;
   1390   1.1       oki 				return;
   1391   1.1       oki 
   1392   1.1       oki 			case '7':
   1393   1.1       oki 				/* save cursor */
   1394   1.1       oki 				ip->save_curx = ip->curx;
   1395   1.1       oki 				ip->save_cury = ip->cury;
   1396   1.1       oki 				ip->save_attribute = ip->attribute;
   1397   1.1       oki 				ip->sc_om = ip->inside_margins;
   1398   1.1       oki 				ip->sc_G0 = ip->G0;
   1399   1.1       oki 				ip->sc_G1 = ip->G1;
   1400   1.1       oki 				ip->sc_G2 = ip->G2;
   1401   1.1       oki 				ip->sc_G3 = ip->G3;
   1402   1.1       oki 				ip->sc_GL = ip->GL;
   1403   1.1       oki 				ip->sc_GR = ip->GR;
   1404   1.1       oki 				ip->escape = 0;
   1405   1.1       oki 				return;
   1406   1.1       oki 
   1407   1.1       oki 			case '8':
   1408   1.1       oki 				/* restore cursor */
   1409   1.1       oki 				ip->curx = ip->save_curx;
   1410   1.1       oki 				ip->cury = ip->save_cury;
   1411   1.1       oki 				ip->attribute = ip->save_attribute;
   1412   1.1       oki 				ip->inside_margins = ip->sc_om;
   1413   1.1       oki 				ip->G0 = ip->sc_G0;
   1414   1.1       oki 				ip->G1 = ip->sc_G1;
   1415   1.1       oki 				ip->G2 = ip->sc_G2;
   1416   1.1       oki 				ip->G3 = ip->sc_G3;
   1417   1.1       oki 				ip->GL = ip->sc_GL;
   1418   1.1       oki 				ip->GR = ip->sc_GR;
   1419   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1420   1.1       oki 				ip->escape = 0;
   1421   1.1       oki 				return;
   1422   1.1       oki 
   1423   1.1       oki 			case '=':
   1424   1.1       oki 				/* keypad application mode */
   1425   1.1       oki 				ip->keypad_appmode = 1;
   1426   1.1       oki 				ip->escape = 0;
   1427   1.1       oki 				return;
   1428   1.1       oki 
   1429   1.1       oki 			case '>':
   1430   1.1       oki 				/* keypad numeric mode */
   1431   1.1       oki 				ip->keypad_appmode = 0;
   1432   1.1       oki 				ip->escape = 0;
   1433   1.1       oki 				return;
   1434   1.1       oki 
   1435   1.1       oki 			case 'Z':	/* request ID */
   1436  1.69   tsutsui 				if (ip->emul_level == EMUL_VT100) {
   1437  1.69   tsutsui 					/* XXX not clean */
   1438  1.69   tsutsui 					ite_sendstr(ip, "\033[61;0c");
   1439  1.69   tsutsui 				} else {
   1440  1.69   tsutsui 					/* XXX not clean */
   1441  1.69   tsutsui 					ite_sendstr(ip, "\033[63;0c");
   1442  1.69   tsutsui 				}
   1443   1.1       oki 				ip->escape = 0;
   1444   1.1       oki 				return;
   1445   1.1       oki 
   1446   1.1       oki 			/* default catch all for not recognized ESC sequences */
   1447   1.1       oki 			default:
   1448   1.1       oki 				ip->escape = 0;
   1449   1.1       oki 				return;
   1450   1.1       oki 			}
   1451   1.1       oki 			break;
   1452   1.1       oki 
   1453   1.1       oki 		case '(': /* designate G0 */
   1454   1.1       oki 			switch (c) {
   1455   1.1       oki 			case 'B': /* USASCII */
   1456   1.1       oki 				ip->G0 = CSET_ASCII;
   1457   1.1       oki 				ip->escape = 0;
   1458   1.1       oki 				return;
   1459   1.1       oki 			case 'I':
   1460   1.1       oki 				ip->G0 = CSET_JISKANA;
   1461   1.1       oki 				ip->escape = 0;
   1462   1.1       oki 				return;
   1463   1.1       oki 			case 'J':
   1464   1.1       oki 				ip->G0 = CSET_JISROMA;
   1465   1.1       oki 				ip->escape = 0;
   1466   1.1       oki 				return;
   1467  1.70   tsutsui 			case '0': /* DEC special graphics */
   1468  1.69   tsutsui 				ip->G0 = CSET_DECGRAPH;
   1469  1.69   tsutsui 				ip->escape = 0;
   1470  1.69   tsutsui 				return;
   1471   1.1       oki 			case 'A': /* British or ISO-Latin-1 */
   1472   1.1       oki 			case 'H': /* Swedish */
   1473   1.1       oki 			case 'K': /* German */
   1474   1.1       oki 			case 'R': /* French */
   1475   1.1       oki 			case 'Y': /* Italian */
   1476   1.1       oki 			case 'Z': /* Spanish */
   1477   1.1       oki 			default:
   1478   1.1       oki 				/* not supported */
   1479   1.1       oki 				ip->escape = 0;
   1480   1.1       oki 				return;
   1481   1.1       oki 			}
   1482   1.1       oki 
   1483   1.1       oki 		case ')': /* designate G1 */
   1484  1.70   tsutsui 			ip->escape = 0;
   1485   1.1       oki 			return;
   1486   1.1       oki 
   1487   1.1       oki 		case '$': /* 94-multibyte character set */
   1488   1.1       oki 			switch (c) {
   1489   1.1       oki 			case '@':
   1490   1.1       oki 				ip->G0 = CSET_JIS1978;
   1491   1.1       oki 				ip->escape = 0;
   1492   1.1       oki 				return;
   1493   1.1       oki 			case 'B':
   1494   1.1       oki 				ip->G0 = CSET_JIS1983;
   1495   1.1       oki 				ip->escape = 0;
   1496   1.1       oki 				return;
   1497   1.1       oki 			case 'D':
   1498   1.1       oki 				ip->G0 = CSET_JIS1990;
   1499   1.1       oki 				ip->escape = 0;
   1500   1.1       oki 				return;
   1501   1.1       oki 			default:
   1502   1.1       oki 				/* not supported */
   1503   1.1       oki 				ip->escape = 0;
   1504   1.1       oki 				return;
   1505   1.1       oki 			}
   1506   1.1       oki 
   1507   1.1       oki 		case ' ':
   1508   1.1       oki 			switch (c) {
   1509   1.1       oki 			case 'F':
   1510   1.1       oki 				ip->eightbit_C1 = 0;
   1511   1.1       oki 				ip->escape = 0;
   1512   1.1       oki 				return;
   1513   1.1       oki 
   1514   1.1       oki 			case 'G':
   1515   1.1       oki 				ip->eightbit_C1 = 1;
   1516   1.1       oki 				ip->escape = 0;
   1517   1.1       oki 				return;
   1518   1.1       oki 
   1519   1.1       oki 			default:
   1520   1.1       oki 				/* not supported */
   1521   1.1       oki 				ip->escape = 0;
   1522   1.1       oki 				return;
   1523   1.1       oki 			}
   1524   1.1       oki 			break;
   1525   1.1       oki 
   1526   1.1       oki 		case '#':
   1527   1.1       oki 			switch (c) {
   1528   1.1       oki 			case '5':
   1529   1.1       oki 				/* single height, single width */
   1530   1.1       oki 				ip->escape = 0;
   1531   1.1       oki 				return;
   1532   1.1       oki 
   1533   1.1       oki 			case '6':
   1534   1.1       oki 				/* double width, single height */
   1535   1.1       oki 				ip->escape = 0;
   1536   1.1       oki 				return;
   1537   1.1       oki 
   1538   1.1       oki 			case '3':
   1539   1.1       oki 				/* top half */
   1540   1.1       oki 				ip->escape = 0;
   1541   1.1       oki 				return;
   1542   1.1       oki 
   1543   1.1       oki 			case '4':
   1544   1.1       oki 				/* bottom half */
   1545   1.1       oki 				ip->escape = 0;
   1546   1.1       oki 				return;
   1547   1.1       oki 
   1548   1.1       oki 			case '8':
   1549   1.1       oki 				/* screen alignment pattern... */
   1550  1.49     isaki 				alignment_display(ip);
   1551   1.1       oki 				ip->escape = 0;
   1552   1.1       oki 				return;
   1553   1.1       oki 
   1554   1.1       oki 			default:
   1555   1.1       oki 				ip->escape = 0;
   1556   1.1       oki 				return;
   1557   1.1       oki 			}
   1558   1.1       oki 			break;
   1559   1.1       oki 
   1560   1.1       oki 		case CSI:
   1561   1.1       oki 			/* the biggie... */
   1562   1.1       oki 			switch (c) {
   1563  1.69   tsutsui 			case '0':
   1564  1.69   tsutsui 			case '1':
   1565  1.69   tsutsui 			case '2':
   1566  1.69   tsutsui 			case '3':
   1567  1.69   tsutsui 			case '4':
   1568  1.69   tsutsui 			case '5':
   1569  1.69   tsutsui 			case '6':
   1570  1.69   tsutsui 			case '7':
   1571  1.69   tsutsui 			case '8':
   1572  1.69   tsutsui 			case '9':
   1573  1.69   tsutsui 			case ';':
   1574  1.69   tsutsui 			case '\"':
   1575  1.69   tsutsui 			case '$':
   1576  1.69   tsutsui 			case '>':
   1577   1.1       oki 				if (ip->ap < ip->argbuf + MAX_ARGSIZE)
   1578   1.1       oki 					*ip->ap++ = c;
   1579   1.1       oki 				return;
   1580   1.1       oki 
   1581   1.1       oki 			case 'p':
   1582   1.1       oki 				*ip->ap = 0;
   1583   1.1       oki 				if (!strncmp(ip->argbuf, "61\"", 3))
   1584   1.1       oki 					ip->emul_level = EMUL_VT100;
   1585  1.69   tsutsui 				else if (!strncmp(ip->argbuf, "63;1\"", 5) ||
   1586  1.69   tsutsui 					 !strncmp(ip->argbuf, "62;1\"", 5))
   1587   1.1       oki 					ip->emul_level = EMUL_VT300_7;
   1588   1.1       oki 				else
   1589   1.1       oki 					ip->emul_level = EMUL_VT300_8;
   1590   1.1       oki 				ip->escape = 0;
   1591   1.1       oki 				return;
   1592   1.1       oki 
   1593   1.1       oki 			case '?':
   1594   1.1       oki 				*ip->ap = 0;
   1595   1.1       oki 				ip->escape = '?';
   1596   1.1       oki 				ip->ap = ip->argbuf;
   1597   1.1       oki 				return;
   1598   1.1       oki 
   1599   1.1       oki 			case 'c':
   1600   1.1       oki 				/* device attributes */
   1601   1.1       oki 				*ip->ap = 0;
   1602   1.1       oki 				if (ip->argbuf[0] == '>') {
   1603  1.49     isaki 					ite_sendstr(ip, "\033[>24;0;0;0c");
   1604  1.69   tsutsui 				} else {
   1605   1.1       oki 					switch (ite_zargnum(ip)) {
   1606   1.1       oki 					case 0:
   1607  1.69   tsutsui 						/*
   1608  1.69   tsutsui 						 * primary DA request, send
   1609  1.69   tsutsui 						 * primary DA response
   1610  1.69   tsutsui 						 */
   1611  1.69   tsutsui 						if (ip->emul_level ==
   1612  1.69   tsutsui 						    EMUL_VT100)
   1613  1.69   tsutsui 							ite_sendstr(ip,
   1614  1.69   tsutsui 							    "\033[?1;1c");
   1615   1.1       oki 						else
   1616  1.69   tsutsui 							ite_sendstr(ip,
   1617  1.69   tsutsui 							    "\033[63;0c");
   1618   1.1       oki 						break;
   1619   1.1       oki 					}
   1620  1.69   tsutsui 				}
   1621   1.1       oki 				ip->escape = 0;
   1622   1.1       oki 				return;
   1623   1.1       oki 
   1624   1.1       oki 			case 'n':
   1625   1.1       oki 				switch (ite_zargnum(ip)) {
   1626   1.1       oki 				case 5:
   1627  1.69   tsutsui 					/* no malfunction */
   1628  1.69   tsutsui 					ite_sendstr(ip, "\033[0n");
   1629   1.1       oki 					break;
   1630   1.1       oki 				case 6:
   1631   1.1       oki 					/* cursor position report */
   1632  1.62  christos 					snprintf(ip->argbuf, sizeof(ip->argbuf),
   1633  1.62  christos 					    "\033[%d;%dR",
   1634  1.62  christos 					     ip->cury + 1, ip->curx + 1);
   1635  1.49     isaki 					ite_sendstr(ip, ip->argbuf);
   1636   1.1       oki 					break;
   1637   1.1       oki 				}
   1638   1.1       oki 				ip->escape = 0;
   1639   1.1       oki 				return;
   1640   1.1       oki 
   1641   1.1       oki 			case 'x':
   1642   1.1       oki 				switch (ite_zargnum(ip)) {
   1643   1.1       oki 				case 0:
   1644   1.1       oki 					/* Fake some terminal parameters.  */
   1645  1.69   tsutsui 					ite_sendstr(ip,
   1646  1.69   tsutsui 					    "\033[2;1;1;112;112;1;0x");
   1647   1.1       oki 					break;
   1648   1.1       oki 				case 1:
   1649  1.69   tsutsui 					ite_sendstr(ip,
   1650  1.69   tsutsui 					    "\033[3;1;1;112;112;1;0x");
   1651   1.1       oki 					break;
   1652   1.1       oki 				}
   1653   1.1       oki 				ip->escape = 0;
   1654   1.1       oki 				return;
   1655   1.1       oki 
   1656   1.1       oki 			case 'g':
   1657   1.1       oki 				/* clear tabs */
   1658   1.1       oki 				switch (ite_zargnum(ip)) {
   1659   1.1       oki 				case 0:
   1660   1.1       oki 					if (ip->curx < ip->cols)
   1661   1.1       oki 						ip->tabs[ip->curx] = 0;
   1662   1.1       oki 					break;
   1663   1.1       oki 				case 3:
   1664   1.1       oki 					for (n = 0; n < ip->cols; n++)
   1665   1.1       oki 						ip->tabs[n] = 0;
   1666   1.1       oki 					break;
   1667   1.1       oki 
   1668   1.1       oki 				default:
   1669   1.1       oki 					/* ignore */
   1670   1.1       oki 					break;
   1671   1.1       oki 				}
   1672   1.1       oki 				ip->escape = 0;
   1673   1.1       oki 				return;
   1674   1.1       oki 
   1675   1.1       oki 			case 'h': /* set mode */
   1676   1.1       oki 			case 'l': /* reset mode */
   1677  1.49     isaki 				n = ite_zargnum(ip);
   1678   1.1       oki 				switch (n) {
   1679   1.1       oki 				case 4:
   1680  1.69   tsutsui 					/* insert/replace mode */
   1681  1.69   tsutsui 					ip->imode = (c == 'h');
   1682   1.1       oki 					break;
   1683   1.1       oki 				case 20:
   1684   1.1       oki 					ip->linefeed_newline = (c == 'h');
   1685   1.1       oki 					break;
   1686   1.1       oki 				}
   1687   1.1       oki 				ip->escape = 0;
   1688   1.1       oki 				return;
   1689   1.1       oki 
   1690   1.1       oki 			case 'M':
   1691   1.1       oki 				/* delete line */
   1692  1.49     isaki 				ite_dnline(ip, ite_argnum(ip));
   1693   1.1       oki 				ip->escape = 0;
   1694   1.1       oki 				return;
   1695   1.1       oki 
   1696   1.1       oki 			case 'L':
   1697   1.1       oki 				/* insert line */
   1698  1.49     isaki 				ite_inline(ip, ite_argnum(ip));
   1699   1.1       oki 				ip->escape = 0;
   1700   1.1       oki 				return;
   1701   1.1       oki 
   1702   1.1       oki 			case 'P':
   1703   1.1       oki 				/* delete char */
   1704  1.49     isaki 				ite_dnchar(ip, ite_argnum(ip));
   1705   1.1       oki 				ip->escape = 0;
   1706   1.1       oki 				return;
   1707   1.1       oki 
   1708   1.1       oki 			case '@':
   1709   1.1       oki 				/* insert char(s) */
   1710  1.49     isaki 				ite_inchar(ip, ite_argnum(ip));
   1711   1.1       oki 				ip->escape = 0;
   1712   1.1       oki 				return;
   1713   1.1       oki 
   1714   1.1       oki 			case '!':
   1715   1.1       oki 				/* soft terminal reset */
   1716   1.1       oki 				ip->escape = 0; /* XXX */
   1717   1.1       oki 				return;
   1718   1.1       oki 
   1719   1.1       oki 			case 'G':
   1720  1.69   tsutsui 				/*
   1721  1.69   tsutsui 				 * this one was *not* in my vt320 manual but
   1722  1.69   tsutsui 				 * in a vt320 termcap entry.. who is right?
   1723  1.69   tsutsui 				 * It's supposed to set the horizontal cursor
   1724  1.69   tsutsui 				 * position.
   1725  1.69   tsutsui 				 */
   1726   1.1       oki 				*ip->ap = 0;
   1727  1.49     isaki 				x = atoi(ip->argbuf);
   1728  1.69   tsutsui 				if (x != 0)
   1729  1.49     isaki 					x--;
   1730  1.64  riastrad 				ip->curx = uimin(x, ip->cols - 1);
   1731   1.1       oki 				ip->escape = 0;
   1732   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1733  1.49     isaki 				clr_attr(ip, ATTR_INV);
   1734   1.1       oki 				return;
   1735   1.1       oki 
   1736   1.1       oki 			case 'd':
   1737  1.69   tsutsui 				/*
   1738  1.69   tsutsui 				 * same thing here, this one's for setting
   1739  1.69   tsutsui 				 * the absolute vertical cursor position.
   1740  1.69   tsutsui 				 * Not documented...
   1741  1.69   tsutsui 				 */
   1742   1.1       oki 				*ip->ap = 0;
   1743  1.49     isaki 				y = atoi(ip->argbuf);
   1744  1.49     isaki 				if (y)
   1745  1.49     isaki 					y--;
   1746   1.1       oki 				if (ip->inside_margins)
   1747   1.1       oki 					y += ip->top_margin;
   1748  1.64  riastrad 				ip->cury = uimin(y, ip->rows - 1);
   1749   1.1       oki 				ip->escape = 0;
   1750   1.1       oki 				snap_cury(ip);
   1751   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1752  1.49     isaki 				clr_attr(ip, ATTR_INV);
   1753   1.1       oki 				return;
   1754   1.1       oki 
   1755   1.1       oki 			case 'H':
   1756   1.1       oki 			case 'f':
   1757   1.1       oki 				*ip->ap = 0;
   1758  1.49     isaki 				y = atoi(ip->argbuf);
   1759   1.1       oki 				x = 0;
   1760  1.36  jdolecek 				cp = strchr(ip->argbuf, ';');
   1761  1.69   tsutsui 				if (cp != NULL)
   1762  1.49     isaki 					x = atoi(cp + 1);
   1763  1.69   tsutsui 				if (x != 0)
   1764  1.49     isaki 					x--;
   1765  1.69   tsutsui 				if (y != 0)
   1766  1.49     isaki 					y--;
   1767  1.69   tsutsui 				if (ip->inside_margins != 0)
   1768   1.1       oki 					y += ip->top_margin;
   1769  1.64  riastrad 				ip->cury = uimin(y, ip->rows - 1);
   1770  1.64  riastrad 				ip->curx = uimin(x, ip->cols - 1);
   1771   1.1       oki 				ip->escape = 0;
   1772   1.1       oki 				snap_cury(ip);
   1773   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1774  1.49     isaki 				/*clr_attr(ip, ATTR_INV);*/
   1775   1.1       oki 				return;
   1776   1.1       oki 
   1777   1.1       oki 			case 'A':
   1778   1.1       oki 				/* cursor up */
   1779  1.49     isaki 				n = ite_argnum(ip);
   1780   1.1       oki 				n = ip->cury - (n ? n : 1);
   1781  1.49     isaki 				if (n < 0)
   1782  1.49     isaki 					n = 0;
   1783   1.1       oki 				if (ip->inside_margins)
   1784  1.64  riastrad 					n = uimax(ip->top_margin, n);
   1785   1.1       oki 				else if (n == ip->top_margin - 1)
   1786  1.69   tsutsui 					/*
   1787  1.69   tsutsui 					 * allow scrolling outside region,
   1788  1.69   tsutsui 					 * but don't scroll out of active
   1789  1.69   tsutsui 					 * region without explicit CUP
   1790  1.69   tsutsui 					 */
   1791   1.1       oki 					n = ip->top_margin;
   1792   1.1       oki 				ip->cury = n;
   1793   1.1       oki 				ip->escape = 0;
   1794   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1795  1.49     isaki 				clr_attr(ip, ATTR_INV);
   1796   1.1       oki 				return;
   1797   1.1       oki 
   1798   1.1       oki 			case 'B':
   1799   1.1       oki 				/* cursor down */
   1800  1.49     isaki 				n = ite_argnum(ip);
   1801   1.1       oki 				n = ip->cury + (n ? n : 1);
   1802  1.64  riastrad 				n = uimin(ip->rows - 1, n);
   1803   1.1       oki #if 0
   1804   1.1       oki 				if (ip->inside_margins)
   1805   1.1       oki #endif
   1806  1.64  riastrad 					n = uimin(ip->bottom_margin, n);
   1807   1.1       oki #if 0
   1808   1.1       oki 				else if (n == ip->bottom_margin + 1)
   1809  1.69   tsutsui 					/*
   1810  1.69   tsutsui 					 * allow scrolling outside region,
   1811  1.69   tsutsui 					 * but don't scroll out of active
   1812  1.69   tsutsui 					 * region without explicit CUP
   1813  1.69   tsutsui 					 */
   1814   1.1       oki 					n = ip->bottom_margin;
   1815   1.1       oki #endif
   1816   1.1       oki 				ip->cury = n;
   1817   1.1       oki 				ip->escape = 0;
   1818   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1819  1.49     isaki 				clr_attr(ip, ATTR_INV);
   1820   1.1       oki 				return;
   1821   1.1       oki 
   1822   1.1       oki 			case 'C':
   1823   1.1       oki 				/* cursor forward */
   1824  1.49     isaki 				n = ite_argnum(ip);
   1825   1.1       oki 				n = n ? n : 1;
   1826  1.64  riastrad 				ip->curx = uimin(ip->curx + n, ip->cols - 1);
   1827   1.1       oki 				ip->escape = 0;
   1828   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1829  1.49     isaki 				clr_attr(ip, ATTR_INV);
   1830   1.1       oki 				return;
   1831   1.1       oki 
   1832   1.1       oki 			case 'D':
   1833   1.1       oki 				/* cursor backward */
   1834  1.49     isaki 				n = ite_argnum(ip);
   1835   1.1       oki 				n = n ? n : 1;
   1836   1.1       oki 				n = ip->curx - n;
   1837   1.1       oki 				ip->curx = n >= 0 ? n : 0;
   1838   1.1       oki 				ip->escape = 0;
   1839   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   1840  1.49     isaki 				clr_attr(ip, ATTR_INV);
   1841   1.1       oki 				return;
   1842   1.1       oki 
   1843   1.1       oki 			case 'J':
   1844   1.1       oki 				/* erase screen */
   1845   1.1       oki 				*ip->ap = 0;
   1846  1.49     isaki 				n = ite_zargnum(ip);
   1847   1.1       oki 				if (n == 0)
   1848   1.1       oki 					ite_clrtoeos(ip);
   1849   1.1       oki 				else if (n == 1)
   1850   1.1       oki 					ite_clrtobos(ip);
   1851   1.1       oki 				else if (n == 2)
   1852   1.1       oki 					ite_clrscreen(ip);
   1853   1.1       oki 				ip->escape = 0;
   1854   1.1       oki 				return;
   1855   1.1       oki 
   1856   1.1       oki 			case 'K':
   1857   1.1       oki 				/* erase line */
   1858  1.49     isaki 				n = ite_zargnum(ip);
   1859   1.1       oki 				if (n == 0)
   1860   1.1       oki 					ite_clrtoeol(ip);
   1861   1.1       oki 				else if (n == 1)
   1862   1.1       oki 					ite_clrtobol(ip);
   1863   1.1       oki 				else if (n == 2)
   1864   1.1       oki 					ite_clrline(ip);
   1865   1.1       oki 				ip->escape = 0;
   1866   1.1       oki 				return;
   1867   1.1       oki 
   1868   1.1       oki 			case 'S':
   1869   1.1       oki 				/* scroll up */
   1870  1.49     isaki 				n = ite_zargnum(ip);
   1871   1.1       oki 				if (n <= 0)
   1872   1.1       oki 					n = 1;
   1873   1.1       oki 				else if (n > ip->rows-1)
   1874   1.1       oki 					n = ip->rows-1;
   1875   1.1       oki 				SUBR_SCROLL(ip, ip->rows-1, 0, n, SCROLL_UP);
   1876   1.1       oki 				ip->escape = 0;
   1877   1.1       oki 				return;
   1878   1.1       oki 
   1879   1.1       oki 			case 'T':
   1880   1.1       oki 				/* scroll down */
   1881  1.49     isaki 				n = ite_zargnum(ip);
   1882   1.1       oki 				if (n <= 0)
   1883   1.1       oki 					n = 1;
   1884   1.1       oki 				else if (n > ip->rows-1)
   1885   1.1       oki 					n = ip->rows-1;
   1886   1.1       oki 				SUBR_SCROLL(ip, 0, 0, n, SCROLL_DOWN);
   1887   1.1       oki 				ip->escape = 0;
   1888   1.1       oki 				return;
   1889   1.1       oki 
   1890   1.1       oki 			case 'X':
   1891   1.1       oki 				/* erase character */
   1892   1.1       oki 				n = ite_argnum(ip) - 1;
   1893  1.64  riastrad 				n = uimin(n, ip->cols - 1 - ip->curx);
   1894   1.1       oki 				for (; n >= 0; n--) {
   1895  1.69   tsutsui 					attrclr(ip, ip->cury, ip->curx + n,
   1896  1.69   tsutsui 					    1, 1);
   1897  1.69   tsutsui 					SUBR_PUTC(ip, ' ',
   1898  1.69   tsutsui 					    ip->cury, ip->curx + n, ATTR_NOR);
   1899   1.1       oki 				}
   1900   1.1       oki 				ip->escape = 0;
   1901   1.1       oki 				return;
   1902   1.1       oki 
   1903   1.1       oki 			case '}': case '`':
   1904   1.1       oki 				/* status line control */
   1905   1.1       oki 				ip->escape = 0;
   1906   1.1       oki 				return;
   1907   1.1       oki 
   1908   1.1       oki 			case 'r':
   1909   1.1       oki 				/* set scrolling region */
   1910   1.1       oki 				ip->escape = 0;
   1911   1.1       oki 				*ip->ap = 0;
   1912  1.49     isaki 				x = atoi(ip->argbuf);
   1913   1.1       oki 				x = x ? x : 1;
   1914   1.1       oki 				y = ip->rows;
   1915  1.36  jdolecek 				cp = strchr(ip->argbuf, ';');
   1916   1.1       oki 				if (cp) {
   1917  1.49     isaki 					y = atoi(cp + 1);
   1918   1.1       oki 					y = y ? y : ip->rows;
   1919   1.1       oki 				}
   1920   1.1       oki 				if (y <= x)
   1921   1.1       oki 					return;
   1922   1.1       oki 				x--;
   1923   1.1       oki 				y--;
   1924  1.64  riastrad 				ip->top_margin = uimin(x, ip->rows - 2);
   1925  1.64  riastrad 				ip->bottom_margin = uimin(y, ip->rows - 1);
   1926   1.1       oki 				if (ip->inside_margins) {
   1927   1.1       oki 					ip->cury = ip->top_margin;
   1928   1.1       oki 				} else
   1929   1.1       oki 					ip->cury = 0;
   1930   1.1       oki 				ip->curx = 0;
   1931   1.1       oki 				return;
   1932   1.1       oki 
   1933   1.1       oki 			case 'm':
   1934   1.1       oki 				/* big attribute setter/resetter */
   1935   1.1       oki 			{
   1936  1.40        he 				char *c_p;
   1937  1.69   tsutsui 
   1938   1.1       oki 				*ip->ap = 0;
   1939   1.1       oki 				/* kludge to make CSIm work (== CSI0m) */
   1940   1.1       oki 				if (ip->ap == ip->argbuf)
   1941   1.1       oki 					ip->ap++;
   1942  1.40        he 				for (c_p = ip->argbuf; c_p < ip->ap; ) {
   1943  1.40        he 					switch (*c_p) {
   1944   1.1       oki 					case 0:
   1945   1.1       oki 					case '0':
   1946  1.49     isaki 						clr_attr(ip, ATTR_ALL);
   1947   1.1       oki 						ip->fgcolor = 7;
   1948   1.1       oki 						ip->bgcolor = 0;
   1949  1.40        he 						c_p++;
   1950   1.1       oki 						break;
   1951   1.1       oki 
   1952   1.1       oki 					case '1':
   1953  1.49     isaki 						set_attr(ip, ATTR_BOLD);
   1954  1.40        he 						c_p++;
   1955   1.1       oki 						break;
   1956   1.1       oki 
   1957   1.1       oki 					case '2':
   1958  1.40        he 						switch (c_p[1]) {
   1959   1.1       oki 						case '2':
   1960  1.49     isaki 							clr_attr(ip, ATTR_BOLD);
   1961  1.40        he 							c_p += 2;
   1962   1.1       oki 							break;
   1963   1.1       oki 
   1964   1.1       oki 						case '4':
   1965  1.49     isaki 							clr_attr(ip, ATTR_UL);
   1966  1.40        he 							c_p += 2;
   1967   1.1       oki 							break;
   1968   1.1       oki 
   1969   1.1       oki 						case '5':
   1970  1.69   tsutsui 							clr_attr(ip,
   1971  1.69   tsutsui 							    ATTR_BLINK);
   1972  1.40        he 							c_p += 2;
   1973   1.1       oki 							break;
   1974   1.1       oki 
   1975   1.1       oki 						case '7':
   1976  1.49     isaki 							clr_attr(ip, ATTR_INV);
   1977  1.40        he 							c_p += 2;
   1978   1.1       oki 							break;
   1979   1.1       oki 
   1980   1.1       oki 						default:
   1981  1.40        he 							c_p++;
   1982   1.1       oki 							break;
   1983   1.1       oki 						}
   1984   1.1       oki 						break;
   1985   1.1       oki 
   1986   1.1       oki 					case '3':
   1987  1.40        he 						switch (c_p[1]) {
   1988  1.69   tsutsui 						case '0':
   1989  1.69   tsutsui 						case '1':
   1990  1.69   tsutsui 						case '2':
   1991  1.69   tsutsui 						case '3':
   1992  1.69   tsutsui 						case '4':
   1993  1.69   tsutsui 						case '5':
   1994  1.69   tsutsui 						case '6':
   1995  1.69   tsutsui 						case '7':
   1996   1.1       oki 							/* foreground colors */
   1997  1.69   tsutsui 							ip->fgcolor =
   1998  1.69   tsutsui 							    c_p[1] - '0';
   1999  1.40        he 							c_p += 2;
   2000   1.1       oki 							break;
   2001   1.1       oki 						default:
   2002  1.40        he 							c_p++;
   2003   1.1       oki 							break;
   2004   1.1       oki 						}
   2005   1.1       oki 						break;
   2006   1.1       oki 
   2007   1.1       oki 					case '4':
   2008  1.40        he 						switch (c_p[1]) {
   2009  1.69   tsutsui 						case '0':
   2010  1.69   tsutsui 						case '1':
   2011  1.69   tsutsui 						case '2':
   2012  1.69   tsutsui 						case '3':
   2013  1.69   tsutsui 						case '4':
   2014  1.69   tsutsui 						case '5':
   2015  1.69   tsutsui 						case '6':
   2016  1.69   tsutsui 						case '7':
   2017   1.1       oki 							/* background colors */
   2018  1.69   tsutsui 							ip->bgcolor =
   2019  1.69   tsutsui 							    c_p[1] - '0';
   2020  1.40        he 							c_p += 2;
   2021   1.1       oki 							break;
   2022   1.1       oki 						default:
   2023  1.49     isaki 							set_attr(ip, ATTR_UL);
   2024  1.40        he 							c_p++;
   2025   1.1       oki 							break;
   2026   1.1       oki 						}
   2027   1.1       oki 						break;
   2028   1.1       oki 
   2029   1.1       oki 					case '5':
   2030  1.49     isaki 						set_attr(ip, ATTR_BLINK);
   2031  1.40        he 						c_p++;
   2032   1.1       oki 						break;
   2033   1.1       oki 
   2034   1.1       oki 					case '7':
   2035  1.49     isaki 						set_attr(ip, ATTR_INV);
   2036  1.40        he 						c_p++;
   2037   1.1       oki 						break;
   2038   1.1       oki 
   2039   1.1       oki 					default:
   2040  1.40        he 						c_p++;
   2041   1.1       oki 						break;
   2042   1.1       oki 					}
   2043   1.1       oki 				}
   2044   1.1       oki 
   2045   1.1       oki 			}
   2046   1.1       oki 				ip->escape = 0;
   2047   1.1       oki 				return;
   2048   1.1       oki 
   2049   1.1       oki 			case 'u':
   2050   1.1       oki 				/* DECRQTSR */
   2051  1.49     isaki 				ite_sendstr(ip, "\033P\033\\");
   2052   1.1       oki 				ip->escape = 0;
   2053   1.1       oki 				return;
   2054   1.1       oki 
   2055   1.1       oki 			default:
   2056   1.1       oki 				ip->escape = 0;
   2057   1.1       oki 				return;
   2058   1.1       oki 			}
   2059   1.1       oki 			break;
   2060   1.1       oki 
   2061   1.1       oki 		case '?':	/* CSI ? */
   2062   1.1       oki 			switch (c) {
   2063  1.69   tsutsui 			case '0':
   2064  1.69   tsutsui 			case '1':
   2065  1.69   tsutsui 			case '2':
   2066  1.69   tsutsui 			case '3':
   2067  1.69   tsutsui 			case '4':
   2068  1.69   tsutsui 			case '5':
   2069  1.69   tsutsui 			case '6':
   2070  1.69   tsutsui 			case '7':
   2071  1.69   tsutsui 			case '8':
   2072  1.69   tsutsui 			case '9':
   2073  1.69   tsutsui 			case ';':
   2074  1.69   tsutsui 			case '\"':
   2075  1.69   tsutsui 			case '$':
   2076  1.69   tsutsui 				/*
   2077  1.69   tsutsui 				 * Don't fill the last character; it's needed.
   2078  1.69   tsutsui 				 */
   2079   1.1       oki 				/* XXX yeah, where ?? */
   2080   1.1       oki 				if (ip->ap < ip->argbuf + MAX_ARGSIZE - 1)
   2081   1.1       oki 					*ip->ap++ = c;
   2082   1.1       oki 				return;
   2083   1.1       oki 
   2084   1.1       oki 			case 'n':
   2085   1.1       oki 				/* Terminal Reports */
   2086   1.1       oki 				*ip->ap = 0;
   2087   1.1       oki 				if (ip->ap == &ip->argbuf[2]) {
   2088   1.1       oki 					if (!strncmp(ip->argbuf, "15", 2))
   2089   1.1       oki 						/* printer status: no printer */
   2090  1.49     isaki 						ite_sendstr(ip, "\033[13n");
   2091   1.1       oki 					else if (!strncmp(ip->argbuf, "25", 2))
   2092   1.1       oki 						/* udk status */
   2093  1.49     isaki 						ite_sendstr(ip, "\033[20n");
   2094   1.1       oki 					else if (!strncmp(ip->argbuf, "26", 2))
   2095   1.1       oki 						/* keyboard dialect: US */
   2096  1.49     isaki 						ite_sendstr(ip, "\033[27;1n");
   2097   1.1       oki 				}
   2098   1.1       oki 				ip->escape = 0;
   2099   1.1       oki 				return;
   2100   1.1       oki 
   2101   1.1       oki 			case 'h': /* set dec private modes */
   2102   1.1       oki 			case 'l': /* reset dec private modes */
   2103  1.49     isaki 				n = ite_zargnum(ip);
   2104   1.1       oki 				switch (n) {
   2105   1.1       oki 				case 1:
   2106   1.1       oki 					/* CKM - cursor key mode */
   2107   1.1       oki 					ip->cursor_appmode = (c == 'h');
   2108   1.1       oki 					break;
   2109   1.1       oki 
   2110   1.1       oki 				case 3:
   2111   1.1       oki 					/* 132/80 columns (132 == 'h') */
   2112   1.1       oki 					break;
   2113   1.1       oki 
   2114   1.1       oki 				case 4: /* smooth scroll */
   2115   1.1       oki 					break;
   2116   1.1       oki 
   2117   1.1       oki 				case 5:
   2118  1.69   tsutsui 					/*
   2119  1.69   tsutsui 					 * light background (=='h') /
   2120  1.69   tsutsui 					 * dark background (=='l')
   2121  1.69   tsutsui 					 */
   2122   1.1       oki 					break;
   2123   1.1       oki 
   2124   1.1       oki 				case 6: /* origin mode */
   2125   1.1       oki 					ip->inside_margins = (c == 'h');
   2126   1.1       oki #if 0
   2127   1.1       oki 					ip->curx = 0;
   2128  1.69   tsutsui 					ip->cury = ip->inside_margins ?
   2129  1.69   tsutsui 					    ip->top_margin : 0;
   2130   1.1       oki 					SUBR_CURSOR(ip, MOVE_CURSOR);
   2131   1.1       oki #endif
   2132   1.1       oki 					break;
   2133   1.1       oki 
   2134   1.1       oki 				case 7: /* auto wraparound */
   2135   1.1       oki 					ip->auto_wrap = (c == 'h');
   2136   1.1       oki 					break;
   2137   1.1       oki 
   2138   1.1       oki 				case 8: /* keyboard repeat */
   2139   1.1       oki 					ip->key_repeat = (c == 'h');
   2140   1.1       oki 					break;
   2141   1.1       oki 
   2142   1.1       oki 				case 20: /* newline mode */
   2143   1.1       oki 					ip->linefeed_newline = (c == 'h');
   2144   1.1       oki 					break;
   2145   1.1       oki 
   2146   1.1       oki 				case 25: /* cursor on/off */
   2147  1.69   tsutsui 					SUBR_CURSOR(ip, (c == 'h') ?
   2148  1.69   tsutsui 					    DRAW_CURSOR : ERASE_CURSOR);
   2149   1.1       oki 					break;
   2150   1.1       oki 				}
   2151   1.1       oki 				ip->escape = 0;
   2152   1.1       oki 				return;
   2153   1.1       oki 
   2154   1.1       oki 			case 'K':
   2155   1.1       oki 				/* selective erase in line */
   2156   1.1       oki 			case 'J':
   2157   1.1       oki 				/* selective erase in display */
   2158   1.1       oki 
   2159   1.1       oki 			default:
   2160   1.1       oki 				ip->escape = 0;
   2161   1.1       oki 				return;
   2162   1.1       oki 			}
   2163   1.1       oki 			break;
   2164   1.1       oki 
   2165   1.1       oki 		default:
   2166   1.1       oki 			ip->escape = 0;
   2167   1.1       oki 			return;
   2168   1.1       oki 		}
   2169   1.1       oki 	}
   2170   1.1       oki 
   2171   1.1       oki 	switch (c) {
   2172   1.1       oki 	case 0x00:	/* NUL */
   2173   1.1       oki 	case 0x01:	/* SOH */
   2174   1.1       oki 	case 0x02:	/* STX */
   2175   1.1       oki 	case 0x03:	/* ETX */
   2176   1.1       oki 	case 0x04:	/* EOT */
   2177   1.1       oki 	case 0x05:	/* ENQ */
   2178   1.1       oki 	case 0x06:	/* ACK */
   2179   1.1       oki 		break;
   2180   1.1       oki 
   2181   1.1       oki 	case BEL:
   2182   1.1       oki #if NBELL > 0
   2183  1.60   tsutsui 		if (kbd_ite && ite_tty[device_unit(kbd_ite->device)])
   2184   1.1       oki 			opm_bell();
   2185   1.1       oki #endif
   2186   1.1       oki 		break;
   2187   1.1       oki 
   2188   1.1       oki 	case BS:
   2189   1.1       oki 		if (--ip->curx < 0)
   2190   1.1       oki 			ip->curx = 0;
   2191   1.1       oki 		else
   2192   1.1       oki 			SUBR_CURSOR(ip, MOVE_CURSOR);
   2193   1.1       oki 		break;
   2194   1.1       oki 
   2195   1.1       oki 	case HT:
   2196   1.1       oki 		for (n = ip->curx + 1; n < ip->cols; n++) {
   2197   1.1       oki 			if (ip->tabs[n]) {
   2198   1.1       oki 				ip->curx = n;
   2199   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   2200   1.1       oki 				break;
   2201   1.1       oki 			}
   2202   1.1       oki 		}
   2203   1.1       oki 		break;
   2204   1.1       oki 
   2205   1.1       oki 	case VT:	/* VT is treated like LF */
   2206   1.1       oki 	case FF:	/* so is FF */
   2207   1.1       oki 	case LF:
   2208  1.69   tsutsui 		/*
   2209  1.69   tsutsui 		 * cr->crlf distinction is done here, on output,
   2210  1.69   tsutsui 		 * not on input!
   2211  1.69   tsutsui 		 */
   2212   1.1       oki 		if (ip->linefeed_newline)
   2213  1.49     isaki 			ite_crlf(ip);
   2214   1.1       oki 		else
   2215  1.49     isaki 			ite_lf(ip);
   2216   1.1       oki 		break;
   2217   1.1       oki 
   2218   1.1       oki 	case CR:
   2219  1.49     isaki 		ite_cr(ip);
   2220   1.1       oki 		break;
   2221   1.1       oki 
   2222   1.1       oki 	case SO:
   2223   1.1       oki 		ip->GL = &ip->G1;
   2224   1.1       oki 		break;
   2225   1.1       oki 
   2226   1.1       oki 	case SI:
   2227   1.1       oki 		ip->GL = &ip->G0;
   2228   1.1       oki 		break;
   2229   1.1       oki 
   2230   1.1       oki 	case 0x10:	/* DLE */
   2231   1.1       oki 	case 0x11:	/* DC1/XON */
   2232   1.1       oki 	case 0x12:	/* DC2 */
   2233   1.1       oki 	case 0x13:	/* DC3/XOFF */
   2234   1.1       oki 	case 0x14:	/* DC4 */
   2235   1.1       oki 	case 0x15:	/* NAK */
   2236   1.1       oki 	case 0x16:	/* SYN */
   2237   1.1       oki 	case 0x17:	/* ETB */
   2238   1.1       oki 		break;
   2239   1.1       oki 
   2240   1.1       oki 	case CAN:
   2241   1.1       oki 		ip->escape = 0;	/* cancel any escape sequence in progress */
   2242   1.1       oki 		break;
   2243   1.1       oki 
   2244   1.1       oki 	case 0x19:	/* EM */
   2245   1.1       oki 		break;
   2246   1.1       oki 
   2247   1.1       oki 	case SUB:
   2248   1.1       oki 		ip->escape = 0;	/* dito, but see below */
   2249   1.1       oki 		/* should also display a reverse question mark!! */
   2250   1.1       oki 		break;
   2251   1.1       oki 
   2252   1.1       oki 	case ESC:
   2253   1.1       oki 		ip->escape = ESC;
   2254   1.1       oki 		break;
   2255   1.1       oki 
   2256   1.1       oki 	case 0x1c:	/* FS */
   2257   1.1       oki 	case 0x1d:	/* GS */
   2258   1.1       oki 	case 0x1e:	/* RS */
   2259   1.1       oki 	case 0x1f:	/* US */
   2260   1.1       oki 		break;
   2261   1.1       oki 
   2262   1.1       oki 	/* now it gets weird.. 8bit control sequences.. */
   2263   1.1       oki 	case IND:	/* index: move cursor down, scroll */
   2264  1.49     isaki 		ite_index(ip);
   2265   1.1       oki 		break;
   2266   1.1       oki 
   2267   1.1       oki 	case NEL:	/* next line. next line, first pos. */
   2268  1.49     isaki 		ite_crlf(ip);
   2269   1.1       oki 		break;
   2270   1.1       oki 
   2271   1.1       oki 	case HTS:	/* set horizontal tab */
   2272   1.1       oki 		if (ip->curx < ip->cols)
   2273   1.1       oki 			ip->tabs[ip->curx] = 1;
   2274   1.1       oki 		break;
   2275   1.1       oki 
   2276   1.1       oki 	case RI:	/* reverse index */
   2277  1.49     isaki 		ite_rlf(ip);
   2278   1.1       oki 		break;
   2279   1.1       oki 
   2280   1.1       oki 	case SS2:	/* go into G2 for one character */
   2281   1.1       oki 		ip->save_GL = ip->GR;	/* GL XXX EUC */
   2282   1.1       oki 		ip->GR = &ip->G2;	/* GL XXX */
   2283   1.1       oki 		break;
   2284   1.1       oki 
   2285   1.1       oki 	case SS3:	/* go into G3 for one character */
   2286   1.1       oki 		ip->save_GL = ip->GR;	/* GL XXX EUC */
   2287   1.1       oki 		ip->GR = &ip->G3;	/* GL XXX */
   2288   1.1       oki 		break;
   2289   1.1       oki 
   2290   1.1       oki 	case DCS:	/* device control string introducer */
   2291   1.1       oki 		ip->escape = DCS;
   2292   1.1       oki 		ip->ap = ip->argbuf;
   2293   1.1       oki 		break;
   2294   1.1       oki 
   2295   1.1       oki 	case CSI:	/* control sequence introducer */
   2296   1.1       oki 		ip->escape = CSI;
   2297   1.1       oki 		ip->ap = ip->argbuf;
   2298   1.1       oki 		break;
   2299   1.1       oki 
   2300   1.1       oki 	case ST:	/* string terminator */
   2301   1.1       oki 		/* ignore, if not used as terminator */
   2302   1.1       oki 		break;
   2303   1.1       oki 
   2304  1.69   tsutsui 	case OSC:	/* introduces OS command. */
   2305  1.69   tsutsui 		/* Ignore everything upto ST */
   2306   1.1       oki 		ip->escape = OSC;
   2307   1.1       oki 		break;
   2308   1.1       oki 
   2309  1.69   tsutsui 	case PM:	/* privacy message */
   2310  1.69   tsutsui 		/* ignore everything upto ST */
   2311   1.1       oki 		ip->escape = PM;
   2312   1.1       oki 		break;
   2313   1.1       oki 
   2314  1.69   tsutsui 	case APC:	/* application program command */
   2315  1.69   tsutsui 		/* ignore everything upto ST */
   2316   1.1       oki 		ip->escape = APC;
   2317   1.1       oki 		break;
   2318   1.1       oki 
   2319   1.1       oki 	case DEL:
   2320   1.1       oki 		break;
   2321   1.1       oki 
   2322   1.1       oki 	default:
   2323  1.69   tsutsui 		if (ip->save_char == 0 &&
   2324  1.69   tsutsui 		    (*((c & 0x80) ? ip->GR : ip->GL) & CSET_MULTI) != 0) {
   2325   1.1       oki 			ip->save_char = c;
   2326   1.1       oki 			break;
   2327   1.1       oki 		}
   2328  1.69   tsutsui 		if (ip->imode != 0)
   2329   1.1       oki 			ite_inchar(ip, ip->save_char ? 2 : 1);
   2330   1.1       oki 		iteprecheckwrap(ip);
   2331   1.1       oki #ifdef DO_WEIRD_ATTRIBUTES
   2332   1.1       oki 		if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
   2333   1.1       oki 			attrset(ip, ATTR_INV);
   2334   1.1       oki 			SUBR_PUTC(ip, c, ip->cury, ip->curx, ATTR_INV);
   2335   1.1       oki 		}
   2336   1.1       oki 		else
   2337   1.1       oki 			SUBR_PUTC(ip, c, ip->cury, ip->curx, ATTR_NOR);
   2338   1.1       oki #else
   2339   1.1       oki 		SUBR_PUTC(ip, c, ip->cury, ip->curx, ip->attribute);
   2340   1.1       oki #endif
   2341  1.69   tsutsui 		/*SUBR_CURSOR(ip, DRAW_CURSOR);*/
   2342   1.1       oki 		itecheckwrap(ip);
   2343   1.1       oki 		if (ip->save_char) {
   2344   1.1       oki 			itecheckwrap(ip);
   2345   1.1       oki 			ip->save_char = 0;
   2346   1.1       oki 		}
   2347   1.1       oki 		if (ip->save_GL) {
   2348   1.1       oki 			/*
   2349   1.1       oki 			 * reset single shift
   2350   1.1       oki 			 */
   2351   1.1       oki 			ip->GR = ip->save_GL;
   2352   1.1       oki 			ip->save_GL = 0;
   2353   1.1       oki 		}
   2354   1.1       oki 		break;
   2355   1.1       oki 	}
   2356   1.1       oki }
   2357   1.1       oki 
   2358  1.49     isaki static void
   2359  1.38       chs iteprecheckwrap(struct ite_softc *ip)
   2360   1.1       oki {
   2361  1.69   tsutsui 
   2362   1.1       oki 	if (ip->auto_wrap && ip->curx + (ip->save_char ? 1 : 0) == ip->cols) {
   2363   1.1       oki 		ip->curx = 0;
   2364   1.1       oki 		clr_attr(ip, ATTR_INV);
   2365   1.1       oki 		if (++ip->cury >= ip->bottom_margin + 1) {
   2366   1.1       oki 			ip->cury = ip->bottom_margin;
   2367   1.1       oki 			/*SUBR_CURSOR(ip, MOVE_CURSOR);*/
   2368   1.1       oki 			SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
   2369   1.1       oki 			ite_clrtoeol(ip);
   2370   1.1       oki 		} /*else
   2371   1.1       oki 			SUBR_CURSOR(ip, MOVE_CURSOR);*/
   2372   1.1       oki 	}
   2373   1.1       oki }
   2374   1.1       oki 
   2375  1.49     isaki static void
   2376  1.38       chs itecheckwrap(struct ite_softc *ip)
   2377   1.1       oki {
   2378  1.69   tsutsui 
   2379   1.1       oki #if 0
   2380   1.1       oki 	if (++ip->curx == ip->cols) {
   2381   1.1       oki 		if (ip->auto_wrap) {
   2382   1.1       oki 			ip->curx = 0;
   2383   1.1       oki 			clr_attr(ip, ATTR_INV);
   2384   1.1       oki 			if (++ip->cury >= ip->bottom_margin + 1) {
   2385   1.1       oki 				ip->cury = ip->bottom_margin;
   2386   1.1       oki 				SUBR_CURSOR(ip, MOVE_CURSOR);
   2387  1.69   tsutsui 				SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1,
   2388  1.69   tsutsui 				    SCROLL_UP);
   2389   1.1       oki 				ite_clrtoeol(ip);
   2390   1.1       oki 				return;
   2391   1.1       oki 			}
   2392   1.1       oki 		} else
   2393   1.1       oki 			/* stay there if no autowrap.. */
   2394   1.1       oki 			ip->curx--;
   2395   1.1       oki 	}
   2396   1.1       oki #else
   2397   1.1       oki 	if (ip->curx < ip->cols) {
   2398   1.1       oki 		ip->curx++;
   2399   1.1       oki 		/*SUBR_CURSOR(ip, MOVE_CURSOR);*/
   2400   1.1       oki 	}
   2401   1.1       oki #endif
   2402   1.1       oki }
   2403   1.1       oki 
   2404  1.69   tsutsui /*
   2405  1.69   tsutsui  * A convertion table from DEC special graphics characters to ASCII characters.
   2406  1.69   tsutsui  * Mostly for box drawing on sysinst(8).
   2407  1.69   tsutsui  */
   2408  1.69   tsutsui const uint8_t ite_decgraph2ascii[128] = {
   2409  1.69   tsutsui 	/* same as ASCII from 0x00 to 0x5e */
   2410  1.69   tsutsui 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   2411  1.69   tsutsui 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   2412  1.69   tsutsui 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
   2413  1.69   tsutsui 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   2414  1.69   tsutsui 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
   2415  1.69   tsutsui 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   2416  1.69   tsutsui 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
   2417  1.69   tsutsui 	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   2418  1.69   tsutsui 	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
   2419  1.69   tsutsui 	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
   2420  1.69   tsutsui 	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
   2421  1.69   tsutsui 	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
   2422  1.69   tsutsui 
   2423  1.69   tsutsui 	/* special graphics characters from 0x5f to 0x7e */
   2424  1.69   tsutsui 	' ',	/* 0x5f NBSP */
   2425  1.69   tsutsui 	'*',	/* 0x60 diamond */
   2426  1.69   tsutsui 	' ',	/* 0x61 medium shade */
   2427  1.69   tsutsui 	' ',	/* 0x62 HT */
   2428  1.69   tsutsui 	' ',	/* 0x63 FF */
   2429  1.69   tsutsui 	' ',	/* 0x64 CR */
   2430  1.69   tsutsui 	' ',	/* 0x65 LF */
   2431  1.69   tsutsui 	' ',	/* 0x66 degree symbol */
   2432  1.69   tsutsui 	' ',	/* 0x67 plus-minus sign */
   2433  1.69   tsutsui 	' ',	/* 0x68 NL */
   2434  1.69   tsutsui 	' ',	/* 0x69 VT */
   2435  1.69   tsutsui 	'+',	/* 0x6a box drawings up left */
   2436  1.69   tsutsui 	'+',	/* 0x6b box drawings down left */
   2437  1.69   tsutsui 	'+',	/* 0x6c box drawings down right */
   2438  1.69   tsutsui 	'+',	/* 0x6d box drawings up right */
   2439  1.69   tsutsui 	'+',	/* 0x6e box drawings vertical horizontal */
   2440  1.69   tsutsui 	'~',	/* 0x6f scan line 1 */
   2441  1.69   tsutsui 	'-',	/* 0x70 scan line 3 */
   2442  1.69   tsutsui 	'-',	/* 0x71 scan line 5 */
   2443  1.69   tsutsui 	'-',	/* 0x72 scan line 7 */
   2444  1.69   tsutsui 	'_',	/* 0x73 scan line 9 */
   2445  1.69   tsutsui 	'+',	/* 0x74 box drawings vertical right */
   2446  1.69   tsutsui 	'+',	/* 0x75 box drawings vertical left */
   2447  1.69   tsutsui 	'+',	/* 0x76 box drawings horizontal up */
   2448  1.69   tsutsui 	'+',	/* 0x77 box drawings horizontal down */
   2449  1.69   tsutsui 	'|',	/* 0x78 box drawings vertical */
   2450  1.69   tsutsui 	'<',	/* 0x79 less than or equal to */
   2451  1.69   tsutsui 	'>',	/* 0x7a greater than or equal to */
   2452  1.69   tsutsui 	' ',	/* 0x7b pi */
   2453  1.69   tsutsui 	' ',	/* 0x7c not equal */
   2454  1.69   tsutsui 	' ',	/* 0x7d pound sign */
   2455  1.69   tsutsui 	'.',	/* 0x7e middle dot */
   2456  1.69   tsutsui 	/* end of special graphics characters */
   2457  1.69   tsutsui 	0x7f
   2458  1.69   tsutsui };
   2459  1.69   tsutsui 
   2460   1.1       oki #endif
   2461   1.1       oki 
   2462  1.14   minoura #if NITE > 0 && NKBD > 0
   2463  1.14   minoura 
   2464   1.1       oki /*
   2465   1.1       oki  * Console functions
   2466   1.1       oki  */
   2467   1.1       oki #include <dev/cons.h>
   2468  1.38       chs extern void kbdenable(int);
   2469  1.38       chs extern int kbdcngetc(void);
   2470   1.1       oki 
   2471   1.1       oki /*
   2472   1.1       oki  * Return a priority in consdev->cn_pri field highest wins.  This function
   2473   1.1       oki  * is called before any devices have been probed.
   2474   1.1       oki  */
   2475  1.49     isaki void
   2476  1.38       chs itecnprobe(struct consdev *cd)
   2477   1.1       oki {
   2478   1.2       oki 	int maj;
   2479   1.1       oki 
   2480   1.1       oki 	/* locate the major number */
   2481  1.29   gehenna 	maj = cdevsw_lookup_major(&ite_cdevsw);
   2482   1.1       oki 
   2483  1.50     isaki 	/*
   2484   1.1       oki 	 * return priority of the best ite (already picked from attach)
   2485   1.1       oki 	 * or CN_DEAD.
   2486   1.1       oki 	 */
   2487   1.1       oki 	if (con_itesoftc.grf == NULL)
   2488   1.1       oki 		cd->cn_pri = CN_DEAD;
   2489   1.1       oki 	else {
   2490   1.1       oki 		con_itesoftc.flags = (ITE_ALIVE|ITE_CONSOLE);
   2491  1.14   minoura 		/*
   2492  1.14   minoura 		 * hardcode the minor number.
   2493  1.14   minoura 		 * currently we support only one ITE, it is enough for now.
   2494  1.14   minoura 		 */
   2495  1.14   minoura 		con_itesoftc.isw = &itesw[0];
   2496   1.1       oki 		cd->cn_pri = CN_INTERNAL;
   2497  1.14   minoura 		cd->cn_dev = makedev(maj, 0);
   2498   1.1       oki 	}
   2499   1.1       oki }
   2500   1.1       oki 
   2501  1.49     isaki void
   2502  1.38       chs itecninit(struct consdev *cd)
   2503   1.1       oki {
   2504   1.1       oki 	struct ite_softc *ip;
   2505   1.1       oki 
   2506   1.1       oki 	ip = getitesp(cd->cn_dev);
   2507   1.1       oki 	iteinit(cd->cn_dev);	       /* init console unit */
   2508   1.1       oki 	ip->flags |= ITE_ACTIVE | ITE_ISCONS;
   2509  1.14   minoura 	kbdenable(0);
   2510  1.14   minoura 	mfp_send_usart(0x49);
   2511   1.1       oki }
   2512   1.1       oki 
   2513   1.1       oki /*
   2514   1.1       oki  * itecnfinish() is called in ite_init() when the device is
   2515  1.68    andvar  * being probed in the normal fashion, thus we can finish setting
   2516   1.1       oki  * up this ite now that the system is more functional.
   2517   1.1       oki  */
   2518  1.49     isaki void
   2519  1.38       chs itecnfinish(struct ite_softc *ip)
   2520   1.1       oki {
   2521   1.1       oki 	static int done;
   2522   1.1       oki 
   2523   1.1       oki 	if (done)
   2524   1.1       oki 		return;
   2525   1.1       oki 	done = 1;
   2526   1.1       oki }
   2527   1.1       oki 
   2528   1.1       oki /*ARGSUSED*/
   2529  1.49     isaki int
   2530  1.38       chs itecngetc(dev_t dev)
   2531   1.1       oki {
   2532  1.38       chs 	int c;
   2533   1.1       oki 
   2534   1.1       oki 	do {
   2535  1.14   minoura 		c = kbdcngetc();
   2536  1.16   minoura 		c = ite_cnfilter(c);
   2537   1.1       oki 	} while (c == -1);
   2538   1.1       oki 	return (c);
   2539   1.1       oki }
   2540   1.1       oki 
   2541  1.49     isaki void
   2542  1.38       chs itecnputc(dev_t dev, int c)
   2543   1.1       oki {
   2544   1.1       oki 	static int paniced = 0;
   2545   1.1       oki 	struct ite_softc *ip = getitesp(dev);
   2546   1.1       oki 	char ch = c;
   2547  1.14   minoura #ifdef ITE_KERNEL_ATTR
   2548  1.14   minoura 	short save_attribute;
   2549  1.14   minoura #endif
   2550   1.1       oki 
   2551   1.1       oki 	if (panicstr && !paniced &&
   2552   1.1       oki 	    (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
   2553   1.1       oki 		(void) iteon(dev, 3);
   2554   1.1       oki 		paniced = 1;
   2555   1.1       oki 	}
   2556  1.14   minoura #ifdef ITE_KERNEL_ATTR
   2557  1.14   minoura 	save_attribute = ip->attribute;
   2558  1.14   minoura 	ip->attribute = ITE_KERNEL_ATTR;
   2559  1.14   minoura #endif
   2560   1.1       oki 	ite_putstr(&ch, 1, dev);
   2561  1.14   minoura #ifdef ITE_KERNEL_ATTR
   2562  1.14   minoura 	ip->attribute = save_attribute;
   2563  1.14   minoura #endif
   2564   1.1       oki }
   2565  1.14   minoura #endif
   2566