/* vt.c VT100 video terminal routine library last changed 24-sep-86 Harold Z. Bencowitz ****************************************************************************** directory: |vtansi() ansi mode |vt52() vt52 mode vtbox(row, col, w, h) make box, line drawing set vtcln(r1, r2) clear rows vtclr(n) clear screen |vtcsav() save cursor |vtcres() restore cursor |vtdark() dark screen |vtrev() reverse video vtdouble(row, col, n, s)* write text in double size vtdown(s1, s2) down load character set |vtdsc(n, c) designate character set |vtscs(n) select character set vtebox(r, c, nc, fc, s, a, s0)* get entry from box vterln(n) erase line vterror() error message |vtgraf() graphics characters |vtnogf() graphics characters off vtgrid(row, col, w, h, a, d) make grid, line drawing set vthome() home cursor vtindx(n) index/reverse index ie scroll down/up |vtjump() jump scrolling |vtsmoo() smooth scrolling vtmbox(row, col, ncol, c)* write a 1 line high box vtmenu(row, col) get reply to menu vtmode(n) set attributes vtmova(row, column) * move cursor absolute vtmovr(n, k) * move cursor relative vtnext() next line vtrbox(nc, fc, is, a, s0) get entry from box, from current position vtrmbox(nc, fc) make box for vtrbox() |vtroll(top, bottom) scroll area |vtnoro() clear scroll area |vtrset() hard reset |vtsrst() soft reset vtttid() identify terminal vttxt(row, column, t) * write text on a line |vtwrap() wraparound mode |vtnowp() wraparound mode off |vt80() 80 columns |vt132() 132 columns vt0_9() down load characters 0 - 9 working(row) flash "working" * these will not work properly with 132 column display *****************************************************************************/ #include #include #define BASE 48 /****************************************************************************/ int vtebox(row, column, ncol, fc, is, address, s0) /* entry box - allow entry to a one line high box starting at row, column which is ncol wide. is is an instruction string "i", "u", "d", "s", "n" for int, unsigned, double, string, or numeric string respectively. address is the address at which to deposit the answer. video mode must be set before. fc is the fill character for the box. s0 is the string to place in the box at the beginning. returns the terminator key (\n, \b, or \t), -1 if bad arguments, or -(terminator key) if no data was entered. The latter allows one to distinguish from "0" entered vs no entry. right and left arrows can be used to move one character within the input string, up and down arrows can be used to move to the beginning or end of the input string respectively. */ int row, column, ncol, fc; char *is, *address, *s0; { register char s[81]; char *cpystr(), cget(), is0, *fs; register int itop, p; int i, c, nn, entry, *pi; int encode(), vtmova(), istsx(), call_emt(); unsigned lenstr(), ijob; double *pd; fs = "%- nb"; /* format for putstr below */ /* * test arguments */ if(row < 1 || row > 24) return(-1); if(column < 1 || column > 80) return(-1); if(ncol < 1) return(-1); if(ncol + column > 81) ncol = 81 - column; if(address == NULL) return(-1); is0 = is[0]; if(is0 != 'i' && is0 != 'd' && is0 != 's' && is0 != 'n' \ && is0 != 'u') return(-1); /* * move to position, initialize */ vtmova(row, column); p = itop = lenstr(s0); if(itop > 0) { fs[2] = fc; /* fs = "%- nb"; */ errfmt(fs, ncol, s0, itop); vtmova(row, column + (itop >= ncol ? ncol - 1 : itop)); cpystr(s, s0, NULL); } /* * set TSX singlechar mode */ if(istsx()) /* if running TSX+ */ i = call_emt(0152, 0, 'S'); /* set singlechar mode */ /* * vt100 to special mode */ ijob = JSW; JSW = ijob | 010000; /* * input characters */ while((c = cget()) != '\n' && c != '\b' && c != '\t') { if(c == ESCAPE) { if((c = cget()) == '[') { if((c = cget()) == 'C') { /* right */ if(p < itop) p++; } else if(c == 'D') { /* left */ if(p > 0) p--; } else if(c == 'A') /* up */ p = 0; else if(c == 'B') /* down */ p = itop; else if(c == '2') { /* vt200 F12 = BS */ if((c = cget()) == '4') { if((c = cget()) == '~') { c = '\b'; break; } } } } } else if(c == '\177' && p > 0) { /* delete */ for(i = p; i <= itop - 1; i++) { s[i-1] = s[i]; } --itop; --p; } else if(isdigit(c) || \ ((c == '+' || c == '-') && p == 0 && is0 != 'n' && is0 !='u')||\ (c == '.' && is0 == 'd') || \ (c == '-' && is0 == 'n') || \ ((c >= ' ' && c <= '~') && is0 == 's')) { for(i = itop - 1; i >= p; i--) { s[i+1] = s[i]; } s[p++] = c; itop++; if(itop > ncol) { for(i = 0; i < ncol; i++) s[i] = s[i + 1]; itop--; if(p > 0) p--; } } else continue; nn = column + (p >= ncol ? ncol - 1 : p); fs[2] = fc; /* fs = "%- nb"; */ vtmova(row, column); errfmt(fs, ncol, s, itop); vtmova(row, nn); } /* * vt100 to normal mode */ JSW = ijob; /* * finish processing the input string */ entry = (itop > 0 ? c : -(c)); if(is0 == 's') { s[itop] = '\0'; cpystr(address, s, NULL); return(entry); } else if(is0 == 'n') { s[itop] = '\0'; cpystr(address, s, NULL); return(entry); } else if(is0 == 'i') { if(itop != 0) encode(s, itop, "%i", address); else { pi = address; *pi = 0; } return(entry); } else if(is0 == 'u') { if(itop != 0) encode(s, itop, "%ui", address); else encode("0", 1, "%ui", address); return(entry); } else { /* is0 == 'd' */ if(itop != 0) encode(s, itop, "%d", address); else { pd = address; *pd = 0.; } return(entry); } } /****************************************************************************/ int vtmbox(row, column, ncol, c) /* write a 1 line high box starting at row, column which is ncol wide and filled with character c. video mode must be set before calling. */ register int column, ncol; int row, c; { int vtmova(); register int i; if(row < 1 || row > 24) return; if(column < 1 || column > 80) return; if(ncol + column > 81) ncol = 80 - column + 1; vtmova(row, column); for(i = 0; i < ncol; i++) errfmt("%ai", c); } /****************************************************************************/ int vtansi() /* ansi mode */ { static char s[] = "<"; /* $< */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vt52() /* vt52 mode */ { static char s[] = "[?2l"; /* $[?2l */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtbox(row, column, width, height) /* draw a box using the vt100/vt200 special graphics character set. row and column are the location of the upper left corner. width and height are the width and height not including the outer character cells of the box, ie the smallest box is 0, 0. */ int row, column, width, height; { char s1[81], s2[81], s3[81]; register int i, k; int vtdcs(), vtmova(); /* * make top string */ k = 0; s1[k++] = 'l'; for(i = 0; i < width; i++) s1[k++] = 'q'; s1[k++] = 'k'; s1[k] = '\0'; /* * make sides string */ k = 0; s2[k++] = 'x'; for(i = 0; i < width; i++) s2[k++] = ' '; s2[k++] = 'x'; s2[k++] = '\0'; /* * make bottom string */ k = 0; s3[k++] = 'm'; for(i = 0; i < width; i++) s3[k++] = 'q'; s3[k++] = 'j'; s3[k] = '\0'; /* * output */ vtdcs(0, '0'); vtmova(row++, column); putstr(STDERR, s1, NULL); for(i = 0; i < height; i++) { vtmova(row++, column); putstr(STDERR, s2, NULL); } vtmova(row, column); putstr(STDERR, s3, NULL); vtdcs(0, 'B'); } /****************************************************************************/ int vtcln(r1, r2) /* clear rows r1 to r2 */ register int r1, r2; { int vtmova(), vterln(); register int i; for(i = r1; i <= r2; i++) { vtmova(i, 1); vterln(2); } } /****************************************************************************/ int vtclr(n) /* clear screen n may be 0 (cursor to end), 1 (cursor to beginning), or 2 (all). */ #define BASE 48 register int n; { static char s[] = ""; /* $[2J */ if(n < 0 || n > 2) n = 2; /* default is clear all */ s[2] = n + BASE; putstr(STDERR, s, NULL); } /****************************************************************************/ int vtcsav() /* save cursor */ { static char s[] = "7"; /* $7 */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtcres() /* restore cursor */ { static char s[] = "8"; /* $7 */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtdark() /* dark screen */ { static char s[] = "[?5l"; /* $[?5l */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtrev() /* reverse video */ { static char s[] = "[?5h"; /* $[?5h */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtdouble(row, column, n, s) /* write text in double size row and column are the upper left corner, s is the text to write, and n is code: 0 double height and width, 1 double height, 2 double width. */ int row, column, n; char *s; { static char s0[] = "#3"; /* $#3 */ static char s1[] = "#4"; /* $#4 */ static char s2[] = "#6"; /* $#6 */ int vtmova(); if(row < 0 || row > 24) return; if(column < 0 || column > 80) return; vtmova(row, column); if(n == 2) { putstr(STDERR, s2, NULL); putstr(STDERR, s, NULL); } else if(n == 1) { putstr(STDERR, s0, NULL); putstr(STDERR, s, NULL); vtmova(++row, column); putstr(STDERR, s1, NULL); putstr(STDERR, s, NULL); } else if(n == 0) { putstr(STDERR, s2, NULL); putstr(STDERR, s0, NULL); putstr(STDERR, s, NULL); vtmova(++row, column); putstr(STDERR, s2, NULL); putstr(STDERR, s1, NULL); putstr(STDERR, s, NULL); } } /****************************************************************************/ int vtdown(spcn, schars) /* down load a character set. both spcn and schars are strings such as "23" and "NGGGGGNo/N@@@@@N?". spcn indicates the character number to start at ("1" is '!' octal 41, decimal 33). schars is a sixel pattern with the top and bottom halves of the character separated by '/'. multiple characters can be entered separated by ';'. */ char *spcn; char *schars; { static char s1[] = "P1;"; static char s2[] = ";1;0;0;0\( @"; static char s3[] = ";\\"; putstr(STDERR, s1, NULL); putstr(STDERR, spcn, NULL); putstr(STDERR, s2, NULL); putstr(STDERR, schars, NULL); putstr(STDERR, s3, NULL); } /****************************************************************************/ int vtdcs(gn, c) /* designate character set. G0, G1, G2, and G3 are selected by using values of 0, 1, 2, or 3 for gn. NOTE: only G0 and G1 are available for VT100. c is a character to select the character set. it may contain a single character B, <, or 0 for ASCII, DEC supplemental, and DEC special graphics respectively (hard character sets). NOTE: only B and 0 are available for the VT100. if c is '~'(tilda) the soft (down-line-loadable) character set is selected (named "@") */ int gn; int c; { static char s[] = "xx"; /* $xx */ static char t[] = "()*+"; static char s1[] = "x @"; /* $x@ */ if(gn < 0 || gn > 3) return; if(c != '~') { s[1] = t[gn]; s[2] = c; putstr(STDERR, s, NULL); } else { s1[1] = t[gn]; putstr(STDERR, s1, NULL); } } /****************************************************************************/ int vtscs(gn) /* select character set. gn of 0, 1, 2, or 3 selects G0, G1, G2, or G3 respectively. NOTE: only G0 and G1 are available for VT100. */ int gn; { char s[3]; if(gn < 0 || gn > 3) return; if(gn <= 1) { s[1] = '\0'; if(gn == 0) s[0] = '\017'; else s[0] = '\016'; } else { s[0] = '\033'; s[2] = '\0'; if(gn == 2) s[1] = 'n'; else s[1] = 'o'; } putstr(STDERR, s, NULL); } /****************************************************************************/ int vterln(n) /* erase line n may be 0 (cursor to end), 1 (cursor to beginning), or 2 (all). */ #define BASE 48 register int n; { static char s[] = ""; /* $[2K */ if(n < 0 || n > 2) n = 2; /* default is clear all */ s[2] = n + BASE; putstr(STDERR, s, NULL); } /****************************************************************************/ int vterror() /* error message go to row 24, column 1; erase the line; set mode reverse; ring bell */ { int vtmova(), vterln(), vtmode(); vtmova(24, 1); vterln(2); vtmode(8); errfmt("%ai%ai", '\007', '\007'); } /****************************************************************************/ int vtgraf() /* graphics characters */ { static char s[] = ")0"; /* $)0 */ static char s1[] = ""; /* SO shift out */ static char flag = NO; if(flag == NO) { putstr(STDERR, s, NULL); /* define G1 character set */ flag = YES; } putstr(STDERR, s1, NULL); /* shift out */ } /****************************************************************************/ int vtnogf() /* graphics characters off */ { static char s[] = ""; /* SI shift in */ putstr(STDERR, s, NULL); /* shift in */ } /****************************************************************************/ int vtgrid(row, column, width, height, across, down) /* draw a grid using the vt100/vt200 special graphics character set. row and column are the location of the upper left corner. width and height are the width and height not including the outer character cells of the boxs making, up the grid (ie the smallest box is 0, 0). across and down are the number of boxes in these directions. */ int row, column, width, height, across, down; { char s1[81], s2[81], s3[81], s4[81]; register int i, j, k; int vtdcs(), vtmova(); /* * make top string */ k = 0; s1[k++] = 'l'; for(j = 0; j < across; j++) { for(i = 0; i < width; i++) s1[k++] = 'q'; s1[k++] = 'w'; } s1[k - 1] = 'k'; s1[k] = '\0'; /* * make sides string */ k = 0; s2[k++] = 'x'; for(j = 0; j < across; j++) { for(i = 0; i < width; i++) s2[k++] = ' '; s2[k++] = 'x'; } s2[k] = '\0'; /* * make interior line string */ k = 0; s3[k++] = 't'; for(j = 0; j < across; j++) { for(i = 0; i < width; i++) s3[k++] = 'q'; s3[k++] = 'n'; } s3[k - 1] = 'u'; s3[k] = '\0'; /* * make bottom string */ k = 0; s4[k++] = 'm'; for(j = 0; j < across; j++) { for(i = 0; i < width; i++) s4[k++] = 'q'; s4[k++] = 'v'; } s4[k - 1] = 'j'; s4[k] = '\0'; /* * output */ vtdcs(0, '0'); vtmova(row++, column); putstr(STDERR, s1, NULL); for(j = 0; j < down; j++) { for(i = 0; i < height; i++) { vtmova(row++, column); putstr(STDERR, s2, NULL); } if(j == down - 1) break; vtmova(row++, column); putstr(STDERR, s3, NULL); } vtmova(row, column); putstr(STDERR, s4, NULL); vtdcs(0, 'B'); } /****************************************************************************/ int vthome() /* home cursor */ { static char s[] = ""; /* $[;H*/ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtindx(n) /* index/reverse index ie scroll down/up n may be UP or DOWN */ register int n; { static char s[] = "D"; /* $D */ if(n == UP) s[1] = 'M'; else if(n == DOWN) s[1] = 'D'; else return; putstr(STDERR, s, NULL); } /****************************************************************************/ int vtjump() /* jump scrolling */ { static char s[] = "[?4l"; /* $[?4l */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtsmoo() /* smooth scrolling */ { static char s[] = "[?4h"; /* $[?4h */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtmenu(row, column) /* get one character form a "[ ]" box used for input to menus. writes box on screen in reverse video and gets one character in special mode. number keys must be followed by but arrows and PF keys work immediately. up, down, left, and right arrows return UP, DOWN, LEFT, and RIGHT respectively. PF1, PF2, PF3, and PF4 return PF1, PF2, PF3, and PF4 respectively. escape returns escape (ie 27 decimal). number keys return the numerical value. other inputs are not allowed. */ int row, column; { char cget(); register int c, l = NULL; int vterln(), vtmova(), vtmode(), putstr(), vtmovr(); unsigned ijob; vtmova(row, column - 1); /* go there */ vtmode(8); /* reverse video */ putstr(STDERR, "[ ]", NULL); /* make box */ vtmovr(LEFT, 2); /* move back into box */ /* * terminal to special mode */ ijob = JSW; JSW = ijob | 010000; /* * */ while((c = cget()) != '\n' || (l < '0' || l > '9')) { if(c == ESCAPE) { /* escape */ if((c = cget()) == '[') { if((c = cget()) == 'A') c = UP; else if(c == 'B') c = DOWN; else if(c == 'C') c = RIGHT; else if(c == 'D') c = LEFT; } else if(c == 'O') { if((c = cget()) == 'P') c = PF1; else if(c == 'Q') c = PF2; else if(c == 'R') c = PF3; else if(c == 'S') c = PF4; } } l = c; if(c >= PF1 && c <= RIGHT) break; if(c >= '0' && c <= '9') errfmt("%ai", c); else errfmt(" "); vtmovr(LEFT, 1); } if(l >= '0' && l <= '9') /* 0-9 return true value */ l -= 48; /* others return ASCII */ /* * terminal to normal mode */ JSW = ijob; vtmode(0); vterln(2); /* * end */ return(l); } /****************************************************************************/ int vtmode(n) /* set attributes n may be NULL or sum of any combination of 1 bold, 2 underscore, 4 blink, or 8 reverse. */ register int n; { static char s[] = ""; /* $[0m */ static char s1[] = "[ "; /* $[(8 spaces) */ register int i = 2; if(n < 0 || n > 15) return; putstr(STDERR, s, NULL); /* clear all attributes */ if(n == NULL) { return; } if(n & 1) { s1[i++] = '1'; s1[i++] = ';'; } if(n & 2) { s1[i++] = '4'; s1[i++] = ';'; } if(n & 4) { s1[i++] = '5'; s1[i++] = ';'; } if(n & 8) { s1[i++] = '7'; s1[i++] = ';'; } s1[i-1] = 'm'; s1[i] = '\0'; putstr(STDERR, s1, NULL); } /****************************************************************************/ int vtmova(row, column) /* move cursor absolute */ register int row, column; { static char s[] = "p;pppH"; /* $[pp;pppH */ register int i = 2; unsigned decode(); if(row < 0 || row > 24) return; if(column < 0 || column > 80) return; i += decode(&s[2], 2, "%i", row); s[i++] = ';'; i += decode(&s[i], 3, "%i", column); s[i++] = 'H'; s[i] = '\0'; putstr(STDERR, s, NULL); } /****************************************************************************/ int vtmovr(n, k) /* move cursor relative n may be UP, DOWN, RIGHT, or LEFT. k is the number of lines or spaces to move. */ register int n, k; { static char s[] = "pA"; /* $[ppA */ register int i = 2; unsigned decode(); if(n < UP || n > LEFT) return; if(n == UP || n == DOWN) { if(k < 1 || k > 23) return; } else { if(k < 1 || k > 79) return; } i += decode(&s[2], 2, "%i", k); if(n == UP) s[i] = 'A'; else if(n == DOWN) s[i] = 'B'; else if(n == LEFT) s[i] = 'D'; else if(n == RIGHT) s[i] = 'C'; s[++i] = '\0'; putstr(STDERR, s, NULL); } /****************************************************************************/ int vtnext() /* next line */ { static char s[] = "E"; /* $E*/ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtrbox(ncol, fc, is, address, s0) /* entry box - allow entry to a one line high box which is ncol wide starting at current position. is is an instruction string "i", "u", "d", "s", "n" for int, unsigned, double, string, or numeric string respectively. address is the address at which to deposit the answer. video mode must be set before. fc is the fill character for the box. s0 is the string to place in the box at the beginning. returns the terminator key (\n, \b, or \t), -1 if bad arguments, or -(terminator key) if no data was entered. The latter allows one to distinguish from "0" entered vs no entry. right and left arrows can be used to move one character within the input string, up and down arrows can be used to move to the beginning or end of the input string respectively. */ int ncol, fc; char *is, *address, *s0; { register char s[81]; char *cpystr(), cget(), is0, *fs; int lastn = 0; int i, c, nn, entry, encode(), vtmovr(); register int itop, p; unsigned lenstr(), ijob; double *pd; fs = "%- nb"; /* format for putstr below */ /* * test arguments */ if(ncol < 1) return(-1); if(ncol > 80) ncol = 80; if(address == NULL) return(-1); is0 = is[0]; if(is0 != 'i' && is0 != 'd' && is0 != 's' && is0 != 'n' \ && is0 != 'u') return(-1); /* * move to position, initialize */ p = itop = lenstr(s0); if(itop > 0) { fs[2] = fc; /* fs = "%- nb"; */ errfmt(fs, ncol, s0, itop); vtmovr(LEFT, (itop >= ncol ? ncol - 1 : itop)); lastn = itop; /* new */ cpystr(s, s0, NULL); } /* * vt100 to special mode */ ijob = JSW; JSW = ijob | 010000; /* * input characters */ while((c = cget()) != '\n' && c != '\b' && c != '\t') { if(c == ESCAPE) { if((c = cget()) == '[') { if((c = cget()) == 'C') { /* right */ if(p < itop) p++; } else if(c == 'D') { /* left */ if(p > 0) p--; } else if(c == 'A') /* up */ p = 0; else if(c == 'B') /* down */ p = itop; } } else if(c == '\177' && p > 0) { /* delete */ for(i = p; i <= itop - 1; i++) { s[i-1] = s[i]; } --itop; --p; } else if(isdigit(c) || \ ((c == '+' || c == '-') && p == 0 && is0 != 'n' && is0 !='u')||\ (c == '.' && is0 == 'd') || \ (c == '-' && is0 == 'n') || \ ((c >= ' ' && c <= '~') && is0 == 's')) { for(i = itop - 1; i >= p; i--) { s[i+1] = s[i]; } s[p++] = c; itop++; if(itop > ncol) { for(i = 0; i < ncol; i++) s[i] = s[i + 1]; itop--; if(p > 0) p--; } } else continue; nn = (p >= ncol ? ncol - 1 : p); fs[2] = fc; /* fs = "%- nb"; */ vtmovr(LEFT, lastn); lastn = nn; /* new */ errfmt(fs, ncol, s, itop); vtmovr(LEFT, ncol - nn); } vtmovr(LEFT, nn); /* * vt100 to normal mode */ JSW = ijob; /* * finish processing the input string */ entry = (itop > 0 ? c : -(c)); if(is0 == 's') { s[itop] = '\0'; cpystr(address, s, NULL); return(entry); } else if(is0 == 'n') { s[itop] = '\0'; cpystr(address, s, NULL); return(entry); } else if(is0 == 'i') { if(itop != 0) encode(s, itop, "%i", address); else *address = 0; return(entry); } else if(is0 == 'u') { if(itop != 0) encode(s, itop, "%ui", address); else encode("0", 1, "%ui", address); return(entry); } else { /* is0 == 'd' */ if(itop != 0) encode(s, itop, "%d", address); else { pd = address; *pd = 0.; } return(entry); } } /****************************************************************************/ int vtrmbx(ncol, c) /* write a 1 line high box which is ncol wide and filled with character c. video mode must be set before calling. */ register int ncol; int c; { int vtmovr(); register int i; for(i = 0; i < ncol; i++) errfmt("%ai", c); vtmovr(LEFT, ncol); } /****************************************************************************/ int vtroll(top, bottom) /* scroll area */ register int top, bottom; { static char s[] = "p;ppr"; /* $[pp;ppr */ register int i = 2; unsigned decode(); if(top < 1 || top > 24) return; if(bottom < 1 || bottom > 24) return; if(bottom < top) return; i += decode(&s[2], 2, "%i", top); s[i++] = ';'; i += decode(&s[i], 2, "%i", bottom); s[i++] = 'r'; s[i] = '\0'; putstr(STDERR, s, NULL); } /****************************************************************************/ int vtnoro() /* clear scroll area */ { static char s[] = ""; /* $[r*/ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtrset() /* hard reset */ { static char s[] = "c"; /* $c */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtsrst() /* soft reset for VT220 */ { static char s[] = "[!p"; /* $[!p */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtttid() /* determines terminal type. returns 52, 100, 101, 102, 125, 132, 200, or 208 indicating vt*. vt220 and vt240 both return 200. a return of 208 indicates a vt200 series in 8-bit mode. vt52 $/Z vt100 $[?1;Xc where X is: 0 no options 1 processor option (STP) 2 advanced video option (AVO) 3 AVO and STP 4 graphics option (GPO) 5 GPO and STP 6 GPO and AVO 7 GPO, STP, AVO 11 printer port (PP) 15 PP and GPO vt125 $[?12 vt132 $[?4;Xc where X is: 11 printer port (PP) 15 PP and GPO vt101 $[?1;0c vt102 $[?6c vt200 8 bit $?62 vt200 7 bit $[?62;X;X;.... where X is: 1 132 columns 2 printer port 6 selective erase 7 DRCS 8 UDK 9 7 bit character national replacement sets */ { char s_inp[21]; int c_inp, cget(); register int kount = 0, i = 0; int ttflush(); unsigned int ijob; /* * special terminal mode */ ijob = JSW; JSW = ijob | 010000; /* * get terminal id string */ label: if(kount++ > 3) /* quit if it doesn't work */ return(0); ttflush(); /* flush terminal input buffer */ putstr(STDERR, "Z", NULL); /* $Z */ for(i = 0; ((c_inp = cget()) != 'c' && c_inp != 'Z') && i < 20; i++) s_inp[i] = c_inp; /* read in the id string */ /* * process string */ if(s_inp[0] == ESCAPE && s_inp[1] == '\057' && c_inp == 'Z') { JSW = ijob; return(52); /* $/Z vt52 */ } if(s_inp[1] == '?' && s_inp[2] == '6' && s_inp[3] == '2') { JSW = ijob; return(208); /* vt200 eight bit mode */ } if(s_inp[0] != ESCAPE || s_inp[1] != '[' || s_inp[2] != '?') goto label; /* unrecognized string try again */ /* * reset terminal */ JSW = ijob; /* * process string */ if(s_inp[3] == '1') { if(s_inp[4] == '2') /* $[?12 vt125 */ return(125); else if(s_inp[4] == ';') { if(s_inp[5] == '0') /* $[?1;0 vt101 */ return(101); else if(s_inp[5] >= '1' && s_inp[5] <= '7') /*$[?1;(1-7)vt100 */ return(100); else return(0); /* this should never happen */ } else return(0); /* this should never happen */ } else if(s_inp[3] == '4') /* $[?4 vt132 */ return(132); else if(s_inp[3] == '6') { if(s_inp[4] == '2') /* $[?62 vt200 7 bit */ return(200); else if(s_inp[4] == '\0') /* $[?6 vt102 */ return(102); else return(0); /* this should never happen */ } else return(0); } /****************************************************************************/ int vttxt(row, column, s) /* write text on a line */ register int row, column; register char *s; { int vtmova(), vtmode(); if(row < 0 || row > 24) return; if(column < 0 || column > 80) return; vtmova(row, column); putstr(STDERR, s, NULL); } /****************************************************************************/ int vtwrap() /* wraparound mode */ { static char s[] = "[?7h"; /* $[?7h */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vtnowp() /* wraparound mode off */ { static char s[] = "[?7l"; /* $[?7l */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vt80() /* 80 columns */ { static char s[] = "[?3l"; /* $[?3l */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vt132() /* 132 columns */ { static char s[] = "[?3h"; /* $[?3/ */ putstr(STDERR, s, NULL); } /****************************************************************************/ int vt0_9() /* down load characters 0 - 9 */ { static char sa[]="wCAAACw?/?@AAA@??;?GC}????/?AABAA??;CaaQQQK?/BAAAAAA?;"; static char sb[]="AAAQYUa?/@AAAAA@?;_ogc}__?/????B???;]QIIIIq?/@AAAAA@?;"; static char sc[]="wcQQQQ_?/@AAAAA@?;AAAaQIE?/??B?????;kQQQQQk?/@AAAAA@?;"; static char sd[]="KQQQQI{?/?AAAA@??;"; static char s1[] = "P1;16;1;0;0;0\( @"; static char s2[] = "\\"; putstr(STDERR, s1, NULL); putstr(STDERR, sa, NULL); putstr(STDERR, sb, NULL); putstr(STDERR, sc, NULL); putstr(STDERR, sd, NULL); putstr(STDERR, s2, NULL); } /****************************************************************************/ int working(row) /* display "working" in blinking reverse video in the middle of row. */ register int row; { int vtmova(), vtmode(); vtmova(row, 36); vtmode(12); errfmt("working"); vtmode(0); vtmova(24, 1); }