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