Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / classes / zune / betterstring / includes / mccheader.c
blobe03147f438ebdd5bfd5d1426882be774a4ba4448
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
61 ClassInit
62 ClassExit
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
72 mui.h include file.
74 ---
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
92 PreClassInit
93 PostClassExit
94 ClassInit
95 ClassExit
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
108 is open then.
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
112 mui.h include file.
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
125 Example: Myclass.c
126 #define CLASS MUIC_Myclass // name of class, e.g. "Myclass.mcc"
127 #define SUPERCLASS MUIC_Area // name of superclass
128 struct Data
130 LONG MyData;
131 struct Foobar MyData2;
132 // ...
134 #define UserLibID "$VER: Myclass.mcc 17.53 (11.11.96)"
135 #define VERSION 17
136 #define REVISION 53
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) )
142 // ...
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 /******************************************************************************/
160 /* Includes */
161 /******************************************************************************/
163 /* MorphOS relevant includes... */
164 #ifdef __MORPHOS__
165 #include <emul/emulinterface.h>
166 #include <emul/emulregs.h>
167 #endif
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>
177 #include <dos/dos.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;
206 #else
207 struct Library *MUIMasterBase;
208 struct ExecBase *SysBase;
209 struct Library *UtilityBase;
210 struct DosLibrary *DOSBase;
211 struct GfxBase *GfxBase;
212 struct IntuitionBase *IntuitionBase;
213 #endif
215 #ifdef SUPERCLASS
216 static struct MUI_CustomClass *ThisClass;
217 #endif
219 #ifdef SUPERCLASSP
220 static struct MUI_CustomClass *ThisClassP;
221 #endif
223 #ifdef __GNUC__
224 #ifdef USE_UTILITYBASE
225 struct Library *__UtilityBase; // required by libnix & clib2
226 #endif
227 #ifdef __libnix__
228 /* these one are needed copies for libnix.a */
229 #ifdef USE_MATHIEEEDOUBBASBASE
230 struct Library *__MathIeeeDoubBasBase;
231 #endif
232 #ifdef USE_MATHIEEEDOUBTRANSBASE
233 struct Library *__MathIeeeDoubTransBase;
234 #endif
235 #endif
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 */
242 struct LibraryHeader
244 struct Library lh_Library;
245 UWORD lh_Pad1;
246 BPTR lh_Segment;
247 struct SignalSemaphore lh_Semaphore;
248 UWORD lh_Pad2;
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);
283 #else
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));
292 #endif
294 /******************************************************************************/
295 /* Dummy entry point and LibNull() function all in one */
296 /******************************************************************************/
298 #if defined(__amigaos4__)
299 int _start(void)
300 #else
301 int Main(void)
302 #endif
304 return RETURN_FAIL;
307 LONG LIBFUNC LibNull(VOID)
309 return(0);
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[] =
330 (APTR)LibObtain,
331 (APTR)LibRelease,
332 (APTR)NULL,
333 (APTR)NULL,
334 (APTR)LibOpen,
335 (APTR)LibClose,
336 (APTR)LibExpunge,
337 (APTR)NULL,
338 (APTR)-1
341 STATIC CONST struct TagItem LibManagerTags[] =
343 {MIT_Name, (ULONG)"__library"},
344 {MIT_VectorTable, (ULONG)LibManagerVectors},
345 {MIT_Version, 1},
346 {TAG_DONE, 0}
349 /* ------------------- Library Interface(s) ------------------------ */
351 STATIC CONST APTR LibVectors[] =
353 (APTR)LibObtain,
354 (APTR)LibRelease,
355 (APTR)NULL,
356 (APTR)NULL,
357 (APTR)MCC_Query,
358 (APTR)-1
361 STATIC CONST struct TagItem MainTags[] =
363 {MIT_Name, (ULONG)"main"},
364 {MIT_VectorTable, (ULONG)LibVectors},
365 {MIT_Version, 1},
366 {TAG_DONE, 0}
369 STATIC CONST ULONG LibInterfaces[] =
371 (ULONG)LibManagerTags,
372 (ULONG)MainTags,
373 (ULONG)0
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
378 // our binary here.
379 #ifndef NO_VECTABLE68K
380 extern const APTR VecTable68K[];
381 #endif
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},
390 #endif
391 {TAG_DONE, 0}
394 #else
396 static const APTR LibVectors[] =
398 #ifdef __MORPHOS__
399 (APTR)FUNCARRAY_32BIT_NATIVE,
400 #endif
401 (APTR)LibOpen,
402 (APTR)LibClose,
403 (APTR)LibExpunge,
404 (APTR)LibNull,
405 (APTR)MCC_Query,
406 (APTR)-1
409 #endif
411 /* ------------------- ROM Tag ------------------------ */
412 static const USED_VAR struct Resident ROMTag =
414 RTC_MATCHWORD,
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__)
420 RTF_PPC,
421 #else
423 #endif
424 VERSION,
425 NT_LIBRARY,
427 (char *)UserLibName,
428 (char *)UserLibID+6,
429 #if defined(__amigaos4__)
430 (APTR)LibCreateTags, // This table is for initializing the Library.
431 #else
432 (APTR)LibInit,
433 #endif
434 #if defined(__MORPHOS__)
435 REVISION,
437 #endif
440 #if defined(__MORPHOS__)
442 * To tell the loader that this is a new emulppc elf and not
443 * one for the ppc.library.
444 * ** IMPORTANT **
446 const USED_VAR ULONG __amigappc__ = 1;
447 const USED_VAR ULONG __abox__ = 1;
449 #undef USE_SEMAPHORE
451 #else
453 #ifndef USE_SEMAPHORE
454 #define USE_SEMAPHORE
455 #endif
457 #endif /* __MORPHOS */
459 #ifndef __amigaos4__
460 #define DeleteLibrary(LIB) \
461 FreeMem((STRPTR)(LIB)-(LIB)->lib_NegSize, (ULONG)((LIB)->lib_NegSize+(LIB)->lib_PosSize))
462 #endif
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;
472 IExec = pIExec;
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);
493 return(NULL);
497 return(base);
500 #else
502 #ifdef __MORPHOS__
503 #undef CLASS_STACKSWAP
504 struct LibraryHeader *LibInit(struct LibraryHeader *base, BPTR Segment, struct ExecBase *sb)
506 #else
507 struct LibraryHeader * ASM SAVEDS LibInit(REG(a0, BPTR Segment), REG(a6, struct ExecBase *sb))
509 #endif
511 #if defined(CLASS_STACKSWAP)
512 static struct StackSwapStruct *stack;
513 #endif
514 #if !defined(__MORPHOS__)
515 struct LibraryHeader *base;
516 #endif
518 SysBase = sb;
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))
525 return(NULL);
526 #endif
528 #if defined(CLASS_STACKSWAP)
529 if ( !( stack = AllocMem( sizeof( struct StackSwapStruct ) + 8192, MEMF_PUBLIC | MEMF_CLEAR ) ) )
530 return( NULL );
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" ) );
537 StackSwap( stack );
538 #endif
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);
555 #endif
557 #if defined(CLASS_STACKSWAP)
558 base->lh_Stack = stack;
559 #endif
561 //if(UserLibInit((struct Library *)base))
563 D(bug( "AddLibrary()\n") );
564 AddLibrary((struct Library *)base);
566 /*else
568 DeleteLibrary(&base->lh_Library)
569 base = NULL;
573 else
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" ) );
582 #endif
584 return(base);
586 #endif
588 /*****************************************************************************************************/
589 /*****************************************************************************************************/
591 #ifdef __amigaos4__
592 BPTR LibExpunge(struct LibraryManagerInterface *Self)
594 struct LibraryHeader *base = (struct LibraryHeader *)Self->Data.LibBase;
595 #elif __MORPHOS__
596 BPTR LibExpunge(void)
598 struct LibraryHeader *base = (void *)REG_A6;
599 #else
600 BPTR ASM SAVEDS LibExpunge(REG(a6, struct LibraryHeader *base))
602 #endif
603 BPTR rc;
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") );
611 return(0);
615 if(!UserLibExpunge(&base->lh_Library))
617 D(bug("UserLibExpunge() failed, setting LIBF_DELEXP\n"));
618 base->lh_Library.lib_Flags |= LIBF_DELEXP;
619 return(0);
623 Remove((struct Node *)base);
624 rc = base->lh_Segment;
626 DeleteLibrary(&base->lh_Library);
628 return(rc);
631 /*****************************************************************************************************/
632 /*****************************************************************************************************/
634 #ifdef __amigaos4__
635 struct LibraryHeader *LibOpen(struct LibraryManagerInterface *Self, UNUSED ULONG version)
637 struct LibraryHeader *base = (struct LibraryHeader *)Self->Data.LibBase;
638 #elif __MORPHOS__
639 struct LibraryHeader *LibOpen( void )
641 struct LibraryHeader *base = (void *)REG_A6;
642 #else
643 struct LibraryHeader * ASM SAVEDS LibOpen(REG(a6, struct LibraryHeader *base))
645 #endif
646 struct LibraryHeader *rc;
648 /* Kill the Delayed Expunge flag since we are opened again */
649 base->lh_Library.lib_Flags &= ~LIBF_DELEXP;
651 #ifdef USE_SEMAPHORE
652 ObtainSemaphore(&base->lh_Semaphore);
653 #endif
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;
664 #endif
666 rc = base;
668 else
670 rc = NULL;
671 base->lh_Library.lib_OpenCnt--;
672 D(bug("\7UserLibOpen() failed\n") );
675 #ifdef USE_SEMAPHORE
676 ReleaseSemaphore(&base->lh_Semaphore);
677 #endif
679 return(rc);
682 /*****************************************************************************************************/
683 /*****************************************************************************************************/
685 #ifdef __amigaos4__
686 BPTR LibClose(struct LibraryManagerInterface *Self)
688 struct LibraryHeader *base = (struct LibraryHeader *)Self->Data.LibBase;
689 #elif __MORPHOS__
690 BPTR LibClose(void)
692 struct LibraryHeader *base = (struct LibraryHeader *)REG_A6;
693 #else
694 BPTR ASM SAVEDS LibClose(REG(a6, struct LibraryHeader *base))
696 #endif
697 BPTR rc = 0;
699 #ifdef USE_SEMAPHORE
700 ObtainSemaphore(&base->lh_Semaphore);
701 #endif
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--;
709 #ifdef USE_SEMAPHORE
710 ReleaseSemaphore(&base->lh_Semaphore);
711 #endif
713 if(base->lh_Library.lib_OpenCnt == 0 &&
714 base->lh_Library.lib_Flags & LIBF_DELEXP)
716 #ifdef __amigaos4__
717 rc = LibExpunge(Self);
718 #elif __MORPHOS__
719 rc = LibExpunge();
720 #else
721 rc = LibExpunge(base);
722 #endif
725 return(rc);
728 /*****************************************************************************************************/
729 /*****************************************************************************************************/
731 #ifdef SUPERCLASS
732 DISPATCHERPROTO(_Dispatcher);
733 #endif
735 #ifdef SUPERCLASSP
736 DISPATCHERPROTO(_DispatcherP);
737 #endif
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)
747 return(TRUE);
749 #ifndef MASTERVERSION
750 #define MASTERVERSION MUIMASTER_VMIN
751 #endif
753 if((MUIMasterBase = OpenLibrary("muimaster.library", MASTERVERSION)) &&
754 GETINTERFACE(IMUIMaster, MUIMasterBase))
756 #ifdef PreClassInit
757 if (!PreClassInitFunc())
759 return FALSE;
761 #endif
764 #ifdef SUPERCLASS
765 ThisClass = MUI_CreateCustomClass(base, SUPERCLASS, NULL, sizeof(struct INSTDATA), ENTRY(_Dispatcher));
766 if(ThisClass)
767 #endif
769 #ifdef SUPERCLASSP
770 if((ThisClassP = MUI_CreateCustomClass(base, SUPERCLASSP, NULL, sizeof(struct INSTDATAP), ENTRY(_DispatcherP))))
771 #endif
773 #ifdef SUPERCLASS
774 #define THISCLASS ThisClass
775 #else
776 #define THISCLASS ThisClassP
777 #endif
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;
786 #endif
788 if(UtilityBase && DOSBase && GfxBase && IntuitionBase &&
789 GETINTERFACE(IUtility, UtilityBase) &&
790 GETINTERFACE(IDOS, DOSBase) &&
791 GETINTERFACE(IGraphics, GfxBase) &&
792 GETINTERFACE(IIntuition, IntuitionBase))
794 #ifndef ClassInit
795 return(TRUE);
796 #else
797 if(ClassInitFunc(base))
799 return(TRUE);
802 #ifdef SUPERCLASSP
803 MUI_DeleteCustomClass(ThisClassP);
804 ThisClassP = NULL;
805 #endif
806 #endif
809 DROPINTERFACE(IIntuition);
810 DROPINTERFACE(IGraphics);
811 DROPINTERFACE(IDOS);
812 DROPINTERFACE(IUtility);
815 #if defined(SUPERCLASSP) && defined(SUPERCLASS)
816 MUI_DeleteCustomClass(ThisClass);
817 ThisClass = NULL;
818 #endif
821 DROPINTERFACE(IMUIMaster);
822 CloseLibrary(MUIMasterBase);
823 MUIMasterBase = NULL;
826 D(bug("fail.: %08lx %s\n",base,base->lib_Node.ln_Name) );
828 return(FALSE);
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)
843 #ifdef ClassExit
844 ClassExitFunc(base);
845 #endif
847 #ifdef SUPERCLASSP
848 if (ThisClassP)
850 MUI_DeleteCustomClass(ThisClassP);
851 ThisClassP = NULL;
853 #endif
855 #ifdef SUPERCLASS
856 if (ThisClass)
858 MUI_DeleteCustomClass(ThisClass);
859 ThisClass = NULL;
861 #endif
863 #ifdef PostClassExit
864 PostClassExitFunc();
865 #endif
867 DROPINTERFACE(IIntuition);
868 DROPINTERFACE(IGraphics);
869 DROPINTERFACE(IDOS);
870 DROPINTERFACE(IUtility);
872 if (MUIMasterBase)
874 DROPINTERFACE(IMUIMaster);
875 CloseLibrary(MUIMasterBase);
876 MUIMasterBase = NULL;
880 return(TRUE);
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;
893 #else
894 ULONG LIBFUNC MCC_Query(REG(d0, LONG which))
896 #endif
898 switch (which)
900 #ifdef SUPERCLASS
901 case 0: return((ULONG)ThisClass);
902 #endif
904 #ifdef SUPERCLASSP
905 case 1: return((ULONG)ThisClassP);
906 #endif
908 #ifdef PREFSIMAGEOBJECT
909 case 2:
911 Object *obj = PREFSIMAGEOBJECT;
912 return((ULONG)obj);
914 #endif
916 #ifdef ONLYGLOBAL
917 case 3:
919 return(TRUE);
921 #endif
923 #ifdef INFOCLASS
924 case 4:
926 return(TRUE);
928 #endif
930 #ifdef USEDCLASSES
931 case 5:
933 return((ULONG)USEDCLASSES);
935 #endif
937 #ifdef USEDCLASSESP
938 case 6:
940 return((ULONG)USEDCLASSESP);
942 #endif
944 #ifdef SHORTHELP
945 case 7:
947 return((ULONG)SHORTHELP);
949 #endif
952 return(0);