2 Copyright 1995-2010, 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
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)?
84 ScreenToBack(), ScreenToFront()
88 *****************************************************************************/
92 struct ScreenDepthActionMsg msg
;
94 if (reserved
!= NULL
) return;
97 FireScreenNotifyMessageCode((IPTR
) screen
, SNOTIFY_SCREENDEPTH
, flags
, IntuitionBase
);
101 DoASyncAction((APTR
)int_screendepth
, &msg
.msg
, sizeof(msg
), IntuitionBase
);
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
,
119 struct Window
*win
= NULL
;
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
) )
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
) )
140 current
= current
->NextScreen
;
145 if ( ! (flags
& SDEPTH_TOBACK
) ) /* SDEPTH_TOFRONT is #defined as 0 */
147 BOOL changed
= FALSE
;
148 if ( previous
) /* I'm not the very first screen */
151 if ( flags
& SDEPTH_INFAMILY
)
153 if ( GetPrivScreen(current
)->SpecialFlags
& SF_IsChild
)
154 { /* Move me in the front of my family */
155 if ( family
) /* I'm not the first one in my family */
157 previous
->NextScreen
= current
->NextScreen
;
158 current
->NextScreen
= family
;
161 prefamily
->NextScreen
= current
;
165 IntuitionBase
->FirstScreen
= current
;
169 else if ( GetPrivScreen(current
)->SpecialFlags
& SF_IsParent
)
170 { /* Move whole family */
171 if ( prefamily
) /* We are not the first family */
173 prefamily
->NextScreen
= current
->NextScreen
;
174 current
->NextScreen
= IntuitionBase
->FirstScreen
;
175 IntuitionBase
->FirstScreen
= family
;
179 { /* I have no family */
180 previous
->NextScreen
= current
->NextScreen
;
181 current
->NextScreen
= IntuitionBase
->FirstScreen
;
182 IntuitionBase
->FirstScreen
= current
;
185 } /* SDEPTH_INFAMILY */
188 if ( GetPrivScreen(current
)->SpecialFlags
& (SF_IsChild
|SF_IsParent
) )
189 { /* Move my whole family */
192 prefamily
= previous
;
196 { /* We are not the first family */
197 while ( !(GetPrivScreen(current
)->SpecialFlags
& SF_IsParent
) )
199 current
= current
->NextScreen
;
201 prefamily
->NextScreen
= current
->NextScreen
;
202 current
->NextScreen
= IntuitionBase
->FirstScreen
;
203 IntuitionBase
->FirstScreen
= family
;
207 { /* I have no family */
208 previous
->NextScreen
= current
->NextScreen
;
209 current
->NextScreen
= IntuitionBase
->FirstScreen
;
210 IntuitionBase
->FirstScreen
= current
;
213 } /* ! SDEPTH_INFAMILY */
215 } /* if (previous) */
219 /* The screen has been made frontmost, activate its monitor */
220 ActivateMonitor(GetPrivScreen(IntuitionBase
->FirstScreen
)->MonitorObject
, -1, -1, IntuitionBase
);
221 IntuitionBase
->ActiveScreen
= IntuitionBase
->FirstScreen
;
222 } /* if SDEPTH_TO_FRONT */
224 else if ( flags
& SDEPTH_TOBACK
)
226 BOOL changed
= FALSE
;
227 if ( flags
& SDEPTH_INFAMILY
)
229 if ( GetPrivScreen(current
)->SpecialFlags
& SF_IsChild
)
231 /* Go to last screen of this family */
232 while ( !GetPrivScreen(current
->NextScreen
)->SpecialFlags
& SF_IsParent
)
234 current
= current
->NextScreen
;
236 if ( current
!= screen
) /* I'm not the last screen of my family */
240 previous
->NextScreen
= screen
->NextScreen
;
244 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
246 screen
->NextScreen
= current
->NextScreen
;
247 current
->NextScreen
= screen
;
251 else if ( GetPrivScreen(current
)->SpecialFlags
& SF_IsParent
)
253 if ( current
->NextScreen
) /* I'm not the last screen */
255 while ( current
->NextScreen
)
257 current
= current
->NextScreen
;
261 prefamily
->NextScreen
= screen
->NextScreen
;
265 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
269 current
->NextScreen
= family
;
273 current
->NextScreen
= screen
;
275 screen
->NextScreen
= NULL
;
281 if ( current
->NextScreen
) /* I'm not the last screen */
283 while ( current
->NextScreen
)
285 current
= current
->NextScreen
;
289 previous
->NextScreen
= screen
->NextScreen
;
293 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
295 current
->NextScreen
= screen
;
296 screen
->NextScreen
= NULL
;
301 } /* SDEPTH_INFAMILY */
306 if ( GetPrivScreen(current
)->SpecialFlags
& (SF_IsChild
|SF_IsParent
) )
311 prefamily
= previous
;
313 /* Go to last screen of this family */
314 while ( !GetPrivScreen(current
)->SpecialFlags
& SF_IsParent
)
316 current
= current
->NextScreen
;
318 if ( current
->NextScreen
) /* We are not the last family */
320 last
= current
->NextScreen
;
321 while ( last
->NextScreen
)
323 last
= last
->NextScreen
;
327 prefamily
->NextScreen
= current
->NextScreen
;
331 IntuitionBase
->FirstScreen
= current
->NextScreen
;
333 last
->NextScreen
= family
;
334 current
->NextScreen
= NULL
;
338 } /* if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) ) */
341 if ( current
->NextScreen
) /* I'm not the last screen */
343 while ( current
->NextScreen
)
345 current
= current
->NextScreen
;
349 previous
->NextScreen
= screen
->NextScreen
;
353 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
355 current
->NextScreen
= screen
;
356 screen
->NextScreen
= NULL
;
360 } /* current not SF_isChild | SF_IsParent */
362 } /* ! SDEPTH_INFAMILY */
365 /* We have just brought the screen to back. We want to stay on the current monitor,
366 so we activate the frontmost screen on THIS monitor */
367 IntuitionBase
->ActiveScreen
= FindFirstScreen(GetPrivIBase(IntuitionBase
)->ActiveMonitor
, IntuitionBase
);
368 } /* if SDEPTH_TO_BACK */
373 #if 0 /* FIXME: backport, disabled */
374 if (IntuitionBase
->FirstScreen
&& GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_SCREENACTIVATION
)
376 struct Window
*scanw
= 0;
378 for (scanw
= IntuitionBase
->FirstScreen
->FirstWindow
; scanw
; scanw
= scanw
->NextWindow
)
382 if ((IW(scanw
)->activationtime
.tv_secs
> IW(win
)->activationtime
.tv_secs
) ||
383 ((IW(scanw
)->activationtime
.tv_secs
== IW(win
)->activationtime
.tv_secs
) && (IW(scanw
)->activationtime
.tv_micro
> IW(win
)->activationtime
.tv_micro
)))
389 if (!win
) win
= scanw
;
392 if (!win
) win
= IntuitionBase
->FirstScreen
->FirstWindow
;
393 if (IntuitionBase
->ActiveWindow
&& IntuitionBase
->ActiveWindow
->WScreen
== IntuitionBase
->FirstScreen
) win
= NULL
;
397 /* now set the default pub screen */
398 /* if the screen is not a public one we just ignore this */
400 if (IntuitionBase
->FirstScreen
&& GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_DEFPUBSCREEN
)
402 if (GetPrivScreen(IntuitionBase
->FirstScreen
)->pubScrNode
&& (IntuitionBase
->FirstScreen
->Flags
& (PUBLICSCREEN
| WBENCHSCREEN
)))
404 GetPrivIBase(IntuitionBase
)->DefaultPubScreen
= IntuitionBase
->FirstScreen
;