home *** CD-ROM | disk | FTP | other *** search
- /**-----------------------------------------------------------------------
- *
- * ShowInit.c
- * by Paul Mercer, Darin Adler, Paul Snively,
- * Frédéric Miserey, and Alex Rosenberg from an idea by Steve Capps
- *
- * Converted to C by Paul Baxter
- *
- * Created: 6/7/87 PM - First version.
- * Modified: 6/15/87 PM - Changed to standard (Pascal) calling conventions.
- * 6/20/87 PM - Fixed color & Finder bug on Mac II.
- * 6/22/87 DBA - Improved handling of QuickDraw.
- * 6/29/87 DBA - Used scratch8 to avoid conflict with “Easy Access”.
- * 6/30/87 DBA - Changed to a 4-byte scheme with “checksum”.
- * 6/30/87 PFS - Separated into ShowINIT and InnerShowINIT.
- * 7/1/87 DBA - Fixed stack bug and switched to CurApName+.
- * 7/2/87 PM - Added check for old signature in ApplScratch for
- * backword compatibility (TMON Startup).
- * 7/3/87 PM - Removed _SysBeep in ErrorExit since it causes a crash.
- * Also changed ICN# plotter to srcOr mode for Blinker.
- * 7/13/87 PM - Fixed a3 trashing bug in InnerShowINIT - exit code left
- * word on stack (reported by D. Dunham).
- * 7/21/87 PM - Due to popular demand, InitGraf is no longer being called.
- * This avoids the gamma correction problem with Startupscreens
- * getting “washed out” by ShowINIT though someone else is still
- * bound to call InitGraf sooner or later (i.e. InitWindows).
- * 7/29/87 PM - Put InitGraf back in; this is required (reported by C. Derossi
- * at Apple Tech Support). Took out GetPort/SetPort.
- * 10/06/87 PM - Set CurrentA5 properly. Rearranged myVars.
- * 12/28/87 PM - Major revision to accomodate future INIT31 based ShowINIT.
- * 07/14/88 PM - Major revision to get rid of above 'accomodations'.
- * Added color icon 'cicn' support and fixed beep crash.
- * Removed support for old signature.
- * 11/25/89 FCM - Added Y dimension support, icl48 support to get rid of 'obsolete' cicns
- * 3/27/90 AMR - 'cicn's were not being drawn in their native size.
- *
- * 12/01/94 PEB - Modified to use LowMem.h
- * NOTE:
- * In order to draw icl4 or icl8 icons the ICN# must also be present.
- *
- *----------------------------------------------------------------------*/
-
-
- #define myVCheck (LMGetCurApName()+32-8) // a GREAT place to store 8 bytes (it was Darin's idea)
- #define myV (myVCheck+2)
- #define myH (myV+2)
- #define myHCheck (myH+2) // a simple checksum of myH to determine first-timeness
- #define firstX 8 // X coordinate of first icon to be drawn
- #define bottomEdge (8+32) // this far from bottom of screen
- #define iconWidth 32 // size of icon (square normally)
- #define visBuff 8 // a visual buffer between icons of 8 pixels
- #define defaultMoveX (iconWidth+visBuff) // x default amount to move icons (40 pixels)
- #define defaultMoveY 40 // y icon line height
- #define checksumConst 0x1021 // constant used for computing checksum
- #define minColorDepth 4 // minimum bits/pixel for drawing color icons
- #define maxColorDepth 8 // maximum bits/pixel for drawing color icons
- #define BWDepth 1 // Black and White depth
- #define maskOffset 128 // offset to mask in ICN#
- #define iconRowBytes (32/8) // 32/8 bits
-
- #define hasCQDBit 6 // this bit in ROM85 is cleared if Color QuickDraw is available
-
- #define EightBitICON 'icl8'
- #define FourBitICON 'icl4'
- #define OneBitBitICON 'ICN#'
- #define ColorLookUpTable 'clut'
-
- #define kNumQuickDrawPrivates 76
-
- // This is the QuickDraw structure
- typedef struct {
- char privates[kNumQuickDrawPrivates];
- long randSeed;
- BitMap screenBits;
- Cursor arrow;
- Pattern dkGray;
- Pattern ltGray;
- Pattern gray;
- Pattern black;
- Pattern white;
- GrafPtr thePort;
- } myqd;
-
- typedef struct {
- Rect destRect; // drawing rect for icon
- short currMoveX; // holds current moveX value
- BitMap myBitMap; // a portion of the screen for copybits and copymask
- GrafPort myport; // the port we open
- myqd quick_data; // QuickDraw globals
- long localA5; // This it where I hope A5 should be.
- long saveA5; // save this so we can restore A5
- } my_data, * my_dataPtr;
-
- pascal void ShowINIT(short iconID, short moveX);
-
- static void INITTryBW(short iconID, short moveX, my_dataPtr data);
- static void INITTryMaxColor(short iconID, short moveX, my_dataPtr data);
- static void INITTryMinColor(short iconID, short moveX, my_dataPtr data);
-
- static void INITDraw1Bit(Ptr p, short moveX, my_dataPtr data);
- static void INITDrawXBit(Ptr icl, Ptr onebit, unsigned short depth, short moveX, short iconID, my_dataPtr data);
- static void INITDrawCQD(CIconHandle h, short moveX, my_dataPtr data);
-
- static void INITInit(my_dataPtr data);
- static void INITCleanup(my_dataPtr data, short moveX);
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; pascal void ShowINIT(short iconID, short moveX)
- ;
- ; PURPOSE:
- ; This is the main entry point for this module;
- ;
- ; short iconID IN iconID of icon to be drawn
- ; short moveX IN number of horizontal pixels to move (-1 = default = 40)
- ;
- ;------------------------------------------------------------------------------------------------
- */
- pascal void ShowINIT(short iconID, short moveX)
- {
- my_data data;
-
- GDHandle device;
- PixMapHandle pixmap;
- short pixsize;
- pixsize = BWDepth;
-
- if ( LMGetROM85() & (1 << hasCQDBit)) {
- device = LMGetMainDevice();
- pixmap = (*device)->gdPMap;
- pixsize = (*pixmap)->pixelSize;
- }
-
- if (pixsize > minColorDepth) {
- INITTryMaxColor(iconID, moveX, &data);
- }
- else {
- if (pixsize == minColorDepth) {
- INITTryMinColor(iconID, moveX, &data);
- }
- else {
- INITTryBW(iconID, moveX, &data);
- }
- }
- }
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; void INITTryMaxColor(short iconID, short moveX, my_dataPtr data)
- ;
- ; PURPOSE:
- ; Try to initialize for an EightBitICON if possible; otherwise revert to FourBitICON
- ;
- ; short iconID IN iconID of icon to be drawn
- ; short moveX IN number of horizontal pixels to move (-1) = default
- ; my_dataPtr data IN pointer to our global data
- ;
- ;------------------------------------------------------------------------------------------------
- */
- static void INITTryMaxColor(short iconID, short moveX, my_dataPtr data)
- {
- Handle iclhandle, icnhandle;
-
- iclhandle = GetResource(EightBitICON, iconID);
- if (iclhandle == nil) {
- INITTryMinColor(iconID, moveX, data);
- }
- else {
- icnhandle = GetResource(OneBitBitICON, iconID);
- if (icnhandle == nil) {
- ReleaseResource(iclhandle);
- return;
- }
- HLock(iclhandle);
- HLock(icnhandle);
- INITDrawXBit(*iclhandle, *icnhandle, maxColorDepth, moveX, iconID, data);
- ReleaseResource(iclhandle);
- ReleaseResource(icnhandle);
- }
- }
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; void INITTryMinColor(short iconID, short moveX, my_dataPtr data)
- ;
- ; PURPOSE:
- ; Try to initialize for an FourBitICON or cicn; otherwise black and white
- ;
- ; short iconID IN iconID of icon to be drawn
- ; short moveX IN number of horizontal pixels to move (-1) = default
- ; my_dataPtr data IN pointer to our global data
- ;
- ;------------------------------------------------------------------------------------------------
- */
- static void INITTryMinColor(short iconID, short moveX, my_dataPtr data)
- {
- Handle iclhandle, icnhandle;
-
- iclhandle = GetResource(FourBitICON, iconID);
- if (iclhandle == nil) {
- iclhandle = (Handle) GetCIcon(iconID);
- if (iclhandle == nil) {
- INITTryBW(iconID, moveX, data);
- }
- else { // cicn
- INITDrawCQD((CIconHandle)iclhandle, moveX, data);
- DisposeCIcon((CIconHandle)iclhandle);
- }
- }
- else { // FourBitICON
- icnhandle = GetResource(OneBitBitICON, iconID);
- if (icnhandle == nil) {
- ReleaseResource(iclhandle);
- return;
- }
- HLock(iclhandle);
- HLock(icnhandle);
- INITDrawXBit(*iclhandle, *icnhandle, minColorDepth, moveX, iconID, data);
- ReleaseResource(iclhandle);
- ReleaseResource(icnhandle);
- }
- }
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; void INITTryBW(short iconID, short moveX, my_dataPtr data)
- ;
- ; PURPOSE:
- ; Try to initialize for a ICN#
- ;
- ; short iconID IN iconID of icon to be drawn
- ; short moveX IN number of horizontal pixels to move (-1) = default
- ; my_dataPtr data IN pointer to our global data
- ;
- ;------------------------------------------------------------------------------------------------
- */
- static void INITTryBW(short iconID, short moveX, my_dataPtr data)
- {
- OSErr err;
- Handle icnhandle;
-
- icnhandle = GetResource(OneBitBitICON, iconID);
- if (icnhandle) {
- LoadResource(icnhandle);
- err = ResError();
- }
- if ((icnhandle != nil) || (err)) {
- HLock(icnhandle);
- HNoPurge(icnhandle);
- INITDraw1Bit(*icnhandle, moveX, data);
- ReleaseResource(icnhandle);
- }
- }
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; void INITDrawXBit(Ptr icl, Ptr icn, short depth, short moveX, short iconID, my_dataPtr data)
- ;
- ; PURPOSE:
- ; Draw an EightBitICON or FourBitICON icon
- ;
- ; Ptr icl IN pointer to an EightBitICON or a FourBitICON
- ; Ptr icn IN pointer to ICN#
- ; short depth IN depth of icon (4 or 8)
- ; short moveX IN number of horizontal pixels to move (-1 = default = 40)
- ; short iconID IN iconID of icon to be drawn
- ; my_dataPtr data IN pointer to our global data
- ;
- ;------------------------------------------------------------------------------------------------
- */
- static void INITDrawXBit(Ptr icl, Ptr icn, unsigned short depth, short moveX, short iconID, my_dataPtr data)
- {
- PixMapHandle pix;
- CTabHandle clut;
- Handle h;
- Rect srcRect;
- unsigned short rbytes;
-
- pix = NewPixMap();
-
- if (pix == nil) {
- INITTryBW(iconID, moveX, data);
- }
- else {
- INITInit(data);
- HLock((Handle)pix);
- DisposeHandle((Handle) (*pix)->pmTable);
-
- clut = (CTabHandle) RGetResource(ColorLookUpTable, depth);
- (*pix)->pmTable = clut;
-
- (*pix)->baseAddr = icl;
- rbytes = (unsigned short) (iconRowBytes * depth);
- rbytes |= 0x8000;
- (*pix)->rowBytes = rbytes;
- SetRect(&(*pix)->bounds, 0, 0, iconWidth, iconWidth);
- (*pix)->pixelType = chunky;
- (*pix)->pixelSize = depth;
- (*pix)->cmpCount = 1;
- (*pix)->cmpSize = depth;
-
- (data->myBitMap).baseAddr = icn;
- (data->myBitMap).baseAddr += maskOffset;
- (data->myBitMap).rowBytes = iconRowBytes;
- SetRect(&(data->myBitMap).bounds, 0, 0, iconWidth, iconWidth);
-
- SetRect(&srcRect, 0, 0, iconWidth, iconWidth);
-
- CopyMask((BitMap*)*pix, &data->myBitMap, &(data->myport).portBits, &srcRect, &srcRect, &data->destRect);
-
- h = NewHandle(0);
- (*pix)->pmTable = (CTabHandle) h;
- DisposePixMap(pix);
-
- INITCleanup(data, moveX);
- }
- }
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; void INITDrawCQD(CIconHandle h, short moveX, short iconID, my_dataPtr data)
- ;
- ; PURPOSE:
- ; Draw a cicn
- ;
- ; CIconHandle h IN cicn handle
- ; short moveX IN number of horizontal pixels to move (-1) = default
- ; short iconID IN iconID of icon to be drawn
- ; my_dataPtr data IN pointer to our global data
- ;
- ;------------------------------------------------------------------------------------------------
- */
- static void INITDrawCQD(CIconHandle h, short moveX, my_dataPtr data)
- {
- short width, height;
- Rect* r;
-
- INITInit(data);
-
- r = &((*h)->iconPMap).bounds;
- width = (short)(r->right - r->left);
- data->currMoveX = (short)(width + visBuff);
-
- width -= iconWidth;
- (data->destRect).right += width;
-
- height = (short)((r->bottom - r->top) - iconWidth);
- (data->destRect).bottom += height;
-
- PlotCIcon(&data->destRect, h);
-
- INITCleanup(data, moveX);
- }
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; void INITDraw1Bit(Ptr iconPtrHdl, short moveX, short iconID, my_dataPtr data)
- ;
- ; PURPOSE:
- ; Draw a cicn
- ;
- ; Ptr iconPtrHdl IN pointer to ICN#
- ; short moveX IN number of horizontal pixels to move (-1) = default
- ; short iconID IN iconID of icon to be drawn
- ; my_dataPtr data IN pointer to our global data
- ;
- ;------------------------------------------------------------------------------------------------
- */
- static void INITDraw1Bit(Ptr iconPtrHdl, short moveX, my_dataPtr data)
- {
- Rect srcRect;
-
- INITInit(data);
-
- (data->myBitMap).baseAddr = iconPtrHdl;
- (data->myBitMap).baseAddr += maskOffset;
- (data->myBitMap).rowBytes = iconRowBytes;
-
- SetRect(&srcRect, 0, 0, iconWidth, iconWidth);
- SetRect(&(data->myBitMap).bounds, 0, 0, iconWidth, iconWidth);
-
- CopyBits(&data->myBitMap, &(data->myport).portBits, &srcRect, &(data->destRect), srcBic, nil);
-
- (data->myBitMap).baseAddr -= maskOffset;
- CopyBits(&data->myBitMap, &(data->myport).portBits, &srcRect, &(data->destRect), srcOr, nil);
-
- INITCleanup(data, moveX);
- }
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; void INITInit(my_dataPtr data)
- ;
- ; PURPOSE:
- ; Initialize global data and quickdraw. Sets up rect for icon
- ;
- ; my_dataPtr data IN pointer to our global data
- ;
- ;------------------------------------------------------------------------------------------------
- */
- static void INITInit(my_dataPtr data)
- {
- unsigned short temp;
- unsigned long ltemp;
-
- // These 2 lines of code are magic. Don't mess with it!
- data->saveA5 = (long)LMGetCurrentA5();
- SetA5((long) &data->localA5);
-
- InitGraf(&(data->quick_data).thePort);
- OpenPort(&data->myport);
-
- temp = *((unsigned short*)myV);
- temp <<= 1;
- temp ^= checksumConst;
-
- if (*((unsigned short*)myVCheck) != temp) {
- temp = (data->myport).portBits.bounds.bottom;
- temp -= bottomEdge;
- *((unsigned short*)myV) = temp;
- }
-
- temp = *((unsigned short*)myH);
- temp <<= 1;
- temp ^= checksumConst;
-
- if (*((unsigned short*)myHCheck) != temp) {
- *((unsigned short*)myH) = firstX;
- }
-
- ltemp = *((unsigned long*)myV);
- temp = (unsigned short)(ltemp & 0xFFFF);
- temp += iconWidth;
- if ((data->myport).portBits.bounds.right < temp) {
- temp = *((unsigned short*)myV);
- temp -= defaultMoveY;
- *((unsigned short*)myV) = temp;
- *((unsigned short*)myH) = firstX;
- }
- ltemp = *((unsigned long*)myV);
-
- *((unsigned long*)&data->destRect) = ltemp;
- *((unsigned long*)&(data->destRect).bottom) = ltemp;
- (data->destRect).right += iconWidth;
- (data->destRect).bottom += iconWidth;
- data->currMoveX = defaultMoveX;
- }
-
- /*
- ;------------------------------------------------------------------------------------------------
- ;
- ; void INITCleanup(my_dataPtr data, moveX)
- ;
- ; PURPOSE:
- ; Reset currenta5 and kill our quickdraw
- ;
- ; my_dataPtr data IN pointer to our global data
- ;
- ;------------------------------------------------------------------------------------------------
- */
- static void INITCleanup(my_dataPtr data, short moveX)
- {
- short temp, temp2;
-
- temp = *((short*)myH);
- temp2 = moveX;
-
- if (moveX < 0) {
- temp2 = data->currMoveX;
- }
- temp += temp2;
-
- *((short*)myH) = temp;
- temp <<= 1;
- temp ^= checksumConst;
- *((short*)myHCheck) = temp;
-
- temp = *((short*)myV);
- temp <<= 1;
- temp ^= checksumConst;
- *((short*)myVCheck) = temp;
-
- ClosePort(&data->myport);
- SetA5(data->saveA5);
- }
-