Sun Nov 8 16:49:41 2015 UTC ()
Untangle.


(christos)
diff -r1.28 -r1.29 src/sys/dev/wscons/wsemul_sun.c

cvs diff -r1.28 -r1.29 src/sys/dev/wscons/wsemul_sun.c (switch to unified diff)

--- src/sys/dev/wscons/wsemul_sun.c 2010/03/12 08:40:50 1.28
+++ src/sys/dev/wscons/wsemul_sun.c 2015/11/08 16:49:41 1.29
@@ -1,647 +1,647 @@ @@ -1,647 +1,647 @@
1/* $NetBSD: wsemul_sun.c,v 1.28 2010/03/12 08:40:50 jdc Exp $ */ 1/* $NetBSD: wsemul_sun.c,v 1.29 2015/11/08 16:49:41 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. 4 * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software 14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement: 15 * must display the following acknowledgement:
16 * This product includes software developed by Christopher G. Demetriou 16 * This product includes software developed by Christopher G. Demetriou
17 * for the NetBSD Project. 17 * for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products 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 19 * derived from this software without specific prior written permission
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 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 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 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 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 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. 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* XXX DESCRIPTION/SOURCE OF INFORMATION */ 33/* XXX DESCRIPTION/SOURCE OF INFORMATION */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: wsemul_sun.c,v 1.28 2010/03/12 08:40:50 jdc Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: wsemul_sun.c,v 1.29 2015/11/08 16:49:41 christos Exp $");
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40#include <sys/time.h> 40#include <sys/time.h>
41#include <sys/malloc.h> 41#include <sys/malloc.h>
42#include <sys/fcntl.h> 42#include <sys/fcntl.h>
43 43
44#include <dev/wscons/wsconsio.h> 44#include <dev/wscons/wsconsio.h>
45#include <dev/wscons/wsdisplayvar.h> 45#include <dev/wscons/wsdisplayvar.h>
46#include <dev/wscons/wsemulvar.h> 46#include <dev/wscons/wsemulvar.h>
47#include <dev/wscons/wsksymdef.h> 47#include <dev/wscons/wsksymdef.h>
48#include <dev/wscons/ascii.h> 48#include <dev/wscons/ascii.h>
49 49
50void *wsemul_sun_cnattach(const struct wsscreen_descr *, void *, 50void *wsemul_sun_cnattach(const struct wsscreen_descr *, void *,
51 int, int, long); 51 int, int, long);
52void *wsemul_sun_attach(int console, const struct wsscreen_descr *, 52void *wsemul_sun_attach(int console, const struct wsscreen_descr *,
53 void *, int, int, void *, long); 53 void *, int, int, void *, long);
54void wsemul_sun_output(void *cookie, const u_char *data, u_int count, 54void wsemul_sun_output(void *cookie, const u_char *data, u_int count,
55 int); 55 int);
56int wsemul_sun_translate(void *cookie, keysym_t, const char **); 56int wsemul_sun_translate(void *cookie, keysym_t, const char **);
57void wsemul_sun_detach(void *cookie, u_int *crowp, u_int *ccolp); 57void wsemul_sun_detach(void *cookie, u_int *crowp, u_int *ccolp);
58void wsemul_sun_resetop(void *, enum wsemul_resetops); 58void wsemul_sun_resetop(void *, enum wsemul_resetops);
59 59
60const struct wsemul_ops wsemul_sun_ops = { 60const struct wsemul_ops wsemul_sun_ops = {
61 "sun", 61 "sun",
62 wsemul_sun_cnattach, 62 wsemul_sun_cnattach,
63 wsemul_sun_attach, 63 wsemul_sun_attach,
64 wsemul_sun_output, 64 wsemul_sun_output,
65 wsemul_sun_translate, 65 wsemul_sun_translate,
66 wsemul_sun_detach, 66 wsemul_sun_detach,
67 wsemul_sun_resetop, 67 wsemul_sun_resetop,
68 NULL, /* getmsgattrs */ 68 NULL, /* getmsgattrs */
69 NULL, /* setmsgattrs */ 69 NULL, /* setmsgattrs */
70}; 70};
71 71
72#define SUN_EMUL_STATE_NORMAL 0 /* normal processing */ 72#define SUN_EMUL_STATE_NORMAL 0 /* normal processing */
73#define SUN_EMUL_STATE_HAVEESC 1 /* seen start of ctl seq */ 73#define SUN_EMUL_STATE_HAVEESC 1 /* seen start of ctl seq */
74#define SUN_EMUL_STATE_CONTROL 2 /* processing ctl seq */ 74#define SUN_EMUL_STATE_CONTROL 2 /* processing ctl seq */
75 75
76#define SUN_EMUL_NARGS 2 /* max # of args to a command */ 76#define SUN_EMUL_NARGS 2 /* max # of args to a command */
77 77
78struct wsemul_sun_emuldata { 78struct wsemul_sun_emuldata {
79 const struct wsdisplay_emulops *emulops; 79 const struct wsdisplay_emulops *emulops;
80 void *emulcookie; 80 void *emulcookie;
81 void *cbcookie; 81 void *cbcookie;
82 int scrcapabilities; 82 int scrcapabilities;
83 u_int nrows, ncols, crow, ccol; 83 u_int nrows, ncols, crow, ccol;
84 84
85 u_int state; /* processing state */ 85 u_int state; /* processing state */
86 u_int args[SUN_EMUL_NARGS]; /* command args, if CONTROL */ 86 u_int args[SUN_EMUL_NARGS]; /* command args, if CONTROL */
87 u_int scrolldist; /* distance to scroll */ 87 u_int scrolldist; /* distance to scroll */
88 long defattr; /* default attribute (rendition) */ 88 long defattr; /* default attribute (rendition) */
89 long bowattr; /* attribute for reversed mode */ 89 long bowattr; /* attribute for reversed mode */
90 int rendflags; 90 int rendflags;
91#define REND_BOW 1 91#define REND_BOW 1
92#define REND_SO 2 92#define REND_SO 2
93 long curattr; /* currently used attribute */ 93 long curattr; /* currently used attribute */
94 long kernattr; /* attribute for kernel output */ 94 long kernattr; /* attribute for kernel output */
95#ifdef DIAGNOSTIC 95#ifdef DIAGNOSTIC
96 int console; 96 int console;
97#endif 97#endif
98}; 98};
99 99
100static u_int wsemul_sun_output_normal(struct wsemul_sun_emuldata *, 100static u_int wsemul_sun_output_normal(struct wsemul_sun_emuldata *,
101 u_char, int); 101 u_char, int);
102static u_int wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *, u_char); 102static u_int wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *, u_char);
103static u_int wsemul_sun_output_control(struct wsemul_sun_emuldata *, u_char); 103static u_int wsemul_sun_output_control(struct wsemul_sun_emuldata *, u_char);
104static void wsemul_sun_control(struct wsemul_sun_emuldata *, u_char); 104static void wsemul_sun_control(struct wsemul_sun_emuldata *, u_char);
105 105
106struct wsemul_sun_emuldata wsemul_sun_console_emuldata; 106struct wsemul_sun_emuldata wsemul_sun_console_emuldata;
107 107
108/* some useful utility macros */ 108/* some useful utility macros */
109#define ARG(n) (edp->args[(n)]) 109#define ARG(n) (edp->args[(n)])
110#define NORMALIZE_ARG(n) (ARG(n) ? ARG(n) : 1) 110#define NORMALIZE_ARG(n) (ARG(n) ? ARG(n) : 1)
111#define COLS_LEFT (edp->ncols - edp->ccol - 1) 111#define COLS_LEFT (edp->ncols - edp->ccol - 1)
112#define ROWS_LEFT (edp->nrows - edp->crow - 1) 112#define ROWS_LEFT (edp->nrows - edp->crow - 1)
113 113
114void * 114void *
115wsemul_sun_cnattach(const struct wsscreen_descr *type, void *cookie, 115wsemul_sun_cnattach(const struct wsscreen_descr *type, void *cookie,
116 int ccol, int crow, long defattr) 116 int ccol, int crow, long defattr)
117{ 117{
118 struct wsemul_sun_emuldata *edp; 118 struct wsemul_sun_emuldata *edp;
119 int res; 119 int res;
120 120
121 edp = &wsemul_sun_console_emuldata; 121 edp = &wsemul_sun_console_emuldata;
122 122
123 edp->emulops = type->textops; 123 edp->emulops = type->textops;
124 edp->emulcookie = cookie; 124 edp->emulcookie = cookie;
125 edp->scrcapabilities = type->capabilities; 125 edp->scrcapabilities = type->capabilities;
126 edp->nrows = type->nrows; 126 edp->nrows = type->nrows;
127 edp->ncols = type->ncols; 127 edp->ncols = type->ncols;
128 edp->crow = crow; 128 edp->crow = crow;
129 edp->ccol = ccol; 129 edp->ccol = ccol;
130 edp->curattr = edp->defattr = defattr; 130 edp->curattr = edp->defattr = defattr;
131#if defined(WS_KERNEL_FG) || defined(WS_KERNEL_BG) || \ 131#if defined(WS_KERNEL_FG) || defined(WS_KERNEL_BG) || \
132 defined(WS_KERNEL_COLATTR) || defined(WS_KERNEL_MONOATTR) 132 defined(WS_KERNEL_COLATTR) || defined(WS_KERNEL_MONOATTR)
133#ifndef WS_KERNEL_FG 133#ifndef WS_KERNEL_FG
134#define WS_KERNEL_FG WSCOL_WHITE 134#define WS_KERNEL_FG WSCOL_WHITE
135#endif 135#endif
136#ifndef WS_KERNEL_BG 136#ifndef WS_KERNEL_BG
137#define WS_KERNEL_BG WSCOL_BLACK 137#define WS_KERNEL_BG WSCOL_BLACK
138#endif 138#endif
139#ifndef WS_KERNEL_COLATTR 139#ifndef WS_KERNEL_COLATTR
140#define WS_KERNEL_COLATTR 0 140#define WS_KERNEL_COLATTR 0
141#endif 141#endif
142#ifndef WS_KERNEL_MONOATTR 142#ifndef WS_KERNEL_MONOATTR
143#define WS_KERNEL_MONOATTR 0 143#define WS_KERNEL_MONOATTR 0
144#endif 144#endif
145 if (type->capabilities & WSSCREEN_WSCOLORS) 145 if (type->capabilities & WSSCREEN_WSCOLORS)
146 res = (*edp->emulops->allocattr)(cookie, 146 res = (*edp->emulops->allocattr)(cookie,
147 WS_KERNEL_FG, WS_KERNEL_BG, 147 WS_KERNEL_FG, WS_KERNEL_BG,
148 WS_KERNEL_COLATTR | WSATTR_WSCOLORS, 148 WS_KERNEL_COLATTR | WSATTR_WSCOLORS,
149 &edp->kernattr); 149 &edp->kernattr);
150 else 150 else
151 res = (*edp->emulops->allocattr)(cookie, 0, 0, 151 res = (*edp->emulops->allocattr)(cookie, 0, 0,
152 WS_KERNEL_MONOATTR, 152 WS_KERNEL_MONOATTR,
153 &edp->kernattr); 153 &edp->kernattr);
154 if (res) 
155#else 154#else
156 res = 0; /* XXX gcc */ 155 res = EINVAL;
157#endif 156#endif
158 edp->kernattr = defattr; 157 if (res)
 158 edp->kernattr = defattr;
159 159
160 edp->cbcookie = NULL; 160 edp->cbcookie = NULL;
161 161
162 edp->state = SUN_EMUL_STATE_NORMAL; 162 edp->state = SUN_EMUL_STATE_NORMAL;
163 edp->scrolldist = 1; 163 edp->scrolldist = 1;
164#ifdef DIAGNOSTIC 164#ifdef DIAGNOSTIC
165 edp->console = 1; 165 edp->console = 1;
166#endif 166#endif
167 return (edp); 167 return (edp);
168} 168}
169 169
170void * 170void *
171wsemul_sun_attach(int console, const struct wsscreen_descr *type, 171wsemul_sun_attach(int console, const struct wsscreen_descr *type,
172 void *cookie, int ccol, int crow, void *cbcookie, long defattr) 172 void *cookie, int ccol, int crow, void *cbcookie, long defattr)
173{ 173{
174 struct wsemul_sun_emuldata *edp; 174 struct wsemul_sun_emuldata *edp;
175 175
176 if (console) { 176 if (console) {
177 edp = &wsemul_sun_console_emuldata; 177 edp = &wsemul_sun_console_emuldata;
178#ifdef DIAGNOSTIC 178#ifdef DIAGNOSTIC
179 KASSERT(edp->console == 1); 179 KASSERT(edp->console == 1);
180#endif 180#endif
181 } else { 181 } else {
182 edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK); 182 edp = malloc(sizeof *edp, M_DEVBUF, M_WAITOK);
183 183
184 edp->emulops = type->textops; 184 edp->emulops = type->textops;
185 edp->emulcookie = cookie; 185 edp->emulcookie = cookie;
186 edp->scrcapabilities = type->capabilities; 186 edp->scrcapabilities = type->capabilities;
187 edp->nrows = type->nrows; 187 edp->nrows = type->nrows;
188 edp->ncols = type->ncols; 188 edp->ncols = type->ncols;
189 edp->crow = crow; 189 edp->crow = crow;
190 edp->ccol = ccol; 190 edp->ccol = ccol;
191 edp->defattr = defattr; 191 edp->defattr = defattr;
192 192
193 edp->state = SUN_EMUL_STATE_NORMAL; 193 edp->state = SUN_EMUL_STATE_NORMAL;
194 edp->scrolldist = 1; 194 edp->scrolldist = 1;
195#ifdef DIAGNOSTIC 195#ifdef DIAGNOSTIC
196 edp->console = 0; 196 edp->console = 0;
197#endif 197#endif
198 } 198 }
199 199
200 edp->cbcookie = cbcookie; 200 edp->cbcookie = cbcookie;
201 201
202 if ((!(edp->scrcapabilities & WSSCREEN_REVERSE) || 202 if ((!(edp->scrcapabilities & WSSCREEN_REVERSE) ||
203 (*edp->emulops->allocattr)(edp->emulcookie, 0, 0, 203 (*edp->emulops->allocattr)(edp->emulcookie, 0, 0,
204 WSATTR_REVERSE, 204 WSATTR_REVERSE,
205 &edp->bowattr)) && 205 &edp->bowattr)) &&
206 (!(edp->scrcapabilities & WSSCREEN_WSCOLORS) || 206 (!(edp->scrcapabilities & WSSCREEN_WSCOLORS) ||
207 (*edp->emulops->allocattr)(edp->emulcookie, 207 (*edp->emulops->allocattr)(edp->emulcookie,
208 WSCOL_BLACK, WSCOL_WHITE, 208 WSCOL_BLACK, WSCOL_WHITE,
209 WSATTR_WSCOLORS, 209 WSATTR_WSCOLORS,
210 &edp->bowattr))) 210 &edp->bowattr)))
211 edp->bowattr = edp->defattr; 211 edp->bowattr = edp->defattr;
212 212
213 edp->curattr = edp->defattr; 213 edp->curattr = edp->defattr;
214 edp->rendflags = 0; 214 edp->rendflags = 0;
215 215
216 return (edp); 216 return (edp);
217} 217}
218 218
219static inline u_int 219static inline u_int
220wsemul_sun_output_normal(struct wsemul_sun_emuldata *edp, u_char c, int kernel) 220wsemul_sun_output_normal(struct wsemul_sun_emuldata *edp, u_char c, int kernel)
221{ 221{
222 u_int newstate = SUN_EMUL_STATE_NORMAL; 222 u_int newstate = SUN_EMUL_STATE_NORMAL;
223 u_int n; 223 u_int n;
224 224
225 switch (c) { 225 switch (c) {
226 case ASCII_BEL: /* "Bell (BEL)" */ 226 case ASCII_BEL: /* "Bell (BEL)" */
227 wsdisplay_emulbell(edp->cbcookie); 227 wsdisplay_emulbell(edp->cbcookie);
228 break; 228 break;
229 229
230 case ASCII_BS: /* "Backspace (BS)" */ 230 case ASCII_BS: /* "Backspace (BS)" */
231 if (edp->ccol > 0) 231 if (edp->ccol > 0)
232 edp->ccol--; 232 edp->ccol--;
233 break; 233 break;
234 234
235 case ASCII_CR: /* "Return (CR)" */ 235 case ASCII_CR: /* "Return (CR)" */
236 edp->ccol = 0; 236 edp->ccol = 0;
237 break; 237 break;
238 238
239 case ASCII_HT: /* "Tab (TAB)" */ 239 case ASCII_HT: /* "Tab (TAB)" */
240 n = min(8 - (edp->ccol & 7), COLS_LEFT); 240 n = min(8 - (edp->ccol & 7), COLS_LEFT);
241 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow, 241 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
242 edp->ccol, n, 242 edp->ccol, n,
243 kernel ? edp->kernattr : edp->curattr); 243 kernel ? edp->kernattr : edp->curattr);
244 edp->ccol += n; 244 edp->ccol += n;
245 break; 245 break;
246 246
247 case ASCII_FF: /* "Form Feed (FF)" */ 247 case ASCII_FF: /* "Form Feed (FF)" */
248 (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows, 248 (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows,
249 kernel ? edp->kernattr : edp->curattr); 249 kernel ? edp->kernattr : edp->curattr);
250 /* XXX possible in kernel output? */ 250 /* XXX possible in kernel output? */
251 edp->ccol = 0; 251 edp->ccol = 0;
252 edp->crow = 0; 252 edp->crow = 0;
253 break; 253 break;
254 254
255 case ASCII_VT: /* "Reverse Line Feed" */ 255 case ASCII_VT: /* "Reverse Line Feed" */
256 if (edp->crow > 0) 256 if (edp->crow > 0)
257 edp->crow--; 257 edp->crow--;
258 break; 258 break;
259 259
260 case ASCII_ESC: /* "Escape (ESC)" */ 260 case ASCII_ESC: /* "Escape (ESC)" */
261 if (kernel) { 261 if (kernel) {
262 printf("wsemul_sun_output_normal: ESC in kernel output ignored\n"); 262 printf("wsemul_sun_output_normal: ESC in kernel output ignored\n");
263 break; /* ignore the ESC */ 263 break; /* ignore the ESC */
264 } 264 }
265 265
266 if (edp->state == SUN_EMUL_STATE_NORMAL) { 266 if (edp->state == SUN_EMUL_STATE_NORMAL) {
267 newstate = SUN_EMUL_STATE_HAVEESC; 267 newstate = SUN_EMUL_STATE_HAVEESC;
268 break; 268 break;
269 } 269 }
270 /* special case: fall through, we're printing one out */ 270 /* special case: fall through, we're printing one out */
271 /* FALLTHRU */ 271 /* FALLTHRU */
272 272
273 default: /* normal character */ 273 default: /* normal character */
274 (*edp->emulops->putchar)(edp->emulcookie, edp->crow, edp->ccol, 274 (*edp->emulops->putchar)(edp->emulcookie, edp->crow, edp->ccol,
275 c, kernel ? edp->kernattr : edp->curattr); 275 c, kernel ? edp->kernattr : edp->curattr);
276 edp->ccol++; 276 edp->ccol++;
277 277
278 /* if cur col is still on cur line, done. */ 278 /* if cur col is still on cur line, done. */
279 if (edp->ccol < edp->ncols) 279 if (edp->ccol < edp->ncols)
280 break; 280 break;
281 281
282 /* wrap the column around. */ 282 /* wrap the column around. */
283 edp->ccol = 0; 283 edp->ccol = 0;
284 284
285 /* FALLTHRU */ 285 /* FALLTHRU */
286 286
287 case ASCII_LF: /* "Line Feed (LF)" */ 287 case ASCII_LF: /* "Line Feed (LF)" */
288 /* if the cur line isn't the last, incr and leave. */ 288 /* if the cur line isn't the last, incr and leave. */
289 if (edp->crow < edp->nrows - 1) { 289 if (edp->crow < edp->nrows - 1) {
290 edp->crow++; 290 edp->crow++;
291 break; 291 break;
292 } 292 }
293 293
294 /* 294 /*
295 * if we're in wrap-around mode, go to the first 295 * if we're in wrap-around mode, go to the first
296 * line and clear it. 296 * line and clear it.
297 */ 297 */
298 if (edp->scrolldist == 0) { 298 if (edp->scrolldist == 0) {
299 edp->crow = 0; 299 edp->crow = 0;
300 (*edp->emulops->eraserows)(edp->emulcookie, 0, 1, 300 (*edp->emulops->eraserows)(edp->emulcookie, 0, 1,
301 edp->curattr); 301 edp->curattr);
302 break; 302 break;
303 } 303 }
304 304
305 /* scroll by the scrolling distance. */ 305 /* scroll by the scrolling distance. */
306 (*edp->emulops->copyrows)(edp->emulcookie, edp->scrolldist, 0, 306 (*edp->emulops->copyrows)(edp->emulcookie, edp->scrolldist, 0,
307 edp->nrows - edp->scrolldist); 307 edp->nrows - edp->scrolldist);
308 (*edp->emulops->eraserows)(edp->emulcookie, 308 (*edp->emulops->eraserows)(edp->emulcookie,
309 edp->nrows - edp->scrolldist, edp->scrolldist, 309 edp->nrows - edp->scrolldist, edp->scrolldist,
310 edp->curattr); 310 edp->curattr);
311 edp->crow -= edp->scrolldist - 1; 311 edp->crow -= edp->scrolldist - 1;
312 break; 312 break;
313 } 313 }
314 314
315 return (newstate); 315 return (newstate);
316} 316}
317 317
318static inline u_int 318static inline u_int
319wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *edp, u_char c) 319wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *edp, u_char c)
320{ 320{
321 u_int newstate; 321 u_int newstate;
322 322
323 switch (c) { 323 switch (c) {
324 case '[': /* continuation of multi-char sequence */ 324 case '[': /* continuation of multi-char sequence */
325 memset(edp->args, 0, sizeof (edp->args)); 325 memset(edp->args, 0, sizeof (edp->args));
326 newstate = SUN_EMUL_STATE_CONTROL; 326 newstate = SUN_EMUL_STATE_CONTROL;
327 break; 327 break;
328 328
329 default: 329 default:
330 /* spit out the escape char (???), then the new character */ 330 /* spit out the escape char (???), then the new character */
331 wsemul_sun_output_normal(edp, ASCII_ESC, 0); /* ??? */ 331 wsemul_sun_output_normal(edp, ASCII_ESC, 0); /* ??? */
332 newstate = wsemul_sun_output_normal(edp, c, 0); 332 newstate = wsemul_sun_output_normal(edp, c, 0);
333 break; 333 break;
334 } 334 }
335 335
336 return (newstate); 336 return (newstate);
337} 337}
338 338
339static inline void 339static inline void
340wsemul_sun_control(struct wsemul_sun_emuldata *edp, u_char c) 340wsemul_sun_control(struct wsemul_sun_emuldata *edp, u_char c)
341{ 341{
342 u_int n, src, dst; 342 u_int n, src, dst;
343 343
344 switch (c) { 344 switch (c) {
345 case '@': /* "Insert Character (ICH)" */ 345 case '@': /* "Insert Character (ICH)" */
346 n = min(NORMALIZE_ARG(0), COLS_LEFT + 1); 346 n = min(NORMALIZE_ARG(0), COLS_LEFT + 1);
347 src = edp->ccol; 347 src = edp->ccol;
348 dst = edp->ccol + n; 348 dst = edp->ccol + n;
349 if (dst < edp->ncols) { 349 if (dst < edp->ncols) {
350 (*edp->emulops->copycols)(edp->emulcookie, edp->crow, 350 (*edp->emulops->copycols)(edp->emulcookie, edp->crow,
351 src, dst, edp->ncols - dst); 351 src, dst, edp->ncols - dst);
352 } 352 }
353 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow, 353 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
354 src, dst - src, edp->curattr); 354 src, dst - src, edp->curattr);
355 break; 355 break;
356 356
357 case 'A': /* "Cursor Up (CUU)" */ 357 case 'A': /* "Cursor Up (CUU)" */
358 edp->crow -= min(NORMALIZE_ARG(0), edp->crow); 358 edp->crow -= min(NORMALIZE_ARG(0), edp->crow);
359 break; 359 break;
360 360
361 case 'E': /* "Cursor Next Line (CNL)" */ 361 case 'E': /* "Cursor Next Line (CNL)" */
362 edp->ccol = 0; 362 edp->ccol = 0;
363 /* FALLTHRU */ 363 /* FALLTHRU */
364 case 'B': /* "Cursor Down (CUD)" */ 364 case 'B': /* "Cursor Down (CUD)" */
365 edp->crow += min(NORMALIZE_ARG(0), ROWS_LEFT); 365 edp->crow += min(NORMALIZE_ARG(0), ROWS_LEFT);
366 break; 366 break;
367 367
368 case 'C': /* "Cursor Forward (CUF)" */ 368 case 'C': /* "Cursor Forward (CUF)" */
369 edp->ccol += min(NORMALIZE_ARG(0), COLS_LEFT); 369 edp->ccol += min(NORMALIZE_ARG(0), COLS_LEFT);
370 break; 370 break;
371 371
372 case 'D': /* "Cursor Backward (CUB)" */ 372 case 'D': /* "Cursor Backward (CUB)" */
373 edp->ccol -= min(NORMALIZE_ARG(0), edp->ccol); 373 edp->ccol -= min(NORMALIZE_ARG(0), edp->ccol);
374 break; 374 break;
375 375
376 case 'f': /* "Horizontal And Vertical Position (HVP)" */ 376 case 'f': /* "Horizontal And Vertical Position (HVP)" */
377 case 'H': /* "Cursor Position (CUP)" */ 377 case 'H': /* "Cursor Position (CUP)" */
378 edp->crow = min(NORMALIZE_ARG(1), edp->nrows) - 1; 378 edp->crow = min(NORMALIZE_ARG(1), edp->nrows) - 1;
379 edp->ccol = min(NORMALIZE_ARG(0), edp->ncols) - 1; 379 edp->ccol = min(NORMALIZE_ARG(0), edp->ncols) - 1;
380 break; 380 break;
381 381
382 case 'J': /* "Erase in Display (ED)" */ 382 case 'J': /* "Erase in Display (ED)" */
383 if (ROWS_LEFT > 0) { 383 if (ROWS_LEFT > 0) {
384 (*edp->emulops->eraserows)(edp->emulcookie, 384 (*edp->emulops->eraserows)(edp->emulcookie,
385 edp->crow + 1, ROWS_LEFT, edp->curattr); 385 edp->crow + 1, ROWS_LEFT, edp->curattr);
386 } 386 }
387 /* FALLTHRU */ 387 /* FALLTHRU */
388 case 'K': /* "Erase in Line (EL)" */ 388 case 'K': /* "Erase in Line (EL)" */
389 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow, 389 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
390 edp->ccol, COLS_LEFT + 1, edp->curattr); 390 edp->ccol, COLS_LEFT + 1, edp->curattr);
391 break; 391 break;
392 392
393 case 'L': /* "Insert Line (IL)" */ 393 case 'L': /* "Insert Line (IL)" */
394 n = min(NORMALIZE_ARG(0), ROWS_LEFT + 1); 394 n = min(NORMALIZE_ARG(0), ROWS_LEFT + 1);
395 src = edp->crow; 395 src = edp->crow;
396 dst = edp->crow + n; 396 dst = edp->crow + n;
397 if (dst < edp->nrows) { 397 if (dst < edp->nrows) {
398 (*edp->emulops->copyrows)(edp->emulcookie, 398 (*edp->emulops->copyrows)(edp->emulcookie,
399 src, dst, edp->nrows - dst); 399 src, dst, edp->nrows - dst);
400 } 400 }
401 (*edp->emulops->eraserows)(edp->emulcookie, 401 (*edp->emulops->eraserows)(edp->emulcookie,
402 src, dst - src, edp->curattr); 402 src, dst - src, edp->curattr);
403 break; 403 break;
404 404
405 case 'M': /* "Delete Line (DL)" */ 405 case 'M': /* "Delete Line (DL)" */
406 n = min(NORMALIZE_ARG(0), ROWS_LEFT + 1); 406 n = min(NORMALIZE_ARG(0), ROWS_LEFT + 1);
407 src = edp->crow + n; 407 src = edp->crow + n;
408 dst = edp->crow; 408 dst = edp->crow;
409 if (src < edp->nrows) { 409 if (src < edp->nrows) {
410 (*edp->emulops->copyrows)(edp->emulcookie, 410 (*edp->emulops->copyrows)(edp->emulcookie,
411 src, dst, edp->nrows - src); 411 src, dst, edp->nrows - src);
412 } 412 }
413 (*edp->emulops->eraserows)(edp->emulcookie, 413 (*edp->emulops->eraserows)(edp->emulcookie,
414 dst + edp->nrows - src, src - dst, edp->curattr); 414 dst + edp->nrows - src, src - dst, edp->curattr);
415 break; 415 break;
416 416
417 case 'P': /* "Delete Character (DCH)" */ 417 case 'P': /* "Delete Character (DCH)" */
418 n = min(NORMALIZE_ARG(0), COLS_LEFT + 1); 418 n = min(NORMALIZE_ARG(0), COLS_LEFT + 1);
419 src = edp->ccol + n; 419 src = edp->ccol + n;
420 dst = edp->ccol; 420 dst = edp->ccol;
421 if (src < edp->ncols) { 421 if (src < edp->ncols) {
422 (*edp->emulops->copycols)(edp->emulcookie, edp->crow, 422 (*edp->emulops->copycols)(edp->emulcookie, edp->crow,
423 src, dst, edp->ncols - src); 423 src, dst, edp->ncols - src);
424 } 424 }
425 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow, 425 (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
426 dst + edp->ncols - src, src - dst, edp->curattr); 426 dst + edp->ncols - src, src - dst, edp->curattr);
427 break; 427 break;
428 428
429 case 'm': /* "Select Graphic Rendition (SGR)" */ 429 case 'm': /* "Select Graphic Rendition (SGR)" */
430 if (ARG(0)) 430 if (ARG(0))
431 edp->rendflags |= REND_SO; 431 edp->rendflags |= REND_SO;
432 else 432 else
433 edp->rendflags &= ~REND_SO; 433 edp->rendflags &= ~REND_SO;
434 goto setattr; 434 goto setattr;
435 435
436 case 'p': /* "Black On White (SUNBOW)" */ 436 case 'p': /* "Black On White (SUNBOW)" */
437 edp->rendflags |= REND_BOW; 437 edp->rendflags |= REND_BOW;
438 goto setattr; 438 goto setattr;
439 439
440 case 'q': /* "White On Black (SUNWOB)" */ 440 case 'q': /* "White On Black (SUNWOB)" */
441 edp->rendflags &= ~REND_BOW; 441 edp->rendflags &= ~REND_BOW;
442 goto setattr; 442 goto setattr;
443 443
444 case 'r': /* "Set Scrolling (SUNSCRL)" */ 444 case 'r': /* "Set Scrolling (SUNSCRL)" */
445 edp->scrolldist = min(ARG(0), edp->nrows); 445 edp->scrolldist = min(ARG(0), edp->nrows);
446 break; 446 break;
447 447
448 case 's': /* "Reset Terminal Emulator (SUNRESET)" */ 448 case 's': /* "Reset Terminal Emulator (SUNRESET)" */
449 edp->scrolldist = 1; 449 edp->scrolldist = 1;
450 edp->rendflags = 0; 450 edp->rendflags = 0;
451setattr: 451setattr:
452 if (((edp->rendflags & REND_BOW) != 0) ^ 452 if (((edp->rendflags & REND_BOW) != 0) ^
453 ((edp->rendflags & REND_SO) != 0)) 453 ((edp->rendflags & REND_SO) != 0))
454 edp->curattr = edp->bowattr; 454 edp->curattr = edp->bowattr;
455 else 455 else
456 edp->curattr = edp->defattr; 456 edp->curattr = edp->defattr;
457 break; 457 break;
458 } 458 }
459} 459}
460 460
461static inline u_int 461static inline u_int
462wsemul_sun_output_control(struct wsemul_sun_emuldata *edp, u_char c) 462wsemul_sun_output_control(struct wsemul_sun_emuldata *edp, u_char c)
463{ 463{
464 u_int newstate = SUN_EMUL_STATE_CONTROL; 464 u_int newstate = SUN_EMUL_STATE_CONTROL;
465 u_int i; 465 u_int i;
466 466
467 switch (c) { 467 switch (c) {
468 case '0': case '1': case '2': case '3': case '4': /* argument digit */ 468 case '0': case '1': case '2': case '3': case '4': /* argument digit */
469 case '5': case '6': case '7': case '8': case '9': 469 case '5': case '6': case '7': case '8': case '9':
470 edp->args[0] = (edp->args[0] * 10) + (c - '0'); 470 edp->args[0] = (edp->args[0] * 10) + (c - '0');
471 break; 471 break;
472 472
473 case ';': /* argument terminator */ 473 case ';': /* argument terminator */
474 for (i = 1; i < SUN_EMUL_NARGS; i++) 474 for (i = 1; i < SUN_EMUL_NARGS; i++)
475 edp->args[i] = edp->args[i - 1]; 475 edp->args[i] = edp->args[i - 1];
476 edp->args[0] = 0; 476 edp->args[0] = 0;
477 break; 477 break;
478 478
479 default: /* end of escape sequence */ 479 default: /* end of escape sequence */
480 wsemul_sun_control(edp, c); 480 wsemul_sun_control(edp, c);
481 newstate = SUN_EMUL_STATE_NORMAL; 481 newstate = SUN_EMUL_STATE_NORMAL;
482 break; 482 break;
483 } 483 }
484 return (newstate); 484 return (newstate);
485} 485}
486 486
487void 487void
488wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel) 488wsemul_sun_output(void *cookie, const u_char *data, u_int count, int kernel)
489{ 489{
490 struct wsemul_sun_emuldata *edp = cookie; 490 struct wsemul_sun_emuldata *edp = cookie;
491 u_int newstate; 491 u_int newstate;
492 492
493#ifdef DIAGNOSTIC 493#ifdef DIAGNOSTIC
494 if (kernel && !edp->console) 494 if (kernel && !edp->console)
495 panic("wsemul_sun_output: kernel output, not console"); 495 panic("wsemul_sun_output: kernel output, not console");
496#endif 496#endif
497 497
498 /* XXX */ 498 /* XXX */
499 (*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol); 499 (*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol);
500 for (; count > 0; data++, count--) { 500 for (; count > 0; data++, count--) {
501 if (kernel) { 501 if (kernel) {
502 wsemul_sun_output_normal(edp, *data, 1); 502 wsemul_sun_output_normal(edp, *data, 1);
503 continue; 503 continue;
504 } 504 }
505 switch (edp->state) { 505 switch (edp->state) {
506 case SUN_EMUL_STATE_NORMAL: 506 case SUN_EMUL_STATE_NORMAL:
507 /* XXX SCAN INPUT FOR NEWLINES, DO PRESCROLLING */ 507 /* XXX SCAN INPUT FOR NEWLINES, DO PRESCROLLING */
508 newstate = wsemul_sun_output_normal(edp, *data, 0); 508 newstate = wsemul_sun_output_normal(edp, *data, 0);
509 break; 509 break;
510 case SUN_EMUL_STATE_HAVEESC: 510 case SUN_EMUL_STATE_HAVEESC:
511 newstate = wsemul_sun_output_haveesc(edp, *data); 511 newstate = wsemul_sun_output_haveesc(edp, *data);
512 break; 512 break;
513 case SUN_EMUL_STATE_CONTROL: 513 case SUN_EMUL_STATE_CONTROL:
514 newstate = wsemul_sun_output_control(edp, *data); 514 newstate = wsemul_sun_output_control(edp, *data);
515 break; 515 break;
516 default: 516 default:
517#ifdef DIAGNOSTIC 517#ifdef DIAGNOSTIC
518 panic("wsemul_sun: invalid state %d", edp->state); 518 panic("wsemul_sun: invalid state %d", edp->state);
519#endif 519#endif
520 /* try to recover, if things get screwed up... */ 520 /* try to recover, if things get screwed up... */
521 newstate = wsemul_sun_output_normal(edp, *data, 0); 521 newstate = wsemul_sun_output_normal(edp, *data, 0);
522 break; 522 break;
523 } 523 }
524 edp->state = newstate; 524 edp->state = newstate;
525 } 525 }
526 /* XXX */ 526 /* XXX */
527 (*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol); 527 (*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol);
528} 528}
529 529
530static const char *sun_fkeys[] = { 530static const char *sun_fkeys[] = {
531 "\033[224z", /* F1 */ 531 "\033[224z", /* F1 */
532 "\033[225z", 532 "\033[225z",
533 "\033[226z", 533 "\033[226z",
534 "\033[227z", 534 "\033[227z",
535 "\033[228z", 535 "\033[228z",
536 "\033[229z", 536 "\033[229z",
537 "\033[230z", 537 "\033[230z",
538 "\033[231z", 538 "\033[231z",
539 "\033[232z", 539 "\033[232z",
540 "\033[233z", /* F10 */ 540 "\033[233z", /* F10 */
541}; 541};
542 542
543int 543int
544wsemul_sun_translate(void *cookie, keysym_t in, const char **out) 544wsemul_sun_translate(void *cookie, keysym_t in, const char **out)
545{ 545{
546 static char c; 546 static char c;
547 547
548 if (KS_GROUP(in) == KS_GROUP_Plain) { 548 if (KS_GROUP(in) == KS_GROUP_Plain) {
549 /* allow ISO-1 */ 549 /* allow ISO-1 */
550 c = KS_VALUE(in); 550 c = KS_VALUE(in);
551 *out = &c; 551 *out = &c;
552 return (1); 552 return (1);
553 } 553 }
554 554
555 if (KS_GROUP(in) == KS_GROUP_Keypad && (in & 0x80) == 0) { 555 if (KS_GROUP(in) == KS_GROUP_Keypad && (in & 0x80) == 0) {
556 c = in & 0xff; /* turn into ASCII */ 556 c = in & 0xff; /* turn into ASCII */
557 *out = &c; 557 *out = &c;
558 return (1); 558 return (1);
559 } 559 }
560 560
561 if (in >= KS_f1 && in <= KS_f10) { 561 if (in >= KS_f1 && in <= KS_f10) {
562 *out = sun_fkeys[in - KS_f1]; 562 *out = sun_fkeys[in - KS_f1];
563 return (6); 563 return (6);
564 } 564 }
565 if (in >= KS_F1 && in <= KS_F10) { 565 if (in >= KS_F1 && in <= KS_F10) {
566 *out = sun_fkeys[in - KS_F1]; 566 *out = sun_fkeys[in - KS_F1];
567 return (6); 567 return (6);
568 } 568 }
569 if (in >= KS_KP_F1 && in <= KS_KP_F4) { 569 if (in >= KS_KP_F1 && in <= KS_KP_F4) {
570 *out = sun_fkeys[in - KS_KP_F1]; 570 *out = sun_fkeys[in - KS_KP_F1];
571 return (6); 571 return (6);
572 } 572 }
573 573
574 switch (in) { 574 switch (in) {
575 case KS_Home: 575 case KS_Home:
576 case KS_KP_Home: 576 case KS_KP_Home:
577 case KS_KP_Begin: 577 case KS_KP_Begin:
578 *out = "\033[214z"; 578 *out = "\033[214z";
579 return (6); 579 return (6);
580 case KS_End: 580 case KS_End:
581 case KS_KP_End: 581 case KS_KP_End:
582 *out = "\033[220z"; 582 *out = "\033[220z";
583 return (6); 583 return (6);
584 case KS_Prior: 584 case KS_Prior:
585 case KS_KP_Prior: 585 case KS_KP_Prior:
586 *out = "\033[216z"; 586 *out = "\033[216z";
587 return (6); 587 return (6);
588 case KS_Next: 588 case KS_Next:
589 case KS_KP_Next: 589 case KS_KP_Next:
590 *out = "\033[222z"; 590 *out = "\033[222z";
591 return (6); 591 return (6);
592 case KS_Up: 592 case KS_Up:
593 case KS_KP_Up: 593 case KS_KP_Up:
594 *out = "\033[A"; 594 *out = "\033[A";
595 return (3); 595 return (3);
596 case KS_Down: 596 case KS_Down:
597 case KS_KP_Down: 597 case KS_KP_Down:
598 *out = "\033[B"; 598 *out = "\033[B";
599 return (3); 599 return (3);
600 case KS_Left: 600 case KS_Left:
601 case KS_KP_Left: 601 case KS_KP_Left:
602 *out = "\033[D"; 602 *out = "\033[D";
603 return (3); 603 return (3);
604 case KS_Right: 604 case KS_Right:
605 case KS_KP_Right: 605 case KS_KP_Right:
606 *out = "\033[C"; 606 *out = "\033[C";
607 return (3); 607 return (3);
608 case KS_KP_Delete: 608 case KS_KP_Delete:
609 *out = "\177"; 609 *out = "\177";
610 return (1); 610 return (1);
611 } 611 }
612 return (0); 612 return (0);
613} 613}
614 614
615void 615void
616wsemul_sun_detach(void *cookie, u_int *crowp, u_int *ccolp) 616wsemul_sun_detach(void *cookie, u_int *crowp, u_int *ccolp)
617{ 617{
618 struct wsemul_sun_emuldata *edp = cookie; 618 struct wsemul_sun_emuldata *edp = cookie;
619 619
620 *crowp = edp->crow; 620 *crowp = edp->crow;
621 *ccolp = edp->ccol; 621 *ccolp = edp->ccol;
622 if (edp != &wsemul_sun_console_emuldata) 622 if (edp != &wsemul_sun_console_emuldata)
623 free(edp, M_DEVBUF); 623 free(edp, M_DEVBUF);
624} 624}
625 625
626void 626void
627wsemul_sun_resetop(void *cookie, enum wsemul_resetops op) 627wsemul_sun_resetop(void *cookie, enum wsemul_resetops op)
628{ 628{
629 struct wsemul_sun_emuldata *edp = cookie; 629 struct wsemul_sun_emuldata *edp = cookie;
630 630
631 switch (op) { 631 switch (op) {
632 case WSEMUL_RESET: 632 case WSEMUL_RESET:
633 edp->state = SUN_EMUL_STATE_NORMAL; 633 edp->state = SUN_EMUL_STATE_NORMAL;
634 edp->scrolldist = 1; 634 edp->scrolldist = 1;
635 edp->rendflags = 0; 635 edp->rendflags = 0;
636 edp->curattr = edp->defattr; 636 edp->curattr = edp->defattr;
637 break; 637 break;
638 case WSEMUL_CLEARSCREEN: 638 case WSEMUL_CLEARSCREEN:
639 (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows, 639 (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows,
640 edp->defattr); 640 edp->defattr);
641 edp->ccol = edp->crow = 0; 641 edp->ccol = edp->crow = 0;
642 (*edp->emulops->cursor)(edp->emulcookie, 1, 0, 0); 642 (*edp->emulops->cursor)(edp->emulcookie, 1, 0, 0);
643 break; 643 break;
644 default: 644 default:
645 break; 645 break;
646 } 646 }
647} 647}