fall back to a repository that does provide the version of acpica we use. (NicJA)
[AROS.git] / rom / intuition / screendepth.c
blob622cdf0ba5933712efa30dba4cc0299a6cd0de68
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$
6 Change order of screens.
7 */
9 #include <proto/graphics.h>
11 #include "intuition_intern.h"
12 #include "inputhandler.h"
13 #include "inputhandler_actions.h"
15 struct ScreenDepthActionMsg
17 struct IntuiActionMsg msg;
18 struct Screen *screen;
19 ULONG flags;
22 static VOID int_screendepth(struct ScreenDepthActionMsg *msg,
23 struct IntuitionBase *IntuitionBase);
25 /*****************************************************************************
27 NAME */
28 #include <proto/intuition.h>
30 AROS_LH3(void, ScreenDepth,
32 /* SYNOPSIS */
33 AROS_LHA(struct Screen *, screen, A0),
34 AROS_LHA(ULONG , flags, D0),
35 AROS_LHA(APTR , reserved, A1),
37 /* LOCATION */
38 struct IntuitionBase *, IntuitionBase, 131, Intuition)
40 /* FUNCTION
41 Move the specified screen to the front or back, based on passed flag.
42 If the screen is in a group, the screen will change its position in
43 the group only. If the screen is the parent of a group, the whole
44 group will be moved.
46 INPUTS
47 screen - Move this screen.
48 flags - SDEPTH_TOFRONT or SDEPTH_TOBACK for bringing the screen to
49 front or back.
50 If the screen is a child of another screen you may specify
51 SDEPTH_INFAMILY to move the screen within the family. If
52 not specified the whole family will move.
53 reserved - For future use. MUST be NULL by now.
55 RESULT
56 None.
58 NOTES
59 Only the owner of the screen should use SDEPTH_INFAMILY.
60 Intentionally commodities should not change the internal arrangement
61 of screen families.
63 EXAMPLE
65 BUGS
66 I am not sure, if it is enough to just send a SNOTIFY message to one
67 screen. I would suggest, the former FirstScreen gets a SDEPTH_TOBACK
68 message and the new FirstScreen gets a SDEPTH_TOFRONT message.
69 Currently only the screen supplied with ScreenDepth gets a message.
71 But those messages need to be sent in front of the actual
72 screen depth change because of the SNOTIFY_WAIT_REPLY-flag must be
73 able to block the action. But we only know after int_screendepth(),
74 if there was a change and which change took place.
76 So I leave it, as it is. This way SNOTIFY_WAIT_REPLY should work
77 at least. Is there something written in the AutoDocs, how this has
78 to be done (each screen gets a message)?
80 (o1i)
82 SEE ALSO
83 ScreenToBack(), ScreenToFront()
85 INTERNALS
87 *****************************************************************************/
89 AROS_LIBFUNC_INIT
91 struct ScreenDepthActionMsg msg;
93 if (reserved != NULL) return;
94 SANITY_CHECK(screen)
96 FireScreenNotifyMessageCode((IPTR) screen, SNOTIFY_SCREENDEPTH, flags, IntuitionBase);
98 msg.screen = screen;
99 msg.flags = flags;
100 DoASyncAction((APTR)int_screendepth, &msg.msg, sizeof(msg), IntuitionBase);
102 AROS_LIBFUNC_EXIT
104 } /* ScreenDepth */
106 /*****************************************************************************************/
108 static VOID int_screendepth(struct ScreenDepthActionMsg *msg,
109 struct IntuitionBase *IntuitionBase)
111 struct Screen *screen = msg->screen;
112 ULONG flags = msg->flags;
113 ULONG ilock = LockIBase(0); /* before access to FirstScreen */
114 struct Screen *family = NULL,
115 *current = IntuitionBase->FirstScreen,
116 *previous = NULL,
117 *prefamily = NULL;
118 struct Window *win = NULL;
120 /* Find the screen in the list and check for family */
121 while ( current && current!=screen )
123 if ( flags & SDEPTH_INFAMILY )
125 /* Check if this is the first child in a family */
126 if ( !family && (GetPrivScreen(current)->SpecialFlags & SF_IsChild) )
128 family = current;
129 prefamily = previous;
131 /* Check if this screen is a child so next one belongs to current family */
132 if ( family && !(GetPrivScreen(current)->SpecialFlags & SF_IsChild) )
134 family = NULL;
135 prefamily = NULL;
138 previous = current;
139 current = current->NextScreen;
142 if ( current )
144 if ( ! (flags & SDEPTH_TOBACK) ) /* SDEPTH_TOFRONT is #defined as 0 */
146 BOOL changed = FALSE;
147 if ( previous ) /* I'm not the very first screen */
149 changed = TRUE;
150 if ( flags & SDEPTH_INFAMILY )
152 if ( GetPrivScreen(current)->SpecialFlags & SF_IsChild )
153 { /* Move me in the front of my family */
154 if ( family ) /* I'm not the first one in my family */
156 previous->NextScreen = current->NextScreen;
157 current->NextScreen = family;
158 if ( prefamily )
160 prefamily->NextScreen = current;
162 else
164 IntuitionBase->FirstScreen = current;
168 else if ( GetPrivScreen(current)->SpecialFlags & SF_IsParent )
169 { /* Move whole family */
170 if ( prefamily ) /* We are not the first family */
172 prefamily->NextScreen = current->NextScreen;
173 current->NextScreen = IntuitionBase->FirstScreen;
174 IntuitionBase->FirstScreen = family;
177 else
178 { /* I have no family */
179 previous->NextScreen = current->NextScreen;
180 current->NextScreen = IntuitionBase->FirstScreen;
181 IntuitionBase->FirstScreen = current;
184 } /* SDEPTH_INFAMILY */
185 else
187 if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) )
188 { /* Move my whole family */
189 if ( !family )
191 prefamily = previous;
192 family = current;
194 if ( prefamily )
195 { /* We are not the first family */
196 while ( !(GetPrivScreen(current)->SpecialFlags & SF_IsParent) )
198 current = current->NextScreen;
200 prefamily->NextScreen = current->NextScreen;
201 current->NextScreen = IntuitionBase->FirstScreen;
202 IntuitionBase->FirstScreen = family;
205 else
206 { /* I have no family */
207 previous->NextScreen = current->NextScreen;
208 current->NextScreen = IntuitionBase->FirstScreen;
209 IntuitionBase->FirstScreen = current;
212 } /* ! SDEPTH_INFAMILY */
214 } /* if (previous) */
216 if (!changed)
217 goto end;
218 /* The screen has been made frontmost, activate its monitor */
219 ActivateMonitor(GetPrivScreen(IntuitionBase->FirstScreen)->IMonitorNode, -1, -1, IntuitionBase);
220 IntuitionBase->ActiveScreen = IntuitionBase->FirstScreen;
221 } /* if SDEPTH_TO_FRONT */
223 else if ( flags & SDEPTH_TOBACK )
225 BOOL changed = FALSE;
226 if ( flags & SDEPTH_INFAMILY )
228 if ( GetPrivScreen(current)->SpecialFlags & SF_IsChild )
230 /* Go to last screen of this family */
231 while ( !GetPrivScreen(current->NextScreen)->SpecialFlags & SF_IsParent )
233 current = current->NextScreen;
235 if ( current != screen ) /* I'm not the last screen of my family */
237 if ( previous )
239 previous->NextScreen = screen->NextScreen;
241 else
243 IntuitionBase->FirstScreen = screen->NextScreen;
245 screen->NextScreen = current->NextScreen;
246 current->NextScreen = screen;
247 changed = TRUE;
250 else if ( GetPrivScreen(current)->SpecialFlags & SF_IsParent )
252 if ( current->NextScreen ) /* I'm not the last screen */
254 while ( current->NextScreen )
256 current = current->NextScreen;
258 if ( prefamily )
260 prefamily->NextScreen = screen->NextScreen;
262 else
264 IntuitionBase->FirstScreen = screen->NextScreen;
266 if ( family )
268 current->NextScreen = family;
270 else
272 current->NextScreen = screen;
274 screen->NextScreen = NULL;
275 changed = TRUE;
278 else
280 if ( current->NextScreen ) /* I'm not the last screen */
282 while ( current->NextScreen )
284 current = current->NextScreen;
286 if ( previous )
288 previous->NextScreen = screen->NextScreen;
290 else
292 IntuitionBase->FirstScreen = screen->NextScreen;
294 current->NextScreen = screen;
295 screen->NextScreen = NULL;
296 changed = TRUE;
300 } /* SDEPTH_INFAMILY */
301 else
303 struct Screen *last;
305 if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) )
307 if ( !family )
309 family = current;
310 prefamily = previous;
312 /* Go to last screen of this family */
313 while ( !GetPrivScreen(current)->SpecialFlags & SF_IsParent )
315 current = current->NextScreen;
317 if ( current->NextScreen ) /* We are not the last family */
319 last = current->NextScreen;
320 while ( last->NextScreen )
322 last = last->NextScreen;
324 if ( prefamily )
326 prefamily->NextScreen = current->NextScreen;
328 else
330 IntuitionBase->FirstScreen = current->NextScreen;
332 last->NextScreen = family;
333 current->NextScreen = NULL;
334 changed = TRUE;
337 } /* if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) ) */
338 else
340 if ( current->NextScreen ) /* I'm not the last screen */
342 while ( current->NextScreen )
344 current = current->NextScreen;
346 if ( previous )
348 previous->NextScreen = screen->NextScreen;
350 else
352 IntuitionBase->FirstScreen = screen->NextScreen;
354 current->NextScreen = screen;
355 screen->NextScreen = NULL;
356 changed = TRUE;
359 } /* current not SF_isChild | SF_IsParent */
361 } /* ! SDEPTH_INFAMILY */
362 if (!changed)
363 goto end;
364 /* We have just brought the screen to back. We want to stay on the current monitor,
365 so we activate the frontmost screen on THIS monitor */
366 IntuitionBase->ActiveScreen = FindFirstScreen(GetPrivIBase(IntuitionBase)->ActiveMonitor, IntuitionBase);
367 } /* if SDEPTH_TO_BACK */
368 } /* if (current) */
370 RethinkDisplay();
372 #if 0 /* FIXME: backport, disabled */
373 if (IntuitionBase->FirstScreen && GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_SCREENACTIVATION)
375 struct Window *scanw = 0;
377 for (scanw = IntuitionBase->FirstScreen->FirstWindow; scanw ; scanw = scanw->NextWindow)
379 if (win)
381 if ((IW(scanw)->activationtime.tv_secs > IW(win)->activationtime.tv_secs) ||
382 ((IW(scanw)->activationtime.tv_secs == IW(win)->activationtime.tv_secs) && (IW(scanw)->activationtime.tv_micro > IW(win)->activationtime.tv_micro)))
384 win = scanw;
388 if (!win) win = scanw;
391 if (!win) win = IntuitionBase->FirstScreen->FirstWindow;
392 if (IntuitionBase->ActiveWindow && IntuitionBase->ActiveWindow->WScreen == IntuitionBase->FirstScreen) win = NULL;
394 #endif
396 /* now set the default pub screen */
397 /* if the screen is not a public one we just ignore this */
399 if (IntuitionBase->FirstScreen && GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_DEFPUBSCREEN)
401 if (GetPrivScreen(IntuitionBase->FirstScreen)->pubScrNode && (IntuitionBase->FirstScreen->Flags & (PUBLICSCREEN | WBENCHSCREEN)))
403 GetPrivIBase(IntuitionBase)->DefaultPubScreen = IntuitionBase->FirstScreen;
406 end:
407 UnlockIBase(ilock);
409 if (win)
411 ActivateWindow(win);