home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / PRIcon.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  15.0 KB  |  617 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                PRIcon.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWEXCEPT_H
  13. #include "FWExcept.h"
  14. #endif
  15.  
  16. #ifndef PRICON_H
  17. #include "PRIcon.h"
  18. #endif
  19.  
  20. // ----- OS Includes -----
  21.  
  22. #ifndef FWRESFIL_H
  23. #include "FWResFil.h"
  24. #endif
  25.  
  26. #ifndef FWRESFIL_H
  27. #include "FWResFil.h"
  28. #endif
  29.  
  30. #ifndef FWRECT_H
  31. #include "FWRect.h"
  32. #endif
  33.  
  34. #ifndef FWPOINT_H
  35. #include "FWPoint.h"
  36. #endif
  37.  
  38. #ifndef FWGC_H
  39. #include "FWGC.h"
  40. #endif
  41.  
  42. #ifndef FWWINDIB_H
  43. #include "FWWinDIB.h"
  44. #endif
  45.  
  46. // ----- Foundation Includes -----
  47.  
  48. #ifndef FWSTREAM_H
  49. #include "FWStream.h"
  50. #endif
  51.  
  52. #ifndef FWMEMMGR_H
  53. #include "FWMemMgr.h"
  54. #endif
  55.  
  56. #ifndef FWMEMHLP_H
  57. #include "FWMemHlp.h"
  58. #endif
  59.  
  60. // ----- Platform Includes -----
  61.  
  62. #if defined(FW_BUILD_MAC) && !defined(__ICONS__)
  63. #include <Icons.h>
  64. #endif
  65.  
  66. //========================================================================================
  67. //    RunTime Info
  68. //========================================================================================
  69.  
  70. #ifdef FW_BUILD_MAC
  71. #pragma segment FWGraphics_Icon
  72. #endif
  73.  
  74. FW_DEFINE_AUTO(FW_CPrivIconRep)
  75.  
  76. #ifdef FW_BUILD_MAC
  77.  
  78. //----------------------------------------------------------------------------------------
  79. // Action procs for icon enumeration
  80. //----------------------------------------------------------------------------------------
  81.  
  82. static pascal OSErr FlattenActionProc(ResType type, Handle* iconData, void* dataPtr);
  83. static pascal OSErr CopyIconActionProc(ResType type, Handle* iconData, void* dataPtr);
  84. static pascal OSErr GetIconSizeActionProc(ResType type, Handle* iconData, void* dataPtr);
  85.  
  86. #endif
  87.  
  88. //========================================================================================
  89. // class FW_CPrivIconRep
  90. //========================================================================================
  91.  
  92. //----------------------------------------------------------------------------------------
  93. // FW_CPrivIconRep::FW_CPrivIconRep
  94. //----------------------------------------------------------------------------------------
  95. // From platform icon: will not own the icon
  96.  
  97. FW_CPrivIconRep::FW_CPrivIconRep(FW_PlatformIcon platformIcon) :
  98.     fOwnIcon(FALSE),
  99.     fPlatformIcon(platformIcon),
  100.     fMaxIconSize(GetPlatformIconSize(platformIcon))
  101. {
  102.     FW_END_CONSTRUCTOR
  103. }
  104.  
  105. //----------------------------------------------------------------------------------------
  106. // FW_CPrivIconRep::FW_CPrivIconRep
  107. //----------------------------------------------------------------------------------------
  108. // From another icon: will own the icon (a copy is made)
  109.  
  110. FW_CPrivIconRep::FW_CPrivIconRep(const FW_CPrivIconRep& icon) :
  111.     fOwnIcon(TRUE),
  112.     fPlatformIcon(NULL)
  113. {
  114.     fPlatformIcon    = CopyPlatformIcon(icon.fPlatformIcon);
  115.     fMaxIconSize     = GetPlatformIconSize(fPlatformIcon);
  116.  
  117.     FW_END_CONSTRUCTOR
  118. }
  119.  
  120. //----------------------------------------------------------------------------------------
  121. // FW_CPrivIconRep::FW_CPrivIconRep
  122. //----------------------------------------------------------------------------------------
  123. // From resources: will own the icon
  124.  
  125. FW_CPrivIconRep::FW_CPrivIconRep(FW_OResourceFile* resourceFile,
  126.                          FW_ResourceID resID,
  127.                          short size) :
  128.     fOwnIcon(TRUE),
  129.     fPlatformIcon(NULL)
  130. {
  131. #ifdef FW_BUILD_MAC
  132.     FW_ASSERT(size == 32 || size == 16 || size == 12);
  133.     long selector;
  134.     FW_ResourceType resTypes[4];
  135.     
  136.     switch(size)
  137.     {
  138.     case 32:
  139.         selector = svAllLargeData;
  140.         resTypes[0]  = 'ICN#';
  141.         resTypes[1]  = 'icl4';
  142.         resTypes[2]  = 'icl8';
  143.         break;
  144.  
  145.     case 16:
  146.         selector = svAllSmallData;
  147.         resTypes[0]  = 'ics#';
  148.         resTypes[1]  = 'ics4';
  149.         resTypes[2]  = 'ics8';
  150.         break;
  151.  
  152.     case 12:
  153.         selector = svAllMiniData;
  154.         resTypes[0]  = 'icm#';
  155.         resTypes[1]  = 'icm4';
  156.         resTypes[2]  = 'icm8';
  157.         break;
  158.  
  159.     default:
  160.         FW_ASSERT(FALSE);        // Not a valid icon size
  161.     }
  162.     
  163.     // Check to see if the icon is there
  164.     FW_Boolean resourceFound = FALSE;
  165.     FW_SOMEnvironment ev;
  166.     for (short i = 0; i < 3; ++i)
  167.     {
  168.         if (resourceFile->HasResource(ev, resID, resTypes[i]))
  169.         {
  170.             resourceFound = TRUE;
  171.             break;
  172.         }
  173.     }
  174.  
  175.     // Load the icon suite
  176.     FW_PlatformIcon newIconSuite = NULL;
  177.     OSErr err = noErr;
  178.     if(resourceFound)
  179.         err = ::GetIconSuite(&newIconSuite, resID, selector);
  180.  
  181.     FW_FailOnError(err);
  182.     if(!resourceFound || newIconSuite == NULL)
  183.         FW_Failure(FW_xResourceNotFound);
  184.         
  185.     // We need to copy the icon suite in case the resource file is a code fragment
  186.     fPlatformIcon = CopyPlatformIcon(newIconSuite);
  187.     ::DisposeIconSuite(newIconSuite, TRUE);
  188.     fMaxIconSize = size;
  189. #endif
  190. #ifdef FW_BUILD_WIN
  191.     FW_SOMEnvironment ev;
  192.     HINSTANCE hInstance = resourceFile->PrivGetResourceFileID(ev);
  193.     HANDLE hImage = ::LoadImage(hInstance, MAKEINTRESOURCE(resID), IMAGE_ICON, size, size,    0);
  194.     
  195.     if(hImage == NULL)
  196.         FW_Failure(FW_xResourceNotFound);
  197.  
  198.     fPlatformIcon = (HICON) hImage;
  199.     fMaxIconSize = size;        
  200. #endif
  201.     FW_END_CONSTRUCTOR
  202. }
  203.  
  204. //----------------------------------------------------------------------------------------
  205. // FW_CPrivIconRep::FW_CPrivIconRep
  206. //----------------------------------------------------------------------------------------
  207. // From stream: will own the icon
  208.  
  209. FW_CPrivIconRep::FW_CPrivIconRep(FW_CReadableStream& archive) :
  210.     fOwnIcon(TRUE),
  211.     fPlatformIcon(NULL)
  212. {
  213. #ifdef FW_BUILD_MAC
  214.     ::NewIconSuite(&fPlatformIcon);
  215.  
  216.     ResType resType;
  217.     archive.Read(&resType, sizeof(resType));
  218.     while(resType != 0)
  219.     {
  220.         // Read icon data size
  221.         Size iconSize;
  222.         archive >> iconSize;
  223.         
  224.         // Read icon data
  225.         if(iconSize != NULL)
  226.         {
  227.             FW_CAcquireTemporarySystemHandle handle(iconSize);
  228.             archive.Read(handle.GetPointer(), iconSize);
  229.             
  230.             Handle iconHandle = handle.Orphan();
  231.             
  232.             ::AddIconToSuite(iconHandle, fPlatformIcon, resType);
  233.         }
  234.     
  235.         archive.Read(&resType, sizeof(resType));
  236.     }
  237. #endif
  238. #ifdef FW_BUILD_WIN
  239.     // Read the header
  240.     ICONINFO iconInfo;
  241.     archive.Read(&iconInfo, sizeof(iconInfo));
  242.     FW_ASSERT(iconInfo.fIcon);
  243.     
  244.     FW_WinDIB hDIB;
  245.  
  246.     // Read and convert the mask bitmap
  247.     if(iconInfo.hbmMask != NULL)
  248.     {
  249.         hDIB = FW_DIBLoadFromStream(archive, FALSE);
  250.         
  251.         FW_TRY
  252.         {
  253.             iconInfo.hbmMask = FW_DIBConvertToBitmap(hDIB, NULL);
  254.         }
  255.         FW_CATCH_BEGIN
  256.         FW_CATCH_EVERYTHING()
  257.         {
  258.             FW_DIBFree(hDIB);
  259.             FW_THROW_SAME();
  260.         }
  261.         FW_CATCH_END
  262.     }
  263.  
  264.     // Read and convert the color bitmap
  265.     if(iconInfo.hbmColor != NULL)
  266.     {
  267.         hDIB = FW_DIBLoadFromStream(archive, FALSE);
  268.         
  269.         FW_TRY
  270.         {
  271.             iconInfo.hbmColor = FW_DIBConvertToBitmap(hDIB, NULL);
  272.         }
  273.         FW_CATCH_BEGIN
  274.         FW_CATCH_EVERYTHING()
  275.         {
  276.             FW_DIBFree(hDIB);
  277.             ::DeleteObject(iconInfo.hbmMask);
  278.             FW_THROW_SAME();
  279.         }
  280.         FW_CATCH_END
  281.     }
  282.  
  283.     // Try and create the icon
  284.     fPlatformIcon = ::CreateIconIndirect(&iconInfo);
  285.  
  286.     if(fPlatformIcon == NULL)
  287.     {
  288.         ::DeleteObject(iconInfo.hbmMask);
  289.         ::DeleteObject(iconInfo.hbmColor);
  290.         
  291.         FW_Failure(FW_xMemoryExhausted);
  292.     }
  293. #endif
  294.  
  295.     fMaxIconSize = GetPlatformIconSize(fPlatformIcon);
  296.  
  297.     FW_END_CONSTRUCTOR
  298. }
  299.  
  300. //----------------------------------------------------------------------------------------
  301. // FW_CPrivIconRep::~FW_CPrivIconRep
  302. //----------------------------------------------------------------------------------------
  303.  
  304. FW_CPrivIconRep::~FW_CPrivIconRep()
  305. {
  306.     FW_START_DESTRUCTOR
  307.     DisposePlatformIcon();
  308. }
  309.  
  310. //----------------------------------------------------------------------------------------
  311. // FW_CPrivIconRep::Write
  312. //----------------------------------------------------------------------------------------
  313.  
  314. void FW_CPrivIconRep::Write(FW_CWritableStream& archive) const
  315. {
  316. #ifdef FW_BUILD_MAC
  317.     IconActionUPP actionUPP = NewIconActionProc(FlattenActionProc);
  318.     ForEachIconDo(
  319.         fPlatformIcon,
  320.         svAllAvailableData,
  321.         actionUPP,
  322.         (void*) &archive);
  323.     DisposeRoutineDescriptor(actionUPP);
  324.     
  325.     // Append a NULL ResType
  326.     ResType nullType = 0;
  327.     archive.Write(&nullType, sizeof(nullType));
  328. #endif
  329. #ifdef FW_BUILD_WIN
  330.     ICONINFO iconInfo;
  331.     ::GetIconInfo(fPlatformIcon, &iconInfo);
  332.     FW_ASSERT(iconInfo.fIcon);
  333.     
  334.     FW_WinDIB hDIB;
  335.  
  336.     // Write the header
  337.     archive.Write(&iconInfo, sizeof(iconInfo));
  338.     
  339.     // Write the mask bitmap
  340.     if(iconInfo.hbmMask != NULL)
  341.     {
  342.         hDIB = FW_DIBConvertFromBitmap(iconInfo.hbmMask, 0, NULL);
  343.         FW_TRY
  344.         {
  345.             FW_DIBSaveToStream(archive, hDIB, FALSE);
  346.         }    
  347.         FW_CATCH_BEGIN
  348.         FW_CATCH_EVERYTHING()
  349.         {
  350.             FW_DIBFree(hDIB);
  351.             FW_THROW_SAME();
  352.         }
  353.         FW_CATCH_END
  354.     }
  355.  
  356.     // Write the color bitmap
  357.     if(iconInfo.hbmColor != NULL)
  358.     {
  359.         hDIB = FW_DIBConvertFromBitmap(iconInfo.hbmColor, 0, NULL);
  360.         FW_TRY
  361.         {
  362.             FW_DIBSaveToStream(archive, hDIB, FALSE);
  363.         }    
  364.         FW_CATCH_BEGIN
  365.         FW_CATCH_EVERYTHING()
  366.         {
  367.             FW_DIBFree(hDIB);
  368.             FW_THROW_SAME();
  369.         }
  370.         FW_CATCH_END
  371.     }
  372. #endif
  373. }
  374.  
  375. //----------------------------------------------------------------------------------------
  376. // FW_CPrivIconRep::IsEqual
  377. //----------------------------------------------------------------------------------------
  378.  
  379. FW_Boolean FW_CPrivIconRep::IsEqual(const FW_CPrivIconRep* other) const
  380. {
  381.     return fPlatformIcon == other->fPlatformIcon;
  382. }
  383.  
  384. //----------------------------------------------------------------------------------------
  385. // FW_CPrivIconRep::OrphanPlatformIcon
  386. //----------------------------------------------------------------------------------------
  387.  
  388. FW_PlatformIcon FW_CPrivIconRep::OrphanPlatformIcon()
  389. {
  390.     FW_ASSERT(fOwnIcon);
  391.     fOwnIcon = FALSE;
  392.     return fPlatformIcon;
  393. }
  394.  
  395. //----------------------------------------------------------------------------------------
  396. // FW_CPrivIconRep::IsPlatformIconOrphan
  397. //----------------------------------------------------------------------------------------
  398.  
  399. FW_Boolean FW_CPrivIconRep::IsPlatformIconOrphan() const
  400. {
  401.     return !fOwnIcon;
  402. }
  403.  
  404. //----------------------------------------------------------------------------------------
  405. // FW_CPrivIconRep::SetPlatformIcon
  406. //----------------------------------------------------------------------------------------
  407.  
  408. void FW_CPrivIconRep::SetPlatformIcon(FW_PlatformIcon newIcon)
  409. {
  410.     FW_ASSERT(fPlatformIcon != newIcon);
  411.     DisposePlatformIcon();
  412.     fPlatformIcon = newIcon;
  413.     fOwnIcon = FALSE;
  414.     fMaxIconSize = GetPlatformIconSize(fPlatformIcon);
  415. }
  416.  
  417. //----------------------------------------------------------------------------------------
  418. // FW_CPrivIconRep::AdoptPlatformIcon
  419. //----------------------------------------------------------------------------------------
  420.  
  421. void FW_CPrivIconRep::AdoptPlatformIcon(FW_PlatformIcon newIcon)
  422. {
  423.     SetPlatformIcon(newIcon);
  424.     fOwnIcon = TRUE;
  425. }
  426.     
  427. //----------------------------------------------------------------------------------------
  428. // FW_CPrivIconRep::GetIconSize
  429. //----------------------------------------------------------------------------------------
  430.  
  431. void FW_CPrivIconRep::GetIconSize(FW_SPoint& size) const
  432. {
  433.     size.x = size.y = FW_IntToFixed(fMaxIconSize);
  434. }
  435.  
  436. //----------------------------------------------------------------------------------------
  437. // FW_CPrivIconRep::GetIconSize
  438. //----------------------------------------------------------------------------------------
  439.  
  440. void FW_CPrivIconRep::GetIconSize(Environment* ev, FW_SGraphicContext& gc, FW_SPoint& size) const
  441. {
  442.     FW_PrivGC_DeviceToLogicalSize(ev, gc, fMaxIconSize, fMaxIconSize, size);
  443. }
  444.  
  445. //----------------------------------------------------------------------------------------
  446. // FW_CPrivIconRep::DisposePlatformIcon
  447. //----------------------------------------------------------------------------------------
  448.  
  449. void FW_CPrivIconRep::DisposePlatformIcon()
  450. {
  451.     if(fOwnIcon && fPlatformIcon != NULL)
  452.     {
  453. #ifdef FW_BUILD_WIN
  454.         ::DestroyIcon(fPlatformIcon);
  455. #endif
  456. #ifdef FW_BUILD_MAC
  457.         ::DisposeIconSuite(fPlatformIcon, TRUE);
  458. #endif
  459.     }
  460.  
  461.     fPlatformIcon = NULL;
  462.     fOwnIcon = FALSE;
  463. }
  464.  
  465. //----------------------------------------------------------------------------------------
  466. // FW_CPrivIconRep::CopyPlatformIcon
  467. //----------------------------------------------------------------------------------------
  468.  
  469. FW_PlatformIcon    FW_CPrivIconRep::CopyPlatformIcon(FW_PlatformIcon icon)
  470. {
  471. #ifdef FW_BUILD_MAC
  472.     Handle newIconSuite = NULL;
  473.     OSErr err = NewIconSuite(&newIconSuite);
  474.     
  475.     FW_FailOnError(err);
  476.     if(newIconSuite == NULL)
  477.         FW_Failure(FW_xMemoryExhausted);
  478.     
  479.     IconActionUPP actionUPP = NewIconActionProc(CopyIconActionProc);
  480.     ForEachIconDo(
  481.         icon,
  482.         svAllAvailableData,
  483.         actionUPP,
  484.         newIconSuite);
  485.     DisposeRoutineDescriptor(actionUPP);
  486.  
  487.     return newIconSuite;
  488. #endif
  489. #ifdef FW_BUILD_WIN
  490.     HANDLE hImage = ::CopyImage(icon, IMAGE_ICON, 0, 0, LR_COPYRETURNORG);
  491.  
  492.     if(hImage == NULL)
  493.         FW_Failure(FW_xMemoryExhausted);
  494.  
  495.     return (HICON) hImage;        
  496. #endif
  497. }
  498.  
  499. //----------------------------------------------------------------------------------------
  500. // FW_CPrivIconRep::GetPlatformIconSize
  501. //----------------------------------------------------------------------------------------
  502.  
  503. short FW_CPrivIconRep::GetPlatformIconSize(FW_PlatformIcon icon)
  504. {
  505. #ifdef FW_BUILD_MAC
  506.     short maxSize = 0;
  507.  
  508.     IconActionUPP actionUPP = NewIconActionProc(GetIconSizeActionProc);
  509.     ForEachIconDo(
  510.         icon,
  511.         svAllAvailableData,
  512.         actionUPP,
  513.         &maxSize);
  514.     DisposeRoutineDescriptor(actionUPP);
  515.  
  516.     return maxSize;
  517. #endif
  518. #ifdef FW_BUILD_WIN
  519.     ICONINFO iconInfo;
  520.     ::GetIconInfo(icon, &iconInfo);
  521.     FW_ASSERT(iconInfo.fIcon);
  522.     FW_ASSERT(iconInfo.hbmMask != NULL);
  523.     
  524.     BITMAP bmMask;    
  525.     ::GetObject(iconInfo.hbmMask, sizeof(bmMask), &bmMask);
  526.     return (short) bmMask.bmWidth;
  527. #endif
  528. }
  529.  
  530. #ifdef FW_BUILD_MAC
  531.  
  532. //----------------------------------------------------------------------------------------
  533. // FlattenActionProc
  534. //----------------------------------------------------------------------------------------
  535.  
  536. static pascal OSErr FlattenActionProc(ResType type, Handle* iconData, void* dataPtr)
  537. {
  538.     FW_CWritableStream& archive = * (FW_CWritableStream*) dataPtr;
  539.  
  540.     // Write the type
  541.     archive.Write(&type, sizeof(type));
  542.     
  543.     // Get the icon handle and its size
  544.     Handle suiteIcon = *iconData;
  545.     Size suiteIconSize = suiteIcon == NULL ? 0 : ::GetHandleSize(suiteIcon);
  546.  
  547.     archive << suiteIconSize;
  548.  
  549.     // Write the data
  550.     if(suiteIcon != NULL)
  551.     {
  552.         FW_CAcquireLockedSystemHandle lock(suiteIcon);
  553.         archive.Write(lock.GetPointer(), suiteIconSize);
  554.     }
  555.  
  556.     return noErr;
  557. }
  558.  
  559. //----------------------------------------------------------------------------------------
  560. // CopyIconActionProc
  561. //----------------------------------------------------------------------------------------
  562.  
  563. static pascal OSErr CopyIconActionProc(ResType type, Handle* iconData, void* dataPtr)
  564. {
  565.     Handle newIconSuite = (Handle) dataPtr;
  566.  
  567.     Handle suiteIcon = *iconData;
  568.     if(suiteIcon != NULL)
  569.     {
  570.         // Copy icon data
  571.         Handle newIcon = suiteIcon;
  572.         HandToHand(&newIcon);
  573.  
  574.         // Add the new icon to the suite
  575.         AddIconToSuite(newIcon, newIconSuite, type);
  576.     }
  577.     
  578.     return noErr;
  579. }
  580.  
  581. //----------------------------------------------------------------------------------------
  582. // GetIconSizeActionProc
  583. //----------------------------------------------------------------------------------------
  584.  
  585. static pascal OSErr GetIconSizeActionProc(ResType type, Handle* iconData, void* dataPtr)
  586. {
  587.     short* maxSize = (short*) dataPtr;
  588.  
  589.     Handle suiteIcon = *iconData;
  590.     if(suiteIcon != NULL)
  591.     {
  592.         short size = 0;
  593.         switch((type & ~0xFFl) | ' ')
  594.         {
  595.         case 'ICN ':
  596.         case 'icl ':
  597.             size = 32;
  598.             break;
  599.  
  600.         case 'ics ':
  601.             size = 16;
  602.             break;
  603.  
  604.         case 'icm ':
  605.             size = 12;
  606.             break;
  607.         }
  608.  
  609.         if(size > *maxSize)
  610.             *maxSize = size;
  611.     }
  612.  
  613.     return noErr;
  614. }
  615.  
  616. #endif
  617.