NetSurf
libs.c
Go to the documentation of this file.
1/*
2 * Copyright 2014-2020 Chris Young <chris@unsatisfactorysoftware.co.uk>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include "amiga/os3support.h"
20
21#include "amiga/libs.h"
22#include "amiga/misc.h"
23#include "utils/utils.h"
24#include "utils/log.h"
25
26#include <proto/dos.h>
27#include <proto/exec.h>
28#include <proto/intuition.h>
29#include <proto/utility.h>
30
31#include <graphics/gfxbase.h> /* Needed for v54 version check */
32
33#ifndef __amigaos4__
34/* OS3 needs these for the XXXX_GetClass() functions */
35#include <proto/arexx.h>
36#include <proto/bevel.h>
37#include <proto/bitmap.h>
38#include <proto/button.h>
39#include <proto/chooser.h>
40#include <proto/checkbox.h>
41#include <proto/clicktab.h>
42#include <proto/fuelgauge.h>
43#include <proto/getfile.h>
44#include <proto/getfont.h>
45#include <proto/getscreenmode.h>
46#include <proto/integer.h>
47#include <proto/label.h>
48#include <proto/layout.h>
49#include <proto/listbrowser.h>
50#include <proto/radiobutton.h>
51#include <proto/scroller.h>
52#include <proto/space.h>
53#include <proto/speedbar.h>
54#include <proto/string.h>
55#include <proto/window.h>
56#endif
57
58#ifdef __amigaos4__
59#define AMINS_LIB_OPEN(LIB, LIBVER, PREFIX, INTERFACE, INTVER, FAIL) \
60 NSLOG(netsurf, INFO, "Opening %s v%d", LIB, LIBVER); \
61 if((PREFIX##Base = (struct PREFIX##Base *)OpenLibrary(LIB, LIBVER))) { \
62 NSLOG(netsurf, INFO, " -> opened v%d.%d", ((struct Library *)PREFIX##Base)->lib_Version, ((struct Library *)PREFIX##Base)->lib_Revision); \
63 I##PREFIX = (struct PREFIX##IFace *)GetInterface((struct Library *)PREFIX##Base, INTERFACE, INTVER, NULL); \
64 if(I##PREFIX == NULL) { \
65 NSLOG(netsurf, INFO, "Failed to get %s interface v%d of %s", INTERFACE, INTVER, LIB); \
66 AMINS_LIB_CLOSE(PREFIX) \
67 if(FAIL == true) { \
68 STRPTR error = ASPrintf("Unable to open interface %s v%d\nof %s v%ld (fatal error - not an OS4 lib?)", INTERFACE, INTVER, LIB, LIBVER); \
69 ami_misc_fatal_error(error); \
70 FreeVec(error); \
71 return false; \
72 } \
73 } \
74 } else { \
75 NSLOG(netsurf, INFO, "Failed to open %s v%d", LIB, LIBVER); \
76 if(FAIL == true) { \
77 STRPTR error = ASPrintf("Unable to open %s v%ld (fatal error)", LIB, LIBVER); \
78 ami_misc_fatal_error(error); \
79 FreeVec(error); \
80 return false; \
81 } \
82 }
83
84#define AMINS_LIB_CLOSE(PREFIX) \
85 if(I##PREFIX) DropInterface((struct Interface *)I##PREFIX); \
86 if(PREFIX##Base) CloseLibrary((struct Library *)PREFIX##Base); \
87 I##PREFIX = NULL; \
88 PREFIX##Base = NULL;
89
90#define AMINS_LIB_STRUCT(PREFIX) \
91 struct PREFIX##Base *PREFIX##Base = NULL; \
92 struct PREFIX##IFace *I##PREFIX = NULL;
93
94#define AMINS_CLASS_OPEN(CLASS, CLASSVER, PREFIX, CLASSGET, NEEDINTERFACE) \
95 NSLOG(netsurf, INFO, "Opening %s v%d", CLASS, CLASSVER); \
96 if((PREFIX##Base = OpenClass(CLASS, CLASSVER, &PREFIX##Class))) { \
97 NSLOG(netsurf, INFO, " -> opened v%d.%d", ((struct Library *)PREFIX##Base)->lib_Version, ((struct Library *)PREFIX##Base)->lib_Revision); \
98 if(NEEDINTERFACE == true) { \
99 NSLOG(netsurf, INFO, " + interface"); \
100 I##PREFIX = (struct PREFIX##IFace *)GetInterface((struct Library *)PREFIX##Base, "main", 1, NULL); \
101 if(I##PREFIX == NULL) { \
102 NSLOG(netsurf, ERROR, "Failed to get main interface v1 of %s", CLASS); \
103 } \
104 } \
105 } \
106 if(PREFIX##Class == NULL) { \
107 NSLOG(netsurf, INFO, "Failed to open %s v%d", CLASS, CLASSVER); \
108 STRPTR error = ASPrintf("Unable to open %s v%d (fatal error)", CLASS, CLASSVER); \
109 ami_misc_fatal_error(error); \
110 FreeVec(error); \
111 return false; \
112 }
113
114#define AMINS_CLASS_CLOSE(PREFIX) \
115 if(I##PREFIX) DropInterface((struct Interface *)I##PREFIX); \
116 if(PREFIX##Base) CloseClass(PREFIX##Base); \
117 I##PREFIX = NULL; \
118 PREFIX##Base = NULL;
119
120#define AMINS_CLASS_STRUCT(PREFIX) \
121 struct ClassLibrary *PREFIX##Base = NULL; \
122 struct PREFIX##IFace *I##PREFIX = NULL; \
123 Class *PREFIX##Class = NULL;
124
125#else
126#define AMINS_LIB_OPEN(LIB, LIBVER, PREFIX, INTERFACE, INTVER, FAIL) \
127 NSLOG(netsurf, INFO, "Opening %s v%d", LIB, LIBVER); \
128 if((PREFIX##Base = (struct PREFIX##Base *)OpenLibrary(LIB, LIBVER))) { \
129 NSLOG(netsurf, INFO, " -> opened v%d.%d", ((struct Library *)PREFIX##Base)->lib_Version, ((struct Library *)PREFIX##Base)->lib_Revision); \
130 } else { \
131 NSLOG(netsurf, INFO, "Failed to open %s v%d", LIB, LIBVER); \
132 if(FAIL == true) { \
133 STRPTR error = ASPrintf("Unable to open %s v%d (fatal error)", LIB, LIBVER); \
134 ami_misc_fatal_error(error); \
135 FreeVec(error); \
136 return false; \
137 } \
138 }
139
140#define AMINS_LIB_CLOSE(PREFIX) \
141 if(PREFIX##Base) CloseLibrary((struct Library *)PREFIX##Base); \
142 PREFIX##Base = NULL;
143
144#define AMINS_LIB_STRUCT(PREFIX) \
145 struct PREFIX##Base *PREFIX##Base = NULL;
146
147#define AMINS_CLASS_OPEN(CLASS, CLASSVER, PREFIX, CLASSGET, NEEDINTERFACE) \
148 NSLOG(netsurf, INFO, "Opening %s v%d", CLASS, CLASSVER); \
149 if((PREFIX##Base = OpenLibrary(CLASS, CLASSVER))) { \
150 NSLOG(netsurf, INFO, " -> opened v%d.%d", ((struct Library *)PREFIX##Base)->lib_Version, ((struct Library *)PREFIX##Base)->lib_Revision); \
151 PREFIX##Class = CLASSGET##_GetClass(); \
152 } \
153 if(PREFIX##Class == NULL) { \
154 NSLOG(netsurf, INFO, "Failed to open %s v%d", CLASS, CLASSVER); \
155 STRPTR error = ASPrintf("Unable to open %s v%d (fatal error)", CLASS, CLASSVER); \
156 ami_misc_fatal_error(error); \
157 FreeVec(error); \
158 return false; \
159 }
160
161#define AMINS_CLASS_CLOSE(PREFIX) \
162 if(PREFIX##Base) CloseLibrary(PREFIX##Base); \
163 PREFIX##Base = NULL;
164
165#define AMINS_CLASS_STRUCT(PREFIX) \
166 struct Library *PREFIX##Base = NULL; \
167 Class *PREFIX##Class = NULL;
168
169#endif
170
171#define GraphicsBase GfxBase /* graphics.library is a bit weird */
172
173#ifdef __amigaos4__
174AMINS_LIB_STRUCT(Application);
175#else
176AMINS_LIB_STRUCT(Utility)
177#endif
191
194
205AMINS_CLASS_STRUCT(GetScreenMode);
211#ifndef __amigaos4__
213#endif
219
220
222{
223#ifdef __amigaos4__
224 /* Libraries only needed on OS4 */
225 AMINS_LIB_OPEN("application.library", 53, Application, "application", 2, false)
226 AMINS_LIB_OPEN("dos.library", 37, DOS, "main", 1, true)
227#else
228 /* Libraries we get automatically on OS4 but not OS3 */
229 AMINS_LIB_OPEN("utility.library", 37, Utility, "main", 1, true)
230#endif
231 /* Standard libraries for both versions */
232 AMINS_LIB_OPEN("asl.library", 37, Asl, "main", 1, true)
233 AMINS_LIB_OPEN("datatypes.library", 39, DataTypes, "main", 1, true)
234 AMINS_LIB_OPEN("diskfont.library", 40, Diskfont, "main", 1, true)
235 AMINS_LIB_OPEN("gadtools.library", 37, GadTools, "main", 1, true)
236 AMINS_LIB_OPEN("graphics.library", 40, Graphics, "main", 1, true)
237 AMINS_LIB_OPEN("icon.library", 44, Icon, "main", 1, true)
238 AMINS_LIB_OPEN("iffparse.library", 37, IFFParse, "main", 1, true)
239 AMINS_LIB_OPEN("intuition.library", 40, Intuition, "main", 1, true)
240 AMINS_LIB_OPEN("keymap.library", 37, Keymap, "main", 1, true)
241 AMINS_LIB_OPEN("layers.library", 37, Layers, "main", 1, true)
242 AMINS_LIB_OPEN("locale.library", 38, Locale, "main", 1, true)
243 AMINS_LIB_OPEN("workbench.library", 37, Workbench, "main", 1, true)
244
245 /* This is down here as we need to check the graphics.library version
246 * before opening. If it is sufficiently new enough we can avoid using P96.
247 */
248 if(GfxBase->LibNode.lib_Version < 54)
249 AMINS_LIB_OPEN("Picasso96API.library", 0, P96, "main", 1, false)
250
251 /* Non-OS provided libraries */
252 AMINS_LIB_OPEN("codesets.library", 6, Codesets, "main", 1, false)
253 AMINS_LIB_OPEN("guigfx.library", 9, GuiGFX, "main", 1, false)
254
255 /* NB: timer.device is opened in schedule.c (ultimately by the scheduler process).
256 * The library base and interface are obtained there, rather than here, due to
257 * the additional complexities of opening devices, which aren't important here
258 * (as we only need the library interface), but are important for the scheduler
259 * (as it also uses the device interface). We trust that the scheduler has
260 * initialised before any other code requires the timer's library interface,
261 * to avoid opening it twice.
262 */
263
264 /* BOOPSI classes.
265 * Opened using class functions rather than the old-fashioned method.
266 * We get the class pointer once and used our stored copy.
267 * On OS4 these must be opened *after* intuition.library.
268 * NB: the last argument should be "true" only if the class also has
269 * library functions we use.
270 */
271 AMINS_CLASS_OPEN("arexx.class", 41, ARexx, AREXX, false)
272 AMINS_CLASS_OPEN("images/bevel.image", 41, Bevel, BEVEL, false)
273 AMINS_CLASS_OPEN("images/bitmap.image", 41, BitMap, BITMAP, false)
274 AMINS_CLASS_OPEN("gadgets/button.gadget", 42, Button, BUTTON, false)
275 AMINS_CLASS_OPEN("gadgets/checkbox.gadget", 41, CheckBox, CHECKBOX, false)
276 AMINS_CLASS_OPEN("gadgets/chooser.gadget", 41, Chooser, CHOOSER, true)
277 AMINS_CLASS_OPEN("gadgets/clicktab.gadget", 42, ClickTab, CLICKTAB, true)
278 AMINS_CLASS_OPEN("gadgets/fuelgauge.gadget", 41, FuelGauge, FUELGAUGE, false)
279 AMINS_CLASS_OPEN("gadgets/getfile.gadget", 41, GetFile, GETFILE, false)
280 AMINS_CLASS_OPEN("gadgets/getfont.gadget", 41, GetFont, GETFONT, false)
281 AMINS_CLASS_OPEN("gadgets/getscreenmode.gadget", 41, GetScreenMode, GETSCREENMODE, false)
282 AMINS_CLASS_OPEN("gadgets/integer.gadget", 41, Integer, INTEGER, false)
283 AMINS_CLASS_OPEN("images/label.image", 41, Label, LABEL, false)
284 AMINS_CLASS_OPEN("gadgets/layout.gadget", 43, Layout, LAYOUT, true)
285 AMINS_CLASS_OPEN("gadgets/listbrowser.gadget", 41, ListBrowser, LISTBROWSER, true)
286 AMINS_CLASS_OPEN("gadgets/radiobutton.gadget", 41, RadioButton, RADIOBUTTON, false)
287 AMINS_CLASS_OPEN("gadgets/scroller.gadget", 42, Scroller, SCROLLER, false)
288 AMINS_CLASS_OPEN("gadgets/space.gadget", 41, Space, SPACE, false)
289 AMINS_CLASS_OPEN("gadgets/speedbar.gadget", 41, SpeedBar, SPEEDBAR, true)
290 AMINS_CLASS_OPEN("gadgets/string.gadget", 41, String, STRING, false)
291 AMINS_CLASS_OPEN("window.class", 42, Window, WINDOW, false)
292
293#ifndef __amigaos4__
294 /* BOOPSI classes only required prior to OS4 */
295 PageClass = PAGE_GetClass();
296#endif
297
298 return true;
299}
300
302{
303 /* BOOPSI Classes.
304 * On OS4 these must be closed *before* intuition.library
305 */
306 AMINS_CLASS_CLOSE(ARexx)
307 AMINS_CLASS_CLOSE(Bevel)
308 AMINS_CLASS_CLOSE(BitMap)
309 AMINS_CLASS_CLOSE(Button)
310 AMINS_CLASS_CLOSE(CheckBox)
311 AMINS_CLASS_CLOSE(Chooser)
312 AMINS_CLASS_CLOSE(ClickTab)
313 AMINS_CLASS_CLOSE(FuelGauge)
314 AMINS_CLASS_CLOSE(GetFile)
315 AMINS_CLASS_CLOSE(GetFont)
316 AMINS_CLASS_CLOSE(GetScreenMode)
317 AMINS_CLASS_CLOSE(Integer)
318 AMINS_CLASS_CLOSE(Label)
319 AMINS_CLASS_CLOSE(Layout)
320 AMINS_CLASS_CLOSE(ListBrowser)
321 AMINS_CLASS_CLOSE(RadioButton)
322 AMINS_CLASS_CLOSE(Scroller)
323 AMINS_CLASS_CLOSE(Space)
324 AMINS_CLASS_CLOSE(SpeedBar)
325 AMINS_CLASS_CLOSE(String)
326 AMINS_CLASS_CLOSE(Window)
327
328 /* Libraries */
329 AMINS_LIB_CLOSE(Codesets)
330 AMINS_LIB_CLOSE(GuiGFX)
331
332 AMINS_LIB_CLOSE(Asl)
333 AMINS_LIB_CLOSE(DataTypes)
334 AMINS_LIB_CLOSE(Diskfont)
335 AMINS_LIB_CLOSE(GadTools)
336 AMINS_LIB_CLOSE(Graphics)
337 AMINS_LIB_CLOSE(Icon)
338 AMINS_LIB_CLOSE(IFFParse)
339 AMINS_LIB_CLOSE(Intuition)
340 AMINS_LIB_CLOSE(Keymap)
341 AMINS_LIB_CLOSE(Layers)
342 AMINS_LIB_CLOSE(Locale)
343 AMINS_LIB_CLOSE(P96)
344 AMINS_LIB_CLOSE(Workbench)
345#ifdef __amigaos4__
346 AMINS_LIB_CLOSE(Application)
347 AMINS_LIB_CLOSE(DOS)
348#else
349 AMINS_LIB_CLOSE(Utility)
350#endif
351}
352
#define AMINS_CLASS_STRUCT(PREFIX)
Definition: libs.c:165
#define AMINS_CLASS_OPEN(CLASS, CLASSVER, PREFIX, CLASSGET, NEEDINTERFACE)
Definition: libs.c:147
#define AMINS_LIB_STRUCT(PREFIX)
Definition: libs.c:144
#define AMINS_LIB_OPEN(LIB, LIBVER, PREFIX, INTERFACE, INTVER, FAIL)
Definition: libs.c:126
bool ami_libs_open(void)
Definition: libs.c:221
#define AMINS_LIB_CLOSE(PREFIX)
Definition: libs.c:140
void ami_libs_close(void)
Definition: libs.c:301
#define AMINS_CLASS_CLOSE(PREFIX)
Definition: libs.c:161
Class * PageClass
Minimal compatibility header for AmigaOS 3.
Interface to a number of general purpose functionality.