home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / rs / rsinterf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-22  |  39.5 KB  |  1,408 lines

  1. /* rsinterf.c */
  2.  
  3. /* A split of RSmac.c to facilitate keeping my sanity --CCP */
  4.  
  5. #include <Fonts.h>
  6. #include <Palettes.h>
  7. #include <ColorPicker.h>
  8. #include <ctype.h>
  9. #include "TelnetHeader.h"
  10. #include "rsdefs.h"
  11. #include "dialog_resrcdefs.h"
  12. #include "vsdata.h"
  13. #include "wind.h"
  14. #include "rsmac.proto.h"
  15. #include "vsinterf.proto.h"
  16. #include "vsintern.proto.h"
  17. #include "rsinterf.proto.h"
  18. #include "menuseg.proto.h"
  19. #include "maclook.proto.h"
  20. #include "wdefpatch.proto.h"    /* 931112, ragge, NADA, KTH */
  21. #include "parse.proto.h"
  22. #include "network.proto.h"
  23. #include "DlogUtils.proto.h"
  24. #include "url.proto.h"
  25. #include "drag.proto.h"
  26. #include "configure.proto.h"
  27.  
  28.  
  29. extern WindRec *screens;
  30. extern SysEnvRec    theWorld;
  31. extern short    NumberOfColorBoxes;
  32. extern short    BoxColorItems[8];
  33. extern RGBColor    BoxColorData[8];
  34.  
  35. extern short MaxRS;
  36. extern RSdata *RSlocal, *RScurrent;
  37.  
  38. extern RSdata *RSlocal, *RScurrent;
  39. extern Rect    noConst;
  40. extern short RSw,         /* last window used */
  41.     RSa;          /* last attrib used */
  42. extern short RScolor;        /* true if try to use color stuff */
  43. extern short *RScolors;
  44.  
  45. SIMPLE_UPP(ScrollProc,ControlAction);
  46.  
  47. static void HandleDoubleClick(short w, short modifiers);
  48.  
  49. void    RSunload(void) {}
  50.  
  51.  
  52. /*------------------------------------------------------------------------------*/
  53. /* RSselect                                                                        */
  54. /* Handle the mouse down in the session window.  All we know so far is that it    */
  55. /* is somewhere in the content window, and it is NOT an option - click.            */
  56. /* Double clicking now works -- SMB                                                */
  57. // And I fixed it so it works correctly.  Grrrr... - JMB
  58. //    WARNING: Make sure RSlocal[w].selected is 1 when doing selections.  If it is
  59. //        zero, the autoscrolling routines will seriously hose the selection drawing.
  60. //        Heed this advice, it took me two hours to find the cause of this bug! - JMB
  61.  
  62.   /* called on a mouse-down in the text display area of the
  63.     active window. Creates or extends the highlighted selection
  64.     within that window, autoscrolling as appropriate if the user
  65.     drags outside the currently visible part of the display. */
  66. void RSselect( short w, Point pt, EventRecord theEvent)
  67. {
  68.     static    long     lastClick = 0;
  69.     static     Point     lastClickLoc = {0,0};
  70.     GrafPtr tempwndo;
  71.     Point    curr, temp;
  72.     long    clickTime;
  73.     short    shift = (theEvent.modifiers & shiftKey);
  74.     
  75.     RSsetConst(w);
  76.     tempwndo = RSlocal[w].window;
  77.     
  78.     curr = normalize(pt, w);
  79.     clickTime = TickCount();
  80.     
  81.     if  ( ( EqualPt(RSlocal[w].anchor, curr) || EqualPt(RSlocal[w].anchor, RSlocal[w].last) )
  82.             &&  ((clickTime - lastClick) <= GetDblTime())
  83.             && EqualPt(curr, lastClickLoc)) {
  84.         /* NCSA: SB - check to see if this is a special click */
  85.         /* NCSA: SB - It has to be in the right time interval, and in the same spot */
  86.         curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w);
  87.         HandleDoubleClick(w, theEvent.modifiers);
  88.         RSlocal[w].selected = 1;
  89.         lastClick = clickTime;
  90.         lastClickLoc = curr;
  91.         }
  92.     else {
  93.         lastClick = clickTime;
  94.         lastClickLoc = curr;
  95.         if (RSlocal[w].selected) {
  96.             if (!shift) {
  97.               /* unhighlight current selection */
  98.                 RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst);
  99.               /* start new selection */
  100.                 curr = RSlocal[w].last = RSlocal[w].anchor = normalize(pt, w);
  101.             }
  102.             else {
  103.                 RSsortAnchors(w);
  104.                 if ((curr.v < RSlocal[w].anchor.v) || ((curr.v == RSlocal[w].anchor.v) && (curr.h < RSlocal[w].anchor.h))) {
  105.                     temp = RSlocal[w].anchor;
  106.                     RSlocal[w].anchor = RSlocal[w].last;
  107.                     RSlocal[w].last = temp;
  108.                     }
  109.                 }
  110.           }
  111.         else
  112.           {
  113.           /* start new selection */
  114.             curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w);
  115.             RSlocal[w].selected = 1;
  116.             }
  117.             
  118.         while (StillDown())
  119.           {
  120.           /* wait for mouse position to change */
  121.             do {
  122.                 curr = normalize(getlocalmouse(tempwndo), w);
  123.                 } while (EqualPt(curr, RSlocal[w].last) && StillDown());
  124.     
  125.           /* toggle highlight state of text between current and last mouse positions */
  126.             RSinvText(w, curr, RSlocal[w].last, &noConst);
  127.             RSlocal[w].last = curr;
  128.           } /* while */
  129.         }
  130.  
  131.     
  132.     if (EqualPt(RSlocal[w].anchor, RSlocal[w].last)) RSlocal[w].selected = 0;
  133.         else RSlocal[w].selected = 1;
  134.     SetMenusForSelection((short)RSlocal[w].selected);
  135.   } /* RSselect */
  136.   
  137.   void RSzoom
  138.   (
  139.     GrafPtr window, /* window to zoom */
  140.     short code, /* inZoomIn or inZoomOut */
  141.     short shifted /* bring to front or not */
  142.   )
  143.   /* called after a click in the zoom box, to zoom a terminal window. */
  144.   {
  145.     WStateData    **WSDhdl;
  146.     short        w;
  147.     short        h, v, x1, x2, y1, y2;
  148.     short        width, lines;            // For setting Standard State before zooming
  149.     short        top, left;                // Ditto
  150.     
  151.     SetPort(window);
  152.     w = RSfindvwind(window); /* which window is it, anyway */
  153.  
  154.     width = VSmaxwidth(w) + 1;
  155.     lines = VSgetlines(w);
  156.     WSDhdl = (WStateData **)((WindowPeek)window)->dataHandle;
  157.     top = (**WSDhdl).userState.top;
  158.     left = (**WSDhdl).userState.left;
  159.     HLock((Handle)WSDhdl);
  160.     SetRect(&((*WSDhdl)->stdState), left, top, RMAXWINDOWWIDTH + left,
  161.                 RMAXWINDOWHEIGHT + top);
  162.     HUnlock((Handle)WSDhdl);
  163.     
  164.     /* EraseRect(&window->portRect); */
  165.     ZoomWindow(window, code, shifted);
  166.     EraseRect(&window->portRect);            /* BYU 2.4.15 */
  167.  
  168.   /* get new window size */
  169.     h = window->portRect.right - window->portRect.left;
  170.     v = window->portRect.bottom - window->portRect.top;
  171.  
  172.     RSsetsize(w, v, h); /* save new size settings and update scroll bars */
  173.   /* update the visible region of the virtual screen */
  174.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  175.     VSsetrgn(w, x1, y1, (x1 + (h - 16 + CHO) / FWidth -1),
  176.         (y1 + (v - 16 + CVO) / FHeight - 1));
  177.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  178.   /* refresh the part which has been revealed, if any */
  179.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); 
  180.   /* window contents are now completely valid */
  181.     ValidRect(&window->portRect);
  182.   } /* RSzoom */
  183.   
  184.   short RSupdate
  185.   (
  186.     GrafPtr wind
  187.   )
  188.   /* does updating for the specified window, if it's one of mine.
  189.     Returns zero iff it is. */
  190.   {
  191.     short w, x1, x2, y1, y2;
  192.  
  193.     w = RSfindvwind(wind);
  194.     if (RSsetwind(w) < 0)
  195.         return(-1); /* not one of mine */
  196.     BeginUpdate(wind);
  197.     RSregnconv /* find bounds of text area needing updating */
  198.       (
  199.         wind->visRgn,
  200.         &x1, &y1, &x2, &y2,
  201.         RScurrent->fheight, RScurrent->fwidth
  202.       );
  203.     VSredraw(w, x1, y1, x2, y2); /* draw that text */
  204.   /* We must reset, less we risk looking UGLY as sin... */
  205.     BackPat(PATTERN(qd.white));
  206.     PenPat(PATTERN(qd.black));
  207.     if (RScolor)
  208.       {
  209.         PmForeColor(0);
  210.         PmBackColor(1);
  211.       }
  212.     else
  213.       {
  214.         ForeColor((long) RScolors[ RScurrent->color[0]]);        /* normal foreground */
  215.         BackColor((long) RScolors[ RScurrent->color[1]]);        /* normal Background */
  216.       } /* if */
  217.     RSa = -1;
  218.     PenMode(patOr);
  219.     DrawGrowIcon(wind);
  220.     PenMode(patCopy);
  221.     //DrawControls(wind);
  222.     UpdtControl(wind, wind->visRgn);
  223.  
  224.     EndUpdate(wind);
  225.     return(0);
  226.   } /* RSupdate */
  227.   
  228.   short RSTextSelected(short w) {        /* BYU 2.4.11 */
  229.   return(RSlocal[w].selected);    /* BYU 2.4.11 */
  230. }                                /* BYU 2.4.11 */
  231.  
  232. void RSskip
  233.   (
  234.     short w,
  235.     Boolean on
  236.   )
  237.   /* sets the "skip" flag for the specified window (whether ignore
  238.     screen updates until further notice). */
  239.   {
  240.     RSlocal[w].skip = on;
  241.   } /* RSskip */
  242.  
  243.  
  244.   /*
  245. *  This routine is called when the user presses the grow icon, or when the size of
  246. *  the window needs to be adjusted (where==NULL, modifiers==0).
  247. *  It limits the size of the window to a legal range.
  248. */
  249.  
  250. short RSsize (GrafPtr window, long *where, long modifiers)
  251. {
  252.     Rect    SizRect;
  253.     long    size;
  254.     short    w, width, lines;
  255.     short    tw, h, v, x1, x2, y1, y2, th;
  256.     Boolean    changeVSSize = false;
  257.     short    screenIndex = 0;
  258.     Boolean    screenIndexValid = false;
  259.     short     err = noErr;
  260.     if ((w = RSfindvwind(window)) < 0)    /* Not found */
  261.         return (0);
  262.     
  263.     if (modifiers & cmdKey) return (0);
  264.     
  265.     screenIndexValid = (screenIndex = findbyVS(w)) != -1;
  266.  
  267.     changeVSSize = (modifiers & optionKey) == optionKey;
  268.  
  269. #define DONT_DEFAULT_CHANGE_VS_IF_NAWS                // JMB
  270.     // 931112, ragge, NADA, KTH 
  271.     // I think this is the way it should work, if there is naws available it
  272.     // should be used by default, and option toggles behaviour.
  273.     // Maybe it should be user configurable?
  274. #ifndef DONT_DEFAULT_CHANGE_VS_IF_NAWS
  275.     if(screenIndexValid && screens[screenIndex].naws) {
  276.         changeVSSize = (modifiers & optionKey) != optionKey;
  277.     }
  278. #endif
  279.  
  280.     SetPort(window);
  281.  
  282.     width = VSmaxwidth(w) + 1; //VSmaxwidth returns one less than number of columns
  283.     lines = VSgetlines(w);
  284.  
  285.  
  286.     if (changeVSSize) {
  287.         th = INFINITY;
  288.         tw = INFINITY-1;
  289.         }
  290.     else {
  291.         tw = RMAXWINDOWWIDTH;
  292.         th = RMAXWINDOWHEIGHT + 1;
  293.         }
  294.  
  295.     SetRect(&SizRect, 48, 48, tw + 1, th);
  296.     
  297.     if (where)                                            /* grow icon actions */
  298.         {                            
  299.         if (changeVSSize) { /* 931112, ragge, NADA, KTH */
  300.             setupForGrow(window, 1 - CHO, 1 - CVO, FWidth, FHeight);
  301.         }
  302.         size = GrowWindow(window, *(Point *) where, &SizRect);    /* BYU LSC */
  303.         if (changeVSSize) { /* 931112, ragge, NADA, KTH */
  304.             cleanupForGrow(window);
  305.         }
  306.  
  307.         if (size != 0L)
  308.           {
  309.             SizeWindow(window, size & 0xffff, (size >> 16) & 0xffff, FALSE);
  310.             h = window->portRect.right - window->portRect.left;
  311.             v = window->portRect.bottom - window->portRect.top;
  312.           }
  313.         else return(0);                            /* user skipped growing */
  314.       }
  315.     else
  316.       {                                    /* just resize the window */
  317.         h = window->portRect.right - window->portRect.left;    /* same width */
  318.         v = (FHeight) * (VSgetlines(w));                    /* new height */
  319.         SizeWindow(window, h, v, FALSE);                    /* change it */
  320.         }     
  321.  
  322.     RSsetsize(w, v, h); /* save new size settings and update scroll bars */
  323.  
  324.     
  325.   /* update the visible region of the virtual screen */
  326.  
  327.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  328.     VSsetrgn(w, x1, y1, (short)((x1 + (h - 16 + CHO) / FWidth - 1)),
  329.         (short)((y1 + (v - 16) / FHeight - 1)));
  330.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  331.  
  332.     if (changeVSSize) {
  333.         
  334.         switch (VSsetlines(w,y2 -y1 +1)) {
  335.  
  336.         case (-5000):  //no change, we should just return;
  337.             return(0);
  338.             break;
  339.  
  340.         case (-4000): //can't even get enough memory to put VS back to original size
  341.             /* signal this to main program */
  342.             return(-4);
  343.             break;
  344.         
  345.         case (-3000): //no resize: unkown problems, but we put the VS back to original size
  346.             return(0);
  347.             break;
  348.         case (-2000): //no resize: Memory problems, but we put the VS back to original size
  349.             return(-2);
  350.             break;
  351.         default:    //Ok, we can resize; tell host
  352.             RScalcwsize(w,x2 - x1 +1);
  353.             if (screenIndexValid && screens[screenIndex].naws)
  354.                 SendNAWSinfo(&screens[screenIndex], (x2-x1+1), (y2-y1+1));
  355.             return (0);
  356.             break;
  357.         }
  358.     }
  359.  
  360.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1);        /* refresh the part which has been revealed, if any */
  361.     ValidRect(&window->portRect);                        /* window contents are now completely valid */
  362.  
  363.     return (0);
  364.   } /* RSsize */
  365.   
  366. void RSshow( short w)        /* reveals a hidden terminal window. */
  367. {
  368.     if (RSsetwind(w) < 0)
  369.         return;
  370.     
  371.     ShowWindow(RScurrent->window);
  372. }
  373.  
  374. Boolean RSsetcolor
  375.     (
  376.     short w, /* window number */
  377.     short n, /* color entry number */
  378.     RGBColor    Color
  379.     )
  380.   /* sets a new value for the specified color entry of a terminal window. */
  381.   {
  382.     if ( !theWorld.hasColorQD || (RSsetwind(w) < 0) || (n > 5) || (n < 0))
  383.         return(-1);
  384.     RScurrent->RGBs[n] = Color;
  385.  
  386.     if (RScolor) {
  387.       /* only take account of the color settings on a color-capable machine */
  388.         SetEntryColor(RScurrent->pal, n, &RScurrent->RGBs[n]);
  389.         SetPort(RScurrent->window);
  390.         InvalRect(&RScurrent->window->portRect);
  391.       } /* if */
  392.     return(0);
  393.   } /* RSsetcolor */
  394.   
  395.   void RSsendstring
  396.   (
  397.     short w, /* which terminal window */
  398.     char *ptr, /* pointer to data */
  399.     short len /* length of data */
  400.   )
  401.   /* sends some data to the host along the connection associated
  402.     with the specified window. */
  403.   {
  404.     short temp;
  405.  
  406.     temp = findbyVS(w);
  407.     if (temp < 0)
  408.         return;
  409.         netwrite(screens[temp].port, ptr, len);
  410.         netpush(screens[temp].port);                /* BYU 2.4.18 - for Diab systems? */        
  411.   } /* RSsendstring */
  412.  
  413.  
  414. short RSnewwindow
  415.   (
  416.     RectPtr wDims, /* window bounds in pixels */
  417.     short scrollback, /* number of lines to save off top */
  418.     short width, /* number of characters per text line (80 or 132) */
  419.     short lines, /* number of text lines */
  420.     StringPtr name, /* window name */
  421.     short wrapon, /* autowrap on by default */
  422.     short fnum, /* ID of font to use initially */
  423.     short fsiz, /* size of font to use initially */
  424.     short showit, /* window initially visible or not */
  425.     short goaway, /* NCSA 2.5 */
  426.     short forcesave        /* NCSA 2.5: force screen save */
  427.   )
  428.   /* creates a virtual screen and a window to display it in. */
  429.   {
  430.     GrafPort gp; /* temp port for getting text parameters */
  431.     short w;
  432.  
  433.     Rect        pRect;
  434.     short        wheight, wwidth;
  435.     WStateData    *wstate;
  436.     WindowPeek    wpeek;
  437.     CTabHandle    RSctab;
  438.  
  439.   /* create the virtual screen */
  440.     w = VSnewscreen(scrollback, (scrollback != 0), /* NCSA 2.5 */
  441.         width,1, forcesave);    /* NCSA 2.5 */
  442.     if (w < 0) {        /* problems opening the virtual screen -- tell us about it */
  443.         return(-1);
  444.           }
  445.       
  446.     RScurrent = RSlocal + w;
  447.  
  448.     RScurrent->fnum = fnum;
  449.     RScurrent->fsiz = fsiz;
  450.  
  451.     OpenPort(&gp);
  452.     RSTextFont(fnum,fsiz,0);    /* BYU */
  453.     TextSize(fsiz);
  454.     RSfontmetrics();
  455.     ClosePort(&gp);
  456.  
  457.     if ((wDims->right - wDims->left) > RMAXWINDOWWIDTH)
  458.         wDims->right = wDims->left + RMAXWINDOWWIDTH;
  459.     if ((wDims->bottom - wDims->top) > RMAXWINDOWHEIGHT)
  460.         wDims->bottom = wDims->top + RMAXWINDOWHEIGHT;
  461.     wwidth = wDims->right - wDims->left;
  462.     wheight = wDims->bottom - wDims->top;
  463.  
  464.   /* create the window */
  465.     if (!RScolor) {
  466.         RScurrent->window = NewWindow(0L, wDims, name, showit?TRUE:FALSE, 8,    /* BYU LSC */
  467.             kInFront, goaway ? TRUE:FALSE, (long)w);
  468.         RScurrent->pal = NULL;
  469.         if (RScurrent->window == NULL) {
  470.             VSdestroy(w);
  471.             return(-2);
  472.             }
  473.         }
  474.     else
  475.       {
  476.         RScurrent->window = NewCWindow(0L, wDims, name, showit?TRUE:FALSE, (short)8,    /* BYU LSC */
  477.             kInFront, goaway ? TRUE:FALSE, (long)w);
  478.                     /* the screen is not there until we can see it..... */
  479.         if (RScurrent->window == NULL) {
  480.             VSdestroy(w);
  481.             return(-2);
  482.             }
  483.  
  484.         RSctab = (CTabHandle) NewHandleClear((long) (sizeof(ColorTable) + 4 * sizeof(CSpecArray)));
  485.         if (RSctab == NULL) {
  486.             DisposeWindow(RScurrent->window);
  487.             VSdestroy(w);
  488.             return(-2);
  489.             }
  490.         HLock((Handle) RSctab);
  491.  
  492.         (*RSctab)->ctSize = 3;        // Number of entries minus 1
  493.         (*RSctab)->ctFlags = 0;
  494.         RScurrent->RGBs[0].red  =(*RSctab)->ctTable[0].rgb.red        =     0;
  495.         RScurrent->RGBs[0].green=(*RSctab)->ctTable[0].rgb.green    =     0;
  496.         RScurrent->RGBs[0].blue =(*RSctab)->ctTable[0].rgb.blue        =     0;
  497.         RScurrent->RGBs[1].red  =(*RSctab)->ctTable[1].rgb.red        = 65535;
  498.         RScurrent->RGBs[1].green=(*RSctab)->ctTable[1].rgb.green    = 65535;
  499.         RScurrent->RGBs[1].blue =(*RSctab)->ctTable[1].rgb.blue        = 65535;
  500.         RScurrent->RGBs[2].red  =(*RSctab)->ctTable[2].rgb.red        =     0;
  501.         RScurrent->RGBs[2].green=(*RSctab)->ctTable[2].rgb.green    = 61183;
  502.         RScurrent->RGBs[2].blue =(*RSctab)->ctTable[2].rgb.blue        = 11060;
  503.         RScurrent->RGBs[3].red  =(*RSctab)->ctTable[3].rgb.red        = 61183;
  504.         RScurrent->RGBs[3].green=(*RSctab)->ctTable[3].rgb.green    =  2079;
  505.         RScurrent->RGBs[3].blue =(*RSctab)->ctTable[3].rgb.blue        =  4938;
  506.         (*RSctab)->ctTable[0].value = 0;
  507.         (*RSctab)->ctTable[1].value = 0;
  508.         (*RSctab)->ctTable[2].value = 0;
  509.         (*RSctab)->ctTable[3].value = 0;
  510.         HUnlock((Handle) RSctab);
  511.  
  512.         RScurrent->pal = NewPalette(4, RSctab, pmCourteous, 0);
  513.         DisposeHandle((Handle) RSctab);
  514.         if (RScurrent->pal == NULL) {
  515.             DisposeWindow(RScurrent->window);
  516.             VSdestroy(w);
  517.             return(-2);
  518.             }
  519.  
  520.         SetPalette(RScurrent->window, RScurrent->pal, TRUE);
  521.       } /* if */
  522.  
  523.     SetPort(RScurrent->window);
  524.     SetOrigin(CHO, CVO);            /* Cheap way to correct left margin problem */
  525.  
  526.     wpeek = (WindowPeek) RScurrent->window;
  527.  
  528.     HLock(wpeek->dataHandle);
  529.     wstate = (WStateData *) *wpeek->dataHandle;
  530.  
  531.     BlockMove(&wstate->userState, wDims, 8);
  532.     pRect.top = wDims->top;
  533.     pRect.left = wDims->left;
  534.     pRect.right = pRect.left + RMAXWINDOWWIDTH;
  535.     if (pRect.right > TelInfo->screenRect.right)
  536.         pRect.right = TelInfo->screenRect.right;
  537.  
  538.     pRect.bottom = pRect.top + RMAXWINDOWHEIGHT;
  539.     BlockMove(&wstate->stdState, &pRect, 8);
  540.  
  541.   /* create scroll bars for window */
  542.     pRect.top = -1 + CVO;
  543.     pRect.bottom = wheight - 14 + CVO;
  544.     pRect.left = wwidth - 15 + CHO;
  545.     pRect.right = wwidth + CHO;
  546.     RScurrent->scroll = NewControl(RScurrent->window, &pRect, "\p", FALSE,    /* BYU LSC */
  547.         0, 0, 0, 16, 1L);
  548.  
  549.     if (RScurrent->scroll == 0L) return(-3);
  550.  
  551.     pRect.top = wheight - 15 + CVO;
  552.     pRect.bottom = wheight + CVO;
  553.     pRect.left = -1 + CHO;
  554.     pRect.right = wwidth - 14 + CHO;
  555.     RScurrent->left = NewControl(RScurrent->window, &pRect, "\p", FALSE,        /* BYU LSC */
  556.         0, 0, 0, 16, 1L);
  557.  
  558.     if (RScurrent->left == 0L) return(-3);
  559.  
  560.     RScurrent->skip = 0; /* not skipping output initially */
  561.     RScurrent->max = 0; /* scroll bar settings will be properly initialized by subsequent call to VSsetrgn */
  562.     RScurrent->min = 0;
  563.     RScurrent->current = 0;
  564.     RScurrent->lmax = 0;
  565.     RScurrent->lmin = 0;
  566.     RScurrent->lcurrent = 0;
  567.     RScurrent->selected = 0;    /* no selection initially */
  568.     RScurrent->cursorstate = 0;    /* BYU 2.4.11 - cursor off initially */
  569.     RScurrent->flipped = 0;        /* Initially, the color entries are not flipped */
  570.  
  571.     RSsetsize(w, wheight, wwidth);
  572.     VSsetlines(w, lines);
  573.     VSsetrgn(w, 0, 0, ((wwidth - 16 + CHO) / FWidth -1),
  574.         ((wheight - 16 + CVO) / FHeight - 1));
  575.  
  576.     RSTextFont(RScurrent->fnum,RScurrent->fsiz,0);    /* BYU LSC */
  577.     TextSize(RScurrent->fsiz);                /* 9 point*/
  578.     if (!RScolor)
  579.         TextMode(srcXor);            /* Xor mode*/
  580.     else
  581.         TextMode(srcCopy);
  582.  
  583.     if (wrapon)
  584.       /* turn on autowrap */
  585.         VSwrite(w, "\033[?7h",5);
  586.  
  587.     return(w);
  588.   } /* RSnewwindow */
  589.  
  590. short RSmouseintext                /* Point is in global coords */
  591.   (
  592.     short w,
  593.     Point myPoint
  594.   )
  595.   /* is myPoint within the text-display area of the specified window. */
  596.   {
  597.     return
  598.         PtInRect(myPoint, &RSlocal[w].textrect);     /* BYU LSC */
  599.   } /* RSmouseintext */
  600.  
  601. void RSkillwindow
  602.   (
  603.     short w
  604.   )
  605.   /* closes a terminal window. */
  606.   {
  607.      RSdata *temp = RSlocal + w;
  608.  
  609.      if (temp->pal != NULL) {
  610.          DisposePalette(temp->pal);        
  611.          temp->pal = NULL;
  612.         }
  613.  
  614.     VSdestroy(w);        /* destroy the virtual screen */
  615.     KillControls(RSlocal[w].window);  /* Get rid of those little slidy things */
  616.     DisposeWindow(RSlocal[w].window);    /* Get rid of the actual window */
  617.     RSlocal[w].window = 0L;
  618.     RSw = -1;
  619.   }
  620.  
  621. void RSgetcolor
  622.   (
  623.     short w, /* window number */
  624.     short n, /* color entry number */
  625.     unsigned short *r, /* where to return components of color */
  626.     unsigned short *g,
  627.     unsigned short *b
  628.   )
  629.   /* gets the current value for the specified color entry of a terminal window. */
  630.   {
  631.     *r = RSlocal[w].RGBs[n].red;
  632.     *g = RSlocal[w].RGBs[n].green;
  633.     *b = RSlocal[w].RGBs[n].blue;
  634.   } /* RSgetcolor */
  635.  
  636. void    RShide( short w)        /* hides a terminal window. */
  637. {
  638.     if (RSsetwind(w) < 0)
  639.         return;
  640.     
  641.     HideWindow(RScurrent->window);
  642. }
  643.  
  644. GrafPtr RSgetwindow
  645.   (
  646.     short w
  647.   )
  648.   /* returns a pointer to the Mac window structure for the
  649.     specified terminal window. */
  650.   {
  651.     return(RSlocal[w].window);
  652.   } /* RSgetwindow */
  653.  
  654. char **RSGetTextSel
  655.   (
  656.     short w, /* window to look at */
  657.     short table /* nonzero for "table" mode, i e
  658.         replace this many (or more) spaces with a single tab. */
  659.   )
  660.   /* returns the contents of the current selection as a handle,
  661.     or nil if there is no selection. */
  662.   {
  663.     char **charh, *charp;
  664.     short maxwid;
  665.     long realsiz;
  666.     Point Anchor,Last;
  667.  
  668.     if (!RSlocal[w].selected)
  669.         return(0L);    /* No Selection */
  670.     maxwid = VSmaxwidth(w);
  671.     Anchor = RSlocal[w].anchor;
  672.     Last = RSlocal[w].last;
  673.     
  674.     realsiz = Anchor.v - Last.v;
  675.     if (realsiz < 0)
  676.         realsiz = - realsiz;
  677.     realsiz ++;                                /* lines 2,3 selected can be 2 lines */
  678.     realsiz *= (maxwid + 2);
  679.     charh = NewHandle(realsiz);
  680.     if (charh == 0L)
  681.         return((char **) -1L);                /* Boo Boo return */
  682.     HLock(charh);
  683.     charp = *charh;
  684.     realsiz = VSgettext(w, Anchor.h, Anchor.v, Last.h, Last.v,
  685.         charp, realsiz, "\015", table);
  686.     HUnlock(charh);
  687.     SetHandleSize(charh, realsiz);
  688.     return(charh);
  689.   }  /* RSGetTextSel */
  690.  
  691. RgnHandle RSGetTextSelRgn(short w)
  692. {
  693.     Rect    temp, temp2;
  694.     Point    lb, ub;
  695.     Point    curr;
  696.     Point    last;
  697.     RgnHandle    rgnH, tempRgn;
  698.  
  699.     rgnH = NewRgn();
  700.     if (rgnH == nil) {
  701.         return nil;
  702.         }
  703.  
  704.     tempRgn = NewRgn();
  705.     if (tempRgn == nil) {
  706.         DisposeRgn(rgnH);
  707.         return nil;
  708.         }
  709.  
  710.     RSsetwind(w);
  711.  
  712.     curr = RSlocal[w].anchor;
  713.     last = RSlocal[w].last;
  714.  
  715.   /* normalize coordinates with respect to visible area of virtual screen */
  716.     curr.v -= RScurrent->topline;
  717.     curr.h -= RScurrent->leftmarg;
  718.     last.v -= RScurrent->topline;
  719.     last.h -= RScurrent->leftmarg;
  720.  
  721.     if (curr.v == last.v)
  722.       {
  723.       /* highlighted text all on one line */
  724.         if (curr.h < last.h) /* get bounds the right way round */
  725.           {
  726.             ub = curr;
  727.             lb = last;
  728.           }
  729.         else
  730.           {
  731.             ub = last;
  732.             lb = curr;
  733.           } /* if */
  734.         MYSETRECT /* set up rectangle bounding area to be highlighted */
  735.           (
  736.             temp,
  737.             (ub.h + 1) * RScurrent->fwidth,
  738.             ub.v * RScurrent->fheight,
  739.             (lb.h + 1) * RScurrent->fwidth,
  740.             (lb.v + 1) * RScurrent->fheight
  741.           );
  742.         SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */
  743.         RectRgn(rgnH, &temp2);
  744.       }
  745.     else
  746.       {
  747.       /* highlighting across more than one line */
  748.         if (curr.v < last.v)
  749.             ub = curr;
  750.         else
  751.             ub = last;
  752.         if (curr.v > last.v)
  753.             lb = curr;
  754.         else
  755.             lb = last;
  756.         MYSETRECT /* bounds of first (possibly partial) line to be highlighted */
  757.           (
  758.             temp,
  759.             (ub.h + 1) * RScurrent->fwidth,
  760.             ub.v * RScurrent->fheight,
  761.             RScurrent->width,
  762.             (ub.v + 1) * RScurrent->fheight
  763.           );
  764.         SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */
  765.         RectRgn(rgnH, &temp2);
  766.  
  767.         MYSETRECT /* bounds of last (possibly partial) line to be highlighted */
  768.           (
  769.             temp,
  770.             0,
  771.             lb.v * RScurrent->fheight,
  772.             (lb.h + 1) * RScurrent->fwidth,
  773.             (lb.v + 1) * RScurrent->fheight
  774.           );
  775.         SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */
  776.         RectRgn(tempRgn, &temp2);
  777.         UnionRgn(tempRgn, rgnH, rgnH);
  778.  
  779.         if (lb.v - ub.v > 1) /* highlight extends across more than two lines */
  780.           {
  781.           /* highlight complete in-between lines */
  782.             SetRect
  783.               (
  784.                 &temp,
  785.                 0,
  786.                 (ub.v + 1) * RScurrent->fheight,
  787.                 RScurrent->width,
  788.                 lb.v * RScurrent->fheight
  789.               );
  790.             SectRect(&temp, &noConst, &temp2); /* clip to constraint rectangle */
  791.             RectRgn(tempRgn, &temp2);
  792.             UnionRgn(tempRgn, rgnH, rgnH);
  793.  
  794.           } /* if */
  795.       } /* if */
  796.  
  797.     DisposeRgn(tempRgn);
  798.     
  799.     return rgnH;
  800. }
  801.  
  802. short RSfindvwind
  803.   (
  804.     GrafPtr wind
  805.   )
  806.   /* returns the number of the virtual screen associated with
  807.     the specified window, or -4 if not found. */
  808.   {
  809.     short
  810.         i = 0;
  811.     while ((RSlocal[i].window != wind) && (i < MaxRS))
  812.         i++;
  813.     if ((RSlocal[i].window == 0L) || (i >= MaxRS))
  814.         return(-4);
  815.     else
  816.         return(i);
  817.   } /* RSfindvwind */
  818.  
  819. void RSdeactivate
  820.   (
  821.     short w
  822.   )
  823.   /* handles a deactivate event for the specified window. */
  824.   {
  825.     RSsetConst(w);
  826.   /* update the appearance of the grow icon */
  827.     DrawGrowIcon(RSlocal[w].window); 
  828.   /* and deactivate the scroll bars */
  829.     if (RSlocal[w].scroll != 0L)
  830.         HiliteControl(RSlocal[w].scroll, 255);
  831.     if (RSlocal[w].left != 0L)
  832.         HiliteControl(RSlocal[w].left, 255);
  833.   } /* RSdeactivate */
  834.  
  835. void    RScursblink( short w)        /* Blinks the cursor */
  836. {
  837.     GrafPtr    oldwindow;
  838.     long    now = TickCount();
  839.     
  840.     if (now > TelInfo->blinktime) {
  841.         if (VSvalids(w) != 0)            /* BYU 2.4.12 */
  842.             return;                        /* BYU 2.4.12 */
  843.         if (!VSIcursorvisible())        /* BYU 2.4.12 */
  844.             return;                        /* BYU 2.4.12 - cursor isn't visible */
  845.     
  846.         GetPort(&oldwindow);            /* BYU 2.4.11 */
  847.         TelInfo->blinktime = now + 40;            /* BYU 2.4.11 */
  848.         RSlocal[w].cursorstate ^= 1;     /* BYU 2.4.11 */
  849.         SetPort(RSlocal[w].window);        /* BYU 2.4.11 */
  850.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.11 */
  851.         SetPort(oldwindow);                /* BYU 2.4.11 */
  852.     }
  853. } /* RScursblink */
  854.  
  855. void RScursblinkon                        /* BYU 2.4.18 */
  856.   (                                        /* BYU 2.4.18 */
  857.     short w                                /* BYU 2.4.18 */
  858.   )                                        /* BYU 2.4.18 */
  859.   /* Blinks the cursor */                /* BYU 2.4.18 */
  860.   {                                        /* BYU 2.4.18 */
  861.       if (!RSlocal[w].cursorstate) {        /* BYU 2.4.18 */
  862.         GrafPtr oldwindow;                /* BYU 2.4.18 */
  863.         GetPort(&oldwindow);            /* BYU 2.4.18 */
  864.         RSlocal[w].cursorstate = 1;     /* BYU 2.4.18 */
  865.         SetPort(RSlocal[w].window);        /* BYU 2.4.18 */
  866.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.18 */
  867.         SetPort(oldwindow);                /* BYU 2.4.18 */
  868.     }                                    /* BYU 2.4.18 */
  869.   } /* RScursblink */                    /* BYU 2.4.18 */
  870.  
  871. void RScursblinkoff                        /* BYU 2.4.11 */
  872.   (                                        /* BYU 2.4.11 */
  873.     short w                                /* BYU 2.4.11 */
  874.   )                                        /* BYU 2.4.11 */
  875.   /* Blinks the cursor */                /* BYU 2.4.11 */
  876.   {                                        /* BYU 2.4.11 */
  877.       if (RSlocal[w].cursorstate) {        /* BYU 2.4.11 */
  878.         GrafPtr oldwindow;                /* BYU 2.4.11 */
  879.         GetPort(&oldwindow);            /* BYU 2.4.11 */
  880.         RSlocal[w].cursorstate = 0;     /* BYU 2.4.11 */
  881.         SetPort(RSlocal[w].window);        /* BYU 2.4.11 */
  882.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.11 */
  883.         SetPort(oldwindow);                /* BYU 2.4.11 */
  884.     }                                    /* BYU 2.4.11 */
  885.   } /* RScursblink */                    /* BYU 2.4.11 */
  886.  
  887. void    RScprompt(short w)
  888.   /* puts up the dialog that lets the user examine and change the color
  889.     settings for the specified window. */
  890. {
  891.     short        scratchshort, ditem;
  892.     Point        ColorBoxPoint;
  893.     DialogPtr    dptr;
  894.     Boolean        UserLikesNewColor;
  895.     RGBColor    scratchRGBcolor;
  896.     
  897.     dptr = GetNewMySmallDialog(ColorDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  898.  
  899.     for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) {
  900.         BoxColorItems[scratchshort] = ColorNF + scratchshort;
  901.         BlockMove(&(RSlocal[w].RGBs[scratchshort]),
  902.             &BoxColorData[scratchshort], sizeof(RGBColor));
  903.         UItemAssign( dptr, ColorNF + scratchshort, ColorBoxItemProcUPP);
  904.         }
  905.         
  906.     ColorBoxPoint.h = 0;            // Have the color picker center the box on the main
  907.     ColorBoxPoint.v = 0;            // screen
  908.     
  909.     ditem = 3;    
  910.     while (ditem > 2) {
  911.         ModalDialog(ColorBoxModalProcUPP, &ditem);
  912.         switch (ditem) {
  913.             case    ColorNF:    
  914.             case    ColorNB:    
  915.             case    ColorBF:    
  916.             case    ColorBB:    
  917.                 if (theWorld.hasColorQD) {
  918.                     UserLikesNewColor = GetColor(ColorBoxPoint, "\pPlease Select New Color",
  919.                          &BoxColorData[ditem-ColorNF], &scratchRGBcolor);
  920.                     if (UserLikesNewColor)
  921.                         BoxColorData[ditem-ColorNF] = scratchRGBcolor;
  922.                     }
  923.                 break;
  924.                 
  925.             default:
  926.                 break;
  927.             
  928.             } // switch
  929.         } // while
  930.  
  931.     if (ditem == DLOGCancel) {
  932.         DisposeDialog(dptr);
  933.         return;
  934.         }
  935.         
  936.     for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) {
  937.             BlockMove(&BoxColorData[scratchshort], 
  938.                 &(RSlocal[w].RGBs[scratchshort]), sizeof(RGBColor));
  939.         }
  940.     
  941.     /* force redrawing of entire window contents */
  942.     SetPort(RSlocal[w].window);
  943.     InvalRect(&RSlocal[w].window->portRect);
  944.  
  945.     for (scratchshort = 0; scratchshort < 6; scratchshort++)
  946.         SetEntryColor(RSlocal[w].pal, scratchshort, &RSlocal[w].RGBs[scratchshort]);
  947.  
  948.     DisposeDialog(dptr);
  949. } /* RScprompt */
  950.  
  951. /*------------------------------------------------------------------------------*/
  952. /* NCSA: SB - RScalcwsize                                                         */
  953. /*         This routine is used to switch between 80 and 132 column mode. All that    */    
  954. /*         is passed in is the RS window, and the new width.  This calculates the    */    
  955. /*         new window width, resizes the window, and updates everything.  - SMB    */
  956. /*------------------------------------------------------------------------------*/
  957. void RScalcwsize(short w, short width)
  958. {
  959.     short x1,x2,y1,y2;
  960.     short lines;
  961.     short resizeWidth, resizeHeight;
  962.  
  963.     RSsetwind(w);
  964.     VSsetcols(w,(short)(width-1));
  965.     VSgetrgn(w, &x1, &y1, &x2, &y2); /*get current visible region */
  966.     x2= width-1;
  967.     
  968.     lines = VSgetlines(w);                /* NCSA: SB - trust me, you need this... */
  969.     RScurrent->rwidth =
  970.         RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO;
  971.     RScurrent->rheight =
  972.         RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight; 
  973.  
  974.  
  975.     if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO)
  976.           RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO;
  977.     if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16)
  978.           RScurrent->rheight = RMAXWINDOWHEIGHT - 16;
  979.     
  980.     RScheckmaxwind(&RScurrent->window->portRect,RScurrent->rwidth +16,    
  981.                 RScurrent->rheight + 16, &resizeWidth, &resizeHeight);        
  982.     SizeWindow
  983.       (
  984.         RScurrent->window,
  985.         RScurrent->rwidth + 16, RScurrent->rheight+16,
  986.         FALSE
  987.       ); 
  988.     RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16);
  989.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  990.     VSsetrgn(w, x1, y1,
  991.         (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1),
  992.         (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1));
  993.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  994.     
  995.     DrawGrowIcon(RScurrent->window);
  996.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */
  997.     ValidRect(&RScurrent->window->portRect); /* no need to do it again */
  998.     DrawControls(RScurrent->window);
  999. }
  1000.  
  1001. /* handles a click in a terminal window. */
  1002. short RSclick( GrafPtr window, EventRecord theEvent)
  1003. {
  1004.     ControlHandle ctrlh;
  1005.     short w, part, part2, x1, x2, y1, y2;
  1006.     Point    where = theEvent.where;
  1007.     
  1008.     short    shifted = (theEvent.modifiers & shiftKey);
  1009.     short    optioned = (theEvent.modifiers & optionKey);
  1010.     
  1011.     w = 0;
  1012.     while ((RSlocal[w].window != window) && (w < MaxRS))    //find VS 
  1013.         w++;
  1014.     if ((RSlocal[w].window == 0L) || (w >= MaxRS))
  1015.         return(-1); /* what the heck is going on here?? */
  1016.  
  1017.  
  1018.     SetPort(window);
  1019.     GlobalToLocal((Point *) &where);
  1020.     part = FindControl(where, window, &ctrlh);        /* BYU LSC */
  1021.     if (part != 0)
  1022.         switch (part)
  1023.           {
  1024.             case inThumb:
  1025.                 part2 = TrackControl(ctrlh, where, 0L);        /* BYU LSC */
  1026.                 if (part2 == inThumb)
  1027.                   {
  1028.                     part = GetCtlValue(ctrlh);
  1029.                     if (ctrlh == RSlocal[w].scroll)
  1030.                       {
  1031.                       /* scroll visible region vertically */
  1032.                         VSgetrgn(w, &x1, &y1, &x2, &y2);
  1033.                         VSsetrgn(w, x1, part, x2, part + (y2 - y1));
  1034.                       }
  1035.                     else
  1036.                       { /* ctrlh must be .left */
  1037.                       /* scroll visible region horizontally */
  1038.                         VSgetrgn(w, &x1, &y1, &x2, &y2);
  1039.                         VSsetrgn(w, part, y1, part + (x2 - x1), y2);
  1040.                       } /* if */
  1041.                   } /* if */
  1042.                 break;
  1043.             case inUpButton:
  1044.             case inDownButton:
  1045.             case inPageUp:
  1046.             case inPageDown:
  1047.                 part2 = TrackControl(ctrlh, where, ScrollProcUPP);    /* BYU LSC */
  1048.     /*            InvalRect(&(**RSlocal->scroll).contrlRect); */  /* cheap fix */
  1049.                 break;
  1050.             default:
  1051.                 break;
  1052.           } /* switch */
  1053.     else
  1054.       {
  1055.         if (optioned) 
  1056.           {
  1057.           /* send host the appropriate sequences to move the cursor
  1058.             to the specified position */
  1059.             Point x;
  1060.             x = normalize(where, w);
  1061.             VSpossend(w, x.h, x.v, screens[scrn].echo); /* MAT--we can check here if we want to use normal */
  1062.                                                         /* MAT--or EMACS movement. */
  1063.           }
  1064.         else if (ClickInContent(where,w)) {            /* NCSA: SB - prevent BUS error */
  1065.             Boolean    dragged;
  1066.  
  1067.             (void) DragText(&theEvent, where, w, &dragged);
  1068.             if (!dragged) {
  1069.                 RSselect(w, where, theEvent);
  1070.                 }
  1071.             }
  1072.       } /* if */
  1073.     return
  1074.         0;
  1075.   } /* RSclick */
  1076.  
  1077. void RSactivate
  1078.   (
  1079.     short w
  1080.   )
  1081.   /* handles an activate event for the specified window. */
  1082.   {
  1083.     RSsetConst(w);
  1084.   /* display the grow icon */
  1085.     DrawGrowIcon(RSlocal[w].window);
  1086.   /* and activate the scroll bars */
  1087.     if (RSlocal[w].scroll != 0L)
  1088.         HiliteControl(RSlocal[w].scroll, 0);
  1089.     if (RSlocal[w].left != 0L)
  1090.         HiliteControl(RSlocal[w].left, 0);
  1091.   } /* RSactivate */
  1092.  
  1093. /*--------------------------------------------------------------------------*/
  1094. /* HandleDoubleClick                                                        */
  1095. /* This is the routine that does the real dirty work.  Since it is not a    */
  1096. /* true TextEdit window, we have to kinda "fake" the double clicking.  By    */
  1097. /* this time, we already know that a double click has taken place, so check    */
  1098. /* the chars to the left and right of our location, and select all chars     */
  1099. /* that are appropriate    -- SMB                                                */
  1100. /*--------------------------------------------------------------------------*/
  1101. static    void HandleDoubleClick(short w, short modifiers)                                                    
  1102. {                                                                                
  1103.     Point    leftLoc, rightLoc, curr, oldcurr;                                                    
  1104.     long    mySize;                                                            
  1105.     char    theChar[5];                                                            
  1106.     short    mode = -1, newmode, foundEnd=0;                                                            
  1107.     RSsetConst(w);                                                                /* get window dims */                            
  1108.     leftLoc = RSlocal[w].anchor;                                    /* these two should be the same */                            
  1109.     rightLoc = RSlocal[w].last;                                    
  1110.                                                                                 
  1111.     while(!foundEnd)                                                            /* scan to the right first */                                                        
  1112.         {                                                                        
  1113.         mySize = VSgettext(w,rightLoc.h, rightLoc.v, rightLoc.h+1, rightLoc.v,    
  1114.             (char *)theChar,(long)1,"\015",0);                                    
  1115.         if(mySize ==0 || isspace(*theChar))                                    /* stop if not a letter */            
  1116.             foundEnd =1;                                                        
  1117.         else rightLoc.h++;                                                        
  1118.         }                                                                        
  1119.                                                                                 
  1120.     foundEnd =0;                                                                
  1121.     while(!foundEnd)                                                            /* ...and then scan to the left */                                                            
  1122.         {                                                                        
  1123.         mySize = VSgettext(w,leftLoc.h-1, leftLoc.v, leftLoc.h, leftLoc.v,        
  1124.             (char *)theChar,(long)1,"\015",0);                                    
  1125.         if(mySize ==0 || isspace(*theChar))                                        /* STOP! */        
  1126.             foundEnd =1;                                                        
  1127.         else leftLoc.h--;                                                        
  1128.         }                                                                        
  1129.                                                                                 
  1130.     if (leftLoc.h != rightLoc.h) {        /* we selected something */
  1131.         RSlocal[w].anchor = leftLoc;    /* new left bound */
  1132.         RSlocal[w].last = rightLoc;        /* and a matching new right bound */
  1133.         RSlocal[w].selected = 1;        /* give me credit for the selection I just made */
  1134.         RSinvText(w, RSlocal[w].anchor,        /* time to show it off */
  1135.             RSlocal[w].last, &noConst);
  1136.  
  1137.         if (modifiers & cmdKey) {        // Possible URL selection
  1138.             ParseURL(w);
  1139.             }
  1140.         else {                                                                        
  1141.     
  1142.             curr.h = 0; curr.v = 0;
  1143.     
  1144.             while (StillDown()) {
  1145.               /* wait for mouse position to change */
  1146.                 do {
  1147.                     oldcurr = curr;
  1148.                     curr = normalize(getlocalmouse(RSlocal[w].window), w);
  1149.                     } while (EqualPt(curr, oldcurr) && StillDown());
  1150.         
  1151.                 
  1152.                 if ((curr.v < leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h < leftLoc.h))) {
  1153.                     newmode = 1;    // up
  1154.                     }
  1155.                 else if ((curr.v > leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h > rightLoc.h))) {
  1156.                     newmode = 2;    // down
  1157.                     }
  1158.                 else 
  1159.                     newmode = -1;    // inside dbl-clicked word
  1160.                     
  1161.                 /* toggle highlight state of text between current and last mouse positions */
  1162.                 if (mode == -1) {
  1163.                     if (newmode == 2) {
  1164.                         RSlocal[w].anchor = leftLoc;
  1165.                         RSinvText(w, curr, rightLoc, &noConst);
  1166.                         RSlocal[w].last = curr;
  1167.                         }
  1168.                     if (newmode == 1) {
  1169.                         RSlocal[w].anchor = rightLoc;
  1170.                         RSinvText(w, curr, leftLoc, &noConst);
  1171.                         RSlocal[w].last = curr;
  1172.                         }
  1173.                     }
  1174.     
  1175.                 if (mode == 1) {
  1176.                     if (newmode == 2) {
  1177.                         RSlocal[w].anchor = leftLoc;
  1178.                         RSinvText(w, oldcurr, leftLoc, &noConst);
  1179.                         RSinvText(w, rightLoc, curr, &noConst);
  1180.                         RSlocal[w].last = curr;
  1181.                         }
  1182.                     if (newmode == -1) {
  1183.                         RSlocal[w].anchor = leftLoc;
  1184.                         RSinvText(w, oldcurr, leftLoc, &noConst);
  1185.                         RSlocal[w].last = rightLoc;
  1186.                         }
  1187.                     if (newmode == mode) {
  1188.                         RSinvText(w, oldcurr, curr, &noConst);
  1189.                         RSlocal[w].last = curr;
  1190.                         }
  1191.                     }
  1192.                 
  1193.                 if (mode == 2) {
  1194.                     if (newmode == 1) {
  1195.                         RSlocal[w].anchor = rightLoc;
  1196.                         RSinvText(w, oldcurr, rightLoc, &noConst);
  1197.                         RSinvText(w, leftLoc, curr, &noConst);
  1198.                         RSlocal[w].last = curr;
  1199.                         }
  1200.                     if (newmode == -1) {
  1201.                         RSlocal[w].anchor = leftLoc;
  1202.                         RSinvText(w, oldcurr, rightLoc, &noConst);
  1203.                         RSlocal[w].last = rightLoc;
  1204.                         }
  1205.                     if (newmode == mode) {
  1206.                         RSinvText(w, oldcurr, curr, &noConst);
  1207.                         RSlocal[w].last = curr;
  1208.                         }
  1209.                     }
  1210.                     
  1211.                 mode = newmode;
  1212.                 } /* while */
  1213.             }
  1214.         }    
  1215. }
  1216.  
  1217. Point getlocalmouse(GrafPtr wind)
  1218.   /* returns the current mouse position in coordinates local
  1219.     to the specified window. Leaves the current grafPort set
  1220.     to that window. */
  1221.   {
  1222.     Point temp;
  1223.  
  1224.     SetPort(wind);
  1225.     GetMouse(&temp);
  1226.     return(temp);
  1227.   } /* getlocalmouse */
  1228.   
  1229.   /*--------------------------------------------------------------------------*/
  1230. /* NCSA: SB - ClickInContent                                                */
  1231. /*    This procedure is a quick check to see if the mouse click is in the        */
  1232. /*    content region of the window.  Normalize the point to be a VS location    */
  1233. /*     and then see if that is larger than what it should be...                */
  1234. /*    Used by RSClick to see if the click is in the scroll bars, or content..    */
  1235. /*--------------------------------------------------------------------------*/
  1236. short ClickInContent(Point where,short w)                /* NCSA: SB */
  1237. {                                                        /* NCSA: SB */
  1238.     Point x;                                            /* NCSA: SB */
  1239.     x = normalize(where, w);                            /* NCSA: SB */
  1240.     if (x.v >= VSgetlines(w)) return 0;                    /* NCSA: SB */
  1241.     else return 1;                                        /* NCSA: SB */
  1242. }                                                        /* NCSA: SB */
  1243.  
  1244. void RSchangefont(short w, short fnum,long fsiz)
  1245.    /*    Set (w) to font fnum, size fsiz; resize window */
  1246. {
  1247.     Rect pRect;
  1248.     short x1, x2, y1, y2, width, lines;
  1249.     short srw,srh;
  1250.     WStateData *wstate;
  1251.     WindowPeek wpeek;
  1252.     short resizeWidth, resizeHeight;        /* NCSA: SB */
  1253.  
  1254.     RSsetwind(w);
  1255.     srw = RScurrent->rwidth;
  1256.     srh = RScurrent->rheight;
  1257.  
  1258.     if (fnum != -1)
  1259.       {
  1260.         RSTextFont(fnum,fsiz,0);    /* BYU */
  1261.         RScurrent->fnum = fnum;
  1262.       } /* if */
  1263.     
  1264.     if (fsiz)
  1265.       {
  1266.         TextSize(fsiz);
  1267.         RScurrent->fsiz = fsiz;
  1268.       } /* if */
  1269.     
  1270.     RSfontmetrics();
  1271.  
  1272.     width = VSmaxwidth(w) + 1;
  1273.     lines = VSgetlines(w);
  1274.     
  1275.  /* resize window to preserve its dimensions in character cell units */
  1276.     
  1277.     VSgetrgn(w, &x1, &y1, &x2, &y2);    /* get visible region */
  1278.     RScurrent->rwidth =
  1279.         RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO;
  1280.     RScurrent->rheight =
  1281.         RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight;
  1282.  
  1283.     if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO)
  1284.           RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO;
  1285.     if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16)
  1286.           RScurrent->rheight = RMAXWINDOWHEIGHT - 16;
  1287.     
  1288.     RScheckmaxwind(&RScurrent->window->portRect,RScurrent->rwidth +16,    /* NCSA: SB */
  1289.         RScurrent->rheight + 16, &resizeWidth, &resizeHeight);            /* NCSA: SB */
  1290.  
  1291.  
  1292.     SizeWindow
  1293.       (
  1294.         RScurrent->window,
  1295.         RScurrent->rwidth + 16, RScurrent->rheight+16,
  1296.         FALSE
  1297.       ); /*  TRUE if done right */
  1298.     RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16);
  1299.  
  1300.     wpeek = (WindowPeek) RScurrent->window;
  1301.  
  1302.     HLock(wpeek->dataHandle);
  1303.     wstate = (WStateData *) *wpeek->dataHandle;
  1304.  
  1305.     BlockMove(&pRect, &wstate->stdState, 8);
  1306.     pRect.right = pRect.left + RMAXWINDOWWIDTH;
  1307.     if (pRect.right > TelInfo->screenRect.right)
  1308.         pRect.right = TelInfo->screenRect.right;
  1309.     pRect.bottom = pRect.top + RMAXWINDOWHEIGHT;
  1310.     BlockMove(&wstate->stdState, &pRect, 8);
  1311.  
  1312.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  1313.     VSsetrgn(w, x1, y1,
  1314.         (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1),
  1315.         (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1));
  1316.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  1317.     
  1318.     DrawGrowIcon(RScurrent->window);
  1319.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */
  1320.     ValidRect(&RScurrent->window->portRect); /* no need to do it again */
  1321.     DrawControls(RScurrent->window);
  1322.   } /* RSchangefont */
  1323.  
  1324. short RSgetfont
  1325.   (
  1326.     short w, /* which window */
  1327.     short *pfnum, /* where to return font ID */
  1328.     short *pfsiz /* where to return font size */
  1329.   )
  1330.   /* returns the current font ID and size setting for the specified window. */
  1331.   {
  1332.     if (0 > RSsetwind(w))
  1333.         return -1;
  1334.     *pfnum = RScurrent->fnum;
  1335.     *pfsiz = RScurrent->fsiz;
  1336.     return(0);
  1337.   } /* RSgetfont */
  1338.  
  1339. void RSfontmetrics
  1340.   (
  1341.     void
  1342.   )
  1343.   /* calculates various metrics for drawing text with selected font
  1344.     and size in current grafport into *RScurrent. */
  1345.   {
  1346.     FontInfo finforec;
  1347.     GrafPtr myGP;
  1348.  
  1349.     GetPort(&myGP); 
  1350.     GetFontInfo(&finforec);
  1351.     RScurrent->fascent = finforec.ascent;
  1352.     RScurrent->fheight = finforec.ascent + finforec.descent + finforec.leading /* +1 */;
  1353.     RScurrent->monospaced = (CharWidth('W') == CharWidth('i'));   
  1354.  
  1355.     RScurrent->fwidth = CharWidth('W'); 
  1356. }
  1357.  
  1358. pascal void ScrollProc(ControlHandle control, short part)
  1359.   /* scroll-tracking routine which does continuous scrolling of visible
  1360.      region. */
  1361.   {
  1362.     short w, kind, x1, y2, x2, y1;
  1363.  
  1364.     kind = RSfindscroll(control, &w);
  1365.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  1366.  
  1367.     if (kind == 2)
  1368.       { /* horizontal scroll bar */
  1369.         switch (part)
  1370.           {
  1371.             case inUpButton:                            /* Up is left */
  1372.                 VSscrolleft(w, 1);
  1373.                 break;
  1374.             case inDownButton:                            /* Down is right */
  1375.                 VSscrolright(w, 1);
  1376.                 break;
  1377.             case inPageUp:
  1378.                 VSscrolleft(w, x2 - x1); /* scroll a whole windowful */
  1379.                 break;
  1380.             case inPageDown:
  1381.                 VSscrolright(w, x2 - x1); /* scroll a whole windowful */
  1382.                 break;
  1383.             default:
  1384.                 break;
  1385.           } /* switch */
  1386.       }
  1387.     else if (kind == 1)
  1388.       { /* vertical scroll bar */
  1389.         switch (part)
  1390.           {
  1391.             case inUpButton:
  1392.                 VSscrolback(w, 1);
  1393.                 break;
  1394.             case inDownButton:
  1395.                 VSscrolforward(w, 1);
  1396.                 break;
  1397.             case inPageUp:
  1398.                 VSscrolback(w, y2 - y1); /* scroll a whole windowful */
  1399.                 break;
  1400.             case inPageDown:
  1401.                 VSscrolforward(w, y2 - y1); /* scroll a whole windowful */
  1402.                 break;
  1403.             default:
  1404.                 break;
  1405.           } /* switch */
  1406.       } /* if */
  1407.   } /* ScrollProc */
  1408.