2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2013, The MorphOS Development Team. All Rights Reserved.
10 * Things added by AROS, which needs to be kept when merging with newer MorphOS releases:
12 * 1. Explicit library bases
13 * 2. FireScreenNotifyMessage() calls
14 * 3. AddResourceToList() call
15 * 4. Decoration calls (see intuition_customize.h)
16 * 5. Hardcoded initial color table is not used and removed.
17 * AmigaOS-compatible palette is used instead.
18 * 6. Other placed marked by 'AROS:' in comments.
19 * 7. Check #ifdef's. Some of them were rearranged or completely deleted.
20 * We reuse MorphOS skin code where appropriate.
23 #include <aros/config.h>
24 #include <exec/memory.h>
25 #include <utility/tagitem.h>
26 #include <intuition/screens.h>
27 #include <intuition/intuition.h>
28 #include <intuition/imageclass.h>
29 #include <intuition/gadgetclass.h>
30 #include <intuition/monitorclass.h>
31 #include <graphics/modeid.h>
32 #include <graphics/videocontrol.h>
33 #include <graphics/displayinfo.h>
34 #include <graphics/rpattr.h>
35 #include <prefs/screenmode.h>
36 #include <proto/input.h>
37 #include <proto/dos.h>
38 #include <proto/exec.h>
39 #include <proto/graphics.h>
40 #include <proto/layers.h>
41 #include <proto/utility.h>
42 #include <proto/intuition.h>
44 #include <proto/cybergraphics.h>
45 #include <cybergraphx/cybergraphics.h>
47 #include <hidd/graphics.h>
49 #include "intuition_intern.h"
50 #include "intuition_customize.h"
51 #include "intuition_extend.h"
52 #include "inputhandler.h"
53 #include "inputhandler_support.h"
54 #include "inputhandler_actions.h"
56 #include "monitorclass_intern.h"
57 #include "monitorclass_private.h"
59 // disabled as it causes compatibility issues
62 #ifndef DEBUG_OpenScreen
63 #define DEBUG_OpenScreen 0
69 #include <aros/debug.h>
71 struct OpenScreenActionMsg
73 struct IntuiActionMsg msg
;
74 struct IntScreen
*Screen
;
75 struct NewScreen
*NewScreen
;
80 VOID
int_openscreen(struct OpenScreenActionMsg
*msg
,struct IntuitionBase
*IntuitionBase
);
83 extern const ULONG defaultdricolors
[DRIPEN_NUMDRIPENS
];
88 static const char THIS_FILE
[] = __FILE__
;
91 /*****************************************************************************
94 AROS_LH1(struct Screen
*, OpenScreen
,
97 AROS_LHA(struct NewScreen
*, newScreen
, A0
),
100 struct IntuitionBase
*, IntuitionBase
, 33, Intuition
)
117 The function relies on private data being passed in
118 DimensionInfo.reserved[0] by graphics.library/GetDisplayInfoData().
119 Keep this in sync when modifying the code.
121 *****************************************************************************/
125 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
126 struct LayersBase
*LayersBase
= GetPrivIBase(IntuitionBase
)->LayersBase
;
127 struct Library
*UtilityBase
= GetPrivIBase(IntuitionBase
)->UtilityBase
;
129 struct TagItem
*tag
, *tagList
;
130 struct IntScreen
*screen
;
132 struct Hook
*layer_info_hook
= NULL
;
133 struct ColorSpec
*colors
= NULL
;
134 ULONG
*errorPtr
; /* Store error at user specified location */
135 UWORD
*customdripens
= NULL
;
136 ULONG
*colors32
= NULL
;
138 BOOL ok
= TRUE
, rp_inited
= FALSE
, li_inited
= FALSE
, sharepens
= FALSE
;
140 BOOL windowlock
= FALSE
;
141 BOOL dowindowlock
= TRUE
;
143 struct Rectangle
*dclip
= NULL
;
144 LONG overscan
= OSCAN_TEXT
;
145 DisplayInfoHandle displayinfo
= NULL
;
146 struct DisplayInfo dispinfo
;
147 struct DimensionInfo dimensions
;
149 struct MonitorInfo monitor
;
151 ULONG allocbitmapflags
= BMF_DISPLAYABLE
;
154 ULONG vesafallback
= 0;
155 ULONG
*modecontrol
= 0;
156 BOOL compositing
= FALSE
;
159 char *monitorname
= 0;
160 BOOL exactname
= FALSE
;
161 BOOL showpointer
= TRUE
;
162 BOOL gammacontrol
= FALSE
;
163 UBYTE
*gammared
= NULL
, *gammablue
= NULL
, *gammagreen
= NULL
;
164 BOOL support3d
= FALSE
;
165 BOOL adaptsize
= FALSE
;
166 ULONG displaywidth
= 0;
167 ULONG displayheight
= 0;
171 BOOL workbench
= FALSE
;
172 ULONG requesteddepth
= 1;
173 BOOL draggable
= TRUE
;
174 ULONG compflags
= COMPF_ABOVE
; // Default to AmigaOS like behaviour.
175 struct Hook
*compalphahook
= NULL
;
177 struct TagItem modetags
[] =
179 { BIDTAG_Depth
, 0UL },
180 { BIDTAG_DesiredWidth
, 0UL },
181 { BIDTAG_DesiredHeight
, 0UL },
182 { BIDTAG_NominalWidth
, 0UL },
183 { BIDTAG_NominalHeight
, 0UL },
184 { BIDTAG_DIPFMustHave
, 0UL },
188 ULONG modeid
= INVALID_ID
;
190 ASSERT_VALID_PTR_ROMOK(newScreen
);
193 #define COPY(x) screen->Screen.x = ns.x
194 #define SetError(x) if (errorPtr != NULL) *errorPtr = x;
196 D(bug("OpenScreen (%p = { Left=%d Top=%d Width=%d Height=%d Depth=%d })\n"
198 , newScreen
->LeftEdge
205 FireScreenNotifyMessage((IPTR
) newScreen
, SNOTIFY_BEFORE_OPENSCREEN
, IntuitionBase
);
208 if (newScreen
->Type
& NS_EXTENDED
)
210 tagList
= ((struct ExtNewScreen
*)newScreen
)->Extension
;
215 DEBUG_OPENSCREEN(dprintf("OpenScreen: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
216 ns
.LeftEdge
, ns
.TopEdge
, ns
.Width
, ns
.Height
, ns
.Depth
, tagList
));
221 struct Library
*lib
= ComplainOpenLibrary(COMPLAIN_CYBERGFX
,FALSE
,IntuitionBase
);
236 FireScreenNotifyMessage(0, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
242 struct Library
*lib
= ComplainOpenLibrary(COMPLAIN_LOCALE
,FALSE
,IntuitionBase
);
248 OpenintuitionCatalog(IntuitionBase
);
259 struct Library
*lib
= ComplainOpenLibrary(COMPLAIN_CGXSYSTEM
,FALSE
,IntuitionBase
);
274 screen
= NewObjectA(IBase
->screenclass
,0,0);
276 DEBUG_OPENSCREEN(dprintf("OpenScreen: screen 0x%lx\n", screen
));
278 /* Do this really early to be able to report errors */
279 errorPtr
= (ULONG
*)GetTagData((Tag
)SA_ErrorCode
, (IPTR
)NULL
, (struct TagItem
*)tagList
);
281 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ErrorCode 0x%lx\n",errorPtr
));
285 SetError(OSERR_NOMEM
);
291 char *pubname
= NULL
;
293 modeid
= GetTagData(SA_DisplayID
,INVALID_ID
, tagList
);
296 * AROS: MorphOS private tag temporarily disabled. Used by OpenWorkbench().
297 * Information from MorphOS intuition.notes file:
299 * Added SA_OpenWorkbench to fix the OpenScreen handling for this special case, fixes
300 * the problem with autoscroll promoting to a bigger res than the one selected in prefs
302 * CHECKME: May be we also need this ?
304 workbench
= GetTagData(SA_OpenWorkbench
,FALSE
,tagList
);
312 DEBUG_OPENSCREEN(dprintf("OpenScreen: modeid from taglist: %lx\n",modeid
));
314 if (GetTagData(SA_LikeWorkbench
, FALSE
, tagList
))
316 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_LikeWorkbench\n"));
320 * AROS: Use oldstyle ScreenModePrefs structure.
321 * CHECKME: Can we merge better ?
323 ns
.Width
= GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Width
;
324 ns
.Height
= GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Height
;
325 ns
.Depth
= GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Depth
;
326 modeid
= GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_DisplayID
;
328 if (GetPrivIBase(IntuitionBase
)->ScreenModePrefs
.smp_Control
& SMF_AUTOSCROLL
)
330 /* need to mark autoscroll */
331 ns
.Type
|= AUTOSCROLL
;
334 ns
.Width
= IBase
->AmbientScreenMode
.DisplayWidth
;
335 ns
.Height
= IBase
->AmbientScreenMode
.DisplayHeight
;
336 ns
.Depth
= IBase
->AmbientScreenMode
.DisplayDepth
;
337 if (IBase
->AmbientScreenMode
.AutoScroll
) ns
.Type
|= AUTOSCROLL
;
338 displaywidth
= IBase
->AmbientScreenMode
.ModeWidth
;
339 displayheight
= IBase
->AmbientScreenMode
.ModeHeight
;
341 /* jDc: do NOT copy modeid of wb as that will not allow overloading depth param properly */
343 /* unless it's OpenWorkbench! */
347 modeid
= INVALID_ID
; // we'll use the stored ID only in the worst case!
348 compositing
= IBase
->AmbientScreenMode
.Compositing
;
351 /* let's try to limit the new screen to the same monitor ambient would use */
352 /* but only if modeid is a weak one */
353 if ((modeid
== INVALID_ID
) || (ModeNotAvailable(modeid
)) || !FindDisplayInfo(modeid
))
355 if (IBase
->AmbientScreenMode
.ModeMonitor
[0])
357 monitorname
= IBase
->AmbientScreenMode
.ModeMonitor
;
361 struct IMonitorNode
*node
= FindMonitorNode(IBase
->AmbientScreenMode
.ModeID
,IntuitionBase
);
365 monitorname
= node
->MonitorName
;
372 sharepens
= TRUE
; /* not sure */
375 if ((pubname
= (char*)GetTagData(SA_PubName
, 0, tagList
)))
377 /* Name of this public screen. */
378 struct PubScreenNode
*oldpsn
;
381 list
= LockPubScreenList();
383 if ((strcmp(pubname
, "Workbench") == 0) || workbench
)
385 if (IBase
->WorkBench
)
394 /* jDc: LockPubScreen is not safe here as it does not lock
395 screens in private state so we could end up with two
396 screens with the same name */
397 oldpsn
= (struct PubScreenNode
*)FindName(list
,(UBYTE
*)pubname
);
401 SetError(OSERR_PUBNOTUNIQUE
);
406 UnlockPubScreenList();
410 screen
->pubScrNode
= AllocMem(sizeof(struct PubScreenNode
), MEMF_CLEAR
);
412 DEBUG_OPENSCREEN(dprintf("OpenScreen: pubScrNode 0x%lx\n",screen
->pubScrNode
));
414 if (screen
->pubScrNode
== NULL
)
416 SetError(OSERR_NOMEM
);
420 if (ok
&& (screen
->pubScrNode
->psn_Node
.ln_Name
= AllocVec(MAXPUBSCREENNAME
+ 1,MEMF_ANY
)))
424 if ((ns
.Type
& SCREENTYPE
) == CUSTOMSCREEN
)
426 ns
.Type
&= ~SCREENTYPE
;
427 ns
.Type
|= PUBLICSCREEN
;
430 /* Always open public screens in private mode. */
431 screen
->pubScrNode
->psn_Flags
|= PSNF_PRIVATE
;
432 strcpy(screen
->pubScrNode
->psn_Node
.ln_Name
, pubname
);
434 /* Task that should be signalled when the public screen loses
435 its last visitor window. */
437 screen
->pubScrNode
->psn_SigTask
= (struct Task
*)GetTagData(SA_PubTask
, 0, tagList
);
439 /* Signal bit number to use when signalling public screen
442 sigbit
= GetTagData(SA_PubSig
,(ULONG
)-1,tagList
);
444 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubSig 0x%lx\n",sigbit
));
446 if (sigbit
!= (UBYTE
)-1)
448 if (!screen
->pubScrNode
->psn_SigTask
) screen
->pubScrNode
->psn_SigTask
= FindTask(NULL
);
449 screen
->pubScrNode
->psn_SigBit
= sigbit
;
453 /* do not signal with -1 ! */
454 screen
->pubScrNode
->psn_SigTask
= NULL
;
459 SetError(OSERR_NOMEM
);
460 FreeMem(screen
->pubScrNode
, sizeof(struct PubScreenNode
));
461 screen
->pubScrNode
= NULL
;
469 if (modeid
!= INVALID_ID
)
471 /* modes can be on other monitors */
476 while((tag
= NextTagItem ((struct TagItem
**)&tagList
)))
479 DEBUG_OPENSCREEN(dprintf("OpenScreen: Tag 0x%08lx Data 0x%08lx\n",
480 tag
->ti_Tag
, tag
->ti_Data
));
484 case SA_CompositingFlags
:
485 compflags
= tag
->ti_Data
;
486 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_CompositingFlags 0x%p\n", compflags
));
488 case SA_AlphaPreCompositingHook
:
489 compalphahook
= (struct Hook
*)tag
->ti_Data
;
490 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AlphaPreCompositingHook 0x%p\n", compalphahook
));
493 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Left %ld\n",tag
->ti_Data
));
494 ns
.LeftEdge
= tag
->ti_Data
;
497 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Top %ld\n",tag
->ti_Data
));
498 ns
.TopEdge
= tag
->ti_Data
;
501 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Width %ld\n",tag
->ti_Data
));
502 if ((tag
->ti_Data
!= ~0) && (tag
->ti_Data
> 32767))
506 ns
.Width
= tag
->ti_Data
;
509 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Height %ld\n",tag
->ti_Data
));
510 if ((tag
->ti_Data
!= ~0) && (tag
->ti_Data
> 32767))
514 ns
.Height
= tag
->ti_Data
;
517 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Depth %ld\n",tag
->ti_Data
));
518 ns
.Depth
= tag
->ti_Data
;
521 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DetailPen %ld\n",tag
->ti_Data
));
522 ns
.DetailPen
= tag
->ti_Data
;
525 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BlockPen %ld\n",tag
->ti_Data
));
526 ns
.BlockPen
= tag
->ti_Data
;
529 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Type 0x%lx\n",tag
->ti_Data
));
530 ns
.Type
&= ~SCREENTYPE
;
531 ns
.Type
|= tag
->ti_Data
;
535 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Title <%s>\n",tag
->ti_Data
));
536 ns
.DefaultTitle
= (UBYTE
*)tag
->ti_Data
;
540 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Font 0x%lx\n",tag
->ti_Data
));
541 ns
.Font
= (struct TextAttr
*)tag
->ti_Data
;
545 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors32 0x%lx\n",tag
->ti_Data
));
546 colors32
= (ULONG
*)tag
->ti_Data
;
550 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors 0x%lx\n",tag
->ti_Data
));
551 colors
= (struct ColorSpec
*)tag
->ti_Data
;
555 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SysFont 0x%lx\n",tag
->ti_Data
));
556 sysfont
= (WORD
)tag
->ti_Data
;
560 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap 0x%lx\n",tag
->ti_Data
));
563 ns
.Type
|= CUSTOMBITMAP
;
564 ns
.CustomBitMap
= (struct BitMap
*)tag
->ti_Data
;
568 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap==NULL specified, custom BitMap use disabled\n"));
573 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackFill Hook 0x%lx\n",tag
->ti_Data
));
574 layer_info_hook
= (struct Hook
*)tag
->ti_Data
;
578 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Quiet 0x%lx\n",tag
->ti_Data
));
581 ns
.Type
|= SCREENQUIET
;
585 ns
.Type
&= ~SCREENQUIET
;
590 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ShowTitle 0x%lx\n",tag
->ti_Data
));
593 ns
.Type
|= SHOWTITLE
;
597 ns
.Type
&= ~SHOWTITLE
;
602 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Pens 0x%lx\n",tag
->ti_Data
));
603 customdripens
= (UWORD
*)tag
->ti_Data
;
607 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SharePens 0x%lx\n",tag
->ti_Data
));
608 sharepens
= tag
->ti_Data
? TRUE
: FALSE
;
611 ns
.Type
|= PENSHARED
;
613 ns
.Type
&= ~PENSHARED
;
618 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Interleaved 0x%lx\n",tag
->ti_Data
));
621 allocbitmapflags
|= BMF_INTERLEAVED
;
625 allocbitmapflags
&= ~BMF_INTERLEAVED
;
630 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Behind 0x%lx\n",tag
->ti_Data
));
633 ns
.Type
|= SCREENBEHIND
;
637 ns
.Type
&= ~SCREENBEHIND
;
642 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DClip 0x%lx\n",tag
->ti_Data
));
643 dclip
= (struct Rectangle
*)tag
->ti_Data
;
647 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_OverScan 0x%lx\n",tag
->ti_Data
));
648 overscan
= tag
->ti_Data
;
652 case SA_LikeWorkbench
:
663 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AutoScroll 0x%lx\n",tag
->ti_Data
));
666 ns
.Type
|= AUTOSCROLL
;
670 ns
.Type
&= ~AUTOSCROLL
;
675 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FullPalette 0x%lx\n",tag
->ti_Data
));
677 case SA_ColorMapEntries
:
678 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ColorMapEntries 0x%lx\n",tag
->ti_Data
));
679 numcolors
= tag
->ti_Data
; /* AROS: Added support for this tag */
682 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Parent 0x%lx\n",tag
->ti_Data
));
685 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Draggable 0x%lx\n",tag
->ti_Data
));
686 draggable
= tag
->ti_Data
; /* AROS: Added support for this tag */
689 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Exclusive 0x%lx\n",tag
->ti_Data
));
691 case SA_VideoControl
:
692 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_VideoControl 0x%lx\n",tag
->ti_Data
));
693 vctl
= tag
->ti_Data
; /* AROS: Added support for this tag */
696 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FrontChild 0x%lx\n",tag
->ti_Data
));
699 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackChild 0x%lx\n",tag
->ti_Data
));
702 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_MinimizeISG 0x%lx\n",tag
->ti_Data
));
706 monitorname
= (char*)tag
->ti_Data
;
708 #ifndef __AROS__ /* AROS: Disable MorphOS-specific extensions and private stuff */
709 case SA_SkinName
: /* TODO: Complete support for named skins and enable this tag. Value needed. */
710 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SkinName (%s)\n",(char *)tag
->ti_Data
));
711 skinname
= (char *)tag
->ti_Data
;
714 case SA_VesaFallback
:
715 vesafallback
= tag
->ti_Data
;
718 case SA_ModeEditControl
:
719 modecontrol
= (ULONG
*)tag
->ti_Data
;
722 case SA_WindowLock
: /* TODO: We also can support this private tag. In which situations we don't need locking ? */
723 dowindowlock
= tag
->ti_Data
? TRUE
: FALSE
;
726 case SA_CompositingLayers
:
727 compositing
= tag
->ti_Data
? TRUE
: FALSE
;
731 showpointer
= tag
->ti_Data
? TRUE
: FALSE
;
734 case SA_GammaControl
:
735 gammacontrol
= tag
->ti_Data
? TRUE
: FALSE
;
739 gammared
= (UBYTE
*)tag
->ti_Data
;
743 gammablue
= (UBYTE
*)tag
->ti_Data
;
747 gammagreen
= (UBYTE
*)tag
->ti_Data
;
751 support3d
= tag
->ti_Data
? TRUE
: FALSE
;
755 adaptsize
= tag
->ti_Data
? TRUE
: FALSE
;
758 case SA_DisplayWidth
:
759 displaywidth
= (ULONG
)tag
->ti_Data
;
762 case SA_DisplayHeight
:
763 displayheight
= (ULONG
)tag
->ti_Data
;
766 case SA_ExactMatchMonitorName
:
767 exactname
= tag
->ti_Data
? TRUE
: FALSE
;
770 /* TODO: Missing SA_ Tags */
772 DEBUG_OPENSCREEN(dprintf("OpenScreen: unknown tag 0x%lx data 0x%lx\n",
777 } /* switch (tag->ti_Tag) */
779 } /* while ((tag = NextTagItem (&tagList))) */
783 DEBUG_OPENSCREEN(dprintf("OpenScreen: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
784 ns
.LeftEdge
, ns
.TopEdge
, ns
.Width
, ns
.Height
, ns
.Depth
, tagList
));
786 requesteddepth
= ns
.Depth
;
788 /* Fail if bogus size is requested - Piru/jDc */
789 if ((ns
.Width
< -1) || (ns
.Height
< -1))
791 DEBUG_OPENSCREEN(dprintf("!!! OpenScreen(): Width and/or Height negative !!!\n");)
795 /* First Init the RastPort then get the BitPlanes!! */
798 #include "workaround.openscreen.c"
800 /* AROS: Use 3D support code */
803 struct IMonitorNode
*node
= NULL
;
804 ULONG depth
= (ULONG
)-1;
807 /*AROS: We don't need these flags because we keep ModeID together with the BitMap */
808 screen
->Support3D
= TRUE
;
809 allocbitmapflags
|= BMF_3DTARGET
;
811 /* check for SA_DisplayID or SA_MonitorName, this can also return other monitor
812 within the same class of monitors (ex radeon7k instead of 9k) */
813 if (monitorname
|| (modeid
!= INVALID_ID
))
815 DEBUG_OPENSCREEN(dprintf("OpenScreen: 3d hunt modeid 0x%lx monname %s\n",modeid
,monitorname
? monitorname
: "none"));
816 node
= FindBestMonitorNode(NULL
,monitorname
,modeid
,IntuitionBase
);
817 if (node
) depth
= FindBest3dDepth(ns
.Depth
,node
,IntuitionBase
);
820 /* no suitable depth? find a monitor with best 3d capabilities */
821 if ((depth
== (ULONG
)-1) && !exactname
)
823 DEBUG_OPENSCREEN(dprintf("OpenScreen: found no suitable depth. monnode 0x%lx\n",node
));
824 node
= FindBest3dMonitor(NULL
,IntuitionBase
);
825 if (node
) depth
= FindBest3dDepth(ns
.Depth
,node
,IntuitionBase
);
828 /* found a usable depth? find a modeid with that depth within the monitor we found */
829 if (depth
!= (ULONG
)-1)
831 DEBUG_OPENSCREEN(dprintf("OpenScreen: found suitable depth %d. monnode 0x%lx\n",depth
,node
));
834 modeid
= FindBestModeID(node
->MonitorName
,ns
.Depth
,(displaywidth
) ? displaywidth
: ns
.Width
,(displayheight
) ? displayheight
: ns
.Height
,IntuitionBase
);
836 if (modeid
== INVALID_ID
)
838 DEBUG_OPENSCREEN(dprintf("OpenScreen: no 3d available, fail (1)!\n"));
842 /* whoops, no 3d support at all, fail! */
843 DEBUG_OPENSCREEN(dprintf("OpenScreen: no 3d available, fail! (2)\n"));
848 else if (monitorname
)
850 ULONG newmodeid
= INVALID_ID
;
851 newmodeid
= FindBestModeID(monitorname
,ns
.Depth
,(displaywidth
) ? displaywidth
: ns
.Width
,(displayheight
) ? displayheight
: ns
.Height
,IntuitionBase
);
852 if (newmodeid
!= INVALID_ID
) modeid
= newmodeid
;
853 /* monitor not available and exactmatch requested ? */
856 if (newmodeid
== INVALID_ID
)
858 dprintf("uhuh, no modeid!\n");
863 // make sure this is the same monitor!
864 struct IMonitorNode
*node
= FindMonitorNode(newmodeid
,IntuitionBase
);
865 if (!node
|| strcmp(node
->MonitorName
,monitorname
)) ok
= FALSE
;
868 DEBUG_OPENSCREEN(dprintf("OpenScreen: monname %s modeid %lx\n",monitorname
,modeid
));
872 /* Note: CGX patched ModeNotAvailable() alone doesn't return reliable results due to some fallback code for old apps. - Piru */
873 if ((modeid
== INVALID_ID
) || ModeNotAvailable(modeid
) || !FindDisplayInfo(modeid
))
875 struct TagItem bestmodetags
[] =
878 {CYBRBIDTG_NominalWidth
,0},
879 {CYBRBIDTG_NominalHeight
,0},
883 if((modeid
& 0xF00F0000) == 0x40020000)
885 modeid
&= 0x40020000;
888 bestmodetags
[0].ti_Data
= (ns
.Depth
< 8) ? 8 : ns
.Depth
; /* jDc: helps finding a correct mode ;)*/
889 bestmodetags
[1].ti_Data
= (displaywidth
) ? displaywidth
: ns
.Width
;
890 bestmodetags
[2].ti_Data
= (displayheight
) ? displayheight
: ns
.Height
;
892 DEBUG_OPENSCREEN(dprintf("ns.Width %ld ns.Height %ld ns.Depth %ld !!\n",
893 (LONG
) ns
.Width
, (LONG
) ns
.Height
, (LONG
) ns
.Depth
);)
895 modeid
= BestCModeIDTagList(bestmodetags
);
897 DEBUG_OPENSCREEN(dprintf("BestCModeIDTagList returned %ld\n",modeid
);)
902 if ((workbench
) && (IBase
->EmergencyBoot
.monitorname
))
904 struct IMonitorNode
*node
;
908 node
= FindBestMonitorNode(GetMonitorClass(IBase
->EmergencyBoot
.monitorname
,IntuitionBase
),IBase
->EmergencyBoot
.monitorname
,INVALID_ID
,IntuitionBase
);
910 newmodeid
= FakeWorkbenchMode(node
,(ULONG
*)&depthid
,IBase
->EmergencyBoot
.baseresolution
,IntuitionBase
);
912 DEBUG_OPENSCREEN(dprintf("OpenScreen: Emergency Boot! %lx\n",modeid
));
914 if (newmodeid
!= INVALID_ID
)
917 ns
.Width
= IBase
->EmergencyBoot
.baseresolution
;
934 screen
->VESAMode
= ns
.Width
;
935 screen
->VESAModeDepthID
= depthid
;
939 if (workbench
&& (((struct IIHData
*)IBase
->InputHandler
->is_Data
)->ActQualifier
& IEQUALIFIER_CONTROL
))
946 struct IMonitorNode
*node
= NULL
;
950 if (monitorname
) node
= FindBestMonitorNode(GetMonitorClass(monitorname
,IntuitionBase
),monitorname
,INVALID_ID
,IntuitionBase
);
952 newmodeid
= FakeWorkbenchMode(node
,(ULONG
*)&depthid
,vesafallback
,IntuitionBase
);
954 DEBUG_OPENSCREEN(dprintf("OpenScreen: vesa fallback %lx\n",modeid
));
956 if (newmodeid
!= INVALID_ID
)
959 ns
.Width
= vesafallback
;
976 screen
->VESAMode
= ns
.Width
;
977 screen
->VESAModeDepthID
= depthid
;
983 struct IMonitorNode
*inode
= FindMonitorNode(modeid
,IntuitionBase
);
984 modeid
= FakeScreenMode(inode
,ns
.Depth
,IntuitionBase
);
986 DEBUG_OPENSCREEN(dprintf("OpenScreen: fake modeid %lx\n",modeid
));
988 if (modeid
!= INVALID_ID
)
992 case 24: screen
->VESAModeDepthID
= ID_MD24
; break;
993 case 16: screen
->VESAModeDepthID
= ID_MD16
; break;
994 case 15: screen
->VESAModeDepthID
= ID_MD15
; break;
995 default: screen
->VESAModeDepthID
= ID_MD08
; break;
998 screen
->ModeControl
= modecontrol
;
1001 DEBUG_OPENSCREEN(dprintf("OpenScreen: failed to init testmode!\n"));
1009 * AROS: Got OpenScreenTags modeid without monitor, promote to chipset default
1011 * We really need proper mode promotion support.
1013 if ((modeid
& MONITOR_ID_MASK
) == 0)
1015 if (GfxBase
->DisplayFlags
& PAL
)
1016 modeid
|= PAL_MONITOR_ID
;
1017 else if (GfxBase
->DisplayFlags
& NTSC
)
1018 modeid
|= NTSC_MONITOR_ID
;
1021 if (INVALID_ID
== modeid
)
1024 WORD bestwidth
,bestheight
;
1026 modetags
[0].ti_Data
= ns
.Depth
;
1027 modetags
[1].ti_Data
= ns
.Width
;
1028 modetags
[2].ti_Data
= ns
.Height
;
1029 modetags
[3].ti_Data
= ns
.Width
;
1030 modetags
[4].ti_Data
= ns
.Height
;
1034 * AROS: We don't have FindBestWidthAndHeight().
1035 * TODO: Can we merge better here ?
1037 if (ns
.Width
== STDSCREENWIDTH
|| ns
.Width
== 0 || adaptsize
) {modetags
[1].ti_Tag
= TAG_IGNORE
; modetags
[3].ti_Tag
= TAG_IGNORE
;}
1038 if (ns
.Height
== STDSCREENWIDTH
|| ns
.Height
== 0 || adaptsize
) {modetags
[2].ti_Tag
= TAG_IGNORE
; modetags
[4].ti_Tag
= TAG_IGNORE
;}
1040 FindBestWidthAndHeight(&bestwidth
,&bestheight
,ns
.Depth
,IntuitionBase
);
1042 if (ns
.Width
== STDSCREENWIDTH
|| ns
.Width
== 0 || adaptsize
) {modetags
[1].ti_Data
= bestwidth
; modetags
[3].ti_Data
= bestwidth
;}
1043 if (ns
.Height
== STDSCREENWIDTH
|| ns
.Height
== 0 || adaptsize
) {modetags
[2].ti_Data
= bestheight
;modetags
[4].ti_Data
= bestheight
;}
1045 DEBUG_OPENSCREEN(dprintf("Attempt BestModeIDA(). Calculated best width %d height %d. Request: %d/%d.\n",bestwidth
,bestheight
,modetags
[1].ti_Data
,modetags
[2].ti_Data
));
1047 /* AROS: Support old-style HAM or EHB request */
1048 if (newScreen
->ViewModes
& (HAM
| EXTRA_HALFBRITE
))
1050 if (newScreen
->ViewModes
& HAM
) modetags
[5].ti_Data
|= DIPF_IS_HAM
;
1051 if (newScreen
->ViewModes
& EXTRA_HALFBRITE
) modetags
[5].ti_Data
|= DIPF_IS_EXTRAHALFBRITE
;
1055 modetags
[5].ti_Tag
= TAG_IGNORE
;
1058 modeid
= BestModeIDA(modetags
);
1061 if (modeid
== INVALID_ID
&& workbench
)
1064 ULONG newmodeid
= FakeWorkbenchMode(NULL
,(ULONG
*)&depthid
,640,IntuitionBase
);
1067 DEBUG_OPENSCREEN(dprintf("OpenScreen: Vesa Fallback!\n"));
1069 if (newmodeid
!= INVALID_ID
)
1075 screen
->VESAMode
= 640;
1076 screen
->VESAModeDepthID
= depthid
;
1081 if (INVALID_ID
== modeid
)
1083 // wtf? no monitors??
1084 D(bug("!!! OpenScreen(): Could not find any valid modeids. No graphics card? !!!\n"));
1085 SetError(OSERR_UNKNOWNMODE
); /* AROS: Added error core setting, fixed MorphOS bug */
1090 DEBUG_OPENSCREEN(dprintf("OpenScreen: ModeID 0x%08lx\n", modeid
));
1092 InitRastPort(&screen
->Screen
.RastPort
);
1096 if (ok
&& (displayinfo
= FindDisplayInfo(modeid
)) != NULL
&&
1097 GetDisplayInfoData(displayinfo
, (APTR
)&dimensions
, sizeof(dimensions
), DTAG_DIMS
, modeid
)
1098 #ifdef __AROS__ /* AROS: We don't need MonitorSpec, however we get DisplayInfo early to get the compositors bm hooks. */
1099 && GetDisplayInfoData(displayinfo
, (APTR
)&dispinfo
, sizeof(dispinfo
), DTAG_DISP
, modeid
)
1101 && GetDisplayInfoData(displayinfo
, (APTR
)&monitor
, sizeof(monitor
), DTAG_MNTR
, modeid
)
1106 #ifdef __AROS__ /* AROS: Get HIDD composition flags */
1107 screen
->SpecialFlags
= ((compflags
& (dimensions
.reserved
[0] >> 16)) | (dimensions
.reserved
[0] & 0xFFFF)) << 8;
1108 screen
->preAlphaCompHook
= compalphahook
;
1110 if (draggable
) screen
->SpecialFlags
|= SF_Draggable
;
1112 screen
->Monitor
= monitor
.Mspc
;
1118 case OSCAN_STANDARD
:
1119 dclip
= &dimensions
.StdOScan
;
1123 dclip
= &dimensions
.MaxOScan
;
1127 dclip
= &dimensions
.VideoOScan
;
1131 dclip
= &dimensions
.TxtOScan
;
1136 if (ns
.Width
== STDSCREENWIDTH
|| ns
.Width
== 0 || adaptsize
)
1137 ns
.Width
= dclip
->MaxX
- dclip
->MinX
+ 1;
1138 /* AROS: Added raster size limit support */
1139 else if (ns
.Width
< dimensions
.MinRasterWidth
)
1140 ns
.Width
= dimensions
.MinRasterWidth
;
1141 else if (ns
.Width
> dimensions
.MaxRasterWidth
)
1142 ns
.Width
= dimensions
.MaxRasterWidth
;
1144 if (ns
.Height
== STDSCREENHEIGHT
|| ns
.Height
== 0 || adaptsize
)
1145 ns
.Height
= dclip
->MaxY
- dclip
->MinY
+ 1;
1146 /* AROS: Added raster size limit support */
1147 else if (ns
.Height
< dimensions
.MinRasterHeight
)
1148 ns
.Height
= dimensions
.MinRasterHeight
;
1149 else if (ns
.Height
> dimensions
.MaxRasterHeight
)
1150 ns
.Height
= dimensions
.MaxRasterHeight
;
1153 DEBUG_OPENSCREEN(dprintf("OpenScreen: Monitor 0x%lx Width %ld Height %ld\n",
1154 screen
->Monitor
, ns
.Width
, ns
.Height
));
1157 if (ns
.Type
& CUSTOMBITMAP
)
1159 struct BitMap
*custombm
;
1160 custombm
= ns
.CustomBitMap
;
1161 #ifdef __AROS__ /* AROS: We don't have CGX in kickstart */
1162 /* FIXME: m68k Compositor needs to report that it can composit planar bitmaps */
1163 BOOL (*__IsCompositable
) (struct BitMap
*, DisplayInfoHandle
, struct GfxBase
*) = (APTR
)dispinfo
.reserved
[0];
1164 BOOL (*__MakeDisplayable
) (struct BitMap
*, DisplayInfoHandle
, struct GfxBase
*) = (APTR
)dispinfo
.reserved
[1];
1166 if (dispinfo
.reserved
[0])
1168 if (__IsCompositable(custombm
, displayinfo
, GfxBase
))
1170 DEBUG_OPENSCREEN(dprintf("OpenScreen: Marking CustomBitMap 0x%lx as compositable\n", custombm
));
1171 __MakeDisplayable(custombm
, displayinfo
, GfxBase
);
1178 else if ((!IS_HIDD_BM(custombm
)) || (modeid
!= HIDD_BM_HIDDMODE(custombm
)))
1183 if (IsCyberModeID(modeid
) && custombm
)
1185 int pixfmt
= GetCyberIDAttr(CYBRIDATTR_PIXFMT
,modeid
);
1187 if(GetCyberMapAttr(custombm
,CYBRMATTR_PIXFMT
) != pixfmt
)
1189 // incompatible formats !
1194 if(custombm
!= NULL
)
1196 screen
->Screen
.RastPort
.BitMap
= custombm
;
1197 ns
.Depth
= GetBitMapAttr(ns
.CustomBitMap
,BMA_DEPTH
);
1198 DEBUG_OPENSCREEN(dprintf("OpenScreen: CustomBitMap Depth %ld\n",
1201 ns
.CustomBitMap
= NULL
;
1202 ns
.Type
&= ~CUSTOMBITMAP
;
1205 screen
->Screen
.RastPort
.BitMap
= NULL
;
1208 if ((screen
->IMonitorNode
= FindMonitorNode(modeid
,IntuitionBase
)))
1210 DEBUG_OPENSCREEN(dprintf("OpenScreen: MonitorNode 0x%lx\n",
1211 screen
->IMonitorNode
));
1213 DEBUG_OPENSCREEN(dprintf("OpenScreen: No MonitorNode\n"));
1217 if(ok
&& (screen
->Screen
.RastPort
.BitMap
== NULL
))
1219 #ifdef __AROS__ /* AROS: BitMap needs ModeID */
1220 ULONG Depth
= (dimensions
.MaxDepth
> 8) ? dimensions
.MaxDepth
: ns
.Depth
;
1221 struct TagItem bmtags
[] =
1223 {BMATags_DisplayID
, modeid
},
1227 screen
->Screen
.RastPort
.BitMap
= AllocBitMap(ns
.Width
, ns
.Height
, Depth
,
1228 allocbitmapflags
| BMF_CHECKVALUE
,
1229 (struct BitMap
*)bmtags
);
1231 struct BitMap
*root
= NULL
;
1235 ULONG stdwidth
= dimensions
.Nominal
.MaxX
- dimensions
.Nominal
.MinX
+ 1;
1236 ULONG stdheight
= dimensions
.Nominal
.MaxY
- dimensions
.Nominal
.MinY
+ 1;
1239 Depth
= (dimensions
.MaxDepth
> 8) ? dimensions
.MaxDepth
: 8;
1241 Depth
= (dimensions
.MaxDepth
> 8) ? dimensions
.MaxDepth
: ns
.Depth
;
1247 pixfmt
= PIXFMT_RGB15
;
1250 pixfmt
= PIXFMT_RGB16
;
1253 pixfmt
= PIXFMT_BGR24
;
1256 pixfmt
= PIXFMT_ARGB32
;
1259 pixfmt
= PIXFMT_LUT8
;
1263 if (IsCyberModeID(modeid
))
1265 pixfmt
= GetCyberIDAttr(CYBRIDATTR_PIXFMT
,modeid
);
1268 DoMethod((Object
*)screen
->IMonitorNode
,MM_GetRootBitMap
,pixfmt
,(ULONG
)&root
);
1270 DEBUG_OPENSCREEN(dprintf("OpenScreen: root BitMap 0x%lx\n",root
));
1274 allocbitmapflags
&= (BMF_DISPLAYABLE
| BMF_INTERLEAVED
| BMF_3DTARGET
);
1278 allocbitmapflags
|= (BMF_SPECIALFMT
|/*BMF_CLEAR|*/BMF_DISPLAYABLE
|BMF_MINPLANES
);
1279 allocbitmapflags
|= SHIFT_PIXFMT(pixfmt
);
1283 allocbitmapflags
|= (/*BMF_CLEAR|*/BMF_DISPLAYABLE
|BMF_MINPLANES
);
1286 if((screen
->Screen
.RastPort
.BitMap
= AllocBitMap((ns
.Width
> stdwidth
) ? ns
.Width
: stdwidth
,
1287 (ns
.Height
> stdheight
) ? ns
.Height
: stdheight
,
1295 while((screen
->Screen
.RastPort
.BitMap
== NULL
) && (retrycnt
--));
1297 screen
->AllocatedBitMap
= screen
->Screen
.RastPort
.BitMap
;
1299 DEBUG_OPENSCREEN(dprintf("OpenScreen: allocated BitMap 0x%lx\n",screen
->AllocatedBitMap
));
1301 if (screen
->Screen
.RastPort
.BitMap
)
1303 UpdateScreenBitMap(&screen
->Screen
, IntuitionBase
);
1306 * AROS: This seems to be not needed
1307 * TODO: Check if this is really true, test case needed
1311 if (stdwidth
> ns
.Width
)
1313 struct RastPort rport
;
1315 InitRastPort(&rport
);
1316 rport
.BitMap
= screen
->AllocatedBitMap
;
1317 SetRPAttrs(&rport
,RPTAG_PenMode
,FALSE
,RPTAG_FgColor
,0x0,TAG_DONE
);
1319 RectFill(&rport
,ns
.Width
,0,stdwidth
- 1,ns
.Height
- 1);
1322 if (stdheight
> ns
.Height
)
1324 struct RastPort rport
;
1326 InitRastPort(&rport
);
1327 rport
.BitMap
= screen
->AllocatedBitMap
;
1328 SetRPAttrs(&rport
,RPTAG_PenMode
,FALSE
,RPTAG_FgColor
,0x0,TAG_DONE
);
1330 RectFill(&rport
,0,ns
.Height
,ns
.Width
- 1,stdheight
- 1);
1337 DEBUG_OPENSCREEN(dprintf("OpenScreen: BitMap 0x%lx\n",
1338 screen
->Screen
.RastPort
.BitMap
));
1342 DEBUG_OPENSCREEN(dprintf("OpenScreen: no displayinfo\n"));
1343 SetError(OSERR_UNKNOWNMODE
); /* AROS: Added error code setting, fixed MorphOS bug */
1346 D(bug("got BitMap\n"));
1348 /* Init screen's viewport */
1349 InitVPort(&screen
->Screen
.ViewPort
);
1351 /* Allocate a RasInfo struct in which we have a pointer
1352 to the struct BitMap, into which the driver can
1353 store its stuff. (Eg. pointer to a BitMap HIDD object)
1355 screen
->Screen
.ViewPort
.RasInfo
= AllocMem(sizeof(struct RasInfo
), MEMF_ANY
| MEMF_CLEAR
);
1357 DEBUG_OPENSCREEN(dprintf("OpenScreen: RasInfo 0x%lx\n",
1358 screen
->Screen
.ViewPort
.RasInfo
));
1361 (screen
->Screen
.RastPort
.BitMap
== NULL
) ||
1362 (screen
->Screen
.ViewPort
.RasInfo
== NULL
))
1366 /* Store pointer to BitMap, so we can get hold of it
1367 from withing LoadRGBxx() functions
1369 D(bug("got allocated stuff\n"));
1370 screen
->Screen
.ViewPort
.RasInfo
->BitMap
= screen
->Screen
.RastPort
.BitMap
;
1375 /* Read depth from the BitMap to avoid AttachPalExtra/ObtainPen getting
1376 * confused if cgx decided to allocate a higher depth BitMap than what
1379 ns
.Depth
= GetBitMapAttr(screen
->Screen
.RastPort
.BitMap
,BMA_DEPTH
);
1381 if (!numcolors
) /* AROS: Added support for SA_ColorMapEntries */
1386 numcolors
= (ns
.Depth
<= 8) ? (1L << ns
.Depth
) : 256;
1390 /* Get a color map structure. Sufficient colors?? */
1392 DEBUG_OPENSCREEN(dprintf("OpenScreen: Colormap Entries %ld\n",
1394 if ((screen
->Screen
.ViewPort
.ColorMap
= GetColorMap(numcolors
< 32 ? 32 : numcolors
)) != NULL
)
1396 if (0 == AttachPalExtra(screen
->Screen
.ViewPort
.ColorMap
,
1397 &screen
->Screen
.ViewPort
))
1404 refcnt
=(UWORD
*) screen
->Screen
.ViewPort
.ColorMap
->PalExtra
->pe_RefCnt
;
1405 alloclist
= (UBYTE
*)(refcnt
+ screen
->Screen
.ViewPort
.ColorMap
->Count
);
1407 DEBUG_OPENSCREEN(dprintf("OpenScreen: PalExtra alloclist 0x%lx Count %ld\n",alloclist
,screen
->Screen
.ViewPort
.ColorMap
->Count
));
1409 while(i
< screen
->Screen
.ViewPort
.ColorMap
->Count
)
1411 // initialize alloc list to -1,0,1,2,3,4
1413 DEBUG_OPENSCREEN(dprintf("OpenScreen: alloclist[%ld]=%ld\n",
1429 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%lx\n",
1430 screen
->Screen
.ViewPort
.ColorMap
));
1437 APTR handle
= LockBitMapTags(screen
->Screen
.RastPort
.BitMap
,
1438 LBMI_PIXFMT
,(ULONG
)&pixfmt
,TAG_DONE
);
1442 UnLockBitMap(handle
);
1443 screen
->PixelFormat
= pixfmt
;
1447 screen
->PixelFormat
= -1;
1451 screen
->GammaControl
.UseGammaControl
= gammacontrol
;
1452 screen
->GammaControl
.GammaTableR
= gammared
;
1453 screen
->GammaControl
.GammaTableG
= gammagreen
;
1454 screen
->GammaControl
.GammaTableB
= gammablue
;
1457 * AROS: This fragment seems to delay-load default gamma table for the monitor.
1458 * TODO: May be use this approach ?
1460 if (screen
->IMonitorNode
&& !screen
->IMonitorNode
->GammaLoaded
)
1462 int_SkinAction(SKA_LoadGamma
,(ULONG
*)screen
->IMonitorNode
,NULL
,IntuitionBase
);
1463 screen
->IMonitorNode
->GammaLoaded
= TRUE
;
1466 // no hotkey by default
1467 screen
->RecallHotkey
.ia_Key
= 0xFF;
1469 screen
->ModeID
= modeid
;
1473 struct ViewPortExtra
*vpe
= (struct ViewPortExtra
*)GfxNew(VIEWPORT_EXTRA_TYPE
);
1475 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPortExtra 0x%lx\n", vpe
));
1481 struct TagItem tags
[6];
1483 memcpy(&vpe
->DisplayClip
, dclip
,sizeof(struct Rectangle
));
1486 * AROS: Set ViewPort offset and get size from dclip.
1487 * CHECKME: MorphOS source code always sets ViewPort's DWidth and DHeight to
1488 * nominal size, while ViewPortExtra's DisplayClip is still set to OverScan
1489 * rectangle. Whose approach is correct ?
1491 screen
->Screen
.ViewPort
.DxOffset
= ns
.LeftEdge
;
1492 screen
->Screen
.ViewPort
.DyOffset
= ns
.TopEdge
;
1493 screen
->Screen
.ViewPort
.DWidth
= dclip
->MaxX
- dclip
->MinX
+ 1;
1494 screen
->Screen
.ViewPort
.DHeight
= dclip
->MaxY
- dclip
->MinY
+ 1;
1496 /* using vpe data for vesamode/modecontrol is not a good idea since the mode
1497 is changed on the fly and the actual data might not be what we'll use */
1499 if (screen
->VESAMode
)
1501 screen
->Screen
.ViewPort
.DWidth
= screen
->VESAMode
;
1503 switch (screen
->VESAMode
)
1506 screen
->Screen
.ViewPort
.DHeight
= 600;
1510 screen
->Screen
.ViewPort
.DHeight
= 768;
1514 screen
->Screen
.ViewPort
.DWidth
= 640;
1515 screen
->Screen
.ViewPort
.DHeight
= 480;
1518 screen
->VESAMode
= ns
.Width
;
1519 } else if (screen
->ModeControl
) {
1520 screen
->Screen
.ViewPort
.DWidth
= ns
.Width
;
1521 screen
->Screen
.ViewPort
.DHeight
= ns
.Height
;
1523 ULONG stdwidth
= dimensions
.Nominal
.MaxX
- dimensions
.Nominal
.MinX
+ 1;
1524 ULONG stdheight
= dimensions
.Nominal
.MaxY
- dimensions
.Nominal
.MinY
+ 1;
1526 screen
->Screen
.ViewPort
.DWidth
= min(ns
.Width
,stdwidth
);
1527 screen
->Screen
.ViewPort
.DHeight
= min(ns
.Height
,stdheight
);
1530 tags
[0].ti_Tag
= VTAG_ATTACH_CM_SET
;
1531 tags
[0].ti_Data
= (IPTR
)&screen
->Screen
.ViewPort
;
1532 tags
[1].ti_Tag
= VTAG_VIEWPORTEXTRA_SET
;
1533 tags
[1].ti_Data
= (IPTR
)vpe
;
1534 tags
[2].ti_Tag
= VTAG_NORMAL_DISP_SET
;
1535 tags
[2].ti_Data
= (IPTR
)displayinfo
;
1536 tags
[3].ti_Tag
= VTAG_VPMODEID_SET
;
1537 tags
[3].ti_Data
= modeid
;
1538 tags
[4].ti_Tag
= VTAG_SPEVEN_BASE_SET
; /* AROS: Added sprite base and user-supplied tags */
1539 tags
[5].ti_Tag
= VTAG_NEXTBUF_CM
; /* if vctl is 0, this will terminate the list */
1540 tags
[5].ti_Data
= vctl
;
1543 * Originally we could always use palette entries 16-19 for
1544 * sprites, even if the screen has less than 32 colors. AROS may
1545 * run on hardware that does not allow this (e.g. VGA cards).
1546 * In this case we have to shift down sprite colors. Currently
1547 * we use 4 colors before last 4 colors. For example on VGA cards
1548 * with only 16 colors we use colors 9 - 12. Remember that last 4 colors
1549 * of the screen are always used by Intuition.
1550 * Remember that the first color of the sprite is always transparent. So actually
1551 * we use 3, not 4 colors.
1552 * Yes, sprites may look not as expected on screens with low color depth, but at
1553 * least they will be seen. It's better than nothing.
1555 * Note that because our base color number doesn't always divide by 16, we use MSB to store
1556 * the remainder (offset in the color bank). Yes, it's a bit hacky, but i have no better idea
1559 * FIXME: this mapping scheme assumes that we always have at least 16 colors.
1560 * For current display modes supported by AROS it's always true, but in future
1561 * we may support more display modes (for example monochrome ones), and we
1562 * should take into account that on screens with less than 11 colors this simply
1565 * TODO: I think we should have SpriteBase attribute for the BitMap which
1566 * defaults to acceptable value. We should just get its default value here.
1567 * The same attribute would be set by VideoControl() and MakeVPort() in order
1568 * to actually apply the value.
1570 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
1573 spritebase
= (ns
.Depth
< 5) ? (1 << ns
.Depth
) - 8 : 16;
1575 DEBUG_OPENSCREEN(bug("OpenScreen: spritebase is %u\n", spritebase
));
1576 tags
[4].ti_Data
= ((spritebase
& 0x0F) << 8 ) | (spritebase
>> 4);
1578 if (VideoControl(screen
->Screen
.ViewPort
.ColorMap
, tags
) == 0)
1580 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl ok\n"));
1585 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl failed\n"));
1596 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set first 4 colors\n"));
1599 for (k
= 0; k
< 4 && k
< numcolors
; ++k
)
1601 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB32 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1602 screen
->Screen
.ViewPort
,
1603 k
, p
[k
].red
, p
[k
].green
, p
[k
].blue
));
1604 SetRGB32(&screen
->Screen
.ViewPort
, k
, p
[k
].red
, p
[k
].green
, p
[k
].blue
);
1610 * AROS: Use screen depth instead of 'numcolors' in order to calculate
1611 * numbers of last 4 colors of the screen.
1612 * This is necessary because we can have 8- or 16- color screen whose
1613 * ColorMap will still have 32 colors for AmigaOS(tm) compatibility
1616 ULONG lastcol
= ((ns
.Depth
> 8) ? 256 : (1 << ns
.Depth
)) - 4;
1618 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set last 4 colors\n"));
1620 for (k
= 0; k
< 4; ++k
)
1622 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB32 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1623 screen
->Screen
.ViewPort
,
1624 k
+ lastcol
, p
[k
+4].red
, p
[k
+4].green
, p
[k
+4].blue
));
1626 if (k
+ lastcol
< numcolors
)
1628 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
,
1637 SetRGB32(&screen
->Screen
.ViewPort
, k
+ lastcol
, p
[k
+4].red
, p
[k
+4].green
, p
[k
+4].blue
);
1643 * AROS: AmigaOS(tm) 3.1-compatible mouse colors handling
1644 * 1. Allocate pens for the mouse pointer only on LUT screens.
1645 * On hi- and truecolor screens sprite colors come from colormap attached
1646 * to the sprite BitMap itself. See pointerclass::New() for details.
1647 * 2. Use 32-bit pointer colors instead of KS1.3 ActivePreferences->color17
1651 DEBUG_OPENSCREEN(dprintf("OpenScreen: Obtain Mousepointer colors\n"));
1653 for (k
= 1; k
< 4; ++k
, ++q
)
1655 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%P Pen %d R 0x%08X G 0x08X B 0x%08X\n",
1656 screen
->Screen
.ViewPort
.ColorMap
,
1658 p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
));
1659 if (k
+ spritebase
< numcolors
)
1661 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
,
1663 p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
,
1668 /* Can't be allocated, but can still be set. */
1669 SetRGB32(&screen
->Screen
.ViewPort
,
1671 p
[k
+7].red
, p
[k
+7].green
, p
[k
+7].blue
);
1676 if (colors
) /* if SA_Colors tag exists */
1678 DEBUG_OPENSCREEN(dprintf("OpenScreen: set SA_Colors 0x%lx\n",colors
));
1679 for(; colors
->ColorIndex
!= (WORD
)~0; colors
++)
1681 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB4 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1682 screen
->Screen
.ViewPort
,
1687 SetRGB4(&screen
->Screen
.ViewPort
,
1695 if (colors32
) /* if SA_Colors32 tag exists */
1697 DEBUG_OPENSCREEN(dprintf("OpenScreen: LoadRGB32 colors32 0x%lx\n",colors32
));
1698 LoadRGB32(&screen
->Screen
.ViewPort
, (const ULONG
*)colors32
);
1701 D(bug("Loaded colors\n"));
1712 //intui68k filters this
1713 screen
->Screen
.Flags
= (ns
.Type
& ~NS_EXTENDED
);
1715 /* Temporary hack */
1716 if (ns
.Width
>= 500 || ns
.Height
>= 300)
1717 screen
->Screen
.Flags
|= SCREENHIRES
;
1720 Copy the data from the rastport's BitMap
1721 to the screen's BitMap structure
1723 UpdateScreenBitMap(&screen
->Screen
, IntuitionBase
);
1726 screen
->Screen
.WBorTop
= 2;
1727 screen
->Screen
.WBorLeft
= 4;
1728 screen
->Screen
.WBorRight
= 4;
1729 screen
->Screen
.WBorBottom
= 2;
1731 screen
->Screen
.WBorTop
= 6; /* Amiga default is 2 */
1732 screen
->Screen
.WBorLeft
= 4;
1733 screen
->Screen
.WBorRight
= 4;
1734 screen
->Screen
.WBorBottom
= 4; /* Amiga default is 2 */
1737 screen
->Screen
.Title
= ns
.DefaultTitle
;
1739 DEBUG_OPENSCREEN(dprintf("OpenScreen: init layers\n"));
1740 #ifdef __AROS__ /* AROS: We have no compositing layers */
1741 InitLayers(&screen
->Screen
.LayerInfo
);
1743 if (((struct Library
*)LayersBase
)->lib_Version
>= 52 && compositing
&&
1744 screen
->IMonitorNode
->Compositing
)
1746 struct TagItem layerinfotags
[] =
1748 {SA_Width
,screen
->Screen
.Width
},
1749 {SA_Height
,screen
->Screen
.Height
},
1750 {SA_PixelFormat
,screen
->PixelFormat
},
1751 {MA_MemorySize
,screen
->IMonitorNode
->BoardMemory
},
1752 {LT_IgnoreMemoryChecks
, IBase
->LayerSettings
.IgnoreMemoryChecks
},
1753 {SA_CompositingLayers
, TRUE
},
1756 ULONG iscompositing
= FALSE
;
1758 // make SA_CompositingLayers return TRUE (layers will ask)
1759 screen
->Compositing
= TRUE
;
1760 InitScreenLayerInfo(&screen
->Screen
,layerinfotags
);
1762 // validate if we're compositing
1763 LayersControlTags(&screen
->Screen
.LayerInfo
,
1764 LT_GetCompositing
,(ULONG
)&iscompositing
,
1766 // also set current layers settings
1767 LT_AllowDoubleBuffered
, IBase
->LayerSettings
.AllowDoubleBuffered
,
1768 LT_AllowTripleBuffered
, IBase
->LayerSettings
.AllowTripleBuffered
,
1769 LT_IgnoreMemoryChecks
, IBase
->LayerSettings
.IgnoreMemoryChecks
,
1770 LT_LoadBalancing
, IBase
->LayerSettings
.LoadBalancing
,
1774 screen
->Compositing
= iscompositing
? TRUE
: FALSE
;
1778 struct TagItem layerinfotags
[] =
1780 {SA_CompositingLayers
, FALSE
},
1783 screen
->Compositing
= FALSE
;
1784 InitScreenLayerInfo(&screen
->Screen
,layerinfotags
);
1789 if (NULL
!= layer_info_hook
)
1791 DEBUG_OPENSCREEN(dprintf("OpenScreen: instal layerinfohook\n"));
1792 InstallLayerInfoHook(&screen
->Screen
.LayerInfo
, layer_info_hook
);
1794 D(bug("layers intited screen\n"));
1796 /* AROS: We have already obtained resolution data from DisplayInfo */
1798 screen
->DInfo
.dri_Version
= DRI_VERSION
;
1800 GetDisplayInfoData(NULL
, (APTR
)&dispinfo
, sizeof(dispinfo
), DTAG_DISP
, modeid
);
1801 screen
->DInfo
.dri_Version
= MOS_DRI_VERSION
;
1803 screen
->DInfo
.dri_NumPens
= NUMDRIPENS
;
1804 screen
->DInfo
.dri_Pens
= screen
->Pens
;
1805 /* dri_Depth is 8 on hi/true color screens like in AmigaOS with picasso96/cybergraphx */
1806 screen
->DInfo
.dri_Depth
= (ns
.Depth
<= 8) ? ns
.Depth
: 8;
1807 /* AROS: Get resolution from DisplayInfo */
1808 screen
->DInfo
.dri_Resolution
.X
= dispinfo
.Resolution
.x
;
1809 screen
->DInfo
.dri_Resolution
.Y
= dispinfo
.Resolution
.y
;
1810 screen
->DInfo
.dri_Flags
= 0;
1813 /* SA_SysFont overrides SA_Font! */
1815 DEBUG_OPENSCREEN(dprintf("OpenScreen: SysFont = %d, ns.Font = %p\n", sysfont
, ns
.Font
));
1819 /* Is handled below */
1820 DEBUG_OPENSCREEN(dprintf("OpenScreen: skip SysFont for now\n"));
1821 } else if (sysfont
== 1) {
1823 screen
->DInfo
.dri_Font
= SafeReopenFont(IntuitionBase
, &IBase
->ScreenFont
);
1825 if (screen
->DInfo
.dri_Font
)
1827 screen
->SysFont
= TRUE
;
1829 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set ScreenFont\n"));
1831 } else if (ns
.Font
) {
1832 screen
->DInfo
.dri_Font
= OpenFont(ns
.Font
);
1833 DEBUG_OPENSCREEN(dprintf("OpenScreen: custom font 0x%lx\n",screen
->DInfo
.dri_Font
));
1836 if (!screen
->DInfo
.dri_Font
)
1838 /* GfxBase->DefaultFont is *not* always topaz 8. It
1839 can be set with the Font prefs program!! */
1841 screen
->DInfo
.dri_Font
= SafeReopenFont(IntuitionBase
, &GfxBase
->DefaultFont
);
1844 if (!screen
->DInfo
.dri_Font
) ok
= FALSE
;
1850 ULONG
*dripens
= NULL
;
1855 dripens
= (ULONG
*)&IBase
->DriPens2
;
1859 dripens
= (ULONG
*)&IBase
->DriPens4
;
1863 if (colors
|| colors32
)
1865 /* jDc: apps are used to use non-std colors for pen # >=4
1866 dripens4 will be a good fallback for this */
1867 dripens
= (ULONG
*)&IBase
->DriPens4
;
1869 dripens
= (ULONG
*)&IBase
->DriPens8
;
1874 /* set default values for pens */
1875 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Default Pens\n"));
1876 CopyMem(dripens
,screen
->Pens
,sizeof(screen
->Pens
));
1880 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set NewLook\n"));
1881 screen
->DInfo
.dri_Flags
|= DRIF_NEWLOOK
;
1888 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Custom Pens\n"));
1889 screen
->Pens
[DETAILPEN
] = screen
->Screen
.DetailPen
;
1890 screen
->Pens
[BLOCKPEN
] = screen
->Screen
.BlockPen
;
1892 for(i
= 0; (i
< NUMDRIPENS
) && (customdripens
[i
] != (UWORD
)~0) && (screen
->Pens
[i
] != (UWORD
)~0); i
++)
1894 DEBUG_OPENSCREEN(dprintf("OpenScreen: Pen[%ld] %ld --> %ld\n",i
,screen
->Pens
[i
],customdripens
[i
]));
1895 screen
->Pens
[i
] = customdripens
[i
];
1900 * Let's do some broken software validation of the pens
1901 * so we may not run into a black desktop.
1904 DEBUG_OPENSCREEN(dprintf("OpenScreen: Check Default Pens if the make sense\n"));
1905 if (screen
->Screen
.DetailPen
== screen
->Screen
.BlockPen
)
1907 DEBUG_OPENSCREEN(dprintf("OpenScreen: DetailPen==BlockPen..correct\n"));
1908 screen
->Screen
.DetailPen
= 0;
1909 screen
->Screen
.BlockPen
= 1;
1910 } else if (screen
->Screen
.BlockPen
== 0)
1912 DEBUG_OPENSCREEN(dprintf("OpenScreen: BlockPen==0..correct\n"));
1913 screen
->Screen
.BlockPen
= screen
->Screen
.DetailPen
;
1914 screen
->Screen
.DetailPen
= 0;
1917 screen
->Pens
[DETAILPEN
] = screen
->Screen
.DetailPen
;
1918 screen
->Pens
[BLOCKPEN
] = screen
->Screen
.BlockPen
;
1920 /* Allocate shared/exclusive colors */
1923 BYTE color_alloced
[256];
1927 /*for(i = 0; i < 256; i++)
1929 color_alloced[i] = FALSE;
1931 memclr(&color_alloced
,256);
1933 /* Mouse pointer colors */
1935 color_alloced
[17] = TRUE
;
1936 color_alloced
[18] = TRUE
;
1937 color_alloced
[19] = TRUE
;
1939 /* Clamp the pen numbers. This makes sure that values such as -4 or -3
1940 won't result in random memory trashing, but rather index colours from
1941 the end of the shareable palette. - Piru */
1942 mask
= screen
->Screen
.ViewPort
.ColorMap
->PalExtra
->pe_SharableColors
& 0xff;
1944 /* The Pens in the DrawInfo must be allocated as shared */
1946 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen DrawInfo Pens as shared\n"));
1947 for(i
= 0; (i
< NUMDRIPENS
) && (screen
->Pens
[i
] != (UWORD
)~0); i
++)
1949 int pen
= screen
->Pens
[i
] & mask
;
1950 if (!color_alloced
[pen
])
1952 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1953 screen
->Screen
.ViewPort
.ColorMap
,
1956 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
,
1962 color_alloced
[pen
] = TRUE
;
1965 DEBUG_OPENSCREEN(dprintf("OpenScreen: done\n"));
1967 /* If SA_SharePens is FALSE then allocate the rest of the colors
1968 in the colormap as exclusive */
1972 ULONG shnumcolors
= (requesteddepth
<= 8) ? (1L << requesteddepth
) : 256;
1974 /* jDc: hack, colors above requested screen depth are not locked! */
1976 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen the remaining Pens as exclusive\n"));
1977 for(i
= 0; i
< shnumcolors
; i
++)
1979 if (!color_alloced
[i
])
1981 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1982 screen
->Screen
.ViewPort
.ColorMap
,
1984 ObtainPen(screen
->Screen
.ViewPort
.ColorMap
,
1989 PENF_EXCLUSIVE
| PENF_NO_SETCOLOR
);
1993 } /* if (!sharepens) */
2000 screen
->DInfo
.dri_Screen
= &screen
->Screen
; //useful sometimes ;)
2002 screen
->realdepth
= GetBitMapAttr( screen
->Screen
.RastPort
.BitMap
, BMA_DEPTH
);
2004 if (screen
->realdepth
> 8)
2006 screen
->DInfo
.dri_Flags
|= DRIF_DIRECTCOLOR
;
2008 screen
->DInfo
.dri_Flags
&= ~DRIF_DIRECTCOLOR
;
2012 if (!(screen
->DInfo
.dri_Colors
= AllocMem(4 * DRIPEN_NUMDRIPENS
,MEMF_PUBLIC
)))
2017 CopyMem(&defaultdricolors
,screen
->DInfo
.dri_Colors
,sizeof (defaultdricolors
));
2018 memset(((UBYTE
*) screen
->DInfo
.dri_Colors
) + sizeof(defaultdricolors
), 0, 4 * DRIPEN_NUMDRIPENS
- sizeof(defaultdricolors
));
2024 DEBUG_OPENSCREEN(dprintf("OpenScreen: allocating dri_Customize\n"));
2026 if ((screen
->DInfo
.dri_Customize
= AllocMem(sizeof (struct IntuitionCustomize
),MEMF_PUBLIC
|MEMF_CLEAR
)))
2029 struct IntuitionCustomize
*ic
;
2030 ic
= screen
->DInfo
.dri_Customize
;
2031 screen
->DInfo
.dri_Flags
|= DRIF_SKINSSUPPORT
;
2033 /* This initializes CustomizePrefs structure */
2035 if (skinname
) strcpy(ic
->skinname
,skinname
);
2037 InitSemaphore(&ic
->InitLock
);
2039 DEBUG_OPENSCREEN(dprintf("OpenScreen: load skin %s for screen %lx\n",ic
->skinname
,screen
));
2040 int_SkinAction(SKA_LoadSkin
,(ULONG
*)&screen
->DInfo
,(struct Screen
*)screen
,IntuitionBase
);
2042 /* AROS: Use less error-prone skinname handling */
2043 ok
= int_LoadDecorator(skinname
, screen
, IntuitionBase
);
2056 struct windowclassprefs
*wcprefs
;
2057 wcprefs
= (struct windowclassprefs
*)int_GetCustomPrefs(TYPE_WINDOWCLASS
,&screen
->DInfo
,IntuitionBase
);
2058 if (wcprefs
->flags
& WINDOWCLASS_PREFS_1TO1FRAMES
)
2060 screen
->Screen
.WBorLeft
= screen
->Screen
.WBorTop
;
2061 screen
->Screen
.WBorRight
= screen
->Screen
.WBorTop
;
2062 screen
->Screen
.WBorBottom
= screen
->Screen
.WBorTop
;
2064 screen
->Screen
.WBorTop
+= wcprefs
->titlebarincrement
;
2065 int_FreeCustomPrefs(TYPE_WINDOWCLASS
,&screen
->DInfo
,IntuitionBase
);
2072 struct TagItem sysi_tags
[] =
2074 {SYSIA_Which
, MENUCHECK
},
2075 {SYSIA_DrawInfo
, (IPTR
)&screen
->DInfo
},
2079 screen
->DInfo
.dri_CheckMark
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
2080 DEBUG_OPENSCREEN(dprintf("OpenScreen: CheckMark 0x%lx\n",
2081 screen
->DInfo
.dri_CheckMark
));
2083 sysi_tags
[0].ti_Data
= AMIGAKEY
;
2085 screen
->DInfo
.dri_AmigaKey
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
2086 DEBUG_OPENSCREEN(dprintf("OpenScreen: AmigaKey 0x%lx\n",
2087 screen
->DInfo
.dri_AmigaKey
));
2089 /* AROS: We also use submenu image */
2090 sysi_tags
[0].ti_Data
= SUBMENUIMAGE
;
2091 screen
->DInfo
.dri_Customize
->submenu
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
2092 if (!screen
->DInfo
.dri_Customize
->submenu
) ok
=FALSE
;
2094 sysi_tags
[0].ti_Data
= MENUTOGGLEIMAGE
;
2095 screen
->DInfo
.dri_Customize
->menutoggle
= NewObjectA(NULL
, "sysiclass", sysi_tags
);
2096 if (!screen
->DInfo
.dri_Customize
->menutoggle
) ok
= FALSE
;
2099 if (!screen
->DInfo
.dri_CheckMark
|| !screen
->DInfo
.dri_AmigaKey
) ok
= FALSE
;
2104 SetFont(&screen
->Screen
.RastPort
, screen
->DInfo
.dri_Font
);
2106 AskFont(&screen
->Screen
.RastPort
, (struct TextAttr
*) &screen
->textattr
);
2108 screen
->Screen
.Font
= (struct TextAttr
*) &screen
->textattr
;
2110 DEBUG_OPENSCREEN(dprintf("OpenScreen: Font %s/%d\n",
2111 screen
->textattr
.tta_Name
, screen
->textattr
.tta_YSize
));
2113 screen
->Screen
.BarVBorder
= 1;
2114 screen
->Screen
.BarHBorder
= 5;
2115 screen
->Screen
.MenuVBorder
= 2;
2116 screen
->Screen
.MenuHBorder
= 4;
2118 screen
->Screen
.BarHeight
= screen
->DInfo
.dri_Font
->tf_YSize
+ screen
->Screen
.WBorTop
-2 +
2119 screen
->Screen
.BarVBorder
* 2; /* real layer will be 1 pixel higher! */
2122 * AROS: Get size information from decorator.
2123 * This has to be done before we create gadgets because here we may adjust BarHeight.
2125 ok
= int_InitDecorator(&screen
->Screen
);
2128 #define SDEPTH_HEIGHT (screen->Screen.BarHeight + 1)
2132 #define IA_Screen (IA_Dummy + 0x1f) /* OS v44 includes!*/
2134 struct TagItem sdepth_tags
[] =
2138 {GA_Height
, SDEPTH_HEIGHT
},
2139 {GA_SysGadget
, TRUE
},
2140 {GA_SysGType
, GTYP_SDEPTH
},
2141 {GA_RelVerify
, TRUE
},
2145 struct TagItem image_tags
[] =
2148 //{IA_Width , SDEPTH_WIDTH + 1 },
2149 {IA_Height
, SDEPTH_HEIGHT
},
2150 {SYSIA_Which
, SDEPTHIMAGE
},
2151 {SYSIA_DrawInfo
, (IPTR
)&screen
->DInfo
},
2152 {SYSIA_Size
, screen
->Screen
.Flags
& SCREENHIRES
?
2153 SYSISIZE_MEDRES
: SYSISIZE_LOWRES
},
2157 struct Object
*im
= 0;
2159 if (!(screen
->Screen
.Flags
& SCREENQUIET
))
2161 im
= NewObjectA(NULL
, SYSICLASS
, image_tags
);
2164 sdepth_tags
[0].ti_Data
= (IPTR
)im
;
2166 screen
->depthgadget
= NewObjectA(IBase
->windowsysiclass
, NULL
, sdepth_tags
);
2168 DEBUG_OPENSCREEN(dprintf("OpenScreen: DepthGadget 0x%lx\n",
2169 screen
->depthgadget
));
2171 screen
->Screen
.FirstGadget
= (struct Gadget
*)screen
->depthgadget
;
2172 if (screen
->Screen
.FirstGadget
)
2174 struct TagItem gadtags
[] =
2179 IPTR width
; /* AROS: Changed from int to IPTR, 64-bit fix */
2181 GetAttr(GA_Width
, screen
->depthgadget
, &width
);
2183 gadtags
[0].ti_Data
= -width
+ 1;
2184 SetAttrsA(screen
->depthgadget
, gadtags
);
2185 screen
->Screen
.FirstGadget
->GadgetType
|= GTYP_SCRGADGET
;
2187 if (im
) DisposeObject(im
);
2193 for (i
=0;i
<=screen
->DInfo
.dri_NumPens
;i
++)
2195 DEBUG_OPENSCREEN(dprintf("OpenScreen: dri_Pen[%ld] = %ld\n",i
,screen
->DInfo
.dri_Pens
[i
]));
2200 #ifdef USEWINDOWLOCK
2201 /* let's wait for user to finish window drag/size actions to avoid
2202 deadlocks and not break user's input */
2203 if (dowindowlock
&& (!(FindTask(NULL
) == ((struct IIHData
*)IBase
->InputHandler
->is_Data
)->InputDeviceTask
)))
2207 screen
->WindowLock
= TRUE
;
2211 int_CalcSkinInfo(&screen
->Screen
,IntuitionBase
);
2213 int_InitTitlebarBuffer(&screen
->Screen
,IntuitionBase
);
2215 D(bug("calling SetRast()\n"));
2217 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set background color Pen %ld\n",screen
->Pens
[BACKGROUNDPEN
]));
2218 /* Set screen to background color */
2219 SetRast(&screen
->Screen
.RastPort
, screen
->Pens
[BACKGROUNDPEN
]);
2221 D(bug("SetRast() called\n"));
2223 DEBUG_OPENSCREEN(dprintf("OpenScreen: Creating screen bar\n"));
2229 if (IBase
->IControlPrefs
.ic_Flags
& (ICF_DISAPPEARINGTITLEBAR
| ICF_NOWBTITLEBAR
)) screen
->SpecialFlags
|= SF_AppearingBar
;
2231 if (IBase
->IControlPrefs
.ic_Flags
& ICF_NOWBTITLEBAR
) screen
->SpecialFlags
|= SF_InvisibleBar
;
2232 if (IBase
->IControlPrefs
.ic_Flags
& ICF_DISAPPEARINGTITLEBAR
) screen
->SpecialFlags
|= SF_AppearingBar
;
2237 //jDc: ALL screens MUST have BarLayer!
2238 CreateScreenBar(&screen
->Screen
, IntuitionBase
);
2240 if (!screen
->Screen
.BarLayer
) ok
= FALSE
;
2245 if ((ns
.Type
& SCREENTYPE
) == CUSTOMSCREEN
)
2247 screen
->ShowPointer
= showpointer
;
2249 screen
->ShowPointer
= TRUE
;
2252 GetAttr(POINTERA_SharedPointer
, screen
->IMonitorNode
->Pointers
[POINTERTYPE_INVISIBLE
], (IPTR
*)&screen
->Pointer
);
2254 GetAttr(POINTERA_SharedPointer
, IBase
->DefaultPointer
, (IPTR
*)&screen
->Pointer
);
2256 ObtainSharedPointer(screen
->Pointer
, IntuitionBase
);
2257 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sprite DefaultPtr 0x%lx\n",&screen
->Pointer
));
2261 ** jDc: better modify the screen list in sync with inputhandler, this for example allows us to scan the list
2262 ** without any locks when we are on input.device context
2266 struct PubScreenNode
*ps
= NULL
;
2267 struct List
*list
= LockPubScreenList();
2269 /* Additional dupe check, just to be sure */
2270 if (!workbench
&& screen
->pubScrNode
&& (ps
= (struct PubScreenNode
*)FindName(list
,screen
->pubScrNode
->psn_Node
.ln_Name
)))
2277 struct OpenScreenActionMsg msg
;
2279 msg
.Screen
= screen
;
2280 msg
.NewScreen
= &ns
;
2283 DoSyncAction((APTR
)int_openscreen
,&msg
.msg
,IntuitionBase
);
2288 UnlockPubScreenList();
2293 #ifdef USEWINDOWLOCK
2294 if (windowlock
) UNLOCKWINDOW
;
2301 DEBUG_OPENSCREEN(dprintf("OpenScreen: Get ThinLayerInfo\n"));
2302 ThinLayerInfo(&screen
->Screen
.LayerInfo
);
2305 if (screen
->Screen
.ViewPort
.ColorMap
)
2308 struct TagItem tags
[2];
2310 tags
[0].ti_Tag
= VTAG_ATTACH_CM_GET
;
2311 tags
[0].ti_Data
= 0;
2312 tags
[1].ti_Tag
= VTAG_END_CM
;
2314 if (VideoControl(screen
->Screen
.ViewPort
.ColorMap
, tags
) == 0 &&
2317 GfxFree((APTR
)tags
[0].ti_Data
);
2321 FreeColorMap(screen
->Screen
.ViewPort
.ColorMap
);
2324 if (screen
->Screen
.BarLayer
)
2326 DEBUG_OPENSCREEN(dprintf("OpenScreen: KillScreenBar\n"));
2327 KillScreenBar(&screen
->Screen
, IntuitionBase
);
2330 if (screen
->DInfo
.dri_Customize
)
2332 /* AROS: submenu image handling moved out of #ifdef */
2333 DisposeObject(screen
->DInfo
.dri_Customize
->submenu
);
2335 DisposeObject(screen
->DInfo
.dri_Customize
->menutoggle
);
2337 FreeMem(screen
->DInfo
.dri_Customize
,sizeof (struct IntuitionCustomize
));
2340 if (screen
->DInfo
.dri_Colors
) FreeMem(screen
->DInfo
.dri_Colors
,4 * DRIPEN_NUMDRIPENS
);
2342 if (screen
->DInfo
.dri_AmigaKey
)
2344 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose AmigaKey Object\n"));
2345 DisposeObject(screen
->DInfo
.dri_AmigaKey
);
2347 if (screen
->DInfo
.dri_CheckMark
)
2349 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose CheckMark Object\n"));
2350 DisposeObject(screen
->DInfo
.dri_CheckMark
);
2353 if (screen
->DInfo
.dri_Font
)
2355 DEBUG_OPENSCREEN(dprintf("OpenScreen: Close Font\n"));
2356 CloseFont(screen
->DInfo
.dri_Font
);
2359 if (screen
->AllocatedBitMap
&& !(ns
.Type
& CUSTOMBITMAP
))
2361 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free BitMap\n"));
2362 FreeBitMap(screen
->AllocatedBitMap
);
2365 if (screen
->Screen
.ViewPort
.RasInfo
)
2367 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free RasInfo\n"));
2368 FreeMem(screen
->Screen
.ViewPort
.RasInfo
, sizeof (struct RasInfo
));
2373 DEBUG_OPENSCREEN(dprintf("OpenScreen: Trash Rastport\n"));
2374 DeinitRastPort(&screen
->Screen
.RastPort
);
2377 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free Screen\n"));
2378 DisposeObject((APTR
)screen
);
2383 DEBUG_OPENSCREEN(dprintf("OpenScreen: return 0x%lx\n", screen
));
2385 FireScreenNotifyMessage((IPTR
) screen
, SNOTIFY_AFTER_OPENSCREEN
, IntuitionBase
);
2387 ReturnPtr ("OpenScreen", struct Screen
*, (struct Screen
*)screen
);
2393 VOID
int_openscreen(struct OpenScreenActionMsg
*msg
,
2394 struct IntuitionBase
*IntuitionBase
)
2396 struct GfxBase
*GfxBase
= GetPrivIBase(IntuitionBase
)->GfxBase
;
2397 struct IntScreen
*screen
= msg
->Screen
;
2398 struct NewScreen
*ns
= msg
->NewScreen
;
2399 struct List
*list
= msg
->List
;
2400 struct Screen
*oldFirstScreen
;
2401 struct RethinkDisplayActionMsg rmsg
;
2404 DEBUG_OPENSCREEN(dprintf("OpenScreen: Checking for pubScrNode (0x%lx)\n",screen
->pubScrNode
));
2406 /* If this is a public screen, we link it into the intuition global
2407 public screen list */
2408 if (screen
->pubScrNode
!= NULL
)
2410 /* Set the pointer to ourselves */
2411 IS(screen
)->pubScrNode
->psn_Screen
= &screen
->Screen
;
2413 DEBUG_OPENSCREEN(dprintf("OpenScreen: Add Screen to PubList\n"));
2414 AddTail(list
, (struct Node
*)IS(screen
)->pubScrNode
);
2417 if (!ILOCKCHECK(((struct IntuiActionMsg
*)msg
))) lock
= LockIBase((IPTR
)NULL
);
2419 oldFirstScreen
= IntuitionBase
->FirstScreen
;
2420 if (ns
->Type
& SCREENBEHIND
)
2422 struct Screen
**ptr
= &IntuitionBase
->FirstScreen
;
2424 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sort Behind\n"));
2426 IntuitionBase
->ActiveScreen
= &screen
->Screen
;
2428 ptr
= &(*ptr
)->NextScreen
;
2429 *ptr
= &screen
->Screen
;
2433 screen
->Screen
.NextScreen
= IntuitionBase
->FirstScreen
;
2434 IntuitionBase
->FirstScreen
=
2435 IntuitionBase
->ActiveScreen
= &screen
->Screen
;
2436 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set as ActiveScreen\n"));
2439 /* AROS: If it's the first screen being opened, activate its monitor */
2440 if (!oldFirstScreen
)
2441 ActivateMonitor(screen
->IMonitorNode
, -1, -1, IntuitionBase
);
2443 /* set the default pub screen */
2444 if (IBase
->IControlPrefs
.ic_Flags
& ICF_DEFPUBSCREEN
)
2446 if ((IntuitionBase
->FirstScreen
== &screen
->Screen
) && screen
->pubScrNode
&& (screen
->Screen
.Flags
& (PUBLICSCREEN
| WBENCHSCREEN
)))
2448 IBase
->DefaultPubScreen
= &screen
->Screen
;
2452 msg
->Success
= MakeVPort(&IntuitionBase
->ViewLord
, &screen
->Screen
.ViewPort
) ? FALSE
: TRUE
;
2456 /* AROS: Put offsets validated by MakeVPort() back into screen structure */
2457 screen
->Screen
.LeftEdge
= screen
->Screen
.ViewPort
.DxOffset
;
2458 screen
->Screen
.TopEdge
= screen
->Screen
.ViewPort
.DyOffset
;
2461 int_RethinkDisplay(&rmsg
,IntuitionBase
);
2465 if (!(ns
->Type
& SCREENBEHIND
))
2467 // workaround: do not send the event for SCREENBEHIND cause it'd reset the DPMS counter
2468 QueryBlankerEvent(BLANKEREVENT_SCREENDEPTH
,(ULONG
)screen
->IMonitorNode
,IntuitionBase
);
2472 if (!ILOCKCHECK(((struct IntuiActionMsg
*)msg
))) UnlockIBase(lock
);
2474 D(bug("set active screen\n"));
2476 AddResourceToList(screen
, RESOURCE_SCREEN
, IntuitionBase
);