home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Atlanta_1990 / Atlanta-Devcon.1 / Libraries / Intuition / boopsi / myclassinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-26  |  6.2 KB  |  242 lines

  1. /* myclassinit.c -- :ts=8
  2.  * Init, Open, Close, Expunge for myclass.library.
  3.  * Note: although this seems to work well, this library
  4.  * needs to be tested more before it is used as a
  5.  * base for other libraries.
  6.  */
  7.  
  8. /*
  9. Copyright (c) 1989, 1990 Commodore-Amiga, Inc.
  10.  
  11. Executables based on this information may be used in software
  12. for Commodore Amiga computers. All other rights reserved.
  13. This information is provided "as is"; no warranties are made.
  14. All use is at your own risk, and no liability or responsibility
  15. is assumed.
  16. */
  17.  
  18. #include "sysall.h"
  19. #include <exec/libraries.h>
  20. #include <intuition/classes.h>
  21. #include "myclassbase.h"
  22.  
  23. #ifdef printf
  24. #undef printf
  25. #endif
  26. #define printf kprintf
  27.  
  28. #define D(x)    x
  29.  
  30. /* These globals are for library calls from the classes.
  31.  * This library is not rommable as is.
  32.  */
  33. struct  IntuitionBase   *IntuitionBase = NULL;
  34. struct  GfxBase         *GfxBase = NULL;
  35. struct  Library         *UtilityBase = NULL;
  36. struct  Library         *SysBase = NULL;
  37.  
  38. /* gets my public class    */
  39. struct IClass    *initEmbBClass();
  40.  
  41.  
  42. /*
  43.  * The basic protocol here is that if the class pointer
  44.  * MyLibBase.mlb_MyClass is NULL, then this library
  45.  * should be expungable as is.
  46.  *
  47.  * So, myOpen() must clean up if it can't get the library,
  48.  * and myClose() must be completely expungable iff it frees the 
  49.  * class.
  50.  */
  51.  
  52. /*
  53.  * This routine gets called after the library has been allocated.
  54.  * The library pointer is in D0.  The segment list is in A0.
  55.  * If it returns non-zero then the library will be linked into
  56.  * the library list.
  57.  */
  58. struct Library * __saveds
  59. __asm myLibInit(
  60.     register __d0 struct MyLibBase *mlb,
  61.     register __a0 void    *seglist,
  62.     register __a6 void     *sysbase )
  63. {
  64.     D( printf("mylibinit, mlb %lx, seglist %lx, sysbase %lx\n",
  65.         mlb, seglist, sysbase ) );
  66.  
  67.     SysBase = sysbase;    /* set up as global for my class to use */
  68.  
  69.     mlb->mlb_SegList = seglist;
  70.  
  71.     return ( (struct Library *) mlb );
  72. }
  73.  
  74.  
  75. struct Library * __saveds
  76. __asm myLibOpen( register __a6 struct MyLibBase *mlb )
  77. {
  78.    D( printf("openlib: mlb %lx\n", mlb ) );
  79.  
  80.    mlb->mlb_Flags &= ~LIBF_DELEXP;
  81.    if ( ++mlb->mlb_Library.lib_OpenCnt == 1 )
  82.    {
  83.     D( printf("we are the first opener\n") );
  84.  
  85.     /* first open    */
  86.     if ( mlb->mlb_MyClass )
  87.     {
  88.         D( printf("openlib: class is hanging around at %lx\n", 
  89.             mlb->mlb_MyClass ) );
  90.  
  91.         /* class still hanging around, needs only to be re-added */
  92.         /* Also, I've still got the libraries open */
  93.         AddClass( mlb->mlb_MyClass );
  94.     }
  95.     else
  96.     {
  97.         if ( ! openAll( mlb ) ||
  98.             (mlb->mlb_MyClass = initEmbBClass()) == NULL )
  99.         {
  100.         /*** FAILURE TO OPEN ***/
  101.         D( printf("failure to open/initialize\n") );
  102.         closeAll();    /* make self expungeable    */
  103.  
  104.         mlb->mlb_Library.lib_OpenCnt = 0;
  105.         return ( NULL );    /* failed OpenLibrary() */
  106.         }
  107.  
  108.         D(printf("successfully open, class at %lx\n", mlb->mlb_MyClass));
  109.     }
  110.    }
  111.  
  112.    return ( (struct Library *) mlb );
  113. }
  114.  
  115. /*
  116.  * Returns seglist if it is to be freed.
  117.  * Won't expunge if library is open or if class is hanging around.
  118.  */
  119. void * __saveds
  120. __asm myLibExpunge( register __a6 struct MyLibBase *mlb )
  121. {
  122.     void *seglist;
  123.  
  124.     D( printf("myLibExpunge\n") );
  125.     if ( mlb->mlb_Library.lib_OpenCnt || mlb->mlb_MyClass )
  126.     {
  127.     D( printf("can't expunge, set LIBF_DELEXP\n") );
  128.     mlb->mlb_Flags |= LIBF_DELEXP;
  129.         return ( NULL );
  130.     }
  131.  
  132.     D( printf("expunging now.\n") );
  133.  
  134.     /* remove library from lib list */
  135.     Remove( mlb );
  136.  
  137.     /* cache seglist before freeing library     */
  138.     seglist = mlb->mlb_SegList;
  139.     D( printf("seglist at %lx\n", seglist ) );
  140.  
  141.     /* free library node */
  142.     D( printf("freeing library node at %lx, size (hex) %lx\n", 
  143.      mlb,mlb->mlb_Library.lib_NegSize+mlb->mlb_Library.lib_PosSize) );
  144.  
  145.     /* free library base data structure, including the part
  146.      * *before* the Library pointer.
  147.      */
  148.     FreeMem( ((UBYTE *)mlb) - mlb->mlb_Library.lib_NegSize, 
  149.         mlb->mlb_Library.lib_NegSize+mlb->mlb_Library.lib_PosSize);
  150.  
  151.     return ( seglist );
  152. }
  153.  
  154. /*
  155.  * called directly.
  156.  * returns NULL if it isn't expunging
  157.  */
  158. void * __saveds
  159. __asm myLibClose( register __a6 struct MyLibBase *mlb )
  160. {
  161.     struct IClass    *cl;
  162.  
  163.     D( printf("closelib, base at %lx, opencnt %lx\n", mlb,
  164.         mlb->mlb_Library.lib_OpenCnt ) );
  165.     D( printf("object count %lx, subclass count %lx\n",
  166.     mlb->mlb_MyClass->cl_ObjectCount,mlb->mlb_MyClass->cl_SubclassCount));
  167.  
  168.     if ( --mlb->mlb_Library.lib_OpenCnt <= 0 )
  169.     {
  170.     D( printf("we're the last closer\n") );
  171.  
  172.     /* Last user is closing.  Try to free up the class
  173.      * so we can be expunged.
  174.      */
  175.     if ( (cl = mlb->mlb_MyClass) == NULL )
  176.     {
  177.         /* this case shouldn't happen, but you never know */
  178.         D( printf("surprised to find my class == NULL!\n") );
  179.         closeAll();
  180.         goto OUT;
  181.     }
  182.  
  183.     RemoveClass( cl );    /* make class unavailable */
  184.     D( printf("class removed\n") );
  185.  
  186.     /* now that nobody can get at the class, see if anybody
  187.      * still depends on it.  There's a slight hitch here,
  188.      * in that we're assuming that if the two 'counts' are
  189.      * zero, that we'll be able to successfully free our
  190.      * class, OR, that it will be usable after we try.
  191.      */
  192.     if ( cl->cl_ObjectCount == 0 &&
  193.          cl->cl_SubclassCount == 0 &&
  194.          freeEmbBClass( cl ) )
  195.     {
  196.         D( printf("successfully freed class\n") );
  197.         closeAll();
  198.         mlb->mlb_MyClass = NULL;    /* means we're expungable */
  199.     }
  200.  
  201.     /* else, we're all closed, our class is removed, but
  202.      * we're not expungable.
  203.      */
  204.     }
  205. OUT:
  206.     /* delayed expunge stuff */
  207.     if ( mlb->mlb_Library.lib_OpenCnt == 0 &&
  208.         (mlb->mlb_Flags & LIBF_DELEXP ) )
  209.     {
  210.     D( printf("closelib: delayed expunge\n") );
  211.     return ( myLibExpunge( mlb ) );
  212.     }
  213.  
  214.     D( printf("closelib: not expunged, open count %lx, flags %lx\n",
  215.         mlb->mlb_Library.lib_OpenCnt, mlb->mlb_Flags ) );
  216.     return ( NULL );    /* not expunged */
  217. }
  218.  
  219. /* returns 0 if failure */
  220. openAll( mlb )
  221. struct MyLibBase    *mlb;
  222. {
  223.     if (!(UtilityBase=(struct Library *)OpenLibrary("utility.library",36L)))
  224.         return ( 0 );
  225.  
  226.     if (!(IntuitionBase = 
  227.     (struct IntuitionBase *) OpenLibrary("intuition.library", 36L)))
  228.         return ( 0 );
  229.  
  230.     if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 36L)))
  231.         return ( 0 );
  232.  
  233.     return ( 1 );
  234. }
  235.  
  236. closeAll()
  237. {
  238.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  239.     if (GfxBase) CloseLibrary(GfxBase);
  240.     if (UtilityBase) CloseLibrary(UtilityBase);
  241. }
  242.