home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / S / SurferPlus / support.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-27  |  29.6 KB  |  1,015 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        support.c
  3.  
  4.     Contains:    supporting routines for surfer
  5.     
  6.     Written by:    Mary Chan
  7.  
  8.     Copyright:    © 1990 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12.  
  13. #pragma     load    <header.dump>
  14. #include    "TMIntf.h"
  15. #include    "globals.h"
  16.  
  17. short                curindex = 0;                    /* index into the cache buffer */
  18. short                curVertValue = 0;                /* current vertical scrollbar value */
  19. short                curHoriValue = 0;                /* current horizontal scrollbar value */
  20. short                maxVCtl = 0;                    /* max vertical scroll    */
  21. short                maxHCtl = 0;                    /* max vertical scroll    */
  22. Rect                visCacheRect = {0,0,0,0};        /* visible cache area */
  23. Point                oldpoint;                        /* old mouse point */
  24. Point                anchorpoint;                    /* selection's anchorpoint */
  25. Point                mycellSize = {0,0};                /* current cellsize */
  26. Point                myslop = {0,0};                    /* current slop area */
  27. short                oldAuxTop = 0;                    /* current top aux area */
  28. short                oldAuxBottom = 0;                /* current bottom aux area */
  29. short                oldAuxLeft = 0;                    /* current left aux area */
  30. short                oldAuxRight = 0;                /* current right aux area */
  31. short                maxcol = 0;                        /* current max column */
  32. short                totalCache = 0;                    /* total number of cache */
  33. short                offset = 0;                        /* circular buffer offset */
  34. short                curindex = 0;                    /* current index into the circular buffer */
  35. TermEnvironRec        termEnvironment;                /* current terminal env */
  36. Boolean                clikWasInTermArea;                /* was mouse click in the terminal area */
  37. Boolean                clikWasInCacheArea;                /* was mouse click in the cache area */
  38. Boolean                firstClickInCache;                /* was the first mouse down/click in the cache area */
  39. Boolean                isActive = false;                /* is the cache selection being inverted or just framed */
  40.  
  41.  
  42. Point        GetCell( Point anchorpoint, Point cellsize);
  43. Point        GetCellPoint( Point anchorpoint, Point cellsize );
  44.  
  45. /*******************************************************************
  46. *    MyClickProc        - handle mouse tracking in the cache area
  47. *
  48. *    refcon            -    term record's reference constant
  49. *
  50. **********************************************************************/
  51. pascal Boolean        MyClickProc( long refcon )
  52. {
  53. #pragma        unused(refcon)
  54.     Boolean        PtInCache = false;
  55.     Point        where;
  56.     short        scrollVamt;
  57.     short        scrollHamt;
  58.     Rect        cliprect;
  59.     
  60.     cliprect = visCacheRect;
  61.     cliprect.bottom -= CACHBOTTOMSLOP;
  62.     ClipRect( &cliprect );                        /* set clipping area to the cache area */
  63.     where = *((Point*)&((**_GTERM).reserved1));    /* get the mouse location set by the tool */
  64.     if ( PtInRect( where, &visCacheRect ) )    
  65.     {
  66.         /* mouse down is in the cache area */
  67.         Cellboundary( &where );                    /* set point at the cell boundary */
  68.         if ( clikWasInTermArea && !firstClickInCache)
  69.         {    /* pin the anchor point the cache area's bottom right */
  70.             anchorpoint.v = _CACHEDESTRECT.bottom - mycellSize.v - CACHBOTTOMSLOP;
  71.             anchorpoint.h = _CACHEDESTRECT.right - myslop.h;
  72.         }
  73.         else if ( anchorpoint.v == -1 && anchorpoint.h == -1)
  74.         {
  75.             /* pin anchor point to the first mouse down location */
  76.             anchorpoint = where;
  77.         }
  78.         clikWasInCacheArea = true;
  79.  
  80.         /* the mouse point has change, do selection */
  81.         if ( where != oldpoint )
  82.         {
  83.             GetRegion( _NEWRGN, anchorpoint, where );    /* get new selection area */
  84.             CombineNewOldrgn( _NEWRGN, _OLDRGN );        /* hilite the diff between the old and new selection */
  85.             CopyRgn( _NEWRGN, _OLDRGN );
  86.             SetEmptyRgn(_NEWRGN);
  87.             oldpoint = where;
  88.         }
  89.         clikWasInTermArea = false;
  90.         PtInCache = true;
  91.     }
  92.     else if ( PtInRect( where, &_TERMVISRECT) )
  93.     {
  94.         if ( clikWasInCacheArea )                        
  95.         {
  96.             /* extend the selection from cache to term area */
  97.             /* hilite selection till the bottom right of the cache area */
  98.             where.v = _CACHEDESTRECT.bottom - mycellSize.v - CACHBOTTOMSLOP;
  99.             where.h = _CACHEDESTRECT.right - myslop.h;
  100.             GetRegion( _NEWRGN, anchorpoint, where );
  101.             CombineNewOldrgn( _NEWRGN, _OLDRGN );
  102.             CopyRgn( _NEWRGN, _OLDRGN );
  103.             SetEmptyRgn(_NEWRGN);
  104.             oldpoint = where;
  105.             clikWasInCacheArea = false;
  106.         }                        /* if ( !PintoBottom )*/
  107.         clikWasInTermArea = true;
  108.     }                            /* if ( PtInRect( where, _TERMVISRECT) )*/
  109.     else
  110.     {
  111.         scrollVamt = 0;
  112.         scrollHamt = 0;
  113.         /* auto scrolling -- scroll the rect */
  114.         if ( where.v < 0 )
  115.             scrollVamt = mycellSize.v;
  116.         else if ( where.v > (_PORTRECT.bottom - 15 ) )
  117.                 scrollVamt = -mycellSize.v;
  118.                 
  119.         if ( where.h < 0 )
  120.             scrollHamt = mycellSize.h;
  121.         else if ( where.h > (_PORTRECT.right - 15 ) )
  122.                 scrollHamt = -mycellSize.h;
  123.                 
  124.         /* reset the clip area before calling the scroll rect */
  125.         SetClip( _SAVECLIP );
  126.         ScrollCache( &scrollHamt, &scrollVamt, true ) ;
  127.         ClipRect( &visCacheRect );
  128.  
  129.         Cellboundary( &where );        /* set mouse down at cell boundary */
  130.  
  131.         if ( anchorpoint.v == -1 && anchorpoint.h == -1)
  132.         {
  133.             /* init anchor points */
  134.             anchorpoint.v = _CACHEDESTRECT.bottom - mycellSize.v - CACHBOTTOMSLOP;
  135.             anchorpoint.h = _CACHEDESTRECT.right - myslop.h;
  136.         }
  137.         else
  138.         {
  139.             /* offset my points after scrolling */
  140.             anchorpoint.h += scrollHamt;
  141.             anchorpoint.v += scrollVamt;
  142.         }
  143.  
  144.         oldpoint.h += scrollHamt;
  145.         oldpoint.v += scrollVamt;
  146.         if ( oldpoint != where )
  147.         {
  148.             /* hilite the newly exposed area */
  149.             GetRegion( _NEWRGN, anchorpoint, where );
  150.             CombineNewOldrgn( _NEWRGN, _OLDRGN );
  151.             CopyRgn( _NEWRGN, _OLDRGN );
  152.             SetEmptyRgn(_NEWRGN);
  153.         }
  154.         oldpoint = where;
  155.     }
  156.     return PtInCache;
  157. }
  158.  
  159.  
  160.  
  161. /*******************************************************************
  162. *    MyCacheProc        -    handle scroll back caching
  163. *
  164. *    refcon            -    term record's reference constant
  165. *    TermDataBlock    -    pointer to the terminal data block
  166. *
  167. **********************************************************************/
  168. pascal long        MyCacheProc( long refcon, TermDataBlock *theTermData )
  169. {    
  170. #pragma        unused(refcon)
  171.  
  172.     linePtr        curline;
  173.     Rect        theRect;
  174.     
  175.     if ( !theTermData->theData )
  176.         /* nil data handle, return error */
  177.         return ( -1 );
  178.         
  179.     /* dehilite the cache selection */
  180.     DeSelection();
  181.     /* are we at the cache limit yet? points to the head of buffer if so */
  182.     if ( curindex == MAXCACHELINE )
  183.     {
  184.         curindex = 0;                        /* buffer wraps around */
  185.         offset = 1;
  186.     }
  187.     else if ( totalCache != MAXCACHELINE )    /* grow the cache destination rect (cach area ) */
  188.     {
  189.         if ( EmptyRect(&_CACHEDESTRECT) )
  190.         {
  191.             _CACHEDESTRECT.top -= CACHBOTTOMSLOP;
  192.             maxVCtl += CACHBOTTOMSLOP;            /* reset max scroll control value */
  193.             curVertValue += CACHBOTTOMSLOP;        /* increment current scroll control value */
  194.             SetCtlMax( _VERTSCROLLHDL, maxVCtl);
  195.         }
  196.         _CACHEDESTRECT.top -= mycellSize.v;
  197.         /* update the scroll max and current scroll value */
  198.         ++totalCache;
  199.         maxVCtl += mycellSize.v;            /* reset max scroll control value */
  200.         curVertValue += mycellSize.v;        /* increment current scroll control value */
  201.         SetCtlMax( _VERTSCROLLHDL, maxVCtl);
  202.         SetCtlValue( _VERTSCROLLHDL, curVertValue);
  203.     }
  204.     else
  205.     {
  206.         offset++;
  207.     }
  208.         
  209.     /* copy the data */
  210.     HLock( theTermData->theData );
  211.     HLock( _MYDATAHANDLE );
  212.     curline = ((linePtr) *_MYDATAHANDLE) + curindex++;    /* get pointer to the circular buffer */
  213.     _MYDATASIZE = GetHandleSize( theTermData->theData );    /* get data size */
  214.     BlockMove(*(theTermData->theData), (char*)curline, _MYDATASIZE);    /* copy data to my buffer */
  215.     if ( _MYDATASIZE < MAXCACHECOL )
  216.     {
  217.         /* fill the extra with spaces since the cache always has 132 column */
  218.         BlockMove( _BLANKLINE, ((char*)curline)+_MYDATASIZE, MAXCACHECOL-_MYDATASIZE);
  219.     }
  220.     
  221.     /* is the cache area visible? scroll the cache area if it is */
  222.     if ( !EmptyRect( &visCacheRect ) )
  223.     {
  224.         theRect = visCacheRect;
  225.         theRect.bottom--;            /* don't want to scroll the dividing line */
  226.         /* scroll the cache area up a line */
  227.         ScrollRect( &theRect, 0, -mycellSize.v, _UPDATERGN );
  228.         UpdateCache( _UPDATERGN );
  229.     }
  230.     return 0;
  231. }
  232.  
  233.  
  234. /*******************************************************************
  235. *    scrollProc        -    scroll proc call by TrackControl
  236. *
  237. *    theControl        -    which control is active
  238. *    partCode        -    which part of the control is active
  239. *
  240. **********************************************************************/
  241. pascal void scrollProc( ControlHandle theControl, short partCode )
  242. {
  243.     short        scrollHamount = 0;
  244.     short        scrollVamount = 0;
  245.     
  246.     if ( !partCode )                /* partcode == 0, just return to caller */
  247.         return;
  248.  
  249.     if ( partCode == inUpButton || partCode == inDownButton)
  250.     {
  251.         if ( partCode == inUpButton )
  252.         {
  253.             if ( theControl == _VERTSCROLLHDL )
  254.                 scrollVamount = mycellSize.v;
  255.             else
  256.                 scrollHamount = mycellSize.h;
  257.         }
  258.         else 
  259.         {
  260.             if ( theControl == _VERTSCROLLHDL )
  261.                 scrollVamount = -mycellSize.v;
  262.             else
  263.                 scrollHamount = -mycellSize.h;
  264.         }
  265.         ScrollCache( &scrollHamount, &scrollVamount, true );
  266.     }                            /* if ( partCode == inUpButton || partCode == inDownButton)*/
  267.  
  268.  
  269. }
  270.  
  271.  
  272. /*******************************************************************
  273. *    HandleMouseDown        -    handle mouse down in window's content
  274. *
  275. *    window                -    which window does the mouse down occurs
  276. *    event                -    event record
  277. *
  278. **********************************************************************/
  279. HandleMouseDown( window, event )
  280. WindowPtr            window;
  281. EventRecord            *event;
  282. {
  283.     Point            where;
  284.     ControlHandle    whichcontrol;
  285.     short            value;
  286.     short            partcode;
  287.     Rect            theRect;
  288.     
  289.     SetPort( window );
  290.     where = event->where;            /* get the mouse down location */
  291.     /* convert global mouse point into local coordinate */
  292.     GlobalToLocal( &where );
  293.     partcode = FindControl( where, window , &whichcontrol);
  294.     switch ( partcode )
  295.     {
  296.         case 0:    
  297.                 /* mouse down not in the active control area */
  298.                 theRect = _PORTRECT;
  299.                 theRect.right -= 15;
  300.                 theRect.bottom -= 15;
  301.                 /* is mouse down in the inactive control area or in the content? */
  302.                 if ( PtInRect( where, &theRect) )    
  303.                 {
  304.                     DeSelection();                    /* get rid of old selection */
  305.                     clikWasInCacheArea = false;        /* init some var */
  306.                     clikWasInTermArea = false;
  307.                     /* is the first mouse click in the cache area */
  308.                     if ( PtInRect( where, &visCacheRect ) )
  309.                     {
  310.                         firstClickInCache = true;
  311.                     }
  312.                     else
  313.                     {
  314.                         firstClickInCache = false;
  315.                     }
  316.                     /* set clipping region to the cache area */
  317.                     GetClip( _SAVECLIP );
  318.                     TMClick( _GTERM, event );
  319.                     SetClip( _SAVECLIP );
  320.                 }                                            /* if ( PtInRect( where, theRect) ) */
  321.                 break;
  322.         case inUpButton:
  323.         case inDownButton:
  324.                  /* do mouse tracking */
  325.                 value = TrackControl(whichcontrol, where, (ProcPtr)&scrollProc);
  326.     }                            /* switch */
  327. }
  328.  
  329.  
  330. /*******************************************************************
  331. *    UpdateCache            -    update the cache area
  332. *
  333. *    _UPDATERGN            -    the update region
  334. *
  335. **********************************************************************/
  336. UpdateCache( _UPDATERGN )
  337. RgnHandle        _UPDATERGN;
  338. {
  339.     linePtr        curline;
  340.     linePtr        bufferstart;
  341.     short        top;
  342.     short        i;
  343.     TermDataBlock    theTermData;
  344.     short        datasize=MAXCACHECOL;
  345.     Rect        theRect;
  346.     Ptr            dataptr;
  347.     RgnHandle    cache_UPDATERGN;
  348.     short        wraparound;
  349.     short         bottom;
  350.     short        right;
  351.     short        rgntop;
  352.     short        rgnleft;
  353.     Ptr            srcptr;
  354.     RgnHandle    savergn;
  355.     short        updatelinestart;
  356.     short        updatecolstart;
  357.             
  358.     cache_UPDATERGN = NewRgn();
  359.     savergn = NewRgn();
  360.     
  361.     /* we don't want to deal with the terminal area */
  362.     /* get it out of the update region */
  363.     RectRgn( cache_UPDATERGN, &_TERMVISRECT);
  364.     DiffRgn( _UPDATERGN, cache_UPDATERGN, cache_UPDATERGN);
  365.     /* erase the update region which is not in the term area */
  366.     EraseRgn( cache_UPDATERGN );
  367.     
  368.     RectRgn( cache_UPDATERGN, &visCacheRect);
  369.     /* get the intersection of my cache area and the update region */
  370.     SectRgn( cache_UPDATERGN, _UPDATERGN, cache_UPDATERGN);
  371.     
  372.     /* Does any part of the cache area need to be updated? */
  373.     if ( !EmptyRgn( cache_UPDATERGN ) )
  374.     {
  375.         /* the cache area needs to be updated */
  376.         GetClip( savergn );
  377.         SetClip( cache_UPDATERGN );
  378.         
  379.         /* erase the update area */
  380.         EraseRgn( cache_UPDATERGN );
  381.         theRect = _CACHEDESTRECT;
  382.  
  383.         right = _CACHEDESTRECT.left + myslop.h;
  384.         rgnleft = (**cache_UPDATERGN).rgnBBox.left;
  385.         
  386.         /* figure out which column should I start painting from */
  387.         for ( updatecolstart=0; updatecolstart < MAXCACHECOL; updatecolstart++ )
  388.         {
  389.             right += mycellSize.h;
  390.             if ( right > rgnleft )
  391.                 break;
  392.         }
  393. //    debugstr("get updatecolstart");
  394.         datasize -= updatecolstart;
  395.         theRect.left = right - mycellSize.h;
  396.  
  397.         /* figure out where row I should starting painting from  */
  398.         bottom = top = _CACHEDESTRECT.top;
  399.         rgntop = (**cache_UPDATERGN).rgnBBox.top;
  400.         
  401.         for ( updatelinestart=0; updatelinestart < totalCache; updatelinestart++ )
  402.         {
  403.             bottom += mycellSize.v;
  404.             if ( bottom > rgntop )
  405.                 break;
  406.         }
  407.         top = bottom - mycellSize.v;
  408.         theRect.top = top;
  409.         
  410.         HLock( _MYDATAHANDLE);                            /* lock my circular buffer */
  411.         bufferstart = ((linePtr) *_MYDATAHANDLE);
  412.         curline = bufferstart + updatelinestart + offset;        /* pointer to the buffer */
  413.         wraparound = MAXCACHELINE - offset;
  414.         
  415.         HLock( _MYDATAHDL );                                /* lock the one line data handle */
  416.         dataptr = *_MYDATAHDL;
  417.         
  418.         theTermData.theData = _MYDATAHDL;
  419.         theTermData.flags = tmTextTerminal;
  420.         theTermData.auxData = nil;
  421.         
  422.         for ( i = updatelinestart; i < totalCache ; i++ )
  423.         {
  424.             if ( i >= wraparound )
  425.             {
  426.                 curline = bufferstart+i-wraparound;        /* starts from the starting of buffer */
  427.                 wraparound = totalCache+1;
  428.             }
  429.             srcptr = ( (Ptr)curline++) + updatecolstart;
  430.             BlockMove( srcptr, dataptr , datasize);        /* copy from the cir. buffer to the one line buffer handle */            
  431.             /* paint the cached line, calling tool's routine TMPaint for each cached line */
  432.             TMPaint( _GTERM, &theTermData, &theRect);
  433.             theRect.top += mycellSize.v;;
  434.         }
  435.         
  436.         /* draw the cache/terminal dividing line */
  437.         MoveTo( _PORTRECT.left, _CACHEDESTRECT.bottom-1);
  438.         LineTo( _PORTRECT.right, _CACHEDESTRECT.bottom-1);
  439.  
  440.         /* update the selection area */
  441.         DoSelection();                                
  442.         
  443.         SetClip( savergn );
  444.         DisposeRgn( savergn );
  445.         HUnlock(_MYDATAHDL);
  446.         HUnlock(_MYDATAHANDLE);
  447.     }                            /* if EmptyRgn( ) */
  448.     DisposeRgn( cache_UPDATERGN );
  449. }
  450.  
  451. /*******************************************************************
  452. *    InvalGrowBox        -    invalidate the grow box area
  453. *
  454. **********************************************************************/
  455. InvalGrowBox( )
  456. {
  457.     Rect        _GROWRECT;
  458.     
  459.     _GROWRECT = _PORTRECT;
  460.     _GROWRECT.left = _GROWRECT.right - GROWBOXSIZE-1;
  461.     _GROWRECT.top = _GROWRECT.bottom - GROWBOXSIZE -1;
  462.     InvalRect( &_GROWRECT );
  463. }
  464.  
  465. /*******************************************************************
  466. *    DoSizeWindow        -    resize the window
  467. *
  468. *    window                -    window pointer
  469. *    event                -    event record
  470. *
  471. **********************************************************************/
  472. DoSizeWindow( window, event )
  473. WindowPtr        window;
  474. EventRecord        *event;
  475. {
  476.     long        result ;
  477.     short        bottom;
  478.     short        right;
  479.     short        top;
  480.     Rect        newTermRect;
  481.     short        diffV;
  482.     short        diffH;
  483.     
  484.     result = GrowWindow( window, event->where, &_GROWRECT );    
  485.     InvalRect( &(**_VERTSCROLLHDL).contrlRect );
  486.     InvalRect( &(**_HORISCROLLHDL).contrlRect );
  487.     InvalGrowBox();
  488.     SizeWindow(window, LoWord(result), HiWord(result), true);
  489.     
  490.     /* move and resize the control */
  491.     newTermRect = _PORTRECT = window->portRect;
  492.     /* get new the terminal area */
  493.     newTermRect.bottom -= 15;
  494.     newTermRect.right -= 15;
  495.     SectRect( &_CACHEDESTRECT, &newTermRect, &visCacheRect );
  496.     
  497.     right = _PORTRECT.right;
  498.     bottom = _PORTRECT.bottom;
  499.     top = _PORTRECT.top;
  500.  
  501.     MoveControl( _VERTSCROLLHDL, right -15, -1 );
  502.     SizeControl( _VERTSCROLLHDL, 16, bottom-top-GROWBOXSIZE );
  503.     
  504.     MoveControl( _HORISCROLLHDL, -1, bottom -15 );
  505.     SizeControl( _HORISCROLLHDL, right-_PORTRECT.left-GROWBOXSIZE, 16 );
  506.     
  507.     /* resize the terminal area */
  508.     TMResize( _GTERM, &newTermRect );
  509.  
  510.     /* readjust the cache and terminal area */
  511.     if ( (diffV = _PORTRECT.bottom - 15 - (**_GTERM).viewRect.bottom) < 0 )
  512.         diffV = 0;
  513.     if ( (diffH = _PORTRECT.right - 15 - _CACHEDESTRECT.right ) < 0 )
  514.         diffH = 0;
  515.     
  516.     if ( diffV || diffH )
  517.     {
  518.         /* pin the last row and last column to the bottom right of the window */
  519.         ScrollCache( &diffH, &diffV, false ) ;
  520.     }
  521.  
  522.     /* get new control scroll value */
  523.     SetVScrollMax();
  524.     SetHScrollMax();
  525.     InvalRect( &(**_VERTSCROLLHDL).contrlRect );
  526.     InvalRect( &(**_HORISCROLLHDL).contrlRect );
  527.     InvalGrowBox( window );
  528.     
  529.     /* get new visible term area */
  530.     SectRect( &(**_GTERM).viewRect, &(**_GTERM).termRect, &_TERMVISRECT); 
  531.     
  532. }
  533.  
  534. /*******************************************************************
  535. *    SetHScrollMax        -    reset the max of the hori scroll bar
  536. *
  537. **********************************************************************/
  538. SetHScrollMax()
  539. {
  540.     short    totalspace;
  541.     short    totalvis;
  542.     
  543.     totalspace = (_CACHEDESTRECT.right - _CACHEDESTRECT.left );
  544.                  
  545.     totalvis = _PORTRECT.right - _PORTRECT.left - 15;        /* remember that hori scroll bar */
  546.     if ( totalvis >= totalspace )
  547.         maxHCtl = 0;
  548.     else 
  549.         maxHCtl = totalspace-totalvis;
  550.     SetCtlMax( _HORISCROLLHDL, maxHCtl);
  551. }
  552.  
  553.  
  554. /*******************************************************************
  555. *    SetVScrollMax        -    reset the max of the vertical scroll bar
  556. *
  557. **********************************************************************/
  558. SetVScrollMax()
  559. {
  560.     short    totalspace;
  561.     short    totalvis;
  562.     
  563.     totalspace = (_CACHEDESTRECT.bottom - _CACHEDESTRECT.top )
  564.                  + (**_GTERM).viewRect.bottom - (**_GTERM).viewRect.top;
  565.                  
  566.     totalvis = _PORTRECT.bottom - _PORTRECT.top - 15;        /* remember that hori scroll bar */
  567.     if ( totalvis >= totalspace )
  568.         maxVCtl = 0;
  569.     else 
  570.         maxVCtl = totalspace-totalvis;
  571.     SetCtlMax( _VERTSCROLLHDL, maxVCtl);
  572. }
  573.  
  574. /*******************************************************************
  575. *    CheckTermEnv    - get new tool environment from tool if the tool's
  576. *                      environment has changed
  577. *
  578. *    Getit            - always get new environment if true
  579. *
  580. **********************************************************************/
  581. CheckTermEnv( Getit)
  582. Boolean        Getit;
  583. {
  584.     OSErr            err;
  585.     GrafPtr            curport;
  586.     Rect            cur_PORTRECT;
  587.     short            bottom;
  588.     short            diffV;
  589.     short            diffH;
  590.     short            scrollH = 0;
  591.     short            scrollV = 0;
  592.     short            newvalue;
  593.     Point            oldcell1;
  594.     Point            oldcell2;
  595.     Point            oldcellsize;
  596.     Boolean            repaint = false;
  597.     
  598.     /* has the environment changed? */
  599.     /* tmEnvironsChanged was defined to be 2 in the 1.1 CommToolBox interface */
  600.     /* it wasn't defined in the 1.0 CommToolBox interface */
  601.     if ( ((**_GTERM).errCode == tmEnvironsChanged) || Getit ) 
  602.     {
  603.         /* get new terminal environment */
  604.         termEnvironment.version = 0;                        /* must set the right version number before getting environ */
  605.         err = TMGetTermEnvirons(_GTERM, &termEnvironment);
  606.         cur_PORTRECT = _PORTRECT;
  607.         cur_PORTRECT.right -= 15;
  608.         cur_PORTRECT.bottom -= 15;
  609.         if ( err == noErr )                                    /* no error from getting the term environ */
  610.         {
  611.             myslop = termEnvironment.slop;
  612.             if ( termEnvironment.cellSize != mycellSize )    /* the cell size has changed */
  613.             {
  614.                 oldcellsize = mycellSize;
  615.                 mycellSize = termEnvironment.cellSize;
  616.                 /* get _CACHEDESTRECT dimension for setting up the hori scroll value */
  617.                 _CACHEDESTRECT.right = _CACHEDESTRECT.left + mycellSize.h * MAXCACHECOL + myslop.h * 2;
  618.                 /* if not emtpy cacheRect */
  619.                 if ( !EmptyRect( &_CACHEDESTRECT ) )
  620.                 {
  621.                     if ( !EmptyRgn( _OLDRGN) )
  622.                     {
  623.                         SwapPoint( &oldpoint, &anchorpoint );
  624.                         oldcell1 = GetCell( oldpoint , oldcellsize );
  625.                         oldcell2 = GetCell( anchorpoint, oldcellsize);
  626.                         if ( oldcell2.h == oldcell1.h )
  627.                             oldcell2.v++;
  628.                     }
  629.                     /* readjust the cacheRect */
  630.                     bottom = _CACHEDESTRECT.bottom;
  631.                     _CACHEDESTRECT.bottom = _CACHEDESTRECT.top + mycellSize.v * totalCache + CACHBOTTOMSLOP;
  632.                     _CACHEDESTRECT.right = _CACHEDESTRECT.left + mycellSize.h * MAXCACHECOL + myslop.h * 2;
  633.  
  634.                     TMScroll( _GTERM, 0, -(bottom-_CACHEDESTRECT.bottom) );
  635.                     /* readjust the visible part of the cache area */
  636.                     SectRect( &_CACHEDESTRECT, &cur_PORTRECT, &visCacheRect );
  637.                     
  638.                     if ( !EmptyRect( &visCacheRect ) )
  639.                     {
  640.                         if ( curVertValue )
  641.                         {
  642.                             newvalue = mycellSize.v * (curVertValue / oldcellsize.v);
  643.                             scrollV = curVertValue-newvalue;
  644.                             SetCtlValue( _VERTSCROLLHDL, curVertValue = newvalue);
  645.                         }
  646.                     }
  647.                     
  648.                     /* readjust the selection if there's any */
  649.                     if ( !EmptyRgn( _OLDRGN ) )
  650.                     {
  651.                         /* reset selection according to new cellsize */
  652.                         oldpoint = GetCellPoint( oldcell1, mycellSize );
  653.                         anchorpoint = GetCellPoint( oldcell2, mycellSize );
  654.                         GetRegion( _OLDRGN, anchorpoint, oldpoint );    /* get new selection area */
  655.                     }
  656.                 }                                            /* if ( !EmptyRect( &_CACHEDESTRECT ) ) */
  657.                 
  658.                 /* readjust the scroll bar value */
  659.                 SetVScrollMax();
  660.                 SetHScrollMax();
  661.  
  662.                 /* pin rect to the top left corner */
  663.                 if ( curHoriValue)
  664.                 {
  665.                     newvalue = mycellSize.h * (curHoriValue/oldcellsize.h);
  666.                     scrollH = curHoriValue-newvalue;
  667.                     SetCtlValue( _HORISCROLLHDL, curHoriValue = newvalue);
  668.                 }
  669.                 if (scrollH || scrollV )
  670.                 {
  671.                     TMScroll( _GTERM, scrollH, scrollV);
  672.                     /* offset the cache area */
  673.                     OffsetRect( &_CACHEDESTRECT, scrollH, scrollV);
  674.                     /* offset the selection */
  675.                     OffsetRgn( _OLDRGN, scrollH, scrollV );
  676.                     anchorpoint.h += scrollH;
  677.                     anchorpoint.v += scrollV;
  678.                     oldpoint.h += scrollH;
  679.                     oldpoint.v += scrollV;
  680.                     /* get the new visible term area */
  681.                     SectRect( &(**_GTERM).viewRect, &(**_GTERM).termRect, &_TERMVISRECT); 
  682.                     SectRect( &_CACHEDESTRECT, &cur_PORTRECT, &visCacheRect );
  683.                     /* update the cache area */
  684.                 }
  685.                 repaint = true;                
  686.             }                /* if ( mycellSize != oldcellsize ) */
  687.             
  688.             /* has the aux area changed */
  689.             if (  oldAuxTop != termEnvironment.auxSpace.top ||
  690.                   oldAuxBottom != termEnvironment.auxSpace.bottom 
  691.                )                /* Has the aux area changed ?*/
  692.             {
  693.                 /* readjust the control max */
  694.                 SetVScrollMax();
  695.                 oldAuxTop = termEnvironment.auxSpace.top;
  696.                 oldAuxBottom = termEnvironment.auxSpace.bottom;
  697.                 /* get new vis term area and validate it */
  698.                 SectRect( &(**_GTERM).viewRect, &(**_GTERM).termRect, &_TERMVISRECT); 
  699.                 InvalRect( &_TERMVISRECT );
  700.                 repaint = true;
  701.             }
  702.             
  703.             if (  oldAuxRight != termEnvironment.auxSpace.right ||
  704.                   oldAuxLeft != termEnvironment.auxSpace.left 
  705.                )                /* Has the aux area changed ?*/
  706.             {
  707.                 /* readjust the control max */
  708.                 SetHScrollMax();
  709.                 oldAuxLeft = termEnvironment.auxSpace.left;
  710.                 oldAuxRight = termEnvironment.auxSpace.right;
  711.                 SectRect( &(**_GTERM).viewRect, &(**_GTERM).termRect, &_TERMVISRECT); 
  712.                 InvalRect( &_TERMVISRECT );
  713.                 repaint = true;
  714.             }
  715.             
  716.             if ( maxcol != termEnvironment.textCols) 
  717.             {
  718.                 maxcol       = termEnvironment.textCols;
  719.                 SectRect( &(**_GTERM).viewRect, &(**_GTERM).termRect, &_TERMVISRECT); 
  720.                 InvalRect( &_TERMVISRECT );
  721.                 repaint = true;
  722.             }                /* if ( maxcol <> textCols) */
  723.             /* pin the bottom right of the terminal area to the bottom right of the _PORTRECT if neccessary */
  724.             /* readjust the cache and terminal area */
  725.             if ( (diffV = _PORTRECT.bottom - 15 - (**_GTERM).viewRect.bottom) < 0 )
  726.                 diffV = 0;
  727.             if ( (diffH = _PORTRECT.right - 15 - _CACHEDESTRECT.right ) < 0 )
  728.                 diffH = 0;
  729.             
  730.             if ( diffV || diffH )
  731.             {
  732.                 /* pin the last row and last column to the bottom right of the window */
  733.                 ScrollCache( &diffH, &diffV, false ) ;
  734.                 repaint = true;
  735.             }
  736.             if ( repaint )
  737.             {
  738.                 /* repaint the cache area */
  739.                 GetPort( &curport );
  740.                 EraseRgn( curport->visRgn);                /* erase the old viewRect, should be fixed in the tool */
  741.                 InvalRgn( curport->visRgn);                /* repaint the current port */
  742.             }
  743.         }                    /* if ( err = noErr )*/
  744.     }                        /* if ( ((**_GTERM).errCode ) || Getit )*/
  745. }
  746.  
  747. /*******************************************************************
  748. *    DoSelection        - hilite the selection
  749. *
  750. **********************************************************************/
  751. DoSelection(  )
  752. {
  753.     
  754.     if ( !EmptyRgn( _OLDRGN ) )
  755.     {
  756.         BitClr( (Ptr) HiliteMode, pHiliteBit ) ;
  757.         if ( isActive )
  758.             InvertRgn(_OLDRGN);    
  759.         else
  760.             FrameRgn( _OLDRGN );
  761.     }
  762. }
  763.  
  764.  
  765. /*******************************************************************
  766. *    DeSelection        - dehilite the selection
  767. *
  768. **********************************************************************/
  769. DeSelection()
  770. {
  771.     PenState    penn;
  772.     
  773.     GetClip( _SAVECLIP );
  774.     ClipRect( &visCacheRect );
  775.  
  776.     if ( !EmptyRgn( _OLDRGN ) )
  777.     {
  778.         BitClr( (Ptr) HiliteMode, pHiliteBit ) ;
  779.         if ( isActive )
  780.             InvertRgn(_OLDRGN);                /* invert old selection */
  781.         else
  782.         {
  783.             GetPenState(&penn);
  784.             PenMode(patXor);                /* invert old selection frame */    
  785.             FrameRgn( _OLDRGN );
  786.             SetPenState(&penn);
  787.         }
  788.         SetEmptyRgn(_OLDRGN );
  789.     }
  790.     SetPt( &oldpoint, -1, -1 );                /* init some points */
  791.     SetPt( &anchorpoint, -1, -1 );
  792.     SetClip( _SAVECLIP );
  793. }
  794.  
  795. /*******************************************************************
  796. *    ScrollCache        -    scroll the cache area
  797. *
  798. *    scrollHamt        -    pointer to how much to scroll horizontally
  799. *    scrollVamt        -    pointer to how much to scroll vertically
  800. *    updatenow        -    update the area right a way if true, else
  801. *                        invalidate the area for later update
  802. *
  803. **********************************************************************/
  804. ScrollCache( scrollHamt, scrollVamt, updatenow )
  805. short            *scrollHamt;
  806. short            *scrollVamt;
  807. Boolean            updatenow;
  808. {
  809.     Rect        cur_PORTRECT;
  810.     Rect        scrollrect;
  811.     short        locScrollHamt;
  812.     short        locScrollVamt;
  813.  
  814.     cur_PORTRECT = _PORTRECT;
  815.     cur_PORTRECT.right -= 15;
  816.     cur_PORTRECT.bottom -= 15;
  817.     
  818.     locScrollVamt = *scrollVamt;
  819.     locScrollHamt = *scrollHamt;
  820.     if ( locScrollHamt)
  821.     {
  822.         if ( locScrollHamt > 0 )
  823.         {
  824.             if ( curHoriValue)
  825.             {
  826.                 if ( curHoriValue < locScrollHamt )
  827.                 {
  828.                     locScrollHamt = *scrollHamt = curHoriValue;
  829.                     curHoriValue = 0;
  830.                 }
  831.                 else
  832.                 {
  833.                     curHoriValue -= locScrollHamt;
  834.                 }
  835.                 SetCtlValue( _HORISCROLLHDL, curHoriValue);
  836.             }                                    /* if ( curHoriValue)*/
  837.             else
  838.                 *scrollHamt = locScrollHamt = 0;
  839.             
  840.         }                                        /* if ( scrollHamt < 0 )*/
  841.         else                
  842.         {
  843.             if ( curHoriValue < maxHCtl) 
  844.             {
  845.                 if ( (curHoriValue - locScrollHamt) > maxHCtl)
  846.                 {
  847.                     locScrollHamt = *scrollHamt = curHoriValue-maxHCtl;
  848.                     curHoriValue = maxHCtl;
  849.                 }
  850.                 else
  851.                 {
  852.                     curHoriValue -= locScrollHamt;
  853.                 }
  854.                 SetCtlValue( _HORISCROLLHDL, curHoriValue);
  855.             }                                    /* if ( curHoriValue < maxHCtl) */
  856.             else
  857.                 *scrollHamt = locScrollHamt = 0;
  858.         }                                        /* else if ( locScrollHamt < 0 ) */
  859.     }                                            /* if ( locScrollHamt)*/                                            
  860.  
  861.     if ( locScrollVamt )
  862.     {
  863.         if ( locScrollVamt > 0 )
  864.         {
  865.             if ( curVertValue)
  866.             {
  867.                 if ( curVertValue < locScrollVamt )
  868.                 {
  869.                     locScrollVamt = *scrollVamt = curVertValue;
  870.                     curVertValue = 0;
  871.                 }
  872.                 else 
  873.                     curVertValue -= locScrollVamt;
  874.                 SetCtlValue( _VERTSCROLLHDL, curVertValue);
  875.             }                        /* if ( curVertValue ) */
  876.             else
  877.                 *scrollVamt = locScrollVamt = 0;
  878.         }
  879.         else
  880.         {
  881.             if ( curVertValue < maxVCtl )
  882.             {
  883.                 if ( (curVertValue - locScrollVamt) > maxVCtl)
  884.                 {
  885.                     locScrollVamt = *scrollVamt = curVertValue-maxVCtl;
  886.                     curVertValue = maxVCtl;
  887.                 }
  888.                 else
  889.                 {
  890.                     curVertValue -=  locScrollVamt;
  891.                 }
  892.                 SetCtlValue( _VERTSCROLLHDL, curVertValue);
  893.             }                                    /* if ( curVertValue < maxVCtl ) */
  894.             else
  895.                 *scrollVamt = locScrollVamt = 0;
  896.         }                                        /* else if ( locScrollVamt < 0 ) */
  897.     }                                            /* if (locScrollVamt) */
  898.  
  899.  
  900.     if (locScrollVamt || locScrollHamt )
  901.     {
  902.         if ( locScrollVamt > 0 )
  903.         {
  904.             /* scroll the terminal area first */
  905.             TMScroll( _GTERM, locScrollHamt, locScrollVamt);
  906.             /* offset and scroll the cache area */
  907.             OffsetRect( &_CACHEDESTRECT, locScrollHamt, locScrollVamt);
  908.             GetScrollRect( &scrollrect );
  909.             ScrollRect( &scrollrect, locScrollHamt, locScrollVamt, _UPDATERGN );
  910.         }
  911.         else
  912.         {
  913.             GetScrollRect( &scrollrect );
  914.             /* scroll the cache area */
  915.             ScrollRect( &scrollrect, locScrollHamt, locScrollVamt, _UPDATERGN );
  916.             /* offset the area */
  917.             OffsetRect( &_CACHEDESTRECT, locScrollHamt, locScrollVamt);
  918.             /* scroll the terminal area */
  919.             TMScroll( _GTERM, locScrollHamt, locScrollVamt);
  920.         }
  921.         /* offset the selection */
  922.         OffsetRgn( _OLDRGN, locScrollHamt, locScrollVamt);
  923.         anchorpoint.h += locScrollHamt;
  924.         anchorpoint.v += locScrollVamt;
  925.         oldpoint.h += locScrollHamt;
  926.         oldpoint.v += locScrollVamt;
  927.         /* get the new visible term area */
  928.         SectRect( &(**_GTERM).viewRect, &(**_GTERM).termRect, &_TERMVISRECT); 
  929.         SectRect( &_CACHEDESTRECT, &cur_PORTRECT, &visCacheRect );
  930.         /* update the cache area */
  931.         if ( updatenow )
  932.             UpdateCache( _UPDATERGN );
  933.         else
  934.             InvalRgn( _UPDATERGN );
  935.     }
  936. }
  937.  
  938. /*******************************************************************
  939. *    GetScrollRect    -    get the rect to be scrolled
  940. *
  941. *    scrollrect        -    where to return the scroll rect
  942. *
  943. **********************************************************************/
  944. GetScrollRect( scrollrect )
  945. Rect        *scrollrect;
  946. {
  947.     *scrollrect = _CACHEDESTRECT;
  948.     scrollrect->right = _PORTRECT.right - 15;
  949.     scrollrect->left = _PORTRECT.left;
  950.     if ( scrollrect->bottom > _PORTRECT.bottom - 15) 
  951.         scrollrect->bottom = _PORTRECT.bottom - 15;
  952. }
  953.  
  954. /*******************************************************************
  955. *    CacheActivate    -    de/activate the cache area
  956. *
  957. *    activate        -    activate if true, else deactivate
  958. *
  959. **********************************************************************/
  960. CacheActivate( window, activate )
  961. WindowPtr        window;
  962. Boolean            activate;
  963. {
  964.     RgnHandle        oldclip;
  965.     PenState        penn;
  966.     
  967.     if ( activate )
  968.     {
  969.         /* hilite the scroll bars */
  970.         HiliteControl( _VERTSCROLLHDL, 0 );
  971.         HiliteControl( _HORISCROLLHDL, 0 );
  972.         /* draw the control area */
  973.         InvalRect( &((**_VERTSCROLLHDL).contrlRect) );
  974.         InvalRect( &((**_HORISCROLLHDL).contrlRect) );
  975.         /* redraw the grow box */
  976.         InvalGrowBox();
  977.     }
  978.     else
  979.     {
  980.         HiliteControl( _VERTSCROLLHDL, 255 );
  981.         HiliteControl( _HORISCROLLHDL, 255 );
  982.         DrawGrowIcon(window);
  983.     }
  984.     if ( !EmptyRgn( _OLDRGN ) )
  985.     {    
  986.         oldclip = NewRgn();
  987.         GetClip( oldclip );                                /* save old clipping region */
  988.         ClipRect( &visCacheRect );                        /* set new clip area to cache area */
  989.             GetPenState(&penn);
  990.             PenMode(patXor);                            /* set up the appro. pen mode for erasing */                
  991.         if ( activate && !isActive )                    
  992.         {
  993.             /* window isn't active, activate it */
  994.             /* acitivate (hilite) the selection */
  995.             BitClr( (Ptr) HiliteMode, pHiliteBit );
  996.             FrameRgn( _OLDRGN);                            /* erase the framed selection */
  997.             BitClr( (Ptr) HiliteMode, pHiliteBit );        /* hilite selection */
  998.             InvertRgn( _OLDRGN );
  999.         }
  1000.         else if ( isActive && !activate )
  1001.         {
  1002.             /* deactivate the selection */
  1003.             BitClr( (Ptr) HiliteMode, pHiliteBit ) ;
  1004.             InvertRgn( _OLDRGN );                        /* erase old selection */
  1005.             BitClr( (Ptr) HiliteMode, pHiliteBit ) ;
  1006.             FrameRgn( _OLDRGN);                            /* frame the area */
  1007.         }
  1008.         SetClip( oldclip );
  1009.         DisposeRgn( oldclip );
  1010.             SetPenState(&penn);
  1011.     }
  1012.     isActive = activate;
  1013. }
  1014.  
  1015.