define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / rom / intuition / openworkbench.c
blobc3ad50a55c785d8efca06372e509c8eafd86b165
1 /*
2 Copyright 1995-2007, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 #include "intuition_intern.h"
9 #include <intuition/intuition.h>
10 #include <proto/intuition.h>
11 #include <proto/graphics.h>
13 /*****************************************************************************
15 NAME */
17 AROS_LH0(IPTR, OpenWorkBench,
19 /* SYNOPSIS */
21 /* LOCATION */
22 struct IntuitionBase *, IntuitionBase, 35, Intuition)
24 /* FUNCTION
25 Attempt to open the Workbench screen.
27 INPUTS
28 None.
30 RESULT
31 Tries to (re)open WorkBench screen. If successful return value
32 is a pointer to the screen structure, which shouldn't be used,
33 because other programs may close the WorkBench and make the
34 pointer invalid.
35 If this function fails the return value is NULL.
37 NOTES
39 EXAMPLE
41 BUGS
43 SEE ALSO
44 CloseWorkBench()
46 INTERNALS
48 *****************************************************************************/
50 AROS_LIBFUNC_INIT
52 struct Screen *wbscreen;
54 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: <%s>\n",
55 FindTask(NULL)->tc_Node.ln_Name));
57 /* Intuition not up yet? */
58 if (!GetPrivIBase(IntuitionBase)->DefaultPointer)
59 return FALSE;
61 LockPubScreenList();
63 wbscreen = GetPrivIBase(IntuitionBase)->WorkBench;
65 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: Workbench 0x%lx\n",
66 (ULONG) wbscreen));
68 if (wbscreen)
70 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: returning Workbench screen at 0x%lx\n",
71 (ULONG) wbscreen));
73 UnlockPubScreenList();
75 FireScreenNotifyMessage((IPTR) wbscreen, SNOTIFY_AFTER_OPENWB, IntuitionBase);
77 return (IPTR)wbscreen;
79 else
81 /* Open the Workbench screen if we don't have one. */
83 WORD width = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width;
84 WORD height = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height;
85 WORD depth = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Depth;
86 ULONG modeid = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_DisplayID;
88 struct TagItem screenTags[] =
90 { SA_Width, 0 }, /* 0 */
91 { SA_Height, 0 }, /* 1 */
92 { SA_Depth, depth }, /* 2 */
93 { SA_DisplayID, 0 }, /* 3 */
94 { SA_LikeWorkbench, TRUE }, /* 4 */
95 { SA_Type, WBENCHSCREEN }, /* 5 */
96 { SA_Title, (IPTR) "Workbench Screen" }, /* 6 */
97 { SA_PubName, (IPTR) "Workbench" }, /* 7 */
98 { SA_SharePens, TRUE }, /* 8 */
99 { TAG_END, 0 }
102 APTR disphandle = FindDisplayInfo(modeid);
104 if (!disphandle)
106 struct TagItem modetags[] =
108 { BIDTAG_DesiredWidth, width },
109 { BIDTAG_DesiredHeight, height },
110 { BIDTAG_Depth, depth },
111 { TAG_DONE, 0 }
114 modeid = BestModeIDA(modetags);
115 disphandle = FindDisplayInfo(modeid);
118 if (disphandle)
120 struct DimensionInfo dim;
122 #define BOUND(min, val, max) \
123 (((min) > (val)) ? (min) : ((max) < (val)) ? (max) : (val))
125 if (GetDisplayInfoData(disphandle, (UBYTE *)&dim, sizeof(dim), DTAG_DIMS, 0))
127 width = BOUND(dim.MinRasterWidth, width, dim.MaxRasterWidth);
128 height = BOUND(dim.MinRasterHeight, height, dim.MaxRasterHeight);
129 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width = width;
130 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height = height;
132 screenTags[3].ti_Data = modeid;
134 else
135 screenTags[3].ti_Tag = TAG_IGNORE;
137 screenTags[0].ti_Data = width;
138 screenTags[1].ti_Data = height;
140 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: Trying to open Workbench screen\n"));
142 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_BEFORE_OPENWB, IntuitionBase);
144 wbscreen = OpenScreenTagList(NULL, screenTags);
146 if( !wbscreen )
148 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: failed to open Workbench screen !!!!\n"));
150 UnlockPubScreenList();
151 return 0;
154 GetPrivIBase(IntuitionBase)->WorkBench = wbscreen;
156 /* Make the screen public. */
157 PubScreenStatus( wbscreen, 0 );
161 /* We have opened the Workbench Screen. Now tell the Workbench process
162 to open it's windows, if there is one. We still do have the pub screen
163 list locked. But while sending the Message to the Workbench task we
164 must unlock the semaphore, otherwise there can be deadlocks if the
165 Workbench task itself does something which locks the pub screen list.
167 But if we unlock the pub screen list, then some other task could try
168 to close the Workbench screen in the meantime. The trick to solve
169 this problem is to increase the psn_VisitorCount of the Workbench
170 screen here, before unlocking the pub screen list. This way the
171 Workbench screen cannot go away. */
173 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount++;
174 DEBUG_VISITOR(dprintf("OpenWorkbench: new VisitorCount %ld\n",
175 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount));
177 UnlockPubScreenList();
179 DEBUG_VISITOR(dprintf("OpenWorkbench: notify Workbench\n"));
181 /* Don't call this function while pub screen list is locked! */
182 TellWBTaskToOpenWindows(IntuitionBase);
184 /* Now fix the psn_VisitorCount we have increased by one, above. It's probably
185 better to do this by hand, instead of calling UnlockPubScreen, because Un-
186 lockPubScreen can send signal to psn_SigTask. */
188 LockPubScreenList();
189 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount--;
190 DEBUG_VISITOR(dprintf("OpenWorkbench: new VisitorCount %ld\n",
191 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount));
192 UnlockPubScreenList();
194 FireScreenNotifyMessage((IPTR) wbscreen, SNOTIFY_AFTER_OPENWB, IntuitionBase);
196 return (IPTR)wbscreen;
198 AROS_LIBFUNC_EXIT
200 } /* OpenWorkBench */