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