fix properties
[AROS.git] / rom / intuition / screendepth.c
blob0095bf6ca88b88fa8263bec205855baaeacba005
1 /*
2 Copyright 1995-2010, 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
67 I am not sure, if it is enough, to just send a SNOTIFY message to one
68 screen. I would suggest, the former FirstScreen gets a SDEPTH_TOBACK
69 message and the new FirstScreen gets a SDEPTH_TOFRONT message.
70 Currently only the screen supplied with ScreenDepth gets a message.
72 But those messages need to be sent in front of the actual
73 screen depth change because of the SNOTIFY_WAIT_REPLY-flag must be
74 able to block the action. But we only know after int_screendepth(),
75 if there was a change and which change took place.
77 So I leave it, as it is. This way SNOTIFY_WAIT_REPLY should work
78 at least. Is there something written in the AutoDocs, how this has
79 to be done (each screen gets a message)?
81 (o1i)
83 SEE ALSO
84 ScreenToBack(), ScreenToFront()
86 INTERNALS
88 *****************************************************************************/
90 AROS_LIBFUNC_INIT
92 struct ScreenDepthActionMsg msg;
94 if (reserved != NULL) return;
95 SANITY_CHECK(screen)
97 FireScreenNotifyMessageCode((IPTR) screen, SNOTIFY_SCREENDEPTH, flags, IntuitionBase);
99 msg.screen = screen;
100 msg.flags = flags;
101 DoASyncAction((APTR)int_screendepth, &msg.msg, sizeof(msg), IntuitionBase);
103 AROS_LIBFUNC_EXIT
105 } /* ScreenDepth */
107 /*****************************************************************************************/
109 static VOID int_screendepth(struct ScreenDepthActionMsg *msg,
110 struct IntuitionBase *IntuitionBase)
112 struct Screen *screen = msg->screen;
113 ULONG flags = msg->flags;
114 ULONG ilock = LockIBase(0); /* before access to FirstScreen */
115 struct Screen *family = NULL,
116 *current = IntuitionBase->FirstScreen,
117 *previous = NULL,
118 *prefamily = NULL;
119 struct Window *win;
121 /* Find the screen in the list and check for family */
122 while ( current && current!=screen )
124 if ( flags & SDEPTH_INFAMILY )
126 /* Check if this is the first child in a family */
127 if ( !family && (GetPrivScreen(current)->SpecialFlags & SF_IsChild) )
129 family = current;
130 prefamily = previous;
132 /* Check if this screen is a child so next one belongs to current family */
133 if ( family && !(GetPrivScreen(current)->SpecialFlags & SF_IsChild) )
135 family = NULL;
136 prefamily = NULL;
139 previous = current;
140 current = current->NextScreen;
143 if ( current )
145 if ( ! (flags & SDEPTH_TOBACK) ) /* SDEPTH_TOFRONT is #defined as 0 */
147 if ( previous ) /* I'm not the very first screen */
149 if ( flags & SDEPTH_INFAMILY )
151 if ( GetPrivScreen(current)->SpecialFlags & SF_IsChild )
152 { /* Move me in the front of my family */
153 if ( family ) /* I'm not the first one in my family */
155 previous->NextScreen = current->NextScreen;
156 current->NextScreen = family;
157 if ( prefamily )
159 prefamily->NextScreen = current;
161 else
163 IntuitionBase->FirstScreen = current;
167 else if ( GetPrivScreen(current)->SpecialFlags & SF_IsParent )
168 { /* Move whole family */
169 if ( prefamily ) /* We are not the first family */
171 prefamily->NextScreen = current->NextScreen;
172 current->NextScreen = IntuitionBase->FirstScreen;
173 IntuitionBase->FirstScreen = family;
176 else
177 { /* I have no family */
178 previous->NextScreen = current->NextScreen;
179 current->NextScreen = IntuitionBase->FirstScreen;
180 IntuitionBase->FirstScreen = current;
183 } /* SDEPTH_INFAMILY */
184 else
186 if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) )
187 { /* Move my whole family */
188 if ( !family )
190 prefamily = previous;
191 family = current;
193 if ( prefamily )
194 { /* We are not the first family */
195 while ( !(GetPrivScreen(current)->SpecialFlags & SF_IsParent) )
197 current = current->NextScreen;
199 prefamily->NextScreen = current->NextScreen;
200 current->NextScreen = IntuitionBase->FirstScreen;
201 IntuitionBase->FirstScreen = family;
204 else
205 { /* I have no family */
206 previous->NextScreen = current->NextScreen;
207 current->NextScreen = IntuitionBase->FirstScreen;
208 IntuitionBase->FirstScreen = current;
211 } /* ! SDEPTH_INFAMILY */
213 } /* if (previous) */
215 /* The screen has been made frontmost, activate its monitor */
216 ActivateMonitor(GetPrivScreen(IntuitionBase->FirstScreen)->MonitorObject, -1, -1, IntuitionBase);
217 IntuitionBase->ActiveScreen = IntuitionBase->FirstScreen;
218 } /* if SDEPTH_TO_FRONT */
220 else if ( flags & SDEPTH_TOBACK )
222 if ( flags & SDEPTH_INFAMILY )
224 if ( GetPrivScreen(current)->SpecialFlags & SF_IsChild )
226 /* Go to last screen of this family */
227 while ( !GetPrivScreen(current->NextScreen)->SpecialFlags & SF_IsParent )
229 current = current->NextScreen;
231 if ( current != screen ) /* I'm not the last screen of my family */
233 if ( previous )
235 previous->NextScreen = screen->NextScreen;
237 else
239 IntuitionBase->FirstScreen = screen->NextScreen;
241 screen->NextScreen = current->NextScreen;
242 current->NextScreen = screen;
245 else if ( GetPrivScreen(current)->SpecialFlags & SF_IsParent )
247 if ( current->NextScreen ) /* I'm not the last screen */
249 while ( current->NextScreen )
251 current = current->NextScreen;
253 if ( prefamily )
255 prefamily->NextScreen = screen->NextScreen;
257 else
259 IntuitionBase->FirstScreen = screen->NextScreen;
261 if ( family )
263 current->NextScreen = family;
265 else
267 current->NextScreen = screen;
269 screen->NextScreen = NULL;
272 else
274 if ( current->NextScreen ) /* I'm not the last screen */
276 while ( current->NextScreen )
278 current = current->NextScreen;
280 if ( previous )
282 previous->NextScreen = screen->NextScreen;
284 else
286 IntuitionBase->FirstScreen = screen->NextScreen;
288 current->NextScreen = screen;
289 screen->NextScreen = NULL;
293 } /* SDEPTH_INFAMILY */
294 else
296 struct Screen *last;
298 if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) )
300 if ( !family )
302 family = current;
303 prefamily = previous;
305 /* Go to last screen of this family */
306 while ( !GetPrivScreen(current)->SpecialFlags & SF_IsParent )
308 current = current->NextScreen;
310 if ( current->NextScreen ) /* We are not the last family */
312 last = current->NextScreen;
313 while ( last->NextScreen )
315 last = last->NextScreen;
317 if ( prefamily )
319 prefamily->NextScreen = current->NextScreen;
321 else
323 IntuitionBase->FirstScreen = current->NextScreen;
325 last->NextScreen = family;
326 current->NextScreen = NULL;
329 } /* if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) ) */
330 else
332 if ( current->NextScreen ) /* I'm not the last screen */
334 while ( current->NextScreen )
336 current = current->NextScreen;
338 if ( previous )
340 previous->NextScreen = screen->NextScreen;
342 else
344 IntuitionBase->FirstScreen = screen->NextScreen;
346 current->NextScreen = screen;
347 screen->NextScreen = NULL;
350 } /* current not SF_isChild | SF_IsParent */
352 } /* ! SDEPTH_INFAMILY */
354 } /* if SDEPTH_TO_BACK */
355 /* We have just brought the screen to back. We want to stay on the current monitor,
356 so we activate the frontmost screen on THIS monitor */
357 IntuitionBase->ActiveScreen = FindFirstScreen(GetPrivIBase(IntuitionBase)->ActiveMonitor, IntuitionBase);
358 } /* if (current) */
360 RethinkDisplay();
362 win = NULL;
363 #if 0 /* FIXME: backport, disabled */
364 if (IntuitionBase->FirstScreen && GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_SCREENACTIVATION)
366 struct Window *scanw = 0;
368 for (scanw = IntuitionBase->FirstScreen->FirstWindow; scanw ; scanw = scanw->NextWindow)
370 if (win)
372 if ((IW(scanw)->activationtime.tv_secs > IW(win)->activationtime.tv_secs) ||
373 ((IW(scanw)->activationtime.tv_secs == IW(win)->activationtime.tv_secs) && (IW(scanw)->activationtime.tv_micro > IW(win)->activationtime.tv_micro)))
375 win = scanw;
379 if (!win) win = scanw;
382 if (!win) win = IntuitionBase->FirstScreen->FirstWindow;
383 if (IntuitionBase->ActiveWindow && IntuitionBase->ActiveWindow->WScreen == IntuitionBase->FirstScreen) win = NULL;
385 #endif
387 /* now set the default pub screen */
388 /* if the screen is not a public one we just ignore this */
390 if (IntuitionBase->FirstScreen && GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_DEFPUBSCREEN)
392 if (GetPrivScreen(IntuitionBase->FirstScreen)->pubScrNode && (IntuitionBase->FirstScreen->Flags & (PUBLICSCREEN | WBENCHSCREEN)))
394 GetPrivIBase(IntuitionBase)->DefaultPubScreen = IntuitionBase->FirstScreen;
398 UnlockIBase(ilock);
400 if (win)
402 ActivateWindow(win);