home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / datatypes / embed_datatype / classbase.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-12  |  9.1 KB  |  334 lines

  1.  
  2. /*
  3. **
  4. **  $VER: classbase.c 1.3 (12.10.97)
  5. **  embed.datatype 1.3
  6. **
  7. **  Library routines for a DataTypes class
  8. **
  9. **  Written 1996/1997 by Roland 'Gizzy' Mainz
  10. **  Original example source from David N. Junod
  11. **
  12. */
  13.  
  14.  
  15. /* main includes */
  16. #include "classbase.h"
  17.  
  18.  
  19. /****** embed.datatype/--datasheed-- *****************************************
  20. *
  21. *   NAME
  22. *       embed.datatype -- data type which embeds other objects
  23. *
  24. *   SUPERCLASS
  25. *       text.datatype
  26. *
  27. *   FUNCTION
  28. *       The embed data type, a sub-class of the text.datatype, is used
  29. *       to view documents with embedded datatypes objects.
  30. *
  31. *   METHODS
  32. *       OM_NEW -- Create a new text object from a embed document file. The
  33. *           source may only be a file.
  34. *
  35. *       OM_GET -- The DTA_Methods attribute is created from local context.
  36. *
  37. *       GM_GOACTIVE
  38. *       GM_GOINACTIVE
  39. *       DTM_CLEARSELECTED --
  40. *
  41. *       DTM_TRIGGER --
  42. *
  43. *   ATTRIBUTES
  44. *       DTA_Methods -- Set to the supported set of methods, based
  45. *           on the set got from the superclass, extended with methods
  46. *           got from members.
  47. *
  48. +       DTA_TriggerMethods -- Set of trigger methods
  49. *
  50. *   BUGS
  51. *       Horrors !
  52. *
  53. *       - The text rendered by text.datatype ignores and "height" in the
  54. *         line node, this results in a crazy display of text.
  55. *         The embedded objects are shown correctly.
  56. *
  57. *       - Inside GM_HANDLEINPUT: Return codes GMR_PREVACTIVE and
  58. *         GMR_NEXTACTIVE are not supported yet; the usage of string
  59. *         gadgets is limmited therefore :-(
  60. *
  61. *       - A line box is drawn around each datatype, but the line is
  62. *         outside of the gadget box set in the struct Line node.
  63. *         A result of this inconsisteny may be an overwritten
  64. *         window border.
  65. *
  66. *       - Embedding the document itself causes an endless loop until
  67. *         memory is full (then the datatypes waits for more memory...).
  68. *
  69. *       - A new stack frame is allocated for each method; a smarter
  70. *         stack managing scheme should be used.
  71. *
  72. *       - animation.datatype has problems when calculating the
  73. *         gadget box for it's tapedeck.gadget.
  74. *         This works usually fine, but sometimes a small part of the
  75. *         left border will be overwritten.
  76. *
  77. *       - Trigger methods are send as a broadcast method to all
  78. *         members instead to specific ones.
  79. *
  80. *       - DTM_PRINT, DTM_COPY, DTM_WRITE etc. are currently not supported.
  81. *
  82. *
  83. *   HISTORY
  84. *       V1.1
  85. *         Released to dta@amigaworld.com mailinglist for comments.
  86. *
  87. *       V1.2
  88. *         - Implemented own GM_RENDER, which supersets text.datatypes rendering
  89. *           completely.
  90. *
  91. *         - Minor corrections
  92. *
  93. *       V1.3
  94. *         - Recompiled with SAS/C 6.58
  95. *
  96. *         - Added missing WaitBlit in GM_RENDER.
  97. *
  98. *         - AllocBitMap used for Line rebdering now uses BMF_MINPLANES and a
  99. *           friend bitmap.
  100. *
  101. *         - Internal DescroyVisibleList now sets the object's domain box to
  102. *           { SHRT_MAX, SHRT_MAX, 0, 0 } instead of { 0, 0, 0, 0 }.
  103. *
  104. *           This should fix problems if a datatypes class has problems with
  105. *           clipping (e.g. 0 width and/or height).
  106. *
  107. *         - Fixed (hopefully) the bug that the box EraseRect'ed at GM_RENDER
  108. *           was 1 pixel in x/y too large.
  109. *
  110. *         - Now implements correct usage of DTSIF_LAYOUT. This avoids
  111. *           rendering and other unwanted actions during layout (e.g. this
  112. *           reduces flickering).
  113. *
  114. *         - Now a black box is drawn around the object. This feature can be
  115. *           turned off at compile time by disableing the
  116. *           DRAW_BOX_AROUND_OBJECT define cpp statement.
  117. *           A 0-color box would be more usefull if HAM pictures/anims are
  118. *           shown (ide taken from cdgxl).
  119. *
  120. *
  121. *   NOTES
  122. *
  123. *   SEE ALSO
  124. *       text.datatype, amigaguide.datatype,
  125. *       document.datatype
  126. *
  127. *******************************************************************************
  128. *
  129. */
  130.  
  131. /*****************************************************************************/
  132.  
  133. /* local prototypes */
  134. static struct ClassLibrary     *OpenClassLibrary( struct ClassBase *, STRPTR, ULONG );
  135.  
  136. /*****************************************************************************/
  137.  
  138. DISPATCHERFLAGS
  139. struct IClass *ObtainEmbedEngine( REGA6 struct ClassBase *cb )
  140. {
  141.     return( (cb -> cb_Lib . cl_Class) );
  142. }
  143.  
  144. /*****************************************************************************/
  145.  
  146. DISPATCHERFLAGS
  147. struct Library *LibInit( REGD0 struct ClassBase *cb, REGA0 BPTR seglist, REGA6 struct ExecBase *sysbase )
  148. {
  149.     cb -> cb_SegList = seglist;
  150.     cb -> cb_SysBase = sysbase;
  151.  
  152.     InitSemaphore( (&(cb -> cb_Lock)) );
  153.  
  154.     if( (cb -> cb_SysBase -> LibNode . lib_Version) >= 39UL )
  155.     {
  156.       /* Obtain ROM libs */
  157.       if( cb -> cb_IntuitionBase = OpenLibrary( "intuition.library", 39UL ) )
  158.       {
  159.         if( cb -> cb_GfxBase = OpenLibrary( "graphics.library",  39UL ) )
  160.         {
  161.           if( cb -> cb_DOSBase = OpenLibrary( "dos.library", 39UL ) )
  162.           {
  163.             if( cb -> cb_UtilityBase = OpenLibrary( "utility.library", 39UL ) )
  164.             {
  165.               return( (&(cb -> cb_Lib . cl_Lib)) );
  166.  
  167. #ifdef COMMENTED_OUT
  168.               CloseLibrary( UtilityBase );
  169. #endif /* COMMENTED_OUT */
  170.             }
  171.  
  172.             CloseLibrary( DOSBase );
  173.           }
  174.  
  175.           CloseLibrary( GfxBase );
  176.         }
  177.  
  178.         CloseLibrary( IntuitionBase );
  179.       }
  180.     }
  181.  
  182.     return( NULL );
  183. }
  184.  
  185. /*****************************************************************************/
  186.  
  187. DISPATCHERFLAGS
  188. LONG LibOpen( REGA6 struct ClassBase *cb )
  189. {
  190.     LONG retval = (LONG)cb;
  191.     BOOL success = TRUE;
  192.  
  193.     ObtainSemaphore( (&(cb -> cb_Lock)) );
  194.  
  195.     /* Use an internal use counter */
  196.     cb -> cb_Lib . cl_Lib . lib_OpenCnt++;
  197.     cb -> cb_Lib . cl_Lib . lib_Flags &= ~LIBF_DELEXP;
  198.  
  199.     if( (cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 1U )
  200.     {
  201.       if( (cb -> cb_Lib . cl_Class) == NULL )
  202.       {
  203.         success = FALSE;
  204.  
  205.         if( cb -> cb_DataTypesBase = OpenLibrary( "datatypes.library", 39UL ) )
  206.         {
  207.           if( cb -> cb_SuperClassBase = OpenLibrary( "datatypes/text.datatype", 39UL ) )
  208.           {
  209.             cb -> cb_CalendarBase = OpenClassLibrary( cb, "gadgets/calendar.gadget", 37UL );
  210.  
  211.             success = initClass( cb );
  212.           }
  213.         }
  214.       }
  215.     }
  216.  
  217.     if( !success )
  218.     {
  219.       CloseLibrary( (&(cb -> cb_CalendarBase -> cl_Lib)) );
  220.       CloseLibrary( (cb -> cb_SuperClassBase) );
  221.       CloseLibrary( (cb -> cb_DataTypesBase) );
  222.  
  223.       cb -> cb_DataTypesBase = cb -> cb_SuperClassBase = NULL;
  224.       cb -> cb_CalendarBase = NULL;
  225.  
  226.       (cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
  227.  
  228.       retval = 0L;
  229.     }
  230.  
  231.     ReleaseSemaphore( (&(cb -> cb_Lock)) );
  232.  
  233.     return( retval );
  234. }
  235.  
  236. /*****************************************************************************/
  237.  
  238. DISPATCHERFLAGS
  239. LONG LibClose( REGA6 struct ClassBase *cb )
  240. {
  241.     LONG retval = 0L;
  242.  
  243.     ObtainSemaphore( (&(cb -> cb_Lock)) );
  244.  
  245.     if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
  246.     {
  247.       (cb -> cb_Lib . cl_Lib . lib_OpenCnt)--;
  248.     }
  249.  
  250.     if( ((cb -> cb_Lib . cl_Lib . lib_OpenCnt) == 0U) && (cb -> cb_Lib . cl_Class) )
  251.     {
  252.       if( FreeClass( (cb -> cb_Lib . cl_Class) ) )
  253.       {
  254.         cb -> cb_Lib . cl_Class = NULL;
  255.  
  256.         /* Ignores FreeClass return value because there are no embed models without embedclass objects */
  257.         (void)FreeClass( (cb -> cb_EmbedModel) );
  258.         cb -> cb_EmbedModel = NULL;
  259.  
  260.         CloseLibrary( (&(cb -> cb_CalendarBase -> cl_Lib)) );
  261.         CloseLibrary( (cb -> cb_SuperClassBase) );
  262.         CloseLibrary( (cb -> cb_DataTypesBase) );
  263.       }
  264.       else
  265.       {
  266.         cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
  267.       }
  268.     }
  269.  
  270.     ReleaseSemaphore( (&(cb -> cb_Lock)) );
  271.  
  272.     if( (cb -> cb_Lib . cl_Lib . lib_Flags) & LIBF_DELEXP )
  273.     {
  274.       retval = LibExpunge( cb );
  275.     }
  276.  
  277.     return( retval );
  278. }
  279.  
  280. /*****************************************************************************/
  281.  
  282. DISPATCHERFLAGS
  283. LONG LibExpunge( REGA6 struct ClassBase *cb )
  284. {
  285.     BPTR seg;
  286.  
  287.     if( cb -> cb_Lib . cl_Lib . lib_OpenCnt )
  288.     {
  289.       cb -> cb_Lib . cl_Lib . lib_Flags |= LIBF_DELEXP;
  290.  
  291.       seg = NULL;
  292.     }
  293.     else
  294.     {
  295.       Remove( (&(cb -> cb_Lib . cl_Lib . lib_Node)) );
  296.  
  297.       seg = cb -> cb_SegList;
  298.  
  299.       CloseLibrary( (cb -> cb_UtilityBase) );
  300.       CloseLibrary( (cb -> cb_DOSBase) );
  301.       CloseLibrary( (cb -> cb_GfxBase) );
  302.       CloseLibrary( (cb -> cb_IntuitionBase) );
  303.  
  304.       FreeMem( (APTR)((ULONG)(cb) - (ULONG)(cb -> cb_Lib . cl_Lib . lib_NegSize)), (ULONG)((cb -> cb_Lib . cl_Lib . lib_NegSize) + (cb -> cb_Lib . cl_Lib . lib_PosSize)) );
  305.     }
  306.  
  307.     return( (LONG)seg );
  308. }
  309.  
  310.  
  311. /* Try opening the class library from a number of common places. Adapted from CALENDAR_TEST.c/openclass */
  312. static
  313. struct ClassLibrary *OpenClassLibrary( struct ClassBase *cb, STRPTR name, ULONG version )
  314. {
  315.     struct Library *retval;
  316.     UBYTE           buffer[ 512 ];
  317.  
  318.     if( (retval = OpenLibrary( name, version ) ) == NULL )
  319.     {
  320.       mysprintf( cb, buffer, ":classes/%s", name );
  321.  
  322.       if( (retval = OpenLibrary( buffer, version ) ) == NULL )
  323.       {
  324.         mysprintf( cb, buffer, "classes/%s", name );
  325.  
  326.         retval = OpenLibrary( buffer, version );
  327.       }
  328.     }
  329.  
  330.     return( (struct ClassLibrary *)retval );
  331. }
  332.  
  333.  
  334.