fix the sam440 build - rename to prevent ambiguity. (NicJA)
[AROS.git] / rom / intuition / openworkbench.c
blob131da767ebbe81881c045ce78a4dfb80a7b40368
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
5 */
7 #define DEBUG 0
8 #include <aros/config.h>
9 #include <intuition/intuition.h>
10 #include <proto/intuition.h>
11 #include <proto/graphics.h>
13 #include "intuition_intern.h"
15 static ULONG FindMode(ULONG width, ULONG height, ULONG depth, struct IntuitionBase *IntuitionBase)
17 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
18 ULONG modeid;
19 struct TagItem modetags[] =
21 { BIDTAG_DesiredWidth, width }, /* 0 */
22 { BIDTAG_DesiredHeight, height }, /* 1 */
23 { BIDTAG_Depth, depth }, /* 2 */
24 { TAG_DONE, 0 }
27 /* Try to find the specified mode */
28 modeid = BestModeIDA(modetags);
29 D(bug("[OpenWorkbench] Size: %dx%d, depth: %d, ModeID 0x%08X\n", width, height, depth, modeid));
31 if (modeid == INVALID_ID)
33 /* If failed, we can have this resolution, but not this depth. Try 4 colors. */
34 modetags[2].ti_Data = 2;
36 modeid = BestModeIDA(modetags);
37 D(bug("[OpenWorkbench] Size: %dx%d, depth: 2, ModeID 0x%08X\n", width, height, modeid));
40 return modeid;
43 /*****************************************************************************
45 NAME */
46 AROS_LH0(IPTR, OpenWorkBench,
48 /* SYNOPSIS */
50 /* LOCATION */
51 struct IntuitionBase *, IntuitionBase, 35, Intuition)
53 /* FUNCTION
54 Attempt to open the Workbench screen.
56 INPUTS
57 None.
59 RESULT
60 Tries to (re)open WorkBench screen. If successful return value
61 is a pointer to the screen structure, which shouldn't be used,
62 because other programs may close the WorkBench and make the
63 pointer invalid. If this function fails the return value is NULL.
65 NOTES
67 EXAMPLE
69 BUGS
71 SEE ALSO
72 CloseWorkBench()
74 INTERNALS
76 *****************************************************************************/
78 AROS_LIBFUNC_INIT
80 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
81 struct Screen *wbscreen;
83 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: <%s>\n",
84 FindTask(NULL)->tc_Node.ln_Name));
86 /* Intuition not up yet? */
87 if (!GetPrivIBase(IntuitionBase)->DefaultPointer)
88 return FALSE;
90 LockPubScreenList();
92 wbscreen = GetPrivIBase(IntuitionBase)->WorkBench;
94 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: Workbench 0x%lx\n",
95 (ULONG) wbscreen));
97 if (wbscreen)
99 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: returning Workbench screen at 0x%lx\n",
100 (ULONG) wbscreen));
102 UnlockPubScreenList();
104 FireScreenNotifyMessage((IPTR) wbscreen, SNOTIFY_AFTER_OPENWB, IntuitionBase);
106 return (IPTR)wbscreen;
108 else
110 /* Open the Workbench screen if we don't have one. */
111 WORD width, height, depth;
112 ULONG modeid;
113 APTR disphandle;
115 struct TagItem screenTags[] =
117 { SA_Width, 0 }, /* 0 */
118 { SA_Height, 0 }, /* 1 */
119 { SA_Depth, 0 }, /* 2 */
120 { SA_DisplayID, 0 }, /* 3 */
121 { SA_LikeWorkbench, TRUE }, /* 4 */
122 { SA_Type, WBENCHSCREEN }, /* 5 */
123 { SA_Title, (IPTR) "Workbench Screen" }, /* 6 */
124 { SA_PubName, (IPTR) "Workbench" }, /* 7 */
125 { SA_SharePens, TRUE }, /* 8 */
126 { TAG_END, 0 }
129 if (!GetPrivIBase(IntuitionBase)->ScreenModePrefs)
130 SetDisplayDefaults(IntuitionBase);
132 width = GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Width;
133 height = GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Height;
134 depth = GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Depth;
135 modeid = GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_DisplayID;
137 D(bug("[OpenWorkbench] Requested size: %dx%d, depth: %d, ModeID: 0x%08lX\n", width, height, depth, modeid));
139 /* First check if the specified ModeID exists in the system */
140 disphandle = FindDisplayInfo(modeid);
141 if (!disphandle)
143 D(bug("[OpenWorkbench] Invalid ModeID given\n"));
144 modeid = INVALID_ID;
147 if (modeid == INVALID_ID)
150 * We were unable to find the ModeID specified in our prefs. Need to find a replacement.
151 * First we'll try to look up a mode corresponding to user-specified width, height and depth.
154 /* Specifying -1's here causes BestModeIDA() to fail, fix up the values */
155 if (width == STDSCREENWIDTH)
157 D(bug("[OpenWorkbench] Using default width %d\n", GfxBase->NormalDisplayColumns));
158 width = GfxBase->NormalDisplayColumns;
160 if (height == STDSCREENHEIGHT)
162 D(bug("[OpenWorkbench] Using default height %d\n", GfxBase->NormalDisplayRows));
163 height = GfxBase->NormalDisplayRows;
165 if (depth == -1)
166 depth = AROS_NOMINAL_DEPTH;
168 #ifdef __mc68000
169 /* FIXME: less hacky RTG detection */
170 /* select 640x480 if we appear to have RTG hardware (instead of standard PAL/NTSC mode) */
171 if (height < 480)
173 modeid = BestModeID(BIDTAG_DesiredWidth, 800, BIDTAG_DesiredHeight, 600,
174 BIDTAG_Depth, 8, TAG_DONE);
176 if (modeid != INVALID_ID)
178 /* If we have 800x600 or better mode, we assume we have RTG hardware */
179 height = 480;
182 #endif
184 modeid = FindMode(width, height, depth, IntuitionBase);
187 if (modeid == INVALID_ID)
189 /* We don't have any modes with the specified resolution. Try SVGA default (800x600) */
190 modeid = FindMode(800, 600, depth, IntuitionBase);
193 if (modeid == INVALID_ID)
195 /* We don't have any modes with the specified resolution. Try VGA default (640x480) */
196 modeid = FindMode(640, 480, depth, IntuitionBase);
199 if (modeid == INVALID_ID)
201 /* We don't have any modes with the specified resolution. Try Amiga default (640x200) */
202 modeid = FindMode(640, 200, depth, IntuitionBase);
205 if (modeid == INVALID_ID)
208 * There's no even 640x200. Perhaps we are on some mobile device.
209 * Here we try the smallest known screen. This size was picked up
210 * from configure's defaults for old PalmPilot port.
212 modeid = FindMode(160, 160, depth, IntuitionBase);
215 if (modeid != INVALID_ID)
217 struct DimensionInfo dim;
219 #define BOUND(min, val, max) \
220 (((val) == -1) ? -1 : ((min) > (val)) ? (min) : ((max) < (val)) ? (max) : (val))
222 /* Now fix up our specified size to fit into mode's limits. */
223 if (GetDisplayInfoData(NULL, (UBYTE *)&dim, sizeof(dim), DTAG_DIMS, modeid))
225 D(bug("[OpenWorkbench] Minimum size: %dx%d\n", dim.MinRasterWidth, dim.MinRasterHeight));
226 D(bug("[OpenWorkbench] Maximum size: %dx%d\n", dim.MaxRasterWidth, dim.MaxRasterHeight));
227 D(bug("[OpenWorkbench] Maximum depth: %d\n", dim.MaxDepth));
229 width = BOUND(dim.MinRasterWidth, width, dim.MaxRasterWidth);
230 height = BOUND(dim.MinRasterHeight, height, dim.MaxRasterHeight);
231 depth = BOUND(0, depth, dim.MaxDepth);
232 D(bug("[OpenWorkbench] Corrected size: %dx%d %dbpp\n", width, height, depth));
234 GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Width = width;
235 GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Height = height;
236 GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Depth = depth;
240 * Cache the used display info.
241 * OpenScreen() with SA_LikeWorkbench set to TRUE
242 * uses the DisplayID field. We MUST have something valid here.
244 if (GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_DisplayID != modeid)
246 GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_DisplayID = modeid;
247 GetPrivIBase(IntuitionBase)->ActivePreferences.wb_Width = width;
248 GetPrivIBase(IntuitionBase)->ActivePreferences.wb_Height = height;
249 GetPrivIBase(IntuitionBase)->ActivePreferences.wb_Depth = depth;
252 screenTags[0].ti_Data = width;
253 screenTags[1].ti_Data = height;
254 screenTags[2].ti_Data = depth;
255 screenTags[3].ti_Data = modeid;
257 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: Trying to open Workbench screen\n"));
259 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_BEFORE_OPENWB, IntuitionBase);
261 wbscreen = OpenScreenTagList(NULL, screenTags);
263 if (wbscreen)
264 GetPrivIBase(IntuitionBase)->ActivePreferences.wb_Depth = GetBitMapAttr(wbscreen->RastPort.BitMap, BMA_DEPTH);
267 if( !wbscreen )
269 DEBUG_OPENWORKBENCH(dprintf("OpenWorkBench: failed to open Workbench screen !!!!\n"));
271 UnlockPubScreenList();
272 return 0;
275 GetPrivIBase(IntuitionBase)->WorkBench = wbscreen;
277 /* Make the screen public. */
278 PubScreenStatus( wbscreen, 0 );
281 /* We have opened the Workbench Screen. Now tell the Workbench process
282 to open it's windows, if there is one. We still do have the pub screen
283 list locked. But while sending the Message to the Workbench task we
284 must unlock the semaphore, otherwise there can be deadlocks if the
285 Workbench task itself does something which locks the pub screen list.
287 But if we unlock the pub screen list, then some other task could try
288 to close the Workbench screen in the meantime. The trick to solve
289 this problem is to increase the psn_VisitorCount of the Workbench
290 screen here, before unlocking the pub screen list. This way the
291 Workbench screen cannot go away. */
293 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount++;
294 DEBUG_VISITOR(dprintf("OpenWorkbench: new VisitorCount %ld\n",
295 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount));
297 UnlockPubScreenList();
299 DEBUG_VISITOR(dprintf("OpenWorkbench: notify Workbench\n"));
301 /* Don't call this function while pub screen list is locked! */
302 TellWBTaskToOpenWindows(IntuitionBase);
304 /* Now fix the psn_VisitorCount we have increased by one, above. It's probably
305 better to do this by hand, instead of calling UnlockPubScreen, because Un-
306 lockPubScreen can send signal to psn_SigTask. */
308 LockPubScreenList();
309 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount--;
310 DEBUG_VISITOR(dprintf("OpenWorkbench: new VisitorCount %ld\n",
311 GetPrivScreen(wbscreen)->pubScrNode->psn_VisitorCount));
312 UnlockPubScreenList();
314 FireScreenNotifyMessage((IPTR) wbscreen, SNOTIFY_AFTER_OPENWB, IntuitionBase);
316 return (IPTR)wbscreen;
318 AROS_LIBFUNC_EXIT
320 } /* OpenWorkBench */