mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-27 22:51:28 +00:00
322 lines
7.7 KiB
C
322 lines
7.7 KiB
C
/*
|
||
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;
|
||
}
|
||
|