home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / EMBL Search / Sources / window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-04  |  17.0 KB  |  741 lines  |  [TEXT/KAHL]

  1. /*
  2. *********************************************************************
  3. *    
  4. *    Window.c
  5. *    General routines for window handling
  6. *        
  7. *    Rainer Fuchs
  8. *  EMBL Data Library
  9. *    Postfach 10.2209
  10. *    D-6900 Heidelberg, FRG
  11. *    E-mail: fuchs@embl-heidelberg.de
  12. *
  13. *    Copyright © 1992 EMBL Data Library
  14. *    
  15. **********************************************************************
  16. *    
  17. */ 
  18.  
  19. #include "EMBL-Search.h"
  20. #include "EMBL-Search.rsrc.h"
  21.  
  22. /*
  23. ******************************* Prototypes ***************************
  24. */
  25.  
  26. #include "window.h"
  27. #include "util.h"
  28. #include "save.h"
  29. #include "query.h"
  30. #include "sequence.h"
  31. #include "results.h"
  32. #include "pstr.h"
  33.  
  34. /*
  35. ********************************* Globals *****************************
  36. */
  37.  
  38. extern FONTINFO     fMonaco,fSystem;
  39. extern MenuHandle    gMenu[MENUNR];
  40. extern Prefs gPrefs;
  41. extern Boolean gHasColorQD;
  42.  
  43. Rect    gDragRect,         /* Max drag area */
  44.         gSeqWinRect,     /* size of sequence entry window */
  45.         gResWinRect,      /* size of result window */
  46.         gQueryWinRect,    /* size of query window */
  47.         gMinRect;        /* minimum and maximum size of res and seq window */
  48.  
  49. WDRec gWindows[MAXWIN];
  50.  
  51.  
  52. /**************************************
  53. *    Check for application window
  54. *    Return value:    TRUE, if window belongs to application
  55. *                        FALSE, if not (or NULL was passed)
  56. */
  57.  
  58. Boolean IsAppWindow(WindowPtr wPtr)
  59. {
  60.     if ( wPtr == NULL )
  61.         return(FALSE);
  62.     else                /* application windows have windowKinds = userKind (8) */
  63.         return (((WindowPeek) wPtr)->windowKind >= userKind ||
  64.                   ((WindowPeek) wPtr)->windowKind == dialogKind);
  65. }
  66.  
  67.  
  68. /**************************************
  69. *    Check for desk accessory window
  70. *    Return value:    TRUE, if window belongs to accessory
  71. *                        FALSE, if not (or NULL was passed)
  72. */
  73.  
  74. Boolean IsDAWindow(WindowPtr wPtr)
  75. {
  76.     if ( wPtr == NULL )
  77.         return(FALSE);
  78.     else                            /* DA windows have negative windowKinds */
  79.         return (((WindowPeek) wPtr)->windowKind < 0);
  80. }
  81.  
  82. /**************************************
  83. *    Centers dialogs and alerts dependent on screen size
  84. *    "what" is the resource type ('DLOG' or 'ALRT')
  85. *    "id" is the resource ID
  86. *    "offset" is the vertical offset from central position in percent (0 =center,
  87. *    100 = top of screen)
  88. *    Return value: none
  89. */
  90.  
  91. void CenterDA(ResType what,short id,short offset)
  92. {
  93. /*    Since the first field in both AlertTemplate and DialogTemplate is boundsRect,
  94.     Alerts are simply treated as Dialogs...This is similar to WindowPtr vs.
  95.     DialogPtr.
  96. */
  97.  
  98.     DialogTHndl    myHandle;
  99.     short            height;
  100.     short            width;
  101.     short            pixels;
  102.     short            mBarHeight=GetMBarHeight();            /* subtract menu bar height */
  103.  
  104.     /* get the resource and calculate width and height */
  105.     
  106.     myHandle=(DialogTHndl)GetResource(what,id);
  107.     if(myHandle == NULL) return;
  108.     
  109.     height=(**myHandle).boundsRect.bottom-(**myHandle).boundsRect.top;
  110.     width=(**myHandle).boundsRect.right-(**myHandle).boundsRect.left;
  111.     
  112.     /* center the window (taking into account menu bar height) */
  113.     
  114.     (**myHandle).boundsRect.top = mBarHeight +
  115.         ((screenBits.bounds.bottom - screenBits.bounds.top) - height)/2;
  116.     /* Adjust for offset */
  117.     pixels=(**myHandle).boundsRect.top * (offset/100.0);
  118.     (**myHandle).boundsRect.top -= pixels;
  119.     (**myHandle).boundsRect.bottom=(**myHandle).boundsRect.top+height;
  120.     (**myHandle).boundsRect.left=
  121.         ((screenBits.bounds.right - screenBits.bounds.left) - width)/2;
  122.     (**myHandle).boundsRect.right=(**myHandle).boundsRect.left+width;
  123. }
  124.  
  125. /**************************************
  126. *    Invalidates areas occupied by vertical and horizontal scroll bars
  127. */
  128.  
  129. void InvalBars(WindowPtr wPtr)
  130. {
  131.     Rect r;
  132.     GrafPtr savePort;
  133.     
  134.     if( wPtr == NULL )
  135.         return;
  136.         
  137.     savePort = ChangePort(wPtr);
  138.     r = wPtr->portRect;
  139.     r.top = r.bottom-SBarWidth;
  140.     InvalRect(&r);
  141.     
  142.     r.top = wPtr->portRect.top;
  143.     r.left = r.right-SBarWidth;
  144.     InvalRect(&r);
  145.     SetPort(savePort);
  146. }
  147.  
  148. /**************************************
  149. *    Initialises values of window record elements
  150. */
  151.  
  152. void ClearWindowRec(WDPtr wdp)
  153. {
  154.     if( wdp == NULL )
  155.         return;
  156.         
  157.     ((WindowPeek)wdp)->windowKind = 0;
  158.     wdp->vScroll=wdp->hScroll = NULL;
  159.     wdp->ctrl1=wdp->ctrl2=wdp->ctrl3=wdp->ctrl4=NULL;
  160.     ((WindowPeek)wdp)->refCon = 0L;
  161.     wdp->vRefNum = 0;
  162.     *(wdp->fName) = EOS;
  163.     wdp->userHandle = NULL;
  164.     wdp->dirty = FALSE;
  165.     wdp->inUse = FALSE;
  166. }
  167.  
  168. /**************************************
  169. *    Windows initialisation
  170. */
  171.  
  172. void PrepWindows()
  173. {
  174.     short    mBarHeight;
  175.     Rect    desktopRect;
  176.     short    i;
  177.     DialogTHndl    myHandle;
  178.  
  179.     mBarHeight=GetMBarHeight();  /*    to allow for varying sizes eg Radius
  180.                                                 screens */
  181.     desktopRect=(**GetGrayRgn()).rgnBBox; /* to deal with multiple monitors */
  182.     
  183.     /* Now make window sizes only dependent on monitor size: */
  184.     
  185.     SetRect(&gMinRect, 4*fMonaco.finfo.widMax+SBarWidth+2*RES_MARGIN,
  186.                             4*fMonaco.height+SBarWidth,
  187.                             desktopRect.right,
  188.                             desktopRect.bottom);
  189.                                                         
  190.     SetRect(&gDragRect,4,mBarHeight+4,desktopRect.right-4,desktopRect.bottom-4);
  191.     
  192.     SetRect(&gSeqWinRect,screenBits.bounds.left+4,
  193.                             screenBits.bounds.top+mBarHeight+20,
  194.                                   screenBits.bounds.left+4+MAXCOL*fMonaco.finfo.widMax +
  195.                                       SBarWidth + 2*SEQ_MARGIN,
  196.                                   screenBits.bounds.top+mBarHeight+20+SBarWidth+
  197.                                       ((screenBits.bounds.bottom-screenBits.bounds.top -
  198.                                       mBarHeight-20-SBarWidth-60)/fMonaco.height) *
  199.                                       fMonaco.height);
  200.                                 /* -60 to let room for staggered windows */
  201.                                 
  202.     SetRect(&gResWinRect,screenBits.bounds.left+4,
  203.                             screenBits.bounds.top+mBarHeight+20,
  204.                                   screenBits.bounds.left+4+MAXCOL*fMonaco.finfo.widMax+
  205.                                       SBarWidth+2*RES_MARGIN,
  206.                                   screenBits.bounds.top+mBarHeight+20+SBarWidth +
  207.                                       ((screenBits.bounds.bottom-screenBits.bounds.top-
  208.                                       mBarHeight-20-SBarWidth - 60)/fMonaco.height) *
  209.                                       fMonaco.height);
  210.                                 /* -60 to let room for staggered windows */
  211.  
  212.     myHandle=(DialogTHndl)GetResource('DLOG',QUERY_DLG);
  213.     if(myHandle == NULL) return;
  214.     
  215.     SetRect(&gQueryWinRect,screenBits.bounds.left+4,
  216.                             screenBits.bounds.top+mBarHeight+20,
  217.                                   screenBits.bounds.left+4+
  218.                                       (**myHandle).boundsRect.right -
  219.                                       (**myHandle).boundsRect.left,
  220.                                   screenBits.bounds.top+mBarHeight+20+
  221.                                       (**myHandle).boundsRect.bottom -
  222.                                       (**myHandle).boundsRect.top);
  223.                                 
  224.     for(i=0;i<MAXWIN;++i)
  225.         ClearWindowRec(&gWindows[i]);
  226. }
  227.  
  228.  
  229. /**************************************
  230. *    Simple staggering of windows by adding an offset to the window frame
  231. */
  232.  
  233. void AdjustPosition(short w, Rect *rect)
  234. {
  235.     short offset1,offset2,offset;
  236.     
  237.     offset1 = 10 * (w % 5);
  238.     offset2 = 5 * (w / 5);
  239.     offset = offset1 + offset2;
  240.     
  241.     rect->top += offset;
  242.     rect->left += offset;
  243.     rect->right += offset;
  244.     rect->bottom += offset;
  245. }
  246.  
  247.  
  248. /**************************************
  249. *    Identifies window description record corresponding to
  250. *    a given WindowPtr
  251. *    Return value:    Pointer to WindowDesc
  252. *                        NULL, if not found
  253. */
  254.  
  255. WDPtr FindMyWindow(WindowPtr wPtr)
  256. {
  257.     register short i;
  258.     
  259.     if( wPtr == NULL )
  260.         return(NULL);
  261.          
  262.     for(i=0;i<MAXWIN;++i) {
  263.         if(wPtr == (WindowPtr)&gWindows[i])
  264.             return(&gWindows[i]);
  265.     }
  266.  
  267.     return(NULL);
  268. }
  269.  
  270. /**************************************
  271. *    find a free window description structure
  272. *    Return value:    array offset of structure, if a free one was found
  273. *                        -1, if not
  274. */
  275.  
  276. short GetFreeWindow()
  277. {
  278.     register short w;
  279.     
  280.     for(w=0;w<MAXWIN;++w) {
  281.         if(gWindows[w].inUse == FALSE)
  282.             return(w);
  283.     }
  284.     
  285.     return(-1);
  286. }
  287.  
  288. /**************************************
  289. *    Grow a window
  290. *    Return value:    none
  291. */
  292.  
  293. void DoGrow(WindowPtr wPtr,Point where)
  294. {
  295.     WDPtr        wdp=FindMyWindow(wPtr);
  296.     long        newBounds;
  297.     short        newHeight,newWidth;
  298.     Rect        tempRect;
  299.     GrafPtr    savePort;
  300.     
  301.     if( wdp == NULL )
  302.         return;
  303.  
  304.     savePort = ChangePort(wPtr);
  305.     InvalBars(wPtr);
  306.     if( (newBounds=GrowWindow(wPtr,where,&gMinRect)) ) {
  307.         newWidth=LoWord(newBounds);
  308.         newHeight=HiWord(newBounds);
  309.         
  310.         /* Adjust size */
  311.        SetRect(&tempRect,0,0,newWidth,newHeight);
  312.        AdjustWSize(((WindowPeek)wdp)->windowKind,&tempRect,fMonaco.height,
  313.                        fMonaco.finfo.widMax);
  314.     
  315.         /* Clear screen (looks nicer) and grow it */
  316.         EraseRect(&wPtr->portRect);
  317.         SizeWindow(wPtr,tempRect.right,tempRect.bottom,TRUE);
  318.         InvalBars(wPtr);
  319.         GrowScroll(wdp);
  320.     
  321.         /* redraw */
  322.         InvalRect(&wPtr->portRect);
  323.         SetVScroll(wdp);
  324.         SetHScroll(wdp);
  325.     }
  326.     SetPort(savePort);
  327. }
  328.  
  329. /**************************************
  330. *    Grow scroll bars
  331. *    Return value:    none
  332. */
  333.  
  334. void GrowScroll(WDPtr wdp)
  335. {
  336.     short    newTop,newBottom,newLeft,newRight;
  337.     WindowPtr wPtr = (WindowPtr)wdp;
  338.     short windowKind;
  339.     
  340.     if ( wdp == NULL )
  341.         return;
  342.         
  343.     windowKind = ((WindowPeek)wdp)->windowKind;
  344.     if(windowKind == queryW)    /* no scroll bars */
  345.         return;
  346.         
  347.     HideControl(wdp->vScroll);
  348.     HideControl(wdp->hScroll);
  349.  
  350.     switch(windowKind) {
  351.         case resW:
  352.             newTop=wPtr->portRect.top+3*fMonaco.height-1;
  353.             break;
  354.         case seqW:
  355.             newTop=wPtr->portRect.top-1;
  356.             break;
  357.     }
  358.     
  359.     newLeft=wPtr->portRect.right-SBarWidth;
  360.     newBottom=wPtr->portRect.bottom-SBarWidth;
  361.     MoveControl(wdp->vScroll,newLeft,newTop);
  362.     SizeControl(wdp->vScroll,SBarWidth+1,newBottom-newTop+1);
  363.     
  364.     newTop=wPtr->portRect.bottom-SBarWidth;
  365.     newLeft=wPtr->portRect.left-1;
  366.     newRight=wPtr->portRect.right-SBarWidth;
  367.     MoveControl(wdp->hScroll,newLeft,newTop);
  368.     SizeControl(wdp->hScroll,newRight-newLeft+1,SBarWidth+1);
  369.  
  370.     ShowControl(wdp->vScroll);
  371.     ShowControl(wdp->hScroll);
  372. }
  373.  
  374.  
  375. /**************************************
  376. *    Zoom a window. In an ideal program we would check to see on which monitor the main
  377. *    part of the window is in order to zoom on this window.
  378. *    Return value:    none
  379. */
  380.  
  381. void DoZoom(WindowPtr wPtr,short partCode)
  382. {
  383.     WDPtr        wdp=FindMyWindow(wPtr);
  384.     short        windowKind;
  385.     Rect        globalPortRect,theSect,zoomRect;
  386.     GDHandle    nthDevice,dominantGDevice;
  387.     long        greatestArea,sectArea;
  388.     short        margin,bias;
  389.     
  390.     if ( wdp == NULL )
  391.         return;
  392.         
  393.     windowKind = ((WindowPeek)wdp)->windowKind;
  394.     if(windowKind == queryW)    /* no zoom box */
  395.         return;
  396.         
  397.     SetPort(wPtr);
  398.     EraseRect(&(wPtr->portRect));
  399.     
  400.     /* Adopted from DTS snippets:
  401.         If there is the possibility of multiple gDevices, then we must check them to make
  402.         sure we are zooming onto the right display device when zooming out. */
  403.         
  404.     if (partCode == inZoomOut && gHasColorQD) {
  405.         /* window's portRect must be converted to global coordinates */
  406.         globalPortRect = wPtr->portRect;
  407.         LocalToGlobal(&TopLeft(globalPortRect));
  408.         LocalToGlobal(&BottomRight(globalPortRect));
  409.  
  410.          nthDevice = GetDeviceList();
  411.         greatestArea = 0;
  412.         /* This loop checks the window against all the gdRects in the
  413.               gDevice list and remembers which gdRect contains the largest
  414.               portion of the window being zoomed. */
  415.         while(nthDevice != NULL) {
  416.             SectRect(&globalPortRect,&(**nthDevice).gdRect,&theSect);
  417.             sectArea = (long)(theSect.right - theSect.left) *
  418.                            (long)(theSect.bottom - theSect.top);
  419.             if (sectArea > greatestArea) {
  420.                 greatestArea = sectArea;
  421.                 dominantGDevice = nthDevice;
  422.             }
  423.             nthDevice = GetNextDevice(nthDevice);
  424.         }
  425.  
  426.         /* We must create a zoom rectangle manually in this case.
  427.                  account for menu bar height as well, if on main device */
  428.         bias = 20;
  429.         if(dominantGDevice == GetMainDevice())
  430.             bias += GetMBarHeight();
  431.             
  432.         zoomRect = (**dominantGDevice).gdRect;
  433.         zoomRect.left += 4;
  434.         zoomRect.top += bias;
  435.         
  436.         if(windowKind == seqW) margin = SEQ_MARGIN;
  437.         else margin = RES_MARGIN;
  438.         zoomRect.right = zoomRect.left + MAXCOL*fMonaco.finfo.widMax +
  439.                                 SBarWidth + 2*margin;
  440.         zoomRect.bottom = zoomRect.top + SBarWidth +
  441.                                 ((zoomRect.bottom - SBarWidth - zoomRect.top)/fMonaco.height)
  442.                                 * fMonaco.height;
  443.             
  444.  
  445.         (**((WStateDataHandle)((WindowPeek)wPtr)->dataHandle)).stdState = zoomRect;
  446.     }      
  447.  
  448.     ZoomWindow(wPtr,partCode,TRUE);
  449.  
  450.     GrowScroll(wdp);
  451.     InvalRect(&(wPtr->portRect));
  452.     switch( ((WindowPeek)wdp)->windowKind) {
  453.         case resW:
  454.             SetVScroll(wdp);
  455.             SetHScroll(wdp);
  456.             break;
  457.         case seqW:
  458.             SetVScroll(wdp);
  459.             SetHScroll(wdp);
  460.             break;
  461.     }
  462. }
  463.  
  464.  
  465. /**************************************
  466. *    Close a window. If shift key is pressed, we do not ask whether file should 
  467. *    be saved.
  468. *    Return value:    TRUE, if successful
  469. *                        FALSE, if error occurred or user cancelled
  470. */
  471.  
  472. Boolean CloseMyWindow(WDPtr wdp, Boolean shift)
  473. {
  474.     short            i;
  475.     Str255        title;
  476.     
  477.     if( wdp == NULL )
  478.         return(TRUE);
  479.     
  480.     GetWTitle((WindowPtr)wdp,title);
  481.     InitCursor();
  482.     if(wdp->dirty && !shift && gPrefs.confirmChg) {
  483.         ParamText(title,"\p","\p","\p");
  484.         CenterDA('ALRT',CLOSE_ALRT,33);
  485.         switch (StopAlert(CLOSE_ALRT, NULL)) {
  486.             case aaSave:
  487.                 if(!DoSave(wdp,TRUE))
  488.                     return(FALSE);
  489.                  break;
  490.             case aaDiscard:
  491.                  break;
  492.              case aaCancel: return(FALSE);
  493.          }
  494.      }
  495.          
  496.     switch( ((WindowPeek)wdp)->windowKind ) {
  497.         case queryW:
  498.             DisposeQuery(wdp);
  499.             break;
  500.         case seqW:
  501.             DisposeSequence(wdp);
  502.             break;
  503.         case resW:
  504.             DisposeResults(wdp);
  505.             break;
  506.     }
  507.     
  508.     DelWindowFromMenu(title);
  509.     
  510.     return(TRUE);
  511. }
  512.  
  513.  
  514. /**************************************
  515. *    Close all windows. If shift key is pressed, we do not ask whether file should 
  516. *    be saved.
  517. *    Return value:    TRUE, if successful
  518. *                        FALSE, if error occurred or user cancelled
  519. */
  520.  
  521. Boolean CloseAllWindows(Boolean shift)
  522. {
  523.     WindowPtr    wPtr;
  524.     WDPtr            wdp;
  525.     short            n;
  526.     
  527.     while( (wPtr = FrontWindow()) != NULL ) {
  528.         n=((WindowPeek)wPtr)->windowKind;
  529.         if(n<0)
  530.             CloseDeskAcc(n);
  531.         else {
  532.             wdp = FindMyWindow(wPtr);
  533.             if(wdp)
  534.                 if(!CloseMyWindow(wdp,shift))
  535.                     return(FALSE);
  536.         }
  537.     }
  538.     return(TRUE);
  539. }
  540.  
  541. /**************************************
  542. *    Adjust value of vertical scroll bar
  543. */
  544.  
  545. void SetVScroll(WDPtr wdp)
  546. {
  547.     Rect            viewRect;
  548.     SeqRecHdl    seqRecHdl;
  549.     ResultHdl    resHdl;
  550.     short            n,visLines,max;
  551.     
  552.     if (wdp == NULL)
  553.         return;
  554.         
  555.     switch(((WindowPeek)wdp)->windowKind) {
  556.         case seqW:
  557.             seqRecHdl = (SeqRecHdl)wdp->userHandle;
  558.             GetViewRect((WindowPtr)wdp,&viewRect);    
  559.             visLines = (viewRect.bottom - viewRect.top) / fMonaco.height;
  560.             n = (**seqRecHdl).nlines - visLines;
  561.             break;
  562.         case resW:
  563.             resHdl = (ResultHdl)wdp->userHandle;
  564.             GetViewRect((WindowPtr)wdp,&viewRect);    
  565.             visLines = (viewRect.bottom - viewRect.top) / fMonaco.height;
  566.             n = (**resHdl).nhits - visLines;
  567.             break;
  568.         case queryW:    /* no scroll bar */
  569.             return;
  570.             break;
  571.     }
  572.  
  573.     max = (n > 0) ? n : 0;
  574.     SetCtlMax(wdp->vScroll,max);
  575. }
  576.  
  577.  
  578. /**************************************
  579. *    Adjust value of horizontal scroll bar
  580. */
  581.  
  582. void SetHScroll(WDPtr wdp)
  583. {
  584.     Rect    viewRect;
  585.     short    n,visCol,max,margin;
  586.     
  587.     if( wdp == NULL )
  588.         return;
  589.         
  590.     switch(((WindowPeek)wdp)->windowKind) {
  591.         case seqW:
  592.             GetViewRect((WindowPtr)wdp,&viewRect);
  593.             margin = SEQ_MARGIN;
  594.             break;
  595.         case resW:
  596.             GetViewRect((WindowPtr)wdp,&viewRect);
  597.             margin = RES_MARGIN;    
  598.             break;
  599.         case queryW:    /* no scroll bar */
  600.             return;
  601.             break;
  602.     }
  603.  
  604.     visCol = (viewRect.right - viewRect.left - 2*margin) / fMonaco.finfo.widMax;
  605.     n = MAXCOL - visCol;    /* We assume a max line length of MAXCOL */
  606.     max = (n > 0) ? n : 0;
  607.     SetCtlMax(wdp->hScroll,max);
  608. }
  609.  
  610. /**************************************
  611. *    Adjusts a rectangle (window size) to look nicer, taking
  612. *    margins and scroll bars into account
  613. *    Return value:    none
  614. *    Side-effect:    adjusted rect in r
  615. */
  616.  
  617. void AdjustWSize(short wKind, Rect *r,short height, short width)
  618. {    
  619.     short margin;
  620.     
  621.     switch(wKind) {
  622.         case seqW:
  623.             margin = SEQ_MARGIN;
  624.             break;
  625.         case resW:
  626.             margin = RES_MARGIN;
  627.             break;
  628.         case queryW:
  629.             break;
  630.     }
  631.  
  632.     r->bottom = r->top + height*((r->bottom - r->top - SBarWidth)/height)
  633.                     + SBarWidth;
  634.  
  635.     r->right = r->left + width*((r->right - r->left - SBarWidth -
  636.                     2*margin)/width) + SBarWidth + 2*margin;
  637. }
  638.  
  639. /**************************************
  640. *    Draw grow icon in a window
  641. *    Return value:    TRUE, if successful
  642. *                        FALSE, if error occurred
  643. */
  644.  
  645. void DoDrawGrowIcon(WindowPtr wPtr)
  646. {
  647.     WDPtr wdp=FindMyWindow(wPtr);
  648.     Rect tempRect;
  649.     RgnHandle tempRgn=NewRgn();
  650.     short windowKind;
  651.     
  652.     if( wdp == NULL )
  653.         return;
  654.         
  655.     windowKind = ((WindowPeek)wdp)->windowKind;
  656.     if(windowKind == queryW)    /* no grow icon */
  657.         return;
  658.     
  659.     tempRect=wPtr->portRect;
  660.     
  661.     switch(((WindowPeek)wdp)->windowKind) {
  662.         case seqW:
  663.             break;
  664.         case resW:
  665.             tempRect.top += 3*fMonaco.height;
  666.             break;
  667.     }
  668.     
  669.     GetClip(tempRgn);
  670.     ClipRect(&tempRect);
  671.     DrawGrowIcon(wPtr);
  672.     SetClip(tempRgn);
  673.     DisposeRgn(tempRgn);
  674. }
  675.  
  676.  
  677. /**************************************
  678. *    Calculation of contents rectangle of a result window
  679. *    Return value:    none
  680. *    Side-effect:    rect in r
  681. */
  682.  
  683. void GetViewRect(WindowPtr wPtr, Rect *r)
  684. {
  685.     WDPtr wdp=FindMyWindow(wPtr);
  686.     
  687.     if( wdp == NULL )
  688.         return;
  689.         
  690.     *r = wPtr->portRect;
  691.  
  692.     switch(((WindowPeek)wdp)->windowKind) {
  693.         case seqW:
  694.             break;
  695.         case resW:
  696.             r->top += 3*fMonaco.height;
  697.             break;
  698.         case queryW:
  699.             break;
  700.     }
  701.  
  702.     r->right -= SBarWidth;
  703.     r->bottom -= SBarWidth;
  704. }
  705.  
  706. /**************************************
  707. *    Add a window title to Windows menu
  708. */
  709.  
  710. void AddWindowToMenu(StringPtr name)
  711. {
  712.     register short    entries=CountMItems(gMenu[WINDOWS]);
  713.             
  714.     /* we first insert a dummy name, then change it with SetItem.
  715.         Otherwise we couldn't insert a name like "myfile;1" which contains
  716.         a meta character */
  717.         
  718.     AppendMenu(gMenu[WINDOWS],"\pdummy");
  719.     SetItem(gMenu[WINDOWS],entries+1,name);
  720.     DrawMenuBar();
  721. }
  722.  
  723. /**************************************
  724. *    Delete a window title from Windows menu
  725. *    Return value:    none
  726. */
  727.  
  728. void DelWindowFromMenu(StringPtr name)
  729. {
  730.     Str255 str;
  731.     register short i;
  732.     register short entries = CountMItems(gMenu[WINDOWS]);
  733.  
  734.     for(i=FIRSTWIN_I;i <= entries;++i) {
  735.         GetItem(gMenu[WINDOWS],i,str);
  736.         if(!pstrcmp(str,name)) {
  737.             DelMenuItem(gMenu[WINDOWS],i);
  738.             break;
  739.         }
  740.     }
  741. }