- Give PCI controllers lower unit numbers than legacy controllers.
[cake.git] / rom / intuition / removeglist.c
blob7de6a1b75ec8434b8a10e53dd18140b748fd41a4
1 /*
2 Copyright © 1995-2007, 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 HISTORY
67 *****************************************************************************/
69 AROS_LIBFUNC_INIT
71 struct Gadget *pred;
72 struct Gadget *last;
73 struct IIHData *iihdata;
74 LONG numGad2;
75 UWORD count;
76 BOOL done = TRUE;
78 EXTENDWORD(numGad);
80 DEBUG_REMOVEGLIST(dprintf("RemoveGList: Window 0x%lx Gadgets 0x%lx Num %ld\n",
81 remPtr, gadget, numGad));
83 if (!numGad) return ~0;
84 if (!gadget) return ~0;
85 if (!remPtr) return ~0;
87 #ifdef USEGADGETLOCK
88 LOCKGADGET
89 #else
90 LOCKWINDOWLAYERS(remPtr);
91 #endif
93 iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
94 pred = (struct Gadget *)&remPtr->FirstGadget;
95 count = 0;
96 numGad2 = numGad;
98 while (pred->NextGadget && pred->NextGadget != gadget)
100 pred = pred->NextGadget;
101 count ++;
104 if (pred->NextGadget)
106 /* Check if one of the gadgets to be removed is the active gadget.
107 If it is, then make it inactive! */
110 for (last = gadget; last && numGad2--; last = last->NextGadget)
112 if ((iihdata->ActiveGadget == last) || (iihdata->ActiveSysGadget == last))
114 done = FALSE;
115 break;
119 if (done)
121 for (last = gadget; last->NextGadget && --numGad; last = last->NextGadget) ;
123 pred->NextGadget = last->NextGadget;
125 /* stegerg: don't do this. DOpus for example relies on gadget->NextGadget
126 not being touched */
127 /* Emm: but the autodocs say it is done for V36 ??? */
128 #if 0
129 last->NextGadget = NULL;
130 #endif
134 } /* if (pred->NextGadget) */
135 else
137 count = ~0;
140 #ifdef USEGADGETLOCK
141 UNLOCKGADGET
142 #else
143 UNLOCKWINDOWLAYERS(remPtr);
144 #endif
146 /* We tried to remove the active gadget. This must be delayed until LMB
147 * is released.
149 if (!done)
151 struct RemoveGListActionMsg msg;
153 msg.window = remPtr;
154 msg.gadget = gadget;
155 msg.numGad = numGad;
159 DEBUG_REMOVEGLIST(dprintf("RemoveGList: trying to remove the active gadget.\n"));
160 DoSyncAction((APTR)int_removeglist, &msg.msg, IntuitionBase);
162 while (!msg.success);
164 count = msg.count;
167 DEBUG_REMOVEGLIST(dprintf("RemoveGList: removed %ld gadgets\n",count));
169 return count;
171 AROS_LIBFUNC_EXIT
173 } /* RemoveGList */
175 static VOID int_removeglist(struct RemoveGListActionMsg *msg,
176 struct IntuitionBase *IntuitionBase)
178 struct Window *remPtr = msg->window;
179 struct Gadget *gadget = msg->gadget;
180 LONG numGad = msg->numGad;
181 struct Gadget *pred;
182 struct Gadget *last;
183 struct IIHData *iihdata;
184 LONG numGad2;
185 UWORD count;
187 DEBUG_REMOVEGLIST(dprintf("IntRemoveGList: Window 0x%lx Gadgets 0x%lx Num %ld\n",
188 remPtr, gadget, numGad));
190 iihdata = (struct IIHData *)GetPrivIBase(IntuitionBase)->InputHandler->is_Data;
192 /* Don't remove the gadget until the LMB is released. */
193 if (iihdata->ActQualifier & IEQUALIFIER_LEFTBUTTON)
195 DEBUG_REMOVEGLIST(dprintf("IntRemoveGList: LMB down\n"));
196 msg->success = FALSE;
197 return;
200 #ifdef USEGADGETLOCK
201 LOCKGADGET
202 #else
203 LOCKWINDOWLAYERS(remPtr);
204 #endif
206 pred = (struct Gadget *)&remPtr->FirstGadget;
208 count = 0;
209 numGad2 = numGad;
211 while (pred->NextGadget && pred->NextGadget != gadget)
213 pred = pred->NextGadget;
214 count ++;
217 if (pred->NextGadget)
219 /* Check if one of the gadgets to be removed is the active gadget.
220 If it is, then make it inactive! If we got here, one of them was
221 the active gadget at the time of RemoveGList, but this may have
222 changed. */
224 for (last = gadget; last && numGad2--; last = last->NextGadget)
226 if ((iihdata->ActiveGadget == last) || (iihdata->ActiveSysGadget == last))
228 switch(last->GadgetType & GTYP_GTYPEMASK)
230 case GTYP_CUSTOMGADGET:
232 struct gpGoInactive gpgi;
234 gpgi.MethodID = GM_GOINACTIVE;
235 gpgi.gpgi_GInfo = NULL;
236 gpgi.gpgi_Abort = 1;
238 DoGadgetMethodA(last, remPtr, NULL, (Msg)&gpgi);
240 if (SYSGADGET_ACTIVE)
242 if (IS_BOOPSI_GADGET(iihdata->ActiveSysGadget))
244 DoGadgetMethodA(iihdata->ActiveSysGadget, remPtr, NULL, (Msg)&gpgi);
246 iihdata->ActiveSysGadget = NULL;
249 break;
253 last->Activation &= ~GACT_ACTIVEGADGET;
254 iihdata->ActiveGadget = NULL;
258 for (last = gadget; last->NextGadget && --numGad; last = last->NextGadget) ;
260 pred->NextGadget = last->NextGadget;
262 /* stegerg: don't do this. DOpus for example relies on gadget->NextGadget
263 not being touched */
264 /* Emm: but the autodocs say it is done for V36 ??? */
265 #if 0
266 last->NextGadget = NULL;
267 #endif
269 } /* if (pred->NextGadget) */
270 else
272 count = ~0;
275 #ifdef USEGADGETLOCK
276 UNLOCKGADGET
277 #else
278 UNLOCKWINDOWLAYERS(remPtr);
279 #endif
281 DEBUG_REMOVEGLIST(dprintf("IntRemoveGList: done\n"));
283 msg->count = count;
284 msg->success = TRUE;