Metropoli BBS
VIEWER: vt100.c MODE: TEXT (ASCII)
/*
Copyright (C) Magna Carta Software, Inc. 1990, 1991.  All Rights Reserved.
C COMMUNICATIONS TOOLKIT
VT100.C -- VT100 terminal emulation routines.
*/

#define CCT_DEVELOPMENT
#if (defined(CCTW) || defined(_WINDOWS))
    #include <windows.h>
#endif
#include <comm.h>
#include <ansi.h>
#include <vt.h>


/*
VT100_INIT -- Memory initialization of DEC VT100 (assumes ANSI mode).
*/
void vt100_init(TERMINAL *t)
{
    t->type             = DEC_VT100;
    t->att              = 7;
    t->csi              = 0X1B;
    t->cur_pos          = ansi_cursor_;
    t->d_att            = 7;
    t->d_rows           = 24;
    t->d_cols           = 80;
    t->delim1           = ';';
    t->dispatch_ctrl    = vt_dispatch_ctrl_;
    t->erase            = ansi_erase_;
    t->mode             = DECANM;
    t->offset           = 1;
    t->parse_cmd        = ansi_parse_cmd_;
    t->parse_parms      = term_ascii_parse_parms_;
    t->reset_mode       = vt_reset_mode_;
    t->set_mode         = vt_set_mode_;
    t->sgr              = ansi_sgr_;

    /* KEYSTROKES */
    if (enhanced_kbd) {
        /* IF THE ENHANCED KEYBOARD IS PRESENT AND HAS BIOS SUPPORT, USE IT */
        term_assign_key(t, GREY_UP_ARROW,    0, "\x1B[A");
        term_assign_key(t, GREY_DOWN_ARROW,  0, "\x1B[B");
        term_assign_key(t, GREY_RIGHT_ARROW, 0, "\x1B[C");
        term_assign_key(t, GREY_LEFT_ARROW,  0, "\x1B[D");
    }
    else {
        term_assign_key(t, S_UP_ARROW,    0, "\x1B[A");
        term_assign_key(t, S_DOWN_ARROW,  0, "\x1B[B");
        term_assign_key(t, S_RIGHT_ARROW, 0, "\x1B[C");
        term_assign_key(t, S_LEFT_ARROW,  0, "\x1B[D");
    }
    term_assign_key(t, F1,          0, "\x1BOP");
    term_assign_key(t, F2,          0, "\x1BOQ");
    term_assign_key(t, F3,          0, "\x1BOR");
    term_assign_key(t, F4,          0, "\x1BOS");
    term_assign_key(t, BACKSPACE,   0, "\x7F");

    vt100_private_(t, MODE_DECKPAM);        /* assign auxilliary keypad keys */

    /* === RECEIVED COMMANDS === */
    /* CURSOR CONTROL */
    term_assign_cmd(t, CUU, "[%A",   ansi_cursor_, NULL);
    term_assign_cmd(t, CUD, "[%B",   ansi_cursor_, NULL);
    term_assign_cmd(t, CUF, "[%C",   ansi_cursor_, NULL);
    term_assign_cmd(t, CUB, "[%D",   ansi_cursor_, NULL);
    term_assign_cmd(t, CUP, "[%;%H", ansi_cursor_, NULL);
    term_assign_cmd(t, HVP, "[%;%f", ansi_cursor_, NULL);

    term_assign_cmd(t, HTS, "H", (void (*)(TERMINAL *, short)) ansi_hts_, NULL);       /* horizontal tab set */
    term_assign_cmd(t, TBC, "[%g", (void (*)(TERMINAL *, short)) ansi_tbc_, NULL);     /* tabulation clear */
    term_assign_cmd(t, IND, "D", ansi_cursor_, NULL);    /* down one line */
    term_assign_cmd(t, NEL, "E", ansi_cursor_, NULL);    /* next line */
    term_assign_cmd(t, HTS, "M", ansi_cursor_, NULL);    /* reverse index */

    /* ERASE IN DISPLAY */
    term_assign_cmd(t, EED0,"[J",  ansi_erase_, NULL);
    term_assign_cmd(t, EED1,"[0J", ansi_erase_, NULL);
    term_assign_cmd(t, EBD, "[1J", ansi_erase_, NULL);
    term_assign_cmd(t, ED,  "[2J", ansi_erase_, NULL);

    /* ERASE IN LINE */
    term_assign_cmd(t, EEL0, "[K",  ansi_erase_, NULL);
    term_assign_cmd(t, EEL1, "[0K", ansi_erase_, NULL);
    term_assign_cmd(t, EBL,  "[1K", ansi_erase_, NULL);
    term_assign_cmd(t, EL,   "[2K", ansi_erase_, NULL);

    /* STATUS REPORTS */
    term_assign_cmd(t, TDSR,  "[5n", (void (*)(TERMINAL *, short)) NULL, "\x1B[0n");
    term_assign_cmd(t, CPR,   "[6n", (void (*)(TERMINAL *, short)) ansi_cpr_, NULL);
    term_assign_cmd(t, DA,    "[%c", (void (*)(TERMINAL *, short)) NULL, "\x1B[?1;0c");
    term_assign_cmd(t, TERMID,"Z",   (void (*)(TERMINAL *, short)) NULL, "\x1B[?1;0c");

    term_assign_cmd(t, RIS,         "c",      (void (*)(TERMINAL *, short)) ansi_reset_,   NULL);
    term_assign_cmd(t, RM,          "[?%;%l", vt_reset_mode_,NULL);
    term_assign_cmd(t, SGR,         "[%;%m",  (void (*)(TERMINAL *, short)) ansi_sgr_,     NULL);
    term_assign_cmd(t, SM,          "[?%;%h", vt_set_mode_,  NULL);
    term_assign_cmd(t, MODE_DECKPAM,"=",      vt100_private_,NULL);
    term_assign_cmd(t, MODE_DECKPNM,">",      vt100_private_,NULL);
    term_assign_cmd(t, MODE_DECANM, "<",      vt_set_mode_,  NULL);
    term_assign_cmd(t, MODE_DECRC,  "8",      vt100_private_,NULL);
    term_assign_cmd(t, MODE_DECSC,  "7",      vt100_private_,NULL);
    term_assign_cmd(t, MODE_DECSTBM,"[%;%r",  vt100_private_,NULL);
    term_assign_cmd(t, MODE_DECSWL, "#5",     vt100_private_,NULL);
}



/*
VT100_PRIVATE -- Function to handle DEC private sequences for the VTxxx line
of terminals.
*/
void vt100_private_(TERMINAL *t, short cmd)
{
    switch (cmd) {
        case MODE_DECKPAM:                  /* keypad application mode */
            if (isansi_(t)) {
                term_assign_key(t, PLUS,        0, "\x1BOl");   /* VT100 comma */
                term_assign_key(t, MINUS,       0, "\x1BOm");
                term_assign_key(t, KP_ENTER,    0, "\x1BOM");
                term_assign_key(t, DELETE,      0, "\x1BOn");
                term_assign_key(t, INSERT,      0, "\x1BOp");
                term_assign_key(t, END,         0, "\x1BOq");
                term_assign_key(t, DOWN_ARROW,  0, "\x1BOr");
                term_assign_key(t, PAGE_DOWN,   0, "\x1BOs");
                term_assign_key(t, LEFT_ARROW,  0, "\x1BOt");
                term_assign_key(t, KP_5,        0, "\x1BOu");
                term_assign_key(t, RIGHT_ARROW, 0, "\x1BOv");
                term_assign_key(t, HOME,        0, "\x1BOw");
                term_assign_key(t, UP_ARROW,    0, "\x1BOx");
                term_assign_key(t, PAGE_UP,     0, "\x1BOy");
            }
            else {
                term_assign_key(t, PLUS,        0, "\x1B?l");  /* VT52 comma */
                term_assign_key(t, MINUS,       0, "\x1BOm");
                term_assign_key(t, KP_ENTER,    0, "\x1B?M");
                term_assign_key(t, DELETE,      0, "\x1B?n");
                term_assign_key(t, INSERT,      0, "\x1B?p");
                term_assign_key(t, END,         0, "\x1B?q");
                term_assign_key(t, DOWN_ARROW,  0, "\x1B?r");
                term_assign_key(t, PAGE_DOWN,   0, "\x1B?s");
                term_assign_key(t, LEFT_ARROW,  0, "\x1B?t");
                term_assign_key(t, KP_5,        0, "\x1B?u");
                term_assign_key(t, RIGHT_ARROW, 0, "\x1B?v");
                term_assign_key(t, HOME,        0, "\x1B?w");
                term_assign_key(t, UP_ARROW,    0, "\x1B?x");
                term_assign_key(t, PAGE_UP,     0, "\x1B?y");
            }
            break;

        case MODE_DECKPNM:                  /* keypad numeric mode */
            term_assign_key(t, PLUS,        0, ",");   /* VT100 comma */
            term_assign_key(t, MINUS,       0, "-");
            if (isaddlf_(t)) term_assign_key(t, KP_ENTER, 0, "\r\n");
            else term_assign_key(t, KP_ENTER,  0, "\r");
            term_assign_key(t, DELETE,      0, ".");
            term_assign_key(t, INSERT,      0, "0");
            term_assign_key(t, END,         0, "1");
            term_assign_key(t, DOWN_ARROW,  0, "2");
            term_assign_key(t, PAGE_DOWN,   0, "3");
            term_assign_key(t, LEFT_ARROW,  0, "4");
            term_assign_key(t, KP_5,        0, "5");
            term_assign_key(t, RIGHT_ARROW, 0, "6");
            term_assign_key(t, HOME,        0, "7");
            term_assign_key(t, UP_ARROW,    0, "8");
            term_assign_key(t, PAGE_UP,     0, "9");
            break;

        case MODE_DECRC:                    /* restore cursor */
            t->crow = t->crowold;
            t->ccol = t->ccolold;
            (*t->cur_pos_)(t, t->ccol, t->crow);
            break;

        case MODE_DECSC:                    /* save cursor */
            t->crowold = t->crow;
            t->ccolold = t->ccol;
            break;

        case MODE_DECSCL:                   /* compatibility level */
            switch (t->num[0]) {
                case 61:
                    if (t->type != DEC_VT100)
                        init_term(t->port, t, (void (*)()) vt100_init, t->vid_init);
                    break;

                case 62:
                    if (t->num[1] == 0 || t->num[1] == 2) {
                        if (t->databits != 8) {
#if XDEBUG
                            printf("HOST: Requested 8-bit controls on < 8-bit line");
#endif
                        }
                        else {
                            /* set to 8-bit mode */
                        }
                    }
                    else if (t->num[1] == 1) {
                        if (t->type != DEC_VT220)
                            init_term(t->port, t, (void (*)()) vt220_init, t->vid_init);
                        if (t->databits != 7) (*t->set_databits)(t, 8);
                    }

                    break;

                default:
#if XDEBUG
                    printf("HOST: Tried to set unknown compatibility level");
#endif
                    break;
            }
            break;

        case MODE_DECSTBM:                  /* set top and bottom margins */
            if (t->num[0] < t->num[1]) {
                t->tmargin = (t->num[0] == 0) ? 0 : t->num[0]-1;
                t->bmargin = (t->num[1] == 0) ? t->d_rows - 1 : t->num[1]-1;
                t->ccol = t->crow = 0;
            }
            else {
                t->tmargin = t->ctmargin = 0;
                t->bmargin = t->cbmargin = t->d_rows - 1;
            }
            if (isdecom_(t)) {
                t->cbmargin = t->bmargin;
                t->ccol = t->clmargin = t->lmargin;
                t->crow = t->ctmargin = t->tmargin;
            }
            (*t->cur_pos_)(t, t->ccol, t->crow);
            break;

        case MODE_DECSWL:                   /* single width line */
            break;

        case MODE_DECANM:                   /* enter ANSI mode */
            t->mode |= DECANM;
            break;

        default:
#if XDEBUG
            printf("Unknown DEC Private command %s", t->cmdbuf);
#endif
            break;
    }
}

[ RETURN TO DIRECTORY ]