home *** CD-ROM | disk | FTP | other *** search
/ MACD 9 / MACD9.iso / Datatypes / BMPdt / source / libinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-19  |  7.6 KB  |  313 lines

  1. /*
  2. ** BMP Datatype
  3. **
  4. ** written by Gunther Nikl (gnikl@informatik.uni-rostock.de)
  5. ** 
  6. ** loosly based on libinit.c of AIFF datatype 1.16 from Olaf "Olsen" Barthel
  7. */
  8.  
  9. #include "classbase.h"
  10.  
  11. /****************************************************************************/
  12.  
  13. #define VERSION  40
  14. #define REVISION 11
  15. #define LIBNAME  "bmp.datatype\0bmp 40.11 (19.9.98) by Gunther Nikl\r\n"
  16.  
  17. PLAIN( struct Library *UtilityBase; )
  18. PLAIN( ALIAS(__UtilityBase,UtilityBase) )
  19.  
  20. /****************************************************************************/
  21.  
  22.   // First executable routine of this library; must return an error
  23.   // to the unsuspecting caller
  24.  
  25. LONG
  26. ReturnError(VOID)
  27. {
  28.   return -1;
  29. }
  30.  
  31. /****************************************************************************/
  32.  
  33.   /* Cleanup(struct ClassBase *cb):
  34.    *
  35.    *  Frees all resources allocated by LibOpen()
  36.    */
  37.  
  38. STATIC VOID
  39. Cleanup(struct ClassBase *cb)
  40. {
  41.   LREG(a6,APTR IntuitionBase) = cb->IntuitionBase;
  42.   struct IClass *cl;
  43.  
  44.   // Note that if FreeClass() doesn't succeed the
  45.   // best the code can do is leave the library in
  46.   // memory thus not crashing the machine due to
  47.   // this kind of error.
  48.  
  49.   if ((cl=cb->PictureClass) && !FreeClass(cl)) {
  50.     AddClass(cl);
  51.   }
  52.   else {
  53.  
  54.     LREG(a6,APTR SysBase) = cb->SysBase;
  55.  
  56.     cb->PictureClass = NULL;
  57.  
  58.     CloseLibrary(cb->SuperClassBase);
  59.     cb->SuperClassBase = NULL;
  60.  
  61.     CloseLibrary(cb->DataTypesBase);
  62.     cb->DataTypesBase = NULL;
  63.  
  64.     PLAIN( CloseLibrary(cb->UtilityBase);
  65.     cb->UtilityBase = NULL; )
  66.  
  67.     CloseLibrary(cb->GfxBase);
  68.     cb->GfxBase = NULL;
  69.  
  70.     CloseLibrary(cb->IntuitionBase);
  71.     cb->IntuitionBase = NULL;
  72.  
  73.     CloseLibrary(cb->DOSBase);
  74.     cb->DOSBase = NULL;
  75.   }
  76. }
  77.  
  78.   /* GetClassEngine(REG(a6,struct ClassBase *cb)):
  79.    *
  80.    *  Get access to the class this library implements
  81.    */
  82.  
  83. ASM(APTR)
  84. GetClassEngine(REG(a6,struct ClassBase *cb))
  85. {
  86.   return cb->PictureClass;
  87. }
  88.  
  89.   /* LibReserved(VOID):
  90.    *
  91.    *  The mandatory reserved library function
  92.    */
  93.  
  94. LONG
  95. LibReserved(VOID)
  96. {
  97.   return 0;
  98. }
  99.  
  100.   /* LibExpunge(REG(a6,struct ClassBase *cb)):
  101.    *
  102.    *  Expunge the library, remove it from memory
  103.    */
  104.  
  105. ASM(BPTR)
  106. LibExpunge(REG(a6,struct ClassBase *cb))
  107. {
  108.   BPTR Result = 0;
  109.  
  110.   // Expunge it later
  111.  
  112.   cb->LibNode.lib_Flags |= LIBF_DELEXP;
  113.  
  114.   // Can we get away with this?
  115.  
  116.   if (!cb->LibNode.lib_OpenCnt && !cb->PictureClass) {
  117.  
  118.     LREG(a6,APTR SysBase) = cb->SysBase;
  119.  
  120.     // Remove the library from the public list
  121.  
  122.     Remove((struct Node *)cb);
  123.  
  124.     // Return the seglist, so it can be unloaded
  125.  
  126.     Result = cb->SegList;
  127.  
  128.     // Free the vector table and the library data
  129.  
  130.     FreeMem((UBYTE *)cb-cb->LibNode.lib_NegSize,cb->LibNode.lib_NegSize+cb->LibNode.lib_PosSize);
  131.   }
  132.  
  133.   // Return the segment pointer, if any
  134.  
  135.   return Result;
  136. }
  137.  
  138.   /* LibClose(REG(a6,struct ClassBase *cb)):
  139.    *
  140.    *  Close the library, as called by CloseLibrary()
  141.    */
  142.  
  143. ASM(BPTR)
  144. LibClose(REG(a6,struct ClassBase *cb))
  145. {
  146.   LREG(a6,APTR SysBase) = cb->SysBase;
  147.   BPTR Result;
  148.  
  149.   // We are going to modify shared data,
  150.   // so watch out
  151.  
  152.   ObtainSemaphore(&cb->LockSemaphore);
  153.  
  154.   // Decrement usage count and check how
  155.   // many customers we still have
  156.  
  157.   if (!cb->LibNode.lib_OpenCnt || !--cb->LibNode.lib_OpenCnt)
  158.     Cleanup(cb);
  159.  
  160.   // Release the lock
  161.  
  162.   ReleaseSemaphore(&cb->LockSemaphore);
  163.  
  164.   // Can we remove ourselves?
  165.  
  166.   Result = 0;
  167.  
  168.   if (cb->LibNode.lib_Flags & LIBF_DELEXP)
  169.     Result = LibExpunge(cb);
  170.  
  171.   return Result;
  172. }
  173.  
  174. INLINE struct IClass *CreateClass(APTR cb,APTR IntuitionBase)
  175. {
  176.   struct IClass *cl = MakeClass(LIBNAME,"datatypes/picture.datatype"+10,NULL,0,0);
  177.   ASM(VOID) Dispatch();
  178.  
  179.   if (cl) {
  180.     cl->cl_Dispatcher.h_Entry = (HOOKFUNC)Dispatch; cl->cl_UserData = (ULONG)cb; AddClass(cl);
  181.   }
  182.  
  183.   return cl;
  184. }
  185.  
  186.   /* LibOpen(REG(a6,struct ClassBase *cb)):
  187.    *
  188.    *  Open the library, as called via OpenLibrary()
  189.    */
  190.  
  191. ASM(APTR)
  192. LibOpen(REG(a6,struct ClassBase *cb))
  193. {
  194.   APTR IntBase, SysBase = cb->SysBase, Result = cb;
  195.   UWORD OpenCount;
  196.  
  197.   // We are going to modify data while in multitasking,
  198.   // so watch out
  199.  
  200.   ObtainSemaphore(&cb->LockSemaphore);
  201.  
  202.   // Is this the first initialization?
  203.  
  204.   if ((OpenCount=cb->LibNode.lib_OpenCnt) == 0 && !cb->PictureClass &&
  205.       ((cb->DOSBase=OpenLibrary("dos.library",39)) == NULL ||
  206.        (cb->IntuitionBase=IntBase=OpenLibrary("intuition.library",39)) == NULL ||
  207.        (cb->GfxBase=OpenLibrary("graphics.library",39)) == NULL ||
  208.        PLAIN( (UtilityBase=cb->UtilityBase=OpenLibrary("utility.library",39)) == NULL || )
  209.        (cb->DataTypesBase=OpenLibrary("datatypes.library",39)) == NULL ||
  210.        (cb->SuperClassBase=OpenLibrary("datatypes/picture.datatype",39)) == NULL ||
  211.        (cb->PictureClass=CreateClass(cb,IntBase)) == NULL))
  212.   {
  213.     Cleanup(cb); Result = NULL;
  214.   }
  215.   else
  216.     ++OpenCount;
  217.  
  218.   // Prevent delayed expunge and adjust OpenCount
  219.  
  220.   cb->LibNode.lib_Flags &= ~LIBF_DELEXP;
  221.   cb->LibNode.lib_OpenCnt = OpenCount;
  222.  
  223.   // Release the lock
  224.  
  225.   ReleaseSemaphore(&cb->LockSemaphore);
  226.  
  227.   // Return the library base, if any
  228.  
  229.   return Result;
  230. }
  231.  
  232.   /* LibInit():
  233.    *
  234.    *  Initialize the library
  235.    */
  236.  
  237. ASM(APTR)
  238. LibInit(REG(a0,BPTR SegList),REG(d0,struct ClassBase *cb),REG(a6,APTR sysBase))
  239. {
  240.   LREG(a6,struct ExecBase *SysBase) = sysBase;
  241.  
  242.   // Set up the header data; everything that doesn't get
  243.   // set up here will have been set up by InitResident()
  244.  
  245.   cb->LibNode.lib_Revision = REVISION;
  246.  
  247.   // Remember the segment pointer
  248.  
  249.   cb->SegList = SegList;
  250.  
  251.   // Remember the exec library base pointer
  252.  
  253.   cb->SysBase = &SysBase->LibNode;
  254.  
  255.   // Initialize the shared data access semaphore
  256.  
  257.   InitSemaphore(&cb->LockSemaphore);
  258.  
  259.   // sanity check(s)
  260.  
  261.   if (39>SysBase->LibNode.lib_Version || REQUIRES_68020(SysBase->AttnFlags)) {
  262.     FreeMem((UBYTE *)cb-cb->LibNode.lib_NegSize,cb->LibNode.lib_NegSize+cb->LibNode.lib_PosSize);
  263.     cb = NULL;
  264.   }
  265.  
  266.   return cb;
  267. }
  268.  
  269. /****************************************************************************/
  270.  
  271.   // This is the table of functions that make up the library. The first
  272.   // four are mandatory, everything following it are user callable
  273.   // routines. The table is terminated by the value -1.
  274.  
  275. static const APTR LibVectors[] = {
  276.   (APTR)LibOpen,
  277.   (APTR)LibClose,
  278.   (APTR)LibExpunge,
  279.   (APTR)LibReserved,
  280.   (APTR)GetClassEngine,
  281.   (APTR)-1
  282. };
  283.  
  284.   // The following data structures and data are responsible for
  285.   // setting up the Library base data structure and the library
  286.   // function vector.
  287.  
  288. static const ULONG LibInitTable[] = {
  289.   (ULONG)sizeof(struct ClassBase), // Size of the base data structure
  290.   (ULONG)LibVectors,               // Points to the function vector
  291.   (ULONG)NULL,                     // Library base data structure setup table
  292.   (ULONG)LibInit                   // The address of the routine to do the setup
  293. };
  294.  
  295. /****************************************************************************/
  296.  
  297.   // The library loader looks for this marker in the memory
  298.   // the library code and data will occupy. It is responsible
  299.   // setting up the Library base data structure.
  300.  
  301. static const struct Resident RomTag = {
  302.   RTC_MATCHWORD,                // Marker value
  303.   (struct Resident *)&RomTag,   // This points back to itself
  304.   (struct Resident *)&RomTag+1, // This points behind this marker
  305.   RTF_AUTOINIT,                 // The Library should be set up according to the given table
  306.   VERSION,                      // The version of this Library
  307.   NT_LIBRARY,                   // This defines this module as a Library
  308.   0,                            // Initialization priority of this Library; unused
  309.   LIBNAME,                      // Points to the name of the Library
  310.   LIBNAME+13,                   // The identification string of this Library
  311.   (APTR)LibInitTable            // This table is for initializing the Library
  312. };
  313.