1 /*****************************************************************************
3 This code serves as a basis for writing a library-based MUI custom class
4 (xyz.mcc) and its preferences editor (xyz.mcp).
6 You need to define a few things in your main source file, then include
7 this file and then continue with your classes methods. The order is
8 important, mccheader.c must be the first code-generating module.
10 Things to be defined before mccheader.c is included:
12 (1) UserLibID - version string for your class. must follow normal $VER: string conventions.
13 (2) VERSION - version number of the class. must match the one given in the $VER: string.
14 (3) REVISION - revision number of the class. must match the one given in the $VER: string.
15 (4) CLASS - Name of your class, ".mcc" or ".mcp" must always be appended.
17 (5) SUPERCLASS - superclass of your class.
18 (6) struct Data - instance data structure.
19 (7) _Dispatcher - your dispatcher function.
21 (8) SUPERCLASSP - Superclass of the preferences class, must be MUIC_Mccprefs or a subclass.
22 (9) struct DataP - instance data structure of preferences class.
23 (10) _DispatcherP - dispatcher for the preferences class.
25 (11) USEDCLASSES - Other custom classes required by this class (NULL terminated string array)
26 (12) USEDCLASSESP - Preferences classes (.mcp) required by this class (NULL terminated string array)
27 (13) SHORTHELP - .mcp help text for prefs program's listview.
29 Items (1) to (4) must always be defined. If you create a stand-alone
30 custom class (*.mcc) without preferences editor, also define (5), (6)
31 and (7). Name your class and the resulting ouptut file "Myclass.mcc".
33 If you create a preferences class (*.mcp) for a custom class, define
34 (8), (9) and (10) instead of (5), (6) and (7). Name your class and the
35 resulting output file "Myclass.mcp".
37 If you create a custom class with included preferences editor, define
38 all the above. Note that in this case, the name of your class and the
39 resulting output file is always "Myclass.mcc". MUI will automatically
40 recognize that there's also a "Myclass.mcp" included. Having a builtin
41 preferences class reduces the need for a second file but increases the
42 size and memory consuption of the class.
44 (11) If your class requires other mcc custom classes, list them in the
45 static array USEDCLASSES like this:
46 #define USEDCLASSES used_classes
47 const STRPTR used_classes[] = { "Busy.mcc", "Listtree.mcc", NULL };
49 (12) If your class has one (or more) preferences classes, list them in
50 the array USEDCLASSESP like this:
51 #define USEDCLASSESP used_classesP
52 const STRPTR used_classesP[] = { "Myclass.mcp", "Popxxx.mcp", NULL };
54 (13) If you want MUI to display additional help text (besides name,
55 version and copyright) when the mouse pointer is over your mcp entry
56 in the prefs listview:
57 #define SHORTHELP "ANSI display for terminal programs."
59 If your class needs custom initialization (e.g. opening other
60 libraries), you can define
63 to point to custom functions. These functions need to have the prototypes
64 BOOL ClassInitFunc(struct Library *base);
65 VOID ClassExitFunc(struct Library *base);
66 and will be called right after the class has been created and right
67 before the class is being deleted. If your init func returns FALSE,
68 the custom class will be unloaded immediately.
70 Define the minimum version of muimaster.libray in MASTERVERSION. If you
71 don't define MASTERVERSION, it will default to MUIMASTER_VMIN from the
75 Items (1) to (4) must always be defined. If you create a stand-alone
76 custom class (*.mcc) without preferences editor, also define (5), (6)
77 and (7). Name your class and the resulting ouptut file "Myclass.mcc".
79 If you create a preferences class (*.mcp) for a custom class, define
80 (8), (9) and (10) instead of (5), (6) and (7). Name your class and the
81 resulting output file "Myclass.mcp".
83 If you create a custom class with included preferences editor, define
84 all the above. Note that in this case, the name of your class and the
85 resulting output file is always "Myclass.mcc". MUI will automatically
86 recognize that there's also a "Myclass.mcp" included. Having a builtin
87 preferences class reduces the need for a second file but increases the
88 size and memory consuption of the class.
90 If your class needs custom initialization (e.g. opening other
91 libraries), you can define
96 to point to custom functions. These functions need to have the prototypes
97 BOOL ClassInitFunc(struct Library *base);
98 VOID ClassExitFunc(struct Library *base);
99 and will be called right after the class has been created and right
100 before the class is being deleted. If your init func returns FALSE,
101 the custom class will be unloaded immediately.
103 BOOL PreClassInitFunc(void);
104 VOID PostClassExitFunc(void);
106 These functions will be called BEFORE the class is created and AFTER the
107 class is deleted, if something depends on it for example. MUIMasterBase
110 Define the minimum version of muimaster.libray in MASTERVERSION. If you
111 don't define MASTERVERSION, it will default to MUIMASTER_VMIN from the
114 This code automatically defines and initializes the following variables:
115 struct Library *MUIMasterBase;
116 struct Library *SysBase;
117 struct Library *UtilityBase;
118 struct DosLibrary *DOSBase;
119 struct GfxBase *GfxBase;
120 struct IntuitionBase *IntuitionBase;
121 struct Library *MUIClassBase; // your classes library base
122 struct MUI_CustomClass *ThisClass; // your custom class
123 struct MUI_CustomClass *ThisClassP; // your preferences class
126 #define CLASS MUIC_Myclass // name of class, e.g. "Myclass.mcc"
127 #define SUPERCLASS MUIC_Area // name of superclass
131 struct Foobar MyData2;
134 #define UserLibID "$VER: Myclass.mcc 17.53 (11.11.96)"
137 #include "mccheader.c"
138 ULONG ASM SAVEDS _Dispatcher(REG(a0) struct IClass *cl GNUCREG(a0),
139 REG(a2) Object *obj GNUCREG(a2),
140 REG(a1) Msg msg GNUCREG(a1) )
145 Compiling and linking with SAS-C can look like this:
146 Myclass.mcc: Myclass.c
147 sc $(CFLAGS) $*.c OBJNAME $*.o
148 slink to $@ from $*.o lib $(LINKERLIBS) $(LINKERFLAGS)
150 Note well that we don't use SAS library creation feature here, it simply
151 sucks too much. It's not much more complicated to do the library
152 initialziation ourselves and we have better control over everything.
154 Make sure to read the whole source to get some interesting comments
155 and some understanding on how libraries are created!
157 *****************************************************************************/
159 /******************************************************************************/
161 /******************************************************************************/
163 /* MorphOS relevant includes... */
165 #include <emul/emulinterface.h>
166 #include <emul/emulregs.h>
169 /* a few other includes... */
171 #include <exec/types.h>
172 #include <exec/memory.h>
173 #include <exec/libraries.h>
174 #include <exec/semaphores.h>
175 #include <exec/resident.h>
176 #include <exec/execbase.h>
179 #include <proto/exec.h>
180 #include <proto/muimaster.h>
181 #include <proto/utility.h>
182 #include <proto/dos.h>
183 #include <proto/graphics.h>
184 #include <proto/intuition.h>
186 /* The name of the class will also become the name of the library. */
187 /* We need a pointer to this string in our ROMTag (see below). */
189 static const char UserLibName
[] = CLASS
;
191 /* Here's our global data, described above. */
193 #if defined(__amigaos4__)
194 struct Library
*MUIMasterBase
= NULL
;
195 struct Library
*SysBase
= NULL
;
196 struct Library
*UtilityBase
= NULL
;
197 struct Library
*DOSBase
= NULL
;
198 struct Library
*GfxBase
= NULL
;
199 struct Library
*IntuitionBase
= NULL
;
200 struct MUIMasterIFace
*IMUIMaster
= NULL
;
201 struct ExecIFace
*IExec
= NULL
;
202 struct UtilityIFace
*IUtility
= NULL
;
203 struct DOSIFace
*IDOS
= NULL
;
204 struct GraphicsIFace
*IGraphics
= NULL
;
205 struct IntuitionIFace
*IIntuition
= NULL
;
207 struct Library
*MUIMasterBase
= NULL
;
208 struct ExecBase
*SysBase
= NULL
;
209 struct Library
*UtilityBase
= NULL
;
210 struct DosLibrary
*DOSBase
= NULL
;
211 struct GfxBase
*GfxBase
= NULL
;
212 struct IntuitionBase
*IntuitionBase
= NULL
;
216 static struct MUI_CustomClass
*ThisClass
= NULL
;
220 static struct MUI_CustomClass
*ThisClassP
= NULL
;
224 #ifdef USE_UTILITYBASE
225 struct Library
*__UtilityBase
= NULL
; // required by libnix & clib2
228 /* these one are needed copies for libnix.a */
229 #ifdef USE_MATHIEEEDOUBBASBASE
230 struct Library
*__MathIeeeDoubBasBase
= NULL
;
232 #ifdef USE_MATHIEEEDOUBTRANSBASE
233 struct Library
*__MathIeeeDoubTransBase
= NULL
;
236 #endif /* __GNUC__ */
238 /* Our library structure, consisting of a struct Library, a segment pointer */
239 /* and a semaphore. We need the semaphore to protect init/exit stuff in our */
240 /* open/close functions */
244 struct Library lh_Library
;
247 struct SignalSemaphore lh_Semaphore
;
249 struct StackSwapStruct
*lh_Stack
;
252 /******************************************************************************/
253 /* External references */
254 /******************************************************************************/
256 //static BOOL LIBFUNC UserLibInit (struct Library *base);
257 //static BOOL LIBFUNC UserLibExpunge(struct Library *base);
258 static BOOL LIBFUNC
UserLibOpen (struct Library
*base
);
259 static BOOL LIBFUNC
UserLibClose (struct Library
*base
);
261 /******************************************************************************/
262 /* Local Structures & Prototypes */
263 /******************************************************************************/
265 #if defined(__amigaos4__)
267 struct LibraryHeader
* LIBFUNC
LibInit (struct LibraryHeader
*base
, BPTR librarySegment
, struct ExecIFace
*pIExec
);
268 BPTR LIBFUNC
LibExpunge(struct LibraryManagerInterface
*Self
);
269 struct LibraryHeader
* LIBFUNC
LibOpen (struct LibraryManagerInterface
*Self
, ULONG version
);
270 BPTR LIBFUNC
LibClose (struct LibraryManagerInterface
*Self
);
271 LONG LIBFUNC
LibNull (void);
272 ULONG LIBFUNC
MCC_Query (UNUSED
struct Interface
*self
, REG(d0
, LONG which
));
274 #elif defined(__MORPHOS__)
276 struct LibraryHeader
* LIBFUNC
LibInit (struct LibraryHeader
*base
, BPTR Segment
, struct ExecBase
*SysBase
);
277 BPTR LIBFUNC
LibExpunge(void);
278 struct LibraryHeader
* LIBFUNC
LibOpen (void);
279 BPTR LIBFUNC
LibClose (void);
280 LONG LIBFUNC
LibNull (void);
281 ULONG LIBFUNC
MCC_Query (void);
285 struct LibraryHeader
* LIBFUNC
LibInit (REG(a0
, BPTR Segment
), REG(a6
, struct ExecBase
*SysBase
));
286 BPTR LIBFUNC
LibExpunge(REG(a6
, struct LibraryHeader
*base
));
287 struct LibraryHeader
* LIBFUNC
LibOpen (REG(a6
, struct LibraryHeader
*base
));
288 BPTR LIBFUNC
LibClose (REG(a6
, struct LibraryHeader
*base
));
289 LONG LIBFUNC
LibNull (void);
290 ULONG LIBFUNC
MCC_Query (REG(d0
, LONG which
));
294 /******************************************************************************/
295 /* Dummy entry point and LibNull() function all in one */
296 /******************************************************************************/
303 LONG LIBFUNC
LibNull(VOID
)
308 /******************************************************************************/
309 /* Local data structures */
310 /******************************************************************************/
312 #if defined(__amigaos4__)
313 /* ------------------- OS4 Manager Interface ------------------------ */
314 STATIC ULONG
LibObtain(struct LibraryManagerInterface
*Self
)
316 return(Self
->Data
.RefCount
++);
319 STATIC ULONG
LibRelease(struct LibraryManagerInterface
*Self
)
321 return(Self
->Data
.RefCount
--);
324 STATIC CONST APTR LibManagerVectors
[] =
337 STATIC CONST
struct TagItem LibManagerTags
[] =
339 {MIT_Name
, (ULONG
)"__library"},
340 {MIT_VectorTable
, (ULONG
)LibManagerVectors
},
345 /* ------------------- Library Interface(s) ------------------------ */
347 STATIC CONST APTR LibVectors
[] =
357 STATIC CONST
struct TagItem MainTags
[] =
359 {MIT_Name
, (ULONG
)"main"},
360 {MIT_VectorTable
, (ULONG
)LibVectors
},
365 STATIC CONST ULONG LibInterfaces
[] =
367 (ULONG
)LibManagerTags
,
372 // Out libraries always have to carry a 68k jump table with it, so
373 // lets define it here as extern, as we are going to link it to
375 #ifndef NO_VECTABLE68K
376 extern const APTR VecTable68K
[];
379 STATIC CONST
struct TagItem LibCreateTags
[] =
381 {CLT_DataSize
, (ULONG
)(sizeof(struct LibraryHeader
))},
382 {CLT_InitFunc
, (ULONG
)LibInit
},
383 {CLT_Interfaces
, (ULONG
)LibInterfaces
},
384 #ifndef NO_VECTABLE68K
385 {CLT_Vector68K
, (ULONG
)VecTable68K
},
392 static const APTR LibVectors
[] =
395 (APTR
)FUNCARRAY_32BIT_NATIVE
,
407 /* ------------------- ROM Tag ------------------------ */
408 static const USED_VAR
struct Resident ROMTag
=
411 (struct Resident
*)&ROMTag
,
412 (struct Resident
*)&ROMTag
+ 1,
413 #if defined(__amigaos4__)
414 RTF_AUTOINIT
|RTF_NATIVE
, // The Library should be set up according to the given table.
415 #elif defined(__MORPHOS__)
425 #if defined(__amigaos4__)
426 (APTR
)LibCreateTags
, // This table is for initializing the Library.
430 #if defined(__MORPHOS__)
436 #if defined(__MORPHOS__)
438 * To tell the loader that this is a new emulppc elf and not
439 * one for the ppc.library.
442 const USED_VAR ULONG __amigappc__
= 1;
443 const USED_VAR ULONG __abox__
= 1;
449 #ifndef USE_SEMAPHORE
450 #define USE_SEMAPHORE
453 #endif /* __MORPHOS */
456 #define DeleteLibrary(LIB) \
457 FreeMem((STRPTR)(LIB)-(LIB)->lib_NegSize, (ULONG)((LIB)->lib_NegSize+(LIB)->lib_PosSize))
460 /******************************************************************************/
461 /* Standard Library Functions, all of them are called in Forbid() state. */
462 /******************************************************************************/
464 #if defined(__amigaos4__)
465 struct LibraryHeader
* ASM SAVEDS
LibInit(struct LibraryHeader
*base
, BPTR librarySegment
, struct ExecIFace
*pIExec
)
467 struct ExecBase
*sb
= (struct ExecBase
*)pIExec
->Data
.LibBase
;
469 SysBase
= (struct Library
*)sb
;
471 D(DBF_STARTUP
, "start... (segment=%08lx)", librarySegment
);
473 base
->lh_Library
.lib_Node
.ln_Type
= NT_LIBRARY
;
474 base
->lh_Library
.lib_Node
.ln_Pri
= 0;
475 base
->lh_Library
.lib_Node
.ln_Name
= (char *)UserLibName
;
476 base
->lh_Library
.lib_Flags
= LIBF_CHANGED
| LIBF_SUMUSED
;
477 base
->lh_Library
.lib_Version
= VERSION
;
478 base
->lh_Library
.lib_Revision
= REVISION
;
479 base
->lh_Library
.lib_IdString
= (char *)UserLibID
;
481 base
->lh_Segment
= librarySegment
;
483 InitSemaphore(&base
->lh_Semaphore
);
486 if(!UserLibInit((struct Library *)base))
488 DeleteLibrary((struct Library *)base);
499 #undef CLASS_STACKSWAP
500 struct LibraryHeader
*LibInit(struct LibraryHeader
*base
, BPTR Segment
, struct ExecBase
*sb
)
503 struct LibraryHeader
* ASM SAVEDS
LibInit(REG(a0
, BPTR Segment
), REG(a6
, struct ExecBase
*sb
))
507 #if defined(CLASS_STACKSWAP)
508 static struct StackSwapStruct
*stack
;
510 #if !defined(__MORPHOS__)
511 struct LibraryHeader
*base
;
516 D(DBF_STARTUP
, "Start..." );
518 // make sure that this is really a 68020+ machine if optimized for 020+
519 #if _M68060 || _M68040 || _M68030 || _M68020 || __mc68020 || __mc68030 || __mc68040 || __mc68060
520 if(!(SysBase
->AttnFlags
& AFF_68020
))
524 #if defined(CLASS_STACKSWAP)
525 if ( !( stack
= AllocMem( sizeof( struct StackSwapStruct
) + 8192, MEMF_PUBLIC
| MEMF_CLEAR
) ) )
528 stack
->stk_Lower
= (APTR
)( (ULONG
)stack
+ sizeof( struct StackSwapStruct
) );
529 stack
->stk_Upper
= (ULONG
)( (ULONG
)stack
->stk_Lower
+ 8192 );
530 stack
->stk_Pointer
= (APTR
)stack
->stk_Upper
;
532 D(DBF_STARTUP
, "Before StackSwap()");
536 if((base
= (struct LibraryHeader
*)MakeLibrary((APTR
)LibVectors
,NULL
,NULL
,sizeof(struct LibraryHeader
),NULL
)))
538 D(DBF_STARTUP
, "After MakeLibrary()");
540 base
->lh_Library
.lib_Node
.ln_Type
= NT_LIBRARY
;
541 base
->lh_Library
.lib_Node
.ln_Name
= (char *)UserLibName
;
542 base
->lh_Library
.lib_Flags
= LIBF_CHANGED
| LIBF_SUMUSED
;
543 base
->lh_Library
.lib_Version
= VERSION
;
544 base
->lh_Library
.lib_Revision
= REVISION
;
545 base
->lh_Library
.lib_IdString
= (char *)UserLibID
;
547 base
->lh_Segment
= Segment
;
549 #if defined(USE_SEMAPHORE)
550 InitSemaphore(&base
->lh_Semaphore
);
553 #if defined(CLASS_STACKSWAP)
554 base
->lh_Stack
= stack
;
557 //if(UserLibInit((struct Library *)base))
559 D(DBF_STARTUP
, "AddLibrary()");
560 AddLibrary((struct Library
*)base
);
564 DeleteLibrary(&base->lh_Library)
571 D(DBF_STARTUP
, "\7MakeLibrary() failed");
574 #if defined(CLASS_STACKSWAP)
575 StackSwap(base
->lh_Stack
);
576 FreeMem(base
->lh_Stack
, sizeof(struct StackSwapStruct
) + 8192);
577 D(DBF_STARTUP
, "After second StackSwap()");
584 /*****************************************************************************************************/
585 /*****************************************************************************************************/
588 BPTR
LibExpunge(struct LibraryManagerInterface
*Self
)
590 struct LibraryHeader
*base
= (struct LibraryHeader
*)Self
->Data
.LibBase
;
592 BPTR
LibExpunge(void)
594 struct LibraryHeader
*base
= (void *)REG_A6
;
596 BPTR ASM SAVEDS
LibExpunge(REG(a6
, struct LibraryHeader
*base
))
601 D(DBF_STARTUP
, "OpenCount = %ld", base
->lh_Library
.lib_OpenCnt
);
603 if(base
->lh_Library
.lib_OpenCnt
> 0)
605 base
->lh_Library
.lib_Flags
|= LIBF_DELEXP
;
606 D(DBF_STARTUP
, "Setting LIBF_DELEXP");
611 if(!UserLibExpunge(&base->lh_Library))
613 D(DBF_STARTUP, "UserLibExpunge() failed, setting LIBF_DELEXP");
614 base->lh_Library.lib_Flags |= LIBF_DELEXP;
619 Remove((struct Node
*)base
);
620 rc
= base
->lh_Segment
;
622 DeleteLibrary(&base
->lh_Library
);
627 /*****************************************************************************************************/
628 /*****************************************************************************************************/
631 struct LibraryHeader
*LibOpen(struct LibraryManagerInterface
*Self
, UNUSED ULONG version
)
633 struct LibraryHeader
*base
= (struct LibraryHeader
*)Self
->Data
.LibBase
;
635 struct LibraryHeader
*LibOpen( void )
637 struct LibraryHeader
*base
= (void *)REG_A6
;
639 struct LibraryHeader
* ASM SAVEDS
LibOpen(REG(a6
, struct LibraryHeader
*base
))
642 struct LibraryHeader
*rc
;
644 /* Kill the Delayed Expunge flag since we are opened again */
645 base
->lh_Library
.lib_Flags
&= ~LIBF_DELEXP
;
648 ObtainSemaphore(&base
->lh_Semaphore
);
651 base
->lh_Library
.lib_OpenCnt
++;
653 D(DBF_STARTUP
, "OpenCount = %ld", base
->lh_Library
.lib_OpenCnt
);
655 if(UserLibOpen(&base
->lh_Library
))
657 #ifdef CLASS_VERSIONFAKE
658 base
->lh_Library
.lib_Version
= MUIMasterBase
->lib_Version
;
659 base
->lh_Library
.lib_Revision
= MUIMasterBase
->lib_Revision
;
667 base
->lh_Library
.lib_OpenCnt
--;
668 D(DBF_STARTUP
, "\7UserLibOpen() failed");
672 ReleaseSemaphore(&base
->lh_Semaphore
);
678 /*****************************************************************************************************/
679 /*****************************************************************************************************/
682 BPTR
LibClose(struct LibraryManagerInterface
*Self
)
684 struct LibraryHeader
*base
= (struct LibraryHeader
*)Self
->Data
.LibBase
;
688 struct LibraryHeader
*base
= (struct LibraryHeader
*)REG_A6
;
690 BPTR ASM SAVEDS
LibClose(REG(a6
, struct LibraryHeader
*base
))
696 ObtainSemaphore(&base
->lh_Semaphore
);
699 D(DBF_STARTUP
, "OpenCount = %ld %s", base
->lh_Library
.lib_OpenCnt
, base
->lh_Library
.lib_OpenCnt
== 0 ? "\7ERROR" : "");
701 UserLibClose((struct Library
*)base
);
703 base
->lh_Library
.lib_OpenCnt
--;
706 ReleaseSemaphore(&base
->lh_Semaphore
);
709 if(base
->lh_Library
.lib_OpenCnt
== 0 &&
710 base
->lh_Library
.lib_Flags
& LIBF_DELEXP
)
713 rc
= LibExpunge(Self
);
717 rc
= LibExpunge(base
);
724 /*****************************************************************************************************/
725 /*****************************************************************************************************/
728 DISPATCHERPROTO(_Dispatcher
);
732 DISPATCHERPROTO(_DispatcherP
);
735 BOOL
UserLibOpen(struct Library
*base
)
737 BOOL
PreClassInitFunc(void);
738 BOOL
ClassInitFunc(struct Library
*base
);
740 D(DBF_STARTUP
, "OpenCount = %ld", base
->lib_OpenCnt
);
742 if (base
->lib_OpenCnt
!=1)
745 #ifndef MASTERVERSION
746 #define MASTERVERSION MUIMASTER_VMIN
749 if((MUIMasterBase
= OpenLibrary(MUIMASTER_NAME
, MASTERVERSION
)) &&
750 GETINTERFACE(IMUIMaster
, MUIMasterBase
))
753 if (!PreClassInitFunc())
761 ThisClass
= MUI_CreateCustomClass(base
, SUPERCLASS
, NULL
, sizeof(struct INSTDATA
), ENTRY(_Dispatcher
));
766 if((ThisClassP
= MUI_CreateCustomClass(base
, SUPERCLASSP
, NULL
, sizeof(struct INSTDATAP
), ENTRY(_DispatcherP
))))
770 #define THISCLASS ThisClass
772 #define THISCLASS ThisClassP
775 UtilityBase
= (APTR
)THISCLASS
->mcc_UtilityBase
;
776 DOSBase
= (APTR
)THISCLASS
->mcc_DOSBase
;
777 GfxBase
= (APTR
)THISCLASS
->mcc_GfxBase
;
778 IntuitionBase
= (APTR
)THISCLASS
->mcc_IntuitionBase
;
780 #ifdef USE_UTILITYBASE
781 __UtilityBase
= (APTR
)UtilityBase
;
784 if(UtilityBase
&& DOSBase
&& GfxBase
&& IntuitionBase
&&
785 GETINTERFACE(IUtility
, UtilityBase
) &&
786 GETINTERFACE(IDOS
, DOSBase
) &&
787 GETINTERFACE(IGraphics
, GfxBase
) &&
788 GETINTERFACE(IIntuition
, IntuitionBase
))
797 if(ClassInitFunc(base
))
803 MUI_DeleteCustomClass(ThisClassP
);
809 DROPINTERFACE(IIntuition
);
810 DROPINTERFACE(IGraphics
);
812 DROPINTERFACE(IUtility
);
815 #if defined(SUPERCLASSP) && defined(SUPERCLASS)
816 MUI_DeleteCustomClass(ThisClass
);
821 DROPINTERFACE(IMUIMaster
);
822 CloseLibrary(MUIMasterBase
);
823 MUIMasterBase
= NULL
;
826 D(DBF_STARTUP
, "fail.: %08lx %s",base
,base
->lib_Node
.ln_Name
);
831 /*****************************************************************************************************/
832 /*****************************************************************************************************/
834 BOOL
UserLibClose(struct Library
*base
)
836 VOID
PostClassExitFunc(void);
837 VOID
ClassExitFunc(struct Library
*base
);
839 D(DBF_STARTUP
, "OpenCount = %ld", base
->lib_OpenCnt
);
841 if (base
->lib_OpenCnt
==1)
850 MUI_DeleteCustomClass(ThisClassP
);
858 MUI_DeleteCustomClass(ThisClass
);
867 DROPINTERFACE(IIntuition
);
868 DROPINTERFACE(IGraphics
);
870 DROPINTERFACE(IUtility
);
874 DROPINTERFACE(IMUIMaster
);
875 CloseLibrary(MUIMasterBase
);
876 MUIMasterBase
= NULL
;
883 /*****************************************************************************************************/
884 /*****************************************************************************************************/
886 #if defined(__amigaos4__)
887 ULONG LIBFUNC
MCC_Query(UNUSED
struct Interface
*self
, REG(d0
, LONG which
))
889 #elif defined(__MORPHOS__)
890 ULONG
MCC_Query(void)
892 LONG which
= (LONG
)REG_D0
;
894 ULONG LIBFUNC
MCC_Query(REG(d0
, LONG which
))
901 case 0: return((ULONG
)ThisClass
);
905 case 1: return((ULONG
)ThisClassP
);
908 #ifdef PREFSIMAGEOBJECT
911 Object
*obj
= PREFSIMAGEOBJECT
;
933 return((ULONG
)USEDCLASSES
);
940 return((ULONG
)USEDCLASSESP
);
947 return((ULONG
)SHORTHELP
);