;/* sc resopt opt opttime strmer nostkchk nostartup data=fo parm=r link noicons selib.c to solidexample.library ;ppc-morphos-gcc -noixemul -nostartfiles -Wall -O2 selib.c -labox -o solidexample.library quit */ /* Written by Harry Sintonen * Public Domain. */ #define USE_INLINE_STDARG 1 #define __USE_SYSBASE 1 #include #include #include #include #include #include #if defined(__GNUC__) && __GNUC__ > 2 #define __USED__ __attribute__ ((__used__)) #else #define __USED__ #endif struct MyBase { struct Library lib_lib; BPTR lib_seglist; struct ExecBase *lib_SysBase; struct SignalSemaphore lib_listsema; struct MinList lib_list; }; #define SysBase LibBase->lib_SysBase #ifdef __MORPHOS__ static struct Library *initfunc(struct MyBase *, BPTR, struct ExecBase *); static struct Library *lib_open(void); static BPTR lib_close(void); static BPTR lib_expunge(void); static LONG lib_dummy(void); static APTR lib_createnotify(void); static void lib_deletenotify(void); static void lib_donotify(void); #elif defined(__SASC) static struct Library * __asm initfunc(register __d0 struct MyBase *, register __a0 BPTR, register __a6 struct ExecBase *); static struct Library * __asm lib_open(register __a6 APTR); static BPTR __asm lib_close(register __a6 APTR); static BPTR __asm lib_expunge(register __a6 APTR); static LONG __asm lib_dummy(void); static APTR __asm lib_createnotify(register __a0 APTR, register __a6 APTR); static void __asm lib_deletenotify(register __a0 APTR, register __a6 APTR); static void __asm lib_donotify(register __d0 ULONG, register __a6 APTR); #endif static const CONST_APTR functable[] = { #ifdef __MORPHOS__ (APTR) FUNCARRAY_32BIT_NATIVE, #endif (APTR) lib_open, (APTR) lib_close, (APTR) lib_expunge, (APTR) lib_dummy, (APTR) lib_createnotify, (APTR) lib_deletenotify, (APTR) lib_donotify, (APTR) ~0, }; static const struct { ULONG possize; CONST_APTR functable; CONST_APTR initdata; CONST_APTR initfunc; } init = { sizeof(struct MyBase), functable, NULL, initfunc }; static const UBYTE vertag[] = "$VER: solidexample.library 1.0 (07.08.2008)"; const struct Resident resident __USED__ = { RTC_MATCHWORD, (struct Resident *) &resident, (struct Resident *) (&resident + 1), #ifdef __MORPHOS__ RTF_PPC | #endif RTF_AUTOINIT, 1, NT_LIBRARY, 0, "solidexample.library", (STRPTR) &vertag[6], (APTR) &init }; #ifdef __MORPHOS__ const int __abox__ __USED__ = 1; #endif LONG dummy(void) { return -1; } #ifdef __MORPHOS__ static struct Library *initfunc(struct MyBase *LibBase, BPTR SegList, struct ExecBase *sysBase) #elif defined(__SASC) static struct Library * __asm initfunc(register __d0 struct MyBase *LibBase, register __a0 BPTR SegList, register __a6 struct ExecBase *sysBase) #endif { SysBase = sysBase; LibBase->lib_lib.lib_Revision = 0; LibBase->lib_seglist = SegList; InitSemaphore(&LibBase->lib_listsema); NewList((struct List *) &LibBase->lib_list); return &LibBase->lib_lib; } static struct Library *open(struct MyBase *LibBase) { LibBase->lib_lib.lib_Flags &= ~LIBF_DELEXP; LibBase->lib_lib.lib_OpenCnt++; return &LibBase->lib_lib; } static BPTR expunge(struct MyBase *LibBase); static BPTR close(struct MyBase *LibBase) { BPTR seglist = 0; if (--LibBase->lib_lib.lib_OpenCnt == 0 && (LibBase->lib_lib.lib_Flags & LIBF_DELEXP)) { seglist = expunge(LibBase); } return seglist; } static BPTR expunge(struct MyBase *LibBase) { #undef SysBase struct ExecBase *SysBase = LibBase->lib_SysBase; BPTR seglist = 0; if (!LibBase->lib_lib.lib_OpenCnt) { Remove(&LibBase->lib_lib.lib_Node); seglist = LibBase->lib_seglist; FreeMem((UBYTE *) LibBase - LibBase->lib_lib.lib_NegSize, LibBase->lib_lib.lib_NegSize + LibBase->lib_lib.lib_PosSize); } else { LibBase->lib_lib.lib_Flags |= LIBF_DELEXP; } return seglist; #define SysBase LibBase->lib_SysBase } struct notify { struct MinNode node; ULONG foo; ULONG bar; ULONG bleh; }; static APTR createnotify(struct MyBase *LibBase, struct TagItem *taglist) { struct notify *notify; notify = AllocMem(sizeof(*notify), MEMF_ANY); if (notify) { notify->foo = 1; notify->bar = 2; notify->bleh = 3; ObtainSemaphore(&LibBase->lib_listsema); AddTail((struct List *) &LibBase->lib_list, (struct Node *) ¬ify->node); ReleaseSemaphore(&LibBase->lib_listsema); } return notify; } static void deletenotify(struct MyBase *LibBase, struct notify *notify) { if (notify) { ObtainSemaphore(&LibBase->lib_listsema); Remove((struct Node *) ¬ify->node); ReleaseSemaphore(&LibBase->lib_listsema); FreeMem(notify, sizeof(*notify)); } } static void donotify(struct MyBase *LibBase, ULONG value) { struct notify *notify; ObtainSemaphoreShared(&LibBase->lib_listsema); for (notify = (APTR) LibBase->lib_list.mlh_Head; notify->node.mln_Succ; notify = (APTR) notify->node.mln_Succ) { if (notify->foo == value) { notify->bar++; notify->bleh--; } } ReleaseSemaphore(&LibBase->lib_listsema); } #ifdef __MORPHOS__ static struct Library *lib_open(void) { struct MyBase *LibBase = (APTR) REG_A6; return open(LibBase); } static BPTR lib_close(void) { struct MyBase *LibBase = (APTR) REG_A6; return close(LibBase); } static BPTR lib_expunge(void) { struct MyBase *LibBase = (APTR) REG_A6; return expunge(LibBase); } static LONG lib_dummy(void) { return 0; } static APTR lib_createnotify(void) { struct MyBase *LibBase = (APTR) REG_A6; APTR arg1 = (APTR) REG_A0; return createnotify(LibBase, arg1); } static void lib_deletenotify(void) { struct MyBase *LibBase = (APTR) REG_A6; APTR arg1 = (APTR) REG_A0; deletenotify(LibBase, arg1); } static void lib_donotify(void) { struct MyBase *LibBase = (APTR) REG_A6; ULONG arg1 = (ULONG) REG_D0; donotify(LibBase, arg1); } #elif defined(__SASC) static struct Library * __asm lib_open(register __a6 APTR base) { return open(base); } static BPTR __asm lib_close(register __a6 APTR base) { return close(base); } static BPTR __asm lib_expunge(register __a6 APTR base) { return expunge(base); } static LONG __asm lib_dummy(void) { return 0; } static APTR __asm lib_createnotify(register __a0 APTR arg1, register __a6 APTR base) { return createnotify(base, arg1); } static void __asm lib_deletenotify(register __a0 APTR arg1, register __a6 APTR base) { deletenotify(base, arg1); } static void __asm lib_donotify(register __d0 ULONG arg1, register __a6 APTR base) { donotify(base, arg1); } #endif