Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / asl / aslrequest.c
blob16ea8a1525b4a53b495c8285c015d146d52a3801
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
8 #include <proto/dos.h>
9 #include <proto/utility.h>
10 #include <proto/intuition.h>
11 #include <proto/graphics.h>
12 #include <string.h>
13 #include <intuition/intuition.h>
14 #include "asl_intern.h"
16 struct LayoutData *AllocCommon(ULONG, struct IntReq *, APTR, struct AslBase_intern *);
17 VOID FreeCommon(struct LayoutData *, struct AslBase_intern *);
18 BOOL HandleEvents(struct LayoutData *, struct AslReqInfo *, struct AslBase_intern *);
21 #define SDEBUG 0
22 #define DEBUG 0
25 # include <aros/debug.h>
27 /*****************************************************************************
29 NAME */
30 #include <proto/asl.h>
31 #include <utility/tagitem.h>
33 AROS_LH2(BOOL, AslRequest,
35 /* SYNOPSIS */
36 AROS_LHA(APTR , requester, A0),
37 AROS_LHA(struct TagItem *, tagList, A1),
39 /* LOCATION */
40 struct Library *, AslBase, 10, Asl)
42 /* FUNCTION
44 INPUTS
46 RESULT
48 NOTES
50 EXAMPLE
52 BUGS
54 SEE ALSO
56 INTERNALS
58 HISTORY
59 27-11-96 digulla automatically created from
60 asl_lib.fd and clib/asl_protos.h
62 *****************************************************************************/
64 AROS_LIBFUNC_INIT
66 struct ReqNode *reqnode;
67 struct IntReq *intreq;
68 struct AslReqInfo *reqinfo;
69 struct LayoutData *ld;
70 struct Window *win;
73 BOOL success = FALSE;
75 D(bug("AslRequest(requester=%p, tagList=%p)\n", requester, tagList));
77 if (!requester)
79 SetIoErr(ERROR_NO_FREE_STORE);
80 return (FALSE);
83 /* Find the correspondent internal structure */
84 reqnode = FindReqNode(requester, ASLB(AslBase));
85 if (!reqnode)
87 return (FALSE);
90 intreq = reqnode->rn_IntReq;
91 reqinfo = &(ASLB(AslBase)->ReqInfo[intreq->ir_ReqType]);
93 /* stegerg: this must be done when the Requester is terminated
94 ** before setting the new output variables in the Requester struct.
96 ** StripRequester(requester, intreq->ir_ReqType, ASLB(AslBase));
99 /* Parse new tags if supplied */
100 if (tagList)
102 struct ParseTagArgs pta;
104 ParseCommonTags(intreq, tagList, ASLB(AslBase));
106 /* Parse requester specific tags */
107 pta.pta_IntReq = intreq;
108 pta.pta_Req = reqnode->rn_Req;
109 pta.pta_Tags = tagList;
111 CallHookPkt(&(reqinfo->ParseTagsHook), &pta, ASLB(AslBase));
114 /* Now do the layout stuff */
117 /* Do some allocations common for all requesters */
118 ld = AllocCommon(reqinfo->UserDataSize, intreq, requester, ASLB(AslBase));
119 if (ld)
121 D(bug("Common stuff allocated\n"));
123 /* Tell the specific requester to initialize */
125 ld->ld_Command = LDCMD_INIT;
127 if (CallHookPkt( &(reqinfo->GadgetryHook), ld, ASLB(AslBase)))
129 struct NewWindow nw;
130 struct TagItem wintags[] =
132 {WA_CustomScreen , (IPTR)ld->ld_Screen }, /* stegerg: requesters should not use WA_PubScreen */
133 {WA_InnerWidth , 0 },
134 {WA_InnerHeight , 0 },
135 {WA_AutoAdjust , TRUE },
136 {WA_NewLookMenus , TRUE },
137 #if AVOID_FLICKER
138 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
139 #endif
140 {TAG_DONE }
142 ULONG idcmp;
143 BOOL privateidcmp;
145 memset(&nw, 0L, sizeof (struct NewWindow));
147 nw.Width = (intreq->ir_Width > ld->ld_MinWidth) ? intreq->ir_Width : ld->ld_MinWidth;
148 nw.Height = (intreq->ir_Height > ld->ld_MinHeight) ? intreq->ir_Height : ld->ld_MinHeight;
150 if (intreq->ir_LeftEdge >= 0)
152 nw.LeftEdge = intreq->ir_LeftEdge;
153 } else {
154 nw.LeftEdge = (ld->ld_Screen->Width - (nw.Width + ld->ld_WBorLeft + ld->ld_WBorRight)) / 2;
156 if (intreq->ir_TopEdge >= 0)
158 nw.TopEdge = intreq->ir_TopEdge;
159 } else {
160 nw.TopEdge = (ld->ld_Screen->Height - (nw.Height + ld->ld_WBorTop + ld->ld_WBorBottom)) / 2;
163 D(bug("MinWidth: %d, MinHeight: %d\n", ld->ld_MinWidth, ld->ld_MinHeight));
165 nw.Title = intreq->ir_TitleText;
166 if (!nw.Title)
168 nw.Title = GetString(intreq->ir_TitleID, intreq->ir_Catalog, ASLB(AslBase));
171 D(bug("\tWindow title: %s", nw.Title));
173 /* nw.FirstGadget = ld->ld_GList;
175 nw.Flags = WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
176 WFLG_SIZEGADGET | WFLG_SIZEBBOTTOM | WFLG_SIMPLE_REFRESH |
177 WFLG_NOCAREREFRESH;
179 if (!(intreq->ir_Flags & IF_OPENINACTIVE))
181 nw.Flags |= WFLG_ACTIVATE;
184 idcmp = IDCMP_CLOSEWINDOW | IDCMP_GADGETUP | IDCMP_MOUSEMOVE |
185 IDCMP_NEWSIZE | IDCMP_REFRESHWINDOW | IDCMP_GADGETDOWN |
186 IDCMP_MENUPICK | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
187 IDCMP_MOUSEBUTTONS;
189 wintags[1].ti_Data = nw.Width;
190 wintags[2].ti_Data = nw.Height;
192 privateidcmp = ((intreq->ir_Flags & IF_PRIVATEIDCMP) || (!intreq->ir_Window));
193 if (privateidcmp)
195 nw.IDCMPFlags = idcmp;
198 win = OpenWindowTagList(&nw, wintags);
199 if (win)
201 if (!privateidcmp)
203 win->UserPort = intreq->ir_Window->UserPort;
204 ModifyIDCMP(win, idcmp);
207 ld->ld_Window = win;
209 ObtainSemaphore( &(ASLB(AslBase)->ReqListSem) );
210 reqnode->rn_ReqWindow = win;
211 ReleaseSemaphore(&(ASLB(AslBase)->ReqListSem));
213 D(bug("Window opened\n"));
215 D(bug
217 "\tLeft: %d\n\tTop: %d\n\tWidth: %d\n\tHeight: %d\n",
218 win->LeftEdge,
219 win->TopEdge,
220 win->Width,
221 win->Height
225 /* Constraint the window minsize */
227 WindowLimits
229 win,
230 ld->ld_MinWidth + win->BorderLeft + win->BorderRight,
231 ld->ld_MinHeight + win->BorderTop + win->BorderBottom,
236 D(bug("Window limits set\n"));
238 SetFont(win->RPort, ld->ld_Font);
240 /* Layout the requester */
241 ld->ld_Command = LDCMD_LAYOUT;
242 if (CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase)))
244 D(bug("Gadgetry layout done\n"));
246 if (ld->ld_GList)
248 D(bug("Adding glist\n"));
249 AddGList(win, ld->ld_GList, -1, -1, NULL);
250 D(bug("Refreshing glist\n"));
251 RefreshGList(ld->ld_GList, win, NULL, -1);
253 D(bug("Gadgetlist refreshed\n"));
256 if (ld->ld_Menu) SetMenuStrip(win, ld->ld_Menu);
258 ld->ld_Command = LDCMD_WINDOWOPENED;
259 CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase));
261 if (intreq->ir_Flags & IF_POPTOFRONT)
263 struct Screen *frontscr;
264 ULONG ilock;
266 ilock = LockIBase(0);
267 frontscr = IntuitionBase->FirstScreen;
268 UnlockIBase(ilock);
270 if (frontscr != win->WScreen)
272 ScreenToFront(win->WScreen);
273 intreq->ir_Flags |= IF_POPPEDTOFRONT;
277 /* Wait for the user to do something */
278 success = HandleEvents(ld, reqinfo, ASLB(AslBase));
280 /* Finished with event handling, clean up requester
281 specific stuff */
283 ld->ld_Command = LDCMD_CLEANUP;
284 CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase));
286 } /* if (CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase))) */
288 /* win is closed in FreeCommon */
290 } /* if (win) */
292 } /* if (CallHookPkt( &(reqinfo->GadgetryHook), ld, ASLB(AslBase))) */
294 ObtainSemaphore( &(ASLB(AslBase)->ReqListSem) );
295 reqnode->rn_ReqWindow = NULL;
296 ReleaseSemaphore(&(ASLB(AslBase)->ReqListSem));
298 FreeCommon(ld, ASLB(AslBase));
300 } /* if (ld) */
302 ReturnBool ("AslRequest", success);
304 AROS_LIBFUNC_EXIT
305 } /* AslRequest */