Hint added.
[AROS.git] / workbench / libs / gl / gl_init.c
blobabe4d98b51f4e8645f906d1080926e076fd5c2f1
1 /*
2 Copyright 2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 //#define DEBUG 1
7 #include <aros/debug.h>
9 #include <proto/exec.h>
10 #include <proto/dos.h>
12 #include <proto/alib.h>
14 #include <aros/libcall.h>
15 #include <exec/resident.h>
16 #include <libraries/dos.h>
18 #include <stdio.h>
19 #include <string.h>
21 #include "gl_intern.h"
23 #define DOSBase GLB(base)->glb_DOS
25 static AROS_UFP3 (struct Library *, GM_UNIQUENAME(LibInit),
26 AROS_UFPA(struct Library *, base, D0),
27 AROS_UFPA(BPTR, librarySegment, A0),
28 AROS_UFPA(struct ExecBase *, sysBase, A6)
30 static AROS_LD1 (struct Library *, GM_UNIQUENAME(LibOpen),
31 AROS_LPA (ULONG, version, D0),
32 struct Library *, base, 1, GL
34 static AROS_LD0 (BPTR, GM_UNIQUENAME(LibClose),
35 struct Library *, base, 2, GL
37 static AROS_LD1(BPTR, GM_UNIQUENAME(LibExpunge),
38 AROS_LPA(struct Library *, __extrabase, D0),
39 struct Library *, base, 3, GL
42 __startup int Main(void)
44 return RETURN_FAIL;
47 struct ExecBase *SysBase = NULL;
49 static const char GM_UNIQUENAME(LibName)[] = MOD_NAME_STRING;
50 static const char GM_UNIQUENAME(LibID)[] = VERSION_STRING;
52 static IPTR GM_UNIQUENAME(LibNull)(VOID)
54 return(0);
57 STATIC CONST CONST_APTR GM_UNIQUENAME(LibVectors)[] =
59 (CONST_APTR)AROS_SLIB_ENTRY(GM_UNIQUENAME(LibOpen), GL, 1),
60 (CONST_APTR)AROS_SLIB_ENTRY(GM_UNIQUENAME(LibClose), GL, 2),
61 (CONST_APTR)AROS_SLIB_ENTRY(GM_UNIQUENAME(LibExpunge), GL, 3),
62 (CONST_APTR)GM_UNIQUENAME(LibNull),
63 (CONST_APTR)-1
66 STATIC CONST IPTR GM_UNIQUENAME(LibInitTab)[] =
68 sizeof(struct LIBBASE),
69 (IPTR)GM_UNIQUENAME(LibVectors),
70 (IPTR)NULL,
71 (IPTR)GM_UNIQUENAME(LibInit)
74 static const struct Resident ROMTag __attribute__((used)) =
76 RTC_MATCHWORD,
77 (struct Resident *)&ROMTag,
78 (struct Resident *)(&ROMTag + 1),
79 RESIDENTFLAGS,
80 VERSION_NUMBER,
81 NT_LIBRARY,
83 (char *)GM_UNIQUENAME(LibName),
84 (char *)(GM_UNIQUENAME(LibID) + 6), // +6 to skip '$VER: '
85 (APTR)GM_UNIQUENAME(LibInitTab),
86 REVISION_NUMBER,
90 #define BUFFER_SIZE 256
92 char *GetGLVarPath(struct Library *base)
94 char pathBuff[BUFFER_SIZE];
95 BPTR pathLock = BNULL;
97 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__));
99 if ((pathLock = Lock("ENV:SYS", SHARED_LOCK)) != BNULL)
101 if (NameFromLock(pathLock, pathBuff, BUFFER_SIZE))
103 GLB(base)->glb_Notify.nr_Name = AllocVec(strlen(pathBuff) + 4, MEMF_PUBLIC);
104 sprintf(GLB(base)->glb_Notify.nr_Name, "%s/GL", pathBuff);
105 D(bug("[GL] %s: using '%s'\n", __PRETTY_FUNCTION__, GLB(base)->glb_Notify.nr_Name));
107 UnLock(pathLock);
109 return GLB(base)->glb_Notify.nr_Name;
112 void GetGLVar(struct Library *base)
114 LONG Var_Length;
115 char Var_Value[BUFFER_SIZE];
117 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__));
119 FreeVec(GLB(base)->glb_GLImpl);
121 Var_Length = GetVar((STRPTR)"SYS/GL",
122 &Var_Value[0],
123 BUFFER_SIZE,
124 GVF_GLOBAL_ONLY | LV_VAR
127 if (Var_Length != -1)
129 if ((GLB(base)->glb_GLImpl = AllocVec(strlen(Var_Value) + strlen(".library") + 1, MEMF_PUBLIC)) != NULL)
131 sprintf(GLB(base)->glb_GLImpl, "%s.library", Var_Value);
132 D(bug("[GL] %s: using '%s' for %s\n", __PRETTY_FUNCTION__, GLB(base)->glb_GLImpl, Var_Value));
137 void gl_EnvNotifyProc(void)
139 struct Process *pr = (struct Process *) FindTask (NULL);
140 struct Library *base = ((struct Task *)pr)->tc_UserData;
141 struct Message *msg;
143 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__));
145 while (TRUE)
147 WaitPort (&pr->pr_MsgPort);
148 while ((msg = GetMsg (&pr->pr_MsgPort)))
149 ReplyMsg(msg);
151 GetGLVar(base);
155 void SetupGLVarNotification(struct Library *base)
157 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__));
159 if (!GLB(base)->glb_Notify.nr_Name)
160 GetGLVarPath(base);
162 if (GLB(base)->glb_Notify.nr_Name)
164 if (!GLB(base)->glb_Notify.nr_stuff.nr_Msg.nr_Port)
166 struct TagItem enprocTags[] =
168 { NP_Entry, (IPTR)gl_EnvNotifyProc },
169 { NP_UserData, (IPTR)base },
170 { TAG_END, 0 }
172 struct Process *enProc;
173 if ((enProc = CreateNewProc(enprocTags)) != NULL)
175 D(bug("[GL] %s: FS Notification Proc @ 0x%p for '%s'\n", __PRETTY_FUNCTION__, enProc, GLB(base)->glb_Notify.nr_Name));
177 GLB(base)->glb_Notify.nr_stuff.nr_Msg.nr_Port = &enProc->pr_MsgPort;
179 D(bug("[GL] %s: MsgPort @ 0x%p\n", __PRETTY_FUNCTION__,GLB(base)->glb_Notify.nr_stuff.nr_Msg.nr_Port));
182 if (GLB(base)->glb_Notify.nr_stuff.nr_Msg.nr_Port && !GLB(base)->glb_Notify.nr_FullName)
184 GLB(base)->glb_Notify.nr_Flags = NRF_SEND_MESSAGE|NRB_NOTIFY_INITIAL;
185 StartNotify(&GLB(base)->glb_Notify);
186 D(bug("[GL] %s: Started FS Notification for '%s'\n", __PRETTY_FUNCTION__, GLB(base)->glb_Notify.nr_FullName));
191 static AROS_UFH3(struct Library *, GM_UNIQUENAME(LibInit),
192 AROS_UFHA(struct Library *, base, D0),
193 AROS_UFHA(BPTR, librarySegment, A0),
194 AROS_UFHA(struct ExecBase *, sysBase, A6)
197 AROS_USERFUNC_INIT
199 SysBase = sysBase;
201 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__));
203 D(bug("[GL] %s: base @ 0x%p, SysBase @ 0x%p\n", __PRETTY_FUNCTION__, base, SysBase));
205 // setup the library structure.
206 GLB(base)->glb_Lib.lib_Node.ln_Type = NT_LIBRARY;
207 GLB(base)->glb_Lib.lib_Node.ln_Pri = 0;
208 GLB(base)->glb_Lib.lib_Node.ln_Name = (char *)GM_UNIQUENAME(LibName);
209 GLB(base)->glb_Lib.lib_Flags = LIBF_CHANGED | LIBF_SUMUSED;
210 GLB(base)->glb_Lib.lib_Version = VERSION_NUMBER;
211 GLB(base)->glb_Lib.lib_Revision = REVISION_NUMBER;
212 GLB(base)->glb_Lib.lib_IdString = (char *)(GM_UNIQUENAME(LibID) + 6);
214 GLB(base)->glb_DOS = OpenLibrary("dos.library", 0);
216 D(bug("[GL] %s: DOSBase @ 0x%p\n", __PRETTY_FUNCTION__, DOSBase));
218 memset(&GLB(base)->glb_Sem, 0,
219 sizeof(struct SignalSemaphore) + sizeof(struct NotifyRequest));
220 InitSemaphore(&GLB(base)->glb_Sem);
222 // TODO: the following line is a workaround for a bug in
223 // the notification system.
224 GetGLVar(base);
226 SetupGLVarNotification(base);
228 // return the library base as success
229 return base;
231 AROS_USERFUNC_EXIT
234 static AROS_LH1(struct Library *, GM_UNIQUENAME(LibOpen),
235 AROS_LHA(ULONG, version, D0),
236 struct Library *, base, 1, GL
239 AROS_LIBFUNC_INIT
241 struct Library *res = NULL;
242 char *glImplementation;
244 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__));
246 // delete the late expunge flag
247 GLB(base)->glb_Lib.lib_Flags &= ~LIBF_DELEXP;
249 if (GLB(base)->glb_GLImpl)
250 glImplementation = GLB(base)->glb_GLImpl;
251 else
252 glImplementation = "mesa3dgl.library";
254 D(bug("[GL] %s: Attempting to use '%s' version %d\n", __PRETTY_FUNCTION__, glImplementation, version));
256 res = OpenLibrary(glImplementation, version);
258 return res;
260 AROS_LIBFUNC_EXIT
263 /* NB: we dont ever really close */
265 static AROS_LH0(BPTR, GM_UNIQUENAME(LibClose),
266 struct Library *, base, 2, GL
269 AROS_LIBFUNC_INIT
271 BPTR rc = 0;
273 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__));
275 return rc;
277 AROS_LIBFUNC_EXIT
280 static AROS_LH1(BPTR, GM_UNIQUENAME(LibExpunge),
281 AROS_LHA(struct Library *, __extrabase, D0),
282 struct Library *, base, 3, GL
285 AROS_LIBFUNC_INIT
287 BPTR rc = 0;
289 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__));
291 return rc;
293 AROS_LIBFUNC_EXIT