2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
6 Change order of screens.
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
;
22 static VOID
int_screendepth(struct ScreenDepthActionMsg
*msg
,
23 struct IntuitionBase
*IntuitionBase
);
25 /*****************************************************************************
28 #include <proto/intuition.h>
30 AROS_LH3(void, ScreenDepth
,
33 AROS_LHA(struct Screen
*, screen
, A0
),
34 AROS_LHA(ULONG
, flags
, D0
),
35 AROS_LHA(APTR
, reserved
, A1
),
38 struct IntuitionBase
*, IntuitionBase
, 131, Intuition
)
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
47 screen - Move this screen.
48 flags - SDEPTH_TOFRONT or SDEPTH_TOBACK for bringing the screen to
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.
59 Only the owner of the screen should use SDEPTH_INFAMILY.
60 Intentionally commodities should not change the internal arrangement
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)?
83 ScreenToBack(), ScreenToFront()
87 *****************************************************************************/
91 struct ScreenDepthActionMsg msg
;
93 if (reserved
!= NULL
) return;
96 FireScreenNotifyMessageCode((IPTR
) screen
, SNOTIFY_SCREENDEPTH
, flags
, IntuitionBase
);
100 DoASyncAction((APTR
)int_screendepth
, &msg
.msg
, sizeof(msg
), IntuitionBase
);
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
,
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
) )
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
) )
139 current
= current
->NextScreen
;
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 */
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
;
160 prefamily
->NextScreen
= current
;
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
;
178 { /* I have no family */
179 previous
->NextScreen
= current
->NextScreen
;
180 current
->NextScreen
= IntuitionBase
->FirstScreen
;
181 IntuitionBase
->FirstScreen
= current
;
184 } /* SDEPTH_INFAMILY */
187 if ( GetPrivScreen(current
)->SpecialFlags
& (SF_IsChild
|SF_IsParent
) )
188 { /* Move my whole family */
191 prefamily
= previous
;
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
;
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) */
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 */
239 previous
->NextScreen
= screen
->NextScreen
;
243 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
245 screen
->NextScreen
= current
->NextScreen
;
246 current
->NextScreen
= screen
;
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
;
260 prefamily
->NextScreen
= screen
->NextScreen
;
264 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
268 current
->NextScreen
= family
;
272 current
->NextScreen
= screen
;
274 screen
->NextScreen
= NULL
;
280 if ( current
->NextScreen
) /* I'm not the last screen */
282 while ( current
->NextScreen
)
284 current
= current
->NextScreen
;
288 previous
->NextScreen
= screen
->NextScreen
;
292 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
294 current
->NextScreen
= screen
;
295 screen
->NextScreen
= NULL
;
300 } /* SDEPTH_INFAMILY */
305 if ( GetPrivScreen(current
)->SpecialFlags
& (SF_IsChild
|SF_IsParent
) )
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
;
326 prefamily
->NextScreen
= current
->NextScreen
;
330 IntuitionBase
->FirstScreen
= current
->NextScreen
;
332 last
->NextScreen
= family
;
333 current
->NextScreen
= NULL
;
337 } /* if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) ) */
340 if ( current
->NextScreen
) /* I'm not the last screen */
342 while ( current
->NextScreen
)
344 current
= current
->NextScreen
;
348 previous
->NextScreen
= screen
->NextScreen
;
352 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
354 current
->NextScreen
= screen
;
355 screen
->NextScreen
= NULL
;
359 } /* current not SF_isChild | SF_IsParent */
361 } /* ! SDEPTH_INFAMILY */
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 */
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
)
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
)))
388 if (!win
) win
= scanw
;
391 if (!win
) win
= IntuitionBase
->FirstScreen
->FirstWindow
;
392 if (IntuitionBase
->ActiveWindow
&& IntuitionBase
->ActiveWindow
->WScreen
== IntuitionBase
->FirstScreen
) win
= NULL
;
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
;