supermario/base/SuperMarioProj.1994-02-09/Toolbox/ComponentMgr/ThingFiles.c
2019-06-29 23:17:50 +08:00

322 lines
7.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
File: ThingFiles.c
Copyright: © 1991-1993 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<SM4> 8/5/93 JDR integrate Component Mgr from Reality
<8> 6/13/93 JDR Rolled in the ComponentMgr sources from QuickTime 1.6.
<7> 5/29/92 DCL Included TextUtils.h. RelString moved there for the New Inside
Mac.
<6> 12/12/91 DTY #1018054: If _HomeResFile returns 0 in _FSSpecFromResource, use
the file reference number in SysMap instead.
<5> 12/6/91 YK Removed System6 conditionals. Object compare identical to <4>.
<4> 12/5/91 YK Rolled in QuickTime GM:
<3> 11/6/91 YK Corrected comments. I misunderstood revision number.
<2> 11/6/91 YK Replaced code with System 7 trap. Added code for 'thng' in
System file. Removed unnecessary include statement.
<3> 5/18/91 dvb Thing->Component
<2> 5/2/91 BAL Updated to latest think headers
<1> 3/28/91 BAL first checked in
To Do:
*/
#include <Files.h>
#include <Resources.h>
#include <Memory.h>
#include <SysEqu.h>
#include <TextUtils.h>
#include <Errors.h>
#include <Icons.h>
#include "PrivateThingManager.h"
OSErr GrowRTFileTable(short growCount);
OSErr _FSSpecFromResource( Handle h, FSSpec *fileSpec )
{
OSErr error = 0;
FCBPBRec anFCB;
Str255 fName;
short fref;
fref = HomeResFile( h );
if (fref < 0) return ResError();
if (fref == 0) // <6> Convert a reference number
fref = *(short *)SysMap; // <6> of 0 to the system files refNum.
anFCB.ioCompletion = 0;
anFCB.ioVRefNum = 0;
anFCB.ioRefNum = fref;
anFCB.ioFCBIndx = 0;
fName[0] = 0;
anFCB.ioNamePtr = (StringPtr)fName;
if (error = PBGetFCBInfoSync( &anFCB )) goto bail;
error = FSMakeFSSpec( anFCB.ioFCBVRefNum, anFCB.ioFCBParID, anFCB.ioNamePtr, fileSpec);
bail:
return (error);
}
Boolean FSSpecEqual( register FSSpec *fileSpecA, register FSSpec *fileSpecB )
{
return ((fileSpecA->vRefNum == fileSpecB->vRefNum)
&& (fileSpecA->parID == fileSpecB->parID)
&& !RelString(fileSpecA->name,fileSpecB->name,false,true));
}
short AddComponentFSSpec( FSSpec *fspec )
{
register rtFile *rtFileList = ComponentManagerGlobals->rtFileTable;
register short i, empty = -1;
register short count = ComponentManagerGlobals->rtFileTotalCount;
HParamBlockRec pb;
OSErr err = -1;
// get the file's id
pb.fidParam.ioNamePtr = fspec->name;
pb.fidParam.ioVRefNum = fspec->vRefNum;
pb.fidParam.ioSrcDirID = fspec->parID;
err = PBCreateFileIDRefSync(&pb);
if (err == fidExists) err = noErr;
/* first check to see if it's already there */
for (i=0; i<count; i++) {
if (rtFileList->referenceCount) /* is this spot in use? */
{
if (rtFileList->vRefNum == 0)
{
// this entry contains an FSSpec handle, not a file id
if ( FSSpecEqual(*(FSSpec **)rtFileList->fileID, fspec) )
{
foundIndex:
rtFileList->referenceCount++;
return i;
}
}
else
{
// this entry contains a file id
if ((fspec->vRefNum == rtFileList->vRefNum) &&
(pb.fidParam.ioFileID == rtFileList->fileID))
goto foundIndex;
}
}
else
empty = i;
rtFileList++;
}
/* didn't find it so add it to an empty spot */
if (empty < 0) {
// need to grow the table. no empty spot was available.
if (GrowRTFileTable( kComponentFileAllocationSize ))
return empty; /* error: could not allocate a file entry */
empty = ComponentManagerGlobals->rtFileTotalCount - 1; // last entry should always be free
}
rtFileList = ComponentManagerGlobals->rtFileTable + empty;
if (err) {
// need to make a copy of the FSSpec and save it away
rtFileList->fileID = (Handle)NewHandleSys(0);
if (rtFileList->fileID) {
PtrAndHand((Ptr)fspec, (Handle)rtFileList->fileID, sizeof(FSSpec));
if (MemError() == noErr) {
rtFileList->vRefNum = 0;
goto rememberFile;
}
}
empty = -1;
}
else {
// just save away the file id
rtFileList->vRefNum = fspec->vRefNum;
rtFileList->fileID = pb.fidParam.ioFileID;
rememberFile:
rtFileList->referenceCount = 1;
ComponentManagerGlobals->rtFileUsedCount++;
}
return empty;
}
OSErr GrowRTFileTable( short growCount )
/*
* Grow the table of registered thing files.
*/
{
register rtFile *aTable;
rtFile *oldTable, *newTable;
long oldTableSize;
oldTableSize = ComponentManagerGlobals->rtFileTotalCount * sizeof(rtFile);
oldTable = ComponentManagerGlobals->rtFileTable;
newTable = aTable = (rtFile *)NewPtrSysClear( oldTableSize + (long)growCount * sizeof(rtFile));
if (!aTable)
return MemError();
BlockMove((Ptr)oldTable, (Ptr)aTable, oldTableSize);
ComponentManagerGlobals->rtFileTable = newTable; /* begin using new table */
ComponentManagerGlobals->rtFileTotalCount += growCount;
if (oldTable)
DisposPtr((Ptr)oldTable); /* dump the old one */
return 0;
}
rtFileNum AddComponentResFile( Handle h )
{
FSSpec fspec;
if (_FSSpecFromResource( h, &fspec ))
return -1;
return AddComponentFSSpec(&fspec);
}
OSErr RemoveComponentResFile( rtFileNum fn )
{
register rtFile *rtFileList;
/* first check to see if it's a valid file number */
if ((fn < 0) || (fn >= ComponentManagerGlobals->rtFileTotalCount))
return -1;
rtFileList = ComponentManagerGlobals->rtFileTable + fn;
if (!--rtFileList->referenceCount)
{
// since the reference count went to zero, this spot is free
if (rtFileList->vRefNum == 0)
{
// the file id was really a handle to an FSSpec, so toss it
DisposHandle((Handle)rtFileList->fileID);
}
ComponentManagerGlobals->rtFileUsedCount--;
}
return 0;
}
typedef struct getIconRecord {
Component c;
short resID;
} getIconRecord;
static pascal OSErr GetIconFromResource(ResType theType, Handle *theIcon, getIconRecord *refCon)
{
OSErr err;
Handle h;
if (!refCon->resID)
h = nil; // no icon suite, but fake it for the 1-bit icon case
else {
h = Get1Resource(theType, refCon->resID);
err = ResError();
}
if (!h || (err == -192)) {
if (theType == 'ICN#') {
// just get the old style component icon instead
Handle h = NewHandle(128);
GetComponentInfo(refCon->c, nil, nil, nil, h);
if (!h || !*h)
DisposHandle(h);
else
*theIcon = h;
}
return noErr;
}
if (err) return err;
LoadResource(h);
if (err = ResError()) return err;
DetachResource(h);
if (err = ResError()) return err;
*theIcon = h;
HNoPurge(*theIcon);
return noErr;
}
pascal OSErr __GetComponentIconSuite(Component aComponent, Handle *iconSuite)
{
register RegisteredComponent *rt;
OSErr err;
short resref = -1;
short saveRes;
short suiteID = 0;
getIconRecord refCon;
*iconSuite = nil;
if( ! (rt = ValidComponent(aComponent)) )
return invalidComponentID; /* error : not a valid component ID */
if (rt->rtFlags & rtfHasIconSuite) {
Handle h;
ComponentResourceExtension *cre;
// open the thing's resource file
saveRes = CurResFile();
resref = OpenComponentResFile(aComponent);
if (resref == -1)
return resNotFound;
// get the thing resource which points to the suite
h = Get1Resource(rt->rtResourceType, rt->rtResourceID);
if (err = ResError()) goto bail;
LoadResource(h);
if (err = ResError()) goto bail;
cre = (ComponentResourceExtension *)((long)*h + sizeof(ComponentResource));
suiteID = cre->componentIconFamily;
ReleaseResource(h); // we're done with this
}
// use the Icon Suite Manager stuff to load up the icon suite (can't use GetIconSuite
// because it won't detach the resources for us)
err = NewIconSuite(iconSuite);
if (err) goto bail;
refCon.resID = suiteID;
refCon.c = aComponent;
err = ForEachIconDo(*iconSuite, -1, (IconAction)GetIconFromResource, &refCon);
bail:
if (resref != -1) {
CloseComponentResFile(resref);
UseResFile(saveRes);
}
if (err && *iconSuite) {
DisposeIconSuite(*iconSuite, true);
*iconSuite = nil;
}
return err;
}