/*
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;
}
}