fix properties
[AROS.git] / rom / intuition / openscreen.c
blob143cb048043fad17178713ec7eb45b32e322fb30
1 /*
2 Copyright 1995-2010, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
4 $Id$
6 Open a new screen.
7 */
9 #include <exec/memory.h>
10 #include <utility/tagitem.h>
11 #include <intuition/screens.h>
12 #include <intuition/intuition.h>
13 #include <intuition/imageclass.h>
14 #include <intuition/windecorclass.h>
15 #include <intuition/scrdecorclass.h>
16 #include <intuition/gadgetclass.h>
17 #include <intuition/extensions.h>
18 #include <graphics/modeid.h>
19 #include <graphics/videocontrol.h>
20 #include <graphics/displayinfo.h>
21 #include <prefs/screenmode.h>
22 #include <proto/exec.h>
23 #include <proto/graphics.h>
24 #include <proto/layers.h>
25 #include <proto/utility.h>
26 #include <proto/intuition.h>
27 #include <proto/dos.h>
28 #include <string.h>
29 #include <proto/cybergraphics.h>
30 #include <cybergraphx/cybergraphics.h>
31 #include "intuition_intern.h"
32 #include "intuition_customize.h"
33 #include "intuition_extend.h"
34 #include "inputhandler.h"
35 #include "inputhandler_support.h"
36 #include "inputhandler_actions.h"
37 #include "menus.h"
38 #include "monitorclass_private.h"
40 #ifndef DEBUG_OpenScreen
41 #define DEBUG_OpenScreen 0
42 #endif
43 #undef DEBUG
44 #if DEBUG_OpenScreen
45 #define DEBUG 1
46 #endif
47 #include <aros/debug.h>
49 struct OpenScreenActionMsg
51 struct IntuiActionMsg msg;
52 struct IntScreen *Screen;
53 struct NewScreen *NewScreen;
54 struct List *List;
57 static VOID int_openscreen(struct OpenScreenActionMsg *msg,
58 struct IntuitionBase *IntuitionBase);
60 #ifdef SKINS
61 extern const ULONG defaultdricolors[DRIPEN_NUMDRIPENS];
62 #endif
64 /*****************************************************************************
66 NAME */
68 AROS_LH1(struct Screen *, OpenScreen,
70 /* SYNOPSIS */
71 AROS_LHA(struct NewScreen *, newScreen, A0),
73 /* LOCATION */
74 struct IntuitionBase *, IntuitionBase, 33, Intuition)
76 /* FUNCTION
78 INPUTS
80 RESULT
82 NOTES
84 EXAMPLE
86 BUGS
88 SEE ALSO
90 INTERNALS
91 The function relies on display driver object being passed in DimensionInfo.reserved[0]
92 by graphics.library/GetDisplayInfoData()
94 HISTORY
95 29-10-95 digulla automatically created from
96 intuition_lib.fd and clib/intuition_protos.h
98 *****************************************************************************/
100 AROS_LIBFUNC_INIT
102 struct NewScreen ns;
103 struct TagItem *tag, *tagList;
104 IPTR vctl = 0;
105 struct IntScreen *screen;
106 int success;
107 struct Hook *layer_info_hook = NULL;
108 struct ColorSpec *colors = NULL;
109 ULONG *errorPtr; /* Store error at user specified location */
110 UWORD *customdripens = NULL;
111 ULONG *colors32 = NULL;
112 WORD sysfont = -1;
113 BOOL ok = TRUE, rp_inited = FALSE, li_inited = FALSE, sharepens = FALSE;
114 #ifdef USEWINDOWLOCK
115 BOOL windowlock = FALSE;
116 #endif
117 struct Rectangle *dclip = NULL;
118 LONG overscan = OSCAN_TEXT;
119 DisplayInfoHandle displayinfo;
120 struct DimensionInfo dimensions;
121 #ifdef __MORPHOS__
122 struct MonitorInfo monitor;
123 #endif
124 ULONG allocbitmapflags = BMF_DISPLAYABLE;
125 //ULONG lock;
126 WORD numcolors = 0;
127 UWORD spritebase;
128 BOOL workbench = FALSE;
129 BOOL draggable = TRUE;
130 struct TagItem modetags[] =
132 { BIDTAG_Depth , 0UL },
133 { BIDTAG_DesiredWidth , 0UL },
134 { BIDTAG_DesiredHeight , 0UL },
135 { TAG_DONE }
137 ULONG modeid = INVALID_ID;
139 /* Intuition not up yet? */
140 if (!GetPrivIBase(IntuitionBase)->DefaultPointer)
141 return FALSE;
143 ASSERT_VALID_PTR_ROMOK(newScreen);
145 #define COPY(x) screen->Screen.x = ns.x
146 #define SetError(x) if (errorPtr != NULL) *errorPtr = x;
148 D(bug("OpenScreen (%p = { Left=%d Top=%d Width=%d Height=%d Depth=%d })\n"
149 , newScreen
150 , newScreen->LeftEdge
151 , newScreen->TopEdge
152 , newScreen->Width
153 , newScreen->Height
154 , newScreen->Depth
157 FireScreenNotifyMessage((IPTR) newScreen, SNOTIFY_BEFORE_OPENSCREEN, IntuitionBase);
159 ns = *newScreen;
161 if (newScreen->Type & NS_EXTENDED)
163 tagList = ((struct ExtNewScreen *)newScreen)->Extension;
165 else
167 tagList = NULL;
170 DEBUG_OPENSCREEN(dprintf("OpenScreen: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
171 ns.LeftEdge, ns.TopEdge, ns.Width, ns.Height, ns.Depth, tagList));
173 #ifdef __MORPHOS__
174 if (!LocaleBase) LocaleBase = OpenLibrary("locale.library",0);
175 if (!LocaleBase) return NULL;
176 #endif
178 #ifdef USEGETIPREFS //needs INTUITION_THEME_ENCHANCEMENT!
179 if (!GetPrivIBase(IntuitionBase)->IPrefsLoaded && FindPort(SKINMANAGERPORTNAME))
181 /* let's init prefs before 1st OpenScreen that needs them*/
182 int_SkinAction(SKA_GetIPrefs,0,0,IntuitionBase);
184 #endif
186 screen = AllocMem(sizeof (struct IntScreen), MEMF_ANY | MEMF_CLEAR);
188 DEBUG_OPENSCREEN(dprintf("OpenScreen: screen 0x%lx\n", screen));
190 /* Do this really early to be able to report errors */
191 errorPtr = (ULONG *)GetTagData(SA_ErrorCode, 0, tagList);
193 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ErrorCode 0x%lx\n",errorPtr));
195 if (screen == NULL)
197 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
198 SetError(OSERR_NOMEM);
199 return NULL;
202 if (tagList)
204 if (GetTagData(SA_LikeWorkbench, FALSE, tagList))
207 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_LikeWorkbench\n"));
209 ns.Width = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width;
210 ns.Height = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height;
211 ns.Depth = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Depth;
212 modeid = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_DisplayID;
214 if (GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Control & SMF_AUTOSCROLL)
216 /* need to mark autoscroll */
217 ns.Type |= AUTOSCROLL;
219 sysfont = 1;
220 sharepens = TRUE; /* not sure */
223 while((tag = NextTagItem ((const struct TagItem **)&tagList)))
225 DEBUG_OPENSCREEN(dprintf("OpenScreen: Tag 0x%08lx Data 0x%08lx\n",
226 tag->ti_Tag, tag->ti_Data));
227 switch(tag->ti_Tag)
229 case SA_Left:
230 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Left %ld\n",tag->ti_Data));
231 ns.LeftEdge = tag->ti_Data;
232 break;
234 case SA_Top:
235 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Top %ld\n",tag->ti_Data));
236 ns.TopEdge = tag->ti_Data;
237 break;
239 case SA_Width:
240 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Width %ld\n",tag->ti_Data));
241 ns.Width = tag->ti_Data;
242 break;
244 case SA_Height:
245 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Height %ld\n",tag->ti_Data));
246 ns.Height = tag->ti_Data;
247 break;
249 case SA_Depth:
250 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Depth %ld\n",tag->ti_Data));
251 ns.Depth = tag->ti_Data;
252 break;
254 case SA_DetailPen:
255 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DetailPen %ld\n",tag->ti_Data));
256 ns.DetailPen = tag->ti_Data;
257 break;
259 case SA_BlockPen:
260 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BlockPen %ld\n",tag->ti_Data));
261 ns.BlockPen = tag->ti_Data;
262 break;
264 case SA_Type:
265 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Type 0x%lx\n",tag->ti_Data));
266 ns.Type &= ~SCREENTYPE;
267 ns.Type |= tag->ti_Data;
268 break;
270 case SA_Title:
271 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Title <%s>\n",tag->ti_Data));
272 ns.DefaultTitle = (UBYTE *)tag->ti_Data;
273 break;
275 case SA_ID:
276 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ID <%s>\n",tag->ti_Data));
277 screen->ID = StrDup((STRPTR)tag->ti_Data);
278 break;
280 case SA_Font:
281 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Font 0x%lx\n",tag->ti_Data));
282 ns.Font = (struct TextAttr *)tag->ti_Data;
283 break;
285 case SA_Colors32:
286 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors32 0x%lx\n",tag->ti_Data));
287 colors32 = (ULONG *)tag->ti_Data;
288 break;
290 case SA_Colors:
291 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors 0x%lx\n",tag->ti_Data));
292 colors = (struct ColorSpec *)tag->ti_Data;
293 break;
295 case SA_SysFont:
296 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SysFont 0x%lx\n",tag->ti_Data));
297 sysfont = (WORD)tag->ti_Data;
298 break;
300 case SA_BitMap:
301 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap 0x%lx\n",tag->ti_Data));
302 if(tag->ti_Data)
304 ns.Type |= CUSTOMBITMAP;
305 ns.CustomBitMap = (struct BitMap *)tag->ti_Data;
307 else
309 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap==NULL specified, custom bitmap use disabled\n"));
311 break;
313 /* Name of this public screen. */
314 case SA_PubName:
315 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubName <%s>\n",tag->ti_Data));
316 if (!tag->ti_Data)
318 screen->pubScrNode = AllocMem(sizeof(struct PubScreenNode), MEMF_CLEAR);
319 break;
321 else
323 struct Screen *old;
325 LockPubScreenList();
327 if (strcasecmp((char *)tag->ti_Data, "Workbench") == 0)
329 /* FIXME: This would still not be safe, if a normal app tried to open its own screen with SA_PubName=Workbench */
330 if (GetPrivIBase(IntuitionBase)->WorkBench)
332 UnlockPubScreenList();
334 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
336 return NULL;
338 workbench = TRUE;
340 else
342 old = LockPubScreen((STRPTR)tag->ti_Data);
344 if (old != NULL)
346 UnlockPubScreen(NULL, old);
347 SetError(OSERR_PUBNOTUNIQUE);
348 UnlockPubScreenList();
349 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
351 return NULL;
355 UnlockPubScreenList();
358 screen->pubScrNode = AllocMem(sizeof(struct PubScreenNode), MEMF_CLEAR);
360 DEBUG_OPENSCREEN(dprintf("OpenScreen: pubScrNode 0x%lx\n",screen->pubScrNode));
362 if (screen->pubScrNode == NULL)
364 SetError(OSERR_NOMEM);
365 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
367 return NULL;
370 if ((ns.Type & SCREENTYPE) == CUSTOMSCREEN)
372 ns.Type &= ~SCREENTYPE;
373 ns.Type |= PUBLICSCREEN;
376 screen->pubScrNode->psn_Node.ln_Name = AllocVec(MAXPUBSCREENNAME + 1,
377 MEMF_ANY);
379 if (screen->pubScrNode->psn_Node.ln_Name == NULL)
381 SetError(OSERR_NOMEM);
382 FreeMem(screen->pubScrNode, sizeof(struct PubScreenNode));
383 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
385 return NULL;
388 /* Always open public screens in private mode. */
389 screen->pubScrNode->psn_Flags |= PSNF_PRIVATE;
390 strcpy(screen->pubScrNode->psn_Node.ln_Name, (STRPTR)tag->ti_Data);
391 break;
393 /* Signal bit number to use when signalling public screen
394 signal task. */
395 case SA_PubSig:
396 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubSig 0x%lx\n",tag->ti_Data));
397 if (screen->pubScrNode == NULL)
399 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
401 return NULL;
403 /* If no PubTask is set, we set the calling task as default */
404 if (screen->pubScrNode->psn_SigTask == NULL)
405 screen->pubScrNode->psn_SigTask = FindTask(NULL);
407 screen->pubScrNode->psn_SigBit = (UBYTE)tag->ti_Data;
408 break;
410 /* Task that should be signalled when the public screen loses
411 its last visitor window. */
412 case SA_PubTask:
413 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubTask 0x%lx\n",tag->ti_Data));
414 if (screen->pubScrNode == NULL)
416 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
417 return NULL;
419 screen->pubScrNode->psn_SigTask = (struct Task *)tag->ti_Data;
420 break;
422 case SA_BackFill:
423 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackFill Hook 0x%lx\n",tag->ti_Data));
424 layer_info_hook = (struct Hook *)tag->ti_Data;
425 break;
427 case SA_Quiet:
428 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Quiet 0x%lx\n",tag->ti_Data));
429 if (tag->ti_Data)
431 ns.Type |= SCREENQUIET;
433 else
435 ns.Type &= ~SCREENQUIET;
437 break;
439 case SA_ShowTitle:
440 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ShowTitle 0x%lx\n",tag->ti_Data));
441 if (tag->ti_Data)
443 ns.Type |= SHOWTITLE;
445 else
447 ns.Type &= ~SHOWTITLE;
449 break;
451 case SA_Pens:
452 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Pens 0x%lx\n",tag->ti_Data));
453 customdripens = (UWORD *)tag->ti_Data;
454 break;
456 case SA_DisplayID:
457 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DisplayID 0x%lx\n",tag->ti_Data));
458 //if (modeid == INVALID_ID)
459 modeid = tag->ti_Data;
460 break;
462 case SA_SharePens:
463 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SharePens 0x%lx\n",tag->ti_Data));
464 sharepens = tag->ti_Data ? TRUE : FALSE;
465 if (tag->ti_Data)
467 ns.Type |= PENSHARED;
469 else
471 ns.Type &= ~PENSHARED;
473 break;
475 case SA_Interleaved:
476 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Interleaved 0x%lx\n",tag->ti_Data));
477 if (tag->ti_Data)
479 allocbitmapflags |= BMF_INTERLEAVED;
481 else
483 allocbitmapflags &= ~BMF_INTERLEAVED;
485 break;
487 case SA_Behind:
488 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Behind 0x%lx\n",tag->ti_Data));
489 if (tag->ti_Data)
491 ns.Type |= SCREENBEHIND;
493 else
495 ns.Type &= ~SCREENBEHIND;
497 break;
499 case SA_DClip:
500 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DClip 0x%lx\n",tag->ti_Data));
501 dclip = (struct Rectangle *)tag->ti_Data;
502 break;
504 case SA_Overscan:
505 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_OverScan 0x%lx\n",tag->ti_Data));
506 overscan = tag->ti_Data;
507 break;
509 case SA_LikeWorkbench:
510 case SA_ErrorCode:
512 * handled elsewhere
514 break;
516 case SA_AutoScroll:
517 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AutoScroll 0x%lx\n",tag->ti_Data));
518 ns.Type |= AUTOSCROLL;
519 break;
521 case SA_FullPalette:
522 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FullPalette 0x%lx\n",tag->ti_Data));
523 break;
525 case SA_ColorMapEntries:
526 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ColorMapEntries 0x%lx\n",tag->ti_Data));
527 numcolors = tag->ti_Data;
528 break;
530 case SA_Parent:
531 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Parent 0x%lx\n",tag->ti_Data));
532 break;
534 case SA_Draggable:
535 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Draggable 0x%lx\n",tag->ti_Data));
536 draggable = tag->ti_Data;
537 break;
539 case SA_Exclusive:
540 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Exclusive 0x%lx\n",tag->ti_Data));
541 break;
543 case SA_VideoControl:
544 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_VideoControl 0x%p\n",tag->ti_Data));
545 vctl = tag->ti_Data;
546 break;
548 case SA_FrontChild:
549 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FrontChild 0x%lx\n",tag->ti_Data));
550 break;
552 case SA_BackChild:
553 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackChild 0x%lx\n",tag->ti_Data));
554 break;
556 case SA_MinimizeISG:
557 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_MinimizeISG 0x%lx\n",tag->ti_Data));
558 break;
560 /* TODO: Missing SA_ Tags */
561 default:
562 DEBUG_OPENSCREEN(dprintf("OpenScreen: unknown tag 0x%lx data 0x%lx\n",
563 tag->ti_Tag,
564 tag->ti_Data));
565 break;
567 } /* switch (tag->ti_Tag) */
569 } /* while ((tag = NextTagItem (&tagList))) */
571 } /* if (tagList) */
573 DEBUG_OPENSCREEN(dprintf("OpenScreen: Requested: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
574 ns.LeftEdge, ns.TopEdge, ns.Width, ns.Height, ns.Depth, tagList));
576 /* First Init the RastPort then get the BitPlanes!! */
578 modetags[0].ti_Data = ns.Depth;
579 if (ns.Width != STDSCREENWIDTH)
581 modetags[1].ti_Data = ns.Width;
583 else
585 modetags[1].ti_Tag = TAG_IGNORE;
588 if (ns.Height != STDSCREENHEIGHT)
590 modetags[2].ti_Data = ns.Height;
592 else
594 modetags[2].ti_Tag = TAG_IGNORE;
597 /* if default HIRES_KEY or HIRESLACE_KEY is passed, make sure we find a replacement mode. */
598 if (INVALID_ID != modeid)
600 if (FindDisplayInfo(modeid) == NULL)
602 switch(modeid)
604 case HIRES_KEY:
605 case HIRESLACE_KEY:
607 modetags[1].ti_Data = ns.Width;
608 modetags[2].ti_Data = ns.Height;
610 DEBUG_OPENSCREEN(dprintf("resetting native mode id !!\n");)
611 DEBUG_OPENSCREEN(dprintf("ns.Width %ld ns.Height %ld ns.Depth %ld !!\n",
612 (LONG) ns.Width, (LONG) ns.Height, (LONG) ns.Depth);)
614 modeid = INVALID_ID;
616 break;
618 default:
619 break;
624 if (INVALID_ID == modeid)
626 modeid = BestModeIDA(modetags);
627 if (INVALID_ID == modeid)
629 DEBUG_OPENSCREEN(dprintf("!!! OpenScreen: Could not find valid modeid !!!\n");)
630 FireScreenNotifyMessage((IPTR) NULL, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
632 return NULL;
636 DEBUG_OPENSCREEN(dprintf("OpenScreen: Corrected ModeID: 0x%08lx\n", modeid));
638 InitRastPort(&screen->Screen.RastPort);
639 rp_inited = TRUE;
640 success = FALSE;
642 if ((displayinfo = FindDisplayInfo(modeid)) != NULL &&
643 GetDisplayInfoData(displayinfo, (APTR)&dimensions, sizeof(dimensions), DTAG_DIMS, modeid)
644 #ifdef __MORPHOS__
645 && GetDisplayInfoData(displayinfo, &monitor, sizeof(monitor), DTAG_MNTR, modeid)
646 #endif
649 #ifdef __MORPHOS__
650 screen->Monitor = monitor.Mspc;
651 #else
652 screen->MonitorObject = (Object *)dimensions.reserved[0];
653 screen->SpecialFlags = DoMethod(screen->MonitorObject, MM_GetCompositionFlags, modeid) << 8;
654 #endif
655 success = TRUE;
657 if (dclip == NULL)
659 switch (overscan)
661 case OSCAN_STANDARD:
662 dclip = &dimensions.StdOScan;
663 break;
665 case OSCAN_MAX:
666 dclip = &dimensions.MaxOScan;
667 break;
669 case OSCAN_VIDEO:
670 dclip = &dimensions.VideoOScan;
671 break;
673 default:
674 dclip = &dimensions.TxtOScan;
675 break;
679 if (ns.Width == STDSCREENWIDTH)
680 ns.Width = dclip->MaxX - dclip->MinX + 1;
681 else if (ns.Width < dimensions.MinRasterWidth)
682 ns.Width = dimensions.MinRasterWidth;
683 else if (ns.Width > dimensions.MaxRasterWidth)
684 ns.Width = dimensions.MaxRasterWidth;
686 if (ns.Height == STDSCREENHEIGHT)
687 ns.Height = dclip->MaxY - dclip->MinY + 1;
688 else if (ns.Height < dimensions.MinRasterHeight)
689 ns.Height = dimensions.MinRasterHeight;
690 else if (ns.Height > dimensions.MaxRasterHeight)
691 ns.Height = dimensions.MaxRasterHeight;
693 DEBUG_OPENSCREEN(dprintf("OpenScreen: Corrected: Width %ld Height %ld\n", ns.Width, ns.Height));
695 screen->Screen.RastPort.BitMap = NULL;
696 if (ns.Type & CUSTOMBITMAP)
698 struct BitMap *custombm;
700 custombm = ns.CustomBitMap;
701 #ifdef __MORPHOS__
702 if (IsCyberModeID(modeid) && custombm)
704 int pixfmt = GetCyberIDAttr(CYBRIDATTR_PIXFMT,modeid);
706 if(GetCyberMapAttr(custombm,CYBRMATTR_PIXFMT) != pixfmt)
708 // incompatible formats !
709 custombm = NULL;
712 #else
713 if (!(custombm->Flags & BMF_SPECIALFMT) || (modeid != (ULONG)custombm->Planes[7]))
714 custombm = NULL;
715 #endif
717 if(custombm != NULL)
719 screen->Screen.RastPort.BitMap = custombm;
720 ns.Depth = GetBitMapAttr(ns.CustomBitMap,BMA_DEPTH);
721 DEBUG_OPENSCREEN(dprintf("OpenScreen: CustomBitmap Depth %ld\n",
722 ns.Depth));
724 else
726 ns.CustomBitMap = NULL;
727 ns.Type &= ~CUSTOMBITMAP;
731 if(screen->Screen.RastPort.BitMap == NULL)
733 ULONG Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : ns.Depth;
734 #ifdef __MORPHOS__
735 ULONG pixfmt;
737 switch(Depth)
739 case 15:
740 pixfmt = PIXFMT_RGB15;
741 break;
742 case 16:
743 pixfmt = PIXFMT_RGB16;
744 break;
745 case 24:
746 pixfmt = PIXFMT_BGR24;
747 break;
748 case 32:
749 pixfmt = PIXFMT_ARGB32;
750 break;
751 default:
752 pixfmt = PIXFMT_LUT8;
753 break;
756 if (IsCyberModeID(modeid))
758 pixfmt = GetCyberIDAttr(CYBRIDATTR_PIXFMT,modeid);
762 allocbitmapflags |= (BMF_SPECIALFMT|BMF_CLEAR);
764 screen->Screen.RastPort.BitMap = AllocBitMap(ns.Width,
765 ns.Height,
766 Depth,
767 allocbitmapflags | (pixfmt << 24),
768 NULL);
769 #else
770 struct TagItem bmtags[] = {
771 {BMATags_DisplayID, modeid},
772 {TAG_DONE , 0 }
775 screen->Screen.RastPort.BitMap = AllocBitMap(ns.Width,
776 ns.Height,
777 Depth,
778 allocbitmapflags | BMF_CHECKVALUE,
779 (struct BitMap *)bmtags);
780 #endif
781 screen->AllocatedBitmap = screen->Screen.RastPort.BitMap;
783 memcpy(&screen->Screen.BitMap,screen->Screen.RastPort.BitMap,sizeof(struct BitMap));
786 DEBUG_OPENSCREEN(dprintf("OpenScreen: BitMap 0x%lx\n",
787 screen->Screen.RastPort.BitMap));
789 else
791 DEBUG_OPENSCREEN(dprintf("OpenScreen: no displayinfo\n"));
792 SetError(OSERR_UNKNOWNMODE);
795 /* Init screen's viewport */
796 InitVPort(&screen->Screen.ViewPort);
798 /* Allocate a RasInfo struct in which we have a pointer
799 to the struct BitMap, into which the driver can
800 store its stuff. (Eg. pointer to a BitMap HIDD object)
802 screen->Screen.ViewPort.RasInfo = AllocMem(sizeof(struct RasInfo), MEMF_ANY | MEMF_CLEAR);
804 DEBUG_OPENSCREEN(dprintf("OpenScreen: RasInfo 0x%lx\n",
805 screen->Screen.ViewPort.RasInfo));
807 if (!success ||
808 (screen->Screen.RastPort.BitMap == NULL) ||
809 (screen->Screen.ViewPort.RasInfo == NULL))
811 ok = FALSE;
813 else
815 /* Store pointer to bitmap, so we can get hold of it
816 from withing LoadRGBxx() functions
818 D(bug("got allocated stuff\n"));
819 screen->Screen.ViewPort.RasInfo->BitMap = screen->Screen.RastPort.BitMap;
823 if (ok)
825 /* Read depth from the bitmap to avoid AttachPalExtra/ObtainPen getting
826 * confused if cgx decided to allocate a higher depth bitmap than what
827 * was asked.
829 ns.Depth = GetBitMapAttr(screen->Screen.RastPort.BitMap,BMA_DEPTH);
830 DEBUG_OPENSCREEN(bug("OpenScreen: Real bitmap depth is %u\n", ns.Depth));
832 if (!numcolors) {
833 if (ns.Depth < 5)
834 numcolors = 32;
835 else if (ns.Depth > 8)
836 numcolors = 256;
837 else
838 numcolors = 1L << ns.Depth;
841 /* Get a color map structure. Sufficient colors?? */
843 DEBUG_OPENSCREEN(dprintf("OpenScreen: Colormap Entries %ld\n",
844 numcolors));
846 if ((screen->Screen.ViewPort.ColorMap = GetColorMap(numcolors)) != NULL)
848 if (0 == AttachPalExtra(screen->Screen.ViewPort.ColorMap,
849 &screen->Screen.ViewPort))
851 #if 0
852 int i = 0;
853 char *alloclist;
854 UWORD *refcnt;
856 refcnt =(UWORD*) screen->Screen.ViewPort.ColorMap->PalExtra->pe_RefCnt;
857 alloclist = (UBYTE *)(refcnt + screen->Screen.ViewPort.ColorMap->Count);
859 DEBUG_OPENSCREEN(dprintf("OpenScreen: PalExtra alloclist 0x%lx Count %ld\n",alloclist,screen->Screen.ViewPort.ColorMap->Count));
861 while(i < screen->Screen.ViewPort.ColorMap->Count)
863 // initialize alloc list to -1,0,1,2,3,4
865 DEBUG_OPENSCREEN(dprintf("OpenScreen: alloclist[%ld]=%ld\n",
866 i,alloclist[i]));
867 i++;
869 #endif
871 else
873 ok = FALSE;
876 else
878 ok = FALSE;
881 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%lx\n",
882 screen->Screen.ViewPort.ColorMap));
885 #ifdef __MORPHOS__
886 screen->ModeID = modeid;
887 #endif
889 if (ok)
891 struct ViewPortExtra *vpe = (struct ViewPortExtra *)GfxNew(VIEWPORT_EXTRA_TYPE);
893 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPortExtra 0x%lx\n", vpe));
895 ok = FALSE;
897 if (vpe)
899 struct TagItem tags[6];
901 memcpy(&vpe->DisplayClip, dclip,sizeof(struct Rectangle));
903 screen->Screen.ViewPort.DxOffset = ns.LeftEdge;
904 screen->Screen.ViewPort.DyOffset = ns.TopEdge;
905 screen->Screen.ViewPort.DWidth = dclip->MaxX - dclip->MinX + 1;//ns.Width; /* or from dclip ? */
906 screen->Screen.ViewPort.DHeight = dclip->MaxY - dclip->MinY + 1;//ns.Height;
908 tags[0].ti_Tag = VTAG_ATTACH_CM_SET;
909 tags[0].ti_Data = (IPTR)&screen->Screen.ViewPort;
910 tags[1].ti_Tag = VTAG_VIEWPORTEXTRA_SET;
911 tags[1].ti_Data = (IPTR)vpe;
912 tags[2].ti_Tag = VTAG_NORMAL_DISP_SET;
913 tags[2].ti_Data = (IPTR)displayinfo;
914 tags[3].ti_Tag = VTAG_VPMODEID_SET;
915 tags[3].ti_Data = modeid;
916 tags[4].ti_Tag = VTAG_SPEVEN_BASE_SET;
917 tags[5].ti_Tag = VTAG_NEXTBUF_CM; /* if vctl is 0, this will terminate the list */
918 tags[5].ti_Data = vctl;
920 /* Originally we could always use palette entries 16-19 for
921 sprites, even if the screen has less than 32 colors. AROS may
922 run on hardware that does not allow this (e.g. VGA cards).
923 In this case we have to shift down sprite colors. Currently
924 we use 4 colors before last 4 colors. For example on VGA cards
925 with only 16 colors we use colors 9 - 12. Remember that last 4 colors
926 of the screen are always used by Intuition.
927 Remember that the first color of the sprite is always transparent. So actually
928 we use 3, not 4 colors.
929 Yes, sprites may look not as expected on screens with low color depth, but at
930 least they will be seen. It's better than nothing.
932 Note that because our base color number doesn't always divide by 16, we use MSB to store
933 the remainder (offset in the color bank). Yes, it's a bit hacky, but i have no better idea
934 at the moment.
936 FIXME: this mapping scheme assumes that we always have at least 16 colors.
937 For current display modes supported by AROS it's always true, but in future
938 we may support more display modes (for example monochrome ones), and we
939 should take into account that on screens with less than 11 colors this simply
940 won't work
942 TODO: I think we should have SpriteBase attribute for the bitmap which
943 defaults to acceptable value. We should just get its default value here.
944 The same attribute would be set by VideoControl() and MakeVPort() in order
945 to actually apply the value. */
946 spritebase = (ns.Depth < 5) ? (1 << ns.Depth) - 8 : 16;
947 DEBUG_OPENSCREEN(bug("OpenScreen: spritebase is %u\n", spritebase));
948 tags[4].ti_Data = ((spritebase & 0x0F) << 8 ) | (spritebase >> 4);
950 if (VideoControl(screen->Screen.ViewPort.ColorMap, tags) == 0)
952 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl ok\n"));
953 ok = TRUE;
955 else
957 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl failed\n"));
962 if (ok)
964 struct Color32 *p;
965 int k;
967 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set first 4 colors\n"));
968 p = GetPrivIBase(IntuitionBase)->Colors;
969 for (k = 0; k < 4; ++k)
971 DEBUG_OPENSCREEN(dprintf("OpenScreen: Viewport 0x%p Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
972 &screen->Screen.ViewPort,
973 k, p[k].red, p[k].green, p[k].blue));
974 SetRGB32(&screen->Screen.ViewPort, k, p[k].red, p[k].green, p[k].blue);
977 if (ns.Depth >= 3)
979 ULONG lastcol = ((ns.Depth > 8) ? 256 : (1 << ns.Depth)) - 4;
981 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set last 4 colors (starting from %u)\n", lastcol));
982 for (k = 0; k < 4; ++k)
984 DEBUG_OPENSCREEN(dprintf("OpenScreen: Viewport 0x%p Index %u R 0x%08X G 0x%08X B 0x%08X\n",
985 &screen->Screen.ViewPort,
986 k + lastcol, p[k+4].red, p[k+4].green, p[k+4].blue));
988 if (k + lastcol < numcolors)
989 ObtainPen(screen->Screen.ViewPort.ColorMap, k + lastcol,
990 p[k+4].red, p[k+4].green, p[k+4].blue, 0);
991 else
992 /* Can't be allocated, but can still be set. */
993 SetRGB32(&screen->Screen.ViewPort, k + lastcol,
994 p[k+4].red, p[k+4].green, p[k+4].blue);
997 /* Allocate pens for mouse pointer sprite only on LUT screens. On hi- and
998 truecolor screens sprite colors come from colormap attached to the sprite
999 bitmap itself.
1000 See pointerclass::New() for details. */
1001 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
1002 if (ns.Depth < 9)
1003 #endif
1005 DEBUG_OPENSCREEN(dprintf("OpenScreen: Obtain Mousepointer colors\n"));
1006 /* Allocate pens for the mouse pointer */
1007 for (k = 1; k < 4; ++k)
1009 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPort 0x%p Index %d R 0x%08X G 0x%08X B 0x%08X\n",
1010 &screen->Screen.ViewPort,
1011 k + spritebase,
1012 p[k+7].red,
1013 p[k+7].green,
1014 p[k+7].blue));
1015 if (k + spritebase < numcolors)
1016 ObtainPen(screen->Screen.ViewPort.ColorMap, k + spritebase,
1017 p[k+7].red, p[k+7].green, p[k+7].blue, 0);
1018 else
1019 SetRGB32(&screen->Screen.ViewPort, k + spritebase,
1020 p[k+4].red, p[k+4].green, p[k+4].blue);
1024 if (colors) /* if SA_Colors tag exists */
1026 DEBUG_OPENSCREEN(dprintf("OpenScreen: set SA_Colors 0x%lx\n",colors));
1027 for(; colors->ColorIndex != (WORD)~0; colors++)
1029 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB4 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1030 screen->Screen.ViewPort,
1031 colors,
1032 colors->Red,
1033 colors->Green,
1034 colors->Blue));
1035 SetRGB4(&screen->Screen.ViewPort,
1036 colors->ColorIndex,
1037 colors->Red,
1038 colors->Green,
1039 colors->Blue);
1043 if (colors32) /* if SA_Colors32 tag exists */
1045 DEBUG_OPENSCREEN(dprintf("OpenScreen: LoadRGB32 colors32 0x%lx\n",colors32));
1046 LoadRGB32(&screen->Screen.ViewPort, (const ULONG *)colors32);
1049 D(bug("Loaded colors\n"));
1051 MakeVPort(&IntuitionBase->ViewLord, &screen->Screen.ViewPort);
1052 /* Put validated values into screen structure, this is important */
1053 screen->Screen.LeftEdge = screen->Screen.ViewPort.DxOffset;
1054 screen->Screen.TopEdge = screen->Screen.ViewPort.DyOffset;
1055 COPY(Width);
1056 COPY(Height);
1057 COPY(DetailPen);
1058 COPY(BlockPen);
1059 COPY(Font);
1060 COPY(DefaultTitle);
1062 //intui68k filters this
1063 screen->Screen.Flags = (ns.Type & ~NS_EXTENDED);
1065 /* Temporary hack */
1066 if (ns.Width >= 500 || ns.Height >= 300)
1067 screen->Screen.Flags |= SCREENHIRES;
1070 Copy the data from the rastport's bitmap
1071 to the screen's bitmap structure
1073 screen->Screen.BitMap = *screen->Screen.RastPort.BitMap;
1075 #ifdef __MORPHOS__
1076 screen->Screen.WBorTop = 2;
1077 screen->Screen.WBorLeft = 4;
1078 screen->Screen.WBorRight = 4;
1079 screen->Screen.WBorBottom = 2;
1080 #else
1081 screen->Screen.WBorTop = 3; /* Amiga default is 2 */
1082 screen->Screen.WBorLeft = 4;
1083 screen->Screen.WBorRight = 4;
1084 screen->Screen.WBorBottom = 2; /* Amiga default is 2 */
1085 #endif
1087 screen->Screen.Title = ns.DefaultTitle;
1089 if (screen->ID == NULL) if (screen->Screen.Title) screen->ID = StrDup(screen->Screen.Title);
1091 DEBUG_OPENSCREEN(dprintf("OpenScreen: init layers\n"));
1092 InitLayers(&screen->Screen.LayerInfo);
1093 li_inited = TRUE;
1095 #if 0
1096 /* Root layer now installed automatically by first call
1097 to CreateLayerTagList */
1099 #ifdef CreateLayerTagList
1101 struct TagItem tags[4] =
1103 {LA_Visible , FALSE },
1104 {LA_Priority, ROOTPRIORITY },
1105 {TAG_DONE }
1108 screen->rootLayer =
1109 CreateLayerTagList(&screen->Screen.LayerInfo,
1110 screen->Screen.RastPort.BitMap,
1111 screen->Screen.LeftEdge,
1112 screen->Screen.TopEdge,
1113 screen->Screen.LeftEdge + screen->Screen.Width - 1,
1114 screen->Screen.TopEdge + screen->Screen.Height - 1,
1116 tags);
1118 DEBUG_OPENSCREEN(dprintf("OpenScreen: rootLayer 0x%lx\n",screen->rootLayer));
1120 #endif
1121 #endif
1123 if (NULL != layer_info_hook)
1125 DEBUG_OPENSCREEN(dprintf("OpenScreen: instal layerinfohook\n"));
1126 InstallLayerInfoHook(&screen->Screen.LayerInfo, layer_info_hook);
1128 D(bug("layers intited screen\n"));
1130 screen->DInfo.dri.dri_Version = DRI_VERSION;
1131 screen->DInfo.dri.dri_NumPens = NUMDRIPENS;
1132 screen->DInfo.dri.dri_Pens = screen->Pens;
1133 /* dri_Depth is 8 on hi/true color screens like in AmigaOS with picasso96/cybergraphx */
1134 screen->DInfo.dri.dri_Depth = (ns.Depth <= 8) ? ns.Depth : 8;
1135 /* FIXME: Resolution should be monitor dependent */
1136 screen->DInfo.dri.dri_Resolution.X = 44;
1137 screen->DInfo.dri.dri_Resolution.Y = 44;
1139 if (ns.Depth > 8) screen->DInfo.dri.dri_Flags = DRIF_DIRECTCOLOR;
1141 screen->DInfo.dri_Screen = &screen->Screen;
1143 /* SA_SysFont overrides SA_Font! */
1145 DEBUG_OPENSCREEN(dprintf("OpenScreen: SysFont = %d, ns.Font = %p\n", sysfont, ns.Font));
1147 if (sysfont == 0)
1149 /* Is handled below */
1150 DEBUG_OPENSCREEN(dprintf("OpenScreen: skip SysFont for now\n"));
1152 else if (sysfont == 1)
1154 #if 1
1155 /* Use safe OpenFont here - Piru
1157 screen->DInfo.dri.dri_Font = SafeReopenFont(IntuitionBase, &GetPrivIBase(IntuitionBase)->ScreenFont);
1158 #else
1159 #warning: Really hacky way of re-opening ScreenFont
1161 Forbid();
1162 screen->DInfo.dri.dri_Font = GetPrivIBase(IntuitionBase)->ScreenFont;
1163 screen->DInfo.dri.dri_Font->tf_Accessors++;
1164 Permit();
1165 #endif
1167 screen->SpecialFlags |= SF_SysFont;
1169 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set ScreenFont\n"));
1172 else if (ns.Font)
1174 screen->DInfo.dri.dri_Font = OpenFont(ns.Font);
1175 DEBUG_OPENSCREEN(dprintf("OpenScreen: custom font 0x%lx\n",screen->DInfo.dri.dri_Font));
1178 if (!screen->DInfo.dri.dri_Font)
1180 /* GfxBase->DefaultFont is *not* always topaz 8. It
1181 can be set with the Font prefs program!! */
1183 #if 1
1184 /* Use safe OpenFont.. - Piru
1186 screen->DInfo.dri.dri_Font = SafeReopenFont(IntuitionBase, &GfxBase->DefaultFont);
1187 #else
1189 #warning: Really hacky way of re-opening system default font
1191 Forbid();
1192 screen->DInfo.dri.dri_Font = GfxBase->DefaultFont;
1193 screen->DInfo.dri.dri_Font->tf_Accessors++;
1194 Permit();
1195 #endif
1198 if (!screen->DInfo.dri.dri_Font) ok = FALSE;
1200 } /* if (ok) */
1202 if (ok)
1204 /* set default values for pens */
1205 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Default Pens\n"));
1207 CopyMem(ns.Depth == 1 ? GetPrivIBase(IntuitionBase)->DriPens2
1208 : ns.Depth == 4 ? GetPrivIBase(IntuitionBase)->DriPens4
1209 : GetPrivIBase(IntuitionBase)->DriPens8,
1210 screen->Pens,
1211 sizeof(screen->Pens));
1213 if (ns.Depth > 1)
1215 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set NewLook\n"));
1216 screen->DInfo.dri.dri_Flags |= DRIF_NEWLOOK;
1220 if (customdripens)
1222 WORD i;
1224 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Custom Pens\n"));
1226 screen->Pens[DETAILPEN] = screen->Screen.DetailPen;
1227 screen->Pens[BLOCKPEN] = screen->Screen.BlockPen;
1229 for(i = 0; (i < NUMDRIPENS) && (customdripens[i] != (UWORD)~0); i++)
1231 DEBUG_OPENSCREEN(dprintf("OpenScreen: Pen[%ld] %ld\n",i,screen->Pens[i]));
1232 screen->Pens[i] = customdripens[i];
1235 else
1238 * Let`s do some broken software validation of the pens
1239 * so we may not run into a black desktop.
1242 DEBUG_OPENSCREEN(dprintf("OpenScreen: Check Default Pens if the make sense\n"));
1243 if (screen->Screen.DetailPen == screen->Screen.BlockPen)
1245 DEBUG_OPENSCREEN(dprintf("OpenScreen: DetailPen==BlockPen..correct\n"));
1246 screen->Screen.DetailPen = 0;
1247 screen->Screen.BlockPen = 1;
1249 else
1250 if (screen->Screen.BlockPen == 0)
1252 DEBUG_OPENSCREEN(dprintf("OpenScreen: BlockPen==0..correct\n"));
1253 screen->Screen.BlockPen = screen->Screen.DetailPen;
1254 screen->Screen.DetailPen = 0;
1257 screen->Pens[DETAILPEN] = screen->Screen.DetailPen;
1258 screen->Pens[BLOCKPEN] = screen->Screen.BlockPen;
1261 /* Allocate shared/exclusive colors */
1264 BYTE color_alloced[256];
1266 WORD i;
1268 for(i = 0; i < 256; i++)
1270 color_alloced[i] = FALSE;
1273 /* Mouse pointer colors */
1275 color_alloced[17] = TRUE;
1276 color_alloced[18] = TRUE;
1277 color_alloced[19] = TRUE;
1279 /* The Pens in the DrawInfo must be allocated as shared */
1281 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen DrawInfo Pens as shared\n"));
1283 for(i = 0; i < NUMDRIPENS; i++)
1285 int pen = screen->Pens[i];
1287 if (!color_alloced[pen])
1289 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1290 screen->Screen.ViewPort.ColorMap,
1291 pen));
1293 ObtainPen(screen->Screen.ViewPort.ColorMap,
1294 pen,
1298 PENF_NO_SETCOLOR);
1299 color_alloced[pen] = TRUE;
1302 DEBUG_OPENSCREEN(dprintf("OpenScreen: done\n"));
1304 /* If SA_SharePens is FALSE then allocate the rest of the colors
1305 in the colormap as exclusive */
1307 if (!sharepens)
1309 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen the remaining Pens as exclusive\n"));
1311 for(i = 0; i < numcolors; i++)
1313 if (!color_alloced[i])
1315 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1316 screen->Screen.ViewPort.ColorMap,
1317 i));
1318 ObtainPen(screen->Screen.ViewPort.ColorMap,
1323 PENF_EXCLUSIVE | PENF_NO_SETCOLOR);
1327 } /* if (!sharepens) */
1332 #ifdef SKINS
1333 if (ok)
1335 ULONG realdepth;
1337 screen->DInfo.dri_Screen = &screen->Screen; //useful sometimes ;)
1339 realdepth = GetBitMapAttr( screen->Screen.RastPort.BitMap, BMA_DEPTH );
1340 if (realdepth > 8)
1342 screen->DInfo.dri_Flags |= DRIF_DIRECTCOLOR;
1344 else
1346 screen->DInfo.dri_Flags &= ~DRIF_DIRECTCOLOR;
1349 if (!(screen->DInfo.dri_Colors = AllocMem(4 * DRIPEN_NUMDRIPENS,MEMF_PUBLIC)))
1350 ok = FALSE;
1352 if (ok)
1354 CopyMem(&defaultdricolors,screen->DInfo.dri_Colors,sizeof (defaultdricolors));
1355 memset(((UBYTE *) screen->DInfo.dri_Colors) + sizeof(defaultdricolors), 0, 4 * DRIPEN_NUMDRIPENS - sizeof(defaultdricolors));
1358 if (ok)
1360 if ((screen->DInfo.dri_Customize = AllocMem(sizeof (struct IntuitionCustomize),MEMF_PUBLIC|MEMF_CLEAR)))
1362 struct IntuitionCustomize *ic;
1363 ic = screen->DInfo.dri_Customize;
1364 screen->DInfo.dri_Flags |= DRIF_SKINSSUPPORT;
1365 /* This initializes CustomizePrefs structure */
1367 int_SkinAction(SKA_LoadSkin,(ULONG*)&screen->DInfo,(struct Screen *)screen,IntuitionBase);
1369 else
1371 ok = FALSE;
1376 if (ok)
1378 struct windowclassprefs *wcprefs;
1380 wcprefs = (struct windowclassprefs *)int_GetCustomPrefs(TYPE_WINDOWCLASS,&screen->DInfo,IntuitionBase);
1381 if (wcprefs->flags & WINDOWCLASS_PREFS_1TO1FRAMES)
1383 screen->Screen.WBorLeft = screen->Screen.WBorTop;
1384 screen->Screen.WBorRight = screen->Screen.WBorTop;
1385 screen->Screen.WBorBottom = screen->Screen.WBorTop;
1387 #ifdef TITLEHACK
1388 screen->Screen.WBorTop += wcprefs->titlebarincrement;
1389 #endif
1390 int_FreeCustomPrefs(TYPE_WINDOWCLASS,&screen->DInfo,IntuitionBase);
1393 #endif
1395 if (ok)
1397 IPTR userbuffersize;
1399 struct NewDecorator *nd;
1401 nd = ((struct IntIntuitionBase *)(IntuitionBase))->Decorator;
1403 ObtainSemaphore(&((struct IntIntuitionBase *)(IntuitionBase))->ScrDecorSem);
1405 struct DosLibrary *DOSBase;
1407 DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 40);
1408 if (DOSBase)
1410 struct Node *node;
1411 if (!IsListEmpty(&GetPrivIBase(IntuitionBase)->Decorations))
1413 node = GetPrivIBase(IntuitionBase)->Decorations.lh_Head;
1414 for (; node->ln_Succ; node = node->ln_Succ)
1416 struct NewDecorator *d = (struct NewDecorator *) node;
1417 if ((d->nd_IntPattern != NULL) && (screen->ID != NULL)) if (MatchPattern(d->nd_IntPattern, screen->ID)) nd = d;
1421 CloseLibrary((struct Library *) DOSBase);
1424 // if (MatchPattern(tl->parsename, task->tc_Node.ln_Name)) b = tl;
1426 if (nd != NULL)
1428 screen->ScrDecorObj = nd->nd_Screen;
1429 screen->WinDecorObj = nd->nd_Window;
1430 screen->MenuDecorObj = nd->nd_Menu;
1432 else
1434 screen->ScrDecorObj = ((struct IntIntuitionBase *)(IntuitionBase))->ScrDecorObj;
1435 screen->WinDecorObj = ((struct IntIntuitionBase *)(IntuitionBase))->WinDecorObj;
1436 screen->MenuDecorObj = ((struct IntIntuitionBase *)(IntuitionBase))->MenuDecorObj;
1438 screen->Decorator = nd;
1440 if (screen->Decorator) screen->Decorator->nd_cnt++;
1442 ReleaseSemaphore(&((struct IntIntuitionBase *)(IntuitionBase))->ScrDecorSem);
1444 GetAttr(SDA_UserBuffer, screen->ScrDecorObj, &userbuffersize);
1446 if (userbuffersize)
1448 screen->DecorUserBufferSize = userbuffersize;
1449 screen->DecorUserBuffer = (IPTR) AllocMem(userbuffersize, MEMF_ANY | MEMF_CLEAR);
1450 if (!screen->DecorUserBuffer) ok = FALSE;
1454 if (ok)
1456 struct TagItem sysi_tags[] =
1458 {SYSIA_Which , MENUCHECK },
1459 {SYSIA_DrawInfo , (IPTR)&screen->DInfo },
1460 {SYSIA_UserBuffer, screen->DecorUserBuffer },
1462 {TAG_DONE }
1465 screen->DInfo.dri.dri_CheckMark = NewObjectA(NULL, "sysiclass", sysi_tags);
1466 DEBUG_OPENSCREEN(dprintf("OpenScreen: CheckMark 0x%lx\n",
1467 screen->DInfo.dri.dri_CheckMark));
1469 sysi_tags[0].ti_Data = AMIGAKEY;
1471 screen->DInfo.dri.dri_AmigaKey = NewObjectA(NULL, "sysiclass", sysi_tags);
1472 DEBUG_OPENSCREEN(dprintf("OpenScreen: AmigaKey 0x%lx\n",
1473 screen->DInfo.dri.dri_AmigaKey));
1475 sysi_tags[0].ti_Data = SUBMENUIMAGE;
1477 screen->DInfo.dri.dri_SubMenuImage = NewObjectA(NULL, "sysiclass", sysi_tags);
1478 DEBUG_OPENSCREEN(dprintf("OpenScreen: SubMenuImage 0x%lx\n",
1479 screen->DInfo.dri.dri_SubMenuImage));
1481 #ifdef SKINS
1482 sysi_tags[0].ti_Data = SUBMENUIMAGE;
1483 screen->DInfo.dri_Customize->submenu = NewObjectA(NULL, "sysiclass", sysi_tags);
1484 sysi_tags[0].ti_Data = MENUTOGGLEIMAGE;
1485 screen->DInfo.dri_Customize->menutoggle = NewObjectA(NULL, "sysiclass", sysi_tags);
1486 if (!screen->DInfo.dri_Customize->submenu ||
1487 !screen->DInfo.dri_Customize->menutoggle) ok = FALSE;
1488 #endif
1490 if (!screen->DInfo.dri.dri_CheckMark || !screen->DInfo.dri.dri_AmigaKey || !screen->DInfo.dri.dri_SubMenuImage) ok = FALSE;
1495 if (ok)
1497 SetFont(&screen->Screen.RastPort, screen->DInfo.dri.dri_Font);
1499 AskFont(&screen->Screen.RastPort, (struct TextAttr *) &screen->textattr);
1501 screen->Screen.Font = (struct TextAttr *) &screen->textattr;
1503 DEBUG_OPENSCREEN(dprintf("OpenScreen: Font %s/%d\n",
1504 screen->textattr.tta_Name, screen->textattr.tta_YSize));
1506 screen->Screen.BarVBorder = 1; /* on the Amiga it is (usually?) 1 */
1507 screen->Screen.BarHBorder = 5;
1508 screen->Screen.MenuVBorder = 2; /* on the Amiga it is (usually?) 2 */
1509 screen->Screen.MenuHBorder = 4;
1511 struct sdpInitScreen msg;
1513 msg.MethodID = SDM_INITSCREEN;
1514 msg.sdp_Screen = &screen->Screen;
1515 msg.sdp_TrueColor = screen->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR;
1516 msg.sdp_FontHeight = screen->DInfo.dri.dri_Font->tf_YSize;
1517 msg.sdp_BarVBorder = screen->Screen.BarVBorder;
1518 msg.sdp_BarHBorder = screen->Screen.BarHBorder;
1519 msg.sdp_MenuVBorder = screen->Screen.MenuVBorder;
1520 msg.spd_MenuHBorder = screen->Screen.MenuHBorder;
1521 msg.sdp_WBorTop = screen->Screen.WBorTop;
1522 msg.sdp_WBorLeft = screen->Screen.WBorLeft;
1523 msg.sdp_WBorRight = screen->Screen.WBorRight;
1524 msg.sdp_WBorBottom = screen->Screen.WBorBottom;
1526 #ifdef TITLEHACK
1527 msg.sdp_TitleHack = screen->Screen.WBorTop-2;
1528 #else
1529 msg.sdp_TitleHack = 0;
1530 #endif
1532 msg.sdp_BarHeight = msg.sdp_FontHeight + msg.sdp_BarVBorder * 2 + msg.sdp_TitleHack;
1533 msg.sdp_UserBuffer = ((struct IntScreen *)screen)->DecorUserBuffer;
1535 if (!DoMethodA(((struct IntScreen *)(screen))->ScrDecorObj, (Msg)&msg)) ok = FALSE;
1536 if (ok)
1538 screen->Screen.BarHeight = msg.sdp_BarHeight;
1539 screen->Screen.BarVBorder = msg.sdp_BarVBorder;
1540 screen->Screen.BarHBorder = msg.sdp_BarHBorder;
1541 screen->Screen.MenuVBorder = msg.sdp_MenuVBorder;
1542 screen->Screen.MenuHBorder = msg.spd_MenuHBorder;
1543 screen->Screen.WBorTop = msg.sdp_WBorTop;
1544 screen->Screen.WBorLeft = msg.sdp_WBorLeft;
1545 screen->Screen.WBorRight = msg.sdp_WBorRight;
1546 screen->Screen.WBorBottom = msg.sdp_WBorBottom;
1551 if (ok)
1553 #define SDEPTH_HEIGHT (screen->Screen.BarHeight + 1)
1554 #ifdef IA_Screen
1555 #undef IA_Screen
1556 #endif
1557 #define IA_Screen (IA_Dummy + 0x1f) /* OS v44 includes!*/
1559 struct TagItem sdepth_tags[] =
1561 {GA_Image , 0 },
1562 {GA_Top , 0 },
1563 #if SQUARE_WIN_GADGETS
1564 {GA_Width , SDEPTH_HEIGHT },
1565 #endif
1566 {GA_Height , SDEPTH_HEIGHT },
1567 {GA_SysGadget , TRUE },
1568 {GA_SysGType , GTYP_SDEPTH },
1569 {GA_RelVerify , TRUE },
1570 {TAG_DONE }
1573 Object *im = 0;
1575 if (!(screen->Screen.Flags & SCREENQUIET))
1577 im = CreateStdSysImage(SDEPTHIMAGE, SDEPTH_HEIGHT, &screen->Screen, (APTR) ((struct IntScreen *)screen)->DecorUserBuffer,
1578 (struct DrawInfo *)&screen->DInfo, IntuitionBase);
1581 sdepth_tags[0].ti_Data = (IPTR)im;
1583 screen->depthgadget = NewObjectA(NULL, BUTTONGCLASS, sdepth_tags );
1585 DEBUG_OPENSCREEN(dprintf("OpenScreen: DepthGadget 0x%lx\n",
1586 screen->depthgadget));
1588 screen->Screen.FirstGadget = (struct Gadget *)screen->depthgadget;
1589 if (screen->Screen.FirstGadget)
1591 struct sdpLayoutScreenGadgets msg;
1593 screen->Screen.FirstGadget->GadgetType |= GTYP_SCRGADGET;
1595 msg.MethodID = SDM_LAYOUT_SCREENGADGETS;
1596 msg.sdp_TrueColor = screen->DInfo.dri.dri_Flags & DRIF_DIRECTCOLOR;
1597 msg.sdp_Layer = screen->Screen.BarLayer;
1598 msg.sdp_Gadgets = screen->Screen.FirstGadget;
1599 msg.sdp_Flags = SDF_LSG_INITIAL | SDF_LSG_MULTIPLE;
1600 msg.sdp_UserBuffer = ((struct IntScreen *)screen)->DecorUserBuffer;
1602 DoMethodA(((struct IntScreen *)(screen))->ScrDecorObj, (Msg)&msg);
1604 #if 0
1605 struct TagItem gadtags[] =
1607 {GA_RelRight, 0 },
1608 {TAG_DONE }
1610 IPTR width;
1612 GetAttr(GA_Width, screen->depthgadget, &width);
1614 gadtags[0].ti_Data = -width + 1;
1615 SetAttrsA(screen->depthgadget, gadtags);
1616 #endif
1619 else
1621 if (im) DisposeObject(im);
1625 #if DEBUG_OpenScreen
1627 int i;
1629 for (i = 0; i <= screen->DInfo.dri.dri_NumPens; i++)
1631 dprintf("OpenScreen: dri_Pen[%ld] = %ld\n", i, screen->DInfo.dri.dri_Pens[i]);
1634 #endif
1636 #ifdef USEWINDOWLOCK
1637 /* let's wait for user to finish window drag/size actions to avoid
1638 deadlocks and not break user's input */
1639 ObtainSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
1640 windowlock = TRUE;
1641 #endif
1643 #ifdef SKINS
1644 int_CalcSkinInfo(&screen->Screen,IntuitionBase);
1645 int_InitTitlebarBuffer(screen,IntuitionBase);
1646 #endif
1648 D(bug("Calling SetRast()\n"));
1650 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set background color Pen %ld\n",screen->Pens[BACKGROUNDPEN]));
1651 /* Set screen to background color */
1652 SetRast(&screen->Screen.RastPort, screen->Pens[BACKGROUNDPEN]);
1654 D(bug("SetRast() called\n"));
1656 DEBUG_OPENSCREEN(dprintf("OpenScreen: Creating screen bar\n"));
1658 #ifdef SKINS
1659 if (workbench)
1661 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_NOWBTITLEBAR) screen->SpecialFlags |= SF_InvisibleBar;
1662 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_DISAPPEARINGTITLEBAR) screen->SpecialFlags |= SF_AppearingBar;
1664 #endif
1665 if (draggable)
1666 screen->SpecialFlags |= SF_Draggable;
1667 DEBUG_OPENSCREEN(bug("OpenScreen: Special flags: 0x%04X\n", screen->SpecialFlags));
1669 //jDc: ALL screens MUST have BarLayer!
1670 CreateScreenBar(&screen->Screen, IntuitionBase);
1672 DEBUG_OPENSCREEN(bug("OpenScreen: ScreenBar = %p\n", screen->Screen.BarLayer));
1674 if (!screen->Screen.BarLayer) ok = FALSE;
1677 ** jDc: better modify the screen list in sync with inputhandler, this for example allows us to scan the list
1678 ** without any locks when we are on input.device context
1680 if (ok)
1682 struct OpenScreenActionMsg msg;
1683 struct List *list = LockPubScreenList();
1685 msg.Screen = screen;
1686 msg.NewScreen = &ns;
1687 msg.List = list;
1689 DEBUG_OPENSCREEN(dprintf("OpenScreen: Calling DoSyncAction()\n"));
1691 DoSyncAction((APTR)int_openscreen,&msg.msg,IntuitionBase);
1693 DEBUG_OPENSCREEN(dprintf("OpenScreen: DoSyncAction returned\n"));
1695 UnlockPubScreenList();
1698 } /* if (ok) */
1700 if (ok)
1702 GetAttr(POINTERA_SharedPointer, GetPrivIBase(IntuitionBase)->DefaultPointer, (IPTR *)&screen->Pointer);
1703 ObtainSharedPointer(screen->Pointer, IntuitionBase);
1704 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sprite DefaultPtr 0x%lx\n",&screen->Pointer));
1707 #ifdef __MORPHOS__
1708 if (ok)
1710 ok = MakeScreen(&screen->Screen) == 0;
1711 DEBUG_OPENSCREEN(dprintf("OpenScreen: MakeScreen %s\n", ok ? "ok" : "failed"));
1713 #endif
1714 if (ok)
1716 ok = RethinkDisplay() == 0;
1717 DEBUG_OPENSCREEN(dprintf("OpenScreen: RethinkDisplay %s\n", ok ? "ok" : "failed"));
1720 #ifdef SKINS
1721 if (ok)
1723 FireMenuMessage(MMCODE_STARTCLOCK,NULL,NULL,IntuitionBase);
1725 #endif
1727 #ifdef USEWINDOWLOCK
1728 if (windowlock) ReleaseSemaphore(&GetPrivIBase(IntuitionBase)->WindowLock);
1729 #endif
1731 if (!ok)
1733 if (li_inited)
1735 DEBUG_OPENSCREEN(dprintf("OpenScreen: Get ThinLayerInfo\n"));
1736 ThinLayerInfo(&screen->Screen.LayerInfo);
1739 if (screen->Screen.ViewPort.ColorMap)
1741 FreeColorMap(screen->Screen.ViewPort.ColorMap);
1744 if (screen->Screen.BarLayer)
1746 DEBUG_OPENSCREEN(dprintf("OpenScreen: KillScreenBar\n"));
1747 KillScreenBar(&screen->Screen, IntuitionBase);
1750 #ifdef SKINS
1751 DisposeObject(screen->DInfo.dri_Customize->submenu);
1752 DisposeObject(screen->DInfo.dri_Customize->menutoggle);
1753 if (screen->DInfo.dri_Customize) FreeMem(screen->DInfo.dri_Customize,sizeof (struct IntuitionCustomize));
1754 if (screen->DInfo.dri_Colors) FreeMem(screen->DInfo.dri_Colors,4 * DRIPEN_NUMDRIPENS);
1755 #endif
1756 if (screen->DInfo.dri.dri_AmigaKey)
1758 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose AmigaKey Object\n"));
1759 DisposeObject(screen->DInfo.dri.dri_AmigaKey);
1761 if (screen->DInfo.dri.dri_CheckMark)
1763 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose CheckMark Object\n"));
1764 DisposeObject(screen->DInfo.dri.dri_CheckMark);
1767 if (screen->DInfo.dri.dri_SubMenuImage)
1769 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose SubMenuImage Object\n"));
1770 DisposeObject(screen->DInfo.dri.dri_SubMenuImage);
1773 if (screen->DInfo.dri.dri_Font)
1775 DEBUG_OPENSCREEN(dprintf("OpenScreen: Close Font\n"));
1776 CloseFont(screen->DInfo.dri.dri_Font);
1779 if (screen->AllocatedBitmap && !(ns.Type & CUSTOMBITMAP))
1781 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free BitMap\n"));
1782 FreeBitMap(screen->AllocatedBitmap);
1785 if (screen->Screen.ViewPort.RasInfo)
1787 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free RasInfo\n"));
1788 FreeMem(screen->Screen.ViewPort.RasInfo, sizeof (struct RasInfo));
1791 if (rp_inited)
1793 DEBUG_OPENSCREEN(dprintf("OpenScreen: Trash Rastport\n"));
1794 DeinitRastPort(&screen->Screen.RastPort);
1797 if (screen->DecorUserBuffer)
1799 FreeMem((void *)screen->DecorUserBuffer, screen->DecorUserBufferSize);
1802 if (screen->Decorator) screen->Decorator->nd_cnt--;
1804 if (screen->ID) FreeVec(screen->ID);
1806 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free Screen\n"));
1807 FreeMem (screen, sizeof (struct IntScreen));
1809 screen = 0;
1811 } /* if (!ok) */
1813 DEBUG_OPENSCREEN(dprintf("OpenScreen: return 0x%lx\n", screen));
1815 FireScreenNotifyMessage((IPTR) screen, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
1817 ReturnPtr ("OpenScreen", struct Screen *, (struct Screen *)screen);
1819 AROS_LIBFUNC_EXIT
1821 } /* OpenScreen */
1823 static VOID int_openscreen(struct OpenScreenActionMsg *msg,
1824 struct IntuitionBase *IntuitionBase)
1826 ULONG lock;
1827 struct IntScreen *screen = msg->Screen;
1828 struct NewScreen *ns = msg->NewScreen;
1829 struct List *list = msg->List;
1830 struct Screen *oldFirstScreen;
1832 DEBUG_OPENSCREEN(dprintf("OpenScreen: Checking for pubScrNode (0x%lx)\n",screen->pubScrNode));
1834 /* If this is a public screen, we link it into the intuition global
1835 public screen list */
1836 if (screen->pubScrNode != NULL)
1838 /* Set the pointer to ourselves */
1839 GetPrivScreen(screen)->pubScrNode->psn_Screen = &screen->Screen;
1841 DEBUG_OPENSCREEN(dprintf("OpenScreen: Add Screen to PubList\n"));
1842 AddTail(list, (struct Node *)GetPrivScreen(screen)->pubScrNode);
1845 lock = LockIBase(0);
1847 oldFirstScreen = IntuitionBase->FirstScreen;
1849 if (ns->Type & SCREENBEHIND)
1851 struct Screen **ptr = &IntuitionBase->FirstScreen;
1853 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sort Behind\n"));
1854 if (!*ptr)
1855 IntuitionBase->ActiveScreen = &screen->Screen;
1856 while (*ptr)
1857 ptr = &(*ptr)->NextScreen;
1858 *ptr = &screen->Screen;
1860 else
1862 screen->Screen.NextScreen = IntuitionBase->FirstScreen;
1863 IntuitionBase->FirstScreen =
1864 IntuitionBase->ActiveScreen = &screen->Screen;
1865 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set as ActiveScreen\n"));
1868 /* If it's the first screen being opened, activate its monitor */
1869 if (!oldFirstScreen)
1870 ActivateMonitor(screen->MonitorObject, -1, -1, IntuitionBase);
1872 /* set the default pub screen */
1873 if (GetPrivIBase(IntuitionBase)->IControlPrefs.ic_Flags & ICF_DEFPUBSCREEN)
1875 if ((IntuitionBase->FirstScreen == &screen->Screen) && screen->pubScrNode && (screen->Screen.Flags & (PUBLICSCREEN | WBENCHSCREEN)))
1877 GetPrivIBase(IntuitionBase)->DefaultPubScreen = &screen->Screen;
1881 UnlockIBase(lock);
1883 D(bug("set active screen\n"));
1885 AddResourceToList(screen, RESOURCE_SCREEN, IntuitionBase);