home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Telnet 2.6.1d1 / src / source / vs / rsmac.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-18  |  71.8 KB  |  2,554 lines  |  [TEXT/KAHL]

  1. #define NCSA_TELNET
  2. /*
  3.  *
  4.  *      Virtual Screen Kernel Macintosh Real Screen Interface
  5.  *                          (rsmac.c)
  6.  *
  7.  *   National Center for Supercomputing Applications
  8.  *      by Gaige B. Paulsen
  9.  *
  10.  *    This file contains the macintosh real screen calls for the NCSA
  11.  *  Virtual Screen Kernel.
  12.  *
  13.  *      RSbell(w)                   - Ring window w's bell
  14.  *      RScursoff(w)                - Turn the cursor off in w
  15.  *      RScurson(w,x,y)             - Turn the cursor on in w at x,y
  16.  *      RSdraw(w,x,y,a,len,ptr)     - Draw @x,y in w string@ptr for length len
  17.  *      RSdelchars(w,x,y,n)         - Delete n chars in w from x,y
  18.  *      RSdellines(w,t,b,n)         - Delete n lines in region t->b in w
  19.  *      RSerase(w,x1,y1,x2,y2)      - Erase from x1,y1 to x2,y2 in w
  20.  *      RSinitall()                 - Initialize the world if necessary
  21.  *      RSinslines(w,t,b,n)         - Insert n lines in region t->b in w
  22.  *      RSinsstring(w,x,y,a,len,ptr)- Insert len chars @x,y in w attrib a
  23.  *      RSsendstring(w,ptr,len)     - Send string @ptr length len from window w
  24.  *        RSbufinfo( w, total,current)- Tells you the total/current lines in buffer
  25.  *        RSdrawsep( w, y1,draw)        - Tells you to draw the line at y1 (0 is erase)
  26.  *        RSmargininfo( w, total, current)    - Tells you total/current columns in VS
  27.  *
  28.  *
  29.  *  Macintosh only Routines:
  30.  *    NI    RSregnconv( *)                - Convert region to rect coords
  31.  *  NI  RSsetwind(w)                - Set the port and vars to window w
  32.  *  NI  RSsetattr(a)                - Set font/text style to a
  33.  *    NI    RSsetConst(w)
  34.  *    ML    RSattach(w,wind)            - Attach the RS (w) to window wind
  35.  *    ML    RSdetach(w)                - Ready window for go-away
  36.  *    ML    RSselect(w,pt,shift)        - Handle selection RS (w) point (pt) and (shift) if held down
  37.  *    ML    RSzoom(window,code,shifted)    - Zoom Box handling
  38.  *    ML    RSsize( window, where)        - Resize handling
  39.  *    IN    RSgetwindow(w)                - Get the WindowPtr for RS (w)
  40.  *    IN    RSfindvwind(wind)            - Find the (RS/VS) # of wind
  41.  *    IN    RSfindscroll( control, n)    - Find which VS the control is in and which control it is
  42.  *      RSupdate(wind)                - Handle updates on WIND, return 0 if not an RS
  43.  *        RSactivate(w)                - Handle activate events 
  44.  *        RSdeactivate(w)                - Handle deactivate events 
  45.  *        RSGetTextSel(w,table)        - Returns handle to text selection of window w, table->tabs
  46.  *        RSchangefont(w,fnum,fsiz,r)    - Set (w) to font fnum, size fsiz, resize window if (r)
  47.  *        RSgetfont(w, &fnum, &fsiz)    - Get the font size and number into fnum and fsiz
  48.  *        RSnewwindow( wDims, sb, wid, lines
  49.  *            name,wrap,fnum,fsiz,
  50.  *            showit, goaway)            - Returns VS # of newly created text window -
  51.  *                                      wDims (dimension),sb(scrollback),wid(width 80/132),
  52.  *                                    lines (# of lines, 24 <> 66),
  53.  *                                      name(window), wrap(0/1),fnum,fsiz, showit(vis),goaway(0,1)
  54.  *        RSkillwindow( w)            - Destroys, deallocates, kills window (w)
  55.  *        RSclick(window, eventRecord)- Handle clicks in window (returns false if not RS window)
  56.  *        RShide(w)                    - Hide RS (w)
  57.  *        RSshow(w)                    - Show RS (w)
  58.  *        RScprompt(w, FilterProc)    - Prompt for colors...FilterProc is for Modal Dialog
  59.  *        RSsetcolor(w,n,r,g,b)        - Set one of the 4 colors of RS (w) to R,G,B
  60.  *        RSgetcolor(w,n,r,g,b)        - Get one of the 4 colors of RS (w) into R,G,B
  61.  *        RSmouseintext(w,myPoint)    - Returns true if Mouse is in text part of current RS window
  62.  *        RSskip(w,on)                - Activate/deactivate drawing in an RS
  63.  *        
  64.  *        IN - Informational
  65.  *        ML - Mid Level
  66.  *        NI - Necessary Internal
  67.  *           - Suggested calls
  68.  *
  69.  *      Version Date    Notes
  70.  *      ------- ------  ---------------------------------------------------
  71.  *      0.01    861102  Initial coding -GBP
  72.  *      0.25    861106  Added code from screen.c -GBP
  73.  *      0.50    861113  First compiled edition -GBP
  74.  *        2.1        871130    NCSA Telnet 2.1 -GBP
  75.  *        2.2     880715    NCSA Telnet 2.2 -GBP
  76.  *        2.6        7/92    put globals into struct, cursors into array, and cleaned up 
  77.  *                        some of the font typedefs            Scott Bulmahn
  78.  *        2.6b4    12/92    Cleaned up the code, and added double clicking -- Scott Bulmahn
  79.  *
  80.  */
  81.  
  82. #ifdef MPW
  83. #pragma segment RS
  84. #endif
  85.  
  86. #define __ALLNU__
  87. #include <OSUtils.h>
  88. #include <Palettes.h>
  89. #include <Picker.h>        /* BYU LSC */
  90. #include <Fonts.h>
  91. #include <stdio.h>
  92. #include <string.h>
  93. #include <ctype.h>
  94.  
  95. #include "TelnetHeader.h"
  96. #include "DlogUtils.proto.h"
  97. #include "configure.proto.h"    // For colorboxmodalproc and colorboxproc
  98. #include "maclook.proto.h"
  99. #include "network.proto.h"
  100. #include "menuseg.proto.h"
  101. #include "vskeys.h"
  102. #include "vsdata.h"
  103. #include "vsinterf.proto.h"
  104. #include "vsintern.proto.h"
  105. #include "telneterrors.h"
  106. #include "wind.h"
  107. #include "rsdefs.h"
  108. #include "parse.proto.h"        // For SendNAWSinfo proto
  109. #include "wdefpatch.proto.h"    /* 931112, ragge, NADA, KTH */
  110.  
  111. #define NFDEF {0,0,0}
  112. #define NBDEF {65535,65535,65535}
  113. #define BFDEF {0,61183,11060}
  114. #define BBDEF {61183,2079,4938}
  115. #define UFDEF {1,0,0}
  116. #define UBDEF {0,0,0}
  117.  
  118. #define    MYSETRECT(a,b,c,d,e)    a.left = b; \
  119.                                 a.top = c;\
  120.                                 a.right = d;\
  121.                                 a.bottom = e;\
  122.                                 
  123. #define INFINITY    20000        // Will screens ever be this large?
  124.  
  125. #ifdef NCSA_TELNET
  126. extern WindRec *screens;
  127. #endif NCSA_TELNET
  128. extern SysEnvRec    theWorld;
  129.  
  130. #include "rsmac.proto.h"
  131.  
  132. void RScheckmaxwind(Rect *,short , 
  133.             short , short *, short *);
  134.  
  135. void RScalcwsize(short w, short width);
  136.  
  137. short MaxRS;
  138.  
  139. RSdata *RSlocal, *RScurrent;
  140. Rect    noConst,
  141.         RScur;                /* cursor rectangle */
  142.  
  143. RgnHandle RSuRgn;            /* update region */
  144.  
  145. short RSw=-1,         /* last window used */
  146.     RSa=0;          /* last attrib used */
  147. short RScolor=1;        /* true if try to use color stuff */
  148.  
  149. short RScolors[]=
  150.     { 33,            /* black */
  151.       30,            /* white */
  152.       205,            /* red */
  153.       341,            /* green */
  154.       409,            /* blue */
  155.       273,            /* cyan */
  156.       137,            /* magenta */
  157.       69            /* yellow */
  158.       };
  159.  
  160. void    RSunload(void) {}
  161.  
  162. void RSinitall
  163.   (
  164.     short max /* max nr windows to allow */
  165.   )
  166.   /* initializes handling of terminal windows. */
  167.   {
  168.     short i;
  169.     extern SysEnvRec theWorld;
  170.  
  171.     MaxRS = max;
  172.     RSlocal = (RSdata *) NewPtrClear(MaxRS * sizeof(RSdata));
  173.     for (i = 0; i < MaxRS; RSlocal[i++].window = 0L)
  174.       {
  175.         RScurrent = RSlocal + i;
  176.         RScurrent->id = 'RSDA';
  177.         RScurrent->color[0] = 0;            /* Foreground */
  178.         RScurrent->color[1] = 1;            /* Background */
  179.         RScurrent->color[2] = 2;            /* Blink Fore */
  180.         RScurrent->color[3] = 3;            /* Blink Back */
  181.         RScurrent->cursor.top = 0;
  182.         RScurrent->cursor.bottom = 0;
  183.         RScurrent->cursor.left = 0;
  184.         RScurrent->cursor.right = 0;
  185.       }
  186.     RSuRgn = NewRgn();
  187.     RScur.left = 0;
  188.     RScur.top = 0;
  189.     RScur.bottom = 0;
  190.     RScur.right = 0;
  191.     RScolor = theWorld.hasColorQD;
  192.   } /* RSinitall */
  193.  
  194. short RSTextSelected(short w) {        /* BYU 2.4.11 */
  195.   return(RSlocal[w].selected);    /* BYU 2.4.11 */
  196. }                                /* BYU 2.4.11 */
  197.  
  198. void RSsetConst
  199.   (
  200.     short w
  201.   )
  202.   /* sets "noConst" global to a zero-based rectangle equal in size
  203.     to the specified terminal window. */
  204.   {
  205.   noConst.left = 0;
  206.   noConst.top = 0;
  207.   noConst.right = RSlocal[w].width;
  208.   noConst.bottom = RSlocal[w].height;
  209.   } /* RSsetConst */
  210.  
  211. /****************************************************************************/
  212. /*  Given a window record number, do a SetPort() to the window associated with
  213. *   that window record.
  214. */
  215. short RSsetwind
  216.   (
  217.     short w
  218.   )
  219.   {
  220.     if ((w < 0) || (w > MaxRS))
  221.         return(-3);
  222.     if (RSw != w)                                /* if last window used is different */
  223.       {
  224.         if (RSlocal[w].window == 0L)
  225.             return(-4);
  226.         RScurrent = RSlocal + w;
  227.         RSw = w;
  228.         RSa = -1; /* attributes will need setting */
  229.         SetPort(RScurrent->window);
  230.         return(1);
  231.       }
  232.     SetPort(RScurrent->window);
  233.     return(0);
  234.   } /* RSsetwind */
  235.  
  236. void RSbell
  237.   (
  238.     short w
  239.   )
  240.   /* gives an audible signal associated with the specified window. */
  241.   {
  242.     RSsetwind(w);
  243.     if (FrontWindow() != RScurrent->window)
  244.       {
  245.       /* beep and temporarily invert the window contents, so
  246.         the user sees which window is beeping */
  247.         InvertRect(&RScurrent->window->portRect);
  248.         SysBeep(8);
  249.         InvertRect(&RScurrent->window->portRect);
  250.       }
  251.     else
  252.       /* window is frontmost--just beep */
  253.         SysBeep(8);
  254.   } /* RSbell */
  255.  
  256. void    RScursblink( short w)        /* Blinks the cursor */
  257. {
  258.     GrafPtr    oldwindow;
  259.     long    now = TickCount();
  260.     
  261.     if (now > TelInfo->blinktime) {
  262.         if (VSvalids(w) != 0)            /* BYU 2.4.12 */
  263.             return;                        /* BYU 2.4.12 */
  264.         if (!VSIcursorvisible())        /* BYU 2.4.12 */
  265.             return;                        /* BYU 2.4.12 - cursor isn't visible */
  266.     
  267.         GetPort(&oldwindow);            /* BYU 2.4.11 */
  268.         TelInfo->blinktime = now + 40;            /* BYU 2.4.11 */
  269.         RSlocal[w].cursorstate ^= 1;     /* BYU 2.4.11 */
  270.         SetPort(RSlocal[w].window);        /* BYU 2.4.11 */
  271.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.11 */
  272.         SetPort(oldwindow);                /* BYU 2.4.11 */
  273.     }
  274. } /* RScursblink */
  275.  
  276. void RScursblinkon                        /* BYU 2.4.18 */
  277.   (                                        /* BYU 2.4.18 */
  278.     short w                                /* BYU 2.4.18 */
  279.   )                                        /* BYU 2.4.18 */
  280.   /* Blinks the cursor */                /* BYU 2.4.18 */
  281.   {                                        /* BYU 2.4.18 */
  282.       if (!RSlocal[w].cursorstate) {        /* BYU 2.4.18 */
  283.         GrafPtr oldwindow;                /* BYU 2.4.18 */
  284.         GetPort(&oldwindow);            /* BYU 2.4.18 */
  285.         RSlocal[w].cursorstate = 1;     /* BYU 2.4.18 */
  286.         SetPort(RSlocal[w].window);        /* BYU 2.4.18 */
  287.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.18 */
  288.         SetPort(oldwindow);                /* BYU 2.4.18 */
  289.     }                                    /* BYU 2.4.18 */
  290.   } /* RScursblink */                    /* BYU 2.4.18 */
  291.  
  292. void RScursblinkoff                        /* BYU 2.4.11 */
  293.   (                                        /* BYU 2.4.11 */
  294.     short w                                /* BYU 2.4.11 */
  295.   )                                        /* BYU 2.4.11 */
  296.   /* Blinks the cursor */                /* BYU 2.4.11 */
  297.   {                                        /* BYU 2.4.11 */
  298.       if (RSlocal[w].cursorstate) {        /* BYU 2.4.11 */
  299.         GrafPtr oldwindow;                /* BYU 2.4.11 */
  300.         GetPort(&oldwindow);            /* BYU 2.4.11 */
  301.         RSlocal[w].cursorstate = 0;     /* BYU 2.4.11 */
  302.         SetPort(RSlocal[w].window);        /* BYU 2.4.11 */
  303.         InvertRect(&RSlocal[w].cursor);    /* BYU 2.4.11 */
  304.         SetPort(oldwindow);                /* BYU 2.4.11 */
  305.     }                                    /* BYU 2.4.11 */
  306.   } /* RScursblink */                    /* BYU 2.4.11 */
  307.  
  308. void RScursoff
  309.   (
  310.     short w
  311.   )
  312.   /* hides the text cursor for the specified window. Assumes it
  313.     is currently being shown. */
  314.   {
  315.     if (RSlocal[w].skip || !RSlocal[w].cursorstate)        /* BYU 2.4.11 */
  316.         return;
  317.     RSsetwind(w);
  318.     RScurrent->cursorstate = 0;                            /* BYU 2.4.11 */
  319.     InvertRect(&RScurrent->cursor);
  320.   } /* RScursoff */
  321.  
  322. void RScurson
  323.   (
  324.     short w,
  325.     short x,
  326.     short y
  327.   )
  328.   /* displays the text cursor for the specified window, at the
  329.     specified position. Assumes it isn't currently being shown. */
  330.   {
  331.     if (RSlocal[w].skip || RSlocal[w].cursorstate)        /* BYU 2.4.11 */
  332.         return;
  333.     RSsetwind(w);
  334.  
  335.     RScurrent->cursor.left = x * RScurrent->fwidth;            /* BYU 2.4.11 */
  336.     RScurrent->cursor.top  = y * RScurrent->fheight;        /* BYU 2.4.11 */
  337.  
  338.     switch (gApplicationPrefs->CursorType) {                                            /* BYU 2.4.11 */
  339.         case UNDERSCORECURSOR:                                        /* BYU 2.4.11 */
  340.             RScurrent->cursor.top  += RScurrent->fheight;            /* BYU 2.4.11 */
  341.             RScurrent->cursor.right  = RScurrent->cursor.left + RScurrent->fwidth;    /* BYU 2.4.11 */
  342.             RScurrent->cursor.bottom = RScurrent->cursor.top + 1;    /* BYU 2.4.11 */
  343.             break;
  344.         case VERTICALCURSOR:                                        /* BYU 2.4.11 */
  345.             RScurrent->cursor.left += 2;                            /* BYU 2.4.11 */
  346.             RScurrent->cursor.right  = RScurrent->cursor.left + 1;    /* BYU 2.4.11 */
  347.             RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight;    /* BYU 2.4.11 */
  348.             break;
  349.         case BLOCKCURSOR:                                            /* BYU 2.4.11 */
  350.         default:                                                    /* BYU 2.4.11 */
  351.             RScurrent->cursor.right  = RScurrent->cursor.left + RScurrent->fwidth;    /* BYU 2.4.11 */
  352.             RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight;    /* BYU 2.4.11 */
  353.             break;
  354.     }
  355.  
  356.     if (!gApplicationPrefs->BlinkCursor) {                                    /* BYU 2.4.11 */
  357.         RScurrent->cursorstate = 1;                        /* BYU 2.4.11 */
  358.         InvertRect(&RScurrent->cursor);                    /* BYU 2.4.11 */
  359.     }                                                    /* BYU 2.4.11 */
  360.   } /* RScurson */
  361.  
  362. void RSTextFont(short myfnum, short myfsiz, short myface)                 /* BYU */
  363. {                                        /* BYU */
  364.     if ((myfnum == monaco) &&             /* BYU - If Monaco, size 9, and bold, then */
  365.         (myfsiz == 9) &&                /* BYU */
  366.         (myface & bold))    {            /* BYU */
  367.         TextFont(75);                    /* BYU - use NCSA's Monaco. */
  368.     } else {                            /* BYU */
  369.         TextFont(myfnum);                /* BYU */
  370.     }                                    /* BYU */
  371. }                                        /* BYU */
  372.  
  373. void RSsetattr
  374.   (
  375.     short a
  376.   )
  377.   /* sets the text attributes for drawing into the current window. */
  378.   {
  379.      GrafPtr    thePort;            /* NCSA: SB */
  380.     
  381.     GetPort(&thePort);            /* NCSA: SB */
  382.  
  383.    if (VSisgrph(a))
  384.         TextFont(74); /* use "NCSA VT" font for special graphics */
  385.     else
  386. #if 1                                                    /* BYU */
  387.         RSTextFont(RScurrent->fnum,RScurrent->fsiz,a);     /* BYU - use user-selected text font */
  388. #else
  389.         TextFont(RScurrent->fnum); /* use user-selected text font */
  390. #endif
  391.  
  392.     TextSize(RScurrent->fsiz);
  393.  
  394. /* BYU - bold system fonts don't work (they overwrite the scroll bars), 
  395.          but NCSA's 9 point Monaco bold works okay. */
  396.  
  397.     TextFace((a & outline) >> 1);     /* BYU - do outline as underline setting */
  398.  
  399. #ifdef GOTTHEGOUGH
  400.     if (a & bold)                                    /* NCSA: SB */
  401.         TextFace(thePort->txFace + bold);            /* NCSA: SB */
  402. #endif
  403.  
  404.   /* set up reverse video setting */
  405.     if (RScolor)
  406.       {
  407.         if (VSisrev(a))
  408.             TextMode(notSrcCopy);
  409.         else
  410.             TextMode(srcCopy);
  411.       }
  412.     else
  413.       {
  414.         if (VSisrev(a))
  415.           {
  416.             BackPat(PATTERN(qd.black));    /* Reverses current attributes regard */
  417.             PenPat(PATTERN(qd.white));    /* less of the color, etc.... */
  418.           }
  419.         else
  420.           {
  421.             BackPat(PATTERN(qd.white));
  422.             PenPat(PATTERN(qd.black));
  423.           } /* if */
  424.       } /* if */
  425.   /* use colors to stand in for blink setting */
  426.     if (VSisblnk(a))
  427.       {
  428.         if (RScolor)
  429.           {
  430.             PmForeColor(2);
  431.             PmBackColor(3);
  432.           }
  433.         else
  434.           {
  435.             ForeColor((long) RScolors[RScurrent->color[2]]);    /* Blink foreground */
  436.             BackColor((long) RScolors[RScurrent->color[3]]);    /* Blink Background */
  437.           } /* if */
  438.       }
  439.     else
  440.       {
  441.         if (RScolor)
  442.           {
  443.             PmForeColor(0);
  444.             PmBackColor(1);
  445.           }
  446.         else
  447.           {
  448.             ForeColor((long) RScolors[RScurrent->color[0]]);    /* normal foreground */
  449.             BackColor((long) RScolors[RScurrent->color[1]]);    /* normal Background */
  450.           } /* if */
  451.       } /* if */
  452.     RSa = a;
  453.   } /* RSsetattr */
  454.  
  455. #ifdef    NO_UNIVERSAL
  456. #define LMGetHiliteMode() (* (unsigned char *) 0x0938)
  457. #define LMSetHiliteMode(HiliteModeValue) ((* (unsigned char *) 0x0938) = (HiliteModeValue))
  458. #endif
  459.  
  460. void DoHiliteMode(void)        /* BYU LSC */
  461.   /* enables use of highlighting in place of simple color inversion
  462.     for next QuickDraw operation. */
  463.   {
  464.       
  465.       LMSetHiliteMode(LMGetHiliteMode() & 0x7F);
  466. //    char *p = (char *) 0x938; /* pointer to HiliteMode low-memory global */
  467. //    *p = *p & 0x7f; /* clear the HiliteBit */
  468.   } /* HiliteMode */
  469.  
  470. void RSinvText
  471.   (
  472.     short w, 
  473.     Point curr,
  474.     Point last,
  475.     RectPtr constrain /* don't highlight anything outside this rectangle */
  476.   )
  477.   /* highlights the text from curr to last inclusive. */
  478.   {
  479.     Rect temp, temp2;
  480.     Point lb, ub;
  481.  
  482.     RSsetwind(w);
  483.   /* normalize coordinates with respect to visible area of virtual screen */
  484.     curr.v -= RScurrent->topline;
  485.     curr.h -= RScurrent->leftmarg;
  486.     last.v -= RScurrent->topline;
  487.     last.h -= RScurrent->leftmarg;
  488.  
  489.     if (curr.v == last.v)
  490.       {
  491.       /* highlighted text all on one line */
  492.         if (curr.h < last.h) /* get bounds the right way round */
  493.           {
  494.             ub = curr;
  495.             lb = last;
  496.           }
  497.         else
  498.           {
  499.             ub = last;
  500.             lb = curr;
  501.           } /* if */
  502.         MYSETRECT /* set up rectangle bounding area to be highlighted */
  503.           (
  504.             temp,
  505.             (ub.h + 1) * RScurrent->fwidth,
  506.             ub.v * RScurrent->fheight,
  507.             (lb.h + 1) * RScurrent->fwidth,
  508.             (lb.v + 1) * RScurrent->fheight
  509.           );
  510.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  511.         DoHiliteMode();                        /* BYU LSC */
  512.         InvertRect(&temp2);
  513.       }
  514.     else
  515.       {
  516.       /* highlighting across more than one line */
  517.         if (curr.v < last.v)
  518.             ub = curr;
  519.         else
  520.             ub = last;
  521.         if (curr.v > last.v)
  522.             lb = curr;
  523.         else
  524.             lb = last;
  525.         MYSETRECT /* bounds of first (possibly partial) line to be highlighted */
  526.           (
  527.             temp,
  528.             (ub.h + 1) * RScurrent->fwidth,
  529.             ub.v * RScurrent->fheight,
  530.             RScurrent->width,
  531.             (ub.v + 1) * RScurrent->fheight
  532.           );
  533.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  534.         DoHiliteMode();                        /* BYU LSC */
  535.         InvertRect(&temp2);
  536.         MYSETRECT /* bounds of last (possibly partial) line to be highlighted */
  537.           (
  538.             temp,
  539.             0,
  540.             lb.v * RScurrent->fheight,
  541.             (lb.h + 1) * RScurrent->fwidth,
  542.             (lb.v + 1) * RScurrent->fheight
  543.           );
  544.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  545.         DoHiliteMode();                        /* BYU LSC */
  546.         InvertRect(&temp2);
  547.  
  548.         if (lb.v - ub.v > 1) /* highlight extends across more than two lines */
  549.           {
  550.           /* highlight complete in-between lines */
  551.             SetRect
  552.               (
  553.                 &temp,
  554.                 0,
  555.                 (ub.v + 1) * RScurrent->fheight,
  556.                 RScurrent->width,
  557.                 lb.v * RScurrent->fheight
  558.               );
  559.             SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  560.             DoHiliteMode();                        /* BYU LSC */
  561.             InvertRect(&temp2);
  562.  
  563.           } /* if */
  564.       } /* if */
  565.   } /* RSinvText */
  566.  
  567. void RSdraw
  568.   (
  569.     short w, /* window number */
  570.     short x, /* starting column */
  571.     short y, /* line on which to draw */
  572.     short a, /* text attributes */
  573.     short len, /* length of text to draw */
  574.     char *ptr /* pointer to text */
  575.   )
  576.   /* draws a piece of text (assumed to fit on a single line) in a window,
  577.     using the specified attributes. If any part of the text falls
  578.     within the current selection, it will be highlighted. */
  579.   {
  580.     Rect rect;
  581.     static char temp[128];
  582.     short ys;
  583.     static short theLen;
  584.  
  585.     if (RSlocal[w].skip)
  586.         return;
  587.     RSsetwind(w);
  588.     RSsetattr(0);
  589.     MYSETRECT /* set up rectangle bounding text being drawn */
  590.       (
  591.         rect,
  592.         x * RScurrent->fwidth,
  593.         y * RScurrent->fheight,
  594.         (x + len) * RScurrent->fwidth,
  595.         (y + 1) * RScurrent->fheight
  596.       );
  597.     if (RSa != a)
  598.         RSsetattr(a);
  599.     if (x <= 0)            /* BYU 2.4.12 - Without this, 1 pixel column of reverse */
  600.       rect.left = -3;    /* BYU 2.4.12 - video text does not clear at left margin */
  601. #ifdef OLDM
  602.     if (!RScolor)
  603. #endif OLDM
  604.         EraseRect(&rect);
  605.     if (x <= 0)            /* BYU 2.4.12 - Okay, just putting it back the way it was */
  606.       rect.left = 0;    /* BYU 2.4.12 */
  607.     ys = y * RScurrent->fheight + RScurrent->fascent;
  608.         MoveTo(x * RScurrent->fwidth, ys);
  609.     strncpy(temp,ptr,len);
  610.     temp[len]=0;
  611.     theLen = StringWidth((StringPtr)temp);
  612.     
  613. #ifdef NEWTXT
  614.         DrawText(ptr, 0, len);
  615.         
  616. #else
  617.     if (RScurrent->monospaced)
  618.         DrawText(ptr, 0, len);
  619.     else
  620.         while (len--)
  621.           {
  622.           /* draw the characters one at a time to defeat the proportional spacing */
  623.             DrawChar(*ptr++);
  624.             MoveTo((++x) * RScurrent->fwidth, ys);  /*good version */
  625. /*            MoveTo((++x) * CharWidth(*(ptr-1)), ys); */
  626.           } /* while */
  627. #endif
  628.     if (RScurrent->selected)
  629.         RSinvText(w, *(Point *) &RScurrent->anchor,
  630.             *(Point *) &RScurrent->last, &rect);
  631.   } /* RSdraw */
  632.  
  633. void RSdelcols
  634.   (
  635.     short w,
  636.     short n /* number of columns to scroll */
  637.   )
  638.   /* scrolls the entire visible display of a virtual screen the
  639.     specified number of columns to the left, blanking out
  640.     the newly-revealed area. */
  641.   {
  642.     Rect rect;
  643.  
  644.     if (RSlocal[w].skip)
  645.         return;
  646.     RSsetwind(w);
  647.     MYSETRECT /* bounds of entire text area, for scrolling */
  648.       (
  649.         rect,
  650.         0,
  651.         0,
  652.         RScurrent->width,
  653.         RScurrent->height
  654.       );
  655.     ScrollRect(&rect, -n * RScurrent->fwidth, 0, RSuRgn);
  656.     InvalRgn(RSuRgn);
  657.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  658.     MYSETRECT /* bounds of newly-revealed area */
  659.       (
  660.         rect,
  661.         RScurrent->width - (n * RScurrent->fwidth),
  662.         0,
  663.         RScurrent->width,
  664.         RScurrent->height
  665.       );
  666.     if (RScurrent->selected)
  667.       /* highlight any newly-revealed part of the current selection */
  668.         RSinvText(w, *(Point *) &RScurrent->anchor,
  669.             *(Point *) &RScurrent->last, &rect);
  670.   } /* RSdelcols */
  671.  
  672. void RSdelchars
  673.   (
  674.     short w, /* affected window */
  675.     short x, /* column to delete from */
  676.     short y, /* line on which to do deletion */
  677.     short n /* number of characters to delete */
  678.   )
  679.   /* deletes the specified number of characters from the specified
  680.     position to the right, moving the remainder of the line to the
  681.     left. */
  682.   {
  683.     Rect rect;
  684.  
  685.     if (RSlocal[w].skip)
  686.         return;
  687.     RSsetwind(w);
  688.     RSsetattr(0); /* avoid funny pen modes */
  689.     MYSETRECT /* bounds of area from starting column to end of line */
  690.       (
  691.         rect,
  692.         x * RScurrent->fwidth,
  693.         y * RScurrent->fheight,
  694.         RScurrent->width,
  695.         (y + 1) * RScurrent->fheight
  696.       );
  697.     if ((x + n) * RScurrent->fwidth > RScurrent->width)
  698.       /* deleting to end of line */
  699.         EraseRect(&rect);
  700.     else
  701.       {
  702.       /* scroll remainder of line to the left */
  703.         ScrollRect(&rect, - RScurrent->fwidth * n, 0, RSuRgn);
  704.         InvalRgn(RSuRgn);
  705.            ValidRect(&rect); /* leave newly-revealed area blank */
  706.         if (RScurrent->selected)
  707.           {
  708.           /* highlight any part of selection which lies in newly-blanked area */
  709.             HLock((Handle) RSuRgn);
  710.             RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &((*RSuRgn)->rgnBBox));
  711.             HUnlock((Handle) RSuRgn);
  712.           } /* if */
  713.       } /* if */
  714.   } /* RSdelchars */
  715.  
  716. void RSdellines
  717.   (
  718.     short w, /* affected window */
  719.     short t, /* top line of affected region */
  720.     short b, /* bottom line of affected region */
  721.     short n, /* number of lines to delete */
  722.     short scrolled
  723.       /*
  724.         -ve => cancel current selection, if any;
  725.         +ve => selection has moved up one line;
  726.         0 => don't touch selection
  727.       */
  728.   )
  729.   /* deletes lines at the top of the specified region of a window,
  730.     inserting new blank lines at the bottom, and scrolling up the
  731.     stuff in between. */
  732.   {
  733.     Rect    rect;
  734.     short    RSfheightTimesn, RSfheightTimesbplus1;
  735.  
  736.     if (RSlocal[w].skip)
  737.         return;
  738.  
  739.     RSsetwind(w);
  740.     RSsetConst(w);
  741.     RSsetattr(0); /* avoid funny pen modes */
  742.  
  743.     if (scrolled)
  744.       {
  745.         if (RScurrent->selected && scrolled < 0)
  746.           {
  747.           /* unhighlight and cancel current selection */
  748.             RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &noConst);
  749.             RScurrent->selected = 0;
  750.           }
  751.         else
  752.           {
  753.             RScurrent->last.v -= 1;        /* Subtract one from each of the */
  754.             RScurrent->anchor.v -= 1;    /* vertical Selection components */
  755.           } /* if */
  756.       } /* if */
  757.  
  758.     rect.left = -1;                            /* BYU 2.4.12 - necessary */
  759.     rect.right = RScurrent->width;
  760.     rect.top = t * RScurrent->fheight;
  761.     RSfheightTimesbplus1 = (b + 1) * RScurrent->fheight;
  762.     rect.bottom = RSfheightTimesbplus1;
  763.  
  764.   /* adjust the update region to track the scrolled window contents */
  765.       RSfheightTimesn = RScurrent->fheight * n;
  766.     OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn,
  767.         0, -RSfheightTimesn);
  768.     ScrollRect(&rect, 0, -RSfheightTimesn , RSuRgn);
  769.     RSsetattr(VSIw->attrib); /* restore mode for text drawing */
  770.     InvalRgn(RSuRgn);
  771.  
  772.   /* validate the area containing the newly-inserted blank lines. */
  773.   /* any necessary redrawing in newly-revealed area will be done by caller */
  774.     MYSETRECT
  775.       (
  776.         rect,
  777.         0,
  778.         (b - n + 1) * RScurrent->fheight - 1,
  779.         RScurrent->width,
  780.         RSfheightTimesbplus1 + 1
  781.       );
  782.  
  783.     ValidRect(&rect);
  784.   } /* RSdellines */
  785.  
  786. void RSerase
  787.   (
  788.     short w, /* affected window */
  789.     short x1, /* left column */
  790.     short y1, /* top line */
  791.     short x2, /* right column */
  792.     short y2 /* bottom line */
  793.   )
  794.   /* erases a rectangular portion of the screen display, preserving
  795.     the selection highlight. */
  796.   {
  797.     Rect rect;
  798.  
  799.     if (RSlocal[w].skip)
  800.         return;
  801.     RSsetwind(w);
  802.     RSsetattr(0); /* avoid funny pen modes */
  803.     SetRect
  804.       (
  805.         &rect,
  806.         x1 * RScurrent->fwidth,
  807.         y1 * RScurrent->fheight,
  808.         (x2 + 1) * RScurrent->fwidth - 1,
  809.         (y2 + 1) * RScurrent->fheight + 1
  810.       );
  811.     if (rect.left <= 0)                        /* little buffer strip on left */
  812.         rect.left = CHO;
  813.     if (rect.right >= RScurrent->width - 1)
  814.         rect.right = RScurrent->rwidth - 2;    /* clear to edge of window, including edge strip */
  815.     if (rect.bottom >= RScurrent->height - 2)
  816.         rect.bottom = RScurrent->rheight + 1;    /* clear to bottom edge also */
  817.     EraseRect(&rect);
  818.     if (RScurrent->selected)
  819.       /* highlight any part of the selection within the cleared area */
  820.         RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect);
  821.   } /* RSerase */
  822.  
  823. void RSinslines
  824.   (
  825.     short w, /* affected window */
  826.     short t, /* where to insert blank lines */
  827.     short b, /* bottom of area to scroll */
  828.     short n, /* number of lines to insert */
  829.     short scrolled /* -ve <=> cancel current selection, if any */
  830.   )
  831.   /* inserts blank lines at the top of the given area of the display,
  832.     scrolling the rest of it down. */
  833.   {
  834.     Rect rect;
  835.  
  836.     if (RSlocal[w].skip)
  837.         return;
  838.     RSsetwind(w);
  839.     RSsetConst(w);
  840.     RSsetattr(0); /* avoid funny pen modes */
  841.     if (RScurrent->selected && (scrolled < 0))
  842.       {
  843.       /* unhighlight and cancel selection */
  844.         RSinvText(w, *(Point *) &RScurrent->anchor,
  845.             *(Point *) &RScurrent->last, &noConst);
  846.         RScurrent->selected = 0;
  847.       } /* if */
  848.     rect.left = -1;                        /* BYU 2.4.12 - necessary */
  849.     rect.right = RScurrent->width;
  850.     rect.top = t * RScurrent->fheight;
  851.     rect.bottom = (b + 1) * RScurrent->fheight;
  852.   /* adjust the update region to track the scrolled window contents */
  853.     OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn,
  854.         0, RScurrent->fheight * n);
  855.     ScrollRect(&rect, 0, RScurrent->fheight * n, RSuRgn);
  856.     InvalRgn(RSuRgn);
  857.   /* newly-inserted area is already blank -- validate it to avoid redrawing. */
  858.   /* any necessary redrawing will be done by caller */
  859.     SetRect(&rect, 0, t * RScurrent->fheight - 1,
  860.         RScurrent->width, (t + n) * RScurrent->fheight + 1);
  861.     ValidRect(&rect);
  862.   } /* RSinslines */
  863.  
  864. void RSinscols
  865.   (
  866.     short w,
  867.     short n /* number of columns to insert */
  868.   )
  869.   /* inserts blank columns at the left side of the text display in
  870.     the specified window, scrolling its current contents to the right.
  871.     Maintains the selection highlight, but doesn't move the selection.
  872.     Doesn't even unhighlight text which moves out of the selection area. */
  873.   {
  874.     Rect rect;
  875.  
  876.     if (RSlocal[w].skip)
  877.         return;
  878.     RSsetwind(w);
  879.     SetRect /* bounds of entire text area */
  880.       (
  881.         &rect,
  882.         0,
  883.         0,
  884.         RScurrent->width,
  885.         RScurrent->height
  886.       );
  887.     ScrollRect(&rect, n * RScurrent->fwidth, 0, RSuRgn);
  888.     InvalRgn(RSuRgn);
  889.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  890.     SetRect /* bounds of newly-inserted blank area */
  891.       (
  892.         &rect,
  893.         0,
  894.         0,
  895.         (n + 1) * RScurrent->fwidth - 1,
  896.         RScurrent->height
  897.       );
  898.     if (RScurrent->selected)
  899.       /* highlight any part of the selection in the newly-blanked area */
  900.         RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect);
  901.   } /* RSinscols */
  902.  
  903. void RSinsstring
  904.   (
  905.     short w, /* affected window */
  906.     short x, /* starting column at which to insert */
  907.     short y, /* line on which to insert */
  908.     short a, /* attributes for inserted text */
  909.     short len, /* length of inserted text */
  910.     char *ptr /* pointer to inserted text */
  911.   )
  912.   /* inserts a string of characters at the specified position, scrolling
  913.     the rest of the line to the right. Highlights any part of the newly-
  914.     inserted text lying within the current selection. */
  915.   {
  916.     Rect rect;
  917.  
  918.     if (RSlocal[w].skip)
  919.         return;
  920.     RSsetwind(w);
  921.     SetRect /* bounds of part of line from specified position to end of line */
  922.       (
  923.         &rect,
  924.         x * RScurrent->fwidth,
  925.         y * RScurrent->fheight,
  926.         RScurrent->width,
  927.         (y + 1) * RScurrent->fheight
  928.       );
  929.     ScrollRect(&rect, len * RScurrent->fwidth, 0, RSuRgn); /* scroll remainder of line to the right */
  930.     if (RSa != a)
  931.         RSsetattr(a);
  932.     InvalRgn(RSuRgn);
  933.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  934.     SetRect /* bounds area to contain inserted string */
  935.       (
  936.         &rect,
  937.         x * RScurrent->fwidth,
  938.         y * RScurrent->fheight,
  939.         (x + len) * RScurrent->fwidth,
  940.         (y + 1) * RScurrent->fheight
  941.       );
  942.     EraseRect(&rect); /* erase area to appropriate background */
  943.     MoveTo
  944.       (
  945.         x * RScurrent->fwidth,
  946.         y * RScurrent->fheight + RScurrent->fascent
  947.       );
  948.     DrawText(ptr, 0, len);
  949.     if (RScurrent->selected)
  950.       /* highlight any part of selection covering the newly-inserted text */
  951.         RSinvText(w, *(Point *) &RScurrent->anchor,
  952.             *(Point *) &RScurrent->last, &rect);
  953.   } /* RSinsstring */
  954.  
  955. void RSsendstring
  956.   (
  957.     short w, /* which terminal window */
  958.     char *ptr, /* pointer to data */
  959.     short len /* length of data */
  960.   )
  961.   /* sends some data to the host along the connection associated
  962.     with the specified window. */
  963.   {
  964. #ifdef NCSA_TELNET
  965.     short temp;
  966.  
  967.     temp = findbyVS(w);
  968.     if (temp < 0)
  969.         return;
  970. /*    if (!screens[scrn].lmflag)    */
  971.         netwrite(screens[temp].port, ptr, len);
  972.         netpush(screens[temp].port);                /* BYU 2.4.18 - for Diab systems? */
  973. /*    else 
  974.         {
  975.         sprintf(screens[scrn].kbbuf,"%s",ptr);
  976.         screens[scrn].kblen += len;
  977.         if (screens[scrn].echo) parse(&screens[scrn],ptr,len);
  978.         }*/
  979.         
  980. #else
  981.     while (len--)
  982.         putu(*ptr++);
  983. #endif
  984.   } /* RSsendstring */
  985.  
  986. void RSmargininfo
  987.   (
  988.     short w,
  989.     short total, /* number of invisible character positions (screen width less visible width) */
  990.     short current /* leftmost visible character position */
  991.   )
  992.   /* updates the horizontal scroll bar and associated variables
  993.     to reflect the current view of the virtual screen within the
  994.     specified window. */
  995.   {
  996.     RSlocal[w].leftmarg = current;            /* Adjust local vars */
  997.     if (RSlocal[w].lcurrent != current)
  998.         SetCtlValue(RSlocal[w].left, (RSlocal[w].lcurrent = current));
  999.     if (RSlocal[w].lmax != total)
  1000.         SetCtlMax(RSlocal[w].left, (RSlocal[w].lmax = total));
  1001.   } /* RSmargininfo */
  1002.  
  1003. void RSbufinfo
  1004.   (
  1005.     short w, /* affected window */
  1006.     short total, /* number of lines of scrollback */
  1007.     short current, /* current topmost visible line */
  1008.     short bottom /* current bottommost visible line */
  1009.   )
  1010.   /* readjusts the vertical scroll bar and associated variables
  1011.     to reflect the current view of the virtual screen within the
  1012.     specified window. */
  1013.   {
  1014.     RSdata *RSthis;
  1015.     short newmax;
  1016.  
  1017.     RSthis = RSlocal + w;
  1018.     RSthis->topline = current;            /* Adjust local vars */
  1019.     if (RSthis->min != -total)
  1020.       {
  1021.         SetCtlMin(RSthis->scroll, (RSthis->min = -total));
  1022.         SetCtlValue(RSthis->scroll, (RSthis->current = current));
  1023.       } /* if */
  1024.  
  1025.     if (RSthis->current != current)
  1026.         SetCtlValue(RSthis->scroll, (RSthis->current = current));
  1027.     newmax = (VSgetlines(w) - 1) - (bottom - current);
  1028.     if (RSthis->max != newmax)
  1029.       {
  1030.         SetCtlMax(RSthis->scroll, (RSthis->max = newmax));
  1031.         SetCtlValue(RSthis->scroll, (RSthis->current = current));
  1032.       } /* if */
  1033.  
  1034.   } /* RSbufinfo */
  1035.  
  1036. GrafPtr RSgetwindow
  1037.   (
  1038.     short w
  1039.   )
  1040.   /* returns a pointer to the Mac window structure for the
  1041.     specified terminal window. */
  1042.   {
  1043.     return(RSlocal[w].window);
  1044.   } /* RSgetwindow */
  1045.  
  1046. void RSattach
  1047.   (
  1048.     short w,
  1049.     GrafPtr wind
  1050.   )
  1051.   /* attaches the specified window to a virtual screen, for
  1052.     use for displaying that screen. */
  1053.   {
  1054.     RSlocal[w].window = wind;
  1055.     RSlocal[w].selected = 0;
  1056.     RScurrent->cursorstate = 0;    /* BYU 2.4.11 - cursor off */
  1057.     SetPort(wind);
  1058. #if 1                                /* BYU */
  1059.     RSTextFont(FONT,FSIZE,0);            /* BYU */
  1060. #else
  1061.     TextFont(FONT);
  1062. #endif
  1063.     TextSize(FSIZE);
  1064.     if (!RScolor)
  1065.         TextMode(srcXor);            /* Xor mode*/
  1066.     else
  1067.         TextMode(srcCopy);
  1068.     RSw = -1;    /* make sure we don't write in wrong place */
  1069.   } /* RSattach */
  1070.  
  1071. void RSdetach
  1072.   (
  1073.     short w
  1074.   )
  1075.   /* detaches the window for the specified virtual screen. */
  1076.   {
  1077.     RSlocal[w].window = 0L;
  1078.     RSw = -1;    /* make sure we don't write in wrong place */
  1079.   } /* RSdetach */
  1080.  
  1081. short RSfindvwind
  1082.   (
  1083.     GrafPtr wind
  1084.   )
  1085.   /* returns the number of the virtual screen associated with
  1086.     the specified window, or -4 if not found. */
  1087.   {
  1088.     short
  1089.         i = 0;
  1090.     while ((RSlocal[i].window != wind) && (i < MaxRS))
  1091.         i++;
  1092.     if ((RSlocal[i].window == 0L) || (i >= MaxRS))
  1093.         return(-4);
  1094.     else
  1095.         return(i);
  1096.   } /* RSfindvwind */
  1097.  
  1098. short RSfindscroll                /* Find screen index by control*/
  1099.   (
  1100.     ControlHandle control,
  1101.     short *n
  1102.   )
  1103.   /* finds the window to which the given scroll bar belongs.
  1104.     Returns the window number in *n if found, and a function
  1105.     result of 1 for a vertical scroll bar, 2 for a horizontal
  1106.     one, or -1 if the window wasn't found. */
  1107.   {
  1108.   /* look for a vertical scroll bar */
  1109.     *n = 0;
  1110.     while ((*n < MaxRS) && (control != RSlocal[*n].scroll))
  1111.         (*n)++;
  1112.     if (*n < MaxRS)
  1113.         return (1); /* found it */
  1114.   /* look for a horizontal scroll bar */
  1115.     *n = 0;
  1116.     while ((*n < MaxRS) && (control != RSlocal[*n].left))
  1117.         (*n)++;
  1118.     if (*n < MaxRS)
  1119.         return (2); /* found it */
  1120.     return(-1); /* not found */
  1121.   } /* RSfindscroll */
  1122.  
  1123. void RSregnconv
  1124.   (
  1125.     RgnHandle regn,
  1126.     short *x1, /* left (output) */
  1127.     short *y1, /* top (output) */
  1128.     short *x2, /* right (output) */
  1129.     short *y2, /* bottom (output) */
  1130.     short fh, /* font character height */
  1131.     short fw /* font character width */
  1132.   )
  1133.   /* converts the bounding box of the specified QuickDraw region
  1134.     into units of character positions (using the specified character
  1135.     height and width) and returns the results in *x1, *y1, *x2 and *y2. */
  1136.   {
  1137.     HLock((Handle) regn);
  1138.     *y1 = ((*regn)->rgnBBox.top) / fh;
  1139.     *y2 = (((*regn)->rgnBBox.bottom) + fh - 1) / fh;
  1140.     *x1 = ((*regn)->rgnBBox.left) / fw;
  1141.     *x2 = (((*regn)->rgnBBox.right) + fw - 1) / fw;
  1142.     HUnlock((Handle) regn);
  1143.     if (*x1 < 0)
  1144.         *x1 = 0;
  1145.     if (*y1 < 0)
  1146.         *y1 = 0;
  1147.     if (*x2 < 0)
  1148.         *x2 = 0;
  1149.     if (*y2 < 0)
  1150.         *y2 = 0;
  1151. #ifdef WHONEEDSIT
  1152.     if (*x1> VSIw->maxwidth)
  1153.         *x1 = VSIw->maxwidth;
  1154.     if (*x2 > VSIw->maxwidth)
  1155.         *x2 = VSIw->maxwidth;
  1156.     if (*y1 > VSIw->lines)
  1157.         *y1 = VSIw->lines;
  1158.     if (*y2 > VSIw->lines)
  1159.         *y2 = VSIw->lines;
  1160. #endif WHONEEDSIT
  1161.   } /* RSregnconv */
  1162.  
  1163. short RSupdate
  1164.   (
  1165.     GrafPtr wind
  1166.   )
  1167.   /* does updating for the specified window, if it's one of mine.
  1168.     Returns zero iff it is. */
  1169.   {
  1170.     short w, x1, x2, y1, y2;
  1171.  
  1172.     w = RSfindvwind(wind);
  1173.     if (RSsetwind(w) < 0)
  1174.         return(-1); /* not one of mine */
  1175.     BeginUpdate(wind);
  1176.     RSregnconv /* find bounds of text area needing updating */
  1177.       (
  1178.         wind->visRgn,
  1179.         &x1, &y1, &x2, &y2,
  1180.         RScurrent->fheight, RScurrent->fwidth
  1181.       );
  1182.     VSredraw(w, x1, y1, x2, y2); /* draw that text */
  1183.   /* We must reset, less we risk looking UGLY as sin... */
  1184.     BackPat(PATTERN(qd.white));
  1185.     PenPat(PATTERN(qd.black));
  1186.     if (RScolor)
  1187.       {
  1188.         PmForeColor(0);
  1189.         PmBackColor(1);
  1190.       }
  1191.     else
  1192.       {
  1193.         ForeColor((long) RScolors[ RScurrent->color[0]]);        /* normal foreground */
  1194.         BackColor((long) RScolors[ RScurrent->color[1]]);        /* normal Background */
  1195.       } /* if */
  1196.     RSa = -1;
  1197.     PenMode(patOr);
  1198.     DrawGrowIcon(wind);
  1199.     PenMode(patCopy);
  1200.     DrawControls(wind);
  1201.     EndUpdate(wind);
  1202.     return(0);
  1203.   } /* RSupdate */
  1204.  
  1205. #ifdef FASTERCOMMENTED
  1206.  
  1207. RSupdprint(WindowPeek wind)
  1208.   /* debugging routine: displays bounds (in character units) of
  1209.     update region of specified window. */
  1210.   {
  1211.     short x, y, z, w;
  1212.     char tbuf[50];
  1213.  
  1214.     RSregnconv(wind->updateRgn, &x, &y, &z, &w);
  1215. //    sprintf(tbuf, "RSregnconv: %d,%d,%d,%d", x, y, z, w);
  1216. //    putln(tbuf);
  1217.   } /* RSupdprint */
  1218.  
  1219. #endif
  1220.  
  1221. Point getlocalmouse(GrafPtr wind)
  1222.   /* returns the current mouse position in coordinates local
  1223.     to the specified window. Leaves the current grafPort set
  1224.     to that window. */
  1225.   {
  1226.     Point temp;
  1227.  
  1228.     SetPort(wind);
  1229.     GetMouse(&temp);
  1230.     return(temp);
  1231.   } /* getlocalmouse */
  1232.  
  1233. #define    Fwidthhalf    FWidth/2
  1234.  
  1235. Point normalize(Point in, short w)
  1236.   /* converts in from a pixel position in local coordinates to
  1237.     a character cell position within the virtual screen corresponding
  1238.     to the specified window. Constrains the position to lie within
  1239.     the currently-visible region of the screen, autoscrolling the
  1240.     screen if necessary. */
  1241.   {
  1242.  
  1243.     if (in.v <0)
  1244.       {
  1245.         in.v = 0;
  1246.         VSscrolback(w, 1);
  1247.       } /* if */
  1248.     if (in.v > RSlocal[w].height)
  1249.       {
  1250.         in.v = RSlocal[w].height;
  1251.         VSscrolforward(w, 1);
  1252.       } /* if */
  1253.     in.v = in.v / FHeight;
  1254.  
  1255.     if (in.h < 0)
  1256.       {
  1257.         in.h = -1;
  1258.         VSscrolleft(w, 1);
  1259.       } /* if */
  1260.     if (in.h > RSlocal[w].width)
  1261.       {
  1262.         in.h = RSlocal[w].width;
  1263.         VSscrolright(w, 1);
  1264.       } /* if */
  1265.   /* in.h = (in.h + Fwidthhalf) / FWidth - 1; */
  1266.   /* the MPW C 3.0 compiler has a bug in its register allocation */
  1267.   /* which keeps the above line from working. So, replace it with this: */
  1268.     in.h = in.h + Fwidthhalf;
  1269.     in.h = in.h / FWidth - 1;
  1270.   /* note the bug has been fixed in the 3.1 compiler. */
  1271.   /* convert to virtual screen coordinates */
  1272.     in.v += RSlocal[w].topline;
  1273.     in.h += RSlocal[w].leftmarg;
  1274.     return(in);
  1275.   } /* normalize */
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.  
  1282.  
  1283.  
  1284.  
  1285. /*--------------------------------------------------------------------------*/
  1286. /* HandleDoubleClick                                                        */
  1287. /* This is the routine that does the real dirty work.  Since it is not a    */
  1288. /* true TextEdit window, we have to kinda "fake" the double clicking.  By    */
  1289. /* this time, we already know that a double click has taken place, so check    */
  1290. /* the chars to the left and right of our location, and select all chars     */
  1291. /* that are appropriate    -- SMB                                                */
  1292. /*--------------------------------------------------------------------------*/
  1293. void HandleDoubleClick(short w)                                                    
  1294. {                                                                                
  1295.     Point    leftLoc, rightLoc, curr, oldcurr;                                                    
  1296.     long    mySize;                                                            
  1297.     char    theChar[5];                                                            
  1298.     short    mode = -1, newmode, foundEnd=0;                                                            
  1299.                                                                                 
  1300.     RSsetConst(w);                                                                /* get window dims */                            
  1301.     leftLoc = RSlocal[w].anchor;                                    /* these two should be the same */                            
  1302.     rightLoc = RSlocal[w].last;                                    
  1303.                                                                                 
  1304.     while(!foundEnd)                                                            /* scan to the right first */                                                        
  1305.         {                                                                        
  1306.         mySize = VSgettext(w,rightLoc.h, rightLoc.v, rightLoc.h+1, rightLoc.v,    
  1307.             (char *)theChar,(long)1,"\015",0);                                    
  1308.         if(mySize ==0 || isspace(*theChar))                                    /* stop if not a letter */            
  1309.             foundEnd =1;                                                        
  1310.         else rightLoc.h++;                                                        
  1311.         }                                                                        
  1312.                                                                                 
  1313.     foundEnd =0;                                                                
  1314.     while(!foundEnd)                                                            /* ...and then scan to the left */                                                            
  1315.         {                                                                        
  1316.         mySize = VSgettext(w,leftLoc.h-1, leftLoc.v, leftLoc.h, leftLoc.v,        
  1317.             (char *)theChar,(long)1,"\015",0);                                    
  1318.         if(mySize ==0 || isspace(*theChar))                                        /* STOP! */        
  1319.             foundEnd =1;                                                        
  1320.         else leftLoc.h--;                                                        
  1321.         }                                                                        
  1322.                                                                                 
  1323.     if (leftLoc.h != rightLoc.h)                                                /* we selected something */                            
  1324.         {                                                                        
  1325.         RSlocal[w].anchor = leftLoc;                                    /* new left bound */
  1326.         RSlocal[w].last = rightLoc;                                    /* and a matching new right bound */
  1327.         RSlocal[w].selected =1;                                                    /* give me credit for the selection I just made */
  1328.         RSinvText(w, RSlocal[w].anchor,                                /* time to show it off */
  1329.             RSlocal[w].last, &noConst);
  1330.  
  1331.         curr.h = 0; curr.v = 0;
  1332.  
  1333.         while (StillDown()) {
  1334.           /* wait for mouse position to change */
  1335.             do {
  1336.                 oldcurr = curr;
  1337.                 curr = normalize(getlocalmouse(RSlocal[w].window), w);
  1338.                 } while (EqualPt(curr, oldcurr) && StillDown());
  1339.     
  1340.             
  1341.             if ((curr.v < leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h < leftLoc.h))) {
  1342.                 newmode = 1;    // up
  1343.                 }
  1344.             else if ((curr.v > leftLoc.v) || ((curr.v == leftLoc.v) && (curr.h > rightLoc.h))) {
  1345.                 newmode = 2;    // down
  1346.                 }
  1347.             else 
  1348.                 newmode = -1;    // inside dbl-clicked word
  1349.                 
  1350.             /* toggle highlight state of text between current and last mouse positions */
  1351.             if (mode == -1) {
  1352.                 if (newmode == 2) {
  1353.                     RSlocal[w].anchor = leftLoc;
  1354.                     RSinvText(w, curr, rightLoc, &noConst);
  1355.                     RSlocal[w].last = curr;
  1356.                     }
  1357.                 if (newmode == 1) {
  1358.                     RSlocal[w].anchor = rightLoc;
  1359.                     RSinvText(w, curr, leftLoc, &noConst);
  1360.                     RSlocal[w].last = curr;
  1361.                     }
  1362.                 }
  1363.  
  1364.             if (mode == 1) {
  1365.                 if (newmode == 2) {
  1366.                     RSlocal[w].anchor = leftLoc;
  1367.                     RSinvText(w, oldcurr, leftLoc, &noConst);
  1368.                     RSinvText(w, rightLoc, curr, &noConst);
  1369.                     RSlocal[w].last = curr;
  1370.                     }
  1371.                 if (newmode == -1) {
  1372.                     RSlocal[w].anchor = leftLoc;
  1373.                     RSinvText(w, oldcurr, leftLoc, &noConst);
  1374.                     RSlocal[w].last = rightLoc;
  1375.                     }
  1376.                 if (newmode == mode) {
  1377.                     RSinvText(w, oldcurr, curr, &noConst);
  1378.                     RSlocal[w].last = curr;
  1379.                     }
  1380.                 }
  1381.             
  1382.             if (mode == 2) {
  1383.                 if (newmode == 1) {
  1384.                     RSlocal[w].anchor = rightLoc;
  1385.                     RSinvText(w, oldcurr, rightLoc, &noConst);
  1386.                     RSinvText(w, leftLoc, curr, &noConst);
  1387.                     RSlocal[w].last = curr;
  1388.                     }
  1389.                 if (newmode == -1) {
  1390.                     RSlocal[w].anchor = leftLoc;
  1391.                     RSinvText(w, oldcurr, rightLoc, &noConst);
  1392.                     RSlocal[w].last = rightLoc;
  1393.                     }
  1394.                 if (newmode == mode) {
  1395.                     RSinvText(w, oldcurr, curr, &noConst);
  1396.                     RSlocal[w].last = curr;
  1397.                     }
  1398.                 }
  1399.                 
  1400.             mode = newmode;
  1401.             } /* while */
  1402.         }    
  1403. }
  1404.     
  1405.  
  1406. void    RSsortAnchors(short w)
  1407. {
  1408.     Point    temp;
  1409.     
  1410.     if (RSlocal[w].anchor.v > RSlocal[w].last.v) {
  1411.         temp = RSlocal[w].anchor;
  1412.         RSlocal[w].anchor = RSlocal[w].last;
  1413.         RSlocal[w].last = temp;
  1414.         }
  1415.         
  1416.     if ((RSlocal[w].anchor.v == RSlocal[w].last.v) && (RSlocal[w].anchor.h > RSlocal[w].last.h)) {
  1417.         temp = RSlocal[w].anchor;
  1418.         RSlocal[w].anchor = RSlocal[w].last;
  1419.         RSlocal[w].last = temp;
  1420.         }
  1421. }    
  1422.  
  1423. /*------------------------------------------------------------------------------*/
  1424. /* RSselect                                                                        */
  1425. /* Handle the mouse down in the session window.  All we know so far is that it    */
  1426. /* is somewhere in the content window, and it is NOT an option - click.            */
  1427. /* Double clicking now works -- SMB                                                */
  1428. // And I fixed it so it works correctly.  Grrrr... - JMB
  1429. //    WARNING: Make sure RSlocal[w].selected is 1 when doing selections.  If it is
  1430. //        zero, the autoscrolling routines will seriously hose the selection drawing.
  1431. //        Heed this advice, it took me two hours to find the cause of this bug! - JMB
  1432.  
  1433.   /* called on a mouse-down in the text display area of the
  1434.     active window. Creates or extends the highlighted selection
  1435.     within that window, autoscrolling as appropriate if the user
  1436.     drags outside the currently visible part of the display. */
  1437. void RSselect( short w, Point pt, EventRecord theEvent)
  1438. {
  1439.     static    long     lastClick = 0;
  1440.     static     Point     lastClickLoc = {0,0};
  1441.     GrafPtr tempwndo;
  1442.     Point    curr, temp;
  1443.     long    clickTime;
  1444.     short    shift = (theEvent.modifiers & shiftKey);
  1445.     
  1446.     RSsetConst(w);
  1447.     tempwndo = RSlocal[w].window;
  1448.     
  1449.     curr = normalize(pt, w);
  1450.     clickTime = TickCount();
  1451.     
  1452.     if  ( ( EqualPt(RSlocal[w].anchor, curr) || EqualPt(RSlocal[w].anchor, RSlocal[w].last) )
  1453.             &&  ((clickTime - lastClick) <= GetDblTime())
  1454.             && EqualPt(curr, lastClickLoc)) {
  1455.         /* NCSA: SB - check to see if this is a special click */
  1456.         /* NCSA: SB - It has to be in the right time interval, and in the same spot */
  1457.         curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w);
  1458.         HandleDoubleClick(w);
  1459.         RSlocal[w].selected = 1;
  1460.         lastClick = clickTime;
  1461.         lastClickLoc = curr;
  1462.         }
  1463.     else {
  1464.         lastClick = clickTime;
  1465.         lastClickLoc = curr;
  1466.         if (RSlocal[w].selected) {
  1467.             if (!shift) {
  1468.               /* unhighlight current selection */
  1469.                 RSinvText(w, RSlocal[ w].anchor, RSlocal[w].last, &noConst);
  1470.               /* start new selection */
  1471.                 curr = RSlocal[w].last = RSlocal[w].anchor = normalize(pt, w);
  1472.             }
  1473.             else {
  1474.                 RSsortAnchors(w);
  1475.                 if ((curr.v < RSlocal[w].anchor.v) || ((curr.v == RSlocal[w].anchor.v) && (curr.h < RSlocal[w].anchor.h))) {
  1476.                     temp = RSlocal[w].anchor;
  1477.                     RSlocal[w].anchor = RSlocal[w].last;
  1478.                     RSlocal[w].last = temp;
  1479.                     }
  1480.                 }
  1481.           }
  1482.         else
  1483.           {
  1484.           /* start new selection */
  1485.             curr = RSlocal[w].anchor = RSlocal[w].last = normalize(pt, w);
  1486.             RSlocal[w].selected = 1;
  1487.             }
  1488.             
  1489.         while (StillDown())
  1490.           {
  1491.           /* wait for mouse position to change */
  1492.             do {
  1493.                 curr = normalize(getlocalmouse(tempwndo), w);
  1494.                 } while (EqualPt(curr, RSlocal[w].last) && StillDown());
  1495.     
  1496.           /* toggle highlight state of text between current and last mouse positions */
  1497.             RSinvText(w, curr, RSlocal[w].last, &noConst);
  1498.             RSlocal[w].last = curr;
  1499.           } /* while */
  1500.         }
  1501.  
  1502.     
  1503.     if (EqualPt(RSlocal[w].anchor, RSlocal[w].last)) RSlocal[w].selected = 0;
  1504.         else RSlocal[w].selected = 1;
  1505.     SetMenusForSelection((short)RSlocal[w].selected);
  1506.   } /* RSselect */
  1507.  
  1508. void RSactivate
  1509.   (
  1510.     short w
  1511.   )
  1512.   /* handles an activate event for the specified window. */
  1513.   {
  1514.     RSsetConst(w);
  1515.   /* display the grow icon */
  1516.     DrawGrowIcon(RSlocal[w].window);
  1517.   /* and activate the scroll bars */
  1518.     if (RSlocal[w].scroll != 0L)
  1519.         HiliteControl(RSlocal[w].scroll, 0);
  1520.     if (RSlocal[w].left != 0L)
  1521.         HiliteControl(RSlocal[w].left, 0);
  1522.   } /* RSactivate */
  1523.  
  1524. void RSdeactivate
  1525.   (
  1526.     short w
  1527.   )
  1528.   /* handles a deactivate event for the specified window. */
  1529.   {
  1530.     RSsetConst(w);
  1531.   /* update the appearance of the grow icon */
  1532.     DrawGrowIcon(RSlocal[w].window); 
  1533.   /* and deactivate the scroll bars */
  1534.     if (RSlocal[w].scroll != 0L)
  1535.         HiliteControl(RSlocal[w].scroll, 255);
  1536.     if (RSlocal[w].left != 0L)
  1537.         HiliteControl(RSlocal[w].left, 255);
  1538.   } /* RSdeactivate */
  1539.  
  1540. char **RSGetTextSel
  1541.   (
  1542.     short w, /* window to look at */
  1543.     short table /* nonzero for "table" mode, i e
  1544.         replace this many (or more) spaces with a single tab. */
  1545.   )
  1546.   /* returns the contents of the current selection as a handle,
  1547.     or nil if there is no selection. */
  1548.   {
  1549.     char **charh, *charp;
  1550.     short maxwid;
  1551.     long realsiz;
  1552.     Point Anchor,Last;
  1553.  
  1554.     if (!RSlocal[w].selected)
  1555.         return(0L);    /* No Selection */
  1556.     maxwid = VSmaxwidth(w);
  1557.     Anchor = RSlocal[w].anchor;
  1558.     Last = RSlocal[w].last;
  1559.     
  1560.     realsiz = Anchor.v - Last.v;
  1561.     if (realsiz < 0)
  1562.         realsiz = - realsiz;
  1563.     realsiz ++;                                /* lines 2,3 selected can be 2 lines */
  1564.     realsiz *= (maxwid + 2);
  1565. //    sprintf(tempc, "Size of block=%d", realsiz);
  1566. //    putln(tempc);
  1567.     charh = NewHandle(realsiz);
  1568.     if (charh == 0L)
  1569.         return((char **) -1L);                /* Boo Boo return */
  1570.     HLock(charh);
  1571.     charp = *charh;
  1572.     realsiz = VSgettext(w, Anchor.h, Anchor.v, Last.h, Last.v,
  1573.         charp, realsiz, "\015", table);
  1574. //    putln("unlocking");
  1575.     HUnlock(charh);
  1576.     SetHandleSize(charh, realsiz);
  1577. //    sprintf(tempc, "Size of clip=%d", realsiz);
  1578. //    putln(tempc);
  1579.     return(charh);
  1580.   }  /* RSGetTextSel */
  1581.  
  1582. void    RSsetsize( short w, short v, short h)
  1583. /*    saves the new size settings for a window, and repositions
  1584.     the scroll bars accordingly. */
  1585. {
  1586.     RSlocal[w].height = ((v - 16 + CVO) / FHeight) * FHeight;
  1587.     RSlocal[w].width = ((h - 16 + CHO) / FWidth) * FWidth;
  1588.     RSlocal[w].rheight = v - 16;
  1589.     RSlocal[w].rwidth = h - 16;
  1590.  
  1591. /*
  1592. *  Get rid of the scroll bars which were in the old size.
  1593. *  Hiding them causes the region to be updated later.
  1594. */
  1595.     if (RSlocal[w].scroll != NULL )
  1596.         HideControl(RSlocal[w].scroll);
  1597.     if (RSlocal[w].left != NULL ) 
  1598.         HideControl(RSlocal[w].left);
  1599.  
  1600.     DrawGrowIcon(RSlocal[w].window);            /* Draw in the necessary bugger */
  1601.  
  1602. /*    move the scroll bars to their new positions and sizes, and redisplay them */    
  1603.  
  1604.     if (RSlocal[w].scroll != NULL ) {
  1605.         SizeControl(RSlocal[w].scroll, 16, (v - 13));
  1606.         MoveControl(RSlocal[w].scroll, (h - 15) + CHO, -1 + CVO);
  1607.         ShowControl(RSlocal[w].scroll);
  1608.         }
  1609.     if (RSlocal[w].left != NULL ) {
  1610.         SizeControl(RSlocal[w].left, (h - 13), 16);
  1611.         MoveControl(RSlocal[w].left, -1 + CHO,  (v - 15) + CVO);
  1612.         ShowControl(RSlocal[w].left);
  1613.         }
  1614.         
  1615.     SetRect(&RSlocal[w].textrect, 0, 0, RSlocal[w].rwidth, RSlocal[w].rheight);
  1616.     
  1617. } /* RSsetsize */
  1618.  
  1619. void RSdrawsep
  1620.   (
  1621.     short w,
  1622.     short y1,
  1623.     short draw /* 1 to draw the line, 0 to erase the existing line */
  1624.   )
  1625.   /* draws a dotted line separating the screen contents from the
  1626.     scrollback area. This is currently conditionally compiled to
  1627.     be a no-op. */
  1628.   {
  1629. #ifdef SEPLINE
  1630.     RSsetwind(w);
  1631.     PenPat(gray);
  1632.     if (draw)
  1633.         PenMode(srcCopy);
  1634.     else
  1635.         PenMode(srcXor);
  1636.     MoveTo(0, y1 * RScurrent->fheight);
  1637.     Line(RSlocal[w].width-1, 0);
  1638.     PenMode(srcOr);
  1639.     RSsetattr(0);
  1640. #else
  1641. #pragma unused(w, y1, draw)
  1642. #endif SEPLINE
  1643.   } /* RSdrawsep */
  1644.  
  1645. void RSfontmetrics
  1646.   (
  1647.     void
  1648.   )
  1649.   /* calculates various metrics for drawing text with selected font
  1650.     and size in current grafport into *RScurrent. */
  1651.   {
  1652.     FontInfo finforec;
  1653.     GrafPtr myGP;
  1654.  
  1655.     GetPort(&myGP); 
  1656. #ifdef GOTTHEDOUGH
  1657.     TextFace(bold);            /* NCSA: SB */
  1658. #endif
  1659.     GetFontInfo(&finforec);
  1660.     RScurrent->fascent = finforec.ascent;
  1661.     RScurrent->fheight = finforec.ascent + finforec.descent + finforec.leading /* +1 */;
  1662.     RScurrent->monospaced = (CharWidth('W') == CharWidth('i'));   
  1663. /*    RScurrent->monospaced = (CharWidth('W') == CharWidth('i') == CharWidth(' '));  */
  1664.  
  1665. /*    if (RScurrent->monospaced)    */                        /* NCSA: SB */
  1666.         RScurrent->fwidth = CharWidth('W'); 
  1667. /*    else     
  1668.         RScurrent->fwidth = finforec.widMax; */            /* NCSA: SB */
  1669. #ifdef GOTTHEDOUGH
  1670.     TextFace(myGP->txFace - bold);        /* NCSA: SB */
  1671. #endif
  1672. }
  1673.  
  1674. void RSchangefont
  1675.   (
  1676.     short w,
  1677.     short fnum, /* new font ID or -1 for no change */
  1678.     long fsiz, /* new font size or 0 for no change */
  1679.     short resizwind /* should I resize window to keep same number of visible lines & cols */
  1680.   )
  1681.   {
  1682.     Rect pRect;
  1683.     short x1, x2, y1, y2, width, lines;
  1684.     short srw,srh;
  1685.     WStateData *wstate;
  1686.     WindowPeek wpeek;
  1687.     short resizeWidth, resizeHeight;        /* NCSA: SB */
  1688.  
  1689.     RSsetwind(w);
  1690.     srw = RScurrent->rwidth;
  1691.     srh = RScurrent->rheight;
  1692.  
  1693.     if (fnum != -1)
  1694.       {
  1695. #if 1                                /* BYU */
  1696.         RSTextFont(fnum,fsiz,0);    /* BYU */
  1697. #else
  1698.         TextFont(fnum);
  1699. #endif
  1700.         RScurrent->fnum = fnum;
  1701.       } /* if */
  1702.     if (fsiz)
  1703.       {
  1704.         TextSize(fsiz);
  1705.         RScurrent->fsiz = fsiz;
  1706.       } /* if */
  1707.     RSfontmetrics();
  1708.  
  1709.     width = VSmaxwidth(w) + 1;
  1710.     lines = VSgetlines(w);
  1711.     if (!resizwind)
  1712.       {
  1713.       /* round window size to new character cell dimensions */
  1714.         RScurrent->height =
  1715.             ((RScurrent->rheight) / RScurrent->fheight) * RScurrent->fheight;
  1716.         RScurrent->width =
  1717.             ((RScurrent->rwidth + CHO) / RScurrent->fwidth ) * RScurrent->fwidth
  1718.                 - CHO;
  1719.       }
  1720.     else
  1721.       {
  1722.       /* resize window to preserve its dimensions in character cell units */
  1723.         VSgetrgn(w, &x1, &y1, &x2, &y2);
  1724.         RScurrent->rwidth =
  1725.             RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO;
  1726.         RScurrent->rheight =
  1727.             RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight;
  1728.       } /* if */
  1729.  
  1730.     if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO)
  1731.           RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO;
  1732.     if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16)
  1733.           RScurrent->rheight = RMAXWINDOWHEIGHT - 16;
  1734.     
  1735.     RScheckmaxwind(&RScurrent->window->portRect,RScurrent->rwidth +16,    /* NCSA: SB */
  1736.         RScurrent->rheight + 16, &resizeWidth, &resizeHeight);            /* NCSA: SB */
  1737.  
  1738.  
  1739.     SizeWindow
  1740.       (
  1741.         RScurrent->window,
  1742.         RScurrent->rwidth + 16, RScurrent->rheight+16,
  1743.         FALSE
  1744.       ); /*  TRUE if done right */
  1745.     RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16);
  1746.  
  1747.     wpeek = (WindowPeek) RScurrent->window;
  1748.  
  1749.     HLock(wpeek->dataHandle);
  1750.     wstate = (WStateData *) *wpeek->dataHandle;
  1751.  
  1752.     BlockMove(&pRect, &wstate->stdState, 8);
  1753.     pRect.right = pRect.left + RMAXWINDOWWIDTH;
  1754.     if (pRect.right > TelInfo->screenRect.right)
  1755.         pRect.right = TelInfo->screenRect.right;
  1756.     pRect.bottom = pRect.top + RMAXWINDOWHEIGHT;
  1757.     BlockMove(&wstate->stdState, &pRect, 8);
  1758.  
  1759.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  1760.     VSsetrgn(w, x1, y1,
  1761.         (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1),
  1762.         (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1));
  1763.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  1764.     
  1765.     DrawGrowIcon(RScurrent->window);
  1766.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */
  1767.     ValidRect(&RScurrent->window->portRect); /* no need to do it again */
  1768.     DrawControls(RScurrent->window);
  1769.   } /* RSchangefont */
  1770.  
  1771. short RSgetfont
  1772.   (
  1773.     short w, /* which window */
  1774.     short *pfnum, /* where to return font ID */
  1775.     short *pfsiz /* where to return font size */
  1776.   )
  1777.   /* returns the current font ID and size setting for the specified window. */
  1778.   {
  1779. /*
  1780. *  Bug fix.  RSsetwind's error conditions are all < 0.  There is a success condition == 1.
  1781. *  TK 12/17/88
  1782. */
  1783.     if (0 > RSsetwind(w))
  1784.         return -1;
  1785.     *pfnum = RScurrent->fnum;
  1786.     *pfsiz = RScurrent->fsiz;
  1787.     return(0);
  1788.   } /* RSgetfont */
  1789.  
  1790. short RSnewwindow
  1791.   (
  1792.     RectPtr wDims, /* window bounds in pixels */
  1793.     short scrollback, /* number of lines to save off top */
  1794.     short width, /* number of characters per text line (80 or 132) */
  1795.     short lines, /* number of text lines */
  1796.     StringPtr name, /* window name */
  1797.     short wrapon, /* autowrap on by default */
  1798.     short fnum, /* ID of font to use initially */
  1799.     short fsiz, /* size of font to use initially */
  1800.     short showit, /* window initially visible or not */
  1801.     short goaway, /* NCSA 2.5 */
  1802.     short forcesave        /* NCSA 2.5: force screen save */
  1803.   )
  1804.   /* creates a virtual screen and a window to display it in. */
  1805.   {
  1806.     GrafPort gp; /* temp port for getting text parameters */
  1807.     short w;
  1808.  
  1809.     Rect        pRect;
  1810.     short        wheight, wwidth;
  1811.     WStateData    *wstate;
  1812.     WindowPeek    wpeek;
  1813.     CTabHandle    RSctab;
  1814.  
  1815.   /* create the virtual screen */
  1816.     w = VSnewscreen(scrollback, (scrollback != 0), /* NCSA 2.5 */
  1817.         width,1, forcesave);    /* NCSA 2.5 */
  1818.     if (w < 0) {        /* problems opening the virtual screen -- tell us about it */
  1819.         return(-1);
  1820.           }
  1821.       
  1822.     RScurrent = RSlocal + w;
  1823.  
  1824.     RScurrent->fnum = fnum;
  1825.     RScurrent->fsiz = fsiz;
  1826.  
  1827.     OpenPort(&gp);
  1828. #if 1                            /* BYU */
  1829.     RSTextFont(fnum,fsiz,0);    /* BYU */
  1830. #else
  1831.     TextFont(fnum);
  1832. #endif
  1833.     TextSize(fsiz);
  1834.     RSfontmetrics();
  1835.     ClosePort(&gp);
  1836.  
  1837.     if ((wDims->right - wDims->left) > RMAXWINDOWWIDTH)
  1838.         wDims->right = wDims->left + RMAXWINDOWWIDTH;
  1839.     if ((wDims->bottom - wDims->top) > RMAXWINDOWHEIGHT)
  1840.         wDims->bottom = wDims->top + RMAXWINDOWHEIGHT;
  1841.     wwidth = wDims->right - wDims->left;
  1842.     wheight = wDims->bottom - wDims->top;
  1843.  
  1844.   /* create the window */
  1845.     if (!RScolor) {
  1846.         RScurrent->window = NewWindow(0L, wDims, name, showit?TRUE:FALSE, 8,    /* BYU LSC */
  1847.             kInFront, goaway ? TRUE:FALSE, (long)w);
  1848.         RScurrent->pal = NULL;
  1849.         if (RScurrent->window == NULL) {
  1850.             VSdetach(w);
  1851.             return(-2);
  1852.             }
  1853.         }
  1854.     else
  1855.       {
  1856.         RScurrent->window = NewCWindow(0L, wDims, name, showit?TRUE:FALSE, (short)8,    /* BYU LSC */
  1857.             kInFront, goaway ? TRUE:FALSE, (long)w);
  1858.                     /* the screen is not there until we can see it..... */
  1859.         if (RScurrent->window == NULL) {
  1860.             VSdetach(w);
  1861.             return(-2);
  1862.             }
  1863.  
  1864.         RSctab = (CTabHandle) NewHandleClear((long) (sizeof(ColorTable) + 4 * sizeof(CSpecArray)));
  1865.         if (RSctab == NULL) {
  1866.             DisposeWindow(RScurrent->window);
  1867.             VSdetach(w);
  1868.             return(-2);
  1869.             }
  1870.         HLock((Handle) RSctab);
  1871.  
  1872.         (*RSctab)->ctSize = 3;        // Number of entries minus 1
  1873.         (*RSctab)->ctFlags = 0;
  1874.         RScurrent->RGBs[0].red  =(*RSctab)->ctTable[0].rgb.red        =     0;
  1875.         RScurrent->RGBs[0].green=(*RSctab)->ctTable[0].rgb.green    =     0;
  1876.         RScurrent->RGBs[0].blue =(*RSctab)->ctTable[0].rgb.blue        =     0;
  1877.         RScurrent->RGBs[1].red  =(*RSctab)->ctTable[1].rgb.red        = 65535;
  1878.         RScurrent->RGBs[1].green=(*RSctab)->ctTable[1].rgb.green    = 65535;
  1879.         RScurrent->RGBs[1].blue =(*RSctab)->ctTable[1].rgb.blue        = 65535;
  1880.         RScurrent->RGBs[2].red  =(*RSctab)->ctTable[2].rgb.red        =     0;
  1881.         RScurrent->RGBs[2].green=(*RSctab)->ctTable[2].rgb.green    = 61183;
  1882.         RScurrent->RGBs[2].blue =(*RSctab)->ctTable[2].rgb.blue        = 11060;
  1883.         RScurrent->RGBs[3].red  =(*RSctab)->ctTable[3].rgb.red        = 61183;
  1884.         RScurrent->RGBs[3].green=(*RSctab)->ctTable[3].rgb.green    =  2079;
  1885.         RScurrent->RGBs[3].blue =(*RSctab)->ctTable[3].rgb.blue        =  4938;
  1886.         (*RSctab)->ctTable[0].value = 0;
  1887.         (*RSctab)->ctTable[1].value = 0;
  1888.         (*RSctab)->ctTable[2].value = 0;
  1889.         (*RSctab)->ctTable[3].value = 0;
  1890.         HUnlock((Handle) RSctab);
  1891.  
  1892.         RScurrent->pal = NewPalette(4, RSctab, pmCourteous, 0);
  1893.         DisposeHandle((Handle) RSctab);
  1894.         if (RScurrent->pal == NULL) {
  1895.             DisposeWindow(RScurrent->window);
  1896.             VSdetach(w);
  1897.             return(-2);
  1898.             }
  1899.  
  1900.         SetPalette(RScurrent->window, RScurrent->pal, TRUE);
  1901.       } /* if */
  1902.  
  1903.     SetPort(RScurrent->window);
  1904.     SetOrigin(CHO, CVO);            /* Cheap way to correct left margin problem */
  1905.  
  1906.     wpeek = (WindowPeek) RScurrent->window;
  1907.  
  1908.     HLock(wpeek->dataHandle);
  1909.     wstate = (WStateData *) *wpeek->dataHandle;
  1910.  
  1911.     BlockMove(&wstate->userState, wDims, 8);
  1912.     pRect.top = wDims->top;
  1913.     pRect.left = wDims->left;
  1914.     pRect.right = pRect.left + RMAXWINDOWWIDTH;
  1915.     if (pRect.right > TelInfo->screenRect.right)
  1916.         pRect.right = TelInfo->screenRect.right;
  1917.  
  1918.     pRect.bottom = pRect.top + RMAXWINDOWHEIGHT;
  1919.     BlockMove(&wstate->stdState, &pRect, 8);
  1920.  
  1921.   /* create scroll bars for window */
  1922.     pRect.top = -1 + CVO;
  1923.     pRect.bottom = wheight - 14 + CVO;
  1924.     pRect.left = wwidth - 15 + CHO;
  1925.     pRect.right = wwidth + CHO;
  1926.     RScurrent->scroll = NewControl(RScurrent->window, &pRect, "\p", FALSE,    /* BYU LSC */
  1927.         0, 0, 0, 16, 1L);
  1928.  
  1929.     if (RScurrent->scroll == 0L) return(-3);
  1930.  
  1931.     pRect.top = wheight - 15 + CVO;
  1932.     pRect.bottom = wheight + CVO;
  1933.     pRect.left = -1 + CHO;
  1934.     pRect.right = wwidth - 14 + CHO;
  1935.     RScurrent->left = NewControl(RScurrent->window, &pRect, "\p", FALSE,        /* BYU LSC */
  1936.         0, 0, 0, 16, 1L);
  1937.  
  1938.     if (RScurrent->left == 0L) return(-3);
  1939.  
  1940.     RScurrent->skip = 0; /* not skipping output initially */
  1941.     RScurrent->max = 0; /* scroll bar settings will be properly initialized by subsequent call to VSsetrgn */
  1942.     RScurrent->min = 0;
  1943.     RScurrent->current = 0;
  1944.     RScurrent->lmax = 0;
  1945.     RScurrent->lmin = 0;
  1946.     RScurrent->lcurrent = 0;
  1947.     RScurrent->selected = 0;    /* no selection initially */
  1948.     RScurrent->cursorstate = 0;    /* BYU 2.4.11 - cursor off initially */
  1949.     RScurrent->flipped = 0;        /* Initially, the color entries are not flipped */
  1950.  
  1951.     RSsetsize(w, wheight, wwidth);
  1952.     VSsetlines(w, lines);
  1953.     VSsetrgn(w, 0, 0, ((wwidth - 16 + CHO) / FWidth -1),
  1954.         ((wheight - 16 + CVO) / FHeight - 1));
  1955.  
  1956. #if 1                                                /* BYU */
  1957.     RSTextFont(RScurrent->fnum,RScurrent->fsiz,0);    /* BYU LSC */
  1958. #else
  1959.     TextFont(RScurrent->fnum);
  1960. #endif
  1961.     TextSize(RScurrent->fsiz);                /* 9 point*/
  1962.     if (!RScolor)
  1963.         TextMode(srcXor);            /* Xor mode*/
  1964.     else
  1965.         TextMode(srcCopy);
  1966.  
  1967.     if (wrapon)
  1968.       /* turn on autowrap */
  1969.         VSwrite(w, "\033[?7h",5);
  1970.  
  1971.     return(w);
  1972.   } /* RSnewwindow */
  1973.  
  1974. void RSkillwindow
  1975.   (
  1976.     short w
  1977.   )
  1978.   /* closes a terminal window. */
  1979.   {
  1980.      RSdata *temp = RSlocal + w;
  1981.  
  1982.      if (temp->pal) {
  1983.          DisposePalette(temp->pal);        
  1984.          temp->pal = NULL;
  1985.         }
  1986.  
  1987.     VSdetach(w);        /* Detach the virtual screen */
  1988.     KillControls(RSlocal[w].window);  /* Get rid of those little slidy things */
  1989.     DisposeWindow(RSlocal[w].window);    /* Get rid of the actual window */
  1990.     RSdetach(w);        /* Detach from the table */
  1991.   }
  1992.  
  1993. void RSzoom
  1994.   (
  1995.     GrafPtr window, /* window to zoom */
  1996.     short code, /* inZoomIn or inZoomOut */
  1997.     short shifted /* bring to front or not */
  1998.   )
  1999.   /* called after a click in the zoom box, to zoom a terminal window. */
  2000.   {
  2001.     WStateData    **WSDhdl;
  2002.     short        w;
  2003.     short        h, v, x1, x2, y1, y2;
  2004.     short        width, lines;            // For setting Standard State before zooming
  2005.     short        top, left;                // Ditto
  2006.     
  2007.     SetPort(window);
  2008.     w = RSfindvwind(window); /* which window is it, anyway */
  2009.  
  2010.     width = VSmaxwidth(w) + 1;
  2011.     lines = VSgetlines(w);
  2012.     WSDhdl = (WStateData **)((WindowPeek)window)->dataHandle;
  2013.     top = (**WSDhdl).userState.top;
  2014.     left = (**WSDhdl).userState.left;
  2015.     HLock((Handle)WSDhdl);
  2016.     SetRect(&((*WSDhdl)->stdState), left, top, RMAXWINDOWWIDTH + left,
  2017.                 RMAXWINDOWHEIGHT + top);
  2018.     HUnlock((Handle)WSDhdl);
  2019.     
  2020.     /* EraseRect(&window->portRect); */
  2021.     ZoomWindow(window, code, shifted);
  2022.     EraseRect(&window->portRect);            /* BYU 2.4.15 */
  2023.  
  2024.   /* get new window size */
  2025.     h = window->portRect.right - window->portRect.left;
  2026.     v = window->portRect.bottom - window->portRect.top;
  2027.  
  2028.     RSsetsize(w, v, h); /* save new size settings and update scroll bars */
  2029.   /* update the visible region of the virtual screen */
  2030.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  2031.     VSsetrgn(w, x1, y1, (x1 + (h - 16 + CHO) / FWidth -1),
  2032.         (y1 + (v - 16 + CVO) / FHeight - 1));
  2033.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  2034.   /* refresh the part which has been revealed, if any */
  2035.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); 
  2036.   /* window contents are now completely valid */
  2037.     ValidRect(&window->portRect);
  2038.   } /* RSzoom */
  2039.  
  2040. /*
  2041. *  This routine is called when the user presses the grow icon, or when the size of
  2042. *  the window needs to be adjusted (where==NULL, modifiers==0).
  2043. *  It limits the size of the window to a legal range.
  2044. */
  2045.  
  2046. void RSsize (GrafPtr window, long *where, long modifiers)
  2047. {
  2048.     Rect    SizRect;
  2049.     long    size;
  2050.     short    w, width, lines;
  2051.     short    tw, h, v, x1, x2, y1, y2, th;
  2052.     Boolean    changeVSSize = false;
  2053.     short    screenIndex = 0;
  2054.     Boolean    screenIndexValid = false;
  2055.  
  2056.     if ((w = RSfindvwind(window)) < 0)
  2057.         return;
  2058.     
  2059.     if (modifiers & cmdKey) return;
  2060.     
  2061.     screenIndexValid = (screenIndex = findbyVS(w)) != -1;
  2062.  
  2063.     changeVSSize = (modifiers & optionKey) == optionKey;
  2064.  
  2065. #define DONT_DEFAULT_CHANGE_VS_IF_NAWS                // JMB
  2066.     // 931112, ragge, NADA, KTH 
  2067.     // I think this is the way it should work, if there is naws available it
  2068.     // should be used by default, and option toggles behaviour.
  2069.     // Maybe it should be user configurable?
  2070. #ifndef DONT_DEFAULT_CHANGE_VS_IF_NAWS
  2071.     if(screenIndexValid && screens[screenIndex].naws) {
  2072.         changeVSSize = (modifiers & optionKey) != optionKey;
  2073.     }
  2074. #endif
  2075.  
  2076.     SetPort(window);
  2077.  
  2078.     width = VSmaxwidth(w) + 1;
  2079.     lines = VSgetlines(w);
  2080.  
  2081.  
  2082.     if (changeVSSize) {
  2083.         th = INFINITY;
  2084.         tw = INFINITY-1;
  2085.         }
  2086.     else {
  2087.         tw = RMAXWINDOWWIDTH;
  2088.         th = RMAXWINDOWHEIGHT + 1;
  2089.         }
  2090.  
  2091.     SetRect(&SizRect, 48, 48, tw + 1, th);
  2092.     
  2093.     if (where)                                            /* grow icon actions */
  2094.         {                            
  2095.         if (changeVSSize) { /* 931112, ragge, NADA, KTH */
  2096.             setupForGrow(window, 1 - CHO, 1 - CVO, FWidth, FHeight);
  2097.         }
  2098.         size = GrowWindow(window, *(Point *) where, &SizRect);    /* BYU LSC */
  2099.         if (changeVSSize) { /* 931112, ragge, NADA, KTH */
  2100.             cleanupForGrow(window);
  2101.         }
  2102.  
  2103.         if (size != 0L)
  2104.           {
  2105.             SizeWindow(window, size & 0xffff, (size >> 16) & 0xffff, FALSE);
  2106.             h = window->portRect.right - window->portRect.left;
  2107.             v = window->portRect.bottom - window->portRect.top;
  2108.           }
  2109.         else return;                            /* user skipped growing */
  2110.       }
  2111.     else
  2112.       {                                    /* just resize the window */
  2113.         h = window->portRect.right - window->portRect.left;    /* same width */
  2114.         v = (FHeight) * (VSgetlines(w));                    /* new height */
  2115.         SizeWindow(window, h, v, FALSE);                    /* change it */
  2116.         }     
  2117.  
  2118.     RSsetsize(w, v, h); /* save new size settings and update scroll bars */
  2119.  
  2120.     
  2121.   /* update the visible region of the virtual screen */
  2122.  
  2123.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  2124.     VSsetrgn(w, x1, y1, (short)((x1 + (h - 16 + CHO) / FWidth - 1)),
  2125.         (short)((y1 + (v - 16) / FHeight - 1)));
  2126.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  2127.  
  2128.     if (changeVSSize) {
  2129.         
  2130.         VSsetlines(w,y2 -y1 +1);
  2131.         RScalcwsize(w,x2 - x1 +1);
  2132.         if (screenIndexValid && screens[screenIndex].naws)
  2133.             SendNAWSinfo(&screens[screenIndex], (x2-x1+1), (y2-y1+1));
  2134.         return;
  2135.         }
  2136.  
  2137.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1);        /* refresh the part which has been revealed, if any */
  2138.     ValidRect(&window->portRect);                        /* window contents are now completely valid */
  2139.   } /* RSsize */
  2140.  
  2141.  
  2142.  
  2143. SIMPLE_UPP(ScrollProc,ControlAction);
  2144. pascal void ScrollProc(ControlHandle control, short part)
  2145.   /* scroll-tracking routine which does continuous scrolling of visible
  2146.      region. */
  2147.   {
  2148.     short w, kind, x1, y2, x2, y1;
  2149.  
  2150.     kind = RSfindscroll(control, &w);
  2151.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  2152.  
  2153.     if (kind == 2)
  2154.       { /* horizontal scroll bar */
  2155.         switch (part)
  2156.           {
  2157.             case inUpButton:                            /* Up is left */
  2158.                 VSscrolleft(w, 1);
  2159.                 break;
  2160.             case inDownButton:                            /* Down is right */
  2161.                 VSscrolright(w, 1);
  2162.                 break;
  2163.             case inPageUp:
  2164.                 VSscrolleft(w, x2 - x1); /* scroll a whole windowful */
  2165.                 break;
  2166.             case inPageDown:
  2167.                 VSscrolright(w, x2 - x1); /* scroll a whole windowful */
  2168.                 break;
  2169.             default:
  2170.                 break;
  2171.           } /* switch */
  2172.       }
  2173.     else if (kind == 1)
  2174.       { /* vertical scroll bar */
  2175.         switch (part)
  2176.           {
  2177.             case inUpButton:
  2178.                 VSscrolback(w, 1);
  2179.                 break;
  2180.             case inDownButton:
  2181.                 VSscrolforward(w, 1);
  2182.                 break;
  2183.             case inPageUp:
  2184.                 VSscrolback(w, y2 - y1); /* scroll a whole windowful */
  2185.                 break;
  2186.             case inPageDown:
  2187.                 VSscrolforward(w, y2 - y1); /* scroll a whole windowful */
  2188.                 break;
  2189.             default:
  2190.                 break;
  2191.           } /* switch */
  2192.       } /* if */
  2193.   } /* ScrollProc */
  2194.  
  2195. /* handles a click in a terminal window. */
  2196. short RSclick( GrafPtr window, EventRecord theEvent)
  2197. {
  2198.     ControlHandle ctrlh;
  2199.     short w, part, part2, x1, x2, y1, y2;
  2200.     Point    where = theEvent.where;
  2201.     short    shifted = (theEvent.modifiers & shiftKey);
  2202.     short    optioned = (theEvent.modifiers & optionKey);
  2203.  
  2204.     w = RSfindvwind(window);
  2205.     if (w < 0)
  2206.         return -1; /* what the heck is going on here?? */
  2207.     SetPort(window);
  2208.     GlobalToLocal((Point *) &where);
  2209.     part = FindControl(where, window, &ctrlh);        /* BYU LSC */
  2210.     if (part != 0)
  2211.         switch (part)
  2212.           {
  2213.             case inThumb:
  2214.                 part2 = TrackControl(ctrlh, where, 0L);        /* BYU LSC */
  2215.                 if (part2 == inThumb)
  2216.                   {
  2217.                     part = GetCtlValue(ctrlh);
  2218.                     if (ctrlh == RSlocal[w].scroll)
  2219.                       {
  2220.                       /* scroll visible region vertically */
  2221.                         VSgetrgn(w, &x1, &y1, &x2, &y2);
  2222.                         VSsetrgn(w, x1, part, x2, part + (y2 - y1));
  2223.                       }
  2224.                     else
  2225.                       { /* ctrlh must be .left */
  2226.                       /* scroll visible region horizontally */
  2227.                         VSgetrgn(w, &x1, &y1, &x2, &y2);
  2228.                         VSsetrgn(w, part, y1, part + (x2 - x1), y2);
  2229.                       } /* if */
  2230.                   } /* if */
  2231.                 break;
  2232.             case inUpButton:
  2233.             case inDownButton:
  2234.             case inPageUp:
  2235.             case inPageDown:
  2236.                 part2 = TrackControl(ctrlh, where, ScrollProcUPP);    /* BYU LSC */
  2237.     /*            InvalRect(&(**RSlocal->scroll).contrlRect); */  /* cheap fix */
  2238.                 break;
  2239.             default:
  2240.                 break;
  2241.           } /* switch */
  2242.     else
  2243.       {
  2244.         if (optioned) 
  2245.           {
  2246.           /* send host the appropriate sequences to move the cursor
  2247.             to the specified position */
  2248.             Point x;
  2249.             x = normalize(where, w);
  2250.             VSpossend(w, x.h, x.v, screens[scrn].echo); /* MAT--we can check here if we want to use normal */
  2251.                                                         /* MAT--or EMACS movement. */
  2252.           }
  2253.         else if (ClickInContent(where,w))            /* NCSA: SB - prevent BUS error */
  2254.             RSselect(w, where, theEvent);            
  2255.       } /* if */
  2256.     return
  2257.         0;
  2258.   } /* RSclick */
  2259.  
  2260. void    RShide( short w)        /* hides a terminal window. */
  2261. {
  2262.     if (RSsetwind(w) < 0)
  2263.         return;
  2264.     
  2265.     HideWindow(RScurrent->window);
  2266. }
  2267.  
  2268. void    RSshow( short w)        /* reveals a hidden terminal window. */
  2269. {
  2270.     if (RSsetwind(w) < 0)
  2271.         return;
  2272.     
  2273.     ShowWindow(RScurrent->window);
  2274. }
  2275.  
  2276.  
  2277. #ifdef NCSA_TELNET
  2278.  
  2279. extern short    NumberOfColorBoxes;
  2280. extern short    BoxColorItems[8];
  2281. extern RGBColor    BoxColorData[8];
  2282.  
  2283. void    RScprompt(short w)
  2284.   /* puts up the dialog that lets the user examine and change the color
  2285.     settings for the specified window. */
  2286. {
  2287.     short        scratchshort, ditem;
  2288.     Point        ColorBoxPoint;
  2289.     DialogPtr    dptr;
  2290.     Boolean        UserLikesNewColor;
  2291.     RGBColor    scratchRGBcolor;
  2292.     
  2293.     dptr = GetNewMySmallDialog(ColorDLOG, NULL, kInFront, (void *)ThirdCenterDialog);
  2294.  
  2295.     for (scratchshort = 0, NumberOfColorBoxes = 4; scratchshort < NumberOfColorBoxes; scratchshort++) {
  2296.         BoxColorItems[scratchshort] = ColorNF + scratchshort;
  2297.         BlockMove(&(RSlocal[w].RGBs[scratchshort]),
  2298.             &BoxColorData[scratchshort], sizeof(RGBColor));
  2299.         UItemAssign( dptr, ColorNF + scratchshort, ColorBoxItemProcUPP);
  2300.         }
  2301.         
  2302.     ColorBoxPoint.h = 0;            // Have the color picker center the box on the main
  2303.     ColorBoxPoint.v = 0;            // screen
  2304.     
  2305.     ditem = 3;    
  2306.     while (ditem > 2) {
  2307.         ModalDialog(ColorBoxModalProcUPP, &ditem);
  2308.         switch (ditem) {
  2309.             case    ColorNF:    
  2310.             case    ColorNB:    
  2311.             case    ColorBF:    
  2312.             case    ColorBB:    
  2313.                 if (theWorld.hasColorQD) {
  2314.                     UserLikesNewColor = GetColor(ColorBoxPoint, "\pPlease Select New Color",
  2315.                          &BoxColorData[ditem-ColorNF], &scratchRGBcolor);
  2316.                     if (UserLikesNewColor)
  2317.                         BoxColorData[ditem-ColorNF] = scratchRGBcolor;
  2318.                     }
  2319.                 break;
  2320.                 
  2321.             default:
  2322.                 break;
  2323.             
  2324.             } // switch
  2325.         } // while
  2326.  
  2327.     if (ditem == DLOGCancel) {
  2328.         DisposeDialog(dptr);
  2329.         return;
  2330.         }
  2331.         
  2332.     for (scratchshort = 0; scratchshort < NumberOfColorBoxes; scratchshort++) {
  2333.             BlockMove(&BoxColorData[scratchshort], 
  2334.                 &(RSlocal[w].RGBs[scratchshort]), sizeof(RGBColor));
  2335.         }
  2336.     
  2337.     /* force redrawing of entire window contents */
  2338.     SetPort(RSlocal[w].window);
  2339.     InvalRect(&RSlocal[w].window->portRect);
  2340.  
  2341.     for (scratchshort = 0; scratchshort < 6; scratchshort++)
  2342.         SetEntryColor(RSlocal[w].pal, scratchshort, &RSlocal[w].RGBs[scratchshort]);
  2343.  
  2344.     DisposeDialog(dptr);
  2345. } /* RScprompt */
  2346.  
  2347. short RSsetcolor
  2348.   (
  2349.     short w, /* window number */
  2350.     short n, /* color entry number */
  2351.     unsigned short r, /* components of new color */
  2352.     unsigned short g,
  2353.     unsigned short b
  2354.   )
  2355.   /* sets a new value for the specified color entry of a terminal window. */
  2356.   {
  2357.     if ( !theWorld.hasColorQD || (RSsetwind(w) < 0))        /* BYU */
  2358.         return(-1);
  2359.     RScurrent->RGBs[n].red = r;
  2360.     RScurrent->RGBs[n].green = g;
  2361.     RScurrent->RGBs[n].blue = b;
  2362.     if (RScolor)
  2363.       {
  2364.       /* only take account of the color settings on a color-capable machine */
  2365.         SetEntryColor(RScurrent->pal, n, &RScurrent->RGBs[n]);
  2366.         SetPort(RScurrent->window);
  2367.         InvalRect(&RScurrent->window->portRect);
  2368.       } /* if */
  2369.     return(0);
  2370.   } /* RSsetcolor */
  2371.  
  2372. Boolean NewRSsetcolor
  2373.     (
  2374.     short w, /* window number */
  2375.     short n, /* color entry number */
  2376.     RGBColor    Color
  2377.     )
  2378.   /* sets a new value for the specified color entry of a terminal window. */
  2379.   {
  2380.     if ( !theWorld.hasColorQD || (RSsetwind(w) < 0) || (n > 5) || (n < 0))
  2381.         return(-1);
  2382.     RScurrent->RGBs[n] = Color;
  2383.  
  2384.     if (RScolor) {
  2385.       /* only take account of the color settings on a color-capable machine */
  2386.         SetEntryColor(RScurrent->pal, n, &RScurrent->RGBs[n]);
  2387.         SetPort(RScurrent->window);
  2388.         InvalRect(&RScurrent->window->portRect);
  2389.       } /* if */
  2390.     return(0);
  2391.   } /* RSsetcolor */
  2392.  
  2393. void RSgetcolor
  2394.   (
  2395.     short w, /* window number */
  2396.     short n, /* color entry number */
  2397.     unsigned short *r, /* where to return components of color */
  2398.     unsigned short *g,
  2399.     unsigned short *b
  2400.   )
  2401.   /* gets the current value for the specified color entry of a terminal window. */
  2402.   {
  2403.     *r = RSlocal[w].RGBs[n].red;
  2404.     *g = RSlocal[w].RGBs[n].green;
  2405.     *b = RSlocal[w].RGBs[n].blue;
  2406.   } /* RSgetcolor */
  2407.  
  2408. short RSmouseintext                /* Point is in global coords */
  2409.   (
  2410.     short w,
  2411.     Point myPoint
  2412.   )
  2413.   /* is myPoint within the text-display area of the specified window. */
  2414.   {
  2415.     return
  2416.         PtInRect(myPoint, &RSlocal[w].textrect);     /* BYU LSC */
  2417.   } /* RSmouseintext */
  2418.  
  2419. void RSskip
  2420.   (
  2421.     short w,
  2422.     Boolean on
  2423.   )
  2424.   /* sets the "skip" flag for the specified window (whether ignore
  2425.     screen updates until further notice). */
  2426.   {
  2427.     RSlocal[w].skip = on;
  2428.   } /* RSskip */
  2429.  
  2430. /**********************************************************************************/
  2431. /*  Make sure at least this much memory is available before allocating more memory
  2432. *   for me.  Returns true or false whether that much is available.
  2433. */
  2434. short RSokmem
  2435.   (
  2436.     short amount
  2437.   )
  2438.   {
  2439.     char *p;
  2440.     
  2441.     if (NULL == (p = NewPtr(amount)))
  2442.         return(0);
  2443.     DisposPtr(p);
  2444.     return(1);
  2445.   } /* RSokmem */
  2446.  
  2447. /*------------------------------------------------------------------------------*/
  2448. /* NCSA: SB - RScalcwsize                                                         */
  2449. /*         This routine is used to switch between 80 and 132 column mode. All that    */    
  2450. /*         is passed in is the RS window, and the new width.  This calculates the    */    
  2451. /*         new window width, resizes the window, and updates everything.  - SMB    */
  2452. /*------------------------------------------------------------------------------*/
  2453. void RScalcwsize(short w, short width)
  2454. {
  2455.     short x1,x2,y1,y2;
  2456.     short lines;
  2457.     
  2458.     RSsetwind(w);
  2459.     VSsetcols(w,(short)(width-1));
  2460.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  2461.     x2= width-1;
  2462.     
  2463.     lines = VSgetlines(w);                /* NCSA: SB - trust me, you need this... */
  2464.     RScurrent->rwidth =
  2465.         RScurrent->width = (x2 - x1 + 1) * RScurrent->fwidth - CHO;
  2466.     RScurrent->rheight =
  2467.         RScurrent->height= (y2 - y1 + 1) * RScurrent->fheight; 
  2468.  
  2469.  
  2470.     if (RScurrent->rwidth > RMAXWINDOWWIDTH - 16 - CHO)
  2471.           RScurrent->rwidth = RMAXWINDOWWIDTH - 16 - CHO;
  2472.     if (RScurrent->rheight > RMAXWINDOWHEIGHT - 16)
  2473.           RScurrent->rheight = RMAXWINDOWHEIGHT - 16;
  2474.     
  2475.     SizeWindow
  2476.       (
  2477.         RScurrent->window,
  2478.         RScurrent->rwidth + 16, RScurrent->rheight+16,
  2479.         FALSE
  2480.       ); 
  2481.     RSsetsize(w, RScurrent->rheight + 16, RScurrent->rwidth + 16);
  2482.     VSgetrgn(w, &x1, &y1, &x2, &y2);
  2483.     VSsetrgn(w, x1, y1,
  2484.         (short) (x1 + (RScurrent->rwidth ) / RScurrent->fwidth - 1),
  2485.         (short) (y1 + (RScurrent->rheight) / RScurrent->fheight - 1));
  2486.     VSgetrgn(w, &x1, &y1, &x2, &y2);        /* Get new region */
  2487.     
  2488.     DrawGrowIcon(RScurrent->window);
  2489.     VSredraw(w, 0, 0, x2 - x1 + 1, y2 - y1 + 1); /* redraw newly-revealed area, if any */
  2490.     ValidRect(&RScurrent->window->portRect); /* no need to do it again */
  2491.     DrawControls(RScurrent->window);
  2492. }
  2493.  
  2494.  
  2495. /*--------------------------------------------------------------------------*/
  2496. /* NCSA: SB - RSbackground                                                    */
  2497. /*    This procedure allows Telnet to switch from dark background to light    */
  2498. /*    background.  Save the current state into the RSdata struct, so that        */
  2499. /*     we know our background state next time we want to do anything.            */
  2500. /*    Make sure the screen contents (and palette) is updated NOW.                */
  2501. /*--------------------------------------------------------------------------*/
  2502. void RSbackground(short w, short value)
  2503. {
  2504.     RGBColor temp;
  2505.     short x;
  2506.     
  2507.     RSsetwind(w);
  2508.     if ((value && !RSlocal[w].flipped) || (!value && RSlocal[w].flipped))
  2509.         {    
  2510.         RSlocal[w].flipped = !RSlocal[w].flipped;
  2511.  
  2512.         temp = RSlocal[w].RGBs[0];
  2513.         RSlocal[w].RGBs[0] = RSlocal[w].RGBs[1];
  2514.         RSlocal[w].RGBs[1] = temp;
  2515.         
  2516.         SetPort(RSlocal[w].window);
  2517.         InvalRect(&RSlocal[w].window->portRect);
  2518.     
  2519.         for (x = 0; x < 4; x++)
  2520.             SetEntryColor(RSlocal[w].pal, x, &RSlocal[w].RGBs[x]);
  2521.         }
  2522. }
  2523.  
  2524. void RScheckmaxwind(Rect *origRect,short origW, 
  2525.             short origH, short *endW, short *endH)
  2526. {
  2527.     *endW = origW;
  2528.     *endH = origH;
  2529.     
  2530.     if (origW > (TelInfo->screenRect.right - origRect->left -15 ))
  2531.         *endW = TelInfo->screenRect.right - origRect->left -15;
  2532.  
  2533.     if (origH > (TelInfo->screenRect.bottom - origRect->top -15 ))
  2534.         *endH = TelInfo->screenRect.bottom - origRect->top -15;
  2535. }        
  2536.  
  2537.  
  2538. /*--------------------------------------------------------------------------*/
  2539. /* NCSA: SB - ClickInContent                                                */
  2540. /*    This procedure is a quick check to see if the mouse click is in the        */
  2541. /*    content region of the window.  Normalize the point to be a VS location    */
  2542. /*     and then see if that is larger than what it should be...                */
  2543. /*    Used by RSClick to see if the click is in the scroll bars, or content..    */
  2544. /*--------------------------------------------------------------------------*/
  2545. short ClickInContent(Point where,short w)                /* NCSA: SB */
  2546. {                                                        /* NCSA: SB */
  2547.     Point x;                                            /* NCSA: SB */
  2548.     x = normalize(where, w);                            /* NCSA: SB */
  2549.     if (x.v >= VSgetlines(w)) return 0;                    /* NCSA: SB */
  2550.     else return 1;                                        /* NCSA: SB */
  2551. }                                                        /* NCSA: SB */
  2552.  
  2553. #endif NCSA_TELNET
  2554.