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