home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-02 | 7.6 KB | 333 lines | [TEXT/KAHL] |
- /*
- File: Loader.c
-
- Contains: Loader component routines.
-
- Refer to develop Issue 15, "Managing Component Registration",
- for details on this code.
-
- Written by: Gary Woodcock
-
- Copyright: © 1993 by Apple Computer, Inc.
-
- Change History (most recent first):
-
- */
-
- //-----------------------------------------------------------------------
- // Includes
-
- #include "LoaderPrivate.h"
-
- #include <Errors.h>
- #include <Memory.h>
- #include <Packages.h>
- #include <Resources.h>
- #include <SysEqu.h>
- #include <Events.h>
-
- //-----------------------------------------------------------------------
- // Private prototypes
-
- static OSErr
- LoadComponents (ResType loadListResType, short loadListResID);
-
- //-----------------------------------------------------------------------
-
- #ifdef BUILD_LINKED
-
- // Use this declaration when we're running linked (for debugging)
- pascal ComponentResult
- LoaderDispatcher (ComponentParameters *params, Handle storage)
-
- #else
-
- // Use this declaration when we're a standalone component
- pascal ComponentResult
- main (ComponentParameters *params, Handle storage)
-
- #endif BUILD_LINKED
-
- {
- // This routine is the main dispatcher for the component
-
- ComponentResult result = noErr;
- ComponentFunction loaderFunction = nil;
-
- // Did we get a Component Manager request code (< 0)?
- if (params->what < 0)
- {
- switch (params->what)
- {
- case kComponentOpenSelect: // Open request
- {
- loaderFunction = _LoaderOpen;
- break;
- }
- case kComponentCloseSelect: // Close request
- {
- loaderFunction = _LoaderClose;
- break;
- }
- case kComponentCanDoSelect: // Can Do request
- {
- result = CallComponentFunction (params,
- (ComponentFunction) _LoaderCanDo);
- break;
- }
- case kComponentVersionSelect: // Version request
- {
- result = CallComponentFunction (params,
- (ComponentFunction) _LoaderVersion);
- break;
- }
- case kComponentRegisterSelect: // Register request
- {
- loaderFunction = _LoaderRegister;
- break;
- }
- case kComponentTargetSelect: // Target request not supported
- case kComponentUnregisterSelect: // Unregister request
- default: // Unknown request
- {
- result = badComponentSelector;
- break;
- }
- }
- }
- else // Unknown request
- {
- result = badComponentSelector;
- }
- if (loaderFunction != nil)
- {
- result = CallComponentFunctionWithStorage (storage, params, loaderFunction);
- }
- return (result);
- }
-
- //-----------------------------------------------------------------------
-
- pascal ComponentResult
- _LoaderOpen (Handle storage, ComponentInstance self)
- {
- #pragma unused (storage)
-
- ComponentResult result = noErr;
-
- #ifdef THINK_C
-
- SetComponentInstanceA5 (self, *(long *) CurrentA5);
-
- #endif THINK_C
-
- // Can we open another instance?
- if (CountComponentInstances ((Component) self) <= kMaxLoaderInstances)
- {
- // Get our instance storage
- LoaderPrivateGlobalsHdl globals = (LoaderPrivateGlobalsHdl) NewHandleClear (sizeof (LoaderPrivateGlobals));
-
- // Did we get our storage?
- if (globals != nil)
- {
- // Keep a reference to self
- (**globals).self = (Component) self;
-
- // Set storage ref
- SetComponentInstanceStorage (self, (Handle) globals);
- }
- else // NewHandleClear failed
- {
- result = MemError();
- }
- }
- else // No more instances can be opened
- {
- result = -1L; // Return anonymous error
- }
- return (result);
- }
-
- //-----------------------------------------------------------------------
-
- pascal ComponentResult
- _LoaderClose (Handle storage, ComponentInstance self)
- {
- LoaderPrivateGlobalsHdl globals = (LoaderPrivateGlobalsHdl) storage;
- ComponentResult result = noErr;
-
- // Do we have any clean up to do?
- if (globals != nil)
- {
- // Dispose globals
- DisposHandle ((Handle) globals);
- }
- return (result);
- }
-
- //-----------------------------------------------------------------------
-
- pascal ComponentResult
- _LoaderCanDo (short selector)
- {
- // Case on the request code
- switch (selector)
- {
- // Component Manager request codes
- case kComponentOpenSelect:
- case kComponentCloseSelect:
- case kComponentCanDoSelect:
- case kComponentVersionSelect:
- case kComponentRegisterSelect:
- {
- return (true);
- }
-
- // Unsupported or unknown request codes
- case kComponentTargetSelect: // Target request not supported
- case kComponentUnregisterSelect: // Unregister request not supported
- default: // Not a request code we recognize
- {
- return (false);
- }
- }
- }
-
- //-----------------------------------------------------------------------
-
- pascal ComponentResult
- _LoaderVersion (void)
- {
- // Return the version info
- return (loaderInterfaceRev);
- }
-
- //-----------------------------------------------------------------------
-
- pascal ComponentResult
- _LoaderRegister (Handle storage)
- {
- KeyMap keys;
- LoaderPrivateGlobalsHdl globals = (LoaderPrivateGlobalsHdl) storage;
- OSErr result = noErr;
-
- #ifndef BUILD_LINKED
-
- short savedResRefNum = CurResFile();
- short compResRefNum = OpenComponentResFile ((**globals).self);
-
- // Use the component's res file (not the THINK project res file) if we're
- // running standalone
- UseResFile (compResRefNum);
-
- #endif BUILD_LINKED
-
- // If mouse or shift key down, don't bother
- GetKeys (keys);
- if (!Button() && !(1 & keys[1]))
- {
- // Load the components!
- result = LoadComponents (kComponentLoadListResType, kLoaderBaseResID);
- }
-
- #ifndef BUILD_LINKED
-
- // Restore the res file (if running standalone)
- CloseComponentResFile (compResRefNum);
- UseResFile (savedResRefNum);
-
- #endif BUILD_LINKED
-
- return ((result == noErr) ? 0L : 1L);
- }
-
- //-----------------------------------------------------------------------
-
- static OSErr
- LoadComponents (ResType loadListResType, short loadListResID)
- {
- OSErr result = noErr;
- ComponentLoadListHdl componentLoadList = (ComponentLoadListHdl) Get1Resource (loadListResType, loadListResID);
-
- // Did we get the component load list?
- if (componentLoadList != nil)
- {
- ComponentLoadSpec componentLoadSpec;
- ComponentResourceHandle componentResHdl;
- Component componentID;
- short numComponentsToLoad = (**componentLoadList).count;
- short i;
-
- for (i = 0; i < numComponentsToLoad; i++)
- {
- // Get the component load spec
- componentLoadSpec = (**componentLoadList).spec[i];
-
- // Get the component resource pointed to by this spec
- componentResHdl = (ComponentResourceHandle) Get1Resource
- (componentLoadSpec.componentResType, componentLoadSpec.componentResID);
-
- // Did we get it?
- if (componentResHdl != nil)
- {
- // Register it
- componentID = RegisterComponentResource (componentResHdl, kRegisterGlobally);
- if (componentID == 0L) // RegisterComponentResource failed
- {
- result = -1L; // Return anonymous error
- }
- }
- else // Get1Resource failed
- {
- result = ResError();
- }
- }
- }
- else // Couldn't get component loader resource
- {
- result = ResError();
- }
- return (result);
- }
-
- //-----------------------------------------------------------------------
-
- #ifdef THINK_C
- #ifdef BUILD_LINKED
-
- Component
- RegisterLoader (void)
- {
- ComponentDescription theDesc;
- Handle name;
- Component theComp;
-
- // Set up component description
- theDesc.componentType = 'tldr';
- theDesc.componentSubType = kAnyComponentSubType;
- theDesc.componentManufacturer = 'appl';
- theDesc.componentFlags = cmpWantsRegisterMessage;
- theDesc.componentFlagsMask = kAnyComponentFlagsMask;
-
- // Name the component
- PtrToHand ("\pLoader (linked)", &name, 15);
-
- // Register with the component main entry point
- theComp = RegisterComponent (&theDesc, (void *)LoaderDispatcher, 0, name, 0, 0);
-
- // Clean up
- if (name != nil)
- {
- DisposHandle (name);
- }
- return (theComp);
- }
-
- #endif BUILD_LINKED
- #endif THINK_C
-
- //-----------------------------------------------------------------------
-
-
-
-