Home | History | Annotate | Line # | Download | only in wscons
wsemul_vt100.c revision 1.24.2.2
      1  1.24.2.2     skrll /* $NetBSD: wsemul_vt100.c,v 1.24.2.2 2004/09/18 14:52:24 skrll Exp $ */
      2       1.1  drochner 
      3       1.1  drochner /*
      4       1.1  drochner  * Copyright (c) 1998
      5       1.1  drochner  *	Matthias Drochner.  All rights reserved.
      6       1.1  drochner  *
      7       1.1  drochner  * Redistribution and use in source and binary forms, with or without
      8       1.1  drochner  * modification, are permitted provided that the following conditions
      9       1.1  drochner  * are met:
     10       1.1  drochner  * 1. Redistributions of source code must retain the above copyright
     11       1.1  drochner  *    notice, this list of conditions and the following disclaimer.
     12       1.1  drochner  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  drochner  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  drochner  *    documentation and/or other materials provided with the distribution.
     15       1.1  drochner  *
     16       1.1  drochner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17       1.1  drochner  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18       1.1  drochner  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19       1.1  drochner  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20       1.1  drochner  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21       1.1  drochner  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22       1.1  drochner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23       1.1  drochner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24       1.1  drochner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25       1.1  drochner  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26       1.1  drochner  *
     27       1.1  drochner  */
     28      1.16     lukem 
     29      1.16     lukem #include <sys/cdefs.h>
     30  1.24.2.2     skrll __KERNEL_RCSID(0, "$NetBSD: wsemul_vt100.c,v 1.24.2.2 2004/09/18 14:52:24 skrll Exp $");
     31  1.24.2.1     skrll 
     32  1.24.2.1     skrll #include "opt_wsmsgattrs.h"
     33       1.1  drochner 
     34       1.1  drochner #include <sys/param.h>
     35       1.1  drochner #include <sys/systm.h>
     36       1.1  drochner #include <sys/time.h>
     37       1.1  drochner #include <sys/malloc.h>
     38       1.1  drochner #include <sys/fcntl.h>
     39       1.1  drochner 
     40       1.1  drochner #include <dev/wscons/wsconsio.h>
     41       1.1  drochner #include <dev/wscons/wsdisplayvar.h>
     42       1.1  drochner #include <dev/wscons/wsemulvar.h>
     43       1.1  drochner #include <dev/wscons/wsemul_vt100var.h>
     44       1.1  drochner #include <dev/wscons/ascii.h>
     45       1.1  drochner 
     46      1.15  augustss void	*wsemul_vt100_cnattach(const struct wsscreen_descr *, void *,
     47      1.15  augustss 			       int, int, long);
     48      1.15  augustss void	*wsemul_vt100_attach(int console, const struct wsscreen_descr *,
     49      1.15  augustss 			     void *, int, int, void *, long);
     50      1.15  augustss void	wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int);
     51      1.15  augustss void	wsemul_vt100_detach(void *cookie, u_int *crowp, u_int *ccolp);
     52      1.15  augustss void	wsemul_vt100_resetop(void *, enum wsemul_resetops);
     53  1.24.2.1     skrll #ifdef WSDISPLAY_CUSTOM_OUTPUT
     54  1.24.2.1     skrll static void wsemul_vt100_getmsgattrs(void *, struct wsdisplay_msgattrs *);
     55  1.24.2.1     skrll static void wsemul_vt100_setmsgattrs(void *, const struct wsscreen_descr *,
     56  1.24.2.1     skrll                                      const struct wsdisplay_msgattrs *);
     57  1.24.2.1     skrll #endif /* WSDISPLAY_CUSTOM_OUTPUT */
     58       1.1  drochner 
     59       1.1  drochner const struct wsemul_ops wsemul_vt100_ops = {
     60       1.1  drochner 	"vt100",
     61       1.1  drochner 	wsemul_vt100_cnattach,
     62       1.1  drochner 	wsemul_vt100_attach,
     63       1.1  drochner 	wsemul_vt100_output,
     64       1.1  drochner 	wsemul_vt100_translate,
     65       1.1  drochner 	wsemul_vt100_detach,
     66  1.24.2.1     skrll 	wsemul_vt100_resetop,
     67  1.24.2.1     skrll #ifdef WSDISPLAY_CUSTOM_OUTPUT
     68  1.24.2.1     skrll 	wsemul_vt100_getmsgattrs,
     69  1.24.2.1     skrll 	wsemul_vt100_setmsgattrs,
     70  1.24.2.1     skrll #else
     71  1.24.2.1     skrll 	NULL,
     72  1.24.2.1     skrll 	NULL,
     73  1.24.2.1     skrll #endif
     74       1.1  drochner };
     75       1.1  drochner 
     76       1.1  drochner struct wsemul_vt100_emuldata wsemul_vt100_console_emuldata;
     77       1.1  drochner 
     78      1.15  augustss static void wsemul_vt100_init(struct wsemul_vt100_emuldata *,
     79      1.15  augustss 			      const struct wsscreen_descr *,
     80      1.15  augustss 			      void *, int, int, long);
     81      1.15  augustss 
     82      1.15  augustss static void wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *,
     83      1.15  augustss 				       u_char, int);
     84      1.15  augustss static void wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *,
     85      1.15  augustss 				     u_char, int);
     86      1.21  sommerfe static void wsemul_vt100_nextline(struct wsemul_vt100_emuldata *);
     87      1.15  augustss typedef u_int vt100_handler(struct wsemul_vt100_emuldata *, u_char);
     88      1.21  sommerfe 
     89       1.1  drochner static vt100_handler
     90       1.1  drochner wsemul_vt100_output_esc,
     91       1.1  drochner wsemul_vt100_output_csi,
     92       1.1  drochner wsemul_vt100_output_scs94,
     93       1.1  drochner wsemul_vt100_output_scs94_percent,
     94       1.1  drochner wsemul_vt100_output_scs96,
     95       1.1  drochner wsemul_vt100_output_scs96_percent,
     96       1.3  drochner wsemul_vt100_output_esc_hash,
     97       1.1  drochner wsemul_vt100_output_esc_spc,
     98       1.1  drochner wsemul_vt100_output_string,
     99       1.1  drochner wsemul_vt100_output_string_esc,
    100       1.1  drochner wsemul_vt100_output_dcs,
    101       1.1  drochner wsemul_vt100_output_dcs_dollar;
    102       1.1  drochner 
    103       1.1  drochner #define	VT100_EMUL_STATE_NORMAL		0	/* normal processing */
    104       1.1  drochner #define	VT100_EMUL_STATE_ESC		1	/* got ESC */
    105       1.1  drochner #define	VT100_EMUL_STATE_CSI		2	/* got CSI (ESC[) */
    106       1.3  drochner #define	VT100_EMUL_STATE_SCS94		3	/* got ESC{()*+} */
    107       1.3  drochner #define	VT100_EMUL_STATE_SCS94_PERCENT	4	/* got ESC{()*+}% */
    108       1.3  drochner #define	VT100_EMUL_STATE_SCS96		5	/* got ESC{-./} */
    109       1.3  drochner #define	VT100_EMUL_STATE_SCS96_PERCENT	6	/* got ESC{-./}% */
    110       1.3  drochner #define	VT100_EMUL_STATE_ESC_HASH	7	/* got ESC# */
    111       1.3  drochner #define	VT100_EMUL_STATE_ESC_SPC	8	/* got ESC<SPC> */
    112       1.3  drochner #define	VT100_EMUL_STATE_STRING		9	/* waiting for ST (ESC\) */
    113       1.3  drochner #define	VT100_EMUL_STATE_STRING_ESC	10	/* waiting for ST, got ESC */
    114       1.3  drochner #define	VT100_EMUL_STATE_DCS		11	/* got DCS (ESC P) */
    115       1.3  drochner #define	VT100_EMUL_STATE_DCS_DOLLAR	12	/* got DCS<p>$ */
    116       1.1  drochner 
    117       1.1  drochner vt100_handler *vt100_output[] = {
    118       1.1  drochner 	wsemul_vt100_output_esc,
    119       1.1  drochner 	wsemul_vt100_output_csi,
    120       1.1  drochner 	wsemul_vt100_output_scs94,
    121       1.1  drochner 	wsemul_vt100_output_scs94_percent,
    122       1.1  drochner 	wsemul_vt100_output_scs96,
    123       1.1  drochner 	wsemul_vt100_output_scs96_percent,
    124       1.3  drochner 	wsemul_vt100_output_esc_hash,
    125       1.1  drochner 	wsemul_vt100_output_esc_spc,
    126       1.1  drochner 	wsemul_vt100_output_string,
    127       1.1  drochner 	wsemul_vt100_output_string_esc,
    128       1.1  drochner 	wsemul_vt100_output_dcs,
    129       1.1  drochner 	wsemul_vt100_output_dcs_dollar,
    130       1.1  drochner };
    131       1.1  drochner 
    132       1.1  drochner static void
    133      1.15  augustss wsemul_vt100_init(struct wsemul_vt100_emuldata *edp,
    134      1.15  augustss 	const struct wsscreen_descr *type, void *cookie, int ccol, int crow,
    135      1.15  augustss 	long defattr)
    136       1.1  drochner {
    137  1.24.2.1     skrll 	int error;
    138  1.24.2.1     skrll 
    139       1.1  drochner 	edp->emulops = type->textops;
    140       1.1  drochner 	edp->emulcookie = cookie;
    141       1.1  drochner 	edp->scrcapabilities = type->capabilities;
    142       1.1  drochner 	edp->nrows = type->nrows;
    143       1.1  drochner 	edp->ncols = type->ncols;
    144       1.1  drochner 	edp->crow = crow;
    145       1.1  drochner 	edp->ccol = ccol;
    146  1.24.2.1     skrll 
    147  1.24.2.1     skrll 	/* The underlying driver has already allocated a default and simple
    148  1.24.2.1     skrll 	 * attribute for us, which is stored in defattr.  We try to set the
    149  1.24.2.1     skrll 	 * values specified by the kernel options below, but in case of
    150  1.24.2.1     skrll 	 * failure we fallback to the value given by the driver. */
    151  1.24.2.1     skrll 
    152  1.24.2.1     skrll 	if (type->capabilities & WSSCREEN_WSCOLORS) {
    153  1.24.2.1     skrll 		edp->msgattrs.default_attrs = WS_DEFAULT_COLATTR |
    154  1.24.2.1     skrll 		    WSATTR_WSCOLORS;
    155  1.24.2.1     skrll 		edp->msgattrs.default_bg = WS_DEFAULT_BG;
    156  1.24.2.1     skrll 		edp->msgattrs.default_fg = WS_DEFAULT_FG;
    157  1.24.2.1     skrll 
    158  1.24.2.1     skrll 		edp->msgattrs.kernel_attrs = WS_KERNEL_COLATTR |
    159  1.24.2.1     skrll 		    WSATTR_WSCOLORS;
    160  1.24.2.1     skrll 		edp->msgattrs.kernel_bg = WS_KERNEL_BG;
    161  1.24.2.1     skrll 		edp->msgattrs.kernel_fg = WS_KERNEL_FG;
    162  1.24.2.1     skrll 	} else {
    163  1.24.2.1     skrll 		edp->msgattrs.default_attrs = WS_DEFAULT_MONOATTR;
    164  1.24.2.1     skrll 		edp->msgattrs.default_bg = edp->msgattrs.default_fg = 0;
    165  1.24.2.1     skrll 
    166  1.24.2.1     skrll 		edp->msgattrs.kernel_attrs = WS_KERNEL_MONOATTR;
    167  1.24.2.1     skrll 		edp->msgattrs.kernel_bg = edp->msgattrs.kernel_fg = 0;
    168  1.24.2.1     skrll 	}
    169  1.24.2.1     skrll 
    170  1.24.2.1     skrll 	error = (*edp->emulops->allocattr)(cookie,
    171  1.24.2.1     skrll 					   edp->msgattrs.default_fg,
    172  1.24.2.1     skrll 					   edp->msgattrs.default_bg,
    173  1.24.2.1     skrll 					   edp->msgattrs.default_attrs,
    174  1.24.2.1     skrll 					   &edp->defattr);
    175  1.24.2.1     skrll 	if (error) {
    176  1.24.2.1     skrll 		edp->defattr = defattr;
    177  1.24.2.1     skrll 		/* XXX This assumes the driver has allocated white on black
    178  1.24.2.1     skrll 		 * XXX as the default attribute, which is not always true.
    179  1.24.2.1     skrll 		 * XXX Maybe we need an emulop that, given an attribute,
    180  1.24.2.1     skrll 		 * XXX (defattr) returns its flags and colors? */
    181  1.24.2.1     skrll 		edp->msgattrs.default_attrs = 0;
    182  1.24.2.1     skrll 		edp->msgattrs.default_bg = WSCOL_BLACK;
    183  1.24.2.1     skrll 		edp->msgattrs.default_fg = WSCOL_WHITE;
    184  1.24.2.1     skrll 	} else {
    185  1.24.2.1     skrll 		if (edp->emulops->replaceattr != NULL)
    186  1.24.2.1     skrll 			(*edp->emulops->replaceattr)(cookie, defattr,
    187  1.24.2.1     skrll 			                             edp->defattr);
    188  1.24.2.1     skrll 	}
    189  1.24.2.1     skrll 
    190  1.24.2.1     skrll #if defined(WS_KERNEL_CUSTOMIZED)
    191  1.24.2.1     skrll 	/* Set up kernel colors, in case they were customized by the user;
    192  1.24.2.1     skrll 	 * otherwise default to the colors specified for the console.
    193  1.24.2.1     skrll 	 * In case of failure, we use console colors too; we can assume
    194  1.24.2.1     skrll 	 * they are good as they have been previously allocated and
    195  1.24.2.1     skrll 	 * verified. */
    196  1.24.2.1     skrll 	error = (*edp->emulops->allocattr)(cookie,
    197  1.24.2.1     skrll 					   edp->msgattrs.kernel_fg,
    198  1.24.2.1     skrll 					   edp->msgattrs.kernel_bg,
    199  1.24.2.1     skrll 					   edp->msgattrs.kernel_attrs,
    200  1.24.2.1     skrll 					   &edp->kernattr);
    201  1.24.2.1     skrll 	if (error)
    202  1.24.2.1     skrll #endif
    203  1.24.2.1     skrll 	edp->kernattr = edp->defattr;
    204       1.1  drochner }
    205       1.1  drochner 
    206       1.1  drochner void *
    207      1.15  augustss wsemul_vt100_cnattach(const struct wsscreen_descr *type, void *cookie,
    208      1.15  augustss 	int ccol, int crow, long defattr)
    209       1.1  drochner {
    210       1.1  drochner 	struct wsemul_vt100_emuldata *edp;
    211       1.1  drochner 
    212       1.1  drochner 	edp = &wsemul_vt100_console_emuldata;
    213       1.1  drochner 	wsemul_vt100_init(edp, type, cookie, ccol, crow, defattr);
    214       1.1  drochner #ifdef DIAGNOSTIC
    215       1.1  drochner 	edp->console = 1;
    216       1.1  drochner #endif
    217       1.1  drochner 	edp->cbcookie = NULL;
    218       1.1  drochner 
    219       1.1  drochner 	edp->tabs = 0;
    220       1.3  drochner 	edp->dblwid = 0;
    221       1.3  drochner 	edp->dw = 0;
    222       1.1  drochner 	edp->dcsarg = 0;
    223       1.3  drochner 	edp->isolatin1tab = edp->decgraphtab = edp->dectechtab = 0;
    224       1.3  drochner 	edp->nrctab = 0;
    225       1.1  drochner 	wsemul_vt100_reset(edp);
    226       1.1  drochner 	return (edp);
    227       1.1  drochner }
    228       1.1  drochner 
    229       1.1  drochner void *
    230      1.15  augustss wsemul_vt100_attach(int console, const struct wsscreen_descr *type,
    231      1.15  augustss 	void *cookie, int ccol, int crow, void *cbcookie, long defattr)
    232       1.1  drochner {
    233       1.1  drochner 	struct wsemul_vt100_emuldata *edp;
    234       1.1  drochner 
    235       1.1  drochner 	if (console) {
    236       1.1  drochner 		edp = &wsemul_vt100_console_emuldata;
    237       1.1  drochner #ifdef DIAGNOSTIC
    238       1.1  drochner 		KASSERT(edp->console == 1);
    239       1.1  drochner #endif
    240       1.1  drochner 	} else {
    241       1.1  drochner 		edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK);
    242       1.1  drochner 		wsemul_vt100_init(edp, type, cookie, ccol, crow, defattr);
    243       1.1  drochner #ifdef DIAGNOSTIC
    244       1.1  drochner 		edp->console = 0;
    245       1.1  drochner #endif
    246       1.1  drochner 	}
    247       1.1  drochner 	edp->cbcookie = cbcookie;
    248       1.1  drochner 
    249       1.4  drochner 	edp->tabs = malloc(edp->ncols, M_DEVBUF, M_NOWAIT);
    250      1.17   tsutsui 	edp->dblwid = malloc(edp->nrows, M_DEVBUF, M_NOWAIT|M_ZERO);
    251       1.3  drochner 	edp->dw = 0;
    252       1.1  drochner 	edp->dcsarg = malloc(DCS_MAXLEN, M_DEVBUF, M_NOWAIT);
    253       1.3  drochner 	edp->isolatin1tab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
    254       1.3  drochner 	edp->decgraphtab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
    255       1.3  drochner 	edp->dectechtab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
    256       1.3  drochner 	edp->nrctab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
    257       1.3  drochner 	vt100_initchartables(edp);
    258       1.1  drochner 	wsemul_vt100_reset(edp);
    259       1.1  drochner 	return (edp);
    260       1.1  drochner }
    261       1.1  drochner 
    262       1.1  drochner void
    263      1.15  augustss wsemul_vt100_detach(void *cookie, u_int *crowp, u_int *ccolp)
    264       1.1  drochner {
    265       1.1  drochner 	struct wsemul_vt100_emuldata *edp = cookie;
    266       1.1  drochner 
    267       1.1  drochner 	*crowp = edp->crow;
    268       1.1  drochner 	*ccolp = edp->ccol;
    269       1.3  drochner #define f(ptr) if (ptr) {free(ptr, M_DEVBUF); ptr = 0;}
    270       1.3  drochner 	f(edp->tabs)
    271       1.3  drochner 	f(edp->dblwid)
    272       1.3  drochner 	f(edp->dcsarg)
    273       1.3  drochner 	f(edp->isolatin1tab)
    274       1.3  drochner 	f(edp->decgraphtab)
    275       1.3  drochner 	f(edp->dectechtab)
    276       1.3  drochner 	f(edp->nrctab)
    277       1.3  drochner #undef f
    278       1.1  drochner 	if (edp != &wsemul_vt100_console_emuldata)
    279       1.1  drochner 		free(edp, M_DEVBUF);
    280       1.9  drochner }
    281       1.9  drochner 
    282       1.9  drochner void
    283      1.15  augustss wsemul_vt100_resetop(void *cookie, enum wsemul_resetops op)
    284       1.9  drochner {
    285       1.9  drochner 	struct wsemul_vt100_emuldata *edp = cookie;
    286       1.9  drochner 
    287       1.9  drochner 	switch (op) {
    288       1.9  drochner 	case WSEMUL_RESET:
    289       1.9  drochner 		wsemul_vt100_reset(edp);
    290       1.9  drochner 		break;
    291       1.9  drochner 	case WSEMUL_SYNCFONT:
    292       1.9  drochner 		vt100_initchartables(edp);
    293      1.10  drochner 		break;
    294      1.10  drochner 	case WSEMUL_CLEARSCREEN:
    295      1.10  drochner 		wsemul_vt100_ed(edp, 2);
    296      1.10  drochner 		edp->ccol = edp->crow = 0;
    297      1.10  drochner 		(*edp->emulops->cursor)(edp->emulcookie,
    298      1.10  drochner 					edp->flags & VTFL_CURSORON, 0, 0);
    299      1.10  drochner 		break;
    300      1.10  drochner 	default:
    301       1.9  drochner 		break;
    302       1.9  drochner 	}
    303       1.1  drochner }
    304       1.1  drochner 
    305       1.1  drochner void
    306      1.15  augustss wsemul_vt100_reset(struct wsemul_vt100_emuldata *edp)
    307       1.1  drochner {
    308       1.1  drochner 	int i;
    309       1.1  drochner 
    310       1.1  drochner 	edp->state = VT100_EMUL_STATE_NORMAL;
    311       1.1  drochner 	edp->flags = VTFL_DECAWM | VTFL_CURSORON;
    312      1.13   mycroft 	edp->bkgdattr = edp->curattr = edp->defattr;
    313  1.24.2.1     skrll 	edp->attrflags = edp->msgattrs.default_attrs;
    314  1.24.2.1     skrll 	edp->fgcol = edp->msgattrs.default_fg;
    315  1.24.2.1     skrll 	edp->bgcol = edp->msgattrs.default_bg;
    316       1.1  drochner 	edp->scrreg_startrow = 0;
    317       1.1  drochner 	edp->scrreg_nrows = edp->nrows;
    318       1.1  drochner 	if (edp->tabs) {
    319       1.8  augustss 		memset(edp->tabs, 0, edp->ncols);
    320       1.6  drochner 		for (i = 8; i < edp->ncols; i += 8)
    321       1.1  drochner 			edp->tabs[i] = 1;
    322       1.1  drochner 	}
    323       1.1  drochner 	edp->dcspos = 0;
    324       1.1  drochner 	edp->dcstype = 0;
    325       1.3  drochner 	edp->chartab_G[0] = 0;
    326       1.3  drochner 	edp->chartab_G[1] = edp->nrctab; /* ??? */
    327       1.3  drochner 	edp->chartab_G[2] = edp->isolatin1tab;
    328       1.3  drochner 	edp->chartab_G[3] = edp->isolatin1tab;
    329       1.3  drochner 	edp->chartab0 = 0;
    330       1.3  drochner 	edp->chartab1 = 2;
    331       1.3  drochner 	edp->sschartab = 0;
    332       1.1  drochner }
    333       1.1  drochner 
    334       1.1  drochner /*
    335       1.1  drochner  * now all the state machine bits
    336       1.1  drochner  */
    337       1.1  drochner 
    338      1.21  sommerfe /*
    339      1.21  sommerfe  * Move the cursor to the next line if possible. If the cursor is at
    340      1.21  sommerfe  * the bottom of the scroll area, then scroll it up. If the cursor is
    341      1.21  sommerfe  * at the bottom of the screen then don't move it down.
    342      1.21  sommerfe  */
    343       1.7  drochner static void
    344      1.21  sommerfe wsemul_vt100_nextline(struct wsemul_vt100_emuldata *edp)
    345      1.21  sommerfe {
    346      1.21  sommerfe 	if (ROWS_BELOW == 0) {
    347      1.21  sommerfe 		/* Bottom of the scroll region. */
    348      1.21  sommerfe 	  	wsemul_vt100_scrollup(edp, 1);
    349      1.21  sommerfe 	} else {
    350      1.21  sommerfe 		if ((edp->crow+1) < edp->nrows)
    351      1.21  sommerfe 			/* Cursor not at the bottom of the screen. */
    352      1.21  sommerfe 			edp->crow++;
    353      1.21  sommerfe 		CHECK_DW;
    354      1.21  sommerfe 	}
    355      1.21  sommerfe }
    356      1.21  sommerfe 
    357      1.22  sommerfe static void
    358      1.15  augustss wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *edp, u_char c,
    359      1.15  augustss 	int kernel)
    360       1.1  drochner {
    361       1.7  drochner 	u_int *ct, dc;
    362       1.7  drochner 
    363       1.7  drochner 	if ((edp->flags & (VTFL_LASTCHAR | VTFL_DECAWM)) ==
    364       1.7  drochner 	    (VTFL_LASTCHAR | VTFL_DECAWM)) {
    365      1.21  sommerfe 		wsemul_vt100_nextline(edp);
    366       1.7  drochner 		edp->ccol = 0;
    367       1.7  drochner 		edp->flags &= ~VTFL_LASTCHAR;
    368       1.7  drochner 	}
    369       1.7  drochner 
    370       1.7  drochner 	if (c & 0x80) {
    371       1.7  drochner 		c &= 0x7f;
    372       1.7  drochner 		ct = edp->chartab_G[edp->chartab1];
    373       1.7  drochner 	} else {
    374       1.7  drochner 		if (edp->sschartab) {
    375       1.7  drochner 			ct = edp->chartab_G[edp->sschartab];
    376       1.7  drochner 			edp->sschartab = 0;
    377       1.7  drochner 		} else
    378       1.7  drochner 			ct = edp->chartab_G[edp->chartab0];
    379       1.7  drochner 	}
    380       1.7  drochner 	dc = (ct ? ct[c] : c);
    381       1.7  drochner 
    382       1.7  drochner 	if ((edp->flags & VTFL_INSERTMODE) && COLS_LEFT)
    383       1.7  drochner 		COPYCOLS(edp->ccol, edp->ccol + 1, COLS_LEFT);
    384       1.7  drochner 
    385       1.7  drochner 	(*edp->emulops->putchar)(edp->emulcookie, edp->crow,
    386       1.7  drochner 				 edp->ccol << edp->dw, dc,
    387       1.7  drochner 				 kernel ? edp->kernattr : edp->curattr);
    388       1.7  drochner 
    389       1.7  drochner 	if (COLS_LEFT)
    390       1.7  drochner 		edp->ccol++;
    391       1.7  drochner 	else
    392       1.7  drochner 		edp->flags |= VTFL_LASTCHAR;
    393       1.7  drochner }
    394       1.7  drochner 
    395       1.7  drochner static void
    396      1.15  augustss wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *edp, u_char c,
    397      1.15  augustss 	int kernel)
    398       1.7  drochner {
    399       1.7  drochner 	u_int n;
    400       1.1  drochner 
    401       1.1  drochner 	switch (c) {
    402      1.19  junyoung 	case ASCII_NUL:
    403      1.19  junyoung 	default:
    404       1.1  drochner 		/* ignore */
    405       1.1  drochner 		break;
    406      1.19  junyoung 	case ASCII_BEL:
    407       1.1  drochner 		wsdisplay_emulbell(edp->cbcookie);
    408       1.1  drochner 		break;
    409      1.19  junyoung 	case ASCII_BS:
    410       1.1  drochner 		if (edp->ccol > 0) {
    411       1.1  drochner 			edp->ccol--;
    412       1.1  drochner 			edp->flags &= ~VTFL_LASTCHAR;
    413       1.1  drochner 		}
    414       1.1  drochner 		break;
    415      1.19  junyoung 	case ASCII_CR:
    416       1.1  drochner 		edp->ccol = 0;
    417       1.1  drochner 		edp->flags &= ~VTFL_LASTCHAR;
    418       1.1  drochner 		break;
    419      1.19  junyoung 	case ASCII_HT:
    420       1.1  drochner 		if (edp->tabs) {
    421       1.3  drochner 			if (!COLS_LEFT)
    422       1.1  drochner 				break;
    423       1.3  drochner 			for (n = edp->ccol + 1; n < NCOLS - 1; n++)
    424       1.1  drochner 				if (edp->tabs[n])
    425       1.1  drochner 					break;
    426       1.1  drochner 		} else {
    427       1.1  drochner 			n = edp->ccol + min(8 - (edp->ccol & 7), COLS_LEFT);
    428       1.1  drochner 		}
    429       1.1  drochner 		edp->ccol = n;
    430       1.1  drochner 		break;
    431      1.19  junyoung 	case ASCII_SO: /* LS1 */
    432       1.3  drochner 		edp->chartab0 = 1;
    433       1.3  drochner 		break;
    434      1.19  junyoung 	case ASCII_SI: /* LS0 */
    435       1.3  drochner 		edp->chartab0 = 0;
    436       1.1  drochner 		break;
    437      1.19  junyoung 	case ASCII_ESC:
    438      1.14  jdolecek 		if (kernel) {
    439      1.14  jdolecek 			printf("wsemul_vt100_output_c0c1: ESC in kernel output ignored\n");
    440      1.14  jdolecek 			break;	/* ignore the ESC */
    441      1.14  jdolecek 		}
    442      1.14  jdolecek 
    443       1.7  drochner 		if (edp->state == VT100_EMUL_STATE_STRING) {
    444       1.7  drochner 			/* might be a string end */
    445       1.7  drochner 			edp->state = VT100_EMUL_STATE_STRING_ESC;
    446       1.7  drochner 		} else {
    447       1.7  drochner 			/* XXX cancel current escape sequence */
    448       1.7  drochner 			edp->state = VT100_EMUL_STATE_ESC;
    449       1.7  drochner 		}
    450       1.1  drochner 		break;
    451       1.1  drochner #if 0
    452      1.19  junyoung 	case CSI: /* 8-bit */
    453       1.7  drochner 		/* XXX cancel current escape sequence */
    454       1.1  drochner 		edp->nargs = 0;
    455       1.8  augustss 		memset(edp->args, 0, sizeof (edp->args));
    456       1.3  drochner 		edp->modif1 = edp->modif2 = '\0';
    457       1.7  drochner 		edp->state = VT100_EMUL_STATE_CSI;
    458       1.1  drochner 		break;
    459      1.19  junyoung 	case DCS: /* 8-bit */
    460       1.7  drochner 		/* XXX cancel current escape sequence */
    461       1.1  drochner 		edp->nargs = 0;
    462       1.8  augustss 		memset(edp->args, 0, sizeof (edp->args));
    463       1.7  drochner 		edp->state = VT100_EMUL_STATE_DCS;
    464       1.1  drochner 		break;
    465      1.19  junyoung 	case ST: /* string end 8-bit */
    466       1.7  drochner 		/* XXX only in VT100_EMUL_STATE_STRING */
    467       1.7  drochner 		wsemul_vt100_handle_dcs(edp);
    468       1.7  drochner 		return (VT100_EMUL_STATE_NORMAL);
    469       1.1  drochner #endif
    470      1.19  junyoung 	case ASCII_LF:
    471      1.19  junyoung 	case ASCII_VT:
    472      1.19  junyoung 	case ASCII_FF:
    473      1.21  sommerfe 		wsemul_vt100_nextline(edp);
    474       1.1  drochner 		break;
    475       1.1  drochner 	}
    476       1.1  drochner }
    477       1.1  drochner 
    478       1.1  drochner static u_int
    479      1.15  augustss wsemul_vt100_output_esc(struct wsemul_vt100_emuldata *edp, u_char c)
    480       1.1  drochner {
    481       1.1  drochner 	u_int newstate = VT100_EMUL_STATE_NORMAL;
    482       1.3  drochner 	int i;
    483       1.1  drochner 
    484       1.1  drochner 	switch (c) {
    485      1.19  junyoung 	case '[': /* CSI */
    486       1.1  drochner 		edp->nargs = 0;
    487       1.8  augustss 		memset(edp->args, 0, sizeof (edp->args));
    488       1.3  drochner 		edp->modif1 = edp->modif2 = '\0';
    489       1.1  drochner 		newstate = VT100_EMUL_STATE_CSI;
    490       1.1  drochner 		break;
    491      1.19  junyoung 	case '7': /* DECSC */
    492      1.24  christos 		edp->flags |= VTFL_SAVEDCURS;
    493       1.1  drochner 		edp->savedcursor_row = edp->crow;
    494       1.1  drochner 		edp->savedcursor_col = edp->ccol;
    495       1.3  drochner 		edp->savedattr = edp->curattr;
    496      1.13   mycroft 		edp->savedbkgdattr = edp->bkgdattr;
    497       1.3  drochner 		edp->savedattrflags = edp->attrflags;
    498       1.3  drochner 		edp->savedfgcol = edp->fgcol;
    499       1.3  drochner 		edp->savedbgcol = edp->bgcol;
    500       1.3  drochner 		for (i = 0; i < 4; i++)
    501       1.3  drochner 			edp->savedchartab_G[i] = edp->chartab_G[i];
    502       1.3  drochner 		edp->savedchartab0 = edp->chartab0;
    503       1.3  drochner 		edp->savedchartab1 = edp->chartab1;
    504       1.1  drochner 		break;
    505      1.19  junyoung 	case '8': /* DECRC */
    506      1.24  christos 		if ((edp->flags & VTFL_SAVEDCURS) == 0)
    507      1.24  christos 			break;
    508       1.1  drochner 		edp->crow = edp->savedcursor_row;
    509       1.1  drochner 		edp->ccol = edp->savedcursor_col;
    510       1.3  drochner 		edp->curattr = edp->savedattr;
    511      1.13   mycroft 		edp->bkgdattr = edp->savedbkgdattr;
    512       1.3  drochner 		edp->attrflags = edp->savedattrflags;
    513       1.3  drochner 		edp->fgcol = edp->savedfgcol;
    514       1.3  drochner 		edp->bgcol = edp->savedbgcol;
    515       1.3  drochner 		for (i = 0; i < 4; i++)
    516       1.3  drochner 			edp->chartab_G[i] = edp->savedchartab_G[i];
    517       1.3  drochner 		edp->chartab0 = edp->savedchartab0;
    518       1.3  drochner 		edp->chartab1 = edp->savedchartab1;
    519       1.1  drochner 		break;
    520      1.19  junyoung 	case '=': /* DECKPAM application mode */
    521       1.1  drochner 		edp->flags |= VTFL_APPLKEYPAD;
    522       1.1  drochner 		break;
    523      1.19  junyoung 	case '>': /* DECKPNM numeric mode */
    524       1.1  drochner 		edp->flags &= ~VTFL_APPLKEYPAD;
    525       1.1  drochner 		break;
    526      1.19  junyoung 	case 'E': /* NEL */
    527       1.1  drochner 		edp->ccol = 0;
    528       1.1  drochner 		/* FALLTHRU */
    529      1.19  junyoung 	case 'D': /* IND */
    530      1.21  sommerfe 		wsemul_vt100_nextline(edp);
    531       1.1  drochner 		break;
    532      1.19  junyoung 	case 'H': /* HTS */
    533       1.1  drochner 		KASSERT(edp->tabs != 0);
    534       1.1  drochner 		edp->tabs[edp->ccol] = 1;
    535       1.1  drochner 		break;
    536      1.19  junyoung 	case '~': /* LS1R */
    537       1.3  drochner 		edp->chartab1 = 1;
    538       1.3  drochner 		break;
    539      1.19  junyoung 	case 'n': /* LS2 */
    540       1.3  drochner 		edp->chartab0 = 2;
    541       1.3  drochner 		break;
    542      1.19  junyoung 	case '}': /* LS2R */
    543       1.3  drochner 		edp->chartab1 = 2;
    544       1.3  drochner 		break;
    545      1.19  junyoung 	case 'o': /* LS3 */
    546       1.3  drochner 		edp->chartab0 = 3;
    547       1.3  drochner 		break;
    548      1.19  junyoung 	case '|': /* LS3R */
    549       1.3  drochner 		edp->chartab1 = 3;
    550       1.1  drochner 		break;
    551      1.19  junyoung 	case 'N': /* SS2 */
    552       1.3  drochner 		edp->sschartab = 2;
    553       1.3  drochner 		break;
    554      1.19  junyoung 	case 'O': /* SS3 */
    555       1.3  drochner 		edp->sschartab = 3;
    556       1.1  drochner 		break;
    557      1.19  junyoung 	case 'M': /* RI */
    558       1.1  drochner 		if (ROWS_ABOVE > 0) {
    559       1.1  drochner 			edp->crow--;
    560       1.3  drochner 			CHECK_DW;
    561       1.1  drochner 			break;
    562       1.1  drochner 		}
    563       1.1  drochner 		wsemul_vt100_scrolldown(edp, 1);
    564       1.1  drochner 		break;
    565      1.19  junyoung 	case 'P': /* DCS */
    566       1.1  drochner 		edp->nargs = 0;
    567       1.8  augustss 		memset(edp->args, 0, sizeof (edp->args));
    568       1.1  drochner 		newstate = VT100_EMUL_STATE_DCS;
    569       1.1  drochner 		break;
    570      1.19  junyoung 	case 'c': /* RIS */
    571       1.1  drochner 		wsemul_vt100_reset(edp);
    572       1.3  drochner 		wsemul_vt100_ed(edp, 2);
    573       1.1  drochner 		edp->ccol = edp->crow = 0;
    574       1.1  drochner 		break;
    575      1.19  junyoung 	case '(': case ')': case '*': case '+': /* SCS */
    576       1.3  drochner 		edp->designating = c - '(';
    577       1.1  drochner 		newstate = VT100_EMUL_STATE_SCS94;
    578       1.1  drochner 		break;
    579      1.19  junyoung 	case '-': case '.': case '/': /* SCS */
    580       1.3  drochner 		edp->designating = c - '-' + 1;
    581       1.1  drochner 		newstate = VT100_EMUL_STATE_SCS96;
    582       1.1  drochner 		break;
    583      1.19  junyoung 	case '#':
    584       1.3  drochner 		newstate = VT100_EMUL_STATE_ESC_HASH;
    585       1.1  drochner 		break;
    586      1.19  junyoung 	case ' ': /* 7/8 bit */
    587       1.1  drochner 		newstate = VT100_EMUL_STATE_ESC_SPC;
    588       1.1  drochner 		break;
    589      1.19  junyoung 	case ']': /* OSC operating system command */
    590      1.19  junyoung 	case '^': /* PM privacy message */
    591      1.19  junyoung 	case '_': /* APC application program command */
    592       1.1  drochner 		/* ignored */
    593       1.1  drochner 		newstate = VT100_EMUL_STATE_STRING;
    594       1.1  drochner 		break;
    595      1.19  junyoung 	case '<': /* exit VT52 mode - ignored */
    596       1.1  drochner 		break;
    597      1.19  junyoung 	default:
    598       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    599       1.1  drochner 		printf("ESC%c unknown\n", c);
    600       1.1  drochner #endif
    601       1.1  drochner 		break;
    602       1.1  drochner 	}
    603       1.1  drochner 
    604       1.1  drochner 	return (newstate);
    605       1.1  drochner }
    606       1.1  drochner 
    607       1.1  drochner static u_int
    608      1.15  augustss wsemul_vt100_output_scs94(struct wsemul_vt100_emuldata *edp, u_char c)
    609       1.1  drochner {
    610       1.1  drochner 	u_int newstate = VT100_EMUL_STATE_NORMAL;
    611       1.1  drochner 
    612       1.1  drochner 	switch (c) {
    613      1.19  junyoung 	case '%': /* probably DEC supplemental graphic */
    614       1.1  drochner 		newstate = VT100_EMUL_STATE_SCS94_PERCENT;
    615       1.1  drochner 		break;
    616      1.19  junyoung 	case 'A': /* british / national */
    617       1.3  drochner 		edp->chartab_G[edp->designating] = edp->nrctab;
    618       1.3  drochner 		break;
    619      1.19  junyoung 	case 'B': /* ASCII */
    620       1.3  drochner 		edp->chartab_G[edp->designating] = 0;
    621       1.3  drochner 		break;
    622      1.19  junyoung 	case '<': /* user preferred supplemental */
    623       1.3  drochner 		/* XXX not really "user" preferred */
    624       1.3  drochner 		edp->chartab_G[edp->designating] = edp->isolatin1tab;
    625       1.3  drochner 		break;
    626      1.19  junyoung 	case '0': /* DEC special graphic */
    627       1.3  drochner 		edp->chartab_G[edp->designating] = edp->decgraphtab;
    628       1.3  drochner 		break;
    629      1.19  junyoung 	case '>': /* DEC tech */
    630       1.3  drochner 		edp->chartab_G[edp->designating] = edp->dectechtab;
    631       1.1  drochner 		break;
    632      1.19  junyoung 	default:
    633       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    634       1.3  drochner 		printf("ESC%c%c unknown\n", edp->designating + '(', c);
    635       1.1  drochner #endif
    636       1.1  drochner 		break;
    637       1.1  drochner 	}
    638       1.1  drochner 	return (newstate);
    639       1.1  drochner }
    640       1.1  drochner 
    641       1.1  drochner static u_int
    642      1.15  augustss wsemul_vt100_output_scs94_percent(struct wsemul_vt100_emuldata *edp, u_char c)
    643       1.1  drochner {
    644       1.1  drochner 	switch (c) {
    645      1.19  junyoung 	case '5': /* DEC supplemental graphic */
    646       1.3  drochner 		/* XXX there are differences */
    647       1.3  drochner 		edp->chartab_G[edp->designating] = edp->isolatin1tab;
    648       1.1  drochner 		break;
    649      1.19  junyoung 	default:
    650       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    651       1.3  drochner 		printf("ESC%c%%%c unknown\n", edp->designating + '(', c);
    652       1.1  drochner #endif
    653       1.1  drochner 		break;
    654       1.1  drochner 	}
    655       1.1  drochner 	return (VT100_EMUL_STATE_NORMAL);
    656       1.1  drochner }
    657       1.1  drochner 
    658       1.1  drochner static u_int
    659      1.15  augustss wsemul_vt100_output_scs96(struct wsemul_vt100_emuldata *edp, u_char c)
    660       1.1  drochner {
    661       1.1  drochner 	u_int newstate = VT100_EMUL_STATE_NORMAL;
    662       1.3  drochner 	int nrc;
    663       1.1  drochner 
    664       1.1  drochner 	switch (c) {
    665      1.19  junyoung 	case '%': /* probably portugese */
    666       1.1  drochner 		newstate = VT100_EMUL_STATE_SCS96_PERCENT;
    667       1.1  drochner 		break;
    668      1.19  junyoung 	case 'A': /* ISO-latin-1 supplemental */
    669       1.3  drochner 		edp->chartab_G[edp->designating] = edp->isolatin1tab;
    670       1.3  drochner 		break;
    671      1.19  junyoung 	case '4': /* dutch */
    672       1.3  drochner 		nrc = 1;
    673       1.3  drochner 		goto setnrc;
    674      1.19  junyoung 	case '5': case 'C': /* finnish */
    675       1.3  drochner 		nrc = 2;
    676       1.3  drochner 		goto setnrc;
    677      1.19  junyoung 	case 'R': /* french */
    678       1.3  drochner 		nrc = 3;
    679       1.3  drochner 		goto setnrc;
    680      1.19  junyoung 	case 'Q': /* french canadian */
    681       1.3  drochner 		nrc = 4;
    682       1.3  drochner 		goto setnrc;
    683      1.19  junyoung 	case 'K': /* german */
    684       1.3  drochner 		nrc = 5;
    685       1.3  drochner 		goto setnrc;
    686      1.19  junyoung 	case 'Y': /* italian */
    687       1.3  drochner 		nrc = 6;
    688       1.3  drochner 		goto setnrc;
    689      1.19  junyoung 	case 'E': case '6': /* norwegian / danish */
    690       1.3  drochner 		nrc = 7;
    691       1.3  drochner 		goto setnrc;
    692      1.19  junyoung 	case 'Z': /* spanish */
    693       1.3  drochner 		nrc = 9;
    694       1.3  drochner 		goto setnrc;
    695      1.19  junyoung 	case '7': case 'H': /* swedish */
    696       1.3  drochner 		nrc = 10;
    697       1.3  drochner 		goto setnrc;
    698      1.19  junyoung 	case '=': /* swiss */
    699       1.3  drochner 		nrc = 11;
    700       1.3  drochner setnrc:
    701       1.3  drochner 		vt100_setnrc(edp, nrc); /* what table ??? */
    702       1.1  drochner 		break;
    703      1.19  junyoung 	default:
    704       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    705       1.3  drochner 		printf("ESC%c%c unknown\n", edp->designating + '-' - 1, c);
    706       1.1  drochner #endif
    707       1.1  drochner 		break;
    708       1.1  drochner 	}
    709       1.1  drochner 	return (newstate);
    710       1.1  drochner }
    711       1.1  drochner 
    712       1.1  drochner static u_int
    713      1.15  augustss wsemul_vt100_output_scs96_percent(struct wsemul_vt100_emuldata *edp, u_char c)
    714       1.1  drochner {
    715       1.1  drochner 	switch (c) {
    716      1.19  junyoung 	case '6': /* portugese */
    717       1.3  drochner 		vt100_setnrc(edp, 8);
    718       1.1  drochner 		break;
    719      1.19  junyoung 	default:
    720       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    721       1.3  drochner 		printf("ESC%c%%%c unknown\n", edp->designating + '-', c);
    722       1.1  drochner #endif
    723       1.1  drochner 		break;
    724       1.1  drochner 	}
    725       1.1  drochner 	return (VT100_EMUL_STATE_NORMAL);
    726       1.1  drochner }
    727       1.1  drochner 
    728       1.1  drochner static u_int
    729      1.15  augustss wsemul_vt100_output_esc_spc(struct wsemul_vt100_emuldata *edp, u_char c)
    730       1.1  drochner {
    731       1.1  drochner 	switch (c) {
    732      1.19  junyoung 	case 'F': /* 7-bit controls */
    733      1.19  junyoung 	case 'G': /* 8-bit controls */
    734       1.1  drochner #ifdef VT100_PRINTNOTIMPL
    735       1.1  drochner 		printf("ESC<SPC>%c ignored\n", c);
    736       1.1  drochner #endif
    737       1.1  drochner 		break;
    738      1.19  junyoung 	default:
    739       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    740       1.1  drochner 		printf("ESC<SPC>%c unknown\n", c);
    741       1.1  drochner #endif
    742       1.1  drochner 		break;
    743       1.1  drochner 	}
    744       1.1  drochner 	return (VT100_EMUL_STATE_NORMAL);
    745       1.1  drochner }
    746       1.1  drochner 
    747       1.1  drochner static u_int
    748      1.15  augustss wsemul_vt100_output_string(struct wsemul_vt100_emuldata *edp, u_char c)
    749       1.1  drochner {
    750       1.7  drochner 	if (edp->dcstype && edp->dcspos < DCS_MAXLEN)
    751       1.7  drochner 		edp->dcsarg[edp->dcspos++] = c;
    752       1.1  drochner 	return (VT100_EMUL_STATE_STRING);
    753       1.1  drochner }
    754       1.1  drochner 
    755       1.1  drochner static u_int
    756      1.15  augustss wsemul_vt100_output_string_esc(struct wsemul_vt100_emuldata *edp, u_char c)
    757       1.1  drochner {
    758       1.1  drochner 	if (c == '\\') { /* ST complete */
    759       1.1  drochner 		wsemul_vt100_handle_dcs(edp);
    760       1.1  drochner 		return (VT100_EMUL_STATE_NORMAL);
    761       1.1  drochner 	} else
    762       1.1  drochner 		return (VT100_EMUL_STATE_STRING);
    763       1.1  drochner }
    764       1.1  drochner 
    765       1.1  drochner static u_int
    766      1.15  augustss wsemul_vt100_output_dcs(struct wsemul_vt100_emuldata *edp, u_char c)
    767       1.1  drochner {
    768       1.1  drochner 	u_int newstate = VT100_EMUL_STATE_DCS;
    769       1.1  drochner 
    770       1.1  drochner 	switch (c) {
    771      1.19  junyoung 	case '0': case '1': case '2': case '3': case '4':
    772      1.19  junyoung 	case '5': case '6': case '7': case '8': case '9':
    773       1.1  drochner 		/* argument digit */
    774       1.1  drochner 		if (edp->nargs > VT100_EMUL_NARGS - 1)
    775       1.1  drochner 			break;
    776       1.1  drochner 		edp->args[edp->nargs] = (edp->args[edp->nargs] * 10) +
    777       1.1  drochner 		    (c - '0');
    778       1.1  drochner 		break;
    779      1.19  junyoung 	case ';': /* argument terminator */
    780       1.1  drochner 		edp->nargs++;
    781       1.1  drochner 		break;
    782      1.19  junyoung 	default:
    783       1.1  drochner 		edp->nargs++;
    784       1.1  drochner 		if (edp->nargs > VT100_EMUL_NARGS) {
    785       1.1  drochner #ifdef VT100_DEBUG
    786       1.1  drochner 			printf("vt100: too many arguments\n");
    787       1.1  drochner #endif
    788       1.1  drochner 			edp->nargs = VT100_EMUL_NARGS;
    789       1.1  drochner 		}
    790       1.1  drochner 		newstate = VT100_EMUL_STATE_STRING;
    791       1.1  drochner 		switch (c) {
    792      1.19  junyoung 		case '$':
    793       1.1  drochner 			newstate = VT100_EMUL_STATE_DCS_DOLLAR;
    794       1.1  drochner 			break;
    795      1.19  junyoung 		case '{': /* DECDLD soft charset */
    796      1.19  junyoung 		case '!': /* DECRQUPSS user preferred supplemental set */
    797       1.1  drochner 			/* 'u' must follow - need another state */
    798      1.19  junyoung 		case '|': /* DECUDK program F6..F20 */
    799       1.1  drochner #ifdef VT100_PRINTNOTIMPL
    800       1.1  drochner 			printf("DCS%c ignored\n", c);
    801       1.1  drochner #endif
    802       1.1  drochner 			break;
    803      1.19  junyoung 		default:
    804       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    805       1.1  drochner 			printf("DCS%c (%d, %d) unknown\n", c, ARG(0), ARG(1));
    806       1.1  drochner #endif
    807       1.1  drochner 			break;
    808       1.1  drochner 		}
    809       1.1  drochner 	}
    810       1.1  drochner 
    811       1.1  drochner 	return (newstate);
    812       1.1  drochner }
    813       1.1  drochner 
    814       1.1  drochner static u_int
    815      1.15  augustss wsemul_vt100_output_dcs_dollar(struct wsemul_vt100_emuldata *edp, u_char c)
    816       1.1  drochner {
    817       1.1  drochner 	switch (c) {
    818      1.19  junyoung 	case 'p': /* DECRSTS terminal state restore */
    819      1.19  junyoung 	case 'q': /* DECRQSS control function request */
    820       1.1  drochner #ifdef VT100_PRINTNOTIMPL
    821       1.1  drochner 		printf("DCS$%c ignored\n", c);
    822       1.1  drochner #endif
    823       1.1  drochner 		break;
    824      1.19  junyoung 	case 't': /* DECRSPS restore presentation state */
    825       1.1  drochner 		switch (ARG(0)) {
    826      1.19  junyoung 		case 0: /* error */
    827       1.1  drochner 			break;
    828      1.19  junyoung 		case 1: /* cursor information restore */
    829       1.1  drochner #ifdef VT100_PRINTNOTIMPL
    830       1.1  drochner 			printf("DCS1$t ignored\n");
    831       1.1  drochner #endif
    832       1.1  drochner 			break;
    833      1.19  junyoung 		case 2: /* tab stop restore */
    834       1.1  drochner 			edp->dcspos = 0;
    835       1.1  drochner 			edp->dcstype = DCSTYPE_TABRESTORE;
    836       1.1  drochner 			break;
    837      1.19  junyoung 		default:
    838       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    839       1.1  drochner 			printf("DCS%d$t unknown\n", ARG(0));
    840       1.1  drochner #endif
    841       1.1  drochner 			break;
    842       1.1  drochner 		}
    843       1.1  drochner 		break;
    844      1.19  junyoung 	default:
    845       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    846       1.1  drochner 		printf("DCS$%c (%d, %d) unknown\n", c, ARG(0), ARG(1));
    847       1.1  drochner #endif
    848       1.1  drochner 		break;
    849       1.1  drochner 	}
    850       1.1  drochner 	return (VT100_EMUL_STATE_STRING);
    851       1.1  drochner }
    852       1.1  drochner 
    853       1.1  drochner static u_int
    854      1.15  augustss wsemul_vt100_output_esc_hash(struct wsemul_vt100_emuldata *edp, u_char c)
    855       1.1  drochner {
    856      1.23  drochner 	int i, j;
    857       1.1  drochner 
    858       1.1  drochner 	switch (c) {
    859      1.19  junyoung 	case '5': /*  DECSWL single width, single height */
    860       1.3  drochner 		if (edp->dw) {
    861       1.3  drochner 			for (i = 0; i < edp->ncols / 2; i++)
    862       1.3  drochner 				(*edp->emulops->copycols)(edp->emulcookie,
    863       1.3  drochner 							  edp->crow,
    864       1.3  drochner 							  2 * i, i, 1);
    865       1.3  drochner 			(*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
    866       1.3  drochner 						   i, edp->ncols - i,
    867      1.13   mycroft 						   edp->bkgdattr);
    868       1.3  drochner 			edp->dblwid[edp->crow] = 0;
    869       1.3  drochner 			edp->dw = 0;
    870       1.1  drochner 		}
    871       1.1  drochner 		break;
    872      1.19  junyoung 	case '6': /*  DECDWL double width, single height */
    873      1.19  junyoung 	case '3': /*  DECDHL double width, double height, top half */
    874      1.19  junyoung 	case '4': /*  DECDHL double width, double height, bottom half */
    875       1.3  drochner 		if (!edp->dw) {
    876       1.3  drochner 			for (i = edp->ncols / 2 - 1; i >= 0; i--)
    877       1.3  drochner 				(*edp->emulops->copycols)(edp->emulcookie,
    878       1.3  drochner 							  edp->crow,
    879       1.3  drochner 							  i, 2 * i, 1);
    880       1.3  drochner 			for (i = 0; i < edp->ncols / 2; i++)
    881       1.3  drochner 				(*edp->emulops->erasecols)(edp->emulcookie,
    882       1.3  drochner 							   edp->crow,
    883       1.3  drochner 							   2 * i + 1, 1,
    884      1.13   mycroft 							   edp->bkgdattr);
    885       1.3  drochner 			edp->dblwid[edp->crow] = 1;
    886       1.3  drochner 			edp->dw = 1;
    887       1.3  drochner 			if (edp->ccol > (edp->ncols >> 1) - 1)
    888       1.3  drochner 				edp->ccol = (edp->ncols >> 1) - 1;
    889       1.3  drochner 		}
    890       1.1  drochner 		break;
    891      1.23  drochner 	case '8': /* DECALN */
    892       1.1  drochner 		for (i = 0; i < edp->nrows; i++)
    893       1.1  drochner 			for (j = 0; j < edp->ncols; j++)
    894       1.2  drochner 				(*edp->emulops->putchar)(edp->emulcookie, i, j,
    895       1.2  drochner 							 'E', edp->curattr);
    896       1.1  drochner 		edp->ccol = 0;
    897       1.1  drochner 		edp->crow = 0;
    898       1.1  drochner 		break;
    899      1.19  junyoung 	default:
    900       1.1  drochner #ifdef VT100_PRINTUNKNOWN
    901       1.1  drochner 		printf("ESC#%c unknown\n", c);
    902       1.1  drochner #endif
    903       1.1  drochner 		break;
    904       1.1  drochner 	}
    905       1.1  drochner 	return (VT100_EMUL_STATE_NORMAL);
    906       1.1  drochner }
    907       1.1  drochner 
    908       1.1  drochner static u_int
    909      1.15  augustss wsemul_vt100_output_csi(struct wsemul_vt100_emuldata *edp, u_char c)
    910       1.1  drochner {
    911       1.1  drochner 	u_int newstate = VT100_EMUL_STATE_CSI;
    912       1.1  drochner 
    913       1.1  drochner 	switch (c) {
    914      1.19  junyoung 	case '0': case '1': case '2': case '3': case '4':
    915      1.19  junyoung 	case '5': case '6': case '7': case '8': case '9':
    916       1.1  drochner 		/* argument digit */
    917       1.1  drochner 		if (edp->nargs > VT100_EMUL_NARGS - 1)
    918       1.1  drochner 			break;
    919       1.1  drochner 		edp->args[edp->nargs] = (edp->args[edp->nargs] * 10) +
    920       1.1  drochner 		    (c - '0');
    921       1.1  drochner 		break;
    922      1.19  junyoung 	case ';': /* argument terminator */
    923       1.1  drochner 		edp->nargs++;
    924       1.1  drochner 		break;
    925      1.19  junyoung 	case '?': /* DEC specific */
    926      1.19  junyoung 	case '>': /* DA query */
    927       1.3  drochner 		edp->modif1 = c;
    928       1.1  drochner 		break;
    929      1.19  junyoung 	case '!':
    930      1.19  junyoung 	case '"':
    931      1.19  junyoung 	case '$':
    932      1.19  junyoung 	case '&':
    933       1.3  drochner 		edp->modif2 = c;
    934       1.1  drochner 		break;
    935      1.19  junyoung 	default: /* end of escape sequence */
    936       1.1  drochner 		edp->nargs++;
    937       1.1  drochner 		if (edp->nargs > VT100_EMUL_NARGS) {
    938       1.1  drochner #ifdef VT100_DEBUG
    939       1.1  drochner 			printf("vt100: too many arguments\n");
    940       1.1  drochner #endif
    941       1.1  drochner 			edp->nargs = VT100_EMUL_NARGS;
    942       1.1  drochner 		}
    943       1.1  drochner 		wsemul_vt100_handle_csi(edp, c);
    944       1.1  drochner 		newstate = VT100_EMUL_STATE_NORMAL;
    945       1.1  drochner 		break;
    946       1.1  drochner 	}
    947       1.1  drochner 	return (newstate);
    948       1.1  drochner }
    949       1.1  drochner 
    950       1.1  drochner void
    951      1.15  augustss wsemul_vt100_output(void *cookie, const u_char *data, u_int count, int kernel)
    952       1.1  drochner {
    953       1.1  drochner 	struct wsemul_vt100_emuldata *edp = cookie;
    954       1.1  drochner 
    955       1.1  drochner #ifdef DIAGNOSTIC
    956       1.1  drochner 	if (kernel && !edp->console)
    957       1.1  drochner 		panic("wsemul_vt100_output: kernel output, not console");
    958       1.1  drochner #endif
    959       1.1  drochner 
    960      1.12   mycroft 	if (edp->flags & VTFL_CURSORON)
    961      1.12   mycroft 		(*edp->emulops->cursor)(edp->emulcookie, 0,
    962      1.12   mycroft 					edp->crow, edp->ccol << edp->dw);
    963       1.1  drochner 	for (; count > 0; data++, count--) {
    964       1.7  drochner 		if ((*data & 0x7f) < 0x20) {
    965       1.7  drochner 			wsemul_vt100_output_c0c1(edp, *data, kernel);
    966       1.7  drochner 			continue;
    967       1.7  drochner 		}
    968       1.1  drochner 		if (edp->state == VT100_EMUL_STATE_NORMAL || kernel) {
    969       1.7  drochner 			wsemul_vt100_output_normal(edp, *data, kernel);
    970       1.1  drochner 			continue;
    971       1.1  drochner 		}
    972       1.1  drochner #ifdef DIAGNOSTIC
    973       1.1  drochner 		if (edp->state > sizeof(vt100_output) / sizeof(vt100_output[0]))
    974      1.20    provos 			panic("wsemul_vt100: invalid state %d", edp->state);
    975       1.1  drochner #endif
    976       1.1  drochner 		edp->state = vt100_output[edp->state - 1](edp, *data);
    977       1.1  drochner 	}
    978      1.12   mycroft 	if (edp->flags & VTFL_CURSORON)
    979      1.12   mycroft 		(*edp->emulops->cursor)(edp->emulcookie, 1,
    980      1.12   mycroft 					edp->crow, edp->ccol << edp->dw);
    981       1.1  drochner }
    982  1.24.2.1     skrll 
    983  1.24.2.1     skrll #ifdef WSDISPLAY_CUSTOM_OUTPUT
    984  1.24.2.1     skrll static void
    985  1.24.2.1     skrll wsemul_vt100_getmsgattrs(void *cookie, struct wsdisplay_msgattrs *ma)
    986  1.24.2.1     skrll {
    987  1.24.2.1     skrll 	struct wsemul_vt100_emuldata *edp = cookie;
    988  1.24.2.1     skrll 
    989  1.24.2.1     skrll 	*ma = edp->msgattrs;
    990  1.24.2.1     skrll }
    991  1.24.2.1     skrll 
    992  1.24.2.1     skrll static void
    993  1.24.2.1     skrll wsemul_vt100_setmsgattrs(void *cookie, const struct wsscreen_descr *type,
    994  1.24.2.1     skrll                          const struct wsdisplay_msgattrs *ma)
    995  1.24.2.1     skrll {
    996  1.24.2.1     skrll 	int error;
    997  1.24.2.1     skrll 	long tmp;
    998  1.24.2.1     skrll 	struct wsemul_vt100_emuldata *edp = cookie;
    999  1.24.2.1     skrll 
   1000  1.24.2.1     skrll 	edp->msgattrs = *ma;
   1001  1.24.2.1     skrll 	if (type->capabilities & WSSCREEN_WSCOLORS) {
   1002  1.24.2.1     skrll 		edp->msgattrs.default_attrs |= WSATTR_WSCOLORS;
   1003  1.24.2.1     skrll 		edp->msgattrs.kernel_attrs |= WSATTR_WSCOLORS;
   1004  1.24.2.1     skrll 	} else {
   1005  1.24.2.1     skrll 		edp->msgattrs.default_bg = edp->msgattrs.kernel_bg = 0;
   1006  1.24.2.1     skrll 		edp->msgattrs.default_fg = edp->msgattrs.kernel_fg = 0;
   1007  1.24.2.1     skrll 	}
   1008  1.24.2.1     skrll 
   1009  1.24.2.1     skrll 	error = (*edp->emulops->allocattr)(edp->emulcookie,
   1010  1.24.2.1     skrll 	                                   edp->msgattrs.default_fg,
   1011  1.24.2.1     skrll 					   edp->msgattrs.default_bg,
   1012  1.24.2.1     skrll 	                                   edp->msgattrs.default_attrs,
   1013  1.24.2.1     skrll 	                                   &tmp);
   1014  1.24.2.1     skrll #ifdef VT100_DEBUG
   1015  1.24.2.1     skrll 	if (error)
   1016  1.24.2.1     skrll 		printf("vt100: failed to allocate attribute for default "
   1017  1.24.2.1     skrll 		       "messages\n");
   1018  1.24.2.1     skrll 	else
   1019  1.24.2.1     skrll #endif
   1020  1.24.2.1     skrll 	{
   1021  1.24.2.1     skrll 		if (edp->curattr == edp->defattr) {
   1022  1.24.2.1     skrll 			edp->bkgdattr = edp->curattr = tmp;
   1023  1.24.2.1     skrll 			edp->attrflags = edp->msgattrs.default_attrs;
   1024  1.24.2.1     skrll 			edp->bgcol = edp->msgattrs.default_bg;
   1025  1.24.2.1     skrll 			edp->fgcol = edp->msgattrs.default_fg;
   1026  1.24.2.1     skrll 		} else {
   1027  1.24.2.1     skrll 			edp->savedbkgdattr = edp->savedattr = tmp;
   1028  1.24.2.1     skrll 			edp->savedattrflags = edp->msgattrs.default_attrs;
   1029  1.24.2.1     skrll 			edp->savedbgcol = edp->msgattrs.default_bg;
   1030  1.24.2.1     skrll 			edp->savedfgcol = edp->msgattrs.default_fg;
   1031  1.24.2.1     skrll 		}
   1032  1.24.2.1     skrll 		if (edp->emulops->replaceattr != NULL)
   1033  1.24.2.1     skrll 			(*edp->emulops->replaceattr)(edp->emulcookie,
   1034  1.24.2.1     skrll 			                             edp->defattr, tmp);
   1035  1.24.2.1     skrll 		edp->defattr = tmp;
   1036  1.24.2.1     skrll 	}
   1037  1.24.2.1     skrll 
   1038  1.24.2.1     skrll 	error = (*edp->emulops->allocattr)(edp->emulcookie,
   1039  1.24.2.1     skrll 	                                   edp->msgattrs.kernel_fg,
   1040  1.24.2.1     skrll 					   edp->msgattrs.kernel_bg,
   1041  1.24.2.1     skrll 	                                   edp->msgattrs.kernel_attrs,
   1042  1.24.2.1     skrll 	                                   &tmp);
   1043  1.24.2.1     skrll #ifdef VT100_DEBUG
   1044  1.24.2.1     skrll 	if (error)
   1045  1.24.2.1     skrll 		printf("vt100: failed to allocate attribute for kernel "
   1046  1.24.2.1     skrll 		       "messages\n");
   1047  1.24.2.1     skrll 	else
   1048  1.24.2.1     skrll #endif
   1049  1.24.2.1     skrll 	{
   1050  1.24.2.1     skrll 		if (edp->emulops->replaceattr != NULL)
   1051  1.24.2.1     skrll 			(*edp->emulops->replaceattr)(edp->emulcookie,
   1052  1.24.2.1     skrll 			                             edp->kernattr, tmp);
   1053  1.24.2.1     skrll 		edp->kernattr = tmp;
   1054  1.24.2.1     skrll 	}
   1055  1.24.2.1     skrll }
   1056  1.24.2.1     skrll #endif /* WSDISPLAY_CUSTOM_OUTPUT */
   1057