// iigs/resource.h - typed-C facade over the IIgs Resource Manager. // // Phase 3.4 STUB-ONLY landing. The bundler + linker integration ship // fully (see tools/rsrcBundle/), but the *runtime* path is blocked on // Phase 1.1 (the GS/OS fopen hang). GS/OS 6.0.2 + ResourceStartUp + // OpenResourceFile reaches the same path that hangs in fopen today, so // the LoadResource()/GetResourceSize() entry points below return error // codes instead of calling the toolbox. When Phase 1.1 lands, flip // IIGS_RESOURCE_RUNTIME_ENABLED to 1 (or define it at the compiler // level) and rebuild the runtime - the same C surface stays. // // What you GET today: // - resourceProbeInit() reports whether the runtime path is enabled. // - LoadResource() / GetResourceSize() return RES_ERR_BLOCKED unless // IIGS_RESOURCE_RUNTIME_ENABLED is set at compile time. // // HLock semantics (IMPORTANT for future Phase 1.1 unblock): // The toolbox LoadResource() returns a HANDLE (void **) to a master // pointer in MM-relocatable storage. The application MUST call // HLock() before dereferencing if it intends to call ANY toolbox // routine that could trigger a heap compaction (most do). Without // the HLock, the master pointer can be rewritten under you between // the LoadResource and the deref. The typed wrappers below DO NOT // call HLock for you - that is a deliberate choice because over- // locking is a memory-fragmentation footgun and the right scope is // workload-specific. Callers should: // void **h = LoadResourceTyped(0x8014, 1); // HLock(h); // const RTextT *t = (const RTextT *)*h; // ... use t ... // HUnlock(h); #ifndef IIGS_RESOURCE_H #define IIGS_RESOURCE_H #ifdef __cplusplus extern "C" { #endif #include // Flip to 1 (or pass -DIIGS_RESOURCE_RUNTIME_ENABLED=1 on the build line) // once Phase 1.1 unblocks GS/OS fopen on 6.0.2. At that point the typed // wrappers below dispatch into the live toolbox; until then they stub. #ifndef IIGS_RESOURCE_RUNTIME_ENABLED #define IIGS_RESOURCE_RUNTIME_ENABLED 0 #endif // Status codes returned by the typed wrappers. Mirror the runtime's // existing errno-style convention (negative = error). enum { RES_OK = 0, RES_ERR_BLOCKED = -1, // Phase 1.1 runtime path still blocked RES_ERR_NOT_STARTED = -2, // resourceProbeInit() not called yet RES_ERR_NOT_FOUND = -3, // OpenResourceFile / LoadResource failed RES_ERR_TOOLBOX = -4 // Resource Manager returned non-zero }; // Resource type codes we expect to bundle. See Apple IIgs Toolbox // Reference Vol 3 chapter 42 for the canonical list. Defined here as // constants so callers don't have to use raw hex. #define RES_TYPE_RICON 0x8005 #define RES_TYPE_RTEXT 0x8014 #define RES_TYPE_RPSTRING 0x8015 #define RES_TYPE_RCSTRING 0x8016 // Resource ID type matching the toolbox (32-bit on disk and in the // rIndex; the public API uses uint32_t). typedef uint32_t IigsResIdT; // Resource type code (16-bit; high bit reserved for system/extended // types, low 15 bits for the actual code). typedef uint16_t IigsResTypeT; // One-shot Resource Manager bring-up. Calls MMStartUp + TLStartUp + // ResourceStartUp + OpenResourceFile (on our own pathname) when the // runtime path is enabled. Always callable; safe to call more than // once (subsequent calls are no-ops). // // Returns: // RES_OK if the resource fork was opened (or the stub // path "succeeded" with no-op behavior), // RES_ERR_BLOCKED if compiled with IIGS_RESOURCE_RUNTIME_ENABLED=0 // (the default until Phase 1.1 lands), // RES_ERR_TOOLBOX if any of the StartUp calls returned non-zero. int resourceProbeInit(void); // Read whether the runtime path is live. Cheap; returns 1 iff a // successful resourceProbeInit() has run AND the build enabled the // runtime path. Returns 0 in the stub-only landing. int resourceRuntimeEnabled(void); // LoadResource typed wrapper. Returns a HANDLE (void **) on success, // or NULL on failure (and sets *err if non-NULL). // // Caller is responsible for HLock/HUnlock pairing around any usage that // crosses a toolbox call; see HLock semantics block at the top of this // file. void **iigsLoadResource(IigsResTypeT resType, IigsResIdT resId, int *err); // GetResourceSize typed wrapper. Returns the byte size of the resource // or 0 on failure (and sets *err if non-NULL). uint32_t iigsGetResourceSize(IigsResTypeT resType, IigsResIdT resId, int *err); #ifdef __cplusplus } #endif #endif // IIGS_RESOURCE_H