#include "sysinc.h" #include "mgl/gl.h" #include "mgl/glutcontext.h" #include #include "mglut.library_rev.h" #include "interfaces/glut.h" #include #include "glut_internal.h" #include "glut_vectors.c" struct Library *MiniGLBase; struct MiniGLIFace *IMiniGL; struct Library *IntuitionBase; struct IntuitionIFace *IIntuition; struct ExecIFace *IExec; struct DOSIFace *IDOS; static struct Device *__TimerBase; struct TimerIFace *__ITimer; static struct Library *__KeymapBase; struct KeymapIFace *__IKeymap; struct Interface *INewlib; APTR segList = 0; struct Library * libOpen(struct LibraryManagerInterface *Self, ULONG version) { struct Library *libBase = Self->Data.LibBase; dprintf("In libOpen\n"); /* Add up the open count */ libBase->lib_OpenCnt++; /* Clear pending expunge */ libBase->lib_Flags &= ~LIBF_DELEXP; return libBase; } APTR libExpunge(struct LibraryManagerInterface *Self) { struct Library *libBase = Self->Data.LibBase; /* Check if we're still open */ if (libBase->lib_OpenCnt) { /* We are, delay the expunge */ libBase->lib_Flags |= LIBF_DELEXP; return 0; } if (IMiniGL) { IExec->DropInterface((struct Interface *)IMiniGL); IMiniGL = 0; } if (MiniGLBase) { IExec->CloseLibrary(MiniGLBase); MiniGLBase = 0; } if (IIntuition) { IExec->DropInterface((struct Interface *)IIntuition); IIntuition = 0; } if (IntuitionBase) { IExec->CloseLibrary(IntuitionBase); IntuitionBase = 0; } if (__ITimer) { IExec->DropInterface((struct Interface *)__ITimer); __ITimer = 0; } if(__IKeymap) { IExec->DropInterface((struct Interface *)__IKeymap); __IKeymap = NULL; } if(__KeymapBase) { IExec->CloseLibrary(__KeymapBase); __KeymapBase = NULL; } if(INewlib) { struct Library *newlibBase = INewlib->Data.LibBase; IExec->DropInterface(INewlib); IExec->CloseLibrary(newlibBase); INewlib = 0; } /* No one uses us, so really expunge. Start by removing us from the library list */ IExec->Remove((struct Node *)libBase); /* Delete ourselves */ IExec->DeleteLibrary(libBase); IExec->Release(); /* Finally, return the handle so whoever loaded us into memory can get rid of us */ return segList; } APTR libClose(struct LibraryManagerInterface *Self) { struct Library *libBase = Self->Data.LibBase; /* Make the close count */ libBase->lib_OpenCnt--; /* If we're still open, do nothing */ if (libBase->lib_OpenCnt > 0) return 0; /* Otherwise, if an expunge is pending, execute it now */ if (libBase->lib_Flags & LIBF_DELEXP) { return libExpunge(Self); } return 0; } struct Library * libInit(struct Library *libBase, APTR seglist, struct Interface *exec) { struct ExecLibrary *SysBase; struct Library *DOSBase; struct Library *newlibBase; /* Initialize the library base */ dprintf("Initializing library base %p, IExec = %p\n", libBase, exec); libBase->lib_Revision = (int)REVISION; segList = seglist; IExec = (struct ExecIFace *)exec; SysBase = (struct ExecLibrary *)IExec->Data.LibBase; DOSBase = IExec->OpenLibrary("dos.library", 0); IDOS = (struct DOSIFace *)IExec->GetInterface(DOSBase, "main", 1, NULL); newlibBase = IExec->OpenLibrary("newlib.library", 52); if (!newlibBase) { IExec->Alert(AT_Recovery | AG_OpenLib);// ##### FIXME! ##### | AO_NewlibLib ); return NULL; } INewlib = IExec->GetInterface(newlibBase, "main", 1, NULL); if (!INewlib) { IExec->CloseLibrary(newlibBase); IExec->Alert(AT_Recovery | AG_OpenLib);// ##### FIXME! ##### | AO_NewlibLib ); return NULL; } MiniGLBase = IExec->OpenLibrary("minigl.library", MIN_MINIGLVERSION); if (!MiniGLBase) return NULL; IMiniGL = (struct MiniGLIFace *)IExec->GetInterface(MiniGLBase, "main", 1, NULL); if (!IMiniGL) { IExec->CloseLibrary(MiniGLBase); return NULL; } /* These will never fail */ IntuitionBase = IExec->OpenLibrary("intuition.library", 0); IIntuition = (struct IntuitionIFace *)IExec->GetInterface(IntuitionBase, "main", 1, NULL); __TimerBase = (struct Device *)IExec->FindName( &((struct ExecBase *)SysBase)->DeviceList, "timer.device"); __ITimer = (struct TimerIFace *)IExec->GetInterface( (struct Library *)__TimerBase, "main", 1, NULL); __KeymapBase = IExec->OpenLibrary("keymap.library", 36); __IKeymap = (struct KeymapIFace *)IExec->GetInterface(__KeymapBase, "main", 1, NULL); dprintf("Done (__ITimer = %p)\n", __ITimer); /* Return libBase here to indicate success, or 0 if something failed */ return libBase; } uint32 defaultObtain(struct Interface *Self) { return ++Self->Data.RefCount; } uint32 defaultRelease(struct Interface *Self) { return --Self->Data.RefCount; } uint32 glut_Obtain(struct GlutIFace *Self) { if(Self->Data.RefCount == 0) { // Initialize a few essentials (it's better to do these here instead of in glutInit()) GLUTcontext ctx = (GLUTcontext)GET_INSTANCE(Self); IExec->NewMinList(&ctx->freeTimerHookList); IExec->NewMinList(&ctx->activeTimerHookList); ctx->timerHookPort = IExec->CreatePort( 0, 0 ); if(!ctx->timerHookPort) { dprintf("Error: Could not allocate a message port\n"); } } return ++Self->Data.RefCount; } uint32 glut_Release(struct GlutIFace *Self) { uint32 ref; ref = --Self->Data.RefCount; if (Self->Data.RefCount == 0 && (Self->Data.Flags & IFLF_CLONED)) Self->Expunge(); return ref; } void glut_Expunge(struct GlutIFace *Self) { void *base = (void *)GET_INSTANCE(Self); GLUTcontext ctx = (GLUTcontext)GET_INSTANCE(Self); if(ctx->timerHookPort) { IExec->DeletePort(ctx->timerHookPort); ctx->timerHookPort = NULL; } IExec->FreeVec(base); } struct Interface *glut_Clone(struct GlutIFace *Self) { uint8 *base; uint32 size = Self->Data.PositiveSize + Self->Data.NegativeSize; struct GlutIFace *clone; dprintf("Positive = %ld, Negative = %ld, total = %ld\n", Self->Data.PositiveSize, Self->Data.NegativeSize, size); base = (uint8 *)IExec->AllocVec(size, MEMF_PUBLIC|MEMF_CLEAR); if (!base) return 0; clone = (struct GlutIFace *) (base + Self->Data.NegativeSize); /* Copy the functions */ IExec->CopyMem((APTR)Self, (APTR)clone, Self->Data.PositiveSize); clone->Data.Flags |= IFLF_CLONED; clone->Data.RefCount = 0; return (struct Interface *)clone; } /* Manager interface vectors */ void *manager_vectors[] = { (void *)defaultObtain, (void *)defaultRelease, (void *)0, (void *)0, (void *)libOpen, (void *)libClose, (void *)libExpunge, (void *)0, (void *)-1, }; /* "__library" interface tag list */ struct TagItem managerTags[] = { {MIT_Name, (ULONG)"__library"}, {MIT_VectorTable, (ULONG)manager_vectors}, {MIT_Version, 1}, {TAG_DONE, 0} }; struct TagItem mainTags[] = { {MIT_Name, (ULONG)"main"}, {MIT_DataSize, sizeof(struct GLUTcontext_t)}, {MIT_Flags, IFLF_PRIVATE}, {MIT_VectorTable, (ULONG)main_vectors}, {MIT_Version, 1}, {TAG_DONE, 0} }; uint32 libInterfaces[] = { (uint32)managerTags, (uint32)mainTags, 0 }; struct TagItem libCreateTags[] = { {CLT_DataSize, (uint32)sizeof(struct Library)}, {CLT_InitFunc, (uint32)libInit}, {CLT_Interfaces, (uint32)libInterfaces}, {TAG_DONE, 0}, }; struct Resident glut_res __attribute__((used)) = { RTC_MATCHWORD, &glut_res, &glut_res+1, RTF_AUTOINIT|RTF_NATIVE|RTF_COLDSTART, (int)VERSION, NT_LIBRARY, 0, (char *)"mglut.library", (char *)VSTRING, libCreateTags }; void _start(void) { }