home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Frameworks / Extension Shell 1.3 / Extension Shell 1.3 (Source) / ShowIcon.c < prev    next >
Encoding:
Text File  |  1994-04-06  |  8.8 KB  |  326 lines  |  [TEXT/R*ch]

  1. /*    NAME:
  2.         ShowIcon.c
  3.  
  4.     WRITTEN BY:
  5.         Various... see description.
  6.  
  7.     MODIFIED BY:
  8.         Dair Grant
  9.                 
  10.     DESCRIPTION:
  11.         This code is based variously on James Walker's ShowIcon7.c code, and Patrick
  12.         Beard's ShowIconFamily code. ShowIconFamily was itself based on the original
  13.         ShowInit - by Paul Mercer, Darin Adler, and Paul Snively, from an idea by
  14.         Steve Capps.
  15.  
  16.         This is the de facto standard used by all Mac INITs.
  17.  
  18.     NOTES:
  19.         •    Compiled with THINK C 6.0.
  20.  
  21.         •    We use the System 7 IconSuite calls to display the appropriate icon
  22.             from our INIT code's icon family. This looks after bit depths, and
  23.             removes the need for 'cicn's for colour displays.
  24.         
  25.         •    If we're not running under System 7, we can only handle 'ICN#'
  26.             resources.
  27.             
  28.         •    Make sure you have to most up-to-date copy of <Icons.h>. The IconSuite
  29.             routines were missing from some older versions of THINK C.
  30.             
  31.     ___________________________________________________________________________
  32.  
  33.     VERSION HISTORY:
  34.         (Jan 1994, dg)
  35.             •    First publicly distributed version.
  36.  
  37.  
  38.     ___________________________________________________________________________
  39. */
  40. //=============================================================================
  41. //        Include files                                                                     
  42. //-----------------------------------------------------------------------------
  43. #include <Icons.h>
  44. #include "ESConstants.h"
  45. #include "ShowIcon.h"
  46.  
  47.  
  48.  
  49.  
  50.  
  51. //=============================================================================
  52. //        Private function prototypes                                                                     
  53. //-----------------------------------------------------------------------------
  54. void        GetIconRect(Rect *theRect, Rect *thePortRect);
  55. void        NextPosition(void);
  56. short        CheckSum(register short x);
  57. void        PlotBWIcon(Rect *iconRect, Handle theIcon);
  58.  
  59.  
  60.  
  61.  
  62.  
  63. //=============================================================================
  64. //        Global variables                                                                 
  65. //-----------------------------------------------------------------------------
  66. // ShowInit's information is nestled at the tail end of CurApName.
  67. // It consists of a short which encodes the next horizontal offset,
  68. // and another short which is that value checksummed.
  69. extern  short  gCurrX        : 0x92C;            // CurApName + 28
  70. extern  short  gTheCheckSum    : 0x92E;            // CurApName + 30
  71.  
  72.  
  73.  
  74.  
  75.  
  76. //=============================================================================
  77. //        Private defines                                                                     
  78. //-----------------------------------------------------------------------------
  79. #define kCheckSumConst        0x1021            // Check-sum constant
  80. #define kInitialXPosition    8                // First horizontal position
  81. #define kYOffset            40                // Amount icons advance by vertically
  82. #define kXOffset            40                // Amount icons advance by horizontally
  83. #define kIconDimension        32                // Width/Height of an icon
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94. //=============================================================================
  95. //        PlotINITIcon : Plot a series of icons on the screen.                                                                 
  96. //-----------------------------------------------------------------------------
  97. //        Note :    We are passed an array of icon resource IDs, the number of
  98. //                valid IDs there are in the array, the number of ticks to wait
  99. //                between showing each icon, and a status flag for the presence
  100. //                of System 7.
  101. //
  102. //                Usually Extensions will pass in only one icon, but this allows
  103. //                us to support animated icons as well.
  104. //
  105. //                We use System 7's IconSuite routines to plot the icons. These
  106. //                look after all the details of deciding what icon to use,
  107. //                depending on the depth of the display. They also work using
  108. //                the same icon families that the Finder uses, which means
  109. //                there's no need for a 'cicn' version.
  110. //
  111. //                If we don't have System 7, we don't have access to the
  112. //                IconSuite routines, and so have to resort to plotting 'ICN#'
  113. //                resources.
  114. //-----------------------------------------------------------------------------
  115. void PlotINITIcon(Boolean haveSys7, int animDelay, int numIcons, int (*theIcons)[])
  116. {    CGrafPtr    oldPort;
  117.     GrafPort    newPort;
  118.     Handle        theIconHnds[kMaxNumIcons+1];
  119.     Rect         theIconPos;
  120.     long        theTicks;
  121.     int            i;
  122.  
  123.  
  124.  
  125.  
  126.     // Save the port, and open a new one
  127.     GetPort(&oldPort);
  128.     OpenCPort(&newPort);
  129.     SetPort(&newPort);
  130.  
  131.  
  132.  
  133.     // Work out where we should draw the icon
  134.     GetIconRect(&theIconPos, &newPort.portRect);
  135.  
  136.  
  137.  
  138.     // Read in handles to as many icons as we have to/can. If we Get/Plot/Dispose
  139.     // of each icon in turn, we can get jerky animation.
  140.     for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
  141.         {
  142.         if (haveSys7)
  143.             GetIconSuite(&theIconHnds[i], (*theIcons)[i], svAllLargeData);
  144.         else
  145.             theIconHnds[i] = GetResource('ICN#', (*theIcons)[i]);
  146.         }
  147.     
  148.         
  149.  
  150.     // Plot all the icons, with the right delay
  151.     for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
  152.         {
  153.         if (haveSys7)
  154.             PlotIconSuite(&theIconPos, atNone, ttNone, theIconHnds[i]);
  155.         else
  156.             PlotBWIcon(&theIconPos, theIconHnds[i]);
  157.         Delay(animDelay, &theTicks);
  158.         }
  159.     
  160.     
  161.     
  162.     // Before releasing them again
  163.     for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
  164.         {
  165.         if (haveSys7)
  166.             DisposeIconSuite(theIconHnds[i], true);
  167.         else
  168.             ReleaseResource(theIconHnds[i]);
  169.         }
  170.  
  171.  
  172.     
  173.     // Set things up for the next INIT's icon - but only if we
  174.     // actually showed anything
  175.     if (numIcons > 0)
  176.         NextPosition();
  177.  
  178.  
  179.  
  180.     // Dispose of our temporary port, and restore the old one
  181.     CloseCPort(&newPort);
  182.     SetPort(oldPort);
  183. }
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194. //=============================================================================
  195. //        GetIconRect : Calculate the correct position for our INIT's icon.                                                                 
  196. //-----------------------------------------------------------------------------
  197. //        Note :    We leave the correct position in theRect. We are given the
  198. //                portRect field of the current graphics port in thePortRect.
  199. //
  200. //                *theRect is forced to be onscreen. This is done by taking
  201. //                the horizontal offset modulo the screen width to generate the
  202. //                horizontal position of the icon, and the offset divided by the
  203. //                screen width to generate the proper row. This mechanism can get
  204. //                messed up if people plot icons at non-standard offsets.
  205. //
  206. //                We are also responsible for initialising the ShowInitIcon
  207. //                mechanism if we're the first INIT to load.
  208. //-----------------------------------------------------------------------------
  209. void GetIconRect(Rect *theRect, Rect *thePortRect)
  210. {    short    screenWid;
  211.  
  212.  
  213.  
  214.  
  215.     // If we're the first INIT to run we need to initialize the horizontal value
  216.     if (((gCurrX << 1) ^ kCheckSumConst) != gTheCheckSum)
  217.         gCurrX = kInitialXPosition;
  218.  
  219.  
  220.  
  221.     // Get the width of the screen, making sure we don't run off the edge
  222.     screenWid  = thePortRect->right - thePortRect->left;
  223.     screenWid -= screenWid % kXOffset;
  224.     
  225.     
  226.     
  227.     // Work out where the rectangle is going to be
  228.     theRect->left    = (gCurrX % screenWid);
  229.     theRect->right    = theRect->left + kIconDimension;
  230.     theRect->top    = thePortRect->bottom - (kYOffset * (1 + gCurrX / screenWid));
  231.     theRect->bottom    = theRect->top  + kIconDimension;
  232. }
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243. //=============================================================================
  244. //        NextPosition : Advance the ShowIcon position for the next INIT.                                                                 
  245. //-----------------------------------------------------------------------------
  246. //        Note :    In Patrick Beard's original version, this was done at the end
  247. //                of GetIconRect. That caused incorrect behaviour when IconWrap
  248. //                1.2 was used to wrap icons.
  249. //
  250. //                If an INIT using that version of ShowIconFamily was the first
  251. //                in a row, then the second icon in that row would land on top of
  252. //                it.
  253. //-----------------------------------------------------------------------------
  254. void NextPosition(void)
  255. {
  256.  
  257.  
  258.  
  259.  
  260.     // Advance the position for the next icon.
  261.     gCurrX += kXOffset;
  262.     
  263.  
  264.     
  265.     // Recompute the checksum.
  266.     gTheCheckSum = (gCurrX << 1) ^ kCheckSumConst;
  267. }
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278. //=============================================================================
  279. //        PlotBWIcon : Plot an 'ICN#' icon.                                                                 
  280. //-----------------------------------------------------------------------------
  281. //        Note :    We leave theIcon in the state we found it - unlocked.
  282. //
  283. //                This routine is based on Jim Friedlander's Technical Note,
  284. //                “Drawing Icons”
  285. //-----------------------------------------------------------------------------
  286. void PlotBWIcon(Rect *iconRect, Handle theIcon)
  287. {    BitMap        src, dest;
  288.     GrafPtr        myPort;
  289.  
  290.  
  291.  
  292.  
  293.     // If we don't have an icon, there's not much point in plotting it.
  294.     // But, if we do have one, we've got to lock it down.
  295.     if (theIcon == nil)
  296.         return;
  297.     else
  298.         HLock(theIcon);
  299.  
  300.     
  301.     
  302.     // Prepare the source and destination bitmaps.
  303.     src.baseAddr = *theIcon + 128;                            // Offset to Mask.
  304.     src.rowBytes = 4;
  305.     SetRect(&src.bounds, 0, 0, 32, 32);
  306.     GetPort(&myPort);
  307.     dest = ((GrafPtr) myPort)->portBits;
  308.  
  309.     
  310.     
  311.     // Transfer the mask.
  312.     CopyBits(&src, &dest, &src.bounds, iconRect, srcBic, nil);
  313.     
  314.     
  315.     
  316.     // Followed by the icon.
  317.     src.baseAddr = *theIcon;                                /// 0 offset to icon data.
  318.     CopyBits(&src, &dest, &src.bounds, iconRect, srcOr, nil);
  319.  
  320.  
  321.  
  322.     // Unlock the icon.
  323.     HUnlock(theIcon);
  324. }
  325.  
  326.