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
,
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 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
;
159 prefamily
->NextScreen
= current
;
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
;
177 { /* I have no family */
178 previous
->NextScreen
= current
->NextScreen
;
179 current
->NextScreen
= IntuitionBase
->FirstScreen
;
180 IntuitionBase
->FirstScreen
= current
;
183 } /* SDEPTH_INFAMILY */
186 if ( GetPrivScreen(current
)->SpecialFlags
& (SF_IsChild
|SF_IsParent
) )
187 { /* Move my whole family */
190 prefamily
= previous
;
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
;
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 */
235 previous
->NextScreen
= screen
->NextScreen
;
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
;
255 prefamily
->NextScreen
= screen
->NextScreen
;
259 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
263 current
->NextScreen
= family
;
267 current
->NextScreen
= screen
;
269 screen
->NextScreen
= NULL
;
274 if ( current
->NextScreen
) /* I'm not the last screen */
276 while ( current
->NextScreen
)
278 current
= current
->NextScreen
;
282 previous
->NextScreen
= screen
->NextScreen
;
286 IntuitionBase
->FirstScreen
= screen
->NextScreen
;
288 current
->NextScreen
= screen
;
289 screen
->NextScreen
= NULL
;
293 } /* SDEPTH_INFAMILY */
298 if ( GetPrivScreen(current
)->SpecialFlags
& (SF_IsChild
|SF_IsParent
) )
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
;
319 prefamily
->NextScreen
= current
->NextScreen
;
323 IntuitionBase
->FirstScreen
= current
->NextScreen
;
325 last
->NextScreen
= family
;
326 current
->NextScreen
= NULL
;
329 } /* if ( GetPrivScreen(current)->SpecialFlags & (SF_IsChild|SF_IsParent) ) */
332 if ( current
->NextScreen
) /* I'm not the last screen */
334 while ( current
->NextScreen
)
336 current
= current
->NextScreen
;
340 previous
->NextScreen
= screen
->NextScreen
;
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
);
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
)
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
)))
379 if (!win
) win
= scanw
;
382 if (!win
) win
= IntuitionBase
->FirstScreen
->FirstWindow
;
383 if (IntuitionBase
->ActiveWindow
&& IntuitionBase
->ActiveWindow
->WScreen
== IntuitionBase
->FirstScreen
) win
= NULL
;
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
;