2 Copyright 2015, The AROS Development Team. All rights reserved.
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>
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)
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
)
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
),
66 STATIC CONST IPTR
GM_UNIQUENAME(LibInitTab
)[] =
68 sizeof(struct LIBBASE
),
69 (IPTR
)GM_UNIQUENAME(LibVectors
),
71 (IPTR
)GM_UNIQUENAME(LibInit
)
74 static const struct Resident ROMTag
__attribute__((used
)) =
77 (struct Resident
*)&ROMTag
,
78 (struct Resident
*)(&ROMTag
+ 1),
83 (char *)GM_UNIQUENAME(LibName
),
84 (char *)(GM_UNIQUENAME(LibID
) + 6), // +6 to skip '$VER: '
85 (APTR
)GM_UNIQUENAME(LibInitTab
),
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
));
109 return GLB(base
)->glb_Notify
.nr_Name
;
112 void GetGLVar(struct Library
*base
)
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",
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
;
143 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__
));
147 WaitPort (&pr
->pr_MsgPort
);
148 while ((msg
= GetMsg (&pr
->pr_MsgPort
)))
155 void SetupGLVarNotification(struct Library
*base
)
157 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__
));
159 if (!GLB(base
)->glb_Notify
.nr_Name
)
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
},
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
)
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.
226 SetupGLVarNotification(base
);
228 // return the library base as success
234 static AROS_LH1(struct Library
*, GM_UNIQUENAME(LibOpen
),
235 AROS_LHA(ULONG
, version
, D0
),
236 struct Library
*, base
, 1, GL
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
;
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
);
263 /* NB: we dont ever really close */
265 static AROS_LH0(BPTR
, GM_UNIQUENAME(LibClose
),
266 struct Library
*, base
, 2, GL
273 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__
));
280 static AROS_LH1(BPTR
, GM_UNIQUENAME(LibExpunge
),
281 AROS_LHA(struct Library
*, __extrabase
, D0
),
282 struct Library
*, base
, 3, GL
289 D(bug("[GL] %s()\n", __PRETTY_FUNCTION__
));