2 Copyright 1995-2003, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
9 #include <graphics/videocontrol.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <proto/layers.h>
13 #include "intuition_intern.h"
14 #include "inputhandler_actions.h"
17 # include "intuition_customize.h"
20 #ifndef DEBUG_CloseScreen
21 #define DEBUG_CloseScreen 0
27 #include <aros/debug.h>
29 struct CloseScreenActionMsg
31 struct IntuiActionMsg msg
;
32 struct Screen
*Screen
;
35 static VOID
int_closescreen(struct CloseScreenActionMsg
*msg
,
36 struct IntuitionBase
*IntuitionBase
);
38 /*****************************************************************************
41 #include <intuition/screens.h>
42 #include <proto/intuition.h>
44 AROS_LH1(BOOL
, CloseScreen
,
47 AROS_LHA(struct Screen
*, screen
, A0
),
50 struct IntuitionBase
*, IntuitionBase
, 11, Intuition
)
54 Release all resources held by a screen and close it down visually.
58 screen -- pointer to the screen to be closed
62 TRUE if the screen is successfully closed, FALSE if there were still
63 windows left on the screen (which means the screen is not closed).
75 *****************************************************************************/
78 AROS_LIBBASE_EXT_DECL(struct IntuitionBase
*,IntuitionBase
)
80 struct CloseScreenActionMsg msg
;
82 DEBUG_CLOSESCREEN(dprintf("CloseScreen: Screen 0x%lx\n", screen
));
84 D(bug("CloseScreen (%p)\n", screen
));
88 ReturnBool("CloseScreen",TRUE
);
91 if (screen
!= GetPrivIBase(IntuitionBase
)->WorkBench
) FireScreenNotifyMessage((IPTR
) screen
, SNOTIFY_BEFORE_CLOSESCREEN
, IntuitionBase
);
94 /* there's a second check below for public screens */
95 if (screen
->FirstWindow
)
97 D(bug("CloseScreen: fail, window still opened\n"));
98 ReturnBool("CloseScreen",FALSE
);
102 /* let's wait for user to finish window drag/size actions to avoid
103 deadlocks and not break user's input */
104 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
107 DEBUG_CLOSESCREEN(dprintf("CloseScreen: LockPubScreenList\n"));
109 DEBUG_CLOSESCREEN(dprintf("CloseScreen: LockPubScreenList done\n"));
112 DoSyncAction((APTR
)int_closescreen
,&msg
.msg
,IntuitionBase
);
114 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockPubScreenList\n"));
115 UnlockPubScreenList();
116 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockPubScreenList done\n"));
118 if (GetPrivScreen(screen
)->pubScrNode
!= NULL
)
121 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
123 DEBUG_CLOSESCREEN(dprintf("CloseScreen: failed\n"));
124 //something went wrong! int_closescreen is supposed to clear pubScrNode ptr!
128 /* kill screen bar */
129 KillScreenBar(screen
, IntuitionBase
);
131 /* kill depth gadget */
132 if (((struct IntScreen
*)screen
)->depthgadget
)
134 Object
*im
= (Object
*)((struct Gadget
*)(((struct IntScreen
*)screen
)->depthgadget
))->GadgetRender
;
137 DisposeObject(((struct IntScreen
*)screen
)->depthgadget
);
143 FreeVPortCopLists(&screen
->ViewPort
);
146 struct TagItem tags
[2];
148 tags
[0].ti_Tag
= VTAG_ATTACH_CM_GET
;
150 tags
[1].ti_Tag
= VTAG_END_CM
;
152 if (VideoControl(screen
->ViewPort
.ColorMap
, tags
))
154 GfxFree((APTR
)tags
[0].ti_Data
);
158 /* !!! Setting a new front bitmap MUST be done before freeing the old one */
159 if (NULL
!= IntuitionBase
->FirstScreen
)
161 /* We MUST pas FALSE in the "copyback" parameter
162 since the old screen bitmap has been deleted
164 SetFrontBitMap(IntuitionBase
->FirstScreen
->RastPort
.BitMap
, FALSE
);
169 SetFrontBitMap(NULL
, FALSE
);
174 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
177 /* Free the RasInfo of the viewport */
178 FreeMem(screen
->ViewPort
.RasInfo
, sizeof (struct RasInfo
));
180 /* Uninit the layerinfo */
182 ThinLayerInfo(&screen
->LayerInfo
);
184 /* Free the screen's bitmap */
186 if (GetPrivScreen(screen
)->AllocatedBitmap
)
187 FreeBitMap(GetPrivScreen(screen
)->AllocatedBitmap
);
188 screen
->RastPort
.BitMap
= NULL
;
190 /* Free the RastPort's contents */
191 DeinitRastPort(&screen
->RastPort
);
193 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri_ScrDecorObj
);
194 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri_WinDecorObj
);
197 if (((struct IntScreen
*)screen
)->DInfo
.dri_Customize
)
200 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri_Customize
->submenu
);
201 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri_Customize
->menutoggle
);
202 int_SkinAction(SKA_FreeSkin
,(ULONG
*)&((struct IntScreen
*)(screen
))->DInfo
,(struct Screen
*)screen
,IntuitionBase
);
203 int_FreeTitlebarBuffer(((struct IntScreen
*)(screen
)),IntuitionBase
);
204 FreeMem(((struct IntScreen
*)screen
)->DInfo
.dri_Customize
,sizeof (struct IntuitionCustomize
));
208 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri
.dri_CheckMark
);
209 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri
.dri_AmigaKey
);
212 CloseFont(((struct IntScreen
*)screen
)->DInfo
.dri
.dri_Font
);
214 /* Free the ColorMap */
215 FreeColorMap(screen
->ViewPort
.ColorMap
);
217 /* Free the sprite */
218 ReleaseSharedPointer(((struct IntScreen
*)screen
)->Pointer
, IntuitionBase
);
220 /* Free the memory */
221 FreeMem(screen
, sizeof (struct IntScreen
));
223 if (screen
!= GetPrivIBase(IntuitionBase
)->WorkBench
) FireScreenNotifyMessage((IPTR
) screen
, SNOTIFY_AFTER_CLOSESCREEN
, IntuitionBase
);
225 DEBUG_CLOSESCREEN(dprintf("CloseScreen: ok\n"));
227 ReturnBool("CloseScreen",TRUE
);
232 static VOID
int_closescreen(struct CloseScreenActionMsg
*msg
,
233 struct IntuitionBase
*IntuitionBase
)
235 struct Screen
*parent
,*screen
= msg
->Screen
;
236 struct Window
*win
= 0;
239 /* If this is a public screen, free related information if there are
240 no windows left on the screen */
241 if (GetPrivScreen(screen
)->pubScrNode
!= NULL
)
243 if(GetPrivScreen(screen
)->pubScrNode
->psn_VisitorCount
|| screen
->FirstWindow
)
245 DEBUG_CLOSESCREEN(dprintf("CloseScreen: failed\n"));
249 Remove((struct Node
*)GetPrivScreen(screen
)->pubScrNode
);
251 if(GetPrivScreen(screen
)->pubScrNode
->psn_Node
.ln_Name
!= NULL
)
252 FreeVec(GetPrivScreen(screen
)->pubScrNode
->psn_Node
.ln_Name
);
254 FreeMem(GetPrivScreen(screen
)->pubScrNode
,
255 sizeof(struct PubScreenNode
));
257 GetPrivScreen(screen
)->pubScrNode
= 0;
260 RemoveResourceFromList(screen
, RESOURCE_SCREEN
, IntuitionBase
);
262 DEBUG_CLOSESCREEN(dprintf("CloseScreen: LockIBase\n"));
266 DEBUG_CLOSESCREEN(dprintf("CloseScreen: LockIBase done\n"));
268 /* Trick: Since NextScreen is the first field of the structure,
269 we can use the pointer in the IntuitionBase as a screen with
270 the structure-size of one pointer */
271 parent
= (struct Screen
*)&(IntuitionBase
->FirstScreen
);
273 /* For all screens... */
274 while (parent
->NextScreen
)
276 /* If the screen to close is the next screen... */
277 if (parent
->NextScreen
== screen
)
281 parent
->NextScreen
= screen
->NextScreen
;
283 /* Check ActiveScreen */
284 if (IntuitionBase
->ActiveScreen
== screen
)
286 if (screen
->NextScreen
)
287 IntuitionBase
->ActiveScreen
= screen
->NextScreen
;
288 else if (IntuitionBase
->FirstScreen
)
289 IntuitionBase
->ActiveScreen
= parent
;
291 IntuitionBase
->ActiveScreen
= NULL
;
294 /* now let's set the default pub screen */
295 if (GetPrivIBase(IntuitionBase
)->DefaultPubScreen
== screen
)
300 GetPrivIBase(IntuitionBase
)->DefaultPubScreen
= NULL
;
301 scr
= IntuitionBase
->FirstScreen
;
303 if (scr
&& GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_DEFPUBSCREEN
&& GetPrivScreen(scr
)->pubScrNode
&& (scr
->Flags
& (PUBLICSCREEN
| WBENCHSCREEN
)))
305 GetPrivIBase(IntuitionBase
)->DefaultPubScreen
= scr
;
309 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockIBase\n"));
311 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockIBase done\n"));
313 #ifdef TIMEVALWINDOWACTIVATION
314 if (IntuitionBase
->FirstScreen
&& ((GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_SCREENACTIVATION
) || !IntuitionBase
->ActiveWindow
))
316 struct Window
*scanw
= 0;
318 for (scanw
= IntuitionBase
->FirstScreen
->FirstWindow
; scanw
; scanw
= scanw
->NextWindow
)
322 if ((IW(scanw
)->activationtime
.tv_secs
> IW(win
)->activationtime
.tv_secs
) ||
323 ((IW(scanw
)->activationtime
.tv_secs
== IW(win
)->activationtime
.tv_secs
) && (IW(scanw
)->activationtime
.tv_micro
> IW(win
)->activationtime
.tv_micro
)))
329 if (!win
) win
= scanw
;
332 if (!win
) win
= IntuitionBase
->FirstScreen
->FirstWindow
;
333 if (GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_SCREENACTIVATION
)
334 if (IntuitionBase
->ActiveWindow
&& IntuitionBase
->ActiveWindow
->WScreen
== IntuitionBase
->FirstScreen
) win
= NULL
;
335 if (win
) ActivateWindow(win
);
340 parent
= parent
->NextScreen
;
343 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockIBase\n"));
345 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockIBase done\n"));