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