NetSurf
os3support.c
Go to the documentation of this file.
1/*
2 * Copyright 2014 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/** \file
20 * Compatibility functions for AmigaOS 3
21 */
22
23#ifndef __amigaos4__
24#include "os3support.h"
25
26#include <inttypes.h>
27#include <stdarg.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <ctype.h>
31
32#include <proto/bullet.h>
33#include <proto/exec.h>
34#include <proto/intuition.h>
35#include <proto/dos.h>
36#include <proto/utility.h>
37
38#include <diskfont/diskfont.h>
39#include <diskfont/diskfonttag.h>
40#include <intuition/gadgetclass.h>
41
42#include "utils/log.h"
43
44#define SUCCESS (TRUE)
45#define FAILURE (FALSE)
46#define NO !
47
48/* Utility */
50{
51 STRPTR Index;
52 LONG Size;
54};
55
56STATIC VOID ASM
58 REG(a3, struct FormatContext * Context),
59 REG(d0, UBYTE Char))
60{
61 /* Is there still room? */
62 if(Context->Size > 0)
63 {
64 (*Context->Index) = Char;
65
66 Context->Index++;
67 Context->Size--;
68
69 /* Is there only a single character left? */
70 if(Context->Size == 1)
71 {
72 /* Provide null-termination. */
73 (*Context->Index) = '\0';
74
75 /* Don't store any further characters. */
76 Context->Size = 0;
77 }
78 }
79 else
80 {
81 Context->Overflow = TRUE;
82 }
83}
84
85BOOL
87 LONG MaxLen,
88 STRPTR Buffer,
89 const STRPTR FormatString,
90 const va_list VarArgs)
91{
92 BOOL result = FAILURE;
93
94 /* format a text, but place only up to MaxLen
95 * characters in the output buffer (including
96 * the terminating NUL)
97 */
98
99 if (Buffer == NULL || FormatString == NULL) return(result);
100
101 if(MaxLen > 1)
102 {
103 struct FormatContext Context;
104
105 Context.Index = Buffer;
106 Context.Size = MaxLen;
107 Context.Overflow = FALSE;
108
109 RawDoFmt(FormatString,(APTR)VarArgs,(VOID (*)())StuffChar,(APTR)&Context);
110
111 if(NO Context.Overflow)
112 result = SUCCESS;
113 }
114
115 return(result);
116}
117
118BOOL
120 LONG MaxLen,
121 STRPTR Buffer,
122 const STRPTR FormatString,
123 ...)
124{
125 va_list VarArgs;
126 BOOL result = FAILURE;
127
128 /* format a text, varargs version */
129
130 if (Buffer == NULL && FormatString == NULL) return result;
131
132 va_start(VarArgs,FormatString);
133 result = VSPrintfN(MaxLen,Buffer,FormatString,VarArgs);
134 va_end(VarArgs);
135
136 return(result);
137}
138
139char *ASPrintf(const char *fmt, ...)
140{
141 int r;
142 va_list ap;
143 static char buffer[2048];
144 char *rbuf;
145
146 va_start(ap, fmt);
147 r = VSPrintfN(2048, buffer, (const STRPTR)fmt, ap);
148 va_end(ap);
149
150 r = strlen(buffer);
151 rbuf = AllocVec(r+1, MEMF_CLEAR);
152 if (rbuf != NULL)
153 {
154 strncpy(rbuf, buffer, r);
155 }
156 return rbuf;
157}
158
159/* C */
160char *strlwr(char *str)
161{
162 size_t i;
163 size_t len = strlen(str);
164
165 for(i=0; i<len; i++)
166 str[i] = tolower((unsigned char)str[i]);
167
168 return str;
169}
170
171char *strsep(char **s1, const char *s2)
172{
173 char *const p1 = *s1;
174
175 if (p1 != NULL) {
176 *s1 = strpbrk(p1, s2);
177 if (*s1 != NULL) {
178 *(*s1)++ = '\0';
179 }
180 }
181 return p1;
182}
183
184int alphasort(const struct dirent **d1, const struct dirent **d2)
185{
186 /*\todo stub function, needs writing, preferably into clib2 */
187 return 0;
188}
189
190int scandir(const char *dir, struct dirent ***namelist,
191 int (*filter)(const struct dirent *),
192 int (*compar)(const struct dirent **, const struct dirent **))
193{
194 /*\todo stub function, needs writing, preferably into clib2 */
195 return 0;
196}
197
198long long int strtoll(const char *nptr, char **endptr, int base)
199{
200 return (long long int)strtol(nptr, endptr, base);
201}
202
203/* Diskfont */
204struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG flags)
205{
206 BPTR fh = 0;
207 int64 size = 0;
208 struct TagItem *ti;
209 UBYTE *buffer;
210 STRPTR fname, otagpath, fontpath;
211 struct BulletBase *BulletBase;
212 struct OutlineFont *of = NULL;
213 struct GlyphEngine *gengine;
214 char *p = 0;
215 struct FontContentsHeader fch;
216
217 if((p = strrchr(fileName, '.')))
218 *p = '\0';
219
220 fontpath = (STRPTR)ASPrintf("FONTS:%s.font", fileName);
221 fh = Open(fontpath, MODE_OLDFILE);
222
223 if(fh == 0) {
224 NSLOG(netsurf, INFO, "Unable to open FONT %s", fontpath);
225 FreeVec(fontpath);
226 return NULL;
227 }
228
229 if(Read(fh, &fch, sizeof(struct FontContentsHeader)) != sizeof(struct FontContentsHeader)) {
230 NSLOG(netsurf, INFO, "Unable to read FONT %s", fontpath);
231 FreeVec(fontpath);
232 Close(fh);
233 return NULL;
234 }
235
236 Close(fh);
237
238 if(fch.fch_FileID != OFCH_ID) {
239 NSLOG(netsurf, INFO, "%s is not an outline font!", fontpath);
240 FreeVec(fontpath);
241 return NULL;
242 }
243
244 otagpath = (STRPTR)ASPrintf("FONTS:%s.otag", fileName);
245 fh = Open(otagpath, MODE_OLDFILE);
246
247 if(p) *p = '.';
248
249 if(fh == 0) {
250 NSLOG(netsurf, INFO, "Unable to open OTAG %s", otagpath);
251 FreeVec(otagpath);
252 return NULL;
253 }
254
255 size = GetFileSize(fh);
256 buffer = (UBYTE *)malloc(size);
257 if(buffer == NULL) {
258 NSLOG(netsurf, INFO, "Unable to allocate memory");
259 Close(fh);
260 FreeVec(otagpath);
261 return NULL;
262 }
263
264 Read(fh, buffer, size);
265 Close(fh);
266
267 /* The first tag is supposed to be OT_FileIdent and should equal 'size' */
268 struct TagItem *tag = (struct TagItem *)buffer;
269 if((tag->ti_Tag != OT_FileIdent) || (tag->ti_Data != (ULONG)size)) {
270 NSLOG(netsurf, INFO, "Invalid OTAG file");
271 free(buffer);
272 FreeVec(otagpath);
273 return NULL;
274 }
275
276 /* Relocate all the OT_Indirect tags */
277 while((ti = NextTagItem(&tag))) {
278 if(ti->ti_Tag & OT_Indirect) {
279 ti->ti_Data += (ULONG)buffer;
280 }
281 }
282
283 /* Find OT_Engine and open the font engine */
284 if(ti = FindTagItem(OT_Engine, buffer)) {
285 NSLOG(netsurf, INFO, "Using font engine %s", ti->ti_Data);
286 fname = ASPrintf("%s.library", ti->ti_Data);
287 } else {
288 NSLOG(netsurf, INFO, "Cannot find OT_Engine tag");
289 free(buffer);
290 FreeVec(otagpath);
291 return NULL;
292 }
293
294 BulletBase = (struct BulletBase *)OpenLibrary(fname, 0L);
295
296 if(BulletBase == NULL) {
297 NSLOG(netsurf, INFO, "Unable to open font engine %s", fname);
298 free(buffer);
299 FreeVec(fname);
300 FreeVec(otagpath);
301 }
302
303 FreeVec(fname);
304
305 gengine = OpenEngine();
306
307 SetInfo(gengine,
308 OT_OTagPath, (ULONG)otagpath,
309 OT_OTagList, (ULONG)buffer,
310 TAG_DONE);
311
312 of = calloc(1, sizeof(struct OutlineFont));
313 if(of == NULL) return NULL;
314
315 of->BulletBase = BulletBase;
316 of->GEngine = gengine;
317 of->OTagPath = otagpath;
318 of->olf_OTagList = buffer;
319
320 return of;
321}
322
323void CloseOutlineFont(struct OutlineFont *of, struct List *list)
324{
325 struct BulletBase *BulletBase = of->BulletBase;
326
327 CloseEngine(of->GEngine);
328 CloseLibrary((struct Library *)BulletBase);
329
330 FreeVec(of->OTagPath);
331 free(of->olf_OTagList);
332 free(of);
333}
334
335
336/* DOS */
338{
339 int32 size = 0;
340 struct FileInfoBlock *fib = AllocDosObject(DOS_FIB, NULL);
341 if(fib == NULL) return 0;
342
343 ExamineFH(fh, fib);
344 size = fib->fib_Size;
345
346 FreeDosObject(DOS_FIB, fib);
347 return (int64)size;
348}
349
350void FreeSysObject(ULONG type, APTR obj)
351{
352 switch(type) {
353 case ASOT_PORT:
354 DeleteMsgPort(obj);
355 break;
356 case ASOT_IOREQUEST:
357 DeleteIORequest(obj);
358 break;
359 }
360}
361
362
363/* Exec */
364struct Node *GetHead(struct List *list)
365{
366 struct Node *res = NULL;
367
368 if ((NULL != list) && (NULL != list->lh_Head->ln_Succ))
369 {
370 res = list->lh_Head;
371 }
372 return res;
373}
374
375struct Node *GetPred(struct Node *node)
376{
377 if (node->ln_Pred->ln_Pred == NULL) return NULL;
378 return node->ln_Pred;
379}
380
381struct Node *GetSucc(struct Node *node)
382{
383 if (node->ln_Succ->ln_Succ == NULL) return NULL;
384 return node->ln_Succ;
385}
386
387
388/* Intuition */
389uint32 GetAttrs(Object *obj, Tag tag1, ...)
390{
391 va_list ap;
392 Tag tag = tag1;
393 ULONG data = 0;
394 int i = 0;
395
396 va_start(ap, tag1);
397
398 while(tag != TAG_DONE) {
399 data = va_arg(ap, ULONG);
400 i += GetAttr(tag, obj, (void *)data);
401 tag = va_arg(ap, Tag);
402 }
403 va_end(ap);
404
405 return i;
406}
407
408ULONG RefreshSetGadgetAttrsA(struct Gadget *g, struct Window *w, struct Requester *r, struct TagItem *tags)
409{
410 ULONG retval;
411 BOOL changedisabled = FALSE;
412 BOOL disabled;
413 struct TagItem *ti;
414
415 if (w) {
416 if ((ti = FindTagItem(GA_Disabled,tags)) && (ti->ti_Data != FALSE)) {
417 changedisabled = TRUE;
418 disabled = g->Flags & GFLG_DISABLED;
419 }
420 }
421 retval = SetGadgetAttrsA(g,w,r,tags);
422 if (w && (retval || (changedisabled && disabled != (g->Flags & GFLG_DISABLED)))) {
423 RefreshGList(g,w,r,1);
424 retval = 1;
425 }
426 return retval;
427}
428
429ULONG RefreshSetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, Tag tag1, ...)
430{
431 return RefreshSetGadgetAttrsA(g,w,r,(struct TagItem *) &tag1);
432}
433
434APTR NewObject(struct IClass * classPtr, CONST_STRPTR classID, ULONG tagList, ...)
435{
436 return NewObjectA(classPtr, classID, (const struct TagItem *) &tagList);
437}
438#endif
439
STATIC char result[100]
Definition: arexx.c:77
static osspriteop_area * buffer
The buffer characteristics.
Definition: buffer.c:55
const char * type
Definition: filetype.cpp:44
static int compar(const void *va, const void *vb)
Quick sort comparison.
Netsurf additional integer type formatting macros.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
int scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **))
Definition: os3support.c:190
BOOL VSPrintfN(LONG MaxLen, STRPTR Buffer, const STRPTR FormatString, const va_list VarArgs)
Definition: os3support.c:86
BOOL SPrintfN(LONG MaxLen, STRPTR Buffer, const STRPTR FormatString,...)
Definition: os3support.c:119
struct Node * GetPred(struct Node *node)
Definition: os3support.c:375
void FreeSysObject(ULONG type, APTR obj)
Definition: os3support.c:350
void CloseOutlineFont(struct OutlineFont *of, struct List *list)
Definition: os3support.c:323
APTR NewObject(struct IClass *classPtr, CONST_STRPTR classID, ULONG tagList,...)
Definition: os3support.c:434
char * ASPrintf(const char *fmt,...)
Definition: os3support.c:139
int alphasort(const struct dirent **d1, const struct dirent **d2)
Definition: os3support.c:184
#define FAILURE
Definition: os3support.c:45
struct OutlineFont * OpenOutlineFont(STRPTR fileName, struct List *list, ULONG flags)
Definition: os3support.c:204
int64 GetFileSize(BPTR fh)
Definition: os3support.c:337
long long int strtoll(const char *nptr, char **endptr, int base)
Definition: os3support.c:198
char * strlwr(char *str)
Definition: os3support.c:160
STATIC VOID ASM StuffChar(REG(a3, struct FormatContext *Context), REG(d0, UBYTE Char))
Definition: os3support.c:57
#define NO
Definition: os3support.c:46
char * strsep(char **s1, const char *s2)
Definition: os3support.c:171
uint32 GetAttrs(Object *obj, Tag tag1,...)
Definition: os3support.c:389
ULONG RefreshSetGadgetAttrsA(struct Gadget *g, struct Window *w, struct Requester *r, struct TagItem *tags)
Definition: os3support.c:408
#define SUCCESS
Definition: os3support.c:44
struct Node * GetHead(struct List *list)
Definition: os3support.c:364
ULONG RefreshSetGadgetAttrs(struct Gadget *g, struct Window *w, struct Requester *r, Tag tag1,...)
Definition: os3support.c:429
struct Node * GetSucc(struct Node *node)
Definition: os3support.c:381
Minimal compatibility header for AmigaOS 3.
int64_t int64
Definition: os3support.h:185
#define ASM
Definition: os3support.h:44
@ ASOT_PORT
Definition: os3support.h:226
@ ASOT_IOREQUEST
Definition: os3support.h:227
int32_t int32
Definition: os3support.h:183
uint32_t uint32
Definition: os3support.h:184
#define REG(reg, arg)
Definition: os3support.h:48
@ base
Definition: punycode.c:19
STRPTR Index
Definition: os3support.c:51
struct GlyphEngine * GEngine
Definition: os3support.h:203
struct TagItem * olf_OTagList
Definition: os3support.h:205
STRPTR OTagPath
Definition: os3support.h:204
struct BulletBase * BulletBase
Definition: os3support.h:202