/* File: ThingFiles.c Copyright: © 1991-1993 by Apple Computer, Inc., all rights reserved. Change History (most recent first): 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 #include #include #include #include #include #include #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; ireferenceCount) /* 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; }