revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / datatypes / doasynclayout.c
blob97830f330bdcb827fdf2ec7055cfd783efc3a24d
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #define USE_BOOPSI_STUBS
10 #include <utility/tagitem.h>
11 #include <dos/dostags.h>
12 #include <dos/dosextens.h>
13 #include <proto/dos.h>
14 #include <proto/intuition.h>
15 #include <intuition/intuition.h>
16 #include <intuition/gadgetclass.h>
17 #include <intuition/cghooks.h>
18 #include <clib/boopsistubs.h>
19 #include "datatypes_intern.h"
21 struct LayoutMessage
23 struct Message lm_Msg;
24 struct DataTypesBase *lm_dtb;
25 Object *lm_object;
26 struct Window *lm_window;
27 struct gpLayout lm_gplayout;
28 struct GadgetInfo lm_ginfo;
32 void AsyncLayouter(void)
34 struct DataTypesBase *dtb;
35 struct LayoutMessage *lm;
36 struct DTSpecialInfo *dtsi;
37 Object *object;
38 BOOL done = FALSE;
40 struct Process *MyProc = (struct Process *)FindTask(NULL);
42 WaitPort(&MyProc->pr_MsgPort);
43 lm = (struct LayoutMessage *)GetMsg(&MyProc->pr_MsgPort);
45 dtb = lm->lm_dtb;
47 object = lm->lm_object;
48 dtsi = ((struct Gadget *)object)->SpecialInfo;
50 ObtainSemaphore(&dtsi->si_Lock);
52 lm->lm_gplayout.MethodID = DTM_ASYNCLAYOUT;
54 while (!done)
56 DoMethodA(object, (Msg)&lm->lm_gplayout);
58 ObtainSemaphore(&(GPB(dtb)->dtb_Semaphores[SEM_ASYNC]));
59 if (dtsi->si_Flags & DTSIF_NEWSIZE)
61 /* Ensure the method is only called once more unless there's
62 another request to restart it */
63 dtsi->si_Flags &= ~DTSIF_NEWSIZE;
65 /* Ensure Ctrl-C is cleared in case it was set again after the
66 method saw it, or the method finished without seeing it */
67 CheckSignal(SIGBREAKF_CTRL_C);
69 else
71 /* Prepare to exit */
72 dtsi->si_Flags &= ~DTSIF_LAYOUT;
73 setattrs((struct Library *)dtb, object, DTA_LayoutProc, NULL,
74 TAG_DONE);
75 done = TRUE;
77 ReleaseSemaphore(&(GPB(dtb)->dtb_Semaphores[SEM_ASYNC]));
80 ReleaseSemaphore(&dtsi->si_Lock);
82 DoGad_OM_NOTIFY((struct Library *)dtb, object, lm->lm_window, NULL, 0,
83 GA_ID, (ULONG)((struct Gadget *)object)->GadgetID,
84 DTA_Data, object,
85 DTA_TopVert, dtsi->si_TopVert,
86 DTA_VisibleVert, dtsi->si_VisVert,
87 DTA_TotalVert, dtsi->si_TotVert,
88 DTA_TopHoriz, dtsi->si_TopHoriz,
89 DTA_VisibleHoriz, dtsi->si_VisHoriz,
90 DTA_TotalHoriz, dtsi->si_TotHoriz,
91 DTA_Sync, TRUE,
92 DTA_Busy, FALSE,
93 TAG_DONE);
95 Forbid();
97 dtsi->si_Flags &= ~DTSIF_LAYOUTPROC;
99 FreeVec(lm);
103 /*****************************************************************************
105 NAME */
106 #include <proto/datatypes.h>
108 AROS_LH2(ULONG, DoAsyncLayout,
110 /* SYNOPSIS */
111 AROS_LHA(Object * , object, A0),
112 AROS_LHA(struct gpLayout *, gpl , A1),
114 /* LOCATION */
115 struct Library *, DataTypesBase, 14, DataTypes)
117 /* FUNCTION
119 Perform an object's DTM_ASYNCLAYOUT method -- doing it asynchronously
120 off loads the input.device. The method should exit when a SIGBREAK_CTRL_C
121 is received; this signal means that the data is obsolete and the
122 method will be called again.
124 INPUTS
126 object -- pointer to data type object
127 gpl -- gpLayout message pointer
129 RESULT
131 NOTES
133 EXAMPLE
135 BUGS
137 SEE ALSO
139 INTERNALS
141 *****************************************************************************/
143 AROS_LIBFUNC_INIT
145 ULONG retval = FALSE;
146 struct DTSpecialInfo *dtsi=((struct Gadget *)object)->SpecialInfo;
147 struct Process *LayoutProc;
149 ObtainSemaphore(&(GPB(DataTypesBase)->dtb_Semaphores[SEM_ASYNC]));
151 if(dtsi->si_Flags & DTSIF_LAYOUT)
153 dtsi->si_Flags |= DTSIF_NEWSIZE;
155 if(GetAttr(DTA_LayoutProc, object, (IPTR *)&LayoutProc))
157 if(LayoutProc != NULL)
158 Signal((struct Task *)LayoutProc, SIGBREAKF_CTRL_C);
161 retval = TRUE;
163 else
165 struct LayoutMessage *lm;
167 dtsi->si_Flags |= (DTSIF_LAYOUT | DTSIF_LAYOUTPROC);
169 Do_OM_NOTIFY(DataTypesBase, object, gpl->gpl_GInfo, 0, DTA_Data, NULL,
170 TAG_DONE);
172 if((lm = AllocVec(sizeof(struct LayoutMessage),
173 MEMF_PUBLIC | MEMF_CLEAR)))
175 struct TagItem Tags[5];
177 lm->lm_Msg.mn_Node.ln_Type = NT_MESSAGE;
178 lm->lm_Msg.mn_Length = sizeof(struct LayoutMessage);
179 lm->lm_dtb = (struct DataTypesBase *)DataTypesBase;
180 lm->lm_object = object;
181 lm->lm_window = gpl->gpl_GInfo->gi_Window;
182 lm->lm_gplayout = *gpl;
183 lm->lm_ginfo= *gpl->gpl_GInfo;
184 lm->lm_gplayout.gpl_GInfo= &lm->lm_ginfo;
186 Tags[0].ti_Tag = NP_StackSize;
187 Tags[0].ti_Data = AROS_STACKSIZE;
188 Tags[1].ti_Tag = NP_Entry;
189 Tags[1].ti_Data = (IPTR)&AsyncLayouter;
190 Tags[2].ti_Tag = NP_Priority;
191 Tags[2].ti_Data = 0;
192 Tags[3].ti_Tag = NP_Name;
193 Tags[3].ti_Data = (IPTR)"AsyncLayoutDaemon";
194 Tags[4].ti_Tag = TAG_DONE;
196 if((LayoutProc = CreateNewProc(Tags)))
198 PutMsg(&LayoutProc->pr_MsgPort, &lm->lm_Msg);
200 setattrs(DataTypesBase, object, DTA_LayoutProc, LayoutProc, TAG_DONE);
201 retval = TRUE;
203 else
204 FreeVec(lm);
207 if (!retval) dtsi->si_Flags &= ~(DTSIF_LAYOUT | DTSIF_LAYOUTPROC);
210 ReleaseSemaphore(&(GPB(DataTypesBase)->dtb_Semaphores[SEM_ASYNC]));
212 return retval;
214 AROS_LIBFUNC_EXIT
216 } /* DoAsyncLayout */