home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / ncsat.cpt / Telnet2.5 final / tek / vgtek.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-16  |  38.0 KB  |  1,723 lines

  1. /*
  2.  *    vgtek.c by Aaron Contorer 1987 for NCSA
  3.  *    bugfixes by Tim Krauskopf 1988 for NCSA
  4.  *    TEK4105 support by Dave Whittington 1990 (for NCSA, of course)
  5.  *
  6.  *    Takes Tektronix codes as input; sends output to real graphics devices.
  7.  *
  8.  *    CHANGES TO MAKE:
  9.  *    create a function to make sure a window is attached to a real window.
  10.  *      Calling program will call this whenever switching between active windows.
  11.  *    Pass virtual window number to RG driver so it can call back.
  12.  */
  13.  
  14. #include <Stdio.h>
  15. #include <Stdlib.h>
  16. #include <Memory.h>
  17. #include <QuickDraw.h>
  18. #include <Dialogs.h>
  19. #include "configrec.h"
  20. #include "confile.h"
  21. #include "event.h"
  22. #include "hostform.h" 
  23. #include "maclook.h"
  24. #include "vgtek.h"
  25. #include "vgfont.h"
  26. #include "tekstor.h"
  27. #include "tekrgmac.h"
  28. #include "vsinterf.h"
  29. #include "wind.h"
  30.  
  31. #define FALSE 0
  32. #define TRUE 1
  33. #define MAXVG 20 /* maximum number of VG windows */
  34.  
  35. /* temporary states */
  36. #define HIY 0        /* waiting for various pieces of coordinates */
  37. #define EXTRA 1
  38. #define LOY 2
  39. #define HIX 3
  40. #define LOX 4
  41.  
  42. #define DONE    5    /* not waiting for coordinates */
  43. #define ENTERVEC 6    /* entering vector mode */
  44. #define CANCEL    7    /* done but don't draw a line */
  45. #define RS        8    /* RS - incremental plot mode */
  46. #define ESCOUT    9    /* when you receive an escape char after a draw command */
  47. #define CMD0    50    /* got esc, need 1st cmd letter */
  48. #define SOMEL    51    /* got esc L, need 2nd letter */
  49. #define IGNORE    52    /* ignore next char */
  50. #define SOMEM    53    /* got esc M, need 2nd letter */
  51. #define IGNORE2    54
  52. #define INTEGER    60    /* waiting for 1st integer part */
  53. #define INTEGER1 61    /* waiting for 2nd integer part */
  54. #define INTEGER2 62    /* waiting for 3rd (last) integer part */
  55. #define COLORINT 70
  56. #define GTSIZE0 75
  57. #define GTSIZE1 76
  58. #define    GTEXT    77    /* TEK4105 GraphText            17jul90dsw */
  59. #define MARKER    78    /* TEK4105 Marker select        17jul90dsw */
  60. #define    GTPATH    79    /* TEK4105 GraphText path        17jul90dsw */
  61. #define SOMET    80
  62. #define JUNKARRAY 81
  63. #define STARTDISC 82
  64. #define DISCARDING 83
  65. #define    FPATTERN 84    /* TEK4105 FillPattern            17jul90dsw */
  66. #define    GTROT    85    /* TEK4105 GraphText rotation    17jul90dsw */
  67. #define GTROT1    86
  68. #define    GTINDEX    87    /* TEK4105 GraphText color        17jul90dsw */
  69. #define PANEL    88    /* TEK4105 Begin Panel            23jul90dsw */
  70. #define    SUBPANEL 89    /* TEK4105 Begin^2 Panel        25jul90dsw */
  71. #define TERMSTAT 90    /* TEK4105 Report Term Status    24jul90dsw */
  72. #define    SOMER    91    /* TEK4105 for ViewAttributes    10jan91dsw */
  73. #define    VIEWAT    92    /* TEK4105 ViewAttributes        10jan91dsw */
  74. #define VIEWAT2    93
  75.  
  76. /* output modes */
  77. #define ALPHA    0
  78. #define DRAW    1
  79. #define MARK    3
  80. #define TEMPDRAW 101
  81. #define TEMPMOVE 102
  82. #define TEMPMARK 103
  83.  
  84. /* stroked fonts */
  85. #define CHARWIDE 51        /* total horz. size */
  86. #define CHARTALL 76        /* total vert. size */
  87. #define CHARH    10        /* horz. unit size */
  88. #define CHARV    13        /* vert. unit size */
  89.  
  90. /* TEK type selection dialog.  (4105 vs 4014) 16jul90dsw */
  91. #define    TEKDIALOG    2813        /* dialog resource ID */
  92. #define    TEKD_OK        1
  93. #define    TEKD_4105    2
  94. #define    TEKD_4014    3
  95.  
  96. typedef struct TPOINT *pointlist;
  97. typedef    struct TPOINT {
  98.     int        x,y;
  99.     pointlist    next;
  100. } point,*pointlist;
  101.  
  102. extern int TekFound;        /* is there a tek preference?? */
  103. extern int findbyVS(int);
  104. extern WindRec *screens;
  105. extern int RGgetVS(int);
  106.  
  107. struct VGWINTYPE {
  108.     int        RGdevice,RGnum,theVS;
  109.     char    mode,modesave;                    /* current output mode */
  110.     char    loy,hiy,lox,hix,ex,ey;            /* current graphics coordinates */
  111.     char    nloy,nhiy,nlox,nhix,nex,ney;    /* new coordinates */
  112.     int        curx,cury;                        /* current composite coordinates */
  113.     int        savx,savy;                        /* save the panel's x,y */
  114.     int        winbot,wintop,winleft,winright,wintall,winwide; 
  115.         /* position of window in virutal space */
  116.     int        textcol;                        /* text starts in 0 or 2048 */
  117.     int        intin;                            /* integer parameter being input */
  118.     int        pencolor;                        /* current pen color */
  119.     int        fontnum,charx,chary;            /* char size */
  120.     int        count;                            /* for temporary use in special state loops */
  121.     char    TEKtype;                        /* 4105 or 4014?  added: 16jul90dsw */
  122.     char    TEKMarker;                        /* 4105 marker type 17jul90dsw */
  123.     char    TEKOutline;                        /* 4105 panel outline boolean */
  124.     int        TEKPath;                        /* 4105 GTPath */
  125.     int        TEKPattern;                        /* 4105 Panel Fill Pattern */
  126.     int        TEKIndex;                        /* 4105 GTIndex */
  127.     int        TEKRot;                            /* 4105 GTRotation */
  128.     int        TEKSize;                        /* 4105 GTSize */
  129.     int        TEKBackground;                    /* 4105 Background color */
  130.     pointlist    TEKPanel;                    /* 4105 Panel's list of points */
  131.     pointlist    current;                    /* current point in the list */
  132. };
  133.  
  134.  
  135.  
  136. static struct VGWINTYPE *VGwin[MAXVG];  /* BYU - virtual window descriptors */
  137.  
  138. static char state[MAXVG],savstate[MAXVG];
  139.     /* save state in a parallel array for speed */
  140. static STOREP VGstore[MAXVG]; /* the store where data for this window is kept */
  141. static char storing[MAXVG]; /* are we currently saving data from this window */
  142. static int drawing[MAXVG]; /* redrawing or not? */
  143.  
  144. #define NUMSIZES 6 /* number of char sizes */
  145. static int charxset[NUMSIZES] = {56,51,34,31,112,168};
  146. static int charyset[NUMSIZES] = {88,82,53,48,176,264};
  147.  
  148. /*******************************************************************/
  149.  
  150. void donothing(void)
  151. {
  152. }
  153.  
  154.  
  155. /*
  156.  * DoTEKDialog: have the user specify which TEK type they want after a
  157.  *              TEK Page command.  Default: 4014  Returns which type was
  158.  *              selected.
  159.  */
  160.  
  161. int DoTEKDialog(theType)
  162. int    theType;        /* 4014 TEK type initially...  :-) */
  163. {    
  164. DialogPtr    theDialogPtr;
  165. Rect        myRect;
  166. short        type;
  167. short        theItem;
  168. GrafPtr        tempPort;
  169. Handle        t4105,t4014,hOK;
  170. Boolean        done = FALSE;
  171.  
  172.     GetPort(&tempPort);
  173.  
  174.     theDialogPtr = GetNewDialog(TEKDIALOG,(Ptr) 0L,(WindowPtr) -1L);
  175.     DrawDialog(theDialogPtr);
  176.     if (theType == 0) theType = 2;        /* dont ask me... */
  177.     
  178.     SetPort((GrafPtr) theDialogPtr);
  179.  
  180.     GetDItem(theDialogPtr,TEKD_4105,&type,&t4105,&myRect);
  181.     GetDItem(theDialogPtr,TEKD_4014,&type,&t4014,&myRect);
  182.     GetDItem(theDialogPtr,1,&type,&hOK,&myRect);
  183.  
  184.     PenSize(3,3);
  185.     InsetRect( &myRect,-4,-4);
  186.     FrameRoundRect(&myRect,16,16);
  187.  
  188.     SetCursor(&qd.arrow);
  189.     ShowCursor();
  190.  
  191.     
  192.     while (!done)
  193.     {    
  194.         SetCtlValue((ControlHandle) t4105,(theType == 1));
  195.         SetCtlValue((ControlHandle) t4014,(theType == 2));
  196.  
  197.         ModalDialog((ModalFilterProcPtr) 0L,&theItem);
  198.         
  199.         switch(theItem)
  200.         {
  201.             case TEKD_4105:
  202.                 theType = 1;
  203.                 break;
  204.             case TEKD_4014:
  205.                 theType = 2;
  206.                 break;
  207.             case TEKD_OK:
  208.                 done = TRUE;
  209.                 break;
  210.             default:
  211.                 theType = 0;
  212.                 done = TRUE;
  213.                 break;
  214.         }
  215.     }
  216.  
  217.     CloseDialog(theDialogPtr);
  218.     SetPort(tempPort);
  219.  
  220.     return((int) theType);
  221. }
  222.  
  223. /*
  224.  *    Set font for window 'vw' to size 'n'.
  225.  *    Sizes are 0..3 in Tek 4014 standard.
  226.  *    Sizes 4 & 5 are used internally for Tek 4105 emulation.
  227.  */
  228. static fontnum(vw,n)
  229. int vw,n;
  230. {
  231.     if ((n < 0) || (n >= NUMSIZES)) return(-1);
  232.     VGwin[vw]->fontnum = n;
  233.     VGwin[vw]->charx = charxset[n];
  234.     VGwin[vw]->chary = charyset[n];
  235.     return(0);
  236. }
  237.  
  238.  
  239. static storexy(vw,x,y)
  240. int vw,x,y;
  241. /* set graphics x and y position */
  242. {
  243.     VGwin[vw]->curx = x;
  244.     VGwin[vw]->cury = y;
  245. }
  246.  
  247.  
  248. static joinup(hi,lo,e)
  249. int hi,lo,e;
  250. /* returns the number represented by the 3 pieces */
  251. {
  252. #if 1                                                            /* BYU 2.4.7 */
  253.     return (((hi & 31) << 7) | ((lo & 31) << 2) | (e & 3));        /* BYU 2.4.7 */
  254. #else                                                            /* BYU 2.4.7 */
  255.     return (((hi /* & 31 */ ) << 7) | ((lo /* & 31 */ ) << 2) | (e /* & 3 */));
  256. #endif                                                            /* BYU 2.4.7 */
  257. } /* end joinup() */
  258.  
  259.  
  260. static newcoord(vw)
  261. int vw;
  262. /*
  263.  *    Replace x,y with nx,ny
  264.  */
  265. {
  266.     VGwin[vw]->hiy = VGwin[vw]->nhiy;
  267.     VGwin[vw]->hix = VGwin[vw]->nhix;
  268.     VGwin[vw]->loy = VGwin[vw]->nloy;
  269.     VGwin[vw]->lox = VGwin[vw]->nlox;
  270.     VGwin[vw]->ey  = VGwin[vw]->ney;
  271.     VGwin[vw]->ex  = VGwin[vw]->nex;
  272.  
  273.     VGwin[vw]->curx = joinup(VGwin[vw]->nhix,VGwin[vw]->nlox,VGwin[vw]->nex);
  274.     VGwin[vw]->cury = joinup(VGwin[vw]->nhiy,VGwin[vw]->nloy,VGwin[vw]->ney);
  275. }
  276.  
  277.  
  278. static linefeed(vw)
  279. /* 
  280.  *    Perform a linefeed & cr (CHARTALL units) in specified window.
  281.  */
  282. {
  283. /*    int y = joinup(VGwin[vw]->hiy,VGwin[vw]->loy,VGwin[vw]->ey);*/
  284.     int y = VGwin[vw]->cury;
  285.     int x;
  286.  
  287.     if (y > VGwin[vw]->chary) y -= VGwin[vw]->chary;
  288.     else
  289.     {
  290.         y = 3119 - VGwin[vw]->chary;
  291.         VGwin[vw]->textcol = 2048 - VGwin[vw]->textcol;
  292.     }
  293.     x = VGwin[vw]->textcol;
  294.     storexy(vw,x,y);
  295. }
  296.  
  297. /*
  298.  *    Draw a vector in vw's window from x0,y0 to x1,y1.
  299.  *    Zoom the vector to the current visible window,
  300.  *    and clip it before drawing it.
  301.  *    Uses Liang-Barsky algorithm from ACM Transactions on Graphics,
  302.  *        Vol. 3, No. 1, January 1984, p. 7.
  303.  *
  304.  *  Note: since QuickDraw on the Mac already handles clipping, we
  305.  *          will not do any processing here.
  306.  *  14may91dsw
  307.  *
  308.  */
  309. static clipvec(vw,xa,ya,xb,yb)
  310. int vw;
  311. int xa,ya,xb,yb;
  312. {
  313. int t,b,l,r;
  314. struct VGWINTYPE *vp;
  315.  
  316.     vp = VGwin[vw];        /* BYU mod */
  317.  
  318.     t = vp->wintop;
  319.     b = vp->winbot;
  320.     l = vp->winleft;
  321.     r = vp->winright;
  322.  
  323.     (*RG[vp->RGdevice].drawline) (vp->RGnum,
  324.         (int) ((long)(xa - l) * INXMAX / vp->winwide),
  325.         (int) ((long)(ya- b) * INYMAX / vp->wintall),
  326.         (int) ((long)(xb - l) * INXMAX / vp->winwide),
  327.         (int) ((long)(yb- b) * INYMAX / vp->wintall));
  328. } /* end clipvec() */
  329.  
  330.  
  331. /*
  332.  *    Draw a stroked character at the current cursor location.
  333.  *    Uses simple 8-directional moving, 8-directional drawing.
  334.  *
  335.  *    Modified 17jul90dsw: TEK4105 character set added.
  336.  */
  337. static drawc(vw,c)
  338. int vw;
  339. int c; /* character to draw */
  340. {
  341. int        x,y,savex,savey;
  342. int        strokex,strokey;
  343. int        n;                        /* number of times to perform command */
  344. char    *pstroke;                /* pointer into stroke data */
  345. int        hmag,vmag;
  346. int        xdir,ydir;
  347. int        height;
  348.  
  349.     xdir = 1;
  350.     ydir = 0;
  351.  
  352.     if (c == 10)
  353.     {
  354.         linefeed(vw);
  355.         return(0);
  356.     }
  357.  
  358.     if (c == 7)
  359.     {
  360.         (*RG[VGwin[vw]->RGdevice].bell) (VGwin[vw]->RGnum);
  361.         unstore(VGstore[vw]);
  362.         return(0);
  363.     }
  364.  
  365.     savey = y = VGwin[vw]->cury;
  366.     savex = x = VGwin[vw]->curx;
  367.  
  368.     if (c == 8)
  369.     {
  370.         if (savex <= VGwin[vw]->textcol) return(0);
  371.         savex -= VGwin[vw]->charx;
  372.         if (savex < VGwin[vw]->textcol) savex = VGwin[vw]->textcol;
  373.         VGwin[vw]->cury = savey;
  374.         VGwin[vw]->curx = savex;
  375.         return(0);
  376.     }
  377.  
  378.     if (VGwin[vw]->TEKtype)
  379.     {
  380.         height = VGwin[vw]->TEKSize;
  381.         if (c > 126)
  382.         {
  383.             height = 1;
  384.             (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->pencolor);
  385.         }
  386.         else
  387.             (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->TEKIndex);
  388.         hmag = (height*8);
  389.         vmag = (height*8);
  390.         
  391.         xdir = 0;
  392.         switch(VGwin[vw]->TEKRot)
  393.         {
  394.             case 0:
  395.                 xdir = 1;
  396.                 break;
  397.             case 90:
  398.                 ydir = 1;
  399.                 break;
  400.             case 180:
  401.                 xdir = -1;
  402.                 break;
  403.             case 270:
  404.                 ydir = -1;
  405.                 break;
  406.         }
  407.     }
  408.     else
  409.     {
  410.         hmag = VGwin[vw]->charx / 10;
  411.         vmag = VGwin[vw]->chary / 10;
  412.     }
  413.  
  414.     if ((c < 32) || (c > 137))
  415.         return;
  416.     c -= 32;
  417.     pstroke = (VGwin[vw]->TEKtype) ? VGTEKfont[c] : VGfont[c];
  418.     while (*pstroke)
  419.     {
  420.         strokex = x;
  421.         strokey = y;
  422.         n = (*(pstroke++) - 48);    /* run length */
  423.         c = *(pstroke++);            /* direction code */
  424.  
  425.         switch(c)     /* horizontal movement: positive = right */
  426.         {
  427.         case 'e': case 'd': case 'c': case 'y': case 'h': case 'n':
  428.             x += (n * hmag) * xdir;
  429.             y += (n * hmag) * ydir;
  430.             break;
  431.         case 'q': case 'a': case 'z': case 'r': case 'f': case 'v':
  432.             x -= (n * hmag) * xdir;
  433.             y -= (n * hmag) * ydir;
  434.         }
  435.  
  436.         switch(c)    /* vertical movement: positive = up */
  437.         {
  438.         case 'q': case 'w': case 'e': case 'r': case 't': case 'y':
  439.             x -= (n * vmag) * ydir;
  440.             y += (n * vmag) * xdir;
  441.             break;
  442.         case 'z': case 'x': case 'c': case 'v': case 'b': case 'n':
  443.             x += (n * vmag) * ydir;
  444.             y -= (n * vmag) * xdir;
  445.         }
  446.  
  447.         switch(c)    /* draw or move */
  448.         {
  449.         case 'r': case 't': case 'y': case 'f': case 'h':
  450.         case 'v': case 'b': case 'n':
  451.             clipvec (vw,strokex,strokey,x,y);
  452.             break;
  453.         }
  454.     
  455.     } /* end while not at end of string */
  456.  
  457.     /* Update cursor location to next char position */
  458.     savex += VGwin[vw]->charx * xdir;
  459.     savey += VGwin[vw]->charx * ydir;
  460.     if ((savex < 0) || (savex > 4095) || (savey < 0) || (savey > 3119))
  461.     {
  462.         savex = savex < 0 ? 0 : savex > 4095 ? 4095 : savex;
  463.         savey = savey < 0 ? 0 : savey > 3119 ? 3119 : savey;
  464.     }
  465.  
  466.     if (VGwin[vw]->TEKtype)
  467.         (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->pencolor);
  468.  
  469.     VGwin[vw]->cury = savey;
  470.     VGwin[vw]->curx = savex;
  471. }
  472.  
  473. /***********************************************************
  474. ************************************************************
  475. ***                                                         ***
  476. **    All routines given below may be called by the user      **
  477. **    program.  No routines given above may be called from  **
  478. **    the user program.                                      **
  479. ***                                                         ***
  480. ************************************************************
  481. ***********************************************************/
  482.  
  483. VGalloc()        /* BYU - allocate this structure to save global space */
  484. {                /* BYU */
  485.     int i;        /* BYU */
  486.                                     /* BYU */
  487.     for (i=0; i<MAXVG; i++) {        /* BYU */
  488.         VGwin[i] = (struct VGWINTYPE *) malloc(sizeof(struct VGWINTYPE));    /* BYU */
  489.     }            /* BYU */
  490. }                /* BYU */
  491.  
  492.  
  493. /*
  494.  *    Initialize the whole VG environment.  Should be called ONCE
  495.  *    at program startup before using the VG routines.
  496.  */
  497. void VGinit
  498.   (
  499.     void
  500.   )
  501. {
  502. int i;
  503.  
  504.     for (i = 0; i < MAXVG; i++)
  505.     {
  506.         VGwin[i]->RGdevice = -1; /* no device */
  507.     }                                                /* BYU 2.4.7 */
  508.  
  509.     for (i=0; i<MAXRG; i++) (*RG[i].init)();        /* BYU 2.4.7 - important */
  510.  
  511. }
  512.  
  513. /*
  514.  *    Detach window from its current device and attach it to the
  515.  *    specified device.  Returns negative number if unable to do so.
  516.  *    Sample application:  switching an image from #9 to Hercules.
  517.  *    Must redraw after calling this.
  518.  */
  519. VGdevice(vw,dev)
  520. int vw,dev;
  521. {
  522. int newwin;
  523.  
  524.     newwin = (*RG[dev].newwin)();
  525.     if (newwin<0) return(newwin);    /* unable to open new window */
  526.  
  527.     (*RG[VGwin[vw]->RGdevice].close)(VGwin[vw]->RGnum);
  528.     VGwin[vw]->RGdevice = dev;
  529.     VGwin[vw]->RGnum = newwin;
  530.     VGwin[vw]->pencolor = 1;
  531.     fontnum(vw,1);
  532.     return(0);
  533. }
  534.  
  535.  
  536. /*
  537.  *    create a new VG window and return its number.
  538.  *    New window will be attached to specified real device.
  539.  *    Returns -1 if unable to create a new VG window.
  540.  *
  541.  *    Modified 16jul90dsw: Support selection of 4105 or 4014.
  542.  */
  543. int VGnewwin
  544.   (
  545.     int device, /* number of RG device to use */
  546.     int theVS
  547.   )
  548. {
  549. int vw = 0;
  550. int    theScrn;
  551.  
  552.     while ((vw < MAXVG) && (VGwin[vw]->RGdevice != -1)) vw++;
  553.     if (vw == MAXVG)
  554.         return(-1);
  555.     VGstore[vw] = newstore();
  556.  
  557.     if (VGstore[vw] == NULL)
  558.         return(-1);                    /* Burp.  No memory. */
  559.     VGwin[vw]->RGdevice = device;
  560.     VGwin[vw]->RGnum = (*RG[device].newwin)();
  561.  
  562.     theScrn = findbyVS(theVS);
  563.     VGwin[vw]->TEKtype = screens[theScrn].tektype;
  564.     
  565. /*
  566.  * Added 16jul90dsw: the following 'if' construct was added to handle the
  567.  * selection between 4105 and 4014.  Uses 'DoTEKDialog' above.
  568.  */
  569.  
  570.     if (!TekFound)
  571.     {
  572.         if (!(VGwin[vw]->TEKtype = DoTEKDialog(VGwin[vw]->TEKtype)))
  573.          {
  574.             freestore(VGstore[vw]);        /* User hit CANCEL, so clean up and leave. */
  575.             VGwin[vw]->RGdevice = -1;
  576.             return(-1);
  577.         }
  578.         VGwin[vw]->TEKtype &= 1;
  579.     }
  580.  
  581.     if (VGwin[vw]->RGnum < 0)
  582.     {
  583.         /* no windows available on device */
  584.         freestore(VGstore[vw]);
  585.         VGwin[vw]->RGdevice = -1;    /* Added 16jul90dsw: seems like this is needed. */
  586.         return(-1);
  587.     }
  588.             
  589.     VGwin[vw]->mode = ALPHA;
  590.     VGwin[vw]->TEKPanel = (pointlist) NULL;
  591.     VGwin[vw]->theVS = theVS;
  592.     state[vw] = DONE;
  593.     storing[vw] = TRUE;
  594.     VGwin[vw]->textcol = 0;
  595.     drawing[vw] = 1;
  596.     fontnum(vw,0);
  597.     (*RG[device].pencolor)(VGwin[vw]->RGnum,1);
  598.  
  599.     storexy(vw,0,3071);
  600. #if 1                                        /* BYU 2.4.7 */
  601.     VGzoom(vw,0,0,4095,3119);                /* BYU 2.4.7 - important */
  602. #else                                        /* BYU 2.4.7 */
  603.     VGzoom(vw,0,0,INXMAX-1,INYMAX-1);
  604. #endif                                        /* BYU 2.4.7 */
  605.     return(vw);
  606. }
  607.  
  608.  
  609. /* 
  610.  *    Clear the store associated with window vw.  
  611.  *    All contents are lost.
  612.  *    User program can call this whenever desired.
  613.  *    Automatically called after receipt of Tek page command.
  614.  */
  615. VGclrstor(vw)
  616. int vw;
  617. {
  618.     freestore(VGstore[vw]);
  619.     VGstore[vw] = newstore();
  620.         /* Don't have to check for errors --    */
  621.         /* there was definitely enough memory.    */
  622. }
  623.  
  624.  
  625. VGdumpstore(vw,func)
  626. int vw;
  627. int (*func)();
  628. /*
  629.  *    Successively call the function pointed to by 'func' for each
  630.  *    character stored from window vw.  Each character will
  631.  *    be passed in integer form as the only parameter.  A value of -1
  632.  *    will be passed on the last call to indicate the end of the data.
  633.  */
  634. {
  635.     int        data;
  636.     STOREP    st = VGstore[vw];
  637.  
  638.     topstore(st);
  639.     while ((data = nextitem(st)) != -1) (*func)(data);
  640.     (*func)(-1);
  641. }
  642.  
  643.  
  644. /*
  645.  *    This is the main Tek emulator process.  Pass it the window and
  646.  *    the latest input character, and it will take care of the rest.
  647.  *    Calls RG functions as well as local zoom and character drawing
  648.  *    functions.
  649.  *
  650.  *    Modified 16jul90dsw:
  651.  *        Added 4105 support.
  652.  */
  653. void VGdraw(vw,c)
  654. int        vw;
  655. char    c;            /* the latest input char */
  656. {
  657. char    cmd;
  658. char    value;
  659. char    goagain;    /* true means go thru the function a second time */
  660. char    temp[80];
  661. RgnHandle    PanelRgn;
  662. struct    VGWINTYPE *vp;
  663. pointlist temppoint;
  664.  
  665.     vp = VGwin[vw];        /* BYU */
  666.  
  667.     temp[0] = c;
  668.     temp[1] = (char) 0;
  669.  
  670.     /*** MAIN LOOP ***/
  671.      do
  672.     {
  673.         c &= 0x7f;                /* BYU 2.4.15 */
  674.          cmd = (c >> 5) & 0x03;
  675.         value = c & 0x1f;
  676.         goagain = FALSE;
  677.  
  678.         switch(state[vw])
  679.         {
  680.         case HIY: /* beginning of a vector */
  681.             vp->nhiy = vp->hiy;
  682.             vp->nhix = vp->hix;
  683.             vp->nloy = vp->loy;
  684.             vp->nlox = vp->lox;
  685.             vp->ney  = vp->ey;
  686.             vp->nex  = vp->ex;
  687.             
  688.             switch(cmd)
  689.             {
  690.             case 0:
  691.                 if (value == 27)        /* escape sequence */
  692.                 {
  693.                     state[vw] = ESCOUT;
  694.                     savstate[vw] = HIY;
  695.                 }
  696.                 else if (value < 27)    /* ignore */
  697.                 {
  698.                     break;
  699.                 }
  700.                 else
  701.                 {
  702.                     state[vw] = CANCEL;
  703.                     goagain = TRUE;
  704.                 }
  705.                 break;
  706.             case 1:                        /* hiy */
  707.                 vp->nhiy = value;
  708.                 state[vw] = EXTRA;
  709.                 break;
  710.             case 2:                        /* lox */
  711.                 vp->nlox = value;
  712.                 state[vw] = DONE;
  713.                 break;
  714.             case 3:                        /* extra or loy */
  715.                 vp->nloy = value;
  716.                 state[vw] = LOY;
  717.                 break;
  718.             }
  719.             break;        
  720.         case ESCOUT:
  721.             if ((value != 13) && (value != 10) && (value != 27) && (value != '~'))
  722.             {
  723.                 state[vw] = savstate[vw];        /* skip all EOL-type characters */
  724.                 goagain = TRUE;
  725.             }
  726.             break;
  727.         case EXTRA:    /* got hiy; expecting extra or loy */
  728.             switch(cmd)
  729.             {
  730.             case 0:
  731.                 if (value == 27)        /* escape sequence */
  732.                 {
  733.                     state[vw] = ESCOUT;
  734.                     savstate[vw] = EXTRA;
  735.                 }
  736.                 else if (value < 27)    /* ignore */
  737.                 {
  738.                     break;
  739.                 }
  740.                 else
  741.                 {
  742.                     state[vw] = DONE;
  743.                     goagain = TRUE;
  744.                 }
  745.                 break;
  746.             case 1:                        /* hix */
  747.                 vp->nhix = value;
  748.                 state[vw] = LOX;
  749.                 break;
  750.             case 2:                        /* lox */
  751.                 vp->nlox = value;
  752.                 state[vw] = DONE;
  753.                 break;
  754.             case 3:                        /* extra or loy */
  755.                 vp->nloy = value;
  756.                 state[vw] = LOY;
  757.                 break;
  758.             }
  759.             break;
  760.         case LOY: /* got extra or loy; next may be loy or something else */
  761.             switch(cmd)
  762.             {
  763.             case 0:
  764.                 if (value == 27)        /* escape sequence */
  765.                 {
  766.                     state[vw] = ESCOUT;
  767.                     savstate[vw] = LOY;
  768.                 }
  769.                 else if (value < 27)    /* ignore */
  770.                 {
  771.                     break;
  772.                 }
  773.                 else
  774.                 {
  775.                     state[vw] = DONE;
  776.                     goagain = TRUE;
  777.                 }
  778.                 break;
  779.             case 1: /* hix */
  780.                 vp->nhix = value;
  781.                 state[vw] = LOX;
  782.                 break;
  783.             case 2: /* lox */
  784.                 vp->nlox = value;
  785.                 state[vw] = DONE;
  786.                 break;
  787.             case 3: /* this is loy; previous loy was really extra */
  788.                 vp->ney = (vp->nloy >> 2) & 3;
  789.                 vp->nex = vp->nloy & 3;
  790.                 vp->nloy = value;
  791.                 state[vw] = HIX;
  792.                 break;
  793.             }
  794.             break;
  795.         case HIX:                        /* hix or lox */
  796.             switch(cmd)
  797.             {
  798.             case 0:
  799.                 if (value == 27)        /* escape sequence */
  800.                 {
  801.                     state[vw] = ESCOUT;
  802.                     savstate[vw] = HIX;
  803.                 }
  804.                 else if (value < 27)    /* ignore */
  805.                 {
  806.                     break;
  807.                 }
  808.                 else
  809.                 {
  810.                     state[vw] = DONE;
  811.                     goagain = TRUE;
  812.                 }
  813.                 break;
  814.             case 1:                        /* hix */
  815.                 vp->nhix = value;
  816.                 state[vw] = LOX;
  817.                 break;
  818.             case 2:                        /* lox */
  819.                 vp->nlox = value;
  820.                 state[vw] = DONE;
  821.                 break;
  822.             }
  823.              break;
  824.     
  825.         case LOX:                        /* must be lox */
  826.             switch(cmd)
  827.             {
  828.             case 0:
  829.                 if (value == 27)        /* escape sequence */
  830.                 {
  831.                     state[vw] = ESCOUT;
  832.                     savstate[vw] = LOX;
  833.                 }
  834.                 else if (value < 27)    /* ignore */
  835.                 {
  836.                     break;
  837.                 }
  838.                 else
  839.                 {
  840.                     state[vw] = DONE;
  841.                     goagain = TRUE;
  842.                 }
  843.                 break;
  844.             case 2:
  845.                 vp->nlox = value;
  846.                 state[vw] = DONE;
  847.                 break;
  848.             }
  849.             break;
  850.     
  851.         case ENTERVEC:
  852.             if (c == 7) vp->mode = DRAW;
  853.             if (c < 32)
  854.             {
  855.                 state[vw] = DONE;
  856.                 goagain = TRUE;
  857.                 vp->mode = DONE;
  858.                 break;
  859.             }
  860.             state[vw] = HIY;
  861.             vp->mode = TEMPMOVE;
  862.             vp->modesave = DRAW;
  863.             goagain = TRUE;
  864.             break;
  865.         case RS:
  866.             switch (c)
  867.             {
  868.             case ' ':                /* pen up */
  869.                 vp->modesave = vp->mode;
  870.                 vp->mode = TEMPMOVE;
  871.                 break;
  872.             case 'P':                /* pen down */
  873.                 vp->mode = DRAW;
  874.                 break;
  875.             case 'D':                /* move up */
  876.                 vp->cury++;
  877.                 break;
  878.             case 'E':
  879.                 vp->cury++;
  880.                 vp->curx++;
  881.                 break;
  882.             case 'A':
  883.                 vp->curx++;
  884.                 break;
  885.             case 'I':
  886.                 vp->curx++;
  887.                 vp->cury--;
  888.                 break;
  889.             case 'H':
  890.                 vp->cury--;
  891.                 break;
  892.             case 'J':
  893.                 vp->curx--;
  894.                 vp->cury--;
  895.                 break;
  896.             case 'B':
  897.                 vp->curx--;
  898.                 break;
  899.             case 'F':
  900.                 vp->cury++;
  901.                 vp->curx--;
  902.                 break;
  903.             case 27:
  904.                 savstate[vw] = RS;
  905.                 state[vw] = ESCOUT;
  906.                 break;
  907.             default:
  908. /*                storexy(vw,vp->curx,vp->cury);*/
  909.                 state[vw] = CANCEL;
  910.                 goagain = TRUE;
  911.                 break;
  912.             }
  913.             if (vp->mode == DRAW)
  914.                 clipvec(vw,vp->curx,vp->cury,vp->curx,vp->cury);
  915.             break;
  916.         case CMD0: /* *->CMD0: get 1st letter of cmd */
  917.             switch(c)
  918.             {
  919.             case 29:                    /* GS, start draw */
  920.                 state[vw] = DONE;
  921.                 goagain = TRUE;
  922.                 break;
  923.             case '%':
  924.                 state[vw] = TERMSTAT;
  925.                 break;
  926.             case '8':
  927.                 fontnum(vw,0);
  928.                 state[vw] = DONE;
  929.                 break;
  930.             case '9':
  931.                 fontnum(vw,1);
  932.                 state[vw] = DONE;
  933.                 break;
  934.             case ':':
  935.                 fontnum(vw,2);
  936.                 state[vw] = DONE;
  937.                 break;
  938.             case ';':
  939.                 fontnum(vw,3);
  940.                 state[vw] = DONE;
  941.                 break;
  942.             case 12: /* form feed = clrscr */
  943.                 if (screens[findbyVS(vp->theVS)].ESclear) {        /* BYU 2.4.8 */
  944.                     VGpage(vw);                                    /* BYU 2.4.8 */
  945.                     VGclrstor(vw);                                /* BYU 2.4.8 */
  946.                 }                                                /* BYU 2.4.8 */
  947.                 break;
  948.             case 'L':
  949.                 state[vw] = SOMEL;
  950.                 break;
  951.             case 'K':
  952.                 state[vw] = IGNORE;
  953.                 break;
  954.             case 'M':
  955.                 state[vw] = SOMEM;
  956.                 break;
  957.             case 'R':
  958.                 state[vw] = SOMER;
  959.                 break;
  960.             case 'T':
  961.                 state[vw] = SOMET;
  962.                 break;
  963.             case 26:
  964.                 (*RG[vp->RGdevice].gin)(vp->RGnum);
  965.                 unstore(VGstore[vw]);
  966.                 unstore(VGstore[vw]);
  967.                 break;
  968.             case 10:
  969.             case 13:
  970.             case 27:
  971.             case '~':
  972.                 savstate[vw] = DONE;
  973.                 state[vw] = ESCOUT;
  974.                 break;            /* completely ignore these after ESC */
  975.             default:
  976.                 state[vw] = DONE;
  977.             }
  978.             break;
  979.         case TERMSTAT:
  980.             switch(c)
  981.             {
  982.                 case '!':
  983.                     state[vw] = INTEGER;        /* Drop the next integer */
  984.                     savstate[vw] = DONE;
  985.                     break;
  986.             }
  987.             break;
  988.         case SOMER:
  989.             switch(c)
  990.             {
  991.                 case 'A':
  992.                     state[vw] = INTEGER;
  993.                     savstate[vw] = VIEWAT;
  994.                     break;
  995.             }
  996.             break;
  997.         case VIEWAT:
  998.             state[vw] = INTEGER;
  999.             savstate[vw] = VIEWAT2;
  1000.             goagain = TRUE;
  1001.             break;
  1002.         case VIEWAT2:
  1003.             vp->TEKBackground = vp->intin < 0 ? 0 : vp->intin > 7 ? 7 : vp->intin;
  1004.             state[vw] = INTEGER;
  1005.             savstate[vw] = DONE;
  1006.             goagain = TRUE;
  1007.             break;
  1008.         case SOMET:                /* Got ESC T; now handle 3rd char. */
  1009.             switch(c)
  1010.             {
  1011.             case 'C':            /* GCURSOR */
  1012.                 vp->intin = 3;
  1013.                 state[vw] = STARTDISC;
  1014.                 break;
  1015.             case 'D':
  1016.                 vp->intin = 2;
  1017.                 state[vw] = STARTDISC;
  1018.                 break;
  1019.             case 'F':            /* set dialog area color map */
  1020.                 state[vw] = JUNKARRAY;
  1021.                 break;
  1022.             case 'G':            /* set surface color map */
  1023.                 state[vw] = INTEGER;
  1024.                 savstate[vw] = JUNKARRAY;
  1025.                 break;
  1026.             default:
  1027.                 state[vw] = DONE;
  1028.             }            
  1029.             break;
  1030.         case JUNKARRAY:            /* This character is the beginning of an integer
  1031.                                     array to be discarded.  Get array size. */
  1032.             savstate[vw] = STARTDISC;
  1033.             state[vw] = INTEGER;
  1034.             break;                    
  1035.         case STARTDISC:            /* Begin discarding integers. */
  1036.             vp->count = vp->intin + 1;
  1037.             goagain = TRUE;
  1038.             state[vw] = DISCARDING;
  1039.             break;
  1040.         case DISCARDING:
  1041.             /* We are in the process of discarding an integer array. */
  1042.             goagain = TRUE;
  1043.             if (!(--(vp->count))) state[vw] = DONE;
  1044.             else if (vp->count == 1)
  1045.             {
  1046.                 state[vw] = INTEGER;
  1047.                 savstate[vw] = DONE;
  1048.             }
  1049.             else
  1050.             {
  1051.                 state[vw] = INTEGER;
  1052.                 savstate[vw] = DISCARDING;
  1053.             }
  1054.             break;
  1055.         case INTEGER:
  1056.             if (c & 0x40)
  1057.             {
  1058.                 vp->intin = c & 0x3f;
  1059.                 state[vw] = INTEGER1;
  1060.             }
  1061.             else
  1062.             {
  1063.                 vp->intin = c & 0x0f;
  1064.                 if (!(c & 0x10)) vp->intin *= -1;
  1065.                 state[vw] = savstate[vw];
  1066.             }
  1067.             break;
  1068.         case INTEGER1:
  1069.             if (c & 0x40)
  1070.             {
  1071.                 vp->intin = (vp->intin << 6) | (c & 0x3f);
  1072.                 state[vw] = INTEGER2;
  1073.             }
  1074.             else
  1075.             {
  1076.                 vp->intin = (vp->intin << 4) | (c & 0x0f);
  1077.                 if (!(c & 0x10)) vp->intin *= -1;
  1078.                 state[vw] = savstate[vw];
  1079.             }
  1080.             break;
  1081.         case INTEGER2:
  1082.             vp->intin = (vp->intin << 4) | (c & 0x0f);
  1083.             if (!(c & 0x10)) vp->intin *= -1;
  1084.             state[vw] = savstate[vw];
  1085.             break;
  1086.         case IGNORE:            /* ignore next char; it's not supported */
  1087.             state[vw] = DONE;
  1088.             break;
  1089.         case IGNORE2:            /* ignore next 2 chars */
  1090.             state[vw] = IGNORE;
  1091.             break;
  1092.         case SOMEL:                /* now process 2nd letter */
  1093.             switch(c)
  1094.             {
  1095.             case 'E':                    /* END PANEL 25jul90dsw */
  1096.                 if (vp->TEKtype)
  1097.                 {
  1098.                     if (vp->TEKPanel)
  1099.                     {
  1100.                         if ((vp->current->x != vp->savx) ||
  1101.                             (vp->current->y != vp->savy))
  1102.                         {
  1103.                             temppoint = (pointlist) NewPtr(sizeof(point));
  1104.                             temppoint->x = vp->savx;
  1105.                             temppoint->y = vp->savy;
  1106.                             temppoint->next = (pointlist) NULL;
  1107.                             vp->current->next = temppoint;
  1108.                         }
  1109.                         temppoint = vp->current = vp->TEKPanel;
  1110.                         vp->savx = vp->curx = vp->current->x;
  1111.                         vp->savy = vp->cury = vp->current->y;
  1112.                         vp->current = vp->current->next;
  1113.                         DisposPtr((Ptr) temppoint);
  1114.                         PanelRgn = NewRgn();
  1115.                         OpenRgn();
  1116.                         while (vp->current)
  1117.                         {
  1118.                             clipvec(vw,vp->curx,vp->cury,
  1119.                                     vp->current->x,vp->current->y);
  1120.                             temppoint = vp->current;
  1121.                             vp->curx = vp->current->x;
  1122.                             vp->cury = vp->current->y;
  1123.                             vp->current = vp->current->next;
  1124.                             DisposPtr((Ptr) temppoint);
  1125.                         }
  1126.                         CloseRgn(PanelRgn);
  1127.                         if (vp->TEKPattern <= 0)
  1128.                         (*RG[vp->RGdevice].pencolor)(vp->RGnum,-vp->TEKPattern);
  1129.                         PaintRgn(PanelRgn);
  1130.                 /*        if (vp->TEKOutline) 
  1131.                             FrameRgn(PanelRgn); */
  1132.                         DisposeRgn(PanelRgn);
  1133.                         (*RG[vp->RGdevice].pencolor)(vp->RGnum,vp->pencolor);
  1134.                         vp->TEKPanel = (pointlist) NULL;
  1135.                         vp->curx = vp->savx;
  1136.                         vp->cury = vp->savy;
  1137.                     }
  1138.                 }
  1139.                 state[vw] = DONE;
  1140.                 break;
  1141.             case 'F':                    /* MOVE */
  1142.                 vp->modesave = vp->mode;
  1143.                 vp->mode = TEMPMOVE;
  1144.                 state[vw] = HIY;
  1145.                 break;
  1146.             case 'G':                    /* DRAW */
  1147.                 vp->modesave = vp->mode;
  1148.                 vp->mode = TEMPDRAW;
  1149.                 state[vw] = HIY;
  1150.                 break;
  1151.             case 'H':                    /* MARKER */
  1152.                 vp->modesave = vp->mode;
  1153.                 vp->mode = TEMPMARK;
  1154.                 state[vw] = HIY;
  1155.                 break;
  1156.             case 'I':                    /* DAINDEX 24jul90dsw*/
  1157.                 state[vw] = STARTDISC;
  1158.                 vp->intin = 3;
  1159.                 break;
  1160.             case 'L':
  1161.                 state[vw] = INTEGER;
  1162.                 savstate[vw] = DONE;
  1163.                 break;
  1164.             case 'P':                    /* BEGIN PANEL 17jul90dsw */
  1165.                 if (vp->TEKtype)        /* 4105 only */
  1166.                 {
  1167.                     state[vw] = HIY;
  1168.                     vp->mode = PANEL;
  1169.                 }
  1170.                 else
  1171.                     state[vw] = DONE;
  1172.                 break;
  1173.             case 'T':                    /* GTEXT 17jul90dsw */
  1174.                 if (vp->TEKtype)        /* 4105 only */
  1175.                 {
  1176.                     savstate[vw] = GTEXT;
  1177.                     state[vw] = INTEGER;
  1178.                 }
  1179.                 else
  1180.                     state[vw] = DONE;
  1181.                 break;
  1182.             default:
  1183.                 state[vw] = DONE;
  1184.             }
  1185.             break;
  1186.         case SOMEM:
  1187.             switch(c)
  1188.             {
  1189.             case 'C':                    /* set graphtext size */
  1190.                 savstate[vw] = GTSIZE0;
  1191.                 state[vw] = INTEGER;
  1192.                 break;
  1193.             case 'L':                    /* set line index */
  1194.                 savstate[vw] = COLORINT;
  1195.                 state[vw] = INTEGER;
  1196.                 break;
  1197.             case 'M':                    /* MARKERTYPE 17jul90dsw */
  1198.                 if (vp->TEKtype)
  1199.                 {
  1200.                     savstate[vw] = MARKER;
  1201.                     state[vw] = INTEGER;
  1202.                 }
  1203.                 else
  1204.                     state[vw] = DONE;
  1205.                 break;
  1206.             case 'N':                    /* GTPATH 17jul90dsw */
  1207.                 if (vp->TEKtype)
  1208.                 {
  1209.                     savstate[vw] = GTPATH;
  1210.                     state[vw] = INTEGER;
  1211.                 }
  1212.                 else
  1213.                     state[vw] = DONE;
  1214.                 break;
  1215.             case 'P':                    /* FillPattern 17jul90dsw */
  1216.                 if (vp->TEKtype)
  1217.                 {
  1218.                     savstate[vw] = FPATTERN;
  1219.                     state[vw] = INTEGER;
  1220.                 }
  1221.                 else
  1222.                     state[vw] = DONE;
  1223.                 break;
  1224.             case 'R':                    /* GTROT 17jul90dsw */
  1225.                 if (vp->TEKtype)
  1226.                 {
  1227.                     savstate[vw] = GTROT;
  1228.                     state[vw] = INTEGER;
  1229.                 }
  1230.                 else
  1231.                     state[vw] = DONE;
  1232.                 break;
  1233.             case 'T':                    /* GTINDEX 17jul90dsw */
  1234.                 if (vp->TEKtype)
  1235.                 {
  1236.                     savstate[vw] = GTINDEX;
  1237.                     state[vw] = INTEGER;
  1238.                 }
  1239.                 else
  1240.                     state[vw] = DONE;
  1241.                 break;
  1242.             case 'V':
  1243.                 if (vp->TEKtype)
  1244.                 {
  1245.                     state[vw] = INTEGER;
  1246.                     savstate[vw] = DONE;
  1247.                 }
  1248.                 else
  1249.                     state[vw] = DONE;
  1250.                 break;
  1251.             default:
  1252.                 state[vw] = DONE;
  1253.             }
  1254.             break;
  1255.         case COLORINT:                /* set line index; have integer */
  1256.             vp->pencolor = vp->intin;
  1257.             (*RG[vp->RGdevice].pencolor)(vp->RGnum,vp->intin);
  1258.             state[vw] = CANCEL;
  1259.             goagain = TRUE;            /* we ignored current char; now process it */
  1260.             break;
  1261.         case GTSIZE0:                /* discard the first integer; get the 2nd */
  1262.             state[vw] = INTEGER;    /* get the important middle integer */
  1263.             savstate[vw] = GTSIZE1;
  1264.             goagain = TRUE;
  1265.             break;
  1266.         case GTSIZE1:                /* integer is the height */
  1267.             if (vp->TEKtype)
  1268.             {
  1269.                 if (vp->intin < 88) vp->TEKSize = 1;
  1270.                 else if ((vp->intin > 87) && (vp->intin < 149)) vp->TEKSize = 2;
  1271.                 else if ((vp->intin > 148) && (vp->intin < 209)) vp->TEKSize = 3;
  1272.                 else if (vp->intin > 208) vp->TEKSize = vp->intin / 61;
  1273.                 VGwin[vw]->charx = (vp->TEKSize * 52);
  1274.                 VGwin[vw]->chary = (vp->TEKSize * 64);
  1275.             }
  1276.             else
  1277.             {
  1278.                 if (vp->intin < 88)
  1279.                     fontnum(vw,0);
  1280.                 else if (vp->intin < 149)
  1281.                     fontnum(vw,4);
  1282.                 else
  1283.                     fontnum(vw,5);
  1284.             }
  1285.             state[vw] = INTEGER;    /* discard last integer */
  1286.             savstate[vw] = DONE;
  1287.             goagain = TRUE;
  1288.             break;
  1289.         case GTEXT:                    /* TEK4105 GraphText output.  17jul90dsw */
  1290.             if (vp->intin > 0)
  1291.             {
  1292.                 drawc(vw,(int) c);    /* Draw the character */
  1293.                 vp->intin--;        /* One less character in the string... */
  1294.             }
  1295.             else
  1296.             {
  1297.                 goagain = TRUE;
  1298.                 state[vw] = DONE;
  1299.                 newcoord(vw);
  1300.             }
  1301.             break;
  1302.         case MARKER:                /* TEK4105 Set marker type.  17jul90dsw */
  1303.             vp->TEKMarker = vp->intin;
  1304.             if (vp->TEKMarker > 10) vp->TEKMarker = 10;
  1305.             if (vp->TEKMarker <  0) vp->TEKMarker = 0;
  1306.             state[vw] = DONE;
  1307.             goagain = TRUE;
  1308.             break;
  1309.         case GTPATH:
  1310.             vp->TEKPath = vp->intin;
  1311.             state[vw] = DONE;
  1312.             goagain = TRUE;
  1313.             break;
  1314.         case FPATTERN:
  1315.             vp->TEKPattern = (vp->intin <  -7) ?  -7 :
  1316.                              (vp->intin > 149) ? 149 : vp->intin;
  1317.             state[vw] = DONE;
  1318.             goagain = TRUE;
  1319.             break;
  1320.         case GTROT:
  1321.             vp->TEKRot = vp->intin;
  1322.             state[vw] = INTEGER;
  1323.             savstate[vw] = GTROT1;
  1324.             goagain = TRUE;
  1325.             break;
  1326.         case GTROT1:
  1327.             vp->TEKRot = (vp->TEKRot) << (vp->intin);
  1328.             vp->TEKRot = ((vp->TEKRot + 45) / 90) * 90;
  1329.             state[vw] = DONE;
  1330.             goagain = TRUE;
  1331.             break;
  1332.         case GTINDEX:
  1333.             vp->TEKIndex = (vp->intin < 0) ? 0 : (vp->intin > 7) ? 7 : vp->intin;
  1334.             state[vw] = DONE;
  1335.             goagain = TRUE;
  1336.             break;
  1337.         case PANEL:
  1338.             vp->TEKOutline = (vp->intin == 0) ? 0 : 1;
  1339.             temppoint = (pointlist) NewPtr(sizeof(point));
  1340.             if (vp->TEKPanel)
  1341.             {
  1342.                 if ((vp->current->x != vp->savx) && (vp->current->y != vp->savy))
  1343.                 {
  1344.                     temppoint->x = vp->savx;
  1345.                     temppoint->y = vp->savy;
  1346.                     vp->current->next = temppoint;
  1347.                     vp->current = temppoint;
  1348.                     temppoint = (pointlist) NewPtr(sizeof(point));
  1349.                 }
  1350.                 vp->current->next = temppoint;
  1351.             }
  1352.             else vp->TEKPanel = temppoint;
  1353.             vp->current = temppoint;
  1354.             vp->current->x = vp->savx = joinup(vp->nhix,vp->nlox,vp->nex);
  1355.             vp->current->y = vp->savy = joinup(vp->nhiy,vp->nloy,vp->ney);
  1356.             vp->current->next = (pointlist) NULL;
  1357.             state[vw] = INTEGER;
  1358.             savstate[vw] = PANEL;
  1359.             vp->mode = DONE;
  1360.             newcoord(vw);
  1361.             state[vw] = DONE;
  1362.             goagain = TRUE;
  1363.             break;
  1364.         case DONE:                    /* ready for anything */
  1365.             switch(c)
  1366.             {
  1367.             case 31:                /* US - enter ALPHA mode */
  1368.                 vp->mode = ALPHA; 
  1369.                 state[vw] = CANCEL;
  1370.                 break;
  1371.             case 30:
  1372.                 state[vw] = RS;
  1373.                 break;
  1374.             case 28:
  1375.                 if (vp->TEKtype)
  1376.                 {
  1377.                     vp->mode = MARK;
  1378.                     state[vw] = HIY;
  1379.                 }
  1380.                 break;
  1381.             case 29:                /* GS - enter VECTOR mode */
  1382.                 state[vw] = ENTERVEC;
  1383.                 break;
  1384.             case 27:
  1385.                 state[vw] = CMD0;
  1386.                 break;
  1387.             default:
  1388.                 if (vp->mode == ALPHA)
  1389.                 {
  1390.                     state[vw] = DONE;
  1391.                     if (!vp->TEKtype)
  1392.                         drawc(vw,(int) c);
  1393.                     else
  1394.                     {
  1395.                         VSwrite(vp->theVS,&c,1);
  1396.                         unstore(VGstore[vw]);
  1397.                     }
  1398.                     return;
  1399.                 }
  1400.                 else if ((vp->mode == DRAW) && cmd)
  1401.                 {
  1402.                     state[vw] = HIY;
  1403.                     goagain = TRUE;
  1404.                 }
  1405.                 else if ((vp->mode == MARK) && cmd)
  1406.                 {
  1407.                     state[vw] = HIY;
  1408.                     goagain = TRUE;
  1409.                 }
  1410.                 else if ((vp->mode == DRAW) && ((c == 13) || (c == 10)))
  1411.                 {
  1412.                     /* break drawing mode on CRLF */
  1413.                     vp->mode = ALPHA; 
  1414.                     state[vw] = CANCEL;
  1415.                 }
  1416.                 else
  1417.                 {
  1418.                     state[vw] = DONE;            /* do nothing */
  1419.                     return;
  1420.                 }
  1421.             }
  1422.         }
  1423.     
  1424.         if (state[vw] == DONE)
  1425.         {
  1426.             if (vp->mode == PANEL)
  1427.             {
  1428.                 vp->mode = DONE;
  1429.                 state[vw] = INTEGER;
  1430.                 savstate[vw] = PANEL;
  1431.             }
  1432.             else if ((vp->TEKPanel) && ((vp->mode == DRAW) || (vp->mode == TEMPDRAW)
  1433.                     || (vp->mode == MARK) || (vp->mode == TEMPMARK) ||
  1434.                         (vp->mode == TEMPMOVE)))
  1435.             {
  1436.                 temppoint = (pointlist) NewPtr(sizeof(point));
  1437.                 vp->current->next = temppoint;
  1438.                 vp->current = temppoint;
  1439.                 vp->current->x = joinup(vp->nhix,vp->nlox,vp->nex);
  1440.                 vp->current->y = joinup(vp->nhiy,vp->nloy,vp->ney);
  1441.                 vp->current->next = (pointlist) NULL;
  1442.                 if ((vp->mode == TEMPDRAW) || (vp->mode == TEMPMOVE) ||
  1443.                     (vp->mode == TEMPMARK))
  1444.                     vp->mode = vp->modesave;
  1445.                 newcoord(vw);
  1446.             }
  1447.             else if (vp->mode == TEMPMOVE)
  1448.             {
  1449.                 vp->mode = vp->modesave;
  1450.                 newcoord(vw);
  1451.             }
  1452.             else if ((vp->mode == DRAW) || (vp->mode == TEMPDRAW))
  1453.             {
  1454.                 clipvec(vw,vp->curx,vp->cury,
  1455.                     joinup(vp->nhix,vp->nlox,vp->nex),
  1456.                     joinup(vp->nhiy,vp->nloy,vp->ney));
  1457.                 newcoord(vw);
  1458.                 if (vp->mode == TEMPDRAW) vp->mode = vp->modesave;
  1459.             }
  1460.             else if ((vp->mode == MARK) || (vp->mode == TEMPMARK))
  1461.             {
  1462.                 newcoord(vw);
  1463.                 if (vp->TEKtype) drawc(vw,127 + vp->TEKMarker);
  1464.                 newcoord(vw);
  1465.                 if (vp->mode == TEMPMARK) vp->mode = vp->modesave;
  1466.             }
  1467.         }
  1468.  
  1469.         if (state[vw] == CANCEL) state[vw] = DONE;
  1470.     } while (goagain);
  1471.     return;
  1472. }
  1473.  
  1474.  
  1475. /*  Clear screen and have a few other effects:
  1476.  *    - Return graphics to home position (0,3071)
  1477.  *    - Switch to alpha mode
  1478.  *    This is a standard Tek command; don't look at me.
  1479.  */
  1480. void VGpage
  1481.   (
  1482.     int vw
  1483.   )
  1484. {
  1485.     if (VGwin[vw]->TEKtype)
  1486.         (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,VGwin[vw]->TEKBackground);
  1487.     else
  1488.         (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,0);
  1489.     (*RG[VGwin[vw]->RGdevice].clrscr)(VGwin[vw]->RGnum);
  1490.     (*RG[VGwin[vw]->RGdevice].pencolor)(VGwin[vw]->RGnum,1);
  1491.     VGwin[vw]->mode = ALPHA;
  1492.     state[vw] = DONE;
  1493.     VGwin[vw]->textcol = 0;
  1494.     fontnum(vw,0);
  1495.     storexy(vw,0,3071);
  1496. }
  1497.  
  1498.  
  1499. /*
  1500.  *    Redraw window 'vw' in pieces to window 'dest'.
  1501.  *    Must call this function repeatedly to draw whole image.
  1502.  *    Only draws part of the image at a time, to yield CPU power.
  1503.  *    Returns 0 if needs to be called more, or 1 if the image
  1504.  *    is complete.  Another call would result in the redraw beginning again.
  1505.  *    User should clear screen before beginning redraw.
  1506.  */
  1507. int VGpred(vw,dest)
  1508. int    vw;
  1509. int    dest;
  1510. {
  1511. int        data;
  1512. STOREP    st = VGstore[vw];
  1513. int        count = 0;
  1514.     
  1515.     if (drawing[vw])        /* wasn't redrawing */
  1516.     {
  1517.         topstore(VGstore[vw]);
  1518.         drawing[vw] = 0;    /* redraw incomplete */
  1519.     }
  1520.  
  1521.     while (++count < PREDCOUNT && ((data = nextitem(st)) != -1))
  1522.         VGdraw(dest,data);
  1523.  
  1524.     if (data == -1) drawing[vw] = 1;     /* redraw complete */
  1525.     return(drawing[vw]);
  1526. }
  1527.  
  1528. void VGstopred
  1529.   (
  1530.     int vw
  1531.   )
  1532. /*
  1533.     Abort VGpred redrawing of specified window.
  1534.     Must call this routine if you decide not to complete the redraw.
  1535. */
  1536. {
  1537.     drawing[vw] = 1;
  1538. }
  1539.  
  1540.  
  1541. void VGredraw
  1542.   (
  1543.     int vw,
  1544.     int dest
  1545.   )
  1546. /*
  1547.  *    Redraw the contents of window 'vw' to window 'dest'.
  1548.  *    Does not yield CPU until done.
  1549.  *    User should clear the screen before calling this, to avoid 
  1550.  *    a messy display.
  1551.  */
  1552. {
  1553. int        data;
  1554.  
  1555.     topstore(VGstore[vw]);
  1556.     while ((data = nextitem(VGstore[vw])) != -1) VGdraw(dest,data);
  1557. }
  1558.  
  1559. void VGgiveinfo
  1560.   (
  1561.     int vw
  1562.   )
  1563. /*
  1564.  *    Send interesting information about the virtual window down to
  1565.  *    its RG, so that the RG can make VG calls and display zoom values
  1566.  */
  1567. {
  1568.     (*RG[VGwin[vw]->RGdevice].info)(VGwin[vw]->RGnum,
  1569.     vw,
  1570.     VGwin[vw]->winbot,
  1571.     VGwin[vw]->winleft,
  1572.     VGwin[vw]->wintop,
  1573.     VGwin[vw]->winright);
  1574. }
  1575.  
  1576. void VGzoom
  1577.   (
  1578.     int vw,
  1579.     int x0,
  1580.     int y0,
  1581.     int x1,
  1582.     int y1
  1583.   )
  1584. /*
  1585.  *    Set new borders for zoom/pan region.
  1586.  *    x0,y0 is lower left; x1,y1 is upper right.
  1587.  *    User should redraw after calling this.
  1588.  */
  1589. {
  1590.     VGwin[vw]->winbot = y0;
  1591.     VGwin[vw]->winleft = x0;
  1592.     VGwin[vw]->wintop = y1;
  1593.     VGwin[vw]->winright = x1;
  1594.     VGwin[vw]->wintall = y1 - y0 + 1;
  1595.     VGwin[vw]->winwide = x1 - x0 + 1;
  1596.     VGgiveinfo(vw);
  1597. }
  1598.  
  1599. VGwhatzoom(vw,px0,py0,px1,py1)
  1600. int vw,*px0,*py0,*px1,*py1;
  1601. {
  1602.     *py0 = VGwin[vw]->winbot;
  1603.     *px0 = VGwin[vw]->winleft;
  1604.     *py1 = VGwin[vw]->wintop;
  1605.     *px1 = VGwin[vw]->winright;
  1606. }
  1607.  
  1608. void VGzcpy
  1609.   (
  1610.     int src,
  1611.     int dest
  1612.   )
  1613. /*
  1614.  *    Set zoom/pan borders for window 'dest' equal to those for window 'src'.
  1615.  *    User should redraw window 'dest' after calling this.
  1616.  */
  1617. {
  1618.     VGzoom(dest,VGwin[src]->winleft, VGwin[src]->winbot,
  1619.     VGwin[src]->winright, VGwin[src]->wintop);
  1620. }
  1621.  
  1622. void VGclose
  1623.   (
  1624.     int vw
  1625.   )
  1626. /*
  1627.  *    Close virtual window.
  1628.  *    Release its real graphics device and its store.
  1629.  */
  1630. {
  1631.     (*RG[VGwin[vw]->RGdevice].close)(VGwin[vw]->RGnum);
  1632.     freestore(VGstore[vw]);
  1633.     VGwin[vw]->RGdevice = -1;
  1634. }
  1635.  
  1636. int VGwrite
  1637.   (
  1638.     int vw,
  1639.     char *data,
  1640.     int count
  1641.   )
  1642. /*
  1643.  *    Draw the data pointed to by 'data' of length 'count'
  1644.  *    on window vw, and add it to the store for that window.
  1645.  *    This is THE way for user program to pass Tektronix data.
  1646.  */
  1647. {
  1648. char *c = data;
  1649. char *end = &(data[count]);
  1650. char storeit = storing[vw];
  1651.  
  1652.     if ((VGwin[vw]->RGdevice == -1) || (vw >= MAXVG) || (vw < 0)) return(-1);
  1653.         /* window not open */
  1654.  
  1655.     while (c != end)
  1656.     {
  1657.         if (*c == 24)                /* ASC CAN character */
  1658.             return(c-data+1);
  1659.         if (storeit) addstore(VGstore[vw],*c);
  1660.         VGdraw(vw,*c++);
  1661.  
  1662.     }
  1663.     return(count);
  1664. }
  1665.  
  1666. char *
  1667. VGrgname(rgdev)
  1668. int rgdev;
  1669. /*
  1670.  *    Return a pointer to a human-readable string
  1671.  *    which describes the specified real device
  1672.  */
  1673. {
  1674.     return(*RG[rgdev].devname)();
  1675. }
  1676.  
  1677. VGtmode(rgdev)
  1678. int rgdev;
  1679. /* Put the specified real device into text mode */
  1680. {
  1681.     (*RG[rgdev].tmode)();
  1682. }
  1683.  
  1684.  
  1685. void VGgindata
  1686.   (
  1687.     int vw,
  1688.     int x,
  1689.     int y,
  1690.     char c,
  1691.     char *a
  1692.   )
  1693. /*
  1694.  *    Translate data for output as GIN report.
  1695.  *
  1696.  *    User indicates VW number and x,y coordinates of the GIN cursor.
  1697.  *    Coordinate space is 0-4095, 0-4095 with 0,0 at the bottom left of
  1698.  *    the real window and 4095,4095 at the upper right of the real window.
  1699.  *    'c' is the character to be returned as the keypress.
  1700.  *    'a' is a pointer to an array of 5 characters.  The 5 chars must
  1701.  *    be transmitted by the user to the remote host as the GIN report.
  1702.  */
  1703. {
  1704.     long x2,y2;
  1705.  
  1706.     x2 = ((x * VGwin[vw]->winwide) / INXMAX + VGwin[vw]->winleft) >> 2;
  1707.     y2 = ((y * VGwin[vw]->wintall) / INYMAX + VGwin[vw]->winbot) >> 2;
  1708.  
  1709.     a[0] = c;
  1710.     a[1] = 0x20 | ((x2 & 0x03E0) >> 5);
  1711.     a[2] = 0x20 | (x2 & 0x001F);
  1712.     a[3] = 0x20 | ((y2 & 0x03E0) >> 5);
  1713.     a[4] = 0x20 | (y2 & 0x001F);
  1714. }
  1715.  
  1716.  
  1717.  
  1718.  
  1719. short VGgetVS(short theVGnum)                /* NCSA 2.5: give us the VS */
  1720. {                                            /* NCSA 2.5 */
  1721.     return VGwin[theVGnum]->theVS;            /* NCSA 2.5 */
  1722. }                                            /* NCSA 2.5 */
  1723.