wsemul_dumb.c revision 1.2
1/* $NetBSD: wsemul_dumb.c,v 1.2 1998/05/14 20:49:57 drochner Exp $ */
2
3/*
4 * Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 *    must display the following acknowledgement:
16 *      This product includes software developed by Christopher G. Demetriou
17 *	for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33static const char _copyright[] __attribute__ ((unused)) =
34    "Copyright (c) 1996, 1997 Christopher G. Demetriou.  All rights reserved.";
35static const char _rcsid[] __attribute__ ((unused)) =
36    "$NetBSD: wsemul_dumb.c,v 1.2 1998/05/14 20:49:57 drochner Exp $";
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/time.h>
41#include <sys/malloc.h>
42#include <sys/fcntl.h>
43
44#include <dev/wscons/wsconsio.h>
45#include <dev/wscons/wsdisplayvar.h>
46#include <dev/wscons/wsemulvar.h>
47#include <dev/wscons/ascii.h>
48
49void	*wsemul_dumb_cnattach __P((const struct wsscreen_descr *, void *,
50				   int, int, long));
51void	*wsemul_dumb_attach __P((int console, const struct wsscreen_descr *,
52				 void *, int, int, void *, long));
53void	wsemul_dumb_output __P((void *cookie, const u_char *data, u_int count,
54				int));
55void	wsemul_dumb_detach __P((void *cookie, u_int *crowp, u_int *ccolp));
56
57const struct wsemul_ops wsemul_dumb_ops = {
58	"dumb",
59	wsemul_dumb_cnattach,
60	wsemul_dumb_attach,
61	wsemul_dumb_output,
62	wsemul_dumb_detach,
63};
64
65struct wsemul_dumb_emuldata {
66	const struct wsdisplay_emulops *emulops;
67	void *emulcookie;
68	void *cbcookie;
69	u_int nrows, ncols, crow, ccol;
70	long defattr;
71};
72
73struct wsemul_dumb_emuldata wsemul_dumb_console_emuldata;
74
75void *
76wsemul_dumb_cnattach(type, cookie, ccol, crow, defattr)
77	const struct wsscreen_descr *type;
78	void *cookie;
79	int ccol, crow;
80	long defattr;
81{
82	struct wsemul_dumb_emuldata *edp;
83
84	edp = &wsemul_dumb_console_emuldata;
85
86	edp->emulops = type->textops;
87	edp->emulcookie = cookie;
88	edp->nrows = type->nrows;
89	edp->ncols = type->ncols;
90	edp->crow = crow;
91	edp->ccol = ccol;
92	edp->defattr = defattr;
93	edp->cbcookie = NULL;
94
95	return (edp);
96}
97
98void *
99wsemul_dumb_attach(console, type, cookie, ccol, crow, cbcookie, defattr)
100	int console;
101	const struct wsscreen_descr *type;
102	void *cookie;
103	int ccol, crow;
104	void *cbcookie;
105	long defattr;
106{
107	struct wsemul_dumb_emuldata *edp;
108
109	if (console)
110		edp = &wsemul_dumb_console_emuldata;
111	else {
112		edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK);
113
114		edp->emulops = type->textops;
115		edp->emulcookie = cookie;
116		edp->nrows = type->nrows;
117		edp->ncols = type->ncols;
118		edp->crow = crow;
119		edp->ccol = ccol;
120		edp->defattr = defattr;
121	}
122
123	edp->cbcookie = cbcookie;
124
125	return (edp);
126}
127
128void
129wsemul_dumb_output(cookie, data, count, kernel)
130	void *cookie;
131	const u_char *data;
132	u_int count;
133	int kernel; /* ignored */
134{
135	struct wsemul_dumb_emuldata *edp = cookie;
136	u_char c;
137	int n;
138
139	/* XXX */
140	(*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol);
141	while (count-- > 0) {
142		c = *data++;
143		switch (c) {
144		case ASCII_BEL:
145			wsdisplay_emulbell(edp->cbcookie);
146			break;
147
148		case ASCII_BS:
149			if (edp->ccol > 0)
150				edp->ccol--;
151			break;
152
153		case ASCII_CR:
154			edp->ccol = 0;
155			break;
156
157		case ASCII_HT:
158			n = min(8 - (edp->ccol & 7),
159			    edp->ncols - edp->ccol - 1);
160			(*edp->emulops->erasecols)(edp->emulcookie,
161			    edp->crow, edp->ccol, n, edp->defattr);
162			edp->ccol += n;
163			break;
164
165		case ASCII_NP:
166			(*edp->emulops->eraserows)(edp->emulcookie, 0,
167			    edp->nrows, edp->defattr);
168			edp->ccol = 0;
169			edp->crow = 0;
170			break;
171
172		case ASCII_VT:
173			if (edp->crow > 0)
174				edp->crow--;
175			break;
176
177		default:
178			(*edp->emulops->putstr)(edp->emulcookie, edp->crow,
179			    edp->ccol, &c, 1, edp->defattr);
180			edp->ccol++;
181
182			/* if cur col is still on cur line, done. */
183			if (edp->ccol < edp->ncols)
184				break;
185
186			/* wrap the column around. */
187			edp->ccol = 0;
188
189                	/* FALLTHRU */
190
191		case ASCII_LF:
192	                /* if the cur line isn't the last, incr and leave. */
193			if (edp->crow < edp->nrows - 1) {
194				edp->crow++;
195				break;
196			}
197			n = 1;		/* number of lines to scroll */
198			(*edp->emulops->copyrows)(edp->emulcookie, n, 0,
199			    edp->nrows - n);
200			(*edp->emulops->eraserows)(edp->emulcookie,
201			    edp->nrows - n, n, edp->defattr);
202			edp->crow -= n - 1;
203			break;
204		}
205	}
206	/* XXX */
207	(*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol);
208}
209
210void
211wsemul_dumb_detach(cookie, crowp, ccolp)
212	void *cookie;
213	u_int *crowp, *ccolp;
214{
215	struct wsemul_dumb_emuldata *edp = cookie;
216
217	*crowp = edp->crow;
218	*ccolp = edp->ccol;
219	if (edp != &wsemul_dumb_console_emuldata)
220		free(edp, M_DEVBUF);
221}
222