Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / reqtools / rtfuncs.c
blob6598683d8dbeb48a469f417a8f5035b9259d87b0
1 #include "filereq.h"
2 #include "boopsi.h"
3 #include "rtfuncs.h"
4 #include "globalvars.h"
6 #include <devices/conunit.h>
8 #ifdef __AROS__
10 #include <aros/debug.h>
11 #include <aros/macros.h>
13 #else
15 #define D(x)
16 #define AROS_ASMSYMNAME(x) x
17 #define AROS_LONG2BE(x) x
18 #define AROS_WORD2BE(x) x
20 #endif
22 /****************************************************************************************/
24 struct rtWindowLock
26 struct Requester rtwl_Requester;
27 LONG rtwl_Magic;
28 struct rtWindowLock *rtwl_RequesterPtr;
29 ULONG rtwl_LockCount;
30 ULONG rtwl_ReqInstalled;
32 /* To save window parameters */
33 APTR rtwl_Pointer;
34 BYTE rtwl_PtrHeight;
35 BYTE rtwl_PtrWidth;
36 BYTE rtwl_XOffset;
37 BYTE rtwl_YOffset;
38 WORD rtwl_MinWidth;
39 WORD rtwl_MaxWidth;
40 WORD rtwl_MinHeight;
41 WORD rtwl_MaxHeight;
44 /****************************************************************************************/
46 SAVEDS ASM struct ReqToolsBase *RTFuncs_Init(REGPARAM(d0, struct ReqToolsBase *, RTBase),
47 REGPARAM(a0, BPTR, segList))
49 #ifdef __AROS__
50 /* SysBase is setup in reqtools_init.c */
51 #else
52 SysBase = *(struct ExecBase **)4L;
54 RTBase->SegList = segList;
55 #endif
57 InitSemaphore(&RTBase->ReqToolsPrefs.PrefsSemaphore);
58 RTBase->ReqToolsPrefs.PrefsSize = RTPREFS_SIZE;
59 RTBase->ReqToolsPrefs.IsLoaded = FALSE;
61 /* Set default preferences */
62 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FILEREQ].Size = 75;
63 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FILEREQ].ReqPos = REQPOS_TOPLEFTSCR;
64 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FILEREQ].LeftOffset = 25;
65 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FILEREQ].TopOffset = 18;
66 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FILEREQ].MinEntries = 10;
67 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FILEREQ].MaxEntries = 50;
69 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FONTREQ].Size = 65;
70 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FONTREQ].ReqPos = REQPOS_TOPLEFTSCR;
71 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FONTREQ].LeftOffset = 25;
72 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FONTREQ].TopOffset = 18;
73 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FONTREQ].MinEntries = 6;
74 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_FONTREQ].MaxEntries = 10;
76 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_PALETTEREQ].Size = 65;
77 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_PALETTEREQ].ReqPos = REQPOS_TOPLEFTSCR;
78 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_PALETTEREQ].LeftOffset = 25;
79 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_PALETTEREQ].TopOffset = 18;
80 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_PALETTEREQ].MinEntries = 6;
81 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_PALETTEREQ].MaxEntries = 10;
83 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_SCREENMODEREQ].Size = 65;
84 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_SCREENMODEREQ].ReqPos = REQPOS_TOPLEFTSCR;
85 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_SCREENMODEREQ].LeftOffset = 25;
86 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_SCREENMODEREQ].TopOffset = 18;
87 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_SCREENMODEREQ].MinEntries = 6;
88 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_SCREENMODEREQ].MaxEntries = 10;
90 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_VOLUMEREQ].Size = 65;
91 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_VOLUMEREQ].ReqPos = REQPOS_TOPLEFTSCR;
92 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_VOLUMEREQ].LeftOffset = 25;
93 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_VOLUMEREQ].TopOffset = 18;
94 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_VOLUMEREQ].MinEntries = 6;
95 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_VOLUMEREQ].MaxEntries = 10;
97 // RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_OTHERREQ].Size = 65;
98 // RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_OTHERREQ].ReqPos = REQPOS_TOPLEFTSCR;
99 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_OTHERREQ].LeftOffset = 25;
100 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_OTHERREQ].TopOffset = 18;
101 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_OTHERREQ].MinEntries = 6;
102 RTBase->ReqToolsPrefs.ReqDefaults[RTPREF_OTHERREQ].MaxEntries = 10;
104 return RTBase;
107 /****************************************************************************************/
109 SAVEDS ASM struct ReqToolsBase *RTFuncs_Open(REGPARAM(a6, struct ReqToolsBase *, RTBase),
110 REGPARAM(d0, ULONG, ver))
112 if (DOSBase == NULL)
114 DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37);
115 if (DOSBase == NULL)
116 return NULL;
118 RTBase->DOSBase = DOSBase;
120 if ( ! RTBase->ReqToolsPrefs.IsLoaded)
122 UBYTE configbuffer[RTPREFS_SIZE];
124 /* Read config file */
126 D(bug("reqtools.library: Inside libopen func. Reading config file\n"));
128 memset(configbuffer, 0, sizeof(configbuffer));
130 if (GetVar("ReqTools.prefs",
131 configbuffer,
132 sizeof(configbuffer),
133 GVF_BINARY_VAR | GVF_GLOBAL_ONLY | LV_VAR | GVF_DONT_NULL_TERM) == RTPREFS_SIZE)
135 UBYTE *configptr = configbuffer;
136 ULONG val;
137 WORD i;
139 D(bug("reqtools.library: Inside libopen func. Configfile loaded successfully\n"));
141 #define READ_ULONG *((ULONG *)configptr);configptr += sizeof(ULONG)
142 #define READ_UWORD *((UWORD *)configptr);configptr += sizeof(UWORD)
143 #define RTPREFS (RTBase->ReqToolsPrefs)
145 val = READ_ULONG;
146 RTPREFS.Flags = AROS_LONG2BE(val);
148 for(i = 0;i < RTPREF_NR_OF_REQ; i++)
150 val = READ_ULONG;
151 RTPREFS.ReqDefaults[i].Size = AROS_LONG2BE(val);
153 val = READ_ULONG;
154 RTPREFS.ReqDefaults[i].ReqPos = AROS_LONG2BE(val);
156 val = READ_UWORD;
157 RTPREFS.ReqDefaults[i].LeftOffset = AROS_WORD2BE(val);
159 val = READ_UWORD;
160 RTPREFS.ReqDefaults[i].TopOffset = AROS_WORD2BE(val);
162 val = READ_UWORD;
163 RTPREFS.ReqDefaults[i].MinEntries = AROS_WORD2BE(val);
165 val = READ_UWORD;
166 RTPREFS.ReqDefaults[i].MaxEntries = AROS_WORD2BE(val);
170 RTBase->ReqToolsPrefs.IsLoaded = TRUE;
172 } /* if (! RTBase->ReqToolsPrefs.IsLoaded) */
174 if(IntuitionBase == NULL)
175 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37);
176 RTBase->IntuitionBase = IntuitionBase;
177 if(IntuitionBase == NULL)
178 return NULL;
180 if(GfxBase == NULL)
181 GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37);
182 RTBase->GfxBase = GfxBase;
183 if(GfxBase == NULL)
184 return NULL;
186 if(UtilityBase == NULL)
187 UtilityBase = (struct UtilityBase *)OpenLibrary("utility.library", 37);
188 RTBase->UtilityBase = UtilityBase;
189 if(UtilityBase == NULL)
190 return NULL;
192 if(GadToolsBase == NULL)
193 GadToolsBase = OpenLibrary("gadtools.library", 37);
194 RTBase->GadToolsBase = GadToolsBase;
195 if(GadToolsBase == NULL)
196 return NULL;
198 if(LayersBase == NULL)
199 LayersBase = OpenLibrary("layers.library", 37);
200 if(LayersBase == NULL)
201 return NULL;
203 if(LocaleBase == NULL)
204 LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library", 37);
205 if(LocaleBase == NULL)
206 return NULL;
208 D(bug("reqtools.library: Inside libopen func. Libraries opened successfully.\n"));
210 if (ConsoleDevice == NULL)
212 iorequest.io_Message.mn_Length = sizeof(iorequest);
214 if (OpenDevice("console.device", CONU_LIBRARY, (struct IORequest *)&iorequest, 0))
216 return NULL;
218 ConsoleDevice = iorequest.io_Device;
220 if (ConsoleDevice == NULL)
221 return NULL;
223 D(bug("reqtools.library: Inside libopen func. Console.device opened successfully.\n"));
225 if (ButtonImgClass == NULL)
227 ButtonImgClass = MakeClass(NULL, IMAGECLASS, NULL, sizeof(struct LocalObjData), 0);
228 if (ButtonImgClass)
230 ButtonImgClass->cl_Dispatcher.h_Entry = (APTR)AROS_ASMSYMNAME(myBoopsiDispatch);
231 ButtonImgClass->cl_Dispatcher.h_SubEntry = NULL;
232 ButtonImgClass->cl_UserData = (IPTR)RTBase;
235 if (ButtonImgClass == NULL)
236 return NULL;
238 D(bug("reqtools.library: Inside libopen func. ButtonImgClass create successfully.\n"));
240 #ifndef __AROS__
241 /* I have one more opener. */
242 RTBase->LibNode.lib_Flags &= ~LIBF_DELEXP;
243 RTBase->LibNode.lib_OpenCnt++;
244 #endif
246 D(bug("reqtools.library: Inside libopen func. Returning success.\n"));
248 return RTBase;
251 /****************************************************************************************/
253 SAVEDS ASM BPTR RTFuncs_Close(REGPARAM(a6, struct ReqToolsBase *, RTBase))
255 #ifndef __AROS__
256 /* I have one fewer opener. */
257 RTBase->LibNode.lib_OpenCnt--;
259 if((RTBase->LibNode.lib_Flags & LIBF_DELEXP) != 0)
261 /* CHECKME: used expunge() from reqtools_intern.h. */
263 if(RTBase->LibNode.lib_OpenCnt == 0)
264 return RTFuncs_Expunge(RTBase);
266 RTBase->LibNode.lib_Flags &= ~LIBF_DELEXP;
268 #endif
270 return BNULL;
273 /****************************************************************************************/
275 SAVEDS ASM BPTR RTFuncs_Expunge(REGPARAM(a6, struct ReqToolsBase *, RTBase))
277 BPTR ret = BNULL;
279 #ifndef __AROS__
280 if(RTBase->LibNode.lib_OpenCnt != 0)
282 /* Set the delayed expunge flag and return. */
283 RTBase->LibNode.lib_Flags |= LIBF_DELEXP;
284 return BNULL;
287 /* Get rid of the library. Remove it from the list. */
288 Remove(&RTBase->LibNode.lib_Node);
290 /* Get returncode here - FreeMem() will destroy the field. */
291 ret = RTBase->SegList;
292 #endif
294 D(bug("reqtools.library: Inside libexpunge func. Freeing ButtonImgClass.\n"));
296 if (ButtonImgClass) FreeClass(ButtonImgClass);
298 D(bug("reqtools.library: Inside libexpunge func. Closing console.device.\n"));
300 if (ConsoleDevice) CloseDevice((struct IORequest *)&iorequest);
302 D(bug("reqtools.library: Inside libexpunge func. Closing libraries.\n"));
304 CloseLibrary((struct Library *)DOSBase);
305 CloseLibrary((struct Library *)IntuitionBase);
306 CloseLibrary((struct Library *)UtilityBase);
307 CloseLibrary((struct Library *)GfxBase);
308 CloseLibrary((struct Library *)LocaleBase);
309 CloseLibrary(GadToolsBase);
310 CloseLibrary(LayersBase);
312 D(bug("reqtools.library: Inside libexpunge func. Freeing libbase.\n"));
314 #ifndef __AROS__
315 /* Free the memory. */
316 FreeMem((char *)RTBase-RTBase->LibNode.lib_NegSize,
317 RTBase->LibNode.lib_NegSize + RTBase->LibNode.lib_PosSize);
318 #endif
319 ret = (BPTR)TRUE;
321 return ret;
324 /****************************************************************************************/
326 SAVEDS ASM int RTFuncs_Null(REGPARAM(a6, struct ReqToolsBase *, RTBase))
328 return 0;
332 /****************************************************************************************/
334 SAVEDS ASM struct ReqToolsPrefs *RTFuncs_LockPrefs(REGPARAM(a6, struct ReqToolsBase *, ReqToolsBase))
336 ObtainSemaphore(&ReqToolsBase->ReqToolsPrefs.PrefsSemaphore);
338 return &ReqToolsBase->ReqToolsPrefs;
341 /****************************************************************************************/
343 SAVEDS ASM void RTFuncs_UnlockPrefs(REGPARAM(a6, struct ReqToolsBase *, ReqToolsBase))
345 ReleaseSemaphore(&ReqToolsBase->ReqToolsPrefs.PrefsSemaphore);
348 /****************************************************************************************/
350 SAVEDS ASM IPTR RTFuncs_rtReqHandlerA(REGPARAM(a1, struct rtHandlerInfo *, handlerinfo),
351 REGPARAM(d0, ULONG, sigs),
352 REGPARAM(a0, struct TagItem *, taglist))
354 return ((IPTR (*)(REGPARAM(a1, struct rtHandlerInfo *,),
355 REGPARAM(d0, ULONG,),
356 REGPARAM(a0, struct TagItem *,)))handlerinfo->private1)(handlerinfo, sigs, taglist);
359 /****************************************************************************************/
361 SAVEDS ASM void RTFuncs_rtSetWaitPointer(REGPARAM(a0, struct Window *, window))
363 struct TagItem tags[] = { { WA_BusyPointer, TRUE },
364 { TAG_DONE, 0 } };
366 SetWindowPointerA(window, (struct TagItem *)&tags);
369 /****************************************************************************************/
371 SAVEDS ASM APTR RTFuncs_rtLockWindow(REGPARAM(a0, struct Window *, window))
373 struct rtWindowLock *winLock;
375 /* Is this window already locked? */
376 if(window->FirstRequest != NULL)
378 struct rtWindowLock *wLock = (struct rtWindowLock *)window->FirstRequest;
380 while(wLock != NULL)
382 if(wLock->rtwl_Magic == ('r' << 24 | 't' << 16 | 'L' << 8 | 'W'))
384 if(wLock->rtwl_RequesterPtr == wLock)
386 /* Window was already locked */
387 wLock->rtwl_LockCount++;
389 return wLock;
393 wLock = (struct rtWindowLock *)wLock->rtwl_Requester.OlderRequest;
396 winLock = (struct rtWindowLock *)AllocVec(sizeof(struct rtWindowLock),
397 MEMF_CLEAR);
399 /* No memory? */
400 if(winLock == NULL)
401 return NULL;
403 winLock->rtwl_Magic = 'r' << 24 | 't' << 16 | 'L' << 8 | 'W';
404 winLock->rtwl_RequesterPtr = winLock;
406 winLock->rtwl_MinHeight = window->MinHeight;
407 winLock->rtwl_MaxHeight = window->MaxHeight;
408 winLock->rtwl_MinWidth = window->MinWidth;
409 winLock->rtwl_MaxWidth = window->MaxWidth;
411 WindowLimits(window, window->Width, window->Height,
412 window->Width, window->Height);
414 InitRequester((struct Requester *)winLock);
415 winLock->rtwl_ReqInstalled = Request((struct Requester *)winLock, window);
417 winLock->rtwl_Pointer = window->Pointer;
418 winLock->rtwl_PtrHeight = window->PtrHeight;
419 winLock->rtwl_PtrWidth = window->PtrWidth;
421 rtSetWaitPointer(window);
423 return (APTR)winLock;
426 /****************************************************************************************/
428 SAVEDS ASM VOID RTFuncs_rtUnlockWindow(REGPARAM(a0, struct Window *, window),
429 REGPARAM(a1, APTR, windowlock))
432 struct rtWindowLock *wLock = (struct rtWindowLock *)windowlock;
434 if(wLock == NULL)
435 return;
437 if(wLock->rtwl_LockCount != 0)
439 wLock->rtwl_LockCount--;
441 else
443 struct TagItem tags[] = { { WA_Pointer, (IPTR)wLock->rtwl_Pointer },
444 { TAG_DONE , 0 } };
446 SetWindowPointerA(window, tags);
448 if (wLock->rtwl_ReqInstalled)
449 EndRequest((struct Requester *)wLock, window);
451 WindowLimits(window, wLock->rtwl_MinWidth, wLock->rtwl_MinHeight,
452 wLock->rtwl_MaxWidth, wLock->rtwl_MaxHeight);
454 FreeVec(wLock);
458 /****************************************************************************************/
460 SAVEDS ASM void RTFuncs_rtSpread(REGPARAM(a0, ULONG *, posarray),
461 REGPARAM(a1, ULONG *, sizearray),
462 REGPARAM(d0, ULONG, totalsize),
463 REGPARAM(d1, ULONG, min),
464 REGPARAM(d2, ULONG, max),
465 REGPARAM(d3, ULONG, num))
467 ULONG gadpos = min << 16;
468 ULONG gadgap;
469 UWORD i;
471 gadgap = ((max - min - totalsize) << 16) / (num - 1);
473 posarray[0] = min;
475 for(i = 1; i < num - 1; i++)
477 gadpos += (sizearray[i - 1] << 16) + gadgap;
478 posarray[i] = gadpos >> 16;
481 posarray[num - 1] = max - sizearray[i];
485 /****************************************************************************************/
487 SAVEDS ASM void RTFuncs_ScreenToFrontSafely(REGPARAM(a0, struct Screen *, screen))
489 #ifndef USE_FORBID
490 ULONG ilock;
491 #endif
492 struct Screen *scr;
494 /* Bugfixes: 1. Lock *before* peeking IntuitionBase->FirstScreen
495 2. Favor LockIBase() over Forbid() */
497 #ifdef USE_FORBID
498 Forbid();
499 #else
500 ilock = LockIBase(0);
501 #endif
503 scr = IntuitionBase->FirstScreen;
505 while(scr != NULL)
507 if(scr == screen)
509 #ifdef USE_FORBID
510 ScreenToFront(screen);
511 break;
512 #else
513 /* Forbid before UnlockIBase() to avoid screen from disappearing */
514 Forbid();
516 /* UnlockIBase() basically does ReleaseSemaphore() and that never
517 Wait(), and thus cannot break Forbid(). */
518 UnlockIBase(ilock);
520 /* Actually this will break the Forbid() if it need to Wait() for
521 semaphore, so this function isn't 100% bulletproof anyway... */
522 ScreenToFront(screen);
524 Permit();
526 /* Note: return not break!
528 return;
529 #endif
532 scr = scr->NextScreen;
535 #ifdef USE_FORBID
536 Permit();
537 #else
538 UnlockIBase(ilock);
539 #endif
542 /****************************************************************************************/
544 SAVEDS ASM void RTFuncs_rtSetReqPosition(REGPARAM(d0, ULONG, reqpos),
545 REGPARAM(a0, struct NewWindow *, nw),
546 REGPARAM(a1, struct Screen *, scr),
547 REGPARAM(a2, struct Window *, win))
549 /* TODO: Taken from rtfuncs.asm where the C version was in comments. Might be out of date
552 int mx = 0, my = 0, val, leftedge, topedge;
553 ULONG scrwidth, scrheight;
554 int width, height, left, top;
556 rtGetVScreenSize (scr, &scrwidth, &scrheight);
558 leftedge = -scr->LeftEdge;
559 if (leftedge < 0) leftedge = 0;
561 topedge = -scr->TopEdge;
562 if (topedge < 0) topedge = 0;
564 left = leftedge; top = topedge;
565 width = scrwidth; height = scrheight;
567 switch (reqpos)
569 case REQPOS_DEFAULT:
570 nw->LeftEdge = 25;
571 nw->TopEdge = 18;
572 goto topleftscr;
574 case REQPOS_POINTER:
575 mx = scr->MouseX; my = scr->MouseY;
576 break;
578 case REQPOS_CENTERWIN:
579 if (win)
581 left = win->LeftEdge; top = win->TopEdge;
582 width = win->Width; height = win->Height;
585 case REQPOS_CENTERSCR:
586 mx = (width - nw->Width) / 2 + left;
587 my = (height - nw->Height) / 2 + top;
588 break;
590 case REQPOS_TOPLEFTWIN:
591 if (win)
593 left = win->LeftEdge;
594 top = win->TopEdge;
597 case REQPOS_TOPLEFTSCR:
598 topleftscr:
599 mx = left; my = top;
600 break;
602 } /* switch (reqpos) */
604 /* keep window completely visible */
605 mx += nw->LeftEdge; my += nw->TopEdge;
606 val = leftedge + scrwidth - nw->Width;
608 if (mx < leftedge) mx = leftedge;
609 else if (mx > val) mx = val;
611 val = topedge + scrheight - nw->Height;
613 if (my < topedge) my = topedge;
614 else if (my > val) my = val;
616 nw->LeftEdge = mx; nw->TopEdge = my;
620 /****************************************************************************************/
622 /* This one is from closewindowsafely.asm */
624 SAVEDS ASM void RTFuncs_CloseWindowSafely(REGPARAM(a0, struct Window *, window))
626 struct IntuiMessage *msg;
627 struct Node *succ;
629 Forbid();
631 if(window->UserPort != NULL)
633 msg = (struct IntuiMessage *)window->UserPort->mp_MsgList.lh_Head;
635 while((succ = msg->ExecMessage.mn_Node.ln_Succ))
637 if(msg->IDCMPWindow == window)
639 Remove((struct Node *)msg);
640 ReplyMsg((struct Message *)msg);
643 msg = (struct IntuiMessage *)succ;
647 window->UserPort = NULL;
649 ModifyIDCMP(window, 0);
651 Permit();
653 CloseWindow(window);
656 /****************************************************************************************/
657 /****************************************************************************************/