wsemul_dumb.c revision 1.17
1/* $NetBSD: wsemul_dumb.c,v 1.17 2017/11/03 18:42:35 maya 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.17 2017/11/03 18:42:35 maya 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#include <dev/wscons/wsksymdef.h>
47
48void	*wsemul_dumb_cnattach(const struct wsscreen_descr *, void *,
49				   int, int, long);
50void	*wsemul_dumb_attach(int console, const struct wsscreen_descr *,
51				 void *, int, int, void *, long);
52void	wsemul_dumb_output(void *cookie, const u_char *data, u_int count, int);
53int	wsemul_dumb_translate(void *cookie, keysym_t, const char **);
54void	wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp);
55void	wsemul_dumb_resetop(void *, enum wsemul_resetops);
56
57const struct wsemul_ops wsemul_dumb_ops = {
58	.name = "dumb",
59	.cnattach = wsemul_dumb_cnattach,
60	.attach = wsemul_dumb_attach,
61	.output = wsemul_dumb_output,
62	.translate = wsemul_dumb_translate,
63	.detach = wsemul_dumb_detach,
64	.reset = wsemul_dumb_resetop,
65	.getmsgattrs = NULL,
66	.setmsgattrs = NULL,
67	.resize = NULL,
68};
69
70struct wsemul_dumb_emuldata {
71	const struct wsdisplay_emulops *emulops;
72	void *emulcookie;
73	void *cbcookie;
74	u_int nrows, ncols, crow, ccol;
75	long defattr;
76};
77
78struct wsemul_dumb_emuldata wsemul_dumb_console_emuldata;
79
80void *
81wsemul_dumb_cnattach(const struct wsscreen_descr *type, void *cookie,
82	int ccol, int crow, long defattr)
83{
84	struct wsemul_dumb_emuldata *edp;
85
86	edp = &wsemul_dumb_console_emuldata;
87
88	edp->emulops = type->textops;
89	edp->emulcookie = cookie;
90	edp->nrows = type->nrows;
91	edp->ncols = type->ncols;
92	edp->crow = crow;
93	edp->ccol = ccol;
94	edp->defattr = defattr;
95	edp->cbcookie = NULL;
96
97	return (edp);
98}
99
100void *
101wsemul_dumb_attach(int console, const struct wsscreen_descr *type,
102	void *cookie, int ccol, int crow, void *cbcookie, long defattr)
103{
104	struct wsemul_dumb_emuldata *edp;
105
106	if (console)
107		edp = &wsemul_dumb_console_emuldata;
108	else {
109		edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK);
110
111		edp->emulops = type->textops;
112		edp->emulcookie = cookie;
113		edp->nrows = type->nrows;
114		edp->ncols = type->ncols;
115		edp->crow = crow;
116		edp->ccol = ccol;
117		edp->defattr = defattr;
118	}
119
120	edp->cbcookie = cbcookie;
121
122	return (edp);
123}
124
125void
126wsemul_dumb_output(void *cookie, const u_char *data, u_int count,
127    int kernel)
128{
129	struct wsemul_dumb_emuldata *edp = cookie;
130	u_char c;
131	int n;
132
133	/* XXX */
134	(*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol);
135	while (count-- > 0) {
136		c = *data++;
137		switch (c) {
138		case ASCII_BEL:
139			wsdisplay_emulbell(edp->cbcookie);
140			break;
141
142		case ASCII_BS:
143			if (edp->ccol > 0)
144				edp->ccol--;
145			break;
146
147		case ASCII_CR:
148			edp->ccol = 0;
149			break;
150
151		case ASCII_HT:
152			n = min(8 - (edp->ccol & 7),
153			    edp->ncols - edp->ccol - 1);
154			(*edp->emulops->erasecols)(edp->emulcookie,
155			    edp->crow, edp->ccol, n, edp->defattr);
156			edp->ccol += n;
157			break;
158
159		case ASCII_FF:
160			(*edp->emulops->eraserows)(edp->emulcookie, 0,
161			    edp->nrows, edp->defattr);
162			edp->ccol = 0;
163			edp->crow = 0;
164			break;
165
166		case ASCII_VT:
167			if (edp->crow > 0)
168				edp->crow--;
169			break;
170
171		default:
172			(*edp->emulops->putchar)(edp->emulcookie, edp->crow,
173			    edp->ccol, c, edp->defattr);
174			edp->ccol++;
175
176			/* if cur col is still on cur line, done. */
177			if (edp->ccol < edp->ncols)
178				break;
179
180			/* wrap the column around. */
181			edp->ccol = 0;
182
183                	/* FALLTHRU */
184
185		case ASCII_LF:
186	                /* if the cur line isn't the last, incr and leave. */
187			if (edp->crow < edp->nrows - 1) {
188				edp->crow++;
189				break;
190			}
191			n = 1;		/* number of lines to scroll */
192			(*edp->emulops->copyrows)(edp->emulcookie, n, 0,
193			    edp->nrows - n);
194			(*edp->emulops->eraserows)(edp->emulcookie,
195			    edp->nrows - n, n, edp->defattr);
196			edp->crow -= n - 1;
197			break;
198		}
199	}
200	/* XXX */
201	(*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol);
202}
203
204int
205wsemul_dumb_translate(void *cookie, keysym_t in,
206    const char **out)
207{
208	static char c;
209
210	if (KS_GROUP(in) == KS_GROUP_Plain) {
211		/* allow ISO-1 */
212		c = KS_VALUE(in);
213		*out = &c;
214		return (1);
215	}
216	return (0);
217}
218
219void
220wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp)
221{
222	struct wsemul_dumb_emuldata *edp = cookie;
223
224	*crowp = edp->crow;
225	*ccolp = edp->ccol;
226	if (edp != &wsemul_dumb_console_emuldata)
227		free(edp, M_DEVBUF);
228}
229
230void
231wsemul_dumb_resetop(void *cookie, enum wsemul_resetops op)
232{
233	struct wsemul_dumb_emuldata *edp = cookie;
234
235	switch (op) {
236	case WSEMUL_CLEARSCREEN:
237		(*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows,
238					   edp->defattr);
239		edp->ccol = edp->crow = 0;
240		(*edp->emulops->cursor)(edp->emulcookie, 1, 0, 0);
241		break;
242	default:
243		break;
244	}
245}
246