Annotation of sys/dev/wscons/wsemul_vt100_subr.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: wsemul_vt100_subr.c,v 1.14 2007/01/07 13:31:36 miod Exp $ */
2: /* $NetBSD: wsemul_vt100_subr.c,v 1.7 2000/04/28 21:56:16 mycroft Exp $ */
3:
4: /*
5: * Copyright (c) 1998
6: * Matthias Drochner. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27: *
28: */
29:
30: #include <sys/param.h>
31: #include <sys/systm.h>
32:
33: #include <dev/wscons/wsconsio.h>
34: #include <dev/wscons/wsksymvar.h>
35: #include <dev/wscons/wsdisplayvar.h>
36: #include <dev/wscons/wsemulvar.h>
37: #include <dev/wscons/wsemul_vt100var.h>
38:
39: int vt100_selectattribute(struct wsemul_vt100_emuldata *, int, int, int,
40: long *, long *);
41: int vt100_ansimode(struct wsemul_vt100_emuldata *, int, int);
42: int vt100_decmode(struct wsemul_vt100_emuldata *, int, int);
43: #define VTMODE_SET 33
44: #define VTMODE_RESET 44
45: #define VTMODE_REPORT 55
46:
47: /*
48: * scroll up within scrolling region
49: */
50: void
51: wsemul_vt100_scrollup(edp, n)
52: struct wsemul_vt100_emuldata *edp;
53: int n;
54: {
55: int help;
56:
57: if (n > edp->scrreg_nrows)
58: n = edp->scrreg_nrows;
59:
60: help = edp->scrreg_nrows - n;
61: if (help > 0) {
62: (*edp->emulops->copyrows)(edp->emulcookie,
63: edp->scrreg_startrow + n,
64: edp->scrreg_startrow,
65: help);
66: if (edp->dblwid) /* XXX OVERLAPS */
67: bcopy(&edp->dblwid[edp->scrreg_startrow + n],
68: &edp->dblwid[edp->scrreg_startrow],
69: help);
70: }
71: (*edp->emulops->eraserows)(edp->emulcookie,
72: edp->scrreg_startrow + help, n,
73: edp->bkgdattr);
74: if (edp->dblwid)
75: memset(&edp->dblwid[edp->scrreg_startrow + help], 0, n);
76: CHECK_DW;
77: }
78:
79: /*
80: * scroll down within scrolling region
81: */
82: void
83: wsemul_vt100_scrolldown(edp, n)
84: struct wsemul_vt100_emuldata *edp;
85: int n;
86: {
87: int help;
88:
89: if (n > edp->scrreg_nrows)
90: n = edp->scrreg_nrows;
91:
92: help = edp->scrreg_nrows - n;
93: if (help > 0) {
94: (*edp->emulops->copyrows)(edp->emulcookie,
95: edp->scrreg_startrow,
96: edp->scrreg_startrow + n,
97: help);
98: if (edp->dblwid) /* XXX OVERLAPS */
99: bcopy(&edp->dblwid[edp->scrreg_startrow],
100: &edp->dblwid[edp->scrreg_startrow + n],
101: help);
102: }
103: (*edp->emulops->eraserows)(edp->emulcookie,
104: edp->scrreg_startrow, n,
105: edp->bkgdattr);
106: if (edp->dblwid)
107: memset(&edp->dblwid[edp->scrreg_startrow], 0, n);
108: CHECK_DW;
109: }
110:
111: /*
112: * erase in display
113: */
114: void
115: wsemul_vt100_ed(edp, arg)
116: struct wsemul_vt100_emuldata *edp;
117: int arg;
118: {
119: int n;
120:
121: switch (arg) {
122: case 0: /* cursor to end */
123: ERASECOLS(edp->ccol, COLS_LEFT + 1, edp->bkgdattr);
124: n = edp->nrows - edp->crow - 1;
125: if (n > 0) {
126: (*edp->emulops->eraserows)(edp->emulcookie,
127: edp->crow + 1, n,
128: edp->bkgdattr);
129: if (edp->dblwid)
130: memset(&edp->dblwid[edp->crow + 1], 0, n);
131: }
132: break;
133: case 1: /* beginning to cursor */
134: if (edp->crow > 0) {
135: (*edp->emulops->eraserows)(edp->emulcookie,
136: 0, edp->crow,
137: edp->bkgdattr);
138: if (edp->dblwid)
139: memset(&edp->dblwid[0], 0, edp->crow);
140: }
141: ERASECOLS(0, edp->ccol + 1, edp->bkgdattr);
142: break;
143: case 2: /* complete display */
144: (*edp->emulops->eraserows)(edp->emulcookie,
145: 0, edp->nrows,
146: edp->bkgdattr);
147: if (edp->dblwid)
148: memset(&edp->dblwid[0], 0, edp->nrows);
149: break;
150: default:
151: #ifdef VT100_PRINTUNKNOWN
152: printf("ed(%d) unknown\n", arg);
153: #endif
154: break;
155: }
156: CHECK_DW;
157: }
158:
159: /*
160: * erase in line
161: */
162: void
163: wsemul_vt100_el(edp, arg)
164: struct wsemul_vt100_emuldata *edp;
165: int arg;
166: {
167: switch (arg) {
168: case 0: /* cursor to end */
169: ERASECOLS(edp->ccol, COLS_LEFT + 1, edp->bkgdattr);
170: break;
171: case 1: /* beginning to cursor */
172: ERASECOLS(0, edp->ccol + 1, edp->bkgdattr);
173: break;
174: case 2: /* complete line */
175: (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
176: 0, edp->ncols,
177: edp->bkgdattr);
178: break;
179: default:
180: #ifdef VT100_PRINTUNKNOWN
181: printf("el(%d) unknown\n", arg);
182: #endif
183: break;
184: }
185: }
186:
187: /*
188: * handle commands after CSI (ESC[)
189: */
190: void
191: wsemul_vt100_handle_csi(edp, c)
192: struct wsemul_vt100_emuldata *edp;
193: u_char c;
194: {
195: int n, help, flags, fgcol, bgcol;
196: long attr, bkgdattr;
197:
198: #define A3(a, b, c) (((a) << 16) | ((b) << 8) | (c))
199: switch (A3(edp->modif1, edp->modif2, c)) {
200: case A3('>', '\0', 'c'): /* DA secondary */
201: wsdisplay_emulinput(edp->cbcookie, WSEMUL_VT_ID2,
202: sizeof(WSEMUL_VT_ID2));
203: break;
204:
205: case A3('\0', '\0', 'J'): /* ED selective erase in display */
206: case A3('?', '\0', 'J'): /* DECSED selective erase in display */
207: wsemul_vt100_ed(edp, ARG(0));
208: break;
209: case A3('\0', '\0', 'K'): /* EL selective erase in line */
210: case A3('?', '\0', 'K'): /* DECSEL selective erase in line */
211: wsemul_vt100_el(edp, ARG(0));
212: break;
213: case A3('\0', '\0', 'h'): /* SM */
214: for (n = 0; n < edp->nargs; n++)
215: vt100_ansimode(edp, ARG(n), VTMODE_SET);
216: break;
217: case A3('?', '\0', 'h'): /* DECSM */
218: for (n = 0; n < edp->nargs; n++)
219: vt100_decmode(edp, ARG(n), VTMODE_SET);
220: break;
221: case A3('\0', '\0', 'l'): /* RM */
222: for (n = 0; n < edp->nargs; n++)
223: vt100_ansimode(edp, ARG(n), VTMODE_RESET);
224: break;
225: case A3('?', '\0', 'l'): /* DECRM */
226: for (n = 0; n < edp->nargs; n++)
227: vt100_decmode(edp, ARG(n), VTMODE_RESET);
228: break;
229: case A3('\0', '$', 'p'): /* DECRQM request mode ANSI */
230: vt100_ansimode(edp, ARG(0), VTMODE_REPORT);
231: break;
232: case A3('?', '$', 'p'): /* DECRQM request mode DEC */
233: vt100_decmode(edp, ARG(0), VTMODE_REPORT);
234: break;
235: case A3('\0', '\0', 'i'): /* MC printer controller mode */
236: case A3('?', '\0', 'i'): /* MC printer controller mode */
237: switch (ARG(0)) {
238: case 0: /* print screen */
239: case 1: /* print cursor line */
240: case 4: /* off */
241: case 5: /* on */
242: #ifdef VT100_PRINTNOTIMPL
243: printf("CSI%di ignored\n", ARG(0));
244: #endif
245: break;
246: default:
247: #ifdef VT100_PRINTUNKNOWN
248: printf("CSI%di unknown\n", ARG(0));
249: #endif
250: break;
251: }
252: break;
253:
254: #define A2(a, b) (((a) << 8) | (b))
255: case A2('!', 'p'): /* DECSTR soft reset VT300 only */
256: wsemul_vt100_reset(edp);
257: break;
258:
259: case A2('"', 'p'): /* DECSCL */
260: switch (ARG(0)) {
261: case 61: /* VT100 mode (no further arguments!) */
262: break;
263: case 62:
264: case 63: /* VT300 mode */
265: break;
266: default:
267: #ifdef VT100_PRINTUNKNOWN
268: printf("CSI%d\"p unknown\n", ARG(0));
269: #endif
270: break;
271: }
272: switch (ARG(1)) {
273: case 0:
274: case 2: /* 8-bit controls */
275: #ifdef VT100_PRINTNOTIMPL
276: printf("CSI%d;%d\"p ignored\n", ARG(0), ARG(1));
277: #endif
278: break;
279: case 1: /* 7-bit controls */
280: break;
281: default:
282: #ifdef VT100_PRINTUNKNOWN
283: printf("CSI%d;%d\"p unknown\n", ARG(0), ARG(1));
284: #endif
285: break;
286: }
287: break;
288: case A2('"', 'q'): /* DECSCA select character attribute VT300 */
289: switch (ARG(0)) {
290: case 0:
291: case 1: /* erasable */
292: break;
293: case 2: /* not erasable */
294: #ifdef VT100_PRINTNOTIMPL
295: printf("CSI2\"q ignored\n");
296: #endif
297: break;
298: default:
299: #ifdef VT100_PRINTUNKNOWN
300: printf("CSI%d\"q unknown\n", ARG(0));
301: #endif
302: break;
303: }
304: break;
305:
306: case A2('$', 'u'): /* DECRQTSR request terminal status report */
307: switch (ARG(0)) {
308: case 0: /* ignored */
309: break;
310: case 1: /* terminal state report */
311: #ifdef VT100_PRINTNOTIMPL
312: printf("CSI1$u ignored\n");
313: #endif
314: break;
315: default:
316: #ifdef VT100_PRINTUNKNOWN
317: printf("CSI%d$u unknown\n", ARG(0));
318: #endif
319: break;
320: }
321: break;
322: case A2('$', 'w'): /* DECRQPSR request presentation status report
323: (VT300 only) */
324: switch (ARG(0)) {
325: case 0: /* error */
326: break;
327: case 1: /* cursor information report */
328: #ifdef VT100_PRINTNOTIMPL
329: printf("CSI1$w ignored\n");
330: #endif
331: break;
332: case 2: /* tab stop report */
333: {
334: int i, n, ps = 0;
335: char buf[20];
336:
337: wsdisplay_emulinput(edp->cbcookie, "\033P2$u", 5);
338: if (edp->tabs != NULL)
339: for (i = 0; i < edp->ncols; i++)
340: if (edp->tabs[i]) {
341: n = snprintf(buf, sizeof buf, "%s%d",
342: (ps ? "/" : ""), i + 1);
343: if (n == -1)
344: n = 0;
345: else if (n >= sizeof buf)
346: n = sizeof buf - 1;
347: wsdisplay_emulinput(edp->cbcookie,
348: buf, n);
349: ps = 1;
350: }
351: }
352: wsdisplay_emulinput(edp->cbcookie, "\033\\", 2);
353: break;
354: default:
355: #ifdef VT100_PRINTUNKNOWN
356: printf("CSI%d$w unknown\n", ARG(0));
357: #endif
358: break;
359: }
360: break;
361: case A2('$', '}'): /* DECSASD select active status display */
362: switch (ARG(0)) {
363: case 0: /* main display */
364: case 1: /* status line */
365: #ifdef VT100_PRINTNOTIMPL
366: printf("CSI%d$} ignored\n", ARG(0));
367: #endif
368: break;
369: default:
370: #ifdef VT100_PRINTUNKNOWN
371: printf("CSI%d$} unknown\n", ARG(0));
372: #endif
373: break;
374: }
375: break;
376: case A2('$', '~'): /* DECSSDD select status line type */
377: switch (ARG(0)) {
378: case 0: /* none */
379: case 1: /* indicator */
380: case 2: /* host-writable */
381: #ifdef VT100_PRINTNOTIMPL
382: printf("CSI%d$~ ignored\n", ARG(0));
383: #endif
384: break;
385: default:
386: #ifdef VT100_PRINTUNKNOWN
387: printf("CSI%d$~ unknown\n", ARG(0));
388: #endif
389: break;
390: }
391: break;
392:
393: case A2('&', 'u'): /* DECRQUPSS request user preferred
394: supplemental set */
395: wsdisplay_emulinput(edp->cbcookie, "\033P0!u%5\033\\", 9);
396: break;
397:
398: case '@': /* ICH insert character VT300 only */
399: n = min(DEF1_ARG(0), COLS_LEFT + 1);
400: help = NCOLS - (edp->ccol + n);
401: if (help > 0)
402: COPYCOLS(edp->ccol, edp->ccol + n, help);
403: ERASECOLS(edp->ccol, n, edp->bkgdattr);
404: break;
405: case 'A': /* CUU */
406: edp->crow -= min(DEF1_ARG(0), ROWS_ABOVE);
407: CHECK_DW;
408: break;
409: case 'B': /* CUD */
410: edp->crow += min(DEF1_ARG(0), ROWS_BELOW);
411: CHECK_DW;
412: break;
413: case 'C': /* CUF */
414: edp->ccol += min(DEF1_ARG(0), COLS_LEFT);
415: break;
416: case 'D': /* CUB */
417: edp->ccol -= min(DEF1_ARG(0), edp->ccol);
418: edp->flags &= ~VTFL_LASTCHAR;
419: break;
420: case 'H': /* CUP */
421: case 'f': /* HVP */
422: if (edp->flags & VTFL_DECOM)
423: edp->crow = edp->scrreg_startrow +
424: min(DEF1_ARG(0), edp->scrreg_nrows) - 1;
425: else
426: edp->crow = min(DEF1_ARG(0), edp->nrows) - 1;
427: CHECK_DW;
428: edp->ccol = min(DEF1_ARG(1), NCOLS) - 1;
429: edp->flags &= ~VTFL_LASTCHAR;
430: break;
431: case 'L': /* IL insert line */
432: case 'M': /* DL delete line */
433: n = min(DEF1_ARG(0), ROWS_BELOW + 1);
434: {
435: int savscrstartrow, savscrnrows;
436: savscrstartrow = edp->scrreg_startrow;
437: savscrnrows = edp->scrreg_nrows;
438: edp->scrreg_nrows -= ROWS_ABOVE;
439: edp->scrreg_startrow = edp->crow;
440: if (c == 'L')
441: wsemul_vt100_scrolldown(edp, n);
442: else
443: wsemul_vt100_scrollup(edp, n);
444: edp->scrreg_startrow = savscrstartrow;
445: edp->scrreg_nrows = savscrnrows;
446: }
447: break;
448: case 'P': /* DCH delete character */
449: n = min(DEF1_ARG(0), COLS_LEFT + 1);
450: help = NCOLS - (edp->ccol + n);
451: if (help > 0)
452: COPYCOLS(edp->ccol + n, edp->ccol, help);
453: ERASECOLS(NCOLS - n, n, edp->bkgdattr);
454: break;
455: case 'X': /* ECH erase character */
456: n = min(DEF1_ARG(0), COLS_LEFT + 1);
457: ERASECOLS(edp->ccol, n, edp->bkgdattr);
458: break;
459: case 'c': /* DA primary */
460: if (ARG(0) == 0)
461: wsdisplay_emulinput(edp->cbcookie, WSEMUL_VT_ID1,
462: sizeof(WSEMUL_VT_ID1));
463: break;
464: case 'g': /* TBC */
465: if (edp->tabs != NULL)
466: switch (ARG(0)) {
467: case 0:
468: edp->tabs[edp->ccol] = 0;
469: break;
470: case 3:
471: memset(edp->tabs, 0, edp->ncols);
472: break;
473: default:
474: #ifdef VT100_PRINTUNKNOWN
475: printf("CSI%dg unknown\n", ARG(0));
476: #endif
477: break;
478: }
479: break;
480: case 'm': /* SGR select graphic rendition */
481: flags = edp->attrflags;
482: fgcol = edp->fgcol;
483: bgcol = edp->bgcol;
484: for (n = 0; n < edp->nargs; n++) {
485: switch (ARG(n)) {
486: case 0: /* reset */
487: if (n == edp->nargs - 1) {
488: edp->bkgdattr = edp->curattr = edp->defattr;
489: edp->attrflags = 0;
490: edp->fgcol = WSCOL_WHITE;
491: edp->bgcol = WSCOL_BLACK;
492: return;
493: }
494: flags = 0;
495: fgcol = WSCOL_WHITE;
496: bgcol = WSCOL_BLACK;
497: break;
498: case 1: /* bold */
499: flags |= WSATTR_HILIT;
500: break;
501: case 4: /* underline */
502: flags |= WSATTR_UNDERLINE;
503: break;
504: case 5: /* blink */
505: flags |= WSATTR_BLINK;
506: break;
507: case 7: /* reverse */
508: flags |= WSATTR_REVERSE;
509: break;
510: case 22: /* ~bold VT300 only */
511: flags &= ~WSATTR_HILIT;
512: break;
513: case 24: /* ~underline VT300 only */
514: flags &= ~WSATTR_UNDERLINE;
515: break;
516: case 25: /* ~blink VT300 only */
517: flags &= ~WSATTR_BLINK;
518: break;
519: case 27: /* ~reverse VT300 only */
520: flags &= ~WSATTR_REVERSE;
521: break;
522: case 30: case 31: case 32: case 33:
523: case 34: case 35: case 36: case 37:
524: /* fg color */
525: flags |= WSATTR_WSCOLORS;
526: fgcol = ARG(n) - 30;
527: break;
528: case 40: case 41: case 42: case 43:
529: case 44: case 45: case 46: case 47:
530: /* bg color */
531: flags |= WSATTR_WSCOLORS;
532: bgcol = ARG(n) - 40;
533: break;
534: default:
535: #ifdef VT100_PRINTUNKNOWN
536: printf("CSI%dm unknown\n", ARG(n));
537: #endif
538: break;
539: }
540: }
541: if (vt100_selectattribute(edp, flags, fgcol, bgcol, &attr,
542: &bkgdattr)) {
543: #ifdef VT100_DEBUG
544: printf("error allocating attr %d/%d/%x\n",
545: fgcol, bgcol, flags);
546: #endif
547: } else {
548: edp->curattr = attr;
549: edp->bkgdattr = bkgdattr;
550: edp->attrflags = flags;
551: edp->fgcol = fgcol;
552: edp->bgcol = bgcol;
553: }
554: break;
555: case 'n': /* reports */
556: switch (ARG(0)) {
557: case 5: /* DSR operating status */
558: /* 0 = OK, 3 = malfunction */
559: wsdisplay_emulinput(edp->cbcookie, "\033[0n", 4);
560: break;
561: case 6: /* DSR cursor position report */
562: {
563: char buf[20];
564: int row;
565: if (edp->flags & VTFL_DECOM)
566: row = ROWS_ABOVE;
567: else
568: row = edp->crow;
569: n = snprintf(buf, sizeof buf, "\033[%d;%dR",
570: row + 1, edp->ccol + 1);
571: if (n == -1)
572: n = 0;
573: else if (n >= sizeof buf)
574: n = sizeof buf - 1;
575: wsdisplay_emulinput(edp->cbcookie, buf, n);
576: }
577: break;
578: case 15: /* DSR printer status */
579: /* 13 = no printer, 10 = ready, 11 = not ready */
580: wsdisplay_emulinput(edp->cbcookie, "\033[?13n", 6);
581: break;
582: case 25: /* UDK status - VT300 only */
583: /* 20 = locked, 21 = unlocked */
584: wsdisplay_emulinput(edp->cbcookie, "\033[?21n", 6);
585: break;
586: case 26: /* keyboard dialect */
587: /* 1 = north american , 7 = german */
588: wsdisplay_emulinput(edp->cbcookie, "\033[?27;1n", 8);
589: break;
590: default:
591: #ifdef VT100_PRINTUNKNOWN
592: printf("CSI%dn unknown\n", ARG(0));
593: #endif
594: break;
595: }
596: break;
597: case 'r': /* DECSTBM set top/bottom margins */
598: help = min(DEF1_ARG(0), edp->nrows) - 1;
599: n = min(DEFx_ARG(1, edp->nrows), edp->nrows) - help;
600: if (n < 2) {
601: /* minimal scrolling region has 2 lines */
602: return;
603: } else {
604: edp->scrreg_startrow = help;
605: edp->scrreg_nrows = n;
606: }
607: edp->crow = ((edp->flags & VTFL_DECOM) ?
608: edp->scrreg_startrow : 0);
609: edp->ccol = 0;
610: break;
611: case 'y':
612: switch (ARG(0)) {
613: case 4: /* DECTST invoke confidence test */
614: /* ignore */
615: break;
616: default:
617: #ifdef VT100_PRINTUNKNOWN
618: printf("CSI%dy unknown\n", ARG(0));
619: #endif
620: break;
621: }
622: break;
623: default:
624: #ifdef VT100_PRINTUNKNOWN
625: printf("CSI%c (%d, %d) unknown\n", c, ARG(0), ARG(1));
626: #endif
627: break;
628: }
629: }
630:
631: /*
632: * get an attribute from the graphics driver,
633: * try to find replacements if the desired appearance
634: * is not supported
635: */
636: int
637: vt100_selectattribute(edp, flags, fgcol, bgcol, attr, bkgdattr)
638: struct wsemul_vt100_emuldata *edp;
639: int flags, fgcol, bgcol;
640: long *attr, *bkgdattr;
641: {
642: int error;
643:
644: if ((flags & WSATTR_WSCOLORS) &&
645: !(edp->scrcapabilities & WSSCREEN_WSCOLORS)) {
646: flags &= ~WSATTR_WSCOLORS;
647: #ifdef VT100_DEBUG
648: printf("colors ignored (impossible)\n");
649: #endif
650: }
651: error = (*edp->emulops->alloc_attr)(edp->emulcookie, fgcol, bgcol,
652: flags & WSATTR_WSCOLORS, bkgdattr);
653: if (error)
654: return (error);
655:
656: if ((flags & WSATTR_HILIT) &&
657: !(edp->scrcapabilities & WSSCREEN_HILIT)) {
658: flags &= ~WSATTR_HILIT;
659: if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
660: fgcol = WSCOL_RED;
661: flags |= WSATTR_WSCOLORS;
662: } else {
663: #ifdef VT100_DEBUG
664: printf("bold ignored (impossible)\n");
665: #endif
666: }
667: }
668: if ((flags & WSATTR_UNDERLINE) &&
669: !(edp->scrcapabilities & WSSCREEN_UNDERLINE)) {
670: flags &= ~WSATTR_UNDERLINE;
671: if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
672: fgcol = WSCOL_CYAN;
673: flags &= ~WSATTR_UNDERLINE;
674: flags |= WSATTR_WSCOLORS;
675: } else {
676: #ifdef VT100_DEBUG
677: printf("underline ignored (impossible)\n");
678: #endif
679: }
680: }
681: if ((flags & WSATTR_BLINK) &&
682: !(edp->scrcapabilities & WSSCREEN_BLINK)) {
683: flags &= ~WSATTR_BLINK;
684: #ifdef VT100_DEBUG
685: printf("blink ignored (impossible)\n");
686: #endif
687: }
688: if ((flags & WSATTR_REVERSE) &&
689: !(edp->scrcapabilities & WSSCREEN_REVERSE)) {
690: flags &= ~WSATTR_REVERSE;
691: if (edp->scrcapabilities & WSSCREEN_WSCOLORS) {
692: int help;
693: help = bgcol;
694: bgcol = fgcol;
695: fgcol = help;
696: flags |= WSATTR_WSCOLORS;
697: } else {
698: #ifdef VT100_DEBUG
699: printf("reverse ignored (impossible)\n");
700: #endif
701: }
702: }
703: error = (*edp->emulops->alloc_attr)(edp->emulcookie, fgcol, bgcol,
704: flags, attr);
705: if (error)
706: return (error);
707:
708: return (0);
709: }
710:
711: /*
712: * handle device control sequences if the main state machine
713: * told so by setting edp->dcstype to a nonzero value
714: */
715: void
716: wsemul_vt100_handle_dcs(edp)
717: struct wsemul_vt100_emuldata *edp;
718: {
719: int i, pos;
720:
721: switch (edp->dcstype) {
722: case 0: /* not handled */
723: return;
724: case DCSTYPE_TABRESTORE:
725: if (edp->tabs != NULL) {
726: memset(edp->tabs, 0, edp->ncols);
727: pos = 0;
728: for (i = 0; i < edp->dcspos; i++) {
729: char c = edp->dcsarg[i];
730: switch (c) {
731: case '0': case '1': case '2': case '3':
732: case '4': case '5': case '6': case '7':
733: case '8': case '9':
734: pos = pos * 10 + (edp->dcsarg[i] - '0');
735: break;
736: case '/':
737: if (pos > 0)
738: edp->tabs[pos - 1] = 1;
739: pos = 0;
740: break;
741: default:
742: #ifdef VT100_PRINTUNKNOWN
743: printf("unknown char %c in DCS\n", c);
744: #endif
745: break;
746: }
747: }
748: if (pos > 0)
749: edp->tabs[pos - 1] = 1;
750: }
751: break;
752: default:
753: panic("wsemul_vt100_handle_dcs: bad type %d", edp->dcstype);
754: }
755: edp->dcstype = 0;
756: }
757:
758: int
759: vt100_ansimode(edp, nr, op)
760: struct wsemul_vt100_emuldata *edp;
761: int nr, op;
762: {
763: int res = 0; /* default: unknown */
764:
765: switch (nr) {
766: case 2: /* KAM keyboard locked/unlocked */
767: break;
768: case 3: /* CRM control representation */
769: break;
770: case 4: /* IRM insert/replace characters */
771: if (op == VTMODE_SET)
772: edp->flags |= VTFL_INSERTMODE;
773: else if (op == VTMODE_RESET)
774: edp->flags &= ~VTFL_INSERTMODE;
775: res = ((edp->flags & VTFL_INSERTMODE) ? 1 : 2);
776: break;
777: case 10: /* HEM horizontal editing (permanently reset) */
778: res = 4;
779: break;
780: case 12: /* SRM local echo off/on */
781: res = 4; /* permanently reset ??? */
782: break;
783: case 20: /* LNM newline = newline/linefeed */
784: break;
785: default:
786: #ifdef VT100_PRINTUNKNOWN
787: printf("ANSI mode %d unknown\n", nr);
788: #endif
789: break;
790: }
791: return (res);
792: }
793:
794: int
795: vt100_decmode(edp, nr, op)
796: struct wsemul_vt100_emuldata *edp;
797: int nr, op;
798: {
799: int res = 0; /* default: unknown */
800: int flags;
801:
802: flags = edp->flags;
803: switch (nr) {
804: case 1: /* DECCKM application/nomal cursor keys */
805: if (op == VTMODE_SET)
806: flags |= VTFL_APPLCURSOR;
807: else if (op == VTMODE_RESET)
808: flags &= ~VTFL_APPLCURSOR;
809: res = ((flags & VTFL_APPLCURSOR) ? 1 : 2);
810: break;
811: case 2: /* DECANM ANSI vt100/vt52 */
812: res = 3; /* permanently set ??? */
813: break;
814: case 3: /* DECCOLM 132/80 cols */
815: case 4: /* DECSCLM smooth/jump scroll */
816: case 5: /* DECSCNM light/dark background */
817: res = 4; /* all permanently reset ??? */
818: break;
819: case 6: /* DECOM move within/outside margins */
820: if (op == VTMODE_SET)
821: flags |= VTFL_DECOM;
822: else if (op == VTMODE_RESET)
823: flags &= ~VTFL_DECOM;
824: res = ((flags & VTFL_DECOM) ? 1 : 2);
825: break;
826: case 7: /* DECAWM autowrap */
827: if (op == VTMODE_SET)
828: flags |= VTFL_DECAWM;
829: else if (op == VTMODE_RESET)
830: flags &= ~VTFL_DECAWM;
831: res = ((flags & VTFL_DECAWM) ? 1 : 2);
832: break;
833: case 8: /* DECARM keyboard autorepeat */
834: break;
835: case 18: /* DECPFF print form feed */
836: break;
837: case 19: /* DECPEX printer extent: screen/scrolling region */
838: break;
839: case 25: /* DECTCEM text cursor on/off */
840: if (op == VTMODE_SET)
841: flags |= VTFL_CURSORON;
842: else if (op == VTMODE_RESET)
843: flags &= ~VTFL_CURSORON;
844: if (flags != edp->flags)
845: (*edp->emulops->cursor)(edp->emulcookie,
846: flags & VTFL_CURSORON,
847: edp->crow, edp->ccol);
848: res = ((flags & VTFL_CURSORON) ? 1 : 2);
849: break;
850: case 42: /* DECNRCM use 7-bit NRC /
851: 7/8 bit from DEC multilingual or ISO-latin-1*/
852: if (op == VTMODE_SET)
853: flags |= VTFL_NATCHARSET;
854: else if (op == VTMODE_RESET)
855: flags &= ~VTFL_NATCHARSET;
856: res = ((flags & VTFL_NATCHARSET) ? 1 : 2);
857: break;
858: case 66: /* DECNKM numeric keypad */
859: break;
860: case 68: /* DECKBUM keyboard usage data processing/typewriter */
861: break;
862: default:
863: #ifdef VT100_PRINTUNKNOWN
864: printf("DEC mode %d unknown\n", nr);
865: #endif
866: break;
867: }
868: edp->flags = flags;
869:
870: return (res);
871: }
CVSweb