2 Copyright 1995-2010, The AROS Development Team. All rights reserved.
3 Copyright 2001-2003, The MorphOS Development Team. All Rights Reserved.
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>
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"
38 #include "monitorclass_private.h"
40 #ifndef DEBUG_OpenScreen
41 #define DEBUG_OpenScreen 0
47 #include <aros/debug.h>
49 struct OpenScreenActionMsg
51 struct IntuiActionMsg msg
;
52 struct IntScreen
*Screen
;
53 struct NewScreen
*NewScreen
;
57 static VOID
int_openscreen(struct OpenScreenActionMsg
*msg
,
58 struct IntuitionBase
*IntuitionBase
);
61 extern const ULONG defaultdricolors
[DRIPEN_NUMDRIPENS
];
64 /*****************************************************************************
68 AROS_LH1(struct Screen
*, OpenScreen
,
71 AROS_LHA(struct NewScreen
*, newScreen
, A0
),
74 struct IntuitionBase
*, IntuitionBase
, 33, Intuition
)
91 The function relies on display driver object being passed in DimensionInfo.reserved[0]
92 by graphics.library/GetDisplayInfoData()
95 29-10-95 digulla automatically created from
96 intuition_lib.fd and clib/intuition_protos.h
98 *****************************************************************************/
103 struct TagItem
*tag
, *tagList
;
105 struct IntScreen
*screen
;
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
;
113 BOOL ok
= TRUE
, rp_inited
= FALSE
, li_inited
= FALSE
, sharepens
= FALSE
;
115 BOOL windowlock
= FALSE
;
117 struct Rectangle
*dclip
= NULL
;
118 LONG overscan
= OSCAN_TEXT
;
119 DisplayInfoHandle displayinfo
;
120 struct DimensionInfo dimensions
;
122 struct MonitorInfo monitor
;
124 ULONG allocbitmapflags
= BMF_DISPLAYABLE
;
128 BOOL workbench
= FALSE
;
129 BOOL draggable
= TRUE
;
130 struct TagItem modetags
[] =
132 { BIDTAG_Depth
, 0UL },
133 { BIDTAG_DesiredWidth
, 0UL },
134 { BIDTAG_DesiredHeight
, 0UL },
137 ULONG modeid
= INVALID_ID
;
139 /* Intuition not up yet? */
140 if (!GetPrivIBase(IntuitionBase
)->DefaultPointer
)
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"
150 , newScreen
->LeftEdge
157 FireScreenNotifyMessage((IPTR
) newScreen
, SNOTIFY_BEFORE_OPENSCREEN
, IntuitionBase
);
161 if (newScreen
->Type
& NS_EXTENDED
)
163 tagList
= ((struct ExtNewScreen
*)newScreen
)->Extension
;
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
));
174 if (!LocaleBase
) LocaleBase
= OpenLibrary("locale.library",0);
175 if (!LocaleBase
) return NULL
;
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
);
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
));
197 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
198 SetError(OSERR_NOMEM
);
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
;
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
));
230 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Left %ld\n",tag
->ti_Data
));
231 ns
.LeftEdge
= tag
->ti_Data
;
235 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Top %ld\n",tag
->ti_Data
));
236 ns
.TopEdge
= tag
->ti_Data
;
240 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Width %ld\n",tag
->ti_Data
));
241 ns
.Width
= tag
->ti_Data
;
245 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Height %ld\n",tag
->ti_Data
));
246 ns
.Height
= tag
->ti_Data
;
250 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Depth %ld\n",tag
->ti_Data
));
251 ns
.Depth
= tag
->ti_Data
;
255 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DetailPen %ld\n",tag
->ti_Data
));
256 ns
.DetailPen
= tag
->ti_Data
;
260 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BlockPen %ld\n",tag
->ti_Data
));
261 ns
.BlockPen
= tag
->ti_Data
;
265 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Type 0x%lx\n",tag
->ti_Data
));
266 ns
.Type
&= ~SCREENTYPE
;
267 ns
.Type
|= tag
->ti_Data
;
271 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Title <%s>\n",tag
->ti_Data
));
272 ns
.DefaultTitle
= (UBYTE
*)tag
->ti_Data
;
276 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ID <%s>\n",tag
->ti_Data
));
277 screen
->ID
= StrDup((STRPTR
)tag
->ti_Data
);
281 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Font 0x%lx\n",tag
->ti_Data
));
282 ns
.Font
= (struct TextAttr
*)tag
->ti_Data
;
286 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors32 0x%lx\n",tag
->ti_Data
));
287 colors32
= (ULONG
*)tag
->ti_Data
;
291 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors 0x%lx\n",tag
->ti_Data
));
292 colors
= (struct ColorSpec
*)tag
->ti_Data
;
296 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SysFont 0x%lx\n",tag
->ti_Data
));
297 sysfont
= (WORD
)tag
->ti_Data
;
301 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap 0x%lx\n",tag
->ti_Data
));
304 ns
.Type
|= CUSTOMBITMAP
;
305 ns
.CustomBitMap
= (struct BitMap
*)tag
->ti_Data
;
309 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap==NULL specified, custom bitmap use disabled\n"));
313 /* Name of this public screen. */
315 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubName <%s>\n",tag
->ti_Data
));
318 screen
->pubScrNode
= AllocMem(sizeof(struct PubScreenNode
), MEMF_CLEAR
);
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
);
342 old
= LockPubScreen((STRPTR
)tag
->ti_Data
);
346 UnlockPubScreen(NULL
, old
);
347 SetError(OSERR_PUBNOTUNIQUE
);
348 UnlockPubScreenList();
349 FireScreenNotifyMessage((IPTR
) NULL
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
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
);
370 if ((ns
.Type
& SCREENTYPE
) == CUSTOMSCREEN
)
372 ns
.Type
&= ~SCREENTYPE
;
373 ns
.Type
|= PUBLICSCREEN
;
376 screen
->pubScrNode
->psn_Node
.ln_Name
= AllocVec(MAXPUBSCREENNAME
+ 1,
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
);
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
);
393 /* Signal bit number to use when signalling public screen
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
);
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
;
410 /* Task that should be signalled when the public screen loses
411 its last visitor window. */
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
);
419 screen
->pubScrNode
->psn_SigTask
= (struct Task
*)tag
->ti_Data
;
423 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackFill Hook 0x%lx\n",tag
->ti_Data
));
424 layer_info_hook
= (struct Hook
*)tag
->ti_Data
;
428 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Quiet 0x%lx\n",tag
->ti_Data
));
431 ns
.Type
|= SCREENQUIET
;
435 ns
.Type
&= ~SCREENQUIET
;
440 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ShowTitle 0x%lx\n",tag
->ti_Data
));
443 ns
.Type
|= SHOWTITLE
;
447 ns
.Type
&= ~SHOWTITLE
;
452 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Pens 0x%lx\n",tag
->ti_Data
));
453 customdripens
= (UWORD
*)tag
->ti_Data
;
457 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DisplayID 0x%lx\n",tag
->ti_Data
));
458 //if (modeid == INVALID_ID)
459 modeid
= tag
->ti_Data
;
463 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SharePens 0x%lx\n",tag
->ti_Data
));
464 sharepens
= tag
->ti_Data
? TRUE
: FALSE
;
467 ns
.Type
|= PENSHARED
;
471 ns
.Type
&= ~PENSHARED
;
476 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Interleaved 0x%lx\n",tag
->ti_Data
));
479 allocbitmapflags
|= BMF_INTERLEAVED
;
483 allocbitmapflags
&= ~BMF_INTERLEAVED
;
488 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Behind 0x%lx\n",tag
->ti_Data
));
491 ns
.Type
|= SCREENBEHIND
;
495 ns
.Type
&= ~SCREENBEHIND
;
500 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DClip 0x%lx\n",tag
->ti_Data
));
501 dclip
= (struct Rectangle
*)tag
->ti_Data
;
505 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_OverScan 0x%lx\n",tag
->ti_Data
));
506 overscan
= tag
->ti_Data
;
509 case SA_LikeWorkbench
:
517 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AutoScroll 0x%lx\n",tag
->ti_Data
));
518 ns
.Type
|= AUTOSCROLL
;
522 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FullPalette 0x%lx\n",tag
->ti_Data
));
525 case SA_ColorMapEntries
:
526 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ColorMapEntries 0x%lx\n",tag
->ti_Data
));
527 numcolors
= tag
->ti_Data
;
531 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Parent 0x%lx\n",tag
->ti_Data
));
535 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Draggable 0x%lx\n",tag
->ti_Data
));
536 draggable
= tag
->ti_Data
;
540 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Exclusive 0x%lx\n",tag
->ti_Data
));
543 case SA_VideoControl
:
544 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_VideoControl 0x%p\n",tag
->ti_Data
));
549 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FrontChild 0x%lx\n",tag
->ti_Data
));
553 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackChild 0x%lx\n",tag
->ti_Data
));
557 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_MinimizeISG 0x%lx\n",tag
->ti_Data
));
560 /* TODO: Missing SA_ Tags */
562 DEBUG_OPENSCREEN(dprintf("OpenScreen: unknown tag 0x%lx data 0x%lx\n",
567 } /* switch (tag->ti_Tag) */
569 } /* while ((tag = NextTagItem (&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
;
585 modetags
[1].ti_Tag
= TAG_IGNORE
;
588 if (ns
.Height
!= STDSCREENHEIGHT
)
590 modetags
[2].ti_Data
= ns
.Height
;
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
)
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
);)
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
);
636 DEBUG_OPENSCREEN(dprintf("OpenScreen: Corrected ModeID: 0x%08lx\n", modeid
));
638 InitRastPort(&screen
->Screen
.RastPort
);
642 if ((displayinfo
= FindDisplayInfo(modeid
)) != NULL
&&
643 GetDisplayInfoData(displayinfo
, (APTR
)&dimensions
, sizeof(dimensions
), DTAG_DIMS
, modeid
)
645 && GetDisplayInfoData(displayinfo
, &monitor
, sizeof(monitor
), DTAG_MNTR
, modeid
)
650 screen
->Monitor
= monitor
.Mspc
;
652 screen
->MonitorObject
= (Object
*)dimensions
.reserved
[0];
653 screen
->SpecialFlags
= DoMethod(screen
->MonitorObject
, MM_GetCompositionFlags
, modeid
) << 8;
662 dclip
= &dimensions
.StdOScan
;
666 dclip
= &dimensions
.MaxOScan
;
670 dclip
= &dimensions
.VideoOScan
;
674 dclip
= &dimensions
.TxtOScan
;
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
;
702 if (IsCyberModeID(modeid
) && custombm
)
704 int pixfmt
= GetCyberIDAttr(CYBRIDATTR_PIXFMT
,modeid
);
706 if(GetCyberMapAttr(custombm
,CYBRMATTR_PIXFMT
) != pixfmt
)
708 // incompatible formats !
713 if (!(custombm
->Flags
& BMF_SPECIALFMT
) || (modeid
!= (ULONG
)custombm
->Planes
[7]))
719 screen
->Screen
.RastPort
.BitMap
= custombm
;
720 ns
.Depth
= GetBitMapAttr(ns
.CustomBitMap
,BMA_DEPTH
);
721 DEBUG_OPENSCREEN(dprintf("OpenScreen: CustomBitmap Depth %ld\n",
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
;
740 pixfmt
= PIXFMT_RGB15
;
743 pixfmt
= PIXFMT_RGB16
;
746 pixfmt
= PIXFMT_BGR24
;
749 pixfmt
= PIXFMT_ARGB32
;
752 pixfmt
= PIXFMT_LUT8
;
756 if (IsCyberModeID(modeid
))
758 pixfmt
= GetCyberIDAttr(CYBRIDATTR_PIXFMT
,modeid
);
762 allocbitmapflags
|= (BMF_SPECIALFMT
|BMF_CLEAR
);
764 screen
->Screen
.RastPort
.BitMap
= AllocBitMap(ns
.Width
,
767 allocbitmapflags
| (pixfmt
<< 24),
770 struct TagItem bmtags
[] = {
771 {BMATags_DisplayID
, modeid
},
775 screen
->Screen
.RastPort
.BitMap
= AllocBitMap(ns
.Width
,
778 allocbitmapflags
| BMF_CHECKVALUE
,
779 (struct BitMap
*)bmtags
);
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
));
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
));
808 (screen
->Screen
.RastPort
.BitMap
== NULL
) ||
809 (screen
->Screen
.ViewPort
.RasInfo
== NULL
))
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
;
825 /* Read depth from the bitmap to avoid AttachPalExtra/ObtainPen getting
826 * confused if cgx decided to allocate a higher depth bitmap than what
829 ns
.Depth
= GetBitMapAttr(screen
->Screen
.RastPort
.BitMap
,BMA_DEPTH
);
830 DEBUG_OPENSCREEN(bug("OpenScreen: Real bitmap depth is %u\n", ns
.Depth
));
835 else if (ns
.Depth
> 8)
838 numcolors
= 1L << ns
.Depth
;
841 /* Get a color map structure. Sufficient colors?? */
843 DEBUG_OPENSCREEN(dprintf("OpenScreen: Colormap Entries %ld\n",
846 if ((screen
->Screen
.ViewPort
.ColorMap
= GetColorMap(numcolors
)) != NULL
)
848 if (0 == AttachPalExtra(screen
->Screen
.ViewPort
.ColorMap
,
849 &screen
->Screen
.ViewPort
))
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",
881 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%lx\n",
882 screen
->Screen
.ViewPort
.ColorMap
));
886 screen
->ModeID
= modeid
;
891 struct ViewPortExtra
*vpe
= (struct ViewPortExtra
*)GfxNew(VIEWPORT_EXTRA_TYPE
);
893 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPortExtra 0x%lx\n", 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
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
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"));
957 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl failed\n"));
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
);
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);
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
1000 See pointerclass::New() for details. */
1001 #ifndef ALWAYS_ALLOCATE_SPRITE_COLORS
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
,
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);
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
,
1035 SetRGB4(&screen
->Screen
.ViewPort
,
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
;
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
;
1076 screen
->Screen
.WBorTop
= 2;
1077 screen
->Screen
.WBorLeft
= 4;
1078 screen
->Screen
.WBorRight
= 4;
1079 screen
->Screen
.WBorBottom
= 2;
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 */
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
);
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
},
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,
1118 DEBUG_OPENSCREEN(dprintf("OpenScreen: rootLayer 0x%lx\n",screen
->rootLayer
));
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
));
1149 /* Is handled below */
1150 DEBUG_OPENSCREEN(dprintf("OpenScreen: skip SysFont for now\n"));
1152 else if (sysfont
== 1)
1155 /* Use safe OpenFont here - Piru
1157 screen
->DInfo
.dri
.dri_Font
= SafeReopenFont(IntuitionBase
, &GetPrivIBase(IntuitionBase
)->ScreenFont
);
1159 #warning: Really hacky way of re-opening ScreenFont
1162 screen
->DInfo
.dri
.dri_Font
= GetPrivIBase(IntuitionBase
)->ScreenFont
;
1163 screen
->DInfo
.dri
.dri_Font
->tf_Accessors
++;
1167 screen
->SpecialFlags
|= SF_SysFont
;
1169 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set ScreenFont\n"));
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!! */
1184 /* Use safe OpenFont.. - Piru
1186 screen
->DInfo
.dri
.dri_Font
= SafeReopenFont(IntuitionBase
, &GfxBase
->DefaultFont
);
1189 #warning: Really hacky way of re-opening system default font
1192 screen
->DInfo
.dri
.dri_Font
= GfxBase
->DefaultFont
;
1193 screen
->DInfo
.dri
.dri_Font
->tf_Accessors
++;
1198 if (!screen
->DInfo
.dri
.dri_Font
) ok
= FALSE
;
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
,
1211 sizeof(screen
->Pens
));
1215 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set NewLook\n"));
1216 screen
->DInfo
.dri
.dri_Flags
|= DRIF_NEWLOOK
;
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
];
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;
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];
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
,
1293 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
,
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 */
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
,
1318 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
,
1323 PENF_EXCLUSIVE
| PENF_NO_SETCOLOR
);
1327 } /* if (!sharepens) */
1337 screen
->DInfo
.dri_Screen
= &screen
->Screen
; //useful sometimes ;)
1339 realdepth
= GetBitMapAttr( screen
->Screen
.RastPort
.BitMap
, BMA_DEPTH
);
1342 screen
->DInfo
.dri_Flags
|= DRIF_DIRECTCOLOR
;
1346 screen
->DInfo
.dri_Flags
&= ~DRIF_DIRECTCOLOR
;
1349 if (!(screen
->DInfo
.dri_Colors
= AllocMem(4 * DRIPEN_NUMDRIPENS
,MEMF_PUBLIC
)))
1354 CopyMem(&defaultdricolors
,screen
->DInfo
.dri_Colors
,sizeof (defaultdricolors
));
1355 memset(((UBYTE
*) screen
->DInfo
.dri_Colors
) + sizeof(defaultdricolors
), 0, 4 * DRIPEN_NUMDRIPENS
- sizeof(defaultdricolors
));
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
);
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
;
1388 screen
->Screen
.WBorTop
+= wcprefs
->titlebarincrement
;
1390 int_FreeCustomPrefs(TYPE_WINDOWCLASS
,&screen
->DInfo
,IntuitionBase
);
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);
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;
1428 screen
->ScrDecorObj
= nd
->nd_Screen
;
1429 screen
->WinDecorObj
= nd
->nd_Window
;
1430 screen
->MenuDecorObj
= nd
->nd_Menu
;
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
);
1448 screen
->DecorUserBufferSize
= userbuffersize
;
1449 screen
->DecorUserBuffer
= (IPTR
) AllocMem(userbuffersize
, MEMF_ANY
| MEMF_CLEAR
);
1450 if (!screen
->DecorUserBuffer
) ok
= FALSE
;
1456 struct TagItem sysi_tags
[] =
1458 {SYSIA_Which
, MENUCHECK
},
1459 {SYSIA_DrawInfo
, (IPTR
)&screen
->DInfo
},
1460 {SYSIA_UserBuffer
, screen
->DecorUserBuffer
},
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
));
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
;
1490 if (!screen
->DInfo
.dri
.dri_CheckMark
|| !screen
->DInfo
.dri
.dri_AmigaKey
|| !screen
->DInfo
.dri
.dri_SubMenuImage
) ok
= FALSE
;
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
;
1527 msg
.sdp_TitleHack
= screen
->Screen
.WBorTop
-2;
1529 msg
.sdp_TitleHack
= 0;
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
;
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
;
1553 #define SDEPTH_HEIGHT (screen->Screen.BarHeight + 1)
1557 #define IA_Screen (IA_Dummy + 0x1f) /* OS v44 includes!*/
1559 struct TagItem sdepth_tags
[] =
1563 #if SQUARE_WIN_GADGETS
1564 {GA_Width
, SDEPTH_HEIGHT
},
1566 {GA_Height
, SDEPTH_HEIGHT
},
1567 {GA_SysGadget
, TRUE
},
1568 {GA_SysGType
, GTYP_SDEPTH
},
1569 {GA_RelVerify
, TRUE
},
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
);
1605 struct TagItem gadtags
[] =
1612 GetAttr(GA_Width
, screen
->depthgadget
, &width
);
1614 gadtags
[0].ti_Data
= -width
+ 1;
1615 SetAttrsA(screen
->depthgadget
, gadtags
);
1621 if (im
) DisposeObject(im
);
1625 #if DEBUG_OpenScreen
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
]);
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
);
1644 int_CalcSkinInfo(&screen
->Screen
,IntuitionBase
);
1645 int_InitTitlebarBuffer(screen
,IntuitionBase
);
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"));
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
;
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
1682 struct OpenScreenActionMsg msg
;
1683 struct List
*list
= LockPubScreenList();
1685 msg
.Screen
= screen
;
1686 msg
.NewScreen
= &ns
;
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();
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
));
1710 ok
= MakeScreen(&screen
->Screen
) == 0;
1711 DEBUG_OPENSCREEN(dprintf("OpenScreen: MakeScreen %s\n", ok
? "ok" : "failed"));
1716 ok
= RethinkDisplay() == 0;
1717 DEBUG_OPENSCREEN(dprintf("OpenScreen: RethinkDisplay %s\n", ok
? "ok" : "failed"));
1723 FireMenuMessage(MMCODE_STARTCLOCK
,NULL
,NULL
,IntuitionBase
);
1727 #ifdef USEWINDOWLOCK
1728 if (windowlock
) ReleaseSemaphore(&GetPrivIBase(IntuitionBase
)->WindowLock
);
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
);
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
);
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
));
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
));
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
);
1823 static VOID
int_openscreen(struct OpenScreenActionMsg
*msg
,
1824 struct IntuitionBase
*IntuitionBase
)
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"));
1855 IntuitionBase
->ActiveScreen
= &screen
->Screen
;
1857 ptr
= &(*ptr
)->NextScreen
;
1858 *ptr
= &screen
->Screen
;
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
;
1883 D(bug("set active screen\n"));
1885 AddResourceToList(screen
, RESOURCE_SCREEN
, IntuitionBase
);