home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / TEK / VGTEK.C < prev   
C/C++ Source or Header  |  1992-02-25  |  33KB  |  1,399 lines

  1. /*
  2. vgtek.c by Aaron Contorer 1987 for NCSA
  3. bugfixes by Tim Krauskopf 1988
  4.  
  5. Takes Tektronix codes as input; sends output to real graphics devices.
  6.  
  7. CHANGES TO MAKE:
  8. Create a function to make sure a window is attached to a real window.
  9. Calling program will call this whenever switching between active windows.
  10. Pass virtual window number to RG driver so it can call back.
  11. */
  12.  
  13. #define FALSE 0
  14. #define TRUE 1
  15. #define MAXVG 20     /* maximum number of VG windows */
  16.                     /* temporary states */
  17. #define HIY 0        /* waiting for various pieces of coordinates */
  18. #define EXTRA 1
  19. #define LOY 2
  20. #define HIX 3
  21. #define LOX 4
  22. #define DONE 5        /* not waiting for coordinates */
  23. #define ENTERVEC 6    /* entering vector mode */
  24. #define CANCEL 7    /* done but don't draw a line */
  25. #define RS 8        /* RS - incremental plot mode */
  26. #define ESCOUT 9    /* when you receive an escape char after a draw command */
  27. #define CMD0 50        /* got esc, need 1st cmd letter */
  28. #define SOMEL 51    /* got esc L, need 2nd letter */
  29. #define IGNORE 52    /* ignore next char */
  30. #define SOMEM 53    /* got esc M, need 2nd letter */
  31. #define IGNORE2 54
  32. #define INTEGER 60    /* waiting for 1st integer part */
  33. #define INTEGER1 61    /* waiting for 2nd integer part */
  34. #define INTEGER2 62    /* waiting for 3rd (last) integer part */
  35. #define COLORINT 70
  36. #define GTSIZE0 75
  37. #define GTSIZE1 76
  38. #define SOMET 80
  39. #define JUNKARRAY 81
  40. #define STARTDISC 82
  41. #define DISCARDING 83
  42.                     /* output modes */
  43. #define ALPHA 0
  44. #define DRAW 1
  45. #define MARK 3
  46. #define TEMPDRAW 101
  47. #define TEMPMOVE 102
  48. #define TEMPMARK 103
  49.                     /* stroked fonts */
  50. #define CHARWIDE 51        /* total horz. size */
  51. #define CHARTALL 76        /* total vert. size */
  52. #define CHARH 10        /* horz. unit size */
  53. #define CHARV 13        /* vert. unit size */
  54.                     /* RG coordinate space dimensions */
  55. #define RGXSIZE 4096
  56. #define RGYSIZE 4096
  57.  
  58. #include <stdlib.h>
  59. #include <stdio.h>
  60. #include <fcntl.h>
  61. #include <string.h>
  62. #include "externs.h"
  63. #include "vgtek.h"
  64. #include "vgfont.h"
  65. #include "tekstor.h"
  66.  
  67. #ifdef MSC
  68. #define mousecl    mousecml
  69. #endif
  70.  
  71. static void clipvec(int vw, int xa, int ya, int xb, int yb);
  72. static int fontnum(int vw, int n);
  73. static void storexy(int vw, int x, int y);
  74. static int joinup(int hi, int lo, int e);
  75. static void newcoord(int vw);
  76. static void linefeed(int vw);
  77. static int drawc(int vw, char c);
  78. static int clipt(double p, double q, double *t0, double *t1);
  79.  
  80. extern unsigned char s[550];
  81. extern struct config def;
  82. extern int ftpok, rcpok, temptek, viewmode;
  83. extern int ginon;           /* whether we are in GIN mode or not */
  84. extern int mighty;            /* whether there is a mouse or not hooked up to the system */
  85.  
  86. struct VGWINTYPE 
  87. {
  88.     int RGdevice, RGnum;
  89.     char mode,modesave;                 /* current output mode */
  90.     char loy,hiy,lox,hix,ex,ey;         /* current graphics coordinates */
  91.     char nloy,nhiy,nlox,nhix,nex,ney;     /* new coordinates */
  92.     int curx,cury;                        /* current composite coordinates */
  93.     int winbot,wintop,winleft,winright,wintall,winwide; /* position of window in virtual space */
  94.     int textcol;                        /* text starts in 0 or 2048 */
  95.     int intin;                            /* integer parameter being input */
  96.     int pencolor;                        /* current pen color */
  97.     int fontnum,charx,chary;             /* char size */
  98.     int count;                             /* for temporary use in special state loops */
  99. };
  100.  
  101. static struct VGWINTYPE VGwin[MAXVG];         /* virtual window descriptors */
  102. static char state[MAXVG],savstate[MAXVG];    /* save state in a parallel array for speed */
  103. static STOREP VGstore[MAXVG];                 /* the store where data for this window is kept */
  104. static char storing[MAXVG];                 /* are we currently saving data from this window */
  105. static int drawing[MAXVG];                     /* redrawing or not? */
  106.  
  107. #define NUMSIZES 6                             /* number of char sizes */
  108. static int charxset[NUMSIZES] = {56,51,34,31,112,168};
  109. static int charyset[NUMSIZES] = {88,82,53,48,176,264};
  110.  
  111. void showmouse(void)
  112. {
  113.     int m1=1,m2=0,m3=0,m4=0;        /* mouse variables to show the mouse cursor */
  114.  
  115.     if(mighty) {
  116.         vprint(console->vs, "Mouse Shown\r\n");
  117.         mousecl(&m1,&m2,&m3,&m4);    /* call mouse routine to show mouse cursor */
  118.     }
  119. }                                    /* end showmouse() */
  120.  
  121. void hidemouse(void)
  122. {
  123.     int m1=2,m2=0,m3=0,m4=0;        /* mouse variables to hide the mouse cursor */
  124.  
  125.     if(mighty) {
  126.         vprint(console->vs, "Mouse hidden\r\n");
  127.         mousecl(&m1,&m2,&m3,&m4);    /* call mouse routine to hide mouse cursor */
  128.     }
  129. }                                    /* end hidemouse() */
  130.  
  131. /**************************************************************************/
  132. /*  dispgr
  133. *   display graphics menu screen
  134. */
  135. void dispgr(void)
  136. {
  137.     int c,i,j,k,l;
  138.  
  139.     c=n_color(current->colors[0]);
  140.     n_clear();
  141.     n_cur(0,0);
  142.     n_puts("ALT-G                           Graphics menu");
  143.     n_puts("<            Press the appropriate function key or ESC to resume        >\n");
  144.     strcpy(s,"   F1 - Write postscript to a file called: ");
  145.     strcat(s,def.psfile);
  146.     n_puts(s);
  147.     n_puts(  "   F2 - Change postscript output file name\n");
  148.     strcpy(s,"   F3 - Write HPGL code to a file called: ");
  149.     strcat(s,def.hpfile);
  150.     n_puts(s);
  151.     n_puts(  "   F4 - Change HPGL output file name\n");
  152.     strcpy(s,"   F5 - Write Tektronix 4014 codes to a file called: ");
  153.     strcat(s,def.tekfile);
  154.     n_puts(s);
  155.     n_puts(  "   F6 - Change Tektronix output file name\n");
  156.     VGwhatzoom(temptek,&i,&j,&k,&l);
  157.     sprintf(s,"        View region is currently: %d,%d,%d,%d",i,j,k,l);
  158.     n_puts(s);
  159.     n_puts("   F7 - Set a new view region (Zoom, Pan)");
  160.     n_puts("   RETURN - draw picture on screen in current zoom factor\n");
  161.     n_puts("   Enter choice:");
  162.     viewmode=8;
  163.     n_color(c);
  164. }
  165.  
  166. /*******************************************************************/
  167. /*
  168. *    Set font for window 'vw' to size 'n'.
  169. *    Sizes are 0..3 in Tek 4014 standard.
  170. *    Sizes 4 & 5 are used internally for Tek 4105 emulation.
  171. */
  172. static int fontnum(int vw,int n)
  173. {
  174.     if(n<0||n>=NUMSIZES)
  175.             return(-1);
  176.     VGwin[vw].fontnum=n;
  177.     VGwin[vw].charx=charxset[n];
  178.     VGwin[vw].chary=charyset[n];
  179.     return(0);
  180. }
  181.  
  182. /* set graphics x and y position */
  183. static void storexy(int vw,int x,int y)
  184. {
  185.     VGwin[vw].curx=x;
  186.     VGwin[vw].cury=y;
  187. }
  188.  
  189. /* returns the number represented by the 3 pieces */
  190. static int joinup(int hi,int lo,int e)
  191. {
  192.     return (((hi/*&31*/)<<7)|((lo/*&31*/)<<2)|(e/*&3*/));    /* end joinup() */
  193. }
  194.  
  195. /*
  196.     Replace x,y with nx,ny
  197. */
  198. static void newcoord(int vw)
  199. {
  200.     VGwin[vw].hiy=VGwin[vw].nhiy;
  201.     VGwin[vw].hix=VGwin[vw].nhix;
  202.     VGwin[vw].loy=VGwin[vw].nloy;
  203.     VGwin[vw].lox=VGwin[vw].nlox;
  204.     VGwin[vw].ey=VGwin[vw].ney;
  205.     VGwin[vw].ex=VGwin[vw].nex;
  206.     VGwin[vw].curx=joinup(VGwin[vw].nhix,VGwin[vw].nlox,VGwin[vw].nex);
  207.     VGwin[vw].cury=joinup(VGwin[vw].nhiy,VGwin[vw].nloy,VGwin[vw].ney);
  208. }
  209.  
  210. /*
  211.     Perform a linefeed & cr(CHARTALL units) in specified window.
  212. */
  213. static void linefeed(int vw)
  214. {
  215. /*  int y=joinup(VGwin[vw].hiy,VGwin[vw].loy,VGwin[vw].ey);*/
  216.     int y=VGwin[vw].cury;
  217.     int x;
  218.  
  219.     if(y>VGwin[vw].chary) 
  220.         y -=VGwin[vw].chary;
  221.     else {
  222.         y= 3119-VGwin[vw].chary;
  223.         VGwin[vw].textcol=2048-VGwin[vw].textcol;
  224.       }
  225.     x=VGwin[vw].textcol;
  226.     storexy(vw,x,y);
  227. }
  228.     
  229. #ifdef DEBUG
  230. static int drawc(int vw,char c)
  231. {
  232.     putchar(c);
  233. }
  234.  
  235. #else
  236. /*
  237.     Draw a stroked character at the current cursor location.
  238.     Uses simple 8-directional moving, 8-directional drawing.
  239. */
  240. static drawc(int vw,char c)
  241. {
  242.     int x,y,savex,savey,strokex,strokey;
  243.     int n;            /* number of times to perform command */
  244.     char *pstroke;    /* pointer into stroke data */
  245.     int hmag,vmag;
  246.  
  247.     if(c==10) {
  248.         linefeed(vw);
  249.         return(0);
  250.       }
  251.     if(c==7) {
  252.         (*RG[VGwin[vw].RGdevice].bell)(VGwin[vw].RGnum);
  253.         unstore(VGstore[vw]);
  254.         return(0);
  255.       }
  256.     savey=y=VGwin[vw].cury;
  257.     savex=x=VGwin[vw].curx;
  258.     if(c==8) {
  259.         if(savex<=VGwin[vw].textcol)
  260.             return(0);
  261.         savex-=VGwin[vw].charx;
  262.         if(savex<VGwin[vw].textcol) 
  263.             savex=VGwin[vw].textcol;
  264.         VGwin[vw].cury=savey;
  265.         VGwin[vw].curx=savex;
  266.         return(0);
  267.       }
  268.     hmag=VGwin[vw].charx / 10;
  269.     vmag=VGwin[vw].chary / 10;
  270.     if(3119-savey<VGwin[vw].chary) {
  271.         savey=y=3119-VGwin[vw].chary;
  272.       }
  273.     if(c<32||c>126) 
  274.         return(0);
  275.     c-=32;
  276.     pstroke=VGfont[c];
  277.     while(*pstroke) {
  278.         strokex=x;
  279.         strokey=y;
  280.         n=(*(pstroke++)-48);    /* run length */
  281.         c=*(pstroke++);            /* direction code */
  282.         switch(c) {             /* horizontal movement: positive=right */
  283.             case 'e': 
  284.             case 'd': 
  285.             case 'c': 
  286.             case 'y': 
  287.             case 'h': 
  288.             case 'n':
  289.                 x+=n*hmag;
  290.                 break;
  291.  
  292.             case 'q': 
  293.             case 'a': 
  294.             case 'z': 
  295.             case 'r': 
  296.             case 'f': 
  297.             case 'v':
  298.                 x-=n*hmag;
  299.           }
  300.  
  301.         switch(c) {         /* vertical movement: positive=up */
  302.             case 'q': 
  303.             case 'w': 
  304.             case 'e': 
  305.             case 'r': 
  306.             case 't': 
  307.             case 'y':
  308.                 y+=n*vmag;
  309.                 break;
  310.  
  311.             case 'z': 
  312.             case 'x': 
  313.             case 'c': 
  314.             case 'v': 
  315.             case 'b': 
  316.             case 'n':
  317.                 y-=n*vmag;
  318.           }
  319.  
  320.         switch(c) {         /* draw or move */
  321.             case 'r': 
  322.             case 't': 
  323.             case 'y': 
  324.             case 'f': 
  325.             case 'h':
  326.             case 'v': 
  327.             case 'b': 
  328.             case 'n':
  329.                 clipvec(vw,strokex,strokey,x,y);
  330.                 break;
  331.           }
  332.     
  333.       }                     /* end while not at end of string */
  334.  
  335. /* Update cursor location to next char position */
  336.     if(savex+2*VGwin[vw].chary<=4096)
  337.         savex+=VGwin[vw].charx;
  338.     else {
  339.         savey-=VGwin[vw].chary;
  340.         if(savey<0) {
  341.             savey=3119-VGwin[vw].chary;
  342.             VGwin[vw].textcol=2048-VGwin[vw].textcol;
  343.           }
  344.         savex=VGwin[vw].textcol;
  345.       }
  346.     VGwin[vw].cury=savey;
  347.     VGwin[vw].curx=savex;         /* end drawc() */
  348. }
  349.  
  350. #endif
  351.  
  352. /* To be called only by clipvec() */
  353. static int clipt(double p,double q,double *t0,double *t1)
  354. {
  355.     double r;
  356.  
  357.     if(p<0.0) {
  358.         r=q/p;
  359.         if(r>*t1) 
  360.             return((int)FALSE);
  361.         else 
  362.             if(r>*t0) 
  363.                 *t0=r;
  364.       }
  365.     else if(p>0.0) {
  366.             r=q/p;
  367.             if(r<*t0) 
  368.                 return((int)FALSE);
  369.             else 
  370.                 if(r<*t1) 
  371.                     *t1=r;
  372.       }
  373.     else
  374.         if(q<0.0)
  375.             return((int)FALSE);
  376.     return((int)TRUE);
  377. }
  378.  
  379. #ifdef DEBUG
  380. static void clipvec(int vw,int xa,int ya,int xb,int yb)
  381. {
  382.     printf("%d,%d to %d,%d\n",xa,ya,xb,yb);
  383. }
  384.  
  385. #else
  386. /*
  387.     Draw a vector in vw's window from x0,y0 to x1,y1.
  388.     Zoom the vector to the current visible window,
  389.     and clip it before drawing it.
  390.     Uses Liang-Barsky algorithm from ACM Transactions on Graphics,
  391.         Vol. 3, No. 1, January 1984, p. 7.
  392. */
  393. static void clipvec(int vw,int xa,int ya,int xb,int yb)
  394. {
  395.     int t,b,l,r;
  396.     double x0,y0,x1,y1,t0,t1,deltay,deltax;
  397.     struct VGWINTYPE *vp;
  398.     vp=&VGwin[vw];
  399.  
  400.     t=vp->wintop;
  401.     b=vp->winbot;
  402.     l=vp->winleft;
  403.     r=vp->winright;
  404.  
  405. /* totally visible */
  406.     if(xa<=r&&xb<=r&&xa>=l&&xb>=l&&ya<=t&&yb<=t&&ya>=b&&yb>=b) {
  407.         if (ginon) hidemouse();  /* hide mouse cursor */
  408.         (*RG[vp->RGdevice].drawline)(vp->RGnum,
  409.         (int)((long)(xa - l) * RGXSIZE / vp->winwide),
  410.         (int)((long)(ya- b) * RGYSIZE / vp->wintall),
  411.         (int)((long)(xb - l) * RGXSIZE / vp->winwide),
  412.         (int)((long)(yb- b) * RGYSIZE / vp->wintall));
  413.         if (ginon) showmouse();     /* show mouse cursor */
  414.         return;
  415.       }
  416. /* trivially invisible */
  417.     if((xa>r&&xb>r)||(xa<l&&xb<l)||(ya<b&&yb<b)||(ya>t&&yb>t)) 
  418.         return;
  419. /* the clipping algorithm */
  420.     x0=(double)xa;
  421.     y0=(double)ya;
  422.     x1=(double)xb;
  423.     y1=(double)yb;
  424.     t0=0.0;
  425.     t1=1.0;
  426.     deltax=x1-x0;
  427.  
  428.     if(clipt(-deltax,x0-l,&t0,&t1)) {
  429.         if(clipt(deltax,r-x0,&t0,&t1)) {
  430.             deltay=y1-y0;
  431.             if(clipt(-deltay,y0-b,&t0,&t1)) {
  432.                 if(clipt(deltay,t-y0,&t0,&t1)) {
  433.                     if(t1<1.0) {
  434.                         x1=x0+t1*deltax;
  435.                         y1=y0+t1*deltay;
  436.                       }
  437.                     if(t0>0.0) {
  438.                         x0+=t0*deltax;
  439.                         y0+=t0*deltay;
  440.                       }
  441. /* draw the line, it is at least partially visible */
  442.                     (*RG[vp->RGdevice].drawline)(vp->RGnum,
  443.                         (int)((long)((int)x0-l)*RGXSIZE/vp->winwide),
  444.                         (int)((long)((int)y0-b)*RGYSIZE/vp->wintall),
  445.                         (int)((long)((int)x1-l)*RGXSIZE/vp->winwide),
  446.                         (int)((long)((int)y1-b)*RGYSIZE/vp->wintall));
  447.                   } 
  448.               } 
  449.           } 
  450.       } /* end if */
  451. } /* end clipvec() */
  452. #endif
  453.  
  454. /*******************************************************
  455. ********************************************************
  456. All routines given below may be called by the user
  457. program.  No routines given above may be called from
  458. the user program.
  459. ********************************************************
  460. *******************************************************/
  461.  
  462. /*
  463.     Initialize the whole VG environment.  Should be called ONCE
  464.     at program startup before using the VG routines.
  465. */
  466. void VGinit(void)
  467. {
  468.     int i;
  469.     for(i=0; i<MAXVG; i++)
  470.         VGwin[i].RGdevice=-1; /* no device */
  471. #ifndef DEBUG
  472.     for(i=0; i<MAXRG; i++) 
  473.         (*RG[i].init)();
  474. #endif
  475. }
  476.  
  477. /*
  478.     Make sure window is completely visible, rather than partly or
  479.     completely invisible.
  480.     This function is to be called whenever a window is made active,
  481.     to ensure that the user can see it.
  482. */
  483. void VGuncover(int vw)
  484. {
  485. #ifndef DEBUG
  486.     (*RG[VGwin[vw].RGdevice].uncover)(VGwin[vw].RGnum);
  487. #endif
  488. }
  489.  
  490. #ifdef NOT_USED
  491. /*
  492.     Detach window from its current device and attach it to the
  493.     specified device.  Returns negative number if unable to do so.
  494.     Sample application:  switching an image from #9 to Hercules.
  495.     Must redraw after calling this.
  496. */
  497. int VGdevice(int vw,int dev)
  498. {
  499.     int newwin;
  500.     newwin=(*RG[dev].newwin)();
  501.     if(newwin<0) 
  502.         return((int)newwin);         /* unable to open new window */
  503.     (*RG[VGwin[vw].RGdevice].close)(VGwin[vw].RGnum);
  504.     VGwin[vw].RGdevice=dev;
  505.     VGwin[vw].RGnum=newwin;
  506.     VGwin[vw].pencolor=1;
  507.     fontnum(vw,1);
  508.     return(0);
  509. }
  510. #endif
  511.  
  512. /*
  513.     Create a new VG window and return its number.
  514.     New window will be attached to specified real device.
  515.     Returns -1 if unable to create a new VG window.
  516.  
  517.     device -     number of RG device to use
  518. */
  519. int VGnewwin(int device)
  520. {
  521.     int vw=0;
  522.     while(vw<MAXVG&&VGwin[vw].RGdevice!=-1)
  523.         vw++;
  524.     if(vw==MAXVG) {
  525.         return(-1);
  526.       }
  527.     VGstore[vw]=newstore();
  528.     if(VGstore[vw]==NULL) {
  529.         return(-1);                /* no memory */
  530.       }
  531.     VGwin[vw].RGdevice=device;
  532.     VGwin[vw].RGnum=(*RG[device].newwin)();
  533.     if(VGwin[vw].RGnum< 0) {    /* no windows available on device */
  534.         freestore(VGstore[vw]);
  535.         return(-1);
  536.       }
  537.     VGwin[vw].mode=ALPHA;
  538.     state[vw]=DONE;
  539.     storing[vw]=TRUE;
  540.     VGwin[vw].textcol=0;
  541.     drawing[vw]=1;
  542.     fontnum(vw,0);
  543.     (*RG[device].pencolor)(VGwin[vw].RGnum,1);
  544.     storexy(vw,0,3071);
  545.     VGzoom(vw,0,0,4095,3119);
  546.     return(vw);
  547. }
  548.  
  549. /*
  550.     Clear the store associated with window vw.  
  551.     All contents are lost.
  552.     User program can call this whenever desired.
  553.     Automatically called after receipt of Tek page command.
  554. */
  555. void VGclrstor(int vw)
  556. {
  557.     freestore(VGstore[vw]);
  558.     VGstore[vw]=newstore(); /* Don't have to check for errors; there was definitely enough memory. */
  559. }
  560.  
  561. /*
  562.     Successively call the function pointed to by 'func' for each
  563.     character stored from window vw.  Each character will
  564.     be passed in integer form as the only parameter.  A value of -1
  565.     will be passed on the last call to indicate the end of the data.
  566. */
  567. void VGdumpstore(int vw,void (*func)(int ))
  568. {
  569.     int data;
  570.     STOREP st=VGstore[vw];
  571.  
  572.     topstore(st);
  573.     while((data=nextitem(st))!=-1)(*func)(data);
  574.     (*func)(-1);
  575. }
  576.  
  577. /*
  578.     This is the main Tek emulator process.  Pass it the window and
  579.     the latest input character, and it will take care of the rest.
  580.     Calls RG functions as well as local zoom and character drawing
  581.     functions.
  582. */
  583. void VGdraw(int vw,char c)
  584. {
  585.     char cmd;
  586.     char value;
  587.     char goagain; /* true means go thru the function a second time */
  588.     struct VGWINTYPE *vp;
  589.     vp=&VGwin[vw];
  590.  
  591. /*** MAIN LOOP ***/
  592.      do {
  593.         cmd=(char) ((c>>5) & 0x03);
  594.         value=(char) (c&0x1f);
  595.         goagain=FALSE;
  596.         switch(state[vw]) {
  597.             case HIY:             /* beginning of a vector */
  598.                 vp->nhiy=vp->hiy;
  599.                 vp->nhix=vp->hix;
  600.                 vp->nloy=vp->loy;
  601.                 vp->nlox=vp->lox;
  602.                 vp->ney =vp->ey;
  603.                 vp->nex =vp->ex;
  604.                 switch(cmd) {
  605.                     case 0:
  606.                         if(value==27) {        /* escape sequence */
  607.                             state[vw]=ESCOUT;
  608.                             savstate[vw]=HIY;
  609.                           }
  610.                         else 
  611.                             if(value<27)     /* ignore */
  612.                                 break;
  613.                             else {
  614.                                 state[vw]=CANCEL;
  615.                                 goagain=TRUE;
  616.                               }
  617.                         break;
  618.  
  619.                     case 1:                 /* hiy */
  620.                         vp->nhiy=value;
  621.                         state[vw]=EXTRA;
  622.                         break;
  623.  
  624.                     case 2:                 /* lox */
  625.                         vp->nlox=value;
  626.                         state[vw]=DONE;
  627.                         break;
  628.  
  629.                     case 3:                 /* extra or loy */
  630.                         vp->nloy=value;
  631.                         state[vw]=LOY;
  632.                         break;
  633.                     }
  634.                 break;        
  635.     
  636.             case ESCOUT:
  637.                 if(value!=13&&value!=10&&value!=27&&value!='~') {    /* skip all EOL-type characters */
  638.                     state[vw]=savstate[vw];
  639.                     goagain=TRUE;
  640.                   }
  641.                 break;
  642.  
  643.             case EXTRA:                        /* got hiy; expecting extra or loy */
  644.                 switch(cmd) {
  645.                     case 0:
  646.                         if(value==27) {        /* escape sequence */
  647.                             state[vw]=ESCOUT;
  648.                             savstate[vw]=EXTRA;
  649.                           }
  650.                         else 
  651.                             if(value<27)    /* ignore */
  652.                                 break;
  653.                             else {
  654.                                 state[vw]=DONE;
  655.                                 goagain=TRUE;
  656.                               }
  657.                             break;
  658.  
  659.                     case 1:                 /* hix */
  660.                         vp->nhix=value;
  661.                         state[vw]=LOX;
  662.                         break;
  663.  
  664.                     case 2:                 /* lox */
  665.                         vp->nlox=value;
  666.                         state[vw]=DONE;
  667.                         break;
  668.  
  669.                     case 3:                 /* extra or loy */
  670.                         vp->nloy=value;
  671.                         state[vw]=LOY;
  672.                         break;
  673.                     }
  674.                 break;
  675.     
  676.             case LOY:                         /* got extra or loy; next may be loy or something else */
  677.                 switch(cmd) {
  678.                     case 0:
  679.                         if(value==27) {        /* escape sequence */
  680.                             state[vw]=ESCOUT;
  681.                             savstate[vw]=LOY;
  682.                           }
  683.                         else 
  684.                             if(value<27)     /* ignore */
  685.                                 break;
  686.                             else {
  687.                                 state[vw]=DONE;
  688.                                 goagain=TRUE;
  689.                               }
  690.                         break;
  691.  
  692.                     case 1:                 /* hix */
  693.                         vp->nhix=value;
  694.                         state[vw]=LOX;
  695.                         break;
  696.  
  697.                     case 2:                 /* lox */
  698.                         vp->nlox=value;
  699.                         state[vw]=DONE;
  700.                         break;
  701.  
  702.                     case 3:                 /* this is loy; previous loy was really extra */
  703.                         vp->ney=(char) ((vp->nloy>>2)&3);
  704.                         vp->nex=(char) ((vp->nlox) & 3);
  705.                         vp->nloy=value;
  706.                         state[vw]=HIX;
  707.                         break;
  708.  
  709.                   }
  710.                 break;
  711.     
  712.             case HIX:                         /* hix or lox */
  713.                 switch(cmd) {
  714.                     case 0:
  715.                         if(value==27) {        /* escape sequence */
  716.                             state[vw]=ESCOUT;
  717.                             savstate[vw]=HIX;
  718.                           }
  719.                         else 
  720.                             if(value<27)    /* ignore */
  721.                                 break;
  722.                             else {
  723.                                 state[vw]=DONE;
  724.                                 goagain=TRUE;
  725.                               }
  726.                         break;
  727.  
  728.                     case 1:                 /* hix */
  729.                         vp->nhix=value;
  730.                         state[vw]=LOX;
  731.                         break;
  732.  
  733.                     case 2:                     /* lox */
  734.                         vp->nlox=value;
  735.                         state[vw]=DONE;
  736.                         break;
  737.                   }
  738.                  break;
  739.     
  740.             case LOX:                         /* must be lox */
  741.                 switch(cmd) {
  742.                     case 0:
  743.                         if(value==27) {        /* escape sequence */
  744.                             state[vw]=ESCOUT;
  745.                             savstate[vw]=LOX;
  746.                           }
  747.                         else 
  748.                             if(value< 27)     /* ignore */
  749.                                 break;
  750.                             else {
  751.                                 state[vw]=DONE;
  752.                                 goagain=TRUE;
  753.                               }
  754.                         break;
  755.  
  756.                     case 2:
  757.                         vp->nlox=value;
  758.                         state[vw]=DONE;
  759.                         break;
  760.  
  761.                   }
  762.                 break;
  763.     
  764.             case ENTERVEC:
  765.                 if(c==7)
  766.                     vp->mode=DRAW;
  767.                 if(c<27)
  768.                     break;
  769.                 state[vw]=HIY;
  770.                 vp->mode=TEMPMOVE;
  771.                 vp->modesave=DRAW;
  772.                 goagain=TRUE;
  773.                 break;
  774.  
  775.             case RS:
  776.                 switch(c) {
  777.                     case ' ':                /* pen up */
  778.                         vp->modesave=vp->mode;
  779.                         vp->mode=TEMPMOVE;
  780.                         break;
  781.  
  782.                     case 'P':                /* pen down */
  783.                         vp->mode=DRAW;
  784.                         break;
  785.  
  786.                     case 'D':                /* move up */
  787.                         vp->cury++;
  788.                         break;
  789.  
  790.                     case 'E':
  791.                         vp->cury++;
  792.                         vp->curx++;
  793.                         break;
  794.  
  795.                     case 'A':
  796.                         vp->curx++;
  797.                         break;
  798.  
  799.                     case 'I':
  800.                         vp->curx++;
  801.                         vp->cury--;
  802.                         break;
  803.  
  804.                     case 'H':
  805.                         vp->cury--;
  806.                         break;
  807.  
  808.                     case 'J':
  809.                         vp->curx--;
  810.                         vp->cury--;
  811.                         break;
  812.  
  813.                     case 'B':
  814.                         vp->curx--;
  815.                         break;
  816.  
  817.                     case 'F':
  818.                         vp->cury++;
  819.                         vp->curx--;
  820.                         break;
  821.  
  822.                     case 27:
  823.                         savstate[vw]=RS;
  824.                         state[vw]=ESCOUT;
  825.                         break;
  826.  
  827.                     default:        /*storexy(vw,vp->curx,vp->cury);*/
  828.                         state[vw]=CANCEL;
  829.                         goagain=TRUE;
  830.                         break;
  831.                   }
  832.                 if(vp->mode==DRAW)
  833.                     clipvec(vw,vp->curx,vp->cury,vp->curx,vp->cury);
  834. #ifdef DEBUG
  835.                 printf("RS: %d,%d\n",vp->curx,vp->cury);
  836. #endif
  837.                 break;
  838.  
  839.             case CMD0:                             /* get 1st letter of cmd */
  840.                 switch(c) {
  841.                     case 29:                    /* GS, start draw */
  842.                         state[vw]=DONE;
  843.                         goagain=TRUE;
  844.                         break;
  845.  
  846.                     case '8':
  847.                         fontnum(vw,0);
  848.                         state[vw]=DONE;
  849.                         break;
  850.  
  851.                     case '9':
  852.                         fontnum(vw,1);
  853.                         state[vw]=DONE;
  854.                         break;
  855.  
  856.                     case ':':
  857.                         fontnum(vw,2);
  858.                         state[vw]=DONE;
  859.                         break;
  860.  
  861.                     case ';':
  862.                         fontnum(vw,3);
  863.                         state[vw]=DONE;
  864.                         break;
  865.  
  866.                     case 12: /* form feed=clrscr */
  867.                         VGpage(vw);     /* changes state[vw] to DONE */
  868.                         VGclrstor(vw);                
  869.                         break;
  870.  
  871.                     case 'L':
  872.                         state[vw]=SOMEL;
  873.                         break;
  874.  
  875.                     case 'K':
  876.                         state[vw]=IGNORE;
  877.                         break;
  878.  
  879.                     case 'M':
  880.                         state[vw]=SOMEM;
  881.                         break;
  882.  
  883.                     case 'T':
  884.                         state[vw]=SOMET;
  885.                         break;
  886.  
  887.                     case 26:
  888.                         setgin();            /* set the gin stuff up */
  889.                         unstore(VGstore[vw]);
  890.                         unstore(VGstore[vw]);
  891.                         break;
  892.  
  893.                     case 10:
  894.                     case 13:
  895.                     case 27:
  896.                     case '~':
  897.                         savstate[vw]=DONE;
  898.                         state[vw]=ESCOUT;
  899.                         break;        /* completely ignore these after ESC */
  900.  
  901.                     default:
  902.                         state[vw]=DONE;
  903.                   }                 /* end switch */
  904.                 break;
  905.     
  906.             case SOMET:                /* Got ESC T; now handle 3rd char. */
  907.                 switch(c) {
  908.                     case 'G':         /* set surface color map */
  909.                         state[vw]=INTEGER;
  910.                         savstate[vw]=JUNKARRAY;
  911.                         break;
  912.  
  913.                     case 'F':         /* set dialog area color map */
  914.                         state[vw]=JUNKARRAY;
  915.                         break;
  916.  
  917.                     default:
  918.                         state[vw]=DONE;
  919.                   }            
  920.                 break;
  921.  
  922.             case JUNKARRAY:            /* This character is the beginning of an integer arrayto be discarded.  Get array size. */
  923.                 savstate[vw]=STARTDISC;
  924.                 state[vw]=INTEGER;
  925.                 break;
  926.  
  927.             case STARTDISC:            /* Begin discarding integers. */
  928.                 vp->count=vp->intin + 1;
  929.                 goagain=TRUE;
  930.                 state[vw]=DISCARDING;
  931.                 break;
  932.  
  933.             case DISCARDING:        /* We are in the process of discarding an integer array. */
  934.                 goagain=TRUE;
  935.                 if(!(--(vp->count))) 
  936.                     state[vw]=DONE;
  937.                 else
  938.                     if(vp->count==1) {
  939.                         state[vw]=INTEGER;
  940.                         savstate[vw]=DONE;
  941.                       }
  942.                      else {
  943.                         state[vw]=INTEGER;
  944.                         savstate[vw]=DISCARDING;
  945.                       }
  946.                 break;
  947.  
  948.             case INTEGER:
  949.                 if(c & 0x40) {
  950.                     vp->intin=c & 0x3f;
  951.                     state[vw]=INTEGER1;
  952.                   } 
  953.                 else {
  954.                     vp->intin=c&0x0f;
  955.                     if(!(c & 0x10))
  956.                         vp->intin*=-1;
  957.                     state[vw]=savstate[vw];
  958.                   }
  959.                 break;
  960.  
  961.             case INTEGER1:
  962.                 if(c & 0x40) {
  963.                     vp->intin=(vp->intin<<6)|(c&0x3f);
  964.                     state[vw]=INTEGER2;
  965.                   } 
  966.                 else {
  967.                     vp->intin=(vp->intin<<4)|(c&0x0f);
  968.                     if(!(c & 0x10)) 
  969.                         vp->intin*=-1;
  970.                     state[vw]=savstate[vw];
  971.                   }
  972.                 break;
  973.  
  974.             case INTEGER2:
  975.                 vp->intin=(vp->intin<<4)|(c&0x0f);
  976.                 if(!(c&0x10)) 
  977.                     vp->intin*=-1;
  978.                 state[vw]=savstate[vw];
  979.                 break;
  980.  
  981.             case IGNORE:         /* ignore next char; it's not supported */
  982.                 state[vw]=DONE;
  983.                 break;
  984.     
  985.             case IGNORE2:         /* ignore next 2 chars */
  986.                 state[vw]=IGNORE;
  987.                 break;
  988.  
  989.             case SOMEL:         /* now process 2nd letter */
  990.                 switch(c) {
  991.                     case 'F':     /* move */
  992.                         vp->modesave=vp->mode;
  993.                         vp->mode=TEMPMOVE;
  994.                         state[vw]=HIY;
  995.                         break;
  996.  
  997.                     case 'G':     /* draw */
  998.                         vp->modesave=vp->mode;
  999.                         vp->mode=TEMPDRAW;
  1000.                         state[vw]=HIY;
  1001.                         break;
  1002.  
  1003.                     case 'H':     /* marker */
  1004.                         vp->modesave=vp->mode;
  1005.                         vp->mode=TEMPMARK;
  1006.                         state[vw]=HIY;
  1007.                         break;
  1008.  
  1009.                     case 'Z':   /* clear dialog scroll */
  1010.                         VGpage(vw);     /* changes state[vw] to DONE */
  1011.                         VGclrstor(vw);              
  1012.                         break;
  1013.  
  1014.                     default:
  1015.                         state[vw]=DONE;
  1016.                   }             /* end switch */
  1017.                 break;
  1018.     
  1019.             case SOMEM:
  1020.                 switch(c) {
  1021.                     case 'C':     /* set graphtext size */
  1022.                         savstate[vw]=GTSIZE0;
  1023.                         state[vw]=INTEGER;
  1024.                         break;
  1025.  
  1026.                     case 'L':     /* set line index */
  1027.                         savstate[vw]=COLORINT;
  1028.                         state[vw]=INTEGER;
  1029.                         break;
  1030.  
  1031.                     default:
  1032.                         state[vw]=DONE;
  1033.                   }             /* end switch */
  1034.                 break;
  1035.     
  1036.             case COLORINT:         /* set line index; have integer */
  1037.                 vp->pencolor=vp->intin;
  1038.                 (*RG[vp->RGdevice].pencolor)
  1039.                 (vp->RGnum,vp->intin);
  1040.                 state[vw]=CANCEL;
  1041.                 goagain=TRUE;     /* we ignored current char; now process it */
  1042.                 break;
  1043.  
  1044.             case GTSIZE0:        /* discard the first integer; get the 2nd */
  1045.                 state[vw]=INTEGER; /* get the important middle integer */
  1046.                 savstate[vw]=GTSIZE1;
  1047.                 goagain=TRUE;
  1048.                 break;
  1049.  
  1050.             case GTSIZE1:        /* integer is the height */
  1051.                 if(vp->intin<88)
  1052.                     fontnum(vw,0);
  1053.                 else 
  1054.                     if(vp->intin<149) 
  1055.                         fontnum(vw,4);
  1056.                     else 
  1057.                         fontnum(vw,5);
  1058.                 state[vw]=INTEGER;             /* discard last integer */
  1059.                 savstate[vw]=DONE;
  1060.                 goagain=TRUE;
  1061.                 break;
  1062.  
  1063.  
  1064.             case DONE:             /* ready for anything */
  1065.                 switch(c) {
  1066.                     case 31:
  1067.                         vp->mode=ALPHA; 
  1068.                         state[vw]=CANCEL;
  1069.                         break;
  1070.  
  1071.                     case 30:
  1072.                         state[vw]=RS;
  1073.                         break;
  1074.  
  1075.                     case 28:
  1076.                         if(cmd) {
  1077.                             vp->mode=MARK;
  1078.                             state[vw]=HIY;
  1079.                           }
  1080.                         break;
  1081.  
  1082.                     case 29:
  1083.                         state[vw]=ENTERVEC;
  1084.                         break;
  1085.  
  1086.                     case 27:
  1087.                         state[vw]=CMD0;
  1088.                         break;
  1089.                 
  1090.                     default:
  1091.                         if(vp->mode==ALPHA) { 
  1092.                             drawc(vw,c);
  1093.                             state[vw]=CANCEL;
  1094.                           }
  1095.                         else if(vp->mode==DRAW && cmd) {
  1096.                             state[vw]=HIY;
  1097.                             goagain=TRUE;
  1098.                           }
  1099.                         else if(vp->mode==MARK && cmd) {
  1100.                             state[vw]=HIY;
  1101.                             goagain=TRUE;
  1102.                           }
  1103.                         else if(vp->mode==DRAW &&(c==13||c==10)) {   /* break drawing mode on CRLF */
  1104.                             vp->mode=ALPHA;
  1105.                             state[vw]=CANCEL;
  1106.                           }
  1107.                         else
  1108.                             state[vw]=CANCEL;   /* do nothing */
  1109.                   } /* end switch(c) */
  1110.           } /* end switch(state) */
  1111.         if(state[vw]==DONE) {
  1112.             if(vp->mode==TEMPMOVE) {
  1113.                 vp->mode=vp->modesave;
  1114.                 newcoord(vw);
  1115.               }
  1116.             else 
  1117.                 if(vp->mode==DRAW||vp->mode==TEMPDRAW) {
  1118.                     clipvec(vw,vp->curx,vp->cury,joinup(vp->nhix,vp->nlox,vp->nex),joinup(vp->nhiy,vp->nloy,vp->ney));
  1119.                     if(vp->mode==TEMPDRAW) 
  1120.                         vp->mode=vp->modesave;
  1121.                     newcoord(vw);
  1122.                   }
  1123.                 else 
  1124.                     if(vp->mode==MARK||vp->mode==TEMPMARK)        /* draw marker */
  1125.                         newcoord(vw);
  1126.           }                     /* end if done */
  1127.         if(state[vw]==CANCEL) 
  1128.             state[vw]=DONE;
  1129.       } while(goagain);
  1130. /*** END OF MAIN LOOP ***/
  1131. } /* end VGdraw() */
  1132.  
  1133. /*  Clear screen and have a few other effects:
  1134.     - Return graphics to home position(0,3071)
  1135.     - Switch to alpha mode
  1136.     This is a standard Tek command; don't look at me.
  1137. */
  1138. void VGpage(int vw)
  1139. {
  1140. #ifndef DEBUG
  1141.     (*RG[VGwin[vw].RGdevice].clrscr)(VGwin[vw].RGnum);
  1142.     (*RG[VGwin[vw].RGdevice].pencolor)(VGwin[vw].RGnum,1);
  1143. #endif
  1144.     VGwin[vw].mode=ALPHA;
  1145.     state[vw]=DONE;
  1146.     VGwin[vw].textcol=0;
  1147.     fontnum(vw,0);
  1148.     storexy(vw,0,3071);
  1149. } /* end page */
  1150.  
  1151. /*
  1152.     Redraw window 'vw' in pieces to window 'dest'.
  1153.     Must call this function repeatedly to draw whole image.
  1154.     Only draws part of the image at a time, to yield CPU power.
  1155.     Returns 0 if needs to be called more, or 1 if the image
  1156.     is complete.  Another call would result in the redraw beginning again.
  1157.     User should clear screen before beginning redraw.
  1158. */
  1159. int VGpred(int vw,int dest)
  1160. {
  1161.     int data;
  1162.     STOREP st=VGstore[vw];
  1163.     int count=0;
  1164.  
  1165.     if(drawing[vw]) {                    /* wasn't redrawing */
  1166.         topstore(st);
  1167.         drawing[vw]=0;                    /* redraw incomplete */
  1168.       }
  1169.     while( ++count < (int)PREDCOUNT && ((data=(int)nextitem(st)) != -1) ) 
  1170.         VGdraw(dest,(char)data);
  1171.     if(data==-1)
  1172.         drawing[vw]=1;                     /* redraw complete */
  1173.     return((int)drawing[vw]);
  1174. }
  1175.  
  1176. #ifdef NOT_USED
  1177. /*
  1178.     Abort VGpred redrawing of specified window.
  1179.     Must call this routine if you decide not to complete the redraw.
  1180. */
  1181. void VGstopred(int vw,int dest)
  1182. {
  1183.     drawing[vw]=1;
  1184.     dest=dest;
  1185. }
  1186.  
  1187. /*
  1188.     Redraw the contents of window 'vw' to window 'dest'.
  1189.     Does not yield CPU until done.
  1190.     User should clear the screen before calling this, to avoid 
  1191.     a messy display.
  1192. */
  1193. void VGredraw(int vw,int dest)
  1194. {
  1195.     int data;
  1196.     STOREP st=VGstore[vw];
  1197.  
  1198.     topstore(st);
  1199.     while((data=(int)nextitem(st))!=-1) {
  1200.         VGdraw(dest,(char)data);
  1201.       }
  1202. }
  1203. #endif
  1204.  
  1205. /*
  1206.     Set new borders for zoom/pan region.
  1207.     x0,y0 is lower left; x1,y1 is upper right.
  1208.     User should redraw after calling this.
  1209. */
  1210. void VGzoom(int vw,int x0,int y0,int x1,int y1)
  1211. {
  1212.     VGwin[vw].winbot=y0;
  1213.     VGwin[vw].winleft=x0;
  1214.     VGwin[vw].wintop=y1;
  1215.     VGwin[vw].winright=x1;
  1216.     VGwin[vw].wintall=y1-y0+1;
  1217.     VGwin[vw].winwide=x1-x0+1;
  1218.     VGgiveinfo(vw);
  1219. }
  1220.  
  1221. void VGwhatzoom(int vw,int *px0,int *py0,int *px1,int *py1)
  1222. {
  1223.     *py0=VGwin[vw].winbot;
  1224.     *px0=VGwin[vw].winleft;
  1225.     *py1=VGwin[vw].wintop;
  1226.     *px1=VGwin[vw].winright;
  1227. }
  1228.  
  1229. /*
  1230.     Set zoom/pan borders for window 'dest' equal to those for window 'src'.
  1231.     User should redraw window 'dest' after calling this.
  1232. */
  1233. void VGzcpy(int src,int dest)
  1234. {
  1235.     VGzoom(dest,VGwin[src].winleft, VGwin[src].winbot,
  1236.     VGwin[src].winright, VGwin[src].wintop);
  1237. }
  1238.  
  1239. /*
  1240.     Close virtual window.
  1241.     Release its real graphics device and its store.
  1242. */
  1243. void VGclose(int vw)
  1244. {
  1245.     (*RG[VGwin[vw].RGdevice].close)(VGwin[vw].RGnum);
  1246.     freestore(VGstore[vw]);
  1247.     VGwin[vw].RGdevice=-1;
  1248. }
  1249.  
  1250. /*
  1251.     Draw the data pointed to by 'data' of length 'count'
  1252.     on window vw, and add it to the store for that window.
  1253.     This is THE way for user program to pass Tektronix data.
  1254. */
  1255. int VGwrite(int vw,char *data,int count)
  1256. {
  1257.     char *c=data;
  1258.     char *end=&(data[count]);
  1259.  
  1260.     if(VGwin[vw].RGdevice==-1 || vw>=MAXVG || vw<0)
  1261.         return(-1);        /* window not open */
  1262.     if(storing[vw]) {
  1263.         while(c!=end) {
  1264.             if(*c==24)                /* ASC CAN character */
  1265.                 return((int)(c-data+1));
  1266.             addstore(VGstore[vw], *c);
  1267.             VGdraw(vw,*c++);
  1268.           }
  1269.       } 
  1270.     else {
  1271.         while(c!=end) {
  1272.             if(*c==24)
  1273.                 return((int)(c-data+1));
  1274.             else
  1275.                 VGdraw(vw,*c++);
  1276.           }
  1277.       }
  1278.     return(count);
  1279. }
  1280.  
  1281. /*
  1282.     Send interesting information about the virtual window down to
  1283.     its RG, so that the RG can make VG calls and display zoom values
  1284. */
  1285. void VGgiveinfo(int vw)
  1286. {
  1287.     (*RG[VGwin[vw].RGdevice].info)(VGwin[vw].RGnum,vw,VGwin[vw].winbot,VGwin[vw].winleft,VGwin[vw].wintop,VGwin[vw].winright);
  1288. }
  1289.  
  1290. #ifdef NOT_USED
  1291. /*
  1292.     Return a pointer to a human-readable string
  1293.     which describes the specified real device
  1294. */
  1295. char *VGrgname(int rgdev)
  1296. {
  1297.     return(*RG[rgdev].devname)();
  1298. }
  1299. #endif
  1300.  
  1301. /* Put the specified real device into graphics mode */
  1302. void VGgmode(int rgdev)
  1303. {
  1304. #ifndef DEBUG
  1305.     (*RG[rgdev].gmode)();
  1306. #endif
  1307. }
  1308.  
  1309. /* Put the specified real device into text mode */
  1310. void VGtmode(int rgdev)
  1311. {
  1312.     (*RG[rgdev].tmode)();
  1313. }
  1314.  
  1315. /*
  1316.     Translate data for output as GIN report.
  1317.  
  1318.     User indicates VW number and x,y coordinates of the GIN cursor.
  1319.     Coordinate space is 0-4095, 0-4095 with 0,0 at the bottom left of
  1320.     the real window and 4095,4095 at the upper right of the real window.
  1321.     'c' is the character to be returned as the keypress.
  1322.     'a' is a pointer to an array of 5 characters.  The 5 chars must
  1323.     be transmitted by the user to the remote host as the GIN report.
  1324. */
  1325. void VGgindata(int vw,int x,int y,char c,char *a)
  1326. {
  1327.     unsigned long x1,y1,x2,y2;
  1328.  
  1329.     x2=x;
  1330.     y2=y;
  1331. #ifdef CGW
  1332.     printf("x=%d y=%d\n",x,y);
  1333.     printf("x2=%d y2=%d\n",x2,y2);
  1334. #endif
  1335.     vw-=1;
  1336. #ifdef CGW
  1337.     printf("winwide=%d wintall=%d ",VGwin[vw].winwide,VGwin[vw].wintall);
  1338.     printf("winleft=%d  winbot=%d\n",VGwin[vw].winleft,VGwin[vw].winbot);
  1339. #endif
  1340. #ifdef OLDWAY
  1341.     x2=(((x1*RGXSIZE)/VGwin[vw].winwide)+VGwin[vw].winleft)>>2;
  1342.     y2=(((y1*RGYSIZE)/VGwin[vw].wintall)+VGwin[vw].winbot)>>2;
  1343. #else
  1344.     x1=(x2 * (unsigned long)VGwin[vw].winwide) / 640;
  1345.     y1=(y2 * (unsigned long)VGwin[vw].wintall) / 350;
  1346. #ifdef CGW
  1347.     printf("1 x2=%d  y2=%d\n",(int) x1,(int) y1);
  1348. #endif
  1349.     x1+=VGwin[vw].winleft;
  1350.     y1+=VGwin[vw].winbot;
  1351. #ifdef CGW
  1352.     printf("2 x2=%d  y2=%d\n",(int) x1,(int) y1);
  1353. #endif
  1354.     x1=x1>>2;
  1355.     y1=y1>>2;
  1356. #ifdef CGW
  1357.     printf("3 x2=%d  y2=%d\n",(int) x1,(int) y1);
  1358. #endif
  1359. #endif
  1360.  
  1361.     a[0]=c;
  1362.     a[1]=(char)(0x20 + (x1 >> 5));
  1363.     a[2]=(char)(0x20 | (x1 & 0x001F));
  1364.     a[3]=(char)(0x20 + (y1 >> 5));
  1365.     a[4]=(char)(0x20 | (y1 & 0x001F));
  1366.  
  1367.     printf("a== %c %x %x %x %x\n",a[0],a[1],a[2],a[3],a[4]);
  1368.  
  1369. }
  1370.  
  1371.  
  1372. /**********************************************************************
  1373. *
  1374. * setgin()
  1375. *    shows the GIN cursor on the screen
  1376. */
  1377. void setgin(void )
  1378. {
  1379.     int m1=0,m2=0,m3=0,m4=0;        /* mouse variables to show the mouse cursor */
  1380.  
  1381.     vprint(console->vs,"GIN set\r\n");
  1382.     if(mighty)
  1383.         mousecl(&m1,&m2,&m3,&m4);    /* call mouse routine to show mouse cursor */
  1384.     showmouse();
  1385.     ginon=1;
  1386. } /* end setgin() */
  1387.  
  1388. /**********************************************************************
  1389. *
  1390. * resetgin()
  1391. *    removes the GIN cursor on the screen
  1392. */
  1393. void resetgin(void )
  1394. {
  1395.     hidemouse();
  1396.     vprint(console->vs, "GIN reset\r\n");
  1397.     ginon=0;
  1398. } /* end resetgin() */
  1399.