Annotation of sys/dev/wscons/wsemul_vt100_subr.c, Revision 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