wsemul_dumb.c revision 1.13
1/* $NetBSD: wsemul_dumb.c,v 1.13 2006/10/12 01:32:06 christos 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
33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: wsemul_dumb.c,v 1.13 2006/10/12 01:32:06 christos Exp $");
35
36#include <sys/param.h>
37#include <sys/systm.h>
38#include <sys/time.h>
39#include <sys/malloc.h>
40#include <sys/fcntl.h>
41
42#include <dev/wscons/wsconsio.h>
43#include <dev/wscons/wsdisplayvar.h>
44#include <dev/wscons/wsemulvar.h>
45#include <dev/wscons/ascii.h>
46
47void	*wsemul_dumb_cnattach(const struct wsscreen_descr *, void *,
48				   int, int, long);
49void	*wsemul_dumb_attach(int console, const struct wsscreen_descr *,
50				 void *, int, int, void *, long);
51void	wsemul_dumb_output(void *cookie, const u_char *data, u_int count, int);
52int	wsemul_dumb_translate(void *cookie, keysym_t, const char **);
53void	wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp);
54void	wsemul_dumb_resetop(void *, enum wsemul_resetops);
55
56const struct wsemul_ops wsemul_dumb_ops = {
57	"dumb",
58	wsemul_dumb_cnattach,
59	wsemul_dumb_attach,
60	wsemul_dumb_output,
61	wsemul_dumb_translate,
62	wsemul_dumb_detach,
63	wsemul_dumb_resetop,
64	NULL,	/* getmsgattrs */
65	NULL,	/* setmsgattrs */
66};
67
68struct wsemul_dumb_emuldata {
69	const struct wsdisplay_emulops *emulops;
70	void *emulcookie;
71	void *cbcookie;
72	u_int nrows, ncols, crow, ccol;
73	long defattr;
74};
75
76struct wsemul_dumb_emuldata wsemul_dumb_console_emuldata;
77
78void *
79wsemul_dumb_cnattach(const struct wsscreen_descr *type, void *cookie,
80	int ccol, int crow, 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(int console, const struct wsscreen_descr *type,
100	void *cookie, int ccol, int crow, void *cbcookie, long defattr)
101{
102	struct wsemul_dumb_emuldata *edp;
103
104	if (console)
105		edp = &wsemul_dumb_console_emuldata;
106	else {
107		edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK);
108
109		edp->emulops = type->textops;
110		edp->emulcookie = cookie;
111		edp->nrows = type->nrows;
112		edp->ncols = type->ncols;
113		edp->crow = crow;
114		edp->ccol = ccol;
115		edp->defattr = defattr;
116	}
117
118	edp->cbcookie = cbcookie;
119
120	return (edp);
121}
122
123void
124wsemul_dumb_output(void *cookie, const u_char *data, u_int count,
125    int kernel __unused)
126{
127	struct wsemul_dumb_emuldata *edp = cookie;
128	u_char c;
129	int n;
130
131	/* XXX */
132	(*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol);
133	while (count-- > 0) {
134		c = *data++;
135		switch (c) {
136		case ASCII_BEL:
137			wsdisplay_emulbell(edp->cbcookie);
138			break;
139
140		case ASCII_BS:
141			if (edp->ccol > 0)
142				edp->ccol--;
143			break;
144
145		case ASCII_CR:
146			edp->ccol = 0;
147			break;
148
149		case ASCII_HT:
150			n = min(8 - (edp->ccol & 7),
151			    edp->ncols - edp->ccol - 1);
152			(*edp->emulops->erasecols)(edp->emulcookie,
153			    edp->crow, edp->ccol, n, edp->defattr);
154			edp->ccol += n;
155			break;
156
157		case ASCII_FF:
158			(*edp->emulops->eraserows)(edp->emulcookie, 0,
159			    edp->nrows, edp->defattr);
160			edp->ccol = 0;
161			edp->crow = 0;
162			break;
163
164		case ASCII_VT:
165			if (edp->crow > 0)
166				edp->crow--;
167			break;
168
169		default:
170			(*edp->emulops->putchar)(edp->emulcookie, edp->crow,
171			    edp->ccol, c, edp->defattr);
172			edp->ccol++;
173
174			/* if cur col is still on cur line, done. */
175			if (edp->ccol < edp->ncols)
176				break;
177
178			/* wrap the column around. */
179			edp->ccol = 0;
180
181                	/* FALLTHRU */
182
183		case ASCII_LF:
184	                /* if the cur line isn't the last, incr and leave. */
185			if (edp->crow < edp->nrows - 1) {
186				edp->crow++;
187				break;
188			}
189			n = 1;		/* number of lines to scroll */
190			(*edp->emulops->copyrows)(edp->emulcookie, n, 0,
191			    edp->nrows - n);
192			(*edp->emulops->eraserows)(edp->emulcookie,
193			    edp->nrows - n, n, edp->defattr);
194			edp->crow -= n - 1;
195			break;
196		}
197	}
198	/* XXX */
199	(*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol);
200}
201
202int
203wsemul_dumb_translate(void *cookie __unused, keysym_t in __unused,
204    const char **out __unused)
205{
206	return (0);
207}
208
209void
210wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp)
211{
212	struct wsemul_dumb_emuldata *edp = cookie;
213
214	*crowp = edp->crow;
215	*ccolp = edp->ccol;
216	if (edp != &wsemul_dumb_console_emuldata)
217		free(edp, M_DEVBUF);
218}
219
220void
221wsemul_dumb_resetop(void *cookie, enum wsemul_resetops op)
222{
223	struct wsemul_dumb_emuldata *edp = cookie;
224
225	switch (op) {
226	case WSEMUL_CLEARSCREEN:
227		(*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows,
228					   edp->defattr);
229		edp->ccol = edp->crow = 0;
230		(*edp->emulops->cursor)(edp->emulcookie, 1, 0, 0);
231		break;
232	default:
233		break;
234	}
235}
236