home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-12 | 7.6 KB | 340 lines | [TEXT/R*ch] |
- /* NAME:
- ShowIcon.c
-
- WRITTEN BY:
- Dair Grant, based on Peter Lewis/Jim Walker/François Pottier/
- previous ShowINIT authors' work.
-
- DESCRIPTION:
- This code is based on various bits of icon drawing code, and
- adapted to support animated icons.
-
- NOTES:
- We use the System 7 IconSuite calls to display the appropriate icon
- from our INIT code's icon family. This looks after bit depths, and
- removes the need for 'cicn's for colour displays.
-
- If we can't use the IconSuite routines, we can only handle 'ICN#'
- resources.
-
- ___________________________________________________________________________
- */
- //=============================================================================
- // Include files
- //-----------------------------------------------------------------------------
- #include <Resources.h>
- #include <Icons.h>
- #include "ES.h"
- #include "ShowIcon.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // Private function prototypes
- //-----------------------------------------------------------------------------
- unsigned short CheckSum(unsigned short x);
- void GetIconRect(Rect *theRect, Rect *thePortRect);
- void NextPosition(Rect *theRect);
- void PlotBWIcon(Rect *iconRect, Handle theIcon);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // Private defines
- //-----------------------------------------------------------------------------
- #define LMVCoord (* (short*) 0x92A) // Vertical coordinate
- #define LMVCheckSum (* (short*) 0x928) // Vertical coordinate checksum
- #define LMHCoord (* (short*) 0x92C) // Horizontal coordinate
- #define LMHCheckSum (* (short*) 0x92E) // Horizontal coordinate checksum
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // PlotINITIcon : Plot a series of icons on the screen.
- //-----------------------------------------------------------------------------
- // Note : We are passed an array of icon resource IDs, the number of
- // valid IDs there are in the array, the number of ticks to wait
- // between showing each icon, and a status flag for the presence
- // of Color Quickdraw and the IconSuite routines.
- //
- // Usually Extensions will pass in only one icon, but this allows
- // us to support animated icons as well.
- //
- // We use the _IconSuite routines to plot the icons. These
- // look after all the details of deciding what icon to use,
- // depending on the depth of the display. They also work using
- // the same icon families that the Finder uses, which means
- // there's no need for a 'cicn' version.
- //
- // If we don't have _IconSuite, or Colour QuickDraw, we have to
- // plot an 'ICN#' icon.
- //-----------------------------------------------------------------------------
- void PlotINITIcon(Boolean useIconSuite, short animDelay, short numIcons, short (*theIcons)[])
- { GrafPtr savePort, newPort;
- GrafPort newBWPort;
- CGrafPort newColourPort;
- Handle theIconHnds[kMaxNumIcons+1];
- Rect theIconPos;
- long theTicks;
- short i;
-
-
-
- // Save the port, and open a new one
- GetPort(&savePort);
- if (useIconSuite)
- {
- OpenCPort(&newColourPort);
- newPort = (GrafPtr) &newColourPort;
- }
- else
- {
- OpenPort(&newBWPort);
- newPort = &newBWPort;
- }
- SetPort(newPort);
-
-
-
- // Work out where we should draw the icon
- GetIconRect(&theIconPos, &newPort->portRect);
-
-
- // Read in handles to as many icons as we have to/can. If we Get/Plot/Dispose
- // of each icon in turn, we can get jerky animation.
- for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
- {
- if (useIconSuite)
- GetIconSuite(&theIconHnds[i], (*theIcons)[i], svAllLargeData);
- else
- theIconHnds[i] = GetResource('ICN#', (*theIcons)[i]);
- }
-
-
- // Plot all the icons, with the right delay
- for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
- {
- if (useIconSuite)
- PlotIconSuite(&theIconPos, atNone, ttNone, theIconHnds[i]);
- else
- PlotBWIcon(&theIconPos, theIconHnds[i]);
- Delay(animDelay, &theTicks);
- }
-
-
- // Before releasing them again
- for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
- {
- if (useIconSuite)
- DisposeIconSuite(theIconHnds[i], true);
- else
- ReleaseResource(theIconHnds[i]);
- }
-
-
- // Set things up for the next INIT's icon - if we drew anything
- if (numIcons > 0)
- NextPosition(&theIconPos);
-
-
- // Dispose of our temporary port, and restore the old one
- if (useIconSuite)
- CloseCPort(&newColourPort);
- else
- ClosePort(&newBWPort);
- SetPort(savePort);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // CheckSum : Verify that the previous INIT knew about ShowINIT Icon.
- //-----------------------------------------------------------------------------
- unsigned short CheckSum(unsigned short x)
- {
- return((x << 1) | (x >> 15)) ^ 0x1021;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // GetIconRect : Calculate the correct position for our INIT's icon.
- //-----------------------------------------------------------------------------
- // Note : We leave the correct position in theRect. We are given the
- // portRect field of the current graphics port in thePortRect.
- //
- // *theRect is forced to be onscreen. This is done by taking
- // the horizontal offset modulo the screen width to generate the
- // horizontal position of the icon, and the offset divided by the
- // screen width to generate the proper row. This mechanism can get
- // messed up if people plot icons at non-standard offsets.
- //
- // We are also responsible for initialising the ShowInitIcon
- // mechanism if we're the first INIT to load.
- //-----------------------------------------------------------------------------
- void GetIconRect(Rect *theRect, Rect *thePortRect)
- {
-
- // If we're first, initialise the mechanism for everyone else
- if (CheckSum(LMHCoord) != LMHCheckSum)
- LMHCoord = 8;
- if (CheckSum(LMVCoord) != LMVCheckSum)
- LMVCoord = thePortRect->bottom - 40;
-
-
-
- // Wrap round if we would move off the edge of the screen
- if (LMHCoord + 34 > thePortRect->right)
- {
- theRect->left = 8;
- theRect->top = LMVCoord - 40;
- }
-
- // Otherwise move ourselves to the next position
- else
- {
- theRect->left = LMHCoord;
- theRect->top = LMVCoord;
- }
- theRect->right = theRect->left + 32;
- theRect->bottom = theRect->top + 32;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // NextPosition : Advance the ShowIcon position for the next INIT.
- //-----------------------------------------------------------------------------
- void NextPosition(Rect *theRect)
- {
-
- // Update the position for the next INIT
- LMHCoord = theRect->left + 40;
- LMVCoord = theRect->top;
- LMHCheckSum = CheckSum(LMHCoord);
- LMVCheckSum = CheckSum(LMVCoord);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // PlotBWIcon : Plot an 'ICN#' icon.
- //-----------------------------------------------------------------------------
- void PlotBWIcon(Rect *iconRect, Handle theIcon)
- { BitMap src;
- GrafPtr thePort;
-
-
-
- // Lock the icon down, if we have one
- if (theIcon == nil)
- return;
- else
- HLock(theIcon);
-
-
- // Prepare the source and destination bitmaps
- src.baseAddr = *theIcon + 128; // 128 byte ofset to Mask
- src.rowBytes = 4;
- SetRect(&src.bounds, 0, 0, 32, 32);
- GetPort(&thePort);
-
-
- // Transfer the mask
- CopyBits(&src, &thePort->portBits, &src.bounds, iconRect, srcBic, nil);
-
-
- // Followed by the icon
- src.baseAddr = *theIcon; // 0 byte offset to icon data
- CopyBits(&src, &thePort->portBits, &src.bounds, iconRect, srcOr, nil);
-
-
- // Unlock the icon
- HUnlock(theIcon);
- }
-
-