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

Annotation of sys/dev/wscons/wsemul_vt100.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: wsemul_vt100.c,v 1.18 2007/02/14 01:12:16 jsg Exp $ */
                      2: /* $NetBSD: wsemul_vt100.c,v 1.13 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: #ifndef        SMALL_KERNEL
                     31: #define        JUMP_SCROLL
                     32: #endif
                     33:
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/time.h>
                     37: #include <sys/malloc.h>
                     38: #include <sys/fcntl.h>
                     39:
                     40: #include <dev/wscons/wsconsio.h>
                     41: #include <dev/wscons/wsdisplayvar.h>
                     42: #include <dev/wscons/wsemulvar.h>
                     43: #include <dev/wscons/wsemul_vt100var.h>
                     44: #include <dev/wscons/ascii.h>
                     45:
                     46: void   *wsemul_vt100_cnattach(const struct wsscreen_descr *, void *,
                     47:                                  int, int, long);
                     48: void   *wsemul_vt100_attach(int console, const struct wsscreen_descr *,
                     49:                                  void *, int, int, void *, long);
                     50: void   wsemul_vt100_output(void *cookie, const u_char *data, u_int count,
                     51:                                 int);
                     52: void   wsemul_vt100_detach(void *cookie, u_int *crowp, u_int *ccolp);
                     53: void   wsemul_vt100_resetop(void *, enum wsemul_resetops);
                     54:
                     55: const struct wsemul_ops wsemul_vt100_ops = {
                     56:        "vt100",
                     57:        wsemul_vt100_cnattach,
                     58:        wsemul_vt100_attach,
                     59:        wsemul_vt100_output,
                     60:        wsemul_vt100_translate,
                     61:        wsemul_vt100_detach,
                     62:        wsemul_vt100_resetop
                     63: };
                     64:
                     65: struct wsemul_vt100_emuldata wsemul_vt100_console_emuldata;
                     66:
                     67: void wsemul_vt100_init(struct wsemul_vt100_emuldata *,
                     68:                            const struct wsscreen_descr *, void *, int, int,
                     69:                            long);
                     70:
                     71: void wsemul_vt100_output_normal(struct wsemul_vt100_emuldata *, u_char,
                     72:                                     int);
                     73: void wsemul_vt100_output_c0c1(struct wsemul_vt100_emuldata *, u_char,
                     74:                                   int);
                     75: void wsemul_vt100_nextline(struct wsemul_vt100_emuldata *);
                     76: typedef u_int vt100_handler(struct wsemul_vt100_emuldata *, u_char);
                     77: vt100_handler
                     78: wsemul_vt100_output_esc,
                     79: wsemul_vt100_output_csi,
                     80: wsemul_vt100_output_scs94,
                     81: wsemul_vt100_output_scs94_percent,
                     82: wsemul_vt100_output_scs96,
                     83: wsemul_vt100_output_scs96_percent,
                     84: wsemul_vt100_output_esc_hash,
                     85: wsemul_vt100_output_esc_spc,
                     86: wsemul_vt100_output_string,
                     87: wsemul_vt100_output_string_esc,
                     88: wsemul_vt100_output_dcs,
                     89: wsemul_vt100_output_dcs_dollar;
                     90:
                     91: #define        VT100_EMUL_STATE_NORMAL         0       /* normal processing */
                     92: #define        VT100_EMUL_STATE_ESC            1       /* got ESC */
                     93: #define        VT100_EMUL_STATE_CSI            2       /* got CSI (ESC[) */
                     94: #define        VT100_EMUL_STATE_SCS94          3       /* got ESC{()*+} */
                     95: #define        VT100_EMUL_STATE_SCS94_PERCENT  4       /* got ESC{()*+}% */
                     96: #define        VT100_EMUL_STATE_SCS96          5       /* got ESC{-./} */
                     97: #define        VT100_EMUL_STATE_SCS96_PERCENT  6       /* got ESC{-./}% */
                     98: #define        VT100_EMUL_STATE_ESC_HASH       7       /* got ESC# */
                     99: #define        VT100_EMUL_STATE_ESC_SPC        8       /* got ESC<SPC> */
                    100: #define        VT100_EMUL_STATE_STRING         9       /* waiting for ST (ESC\) */
                    101: #define        VT100_EMUL_STATE_STRING_ESC     10      /* waiting for ST, got ESC */
                    102: #define        VT100_EMUL_STATE_DCS            11      /* got DCS (ESC P) */
                    103: #define        VT100_EMUL_STATE_DCS_DOLLAR     12      /* got DCS<p>$ */
                    104:
                    105: vt100_handler *vt100_output[] = {
                    106:        wsemul_vt100_output_esc,
                    107:        wsemul_vt100_output_csi,
                    108:        wsemul_vt100_output_scs94,
                    109:        wsemul_vt100_output_scs94_percent,
                    110:        wsemul_vt100_output_scs96,
                    111:        wsemul_vt100_output_scs96_percent,
                    112:        wsemul_vt100_output_esc_hash,
                    113:        wsemul_vt100_output_esc_spc,
                    114:        wsemul_vt100_output_string,
                    115:        wsemul_vt100_output_string_esc,
                    116:        wsemul_vt100_output_dcs,
                    117:        wsemul_vt100_output_dcs_dollar,
                    118: };
                    119:
                    120: void
                    121: wsemul_vt100_init(edp, type, cookie, ccol, crow, defattr)
                    122:        struct wsemul_vt100_emuldata *edp;
                    123:        const struct wsscreen_descr *type;
                    124:        void *cookie;
                    125:        int ccol, crow;
                    126:        long defattr;
                    127: {
                    128:        edp->emulops = type->textops;
                    129:        edp->emulcookie = cookie;
                    130:        edp->scrcapabilities = type->capabilities;
                    131:        edp->nrows = type->nrows;
                    132:        edp->ncols = type->ncols;
                    133:        edp->crow = crow;
                    134:        edp->ccol = ccol;
                    135:        edp->defattr = defattr;
                    136: }
                    137:
                    138: void *
                    139: wsemul_vt100_cnattach(type, cookie, ccol, crow, defattr)
                    140:        const struct wsscreen_descr *type;
                    141:        void *cookie;
                    142:        int ccol, crow;
                    143:        long defattr;
                    144: {
                    145:        struct wsemul_vt100_emuldata *edp;
                    146:        int res;
                    147:
                    148:        edp = &wsemul_vt100_console_emuldata;
                    149:        wsemul_vt100_init(edp, type, cookie, ccol, crow, defattr);
                    150: #ifdef DIAGNOSTIC
                    151:        edp->console = 1;
                    152: #endif
                    153:        edp->cbcookie = NULL;
                    154:
                    155: #ifndef WS_KERNEL_FG
                    156: #define WS_KERNEL_FG WSCOL_WHITE
                    157: #endif
                    158: #ifndef WS_KERNEL_BG
                    159: #define WS_KERNEL_BG WSCOL_BLUE
                    160: #endif
                    161: #ifndef WS_KERNEL_COLATTR
                    162: #define WS_KERNEL_COLATTR 0
                    163: #endif
                    164: #ifndef WS_KERNEL_MONOATTR
                    165: #define WS_KERNEL_MONOATTR 0
                    166: #endif
                    167:        if (type->capabilities & WSSCREEN_WSCOLORS)
                    168:                res = (*edp->emulops->alloc_attr)(cookie,
                    169:                                            WS_KERNEL_FG, WS_KERNEL_BG,
                    170:                                            WS_KERNEL_COLATTR | WSATTR_WSCOLORS,
                    171:                                            &edp->kernattr);
                    172:        else
                    173:                res = (*edp->emulops->alloc_attr)(cookie, 0, 0,
                    174:                                            WS_KERNEL_MONOATTR,
                    175:                                            &edp->kernattr);
                    176:        if (res)
                    177:                edp->kernattr = defattr;
                    178:
                    179:        edp->tabs = NULL;
                    180:        edp->dblwid = NULL;
                    181:        edp->dw = 0;
                    182:        edp->dcsarg = 0;
                    183:        edp->isolatin1tab = edp->decgraphtab = edp->dectechtab = NULL;
                    184:        edp->nrctab = NULL;
                    185:        wsemul_vt100_reset(edp);
                    186:        return (edp);
                    187: }
                    188:
                    189: void *
                    190: wsemul_vt100_attach(console, type, cookie, ccol, crow, cbcookie, defattr)
                    191:        int console;
                    192:        const struct wsscreen_descr *type;
                    193:        void *cookie;
                    194:        int ccol, crow;
                    195:        void *cbcookie;
                    196:        long defattr;
                    197: {
                    198:        struct wsemul_vt100_emuldata *edp;
                    199:
                    200:        if (console) {
                    201:                edp = &wsemul_vt100_console_emuldata;
                    202: #ifdef DIAGNOSTIC
                    203:                KASSERT(edp->console == 1);
                    204: #endif
                    205:        } else {
                    206:                edp = malloc(sizeof *edp, M_DEVBUF, M_NOWAIT);
                    207:                if (edp == NULL)
                    208:                        return (NULL);
                    209:                wsemul_vt100_init(edp, type, cookie, ccol, crow, defattr);
                    210: #ifdef DIAGNOSTIC
                    211:                edp->console = 0;
                    212: #endif
                    213:        }
                    214:        edp->cbcookie = cbcookie;
                    215:
                    216:        edp->tabs = malloc(edp->ncols, M_DEVBUF, M_NOWAIT);
                    217:        edp->dblwid = malloc(edp->nrows, M_DEVBUF, M_NOWAIT);
                    218:        if (edp->dblwid != NULL)
                    219:                memset(edp->dblwid, 0, edp->nrows);
                    220:        edp->dw = 0;
                    221:        edp->dcsarg = malloc(DCS_MAXLEN, M_DEVBUF, M_NOWAIT);
                    222:        edp->isolatin1tab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
                    223:        edp->decgraphtab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
                    224:        edp->dectechtab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
                    225:        edp->nrctab = malloc(128 * sizeof(int), M_DEVBUF, M_NOWAIT);
                    226:        vt100_initchartables(edp);
                    227:        wsemul_vt100_reset(edp);
                    228:        return (edp);
                    229: }
                    230:
                    231: void
                    232: wsemul_vt100_detach(cookie, crowp, ccolp)
                    233:        void *cookie;
                    234:        u_int *crowp, *ccolp;
                    235: {
                    236:        struct wsemul_vt100_emuldata *edp = cookie;
                    237:
                    238:        *crowp = edp->crow;
                    239:        *ccolp = edp->ccol;
                    240: #define f(ptr) if (ptr) {free(ptr, M_DEVBUF); ptr = NULL;}
                    241:        f(edp->tabs)
                    242:        f(edp->dblwid)
                    243:        f(edp->dcsarg)
                    244:        f(edp->isolatin1tab)
                    245:        f(edp->decgraphtab)
                    246:        f(edp->dectechtab)
                    247:        f(edp->nrctab)
                    248: #undef f
                    249:        if (edp != &wsemul_vt100_console_emuldata)
                    250:                free(edp, M_DEVBUF);
                    251: }
                    252:
                    253: void
                    254: wsemul_vt100_resetop(cookie, op)
                    255:        void *cookie;
                    256:        enum wsemul_resetops op;
                    257: {
                    258:        struct wsemul_vt100_emuldata *edp = cookie;
                    259:
                    260:        switch (op) {
                    261:        case WSEMUL_RESET:
                    262:                wsemul_vt100_reset(edp);
                    263:                break;
                    264:        case WSEMUL_SYNCFONT:
                    265:                vt100_initchartables(edp);
                    266:                break;
                    267:        case WSEMUL_CLEARSCREEN:
                    268:                wsemul_vt100_ed(edp, 2);
                    269:                edp->ccol = edp->crow = 0;
                    270:                (*edp->emulops->cursor)(edp->emulcookie,
                    271:                                        edp->flags & VTFL_CURSORON, 0, 0);
                    272:                break;
                    273:        default:
                    274:                break;
                    275:        }
                    276: }
                    277:
                    278: void
                    279: wsemul_vt100_reset(edp)
                    280:        struct wsemul_vt100_emuldata *edp;
                    281: {
                    282:        int i;
                    283:
                    284:        edp->state = VT100_EMUL_STATE_NORMAL;
                    285:        edp->flags = VTFL_DECAWM | VTFL_CURSORON;
                    286:        edp->bkgdattr = edp->curattr = edp->defattr;
                    287:        edp->attrflags = 0;
                    288:        edp->fgcol = WSCOL_WHITE;
                    289:        edp->bgcol = WSCOL_BLACK;
                    290:        edp->scrreg_startrow = 0;
                    291:        edp->scrreg_nrows = edp->nrows;
                    292:        if (edp->tabs) {
                    293:                memset(edp->tabs, 0, edp->ncols);
                    294:                for (i = 8; i < edp->ncols; i += 8)
                    295:                        edp->tabs[i] = 1;
                    296:        }
                    297:        edp->dcspos = 0;
                    298:        edp->dcstype = 0;
                    299:        edp->chartab_G[0] = NULL;
                    300:        edp->chartab_G[1] = edp->nrctab; /* ??? */
                    301:        edp->chartab_G[2] = edp->isolatin1tab;
                    302:        edp->chartab_G[3] = edp->isolatin1tab;
                    303:        edp->chartab0 = 0;
                    304:        edp->chartab1 = 2;
                    305:        edp->sschartab = 0;
                    306: }
                    307:
                    308: /*
                    309:  * Move the cursor to the next line if possible. If the cursor is at
                    310:  * the bottom of the scroll area, then scroll it up. If the cursor is
                    311:  * at the bottom of the screen then don't move it down.
                    312:  */
                    313: void
                    314: wsemul_vt100_nextline(struct wsemul_vt100_emuldata *edp)
                    315: {
                    316:        if (ROWS_BELOW == 0) {
                    317:                /* Bottom of the scroll region. */
                    318:                wsemul_vt100_scrollup(edp, 1);
                    319:        } else {
                    320:                if ((edp->crow+1) < edp->nrows)
                    321:                        /* Cursor not at the bottom of the screen. */
                    322:                        edp->crow++;
                    323:                CHECK_DW;
                    324:        }
                    325: }
                    326:
                    327: /*
                    328:  * now all the state machine bits
                    329:  */
                    330:
                    331: void
                    332: wsemul_vt100_output_normal(edp, c, kernel)
                    333:        struct wsemul_vt100_emuldata *edp;
                    334:        u_char c;
                    335:        int kernel;
                    336: {
                    337:        u_int *ct, dc;
                    338:
                    339:        if ((edp->flags & (VTFL_LASTCHAR | VTFL_DECAWM)) ==
                    340:            (VTFL_LASTCHAR | VTFL_DECAWM)) {
                    341:                wsemul_vt100_nextline(edp);
                    342:                edp->ccol = 0;
                    343:                edp->flags &= ~VTFL_LASTCHAR;
                    344:        }
                    345:
                    346:        if (c & 0x80) {
                    347:                c &= 0x7f;
                    348:                ct = edp->chartab_G[edp->chartab1];
                    349:        } else {
                    350:                if (edp->sschartab) {
                    351:                        ct = edp->chartab_G[edp->sschartab];
                    352:                        edp->sschartab = 0;
                    353:                } else
                    354:                        ct = edp->chartab_G[edp->chartab0];
                    355:        }
                    356:        dc = (ct ? ct[c] : c);
                    357:
                    358:        if ((edp->flags & VTFL_INSERTMODE) && COLS_LEFT)
                    359:                COPYCOLS(edp->ccol, edp->ccol + 1, COLS_LEFT);
                    360:
                    361:        (*edp->emulops->putchar)(edp->emulcookie, edp->crow,
                    362:                                 edp->ccol << edp->dw, dc,
                    363:                                 kernel ? edp->kernattr : edp->curattr);
                    364:
                    365:        if (COLS_LEFT)
                    366:                edp->ccol++;
                    367:        else
                    368:                edp->flags |= VTFL_LASTCHAR;
                    369: }
                    370:
                    371: void
                    372: wsemul_vt100_output_c0c1(edp, c, kernel)
                    373:        struct wsemul_vt100_emuldata *edp;
                    374:        u_char c;
                    375:        int kernel;
                    376: {
                    377:        u_int n;
                    378:
                    379:        switch (c) {
                    380:        case ASCII_NUL:
                    381:        default:
                    382:                /* ignore */
                    383:                break;
                    384:        case ASCII_BEL:
                    385:                wsdisplay_emulbell(edp->cbcookie);
                    386:                break;
                    387:        case ASCII_BS:
                    388:                if (edp->ccol > 0) {
                    389:                        edp->ccol--;
                    390:                        edp->flags &= ~VTFL_LASTCHAR;
                    391:                }
                    392:                break;
                    393:        case ASCII_CR:
                    394:                edp->ccol = 0;
                    395:                edp->flags &= ~VTFL_LASTCHAR;
                    396:                break;
                    397:        case ASCII_HT:
                    398:                if (edp->tabs) {
                    399:                        if (!COLS_LEFT)
                    400:                                break;
                    401:                        for (n = edp->ccol + 1; n < NCOLS - 1; n++)
                    402:                                if (edp->tabs[n])
                    403:                                        break;
                    404:                } else {
                    405:                        n = edp->ccol + min(8 - (edp->ccol & 7), COLS_LEFT);
                    406:                }
                    407:                edp->ccol = n;
                    408:                break;
                    409:        case ASCII_SO: /* LS1 */
                    410:                edp->chartab0 = 1;
                    411:                break;
                    412:        case ASCII_SI: /* LS0 */
                    413:                edp->chartab0 = 0;
                    414:                break;
                    415:        case ASCII_ESC:
                    416:                if (kernel) {
                    417:                        printf("wsemul_vt100_output_c0c1: ESC in kernel "
                    418:                            "output ignored\n");
                    419:                        break;  /* ignore the ESC */
                    420:                }
                    421:
                    422:                if (edp->state == VT100_EMUL_STATE_STRING) {
                    423:                        /* might be a string end */
                    424:                        edp->state = VT100_EMUL_STATE_STRING_ESC;
                    425:                } else {
                    426:                        /* XXX cancel current escape sequence */
                    427:                        edp->state = VT100_EMUL_STATE_ESC;
                    428:                }
                    429:                break;
                    430: #if 0
                    431:        case CSI: /* 8-bit */
                    432:                /* XXX cancel current escape sequence */
                    433:                edp->nargs = 0;
                    434:                memset(edp->args, 0, sizeof (edp->args));
                    435:                edp->modif1 = edp->modif2 = '\0';
                    436:                edp->state = VT100_EMUL_STATE_CSI;
                    437:                break;
                    438:        case DCS: /* 8-bit */
                    439:                /* XXX cancel current escape sequence */
                    440:                edp->nargs = 0;
                    441:                memset(edp->args, 0, sizeof (edp->args));
                    442:                edp->state = VT100_EMUL_STATE_DCS;
                    443:                break;
                    444:        case ST: /* string end 8-bit */
                    445:                /* XXX only in VT100_EMUL_STATE_STRING */
                    446:                wsemul_vt100_handle_dcs(edp);
                    447:                return (VT100_EMUL_STATE_NORMAL);
                    448: #endif
                    449:        case ASCII_LF:
                    450:        case ASCII_VT:
                    451:        case ASCII_FF:
                    452:                wsemul_vt100_nextline(edp);
                    453:                break;
                    454:        }
                    455: }
                    456:
                    457: u_int
                    458: wsemul_vt100_output_esc(edp, c)
                    459:        struct wsemul_vt100_emuldata *edp;
                    460:        u_char c;
                    461: {
                    462:        u_int newstate = VT100_EMUL_STATE_NORMAL;
                    463:        int i;
                    464:
                    465:        switch (c) {
                    466:        case '[': /* CSI */
                    467:                edp->nargs = 0;
                    468:                memset(edp->args, 0, sizeof (edp->args));
                    469:                edp->modif1 = edp->modif2 = '\0';
                    470:                newstate = VT100_EMUL_STATE_CSI;
                    471:                break;
                    472:        case '7': /* DECSC */
                    473:                edp->flags |= VTFL_SAVEDCURS;
                    474:                edp->savedcursor_row = edp->crow;
                    475:                edp->savedcursor_col = edp->ccol;
                    476:                edp->savedattr = edp->curattr;
                    477:                edp->savedbkgdattr = edp->bkgdattr;
                    478:                edp->savedattrflags = edp->attrflags;
                    479:                edp->savedfgcol = edp->fgcol;
                    480:                edp->savedbgcol = edp->bgcol;
                    481:                for (i = 0; i < 4; i++)
                    482:                        edp->savedchartab_G[i] = edp->chartab_G[i];
                    483:                edp->savedchartab0 = edp->chartab0;
                    484:                edp->savedchartab1 = edp->chartab1;
                    485:                break;
                    486:        case '8': /* DECRC */
                    487:                if ((edp->flags & VTFL_SAVEDCURS) == 0)
                    488:                        break;
                    489:                edp->crow = edp->savedcursor_row;
                    490:                edp->ccol = edp->savedcursor_col;
                    491:                edp->curattr = edp->savedattr;
                    492:                edp->bkgdattr = edp->savedbkgdattr;
                    493:                edp->attrflags = edp->savedattrflags;
                    494:                edp->fgcol = edp->savedfgcol;
                    495:                edp->bgcol = edp->savedbgcol;
                    496:                for (i = 0; i < 4; i++)
                    497:                        edp->chartab_G[i] = edp->savedchartab_G[i];
                    498:                edp->chartab0 = edp->savedchartab0;
                    499:                edp->chartab1 = edp->savedchartab1;
                    500:                break;
                    501:        case '=': /* DECKPAM application mode */
                    502:                edp->flags |= VTFL_APPLKEYPAD;
                    503:                break;
                    504:        case '>': /* DECKPNM numeric mode */
                    505:                edp->flags &= ~VTFL_APPLKEYPAD;
                    506:                break;
                    507:        case 'E': /* NEL */
                    508:                edp->ccol = 0;
                    509:                /* FALLTHROUGH */
                    510:        case 'D': /* IND */
                    511:                wsemul_vt100_nextline(edp);
                    512:                break;
                    513:        case 'H': /* HTS */
                    514:                if (edp->tabs != NULL)
                    515:                        edp->tabs[edp->ccol] = 1;
                    516:                break;
                    517:        case '~': /* LS1R */
                    518:                edp->chartab1 = 1;
                    519:                break;
                    520:        case 'n': /* LS2 */
                    521:                edp->chartab0 = 2;
                    522:                break;
                    523:        case '}': /* LS2R */
                    524:                edp->chartab1 = 2;
                    525:                break;
                    526:        case 'o': /* LS3 */
                    527:                edp->chartab0 = 3;
                    528:                break;
                    529:        case '|': /* LS3R */
                    530:                edp->chartab1 = 3;
                    531:                break;
                    532:        case 'N': /* SS2 */
                    533:                edp->sschartab = 2;
                    534:                break;
                    535:        case 'O': /* SS3 */
                    536:                edp->sschartab = 3;
                    537:                break;
                    538:        case 'M': /* RI */
                    539:                if (ROWS_ABOVE > 0) {
                    540:                        edp->crow--;
                    541:                        CHECK_DW;
                    542:                        break;
                    543:                }
                    544:                wsemul_vt100_scrolldown(edp, 1);
                    545:                break;
                    546:        case 'P': /* DCS */
                    547:                edp->nargs = 0;
                    548:                memset(edp->args, 0, sizeof (edp->args));
                    549:                newstate = VT100_EMUL_STATE_DCS;
                    550:                break;
                    551:        case 'c': /* RIS */
                    552:                wsemul_vt100_reset(edp);
                    553:                wsemul_vt100_ed(edp, 2);
                    554:                edp->ccol = edp->crow = 0;
                    555:                break;
                    556:        case '(': case ')': case '*': case '+': /* SCS */
                    557:                edp->designating = c - '(';
                    558:                newstate = VT100_EMUL_STATE_SCS94;
                    559:                break;
                    560:        case '-': case '.': case '/': /* SCS */
                    561:                edp->designating = c - '-' + 1;
                    562:                newstate = VT100_EMUL_STATE_SCS96;
                    563:                break;
                    564:        case '#':
                    565:                newstate = VT100_EMUL_STATE_ESC_HASH;
                    566:                break;
                    567:        case ' ': /* 7/8 bit */
                    568:                newstate = VT100_EMUL_STATE_ESC_SPC;
                    569:                break;
                    570:        case ']': /* OSC operating system command */
                    571:        case '^': /* PM privacy message */
                    572:        case '_': /* APC application program command */
                    573:                /* ignored */
                    574:                newstate = VT100_EMUL_STATE_STRING;
                    575:                break;
                    576:        case '<': /* exit VT52 mode - ignored */
                    577:                break;
                    578:            default:
                    579: #ifdef VT100_PRINTUNKNOWN
                    580:                printf("ESC%c unknown\n", c);
                    581: #endif
                    582:                break;
                    583:        }
                    584:
                    585:        return (newstate);
                    586: }
                    587:
                    588: u_int
                    589: wsemul_vt100_output_scs94(edp, c)
                    590:        struct wsemul_vt100_emuldata *edp;
                    591:        u_char c;
                    592: {
                    593:        u_int newstate = VT100_EMUL_STATE_NORMAL;
                    594:
                    595:        switch (c) {
                    596:        case '%': /* probably DEC supplemental graphic */
                    597:                newstate = VT100_EMUL_STATE_SCS94_PERCENT;
                    598:                break;
                    599:        case 'A': /* british / national */
                    600:                edp->chartab_G[edp->designating] = edp->nrctab;
                    601:                break;
                    602:        case 'B': /* ASCII */
                    603:                edp->chartab_G[edp->designating] = 0;
                    604:                break;
                    605:        case '<': /* user preferred supplemental */
                    606:                /* XXX not really "user" preferred */
                    607:                edp->chartab_G[edp->designating] = edp->isolatin1tab;
                    608:                break;
                    609:        case '0': /* DEC special graphic */
                    610:                edp->chartab_G[edp->designating] = edp->decgraphtab;
                    611:                break;
                    612:        case '>': /* DEC tech */
                    613:                edp->chartab_G[edp->designating] = edp->dectechtab;
                    614:                break;
                    615:            default:
                    616: #ifdef VT100_PRINTUNKNOWN
                    617:                printf("ESC%c%c unknown\n", edp->designating + '(', c);
                    618: #endif
                    619:                break;
                    620:        }
                    621:        return (newstate);
                    622: }
                    623:
                    624: u_int
                    625: wsemul_vt100_output_scs94_percent(edp, c)
                    626:        struct wsemul_vt100_emuldata *edp;
                    627:        u_char c;
                    628: {
                    629:        switch (c) {
                    630:        case '5': /* DEC supplemental graphic */
                    631:                /* XXX there are differences */
                    632:                edp->chartab_G[edp->designating] = edp->isolatin1tab;
                    633:                break;
                    634:            default:
                    635: #ifdef VT100_PRINTUNKNOWN
                    636:                printf("ESC%c%%%c unknown\n", edp->designating + '(', c);
                    637: #endif
                    638:                break;
                    639:        }
                    640:        return (VT100_EMUL_STATE_NORMAL);
                    641: }
                    642:
                    643: u_int
                    644: wsemul_vt100_output_scs96(edp, c)
                    645:        struct wsemul_vt100_emuldata *edp;
                    646:        u_char c;
                    647: {
                    648:        u_int newstate = VT100_EMUL_STATE_NORMAL;
                    649:        int nrc;
                    650:
                    651:        switch (c) {
                    652:        case '%': /* probably portugese */
                    653:                newstate = VT100_EMUL_STATE_SCS96_PERCENT;
                    654:                break;
                    655:        case 'A': /* ISO-latin-1 supplemental */
                    656:                edp->chartab_G[edp->designating] = edp->isolatin1tab;
                    657:                break;
                    658:        case '4': /* dutch */
                    659:                nrc = 1;
                    660:                goto setnrc;
                    661:        case '5': case 'C': /* finnish */
                    662:                nrc = 2;
                    663:                goto setnrc;
                    664:        case 'R': /* french */
                    665:                nrc = 3;
                    666:                goto setnrc;
                    667:        case 'Q': /* french canadian */
                    668:                nrc = 4;
                    669:                goto setnrc;
                    670:        case 'K': /* german */
                    671:                nrc = 5;
                    672:                goto setnrc;
                    673:        case 'Y': /* italian */
                    674:                nrc = 6;
                    675:                goto setnrc;
                    676:        case 'E': case '6': /* norwegian / danish */
                    677:                nrc = 7;
                    678:                goto setnrc;
                    679:        case 'Z': /* spanish */
                    680:                nrc = 9;
                    681:                goto setnrc;
                    682:        case '7': case 'H': /* swedish */
                    683:                nrc = 10;
                    684:                goto setnrc;
                    685:        case '=': /* swiss */
                    686:                nrc = 11;
                    687: setnrc:
                    688:                if (vt100_setnrc(edp, nrc) == 0) /* what table ??? */
                    689:                        break;
                    690:                /* else FALLTHROUGH */
                    691:            default:
                    692: #ifdef VT100_PRINTUNKNOWN
                    693:                printf("ESC%c%c unknown\n", edp->designating + '-' - 1, c);
                    694: #endif
                    695:                break;
                    696:        }
                    697:        return (newstate);
                    698: }
                    699:
                    700: u_int
                    701: wsemul_vt100_output_scs96_percent(edp, c)
                    702:        struct wsemul_vt100_emuldata *edp;
                    703:        u_char c;
                    704: {
                    705:        switch (c) {
                    706:        case '6': /* portugese */
                    707:                if (vt100_setnrc(edp, 8) == 0)
                    708:                        break;
                    709:                /* else FALLTHROUGH */
                    710:            default:
                    711: #ifdef VT100_PRINTUNKNOWN
                    712:                printf("ESC%c%%%c unknown\n", edp->designating + '-' - 1, c);
                    713: #endif
                    714:                break;
                    715:        }
                    716:        return (VT100_EMUL_STATE_NORMAL);
                    717: }
                    718:
                    719: u_int
                    720: wsemul_vt100_output_esc_spc(edp, c)
                    721:        struct wsemul_vt100_emuldata *edp;
                    722:        u_char c;
                    723: {
                    724:        switch (c) {
                    725:        case 'F': /* 7-bit controls */
                    726:        case 'G': /* 8-bit controls */
                    727: #ifdef VT100_PRINTNOTIMPL
                    728:                printf("ESC<SPC>%c ignored\n", c);
                    729: #endif
                    730:                break;
                    731:            default:
                    732: #ifdef VT100_PRINTUNKNOWN
                    733:                printf("ESC<SPC>%c unknown\n", c);
                    734: #endif
                    735:                break;
                    736:        }
                    737:        return (VT100_EMUL_STATE_NORMAL);
                    738: }
                    739:
                    740: u_int
                    741: wsemul_vt100_output_string(edp, c)
                    742:        struct wsemul_vt100_emuldata *edp;
                    743:        u_char c;
                    744: {
                    745:        if (edp->dcstype && edp->dcspos < DCS_MAXLEN)
                    746:                edp->dcsarg[edp->dcspos++] = c;
                    747:        return (VT100_EMUL_STATE_STRING);
                    748: }
                    749:
                    750: u_int
                    751: wsemul_vt100_output_string_esc(edp, c)
                    752:        struct wsemul_vt100_emuldata *edp;
                    753:        u_char c;
                    754: {
                    755:        if (c == '\\') { /* ST complete */
                    756:                wsemul_vt100_handle_dcs(edp);
                    757:                return (VT100_EMUL_STATE_NORMAL);
                    758:        } else
                    759:                return (VT100_EMUL_STATE_STRING);
                    760: }
                    761:
                    762: u_int
                    763: wsemul_vt100_output_dcs(edp, c)
                    764:        struct wsemul_vt100_emuldata *edp;
                    765:        u_char c;
                    766: {
                    767:        u_int newstate = VT100_EMUL_STATE_DCS;
                    768:
                    769:        switch (c) {
                    770:        case '0': case '1': case '2': case '3': case '4':
                    771:        case '5': case '6': case '7': case '8': case '9':
                    772:                /* argument digit */
                    773:                if (edp->nargs > VT100_EMUL_NARGS - 1)
                    774:                        break;
                    775:                edp->args[edp->nargs] = (edp->args[edp->nargs] * 10) +
                    776:                    (c - '0');
                    777:                break;
                    778:        case ';': /* argument terminator */
                    779:                edp->nargs++;
                    780:                break;
                    781:            default:
                    782:                edp->nargs++;
                    783:                if (edp->nargs > VT100_EMUL_NARGS) {
                    784: #ifdef VT100_DEBUG
                    785:                        printf("vt100: too many arguments\n");
                    786: #endif
                    787:                        edp->nargs = VT100_EMUL_NARGS;
                    788:                }
                    789:                newstate = VT100_EMUL_STATE_STRING;
                    790:                switch (c) {
                    791:                case '$':
                    792:                        newstate = VT100_EMUL_STATE_DCS_DOLLAR;
                    793:                        break;
                    794:                case '{': /* DECDLD soft charset */
                    795:                case '!': /* DECRQUPSS user preferred supplemental set */
                    796:                        /* 'u' must follow - need another state */
                    797:                case '|': /* DECUDK program F6..F20 */
                    798: #ifdef VT100_PRINTNOTIMPL
                    799:                        printf("DCS%c ignored\n", c);
                    800: #endif
                    801:                        break;
                    802:                    default:
                    803: #ifdef VT100_PRINTUNKNOWN
                    804:                        printf("DCS%c (%d, %d) unknown\n", c, ARG(0), ARG(1));
                    805: #endif
                    806:                        break;
                    807:                }
                    808:        }
                    809:
                    810:        return (newstate);
                    811: }
                    812:
                    813: u_int
                    814: wsemul_vt100_output_dcs_dollar(edp, c)
                    815:        struct wsemul_vt100_emuldata *edp;
                    816:        u_char c;
                    817: {
                    818:        switch (c) {
                    819:        case 'p': /* DECRSTS terminal state restore */
                    820:        case 'q': /* DECRQSS control function request */
                    821: #ifdef VT100_PRINTNOTIMPL
                    822:                printf("DCS$%c ignored\n", c);
                    823: #endif
                    824:                break;
                    825:        case 't': /* DECRSPS restore presentation state */
                    826:                switch (ARG(0)) {
                    827:                case 0: /* error */
                    828:                        break;
                    829:                case 1: /* cursor information restore */
                    830: #ifdef VT100_PRINTNOTIMPL
                    831:                        printf("DCS1$t ignored\n");
                    832: #endif
                    833:                        break;
                    834:                case 2: /* tab stop restore */
                    835:                        edp->dcspos = 0;
                    836:                        edp->dcstype = DCSTYPE_TABRESTORE;
                    837:                        break;
                    838:                    default:
                    839: #ifdef VT100_PRINTUNKNOWN
                    840:                        printf("DCS%d$t unknown\n", ARG(0));
                    841: #endif
                    842:                        break;
                    843:                }
                    844:                break;
                    845:            default:
                    846: #ifdef VT100_PRINTUNKNOWN
                    847:                printf("DCS$%c (%d, %d) unknown\n", c, ARG(0), ARG(1));
                    848: #endif
                    849:                break;
                    850:        }
                    851:        return (VT100_EMUL_STATE_STRING);
                    852: }
                    853:
                    854: u_int
                    855: wsemul_vt100_output_esc_hash(edp, c)
                    856:        struct wsemul_vt100_emuldata *edp;
                    857:        u_char c;
                    858: {
                    859:        int i;
                    860:
                    861:        switch (c) {
                    862:        case '5': /*  DECSWL single width, single height */
                    863:                if (edp->dblwid != NULL && edp->dw != 0) {
                    864:                        for (i = 0; i < edp->ncols / 2; i++)
                    865:                                (*edp->emulops->copycols)(edp->emulcookie,
                    866:                                                          edp->crow,
                    867:                                                          2 * i, i, 1);
                    868:                        (*edp->emulops->erasecols)(edp->emulcookie, edp->crow,
                    869:                                                   i, edp->ncols - i,
                    870:                                                   edp->bkgdattr);
                    871:                        edp->dblwid[edp->crow] = 0;
                    872:                        edp->dw = 0;
                    873:                }
                    874:                break;
                    875:        case '6': /*  DECDWL double width, single height */
                    876:        case '3': /*  DECDHL double width, double height, top half */
                    877:        case '4': /*  DECDHL double width, double height, bottom half */
                    878:                if (edp->dblwid != NULL && edp->dw == 0) {
                    879:                        for (i = edp->ncols / 2 - 1; i >= 0; i--)
                    880:                                (*edp->emulops->copycols)(edp->emulcookie,
                    881:                                                          edp->crow,
                    882:                                                          i, 2 * i, 1);
                    883:                        for (i = 0; i < edp->ncols / 2; i++)
                    884:                                (*edp->emulops->erasecols)(edp->emulcookie,
                    885:                                                           edp->crow,
                    886:                                                           2 * i + 1, 1,
                    887:                                                           edp->bkgdattr);
                    888:                        edp->dblwid[edp->crow] = 1;
                    889:                        edp->dw = 1;
                    890:                        if (edp->ccol > (edp->ncols >> 1) - 1)
                    891:                                edp->ccol = (edp->ncols >> 1) - 1;
                    892:                }
                    893:                break;
                    894:        case '8': { /* DECALN */
                    895:                int i, j;
                    896:                for (i = 0; i < edp->nrows; i++)
                    897:                        for (j = 0; j < edp->ncols; j++)
                    898:                                (*edp->emulops->putchar)(edp->emulcookie, i, j,
                    899:                                                         'E', edp->curattr);
                    900:                }
                    901:                edp->ccol = 0;
                    902:                edp->crow = 0;
                    903:                break;
                    904:            default:
                    905: #ifdef VT100_PRINTUNKNOWN
                    906:                printf("ESC#%c unknown\n", c);
                    907: #endif
                    908:                break;
                    909:        }
                    910:        return (VT100_EMUL_STATE_NORMAL);
                    911: }
                    912:
                    913: u_int
                    914: wsemul_vt100_output_csi(edp, c)
                    915:        struct wsemul_vt100_emuldata *edp;
                    916:        u_char c;
                    917: {
                    918:        u_int newstate = VT100_EMUL_STATE_CSI;
                    919:
                    920:        switch (c) {
                    921:        case '0': case '1': case '2': case '3': case '4':
                    922:        case '5': case '6': case '7': case '8': case '9':
                    923:                /* argument digit */
                    924:                if (edp->nargs > VT100_EMUL_NARGS - 1)
                    925:                        break;
                    926:                edp->args[edp->nargs] = (edp->args[edp->nargs] * 10) +
                    927:                    (c - '0');
                    928:                break;
                    929:        case ';': /* argument terminator */
                    930:                edp->nargs++;
                    931:                break;
                    932:        case '?': /* DEC specific */
                    933:        case '>': /* DA query */
                    934:                edp->modif1 = c;
                    935:                break;
                    936:        case '!':
                    937:        case '"':
                    938:        case '$':
                    939:        case '&':
                    940:                edp->modif2 = c;
                    941:                break;
                    942:            default: /* end of escape sequence */
                    943:                edp->nargs++;
                    944:                if (edp->nargs > VT100_EMUL_NARGS) {
                    945: #ifdef VT100_DEBUG
                    946:                        printf("vt100: too many arguments\n");
                    947: #endif
                    948:                        edp->nargs = VT100_EMUL_NARGS;
                    949:                }
                    950:                wsemul_vt100_handle_csi(edp, c);
                    951:                newstate = VT100_EMUL_STATE_NORMAL;
                    952:                break;
                    953:        }
                    954:        return (newstate);
                    955: }
                    956:
                    957: void
                    958: wsemul_vt100_output(cookie, data, count, kernel)
                    959:        void *cookie;
                    960:        const u_char *data;
                    961:        u_int count;
                    962:        int kernel;
                    963: {
                    964:        struct wsemul_vt100_emuldata *edp = cookie;
                    965: #ifdef JUMP_SCROLL
                    966:        const u_char *eot;
                    967:        u_char curchar;
                    968:        u_int cnt, pos, lines;
                    969: #endif
                    970:
                    971: #ifdef DIAGNOSTIC
                    972:        if (kernel && !edp->console)
                    973:                panic("wsemul_vt100_output: kernel output, not console");
                    974: #endif
                    975:
                    976:        if (edp->flags & VTFL_CURSORON)
                    977:                (*edp->emulops->cursor)(edp->emulcookie, 0,
                    978:                                edp->crow, edp->ccol << edp->dw);
                    979:
                    980:        for (; count > 0; data++, count--) {
                    981: #ifdef JUMP_SCROLL
                    982:                /*
                    983:                 * If we are at the bottom of the scrolling area, count
                    984:                 * newlines until an escape sequence appears.
                    985:                 */
                    986:                if ((edp->state == VT100_EMUL_STATE_NORMAL || kernel) &&
                    987:                    ROWS_BELOW == 0) {
                    988:                        lines = 0;
                    989:                        pos = edp->ccol;
                    990:                        for (eot = data, cnt = count; cnt != 0; eot++, cnt--) {
                    991:                                curchar = *eot;
                    992:                                /*
                    993:                                 * Only char for which
                    994:                                 * wsemul_vt100_output_c0c1() will switch
                    995:                                 * to escape mode, for now.
                    996:                                 * Revisit this when this changes...
                    997:                                 */
                    998:                                if (curchar == ASCII_ESC)
                    999:                                        break;
                   1000:
                   1001:                                if (ISSET(edp->flags, VTFL_DECAWM))
                   1002:                                    switch (curchar) {
                   1003:                                    case ASCII_BS:
                   1004:                                        if (pos > 0)
                   1005:                                                pos--;
                   1006:                                        break;
                   1007:                                    case ASCII_CR:
                   1008:                                        pos = 0;
                   1009:                                        break;
                   1010:                                    case ASCII_HT:
                   1011:                                        if (edp->tabs) {
                   1012:                                                pos++;
                   1013:                                                while (pos < NCOLS - 1 &&
                   1014:                                                    edp->tabs[pos] == 0)
                   1015:                                                        pos++;
                   1016:                                        } else {
                   1017:                                                pos = (pos + 7) & ~7;
                   1018:                                                if (pos >= NCOLS)
                   1019:                                                        pos = NCOLS - 1;
                   1020:                                        }
                   1021:                                        break;
                   1022:                                    default:
                   1023:                                        if ((curchar & 0x7f) < 0x20)
                   1024:                                                break;
                   1025:                                        if (pos++ >= NCOLS) {
                   1026:                                                pos = 0;
                   1027:                                                curchar = ASCII_LF;
                   1028:                                        }
                   1029:                                        break;
                   1030:                                    }
                   1031:
                   1032:                                if (curchar == ASCII_LF ||
                   1033:                                    curchar == ASCII_VT ||
                   1034:                                    curchar == ASCII_FF) {
                   1035:                                        if (++lines >= edp->scrreg_nrows - 1)
                   1036:                                                break;
                   1037:                                }
                   1038:                        }
                   1039:
                   1040:                        if (lines > 1) {
                   1041:                                wsemul_vt100_scrollup(edp, lines);
                   1042:                                edp->crow -= lines;
                   1043:                        }
                   1044:                }
                   1045: #endif
                   1046:
                   1047:                if ((*data & 0x7f) < 0x20) {
                   1048:                        wsemul_vt100_output_c0c1(edp, *data, kernel);
                   1049:                        continue;
                   1050:                }
                   1051:
                   1052:                if (edp->state == VT100_EMUL_STATE_NORMAL || kernel) {
                   1053:                        wsemul_vt100_output_normal(edp, *data, kernel);
                   1054:                        continue;
                   1055:                }
                   1056: #ifdef DIAGNOSTIC
                   1057:                if (edp->state > sizeof(vt100_output) / sizeof(vt100_output[0]))
                   1058:                        panic("wsemul_vt100: invalid state %d", edp->state);
                   1059: #endif
                   1060:                edp->state = vt100_output[edp->state - 1](edp, *data);
                   1061:        }
                   1062:
                   1063:        if (edp->flags & VTFL_CURSORON)
                   1064:                (*edp->emulops->cursor)(edp->emulcookie, 1,
                   1065:                                edp->crow, edp->ccol << edp->dw);
                   1066: }

CVSweb