home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / Screens / rsinterf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-14  |  44.2 KB  |  1,580 lines  |  [TEXT/CWIE]

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