Annotation of sys/dev/wscons/wsemul_sun.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: wsemul_sun.c,v 1.20 2007/02/14 01:12:16 jsg Exp $ */
2: /* $NetBSD: wsemul_sun.c,v 1.11 2000/01/05 11:19:36 drochner Exp $ */
3:
4: /*
5: * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by Christopher G. Demetriou
18: * for the NetBSD Project.
19: * 4. The name of the author may not be used to endorse or promote products
20: * derived from this software without specific prior written permission
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33:
34: /*
35: * This file implements a sun terminal personality for wscons.
36: *
37: * Derived from old rcons code.
38: * Color support from NetBSD's rcons color code, and wsemul_vt100.
39: */
40:
41: #ifndef SMALL_KERNEL
42: #define JUMP_SCROLL
43: #endif
44:
45: #include <sys/param.h>
46: #include <sys/systm.h>
47: #include <sys/time.h>
48: #include <sys/malloc.h>
49: #include <sys/fcntl.h>
50:
51: #include <dev/wscons/wsconsio.h>
52: #include <dev/wscons/wsdisplayvar.h>
53: #include <dev/wscons/wsemulvar.h>
54: #include <dev/wscons/wsksymdef.h>
55: #include <dev/wscons/ascii.h>
56:
57: void *wsemul_sun_cnattach(const struct wsscreen_descr *, void *,
58: int, int, long);
59: void *wsemul_sun_attach(int, const struct wsscreen_descr *,
60: void *, int, int, void *, long);
61: void wsemul_sun_output(void *, const u_char *, u_int, int);
62: int wsemul_sun_translate(void *, keysym_t, char **);
63: void wsemul_sun_detach(void *, u_int *, u_int *);
64: void wsemul_sun_resetop(void *, enum wsemul_resetops);
65:
66: const struct wsemul_ops wsemul_sun_ops = {
67: "sun",
68: wsemul_sun_cnattach,
69: wsemul_sun_attach,
70: wsemul_sun_output,
71: wsemul_sun_translate,
72: wsemul_sun_detach,
73: wsemul_sun_resetop
74: };
75:
76: #define SUN_EMUL_STATE_NORMAL 0 /* normal processing */
77: #define SUN_EMUL_STATE_HAVEESC 1 /* seen start of ctl seq */
78: #define SUN_EMUL_STATE_CONTROL 2 /* processing ctl seq */
79:
80: #define SUN_EMUL_NARGS 2 /* max # of args to a command */
81:
82: struct wsemul_sun_emuldata {
83: const struct wsdisplay_emulops *emulops;
84: void *emulcookie;
85: void *cbcookie;
86: int scrcapabilities;
87: u_int nrows, ncols, crow, ccol;
88: long defattr; /* default attribute (rendition) */
89:
90: u_int state; /* processing state */
91: u_int args[SUN_EMUL_NARGS]; /* command args, if CONTROL */
92: int nargs; /* number of args */
93:
94: u_int scrolldist; /* distance to scroll */
95: long curattr, bkgdattr; /* currently used attribute */
96: long kernattr; /* attribute for kernel output */
97: int attrflags, fgcol, bgcol; /* properties of curattr */
98:
99: #ifdef DIAGNOSTIC
100: int console;
101: #endif
102: };
103:
104: void wsemul_sun_init(struct wsemul_sun_emuldata *,
105: const struct wsscreen_descr *, void *, int, int, long);
106: void wsemul_sun_reset(struct wsemul_sun_emuldata *);
107: void wsemul_sun_output_lowchars(struct wsemul_sun_emuldata *, u_char, int);
108: void wsemul_sun_output_normal(struct wsemul_sun_emuldata *, u_char, int);
109: u_int wsemul_sun_output_haveesc(struct wsemul_sun_emuldata *, u_char);
110: u_int wsemul_sun_output_control(struct wsemul_sun_emuldata *, u_char);
111: void wsemul_sun_control(struct wsemul_sun_emuldata *, u_char);
112: int wsemul_sun_selectattribute(struct wsemul_sun_emuldata *, int, int, int,
113: long *, long *);
114: void wsemul_sun_scrollup(struct wsemul_sun_emuldata *, u_int);
115:
116: struct wsemul_sun_emuldata wsemul_sun_console_emuldata;
117:
118: /* some useful utility macros */
119: #define ARG(n,c) \
120: ((n) >= edp->nargs ? 0 : edp->args[(n) + MAX(0, edp->nargs - (c))])
121: #define NORMALIZE(arg) ((arg) != 0 ? (arg) : 1)
122: #define COLS_LEFT (edp->ncols - 1 - edp->ccol)
123: #define ROWS_LEFT (edp->nrows - 1 - edp->crow)
124:
125: void
126: wsemul_sun_init(edp, type, cookie, ccol, crow, defattr)
127: struct wsemul_sun_emuldata *edp;
128: const struct wsscreen_descr *type;
129: void *cookie;
130: int ccol, crow;
131: long defattr;
132: {
133: edp->emulops = type->textops;
134: edp->emulcookie = cookie;
135: edp->scrcapabilities = type->capabilities;
136: edp->nrows = type->nrows;
137: edp->ncols = type->ncols;
138: edp->crow = crow;
139: edp->ccol = ccol;
140: edp->defattr = defattr;
141: }
142:
143: void
144: wsemul_sun_reset(edp)
145: struct wsemul_sun_emuldata *edp;
146: {
147: edp->state = SUN_EMUL_STATE_NORMAL;
148: edp->bkgdattr = edp->curattr = edp->defattr;
149: edp->attrflags = 0;
150: edp->fgcol = WSCOL_BLACK;
151: edp->bgcol = WSCOL_WHITE;
152: edp->scrolldist = 1;
153: }
154:
155: void *
156: wsemul_sun_cnattach(type, cookie, ccol, crow, defattr)
157: const struct wsscreen_descr *type;
158: void *cookie;
159: int ccol, crow;
160: long defattr;
161: {
162: struct wsemul_sun_emuldata *edp;
163: int res;
164:
165: edp = &wsemul_sun_console_emuldata;
166: wsemul_sun_init(edp, type, cookie, ccol, crow, defattr);
167:
168: #ifndef WS_KERNEL_FG
169: #define WS_KERNEL_FG WSCOL_BLACK
170: #endif
171: #ifndef WS_KERNEL_BG
172: #define WS_KERNEL_BG WSCOL_WHITE
173: #endif
174: #ifndef WS_KERNEL_COLATTR
175: #define WS_KERNEL_COLATTR 0
176: #endif
177: #ifndef WS_KERNEL_MONOATTR
178: #define WS_KERNEL_MONOATTR 0
179: #endif
180: if (type->capabilities & WSSCREEN_WSCOLORS)
181: res = (*edp->emulops->alloc_attr)(cookie,
182: WS_KERNEL_FG, WS_KERNEL_BG,
183: WS_KERNEL_COLATTR | WSATTR_WSCOLORS,
184: &edp->kernattr);
185: else
186: res = (*edp->emulops->alloc_attr)(cookie, 0, 0,
187: WS_KERNEL_MONOATTR,
188: &edp->kernattr);
189: if (res)
190: edp->kernattr = defattr;
191:
192: edp->cbcookie = NULL;
193:
194: #ifdef DIAGNOSTIC
195: edp->console = 1;
196: #endif
197:
198: wsemul_sun_reset(edp);
199: return (edp);
200: }
201:
202: void *
203: wsemul_sun_attach(console, type, cookie, ccol, crow, cbcookie, defattr)
204: int console;
205: const struct wsscreen_descr *type;
206: void *cookie;
207: int ccol, crow;
208: void *cbcookie;
209: long defattr;
210: {
211: struct wsemul_sun_emuldata *edp;
212:
213: if (console) {
214: edp = &wsemul_sun_console_emuldata;
215: #ifdef DIAGNOSTIC
216: KASSERT(edp->console == 1);
217: #endif
218: } else {
219: edp = malloc(sizeof *edp, M_DEVBUF, M_NOWAIT);
220: if (edp == NULL)
221: return (NULL);
222: wsemul_sun_init(edp, type, cookie, ccol, crow, defattr);
223:
224: #ifdef DIAGNOSTIC
225: edp->console = 0;
226: #endif
227: }
228:
229: edp->cbcookie = cbcookie;
230:
231: wsemul_sun_reset(edp);
232: return (edp);
233: }
234:
235: void
236: wsemul_sun_output_lowchars(edp, c, kernel)
237: struct wsemul_sun_emuldata *edp;
238: u_char c;
239: int kernel;
240: {
241: u_int n;
242:
243: switch (c) {
244: case ASCII_NUL:
245: default:
246: /* ignore */
247: break;
248:
249: case ASCII_BEL: /* "Bell (BEL)" */
250: wsdisplay_emulbell(edp->cbcookie);
251: break;
252:
253: case ASCII_BS: /* "Backspace (BS)" */
254: if (edp->ccol > 0)
255: edp->ccol--;
256: break;
257:
258: case ASCII_CR: /* "Return (CR)" */
259: edp->ccol = 0;
260: break;
261:
262: case ASCII_HT: /* "Tab (TAB)" */
263: n = min(8 - (edp->ccol & 7), COLS_LEFT);
264: if (n != 0) {
265: (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
266: edp->ccol, n,
267: kernel ? edp->kernattr : edp->bkgdattr);
268: edp->ccol += n;
269: }
270: break;
271:
272: case ASCII_FF: /* "Form Feed (FF)" */
273: (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows,
274: edp->bkgdattr);
275: edp->ccol = edp->crow = 0;
276: break;
277:
278: case ASCII_VT: /* "Reverse Line Feed" */
279: if (edp->crow > 0)
280: edp->crow--;
281: break;
282:
283: case ASCII_ESC: /* "Escape (ESC)" */
284: if (kernel) {
285: printf("wsemul_sun_output_lowchars: ESC in kernel "
286: "output ignored\n");
287: break; /* ignore the ESC */
288: }
289:
290: edp->state = SUN_EMUL_STATE_HAVEESC;
291: break;
292:
293: case ASCII_LF: /* "Line Feed (LF)" */
294: /* if the cur line isn't the last, incr and leave. */
295: if (ROWS_LEFT > 0)
296: edp->crow++;
297: else
298: wsemul_sun_scrollup(edp, edp->scrolldist);
299: break;
300: }
301: }
302:
303: void
304: wsemul_sun_output_normal(edp, c, kernel)
305: struct wsemul_sun_emuldata *edp;
306: u_char c;
307: int kernel;
308: {
309:
310: (*edp->emulops->putchar)(edp->emulcookie, edp->crow, edp->ccol,
311: c, kernel ? edp->kernattr : edp->curattr);
312:
313: if (++edp->ccol >= edp->ncols) {
314: /* if the cur line isn't the last, incr and leave. */
315: if (ROWS_LEFT > 0)
316: edp->crow++;
317: else
318: wsemul_sun_scrollup(edp, edp->scrolldist);
319: edp->ccol = 0;
320: }
321: }
322:
323: u_int
324: wsemul_sun_output_haveesc(edp, c)
325: struct wsemul_sun_emuldata *edp;
326: u_char c;
327: {
328: u_int newstate;
329:
330: switch (c) {
331: case '[': /* continuation of multi-char sequence */
332: edp->nargs = 0;
333: bzero(edp->args, sizeof (edp->args));
334: newstate = SUN_EMUL_STATE_CONTROL;
335: break;
336:
337: default:
338: #ifdef DEBUG
339: printf("ESC%c unknown\n", c);
340: #endif
341: newstate = SUN_EMUL_STATE_NORMAL; /* XXX is this wise? */
342: break;
343: }
344:
345: return (newstate);
346: }
347:
348: void
349: wsemul_sun_control(edp, c)
350: struct wsemul_sun_emuldata *edp;
351: u_char c;
352: {
353: u_int n, src, dst;
354: int flags, fgcol, bgcol;
355: long attr, bkgdattr;
356:
357: switch (c) {
358: case '@': /* "Insert Character (ICH)" */
359: n = min(NORMALIZE(ARG(0,1)), COLS_LEFT + 1);
360: src = edp->ccol;
361: dst = edp->ccol + n;
362: if (dst < edp->ncols) {
363: (*edp->emulops->copycols)(edp->emulcookie, edp->crow,
364: src, dst, edp->ncols - dst);
365: }
366: (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
367: src, n, edp->bkgdattr);
368: break;
369:
370: case 'A': /* "Cursor Up (CUU)" */
371: edp->crow -= min(NORMALIZE(ARG(0,1)), edp->crow);
372: break;
373:
374: case 'E': /* "Cursor Next Line (CNL)" */
375: edp->ccol = 0;
376: /* FALLTHROUGH */
377: case 'B': /* "Cursor Down (CUD)" */
378: edp->crow += min(NORMALIZE(ARG(0,1)), ROWS_LEFT);
379: break;
380:
381: case 'C': /* "Cursor Forward (CUF)" */
382: edp->ccol += min(NORMALIZE(ARG(0,1)), COLS_LEFT);
383: break;
384:
385: case 'D': /* "Cursor Backward (CUB)" */
386: edp->ccol -= min(NORMALIZE(ARG(0,1)), edp->ccol);
387: break;
388:
389: case 'f': /* "Horizontal And Vertical Position (HVP)" */
390: case 'H': /* "Cursor Position (CUP)" */
391: edp->crow = min(NORMALIZE(ARG(0,2)), edp->nrows) - 1;
392: edp->ccol = min(NORMALIZE(ARG(1,2)), edp->ncols) - 1;
393: break;
394:
395: case 'J': /* "Erase in Display (ED)" */
396: if (ROWS_LEFT > 0) {
397: (*edp->emulops->eraserows)(edp->emulcookie,
398: edp->crow + 1, ROWS_LEFT, edp->bkgdattr);
399: }
400: /* FALLTHROUGH */
401: case 'K': /* "Erase in Line (EL)" */
402: (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
403: edp->ccol, COLS_LEFT + 1, edp->bkgdattr);
404: break;
405:
406: case 'L': /* "Insert Line (IL)" */
407: n = min(NORMALIZE(ARG(0,1)), ROWS_LEFT + 1);
408: src = edp->crow;
409: dst = edp->crow + n;
410: if (dst < edp->nrows) {
411: (*edp->emulops->copyrows)(edp->emulcookie,
412: src, dst, edp->nrows - dst);
413: }
414: (*edp->emulops->eraserows)(edp->emulcookie,
415: src, n, edp->bkgdattr);
416: break;
417:
418: case 'M': /* "Delete Line (DL)" */
419: n = min(NORMALIZE(ARG(0,1)), ROWS_LEFT + 1);
420: src = edp->crow + n;
421: dst = edp->crow;
422: if (src < edp->nrows) {
423: (*edp->emulops->copyrows)(edp->emulcookie,
424: src, dst, edp->nrows - src);
425: }
426: (*edp->emulops->eraserows)(edp->emulcookie,
427: dst + edp->nrows - src, n, edp->bkgdattr);
428: break;
429:
430: case 'P': /* "Delete Character (DCH)" */
431: n = min(NORMALIZE(ARG(0,1)), COLS_LEFT + 1);
432: src = edp->ccol + n;
433: dst = edp->ccol;
434: if (src < edp->ncols) {
435: (*edp->emulops->copycols)(edp->emulcookie, edp->crow,
436: src, dst, edp->ncols - src);
437: }
438: (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
439: edp->ncols - n, n, edp->bkgdattr);
440: break;
441:
442: case 'm': /* "Select Graphic Rendition (SGR)" */
443: flags = edp->attrflags;
444: fgcol = edp->fgcol;
445: bgcol = edp->bgcol;
446:
447: for (n = 0; n < edp->nargs; n++) {
448: switch (ARG(n,edp->nargs)) {
449: /* Clear all attributes || End underline */
450: case 0:
451: if (n == edp->nargs - 1) {
452: edp->bkgdattr =
453: edp->curattr = edp->defattr;
454: edp->attrflags = 0;
455: edp->fgcol = WSCOL_BLACK;
456: edp->bgcol = WSCOL_WHITE;
457: return;
458: }
459: flags = 0;
460: fgcol = WSCOL_BLACK;
461: bgcol = WSCOL_WHITE;
462: break;
463: /* Begin bold */
464: case 1:
465: flags |= WSATTR_HILIT;
466: break;
467: /* Begin underline */
468: case 4:
469: flags |= WSATTR_UNDERLINE;
470: break;
471: /* Begin reverse */
472: case 7:
473: flags |= WSATTR_REVERSE;
474: break;
475: /* ANSI foreground color */
476: case 30: case 31: case 32: case 33:
477: case 34: case 35: case 36: case 37:
478: fgcol = ARG(n,edp->nargs) - 30;
479: break;
480: /* ANSI background color */
481: case 40: case 41: case 42: case 43:
482: case 44: case 45: case 46: case 47:
483: bgcol = ARG(n,edp->nargs) - 40;
484: break;
485: }
486: }
487: setattr:
488: if (wsemul_sun_selectattribute(edp, flags, fgcol, bgcol, &attr,
489: &bkgdattr)) {
490: #ifdef DEBUG
491: printf("error allocating attr %d/%d/%x\n",
492: fgcol, bgcol, flags);
493: #endif
494: } else {
495: edp->curattr = attr;
496: edp->bkgdattr = bkgdattr;
497: edp->attrflags = flags;
498: edp->fgcol = fgcol;
499: edp->bgcol = bgcol;
500: }
501: break;
502:
503: case 'p': /* "Black On White (SUNBOW)" */
504: flags = 0;
505: fgcol = WSCOL_BLACK;
506: bgcol = WSCOL_WHITE;
507: goto setattr;
508:
509: case 'q': /* "White On Black (SUNWOB)" */
510: flags = 0;
511: fgcol = WSCOL_WHITE;
512: bgcol = WSCOL_BLACK;
513: goto setattr;
514:
515: case 'r': /* "Set Scrolling (SUNSCRL)" */
516: edp->scrolldist = min(ARG(0,1), edp->nrows);
517: break;
518:
519: case 's': /* "Reset Terminal Emulator (SUNRESET)" */
520: wsemul_sun_reset(edp);
521: break;
522: }
523: }
524:
525: u_int
526: wsemul_sun_output_control(edp, c)
527: struct wsemul_sun_emuldata *edp;
528: u_char c;
529: {
530: u_int newstate = SUN_EMUL_STATE_CONTROL;
531:
532: switch (c) {
533: case '0': case '1': case '2': case '3': case '4': /* argument digit */
534: case '5': case '6': case '7': case '8': case '9':
535: /*
536: * If we receive more arguments than we are expecting,
537: * discard the earliest arguments.
538: */
539: if (edp->nargs > SUN_EMUL_NARGS - 1) {
540: bcopy(edp->args + 1, edp->args,
541: (SUN_EMUL_NARGS - 1) * sizeof(edp->args[0]));
542: edp->args[edp->nargs = SUN_EMUL_NARGS - 1] = 0;
543: }
544: edp->args[edp->nargs] = (edp->args[edp->nargs] * 10) +
545: (c - '0');
546: break;
547:
548: case ';': /* argument terminator */
549: edp->nargs++;
550: break;
551:
552: default: /* end of escape sequence */
553: edp->nargs++;
554: if (edp->nargs > SUN_EMUL_NARGS)
555: edp->nargs = SUN_EMUL_NARGS;
556: wsemul_sun_control(edp, c);
557: newstate = SUN_EMUL_STATE_NORMAL;
558: break;
559: }
560: return (newstate);
561: }
562:
563: void
564: wsemul_sun_output(cookie, data, count, kernel)
565: void *cookie;
566: const u_char *data;
567: u_int count;
568: int kernel;
569: {
570: struct wsemul_sun_emuldata *edp = cookie;
571: u_int newstate;
572: #ifdef JUMP_SCROLL
573: const u_char *eot;
574: u_char curchar;
575: u_int cnt, pos, lines;
576: #endif
577:
578: #ifdef DIAGNOSTIC
579: if (kernel && !edp->console)
580: panic("wsemul_sun_output: kernel output, not console");
581: #endif
582:
583: /* XXX */
584: (*edp->emulops->cursor)(edp->emulcookie, 0, edp->crow, edp->ccol);
585:
586: for (; count > 0; data++, count--) {
587: #ifdef JUMP_SCROLL
588: /*
589: * If scrolling is not disabled and we are the bottom of
590: * the screen, count newlines until an escape sequence
591: * appears.
592: */
593: if ((edp->state == SUN_EMUL_STATE_NORMAL || kernel) &&
594: ROWS_LEFT == 0 && edp->scrolldist != 0) {
595: lines = 0;
596: pos = edp->ccol;
597: for (eot = data, cnt = count; cnt != 0; eot++, cnt--) {
598: curchar = *eot;
599: if (curchar == ASCII_FF ||
600: curchar == ASCII_VT || curchar == ASCII_ESC)
601: break;
602:
603: switch (curchar) {
604: case ASCII_BS:
605: if (pos > 0)
606: pos--;
607: break;
608: case ASCII_CR:
609: pos = 0;
610: break;
611: case ASCII_HT:
612: pos = (pos + 7) & ~7;
613: if (pos >= edp->ncols)
614: pos = edp->ncols - 1;
615: break;
616: default:
617: if (++pos >= edp->ncols) {
618: pos = 0;
619: curchar = ASCII_LF;
620: }
621: break;
622: }
623: if (curchar == ASCII_LF) {
624: if (++lines >= edp->nrows - 1)
625: break;
626: }
627: }
628:
629: if (lines > 1) {
630: wsemul_sun_scrollup(edp, lines);
631: edp->crow--;
632: }
633: }
634: #endif
635:
636: if (*data < ' ') {
637: wsemul_sun_output_lowchars(edp, *data, kernel);
638: continue;
639: }
640:
641: if (kernel) {
642: wsemul_sun_output_normal(edp, *data, 1);
643: continue;
644: }
645:
646: switch (newstate = edp->state) {
647: case SUN_EMUL_STATE_NORMAL:
648: wsemul_sun_output_normal(edp, *data, 0);
649: break;
650: case SUN_EMUL_STATE_HAVEESC:
651: newstate = wsemul_sun_output_haveesc(edp, *data);
652: break;
653: case SUN_EMUL_STATE_CONTROL:
654: newstate = wsemul_sun_output_control(edp, *data);
655: break;
656: default:
657: #ifdef DIAGNOSTIC
658: panic("wsemul_sun: invalid state %d", edp->state);
659: #else
660: /* try to recover, if things get screwed up... */
661: newstate = SUN_EMUL_STATE_NORMAL;
662: wsemul_sun_output_normal(edp, *data, 0);
663: #endif
664: break;
665: }
666: edp->state = newstate;
667: }
668: /* XXX */
669: (*edp->emulops->cursor)(edp->emulcookie, 1, edp->crow, edp->ccol);
670: }
671:
672:
673: /*
674: * Get an attribute from the graphics driver.
675: * Try to find replacements if the desired appearance is not supported.
676: */
677: int
678: wsemul_sun_selectattribute(edp, flags, fgcol, bgcol, attr, bkgdattr)
679: struct wsemul_sun_emuldata *edp;
680: int flags, fgcol, bgcol;
681: long *attr, *bkgdattr;
682: {
683: int error;
684:
685: /*
686: * Rasops will force white on black as normal output colors, unless
687: * WSATTR_WSCOLORS is specified. Since Sun console is black on white,
688: * always use WSATTR_WSCOLORS and our colors, as we know better.
689: */
690: if (!(edp->scrcapabilities & WSSCREEN_WSCOLORS)) {
691: flags &= ~WSATTR_WSCOLORS;
692: } else {
693: flags |= WSATTR_WSCOLORS;
694: }
695:
696: error = (*edp->emulops->alloc_attr)(edp->emulcookie, fgcol, bgcol,
697: flags & WSATTR_WSCOLORS, bkgdattr);
698: if (error)
699: return (error);
700:
701: if ((flags & WSATTR_HILIT) &&
702: !(edp->scrcapabilities & WSSCREEN_HILIT)) {
703: flags &= ~WSATTR_HILIT;
704: if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
705: fgcol = WSCOL_RED;
706: flags |= WSATTR_WSCOLORS;
707: }
708: }
709: if ((flags & WSATTR_UNDERLINE) &&
710: !(edp->scrcapabilities & WSSCREEN_UNDERLINE)) {
711: flags &= ~WSATTR_UNDERLINE;
712: if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
713: fgcol = WSCOL_CYAN;
714: flags &= ~WSATTR_UNDERLINE;
715: flags |= WSATTR_WSCOLORS;
716: }
717: }
718: if ((flags & WSATTR_BLINK) &&
719: !(edp->scrcapabilities & WSSCREEN_BLINK)) {
720: flags &= ~WSATTR_BLINK;
721: }
722: if ((flags & WSATTR_REVERSE) &&
723: !(edp->scrcapabilities & WSSCREEN_REVERSE)) {
724: flags &= ~WSATTR_REVERSE;
725: if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
726: int help;
727: help = bgcol;
728: bgcol = fgcol;
729: fgcol = help;
730: flags |= WSATTR_WSCOLORS;
731: }
732: }
733: error = (*edp->emulops->alloc_attr)(edp->emulcookie, fgcol, bgcol,
734: flags, attr);
735: if (error)
736: return (error);
737:
738: return (0);
739: }
740:
741: static char *sun_fkeys[] = {
742: "\033[224z", /* F1 */
743: "\033[225z",
744: "\033[226z",
745: "\033[227z",
746: "\033[228z",
747: "\033[229z",
748: "\033[230z",
749: "\033[231z",
750: "\033[232z",
751: "\033[233z",
752: "\033[234z",
753: "\033[235z", /* F12 */
754: };
755:
756: static char *sun_lkeys[] = {
757: "\033[207z", /* KS_Help */
758: NULL, /* KS_Execute */
759: "\033[200z", /* KS_Find */
760: NULL, /* KS_Select */
761: "\033[193z", /* KS_Again */
762: "\033[194z", /* KS_Props */
763: "\033[195z", /* KS_Undo */
764: "\033[196z", /* KS_Front */
765: "\033[197z", /* KS_Copy */
766: "\033[198z", /* KS_Open */
767: "\033[199z", /* KS_Paste */
768: "\033[201z", /* KS_Cut */
769: };
770:
771: int
772: wsemul_sun_translate(cookie, in, out)
773: void *cookie;
774: keysym_t in;
775: char **out;
776: {
777: static char c;
778:
779: if (KS_GROUP(in) == KS_GROUP_Keypad && (in & 0x80) == 0) {
780: c = in & 0xff; /* turn into ASCII */
781: *out = &c;
782: return (1);
783: }
784:
785: if (in >= KS_f1 && in <= KS_f12) {
786: *out = sun_fkeys[in - KS_f1];
787: return (6);
788: }
789: if (in >= KS_F1 && in <= KS_F12) {
790: *out = sun_fkeys[in - KS_F1];
791: return (6);
792: }
793: if (in >= KS_KP_F1 && in <= KS_KP_F4) {
794: *out = sun_fkeys[in - KS_KP_F1];
795: return (6);
796: }
797: if (in >= KS_Help && in <= KS_Cut && sun_lkeys[in - KS_Help] != NULL) {
798: *out = sun_lkeys[in - KS_Help];
799: return (6);
800: }
801:
802: switch (in) {
803: case KS_Home:
804: case KS_KP_Home:
805: case KS_KP_Begin:
806: *out = "\033[214z";
807: return (6);
808: case KS_End:
809: case KS_KP_End:
810: *out = "\033[220z";
811: return (6);
812: case KS_Insert:
813: case KS_KP_Insert:
814: *out = "\033[247z";
815: return (6);
816: case KS_Prior:
817: case KS_KP_Prior:
818: *out = "\033[216z";
819: return (6);
820: case KS_Next:
821: case KS_KP_Next:
822: *out = "\033[222z";
823: return (6);
824: case KS_Up:
825: case KS_KP_Up:
826: *out = "\033[A";
827: return (3);
828: case KS_Down:
829: case KS_KP_Down:
830: *out = "\033[B";
831: return (3);
832: case KS_Left:
833: case KS_KP_Left:
834: *out = "\033[D";
835: return (3);
836: case KS_Right:
837: case KS_KP_Right:
838: *out = "\033[C";
839: return (3);
840: case KS_KP_Delete:
841: *out = "\177";
842: return (1);
843: }
844: return (0);
845: }
846:
847: void
848: wsemul_sun_detach(cookie, crowp, ccolp)
849: void *cookie;
850: u_int *crowp, *ccolp;
851: {
852: struct wsemul_sun_emuldata *edp = cookie;
853:
854: *crowp = edp->crow;
855: *ccolp = edp->ccol;
856: if (edp != &wsemul_sun_console_emuldata)
857: free(edp, M_DEVBUF);
858: }
859:
860: void
861: wsemul_sun_resetop(cookie, op)
862: void *cookie;
863: enum wsemul_resetops op;
864: {
865: struct wsemul_sun_emuldata *edp = cookie;
866:
867: switch (op) {
868: case WSEMUL_RESET:
869: wsemul_sun_reset(edp);
870: break;
871: case WSEMUL_CLEARSCREEN:
872: (*edp->emulops->eraserows)(edp->emulcookie, 0, edp->nrows,
873: edp->bkgdattr);
874: edp->ccol = edp->crow = 0;
875: (*edp->emulops->cursor)(edp->emulcookie, 1, 0, 0);
876: break;
877: default:
878: break;
879: }
880: }
881:
882: void
883: wsemul_sun_scrollup(edp, lines)
884: struct wsemul_sun_emuldata *edp;
885: u_int lines;
886: {
887: /*
888: * if we're in wrap-around mode, go to the first
889: * line and clear it.
890: */
891: if (lines == 0) {
892: edp->crow = 0;
893: (*edp->emulops->eraserows)(edp->emulcookie, 0, 1,
894: edp->bkgdattr);
895: return;
896: }
897:
898: /*
899: * If the scrolling distance is equal to the screen height
900: * (usually 34), clear the screen; otherwise, scroll by the
901: * scrolling distance.
902: */
903: if (lines < edp->nrows)
904: (*edp->emulops->copyrows)(edp->emulcookie, lines, 0,
905: edp->nrows - lines);
906: (*edp->emulops->eraserows)(edp->emulcookie,
907: edp->nrows - lines, lines, edp->bkgdattr);
908: edp->crow -= lines - 1;
909: }
CVSweb