xref: /netbsd-src/sys/dev/wscons/wsemul_dumb.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /* $NetBSD: wsemul_dumb.c,v 1.14 2006/11/16 01:33:31 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.14 2006/11/16 01:33:31 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 
47 void	*wsemul_dumb_cnattach(const struct wsscreen_descr *, void *,
48 				   int, int, long);
49 void	*wsemul_dumb_attach(int console, const struct wsscreen_descr *,
50 				 void *, int, int, void *, long);
51 void	wsemul_dumb_output(void *cookie, const u_char *data, u_int count, int);
52 int	wsemul_dumb_translate(void *cookie, keysym_t, const char **);
53 void	wsemul_dumb_detach(void *cookie, u_int *crowp, u_int *ccolp);
54 void	wsemul_dumb_resetop(void *, enum wsemul_resetops);
55 
56 const 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 
68 struct 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 
76 struct wsemul_dumb_emuldata wsemul_dumb_console_emuldata;
77 
78 void *
79 wsemul_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 
98 void *
99 wsemul_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 
123 void
124 wsemul_dumb_output(void *cookie, const u_char *data, u_int count,
125     int kernel)
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 
202 int
203 wsemul_dumb_translate(void *cookie, keysym_t in,
204     const char **out)
205 {
206 	return (0);
207 }
208 
209 void
210 wsemul_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 
220 void
221 wsemul_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