home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / Effect library / Demo ƒ / MSG Shell ƒ / msg graphics.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-12  |  12.4 KB  |  501 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        msg graphics.c
  4.  
  5. Purpose:    This module handles opening/closing/updating all windows:
  6.             main window, help window, and about windows.  This includes
  7.             manipulating offscreen bitmaps for fun and no profit.
  8.  
  9.  
  10. MSG Demo -- graphic effects demonstration program
  11. Copyright (C) 1992-4 Mark Pilgrim & Dave Blumenthal
  12.  
  13. This program is free software; you can redistribute it and/or modify
  14. it under the terms of the GNU General Public License as published by
  15. the Free Software Foundation; either version 2 of the License, or
  16. (at your option) any later version.
  17.  
  18. This program is distributed in the hope that it will be useful,
  19. but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. GNU General Public License for more details.
  22.  
  23. You should have received a copy of the GNU General Public License
  24. along with this program in a file named "GNU General Public License".
  25. If not, write to the Free Software Foundation, 675 Mass Ave,
  26. Cambridge, MA 02139, USA.
  27.  
  28. \**********************************************************************/
  29.  
  30. #include "msg graphics.h"
  31. #include "msg about.h"
  32. #include "msg help.h"
  33. #include "msg dialogs.h"
  34. #include "msg error.h"
  35. #include "msg menus.h"
  36. #include "msg sounds.h"
  37. #include "msg environment.h"
  38. #include "msg prefs.h"
  39. #include "program globals.h"
  40. #include "demo graphics.h"
  41. #include "demo.h"
  42.  
  43. Boolean            gInitedWindowBounds[NUM_WINDOWS];
  44. Rect            gMainScreenBounds;
  45. Rect            gWindowBounds[NUM_WINDOWS];
  46. GDHandle        gBiggestDevice;
  47. WindowPtr        gTheWindow[NUM_WINDOWS];
  48. int                gHelpWidth;
  49. int                gHelpHeight;
  50. int                gWindowWidth[NUM_WINDOWS];
  51. int                gWindowHeight[NUM_WINDOWS];
  52. Str255            gWindowTitle[NUM_WINDOWS];
  53. int                gWindowType[NUM_WINDOWS];
  54. Boolean            gOffscreenNeedsUpdate[NUM_WINDOWS];
  55. int                gNumHelp;
  56.  
  57. /* internal stuff */
  58. Rect            bRect[NUM_WINDOWS];
  59. Ptr                myBits[NUM_WINDOWS];
  60. CGrafPort        myCGrafPort[NUM_WINDOWS];
  61. CGrafPtr        myCGrafPtr[NUM_WINDOWS];
  62. CTabHandle        ourCMHandle[NUM_WINDOWS];
  63. GrafPort        myGrafPort[NUM_WINDOWS];
  64. GrafPtr            myGrafPtr[NUM_WINDOWS];
  65. int                gLastDepth[NUM_WINDOWS];
  66. int                gMaxDepth[NUM_WINDOWS];
  67.  
  68. void InitMSGGraphics(void)
  69. {
  70.     int                i;
  71.     
  72.     gAboutColorPict=gAboutBWPict=0L;
  73.     
  74.     gWindowWidth[kMainWindow]=500;
  75.     gWindowHeight[kMainWindow]=300;
  76.     
  77.     gWindowWidth[kAbout]=380;
  78.     gWindowHeight[kAbout]=216;
  79.     
  80.     gWindowWidth[kAboutMSG]=243;
  81.     gWindowHeight[kAboutMSG]=243;
  82.     
  83.     gWindowWidth[kHelp]=300;
  84.     gWindowHeight[kHelp]=250;
  85.     
  86.     for (i=0; i<NUM_WINDOWS; i++)
  87.     {
  88.         myCGrafPtr[i]=myGrafPtr[i]=gTheWindow[i]=0L;
  89.         gInitedWindowBounds[i]=FALSE;
  90.         gOffscreenNeedsUpdate[i]=TRUE;
  91.     }
  92.     
  93.     gMaxDepth[kMainWindow]=8;
  94.     gMaxDepth[kAbout]=8;
  95.     gMaxDepth[kAboutMSG]=1;
  96.     gMaxDepth[kHelp]=1;
  97.     
  98.     gWindowType[kMainWindow]=noGrowDocProc;
  99.     gWindowType[kAbout]=altDBoxProc;
  100.     gWindowType[kAboutMSG]=plainDBox;
  101.     gWindowType[kHelp]=noGrowDocProc;
  102.     
  103.     StuffHex(gWindowTitle[kMainWindow], "\p084d53472044656d6f");
  104.     StuffHex(gWindowTitle[kHelp], "\p0448656c70");
  105.     gWindowTitle[kAbout][0]=gWindowTitle[kAboutMSG][0]==0x00;
  106. }
  107.  
  108. void OpenTheWindow(int index)
  109. {
  110.     unsigned long        dummy;
  111.     
  112.     if (!gTheWindow[index])
  113.     {
  114.         if (!gInitedWindowBounds[index])
  115.         {
  116.             if (index==kHelp)
  117.             {
  118.                 gWindowBounds[index].left=10;
  119.                 gWindowBounds[index].top=50;
  120.             }
  121.             else
  122.             {
  123.                 gWindowBounds[index].left = gMainScreenBounds.left + (((gMainScreenBounds.right -
  124.                             gMainScreenBounds.left) - gWindowWidth[index]) / 2);
  125.                 gWindowBounds[index].top = 9+ gMainScreenBounds.top + (((gMainScreenBounds.bottom -
  126.                             gMainScreenBounds.top) - gWindowHeight[index]) / 2);
  127.             }
  128.             if(gWindowBounds[index].top < 30)
  129.                 gWindowBounds[index].top = 30;
  130.             gWindowBounds[index].bottom = gWindowBounds[index].top + gWindowHeight[index];
  131.             gWindowBounds[index].right = gWindowBounds[index].left + gWindowWidth[index];
  132.             gInitedWindowBounds[index]=TRUE;
  133.         }
  134.         
  135.         if(gHasColorQD)
  136.         {
  137.             gTheWindow[index] = NewCWindow(0L, &gWindowBounds[index], gWindowTitle[index],
  138.                 TRUE, gWindowType[index], (WindowPtr)-1L, TRUE, 0L);
  139.         }
  140.         else
  141.         {
  142.             gTheWindow[index] = NewWindow(0L, &gWindowBounds[index], gWindowTitle[index],
  143.                 TRUE, gWindowType[index], (WindowPtr)-1L, TRUE, 0L);
  144.         }
  145.  
  146.         bRect[index] = gTheWindow[index]->portRect;
  147.     }
  148.     
  149.     if (gTheWindow[index])
  150.     {
  151.         SelectWindow(gTheWindow[index]);
  152.         SetPort(gTheWindow[index]);
  153.         UpdateTheWindow(index);
  154.         if (index==kAboutMSG)
  155.             Delay(30, &dummy);
  156.     }
  157.     else ErrorString("\pThere is not enough memory to open the window.","\p");
  158. }
  159.  
  160. void GetMainScreenBounds(void)
  161. {
  162.     gMainScreenBounds = screenBits.bounds;
  163.     gMainScreenBounds.top += MBarHeight;
  164. }
  165.  
  166. int GetWindowDepth(int index)
  167. {
  168.     Rect        tempRect;
  169.     long        biggestSize;
  170.     long        tempSize;
  171.     GDHandle    thisHandle;
  172.     
  173.     if (gHasColorQD)
  174.     {
  175.         if (gTheWindow[index])
  176.         {
  177.             thisHandle = GetDeviceList();
  178.             gBiggestDevice = 0L;
  179.             biggestSize = 0L;
  180.             
  181.             while (thisHandle)
  182.             {
  183.                 if (TestDeviceAttribute(thisHandle, screenDevice) &&
  184.                             TestDeviceAttribute(thisHandle, screenActive))
  185.                     if (SectRect(&(gTheWindow[index]->portRect), &((**thisHandle).gdRect),
  186.                                 &tempRect))
  187.                         if (biggestSize < (tempSize =
  188.                                 ((long)(tempRect.bottom - tempRect.top))
  189.                                 * ((long)(tempRect.right - tempRect.left))))
  190.                         {
  191.                             biggestSize = tempSize;
  192.                             gBiggestDevice = thisHandle;
  193.                         }
  194.                 thisHandle = GetNextDevice(thisHandle);
  195.             }
  196.             
  197.             if (gBiggestDevice)
  198.                 return (**(**gBiggestDevice).gdPMap).pixelSize;
  199.             else
  200.                 return 1;
  201.         }
  202.         else
  203.         {
  204.             return (**(**GetMainDevice()).gdPMap).pixelSize;
  205.         }
  206.     }
  207.     else
  208.     {
  209.         return 1;
  210.     }
  211. }
  212.  
  213. void UpdateTheWindow(int index)
  214. {
  215.     long        offRowBytes, sizeOfOff;
  216.     int            theDepth, i, err;
  217.     GDHandle    oldDevice;
  218.  
  219.     if (((theDepth = GetWindowDepth(index)) > 2) && (gMaxDepth[index]>2))
  220.     {
  221.         /* if we just changed from one color depth to another color depth */
  222.         if((myCGrafPtr[index] != 0L) && (gLastDepth[index] != theDepth))
  223.         {
  224.             DisposeHandle((**(myCGrafPort[index]).portPixMap).pmTable);
  225.             DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  226.             CloseCPort(myCGrafPtr[index]);
  227.             myCGrafPtr[index] = 0L;            
  228.             gOffscreenNeedsUpdate[index]=TRUE;
  229.         }
  230.         
  231.         if (myCGrafPtr[index]==0L)
  232.         {
  233.             /* if we just switched from b/w to color, delete the b/w port */
  234.             if(myGrafPtr[index] != 0L)
  235.             {
  236.                 DisposePtr(myGrafPort[index].portBits.baseAddr);
  237.                 ClosePort(myGrafPtr[index]);
  238.                 myGrafPtr[index] = 0L;
  239.                 gOffscreenNeedsUpdate[index]=TRUE;
  240.             }
  241.             
  242.             if (gBiggestDevice)
  243.             {
  244.                 oldDevice = GetGDevice();
  245.                 SetGDevice(gBiggestDevice);
  246.             }
  247.             else
  248.                 oldDevice = 0L;
  249.             
  250.             myCGrafPtr[index] = &myCGrafPort[index];
  251.             OpenCPort(myCGrafPtr[index]);
  252.             gLastDepth[index] = theDepth = (**(myCGrafPort[index]).portPixMap).pixelSize;
  253.             if (theDepth>gMaxDepth[index])
  254.                 gLastDepth[index]=theDepth=gMaxDepth[index];
  255.             
  256.             offRowBytes = (((theDepth * (bRect[index].right - bRect[index].left)) + 15) >> 4) << 1;
  257.             sizeOfOff = (long)(bRect[index].bottom - bRect[index].top) * offRowBytes;
  258.             OffsetRect(&bRect[index], -bRect[index].left, -bRect[index].top);
  259.             
  260.             myBits[index] = NewPtr(sizeOfOff);
  261.             if(myBits[index] == 0L)
  262.             {
  263.                 CloseCPort(myCGrafPtr[index]);
  264.                 myCGrafPtr[index]=0L;
  265.                 ErrorString("\pThere is not enough memory to open the window.","\p");
  266.             }
  267.             
  268.             (**(myCGrafPort[index]).portPixMap).baseAddr = myBits[index];
  269.             (**(myCGrafPort[index]).portPixMap).rowBytes = offRowBytes + 0x8000;
  270.             (**(myCGrafPort[index]).portPixMap).bounds = bRect[index];
  271.             
  272.             myCGrafPort[index].portRect = bRect[index];
  273.             
  274.             ourCMHandle[index] = (**(**gBiggestDevice).gdPMap).pmTable;
  275.             err = HandToHand(&ourCMHandle[index]);
  276.             if(err != noErr)
  277.             {
  278.                 DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  279.                 CloseCPort(myCGrafPtr[index]);
  280.                 myCGrafPtr[index]=0L;
  281.                 ErrorString("\pThere is not enough memory to open the window.","\p");
  282.             }
  283.             
  284.             for(i = 0; i <= (**ourCMHandle[index]).ctSize; i++)
  285.                 (**ourCMHandle[index]).ctTable[i].value = i;
  286.             (**ourCMHandle[index]).ctFlags &= 0x7fff;
  287.             (**ourCMHandle[index]).ctSeed = GetCTSeed();
  288.             
  289.             (**(myCGrafPort[index]).portPixMap).pmTable = ourCMHandle[index];
  290.             
  291.             if (oldDevice)
  292.                 SetGDevice(oldDevice);
  293.         }
  294.         
  295.         UpdateTheWindowColor(index);
  296.     }
  297.     else
  298.     {
  299.         if (myGrafPtr[index]==0L)
  300.         {
  301.             if(myCGrafPtr[index] != 0L)
  302.             {
  303.                 DisposeHandle((**(myCGrafPort[index]).portPixMap).pmTable);
  304.                 DisposePtr((**(myCGrafPort[index]).portPixMap).baseAddr);
  305.                 CloseCPort(myCGrafPtr[index]);
  306.                 myCGrafPtr[index] = 0L;
  307.                 gOffscreenNeedsUpdate[index]=TRUE;
  308.             }
  309.             
  310.             myGrafPtr[index] = &myGrafPort[index];
  311.             OpenPort(myGrafPtr[index]);
  312.             
  313.             offRowBytes = (((bRect[index].right - bRect[index].left) + 15) >> 4) << 1;
  314.             sizeOfOff = (long)(bRect[index].bottom - bRect[index].top) * offRowBytes;
  315.             OffsetRect(&bRect[index], -bRect[index].left, -bRect[index].top);
  316.             
  317.             myBits[index] = NewPtr(sizeOfOff);
  318.             if(myBits[index] == 0L)
  319.             {
  320.                 ClosePort(myGrafPtr[index]);
  321.                 myGrafPtr[index]=0L;
  322.                 ErrorString("\pThere is not enough memory to open the window.", "\p");
  323.             }
  324.             
  325.             myGrafPort[index].portBits.baseAddr = myBits[index];
  326.             myGrafPort[index].portBits.rowBytes = offRowBytes;
  327.             myGrafPort[index].portBits.bounds = bRect[index];
  328.             myGrafPort[index].portRect = bRect[index];            
  329.         }
  330.         
  331.         UpdateTheWindowBW(index);
  332.     }
  333.     
  334.     ValidRect(&(gTheWindow[index]->portRect));
  335. }
  336.  
  337. void UpdateTheWindowColor(int index)
  338. {
  339.     GDHandle    oldDevice;
  340.     RgnHandle    oldClipRgn;
  341.     RgnHandle    newClipRgn;
  342.     
  343.     if (gWhichWipe!=0)
  344.         gOffscreenNeedsUpdate[index]=TRUE;
  345.     
  346.     if (gOffscreenNeedsUpdate[index])
  347.     {
  348.         oldDevice = GetGDevice();
  349.         SetGDevice(gBiggestDevice);
  350.         oldClipRgn = myCGrafPort[index].clipRgn;
  351.         newClipRgn=NewRgn();
  352.         SetRectRgn(newClipRgn, 0, 0, gWindowWidth[index], gWindowHeight[index]);
  353.         
  354.         myCGrafPort[index].clipRgn=newClipRgn;
  355.             
  356.         SetPort((GrafPtr)myCGrafPtr[index]);
  357.         
  358.         switch (index)
  359.         {
  360.             case kAbout:
  361.                 DrawTheAboutBox(TRUE);
  362.                 break;
  363.             case kAboutMSG:
  364.                 DrawTheCarpet();
  365.                 break;
  366.             case kHelp:
  367.                 DrawTheHelp(TRUE);
  368.                 break;
  369.             default:
  370.                 DrawTheWindowColor(index);
  371.                 break;
  372.         }
  373.         SetGDevice(oldDevice);
  374.         myCGrafPort[index].clipRgn = oldClipRgn;
  375.         DisposeRgn(newClipRgn);
  376.         gOffscreenNeedsUpdate[index]=FALSE;
  377.     }
  378.     
  379.     SetPort(gTheWindow[index]);
  380.     
  381.     if (gWhichWipe!=0)
  382.         WipeDispatch((GrafPtr)myCGrafPtr[index]);
  383.     else
  384.         CopyBits(&(((GrafPtr)myCGrafPtr[index])->portBits),
  385.                     &(gTheWindow[index]->portBits), &bRect[index], &bRect[index], 0, 0L);
  386. }
  387.  
  388. void UpdateTheWindowBW(int index)
  389. {
  390.     RgnHandle    oldClipRgn;
  391.     RgnHandle    newClipRgn;
  392.     
  393.     if (gWhichWipe!=0)
  394.         gOffscreenNeedsUpdate[index]=TRUE;
  395.     
  396.     if (gOffscreenNeedsUpdate[index])
  397.     {
  398.         oldClipRgn = myGrafPort[index].clipRgn;
  399.         newClipRgn=NewRgn();
  400.         SetRectRgn(newClipRgn, 0, 0, gWindowWidth[index], gWindowHeight[index]);
  401.         myCGrafPort[index].clipRgn=newClipRgn;
  402.         SetPort(myGrafPtr[index]);
  403.         switch (index)
  404.         {
  405.             case kAbout:
  406.                 DrawTheAboutBox(FALSE);
  407.                 break;
  408.             case kAboutMSG:
  409.                 DrawTheCarpet();
  410.                 break;
  411.             case kHelp:
  412.                 DrawTheHelp(FALSE);
  413.                 break;
  414.             default:
  415.                 DrawTheWindowBW(index);
  416.                 break;
  417.         }
  418.         myGrafPort[index].clipRgn = oldClipRgn;
  419.         DisposeRgn(newClipRgn);
  420.         gOffscreenNeedsUpdate[index]=FALSE;
  421.     }
  422.     
  423.     SetPort(gTheWindow[index]);
  424.     
  425.     if (gWhichWipe!=0)
  426.         WipeDispatch(myGrafPtr[index]);
  427.     else
  428.         CopyBits(&(myGrafPtr[index]->portBits),
  429.                     &(gTheWindow[index]->portBits), &bRect[index], &bRect[index], 0, 0L);
  430. }
  431.  
  432. void UpdateHelpWindow(void)
  433. {
  434.     gOffscreenNeedsUpdate[kHelp]=TRUE;
  435.     OpenTheWindow(kHelp);
  436. }
  437.  
  438. void CloseTheWindow(int index)
  439. {
  440.     DisposeWindow(gTheWindow[index]);
  441.     gTheWindow[index]=0L;
  442.     
  443.     if (index==kMainWindow)
  444.     {
  445.         gInProgress=FALSE;
  446.         AdjustMenus();
  447.     }
  448.     else if (index==kHelp)
  449.         gOffscreenNeedsUpdate[kHelp]=TRUE;
  450. }
  451.  
  452. void DrawThePicture(PicHandle *thePict, int whichPict, int x, int y)
  453. {
  454.     Rect            temp;
  455.     
  456.     if (*thePict==0L)
  457.         *thePict=(PicHandle)GetPicture(whichPict);
  458.     
  459.     HLock(*thePict);
  460.     temp.top=y;
  461.     temp.left=x;
  462.     temp.bottom=temp.top+(***thePict).picFrame.bottom-(***thePict).picFrame.top;
  463.     temp.right=temp.left+(***thePict).picFrame.right-(***thePict).picFrame.left;
  464.     DrawPicture(*thePict, &temp);
  465.     HUnlock(*thePict);
  466. }
  467.  
  468. void ReleaseThePict(PicHandle *thePict)
  469. {
  470.     if (*thePict!=0L)
  471.     {
  472.         ReleaseResource(*thePict);
  473.         *thePict=0L;
  474.     }
  475. }
  476.  
  477. void ShutDownMSGGraphics(void)
  478. {
  479.     int                i;
  480.     
  481.     ReleaseThePict(gAboutColorPict);
  482.     ReleaseThePict(gAboutBWPict);
  483.     
  484.     for (i=0; i<NUM_WINDOWS; i++)
  485.     {
  486.         if ((myCGrafPtr[i]!=0L) || (myGrafPtr[i]!=0L))
  487.             DisposPtr(myBits[i]);
  488.         if(myCGrafPtr[i] != 0L)
  489.         {
  490.             DisposeHandle((**(myCGrafPort[i]).portPixMap).pmTable);
  491.             CloseCPort(myCGrafPtr[i]);
  492.             myCGrafPtr[i] = 0L;
  493.         }
  494.         if(myGrafPtr[i] != 0L)
  495.         {
  496.             ClosePort(myGrafPtr[i]);
  497.             myGrafPtr[i] = 0L;
  498.         }
  499.     }
  500. }
  501.