home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / macintosh-c / macc-carbon-demos-nonbinhex.sit / macc-carbon-demos-nonbinhex / chap13-demo / GWorldPicCursIcn.c < prev    next >
C/C++ Source or Header  |  2001-05-09  |  32KB  |  1,231 lines

  1. // *******************************************************************************************
  2. // GWorldPicCursIcon.c                                                     CLASSIC EVENT MODEL
  3. // *******************************************************************************************
  4. // 
  5. // This program demonstrates offscreen graphics world, picture, cursor, cursor shape change,
  6. // animated cursor, and icon operations as a result of the user choosing items from a 
  7. // Demonstration menu.  It also demonstrates a modal dialog-based About… box containing a 
  8. // picture.
  9. //
  10. // To keep the non-demonstration code to a minimum, the program contains no functions for
  11. // updating the window or for responding to activate and operating system events.
  12. //
  13. // The program utilises the following resources:
  14. //
  15. // •    A 'plst' resource.
  16. //
  17. // •    An 'MBAR' resource and associated 'MENU' resources (preload, non-purgeable).
  18. //
  19. // •    A 'WIND' resource (purgeable) (initially visible). 
  20. //
  21. // •    An 'acur' resource (purgeable).
  22. //
  23. // •    'CURS' resources associated with the 'acur' resource (preload, purgeable).
  24. //
  25. // •    Two 'cicn' resources (purgeable), one for the Icons menu item and one for drawing in the
  26. //        window.
  27. //
  28. // •    Two icon family resources (purgeable), both for drawing in the window.
  29. //
  30. // •    A 'DLOG' resource (purgeable) and an associated 'DITL' resource (purgeable) and 'PICT'
  31. //        resource for an About GWorldPicCursIcon… dialog box.
  32. //
  33. // •    A 'STR#' resource (purgeable) containing transform constants.
  34. //
  35. // •    A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground, 
  36. //        doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
  37. //
  38. // *******************************************************************************************
  39.  
  40. // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… includes
  41.  
  42. #include <Carbon.h>
  43.  
  44. // …………………………………………………………………………………………………………………………………………………………………………………………………………………………… defines
  45.  
  46. #define rMenubar                                    128
  47. #define rWindow                                        128
  48. #define mAppleApplication                    128
  49. #define  iAbout                                        1
  50. #define mFile                                            129
  51. #define  iQuit                                        12
  52. #define mDemonstration                        131
  53. #define  iOffScreenGWorld1                1
  54. #define  iOffScreenGWorld2                2
  55. #define  iPicture                                    3
  56. #define  iCursor                                    4
  57. #define  iAnimatedCursor1                    5
  58. #define  iAnimatedCursor2                    6
  59. #define  iAnimatedCursorOSX                7
  60. #define  iIcon                                        8
  61. #define rBeachBallCursor                    128
  62. #define rPicture                                    128
  63. #define rTransformStrings                    128
  64. #define rIconFamily1                            128
  65. #define rIconFamily2                            129
  66. #define rColourIcon                                128
  67. #define rAboutDialog                            128
  68. #define kSleepTime                                1
  69. #define kBeachBallTickInterval        5
  70. #define kCountingHandTickInterval    30
  71. #define MAX_UINT32                                0xFFFFFFFF
  72. #define topLeft(r)                                (((Point *) &(r))[0])
  73. #define botRight(r)                                (((Point *) &(r))[1])
  74.  
  75. // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… typedefs
  76.  
  77. typedef struct
  78. {
  79.     SInt16            numberOfFrames;
  80.     SInt16            whichFrame;
  81.     CursHandle    frame[];
  82. } animCurs, *animCursPtr, **animCursHandle;
  83.  
  84. // …………………………………………………………………………………………………………………………………………………………………………………………………… global variables
  85.  
  86. Boolean                    gRunningOnX = false;
  87. WindowRef                gWindowRef;
  88. Boolean                    gDone;
  89. SInt32                    gSleepTime;
  90. RgnHandle                gCursorRegion;
  91. Boolean                    gCursorRegionsActive            = false;
  92. Boolean                    gAnimatedCursor1Active        = false;
  93. Boolean                    gAnimatedCursor2Active        = false;
  94. Boolean                    gAnimatedCursorOSXActive    = false;
  95. animCursHandle    gAnimCursHdl;
  96. SInt16                    gAnimCursTickInterval;
  97. SInt32                    gAnimCursLastTick;
  98. RGBColor                gBlackColour    = { 0x0000, 0x0000, 0x0000 };
  99. RGBColor                gWhiteColour    = { 0xFFFF, 0xFFFF, 0xFFFF };
  100. RGBColor                gBeigeColour    = { 0xF000, 0xE300, 0xC200 };
  101. RGBColor                gBlueColour        = { 0x4444, 0x4444, 0x9999 };
  102.  
  103. // …………………………………………………………………………………………………………………………………………………………………………………………… function prototypes
  104.  
  105. void        main                                    (void);
  106. void        doPreliminaries                (void);
  107. OSErr        quitAppEventHandler        (AppleEvent *,AppleEvent *,SInt32);
  108. void        eventLoop                            (void);
  109. void        doIdle                                (void);
  110. void        doEvents                            (EventRecord *);
  111. void        doMenuChoice                    (SInt32);
  112. void        doOffScreenGWorld1        (void);
  113. void        doOffScreenGWorld2        (void);
  114. void        doPicture                            (void);
  115. void        doCursor                            (void);
  116. void        doChangeCursor                (WindowRef,RgnHandle);
  117. void        doAnimatedCursor1            (void);
  118. void        doAnimatedCursor2            (void);
  119. Boolean    doGetAnimCursor                (SInt16,SInt16);
  120. void        doIncrementAnimCursor    (void);
  121. void        doReleaseAnimCursor        (void);
  122. void        doAnimatedCursorOSX        (void);
  123. void        doIcon                                (void);
  124. void        doAboutDialog                    (void);
  125. void        doDrawStuff                        (void);
  126. UInt16    doRandomNumber                (UInt16,UInt16);
  127.  
  128. // ************************************************************************************** main
  129.  
  130. void  main(void)
  131. {
  132.     UInt32                seconds;
  133.     MenuBarHandle    menubarHdl;
  134.     SInt32                response;
  135.     MenuRef                menuRef;
  136.  
  137.     // ……………………………………………………………………………………………………………………………………………………………………………………… initialise managers
  138.  
  139.     doPreliminaries();
  140.  
  141.     // ……………………………………………………………………………………………………………………………………………………………… seed random number generator
  142.     
  143.     GetDateTime(&seconds);
  144.     SetQDGlobalsRandomSeed(seconds);
  145.  
  146.     // ……………………………………………………………………………………………………………………………………………………………………… set up menu bar and menus
  147.     
  148.     menubarHdl = GetNewMBar(rMenubar);
  149.     if(menubarHdl == NULL)
  150.         ExitToShell();
  151.     SetMenuBar(menubarHdl);
  152.     DrawMenuBar();
  153.  
  154.     Gestalt(gestaltMenuMgrAttr,&response);
  155.     if(response & gestaltMenuMgrAquaLayoutMask)
  156.     {
  157.         menuRef = GetMenuRef(mFile);
  158.         if(menuRef != NULL)
  159.         {
  160.             DeleteMenuItem(menuRef,iQuit);
  161.             DeleteMenuItem(menuRef,iQuit - 1);
  162.             DisableMenuItem(menuRef,0);
  163.         }
  164.     
  165.         menuRef = GetMenuRef(mDemonstration);
  166.         if(menuRef != NULL)
  167.             EnableMenuItem(menuRef,iAnimatedCursorOSX);
  168.  
  169.         gRunningOnX = true;
  170.     }
  171.  
  172.     // …………………………………………………………………………………………………………………………………………………………………………………………………………… open window
  173.  
  174.     if(!(gWindowRef = GetNewCWindow(rWindow,NULL,(WindowRef)-1)))
  175.         ExitToShell();
  176.  
  177.     SetPortWindowPort(gWindowRef);
  178.     TextSize(10);
  179.  
  180.     // ……………………………………………………………………………………………………………………………………………………………………………………………… enter event loop
  181.  
  182.     eventLoop();
  183. }
  184.  
  185. // ************************************************************************** do preliminaries
  186.  
  187. void  doPreliminaries(void)
  188. {
  189.     OSErr    osError;
  190.  
  191.     MoreMasterPointers(64);
  192.     InitCursor();
  193.     FlushEvents(everyEvent,0);
  194.  
  195.     osError = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
  196.                                                         NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler),
  197.                                                         0L,false);
  198.     if(osError != noErr)
  199.         ExitToShell();
  200. }
  201.  
  202. // **************************************************************************** doQuitAppEvent
  203.  
  204. OSErr  quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
  205. {
  206.     OSErr            osError;
  207.     DescType    returnedType;
  208.     Size            actualSize;
  209.  
  210.     osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0,
  211.                                                             &actualSize);
  212.  
  213.     if(osError == errAEDescNotFound)
  214.     {
  215.         gDone = true;
  216.         osError = noErr;
  217.     } 
  218.     else if(osError == noErr)
  219.         osError = errAEParamMissed;
  220.  
  221.     return osError;
  222. }
  223.  
  224. // ********************************************************************************* eventLoop
  225.  
  226. void  eventLoop(void)
  227. {
  228.     EventRecord    eventStructure;
  229.     Boolean            gotEvent;
  230.  
  231.     gDone = false;
  232.     gSleepTime = MAX_UINT32;
  233.     gCursorRegion = NULL;
  234.     
  235.     while(!gDone)
  236.     {
  237.         gotEvent = WaitNextEvent(everyEvent,&eventStructure,gSleepTime,gCursorRegion);
  238.         if(gotEvent)
  239.             doEvents(&eventStructure);
  240.         else
  241.         {
  242.             if(eventStructure.what == nullEvent)
  243.                 doIdle();
  244.         }
  245.     }
  246. }
  247.  
  248. // ************************************************************************************ doIdle
  249.  
  250. void  doIdle(void)
  251. {
  252.     if(gAnimatedCursor1Active || gAnimatedCursor2Active)
  253.         doIncrementAnimCursor();
  254. }
  255.  
  256. // ********************************************************************************** doEvents
  257.  
  258. void    doEvents(EventRecord *eventStrucPtr)
  259. {        
  260.     WindowRef                windowRef;
  261.     WindowPartCode    partCode;
  262.  
  263.     switch(eventStrucPtr->what)
  264.     {
  265.         case kHighLevelEvent:
  266.             AEProcessAppleEvent(eventStrucPtr);
  267.             break;
  268.  
  269.         case mouseDown:
  270.             partCode = FindWindow(eventStrucPtr->where,&windowRef);
  271.             switch(partCode)
  272.             {
  273.                 case inMenuBar:
  274.                     doMenuChoice(MenuSelect(eventStrucPtr->where));
  275.                     break;
  276.  
  277.                 case inContent:
  278.                     if(windowRef != FrontWindow())
  279.                         SelectWindow(windowRef);
  280.                     break;
  281.  
  282.                 case inDrag:
  283.                     DragWindow(windowRef,eventStrucPtr->where,NULL);
  284.                     if(gCursorRegionsActive)
  285.                         doChangeCursor(windowRef,gCursorRegion);
  286.                     break;
  287.             }
  288.             break;
  289.  
  290.         case keyDown:
  291.             if((eventStrucPtr->modifiers & cmdKey) != 0)
  292.                 doMenuChoice(MenuEvent(eventStrucPtr));
  293.             break;
  294.  
  295.         case updateEvt:
  296.             BeginUpdate((WindowRef) eventStrucPtr->message);
  297.             EndUpdate((WindowRef) eventStrucPtr->message);
  298.             break;
  299.  
  300.         case osEvt:
  301.             switch((eventStrucPtr->message >> 24) & 0x000000FF)
  302.             {
  303.                 case suspendResumeMessage:
  304.                     if((eventStrucPtr->message & resumeFlag) == 1)
  305.                         SetThemeCursor(kThemeArrowCursor);
  306.                     break;
  307.                 
  308.                 case mouseMovedMessage:
  309.                     if(gCursorRegionsActive)
  310.                         doChangeCursor(FrontWindow(),gCursorRegion);
  311.                     break;
  312.             }
  313.             break;
  314.     }
  315. }
  316.  
  317. // ****************************************************************************** doMenuChoice
  318.  
  319. void  doMenuChoice(SInt32 menuChoice)
  320. {
  321.     MenuID                menuID;
  322.     MenuItemIndex    menuItem;
  323.         
  324.     menuID = HiWord(menuChoice);
  325.     menuItem = LoWord(menuChoice);
  326.  
  327.     if(menuID == 0)
  328.         return;
  329.  
  330.     if(gAnimatedCursor1Active || gAnimatedCursor2Active)
  331.     {
  332.         if(gAnimatedCursor2Active)
  333.             doReleaseAnimCursor();
  334.  
  335.         SetThemeCursor(kThemeArrowCursor);
  336.         gSleepTime = MAX_UINT32;
  337.  
  338.         gAnimatedCursor1Active = false;
  339.         gAnimatedCursor2Active = false;
  340.     }
  341.     
  342.     if(gAnimatedCursorOSXActive)
  343.         doAnimatedCursorOSX();
  344.  
  345.     if(gCursorRegionsActive == true)
  346.     {
  347.         gCursorRegionsActive = false;
  348.         DisposeRgn(gCursorRegion);
  349.         gCursorRegion = NULL;
  350.     }
  351.  
  352.     switch(menuID)
  353.     {
  354.         case mAppleApplication:
  355.             if(menuItem == iAbout)
  356.                 doAboutDialog();
  357.             break;
  358.  
  359.         case mFile:
  360.             if(menuItem == iQuit)
  361.                 gDone = true;
  362.             break;
  363.  
  364.         case mDemonstration:
  365.             switch(menuItem)
  366.             {
  367.                 case iOffScreenGWorld1:
  368.                     doOffScreenGWorld1();
  369.                     break;            
  370.  
  371.                 case iOffScreenGWorld2:
  372.                     doOffScreenGWorld2();
  373.                     break;
  374.  
  375.                 case iPicture:
  376.                     doPicture();
  377.                     break;
  378.  
  379.                 case iCursor:
  380.                     doCursor();
  381.                     break;
  382.  
  383.                 case iAnimatedCursor1:
  384.                     doAnimatedCursor1();
  385.                     break;
  386.  
  387.                 case iAnimatedCursor2:
  388.                     doAnimatedCursor2();
  389.                     break;
  390.  
  391.                 case iAnimatedCursorOSX:
  392.                     doAnimatedCursorOSX();
  393.                     break;
  394.  
  395.                 case iIcon:
  396.                     doIcon();
  397.                     break;
  398.             }
  399.             break;
  400.     }
  401.  
  402.     HiliteMenu(0);
  403. }
  404.  
  405. // ************************************************************************ doOffScreenGWorld1
  406.  
  407. void  doOffScreenGWorld1(void)
  408. {
  409.     Rect                    portRect, sourceRect, destRect;    
  410.     GrafPtr                windowPortPtr;
  411.     GDHandle            deviceHdl;
  412.     QDErr                    qdErr;
  413.     GWorldPtr            gworldPortPtr;
  414.     PixMapHandle    gworldPixMapHdl, windowPixMapHdl;
  415.     Boolean                lockPixResult;
  416.  
  417.     // …………………………………………………………………………………………………………………………………………………………………………………………………… draw in window
  418.  
  419.     SetWTitle(gWindowRef,"\pTime-consuming drawing operation");
  420.  
  421.     if(!gRunningOnX)
  422.         SetThemeCursor(kThemeWatchCursor);
  423.  
  424.     doDrawStuff();
  425.  
  426.     if(!gRunningOnX)
  427.         SetThemeCursor(kThemeArrowCursor);
  428.     
  429.     SetWTitle(gWindowRef,"\pClick mouse to repeat in offscreen graphics port");
  430.     QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
  431.  
  432.     while(!Button()) ;
  433.  
  434.     if(!gRunningOnX)
  435.         SetThemeCursor(kThemeWatchCursor);
  436.     
  437.     GetWindowPortBounds(gWindowRef,&portRect);
  438.  
  439.     RGBBackColor(&gBlueColour);
  440.     EraseRect(&portRect);
  441.     RGBForeColor(&gWhiteColour);
  442.     MoveTo(190,180);
  443.     DrawString("\pPlease Wait.  Drawing in offscreen graphics port.");    
  444.  
  445.     // …………………………………………………………………………………………………… draw in offscreen graphics port and copy to window
  446.  
  447.     // ......................... save current graphics world and create offscreen graphics world
  448.  
  449.     GetGWorld(&windowPortPtr,&deviceHdl);
  450.  
  451.     qdErr = NewGWorld(&gworldPortPtr,0,&portRect,NULL,NULL,0);
  452.     if(gworldPortPtr == NULL || qdErr != noErr)
  453.     {
  454.         SysBeep(10);
  455.         return;
  456.     }
  457.  
  458.     SetGWorld(gworldPortPtr,NULL);
  459.  
  460.     // ................... lock pixel image for duration of drawing and erase offscreen to white
  461.  
  462.     gworldPixMapHdl = GetGWorldPixMap(gworldPortPtr);
  463.     if(!(lockPixResult = LockPixels(gworldPixMapHdl)))
  464.     {
  465.         SysBeep(10);
  466.         return;
  467.     }
  468.  
  469.     EraseRect(&portRect);    
  470.  
  471.     // ................................................... draw into the offscreen graphics port
  472.  
  473.     doDrawStuff();
  474.  
  475.     // ............................................................ restore saved graphics world
  476.  
  477.     SetGWorld(windowPortPtr,deviceHdl);
  478.  
  479.     // ................................................... set source and destination rectangles
  480.  
  481.     GetPortBounds(gworldPortPtr,&sourceRect);
  482.     GetPortBounds(windowPortPtr,&destRect);
  483.  
  484.     // ............................................................. get window port's pixel map
  485.  
  486.     windowPixMapHdl = GetGWorldPixMap(windowPortPtr);
  487.  
  488.     // ............. ensure background colour is white and foreground colour in black, then copy
  489.  
  490.     RGBBackColor(&gWhiteColour);
  491.     RGBForeColor(&gBlackColour);
  492.  
  493.     CopyBits((BitMap *) *gworldPixMapHdl,
  494.                      (BitMap *) *windowPixMapHdl,
  495.                      &sourceRect,&destRect,srcCopy,NULL);
  496.  
  497.     if(QDError() != noErr)
  498.         SysBeep(10);
  499.  
  500.     // ................................................................................ clean up 
  501.  
  502.     UnlockPixels(gworldPixMapHdl);
  503.     DisposeGWorld(gworldPortPtr);    
  504.  
  505.     if(!gRunningOnX)
  506.         SetThemeCursor(kThemeArrowCursor);
  507.  
  508.     SetWTitle(gWindowRef,"\pOffscreen Graphics Worlds, Pictures,    Cursors and Icons");
  509.     QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
  510. }
  511.  
  512. // ************************************************************************ doOffScreenGWorld2
  513.  
  514. void  doOffScreenGWorld2(void)
  515. {
  516.     PicHandle            picture1Hdl,picture2Hdl;
  517.     Rect                    portRect;
  518.     Rect                    sourceRect, maskRect, maskDisplayRect, dest1Rect, dest2Rect, destRect;
  519.     GrafPtr                windowPortPtr;    
  520.     GDHandle            deviceHdl;
  521.     QDErr                    qdErr;
  522.     GWorldPtr            gworldPortPtr;
  523.     PixMapHandle    gworldPixMapHdl, windowPixMapHdl;
  524.     RgnHandle            region1Hdl, region2Hdl, regionHdl;
  525.     SInt16                a, sourceMode;
  526.  
  527.     RGBBackColor(&gBeigeColour);
  528.     GetWindowPortBounds(gWindowRef,&portRect);    
  529.     EraseRect(&portRect);
  530.  
  531.     // ………………………………………………………………………………………………………… get the source picture and draw it in the window
  532.  
  533.     if(!(picture1Hdl = GetPicture(rPicture)))
  534.         ExitToShell();
  535.     HNoPurge((Handle) picture1Hdl);
  536.     SetRect(&sourceRect,116,35,273,147);
  537.     DrawPicture(picture1Hdl,&sourceRect);
  538.     HPurge((Handle) picture1Hdl);
  539.     MoveTo(116,32);
  540.     DrawString("\pSource image");
  541.  
  542.     // ………………………………………………………………… save current graphics world and create offscreen graphics world
  543.  
  544.     GetGWorld(&windowPortPtr,&deviceHdl);    
  545.  
  546.     SetRect(&maskRect,0,0,157,112);
  547.  
  548.     qdErr = NewGWorld(&gworldPortPtr,0,&maskRect,NULL,NULL,0);    
  549.     if(gworldPortPtr == NULL || qdErr != noErr)
  550.     {
  551.         SysBeep(10);
  552.         return;
  553.     }
  554.  
  555.     SetGWorld(gworldPortPtr,NULL);
  556.  
  557.     // ………………………………………………… lock pixel image for duration of drawing and erase offscreen to white
  558.  
  559.     gworldPixMapHdl = GetGWorldPixMap(gworldPortPtr);
  560.  
  561.     if(!(LockPixels(gworldPixMapHdl)))
  562.     {
  563.         SysBeep(10);
  564.         return;
  565.     }
  566.  
  567.     GetPortBounds(gworldPortPtr,&portRect);    
  568.     EraseRect(&portRect);
  569.  
  570.     // ……………………………………………………………………………………… get mask picture and draw it in offscreen graphics port
  571.  
  572.     if(!(picture2Hdl = GetPicture(rPicture + 1)))
  573.         ExitToShell();
  574.     HNoPurge((Handle) picture2Hdl);
  575.     DrawPicture(picture2Hdl,&maskRect);
  576.  
  577.     // …………………………………………………………………………………………………………………………………………………………………… also draw it in the window
  578.  
  579.     SetGWorld(windowPortPtr,deviceHdl);
  580.     SetRect(&maskDisplayRect,329,35,485,146);
  581.     DrawPicture(picture2Hdl,&maskDisplayRect);
  582.     HPurge((Handle) picture2Hdl);
  583.     MoveTo(329,32);
  584.     DrawString("\pCopy of offscreen mask");
  585.  
  586.     // ……………………………………………………………… define an oval-shaped region and a round rectangle-shaped region
  587.     
  588.     SetRect(&dest1Rect,22,171,296,366);
  589.     region1Hdl = NewRgn();
  590.     OpenRgn();
  591.     FrameOval(&dest1Rect);
  592.     CloseRgn(region1Hdl);
  593.  
  594.     SetRect(&dest2Rect,308,171,582,366);
  595.     region2Hdl = NewRgn();
  596.     OpenRgn();
  597.     FrameRoundRect(&dest2Rect,100,100);
  598.     CloseRgn(region2Hdl);
  599.  
  600.     SetWTitle(GetWindowFromPort(windowPortPtr),"\pClick mouse to copy");
  601.     QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
  602.     while(!Button()) ;
  603.  
  604.     // ............................................................. get window port's pixel map
  605.  
  606.     windowPixMapHdl = GetGWorldPixMap(windowPortPtr);
  607.  
  608.     // …………………… set background and foreground colour, then copy source to destination using mask 
  609.  
  610.     RGBForeColor(&gBlackColour);
  611.     RGBBackColor(&gWhiteColour);
  612.  
  613.     for(a=0;a<2;a++)
  614.     {
  615.         if(a == 0)
  616.         {
  617.             regionHdl = region1Hdl;
  618.             destRect = dest1Rect;
  619.             sourceMode = srcCopy;
  620.             MoveTo(22,168);
  621.             DrawString("\pBoolean source mode srcCopy");
  622.         }
  623.         else
  624.         {
  625.             regionHdl = region2Hdl;
  626.             destRect = dest2Rect;
  627.             sourceMode = srcXor;
  628.             MoveTo(308,168);
  629.             DrawString("\pBoolean source mode srcXor");
  630.         }
  631.  
  632.         CopyDeepMask((BitMap *) *windowPixMapHdl,
  633.                                  (BitMap *) *gworldPixMapHdl,
  634.                                  (BitMap *) *windowPixMapHdl,
  635.                                  &sourceRect,&maskRect,&destRect,sourceMode + ditherCopy,regionHdl);
  636.  
  637.         if(QDError() != noErr)
  638.             SysBeep(10);
  639.     }
  640.  
  641.     // …………………………………………………………………………………………………………………………………………………………………………………………………………………… clean up 
  642.  
  643.     UnlockPixels(gworldPixMapHdl);
  644.     DisposeGWorld(gworldPortPtr);    
  645.  
  646.     ReleaseResource((Handle) picture1Hdl);
  647.     ReleaseResource((Handle) picture2Hdl);
  648.     DisposeRgn(region1Hdl);
  649.     DisposeRgn(region2Hdl);
  650.  
  651.     SetWTitle(gWindowRef,"\pOffscreen Graphics Worlds, Pictures,    Cursors and Icons");
  652.     QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
  653. }
  654.  
  655. // ********************************************************************************* doPicture
  656.  
  657. void  doPicture(void)
  658. {
  659.     Rect                        portRect, pictureRect, theRect;    
  660.     OpenCPicParams    picParams;
  661.     RgnHandle                oldClipRgn;
  662.     PicHandle                pictureHdl;
  663.     SInt16                    a, left, top, right, bottom, random;
  664.     RGBColor                theColour;
  665.     PictInfo                pictInfo;
  666.     Str255                    theString;
  667.  
  668.     RGBBackColor(&gWhiteColour);
  669.     GetWindowPortBounds(gWindowRef,&portRect);
  670.     EraseRect(&portRect);
  671.  
  672.     // ………………………………………………………………………………………………………………………………………………………………………… define picture rectangle
  673.  
  674.     pictureRect = portRect;
  675.     pictureRect.right = (portRect.right - portRect.left) / 2;
  676.     InsetRect(&pictureRect,10,10);
  677.  
  678.     // ……………………………………………………………………………………………………………………………………………………………………………………… set clipping region
  679.  
  680.     oldClipRgn = NewRgn();
  681.     GetClip(oldClipRgn);
  682.     ClipRect(&pictureRect);
  683.  
  684.     // ……………………………………………………………………………………………………………………………………………………… set up OpenCPicParams structure 
  685.  
  686.     picParams.srcRect    = pictureRect;
  687.     picParams.hRes        = 0x00480000;
  688.     picParams.vRes        = 0x00480000;
  689.     picParams.version = -2;
  690.  
  691.     // …………………………………………………………………………………………………………………………………………………………………………………………………… record picture
  692.  
  693.     pictureHdl = OpenCPicture(&picParams);
  694.  
  695.     RGBBackColor(&gBlueColour);
  696.     EraseRect(&pictureRect);
  697.  
  698.     for(a=0;a<300;a++)
  699.     {
  700.         theRect = pictureRect;
  701.  
  702.         theColour.red   = doRandomNumber(0,65535);
  703.         theColour.green = doRandomNumber(0,65535);
  704.         theColour.blue  = doRandomNumber(0,65535);
  705.         RGBForeColor(&theColour);
  706.  
  707.         left = doRandomNumber(10,theRect.right);    
  708.         top = doRandomNumber(10,theRect.bottom);
  709.         right = doRandomNumber(left,theRect.right);    
  710.         bottom = doRandomNumber(top,theRect.bottom);        
  711.         SetRect(&theRect,left,top,right,bottom);
  712.  
  713.         PenMode(doRandomNumber(addOver,adMin));
  714.         
  715.         random = doRandomNumber(0,5);
  716.  
  717.         if(random == 0)
  718.         {
  719.             MoveTo(left,top);
  720.             LineTo(right - 1,bottom - 1);
  721.         }
  722.         else if(random == 1)
  723.             PaintRect(&theRect);
  724.         else if(random == 2)
  725.             PaintRoundRect(&theRect,30,30);
  726.         else if(random == 3)
  727.             PaintOval(&theRect);
  728.         else if(random == 4)
  729.             PaintArc(&theRect,0,300);
  730.         else if(random == 5)
  731.         {
  732.             TextSize(doRandomNumber(10,70));
  733.             MoveTo(left,right);
  734.             DrawString("\pPICTURE");
  735.         }
  736.     }
  737.  
  738.     // …………………………………………………………………………… stop recording, draw picture, restore saved clipping region
  739.  
  740.     ClosePicture();
  741.  
  742.     DrawPicture(pictureHdl,&pictureRect);
  743.  
  744.     SetClip(oldClipRgn);
  745.     DisposeRgn(oldClipRgn);
  746.  
  747.     // ……………………………………………………………………………………………… display some information from the PictInfo structure
  748.  
  749.     RGBForeColor(&gBlueColour);
  750.     RGBBackColor(&gBeigeColour);
  751.     PenMode(patCopy);
  752.     OffsetRect(&pictureRect,300,0);
  753.     EraseRect(&pictureRect);
  754.     FrameRect(&pictureRect);
  755.     TextSize(10);
  756.  
  757.     if(GetPictInfo(pictureHdl,&pictInfo,recordFontInfo + returnColorTable,1,systemMethod,0))
  758.         SysBeep(10);
  759.  
  760.     MoveTo(380,70);
  761.     DrawString("\pSome Picture Information:");
  762.  
  763.     MoveTo(380,100);
  764.     DrawString("\pLines: ");
  765.     NumToString(pictInfo.lineCount,theString);
  766.     DrawString(theString);
  767.  
  768.     MoveTo(380,115);
  769.     DrawString("\pRectangles: ");
  770.     NumToString((long) pictInfo.rectCount,theString);
  771.     DrawString(theString);
  772.  
  773.     MoveTo(380,130);
  774.     DrawString("\pRound rectangles: ");
  775.     NumToString(pictInfo.rRectCount,theString);
  776.     DrawString(theString);
  777.  
  778.     MoveTo(380,145);
  779.     DrawString("\pOvals: ");
  780.     NumToString(pictInfo.ovalCount,theString);
  781.     DrawString(theString);
  782.  
  783.     MoveTo(380,160);
  784.     DrawString("\pArcs: ");
  785.     NumToString(pictInfo.arcCount,theString);
  786.     DrawString(theString);
  787.  
  788.     MoveTo(380,175);
  789.     DrawString("\pPolygons: ");
  790.     NumToString(pictInfo.polyCount,theString);
  791.     DrawString(theString);
  792.  
  793.     MoveTo(380,190);
  794.     DrawString("\pRegions: ");
  795.     NumToString(pictInfo.regionCount,theString);
  796.     DrawString(theString);
  797.  
  798.     MoveTo(380,205);
  799.     DrawString("\pText strings: ");
  800.     NumToString(pictInfo.textCount,theString);
  801.     DrawString(theString);
  802.  
  803.     MoveTo(380,220);
  804.     DrawString("\pUnique fonts: ");
  805.     NumToString(pictInfo.uniqueFonts,theString);
  806.     DrawString(theString);
  807.  
  808.     MoveTo(380,235);
  809.     DrawString("\pUnique colours: ");
  810.     NumToString(pictInfo.uniqueColors,theString);
  811.     DrawString(theString);
  812.  
  813.     MoveTo(380,250);
  814.     DrawString("\pFrame rectangle left: ");
  815.     NumToString(pictInfo.sourceRect.left,theString);
  816.     DrawString(theString);
  817.  
  818.     MoveTo(380,265);
  819.     DrawString("\pFrame rectangle top: ");
  820.     NumToString(pictInfo.sourceRect.top,theString);
  821.     DrawString(theString);
  822.  
  823.     MoveTo(380,280);
  824.     DrawString("\pFrame rectangle right: ");
  825.     NumToString(pictInfo.sourceRect.right,theString);
  826.     DrawString(theString);
  827.  
  828.     MoveTo(380,295);
  829.     DrawString("\pFrame rectangle bottom: ");
  830.     NumToString(pictInfo.sourceRect.bottom,theString);
  831.     DrawString(theString);
  832.  
  833.     QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
  834.  
  835.     // …………………………………………………………………………………………………………………… release memory occupied by Picture structure
  836.  
  837.     KillPicture(pictureHdl);
  838. }
  839.  
  840. // ********************************************************************************** doCursor
  841.  
  842. void  doCursor(void)
  843. {
  844.     Rect        portRect, cursorRect;
  845.     SInt16    a;
  846.  
  847.     RGBBackColor(&gBlueColour);
  848.     GetWindowPortBounds(gWindowRef,&portRect);
  849.     EraseRect(&portRect);
  850.  
  851.     cursorRect = portRect;
  852.  
  853.     for(a=0;a<3;a++)
  854.     {
  855.         InsetRect(&cursorRect,40,40);
  856.  
  857.         if(a == 0 || a == 2)
  858.             RGBBackColor(&gBeigeColour);
  859.         else
  860.             RGBBackColor(&gBlueColour);
  861.  
  862.         EraseRect(&cursorRect);
  863.     }
  864.  
  865.     RGBForeColor(&gBeigeColour);
  866.     MoveTo(10,20);
  867.     DrawString("\pArrow cursor region");
  868.     RGBForeColor(&gBlueColour);
  869.     MoveTo(50,60);
  870.     DrawString("\pIBeam cursor region");
  871.     RGBForeColor(&gBeigeColour);
  872.     MoveTo(90,100);
  873.     DrawString("\pCross cursor region");
  874.     RGBForeColor(&gBlueColour);
  875.     MoveTo(130,140);
  876.     DrawString("\pPlus cursor region");
  877.  
  878.     gCursorRegion = NewRgn();
  879.     doChangeCursor(gWindowRef,gCursorRegion);
  880.  
  881.     gCursorRegionsActive = true;
  882. }
  883.  
  884. // **************************************************************************** doChangeCursor
  885.  
  886. void  doChangeCursor(WindowRef windowRef,RgnHandle cursorRegion)
  887. {
  888.     RgnHandle    arrowCursorRgn;
  889.     RgnHandle    ibeamCursorRgn;
  890.     RgnHandle    crossCursorRgn;
  891.     RgnHandle    plusCursorRgn;
  892.     Rect            cursorRect;
  893.     GrafPtr        oldPort;    
  894.     Point            mousePosition;
  895.     
  896.     arrowCursorRgn = NewRgn();
  897.     ibeamCursorRgn = NewRgn();    
  898.     crossCursorRgn = NewRgn();
  899.     plusCursorRgn     = NewRgn();
  900.  
  901.     SetRectRgn(arrowCursorRgn,-32768,-32768,32766,32766);
  902.  
  903.     GetPort(&oldPort);
  904.     SetPortWindowPort(windowRef);
  905.  
  906.     GetWindowPortBounds(windowRef,&cursorRect);
  907.     LocalToGlobal(&topLeft(cursorRect));
  908.     LocalToGlobal(&botRight(cursorRect));    
  909.  
  910.     InsetRect(&cursorRect,40,40);
  911.     RectRgn(ibeamCursorRgn,&cursorRect);
  912.     DiffRgn(arrowCursorRgn,ibeamCursorRgn,arrowCursorRgn);
  913.  
  914.     InsetRect(&cursorRect,40,40);
  915.     RectRgn(crossCursorRgn,&cursorRect);
  916.     DiffRgn(ibeamCursorRgn,crossCursorRgn,ibeamCursorRgn);
  917.     
  918.     InsetRect(&cursorRect,40,40);
  919.     RectRgn(plusCursorRgn,&cursorRect);
  920.     DiffRgn(crossCursorRgn,plusCursorRgn,crossCursorRgn);
  921.  
  922.     GetGlobalMouse(&mousePosition);
  923.  
  924.     if(PtInRgn(mousePosition,ibeamCursorRgn))
  925.     {
  926.         SetThemeCursor(kThemeIBeamCursor);
  927.         CopyRgn(ibeamCursorRgn,cursorRegion);
  928.     }
  929.     else if(PtInRgn(mousePosition,crossCursorRgn))
  930.     {
  931.         SetThemeCursor(kThemeCrossCursor);
  932.         CopyRgn(crossCursorRgn,cursorRegion);
  933.     }
  934.     else if(PtInRgn(mousePosition,plusCursorRgn))
  935.     {
  936.         SetThemeCursor(kThemePlusCursor);
  937.         CopyRgn(plusCursorRgn,cursorRegion);
  938.     }
  939.     else
  940.     {
  941.         SetThemeCursor(kThemeArrowCursor);
  942.         CopyRgn(arrowCursorRgn,cursorRegion);
  943.     }
  944.  
  945.     DisposeRgn(arrowCursorRgn);
  946.     DisposeRgn(ibeamCursorRgn);
  947.     DisposeRgn(crossCursorRgn);
  948.     DisposeRgn(plusCursorRgn);
  949.  
  950.     SetPort(oldPort);
  951. }
  952.  
  953. // ************************************************************************* doAnimatedCursor1
  954.  
  955. void  doAnimatedCursor1(void)
  956. {
  957.     Rect        portRect;
  958.     Pattern    whitePattern;
  959.  
  960.     BackColor(whiteColor);
  961.     GetWindowPortBounds(gWindowRef,&portRect);
  962.     FillRect(&portRect,GetQDGlobalsWhite(&whitePattern));
  963.  
  964.     gAnimCursTickInterval = kCountingHandTickInterval;
  965.     gSleepTime = gAnimCursTickInterval;
  966.     gAnimatedCursor1Active = true;
  967.  
  968. }
  969.  
  970. // ************************************************************************* doAnimatedCursor2
  971.  
  972. void  doAnimatedCursor2(void)
  973. {
  974.     Rect        portRect;
  975.     Pattern    whitePattern;
  976.     SInt16    animCursResourceID, animCursTickInterval;
  977.  
  978.     BackColor(whiteColor);
  979.     GetWindowPortBounds(gWindowRef,&portRect);
  980.     FillRect(&portRect,GetQDGlobalsWhite(&whitePattern));
  981.  
  982.     animCursResourceID     = rBeachBallCursor;
  983.     animCursTickInterval = kBeachBallTickInterval;
  984.  
  985.     if(doGetAnimCursor(animCursResourceID,animCursTickInterval))
  986.     {
  987.         gSleepTime = animCursTickInterval;
  988.         gAnimatedCursor2Active = true;
  989.     }    
  990.     else
  991.         SysBeep(10);
  992. }
  993.  
  994. // *************************************************************************** doGetAnimCursor
  995.  
  996. Boolean  doGetAnimCursor(SInt16 resourceID,SInt16 tickInterval)
  997. {
  998.     SInt16    cursorID, a = 0;
  999.     Boolean    noError = false;
  1000.  
  1001.     if((gAnimCursHdl = (animCursHandle) GetResource('acur',resourceID)))
  1002.     {
  1003.         noError = true;
  1004.         while((a < (*gAnimCursHdl)->numberOfFrames)  && noError)
  1005.         {
  1006.             cursorID = (SInt16) HiWord((SInt32) (*gAnimCursHdl)->frame[a]);
  1007.             (*gAnimCursHdl)->frame[a] = GetCursor(cursorID);
  1008.             if((*gAnimCursHdl)->frame[a])
  1009.                 a++;
  1010.             else
  1011.                 noError = false;
  1012.         }
  1013.     }
  1014.  
  1015.     if(noError)
  1016.     {
  1017.         gAnimCursTickInterval = tickInterval;
  1018.         gAnimCursLastTick = TickCount();
  1019.         (*gAnimCursHdl)->whichFrame = 0;
  1020.     }
  1021.  
  1022.     return noError;
  1023. }
  1024.  
  1025. // ********************************************************************* doIncrementAnimCursor
  1026.  
  1027. void  doIncrementAnimCursor(void)
  1028. {
  1029.     SInt32                newTick;
  1030.     static UInt32    animationStep;
  1031.  
  1032.     newTick = TickCount();
  1033.     if(newTick < (gAnimCursLastTick + gAnimCursTickInterval))
  1034.         return;
  1035.  
  1036.     if(gAnimatedCursor1Active)
  1037.     {
  1038.         SetAnimatedThemeCursor(kThemeCountingUpAndDownHandCursor,animationStep);
  1039.             animationStep++;
  1040.     }
  1041.     else if(gAnimatedCursor2Active)
  1042.     {
  1043.         SetCursor(*((*gAnimCursHdl)->frame[(*gAnimCursHdl)->whichFrame++]));
  1044.         if((*gAnimCursHdl)->whichFrame == (*gAnimCursHdl)->numberOfFrames)
  1045.             (*gAnimCursHdl)->whichFrame = 0;
  1046.     }
  1047.  
  1048.     gAnimCursLastTick = newTick;
  1049. }
  1050.  
  1051. // *********************************************************************** doReleaseAnimCursor
  1052.  
  1053. void  doReleaseAnimCursor(void)
  1054. {
  1055.     SInt16    a;
  1056.  
  1057.     for(a=0;a<(*gAnimCursHdl)->numberOfFrames;a++)
  1058.         ReleaseResource((Handle) (*gAnimCursHdl)->frame[a]);
  1059.  
  1060.     ReleaseResource((Handle) gAnimCursHdl);
  1061. }
  1062.  
  1063. // *********************************************************************** doAnimatedCursorOSX
  1064.  
  1065. void  doAnimatedCursorOSX(void)
  1066. {
  1067.     if(!gAnimatedCursorOSXActive)
  1068.     {
  1069.         QDDisplayWaitCursor(true);
  1070.         gAnimatedCursorOSXActive = true;
  1071.     }
  1072.     else
  1073.     {
  1074.         QDDisplayWaitCursor(false);
  1075.         gAnimatedCursorOSXActive = false;
  1076.     }
  1077. }
  1078.  
  1079. // ************************************************************************************ doIcon
  1080.  
  1081. void  doIcon(void)
  1082. {
  1083.     Rect                            portRect, theRect;
  1084.     SInt16                        a, b, stringIndex = 1;
  1085.     IconTransformType    transform = 0;
  1086.     Str255                        theString;
  1087.     Handle                        iconSuiteHdl;
  1088.     CIconHandle                ciconHdl;
  1089.  
  1090.     RGBForeColor(&gBlueColour);
  1091.     RGBBackColor(&gBeigeColour);
  1092.     GetWindowPortBounds(gWindowRef,&portRect);
  1093.     EraseRect(&portRect);
  1094.  
  1095.     // …………………………………………………………………………………………………………………………………………………………………… PlotIconID with transforms
  1096.  
  1097.     MoveTo(50,28);
  1098.     DrawString("\pPlotIconID with transforms");
  1099.  
  1100.     for(a=50;a<471;a+=140)
  1101.     {     
  1102.         if(a == 190)
  1103.             transform = 16384;
  1104.         if(a == 330)
  1105.             transform = 256;
  1106.                 
  1107.         for(b=0;b<4;b++)
  1108.         {
  1109.             if(a == 470 && b == 3)
  1110.                 continue;
  1111.  
  1112.             GetIndString(theString,rTransformStrings,stringIndex++);
  1113.             MoveTo(a,b * 60 + 47);
  1114.             DrawString(theString);
  1115.             
  1116.             SetRect(&theRect,a,b * 60 + 50,a + 32,b * 60 + 82);
  1117.             PlotIconID(&theRect,0,transform,rIconFamily1);
  1118.             SetRect(&theRect,a + 40,b * 60 + 50,a + 56,b * 60 + 66);
  1119.             PlotIconID(&theRect,0,transform,rIconFamily1);
  1120.             SetRect(&theRect,a + 64,b * 60 + 50,a + 80,b * 60 + 62);
  1121.             PlotIconID(&theRect,0,transform,rIconFamily1);
  1122.  
  1123.             if(a >= 330)
  1124.                 transform += 256;
  1125.             else
  1126.                 transform ++;
  1127.         }
  1128.     }
  1129.  
  1130.     // ………………………………………………………………………………………………………………………………………………………… GetIconSuite and PlotIconSuite
  1131.  
  1132.     MoveTo(50,275);
  1133.     LineTo(550,275);
  1134.     MoveTo(50,299);
  1135.     DrawString("\pGetIconSuite and PlotIconSuite");
  1136.  
  1137.     GetIconSuite(&iconSuiteHdl,rIconFamily2,kSelectorAllLargeData);
  1138.  
  1139.     SetRect(&theRect,50,324,82,356);
  1140.     PlotIconSuite(&theRect,kAlignNone,kTransformNone,iconSuiteHdl);
  1141.     SetRect(&theRect,118,316,166,364);
  1142.     PlotIconSuite(&theRect,kAlignNone,kTransformNone,iconSuiteHdl);
  1143.     SetRect(&theRect,202,308,266,372);
  1144.     PlotIconSuite(&theRect,kAlignNone,kTransformNone,iconSuiteHdl);
  1145.  
  1146.     // ……………………………………………………………………………………………………………………………………………………………………………… GetCIcon and PlotCIcon
  1147.  
  1148.     MoveTo(330,299);
  1149.     DrawString("\pGetCIcon and PlotCIcon");
  1150.  
  1151.     ciconHdl = GetCIcon(rColourIcon);
  1152.  
  1153.     SetRect(&theRect,330,324,362,356);
  1154.     PlotCIcon(&theRect,ciconHdl);
  1155.     SetRect(&theRect,398,316,446,364);
  1156.     PlotCIcon(&theRect,ciconHdl);
  1157.     SetRect(&theRect,482,308,546,372);
  1158.     PlotCIcon(&theRect,ciconHdl);
  1159. }
  1160.  
  1161. // ***************************************************************************** doAboutDialog
  1162.  
  1163. void  doAboutDialog(void)
  1164. {
  1165.     DialogPtr    dialogPtr;
  1166.     SInt16        itemHit;
  1167.  
  1168.     dialogPtr = GetNewDialog(rAboutDialog,NULL,(WindowRef)-1);
  1169.     ModalDialog(NULL,&itemHit);
  1170.     DisposeDialog(dialogPtr);
  1171. }
  1172.  
  1173. // ******************************************************************************* doDrawStuff
  1174.  
  1175. void  doDrawStuff(void)
  1176. {
  1177.     Rect            portRect, theRect;
  1178.     RGBColor    theColour;
  1179.     SInt16        a, left, top, right, bottom, random;
  1180.  
  1181.     RGBBackColor(&gBlueColour);
  1182.     GetWindowPortBounds(gWindowRef,&portRect);
  1183.     EraseRect(&portRect);
  1184.  
  1185.     for(a=0;a<900;a++)
  1186.     {
  1187.         theRect = portRect;
  1188.  
  1189.         theColour.red   = doRandomNumber(0,65535);
  1190.         theColour.green = doRandomNumber(0,65535);
  1191.         theColour.blue  = doRandomNumber(0,65535);
  1192.         RGBForeColor(&theColour);
  1193.  
  1194.         left = doRandomNumber(0,theRect.right);    
  1195.         top = doRandomNumber(0,theRect.bottom);
  1196.         right = doRandomNumber(left,theRect.right);    
  1197.         bottom = doRandomNumber(top,theRect.bottom);        
  1198.         SetRect(&theRect,left,top,right,bottom);
  1199.  
  1200.         PenMode(doRandomNumber(addOver,adMin));
  1201.         
  1202.         random = doRandomNumber(0,3);
  1203.  
  1204.         if(random == 0)
  1205.             PaintRect(&theRect);
  1206.         else if(random == 1)
  1207.             PaintRoundRect(&theRect,doRandomNumber(10,100),doRandomNumber(10,100));
  1208.         else if(random == 2)
  1209.             PaintOval(&theRect);
  1210.         else if(random == 3)
  1211.             PaintArc(&theRect,0,doRandomNumber(5,330));
  1212.  
  1213.         QDFlushPortBuffer(GetWindowPort(gWindowRef),NULL);
  1214.     }
  1215. }
  1216.  
  1217. // **************************************************************************** doRandomNumber
  1218.  
  1219. UInt16  doRandomNumber(UInt16 minimum, UInt16 maximum)
  1220. {
  1221.     UInt16    randomNumber;
  1222.     SInt32    range, t;
  1223.  
  1224.     randomNumber = Random();
  1225.     range = maximum - minimum + 1;
  1226.     t = (randomNumber * range) / 65536;
  1227.     return (t + minimum);
  1228. }
  1229.  
  1230. // *******************************************************************************************
  1231.