home *** CD-ROM | disk | FTP | other *** search
- /*
- ** BMP Datatype
- **
- ** written by Gunther Nikl (gnikl@informatik.uni-rostock.de)
- **
- ** loosly based on libinit.c of AIFF datatype 1.16 from Olaf "Olsen" Barthel
- */
-
- #include "classbase.h"
-
- /****************************************************************************/
-
- #define VERSION 40
- #define REVISION 11
- #define LIBNAME "bmp.datatype\0bmp 40.11 (19.9.98) by Gunther Nikl\r\n"
-
- PLAIN( struct Library *UtilityBase; )
- PLAIN( ALIAS(__UtilityBase,UtilityBase) )
-
- /****************************************************************************/
-
- // First executable routine of this library; must return an error
- // to the unsuspecting caller
-
- LONG
- ReturnError(VOID)
- {
- return -1;
- }
-
- /****************************************************************************/
-
- /* Cleanup(struct ClassBase *cb):
- *
- * Frees all resources allocated by LibOpen()
- */
-
- STATIC VOID
- Cleanup(struct ClassBase *cb)
- {
- LREG(a6,APTR IntuitionBase) = cb->IntuitionBase;
- struct IClass *cl;
-
- // Note that if FreeClass() doesn't succeed the
- // best the code can do is leave the library in
- // memory thus not crashing the machine due to
- // this kind of error.
-
- if ((cl=cb->PictureClass) && !FreeClass(cl)) {
- AddClass(cl);
- }
- else {
-
- LREG(a6,APTR SysBase) = cb->SysBase;
-
- cb->PictureClass = NULL;
-
- CloseLibrary(cb->SuperClassBase);
- cb->SuperClassBase = NULL;
-
- CloseLibrary(cb->DataTypesBase);
- cb->DataTypesBase = NULL;
-
- PLAIN( CloseLibrary(cb->UtilityBase);
- cb->UtilityBase = NULL; )
-
- CloseLibrary(cb->GfxBase);
- cb->GfxBase = NULL;
-
- CloseLibrary(cb->IntuitionBase);
- cb->IntuitionBase = NULL;
-
- CloseLibrary(cb->DOSBase);
- cb->DOSBase = NULL;
- }
- }
-
- /* GetClassEngine(REG(a6,struct ClassBase *cb)):
- *
- * Get access to the class this library implements
- */
-
- ASM(APTR)
- GetClassEngine(REG(a6,struct ClassBase *cb))
- {
- return cb->PictureClass;
- }
-
- /* LibReserved(VOID):
- *
- * The mandatory reserved library function
- */
-
- LONG
- LibReserved(VOID)
- {
- return 0;
- }
-
- /* LibExpunge(REG(a6,struct ClassBase *cb)):
- *
- * Expunge the library, remove it from memory
- */
-
- ASM(BPTR)
- LibExpunge(REG(a6,struct ClassBase *cb))
- {
- BPTR Result = 0;
-
- // Expunge it later
-
- cb->LibNode.lib_Flags |= LIBF_DELEXP;
-
- // Can we get away with this?
-
- if (!cb->LibNode.lib_OpenCnt && !cb->PictureClass) {
-
- LREG(a6,APTR SysBase) = cb->SysBase;
-
- // Remove the library from the public list
-
- Remove((struct Node *)cb);
-
- // Return the seglist, so it can be unloaded
-
- Result = cb->SegList;
-
- // Free the vector table and the library data
-
- FreeMem((UBYTE *)cb-cb->LibNode.lib_NegSize,cb->LibNode.lib_NegSize+cb->LibNode.lib_PosSize);
- }
-
- // Return the segment pointer, if any
-
- return Result;
- }
-
- /* LibClose(REG(a6,struct ClassBase *cb)):
- *
- * Close the library, as called by CloseLibrary()
- */
-
- ASM(BPTR)
- LibClose(REG(a6,struct ClassBase *cb))
- {
- LREG(a6,APTR SysBase) = cb->SysBase;
- BPTR Result;
-
- // We are going to modify shared data,
- // so watch out
-
- ObtainSemaphore(&cb->LockSemaphore);
-
- // Decrement usage count and check how
- // many customers we still have
-
- if (!cb->LibNode.lib_OpenCnt || !--cb->LibNode.lib_OpenCnt)
- Cleanup(cb);
-
- // Release the lock
-
- ReleaseSemaphore(&cb->LockSemaphore);
-
- // Can we remove ourselves?
-
- Result = 0;
-
- if (cb->LibNode.lib_Flags & LIBF_DELEXP)
- Result = LibExpunge(cb);
-
- return Result;
- }
-
- INLINE struct IClass *CreateClass(APTR cb,APTR IntuitionBase)
- {
- struct IClass *cl = MakeClass(LIBNAME,"datatypes/picture.datatype"+10,NULL,0,0);
- ASM(VOID) Dispatch();
-
- if (cl) {
- cl->cl_Dispatcher.h_Entry = (HOOKFUNC)Dispatch; cl->cl_UserData = (ULONG)cb; AddClass(cl);
- }
-
- return cl;
- }
-
- /* LibOpen(REG(a6,struct ClassBase *cb)):
- *
- * Open the library, as called via OpenLibrary()
- */
-
- ASM(APTR)
- LibOpen(REG(a6,struct ClassBase *cb))
- {
- APTR IntBase, SysBase = cb->SysBase, Result = cb;
- UWORD OpenCount;
-
- // We are going to modify data while in multitasking,
- // so watch out
-
- ObtainSemaphore(&cb->LockSemaphore);
-
- // Is this the first initialization?
-
- if ((OpenCount=cb->LibNode.lib_OpenCnt) == 0 && !cb->PictureClass &&
- ((cb->DOSBase=OpenLibrary("dos.library",39)) == NULL ||
- (cb->IntuitionBase=IntBase=OpenLibrary("intuition.library",39)) == NULL ||
- (cb->GfxBase=OpenLibrary("graphics.library",39)) == NULL ||
- PLAIN( (UtilityBase=cb->UtilityBase=OpenLibrary("utility.library",39)) == NULL || )
- (cb->DataTypesBase=OpenLibrary("datatypes.library",39)) == NULL ||
- (cb->SuperClassBase=OpenLibrary("datatypes/picture.datatype",39)) == NULL ||
- (cb->PictureClass=CreateClass(cb,IntBase)) == NULL))
- {
- Cleanup(cb); Result = NULL;
- }
- else
- ++OpenCount;
-
- // Prevent delayed expunge and adjust OpenCount
-
- cb->LibNode.lib_Flags &= ~LIBF_DELEXP;
- cb->LibNode.lib_OpenCnt = OpenCount;
-
- // Release the lock
-
- ReleaseSemaphore(&cb->LockSemaphore);
-
- // Return the library base, if any
-
- return Result;
- }
-
- /* LibInit():
- *
- * Initialize the library
- */
-
- ASM(APTR)
- LibInit(REG(a0,BPTR SegList),REG(d0,struct ClassBase *cb),REG(a6,APTR sysBase))
- {
- LREG(a6,struct ExecBase *SysBase) = sysBase;
-
- // Set up the header data; everything that doesn't get
- // set up here will have been set up by InitResident()
-
- cb->LibNode.lib_Revision = REVISION;
-
- // Remember the segment pointer
-
- cb->SegList = SegList;
-
- // Remember the exec library base pointer
-
- cb->SysBase = &SysBase->LibNode;
-
- // Initialize the shared data access semaphore
-
- InitSemaphore(&cb->LockSemaphore);
-
- // sanity check(s)
-
- if (39>SysBase->LibNode.lib_Version || REQUIRES_68020(SysBase->AttnFlags)) {
- FreeMem((UBYTE *)cb-cb->LibNode.lib_NegSize,cb->LibNode.lib_NegSize+cb->LibNode.lib_PosSize);
- cb = NULL;
- }
-
- return cb;
- }
-
- /****************************************************************************/
-
- // This is the table of functions that make up the library. The first
- // four are mandatory, everything following it are user callable
- // routines. The table is terminated by the value -1.
-
- static const APTR LibVectors[] = {
- (APTR)LibOpen,
- (APTR)LibClose,
- (APTR)LibExpunge,
- (APTR)LibReserved,
- (APTR)GetClassEngine,
- (APTR)-1
- };
-
- // The following data structures and data are responsible for
- // setting up the Library base data structure and the library
- // function vector.
-
- static const ULONG LibInitTable[] = {
- (ULONG)sizeof(struct ClassBase), // Size of the base data structure
- (ULONG)LibVectors, // Points to the function vector
- (ULONG)NULL, // Library base data structure setup table
- (ULONG)LibInit // The address of the routine to do the setup
- };
-
- /****************************************************************************/
-
- // The library loader looks for this marker in the memory
- // the library code and data will occupy. It is responsible
- // setting up the Library base data structure.
-
- static const struct Resident RomTag = {
- RTC_MATCHWORD, // Marker value
- (struct Resident *)&RomTag, // This points back to itself
- (struct Resident *)&RomTag+1, // This points behind this marker
- RTF_AUTOINIT, // The Library should be set up according to the given table
- VERSION, // The version of this Library
- NT_LIBRARY, // This defines this module as a Library
- 0, // Initialization priority of this Library; unused
- LIBNAME, // Points to the name of the Library
- LIBNAME+13, // The identification string of this Library
- (APTR)LibInitTable // This table is for initializing the Library
- };
-