home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / NCSATELN / TEL23SRC.ZIP / VS / VSEM.C next >
Encoding:
C/C++ Source or Header  |  1991-06-28  |  17.8 KB  |  714 lines

  1. #ifdef lint
  2. static char *SCCSid="%W%        (NCSA)  %G%";
  3. #endif
  4. /*
  5.  *
  6.  *      Virtual Screen Kernel Emulation Routines
  7.  *                     (vsem.c)
  8.  *
  9.  *   National Center for Supercomputing Applications
  10.  *      by Gaige B. Paulsen
  11.  *
  12.  *    This file contains the private emulation calls for the NCSA
  13.  *  Virtual Screen Kernel.
  14.  *
  15.  *      Version   Date    Notes
  16.  *      -------   ------  ---------------------------------------------------
  17.  *        0.01    861102    Initial coding -GBP
  18.  *        0.10    861111    Added/Modified VT emulator -GBP
  19.  *        0.50    861113    First compiled edition -GBP
  20.  *        2.1        871130    NCSA Telnet 2.1 -GBP
  21.  *        2.2    880715    NCSA Telnet 2.2 -GBP
  22.  *        2.3        900930    NCSA Telnet    2.3 -QAK
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <bios.h>
  27. #ifdef MEMORY_DEBUG
  28. #include "memdebug.h"
  29. #endif
  30. #include "vsdata.h"
  31. #include "vskeys.h"
  32. #include "externs.h"
  33.  
  34. int localprint=0;
  35.  
  36. /*  U of Michigan Changes here  and flagged @UM */
  37. /* sends data to local print until we encounter an ESC [ 4 i */
  38. /* the return value is set the number of chars processed     */
  39. char p_esc[4] = "\33[4i";   /* @UM */
  40. int send_localprint(dat, len) /* @UM */
  41. char *dat;
  42. int len;
  43. {
  44. int i, j;
  45. char c;
  46.  
  47. for (i=1; i<=len; i++)    {
  48.   c = *dat++;
  49.   if (p_esc[localprint-1] == c) {
  50.     localprint++;
  51.     if (localprint == 5) {  /* found full string */
  52.      localprint = 0;   /* we are now turned off */
  53.      break;
  54.     }
  55.    }
  56.   else {
  57.     for (j=0; j < (localprint - 1); j++)
  58. #ifdef MSC
  59.        _bios_printer(_PRINTER_WRITE,0,p_esc[j]);
  60.     _bios_printer(_PRINTER_WRITE,0,c);
  61. #elif __TURBOC__
  62.      NEED TO DO THE SAME FOR TURBO   /*    biosprint(0,ptr[i],0);  */
  63. #endif
  64.  /*    putchar(p_esc[j]);          /* CHANGE THIS TO BIOS write */
  65.  /*   putchar(c);    */
  66.     localprint = 1;
  67.   }
  68.  }  /* for */
  69.    return (i);         /* number of chars we consumed */
  70. } /* send_localprint */
  71.  
  72.  
  73.  
  74. void VSem(c,ctr)
  75. unsigned char *c;
  76. int ctr;
  77. {
  78.     int pcount;
  79.     int sx;
  80.     int escflg;
  81.     int insert,
  82.         ocount,
  83.         attrib,
  84.         extra,
  85.         offend;
  86.     char *acurrent,
  87.         *current,
  88.         *start;
  89.  
  90.     escflg=VSIw->escflg;
  91.  
  92. /* @UM */
  93.       if (localprint && (ctr > 0)) {    /* see if printer needs anything */
  94.           pcount = send_localprint(c, ctr);
  95.           ctr -= pcount;
  96.           c += pcount;
  97.          }
  98. /* @UM */
  99.  
  100.     while(ctr>0) {
  101.         while((escflg==0) && (ctr>0) && (*c<32)) {        /* look at first character in the vt100 string, if it is a non-printable ascii code */
  102.             switch(*c) {
  103.                 case 0x1b:        /* ESC found (begin vt100 control sequence) */
  104.                     escflg++;
  105.                     break;
  106.  
  107. #ifdef CISB
  108.                 case 0x05:        /* CTRL-E found (answerback) */
  109.                     bp_ENQ();
  110.                     break;
  111.  
  112. #endif
  113.                 case 0x07:        /* CTRL-G found (bell) */
  114.                     RSbell(VSIwn);
  115.                     break;
  116.  
  117.                 case 0x08:        /* CTRL-H found (backspace) */
  118.                     VSIw->x--;
  119.                     if(VSIw->x < 0)
  120.                         VSIw->x=0;
  121.                     break;
  122.  
  123.                 case 0x09:        /* CTRL-I found (tab) */
  124.                     VSItab();      /* Later change for versatile tabbing */
  125.                     break;
  126.  
  127.                 case 0x0a:        /* CTRL-J found (line feed) */
  128.                 case 0x0b:        /* CTRL-K found (treat as line feed) */
  129.                 case 0x0c:        /* CTRL-L found (treat as line feed) */
  130.                     VSIindex();
  131.                     break;
  132.  
  133.                 case 0x0d:        /* CTRL-M found (carriage feed) */
  134.                     VSIw->x=0;
  135.                     break;
  136.  
  137.                 case 0x0e:        /* CTRL-N found (invoke Graphics (G1) character set) */
  138.                     if(VSIw->G1)
  139.                         VSIw->attrib=VSgraph(VSIw->attrib);
  140.                     else
  141.                         VSIw->attrib=VSnotgraph(VSIw->attrib);
  142.                     VSIw->charset=1;
  143.                     break;
  144.  
  145.                 case 0x0f:        /* CTRL-O found (invoke 'normal' (G0) character set) */
  146.                     if(VSIw->G0)
  147.                         VSIw->attrib=VSgraph(VSIw->attrib);
  148.                     else
  149.                         VSIw->attrib=VSnotgraph(VSIw->attrib);
  150.                     VSIw->charset=0;
  151.                     break;
  152.  
  153. #ifdef CISB
  154.                 case 0x10:        /* CTRL-P found (undocumented in vt100) */
  155.                     bp_DLE( c, ctr);
  156.                     ctr=0;
  157.                     break;
  158. #endif
  159.  
  160. #ifdef NOT_USED
  161.                 case 0x11:        /* CTRL-R found (XON) (unused presently) */
  162.                 case 0x13:        /* CTRL-T found (XOFF) (unused presently) */
  163.                 case 0x18:        /* CTRL-X found (CAN) (unused presently) */
  164.                 case 0x1a:        /* CTRL-Z found (SUB) (unused presently) */
  165.                     break;
  166. #endif
  167.               }    /* end switch */
  168.             c++;        /* advance to the next character in the string */
  169.             ctr--;        /* decrement the counter */
  170.           }    /* end while */
  171.         while((ctr>0) && (escflg==0) && (*c>=32)) {        /* print out printable ascii chars, if we haven't found an ESCAPE char */
  172.             current=start=&VSIw->linest[VSIw->y]->text[VSIw->x];    /* this line is important, both are * chars */
  173.             acurrent=&VSIw->attrst[VSIw->y]->text[VSIw->x];
  174.             attrib=VSIw->attrib;
  175.             insert=VSIw->IRM;           /* boolean */
  176.             ocount=VSIw->x;
  177.             offend=0;
  178.             extra=0;
  179.             sx=VSIw->x;
  180.             if(VSIw->x>VSIw->maxwidth) {
  181.                 if(VSIw->DECAWM) {
  182.                     VSIw->x=0;
  183.                     VSIindex();
  184.                   }    /* end if */
  185.                 else
  186.                     VSIw->x=VSIw->maxwidth;
  187.                 current=start=&VSIw->linest[VSIw->y]->text[VSIw->x];
  188.                 acurrent=&VSIw->attrst[VSIw->y]->text[VSIw->x];
  189.                 ocount=VSIw->x;
  190.                 sx=VSIw->x;
  191.               }    /* end if */
  192.             while((ctr>0) && (*c>=32) && (offend==0)) {
  193.                 if(insert)
  194.                     VSIinschar(1);
  195.                 *current=*c;
  196.                 *acurrent=(char)attrib;
  197.                 c++;
  198.                 ctr--;
  199.                 if(VSIw->x<VSIw->maxwidth) {
  200.                     acurrent++;
  201.                     current++;
  202.                     VSIw->x++;
  203.                   }    /* end if */
  204.                 else {
  205.                     if(VSIw->DECAWM) {
  206.                         VSIw->x++;
  207.                         offend=1;
  208.                       }    /* end if */
  209.                     else {
  210.                         VSIw->x=VSIw->maxwidth;
  211.                         extra=1;
  212.                       }    /* end else */
  213.                   }    /* end else */
  214.               }    /* end while */
  215.             if(insert)
  216.                 VSIinsstring(VSIw->x-ocount+offend+extra,start);        /* actually just decides which RS to use */
  217.             else
  218.                 VSIdraw(VSIwn,sx,VSIw->y,VSIw->attrib,VSIw->x-ocount+offend+extra,start);
  219.           }    /* end while */
  220.         while((ctr>0) && (escflg==1)) {     /* ESC character was found */
  221.             switch(*c) {
  222.                 case 0x08:        /* CTRL-H found (backspace) */
  223.                     VSIw->x--;
  224.                     if(VSIw->x<0)
  225.                         VSIw->x=0;
  226.                     break;
  227.  
  228.                 case '[':               /* mostly cursor movement options, and DEC private stuff following */
  229.                     VSIapclear();
  230.                     escflg++;
  231.                     break;
  232.  
  233.                 case '#':               /* various screen adjustments */
  234.                     escflg=3;
  235.                     break;
  236.  
  237.                 case '(':               /* G0 character set options */
  238.                     escflg=4;
  239.                     break;
  240.  
  241.                 case ')':               /* G1 character set options */
  242.                     escflg=5;
  243.                     break;
  244.  
  245.                 case '>':               /* keypad numeric mode (DECKPAM) */
  246.                     VSIw->DECPAM=0;
  247.                     escflg=0;
  248.                     break;
  249.  
  250.                 case '=':               /* keypad application mode (DECKPAM) */
  251.                     VSIw->DECPAM=1;
  252.                     escflg=0;
  253.                     break;
  254.  
  255.                 case '7':               /* save cursor (DECSC) */
  256.                     VSIsave();
  257.                     escflg=0;
  258.                     break;
  259.  
  260.                 case '8':               /* restore cursor (DECRC) */
  261.                     VSIrestore();
  262.                     escflg=0;
  263.                     break;
  264.  
  265.                 case 'c':               /* reset to initial state (RIS) */
  266.                     VSIreset();
  267.                     escflg=0;
  268.                     break;
  269.  
  270.                 case 'D':               /* index (move down one line) (IND) */
  271.                     VSIindex();
  272.                     escflg=0;
  273.                     break;
  274.  
  275.                 case 'E':               /*  next line (moev down one line and to first column) (NEL) */
  276.                     VSIw->x=0;
  277.                     VSIindex();
  278.                     escflg=0;
  279.                     break;
  280.  
  281.                 case 'H':               /* horizontal tab set (HTS) */
  282.                     VSIw->tabs[VSIw->x]='x';
  283.                     escflg=0;
  284.                     break;
  285.  
  286. #ifdef CISB
  287.                 case 'I':               /* undoumented in vt100 */
  288.                     bp_ESC_I();
  289.                     break;
  290.  
  291. #endif
  292.                 case 'M':               /* reverse index (move up one line) (RI) */
  293.                     VSIrindex();
  294.                     escflg=0;
  295.                     break;
  296.  
  297.                 case 'Z':               /* identify terminal (DECID) */
  298.                     VTsendident();
  299.                     escflg=0;
  300.                     break;
  301.  
  302.                 default:
  303.                     escflg=0;
  304.                     break;
  305.  
  306.               }    /* end switch */
  307.             c++;
  308.             ctr--;
  309.           }    /* end while */
  310.         while((escflg==2) && (ctr>0)) {     /* '[' handling */
  311.             switch(*c) {
  312.                 case 0x08:        /* backspace */
  313.                     VSIw->x--;
  314.                     if(VSIw->x<0)
  315.                         VSIw->x=0;
  316.                     break;
  317.  
  318.                 case '0':
  319.                 case '1':
  320.                 case '2':
  321.                 case '3':
  322.                 case '4':
  323.                 case '5':
  324.                 case '6':
  325.                 case '7':
  326.                 case '8':
  327.                 case '9':               /* numeric parameters */
  328.                     if(VSIw->parms[VSIw->parmptr]<0)
  329.                         VSIw->parms[VSIw->parmptr]=0;
  330.                     VSIw->parms[VSIw->parmptr]*=10;
  331.                     VSIw->parms[VSIw->parmptr]+=*c-'0';
  332.                     break;
  333.  
  334.                 case '?':               /* vt100 mode change */
  335.                     VSIw->parms[VSIw->parmptr++]=(-2);
  336.                     break;
  337.  
  338.                 case ';':               /* parameter divider */
  339.                     VSIw->parmptr++;
  340.                     break;
  341.  
  342.                 case 'A':               /* cursor up (CUU) */
  343.                     if(VSIw->parms[0]<1)
  344.                         VSIw->y--;
  345.                     else
  346.                         VSIw->y-=VSIw->parms[0];
  347.                     if(VSIw->y<VSIw->top)
  348.                         VSIw->y=VSIw->top;
  349.                     VSIrange();
  350.                     escflg=0;
  351.                     break;
  352.  
  353.                 case 'B':               /* cursor down (CUD) */
  354.                     if(VSIw->parms[0]<1)
  355.                         VSIw->y++;
  356.                     else
  357.                         VSIw->y+=VSIw->parms[0];
  358.                     if(VSIw->y>VSIw->bottom)
  359.                         VSIw->y=VSIw->bottom;
  360.                     VSIrange();
  361.                     escflg=0;
  362.                     break;
  363.  
  364.                 case 'C':               /* cursor forward (right) (CUF) */
  365.                     if(VSIw->parms[0]<1)
  366.                         VSIw->x++;
  367.                     else
  368.                         VSIw->x+=VSIw->parms[0];
  369.                     VSIrange();
  370.                     if(VSIw->x>VSIw->maxwidth)
  371.                         VSIw->x=VSIw->maxwidth;
  372.                     escflg=0;
  373.                     break;
  374.  
  375.                 case 'D':               /* cursor backward (left) (CUB) */
  376.                     if(VSIw->parms[0]<1)
  377.                         VSIw->x--;
  378.                     else
  379.                         VSIw->x-=VSIw->parms[0];
  380.                     VSIrange();
  381.                     escflg=0;
  382.                     break;
  383.  
  384.                 case 'f':               /* horizontal & vertical position (HVP) */
  385.                 case 'H':               /* cursor position (CUP) */
  386. #ifdef OLD_WAY
  387.                     if(VSIw->parmptr!=1) {        /* if there weren't enough parameters, perform default action of homing the cursor */
  388.                         VSIw->x=0;
  389. #ifdef NOT_SUPPORTED
  390.                         if(VSIw->DECORG)
  391.                             VSIw->y=VSIw->top;        /* origin mode relative */
  392.                         else
  393.                             VSIw->y=0;
  394. #endif
  395.                         VSIw->y=0;
  396.                       }    /* end if */
  397.                     else {        /* correct number of parameters, so move cursor */
  398.                         VSIw->x=VSIw->parms[1]-1;
  399. #ifdef NOT_SUPPORTED
  400.                         if(VSIw->DECORG)
  401.                             VSIw->y=VSIw->parms[0]-1 + VSIw->top;        /* origin mode relative */
  402.                         else
  403.                             VSIw->y=VSIw->parms[0]-1;
  404. #endif
  405.                         VSIw->y=VSIw->parms[0]-1;
  406.                         VSIrange();
  407.                       }    /* end else */
  408. #else
  409.                     VSIw->x=VSIw->parms[1]-1;
  410. #ifdef NOT_SUPPORTED
  411.                     if(VSIw->DECORG)
  412.                         VSIw->y=VSIw->parms[0]-1 + VSIw->top;        /* origin mode relative */
  413.                     else
  414.                         VSIw->y=VSIw->parms[0]-1;
  415. #endif
  416.                     VSIw->y=VSIw->parms[0]-1;
  417.                     VSIrange();            /* make certain the cursor position is valid */
  418. #endif
  419.                     escflg=0;
  420.                     break;
  421.  
  422.                 case 'J':               /* erase in display (ED) */
  423.                     switch(VSIw->parms[0]) {
  424.                         case -1:
  425.                         case 0:     /* erase from active position to end of screen */
  426.                             VSIeeos();
  427.                             break;
  428.  
  429.                         case 1:     /* erase from start of screen to active position */
  430.                             VSIebos();
  431.                             break;
  432.  
  433.                         case 2:     /* erase whole screen */
  434.                             VSIes();
  435.                             break;
  436.  
  437.                         default:
  438.                             break;
  439.                       }    /* end switch */
  440.                     escflg=0;
  441.                     break;
  442.  
  443.                 case 'K':               /* erase in line (EL) */
  444.                     switch(VSIw->parms[0]) {
  445.                         case -1:
  446.                         case 0:     /* erase to end of line */
  447.                             VSIeeol();
  448.                             break;
  449.  
  450.                         case 1:     /* erase to beginning of line */
  451.                             VSIebol();
  452.                             break;
  453.  
  454.                         case 2:     /* erase whole line */
  455.                             VSIel(-1);
  456.                             break;
  457.  
  458.                         default:
  459.                             break;
  460.                       }    /* end switch */
  461.                     escflg=0;
  462.                     break;
  463.  
  464.                 case 'L':               /* insert n lines preceding current line (IL) */
  465.                     if(VSIw->parms[0]<1)
  466.                         VSIw->parms[0]=1;
  467.                     VSIinslines(VSIw->parms[0],-1);
  468.                     escflg=0;
  469.                     break;
  470.  
  471.                 case 'M':               /* delete n lines from current position downward (DL) */
  472.                     if(VSIw->parms[0]<1)
  473.                         VSIw->parms[0]=1;
  474.                     VSIdellines(VSIw->parms[0],-1);
  475.                     escflg=0;
  476.                     break;
  477.  
  478.                 case 'P':               /* delete n chars from cursor to the left (DCH) */
  479.                     if(VSIw->parms[0]<1)
  480.                         VSIw->parms[0]=1;
  481.                     VSIdelchars(VSIw->parms[0]);
  482.                     escflg=0;
  483.                     break;
  484.  
  485. #ifdef NOT_NEEDED
  486.                 case 'R':               /* receive cursor position status from host */
  487.                     break;
  488. #endif
  489.                 case 'c':               /* device attributes (DA) */
  490.                     VTsendident();
  491.                     escflg=0;
  492.                     break;
  493.  
  494.                 case 'g':               /* tabulation clear (TBC) */
  495.                     if(VSIw->parms[0]==3)    /* clear all tabs */
  496.                         VSItabclear();
  497.                     else
  498.                         if(VSIw->parms[0]<=0)    /* clear tab stop at active position */
  499.                             VSIw->tabs[VSIw->x]=' ';
  500.                     escflg=0;
  501.                     break;
  502.  
  503.                 case 'h':               /* set mode (SM) */
  504.                     VSIsetoption(1);
  505.                     escflg=0;
  506.                     break;
  507.  
  508.                 case 'i':               /* toggle printer */
  509.                     if (VSIw->parms[VSIw->parmptr]==5)
  510.                         localprint=1;
  511.                     else if(VSIw->parms[VSIw->parmptr]==4)
  512.                         localprint=0;
  513.                     escflg=0;
  514.                     break;
  515.  
  516.                 case 'l':               /* reset mode (RM) */
  517.                     VSIsetoption(0);
  518.                     escflg=0;
  519.                     break;
  520.  
  521.                 case 'm':               /* select graphics rendition (SGR) */
  522.                     {
  523.                         int temp=0;
  524.  
  525.                         while(temp<=VSIw->parmptr) {
  526.                             if(VSIw->parms[temp]<1)
  527.                                 VSIw->attrib&=128;
  528.                             else
  529.                                 VSIw->attrib|=(1<<(VSIw->parms[temp]-1));
  530.                             temp++;
  531.                           }    /* end while */
  532.                       }    /* end case */
  533.                     escflg=0;
  534.                     break;
  535.  
  536.                 case 'n':               /* device status report (DSR) */
  537.                     switch(VSIw->parms[0]) {
  538. #ifdef NOT_SUPPORTED
  539.                         case 0: /* response from vt100; ready, no malfunctions */
  540.                         case 3: /* response from vt100; malfunction, retry */
  541. #endif
  542.  
  543.                         case 5: /* send status */
  544.                             VTsendstat();
  545.                             break;
  546.  
  547.                         case 6: /* send active position */
  548.                             VTsendpos();
  549.                             break;
  550.  
  551.                       }    /* end switch */
  552.                     escflg=0;
  553.                     break;
  554.  
  555.                 case 'q':               /* load LEDs (unsupported) (DECLL) */
  556.                     escflg=0;
  557.                     break;
  558.  
  559.                 case 'r':               /* set top & bottom margins (DECSTBM) */
  560.                     if(VSIw->parms[0]<0)
  561.                         VSIw->top=0;
  562.                     else
  563.                         VSIw->top=VSIw->parms[0]-1;
  564.                     if(VSIw->parms[1]<0)
  565.                         VSIw->bottom=VSPBOTTOM;
  566.                     else
  567.                         VSIw->bottom=VSIw->parms[1]-1;
  568.                     if(VSIw->top<0)
  569.                         VSIw->top=0;
  570.                     if(VSIw->top>VSPBOTTOM-1)
  571.                         VSIw->top=VSPBOTTOM-1;
  572.                     if(VSIw->bottom<1)
  573.                         VSIw->bottom=VSPBOTTOM;
  574.                     if(VSIw->bottom>VSPBOTTOM)
  575.                         VSIw->bottom=VSPBOTTOM;
  576.                     if(VSIw->top>=VSIw->bottom) {    /* check for valid scrolling region */
  577.                         if(VSIw->bottom>=1)        /* assume the bottom value has precedence, unless it is as the top of the screen */
  578.                             VSIw->top=VSIw->bottom-1;
  579.                         else                /* totally psychotic case, bottom of screen set to the very top line, move the bottom to below the top */
  580.                             VSIw->bottom=VSIw->top+1;
  581.                       }    /* end if */
  582.                     VSIw->x=0;
  583.                     VSIw->y=0;
  584. #ifdef NOT_SUPPORTED
  585.                     if (VSIw->DECORG)
  586.                         VSIw->y=VSIw->top;    /* origin mode relative */
  587. #endif
  588.                     escflg=0;
  589.                     break;
  590.  
  591. #ifdef NOT_SUPPORTED
  592.                 case 'x':                       /* request/report terminal parameters (DECREQTPARM/DECREPTPARM) */
  593.                 case 'y':                       /* invoke confidence test (DECTST) */
  594.                     break;
  595. #endif
  596.                 default:            /* Dag blasted strays... */
  597.                     escflg=0;
  598.                     break;
  599.  
  600.               }    /* end switch */
  601.             c++;
  602.             ctr--;
  603.  
  604. /* @UM */
  605.             if (localprint && (ctr > 0)) {    /* see if printer needs anything */
  606.                 pcount = send_localprint(c, ctr);
  607.                 ctr -= pcount;
  608.                 c += pcount;
  609.             }
  610. /* @UM */
  611.  
  612.           }    /* end while */
  613.         while((escflg==3) && (ctr>0)) { /* #  Handling */
  614.             switch(*c) {
  615.                 case 0x08:        /* backspace */
  616.                     VSIw->x--;
  617.                     if(VSIw->x<0)
  618.                         VSIw->x=0;
  619.                     break;
  620.  
  621. #ifdef NOT_SUPPORTED
  622.                 case '3':               /* top half of double line (DECDHL) */
  623.                 case '4':               /* bottom half of double line (DECDHL) */
  624.                 case '5':               /* single width line (DECSWL) */
  625.                 case '6':               /* double width line (DECDWL) */
  626.                     break;
  627. #endif
  628.  
  629.                 case '8':               /* screen alignment display (DECALN) */
  630.                     VTalign();
  631.                     escflg=0;
  632.                     break;
  633.  
  634.                 default:
  635.                     escflg=0;
  636.                     break;
  637.  
  638.               }    /* end switch */
  639.             c++;
  640.             ctr--;
  641.           }    /* end while */
  642.         while((escflg==4) && (ctr>0)) { /* ( Handling (GO character set) */
  643.             switch(*c) {
  644.                 case 0x08:        /* backspace */
  645.                     VSIw->x--;
  646.                     if(VSIw->x<0)
  647.                         VSIw->x=0;
  648.                     break;
  649.  
  650.                 case 'A':               /* united kingdom character set (unsupported) */
  651.                 case 'B':               /* ASCII character set */
  652.                 case '1':               /* choose standard graphics (same as ASCII) */
  653.                     VSIw->G0=0;
  654.                     if(!VSIw->charset)
  655.                         VSIw->attrib=VSnotgraph(VSIw->attrib);
  656.                     escflg=0;
  657.                     break;
  658.  
  659.                 case '0':               /* choose special graphics set */
  660.                 case '2':               /* alternate character set (special graphics) */
  661.                     VSIw->G0=1;
  662.                     if(!VSIw->charset)
  663.                         VSIw->attrib=VSgraph(VSIw->attrib);
  664.                     escflg=0;
  665.                     break;
  666.  
  667.                 default:
  668.                     escflg=0;
  669.                     break;
  670.               }    /* end switch */
  671.             c++;
  672.             ctr--;
  673.           }    /* end while */
  674.         while((escflg==5) && (ctr>0)) { /* ) Handling (G1 handling) */
  675.             switch(*c) {
  676.                 case 0x08:        /* backspace */
  677.                     VSIw->x--;
  678.                     if(VSIw->x<0)
  679.                         VSIw->x=0;
  680.                     break;
  681.  
  682.                 case 'A':               /* united kingdom character set (unsupported) */
  683.                 case 'B':               /* ASCII character set */
  684.                 case '1':               /* choose standard graphics (same as ASCII) */
  685.                     VSIw->G1=0;
  686.                     if(VSIw->charset)
  687.                         VSIw->attrib=VSnotgraph(VSIw->attrib);
  688.                     escflg=0;
  689.                     break;
  690.  
  691.                 case '0':               /* choose special graphics set */
  692.                 case '2':               /* alternate character set (special graphics) */
  693.                     VSIw->G1=1;
  694.                     if(VSIw->charset)
  695.                         VSIw->attrib=VSgraph(VSIw->attrib);
  696.                     escflg=0;
  697.                     break;
  698.  
  699.                 default:
  700.                     escflg=0;
  701.                     break;
  702.               }    /* end switch */
  703.             c++;
  704.             ctr--;
  705.           }    /* end while */
  706.         if((escflg>2) && (ctr>0)) {
  707.             escflg=0;
  708.             c++;
  709.             ctr--;
  710.           }    /* end if */
  711.       }    /* end while */
  712.     VSIw->escflg=escflg;
  713. }
  714.