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
;
195 struct Library
*SysBase
;
196 struct Library
*UtilityBase
;
197 struct Library
*DOSBase
;
198 struct Library
*GfxBase
;
199 struct Library
*IntuitionBase
;
200 struct MUIMasterIFace
*IMUIMaster
;
201 struct ExecIFace
*IExec
;
202 struct UtilityIFace
*IUtility
;
203 struct DOSIFace
*IDOS
;
204 struct GraphicsIFace
*IGraphics
;
205 struct IntuitionIFace
*IIntuition
;
207 struct Library
*MUIMasterBase
;
208 struct ExecBase
*SysBase
;
209 struct Library
*UtilityBase
;
210 struct DosLibrary
*DOSBase
;
211 struct GfxBase
*GfxBase
;
212 struct IntuitionBase
*IntuitionBase
;
216 static struct MUI_CustomClass
*ThisClass
;
220 static struct MUI_CustomClass
*ThisClassP
;
224 #ifdef USE_UTILITYBASE
225 struct Library
*__UtilityBase
; // required by libnix & clib2
228 /* these one are needed copies for libnix.a */
229 #ifdef USE_MATHIEEEDOUBBASBASE
230 struct Library
*__MathIeeeDoubBasBase
;
232 #ifdef USE_MATHIEEEDOUBTRANSBASE
233 struct Library
*__MathIeeeDoubTransBase
;
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 /******************************************************************************/
298 #if defined(__amigaos4__)
307 LONG LIBFUNC
LibNull(VOID
)
312 /******************************************************************************/
313 /* Local data structures */
314 /******************************************************************************/
316 #if defined(__amigaos4__)
317 /* ------------------- OS4 Manager Interface ------------------------ */
318 STATIC ULONG
LibObtain(struct LibraryManagerInterface
*Self
)
320 return(Self
->Data
.RefCount
++);
323 STATIC ULONG
LibRelease(struct LibraryManagerInterface
*Self
)
325 return(Self
->Data
.RefCount
--);
328 STATIC CONST APTR LibManagerVectors
[] =
341 STATIC CONST
struct TagItem LibManagerTags
[] =
343 {MIT_Name
, (ULONG
)"__library"},
344 {MIT_VectorTable
, (ULONG
)LibManagerVectors
},
349 /* ------------------- Library Interface(s) ------------------------ */
351 STATIC CONST APTR LibVectors
[] =
361 STATIC CONST
struct TagItem MainTags
[] =
363 {MIT_Name
, (ULONG
)"main"},
364 {MIT_VectorTable
, (ULONG
)LibVectors
},
369 STATIC CONST ULONG LibInterfaces
[] =
371 (ULONG
)LibManagerTags
,
376 // Out libraries always have to carry a 68k jump table with it, so
377 // lets define it here as extern, as we are going to link it to
379 #ifndef NO_VECTABLE68K
380 extern const APTR VecTable68K
[];
383 STATIC CONST
struct TagItem LibCreateTags
[] =
385 {CLT_DataSize
, (ULONG
)(sizeof(struct LibraryHeader
))},
386 {CLT_InitFunc
, (ULONG
)LibInit
},
387 {CLT_Interfaces
, (ULONG
)LibInterfaces
},
388 #ifndef NO_VECTABLE68K
389 {CLT_Vector68K
, (ULONG
)VecTable68K
},
396 static const APTR LibVectors
[] =
399 (APTR
)FUNCARRAY_32BIT_NATIVE
,
411 /* ------------------- ROM Tag ------------------------ */
412 static const USED_VAR
struct Resident ROMTag
=
415 (struct Resident
*)&ROMTag
,
416 (struct Resident
*)&ROMTag
+ 1,
417 #if defined(__amigaos4__)
418 RTF_AUTOINIT
|RTF_NATIVE
, // The Library should be set up according to the given table.
419 #elif defined(__MORPHOS__)
429 #if defined(__amigaos4__)
430 (APTR
)LibCreateTags
, // This table is for initializing the Library.
434 #if defined(__MORPHOS__)
440 #if defined(__MORPHOS__)
442 * To tell the loader that this is a new emulppc elf and not
443 * one for the ppc.library.
446 const USED_VAR ULONG __amigappc__
= 1;
447 const USED_VAR ULONG __abox__
= 1;
453 #ifndef USE_SEMAPHORE
454 #define USE_SEMAPHORE
457 #endif /* __MORPHOS */
460 #define DeleteLibrary(LIB) \
461 FreeMem((STRPTR)(LIB)-(LIB)->lib_NegSize, (ULONG)((LIB)->lib_NegSize+(LIB)->lib_PosSize))
464 /******************************************************************************/
465 /* Standard Library Functions, all of them are called in Forbid() state. */
466 /******************************************************************************/
468 #if defined(__amigaos4__)
469 struct LibraryHeader
* ASM SAVEDS
LibInit(struct LibraryHeader
*base
, BPTR librarySegment
, struct ExecIFace
*pIExec
)
471 struct ExecBase
*sb
= (struct ExecBase
*)pIExec
->Data
.LibBase
;
473 SysBase
= (struct Library
*)sb
;
475 D(bug("start... (segment=%08lx)\n",librarySegment
));
477 base
->lh_Library
.lib_Node
.ln_Type
= NT_LIBRARY
;
478 base
->lh_Library
.lib_Node
.ln_Pri
= 0;
479 base
->lh_Library
.lib_Node
.ln_Name
= (char *)UserLibName
;
480 base
->lh_Library
.lib_Flags
= LIBF_CHANGED
| LIBF_SUMUSED
;
481 base
->lh_Library
.lib_Version
= VERSION
;
482 base
->lh_Library
.lib_Revision
= REVISION
;
483 base
->lh_Library
.lib_IdString
= (char *)UserLibID
;
485 base
->lh_Segment
= librarySegment
;
487 InitSemaphore(&base
->lh_Semaphore
);
490 if(!UserLibInit((struct Library *)base))
492 DeleteLibrary((struct Library *)base);
503 #undef CLASS_STACKSWAP
504 struct LibraryHeader
*LibInit(struct LibraryHeader
*base
, BPTR Segment
, struct ExecBase
*sb
)
507 struct LibraryHeader
* ASM SAVEDS
LibInit(REG(a0
, BPTR Segment
), REG(a6
, struct ExecBase
*sb
))
511 #if defined(CLASS_STACKSWAP)
512 static struct StackSwapStruct
*stack
;
514 #if !defined(__MORPHOS__)
515 struct LibraryHeader
*base
;
520 D(bug( "Start...\n" ) );
522 // make sure that this is really a 68020+ machine if optimized for 020+
523 #if _M68060 || _M68040 || _M68030 || _M68020 || __mc68020 || __mc68030 || __mc68040 || __mc68060
524 if(!(SysBase
->AttnFlags
& AFF_68020
))
528 #if defined(CLASS_STACKSWAP)
529 if ( !( stack
= AllocMem( sizeof( struct StackSwapStruct
) + 8192, MEMF_PUBLIC
| MEMF_CLEAR
) ) )
532 stack
->stk_Lower
= (APTR
)( (ULONG
)stack
+ sizeof( struct StackSwapStruct
) );
533 stack
->stk_Upper
= (ULONG
)( (ULONG
)stack
->stk_Lower
+ 8192 );
534 stack
->stk_Pointer
= (APTR
)stack
->stk_Upper
;
536 D(bug( "Before StackSwap()\n" ) );
540 if((base
= (struct LibraryHeader
*)MakeLibrary((APTR
)LibVectors
,NULL
,NULL
,sizeof(struct LibraryHeader
),NULL
)))
542 D(bug( "After MakeLibrary()\n" ) );
544 base
->lh_Library
.lib_Node
.ln_Type
= NT_LIBRARY
;
545 base
->lh_Library
.lib_Node
.ln_Name
= (char *)UserLibName
;
546 base
->lh_Library
.lib_Flags
= LIBF_CHANGED
| LIBF_SUMUSED
;
547 base
->lh_Library
.lib_Version
= VERSION
;
548 base
->lh_Library
.lib_Revision
= REVISION
;
549 base
->lh_Library
.lib_IdString
= (char *)UserLibID
;
551 base
->lh_Segment
= Segment
;
553 #if defined(USE_SEMAPHORE)
554 InitSemaphore(&base
->lh_Semaphore
);
557 #if defined(CLASS_STACKSWAP)
558 base
->lh_Stack
= stack
;
561 //if(UserLibInit((struct Library *)base))
563 D(bug( "AddLibrary()\n") );
564 AddLibrary((struct Library
*)base
);
568 DeleteLibrary(&base->lh_Library)
575 D(bug("\7MakeLibrary() failed\n") );
578 #if defined(CLASS_STACKSWAP)
579 StackSwap(base
->lh_Stack
);
580 FreeMem(base
->lh_Stack
, sizeof(struct StackSwapStruct
) + 8192);
581 D(bug( "After second StackSwap()\n" ) );
588 /*****************************************************************************************************/
589 /*****************************************************************************************************/
592 BPTR
LibExpunge(struct LibraryManagerInterface
*Self
)
594 struct LibraryHeader
*base
= (struct LibraryHeader
*)Self
->Data
.LibBase
;
596 BPTR
LibExpunge(void)
598 struct LibraryHeader
*base
= (void *)REG_A6
;
600 BPTR ASM SAVEDS
LibExpunge(REG(a6
, struct LibraryHeader
*base
))
605 D(bug( "OpenCount = %ld\n", base
->lh_Library
.lib_OpenCnt
) );
607 if(base
->lh_Library
.lib_OpenCnt
> 0)
609 base
->lh_Library
.lib_Flags
|= LIBF_DELEXP
;
610 D(bug("Setting LIBF_DELEXP\n") );
615 if(!UserLibExpunge(&base->lh_Library))
617 D(bug("UserLibExpunge() failed, setting LIBF_DELEXP\n"));
618 base->lh_Library.lib_Flags |= LIBF_DELEXP;
623 Remove((struct Node
*)base
);
624 rc
= base
->lh_Segment
;
626 DeleteLibrary(&base
->lh_Library
);
631 /*****************************************************************************************************/
632 /*****************************************************************************************************/
635 struct LibraryHeader
*LibOpen(struct LibraryManagerInterface
*Self
, UNUSED ULONG version
)
637 struct LibraryHeader
*base
= (struct LibraryHeader
*)Self
->Data
.LibBase
;
639 struct LibraryHeader
*LibOpen( void )
641 struct LibraryHeader
*base
= (void *)REG_A6
;
643 struct LibraryHeader
* ASM SAVEDS
LibOpen(REG(a6
, struct LibraryHeader
*base
))
646 struct LibraryHeader
*rc
;
648 /* Kill the Delayed Expunge flag since we are opened again */
649 base
->lh_Library
.lib_Flags
&= ~LIBF_DELEXP
;
652 ObtainSemaphore(&base
->lh_Semaphore
);
655 base
->lh_Library
.lib_OpenCnt
++;
657 D(bug( "OpenCount = %ld\n", base
->lh_Library
.lib_OpenCnt
) );
659 if(UserLibOpen(&base
->lh_Library
))
661 #ifdef CLASS_VERSIONFAKE
662 base
->lh_Library
.lib_Version
= MUIMasterBase
->lib_Version
;
663 base
->lh_Library
.lib_Revision
= MUIMasterBase
->lib_Revision
;
671 base
->lh_Library
.lib_OpenCnt
--;
672 D(bug("\7UserLibOpen() failed\n") );
676 ReleaseSemaphore(&base
->lh_Semaphore
);
682 /*****************************************************************************************************/
683 /*****************************************************************************************************/
686 BPTR
LibClose(struct LibraryManagerInterface
*Self
)
688 struct LibraryHeader
*base
= (struct LibraryHeader
*)Self
->Data
.LibBase
;
692 struct LibraryHeader
*base
= (struct LibraryHeader
*)REG_A6
;
694 BPTR ASM SAVEDS
LibClose(REG(a6
, struct LibraryHeader
*base
))
700 ObtainSemaphore(&base
->lh_Semaphore
);
703 D(bug( "OpenCount = %ld %s\n", base
->lh_Library
.lib_OpenCnt
, base
->lh_Library
.lib_OpenCnt
== 0 ? "\7ERROR" : "" ) );
705 UserLibClose((struct Library
*)base
);
707 base
->lh_Library
.lib_OpenCnt
--;
710 ReleaseSemaphore(&base
->lh_Semaphore
);
713 if(base
->lh_Library
.lib_OpenCnt
== 0 &&
714 base
->lh_Library
.lib_Flags
& LIBF_DELEXP
)
717 rc
= LibExpunge(Self
);
721 rc
= LibExpunge(base
);
728 /*****************************************************************************************************/
729 /*****************************************************************************************************/
732 DISPATCHERPROTO(_Dispatcher
);
736 DISPATCHERPROTO(_DispatcherP
);
739 BOOL
UserLibOpen(struct Library
*base
)
741 BOOL
PreClassInitFunc(void);
742 BOOL
ClassInitFunc(struct Library
*base
);
744 D(bug( "OpenCount = %ld\n", base
->lib_OpenCnt
) );
746 if (base
->lib_OpenCnt
!=1)
749 #ifndef MASTERVERSION
750 #define MASTERVERSION MUIMASTER_VMIN
753 if((MUIMasterBase
= OpenLibrary("muimaster.library", MASTERVERSION
)) &&
754 GETINTERFACE(IMUIMaster
, MUIMasterBase
))
757 if (!PreClassInitFunc())
765 ThisClass
= MUI_CreateCustomClass(base
, SUPERCLASS
, NULL
, sizeof(struct INSTDATA
), ENTRY(_Dispatcher
));
770 if((ThisClassP
= MUI_CreateCustomClass(base
, SUPERCLASSP
, NULL
, sizeof(struct INSTDATAP
), ENTRY(_DispatcherP
))))
774 #define THISCLASS ThisClass
776 #define THISCLASS ThisClassP
779 UtilityBase
= (APTR
)THISCLASS
->mcc_UtilityBase
;
780 DOSBase
= (APTR
)THISCLASS
->mcc_DOSBase
;
781 GfxBase
= (APTR
)THISCLASS
->mcc_GfxBase
;
782 IntuitionBase
= (APTR
)THISCLASS
->mcc_IntuitionBase
;
784 #ifdef USE_UTILITYBASE
785 __UtilityBase
= (APTR
)UtilityBase
;
788 if(UtilityBase
&& DOSBase
&& GfxBase
&& IntuitionBase
&&
789 GETINTERFACE(IUtility
, UtilityBase
) &&
790 GETINTERFACE(IDOS
, DOSBase
) &&
791 GETINTERFACE(IGraphics
, GfxBase
) &&
792 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(bug("fail.: %08lx %s\n",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(bug( "OpenCount = %ld\n", 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
);