2 Copyright 1995-2010, 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 *****************************************************************************/
79 struct CloseScreenActionMsg msg
;
81 DEBUG_CLOSESCREEN(dprintf("CloseScreen: Screen 0x%lx\n", screen
));
83 D(bug("CloseScreen (%p)\n", screen
));
87 ReturnBool("CloseScreen",TRUE
);
90 if (screen
!= GetPrivIBase(IntuitionBase
)->WorkBench
) FireScreenNotifyMessage((IPTR
) screen
, SNOTIFY_BEFORE_CLOSESCREEN
, IntuitionBase
);
92 /* Push ExitScreen Message to the Screensdecoration Class */
93 struct sdpExitScreen semsg
;
95 semsg
.MethodID
= SDM_EXITSCREEN
;
96 semsg
.sdp_UserBuffer
= ((struct IntScreen
*)screen
)->DecorUserBuffer
;
97 semsg
.sdp_TrueColor
= (((struct IntScreen
*)screen
)->DInfo
.dri
.dri_Flags
& DRIF_DIRECTCOLOR
);
98 DoMethodA(((struct IntScreen
*)screen
)->ScrDecorObj
, (Msg
)&semsg
);
100 /* there's a second check below for public screens */
101 if (screen
->FirstWindow
)
103 DEBUG_CLOSESCREEN(dprintf("CloseScreen: fail, window still opened\n"));
104 ReturnBool("CloseScreen",FALSE
);
108 /* let's wait for user to finish window drag/size actions to avoid
109 deadlocks and not break user's input */
110 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
113 DEBUG_CLOSESCREEN(dprintf("CloseScreen: LockPubScreenList\n"));
115 DEBUG_CLOSESCREEN(dprintf("CloseScreen: LockPubScreenList done\n"));
118 DoSyncAction((APTR
)int_closescreen
,&msg
.msg
,IntuitionBase
);
120 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockPubScreenList\n"));
121 UnlockPubScreenList();
122 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockPubScreenList done\n"));
124 if (GetPrivScreen(screen
)->pubScrNode
!= NULL
)
127 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
129 DEBUG_CLOSESCREEN(dprintf("CloseScreen: failed\n"));
130 //something went wrong! int_closescreen is supposed to clear pubScrNode ptr!
134 /* kill screen bar */
135 KillScreenBar(screen
, IntuitionBase
);
137 /* kill depth gadget */
138 if (((struct IntScreen
*)screen
)->depthgadget
)
140 Object
*im
= (Object
*)((struct Gadget
*)(((struct IntScreen
*)screen
)->depthgadget
))->GadgetRender
;
143 DisposeObject(((struct IntScreen
*)screen
)->depthgadget
);
148 FreeVPortCopLists(&screen
->ViewPort
);
151 ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
154 /* Free the RasInfo of the viewport */
155 FreeMem(screen
->ViewPort
.RasInfo
, sizeof (struct RasInfo
));
157 /* Uninit the layerinfo */
159 ThinLayerInfo(&screen
->LayerInfo
);
161 /* Free the screen's bitmap */
163 if (GetPrivScreen(screen
)->AllocatedBitmap
)
164 FreeBitMap(GetPrivScreen(screen
)->AllocatedBitmap
);
165 screen
->RastPort
.BitMap
= NULL
;
167 /* Free the RastPort's contents */
168 DeinitRastPort(&screen
->RastPort
);
171 if (((struct IntScreen
*)screen
)->DInfo
.dri_Customize
)
174 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri_Customize
->submenu
);
175 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri_Customize
->menutoggle
);
176 int_SkinAction(SKA_FreeSkin
,(ULONG
*)&((struct IntScreen
*)(screen
))->DInfo
,(struct Screen
*)screen
,IntuitionBase
);
177 int_FreeTitlebarBuffer(((struct IntScreen
*)(screen
)),IntuitionBase
);
178 FreeMem(((struct IntScreen
*)screen
)->DInfo
.dri_Customize
,sizeof (struct IntuitionCustomize
));
182 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri
.dri_CheckMark
);
183 DisposeObject(((struct IntScreen
*)screen
)->DInfo
.dri
.dri_AmigaKey
);
186 CloseFont(((struct IntScreen
*)screen
)->DInfo
.dri
.dri_Font
);
188 /* Free the ColorMap */
189 FreeColorMap(screen
->ViewPort
.ColorMap
);
191 /* Free the sprite */
192 ReleaseSharedPointer(((struct IntScreen
*)screen
)->Pointer
, IntuitionBase
);
194 /* Free the memory */
195 if (((struct IntScreen
*)screen
)->DecorUserBuffer
)
197 FreeMem((APTR
)((struct IntScreen
*)screen
)->DecorUserBuffer
, ((struct IntScreen
*)screen
)->DecorUserBufferSize
);
201 ObtainSemaphore(&((struct IntIntuitionBase
*)(IntuitionBase
))->ScrDecorSem
);
202 ULONG lock
= LockIBase(0);
204 struct NewDecorator
*nd
= ((struct IntScreen
*)screen
)->Decorator
;
206 if ((nd
!= ((struct IntIntuitionBase
*)(IntuitionBase
))->Decorator
) && (nd
!= NULL
))
210 if ((nd
->nd_cnt
== 0) && (nd
->nd_Port
!= NULL
) && (nd
->nd_IntPattern
== NULL
))
212 struct DecoratorMessage msg
;
213 struct MsgPort
*port
= CreateMsgPort();
216 Remove((struct Node
*)nd
);
218 if (nd
->nd_IntPattern
) FreeVec(nd
->nd_IntPattern
);
220 msg
.dm_Message
.mn_ReplyPort
= port
;
221 msg
.dm_Message
.mn_Magic
= MAGIC_DECORATOR
;
222 msg
.dm_Message
.mn_Version
= DECORATOR_VERSION
;
223 msg
.dm_Class
= DM_CLASS_DESTROYDECORATOR
;
226 msg
.dm_Object
= (IPTR
) nd
;
227 PutMsg(nd
->nd_Port
, (struct Message
*) &msg
);
235 ReleaseSemaphore(&((struct IntIntuitionBase
*)(IntuitionBase
))->ScrDecorSem
);
238 /* Free the memory */
239 FreeMem(screen
, sizeof (struct IntScreen
));
241 if (screen
!= GetPrivIBase(IntuitionBase
)->WorkBench
) FireScreenNotifyMessage((IPTR
) screen
, SNOTIFY_AFTER_CLOSESCREEN
, IntuitionBase
);
243 DEBUG_CLOSESCREEN(dprintf("CloseScreen: ok\n"));
245 ReturnBool("CloseScreen",TRUE
);
250 static VOID
int_closescreen(struct CloseScreenActionMsg
*msg
,
251 struct IntuitionBase
*IntuitionBase
)
253 struct Screen
*parent
,*screen
= msg
->Screen
;
254 struct Window
*win
= 0;
257 /* If this is a public screen, free related information if there are
258 no windows left on the screen */
259 if (GetPrivScreen(screen
)->pubScrNode
!= NULL
)
261 if(GetPrivScreen(screen
)->pubScrNode
->psn_VisitorCount
|| screen
->FirstWindow
)
263 DEBUG_CLOSESCREEN(dprintf("CloseScreen: failed\n"));
267 Remove((struct Node
*)GetPrivScreen(screen
)->pubScrNode
);
269 if(GetPrivScreen(screen
)->pubScrNode
->psn_Node
.ln_Name
!= NULL
)
270 FreeVec(GetPrivScreen(screen
)->pubScrNode
->psn_Node
.ln_Name
);
272 FreeMem(GetPrivScreen(screen
)->pubScrNode
,
273 sizeof(struct PubScreenNode
));
275 GetPrivScreen(screen
)->pubScrNode
= 0;
278 RemoveResourceFromList(screen
, RESOURCE_SCREEN
, IntuitionBase
);
280 DEBUG_CLOSESCREEN(dprintf("CloseScreen: LockIBase\n"));
284 DEBUG_CLOSESCREEN(dprintf("CloseScreen: LockIBase done\n"));
286 /* Trick: Since NextScreen is the first field of the structure,
287 we can use the pointer in the IntuitionBase as a screen with
288 the structure-size of one pointer */
289 parent
= (struct Screen
*)&(IntuitionBase
->FirstScreen
);
291 /* For all screens... */
292 while (parent
->NextScreen
)
294 /* If the screen to close is the next screen... */
295 if (parent
->NextScreen
== screen
)
299 parent
->NextScreen
= screen
->NextScreen
;
301 /* Check ActiveScreen */
302 if (IntuitionBase
->ActiveScreen
== screen
)
304 if (screen
->NextScreen
)
305 IntuitionBase
->ActiveScreen
= screen
->NextScreen
;
306 else if (IntuitionBase
->FirstScreen
)
307 IntuitionBase
->ActiveScreen
= parent
;
309 IntuitionBase
->ActiveScreen
= NULL
;
312 /* now let's set the default pub screen */
313 if (GetPrivIBase(IntuitionBase
)->DefaultPubScreen
== screen
)
317 GetPrivIBase(IntuitionBase
)->DefaultPubScreen
= NULL
;
318 scr
= IntuitionBase
->FirstScreen
;
320 if (scr
&& GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_DEFPUBSCREEN
&& GetPrivScreen(scr
)->pubScrNode
&& (scr
->Flags
& (PUBLICSCREEN
| WBENCHSCREEN
)))
322 GetPrivIBase(IntuitionBase
)->DefaultPubScreen
= scr
;
326 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockIBase\n"));
328 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockIBase done\n"));
330 #ifdef TIMEVALWINDOWACTIVATION
331 if (IntuitionBase
->FirstScreen
&& ((GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_SCREENACTIVATION
) || !IntuitionBase
->ActiveWindow
))
333 struct Window
*scanw
= 0;
335 for (scanw
= IntuitionBase
->FirstScreen
->FirstWindow
; scanw
; scanw
= scanw
->NextWindow
)
339 if ((IW(scanw
)->activationtime
.tv_secs
> IW(win
)->activationtime
.tv_secs
) ||
340 ((IW(scanw
)->activationtime
.tv_secs
== IW(win
)->activationtime
.tv_secs
) && (IW(scanw
)->activationtime
.tv_micro
> IW(win
)->activationtime
.tv_micro
)))
346 if (!win
) win
= scanw
;
349 if (!win
) win
= IntuitionBase
->FirstScreen
->FirstWindow
;
350 if (GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_SCREENACTIVATION
)
351 if (IntuitionBase
->ActiveWindow
&& IntuitionBase
->ActiveWindow
->WScreen
== IntuitionBase
->FirstScreen
) win
= NULL
;
352 if (win
) ActivateWindow(win
);
357 parent
= parent
->NextScreen
;
360 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockIBase\n"));
362 DEBUG_CLOSESCREEN(dprintf("CloseScreen: UnLockIBase done\n"));