Listtree.mcc: implement proxying of DisplayHook
[AROS.git] / workbench / libs / asl / aslrequest.c
blobc5a767f087b8d0a2c7c348b810d36a96eda7e42d
1 /*
2 Copyright © 1995-2015, 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 *****************************************************************************/
60 AROS_LIBFUNC_INIT
62 struct ReqNode *reqnode;
63 struct IntReq *intreq;
64 struct AslReqInfo *reqinfo;
65 struct LayoutData *ld;
66 struct Window *win;
69 BOOL success = FALSE;
71 D(bug("AslRequest(requester=%p, tagList=%p)\n", requester, tagList));
73 if (!requester)
75 SetIoErr(ERROR_NO_FREE_STORE);
76 return (FALSE);
79 /* Find the correspondent internal structure */
80 reqnode = FindReqNode(requester, ASLB(AslBase));
81 if (!reqnode)
83 return (FALSE);
86 intreq = reqnode->rn_IntReq;
87 reqinfo = &(ASLB(AslBase)->ReqInfo[intreq->ir_ReqType]);
89 /* stegerg: this must be done when the Requester is terminated
90 ** before setting the new output variables in the Requester struct.
92 ** StripRequester(requester, intreq->ir_ReqType, ASLB(AslBase));
95 /* Parse new tags if supplied */
96 if (tagList)
98 struct ParseTagArgs pta;
100 ParseCommonTags(intreq, tagList, ASLB(AslBase));
102 /* Parse requester specific tags */
103 pta.pta_IntReq = intreq;
104 pta.pta_Req = reqnode->rn_Req;
105 pta.pta_Tags = tagList;
107 CallHookPkt(&(reqinfo->ParseTagsHook), &pta, ASLB(AslBase));
110 /* Now do the layout stuff */
113 /* Do some allocations common for all requesters */
114 ld = AllocCommon(reqinfo->UserDataSize, intreq, requester, ASLB(AslBase));
115 if (ld)
117 D(bug("Common stuff allocated\n"));
119 /* Tell the specific requester to initialize */
121 ld->ld_Command = LDCMD_INIT;
123 if (CallHookPkt( &(reqinfo->GadgetryHook), ld, ASLB(AslBase)))
125 struct NewWindow nw;
126 struct TagItem wintags[] =
128 {WA_CustomScreen , (IPTR)ld->ld_Screen }, /* stegerg: requesters should not use WA_PubScreen */
129 {WA_AutoAdjust , TRUE },
130 {WA_NewLookMenus , TRUE },
131 #if AVOID_FLICKER
132 {WA_BackFill , (IPTR)LAYERS_NOBACKFILL },
133 #endif
134 {TAG_DONE }
136 ULONG idcmp;
137 BOOL privateidcmp;
139 memset(&nw, 0L, sizeof (struct NewWindow));
141 nw.Width = (intreq->ir_Width > ld->ld_MinWidth) ? intreq->ir_Width : ld->ld_MinWidth;
142 nw.Height = (intreq->ir_Height > ld->ld_MinHeight) ? intreq->ir_Height : ld->ld_MinHeight;
144 if (intreq->ir_LeftEdge >= 0)
146 nw.LeftEdge = intreq->ir_LeftEdge;
147 } else {
148 nw.LeftEdge = (ld->ld_Screen->ViewPort.DWidth - (nw.Width + ld->ld_WBorLeft + ld->ld_WBorRight)) / 2
149 - ld->ld_Screen->LeftEdge;
151 if (intreq->ir_TopEdge >= 0)
153 nw.TopEdge = intreq->ir_TopEdge;
154 } else {
155 nw.TopEdge = (ld->ld_Screen->ViewPort.DHeight - (nw.Height + ld->ld_WBorTop + ld->ld_WBorBottom)) / 2
156 - ld->ld_Screen->TopEdge;
159 D(bug("MinWidth: %d, MinHeight: %d\n", ld->ld_MinWidth, ld->ld_MinHeight));
161 nw.Title = intreq->ir_TitleText;
162 if (!nw.Title)
164 nw.Title = GetString(intreq->ir_TitleID, intreq->ir_Catalog, ASLB(AslBase));
167 D(bug("\tWindow title: %s", nw.Title));
169 /* nw.FirstGadget = ld->ld_GList;
171 nw.Flags = WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
172 WFLG_SIZEGADGET | WFLG_SIZEBBOTTOM | WFLG_SIMPLE_REFRESH |
173 WFLG_NOCAREREFRESH;
175 if (!(intreq->ir_Flags & IF_OPENINACTIVE))
177 nw.Flags |= WFLG_ACTIVATE;
180 idcmp = IDCMP_CLOSEWINDOW | IDCMP_GADGETUP | IDCMP_MOUSEMOVE |
181 IDCMP_NEWSIZE | IDCMP_REFRESHWINDOW | IDCMP_GADGETDOWN |
182 IDCMP_MENUPICK | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
183 IDCMP_MOUSEBUTTONS;
185 wintags[1].ti_Data = nw.Width;
186 wintags[2].ti_Data = nw.Height;
188 privateidcmp = ((intreq->ir_Flags & IF_PRIVATEIDCMP) || (!intreq->ir_Window));
189 if (privateidcmp)
191 nw.IDCMPFlags = idcmp;
194 win = OpenWindowTagList(&nw, wintags);
195 if (win)
197 if (!privateidcmp)
199 win->UserPort = intreq->ir_Window->UserPort;
200 ModifyIDCMP(win, idcmp);
203 ld->ld_Window = win;
205 ObtainSemaphore( &(ASLB(AslBase)->ReqListSem) );
206 reqnode->rn_ReqWindow = win;
207 ReleaseSemaphore(&(ASLB(AslBase)->ReqListSem));
209 D(bug("Window opened\n"));
211 D(bug
213 "\tLeft: %d\n\tTop: %d\n\tWidth: %d\n\tHeight: %d\n",
214 win->LeftEdge,
215 win->TopEdge,
216 win->Width,
217 win->Height
221 /* Constraint the window minsize */
223 WindowLimits
225 win,
226 ld->ld_MinWidth + win->BorderLeft + win->BorderRight,
227 ld->ld_MinHeight + win->BorderTop + win->BorderBottom,
232 D(bug("Window limits set\n"));
234 SetFont(win->RPort, ld->ld_Font);
236 /* Layout the requester */
237 ld->ld_Command = LDCMD_LAYOUT;
238 if (CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase)))
240 D(bug("Gadgetry layout done\n"));
242 if (ld->ld_GList)
244 D(bug("Adding glist\n"));
245 AddGList(win, ld->ld_GList, -1, -1, NULL);
246 D(bug("Refreshing glist\n"));
247 RefreshGList(ld->ld_GList, win, NULL, -1);
249 D(bug("Gadgetlist refreshed\n"));
252 if (ld->ld_Menu) SetMenuStrip(win, ld->ld_Menu);
254 ld->ld_Command = LDCMD_WINDOWOPENED;
255 CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase));
257 if (intreq->ir_Flags & IF_POPTOFRONT)
259 struct Screen *frontscr;
260 ULONG ilock;
262 ilock = LockIBase(0);
263 frontscr = IntuitionBase->FirstScreen;
264 UnlockIBase(ilock);
266 if (frontscr != win->WScreen)
268 ScreenToFront(win->WScreen);
269 intreq->ir_Flags |= IF_POPPEDTOFRONT;
273 /* Wait for the user to do something */
274 success = HandleEvents(ld, reqinfo, ASLB(AslBase));
276 /* Finished with event handling, clean up requester
277 specific stuff */
279 ld->ld_Command = LDCMD_CLEANUP;
280 CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase));
282 } /* if (CallHookPkt(&(reqinfo->GadgetryHook), ld, ASLB(AslBase))) */
284 /* win is closed in FreeCommon */
286 } /* if (win) */
288 } /* if (CallHookPkt( &(reqinfo->GadgetryHook), ld, ASLB(AslBase))) */
290 ObtainSemaphore( &(ASLB(AslBase)->ReqListSem) );
291 reqnode->rn_ReqWindow = NULL;
292 ReleaseSemaphore(&(ASLB(AslBase)->ReqListSem));
294 FreeCommon(ld, ASLB(AslBase));
296 } /* if (ld) */
298 ReturnBool ("AslRequest", success);
300 AROS_LIBFUNC_EXIT
301 } /* AslRequest */