Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / asl / basicfuncs.c
blobc8987b56e79bbf827147293f03df0ab5494dc96f
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Basic helpfuncs for Asl.
6 Lang: english
7 */
10 #include <proto/exec.h>
11 #include <proto/utility.h>
12 #include <proto/intuition.h>
13 #include <proto/iffparse.h>
14 #include <proto/diskfont.h>
15 #include <proto/graphics.h>
16 #include <proto/gadtools.h>
17 #include <proto/dos.h>
18 #include <proto/locale.h>
20 #include <exec/lists.h>
21 #include <exec/memory.h>
22 #include <intuition/intuition.h>
23 #include <intuition/screens.h>
24 #include <intuition/classusr.h>
25 #include <intuition/imageclass.h>
26 #include <graphics/gfxbase.h>
27 #include <devices/rawkeycodes.h>
28 #include <prefs/prefhdr.h>
29 #include <prefs/font.h>
30 #include <libraries/iffparse.h>
32 #include <string.h>
34 #include "asl_intern.h"
35 #include "layout.h"
37 #define SDEBUG 0
38 #define DEBUG 0
40 #include <aros/debug.h>
42 /*****************************************************************************************/
44 STATIC BOOL GetRequesterFont(struct LayoutData *, struct AslBase_intern *);
46 #if 0
47 STATIC struct FontPrefs *GetFontPrefs(struct AslBase_intern *);
48 STATIC VOID FreeFontPrefs(struct FontPrefs *, struct AslBase_intern *);
49 #endif
51 /*****************************************************************************************/
53 /* Finds the internal requester data for a requester */
55 struct ReqNode *FindReqNode(APTR req, struct AslBase_intern *AslBase)
57 struct ReqNode *reqnode, *foundreqnode = NULL;
59 ObtainSemaphoreShared( &(AslBase->ReqListSem) );
61 ForeachNode( &(AslBase->ReqList), reqnode)
63 if (reqnode->rn_Req == req)
65 foundreqnode = reqnode;
66 break;
70 ReleaseSemaphore( &(AslBase->ReqListSem) );
72 return (foundreqnode);
75 /*****************************************************************************************/
77 VOID ParseCommonTags
79 struct IntReq *intreq,
80 struct TagItem *taglist,
81 struct AslBase_intern *AslBase
84 struct TagItem *tag;
85 const struct TagItem *tstate = taglist;
87 while ((tag = NextTagItem(&tstate)) != NULL)
89 IPTR tidata = tag->ti_Data;
91 /* The tags that are put "in a row" are defined as the same value,
92 and therefor we only use one of them, but the effect is for all of them
95 switch (tag->ti_Tag)
97 case ASLFR_Window:
98 /* case ASLFO_Window:
99 case ASLSM_Window:
100 case ASL_Window: */ /* Obsolete */
101 intreq->ir_Window = (struct Window *)tidata;
102 break;
104 case ASLFR_Screen:
105 /* case ASLFO_Screen:
106 case ASLSM_Screen: */
107 intreq->ir_Screen = (struct Screen *)tidata;
108 break;
110 case ASLFR_PubScreenName:
111 /* case ASLFO_PubScreenName:
112 case ASLSM_PubScreenName: */
113 if (tidata)
114 intreq->ir_PubScreenName = (STRPTR)tidata;
115 break;
117 case ASLFR_PrivateIDCMP:
118 /* case ASLFO_PrivateIDCMP:
119 case ASLSM_PrivateIDCMP: */
120 if (tidata)
121 intreq->ir_Flags |= IF_PRIVATEIDCMP;
122 else
123 intreq->ir_Flags &= ~IF_PRIVATEIDCMP;
124 break;
127 case ASLFR_IntuiMsgFunc:
128 /* case ASLFO_IntuiMsgFunc:
129 case ASLSM_IntuiMsgFunc: */
130 intreq->ir_IntuiMsgFunc = (struct Hook *)tidata;
131 break;
133 case ASLFR_SleepWindow:
134 /* case ASLFO_SleepWindow:
135 case ASLSM_SleepWindow: */
136 if (tidata)
137 intreq->ir_Flags |= IF_SLEEPWINDOW;
138 else
139 intreq->ir_Flags &= ~IF_SLEEPWINDOW;
140 break;
142 case ASLFR_PopToFront:
143 /* case ASLFO_PopToFront:
144 case ASLSM_PopToFront: */
145 if (tidata)
146 intreq->ir_Flags |= IF_POPTOFRONT;
147 else
148 intreq->ir_Flags &= ~IF_POPTOFRONT;
149 break;
151 case ASLFR_Activate:
152 /* case ASLFO_Activate:
153 case ASLSM_Activate: */
154 if (tidata)
155 intreq->ir_Flags &= ~IF_OPENINACTIVE;
156 else
157 intreq->ir_Flags |= IF_OPENINACTIVE;
158 break;
160 case ASLFR_TextAttr:
161 /* case ASLFO_TextAttr:
162 case ASLSM_TextAttr: */
163 intreq->ir_TextAttr = (struct TextAttr *)tidata;
164 break;
166 case ASLFR_Locale:
167 /* case ASLFO_Locale:
168 case ASLSM_Locale: */
169 intreq->ir_Locale = (struct Locale *)tidata;
170 break;
172 case ASLFR_TitleText:
173 /* case ASLFO_TitleText:
174 case ASLSM_TitleText:
175 case ASL_Hail: */ /* Obsolete */
176 if (tidata)
177 intreq->ir_TitleText = (STRPTR)tidata;
178 break;
181 case ASLFR_PositiveText:
182 /* case ASLFO_PositiveText:
183 case ASLSM_PositiveText:
184 case ASL_OKText: */ /* Obsolete */
185 if (tidata)
187 intreq->ir_PositiveText = (STRPTR)tidata;
188 intreq->ir_Flags |= IF_USER_POSTEXT;
190 break;
192 case ASLFR_NegativeText:
193 /* case ASLFO_NegativeText:
194 case ASLSM_NegativeText:
195 case ASL_CancelText: */ /* Obsolete */
196 if (tidata)
198 intreq->ir_NegativeText = (STRPTR)tidata;
199 intreq->ir_Flags |= IF_USER_NEGTEXT;
201 break;
203 case ASLFR_InitialLeftEdge:
204 /* case ASLFO_InitialLeftEdge:
205 case ASLSM_InitialLeftEdge:
206 case ASL_LeftEdge: */ /* Obsolete */
207 intreq->ir_LeftEdge = (UWORD)tidata;
208 break;
210 case ASLFR_InitialTopEdge:
211 /* case ASLFO_InitialTopEdge:
212 case ASLSM_InitialTopEdge:
213 case ASL_TopEdge: */ /* Obsolete */
214 intreq->ir_TopEdge = (UWORD)tidata;
215 break;
217 case ASLFR_InitialWidth:
218 /* case ASLFO_InitialWidth:
219 case ASLSM_InitialWidth:
220 case ASL_Width: */ /* Obsolete */
221 intreq->ir_Width = (UWORD)tidata;
222 break;
224 case ASLFR_InitialHeight:
225 /* case ASLFO_InitialHeight:
226 case ASLSM_InitialHeight:
227 case ASL_Height: */ /* Obsolete */
228 intreq->ir_Height = (UWORD)tidata;
229 break;
231 default:
232 break;
234 } /* switch (tag->ti_Tag) */
236 } /* while ((tag = NextTagItem((const struct TagItem **)&tstate)) != NULL) */
237 return;
240 /*****************************************************************************************/
242 VOID FreeCommon(struct LayoutData *ld, struct AslBase_intern *AslBase)
244 if (ld)
247 if (ld->ld_IntReq->ir_Catalog) CloseCatalog(ld->ld_IntReq->ir_Catalog);
249 if (ld->ld_Menu)
251 if (ld->ld_Window)
252 ClearMenuStrip(ld->ld_Window);
254 FreeMenus(ld->ld_Menu);
257 if (ld->ld_Window)
259 if (ld->ld_IntReq->ir_Flags & IF_POPPEDTOFRONT)
261 ld->ld_IntReq->ir_Flags &= ~IF_POPPEDTOFRONT;
262 ScreenToBack(ld->ld_Window->WScreen);
265 if ((ld->ld_IntReq->ir_Flags & IF_PRIVATEIDCMP) || (!ld->ld_IntReq->ir_Window))
267 CloseWindow(ld->ld_Window);
269 else
271 CloseWindowSafely(ld->ld_Window, AslBase);
275 D(bug("Window freed\n"));
277 if (ld->ld_VisualInfo) FreeVisualInfo(ld->ld_VisualInfo);
278 if (ld->ld_Dri) FreeScreenDrawInfo(ld->ld_Screen, ld->ld_Dri);
280 if (ld->ld_ScreenLocked)
281 UnlockPubScreen(NULL, ld->ld_Screen);
283 if (ld->ld_UserData)
284 FreeVec(ld->ld_UserData);
286 if (ld->ld_Font)
287 CloseFont(ld->ld_Font);
289 if (ld->ld_TextAttr.ta_Name)
290 FreeVec(ld->ld_TextAttr.ta_Name);
292 DeinitRastPort(&(ld->ld_DummyRP));
294 FreeMem(ld, sizeof (struct LayoutData));
297 return;
300 /*****************************************************************************************/
302 struct LayoutData *AllocCommon
304 ULONG udatasize,
305 struct IntReq *intreq,
306 APTR requester,
307 struct AslBase_intern *AslBase
310 struct Screen *screen = NULL;
311 struct LayoutData *ld;
314 ld = AllocMem(sizeof (struct LayoutData), MEMF_ANY|MEMF_CLEAR);
315 if (!ld)
316 goto failure;
318 /* Save the internal and public requester struct, so that the
319 requester type specific hook may find them */
320 ld->ld_IntReq = intreq;
321 ld->ld_Req = requester;
323 InitRastPort(&(ld->ld_DummyRP));
325 /* We need to lock the screen we should open on to be sure it
326 doesn't go away
329 /* Find screen on which to open window */
331 screen = intreq->ir_Screen;
332 if (!screen && intreq->ir_PubScreenName)
334 if ((screen = LockPubScreen(intreq->ir_PubScreenName)))
336 ld->ld_ScreenLocked = TRUE;
339 if (!screen && intreq->ir_Window)
341 screen = intreq->ir_Window->WScreen;
343 if (!screen && !intreq->ir_PubScreenName)
345 if ((screen = LockPubScreen(NULL)))
347 ld->ld_ScreenLocked = TRUE;
351 if (!screen) goto failure;
353 ld->ld_Screen = screen;
355 if (!(ld->ld_Dri = GetScreenDrawInfo(screen))) goto failure;
357 if (!(ld->ld_VisualInfo = GetVisualInfoA(screen, NULL))) goto failure;
359 ld->ld_WBorLeft = screen->WBorLeft;
360 ld->ld_WBorTop = screen->WBorTop + screen->Font->ta_YSize + 1;
361 ld->ld_WBorRight = screen->WBorRight;
362 ld->ld_WBorBottom = 16;
365 struct TagItem sysi_tags[] =
367 {SYSIA_DrawInfo , (IPTR)ld->ld_Dri },
368 {SYSIA_Which , SIZEIMAGE },
369 {TAG_DONE }
372 Object *im;
374 if ((im = NewObjectA(NULL, SYSICLASS, sysi_tags)))
376 IPTR height;
378 if (GetAttr(IA_Height, im, &height))
380 ld->ld_WBorBottom = height;
382 DisposeObject(im);
387 if(GetBitMapAttr(screen->RastPort.BitMap, BMA_DEPTH) > 8) ld->ld_TrueColor = TRUE;
389 if (!(ld->ld_UserData = AllocVec(udatasize, MEMF_ANY|MEMF_CLEAR)))
390 goto failure;
392 if (!GetRequesterFont(ld, ASLB(AslBase)))
393 goto failure;
395 SetFont( &(ld->ld_DummyRP), ld->ld_Font );
397 if (LocaleBase)
399 struct TagItem tags[] =
401 {OC_BuiltInLanguage , (IPTR)"english"},
402 {OC_Version , 0 },
403 {TAG_DONE }
406 intreq->ir_Catalog = OpenCatalogA(intreq->ir_Locale, "System/Libs/asl.catalog", tags);
409 return (ld);
411 failure:
412 FreeCommon(ld, ASLB(AslBase));
414 return (NULL);
418 /*****************************************************************************************/
420 #define SKIPLONG(ptr, num) ptr += sizeof (LONG) * num
422 #define CONVBYTE(ptr, dest) dest = *ptr ++
424 #define SKIPBYTE(ptr) ptr ++;
426 #define CONVWORD(ptr, dest) dest = ptr[0] << 8 | ptr[1]; \
427 ptr += sizeof (WORD);
429 /*****************************************************************************************/
431 #if 0
433 STATIC struct FontPrefs *GetFontPrefs(struct AslBase_intern *AslBase)
435 struct IFFHandle *iff;
436 struct Library *IFFParseBase;
438 struct StoredProperty *sp;
440 struct FontPrefs *fp = NULL;
442 IFFParseBase = OpenLibrary("iffparse.library", 0);
443 if (IFFParseBase)
445 iff = AllocIFF();
446 if (iff)
449 iff->iff_Stream = (IPTR)Open("ENV:Sys/font.prefs", MODE_OLDFILE);
450 if (iff->iff_Stream)
452 InitIFFasDOS(iff);
454 if (OpenIFF(iff, IFFF_READ) == 0)
456 PropChunk(iff, ID_PREF, ID_FONT);
459 if (ParseIFF(iff, IFFPARSE_SCAN) != 0)
462 sp = FindProp(iff, ID_PREF, ID_FONT);
463 if (sp)
466 fp = AllocMem(sizeof (struct FontPrefs), MEMF_ANY);
467 if (fp)
469 UBYTE *ptr;
470 STRPTR fontname;
473 /* Set ptr to start of struct FontPrefs */
474 ptr = sp->sp_Data;
476 /* Skip 4 first reserved longs */
477 SKIPLONG(ptr, 4);
478 CONVBYTE(ptr, fp->fp_FrontPen);
479 CONVBYTE(ptr, fp->fp_BackPen);
480 CONVBYTE(ptr, fp->fp_DrawMode);
482 CONVWORD(ptr, fp->fp_TextAttr.ta_YSize);
483 CONVBYTE(ptr, fp->fp_TextAttr.ta_Style);
484 CONVBYTE(ptr, fp->fp_TextAttr.ta_Flags);
487 fontname = AllocVec( strlen(ptr) + 1, MEMF_ANY);
488 if (fontname)
490 strcpy(fontname, ptr);
492 fp->fp_TextAttr.ta_Name = fontname;
494 else
496 FreeMem(fp, sizeof (struct FontPrefs));
497 fp = NULL;
500 } /* if (tattr) */
502 } /* if (sp) */
504 } /* if (ParseIFF(iff, IFFPARSE_SCAN) != 0) */
505 CloseIFF(iff);
507 } /* if (OpenIFF(iff)) */
508 Close( (BPTR)iff->iff_Stream );
510 } /* if (iff->iff_Stream) */
511 FreeIFF(iff);
513 } /* if (iff) */
514 CloseLibrary(IFFParseBase);
516 } /* if (IFFParseBase) */
518 return (fp);
520 } /* GetFontPrefs() */
522 #endif
524 /*****************************************************************************************/
526 #if 0
528 STATIC VOID FreeFontPrefs(struct FontPrefs *fp, struct AslBase_intern *AslBase)
531 FreeVec(fp->fp_TextAttr.ta_Name);
532 FreeMem(fp, sizeof (struct FontPrefs));
534 return;
537 #endif
539 /*****************************************************************************************/
541 BOOL GetRequesterFont(struct LayoutData *ld, struct AslBase_intern *AslBase)
543 struct TextFont *font = NULL;
545 struct TextAttr *usedattr, askattr;
547 BOOL success = FALSE;
549 static struct TextAttr topaz8 = {"topaz.font", 8, 0, 0 };
551 /* Default to satisfy GCC */
552 usedattr = &topaz8;
555 Open the font we should use in the GUI.
556 First look for a user supplied TextAttr.
557 If not present, try to get the font preferences from ENV:Sys/font.prefs
558 If this fails, we fall back to topaz 8
561 /* Is there a user supplied font */
562 usedattr = ld->ld_IntReq->ir_TextAttr;
564 if (usedattr)
566 font = OpenDiskFont (usedattr);
569 /* If not, try screen font */
571 if (!font)
573 usedattr = ld->ld_Screen->Font;
574 if (usedattr)
576 font = OpenDiskFont (usedattr);
580 #if 0
581 /* If no font has been opened yet, try the preferences one */
582 if (!font)
584 struct FontPrefs *fprefs;
586 fprefs = GetFontPrefs(ASLB(AslBase));
587 if (fprefs)
589 D(bug("Fontprefs found\n"));
591 D(bug("Name: %s, YSize :%d", fprefs->fp_TextAttr.ta_Name, fprefs->fp_TextAttr.ta_YSize));
593 usedattr = &(fprefs->fp_TextAttr);
594 font = OpenDiskFont(usedattr);
596 if (!font)
598 FreeFontPrefs(fprefs, ASLB(AslBase));
602 #endif
604 /* No success, so try system default font */
606 if (!font)
608 usedattr = &askattr;
610 SetFont(&(ld->ld_DummyRP), GfxBase->DefaultFont);
611 AskFont(&(ld->ld_DummyRP), usedattr);
613 font = OpenDiskFont(usedattr);
616 /* Yet no font, try topaz 8 */
618 if (!font)
620 usedattr = &topaz8;
622 /* Here we should really use OpenDiskFont, but
623 * since AROS can't render diskfonts yet, we must use OpenFont()
626 font = OpenFont(usedattr);
629 if (font)
631 STRPTR fontname;
632 /* We have to store the used textattr for later */
634 fontname = AllocVec (strlen (usedattr->ta_Name) + 1, MEMF_ANY);
636 if (fontname)
638 strcpy (fontname, usedattr->ta_Name);
640 ld->ld_TextAttr.ta_Name = fontname;
641 ld->ld_TextAttr.ta_YSize = usedattr->ta_YSize;
642 ld->ld_TextAttr.ta_Style = usedattr->ta_Style;
643 ld->ld_TextAttr.ta_Flags = usedattr->ta_Flags;
645 ld->ld_Font = font;
647 success = TRUE;
650 return (success);
653 /*****************************************************************************************/
655 BOOL HandleEvents(struct LayoutData *ld, struct AslReqInfo *reqinfo, struct AslBase_intern *AslBase)
657 struct IntReq *intreq = ld->ld_IntReq;
658 APTR req = ld->ld_Req;
659 struct IntuiMessage *imsg;
660 struct MsgPort *port;
661 BOOL success = TRUE;
662 BOOL terminated = FALSE;
664 EnterFunc(bug("HandleEvents(ld=%p, reqinfo=%p)\n", ld, reqinfo));
665 port = ld->ld_Window->UserPort;
667 while (!terminated)
669 if ((imsg = (struct IntuiMessage *)GetMsg(port)) != NULL)
671 if ((imsg->IDCMPWindow == ld->ld_Window) ||
672 (imsg->IDCMPWindow == ld->ld_Window2))
674 switch (imsg->Class)
676 case IDCMP_MOUSEMOVE:
677 break;
679 case IDCMP_NEWSIZE:
680 ld->ld_Command = LDCMD_LAYOUT;
681 CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase));
682 break;
684 case IDCMP_REFRESHWINDOW:
685 BeginRefresh(imsg->IDCMPWindow);
686 EndRefresh(imsg->IDCMPWindow, TRUE);
687 break;
689 default:
690 /* Call the requester specific hook to handle events */
691 ld->ld_Command = LDCMD_HANDLEEVENTS;
692 ld->ld_Event = imsg;
694 success = CallHookPkt( &(reqinfo->GadgetryHook), ld, ASLB(AslBase));
695 if (success == LDRET_FINISHED)
697 success = TRUE;
698 terminated = TRUE;
700 if (!success)
702 success = FALSE;
703 terminated = TRUE;
705 break;
708 } /* switch (imsg->Class */
710 } /* if (imsg->IDCMPWindow is ld->ld_Window or ld->ld_Window2) */
711 else if (intreq->ir_IntuiMsgFunc)
713 #ifdef __MORPHOS__
714 REG_A4 = (ULONG)intreq->ir_BasePtr; /* Compatability */
715 REG_A0 = (ULONG)intreq->ir_IntuiMsgFunc;
716 REG_A2 = (ULONG)req;
717 REG_A1 = (ULONG)imsg;
718 (*MyEmulHandle->EmulCallDirect68k)(intreq->ir_IntuiMsgFunc->h_Entry);
719 #else
720 CallHookPkt(intreq->ir_IntuiMsgFunc, req, imsg);
721 #endif
723 ReplyMsg((struct Message *)imsg);
725 } /* if ((imsg = GetMsg(port)) != NULL) */
726 else
728 Wait(1L << port->mp_SigBit);
731 } /* while (!terminated) */
733 ReturnBool ("HandleEvents", success);
735 } /* HandleEvents() */
737 /*****************************************************************************************/
739 UWORD BiggestTextLength(STRPTR *strarray,
740 UWORD numstrings,
741 struct RastPort *rp,
742 struct AslBase_intern * AslBase)
745 UWORD i, w = 0, new_w;
747 for (i = 0; strarray[i] && i < numstrings; i ++)
749 new_w = TextLength(rp, strarray[i], strlen(strarray[i]));
750 if (new_w > w)
752 w = new_w;
755 return (w);
758 /*****************************************************************************************/
760 /* Strip special info from the requester structure */
762 VOID StripRequester(APTR req, UWORD reqtype, struct AslBase_intern *AslBase)
764 switch (reqtype)
766 case ASL_FileRequest:
768 #undef GetFR
769 #define GetFR(r) ((struct FileRequester *)r)
772 * We can`t free it here, because it`s called by FreeAslRequest
773 * and AslRequest may have been overtaken by some other patch.
774 * Original FreeAslRequest doesn't free them.
775 * With MFR+mungwall it crashed here.
776 * It's freeed anyway when the Pool is deleted.
778 // dprintf("StripRequester: drawer 0x%lx\n",GetFR(req)->fr_Drawer);
779 // MyFreeVecPooled(GetFR(req)->fr_Drawer, AslBase);
780 GetFR(req)->fr_Drawer = NULL;
782 // dprintf("StripRequester: file 0x%lx\n",GetFR(req)->fr_File);
783 // MyFreeVecPooled(GetFR(req)->fr_File, AslBase);
784 GetFR(req)->fr_File = NULL;
786 // dprintf("StripRequester: pattern 0x%lx\n",GetFR(req)->fr_Pattern);
787 // MyFreeVecPooled(GetFR(req)->fr_Pattern, AslBase);
788 GetFR(req)->fr_Pattern = NULL;
790 // dprintf("StripRequester: arglist 0x%lx\n",GetFR(req)->fr_ArgList);
791 if (GetFR(req)->fr_ArgList)
793 struct WBArg *wbarg;
794 BPTR lock = GetFR(req)->fr_ArgList->wa_Lock;
796 // dprintf("StripRequester: lock 0x%lx\n",lock);
797 if (lock) UnLock(lock);
799 // dprintf("StripRequester: numargs 0x%lx\n",GetFR(req)->fr_NumArgs);
801 for (wbarg = GetFR(req)->fr_ArgList; GetFR(req)->fr_NumArgs --; wbarg ++)
803 // dprintf("StripRequester: wbarg 0x%lx\n",wbarg);
804 MyFreeVecPooled(wbarg->wa_Name, AslBase);
807 // dprintf("StripRequester: free arglist\n");
808 MyFreeVecPooled(GetFR(req)->fr_ArgList, AslBase);
809 GetFR(req)->fr_ArgList = NULL;
813 break;
815 case ASL_FontRequest:
817 #undef GetFO
818 #define GetFO(r) ((struct FontRequester *)r)
820 MyFreeVecPooled(GetFO(req)->fo_TAttr.tta_Name, AslBase);
821 GetFO(req)->fo_TAttr.tta_Name = NULL;
823 break;
825 case ASL_ScreenModeRequest:
826 break;
829 return;
832 /*****************************************************************************************/
834 WORD CountNodes(struct List *list, WORD flag)
836 struct Node *node;
837 WORD result = 0;
839 ForeachNode(list, node)
841 if ((node->ln_Pri & flag) == flag) result++;
844 return result;
847 /*****************************************************************************************/
849 struct Node *FindListNode(struct List *list, WORD which)
851 struct Node *node = NULL;
853 if (which >= 0)
855 for(node = list->lh_Head; node->ln_Succ && which; node = node->ln_Succ, which--)
858 if (!node->ln_Succ) node = NULL;
861 return node;
864 /*****************************************************************************************/
866 void SortInNode(APTR req, struct List *list, struct Node *node,
867 WORD (*compare)(APTR req, APTR node1, APTR node2, struct AslBase_intern *AslBase),
868 struct AslBase_intern *AslBase)
870 struct Node *prevnode = NULL;
871 struct Node *checknode;
873 ForeachNode(list, checknode)
875 if (compare(req, node, checknode, AslBase) < 0) break;
877 prevnode = checknode;
880 Insert(list, node, prevnode);
883 /*****************************************************************************************/
885 APTR MyAllocVecPooled(APTR pool, IPTR size, struct AslBase_intern *AslBase)
887 IPTR *mem;
889 //dprintf("MyAllocVecPooled: pool 0x%lx size %ld\n",pool,size);
891 size += sizeof(APTR) * 2;
893 if ((mem = AllocPooled(pool, size)))
895 //dprintf("MyAllocVecPooled: pool 0x%lx mem 0x%lx size %ld\n",pool,mem,size);
896 *mem++ = (IPTR)pool;
897 *mem++ = size;
898 //dprintf("MyAllocVecPooled: mem 0x%lx\n");
901 return mem;
904 /*****************************************************************************************/
906 void MyFreeVecPooled(APTR mem, struct AslBase_intern *AslBase)
908 IPTR *imem = (IPTR *)mem;
910 if (mem)
912 IPTR size = *--imem;
913 APTR pool = (APTR)*--imem;
915 //dprintf("MyFreeVecPooled: pool 0x%lx imem 0x%lx size %ld\n",pool,imem,size);
917 FreePooled(pool, imem, size);
921 /*****************************************************************************************/
923 char *PooledCloneString(const char *name1, const char *name2, APTR pool,
924 struct AslBase_intern *AslBase)
926 char *clone;
927 WORD len1 = strlen(name1) + 1;
928 WORD len2 = name2 ? strlen(name2) : 0;
930 if ((clone = AllocPooled(pool, len1 + len2)))
932 CopyMem(name1, clone, len1);
933 if (name2) CopyMem(name2, clone + len1 - 1, len2 + 1);
936 return clone;
939 /*****************************************************************************************/
941 char *PooledCloneStringLen(const char *name1, ULONG len1, const char *name2, ULONG len2, APTR pool,
942 struct AslBase_intern *AslBase)
944 char *clone;
945 if ((clone = AllocPooled(pool, len1 + len2 + 1)))
947 CopyMem(name1, clone, len1);
948 clone[len1] = '\0';
949 if (name2)
951 CopyMem(name2, clone + len1, len2);
953 clone[len1+len2] = '\0';
955 return clone;
958 /*****************************************************************************************/
960 char *VecCloneString(const char *name1, const char *name2, struct AslBase_intern *AslBase)
962 char *clone;
963 WORD len1 = strlen(name1) + 1;
964 WORD len2 = name2 ? strlen(name2) : 0;
966 if ((clone = AllocVec(len1 + len2, MEMF_PUBLIC)))
968 CopyMem(name1, clone, len1);
969 if (name2) CopyMem(name2, clone + len1 - 1, len2 + 1);
972 return clone;
975 /*****************************************************************************************/
977 char *VecPooledCloneString(const char *name1, const char *name2, APTR pool, struct AslBase_intern *AslBase)
979 char *clone;
980 WORD len1 = strlen(name1) + 1;
981 WORD len2 = name2 ? strlen(name2) : 0;
983 if ((clone = MyAllocVecPooled(pool, len1 + len2, AslBase)))
985 CopyMem(name1, clone, len1);
986 if (name2) CopyMem(name2, clone + len1 - 1, len2 + 1);
989 return clone;
992 /*****************************************************************************************/
994 AROS_UFH2 (void, puttostr,
995 AROS_UFHA(UBYTE, chr, D0),
996 AROS_UFHA(STRPTR *,strPtrPtr,A3)
999 AROS_USERFUNC_INIT
1000 *(*strPtrPtr)= chr;
1001 (*strPtrPtr) ++;
1002 AROS_USERFUNC_EXIT
1005 /*****************************************************************************************/
1007 char *PooledUIntegerToString(IPTR value, APTR pool, struct AslBase_intern *AslBase)
1009 char buffer[30];
1010 char *str = buffer;
1011 char *clone;
1012 WORD len;
1014 /* Create the text */
1016 RawDoFmt("%lu", &value, (VOID_FUNC)AROS_ASMSYMNAME(puttostr), &str);
1018 len = strlen(buffer) + 1;
1020 if ((clone = AllocPooled(pool, len)))
1022 CopyMem(buffer, clone, len);
1025 return clone;
1028 /*****************************************************************************************/
1030 void CloseWindowSafely(struct Window *window, struct AslBase_intern *AslBase)
1032 struct IntuiMessage *msg;
1033 struct Node *succ;
1035 Forbid();
1037 if(window->UserPort != NULL)
1039 msg = (struct IntuiMessage *)window->UserPort->mp_MsgList.lh_Head;
1041 while((succ = msg->ExecMessage.mn_Node.ln_Succ))
1043 if(msg->IDCMPWindow == window)
1045 Remove((struct Node *)msg);
1046 ReplyMsg((struct Message *)msg);
1049 msg = (struct IntuiMessage *)succ;
1053 window->UserPort = NULL;
1055 ModifyIDCMP(window, 0);
1057 Permit();
1059 CloseWindow(window);
1062 /*****************************************************************************************/
1064 AROS_UFH3(ULONG, StringEditFunc,
1065 AROS_UFHA(struct Hook *, hook, A0),
1066 AROS_UFHA(struct SGWork *, sgw, A2),
1067 AROS_UFHA(ULONG *, command, A1))
1069 AROS_USERFUNC_INIT
1071 ULONG retcode = 0;
1073 switch(*command)
1075 case SGH_KEY:
1076 retcode = 1;
1077 switch(sgw->IEvent->ie_Code)
1079 case RAWKEY_PAGEUP:
1080 case RAWKEY_PAGEDOWN:
1081 case RAWKEY_HOME:
1082 case RAWKEY_END:
1083 case RAWKEY_ESCAPE:
1084 case RAWKEY_NM_WHEEL_UP:
1085 case RAWKEY_NM_WHEEL_DOWN:
1086 sgw->Code = STRINGCODE_NOP;
1087 sgw->Actions = SGA_END | SGA_REUSE;
1088 break;
1090 case CURSORUP:
1091 sgw->EditOp = EO_SPECIAL;
1092 sgw->Code = STRINGCODE_CURSORUP;
1093 sgw->Actions = SGA_END;
1094 break;
1096 case CURSORDOWN:
1097 sgw->EditOp = EO_SPECIAL;
1098 sgw->Code = STRINGCODE_CURSORDOWN;
1099 sgw->Actions = SGA_END;
1100 break;
1102 break;
1106 return retcode;
1108 AROS_USERFUNC_EXIT
1112 /*****************************************************************************************/
1114 void PaintInnerFrame(struct RastPort *rp, struct DrawInfo *dri, Object *frameobj,
1115 struct IBox *framebox, struct IBox *innerbox, ULONG pen,
1116 struct AslBase_intern *AslBase)
1118 struct impFrameBox fmsg;
1119 struct IBox cbox;
1120 struct IBox fbox;
1121 WORD x1, y1, x2, y2;
1122 WORD ix1, iy1, ix2, iy2;
1124 cbox.Left = framebox->Left;
1125 cbox.Top = framebox->Top;
1126 cbox.Width = framebox->Width;
1127 cbox.Height = framebox->Height;
1129 fmsg.MethodID = IM_FRAMEBOX;
1130 fmsg.imp_ContentsBox = &cbox;
1131 fmsg.imp_FrameBox = &fbox;
1132 fmsg.imp_DrInfo = dri;
1133 fmsg.imp_FrameFlags = 0;
1135 DoMethodA(frameobj, (Msg)&fmsg);
1137 SetABPenDrMd(rp, pen, 0, JAM1);
1139 x1 = fbox.Left;
1140 y1 = fbox.Top;
1141 x2 = x1 + fbox.Width - 1;
1142 y2 = y1 + fbox.Height - 1;
1144 ix1 = cbox.Left;
1145 iy1 = cbox.Top;
1146 ix2 = ix1 + cbox.Width - 1;
1147 iy2 = iy1 + cbox.Height - 1;
1149 ix1 += (ix1 - x1);
1150 iy1 += (iy1 - y1);
1151 ix2 += (ix2 - x2);
1152 iy2 += (iy2 - y2);
1154 x1 = innerbox->Left - 1;
1155 y1 = innerbox->Top - 1;
1156 x2 = innerbox->Left + innerbox->Width;
1157 y2 = innerbox->Top + innerbox->Height;
1159 RectFill(rp, ix1, iy1, ix2, y1);
1160 RectFill(rp, ix1, iy1, x1, iy2);
1161 RectFill(rp, x2, iy1, ix2, iy2);
1162 RectFill(rp, ix1, y2, ix2, iy2);
1166 /*****************************************************************************************/
1168 void PaintBoxFrame(struct RastPort *rp, struct IBox *outerbox, struct IBox *innerbox,
1169 ULONG pen, struct AslBase_intern *AslBase)
1171 WORD x1, y1, x2, y2;
1172 WORD ix1, iy1, ix2, iy2;
1174 ix1 = outerbox->Left;
1175 iy1 = outerbox->Top - 1;
1176 ix2 = outerbox->Left + outerbox->Width - 1;
1177 iy2 = outerbox->Top + outerbox->Height - 1;
1179 x1 = innerbox->Left - 1;
1180 y1 = innerbox->Top - 1;
1181 x2 = innerbox->Left + innerbox->Width;
1182 y2 = innerbox->Top + innerbox->Height;
1184 SetABPenDrMd(rp, pen, 0, JAM1);
1186 RectFill(rp, ix1, iy1, ix2, y1);
1187 RectFill(rp, ix1, iy1, x1, iy2);
1188 RectFill(rp, x2, iy1, ix2, iy2);
1189 RectFill(rp, ix1, y2, ix2, iy2);
1193 /*****************************************************************************************/