home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 August / August CD.bin / Shareware / Programming / Infinity Windoid WDEF 2.6 / InfinityWindoid.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-05  |  35.2 KB  |  1,428 lines  |  [TEXT/MPS ]

  1. // *****************************************************************************
  2. //
  3. //    FILE:
  4. //        InfinityWindoid.c
  5. //
  6. //    WRITTEN BY:
  7. //        Troy Gaul
  8. //        Infinity Systems
  9. //
  10. //        © 1991-94 Infinity Systems
  11. //        All rights reserved.
  12. //
  13. //    DESCRIPTION:
  14. //        This file contains the main source for a WDEF (Window Definition)
  15. //        resource. It provides a 'windoid' appearance use on floating windows. 
  16. //                
  17. //        See the file 'About Infinity Windoid' for more information and a list
  18. //        of features this WDEF supports.
  19. //
  20. //    HOW TO CONTACT THE AUTHOR:
  21. //        Send e-mail to: t-gaul@i-link.com
  22. //
  23. // -----------------------------------------------------------------------------
  24.  
  25. // *****************************************************************************
  26. //    Include files
  27. // -----------------------------------------------------------------------------
  28.  
  29. #include "WindoidDefines.h"            // must be included before Apple interfaces
  30.  
  31. #include <Types.h>
  32. #include <Memory.h>
  33. #include <QuickDraw.h>
  34. #include <OSUtils.h>
  35. #include <Windows.h>
  36. #include <Palettes.h>
  37. #include <ToolUtils.h>
  38. #include <Desk.h>
  39. #include <Fonts.h>
  40. #ifdef UNIV_HEADERS
  41. #include <MixedMode.h>
  42. #endif
  43.  
  44. #include "WindoidTypes.h"
  45. #include "WindoidUtil.h"
  46.  
  47. // *****************************************************************************
  48. //    Function Prototypes    for main                             
  49. // -----------------------------------------------------------------------------
  50.  
  51. void DoWInit(WindowPeek window, long param, short varCode);
  52. void DoWDispose(WindowPeek window, long param);
  53. long DoWHit(WindowPeek window, long param);
  54. void DoWDraw(WindowPeek window, long param);
  55. void DoWCalcRgns(WindowPeek window, long param);
  56. void DoWGrow(WindowPeek window, long param);
  57. void DoWDrawGIcon(WindowPeek window, long param);
  58.  
  59. ////// *************************************************************************
  60. /////
  61. ////    Windoid Main Function                                                     
  62. ///
  63. // -----------------------------------------------------------------------------
  64. //    This is the main entry point for all calls to this code resource. It
  65. //    dispatches to routines that correspond to the message it is given.
  66. // -----------------------------------------------------------------------------
  67.  
  68. pascal long 
  69. main(short varCode, WindowPeek window, short message, long param) {
  70.     GrafPtr        savePort;
  71.     long        result;
  72.     Boolean        needSyncPorts;
  73.     
  74.     // This sets up the appropriate drawing environment, but only for those
  75.     // messages for which we actually need to draw.
  76.  
  77.     needSyncPorts = (message == wDraw 
  78.                   || message == wHit 
  79.                   || message == wGrow
  80.                   || message == wDrawGIcon) && HasCQDraw();
  81.     if (needSyncPorts) {
  82.         GetPort(&savePort);
  83.         SyncPorts();
  84.     }
  85.     
  86.     switch (message) {
  87.         case wNew:            DoWInit(window, param, varCode);
  88.                             break;
  89.         
  90.         case wDispose:        DoWDispose(window, param);
  91.                             break;
  92.  
  93.         case wDraw:            DoWDraw(window, param & 0xFFFF);
  94.                             break;
  95.             // There's a tech note that says that for the draw message, only
  96.             // the low-order word of param is set correctly, so we should do
  97.             // this (AND with 0xFFFF) to be sure we're looking at the correct 
  98.             // value.
  99.             
  100.         case wHit:            result = DoWHit(window, param);        
  101.                             break;
  102.         
  103.         case wCalcRgns:        DoWCalcRgns(window, param);
  104.                             break;
  105.         
  106.         case wGrow:            DoWGrow(window, param);
  107.                             break;
  108.                             
  109.         case wDrawGIcon:    DoWDrawGIcon(window, param);
  110.                             break;
  111.     }
  112.     
  113.     if (needSyncPorts)
  114.         SetPort(savePort);
  115.     
  116.     return result;
  117. }
  118.  
  119. ////// *************************************************************************
  120. /////
  121. ////    Routines to get Rects for title bar parts                                                     
  122. ///
  123. // -----------------------------------------------------------------------------
  124.  
  125. static void 
  126. GetTitleBar(WindowPeek window, Rect *titleBar) {
  127.     *titleBar = (**(window->strucRgn)).rgnBBox;
  128.  
  129.     if (WindData.isHoriz) {    
  130.     
  131.         // title bar on top
  132.         
  133.         titleBar->bottom = titleBar->top + kTitleHeight;
  134.         titleBar->right -= 1;        // shadow compensation
  135.     } else {            
  136.     
  137.         // title bar on left
  138.         
  139.         titleBar->right = titleBar->left + kTitleHeight;
  140.         titleBar->bottom -= 1;         // shadow compensation
  141.     }
  142. }
  143.  
  144. // -----------------------------------------------------------------------------
  145.  
  146. static void 
  147. GetCloseBox(WindowPeek window, const Rect *titleRect, Rect *theRect) {
  148.     #pragma unused(window)
  149.  
  150.     *theRect = *titleRect;
  151.     if (WindData.isHoriz)
  152.         InsetRect(theRect, kGadgetMargin, kGadgetInset);    // titlebar on top
  153.     else
  154.         InsetRect(theRect, kGadgetInset, kGadgetMargin);    // titlebar on left
  155.  
  156.     theRect->bottom = theRect->top  + kGadgetSize;
  157.     theRect->right  = theRect->left + kGadgetSize;
  158. }
  159.  
  160. // -----------------------------------------------------------------------------
  161. #ifdef ALLOW_ZOOM
  162.  
  163. static void 
  164. GetZoomBox(WindowPeek window, const Rect *titleRect, Rect *theRect) {
  165.     #pragma unused(window)
  166.  
  167.     *theRect = *titleRect;
  168.     if (WindData.isHoriz) {
  169.         InsetRect(theRect, kGadgetMargin, kGadgetInset);    // titlebar on top
  170. #ifndef DONT_ALIGN_ZOOM
  171.         if (IsEven(titleRect->right - titleRect->left))
  172.             OffsetRect(theRect, -1, 0);
  173. #endif
  174.     } else {
  175.         InsetRect(theRect, kGadgetInset, kGadgetMargin);    // titlebar on left
  176. #ifndef DONT_ALIGN_ZOOM
  177.         if (IsEven(titleRect->bottom - titleRect->top))
  178.             OffsetRect(theRect, 0, -1);
  179. #endif
  180.     }
  181.     
  182.     theRect->top = theRect->bottom - kGadgetSize;
  183.     theRect->left = theRect->right - kGadgetSize;
  184. }
  185.  
  186. #endif
  187. // -----------------------------------------------------------------------------
  188. #ifdef ALLOW_GROW
  189.  
  190. static void 
  191. GetGrowBox(WindowPeek window, Rect *theRect) {
  192.     GetGlobalContentRect(window, theRect);
  193.  
  194.     theRect->left = ++theRect->right - kScrollBarPixels;
  195.     theRect->top = ++theRect->bottom - kScrollBarPixels;
  196. }
  197.  
  198. #endif
  199.  
  200. ////// *************************************************************************
  201. /////
  202. ////    Drawing routines                                                     
  203. ///
  204. // -----------------------------------------------------------------------------
  205.  
  206. // *****************************************************************************
  207. //    SetWFrameColor
  208. // -----------------------------------------------------------------------------
  209.  
  210. static void
  211. SetWFrameColor(WindowPeek window, short variation) {
  212.     switch (variation) {
  213.         case blackandwhite:
  214.             ForeColor(blackColor);
  215.             break;
  216.  
  217. #ifndef SYS7_OR_LATER
  218.         case sys6color:
  219.             WctbForeColor(window, wFrameColor);
  220.             break;
  221. #endif
  222.  
  223.         case sys7color:
  224.             if (WindData.ignoreHilite || window->hilited)
  225.                 WctbForeColor(window, wFrameColor);
  226.             else
  227.                 AvgWctbForeColor(window, wHiliteColorLight, wHiliteColorDark,
  228.                                  wInactiveFramePct);
  229.             break;
  230.     }
  231. }
  232.  
  233. // *****************************************************************************
  234. //    SetWTitleColor
  235. // -----------------------------------------------------------------------------
  236. #ifdef TITLE_STRING
  237.  
  238. static void
  239. SetWTitleColor(WindowPeek window, short variation, Boolean active) {
  240.     switch (variation) {
  241.         case blackandwhite:
  242.             break;
  243.  
  244. #ifndef SYS7_OR_LATER
  245.         case sys6color:
  246.             WctbForeColor(window, wTextColor);
  247.             break;
  248. #endif
  249.             
  250.         case sys7color:
  251.             if (active)
  252.                 WctbForeColor(window, wTextColor);
  253.             else        // -- set the color for inactive titlebar text
  254.                 AvgWctbForeColor(window, wHiliteColorLight, wHiliteColorDark,
  255.                                  wInactiveTextPct);
  256.             break;
  257.     }
  258. }
  259.  
  260. #endif
  261.  
  262. // *****************************************************************************
  263. //    SetWTitleBarColors
  264. // -----------------------------------------------------------------------------
  265.  
  266. static void
  267. SetWTitleBarColors(WindowPeek window, short variation, Boolean active) {
  268.  
  269.     //    Set the foreground and background for the drawing of the 
  270.     //    titlebar pattern
  271.     
  272.     switch (variation) {
  273.         case blackandwhite:
  274.             ColorsNormal();
  275.             break;
  276.             
  277. #ifndef SYS7_OR_LATER
  278.  
  279.         case sys6color:
  280.             WctbForeColor(window, wHiliteColor);
  281.             if (active)
  282.                 WctbBackColor(window, wTitleBarColor);
  283.             else
  284.                 WctbBackColor(window, wContentColor);
  285.             break;
  286.  
  287. #endif
  288.  
  289.         case sys7color:
  290.             if (active) {
  291.                 AvgWctbForeColor(window, wHiliteColorLight, wHiliteColorDark, 
  292.                                  wTitleBarDarkPct);
  293.                 AvgWctbBackColor(window, wHiliteColorLight, wHiliteColorDark, 
  294.                                  wTitleBarLightPct);
  295.             } else {
  296.                 WctbForeColor(window, wContentColor);
  297.                 WctbBackColor(window, wContentColor);
  298.             }
  299.             break;
  300.     }
  301. }
  302.  
  303. // *****************************************************************************
  304. //    SetGadgetFrameEraseColors
  305. // -----------------------------------------------------------------------------
  306.  
  307. static void
  308. SetGadgetFrameEraseColors(WindowPeek window, short variation) {
  309.  
  310.     //    Set the foreground and background for the drawing of the 
  311.     //    titlebar pattern, in inverse so we can erase some of the
  312.     //    background by using normal drawing routines
  313.  
  314.     switch (variation) {
  315.         case blackandwhite:
  316.             ForeColor(whiteColor);
  317.             BackColor(blackColor);
  318.             break;
  319.             
  320. #ifndef SYS7_OR_LATER
  321.         case sys6color:
  322.             WctbForeColor(window, wTitleBarColor);
  323.             WctbBackColor(window, wHiliteColor);
  324.             break;
  325. #endif
  326.  
  327.         case sys7color:
  328.             AvgWctbBackColor(window, wHiliteColorLight, wHiliteColorDark, 
  329.                              wTitleBarDarkPct);
  330.             AvgWctbForeColor(window, wHiliteColorLight, wHiliteColorDark, 
  331.                              wTitleBarLightPct);
  332.             break;
  333.     }
  334. }
  335.  
  336. // *****************************************************************************
  337. //    DrawTitlebarTinges
  338. // -----------------------------------------------------------------------------
  339.  
  340. static void
  341. DrawTitlebarTinges(WindowPeek window, short variation, const Rect *bounds) {
  342. #ifdef THICK_TITLEBAR
  343.     Rect tempRect = *bounds;
  344.     InsetRect(&tempRect, 1, 1);
  345.     
  346.     switch (variation) {
  347.         case blackandwhite:
  348.             ForeColor(whiteColor);
  349.             BackColor(blackColor);
  350.             FrameRect(&tempRect);
  351.             break;
  352.  
  353. #ifndef SYS7_OR_LATER
  354.         case sys6color:
  355.             WctbForeColor(window, wTitleBarColor);
  356.             FrameRect(&tempRect);
  357.             break;
  358. #endif
  359.             
  360.         case sys7color:
  361.             AvgWctbForeColor(window, wTingeLight, wTingeDark, 
  362.                              wTitleBarTingeDarkPct);
  363.             FrameBottomRightShading(tempRect);
  364.  
  365.             WctbForeColor(window, wTingeLight);
  366.             tempRect.right--;
  367.             tempRect.bottom--;
  368.             FrameTopLeftShading(tempRect);
  369.             break;
  370.     }
  371. #else
  372.     #pragma unused (window, variation, bounds)
  373. #endif
  374. }
  375.  
  376. // *****************************************************************************
  377. //    DrawCloseBox
  378. // -----------------------------------------------------------------------------
  379.  
  380. static void 
  381. DrawCloseBox(WindowPeek window, short variation, Rect *theRect) {
  382.     Rect tempRect;
  383.  
  384. #ifdef THICK_TITLEBAR
  385.  
  386.     //    Paint the area on the edges out with the background color
  387.  
  388.     SetGadgetFrameEraseColors(window, variation);
  389.     InsetRect(theRect, -kTingeInset, -kTingeInset);
  390.     FrameRect(theRect);
  391.     InsetRect(theRect, kTingeInset, kTingeInset);
  392. #endif
  393.  
  394.     switch (variation) {
  395.         case blackandwhite:
  396.             ColorsNormal();
  397.             FrameBox(theRect);
  398.             break;
  399.         
  400. #ifndef SYS7_OR_LATER
  401.         case sys6color:
  402.             WctbForeColor(window, wHiliteColor);
  403.             WctbBackColor(window, wTitleBarColor);
  404.             FrameBox(theRect);
  405.             break;
  406. #endif
  407.         
  408.         case sys7color:
  409.             WctbForeColor(window, wTingeDark);
  410.             BackColor(whiteColor);
  411.             FrameTopLeftShading(*theRect);
  412.             
  413.             tempRect = *theRect;
  414.             tempRect.top++;
  415.             tempRect.left++;
  416.             WctbForeColor(window, wTingeLight);
  417.             FrameRect(&tempRect);
  418.  
  419.             InsetRect(&tempRect, 1, 1);
  420.             WctbForeColor(window, wTingeDark);
  421.             FrameBottomRightShading(tempRect);
  422.  
  423.             tempRect.right--;
  424.             tempRect.bottom--;
  425.             AvgWctbForeColor(window, wTitleBarLight, wTitleBarDark, 
  426.                              wCloseBoxColor);
  427.             PaintRect(&tempRect);
  428.             break;
  429.     }
  430. }
  431.  
  432. // *****************************************************************************
  433. //    DrawZoomBox -- Draw zoom box
  434. // -----------------------------------------------------------------------------
  435. #ifdef ALLOW_ZOOM
  436.  
  437. static void 
  438. DrawZoomBox(WindowPeek window, short variation, Rect *theRect) {
  439.     Rect tempRect;
  440.  
  441.     DrawCloseBox(window, variation, theRect);
  442.     tempRect = *theRect;
  443.     tempRect.bottom -= 3;
  444.     tempRect.right -= 3;
  445.  
  446.     switch (variation) {
  447.         case blackandwhite:
  448. #ifndef SYS7_OR_LATER
  449.         case sys6color:
  450. #endif
  451.             FrameRect(&tempRect);
  452.             break;
  453.         
  454.         case sys7color:
  455.             WctbForeColor(window, wTingeDark);
  456.             tempRect.left += 2;
  457.             tempRect.top += 2;
  458.             FrameBottomRightShading(tempRect);
  459.             break;
  460.     }
  461. }
  462.  
  463. #endif
  464. // *****************************************************************************
  465. //    DrawXedBox -- Draw close or zoom box with an X in it (or inverted in B&W)
  466. // -----------------------------------------------------------------------------
  467.  
  468. static void 
  469. DrawXedBox(WindowPeek window, short variation, Rect *theRect) {
  470.     switch (variation) {
  471.         case blackandwhite:
  472.             PaintRect(theRect);
  473.             break;
  474.             
  475. #ifndef SYS7_OR_LATER
  476.         case sys6color:
  477.             WctbForeColor(window, wHiliteColor);
  478.             PaintRect(theRect);
  479.             break;
  480. #endif
  481.             
  482.         case sys7color:
  483.             AvgWctbForeColor(window, wTingeLight, wTingeDark, wXedBoxPct);
  484.             PaintRect(theRect);
  485.             
  486.             WctbForeColor(window, wTitleBarDark);
  487.             FrameRect(theRect);
  488.             
  489.             MoveTo(theRect->left,      theRect->top       );    // Draw the 'X'
  490.             LineTo(theRect->right - 1, theRect->bottom - 1);
  491.             MoveTo(theRect->right - 1, theRect->top       );
  492.             LineTo(theRect->left,      theRect->bottom - 1);
  493.             break;
  494.     }
  495. }
  496.  
  497. // *****************************************************************************
  498. //    DrawGrowBox
  499. // -----------------------------------------------------------------------------
  500. #ifdef ALLOW_GROW
  501.  
  502. static void 
  503. DrawGrow3DBox(WindowPeek window, Rect *theRect, Boolean light) {
  504.     Rect tempRect = *theRect;
  505.     
  506.     WctbForeColor(window, wTingeDark);
  507.     FrameRect(theRect);
  508.     
  509.     
  510.     //    Add the top light outer border on the top-left edge
  511.     
  512.     tempRect.left++;
  513.     tempRect.top++;
  514.     WctbForeColor(window, wTingeLight);
  515.     FrameTopLeftShading(tempRect);
  516.  
  517.  
  518.     //    Finally, fill in the center.
  519.     
  520.     InsetRect(&tempRect, 1, 1);
  521.     AvgWctbForeColor(window, wTitleBarLight, wTitleBarDark, 
  522.                      light ? wGrowBoxColorLt : wGrowBoxColorDk);
  523.     PaintRect(&tempRect);
  524. }
  525.  
  526. // -----------------------------------------------------------------------------
  527.  
  528. static void 
  529. DrawGrowBox(WindowPeek window, short variation, Rect *theRect) {
  530.     Rect smallRect; 
  531.     Rect largeRect;
  532.     
  533.     if (!(WindData.ignoreHilite || window->hilited)) { 
  534.  
  535.         switch (variation) {
  536. #ifndef SYS7_OR_LATER
  537.             case sys6color:
  538. #endif
  539.             case sys7color:
  540.                 WctbForeColor(window, wFrameColor);
  541.                 WctbBackColor(window, wContentColor);
  542.                 break;
  543.         }
  544.         FrameBox(theRect);
  545.     } else {
  546.     
  547.         //    Add the size box chevrons.
  548.  
  549. #ifndef SMALL_GROW        // normal grow box
  550.         SetRect(&smallRect, theRect->left + 3, theRect->top + 3,
  551.                             theRect->left + 10, theRect->top + 10);
  552.         SetRect(&largeRect, smallRect.left + 2, smallRect.top + 2, 
  553.                             theRect->right - 2, theRect->bottom - 2);
  554. #else
  555.         SetRect(&smallRect, theRect->left + 2, theRect->top + 2,
  556.                             theRect->left + 7, theRect->top + 7);
  557.         SetRect(&largeRect, smallRect.left + 1, smallRect.top + 1, 
  558.                             theRect->right - 2, theRect->bottom - 2);
  559. #endif
  560.  
  561.         switch (variation) {
  562.             case blackandwhite:
  563. #ifndef SYS7_OR_LATER
  564.             case sys6color:
  565.                 if (variation == sys6color)
  566.                     WctbForeColor(window, wFrameColor);
  567.                 else
  568. #endif
  569.                     ColorsNormal();
  570.                 FrameBox(theRect);
  571.                 
  572.                 FrameRect(&largeRect);
  573.                 FrameBox(&smallRect);
  574.                 break;
  575.             
  576.             case sys7color:
  577.                 WctbForeColor(window, wFrameColor);
  578.                 AvgWctbBackColor(window, wHiliteColorLight, wHiliteColorDark, 
  579.                                  wGrowBoxBackground);
  580.                 FrameBox(theRect);
  581.                 
  582.  
  583.                 //    Draw the dark border parts for the bottom rectangle
  584.  
  585. #ifndef SMALL_GROW
  586.                 OffsetRect(&largeRect, -1, -1);
  587. #endif
  588.                 DrawGrow3DBox(window, &largeRect, false);
  589.                 
  590.  
  591.                 //    Draw the dark border parts for the top rectangle
  592.  
  593. #ifndef SMALL_GROW
  594.                 smallRect.right--;
  595.                 smallRect.bottom--;
  596. #endif
  597.                 DrawGrow3DBox(window, &smallRect, true);
  598.                 break;
  599.         }
  600.     }
  601. }
  602.  
  603. #endif
  604. // -----------------------------------------------------------------------------
  605.  
  606. static void
  607. GetTitlebarPat(Boolean active, Point *corner, Pattern *titlePat) {
  608.  
  609.     // Choose correct pattern, depending on position of window in global
  610.     // coordinates. (Concept of new (2.3) version taken from _Macintosh 
  611.     // Programming Secrets_, Second Edition, by Scott Knaster and Keith 
  612.     // Rollin, page 423.)
  613.  
  614.     long seed;
  615.  
  616.     if (active)
  617.         seed = 0x00550055;
  618.     else
  619.         seed = 0x00000000;
  620.  
  621. #ifdef THICK_TITLEBAR
  622.     if (IsOdd(corner->h))
  623.         seed <<= 1;
  624.     if (IsOdd(corner->v))
  625.         seed <<= 8;
  626. #else
  627.     if (IsEven(corner->h))
  628.         seed <<= 1;
  629.     if (IsEven(corner->v))
  630.         seed <<= 8;
  631. #endif
  632.  
  633.     *((long*) titlePat + 1) = *((long*) titlePat) = seed;
  634. }
  635.  
  636. //*****************************************************************************
  637. //    SubtractGadgetRect
  638. //-----------------------------------------------------------------------------
  639.  
  640. static void
  641. SubtractGadgetRect(RgnHandle theRgn, const Rect *theRect) {
  642.     Rect subRect = *theRect;
  643.     RgnHandle subRgn = NewRgn();
  644.     
  645. #ifdef THICK_TITLEBAR
  646.     InsetRect(&subRect, -kTingeInset, -kTingeInset);
  647.         // to give the correct visual appearance
  648. #endif
  649.     
  650.     RectRgn(subRgn, &subRect);
  651.     DiffRgn(theRgn, subRgn, theRgn);
  652.     
  653.     DisposeRgn(subRgn);
  654. }
  655.  
  656. // *****************************************************************************
  657. //    DrawTitleString
  658. // -----------------------------------------------------------------------------
  659.     // when this routine is called, the background color will be set to the
  660.     // color of the background of the titlebar
  661.  
  662. static void
  663. DrawTitleString(WindowPeek window, short variation, 
  664.                 const Rect *titleRect, Boolean active, 
  665.                 Rect *stringRect) {
  666. #ifdef TITLE_STRING
  667.     short maxWidth;
  668.     short titleWidth;
  669.     short inset;
  670.     short strAreaLeft;
  671.     Rect titleStrBounds;
  672.     RGBColor saveFore;
  673.     RgnHandle saveClip = NewRgn();
  674.     RgnHandle clipRgn = NewRgn();
  675.     
  676.     if (window->titleHandle != nil && (*window->titleHandle)[0] != 0
  677.         && WindData.isHoriz) {
  678.         maxWidth = titleRect->right - titleRect->left - 2 * kGadgetMargin;
  679.         strAreaLeft = titleRect->left + kGadgetMargin;
  680.         if (window->goAwayFlag || window->spareFlag) {
  681.             maxWidth -= 2 * (kGadgetSize + kGadgetMargin);
  682.             strAreaLeft += kGadgetSize + kGadgetMargin;
  683.         }
  684.         
  685.         if (maxWidth > 0) {
  686.  
  687.             //    Set up fonts, colors for text drawing
  688.  
  689.             TextFont(kTitleFont);
  690.             TextSize(kTitleSize);
  691.             TextFace(kTitleStyle);
  692.             TextMode(srcOr);
  693.             HLock((Handle) window->titleHandle);
  694.             
  695.             if (variation != blackandwhite)
  696.                 GetForeColor(&saveFore);
  697.             SetWTitleColor(window, variation, active);
  698.             
  699.             //    Calculate the width of the title string
  700.             
  701.             titleWidth = StringWidth(*window->titleHandle)
  702.                          + 2 * kTitleMargin;
  703.             
  704.             
  705.             //    Limit its size to maxWidth
  706.             
  707.             titleWidth = (titleWidth > maxWidth) ? maxWidth : titleWidth;
  708.             
  709.             
  710.             //    Determine where to position it
  711.             
  712.             inset = (short) (maxWidth - titleWidth) / 2;
  713.  
  714.  
  715.             //    The following is done to make the title appear centered
  716.  
  717.             if (IsEven(titleWidth))                // We need an odd width or  
  718.                 titleWidth--;                    // the overlap is wrong
  719.  
  720. #ifndef THICK_TITLEBAR
  721.             inset -= IsOdd(inset);
  722.                 // This is done so that the title doesn't shift as the window's
  723.                 // width changes.
  724. #else
  725.             inset -= IsEven(inset);
  726. #endif
  727.                 
  728.             SetRect(&titleStrBounds, strAreaLeft + inset, 
  729.                                      titleRect->top + 1, 
  730.                                      strAreaLeft + inset + titleWidth, 
  731.                                      titleRect->bottom - 1); 
  732.  
  733. #ifdef THICK_TITLEBAR
  734.             
  735.             //    Inset the bounds so as not to erase part of the tinges
  736.             
  737.             if (active)
  738.                 InsetRect(&titleStrBounds, 0, kTingeInset);
  739.  
  740. #endif        
  741.  
  742.             //    Make sure this area is cleared to the titlebar background color
  743.             
  744.             EraseRect(&titleStrBounds);
  745.  
  746. #ifdef THICK_TITLEBAR
  747.  
  748.             //    Outset it so decenders may overwrite the bottom tinge
  749.             
  750.             if (active)
  751.                 InsetRect(&titleStrBounds, 0, -kTingeInset);
  752.  
  753. #endif        
  754.  
  755.             //    Return the title string area's boundry
  756.  
  757.             *stringRect = titleStrBounds;
  758.             
  759.             GetClip(saveClip);
  760.             
  761.             
  762.             //    Get the region the title string should go into
  763.             
  764.             InsetRect(&titleStrBounds, kTitleMargin, 0);
  765.             RectRgn(clipRgn, &titleStrBounds);
  766.             
  767.             
  768.             //    Make sure we don't clobber other windows
  769.             
  770.             SectRgn(saveClip, clipRgn, clipRgn);
  771.             SetClip(clipRgn);
  772.  
  773.  
  774.             //    Draw the title
  775.             
  776.             MoveTo(titleStrBounds.left, titleStrBounds.bottom - kTitleVDelta);
  777.             DrawString(*window->titleHandle);
  778.     
  779.     
  780.             //    Clean up
  781.             
  782.             SetClip(saveClip);
  783.  
  784.             if (variation != blackandwhite)
  785.                 RGBForeColor(&saveFore);
  786.  
  787.             HUnlock((Handle) window->titleHandle);
  788.             TextFont(systemFont);
  789.             TextSize(0);
  790.             TextFace(0);
  791.         }
  792.     }
  793.     DisposeRgn(saveClip);
  794.     DisposeRgn(clipRgn);
  795. #else
  796.     #pragma unused (window, variation, titleRect, active, stringRect)
  797. #endif
  798. }
  799.  
  800. // *****************************************************************************
  801. //    DrawTitleBar -- Draw pattern/title into the title bar
  802. // -----------------------------------------------------------------------------
  803.     //    This routine actually draws the pattern into the titlebar. Note: it
  804.     //    takes a Rect as a parameter (not by address) because it goes ahead and
  805.     //    modifies it. I figured this was no worse than needing to copy it into
  806.     //    a local variable, so I went ahead and did it this way.
  807.  
  808. static void 
  809. DrawTitleBar(WindowPeek window, short variation, const Rect *titleRect,
  810.              Boolean active) {
  811.     Rect        tempRect;
  812.     Rect        insetTitleRect;
  813.     Rect        stringRect;
  814.     Pattern        pat;
  815.     RgnHandle    titleRgn = NewRgn();
  816.     
  817.     SetRect(&stringRect, 0, 0, 0, 0);
  818.     
  819.     if (active)
  820.         DrawTitlebarTinges(window, variation, titleRect);
  821.     
  822.     SetWTitleBarColors(window, variation, active);
  823.     
  824.  
  825.     //    Set up the starting region to be the whole titlebar, 
  826.     //    parts will then be 'punched out' of it.
  827.  
  828.     insetTitleRect = *titleRect;
  829.     InsetRect(&insetTitleRect, 1, 1);
  830.     
  831.     if (active)
  832.         InsetRect(&insetTitleRect, kTingeInset, kTingeInset);
  833.     
  834.     RectRgn(titleRgn, &insetTitleRect);
  835.     
  836.     DrawTitleString(window, variation, titleRect, active, &stringRect);
  837.         // since the area affected by the title string is returned in
  838.         // stringRect, we can use it's left and right to draw the pattern
  839.     
  840.     if (!EmptyRect(&stringRect)) {
  841.         RgnHandle tempRgn = NewRgn();
  842.         
  843.         RectRgn(tempRgn, &stringRect);
  844.         DiffRgn(titleRgn, tempRgn, titleRgn);
  845.         
  846.         DisposeRgn(tempRgn);
  847.     }
  848.     
  849.  
  850.     //    Subtract the Close Box
  851.  
  852.     if (active && window->goAwayFlag) {
  853.         GetCloseBox(window, titleRect, &tempRect);
  854.         SubtractGadgetRect(titleRgn, &tempRect);
  855.     }
  856.  
  857. #ifdef ALLOW_ZOOM
  858.  
  859.     //    Subtract the Zoom Box
  860.  
  861.     if (active && window->spareFlag) {
  862.         GetZoomBox(window, titleRect, &tempRect);
  863.         SubtractGadgetRect(titleRgn, &tempRect);
  864.     }
  865. #endif
  866.     
  867.     GetTitlebarPat(active, (Point*) &titleRect->top, (Pattern*) &pat);
  868.     FillRgn(titleRgn, (ConstPatternParam) &pat);
  869.     
  870.     DisposeRgn(titleRgn);
  871. }
  872.  
  873. ////// *************************************************************************
  874. /////
  875. ////    Zoom handling                                                     
  876. ///
  877. // -----------------------------------------------------------------------------
  878. #ifdef ALLOW_ZOOM
  879.     
  880. static void 
  881. SetZoomRects(WindowPeek window) {
  882.     Rect contRect;
  883.     
  884.     if (window->spareFlag) {
  885.         GetGlobalContentRect(window, &contRect);
  886.         WindData.wState.stdState = contRect;
  887. #ifdef MFI_ZOOM
  888.         if (WindData.isHoriz)                            // titlebar on top
  889.             contRect.bottom = contRect.top + 12;
  890.         else                                            // titlebar on left
  891.             contRect.right = contRect.left + 12;
  892. #endif
  893.         WindData.wState.userState = contRect;
  894.             //    The stdState and user state might be backwards from how they
  895.             //    would normally be used by an application. Check this for your
  896.             //    own use and change them if necessary.
  897.     }
  898. }
  899.  
  900. // -----------------------------------------------------------------------------
  901.  
  902. static long 
  903. GetZoomHitType(WindowPeek window) {
  904.     Rect contRect;
  905.     Rect stdRect;
  906.     
  907.     contRect = (**(window->contRgn)).rgnBBox;
  908.     stdRect = WindData.wState.stdState;
  909.     OffsetRect(&stdRect, -stdRect.left + contRect.left, 
  910.                          -stdRect.top + contRect.top);
  911.         // make topLeft the same for content and standard rects, and compare
  912.  
  913.     if (EqualRect(&contRect, &stdRect))
  914.         return wInZoomIn;        // go to user state (make small, MFI)
  915.     else
  916.         return wInZoomOut;        // go to standard state (make normal, MFI)
  917. }
  918.  
  919. #endif
  920. ////// *************************************************************************
  921. /////
  922. ////    DoWInit -- Windoid initialization                                                     
  923. ///
  924. // -----------------------------------------------------------------------------
  925.  
  926. void 
  927. DoWInit(WindowPeek window, long param, short varCode) {
  928.     #pragma unused(param)
  929.     Handle zoomDataHndl;
  930.     WindoidDataPtr wdata;
  931.  
  932.     window->spareFlag = false;
  933.     zoomDataHndl = NewHandle(sizeof(WindoidData));
  934.     if (zoomDataHndl) {
  935.         wdata = (WindoidDataPtr) *zoomDataHndl;        // make it easier to access
  936.         
  937.         wdata->closeToggle         = 0;
  938.         wdata->hasTitlebar        = true;
  939.         wdata->ignoreHilite        = false;
  940.  
  941. #ifdef ALLOW_GROW
  942.  
  943.     #ifdef MACAPP_STYLE
  944.         wdata->hasGrow            = (varCode & kMacApp_hasGrow) != 0;
  945.     #else
  946.         wdata->hasGrow            = (varCode & noGrowDocProc) == 0;
  947.     #endif
  948.  
  949. #endif
  950.  
  951. #ifdef ALLOW_VERT
  952.         wdata->isHoriz             = !((varCode & 1) || (varCode & 2));
  953. #else
  954.         wdata->isHoriz             = true;
  955. #endif
  956.  
  957. #ifdef ALWAYS_HILITE
  958.         wdata->ignoreHilite        = true;
  959. #endif
  960.  
  961. #ifdef MACAPP_STYLE
  962.         wdata->ignoreHilite        = !(kMacApp_toggleTBar & varCode);
  963. #endif
  964.  
  965. #ifdef THINK_STYLE
  966.         if ((varCode & 7) != 0 && (varCode & 7) != 2)
  967.             wdata->hasTitlebar    = false;
  968. #endif
  969.  
  970.  
  971.         //    Set the window's data handle to the right value
  972.         
  973.         window->dataHandle         = zoomDataHndl;
  974.  
  975.  
  976. #ifdef ALLOW_ZOOM
  977.         wdata->zoomToggle        = 0;
  978.         window->spareFlag        = (zoomDocProc & varCode);
  979.         SetZoomRects(window);
  980. #endif
  981.  
  982.     }
  983. }
  984.  
  985. ////// *************************************************************************
  986. /////
  987. ////    DoWDispose -- Windoid disposal                                                     
  988. ///
  989. // -----------------------------------------------------------------------------
  990.  
  991. void 
  992. DoWDispose(WindowPeek window, long param) {
  993.     #pragma unused(param)
  994.  
  995.     if (window->dataHandle)
  996.         DisposeHandle(window->dataHandle);
  997. }
  998.  
  999. ////// *************************************************************************
  1000. /////
  1001. ////    DoWHit -- Windoid hit routine                                                     
  1002. ///
  1003. // -----------------------------------------------------------------------------
  1004.  
  1005. long 
  1006. DoWHit(WindowPeek window, long param) {
  1007.     Rect    titleRect;
  1008.     Rect    theRect;
  1009.     Point    hitPt;
  1010.     long    result;
  1011. #ifdef ALLOW_ZOOM
  1012.     Rect    stdRect;
  1013.     Rect    usrRect;
  1014.     Rect    contentRect;
  1015. #endif
  1016.  
  1017.     hitPt.v = HiWord(param);
  1018.     hitPt.h = LoWord(param);
  1019.     
  1020.     result = wNoHit;
  1021.     if (PtInRgn(hitPt, window->contRgn)) {
  1022.         result = wInContent;
  1023.  
  1024. #ifdef ALLOW_GROW
  1025.  
  1026.         // Look for a Grow region hit
  1027.         
  1028.         if (WindData.hasGrow) {
  1029.             GetGrowBox(window, &theRect);
  1030.             InsetRect(&theRect, -1, -1);
  1031.             if (PtInRect(hitPt, &theRect))
  1032.                 result = wInGrow; 
  1033.         }
  1034.         
  1035. #endif
  1036.  
  1037.     } else {
  1038.         GetTitleBar(window, &titleRect);
  1039.         if (WindData.hasTitlebar && PtInRect(hitPt, &titleRect)) {
  1040.             result = wInDrag;
  1041.             if (WindData.ignoreHilite || window->hilited) {
  1042.  
  1043.                 if (window->goAwayFlag) {
  1044.                     GetCloseBox(window, &titleRect, &theRect);
  1045.                     InsetRect(&theRect, -kGadgetHitFudge, -kGadgetHitFudge);
  1046.                     if (PtInRect(hitPt, &theRect))
  1047.                         result = wInGoAway;
  1048.                 }
  1049.  
  1050. #ifdef ALLOW_ZOOM
  1051.                 if (window->spareFlag) {
  1052.                     GetZoomBox(window, &titleRect, &theRect);
  1053.                     InsetRect(&theRect, -kGadgetHitFudge, -kGadgetHitFudge);
  1054.                     if (PtInRect(hitPt, &theRect)) {
  1055.                         result = GetZoomHitType(window);
  1056.                         
  1057.                         //    Calculate Offset for Zoom Rects (make sure they
  1058.                         //    are up to date)
  1059.                         
  1060.                         contentRect = (**(window->contRgn)).rgnBBox;
  1061.                         stdRect = WindData.wState.stdState;
  1062.                         usrRect = WindData.wState.userState;
  1063.                         
  1064. #ifdef STAYPUT_ZOOM
  1065.                         OffsetRect(&(WindData.wState.stdState), 
  1066.                                    contentRect.left - stdRect.left,
  1067.                                    contentRect.top  - stdRect.top);
  1068.                         OffsetRect(&(WindData.wState.userState), 
  1069.                                    contentRect.left - usrRect.left, 
  1070.                                    contentRect.top  - usrRect.top);
  1071. #else
  1072.                         if (result == wInZoomIn) {
  1073.                             OffsetRect(&(WindData.wState.stdState), 
  1074.                                        contentRect.left - stdRect.left,
  1075.                                        contentRect.top  - stdRect.top);
  1076.                         } else {
  1077.                             OffsetRect(&(WindData.wState.userState), 
  1078.                                        contentRect.left - usrRect.left, 
  1079.                                        contentRect.top  - usrRect.top);
  1080.                         }
  1081. #endif                        
  1082.                     }
  1083.                 }
  1084. #endif
  1085.             }
  1086.         }
  1087.     }
  1088.     return result;
  1089. }
  1090.  
  1091. ////// *************************************************************************
  1092. /////
  1093. ////    DoWDraw -- Windoid drawing routines                                                     
  1094. ///
  1095. // -----------------------------------------------------------------------------
  1096.  
  1097. typedef struct {
  1098.     WindowPeek    wdlWindow;
  1099.     long        wdlParam;
  1100. } WDLDataRec;
  1101.     // This information is used to communicate with DeviceLoop callback routine
  1102.  
  1103. // *****************************************************************************
  1104. //    Windoid drawing loop
  1105. // -----------------------------------------------------------------------------
  1106.     // This routine actually does the real work of the drawing of stuff into
  1107.     // the window.
  1108.  
  1109. static pascal void 
  1110. WindoidDrawLoop(short depth, short deviceFlags, 
  1111.                 GDHandle targetDevice, WDLDataRec *userData) {
  1112.     WindowPeek window;
  1113.     Rect titleRect;
  1114.     Rect tempRect;
  1115.     short variation;
  1116.  
  1117.     window = userData->wdlWindow;    // make sure our macros work
  1118.     variation = CheckDisplay(depth, deviceFlags, targetDevice, window);
  1119.     
  1120.     switch (userData->wdlParam) {
  1121.         case wNoHit:
  1122.             BackColor(whiteColor);
  1123.             
  1124.  
  1125.             //    Frame titlebar
  1126.  
  1127.             if (WindData.hasTitlebar) {
  1128.                 GetTitleBar(window, &titleRect);
  1129.                 SetWFrameColor(window, variation);
  1130.                 FrameRect(&titleRect);
  1131.             }
  1132.             
  1133.             if (WindData.ignoreHilite || window->hilited) {
  1134.  
  1135.                 //    Draw titlebar interior
  1136.  
  1137.                 if (WindData.hasTitlebar)
  1138.                     DrawTitleBar(window, variation, &titleRect, true);
  1139.                 
  1140.  
  1141.                 //    Draw close box
  1142.  
  1143.                 if (window->goAwayFlag) {    
  1144.                     GetCloseBox(window, &titleRect, &tempRect);
  1145.                     DrawCloseBox(window, variation, &tempRect);
  1146.                 }
  1147.                     // Note: I have seen at least one windoid WDEF that is used
  1148.                     // by some applications that does not utilize this flag.
  1149.                     // In that case, I think it always had a close box (or it
  1150.                     // might even have used the varcode to determine this, but
  1151.                     // that wouldn't seem to be a good thing to do).
  1152.  
  1153. #ifdef ALLOW_ZOOM
  1154.  
  1155.                 //    Draw zoom box
  1156.  
  1157.                 if (window->spareFlag) {
  1158.                     GetZoomBox(window, &titleRect, &tempRect);
  1159.                     DrawZoomBox(window, variation, &tempRect);
  1160.                 }
  1161. #endif
  1162.             } else {
  1163.  
  1164.                 //    Draw dimmed titlebar
  1165.  
  1166.                 DrawTitleBar(window, variation, &titleRect, false);
  1167.             }
  1168.             
  1169.             
  1170.             //    Draw content frame and shadow
  1171.  
  1172.             tempRect = (**window->strucRgn).rgnBBox;
  1173.             tempRect.bottom--;
  1174.             tempRect.right--;
  1175.             
  1176.             SetWFrameColor(window, variation);
  1177.             FrameRect(&tempRect);
  1178.             
  1179.  
  1180.             //    Draw Shadow
  1181.  
  1182.             OffsetRect(&tempRect, 1, 1);
  1183.             FrameBottomRightShading(tempRect);
  1184.             break;
  1185.  
  1186.  
  1187.         //    Toggle Go-Away Box
  1188.  
  1189.         case wInGoAway:
  1190.             GetTitleBar(window, &titleRect);
  1191.             GetCloseBox(window, &titleRect, &tempRect);
  1192.             if (WindData.closeToggle)
  1193.                 DrawCloseBox(window, variation, &tempRect);
  1194.             else
  1195.                 DrawXedBox(window, variation, &tempRect);
  1196.             break;
  1197.         
  1198. #ifdef ALLOW_ZOOM
  1199.  
  1200.         //    Toggle Zoom Box
  1201.  
  1202.         default:
  1203.             if (window->spareFlag) {
  1204.                 GetTitleBar(window, &titleRect);
  1205.                 GetZoomBox(window, &titleRect, &tempRect);
  1206.                 if (WindData.zoomToggle)
  1207.                     DrawZoomBox(window, variation, &tempRect);
  1208.                 else
  1209.                     DrawXedBox(window, variation, &tempRect);
  1210.             }
  1211.             break;
  1212. #endif
  1213.     }
  1214.     ColorsNormal();
  1215. }
  1216.  
  1217. // -----------------------------------------------------------------------------
  1218.  
  1219. void 
  1220. DoWDraw(WindowPeek window, long param) {
  1221.     WDLDataRec theUserData;
  1222.  
  1223.     if (window->visible) {
  1224.         theUserData.wdlWindow = window;
  1225.         theUserData.wdlParam = param;
  1226.  
  1227. #ifdef UNIV_HEADERS
  1228.         {
  1229.             DeviceLoopDrawingUPP uppDrawProc;
  1230.             
  1231.             uppDrawProc = NewDeviceLoopDrawingProc(WindoidDrawLoop);
  1232.             OurDeviceLoop(window->strucRgn, uppDrawProc, 
  1233.                           (long) &theUserData, (DeviceLoopFlags) 0);
  1234.             
  1235.             DisposeRoutineDescriptor(uppDrawProc);
  1236.         }
  1237. #else
  1238.         OurDeviceLoop(window->strucRgn, 
  1239.                       (DeviceLoopDrawingProcPtr) WindoidDrawLoop, 
  1240.                       (long) &theUserData, (DeviceLoopFlags) 0);
  1241. #endif
  1242.  
  1243.         switch (param) {
  1244.             case wNoHit:
  1245.                 //    This is so param 0 doesn't get interpreted as a hit in the
  1246.                 //    zoom box, incorrectly.
  1247.                 break;
  1248.                 
  1249.             case wInGoAway:                        // toggle go-away
  1250.                 WindData.closeToggle = ! WindData.closeToggle;
  1251.                 break;
  1252.             
  1253. #ifdef ALLOW_ZOOM
  1254.             default:                            // toggle zoom box
  1255.                 WindData.zoomToggle = ! WindData.zoomToggle;
  1256.                 break;
  1257. #endif
  1258.         }
  1259.     }
  1260. }
  1261.  
  1262. ////// *************************************************************************
  1263. /////
  1264. ////    DoWCalcRgns -- Windoid region calculating routine                                                     
  1265. ///
  1266. // -----------------------------------------------------------------------------
  1267.  
  1268. void 
  1269. DoWCalcRgns(WindowPeek window, long param) {
  1270.     #pragma unused(param)
  1271.     Rect theRect;
  1272.     RgnHandle tempRgn = NewRgn();
  1273.  
  1274.  
  1275.     //    Calculate the content Rect in global coordinates
  1276.     
  1277.     GetGlobalContentRect(window, &theRect);
  1278.     RectRgn(window->contRgn, &theRect);
  1279.  
  1280.  
  1281.     //    Start off with the structure equal to the content
  1282.     //    & make it include the window frame and titlebar
  1283.     
  1284.     InsetRect(&theRect, -1, -1);
  1285.     if (WindData.hasTitlebar) {
  1286.         if (WindData.isHoriz)
  1287.             theRect.top -= kTitleHeight - 1;
  1288.         else
  1289.             theRect.left -= kTitleHeight - 1;
  1290.     }
  1291.     RectRgn(window->strucRgn, &theRect);
  1292.     
  1293.     
  1294.     //    Add the shadow to the structure 
  1295.     
  1296.     OffsetRect(&theRect, 1, 1);
  1297.     RectRgn(tempRgn, &theRect);
  1298.     UnionRgn(tempRgn, window->strucRgn, window->strucRgn);
  1299.     
  1300.     DisposeRgn(tempRgn);
  1301. }
  1302.  
  1303. ////// *************************************************************************
  1304. /////
  1305. ////    DoWGrow -- Draw the growing outline                                                     
  1306. ///
  1307. // -----------------------------------------------------------------------------
  1308.  
  1309. void 
  1310. DoWGrow(WindowPeek window, long param) {
  1311. #ifdef ALLOW_GROW
  1312.     #pragma unused(window)
  1313.     Rect growingRect = *(Rect*) param;
  1314.     
  1315.     if (WindData.isHoriz)
  1316.         growingRect.top  -= kTitleHeight - 1;    // add room for the title bar
  1317.     else
  1318.         growingRect.left -= kTitleHeight - 1;    // add room for the title bar
  1319.     InsetRect(&growingRect, -1, -1);
  1320.     
  1321.     
  1322.     //    Draw the window frame.
  1323.     
  1324.     FrameRect(&growingRect);
  1325.     
  1326.     if (WindData.isHoriz)
  1327.         growingRect.top  += kTitleHeight - 1;
  1328.     else
  1329.         growingRect.left += kTitleHeight - 1;
  1330.     
  1331.     
  1332.     //    Now mark the title bar area
  1333.     
  1334.     MoveTo(growingRect.left, growingRect.top);
  1335.     if (WindData.isHoriz)
  1336.         LineTo(growingRect.right - 2, growingRect.top);
  1337.     else
  1338.         LineTo(growingRect.left, growingRect.bottom - 2);
  1339.     
  1340.     
  1341.     //    Mark the scroll bars too
  1342.     
  1343.     MoveTo(growingRect.right - kScrollBarPixels, growingRect.top + 1);
  1344.     LineTo(growingRect.right - kScrollBarPixels, growingRect.bottom - 2);
  1345.     
  1346.     MoveTo(growingRect.left, growingRect.bottom - kScrollBarPixels);
  1347.     LineTo(growingRect.right - 2, growingRect.bottom - kScrollBarPixels);       
  1348. #else
  1349.     #pragma unused(window, param)
  1350. #endif
  1351. }
  1352.  
  1353. ////// *************************************************************************
  1354. /////
  1355. ////    DoWDrawGIcon -- Draw the grow icon and scroll frame in the lower right                                                     
  1356. ///
  1357. // -----------------------------------------------------------------------------
  1358. #ifdef ALLOW_GROW
  1359.  
  1360. static pascal void 
  1361. GrowBoxDrawLoop(short depth, short deviceFlags, 
  1362.                 GDHandle targetDevice, WDLDataRec *userData) {
  1363.     WindowPeek window;
  1364.     Rect theRect;
  1365.     short variation;
  1366.  
  1367.     window = userData->wdlWindow;    // make sure our macros work
  1368.     variation = CheckDisplay(depth, deviceFlags, targetDevice, window);
  1369.     
  1370.     GetGrowBox(window, &theRect);
  1371.     DrawGrowBox(window, variation, &theRect);
  1372.     
  1373.     ColorsNormal();
  1374. }
  1375.  
  1376. #endif
  1377. // -----------------------------------------------------------------------------
  1378.  
  1379. void 
  1380. DoWDrawGIcon(WindowPeek window, long param) {
  1381. #ifdef ALLOW_GROW
  1382.     #pragma unused(param)
  1383.  
  1384.     if (window->visible && WindData.hasGrow) {
  1385.         WDLDataRec theUserData;
  1386.         RgnHandle saveClip = NewRgn();
  1387.         RgnHandle tempRgn = NewRgn();
  1388.         Point mappingPoint;
  1389.         
  1390.         SectRgn(window->port.visRgn, window->port.clipRgn, tempRgn);
  1391.  
  1392.         GetClip(saveClip);
  1393.         
  1394.         GetGlobalMappingPoint(window, &mappingPoint);
  1395.         OffsetRgn(tempRgn, mappingPoint.h, mappingPoint.v);
  1396.         
  1397.         SetClip(tempRgn);
  1398.         
  1399.         theUserData.wdlWindow = window;
  1400.  
  1401. #ifdef UNIV_HEADERS
  1402.         {
  1403.             DeviceLoopDrawingUPP uppDrawProc;
  1404.             
  1405.             uppDrawProc = NewDeviceLoopDrawingProc(GrowBoxDrawLoop);
  1406.             OurDeviceLoop(window->strucRgn, uppDrawProc, 
  1407.                           (long) &theUserData, (DeviceLoopFlags) 0);
  1408.             
  1409.             DisposeRoutineDescriptor(uppDrawProc);
  1410.         }
  1411. #else
  1412.         OurDeviceLoop(window->strucRgn, 
  1413.                       (DeviceLoopDrawingProcPtr) GrowBoxDrawLoop, 
  1414.                       (long) &theUserData, (DeviceLoopFlags) 0);
  1415. #endif
  1416.  
  1417.         SetClip(saveClip);
  1418.  
  1419.         DisposeRgn(saveClip);
  1420.         DisposeRgn(tempRgn);
  1421.     }
  1422. #else
  1423.     #pragma unused(window, param)
  1424. #endif
  1425. }
  1426.  
  1427. // *****************************************************************************
  1428.