home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / The Hacks! / ReverseMouse / ShowInit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-25  |  14.8 KB  |  494 lines  |  [TEXT/CWIE]

  1. /**-----------------------------------------------------------------------
  2. *
  3. * ShowInit.c
  4. *     by Paul Mercer, Darin Adler, Paul Snively,
  5. *        Frédéric Miserey, and Alex Rosenberg from an idea by Steve Capps
  6. *
  7. *    Converted to C by Paul Baxter
  8. *
  9. *    Created:  6/7/87  PM    - First version.
  10. *    Modified: 6/15/87 PM    - Changed to standard (Pascal) calling conventions.
  11. *         6/20/87 PM    - Fixed color & Finder bug on Mac II.
  12. *         6/22/87 DBA    - Improved handling of QuickDraw.
  13. *         6/29/87 DBA    - Used scratch8 to avoid conflict with “Easy Access”.
  14. *         6/30/87 DBA    - Changed to a 4-byte scheme with “checksum”.
  15. *         6/30/87 PFS    - Separated into ShowINIT and InnerShowINIT.
  16. *         7/1/87  DBA    - Fixed stack bug and switched to CurApName+.
  17. *         7/2/87  PM    - Added check for old signature in ApplScratch for
  18. *                   backword compatibility (TMON Startup).
  19. *         7/3/87  PM    - Removed _SysBeep in ErrorExit since it causes a crash.
  20. *                   Also changed ICN# plotter to srcOr mode for Blinker.
  21. *         7/13/87 PM    - Fixed a3 trashing bug in InnerShowINIT - exit code left
  22. *                   word on stack (reported by D. Dunham).
  23. *         7/21/87 PM    - Due to popular demand, InitGraf is no longer being called.
  24. *                   This avoids the gamma correction problem with Startupscreens
  25. *                   getting  “washed out” by ShowINIT though someone else is still
  26. *                   bound to call InitGraf sooner or later (i.e. InitWindows).
  27. *         7/29/87 PM    - Put InitGraf back in; this is required (reported by C. Derossi
  28. *                   at Apple Tech Support).  Took out GetPort/SetPort.
  29. *        10/06/87  PM    - Set CurrentA5 properly.  Rearranged myVars.
  30. *        12/28/87  PM    - Major revision to accomodate future INIT31 based ShowINIT.
  31. *        07/14/88  PM    - Major revision to get rid of above 'accomodations'.
  32. *                   Added color icon 'cicn' support and fixed beep crash.
  33. *                   Removed support for old signature.
  34. *        11/25/89 FCM    - Added Y dimension support, icl48 support to get rid of 'obsolete' cicns
  35. *         3/27/90  AMR    - 'cicn's were not being drawn in their native size.
  36. *
  37. *         12/01/94 PEB -  Modified to use LowMem.h
  38. *                NOTE:
  39. *                  In order to draw icl4 or icl8 icons the ICN# must also be present.
  40. *
  41. *----------------------------------------------------------------------*/
  42.  
  43.  
  44. #define myVCheck        (LMGetCurApName()+32-8)    // a GREAT place to store 8 bytes (it was Darin's idea)
  45. #define myV                (myVCheck+2)
  46. #define myH             (myV+2)
  47. #define myHCheck        (myH+2)                  // a simple checksum of myH to determine first-timeness
  48. #define firstX               8                     // X coordinate of first icon to be drawn
  49. #define bottomEdge        (8+32)                // this far from bottom of screen
  50. #define iconWidth        32                    // size of icon (square normally)
  51. #define visBuff            8                      // a visual buffer between icons of 8 pixels
  52. #define defaultMoveX    (iconWidth+visBuff)    // x default amount to move icons (40 pixels)
  53. #define defaultMoveY    40                    // y icon line height
  54. #define checksumConst    0x1021                // constant used for computing checksum
  55. #define minColorDepth    4                    // minimum bits/pixel for drawing color icons
  56. #define maxColorDepth    8                    // maximum bits/pixel for drawing color icons
  57. #define BWDepth            1                    // Black and White depth
  58. #define maskOffset        128                    // offset to mask in ICN#
  59. #define iconRowBytes    (32/8)                // 32/8 bits
  60.  
  61. #define hasCQDBit        6                    // this bit in ROM85 is cleared if Color QuickDraw is available
  62.  
  63. #define EightBitICON    'icl8'
  64. #define FourBitICON        'icl4'
  65. #define OneBitBitICON    'ICN#'
  66. #define ColorLookUpTable 'clut'
  67.  
  68. #define kNumQuickDrawPrivates 76
  69.  
  70. // This is the QuickDraw structure
  71. typedef struct  {
  72.     char privates[kNumQuickDrawPrivates];
  73.     long randSeed;
  74.     BitMap screenBits;
  75.     Cursor arrow;
  76.     Pattern dkGray;
  77.     Pattern ltGray;
  78.     Pattern gray;
  79.     Pattern black;
  80.     Pattern white;
  81.     GrafPtr thePort;
  82. } myqd;
  83.  
  84. typedef struct {
  85.     Rect destRect;     // drawing rect for icon
  86.     short currMoveX; // holds current moveX value
  87.     BitMap myBitMap; // a portion of the screen for copybits and copymask
  88.     GrafPort myport; // the port we open
  89.     myqd quick_data; // QuickDraw globals
  90.     long localA5;    // This it where I hope A5 should be.
  91.     long saveA5;     // save this so we can restore A5
  92. } my_data, * my_dataPtr;
  93.  
  94. pascal void ShowINIT(short iconID, short moveX);
  95.  
  96. static void INITTryBW(short iconID, short moveX, my_dataPtr data);
  97. static void INITTryMaxColor(short iconID, short moveX, my_dataPtr data);
  98. static void INITTryMinColor(short iconID, short moveX, my_dataPtr data);
  99.  
  100. static void INITDraw1Bit(Ptr p, short moveX, my_dataPtr data);
  101. static void INITDrawXBit(Ptr icl, Ptr onebit, unsigned short depth, short moveX, short iconID, my_dataPtr data);
  102. static void INITDrawCQD(CIconHandle h, short moveX, my_dataPtr data);
  103.  
  104. static void INITInit(my_dataPtr data);
  105. static void INITCleanup(my_dataPtr data, short moveX);
  106.  
  107. /*
  108. ;------------------------------------------------------------------------------------------------
  109. ;
  110. ; pascal void ShowINIT(short iconID, short moveX)
  111. ;
  112. ;    PURPOSE:
  113. ;        This is the main entry point for this module;
  114. ;
  115. ; short            iconID            IN    iconID of icon to be drawn
  116. ; short            moveX            IN    number of horizontal pixels to move (-1 = default = 40)
  117. ;
  118. ;------------------------------------------------------------------------------------------------
  119. */
  120. pascal void ShowINIT(short iconID, short moveX)
  121. {
  122.     my_data    data;
  123.  
  124.     GDHandle device;
  125.     PixMapHandle pixmap;
  126.     short pixsize;
  127.     pixsize = BWDepth;
  128.  
  129.     if ( LMGetROM85() & (1 << hasCQDBit)) {
  130.         device = LMGetMainDevice();
  131.         pixmap = (*device)->gdPMap;
  132.         pixsize = (*pixmap)->pixelSize;
  133.     }
  134.  
  135.     if (pixsize > minColorDepth) {
  136.         INITTryMaxColor(iconID, moveX, &data);
  137.     }
  138.     else {
  139.         if (pixsize == minColorDepth) {
  140.             INITTryMinColor(iconID, moveX, &data);
  141.         }
  142.         else {
  143.             INITTryBW(iconID, moveX, &data);
  144.         }
  145.     }
  146. }
  147.  
  148. /*
  149. ;------------------------------------------------------------------------------------------------
  150. ;
  151. ; void INITTryMaxColor(short iconID, short moveX, my_dataPtr data)
  152. ;
  153. ;    PURPOSE:
  154. ;        Try to initialize for an EightBitICON if possible; otherwise revert to FourBitICON
  155. ;
  156. ; short            iconID            IN    iconID of icon to be drawn
  157. ; short            moveX            IN    number of horizontal pixels to move (-1) = default
  158. ; my_dataPtr    data            IN    pointer to our global data
  159. ;
  160. ;------------------------------------------------------------------------------------------------
  161. */
  162. static void INITTryMaxColor(short iconID, short moveX, my_dataPtr data)
  163. {
  164.     Handle iclhandle, icnhandle;
  165.  
  166.     iclhandle = GetResource(EightBitICON, iconID);
  167.     if (iclhandle == nil) {
  168.         INITTryMinColor(iconID, moveX, data);
  169.     }
  170.     else {
  171.         icnhandle = GetResource(OneBitBitICON, iconID);
  172.         if (icnhandle == nil) {
  173.             ReleaseResource(iclhandle);
  174.             return;
  175.         }
  176.         HLock(iclhandle);
  177.         HLock(icnhandle);
  178.         INITDrawXBit(*iclhandle, *icnhandle, maxColorDepth, moveX, iconID, data);
  179.         ReleaseResource(iclhandle);
  180.         ReleaseResource(icnhandle);
  181.     }
  182. }
  183.  
  184. /*
  185. ;------------------------------------------------------------------------------------------------
  186. ;
  187. ; void INITTryMinColor(short iconID, short moveX, my_dataPtr data)
  188. ;
  189. ;    PURPOSE:
  190. ;        Try to initialize for an FourBitICON or cicn; otherwise black and white
  191. ;
  192. ; short            iconID            IN    iconID of icon to be drawn
  193. ; short            moveX            IN    number of horizontal pixels to move (-1) = default
  194. ; my_dataPtr    data            IN    pointer to our global data
  195. ;
  196. ;------------------------------------------------------------------------------------------------
  197. */
  198. static void INITTryMinColor(short iconID, short moveX, my_dataPtr data)
  199. {
  200.     Handle iclhandle, icnhandle;
  201.  
  202.     iclhandle = GetResource(FourBitICON, iconID);
  203.     if (iclhandle == nil) {
  204.         iclhandle = (Handle) GetCIcon(iconID);
  205.         if (iclhandle == nil) {
  206.             INITTryBW(iconID, moveX, data);
  207.         }
  208.         else { // cicn
  209.             INITDrawCQD((CIconHandle)iclhandle, moveX, data);
  210.             DisposeCIcon((CIconHandle)iclhandle);
  211.         }
  212.     }
  213.     else { // FourBitICON
  214.         icnhandle = GetResource(OneBitBitICON, iconID);
  215.         if (icnhandle == nil) {
  216.             ReleaseResource(iclhandle);
  217.             return;
  218.         }
  219.         HLock(iclhandle);
  220.         HLock(icnhandle);
  221.         INITDrawXBit(*iclhandle, *icnhandle, minColorDepth, moveX, iconID, data);
  222.         ReleaseResource(iclhandle);
  223.         ReleaseResource(icnhandle);
  224.     }
  225. }
  226.  
  227. /*
  228. ;------------------------------------------------------------------------------------------------
  229. ;
  230. ; void INITTryBW(short iconID, short moveX, my_dataPtr data)
  231. ;
  232. ;    PURPOSE:
  233. ;        Try to initialize for a ICN#
  234. ;
  235. ; short            iconID            IN    iconID of icon to be drawn
  236. ; short            moveX            IN    number of horizontal pixels to move (-1) = default
  237. ; my_dataPtr    data            IN    pointer to our global data
  238. ;
  239. ;------------------------------------------------------------------------------------------------
  240. */
  241. static void INITTryBW(short iconID, short moveX, my_dataPtr data)
  242. {
  243.     OSErr err;
  244.     Handle icnhandle;
  245.  
  246.     icnhandle = GetResource(OneBitBitICON, iconID);
  247.     if (icnhandle) {
  248.         LoadResource(icnhandle);
  249.         err = ResError();
  250.     }
  251.     if ((icnhandle != nil) || (err))  {
  252.         HLock(icnhandle);
  253.         HNoPurge(icnhandle);
  254.         INITDraw1Bit(*icnhandle, moveX, data);
  255.         ReleaseResource(icnhandle);
  256.     }
  257. }
  258.  
  259. /*
  260. ;------------------------------------------------------------------------------------------------
  261. ;
  262. ; void INITDrawXBit(Ptr icl, Ptr icn, short depth, short moveX, short iconID, my_dataPtr data)
  263. ;
  264. ;    PURPOSE:
  265. ;        Draw an EightBitICON or FourBitICON icon
  266. ;
  267. ; Ptr             icl                IN    pointer to an EightBitICON or a FourBitICON
  268. ; Ptr             icn                IN    pointer to ICN#
  269. ; short            depth            IN    depth of icon (4 or 8)
  270. ; short            moveX            IN    number of horizontal pixels to move (-1 = default = 40)
  271. ; short            iconID            IN    iconID of icon to be drawn
  272. ; my_dataPtr    data            IN    pointer to our global data
  273. ;
  274. ;------------------------------------------------------------------------------------------------
  275. */
  276. static void INITDrawXBit(Ptr icl, Ptr icn, unsigned short depth, short moveX, short iconID, my_dataPtr data)
  277. {
  278.     PixMapHandle pix;
  279.     CTabHandle clut;
  280.     Handle h;
  281.     Rect srcRect;
  282.     unsigned short rbytes;
  283.  
  284.     pix = NewPixMap();
  285.  
  286.     if (pix == nil) {
  287.         INITTryBW(iconID, moveX, data);
  288.     }
  289.     else {
  290.         INITInit(data);
  291.         HLock((Handle)pix);
  292.         DisposeHandle((Handle) (*pix)->pmTable);
  293.  
  294.         clut = (CTabHandle) RGetResource(ColorLookUpTable, depth);
  295.         (*pix)->pmTable = clut;
  296.  
  297.         (*pix)->baseAddr = icl;
  298.         rbytes = (unsigned short) (iconRowBytes * depth);
  299.         rbytes |= 0x8000;
  300.         (*pix)->rowBytes = rbytes;
  301.         SetRect(&(*pix)->bounds, 0, 0, iconWidth, iconWidth);
  302.         (*pix)->pixelType = chunky;
  303.         (*pix)->pixelSize = depth;
  304.         (*pix)->cmpCount = 1;
  305.         (*pix)->cmpSize = depth;
  306.  
  307.         (data->myBitMap).baseAddr = icn;
  308.         (data->myBitMap).baseAddr += maskOffset;
  309.         (data->myBitMap).rowBytes = iconRowBytes;
  310.         SetRect(&(data->myBitMap).bounds, 0, 0, iconWidth, iconWidth);
  311.  
  312.         SetRect(&srcRect, 0, 0, iconWidth, iconWidth);
  313.  
  314.         CopyMask((BitMap*)*pix, &data->myBitMap, &(data->myport).portBits, &srcRect, &srcRect, &data->destRect);
  315.  
  316.         h = NewHandle(0);
  317.         (*pix)->pmTable = (CTabHandle) h;
  318.         DisposePixMap(pix);
  319.  
  320.         INITCleanup(data, moveX);
  321.     }
  322. }
  323.  
  324. /*
  325. ;------------------------------------------------------------------------------------------------
  326. ;
  327. ; void INITDrawCQD(CIconHandle h, short moveX, short iconID, my_dataPtr data)
  328. ;
  329. ;    PURPOSE:
  330. ;        Draw a cicn
  331. ;
  332. ; CIconHandle    h                IN    cicn handle
  333. ; short            moveX            IN    number of horizontal pixels to move (-1) = default
  334. ; short            iconID            IN    iconID of icon to be drawn
  335. ; my_dataPtr    data            IN    pointer to our global data
  336. ;
  337. ;------------------------------------------------------------------------------------------------
  338. */
  339. static void INITDrawCQD(CIconHandle h, short moveX, my_dataPtr data)
  340. {
  341.     short width, height;
  342.     Rect* r;
  343.  
  344.     INITInit(data);
  345.  
  346.     r = &((*h)->iconPMap).bounds;
  347.     width = (short)(r->right - r->left);
  348.     data->currMoveX = (short)(width + visBuff);
  349.  
  350.     width -= iconWidth;
  351.     (data->destRect).right += width;
  352.  
  353.     height = (short)((r->bottom - r->top) - iconWidth);
  354.     (data->destRect).bottom += height;
  355.  
  356.     PlotCIcon(&data->destRect, h);
  357.  
  358.     INITCleanup(data, moveX);
  359. }
  360.  
  361. /*
  362. ;------------------------------------------------------------------------------------------------
  363. ;
  364. ; void INITDraw1Bit(Ptr iconPtrHdl, short moveX, short iconID, my_dataPtr data)
  365. ;
  366. ;    PURPOSE:
  367. ;        Draw a cicn
  368. ;
  369. ; Ptr            iconPtrHdl        IN    pointer to ICN#
  370. ; short            moveX            IN    number of horizontal pixels to move (-1) = default
  371. ; short            iconID            IN    iconID of icon to be drawn
  372. ; my_dataPtr    data            IN    pointer to our global data
  373. ;
  374. ;------------------------------------------------------------------------------------------------
  375. */
  376. static void INITDraw1Bit(Ptr iconPtrHdl, short moveX, my_dataPtr data)
  377. {
  378.     Rect srcRect;
  379.  
  380.     INITInit(data);
  381.  
  382.     (data->myBitMap).baseAddr = iconPtrHdl;
  383.     (data->myBitMap).baseAddr += maskOffset;
  384.     (data->myBitMap).rowBytes = iconRowBytes;
  385.  
  386.     SetRect(&srcRect,  0, 0, iconWidth, iconWidth);
  387.     SetRect(&(data->myBitMap).bounds, 0, 0, iconWidth, iconWidth);
  388.  
  389.     CopyBits(&data->myBitMap, &(data->myport).portBits, &srcRect,  &(data->destRect), srcBic, nil);
  390.  
  391.     (data->myBitMap).baseAddr -= maskOffset;
  392.     CopyBits(&data->myBitMap, &(data->myport).portBits, &srcRect,  &(data->destRect), srcOr, nil);
  393.  
  394.     INITCleanup(data, moveX);
  395. }
  396.  
  397. /*
  398. ;------------------------------------------------------------------------------------------------
  399. ;
  400. ; void INITInit(my_dataPtr data)
  401. ;
  402. ;    PURPOSE:
  403. ;        Initialize global data and quickdraw. Sets up rect for icon
  404. ;
  405. ; my_dataPtr    data            IN    pointer to our global data
  406. ;
  407. ;------------------------------------------------------------------------------------------------
  408. */
  409. static void INITInit(my_dataPtr data)
  410. {
  411.     unsigned short temp;
  412.     unsigned long ltemp;
  413.  
  414.     // These 2 lines of code are magic. Don't mess with it!
  415.     data->saveA5 = (long)LMGetCurrentA5();
  416.     SetA5((long) &data->localA5);
  417.  
  418.     InitGraf(&(data->quick_data).thePort);
  419.     OpenPort(&data->myport);
  420.  
  421.     temp = *((unsigned short*)myV);
  422.     temp <<= 1;
  423.     temp ^= checksumConst;
  424.  
  425.     if (*((unsigned short*)myVCheck) != temp) {
  426.         temp = (data->myport).portBits.bounds.bottom;
  427.         temp -= bottomEdge;
  428.         *((unsigned short*)myV) = temp;
  429.     }
  430.  
  431.     temp = *((unsigned short*)myH);
  432.     temp <<= 1;
  433.     temp ^= checksumConst;
  434.  
  435.     if (*((unsigned short*)myHCheck) != temp) {
  436.         *((unsigned short*)myH) = firstX;
  437.     }
  438.  
  439.     ltemp = *((unsigned long*)myV);
  440.     temp = (unsigned short)(ltemp & 0xFFFF);
  441.     temp += iconWidth;
  442.     if ((data->myport).portBits.bounds.right < temp) {
  443.         temp = *((unsigned short*)myV);
  444.         temp -= defaultMoveY;
  445.         *((unsigned short*)myV) = temp;
  446.         *((unsigned short*)myH) = firstX;
  447.     }
  448.     ltemp = *((unsigned long*)myV);
  449.  
  450.     *((unsigned long*)&data->destRect) = ltemp;
  451.     *((unsigned long*)&(data->destRect).bottom) = ltemp;
  452.     (data->destRect).right += iconWidth;
  453.     (data->destRect).bottom += iconWidth;
  454.     data->currMoveX = defaultMoveX;
  455. }
  456.  
  457. /*
  458. ;------------------------------------------------------------------------------------------------
  459. ;
  460. ; void INITCleanup(my_dataPtr data, moveX)
  461. ;
  462. ;    PURPOSE:
  463. ;        Reset  currenta5 and kill our quickdraw
  464. ;
  465. ; my_dataPtr    data            IN    pointer to our global data
  466. ;
  467. ;------------------------------------------------------------------------------------------------
  468. */
  469. static void INITCleanup(my_dataPtr data, short moveX)
  470. {
  471.     short temp, temp2;
  472.  
  473.     temp = *((short*)myH);
  474.     temp2 = moveX;
  475.  
  476.     if (moveX < 0) {
  477.         temp2 = data->currMoveX;
  478.     }
  479.     temp += temp2;
  480.  
  481.     *((short*)myH) = temp;
  482.     temp <<= 1;
  483.     temp ^= checksumConst;
  484.     *((short*)myHCheck) = temp;
  485.  
  486.     temp = *((short*)myV);
  487.     temp <<= 1;
  488.     temp ^= checksumConst;
  489.     *((short*)myVCheck) = temp;
  490.  
  491.     ClosePort(&data->myport);
  492.     SetA5(data->saveA5);
  493. }
  494.