added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / rom / intuition / openworkbench.c
blob173c13434d3807a6f10b365ec4e8b1ec73f7dd9f
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 LockPubScreenList();
59 wbscreen = GetPrivIBase(IntuitionBase)->WorkBench;
61 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: Workbench 0x%lx\n",
62 (ULONG) wbscreen));
64 if (wbscreen)
66 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: returning Workbench screen at 0x%lx\n",
67 (ULONG) wbscreen));
69 UnlockPubScreenList();
71 FireScreenNotifyMessage((IPTR) wbscreen, SNOTIFY_AFTER_OPENWB, IntuitionBase);
73 return (IPTR)wbscreen;
75 else
77 /* Open the Workbench screen if we don't have one. */
79 WORD width = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width;
80 WORD height = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height;
81 WORD depth = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Depth;
82 ULONG modeid = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_DisplayID;
84 struct TagItem screenTags[] =
86 { SA_Width, 0 }, /* 0 */
87 { SA_Height, 0 }, /* 1 */
88 { SA_Depth, depth }, /* 2 */
89 { SA_DisplayID, 0 }, /* 3 */
90 { SA_LikeWorkbench, TRUE }, /* 4 */
91 { SA_Type, WBENCHSCREEN }, /* 5 */
92 { SA_Title, (IPTR) "Workbench Screen" }, /* 6 */
93 { SA_PubName, (IPTR) "Workbench" }, /* 7 */
94 { SA_SharePens, TRUE }, /* 8 */
95 { TAG_END, 0 }
98 APTR disphandle = FindDisplayInfo(modeid);
100 if (!disphandle)
102 struct TagItem modetags[] =
104 { BIDTAG_DesiredWidth, width },
105 { BIDTAG_DesiredHeight, height },
106 { BIDTAG_Depth, depth },
107 { TAG_DONE, 0 }
110 modeid = BestModeIDA(modetags);
111 disphandle = FindDisplayInfo(modeid);
114 if (disphandle)
116 struct DimensionInfo dim;
118 #define BOUND(min, val, max) \
119 (((min) > (val)) ? (min) : ((max) < (val)) ? (max) : (val))
121 if (GetDisplayInfoData(disphandle, (UBYTE *)&dim, sizeof(dim), DTAG_DIMS, 0))
123 width = BOUND(dim.MinRasterWidth, width, dim.MaxRasterWidth);
124 height = BOUND(dim.MinRasterHeight, height, dim.MaxRasterHeight);
125 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width = width;
126 GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height = height;
128 screenTags[3].ti_Data = modeid;
130 else
131 screenTags[3].ti_Tag = TAG_IGNORE;
133 screenTags[0].ti_Data = width;
134 screenTags[1].ti_Data = height;
136 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: Trying to open Workbench screen\n"));
138 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_BEFORE_OPENWB, IntuitionBase);
140 wbscreen = OpenScreenTagList(NULL, screenTags);
142 if( !wbscreen )
144 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: failed to open Workbench screen !!!!\n"));
146 UnlockPubScreenList();
147 return 0;
150 GetPrivIBase(IntuitionBase)->WorkBench = wbscreen;
152 /* Make the screen public. */
153 PubScreenStatus( wbscreen, 0 );
157 /* We have opened the Workbench Screen. Now tell the Workbench process
158 to open it's windows, if there is one. We still do have the pub screen
159 list locked. But while sending the Message to the Workbench task we
160 must unlock the semaphore, otherwise there can be deadlocks if the
161 Workbench task itself does something which locks the pub screen list.
163 But if we unlock the pub screen list, then some other task could try
164 to close the Workbench screen in the meantime. The trick to solve
165 this problem is to increase the psn_VisitorCount of the Workbench
166 screen here, before unlocking the pub screen list. This way the
167 Workbench screen cannot go away. */
169 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount++;
170 DEBUG_VISITOR(dprintf("OpenWorkbench: new VisitorCount %ld\n",
171 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount));
173 UnlockPubScreenList();
175 DEBUG_VISITOR(dprintf("OpenWorkbench: notify Workbench\n"));
177 /* Don't call this function while pub screen list is locked! */
178 TellWBTaskToOpenWindows(IntuitionBase);
180 /* Now fix the psn_VisitorCount we have increased by one, above. It's probably
181 better to do this by hand, instead of calling UnlockPubScreen, because Un-
182 lockPubScreen can send signal to psn_SigTask. */
184 LockPubScreenList();
185 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount--;
186 DEBUG_VISITOR(dprintf("OpenWorkbench: new VisitorCount %ld\n",
187 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount));
188 UnlockPubScreenList();
190 FireScreenNotifyMessage((IPTR) wbscreen, SNOTIFY_AFTER_OPENWB, IntuitionBase);
192 return (IPTR)wbscreen;
194 AROS_LIBFUNC_EXIT
196 } /* OpenWorkBench */