home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 15.0 KB | 617 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: PRIcon.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWOS.hpp"
-
- #ifndef FWEXCEPT_H
- #include "FWExcept.h"
- #endif
-
- #ifndef PRICON_H
- #include "PRIcon.h"
- #endif
-
- // ----- OS Includes -----
-
- #ifndef FWRESFIL_H
- #include "FWResFil.h"
- #endif
-
- #ifndef FWRESFIL_H
- #include "FWResFil.h"
- #endif
-
- #ifndef FWRECT_H
- #include "FWRect.h"
- #endif
-
- #ifndef FWPOINT_H
- #include "FWPoint.h"
- #endif
-
- #ifndef FWGC_H
- #include "FWGC.h"
- #endif
-
- #ifndef FWWINDIB_H
- #include "FWWinDIB.h"
- #endif
-
- // ----- Foundation Includes -----
-
- #ifndef FWSTREAM_H
- #include "FWStream.h"
- #endif
-
- #ifndef FWMEMMGR_H
- #include "FWMemMgr.h"
- #endif
-
- #ifndef FWMEMHLP_H
- #include "FWMemHlp.h"
- #endif
-
- // ----- Platform Includes -----
-
- #if defined(FW_BUILD_MAC) && !defined(__ICONS__)
- #include <Icons.h>
- #endif
-
- //========================================================================================
- // RunTime Info
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment FWGraphics_Icon
- #endif
-
- FW_DEFINE_AUTO(FW_CPrivIconRep)
-
- #ifdef FW_BUILD_MAC
-
- //----------------------------------------------------------------------------------------
- // Action procs for icon enumeration
- //----------------------------------------------------------------------------------------
-
- static pascal OSErr FlattenActionProc(ResType type, Handle* iconData, void* dataPtr);
- static pascal OSErr CopyIconActionProc(ResType type, Handle* iconData, void* dataPtr);
- static pascal OSErr GetIconSizeActionProc(ResType type, Handle* iconData, void* dataPtr);
-
- #endif
-
- //========================================================================================
- // class FW_CPrivIconRep
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::FW_CPrivIconRep
- //----------------------------------------------------------------------------------------
- // From platform icon: will not own the icon
-
- FW_CPrivIconRep::FW_CPrivIconRep(FW_PlatformIcon platformIcon) :
- fOwnIcon(FALSE),
- fPlatformIcon(platformIcon),
- fMaxIconSize(GetPlatformIconSize(platformIcon))
- {
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::FW_CPrivIconRep
- //----------------------------------------------------------------------------------------
- // From another icon: will own the icon (a copy is made)
-
- FW_CPrivIconRep::FW_CPrivIconRep(const FW_CPrivIconRep& icon) :
- fOwnIcon(TRUE),
- fPlatformIcon(NULL)
- {
- fPlatformIcon = CopyPlatformIcon(icon.fPlatformIcon);
- fMaxIconSize = GetPlatformIconSize(fPlatformIcon);
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::FW_CPrivIconRep
- //----------------------------------------------------------------------------------------
- // From resources: will own the icon
-
- FW_CPrivIconRep::FW_CPrivIconRep(FW_OResourceFile* resourceFile,
- FW_ResourceID resID,
- short size) :
- fOwnIcon(TRUE),
- fPlatformIcon(NULL)
- {
- #ifdef FW_BUILD_MAC
- FW_ASSERT(size == 32 || size == 16 || size == 12);
- long selector;
- FW_ResourceType resTypes[4];
-
- switch(size)
- {
- case 32:
- selector = svAllLargeData;
- resTypes[0] = 'ICN#';
- resTypes[1] = 'icl4';
- resTypes[2] = 'icl8';
- break;
-
- case 16:
- selector = svAllSmallData;
- resTypes[0] = 'ics#';
- resTypes[1] = 'ics4';
- resTypes[2] = 'ics8';
- break;
-
- case 12:
- selector = svAllMiniData;
- resTypes[0] = 'icm#';
- resTypes[1] = 'icm4';
- resTypes[2] = 'icm8';
- break;
-
- default:
- FW_ASSERT(FALSE); // Not a valid icon size
- }
-
- // Check to see if the icon is there
- FW_Boolean resourceFound = FALSE;
- FW_SOMEnvironment ev;
- for (short i = 0; i < 3; ++i)
- {
- if (resourceFile->HasResource(ev, resID, resTypes[i]))
- {
- resourceFound = TRUE;
- break;
- }
- }
-
- // Load the icon suite
- FW_PlatformIcon newIconSuite = NULL;
- OSErr err = noErr;
- if(resourceFound)
- err = ::GetIconSuite(&newIconSuite, resID, selector);
-
- FW_FailOnError(err);
- if(!resourceFound || newIconSuite == NULL)
- FW_Failure(FW_xResourceNotFound);
-
- // We need to copy the icon suite in case the resource file is a code fragment
- fPlatformIcon = CopyPlatformIcon(newIconSuite);
- ::DisposeIconSuite(newIconSuite, TRUE);
- fMaxIconSize = size;
- #endif
- #ifdef FW_BUILD_WIN
- FW_SOMEnvironment ev;
- HINSTANCE hInstance = resourceFile->PrivGetResourceFileID(ev);
- HANDLE hImage = ::LoadImage(hInstance, MAKEINTRESOURCE(resID), IMAGE_ICON, size, size, 0);
-
- if(hImage == NULL)
- FW_Failure(FW_xResourceNotFound);
-
- fPlatformIcon = (HICON) hImage;
- fMaxIconSize = size;
- #endif
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::FW_CPrivIconRep
- //----------------------------------------------------------------------------------------
- // From stream: will own the icon
-
- FW_CPrivIconRep::FW_CPrivIconRep(FW_CReadableStream& archive) :
- fOwnIcon(TRUE),
- fPlatformIcon(NULL)
- {
- #ifdef FW_BUILD_MAC
- ::NewIconSuite(&fPlatformIcon);
-
- ResType resType;
- archive.Read(&resType, sizeof(resType));
- while(resType != 0)
- {
- // Read icon data size
- Size iconSize;
- archive >> iconSize;
-
- // Read icon data
- if(iconSize != NULL)
- {
- FW_CAcquireTemporarySystemHandle handle(iconSize);
- archive.Read(handle.GetPointer(), iconSize);
-
- Handle iconHandle = handle.Orphan();
-
- ::AddIconToSuite(iconHandle, fPlatformIcon, resType);
- }
-
- archive.Read(&resType, sizeof(resType));
- }
- #endif
- #ifdef FW_BUILD_WIN
- // Read the header
- ICONINFO iconInfo;
- archive.Read(&iconInfo, sizeof(iconInfo));
- FW_ASSERT(iconInfo.fIcon);
-
- FW_WinDIB hDIB;
-
- // Read and convert the mask bitmap
- if(iconInfo.hbmMask != NULL)
- {
- hDIB = FW_DIBLoadFromStream(archive, FALSE);
-
- FW_TRY
- {
- iconInfo.hbmMask = FW_DIBConvertToBitmap(hDIB, NULL);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- FW_DIBFree(hDIB);
- FW_THROW_SAME();
- }
- FW_CATCH_END
- }
-
- // Read and convert the color bitmap
- if(iconInfo.hbmColor != NULL)
- {
- hDIB = FW_DIBLoadFromStream(archive, FALSE);
-
- FW_TRY
- {
- iconInfo.hbmColor = FW_DIBConvertToBitmap(hDIB, NULL);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- FW_DIBFree(hDIB);
- ::DeleteObject(iconInfo.hbmMask);
- FW_THROW_SAME();
- }
- FW_CATCH_END
- }
-
- // Try and create the icon
- fPlatformIcon = ::CreateIconIndirect(&iconInfo);
-
- if(fPlatformIcon == NULL)
- {
- ::DeleteObject(iconInfo.hbmMask);
- ::DeleteObject(iconInfo.hbmColor);
-
- FW_Failure(FW_xMemoryExhausted);
- }
- #endif
-
- fMaxIconSize = GetPlatformIconSize(fPlatformIcon);
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::~FW_CPrivIconRep
- //----------------------------------------------------------------------------------------
-
- FW_CPrivIconRep::~FW_CPrivIconRep()
- {
- FW_START_DESTRUCTOR
- DisposePlatformIcon();
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::Write
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivIconRep::Write(FW_CWritableStream& archive) const
- {
- #ifdef FW_BUILD_MAC
- IconActionUPP actionUPP = NewIconActionProc(FlattenActionProc);
- ForEachIconDo(
- fPlatformIcon,
- svAllAvailableData,
- actionUPP,
- (void*) &archive);
- DisposeRoutineDescriptor(actionUPP);
-
- // Append a NULL ResType
- ResType nullType = 0;
- archive.Write(&nullType, sizeof(nullType));
- #endif
- #ifdef FW_BUILD_WIN
- ICONINFO iconInfo;
- ::GetIconInfo(fPlatformIcon, &iconInfo);
- FW_ASSERT(iconInfo.fIcon);
-
- FW_WinDIB hDIB;
-
- // Write the header
- archive.Write(&iconInfo, sizeof(iconInfo));
-
- // Write the mask bitmap
- if(iconInfo.hbmMask != NULL)
- {
- hDIB = FW_DIBConvertFromBitmap(iconInfo.hbmMask, 0, NULL);
- FW_TRY
- {
- FW_DIBSaveToStream(archive, hDIB, FALSE);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- FW_DIBFree(hDIB);
- FW_THROW_SAME();
- }
- FW_CATCH_END
- }
-
- // Write the color bitmap
- if(iconInfo.hbmColor != NULL)
- {
- hDIB = FW_DIBConvertFromBitmap(iconInfo.hbmColor, 0, NULL);
- FW_TRY
- {
- FW_DIBSaveToStream(archive, hDIB, FALSE);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- FW_DIBFree(hDIB);
- FW_THROW_SAME();
- }
- FW_CATCH_END
- }
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::IsEqual
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CPrivIconRep::IsEqual(const FW_CPrivIconRep* other) const
- {
- return fPlatformIcon == other->fPlatformIcon;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::OrphanPlatformIcon
- //----------------------------------------------------------------------------------------
-
- FW_PlatformIcon FW_CPrivIconRep::OrphanPlatformIcon()
- {
- FW_ASSERT(fOwnIcon);
- fOwnIcon = FALSE;
- return fPlatformIcon;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::IsPlatformIconOrphan
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CPrivIconRep::IsPlatformIconOrphan() const
- {
- return !fOwnIcon;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::SetPlatformIcon
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivIconRep::SetPlatformIcon(FW_PlatformIcon newIcon)
- {
- FW_ASSERT(fPlatformIcon != newIcon);
- DisposePlatformIcon();
- fPlatformIcon = newIcon;
- fOwnIcon = FALSE;
- fMaxIconSize = GetPlatformIconSize(fPlatformIcon);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::AdoptPlatformIcon
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivIconRep::AdoptPlatformIcon(FW_PlatformIcon newIcon)
- {
- SetPlatformIcon(newIcon);
- fOwnIcon = TRUE;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::GetIconSize
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivIconRep::GetIconSize(FW_SPoint& size) const
- {
- size.x = size.y = FW_IntToFixed(fMaxIconSize);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::GetIconSize
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivIconRep::GetIconSize(Environment* ev, FW_SGraphicContext& gc, FW_SPoint& size) const
- {
- FW_PrivGC_DeviceToLogicalSize(ev, gc, fMaxIconSize, fMaxIconSize, size);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::DisposePlatformIcon
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivIconRep::DisposePlatformIcon()
- {
- if(fOwnIcon && fPlatformIcon != NULL)
- {
- #ifdef FW_BUILD_WIN
- ::DestroyIcon(fPlatformIcon);
- #endif
- #ifdef FW_BUILD_MAC
- ::DisposeIconSuite(fPlatformIcon, TRUE);
- #endif
- }
-
- fPlatformIcon = NULL;
- fOwnIcon = FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::CopyPlatformIcon
- //----------------------------------------------------------------------------------------
-
- FW_PlatformIcon FW_CPrivIconRep::CopyPlatformIcon(FW_PlatformIcon icon)
- {
- #ifdef FW_BUILD_MAC
- Handle newIconSuite = NULL;
- OSErr err = NewIconSuite(&newIconSuite);
-
- FW_FailOnError(err);
- if(newIconSuite == NULL)
- FW_Failure(FW_xMemoryExhausted);
-
- IconActionUPP actionUPP = NewIconActionProc(CopyIconActionProc);
- ForEachIconDo(
- icon,
- svAllAvailableData,
- actionUPP,
- newIconSuite);
- DisposeRoutineDescriptor(actionUPP);
-
- return newIconSuite;
- #endif
- #ifdef FW_BUILD_WIN
- HANDLE hImage = ::CopyImage(icon, IMAGE_ICON, 0, 0, LR_COPYRETURNORG);
-
- if(hImage == NULL)
- FW_Failure(FW_xMemoryExhausted);
-
- return (HICON) hImage;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivIconRep::GetPlatformIconSize
- //----------------------------------------------------------------------------------------
-
- short FW_CPrivIconRep::GetPlatformIconSize(FW_PlatformIcon icon)
- {
- #ifdef FW_BUILD_MAC
- short maxSize = 0;
-
- IconActionUPP actionUPP = NewIconActionProc(GetIconSizeActionProc);
- ForEachIconDo(
- icon,
- svAllAvailableData,
- actionUPP,
- &maxSize);
- DisposeRoutineDescriptor(actionUPP);
-
- return maxSize;
- #endif
- #ifdef FW_BUILD_WIN
- ICONINFO iconInfo;
- ::GetIconInfo(icon, &iconInfo);
- FW_ASSERT(iconInfo.fIcon);
- FW_ASSERT(iconInfo.hbmMask != NULL);
-
- BITMAP bmMask;
- ::GetObject(iconInfo.hbmMask, sizeof(bmMask), &bmMask);
- return (short) bmMask.bmWidth;
- #endif
- }
-
- #ifdef FW_BUILD_MAC
-
- //----------------------------------------------------------------------------------------
- // FlattenActionProc
- //----------------------------------------------------------------------------------------
-
- static pascal OSErr FlattenActionProc(ResType type, Handle* iconData, void* dataPtr)
- {
- FW_CWritableStream& archive = * (FW_CWritableStream*) dataPtr;
-
- // Write the type
- archive.Write(&type, sizeof(type));
-
- // Get the icon handle and its size
- Handle suiteIcon = *iconData;
- Size suiteIconSize = suiteIcon == NULL ? 0 : ::GetHandleSize(suiteIcon);
-
- archive << suiteIconSize;
-
- // Write the data
- if(suiteIcon != NULL)
- {
- FW_CAcquireLockedSystemHandle lock(suiteIcon);
- archive.Write(lock.GetPointer(), suiteIconSize);
- }
-
- return noErr;
- }
-
- //----------------------------------------------------------------------------------------
- // CopyIconActionProc
- //----------------------------------------------------------------------------------------
-
- static pascal OSErr CopyIconActionProc(ResType type, Handle* iconData, void* dataPtr)
- {
- Handle newIconSuite = (Handle) dataPtr;
-
- Handle suiteIcon = *iconData;
- if(suiteIcon != NULL)
- {
- // Copy icon data
- Handle newIcon = suiteIcon;
- HandToHand(&newIcon);
-
- // Add the new icon to the suite
- AddIconToSuite(newIcon, newIconSuite, type);
- }
-
- return noErr;
- }
-
- //----------------------------------------------------------------------------------------
- // GetIconSizeActionProc
- //----------------------------------------------------------------------------------------
-
- static pascal OSErr GetIconSizeActionProc(ResType type, Handle* iconData, void* dataPtr)
- {
- short* maxSize = (short*) dataPtr;
-
- Handle suiteIcon = *iconData;
- if(suiteIcon != NULL)
- {
- short size = 0;
- switch((type & ~0xFFl) | ' ')
- {
- case 'ICN ':
- case 'icl ':
- size = 32;
- break;
-
- case 'ics ':
- size = 16;
- break;
-
- case 'icm ':
- size = 12;
- break;
- }
-
- if(size > *maxSize)
- *maxSize = size;
- }
-
- return noErr;
- }
-
- #endif
-