Add a wishful comment
[AROS.git] / rom / intuition / removeglist.c
blob1f8608e248aa1cb67ec53002f0b8b684b36d0c35
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 #include <proto/layers.h>
8 #include "intuition_intern.h"
9 #include "inputhandler_actions.h"
10 #include "inputhandler.h"
11 #include <intuition/gadgetclass.h>
13 struct RemoveGListActionMsg
15 struct IntuiActionMsg msg;
16 struct Window *window;
17 struct Gadget *gadget;
18 LONG numGad;
19 UWORD count;
20 BOOL success;
23 static VOID int_removeglist(struct RemoveGListActionMsg *msg,
24 struct IntuitionBase *IntuitionBase);
26 /*****************************************************************************
28 NAME */
29 #include <intuition/intuition.h>
30 #include <proto/intuition.h>
32 AROS_LH3(UWORD, RemoveGList,
34 /* SYNOPSIS */
35 AROS_LHA(struct Window *, remPtr, A0),
36 AROS_LHA(struct Gadget *, gadget, A1),
37 AROS_LHA(LONG , numGad, D0),
39 /* LOCATION */
40 struct IntuitionBase *, IntuitionBase, 74, Intuition)
42 /* FUNCTION
43 Remove sublist of gadgets from a window.
45 INPUTS
46 remPtr - window from which gadgets should be removed
47 gadget - pointer gadget to be removed
48 numGad - number of gadgets to remove. Use -1 to remove
49 all gadgets to the end of the list.
51 RESULT
52 Ordinal number of the removed gadget or -1 on failure
54 NOTES
56 EXAMPLE
58 BUGS
60 SEE ALSO
61 RemoveGadget(), AddGadget(), AddGList()
63 INTERNALS
65 *****************************************************************************/
67 AROS_LIBFUNC_INIT
69 struct Gadget *pred;
70 struct Gadget *last;
71 struct IIHData *iihdata;
72 LONG numGad2;
73 UWORD count;
74 BOOL done = TRUE;
76 EXTENDWORD(numGad);
78 DEBUG_REMOVEGLIST(dprintf("RemoveGList: Window 0x%lx Gadgets 0x%lx Num %ld\n",
79 remPtr, gadget, numGad));
81 if (!numGad) return ~0;
82 if (!gadget) return ~0;
83 if (!remPtr) return ~0;
85 #ifdef USEGADGETLOCK
86 LOCKGADGET(IntuitionBase)
87 #else
88 LOCKWINDOWLAYERS(remPtr);
89 #endif
91 iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
92 pred = (struct Gadget *)&remPtr->FirstGadget;
93 count = 0;
94 numGad2 = numGad;
96 while (pred->NextGadget && pred->NextGadget != gadget)
98 pred = pred->NextGadget;
99 count ++;
102 if (pred->NextGadget)
104 /* Check if one of the gadgets to be removed is the active gadget.
105 If it is, then make it inactive! */
108 for (last = gadget; last && numGad2--; last = last->NextGadget)
110 if ((iihdata->ActiveGadget == last) || (iihdata->ActiveSysGadget == last))
112 done = FALSE;
113 break;
117 if (done)
119 for (last = gadget; last->NextGadget && --numGad; last = last->NextGadget) ;
121 pred->NextGadget = last->NextGadget;
123 /* stegerg: don't do this. DOpus for example relies on gadget->NextGadget
124 not being touched */
125 /* Emm: but the autodocs say it is done for V36 ??? */
126 #if 0
127 last->NextGadget = NULL;
128 #endif
132 } /* if (pred->NextGadget) */
133 else
135 count = ~0;
138 #ifdef USEGADGETLOCK
139 UNLOCKGADGET(IntuitionBase)
140 #else
141 UNLOCKWINDOWLAYERS(remPtr);
142 #endif
144 /* We tried to remove the active gadget. This must be delayed until LMB
145 * is released.
147 if (!done)
149 struct RemoveGListActionMsg msg;
151 msg.window = remPtr;
152 msg.gadget = gadget;
153 msg.numGad = numGad;
157 DEBUG_REMOVEGLIST(dprintf("RemoveGList: trying to remove the active gadget.\n"));
158 DoSyncAction((APTR)int_removeglist, &msg.msg, IntuitionBase);
160 while (!msg.success);
162 count = msg.count;
165 DEBUG_REMOVEGLIST(dprintf("RemoveGList: removed %ld gadgets\n",count));
167 return count;
169 AROS_LIBFUNC_EXIT
171 } /* RemoveGList */
173 static VOID int_removeglist(struct RemoveGListActionMsg *msg,
174 struct IntuitionBase *IntuitionBase)
176 struct Window *remPtr = msg->window;
177 struct Gadget *gadget = msg->gadget;
178 LONG numGad = msg->numGad;
179 struct Gadget *pred;
180 struct Gadget *last;
181 struct IIHData *iihdata;
182 LONG numGad2;
183 UWORD count;
185 DEBUG_REMOVEGLIST(dprintf("IntRemoveGList: Window 0x%lx Gadgets 0x%lx Num %ld\n",
186 remPtr, gadget, numGad));
188 iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
190 /* Don't remove the gadget until the LMB is released. */
191 if (iihdata->ActQualifier & IEQUALIFIER_LEFTBUTTON)
193 DEBUG_REMOVEGLIST(dprintf("IntRemoveGList: LMB down\n"));
194 msg->success = FALSE;
195 return;
198 #ifdef USEGADGETLOCK
199 LOCKGADGET(IntuitionBase)
200 #else
201 LOCKWINDOWLAYERS(remPtr);
202 #endif
204 pred = (struct Gadget *)&remPtr->FirstGadget;
206 count = 0;
207 numGad2 = numGad;
209 while (pred->NextGadget && pred->NextGadget != gadget)
211 pred = pred->NextGadget;
212 count ++;
215 if (pred->NextGadget)
217 /* Check if one of the gadgets to be removed is the active gadget.
218 If it is, then make it inactive! If we got here, one of them was
219 the active gadget at the time of RemoveGList, but this may have
220 changed. */
222 for (last = gadget; last && numGad2--; last = last->NextGadget)
224 if ((iihdata->ActiveGadget == last) || (iihdata->ActiveSysGadget == last))
226 switch(last->GadgetType & GTYP_GTYPEMASK)
228 case GTYP_CUSTOMGADGET:
230 struct gpGoInactive gpgi;
232 gpgi.MethodID = GM_GOINACTIVE;
233 gpgi.gpgi_GInfo = NULL;
234 gpgi.gpgi_Abort = 1;
236 DoGadgetMethodA(last, remPtr, NULL, (Msg)&gpgi);
238 if (SYSGADGET_ACTIVE)
240 if (IS_BOOPSI_GADGET(iihdata->ActiveSysGadget))
242 DoGadgetMethodA(iihdata->ActiveSysGadget, remPtr, NULL, (Msg)&gpgi);
244 iihdata->ActiveSysGadget = NULL;
247 break;
251 last->Activation &= ~GACT_ACTIVEGADGET;
252 iihdata->ActiveGadget = NULL;
256 for (last = gadget; last->NextGadget && --numGad; last = last->NextGadget) ;
258 pred->NextGadget = last->NextGadget;
260 /* stegerg: don't do this. DOpus for example relies on gadget->NextGadget
261 not being touched */
262 /* Emm: but the autodocs say it is done for V36 ??? */
263 #if 0
264 last->NextGadget = NULL;
265 #endif
267 } /* if (pred->NextGadget) */
268 else
270 count = ~0;
273 #ifdef USEGADGETLOCK
274 UNLOCKGADGET(IntuitionBase)
275 #else
276 UNLOCKWINDOWLAYERS(remPtr);
277 #endif
279 DEBUG_REMOVEGLIST(dprintf("IntRemoveGList: done\n"));
281 msg->count = count;
282 msg->success = TRUE;