[BACK]Return to wsemul_sun.c CVS log [TXT][DIR] Up to [local] / sys / dev / wscons

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