2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2003, The MorphOS Development Team. All Rights Reserved.
9 #include <aros/config.h>
10 #include <exec/memory.h>
11 #include <utility/tagitem.h>
12 #include <intuition/screens.h>
13 #include <intuition/intuition.h>
14 #include <intuition/imageclass.h>
15 #include <intuition/windecorclass.h>
16 #include <intuition/scrdecorclass.h>
17 #include <intuition/gadgetclass.h>
18 #include <intuition/extensions.h>
19 #include <graphics/modeid.h>
20 #include <graphics/videocontrol.h>
21 #include <graphics/displayinfo.h>
22 #include <prefs/screenmode.h>
23 #include <proto/exec.h>
24 #include <proto/graphics.h>
25 #include <proto/layers.h>
26 #include <proto/utility.h>
27 #include <proto/intuition.h>
28 #include <proto/dos.h>
30 #include <proto/cybergraphics.h>
31 #include <cybergraphx/cybergraphics.h>
32 #include "intuition_intern.h"
33 #include "intuition_customize.h"
34 #include "intuition_extend.h"
35 #include "inputhandler.h"
36 #include "inputhandler_support.h"
37 #include "inputhandler_actions.h"
39 #include "monitorclass_private.h"
41 #ifndef DEBUG_OpenScreen
42 #define DEBUG_OpenScreen 0
48 #include <aros/debug.h>
50 struct OpenScreenActionMsg
52 struct IntuiActionMsg msg
;
53 struct IntScreen
*Screen
;
54 struct NewScreen
*NewScreen
;
58 static VOID
int_openscreen(struct OpenScreenActionMsg
*msg
,
59 struct IntuitionBase
*IntuitionBase
);
62 extern const ULONG defaultdricolors
[DRIPEN_NUMDRIPENS
];
65 /*****************************************************************************
69 AROS_LH1(struct Screen
*, OpenScreen
,
72 AROS_LHA(struct NewScreen
*, newScreen
, A0
),
75 struct IntuitionBase
*, IntuitionBase
, 33, Intuition
)
92 The function relies on private data being passed in DimensionInfo.reserved[0]
93 by graphics.library/GetDisplayInfoData(). Keep this in sync when modifying
97 29-10-95 digulla automatically created from
98 intuition_lib.fd and clib/intuition_protos.h
100 *****************************************************************************/
104 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
105 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
106 struct Library
*UtilityBase
= GetPrivIBase(IntuitionBase
)->UtilityBase
;
108 struct TagItem
*tag
, *tagList
;
110 struct IntScreen
*screen
;
112 struct Hook
*layer_info_hook
= NULL
;
113 struct ColorSpec
*colors
= NULL
;
114 ULONG
*errorPtr
; /* Store error at user specified location */
115 UWORD
*customdripens
= NULL
;
116 ULONG
*colors32
= NULL
;
118 BOOL ok
= TRUE
, rp_inited
= FALSE
, li_inited
= FALSE
, sharepens
= FALSE
;
120 BOOL windowlock
= FALSE
;
122 struct Rectangle
*dclip
= NULL
;
123 LONG overscan
= OSCAN_TEXT
;
124 DisplayInfoHandle displayinfo
;
125 struct DimensionInfo dimensions
;
127 struct MonitorInfo monitor
;
129 ULONG allocbitmapflags
= BMF_DISPLAYABLE
;
134 BOOL workbench
= FALSE
;
136 BOOL draggable
= TRUE
;
137 struct TagItem modetags
[] =
139 { BIDTAG_Depth
, 0UL },
140 { BIDTAG_DesiredWidth
, 0UL },
141 { BIDTAG_DesiredHeight
, 0UL },
142 { BIDTAG_DIPFMustHave
, 0UL },
145 ULONG modeid
= INVALID_ID
;
146 struct DisplayInfo dispinfo
;
148 /* Intuition not up yet? */
149 if (!GetPrivIBase(IntuitionBase
)->DefaultPointer
)
152 ASSERT_VALID_PTR_ROMOK(newScreen
);
154 #define COPY(x) screen->Screen.x = ns.x
155 #define SetError(x) if (errorPtr != NULL) *errorPtr = x;
157 D(bug("OpenScreen (%p = { Left=%d Top=%d Width=%d Height=%d Depth=%d Mode=%04x })\n"
159 , newScreen
->LeftEdge
164 , newScreen
->ViewModes
167 FireScreenNotifyMessage((IPTR
) newScreen
, SNOTIFY_BEFORE_OPENSCREEN
, IntuitionBase
);
171 if (newScreen
->Type
& NS_EXTENDED
)
173 tagList
= ((struct ExtNewScreen
*)newScreen
)->Extension
;
180 DEBUG_OPENSCREEN(dprintf("OpenScreen: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
181 ns
.LeftEdge
, ns
.TopEdge
, ns
.Width
, ns
.Height
, ns
.Depth
, tagList
));
184 if (!LocaleBase
) LocaleBase
= OpenLibrary("locale.library",0);
185 if (!LocaleBase
) return NULL
;
188 #ifdef USEGETIPREFS //needs INTUITION_THEME_ENCHANCEMENT!
189 if (!GetPrivIBase(IntuitionBase
)->IPrefsLoaded
&& FindPort(SKINMANAGERPORTNAME
))
191 /* let's init prefs before 1st OpenScreen that needs them*/
192 int_SkinAction(SKA_GetIPrefs
,0,0,IntuitionBase
);
196 screen
= AllocMem(sizeof (struct IntScreen
), MEMF_ANY
| MEMF_CLEAR
);
198 DEBUG_OPENSCREEN(dprintf("OpenScreen: screen 0x%lx\n", screen
));
200 /* Do this really early to be able to report errors */
201 errorPtr
= (ULONG
*)GetTagData(SA_ErrorCode
, 0, tagList
);
203 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ErrorCode 0x%lx\n",errorPtr
));
207 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
208 SetError(OSERR_NOMEM
);
214 if (GetTagData(SA_LikeWorkbench
, FALSE
, tagList
))
217 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_LikeWorkbench\n"));
219 ns
.Width
= GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Width
;
220 ns
.Height
= GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Height
;
221 ns
.Depth
= GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Depth
;
222 modeid
= GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_DisplayID
;
224 if (GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Control
& SMF_AUTOSCROLL
)
226 /* need to mark autoscroll */
227 ns
.Type
|= AUTOSCROLL
;
230 sharepens
= TRUE
; /* not sure */
233 while((tag
= NextTagItem(&tagList
)))
235 DEBUG_OPENSCREEN(dprintf("OpenScreen: Tag 0x%08lx Data 0x%08lx\n",
236 tag
->ti_Tag
, tag
->ti_Data
));
240 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Left %ld\n",tag
->ti_Data
));
241 ns
.LeftEdge
= tag
->ti_Data
;
245 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Top %ld\n",tag
->ti_Data
));
246 ns
.TopEdge
= tag
->ti_Data
;
250 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Width %ld\n",tag
->ti_Data
));
251 ns
.Width
= tag
->ti_Data
;
255 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Height %ld\n",tag
->ti_Data
));
256 ns
.Height
= tag
->ti_Data
;
260 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Depth %ld\n",tag
->ti_Data
));
261 ns
.Depth
= tag
->ti_Data
;
265 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DetailPen %ld\n",tag
->ti_Data
));
266 ns
.DetailPen
= tag
->ti_Data
;
270 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BlockPen %ld\n",tag
->ti_Data
));
271 ns
.BlockPen
= tag
->ti_Data
;
275 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Type 0x%lx\n",tag
->ti_Data
));
276 ns
.Type
&= ~SCREENTYPE
;
277 ns
.Type
|= tag
->ti_Data
;
281 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Title <%s>\n",tag
->ti_Data
));
282 ns
.DefaultTitle
= (UBYTE
*)tag
->ti_Data
;
286 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Font 0x%lx\n",tag
->ti_Data
));
287 ns
.Font
= (struct TextAttr
*)tag
->ti_Data
;
291 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors32 0x%lx\n",tag
->ti_Data
));
292 colors32
= (ULONG
*)tag
->ti_Data
;
296 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors 0x%lx\n",tag
->ti_Data
));
297 colors
= (struct ColorSpec
*)tag
->ti_Data
;
301 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SysFont 0x%lx\n",tag
->ti_Data
));
302 sysfont
= (WORD
)tag
->ti_Data
;
306 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap 0x%lx\n",tag
->ti_Data
));
309 ns
.Type
|= CUSTOMBITMAP
;
310 ns
.CustomBitMap
= (struct BitMap
*)tag
->ti_Data
;
314 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap==NULL specified, custom bitmap use disabled\n"));
318 /* Name of this public screen. */
320 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubName <%s>\n",tag
->ti_Data
));
323 screen
->pubScrNode
= AllocMem(sizeof(struct PubScreenNode
), MEMF_CLEAR
);
332 if (strcasecmp((char *)tag
->ti_Data
, "Workbench") == 0)
334 /* FIXME: This would still not be safe, if a normal app tried to open its own screen with SA_PubName=Workbench */
335 if (GetPrivIBase(IntuitionBase
)->WorkBench
)
337 UnlockPubScreenList();
339 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
349 old
= LockPubScreen((STRPTR
)tag
->ti_Data
);
353 UnlockPubScreen(NULL
, old
);
354 SetError(OSERR_PUBNOTUNIQUE
);
355 UnlockPubScreenList();
356 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
362 UnlockPubScreenList();
365 screen
->pubScrNode
= AllocMem(sizeof(struct PubScreenNode
), MEMF_CLEAR
);
367 DEBUG_OPENSCREEN(dprintf("OpenScreen: pubScrNode 0x%lx\n",screen
->pubScrNode
));
369 if (screen
->pubScrNode
== NULL
)
371 SetError(OSERR_NOMEM
);
372 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
377 if ((ns
.Type
& SCREENTYPE
) == CUSTOMSCREEN
)
379 ns
.Type
&= ~SCREENTYPE
;
380 ns
.Type
|= PUBLICSCREEN
;
383 screen
->pubScrNode
->psn_Node
.ln_Name
= AllocVec(MAXPUBSCREENNAME
+ 1,
386 if (screen
->pubScrNode
->psn_Node
.ln_Name
== NULL
)
388 SetError(OSERR_NOMEM
);
389 FreeMem(screen
->pubScrNode
, sizeof(struct PubScreenNode
));
390 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
395 /* Always open public screens in private mode. */
396 screen
->pubScrNode
->psn_Flags
|= PSNF_PRIVATE
;
397 strcpy(screen
->pubScrNode
->psn_Node
.ln_Name
, (STRPTR
)tag
->ti_Data
);
400 /* Signal bit number to use when signalling public screen
403 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubSig 0x%lx\n",tag
->ti_Data
));
404 if (screen
->pubScrNode
== NULL
)
406 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
410 /* If no PubTask is set, we set the calling task as default */
411 if (screen
->pubScrNode
->psn_SigTask
== NULL
)
412 screen
->pubScrNode
->psn_SigTask
= FindTask(NULL
);
414 screen
->pubScrNode
->psn_SigBit
= (UBYTE
)tag
->ti_Data
;
417 /* Task that should be signalled when the public screen loses
418 its last visitor window. */
420 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubTask 0x%lx\n",tag
->ti_Data
));
421 if (screen
->pubScrNode
== NULL
)
423 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
426 screen
->pubScrNode
->psn_SigTask
= (struct Task
*)tag
->ti_Data
;
430 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackFill Hook 0x%lx\n",tag
->ti_Data
));
431 layer_info_hook
= (struct Hook
*)tag
->ti_Data
;
435 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Quiet 0x%lx\n",tag
->ti_Data
));
438 ns
.Type
|= SCREENQUIET
;
442 ns
.Type
&= ~SCREENQUIET
;
447 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ShowTitle 0x%lx\n",tag
->ti_Data
));
450 ns
.Type
|= SHOWTITLE
;
454 ns
.Type
&= ~SHOWTITLE
;
459 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Pens 0x%lx\n",tag
->ti_Data
));
460 customdripens
= (UWORD
*)tag
->ti_Data
;
464 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DisplayID 0x%lx\n",tag
->ti_Data
));
465 //if (modeid == INVALID_ID)
466 modeid
= tag
->ti_Data
;
470 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SharePens 0x%lx\n",tag
->ti_Data
));
471 sharepens
= tag
->ti_Data
? TRUE
: FALSE
;
474 ns
.Type
|= PENSHARED
;
478 ns
.Type
&= ~PENSHARED
;
483 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Interleaved 0x%lx\n",tag
->ti_Data
));
486 allocbitmapflags
|= BMF_INTERLEAVED
;
490 allocbitmapflags
&= ~BMF_INTERLEAVED
;
495 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Behind 0x%lx\n",tag
->ti_Data
));
498 ns
.Type
|= SCREENBEHIND
;
502 ns
.Type
&= ~SCREENBEHIND
;
507 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DClip 0x%lx\n",tag
->ti_Data
));
508 dclip
= (struct Rectangle
*)tag
->ti_Data
;
512 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_OverScan 0x%lx\n",tag
->ti_Data
));
513 overscan
= tag
->ti_Data
;
516 case SA_LikeWorkbench
:
524 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AutoScroll 0x%lx\n",tag
->ti_Data
));
525 ns
.Type
|= AUTOSCROLL
;
529 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FullPalette 0x%lx\n",tag
->ti_Data
));
532 case SA_ColorMapEntries
:
533 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ColorMapEntries 0x%lx\n",tag
->ti_Data
));
534 numcolors
= tag
->ti_Data
;
538 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Parent 0x%lx\n",tag
->ti_Data
));
542 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Draggable 0x%lx\n",tag
->ti_Data
));
543 draggable
= tag
->ti_Data
;
547 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Exclusive 0x%lx\n",tag
->ti_Data
));
550 case SA_VideoControl
:
551 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_VideoControl 0x%p\n",tag
->ti_Data
));
556 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FrontChild 0x%lx\n",tag
->ti_Data
));
560 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackChild 0x%lx\n",tag
->ti_Data
));
564 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_MinimizeISG 0x%lx\n",tag
->ti_Data
));
567 /* TODO: Missing SA_ Tags */
569 DEBUG_OPENSCREEN(dprintf("OpenScreen: unknown tag 0x%lx data 0x%lx\n",
574 } /* switch (tag->ti_Tag) */
576 } /* while ((tag = NextTagItem (&tagList))) */
580 DEBUG_OPENSCREEN(dprintf("OpenScreen: Requested: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
581 ns
.LeftEdge
, ns
.TopEdge
, ns
.Width
, ns
.Height
, ns
.Depth
, tagList
));
583 /* First Init the RastPort then get the BitPlanes!! */
585 modetags
[0].ti_Data
= ns
.Depth
;
586 if (ns
.Width
!= STDSCREENWIDTH
)
588 modetags
[1].ti_Data
= ns
.Width
;
592 modetags
[1].ti_Tag
= TAG_IGNORE
;
595 if (ns
.Height
!= STDSCREENHEIGHT
)
597 modetags
[2].ti_Data
= ns
.Height
;
601 modetags
[2].ti_Tag
= TAG_IGNORE
;
604 /* if default HIRES_KEY or HIRESLACE_KEY is passed, make sure we find a replacement mode. */
605 if (INVALID_ID
!= modeid
)
607 if (FindDisplayInfo(modeid
) == NULL
)
614 modetags
[1].ti_Data
= ns
.Width
;
615 modetags
[2].ti_Data
= ns
.Height
;
617 DEBUG_OPENSCREEN(dprintf("resetting native mode id !!\n");)
618 DEBUG_OPENSCREEN(dprintf("ns.Width %ld ns.Height %ld ns.Depth %ld !!\n",
619 (LONG
) ns
.Width
, (LONG
) ns
.Height
, (LONG
) ns
.Depth
);)
629 /* Got OpenScreenTags modeid without monitor, select system default.
630 * We really need proper mode promotion support.
632 if ((modeid
& MONITOR_ID_MASK
) == 0) {
633 modeid
|= (GfxBase
->DisplayFlags
& PAL
) ? PAL_MONITOR_ID
: NTSC_MONITOR_ID
;
639 if (INVALID_ID
== modeid
)
641 /* Old-style HAM or EHB request? */
642 if (newScreen
->ViewModes
& (HAM
| EXTRA_HALFBRITE
)) {
643 if (newScreen
->ViewModes
& HAM
)
644 modetags
[3].ti_Data
|= DIPF_IS_HAM
;
645 if (newScreen
->ViewModes
& EXTRA_HALFBRITE
)
646 modetags
[3].ti_Data
|= DIPF_IS_EXTRAHALFBRITE
;
648 modetags
[3].ti_Tag
= TAG_IGNORE
;
650 modeid
= BestModeIDA(modetags
);
651 if (INVALID_ID
== modeid
)
653 DEBUG_OPENSCREEN(dprintf("!!! OpenScreen: Could not find valid modeid !!!\n");)
655 SetError(OSERR_UNKNOWNMODE
);
656 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
662 DEBUG_OPENSCREEN(dprintf("OpenScreen: Corrected ModeID: 0x%08lx\n", modeid
));
664 InitRastPort(&screen
->Screen
.RastPort
);
668 if ((displayinfo
= FindDisplayInfo(modeid
)) != NULL
&&
669 GetDisplayInfoData(displayinfo
, (APTR
)&dispinfo
, sizeof(dispinfo
), DTAG_DISP
, modeid
)) {
670 screen
->DInfo
.dri
.dri_Resolution
.X
= dispinfo
.Resolution
.x
;
671 screen
->DInfo
.dri
.dri_Resolution
.Y
= dispinfo
.Resolution
.y
;
673 /* Fake a resolution */
674 screen
->DInfo
.dri
.dri_Resolution
.X
= 22;
675 screen
->DInfo
.dri
.dri_Resolution
.Y
= 22;
678 if ((displayinfo
= FindDisplayInfo(modeid
)) != NULL
&&
679 GetDisplayInfoData(displayinfo
, (APTR
)&dimensions
, sizeof(dimensions
), DTAG_DIMS
, modeid
) &&
681 GetDisplayInfoData(displayinfo
, &monitor
, sizeof(monitor
), DTAG_MNTR
, modeid
)
683 ((screen
->MonitorObject
= FindMonitor(modeid
, IntuitionBase
)) != NULL
)
688 screen
->Monitor
= monitor
.Mspc
;
690 /* graphics.library supplies HIDD composition flags here, specially for us */
691 screen
->SpecialFlags
= dimensions
.reserved
[0] << 8;
700 dclip
= &dimensions
.StdOScan
;
704 dclip
= &dimensions
.MaxOScan
;
708 dclip
= &dimensions
.VideoOScan
;
712 dclip
= &dimensions
.TxtOScan
;
717 if (ns
.Width
== STDSCREENWIDTH
)
718 ns
.Width
= dclip
->MaxX
- dclip
->MinX
+ 1;
719 else if (ns
.Width
< dimensions
.MinRasterWidth
)
720 ns
.Width
= dimensions
.MinRasterWidth
;
721 else if (ns
.Width
> dimensions
.MaxRasterWidth
)
722 ns
.Width
= dimensions
.MaxRasterWidth
;
724 if (ns
.Height
== STDSCREENHEIGHT
)
725 ns
.Height
= dclip
->MaxY
- dclip
->MinY
+ 1;
726 else if (ns
.Height
< dimensions
.MinRasterHeight
)
727 ns
.Height
= dimensions
.MinRasterHeight
;
728 else if (ns
.Height
> dimensions
.MaxRasterHeight
)
729 ns
.Height
= dimensions
.MaxRasterHeight
;
731 DEBUG_OPENSCREEN(dprintf("OpenScreen: Corrected: Width %ld Height %ld\n", ns
.Width
, ns
.Height
));
733 screen
->Screen
.RastPort
.BitMap
= NULL
;
734 if (ns
.Type
& CUSTOMBITMAP
)
736 struct BitMap
*custombm
;
738 custombm
= ns
.CustomBitMap
;
740 if (IsCyberModeID(modeid
) && custombm
)
742 int pixfmt
= GetCyberIDAttr(CYBRIDATTR_PIXFMT
,modeid
);
744 if(GetCyberMapAttr(custombm
,CYBRMATTR_PIXFMT
) != pixfmt
)
746 // incompatible formats !
751 if (!(custombm
->Flags
& BMF_SPECIALFMT
) || (modeid
!= (ULONG
)(IPTR
)custombm
->Planes
[7]))
757 screen
->Screen
.RastPort
.BitMap
= custombm
;
758 ns
.Depth
= GetBitMapAttr(ns
.CustomBitMap
,BMA_DEPTH
);
759 DEBUG_OPENSCREEN(dprintf("OpenScreen: CustomBitmap Depth %ld\n",
764 ns
.CustomBitMap
= NULL
;
765 ns
.Type
&= ~CUSTOMBITMAP
;
769 if(screen
->Screen
.RastPort
.BitMap
== NULL
)
771 ULONG Depth
= (dimensions
.MaxDepth
> 8) ? dimensions
.MaxDepth
: ns
.Depth
;
778 pixfmt
= PIXFMT_RGB15
;
781 pixfmt
= PIXFMT_RGB16
;
784 pixfmt
= PIXFMT_BGR24
;
787 pixfmt
= PIXFMT_ARGB32
;
790 pixfmt
= PIXFMT_LUT8
;
794 if (IsCyberModeID(modeid
))
796 pixfmt
= GetCyberIDAttr(CYBRIDATTR_PIXFMT
,modeid
);
800 allocbitmapflags
|= (BMF_SPECIALFMT
|BMF_CLEAR
);
802 screen
->Screen
.RastPort
.BitMap
= AllocBitMap(ns
.Width
,
805 allocbitmapflags
| (pixfmt
<< 24),
808 struct TagItem bmtags
[] = {
809 {BMATags_DisplayID
, modeid
},
813 screen
->Screen
.RastPort
.BitMap
= AllocBitMap(ns
.Width
,
816 allocbitmapflags
| BMF_CHECKVALUE
,
817 (struct BitMap
*)bmtags
);
819 screen
->AllocatedBitmap
= screen
->Screen
.RastPort
.BitMap
;
822 DEBUG_OPENSCREEN(dprintf("OpenScreen: BitMap 0x%lx\n",
823 screen
->Screen
.RastPort
.BitMap
));
827 DEBUG_OPENSCREEN(dprintf("OpenScreen: no displayinfo\n"));
828 SetError(OSERR_UNKNOWNMODE
);
831 /* Init screen's viewport */
832 InitVPort(&screen
->Screen
.ViewPort
);
834 /* Allocate a RasInfo struct in which we have a pointer
835 to the struct BitMap, into which the driver can
836 store its stuff. (Eg. pointer to a BitMap HIDD object)
838 screen
->Screen
.ViewPort
.RasInfo
= AllocMem(sizeof(struct RasInfo
), MEMF_ANY
| MEMF_CLEAR
);
840 DEBUG_OPENSCREEN(dprintf("OpenScreen: RasInfo 0x%lx\n",
841 screen
->Screen
.ViewPort
.RasInfo
));
844 (screen
->Screen
.RastPort
.BitMap
== NULL
) ||
845 (screen
->Screen
.ViewPort
.RasInfo
== NULL
))
851 D(bug("got allocated stuff\n"));
854 * Store pointer to bitmap, so we can get hold of it
855 * from withing LoadRGBxx() functions
857 screen
->Screen
.ViewPort
.RasInfo
->BitMap
= screen
->Screen
.RastPort
.BitMap
;
858 /* Initialize legacy embedded BitMap structure */
859 CopyMem(screen
->Screen
.RastPort
.BitMap
, &screen
->Screen
.BitMap
, sizeof(struct BitMap
));
864 /* Read depth from the bitmap to avoid AttachPalExtra/ObtainPen getting
865 * confused if cgx decided to allocate a higher depth bitmap than what
868 ns
.Depth
= GetBitMapAttr(screen
->Screen
.RastPort
.BitMap
,BMA_DEPTH
);
869 DEBUG_OPENSCREEN(bug("OpenScreen: Real bitmap depth is %u\n", ns
.Depth
));
874 else if (ns
.Depth
> 8)
877 numcolors
= 1L << ns
.Depth
;
880 /* Get a color map structure. Sufficient colors?? */
882 DEBUG_OPENSCREEN(dprintf("OpenScreen: Colormap Entries %ld\n",
885 if ((screen
->Screen
.ViewPort
.ColorMap
= GetColorMap(numcolors
)) != NULL
)
887 if (0 == AttachPalExtra(screen
->Screen
.ViewPort
.ColorMap
,
888 &screen
->Screen
.ViewPort
))
895 refcnt
=(UWORD
*) screen
->Screen
.ViewPort
.ColorMap
->PalExtra
->pe_RefCnt
;
896 alloclist
= (UBYTE
*)(refcnt
+ screen
->Screen
.ViewPort
.ColorMap
->Count
);
898 DEBUG_OPENSCREEN(dprintf("OpenScreen: PalExtra alloclist 0x%lx Count %ld\n",alloclist
,screen
->Screen
.ViewPort
.ColorMap
->Count
));
900 while(i
< screen
->Screen
.ViewPort
.ColorMap
->Count
)
902 // initialize alloc list to -1,0,1,2,3,4
904 DEBUG_OPENSCREEN(dprintf("OpenScreen: alloclist[%ld]=%ld\n",
920 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%lx\n",
921 screen
->Screen
.ViewPort
.ColorMap
));
925 screen
->ModeID
= modeid
;
930 struct ViewPortExtra
*vpe
= (struct ViewPortExtra
*)GfxNew(VIEWPORT_EXTRA_TYPE
);
932 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPortExtra 0x%lx\n", vpe
));
938 struct TagItem tags
[6];
940 memcpy(&vpe
->DisplayClip
, dclip
,sizeof(struct Rectangle
));
942 screen
->Screen
.ViewPort
.DxOffset
= ns
.LeftEdge
;
943 screen
->Screen
.ViewPort
.DyOffset
= ns
.TopEdge
;
944 screen
->Screen
.ViewPort
.DWidth
= dclip
->MaxX
- dclip
->MinX
+ 1;//ns.Width; /* or from dclip ? */
945 screen
->Screen
.ViewPort
.DHeight
= dclip
->MaxY
- dclip
->MinY
+ 1;//ns.Height;
947 tags
[0].ti_Tag
= VTAG_ATTACH_CM_SET
;
948 tags
[0].ti_Data
= (IPTR
)&screen
->Screen
.ViewPort
;
949 tags
[1].ti_Tag
= VTAG_VIEWPORTEXTRA_SET
;
950 tags
[1].ti_Data
= (IPTR
)vpe
;
951 tags
[2].ti_Tag
= VTAG_NORMAL_DISP_SET
;
952 tags
[2].ti_Data
= (IPTR
)displayinfo
;
953 tags
[3].ti_Tag
= VTAG_VPMODEID_SET
;
954 tags
[3].ti_Data
= modeid
;
955 tags
[4].ti_Tag
= VTAG_SPEVEN_BASE_SET
;
956 tags
[5].ti_Tag
= VTAG_NEXTBUF_CM
; /* if vctl is 0, this will terminate the list */
957 tags
[5].ti_Data
= vctl
;
959 /* Originally we could always use palette entries 16-19 for
960 sprites, even if the screen has less than 32 colors. AROS may
961 run on hardware that does not allow this (e.g. VGA cards).
962 In this case we have to shift down sprite colors. Currently
963 we use 4 colors before last 4 colors. For example on VGA cards
964 with only 16 colors we use colors 9 - 12. Remember that last 4 colors
965 of the screen are always used by Intuition.
966 Remember that the first color of the sprite is always transparent. So actually
967 we use 3, not 4 colors.
968 Yes, sprites may look not as expected on screens with low color depth, but at
969 least they will be seen. It's better than nothing.
971 Note that because our base color number doesn't always divide by 16, we use MSB to store
972 the remainder (offset in the color bank). Yes, it's a bit hacky, but i have no better idea
975 FIXME: this mapping scheme assumes that we always have at least 16 colors.
976 For current display modes supported by AROS it's always true, but in future
977 we may support more display modes (for example monochrome ones), and we
978 should take into account that on screens with less than 11 colors this simply
981 TODO: I think we should have SpriteBase attribute for the bitmap which
982 defaults to acceptable value. We should just get its default value here.
983 The same attribute would be set by VideoControl() and MakeVPort() in order
984 to actually apply the value. */
985 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
988 spritebase
= (ns
.Depth
< 5) ? (1 << ns
.Depth
) - 8 : 16;
990 DEBUG_OPENSCREEN(bug("OpenScreen: spritebase is %u\n", spritebase
));
991 tags
[4].ti_Data
= ((spritebase
& 0x0F) << 8 ) | (spritebase
>> 4);
993 if (VideoControl(screen
->Screen
.ViewPort
.ColorMap
, tags
) == 0)
995 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl ok\n"));
1000 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl failed\n"));
1010 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set first 4 colors\n"));
1011 p
= GetPrivIBase(IntuitionBase
)->Colors
;
1012 for (k
= 0; k
< 4; ++k
)
1014 DEBUG_OPENSCREEN(dprintf("OpenScreen: Viewport 0x%p Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1015 &screen
->Screen
.ViewPort
,
1016 k
, p
[k
].red
, p
[k
].green
, p
[k
].blue
));
1017 SetRGB32(&screen
->Screen
.ViewPort
, k
, p
[k
].red
, p
[k
].green
, p
[k
].blue
);
1022 ULONG lastcol
= ((ns
.Depth
> 8) ? 256 : (1 << ns
.Depth
)) - 4;
1024 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set last 4 colors (starting from %u)\n", lastcol
));
1025 for (k
= 0; k
< 4; ++k
)
1027 DEBUG_OPENSCREEN(dprintf("OpenScreen: Viewport 0x%p Index %u R 0x%08X G 0x%08X B 0x%08X\n",
1028 &screen
->Screen
.ViewPort
,
1029 k
+ lastcol
, p
[k
+4].red
, p
[k
+4].green
, p
[k
+4].blue
));
1031 if (k
+ lastcol
< numcolors
)
1032 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
, k
+ lastcol
,
1033 p
[k
+4].red
, p
[k
+4].green
, p
[k
+4].blue
, 0);
1035 /* Can't be allocated, but can still be set. */
1036 SetRGB32(&screen
->Screen
.ViewPort
, k
+ lastcol
,
1037 p
[k
+4].red
, p
[k
+4].green
, p
[k
+4].blue
);
1040 /* Allocate pens for mouse pointer sprite only on LUT screens. On hi- and
1041 truecolor screens sprite colors come from colormap attached to the sprite
1043 See pointerclass::New() for details. */
1044 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
1048 DEBUG_OPENSCREEN(dprintf("OpenScreen: Obtain Mousepointer colors\n"));
1049 /* Allocate pens for the mouse pointer */
1050 for (k
= 1; k
< 4; ++k
)
1053 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPort 0x%p Index %d R 0x%08X G 0x%08X B 0x%08X\n",
1054 &screen
->Screen
.ViewPort
,
1059 if (k
+ spritebase
< numcolors
)
1060 opret
= ObtainPen(screen
->Screen
.ViewPort
.ColorMap
, k
+ spritebase
,
1061 p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
, 0);
1062 if (opret
< 0) /* ObtainPen() fails if spritebase >= number of screen colors */
1063 SetRGB32(&screen
->Screen
.ViewPort
, k
+ spritebase
,
1064 p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
);
1068 if (colors
) /* if SA_Colors tag exists */
1070 DEBUG_OPENSCREEN(dprintf("OpenScreen: set SA_Colors 0x%lx\n",colors
));
1071 for(; colors
->ColorIndex
!= (WORD
)~0; colors
++)
1073 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB4 Viewport 0x%p Index %d R 0x%x G 0x%x B 0x%x\n",
1074 &screen
->Screen
.ViewPort
,
1079 SetRGB4(&screen
->Screen
.ViewPort
,
1087 if (colors32
) /* if SA_Colors32 tag exists */
1089 DEBUG_OPENSCREEN(dprintf("OpenScreen: LoadRGB32 colors32 0x%lx\n",colors32
));
1090 LoadRGB32(&screen
->Screen
.ViewPort
, (const ULONG
*)colors32
);
1093 D(bug("Loaded colors\n"));
1095 MakeVPort(&IntuitionBase
->ViewLord
, &screen
->Screen
.ViewPort
);
1096 /* Put validated values into screen structure, this is important */
1097 screen
->Screen
.LeftEdge
= screen
->Screen
.ViewPort
.DxOffset
;
1098 screen
->Screen
.TopEdge
= screen
->Screen
.ViewPort
.DyOffset
;
1106 //intui68k filters this
1107 screen
->Screen
.Flags
= (ns
.Type
& ~NS_EXTENDED
);
1109 /* Temporary hack, only used to set size of system gadgets */
1110 if (ns
.Width
>= 500 || ns
.Height
>= 300)
1111 screen
->Screen
.Flags
|= SCREENHIRES
;
1114 Copy the data from the rastport's bitmap
1115 to the screen's bitmap structure
1117 screen
->Screen
.BitMap
= *screen
->Screen
.RastPort
.BitMap
;
1120 screen
->Screen
.WBorTop
= 2;
1121 screen
->Screen
.WBorLeft
= 4;
1122 screen
->Screen
.WBorRight
= 4;
1123 screen
->Screen
.WBorBottom
= 2;
1125 screen
->Screen
.WBorTop
= 3; /* Amiga default is 2 */
1126 screen
->Screen
.WBorLeft
= 4;
1127 screen
->Screen
.WBorRight
= 4;
1128 screen
->Screen
.WBorBottom
= 2; /* Amiga default is 2 */
1131 screen
->Screen
.Title
= ns
.DefaultTitle
;
1133 DEBUG_OPENSCREEN(dprintf("OpenScreen: init layers\n"));
1134 InitLayers(&screen
->Screen
.LayerInfo
);
1137 if (NULL
!= layer_info_hook
)
1139 DEBUG_OPENSCREEN(dprintf("OpenScreen: instal layerinfohook\n"));
1140 InstallLayerInfoHook(&screen
->Screen
.LayerInfo
, layer_info_hook
);
1142 D(bug("layers intited screen\n"));
1144 /* Use higher than DRI_VERSION to detect manually created
1145 * DrawInfo structures (for example WB3.1:Prefs/Palette)
1147 screen
->DInfo
.dri
.dri_Version
= DRI_VERSION_AROS
;
1148 screen
->DInfo
.dri
.dri_NumPens
= NUMDRIPENS
;
1149 screen
->DInfo
.dri
.dri_Pens
= screen
->Pens
;
1150 /* dri_Depth is 8 on hi/true color screens like in AmigaOS with picasso96/cybergraphx */
1151 screen
->DInfo
.dri
.dri_Depth
= (ns
.Depth
<= 8) ? ns
.Depth
: 8;
1153 if (ns
.Depth
> 8) screen
->DInfo
.dri
.dri_Flags
= DRIF_DIRECTCOLOR
;
1155 screen
->DInfo
.dri_Screen
= &screen
->Screen
;
1157 /* SA_SysFont overrides SA_Font! */
1159 DEBUG_OPENSCREEN(dprintf("OpenScreen: SysFont = %d, ns.Font = %p\n", sysfont
, ns
.Font
));
1163 /* Is handled below */
1164 DEBUG_OPENSCREEN(dprintf("OpenScreen: skip SysFont for now\n"));
1166 else if (sysfont
== 1)
1169 /* Use safe OpenFont here - Piru
1171 screen
->DInfo
.dri
.dri_Font
= SafeReopenFont(IntuitionBase
, &GetPrivIBase(IntuitionBase
)->ScreenFont
);
1173 #warning: Really hacky way of re-opening ScreenFont
1176 screen
->DInfo
.dri
.dri_Font
= GetPrivIBase(IntuitionBase
)->ScreenFont
;
1177 screen
->DInfo
.dri
.dri_Font
->tf_Accessors
++;
1181 screen
->SpecialFlags
|= SF_SysFont
;
1183 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set ScreenFont\n"));
1188 screen
->DInfo
.dri
.dri_Font
= OpenFont(ns
.Font
);
1189 DEBUG_OPENSCREEN(dprintf("OpenScreen: custom font 0x%lx\n",screen
->DInfo
.dri
.dri_Font
));
1192 if (!screen
->DInfo
.dri
.dri_Font
)
1194 /* GfxBase->DefaultFont is *not* always topaz 8. It
1195 can be set with the Font prefs program!! */
1198 /* Use safe OpenFont.. - Piru
1200 screen
->DInfo
.dri
.dri_Font
= SafeReopenFont(IntuitionBase
, &GfxBase
->DefaultFont
);
1203 #warning: Really hacky way of re-opening system default font
1206 screen
->DInfo
.dri
.dri_Font
= GfxBase
->DefaultFont
;
1207 screen
->DInfo
.dri
.dri_Font
->tf_Accessors
++;
1212 if (!screen
->DInfo
.dri
.dri_Font
) ok
= FALSE
;
1218 /* set default values for pens */
1219 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Default Pens\n"));
1221 CopyMem(ns
.Depth
== 1 ? GetPrivIBase(IntuitionBase
)->DriPens2
1222 : ns
.Depth
== 4 ? GetPrivIBase(IntuitionBase
)->DriPens4
1223 : GetPrivIBase(IntuitionBase
)->DriPens8
,
1225 sizeof(screen
->Pens
));
1229 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set NewLook\n"));
1230 screen
->DInfo
.dri
.dri_Flags
|= DRIF_NEWLOOK
;
1238 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Custom Pens\n"));
1240 screen
->Pens
[DETAILPEN
] = screen
->Screen
.DetailPen
;
1241 screen
->Pens
[BLOCKPEN
] = screen
->Screen
.BlockPen
;
1243 for(i
= 0; (i
< NUMDRIPENS
) && (customdripens
[i
] != (UWORD
)~0); i
++)
1245 DEBUG_OPENSCREEN(dprintf("OpenScreen: Pen[%ld] %ld\n",i
,screen
->Pens
[i
]));
1246 screen
->Pens
[i
] = customdripens
[i
];
1252 * Let`s do some broken software validation of the pens
1253 * so we may not run into a black desktop.
1256 DEBUG_OPENSCREEN(dprintf("OpenScreen: Check Default Pens if the make sense\n"));
1257 if (screen
->Screen
.DetailPen
== screen
->Screen
.BlockPen
)
1259 DEBUG_OPENSCREEN(dprintf("OpenScreen: DetailPen==BlockPen..correct\n"));
1260 screen
->Screen
.DetailPen
= 0;
1261 screen
->Screen
.BlockPen
= 1;
1264 if (screen
->Screen
.BlockPen
== 0)
1266 DEBUG_OPENSCREEN(dprintf("OpenScreen: BlockPen==0..correct\n"));
1267 screen
->Screen
.BlockPen
= screen
->Screen
.DetailPen
;
1268 screen
->Screen
.DetailPen
= 0;
1271 screen
->Pens
[DETAILPEN
] = screen
->Screen
.DetailPen
;
1272 screen
->Pens
[BLOCKPEN
] = screen
->Screen
.BlockPen
;
1275 /* Allocate shared/exclusive colors */
1278 BYTE color_alloced
[256];
1282 for(i
= 0; i
< 256; i
++)
1284 color_alloced
[i
] = FALSE
;
1287 /* Mouse pointer colors */
1289 color_alloced
[17] = TRUE
;
1290 color_alloced
[18] = TRUE
;
1291 color_alloced
[19] = TRUE
;
1293 /* The Pens in the DrawInfo must be allocated as shared */
1295 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen DrawInfo Pens as shared\n"));
1297 for(i
= 0; i
< NUMDRIPENS
; i
++)
1299 int pen
= screen
->Pens
[i
];
1301 if (!color_alloced
[pen
])
1303 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1304 screen
->Screen
.ViewPort
.ColorMap
,
1307 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
,
1313 color_alloced
[pen
] = TRUE
;
1316 DEBUG_OPENSCREEN(dprintf("OpenScreen: done\n"));
1318 /* If SA_SharePens is FALSE then allocate the rest of the colors
1319 in the colormap as exclusive */
1323 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen the remaining Pens as exclusive\n"));
1325 for(i
= 0; i
< numcolors
; i
++)
1327 if (!color_alloced
[i
])
1329 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1330 screen
->Screen
.ViewPort
.ColorMap
,
1332 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
,
1337 PENF_EXCLUSIVE
| PENF_NO_SETCOLOR
);
1341 } /* if (!sharepens) */
1351 screen
->DInfo
.dri_Screen
= &screen
->Screen
; //useful sometimes ;)
1353 realdepth
= GetBitMapAttr( screen
->Screen
.RastPort
.BitMap
, BMA_DEPTH
);
1356 screen
->DInfo
.dri_Flags
|= DRIF_DIRECTCOLOR
;
1360 screen
->DInfo
.dri_Flags
&= ~DRIF_DIRECTCOLOR
;
1363 if (!(screen
->DInfo
.dri_Colors
= AllocMem(4 * DRIPEN_NUMDRIPENS
,MEMF_PUBLIC
)))
1368 CopyMem(&defaultdricolors
,screen
->DInfo
.dri_Colors
,sizeof (defaultdricolors
));
1369 memset(((UBYTE
*) screen
->DInfo
.dri_Colors
) + sizeof(defaultdricolors
), 0, 4 * DRIPEN_NUMDRIPENS
- sizeof(defaultdricolors
));
1374 if ((screen
->DInfo
.dri_Customize
= AllocMem(sizeof (struct IntuitionCustomize
),MEMF_PUBLIC
|MEMF_CLEAR
)))
1376 struct IntuitionCustomize
*ic
;
1377 ic
= screen
->DInfo
.dri_Customize
;
1378 screen
->DInfo
.dri_Flags
|= DRIF_SKINSSUPPORT
;
1379 /* This initializes CustomizePrefs structure */
1381 int_SkinAction(SKA_LoadSkin
,(ULONG
*)&screen
->DInfo
,(struct Screen
*)screen
,IntuitionBase
);
1392 struct windowclassprefs
*wcprefs
;
1394 wcprefs
= (struct windowclassprefs
*)int_GetCustomPrefs(TYPE_WINDOWCLASS
,&screen
->DInfo
,IntuitionBase
);
1395 if (wcprefs
->flags
& WINDOWCLASS_PREFS_1TO1FRAMES
)
1397 screen
->Screen
.WBorLeft
= screen
->Screen
.WBorTop
;
1398 screen
->Screen
.WBorRight
= screen
->Screen
.WBorTop
;
1399 screen
->Screen
.WBorBottom
= screen
->Screen
.WBorTop
;
1402 screen
->Screen
.WBorTop
+= wcprefs
->titlebarincrement
;
1404 int_FreeCustomPrefs(TYPE_WINDOWCLASS
,&screen
->DInfo
,IntuitionBase
);
1411 IPTR userbuffersize
;
1412 struct NewDecorator
*nd
;
1414 nd
= ((struct IntIntuitionBase
*)(IntuitionBase
))->Decorator
;
1416 ObtainSemaphore(&((struct IntIntuitionBase
*)(IntuitionBase
))->ScrDecorSem
);
1418 struct DosLibrary
*DOSBase
= GetPrivIBase(IntuitionBase
)->DOSBase
;
1420 /* Open dos.library only once, when first needed */
1422 GetPrivIBase(IntuitionBase
)->DOSBase
= DOSBase
= (struct DosLibrary
*)OpenLibrary("dos.library", 36);
1428 if (!IsListEmpty(&GetPrivIBase(IntuitionBase
)->Decorations
))
1430 node
= GetPrivIBase(IntuitionBase
)->Decorations
.lh_Head
;
1431 for (; node
->ln_Succ
; node
= node
->ln_Succ
)
1433 struct NewDecorator
*d
= (struct NewDecorator
*) node
;
1435 if ((d
->nd_IntPattern
!= NULL
) && (screen
->Screen
.Title
!= NULL
))
1437 if (MatchPattern(d
->nd_IntPattern
, screen
->Screen
.Title
))
1446 screen
->ScrDecorObj
= NewObjectA(nd
->nd_ScreenClass
, NULL
, nd
->nd_ScreenTags
);
1447 screen
->MenuDecorObj
= NewObjectA(nd
->nd_MenuClass
, NULL
, nd
->nd_MenuTags
);
1448 screen
->WinDecorObj
= NewObjectA(nd
->nd_WindowClass
, NULL
, nd
->nd_WindowTags
);
1452 screen
->ScrDecorObj
= NewObjectA(GetPrivIBase(IntuitionBase
)->ScrDecorClass
, NULL
, GetPrivIBase(IntuitionBase
)->ScrDecorTags
);
1453 screen
->MenuDecorObj
= NewObjectA(GetPrivIBase(IntuitionBase
)->MenuDecorClass
, NULL
, GetPrivIBase(IntuitionBase
)->MenuDecorTags
);
1454 screen
->WinDecorObj
= NewObjectA(GetPrivIBase(IntuitionBase
)->WinDecorClass
, NULL
, GetPrivIBase(IntuitionBase
)->WinDecorTags
);
1456 screen
->Decorator
= nd
;
1458 if (screen
->Decorator
) screen
->Decorator
->nd_cnt
++;
1460 ReleaseSemaphore(&((struct IntIntuitionBase
*)(IntuitionBase
))->ScrDecorSem
);
1462 GetAttr(SDA_UserBuffer
, screen
->ScrDecorObj
, &userbuffersize
);
1466 screen
->DecorUserBufferSize
= userbuffersize
;
1467 screen
->DecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
1468 if (!screen
->DecorUserBuffer
) ok
= FALSE
;
1474 struct TagItem sysi_tags
[] =
1476 {SYSIA_Which
, MENUCHECK
},
1477 {SYSIA_DrawInfo
, (IPTR
)&screen
->DInfo
},
1478 {SYSIA_UserBuffer
, screen
->DecorUserBuffer
},
1483 screen
->DInfo
.dri
.dri_CheckMark
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
1484 DEBUG_OPENSCREEN(dprintf("OpenScreen: CheckMark 0x%lx\n",
1485 screen
->DInfo
.dri
.dri_CheckMark
));
1487 sysi_tags
[0].ti_Data
= AMIGAKEY
;
1489 screen
->DInfo
.dri
.dri_AmigaKey
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
1490 DEBUG_OPENSCREEN(dprintf("OpenScreen: AmigaKey 0x%lx\n",
1491 screen
->DInfo
.dri
.dri_AmigaKey
));
1493 sysi_tags
[0].ti_Data
= SUBMENUIMAGE
;
1495 screen
->DInfo
.dri
.dri_SubMenuImage
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
1496 DEBUG_OPENSCREEN(dprintf("OpenScreen: SubMenuImage 0x%lx\n",
1497 screen
->DInfo
.dri
.dri_SubMenuImage
));
1500 sysi_tags
[0].ti_Data
= SUBMENUIMAGE
;
1501 screen
->DInfo
.dri_Customize
->submenu
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
1502 sysi_tags
[0].ti_Data
= MENUTOGGLEIMAGE
;
1503 screen
->DInfo
.dri_Customize
->menutoggle
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
1504 if (!screen
->DInfo
.dri_Customize
->submenu
||
1505 !screen
->DInfo
.dri_Customize
->menutoggle
) ok
= FALSE
;
1508 if (!screen
->DInfo
.dri
.dri_CheckMark
|| !screen
->DInfo
.dri
.dri_AmigaKey
|| !screen
->DInfo
.dri
.dri_SubMenuImage
) ok
= FALSE
;
1515 SetFont(&screen
->Screen
.RastPort
, screen
->DInfo
.dri
.dri_Font
);
1517 AskFont(&screen
->Screen
.RastPort
, (struct TextAttr
*) &screen
->textattr
);
1519 screen
->Screen
.Font
= (struct TextAttr
*) &screen
->textattr
;
1521 DEBUG_OPENSCREEN(dprintf("OpenScreen: Font %s/%d\n",
1522 screen
->textattr
.tta_Name
, screen
->textattr
.tta_YSize
));
1524 screen
->Screen
.BarVBorder
= 1; /* on the Amiga it is (usually?) 1 */
1525 screen
->Screen
.BarHBorder
= 5;
1526 screen
->Screen
.MenuVBorder
= 2; /* on the Amiga it is (usually?) 2 */
1527 screen
->Screen
.MenuHBorder
= 4;
1529 struct sdpInitScreen msg
;
1531 msg
.MethodID
= SDM_INITSCREEN
;
1532 msg
.sdp_Screen
= &screen
->Screen
;
1533 msg
.sdp_TrueColor
= screen
->DInfo
.dri
.dri_Flags
& DRIF_DIRECTCOLOR
;
1534 msg
.sdp_FontHeight
= screen
->DInfo
.dri
.dri_Font
->tf_YSize
;
1535 msg
.sdp_BarVBorder
= screen
->Screen
.BarVBorder
;
1536 msg
.sdp_BarHBorder
= screen
->Screen
.BarHBorder
;
1537 msg
.sdp_MenuVBorder
= screen
->Screen
.MenuVBorder
;
1538 msg
.spd_MenuHBorder
= screen
->Screen
.MenuHBorder
;
1539 msg
.sdp_WBorTop
= screen
->Screen
.WBorTop
;
1540 msg
.sdp_WBorLeft
= screen
->Screen
.WBorLeft
;
1541 msg
.sdp_WBorRight
= screen
->Screen
.WBorRight
;
1542 msg
.sdp_WBorBottom
= screen
->Screen
.WBorBottom
;
1545 msg
.sdp_TitleHack
= screen
->Screen
.WBorTop
-2;
1547 msg
.sdp_TitleHack
= 0;
1550 msg
.sdp_BarHeight
= msg
.sdp_FontHeight
+ msg
.sdp_BarVBorder
* 2 + msg
.sdp_TitleHack
;
1551 msg
.sdp_UserBuffer
= ((struct IntScreen
*)screen
)->DecorUserBuffer
;
1553 if (!DoMethodA(((struct IntScreen
*)(screen
))->ScrDecorObj
, (Msg
)&msg
)) ok
= FALSE
;
1556 screen
->Screen
.BarHeight
= msg
.sdp_BarHeight
;
1557 screen
->Screen
.BarVBorder
= msg
.sdp_BarVBorder
;
1558 screen
->Screen
.BarHBorder
= msg
.sdp_BarHBorder
;
1559 screen
->Screen
.MenuVBorder
= msg
.sdp_MenuVBorder
;
1560 screen
->Screen
.MenuHBorder
= msg
.spd_MenuHBorder
;
1561 screen
->Screen
.WBorTop
= msg
.sdp_WBorTop
;
1562 screen
->Screen
.WBorLeft
= msg
.sdp_WBorLeft
;
1563 screen
->Screen
.WBorRight
= msg
.sdp_WBorRight
;
1564 screen
->Screen
.WBorBottom
= msg
.sdp_WBorBottom
;
1571 #define SDEPTH_HEIGHT (screen->Screen.BarHeight + 1)
1575 #define IA_Screen (IA_Dummy + 0x1f) /* OS v44 includes!*/
1577 struct TagItem sdepth_tags
[] =
1581 #if SQUARE_WIN_GADGETS
1582 {GA_Width
, SDEPTH_HEIGHT
},
1584 {GA_Height
, SDEPTH_HEIGHT
},
1585 {GA_SysGadget
, TRUE
},
1586 {GA_SysGType
, GTYP_SDEPTH
},
1587 {GA_RelVerify
, TRUE
},
1593 if (!(screen
->Screen
.Flags
& SCREENQUIET
))
1595 im
= CreateStdSysImage(SDEPTHIMAGE
, SDEPTH_HEIGHT
, &screen
->Screen
, (APTR
) ((struct IntScreen
*)screen
)->DecorUserBuffer
,
1596 (struct DrawInfo
*)&screen
->DInfo
, IntuitionBase
);
1599 sdepth_tags
[0].ti_Data
= (IPTR
)im
;
1601 screen
->depthgadget
= NewObjectA(NULL
, BUTTONGCLASS
, sdepth_tags
);
1603 DEBUG_OPENSCREEN(dprintf("OpenScreen: DepthGadget 0x%lx\n",
1604 screen
->depthgadget
));
1606 screen
->Screen
.FirstGadget
= (struct Gadget
*)screen
->depthgadget
;
1607 if (screen
->Screen
.FirstGadget
)
1609 struct sdpLayoutScreenGadgets msg
;
1611 screen
->Screen
.FirstGadget
->GadgetType
|= GTYP_SCRGADGET
;
1613 msg
.MethodID
= SDM_LAYOUT_SCREENGADGETS
;
1614 msg
.sdp_TrueColor
= screen
->DInfo
.dri
.dri_Flags
& DRIF_DIRECTCOLOR
;
1615 msg
.sdp_Layer
= screen
->Screen
.BarLayer
;
1616 msg
.sdp_Gadgets
= screen
->Screen
.FirstGadget
;
1617 msg
.sdp_Flags
= SDF_LSG_INITIAL
| SDF_LSG_MULTIPLE
;
1618 msg
.sdp_UserBuffer
= ((struct IntScreen
*)screen
)->DecorUserBuffer
;
1620 DoMethodA(((struct IntScreen
*)(screen
))->ScrDecorObj
, (Msg
)&msg
);
1623 struct TagItem gadtags
[] =
1630 GetAttr(GA_Width
, screen
->depthgadget
, &width
);
1632 gadtags
[0].ti_Data
= -width
+ 1;
1633 SetAttrsA(screen
->depthgadget
, gadtags
);
1639 if (im
) DisposeObject(im
);
1643 #if DEBUG_OpenScreen
1647 for (i
= 0; i
<= screen
->DInfo
.dri
.dri_NumPens
; i
++)
1649 dprintf("OpenScreen: dri_Pen[%ld] = %ld\n", i
, screen
->DInfo
.dri
.dri_Pens
[i
]);
1654 #ifdef USEWINDOWLOCK
1655 /* let's wait for user to finish window drag/size actions to avoid
1656 deadlocks and not break user's input */
1657 ObtainSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
1662 int_CalcSkinInfo(&screen
->Screen
,IntuitionBase
);
1663 int_InitTitlebarBuffer(screen
,IntuitionBase
);
1666 D(bug("Calling SetRast()\n"));
1668 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set background color Pen %ld\n",screen
->Pens
[BACKGROUNDPEN
]));
1669 /* Set screen to background color */
1670 SetRast(&screen
->Screen
.RastPort
, screen
->Pens
[BACKGROUNDPEN
]);
1672 D(bug("SetRast() called\n"));
1674 DEBUG_OPENSCREEN(dprintf("OpenScreen: Creating screen bar\n"));
1679 if (GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_NOWBTITLEBAR
) screen
->SpecialFlags
|= SF_InvisibleBar
;
1680 if (GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_DISAPPEARINGTITLEBAR
) screen
->SpecialFlags
|= SF_AppearingBar
;
1684 screen
->SpecialFlags
|= SF_Draggable
;
1685 DEBUG_OPENSCREEN(bug("OpenScreen: Special flags: 0x%04X\n", screen
->SpecialFlags
));
1687 //jDc: ALL screens MUST have BarLayer!
1688 CreateScreenBar(&screen
->Screen
, IntuitionBase
);
1690 DEBUG_OPENSCREEN(bug("OpenScreen: ScreenBar = %p\n", screen
->Screen
.BarLayer
));
1692 if (!screen
->Screen
.BarLayer
) ok
= FALSE
;
1695 ** jDc: better modify the screen list in sync with inputhandler, this for example allows us to scan the list
1696 ** without any locks when we are on input.device context
1700 struct OpenScreenActionMsg msg
;
1701 struct List
*list
= LockPubScreenList();
1703 msg
.Screen
= screen
;
1704 msg
.NewScreen
= &ns
;
1707 DEBUG_OPENSCREEN(dprintf("OpenScreen: Calling DoSyncAction()\n"));
1709 DoSyncAction((APTR
)int_openscreen
,&msg
.msg
,IntuitionBase
);
1711 DEBUG_OPENSCREEN(dprintf("OpenScreen: DoSyncAction returned\n"));
1713 UnlockPubScreenList();
1720 GetAttr(POINTERA_SharedPointer
, GetPrivIBase(IntuitionBase
)->DefaultPointer
, (IPTR
*)&screen
->Pointer
);
1721 ObtainSharedPointer(screen
->Pointer
, IntuitionBase
);
1722 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sprite DefaultPtr 0x%lx\n",&screen
->Pointer
));
1728 ok
= MakeScreen(&screen
->Screen
) == 0;
1729 DEBUG_OPENSCREEN(dprintf("OpenScreen: MakeScreen %s\n", ok
? "ok" : "failed"));
1734 ok
= RethinkDisplay() == 0;
1735 DEBUG_OPENSCREEN(dprintf("OpenScreen: RethinkDisplay %s\n", ok
? "ok" : "failed"));
1741 FireMenuMessage(MMCODE_STARTCLOCK
,NULL
,NULL
,IntuitionBase
);
1745 #ifdef USEWINDOWLOCK
1746 if (windowlock
) ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
1753 DEBUG_OPENSCREEN(dprintf("OpenScreen: Get ThinLayerInfo\n"));
1754 ThinLayerInfo(&screen
->Screen
.LayerInfo
);
1757 if (screen
->Screen
.ViewPort
.ColorMap
)
1759 FreeColorMap(screen
->Screen
.ViewPort
.ColorMap
);
1762 if (screen
->Screen
.BarLayer
)
1764 DEBUG_OPENSCREEN(dprintf("OpenScreen: KillScreenBar\n"));
1765 KillScreenBar(&screen
->Screen
, IntuitionBase
);
1769 DisposeObject(screen
->DInfo
.dri_Customize
->submenu
);
1770 DisposeObject(screen
->DInfo
.dri_Customize
->menutoggle
);
1771 if (screen
->DInfo
.dri_Customize
) FreeMem(screen
->DInfo
.dri_Customize
,sizeof (struct IntuitionCustomize
));
1772 if (screen
->DInfo
.dri_Colors
) FreeMem(screen
->DInfo
.dri_Colors
,4 * DRIPEN_NUMDRIPENS
);
1774 if (screen
->DInfo
.dri
.dri_AmigaKey
)
1776 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose AmigaKey Object\n"));
1777 DisposeObject(screen
->DInfo
.dri
.dri_AmigaKey
);
1779 if (screen
->DInfo
.dri
.dri_CheckMark
)
1781 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose CheckMark Object\n"));
1782 DisposeObject(screen
->DInfo
.dri
.dri_CheckMark
);
1785 if (screen
->DInfo
.dri
.dri_SubMenuImage
)
1787 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose SubMenuImage Object\n"));
1788 DisposeObject(screen
->DInfo
.dri
.dri_SubMenuImage
);
1791 if (screen
->DInfo
.dri
.dri_Font
)
1793 DEBUG_OPENSCREEN(dprintf("OpenScreen: Close Font\n"));
1794 CloseFont(screen
->DInfo
.dri
.dri_Font
);
1797 if (screen
->AllocatedBitmap
&& !(ns
.Type
& CUSTOMBITMAP
))
1799 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free BitMap\n"));
1800 FreeBitMap(screen
->AllocatedBitmap
);
1803 if (screen
->Screen
.ViewPort
.RasInfo
)
1805 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free RasInfo\n"));
1806 FreeMem(screen
->Screen
.ViewPort
.RasInfo
, sizeof (struct RasInfo
));
1811 DEBUG_OPENSCREEN(dprintf("OpenScreen: Trash Rastport\n"));
1812 DeinitRastPort(&screen
->Screen
.RastPort
);
1815 if (screen
->DecorUserBuffer
)
1817 FreeMem((void *)screen
->DecorUserBuffer
, screen
->DecorUserBufferSize
);
1820 if (screen
->Decorator
) screen
->Decorator
->nd_cnt
--;
1822 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free Screen\n"));
1823 FreeMem (screen
, sizeof (struct IntScreen
));
1829 DEBUG_OPENSCREEN(dprintf("OpenScreen: return 0x%lx\n", screen
));
1831 FireScreenNotifyMessage((IPTR
) screen
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
1833 ReturnPtr ("OpenScreen", struct Screen
*, (struct Screen
*)screen
);
1839 static VOID
int_openscreen(struct OpenScreenActionMsg
*msg
,
1840 struct IntuitionBase
*IntuitionBase
)
1843 struct IntScreen
*screen
= msg
->Screen
;
1844 struct NewScreen
*ns
= msg
->NewScreen
;
1845 struct List
*list
= msg
->List
;
1846 struct Screen
*oldFirstScreen
;
1848 DEBUG_OPENSCREEN(dprintf("OpenScreen: Checking for pubScrNode (0x%lx)\n",screen
->pubScrNode
));
1850 /* If this is a public screen, we link it into the intuition global
1851 public screen list */
1852 if (screen
->pubScrNode
!= NULL
)
1854 /* Set the pointer to ourselves */
1855 GetPrivScreen(screen
)->pubScrNode
->psn_Screen
= &screen
->Screen
;
1857 DEBUG_OPENSCREEN(dprintf("OpenScreen: Add Screen to PubList\n"));
1858 AddTail(list
, (struct Node
*)GetPrivScreen(screen
)->pubScrNode
);
1861 lock
= LockIBase(0);
1863 oldFirstScreen
= IntuitionBase
->FirstScreen
;
1865 if (ns
->Type
& SCREENBEHIND
)
1867 struct Screen
**ptr
= &IntuitionBase
->FirstScreen
;
1869 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sort Behind\n"));
1871 IntuitionBase
->ActiveScreen
= &screen
->Screen
;
1873 ptr
= &(*ptr
)->NextScreen
;
1874 *ptr
= &screen
->Screen
;
1878 screen
->Screen
.NextScreen
= IntuitionBase
->FirstScreen
;
1879 IntuitionBase
->FirstScreen
=
1880 IntuitionBase
->ActiveScreen
= &screen
->Screen
;
1881 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set as ActiveScreen\n"));
1884 /* If it's the first screen being opened, activate its monitor */
1885 if (!oldFirstScreen
)
1886 ActivateMonitor(screen
->MonitorObject
, -1, -1, IntuitionBase
);
1888 /* set the default pub screen */
1889 if (GetPrivIBase(IntuitionBase
)->IControlPrefs
.ic_Flags
& ICF_DEFPUBSCREEN
)
1891 if ((IntuitionBase
->FirstScreen
== &screen
->Screen
) && screen
->pubScrNode
&& (screen
->Screen
.Flags
& (PUBLICSCREEN
| WBENCHSCREEN
)))
1893 GetPrivIBase(IntuitionBase
)->DefaultPubScreen
= &screen
->Screen
;
1899 D(bug("set active screen\n"));
1901 AddResourceToList(screen
, RESOURCE_SCREEN
, IntuitionBase
);