Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Source/StubMod.c
/* |
StubMod.c |
This file creates the 68k 'ADgm' resource to call your PPC module. |
Its designed to be compiled as a code resource and then included in your PPC shared libary project. |
Created by Steve Zellers |
6/2/95 aea (Andrew Armstrong) Modifed for CodeWarrior & proper CPU checking. |
05/30/96 smz rewrote for "fat" CFM modules |
*/ |
#define GENERATING68K 1 |
#include <ConditionalMacros.h> |
#include <CodeFragments.h> |
#include <MixedMode.h> |
#include <Types.h> |
#include <OSUtils.h> |
#include <Resources.h> |
#include <Memory.h> |
#include <A4Stuff.h> |
#include <Quickdraw.h> |
#include <LowMem.h> |
#include <GestaltEqu.h> |
#include "GraphicsModule_Types.h" |
#define kFragmentName "\pmain" |
#define kEntryPointName "\pmain" |
typedef pascal OSErr (*ModuleProcPtr)(Handle* storage, RgnHandle rgn, short msg, GMParamBlockPtr params); |
enum { |
eModuleDispatchSelector = kPascalStackBased |
| RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) |
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( Handle*))) |
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( RgnHandle))) |
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short))) |
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( GMParamBlock*))) |
}; |
static ConnectionID theConnectionID; |
static Ptr theEntryPoint; |
static ModuleProcPtr theDescriptor = nil; |
static OSErr LocateFile(short refNum, FSSpec* location, long* fileLen) |
{ |
FCBPBRec fcbPB; |
OSErr result; |
fcbPB.ioNamePtr = (StringPtr)location->name; |
fcbPB.ioCompletion = nil; |
fcbPB.ioFCBIndx = 0; |
fcbPB.ioRefNum = refNum; |
result = PBGetFCBInfo(&fcbPB, false); |
if (result == noErr) { |
location->vRefNum = fcbPB.ioFCBVRefNum; |
location->parID = fcbPB.ioFCBParID; |
*fileLen = fcbPB.ioFCBPLen; |
} |
return result; |
} |
static Boolean onPowerPC() |
{ |
long result; |
return Gestalt(gestaltNativeCPUtype, &result) == noErr && result >= gestaltCPU601; |
} |
static RoutineDescriptor theRTD = BUILD_ROUTINE_DESCRIPTOR(eModuleDispatchSelector, nil); |
pascal OSErr main(Handle* storage, RgnHandle rgn, short msg, GMParamBlockPtr params) |
{ |
OSErr err = noErr; |
long cfmPresent; |
long oldA4; |
oldA4 = SetCurrentA4(); |
err = Gestalt(gestaltCFMAttr, &cfmPresent); |
if (err != noErr) { |
Handle errorHandle; |
errorHandle = Get1Resource('STR ', 150); |
if (!errorHandle) |
BlockMove("\pSorry, this module requires the Code Fragment Manager.", params->errorMessage, 255); |
else { |
HLock(errorHandle); |
BlockMove(*errorHandle, params->errorMessage, 255); |
ReleaseResource(errorHandle); |
} |
ExitCodeResource(); |
return -1; |
} |
// open the fragment |
if (msg == Initialize || msg >= ButtonMessage) { |
Ptr exportedEntryPoint; |
SymClass theClass; |
FSSpec thisSpec; |
long thisLen; |
LocateFile(LMGetCurMap(), &thisSpec, &thisLen); |
err = GetDiskFragment(&thisSpec, 0, kWholeFork, kFragmentName, kLoadNewCopy, &theConnectionID, (Ptr*) &exportedEntryPoint, params->errorMessage); |
if (err == noErr) |
err = FindSymbol(theConnectionID, kEntryPointName, &theEntryPoint, &theClass); |
if (err == noErr) { |
theRTD.routineRecords[0].procDescriptor = (ProcPtr) theEntryPoint; |
if (onPowerPC()) { |
theRTD.routineRecords[0].ISA = kPowerPCISA | kPowerPCRTA; |
} else { |
theRTD.routineRecords[0].ISA = kM68kISA | kCFM68kRTA; |
} |
theDescriptor = (ModuleProcPtr) &theRTD; |
} |
} |
if (theDescriptor && (err == noErr)) { |
err = (*theDescriptor)(storage, rgn, msg, params); |
} |
if (msg == Close || err != noErr || msg >= ButtonMessage) { |
CloseConnection(&theConnectionID); |
} |
ExitCodeResource(); |
return err; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14