/* * Copyright 1982 UniSoft Corporation * Use of this material is subject to your disclosure agreement with * AT&T, Western Electric and UniSoft Corporation. * * VT100 emulator * Called with each character destined for the console. * Processes control sequences and keeps track of terminal state. * Calls into bitmap.c actually do the I/O */ /* SENSESCRN resets the contrast on screen output (via the console device * driver) as if a key was hit. */ #include "sys/types.h" #include "sys/l2.h" #define FAST #define SENSESCRN #define MAXVT_N 255 /* maximum value of any numeric parameter */ #define MAXPARAMS 10 /* maximum number of numeric parameters */ short vt_n[MAXPARAMS]; /* numeric parameters of \E[ commands */ char vt_mparam; char vt_tabset[88] = { 0 }; extern char bmbck, bmcolor, bmnormal; extern char *bmscrn; extern char kb_altkp; short vt_maxrow = 38; short vt_maxcol = 88; short vt_row, vt_col; /* cursor location (0-vt_maxrow, 0-vt_maxcol) */ short vtrow_ofs = 1; short vtcol_ofs = 1; /* row and column offsets */ short vt_winscrl = 1; /* lines to scroll each time */ /* This routine interprets the characters destined for the console and * performs like a VT100 . It is implemented in terms of primitives * defined in bitmap.c */ #define CBKSP 1 #define CCR 2 #define CLF 3 #define CHTAB 4 #define CESC 5 #define CBELL 6 #define CGARB 7 #define CCHAR 8 char vt_keytype[] = { CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CBELL, CBKSP, CHTAB, CLF, CLF, CLF, CCR, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CGARB, CESC, CGARB, CGARB, CGARB, CGARB, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CCHAR, CGARB, }; vt_putc (c) register char c; { extern int (*te_putc)(); int vt_esc(); int x; extern time_t lbolt; l2_dtrap = lbolt + l2_dtime; if (l2_dimmed) l2undim(); if (c >= ' ') { bmputc(vt_row+vtrow_ofs,vt_col+vtcol_ofs,c); vt_advance(); bminvert (vt_row+vtrow_ofs, vt_col+vtcol_ofs); return; } bminvert (vt_row+vtrow_ofs, vt_col+vtcol_ofs); switch (vt_keytype[c]) { case CBKSP: if (vt_col > 0) vt_col--; break; case CCR: vt_col = 0; break; case CLF: if (++vt_row >= vt_maxrow) { blt(bmscrn+90*9,bmscrn+90*9*2,9*90*38); vt_row -= vt_winscrl; } break; case CHTAB: for ( x = vt_col+1; x < vt_maxcol-1 ; x++ ) if ( vt_tabset[x] == 1 ) break; vt_col = x; break; case CESC: te_putc = vt_esc; break; case CBELL: beep(); break; case CGARB: break; } bminvert(vt_row+vtrow_ofs,vt_col+vtcol_ofs); } /* * Process the escape sequences to the terminal */ vt_esc(c) /* after ESC key hit */ register char c; { extern int (*te_putc)(); int vt_brck(), vt_putc(); switch (c) { case '[': te_putc = vt_brck; /* check E[ sequence */ return; case '>': /* disable alternate keypad */ kb_altkp = 0; break; case '=': /* enable alternate keypad */ kb_altkp = 1; break; case 'M': /* reverse scroll */ bminvert(vt_row+vtrow_ofs,vt_col+vtcol_ofs); bmrscrl(); bminvert(vt_row+vtrow_ofs,vt_col+vtcol_ofs); break; case 'H': vt_tabset[vt_col]=1; break; } te_putc = vt_putc; return; } vt_brck(c) /* \E[ sequence checked here */ register char c; { extern int (*te_putc)(); int vt_param(), vt_attrb(); vt_mparam = 0; vt_n[0] = vt_n[1] = 0; if (c == ';') { /* missing 1st number - look for 2nd */ te_putc = vt_param; vt_mparam++; return; } if (c >= '0' && c <= '9' ) { vt_n[0] = c - '0'; te_putc = vt_param; return; } if (c == '?') { te_putc = vt_attrb; return; } vt_cmd(c); } vt_param(c) register char c; { register tmp; int vt_putc(); if( c >= '0' && c <= '9' ) { tmp = (vt_n[vt_mparam] * 10) + (c - '0'); vt_n[vt_mparam] = (tmp > MAXVT_N) ? MAXVT_N : tmp; return; } if ( c == ';' ) { if (++vt_mparam >= MAXPARAMS) { /* too many parameters */ te_putc = vt_putc; return; } vt_n[vt_mparam] = 0; return; } vt_cmd(c); } vt_cmd(c) /* now have last char of esc sequence */ register char c; { extern int (*te_putc)(); register vt_n1 = vt_n[0]; register vt_n2 = vt_n[1]; register int x, y; int vt_putc(); if (c == 'f') c = 'H'; if ((c >= 'A') && (c <= 'Z')) { bminvert (vt_row+vtrow_ofs, vt_col+vtcol_ofs); switch (c) { case 'A': /* move cursor up */ if (vt_n1 == 0) vt_n1 = 1; vt_row = (vt_n1 < vt_row) ? (vt_row - vt_n1) : 0; break; case 'B': /* move cursor down */ if (vt_n1 == 0) vt_n1 = 1; y = vt_row + vt_n1; vt_row = (y < vt_maxrow) ? y : vt_maxrow-1; break; case 'C': /* move cursor right */ if (vt_n1 == 0) vt_n1 = 1; y = vt_col + vt_n1; vt_col = (y < vt_maxcol) ? y : vt_maxcol-1; break; case 'D': /* move cursor left */ if (vt_n1 == 0) vt_n1 = 1; vt_col = (vt_n1 < vt_col) ? (vt_col - vt_n1) : 0; break; case 'H': /* move cursor home */ if (vt_n1 == 0) vt_row = 0; else if ((vt_row = vt_n1-1) >= vt_maxrow) vt_row = vt_maxrow - 1; if (vt_n2 == 0) vt_col = 0; else if ((vt_col = vt_n2-1) >= vt_maxcol) vt_col = vt_maxcol - 1; break; case 'J': /* clear screen */ if (vt_n1 == 0) if ((vt_row == 0) && (vt_col == 0)) vt_n1 = 2; switch (vt_n1) { case 0: /* clear from cursor to end */ for (y = vt_col ; y < vt_maxcol ; y++ ) bmputc(vt_row+vtrow_ofs,y+vtcol_ofs,' '); for (x = vt_row+1; x < vt_maxrow ; x++ ) bmblank(x+vtrow_ofs); break; case 1: /* clear from beginning to cursor */ for (x = 0; x < vt_row ; x++ ) bmblank(x+vtrow_ofs); for (y = 0; y <= vt_col ; y++ ) bmputc(vt_row+vtrow_ofs,y+vtcol_ofs,' '); break; case 2: /* clear entire screen */ bmclear(); } break; case 'K': /* clear line */ switch (vt_n1) { case 0: /* clear from cursor to end */ for (y = vt_col ; y < vt_maxcol ; y++ ) bmputc(vt_row+vtrow_ofs,y+vtcol_ofs,' '); break; case 1: /* clear from beginning to cursor */ for (y = 0 ; y <= vt_col ; y++ ) bmputc(vt_row+vtrow_ofs,y+vtcol_ofs,' '); break; case 2: /* clear entire line */ bmblank(vt_row+vtrow_ofs); } break; case 'L': /* insert line(s) */ if (vt_n1 == 0) vt_n1 = 1; if (vt_n1 > vt_maxrow - vt_row) vt_n1 = vt_maxrow - vt_row; for (x=vt_maxrow-1, y=vt_maxrow-vt_n1-1; y >= vt_row; x--, y--) bmcpl(x+vtrow_ofs, y+vtrow_ofs); for ( ; x >= vt_row ; x-- ) bmblank(x+vtrow_ofs); break; case 'M': /* delete line(s) */ if (vt_n1 == 0) vt_n1 = 1; if (vt_n1 > vt_maxrow - vt_row) vt_n1 = vt_maxrow - vt_row; for (x=vt_row, y=vt_row+vt_n1; y < vt_maxrow; x++, y++) bmcpl(x+vtrow_ofs, y+vtrow_ofs); for ( ; x < vt_maxrow ; x++ ) bmblank(x+vtrow_ofs); break; case 'P': /* delete character(s) */ if (vt_n1 == 0) vt_n1 = 1; if (vt_n1 > vt_maxcol - vt_col) vt_n1 = vt_maxcol - vt_col; for (x=vt_col, y=vt_col+vt_n1; y < vt_maxcol; x++, y++) bmmvc(vt_row+vtrow_ofs, x+vtcol_ofs, vt_row+vtrow_ofs, y+vtcol_ofs); for ( ; x < vt_maxcol ; x++ ) bmputc(vt_row+vtrow_ofs,x+vtcol_ofs,' '); break; } bminvert (vt_row+vtrow_ofs, vt_col+vtcol_ofs); } else { switch (c) { case 'g': if (vt_n1 == 0) vt_tabset[vt_col] = 0; else if (vt_n1 == 3) for (x = 0 ; x < vt_maxcol ; x++ ) vt_tabset[x] = 0; break; case 'm': /* set normal display or reverse video */ for (x = 0; x <= vt_mparam; x++) switch (vt_n[x]) { case 0: /* turn underline off, set normal background */ if (bmbck != bmnormal) { bmswitch(); /* invert font table */ bmbck = bmnormal; } bmcolor = bmbck; /* underline off */ break; case 1: case 7: /* set reverse image */ if (bmbck == bmnormal) { bmswitch(); /* invert font table */ bmbck = bmnormal ? 0 : -1; } break; case 4: /* set underline */ bmcolor = bmbck ? 0 : -1; } break; } } te_putc = vt_putc; } vt_attrb(c) /* \E[? */ char c; { int vt_atrb(), vt_putc(); if(c >= '0' && c <= '9') te_putc = vt_atrb; else te_putc = vt_putc; } vt_atrb() { int vt_putc(); te_putc = vt_putc; } vt_advance() { if (++vt_col >= vt_maxcol) { /* wraps around */ vt_col = 0; if (++vt_row >= vt_maxrow) { /* on last line */ blt(bmscrn+90*9,bmscrn+90*9*2,9*90*38); vt_row -= vt_winscrl; } } }