disable debug
[AROS.git] / rom / intuition / openscreen.c
blob30f51df6c40f18862a275390cbe3d3d7822de1ab
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 Copyright © 2001-2013, The MorphOS Development Team. All Rights Reserved.
4 $Id$
6 Open a new screen.
7 */
9 /*
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>
43 #ifdef __MORPHOS__
44 #include <proto/cybergraphics.h>
45 #include <cybergraphx/cybergraphics.h>
46 #else
47 #include <hidd/graphics.h>
48 #endif
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"
55 #include "menus.h"
56 #include "monitorclass_intern.h"
57 #include "monitorclass_private.h"
59 // disabled as it causes compatibility issues
60 //#define USE8BITHACK
62 #ifndef DEBUG_OpenScreen
63 #define DEBUG_OpenScreen 0
64 #endif
65 #undef DEBUG
66 #if DEBUG_OpenScreen
67 #define DEBUG 1
68 #endif
69 #include <aros/debug.h>
71 struct OpenScreenActionMsg
73 struct IntuiActionMsg msg;
74 struct IntScreen *Screen;
75 struct NewScreen *NewScreen;
76 struct List *List;
77 BOOL Success;
80 VOID int_openscreen(struct OpenScreenActionMsg *msg,struct IntuitionBase *IntuitionBase);
82 #ifdef SKINS
83 extern const ULONG defaultdricolors[DRIPEN_NUMDRIPENS];
84 #endif
86 #if DEBUG
87 #undef THIS_FILE
88 static const char THIS_FILE[] = __FILE__;
89 #endif
91 /*****************************************************************************
93 NAME */
94 AROS_LH1(struct Screen *, OpenScreen,
96 /* SYNOPSIS */
97 AROS_LHA(struct NewScreen *, newScreen, A0),
99 /* LOCATION */
100 struct IntuitionBase *, IntuitionBase, 33, Intuition)
102 /* FUNCTION
104 INPUTS
106 RESULT
108 NOTES
110 EXAMPLE
112 BUGS
114 SEE ALSO
116 INTERNALS
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 *****************************************************************************/
123 AROS_LIBFUNC_INIT
125 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
126 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
127 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
128 struct NewScreen ns;
129 struct TagItem *tag, *tagList;
130 struct IntScreen *screen;
131 int success;
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;
137 WORD sysfont = -1;
138 BOOL ok = TRUE, rp_inited = FALSE, li_inited = FALSE, sharepens = FALSE;
139 #ifdef USEWINDOWLOCK
140 BOOL windowlock = FALSE;
141 BOOL dowindowlock = TRUE;
142 #endif
143 struct Rectangle *dclip = NULL;
144 LONG overscan = OSCAN_TEXT;
145 DisplayInfoHandle displayinfo = NULL;
146 struct DisplayInfo dispinfo;
147 struct DimensionInfo dimensions;
148 #ifdef __MORPHOS__
149 struct MonitorInfo monitor;
150 #endif
151 ULONG allocbitmapflags = BMF_DISPLAYABLE;
152 char *skinname = 0;
153 #ifdef SKINS
154 ULONG vesafallback = 0;
155 ULONG *modecontrol = 0;
156 BOOL compositing = FALSE;
157 #endif
158 IPTR vctl = 0;
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;
168 //ULONG lock;
169 WORD numcolors = 0;
170 UWORD spritebase;
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 },
185 { TAG_DONE }
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"
197 , newScreen
198 , newScreen->LeftEdge
199 , newScreen->TopEdge
200 , newScreen->Width
201 , newScreen->Height
202 , newScreen->Depth
205 FireScreenNotifyMessage((IPTR) newScreen, SNOTIFY_BEFORE_OPENSCREEN, IntuitionBase);
206 ns = *newScreen;
208 if (newScreen->Type & NS_EXTENDED)
210 tagList = ((struct ExtNewScreen *)newScreen)->Extension;
211 } else {
212 tagList = NULL;
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));
218 #ifdef __MORPHOS__
219 if (!CyberGfxBase)
221 struct Library *lib = ComplainOpenLibrary(COMPLAIN_CYBERGFX,FALSE,IntuitionBase);
222 Forbid();
223 if (!CyberGfxBase)
225 CyberGfxBase = lib;
226 Permit();
228 else
230 Permit();
231 CloseLibrary(lib);
234 if (!CyberGfxBase)
236 FireScreenNotifyMessage(0, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
237 return NULL;
240 if (!LocaleBase)
242 struct Library *lib = ComplainOpenLibrary(COMPLAIN_LOCALE,FALSE,IntuitionBase);
243 Forbid();
244 if (!LocaleBase)
246 LocaleBase = lib;
247 Permit();
248 OpenintuitionCatalog(IntuitionBase);
250 else
252 Permit();
253 CloseLibrary(lib);
257 if (!CGXSystemBase)
259 struct Library *lib = ComplainOpenLibrary(COMPLAIN_CGXSYSTEM,FALSE,IntuitionBase);
260 Forbid();
261 if (!CGXSystemBase)
263 CGXSystemBase = lib;
264 Permit();
266 else
268 Permit();
269 CloseLibrary(lib);
272 #endif
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));
283 if (screen == NULL)
285 SetError(OSERR_NOMEM);
286 ok = FALSE;
289 if (ok && tagList)
291 char *pubname = NULL;
293 modeid = GetTagData(SA_DisplayID,INVALID_ID, tagList);
294 #ifndef __AROS__
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);
306 if (workbench)
308 compositing = TRUE;
310 #endif
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"));
318 #ifndef SKINS
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;
333 #else
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! */
345 if (workbench)
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;
359 else
361 struct IMonitorNode *node = FindMonitorNode(IBase->AmbientScreenMode.ModeID,IntuitionBase);
363 if (node)
365 monitorname = node->MonitorName;
369 #endif
371 sysfont = 1;
372 sharepens = TRUE; /* not sure */
375 if ((pubname = (char*)GetTagData(SA_PubName, 0, tagList)))
377 /* Name of this public screen. */
378 struct PubScreenNode *oldpsn;
379 struct List *list;
381 list = LockPubScreenList();
383 if ((strcmp(pubname, "Workbench") == 0) || workbench)
385 if (IBase->WorkBench)
387 ok = FALSE;
390 workbench = TRUE;
392 else
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);
399 if (oldpsn)
401 SetError(OSERR_PUBNOTUNIQUE);
402 ok = FALSE;
406 UnlockPubScreenList();
408 if (ok)
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);
417 ok = FALSE;
420 if (ok && (screen->pubScrNode->psn_Node.ln_Name = AllocVec(MAXPUBSCREENNAME + 1,MEMF_ANY)))
422 UBYTE sigbit;
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
440 signal task. */
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;
451 else
453 /* do not signal with -1 ! */
454 screen->pubScrNode->psn_SigTask = NULL;
457 else
459 SetError(OSERR_NOMEM);
460 FreeMem(screen->pubScrNode, sizeof(struct PubScreenNode));
461 screen->pubScrNode = NULL;
462 ok = FALSE;
468 #ifdef SKINS
469 if (modeid != INVALID_ID)
471 /* modes can be on other monitors */
472 monitorname = NULL;
474 #endif
476 while((tag = NextTagItem ((struct TagItem **)&tagList)))
478 #if 1
479 DEBUG_OPENSCREEN(dprintf("OpenScreen: Tag 0x%08lx Data 0x%08lx\n",
480 tag->ti_Tag, tag->ti_Data));
481 #endif
482 switch(tag->ti_Tag)
484 case SA_CompositingFlags:
485 compflags = tag->ti_Data;
486 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_CompositingFlags 0x%p\n", compflags));
487 break;
488 case SA_AlphaPreCompositingHook:
489 compalphahook = (struct Hook *)tag->ti_Data;
490 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AlphaPreCompositingHook 0x%p\n", compalphahook));
491 break;
492 case SA_Left:
493 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Left %ld\n",tag->ti_Data));
494 ns.LeftEdge = tag->ti_Data;
495 break;
496 case SA_Top:
497 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Top %ld\n",tag->ti_Data));
498 ns.TopEdge = tag->ti_Data;
499 break;
500 case SA_Width:
501 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Width %ld\n",tag->ti_Data));
502 if ((tag->ti_Data != ~0) && (tag->ti_Data > 32767))
504 ok = FALSE;
506 ns.Width = tag->ti_Data;
507 break;
508 case SA_Height:
509 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Height %ld\n",tag->ti_Data));
510 if ((tag->ti_Data != ~0) && (tag->ti_Data > 32767))
512 ok = FALSE;
514 ns.Height = tag->ti_Data;
515 break;
516 case SA_Depth:
517 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Depth %ld\n",tag->ti_Data));
518 ns.Depth = tag->ti_Data;
519 break;
520 case SA_DetailPen:
521 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DetailPen %ld\n",tag->ti_Data));
522 ns.DetailPen = tag->ti_Data;
523 break;
524 case SA_BlockPen:
525 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BlockPen %ld\n",tag->ti_Data));
526 ns.BlockPen = tag->ti_Data;
527 break;
528 case SA_Type:
529 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Type 0x%lx\n",tag->ti_Data));
530 ns.Type &= ~SCREENTYPE;
531 ns.Type |= tag->ti_Data;
532 break;
534 case SA_Title:
535 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Title <%s>\n",tag->ti_Data));
536 ns.DefaultTitle = (UBYTE *)tag->ti_Data;
537 break;
539 case SA_Font:
540 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Font 0x%lx\n",tag->ti_Data));
541 ns.Font = (struct TextAttr *)tag->ti_Data;
542 break;
544 case SA_Colors32:
545 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors32 0x%lx\n",tag->ti_Data));
546 colors32 = (ULONG *)tag->ti_Data;
547 break;
549 case SA_Colors:
550 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors 0x%lx\n",tag->ti_Data));
551 colors = (struct ColorSpec *)tag->ti_Data;
552 break;
554 case SA_SysFont:
555 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SysFont 0x%lx\n",tag->ti_Data));
556 sysfont = (WORD)tag->ti_Data;
557 break;
559 case SA_BitMap:
560 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap 0x%lx\n",tag->ti_Data));
561 if(tag->ti_Data)
563 ns.Type |= CUSTOMBITMAP;
564 ns.CustomBitMap = (struct BitMap *)tag->ti_Data;
566 else
568 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap==NULL specified, custom BitMap use disabled\n"));
570 break;
572 case SA_BackFill:
573 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackFill Hook 0x%lx\n",tag->ti_Data));
574 layer_info_hook = (struct Hook *)tag->ti_Data;
575 break;
577 case SA_Quiet:
578 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Quiet 0x%lx\n",tag->ti_Data));
579 if (tag->ti_Data)
581 ns.Type |= SCREENQUIET;
583 else
585 ns.Type &= ~SCREENQUIET;
587 break;
589 case SA_ShowTitle:
590 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ShowTitle 0x%lx\n",tag->ti_Data));
591 if (tag->ti_Data)
593 ns.Type |= SHOWTITLE;
595 else
597 ns.Type &= ~SHOWTITLE;
599 break;
601 case SA_Pens:
602 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Pens 0x%lx\n",tag->ti_Data));
603 customdripens = (UWORD *)tag->ti_Data;
604 break;
606 case SA_SharePens:
607 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SharePens 0x%lx\n",tag->ti_Data));
608 sharepens = tag->ti_Data ? TRUE : FALSE;
609 if (tag->ti_Data)
611 ns.Type |= PENSHARED;
612 } else {
613 ns.Type &= ~PENSHARED;
615 break;
617 case SA_Interleaved:
618 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Interleaved 0x%lx\n",tag->ti_Data));
619 if (tag->ti_Data)
621 allocbitmapflags |= BMF_INTERLEAVED;
623 else
625 allocbitmapflags &= ~BMF_INTERLEAVED;
627 break;
629 case SA_Behind:
630 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Behind 0x%lx\n",tag->ti_Data));
631 if (tag->ti_Data)
633 ns.Type |= SCREENBEHIND;
635 else
637 ns.Type &= ~SCREENBEHIND;
639 break;
641 case SA_DClip:
642 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DClip 0x%lx\n",tag->ti_Data));
643 dclip = (struct Rectangle *)tag->ti_Data;
644 break;
646 case SA_Overscan:
647 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_OverScan 0x%lx\n",tag->ti_Data));
648 overscan = tag->ti_Data;
649 break;
651 case SA_DisplayID:
652 case SA_LikeWorkbench:
653 case SA_ErrorCode:
654 case SA_PubName:
655 case SA_PubSig:
656 case SA_PubTask:
658 * handled elsewhere
660 break;
662 case SA_AutoScroll:
663 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AutoScroll 0x%lx\n",tag->ti_Data));
664 if (tag->ti_Data)
666 ns.Type |= AUTOSCROLL;
668 else
670 ns.Type &= ~AUTOSCROLL;
672 break;
674 case SA_FullPalette:
675 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FullPalette 0x%lx\n",tag->ti_Data));
676 break;
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 */
680 break;
681 case SA_Parent:
682 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Parent 0x%lx\n",tag->ti_Data));
683 break;
684 case SA_Draggable:
685 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Draggable 0x%lx\n",tag->ti_Data));
686 draggable = tag->ti_Data; /* AROS: Added support for this tag */
687 break;
688 case SA_Exclusive:
689 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Exclusive 0x%lx\n",tag->ti_Data));
690 break;
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 */
694 break;
695 case SA_FrontChild:
696 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FrontChild 0x%lx\n",tag->ti_Data));
697 break;
698 case SA_BackChild:
699 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackChild 0x%lx\n",tag->ti_Data));
700 break;
701 case SA_MinimizeISG:
702 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_MinimizeISG 0x%lx\n",tag->ti_Data));
703 break;
705 case SA_MonitorName:
706 monitorname = (char*)tag->ti_Data;
707 break;
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;
712 break;
714 case SA_VesaFallback:
715 vesafallback = tag->ti_Data;
716 break;
718 case SA_ModeEditControl:
719 modecontrol = (ULONG*)tag->ti_Data;
720 break;
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;
724 break;
726 case SA_CompositingLayers:
727 compositing = tag->ti_Data ? TRUE : FALSE;
728 break;
729 #endif
730 case SA_ShowPointer:
731 showpointer = tag->ti_Data ? TRUE : FALSE;
732 break;
734 case SA_GammaControl:
735 gammacontrol = tag->ti_Data ? TRUE : FALSE;
736 break;
738 case SA_GammaRed:
739 gammared = (UBYTE*)tag->ti_Data;
740 break;
742 case SA_GammaBlue:
743 gammablue = (UBYTE*)tag->ti_Data;
744 break;
746 case SA_GammaGreen:
747 gammagreen = (UBYTE*)tag->ti_Data;
748 break;
750 case SA_3DSupport:
751 support3d = tag->ti_Data ? TRUE : FALSE;
752 break;
754 case SA_AdaptSize:
755 adaptsize = tag->ti_Data ? TRUE : FALSE;
756 break;
758 case SA_DisplayWidth:
759 displaywidth = (ULONG)tag->ti_Data;
760 break;
762 case SA_DisplayHeight:
763 displayheight = (ULONG)tag->ti_Data;
764 break;
766 case SA_ExactMatchMonitorName:
767 exactname = tag->ti_Data ? TRUE : FALSE;
768 break;
770 /* TODO: Missing SA_ Tags */
771 default:
772 DEBUG_OPENSCREEN(dprintf("OpenScreen: unknown tag 0x%lx data 0x%lx\n",
773 tag->ti_Tag,
774 tag->ti_Data));
775 break;
777 } /* switch (tag->ti_Tag) */
779 } /* while ((tag = NextTagItem (&tagList))) */
781 } /* if (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");)
792 ok = FALSE;
795 /* First Init the RastPort then get the BitPlanes!! */
797 #ifdef __MORPHOS__
798 #include "workaround.openscreen.c"
799 #endif
800 /* AROS: Use 3D support code */
801 if (support3d)
803 struct IMonitorNode *node = NULL;
804 ULONG depth = (ULONG)-1;
806 #ifndef __AROS__
807 /*AROS: We don't need these flags because we keep ModeID together with the BitMap */
808 screen->Support3D = TRUE;
809 allocbitmapflags |= BMF_3DTARGET;
810 #endif
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));
832 ns.Depth = depth;
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"));
839 ok = FALSE;
841 } else {
842 /* whoops, no 3d support at all, fail! */
843 DEBUG_OPENSCREEN(dprintf("OpenScreen: no 3d available, fail! (2)\n"));
844 ok = FALSE;
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 ? */
854 if (exactname)
856 if (newmodeid == INVALID_ID)
858 dprintf("uhuh, no modeid!\n");
859 ok = FALSE;
861 else
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));
871 #ifdef __MORPHOS__
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[] =
877 {CYBRBIDTG_Depth,0},
878 {CYBRBIDTG_NominalWidth,0},
879 {CYBRBIDTG_NominalHeight,0},
880 {TAG_DONE}
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);)
899 #endif
901 #ifdef SKINS
902 if ((workbench) && (IBase->EmergencyBoot.monitorname))
904 struct IMonitorNode *node;
905 ULONG depthid;
906 ULONG newmodeid;
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)
916 modeid = newmodeid;
917 ns.Width = IBase->EmergencyBoot.baseresolution;
919 switch (ns.Width)
921 case 800:
922 ns.Height = 600;
923 break;
925 case 1024:
926 ns.Height = 768;
927 break;
929 default:
930 ns.Width = 640;
931 ns.Height = 480;
934 screen->VESAMode = ns.Width;
935 screen->VESAModeDepthID = depthid;
939 if (workbench && (((struct IIHData *)IBase->InputHandler->is_Data)->ActQualifier & IEQUALIFIER_CONTROL))
941 vesafallback = 1024;
944 if (vesafallback)
946 struct IMonitorNode *node = NULL;
947 ULONG depthid;
948 ULONG newmodeid;
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)
958 modeid = newmodeid;
959 ns.Width = vesafallback;
961 switch (ns.Width)
963 case 800:
964 ns.Height = 600;
965 break;
967 case 1024:
968 ns.Height = 768;
969 break;
971 default:
972 ns.Width = 640;
973 ns.Height = 480;
976 screen->VESAMode = ns.Width;
977 screen->VESAModeDepthID = depthid;
981 if (modecontrol)
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)
990 switch (ns.Depth)
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;
1000 } else {
1001 DEBUG_OPENSCREEN(dprintf("OpenScreen: failed to init testmode!\n"));
1002 ok = FALSE;
1006 #endif
1009 * AROS: Got OpenScreenTags modeid without monitor, promote to chipset default
1010 * (if present).
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)
1023 #ifndef __AROS__
1024 WORD bestwidth,bestheight;
1025 #endif
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;
1032 #ifdef __AROS__
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;}
1039 #else
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));
1046 #endif
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;
1053 else
1055 modetags[5].ti_Tag = TAG_IGNORE;
1058 modeid = BestModeIDA(modetags);
1060 #ifdef SKINS
1061 if (modeid == INVALID_ID && workbench)
1063 ULONG depthid;
1064 ULONG newmodeid = FakeWorkbenchMode(NULL,(ULONG*)&depthid,640,IntuitionBase);
1065 /* create an ID */
1067 DEBUG_OPENSCREEN(dprintf("OpenScreen: Vesa Fallback!\n"));
1069 if (newmodeid != INVALID_ID)
1071 modeid = newmodeid;
1072 ns.Width = 640;
1073 ns.Height = 480;
1075 screen->VESAMode = 640;
1076 screen->VESAModeDepthID = depthid;
1079 #endif
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 */
1086 ok = FALSE;
1090 DEBUG_OPENSCREEN(dprintf("OpenScreen: ModeID 0x%08lx\n", modeid));
1092 InitRastPort(&screen->Screen.RastPort);
1093 rp_inited = TRUE;
1094 success = FALSE;
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)
1100 #else
1101 && GetDisplayInfoData(displayinfo, (APTR)&monitor, sizeof(monitor), DTAG_MNTR, modeid)
1102 #endif
1105 success = TRUE;
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;
1111 #else
1112 screen->Monitor = monitor.Mspc;
1113 #endif
1114 if (dclip == NULL)
1116 switch (overscan)
1118 case OSCAN_STANDARD:
1119 dclip = &dimensions.StdOScan;
1120 break;
1122 case OSCAN_MAX:
1123 dclip = &dimensions.MaxOScan;
1124 break;
1126 case OSCAN_VIDEO:
1127 dclip = &dimensions.VideoOScan;
1128 break;
1130 default:
1131 dclip = &dimensions.TxtOScan;
1132 break;
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;
1152 #ifndef __AROS__
1153 DEBUG_OPENSCREEN(dprintf("OpenScreen: Monitor 0x%lx Width %ld Height %ld\n",
1154 screen->Monitor, ns.Width, ns.Height));
1155 #endif
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);
1173 else
1175 custombm = NULL;
1178 else if ((!IS_HIDD_BM(custombm)) || (modeid != HIDD_BM_HIDDMODE(custombm)))
1180 custombm = NULL;
1182 #else
1183 if (IsCyberModeID(modeid) && custombm)
1185 int pixfmt = GetCyberIDAttr(CYBRIDATTR_PIXFMT,modeid);
1187 if(GetCyberMapAttr(custombm,CYBRMATTR_PIXFMT) != pixfmt)
1189 // incompatible formats !
1190 custombm = NULL;
1193 #endif
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",
1199 ns.Depth));
1200 } else {
1201 ns.CustomBitMap = NULL;
1202 ns.Type &= ~CUSTOMBITMAP;
1204 } else {
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));
1212 } else {
1213 DEBUG_OPENSCREEN(dprintf("OpenScreen: No MonitorNode\n"));
1214 ok = FALSE;
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},
1224 {TAG_DONE , 0 }
1227 screen->Screen.RastPort.BitMap = AllocBitMap(ns.Width, ns.Height, Depth,
1228 allocbitmapflags | BMF_CHECKVALUE,
1229 (struct BitMap *)bmtags);
1230 #else
1231 struct BitMap *root = NULL;
1232 ULONG pixfmt;
1233 ULONG Depth;
1234 int retrycnt=1;
1235 ULONG stdwidth = dimensions.Nominal.MaxX - dimensions.Nominal.MinX + 1;
1236 ULONG stdheight = dimensions.Nominal.MaxY - dimensions.Nominal.MinY + 1;
1238 #ifdef USE8BITHACK
1239 Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : 8;
1240 #else
1241 Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : ns.Depth;
1242 #endif
1244 switch(Depth)
1246 case 15:
1247 pixfmt = PIXFMT_RGB15;
1248 break;
1249 case 16:
1250 pixfmt = PIXFMT_RGB16;
1251 break;
1252 case 24:
1253 pixfmt = PIXFMT_BGR24;
1254 break;
1255 case 32:
1256 pixfmt = PIXFMT_ARGB32;
1257 break;
1258 default:
1259 pixfmt = PIXFMT_LUT8;
1260 break;
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);
1276 if(root == NULL)
1278 allocbitmapflags |= (BMF_SPECIALFMT|/*BMF_CLEAR|*/BMF_DISPLAYABLE|BMF_MINPLANES);
1279 allocbitmapflags |= SHIFT_PIXFMT(pixfmt);
1281 else
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,
1288 Depth,
1289 allocbitmapflags,
1290 root)) == NULL)
1292 root = NULL;
1295 while((screen->Screen.RastPort.BitMap == NULL) && (retrycnt--));
1296 #endif
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);
1304 #ifndef __AROS__
1306 * AROS: This seems to be not needed
1307 * TODO: Check if this is really true, test case needed
1309 if (Depth > 8)
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);
1333 #endif
1337 DEBUG_OPENSCREEN(dprintf("OpenScreen: BitMap 0x%lx\n",
1338 screen->Screen.RastPort.BitMap));
1340 else
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));
1360 if (!success ||
1361 (screen->Screen.RastPort.BitMap == NULL) ||
1362 (screen->Screen.ViewPort.RasInfo == NULL))
1364 ok = FALSE;
1365 } else {
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;
1373 if (ok)
1375 /* Read depth from the BitMap to avoid AttachPalExtra/ObtainPen getting
1376 * confused if cgx decided to allocate a higher depth BitMap than what
1377 * was asked.
1379 ns.Depth = GetBitMapAttr(screen->Screen.RastPort.BitMap,BMA_DEPTH);
1381 if (!numcolors) /* AROS: Added support for SA_ColorMapEntries */
1383 #ifdef USE8BITHACK
1384 numcolors = 256;
1385 #else
1386 numcolors = (ns.Depth <= 8) ? (1L << ns.Depth) : 256;
1387 #endif
1390 /* Get a color map structure. Sufficient colors?? */
1392 DEBUG_OPENSCREEN(dprintf("OpenScreen: Colormap Entries %ld\n",
1393 numcolors));
1394 if ((screen->Screen.ViewPort.ColorMap = GetColorMap(numcolors < 32 ? 32 : numcolors)) != NULL)
1396 if (0 == AttachPalExtra(screen->Screen.ViewPort.ColorMap,
1397 &screen->Screen.ViewPort))
1399 #if 0
1400 int i=0;
1401 char *alloclist;
1402 UWORD *refcnt;
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",
1414 i,alloclist[i]));
1415 i++;
1417 #endif
1419 else
1421 ok = FALSE;
1424 else
1426 ok = FALSE;
1429 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%lx\n",
1430 screen->Screen.ViewPort.ColorMap));
1433 #ifdef __MORPHOS__
1436 ULONG pixfmt = -1;
1437 APTR handle = LockBitMapTags(screen->Screen.RastPort.BitMap,
1438 LBMI_PIXFMT,(ULONG)&pixfmt,TAG_DONE);
1440 if (handle)
1442 UnLockBitMap(handle);
1443 screen->PixelFormat = pixfmt;
1445 else
1447 screen->PixelFormat = -1;
1450 #endif
1451 screen->GammaControl.UseGammaControl = gammacontrol;
1452 screen->GammaControl.GammaTableR = gammared;
1453 screen->GammaControl.GammaTableG = gammagreen;
1454 screen->GammaControl.GammaTableB = gammablue;
1455 #ifndef __AROS__
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;
1468 #endif
1469 screen->ModeID = modeid;
1471 if (ok)
1473 struct ViewPortExtra *vpe = (struct ViewPortExtra *)GfxNew(VIEWPORT_EXTRA_TYPE);
1475 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPortExtra 0x%lx\n", vpe));
1477 ok = FALSE;
1479 if (vpe)
1481 struct TagItem tags[6];
1483 memcpy(&vpe->DisplayClip, dclip,sizeof(struct Rectangle));
1484 #ifdef __AROS__
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;
1495 #else
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)
1505 case 800:
1506 screen->Screen.ViewPort.DHeight = 600;
1507 break;
1509 case 1024:
1510 screen->Screen.ViewPort.DHeight = 768;
1511 break;
1513 default:
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;
1522 } else {
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);
1529 #endif
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
1557 * at the moment.
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
1563 * won't work
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)
1571 spritebase = 16;
1572 #else
1573 spritebase = (ns.Depth < 5) ? (1 << ns.Depth) - 8 : 16;
1574 #endif
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"));
1581 ok = TRUE;
1583 else
1585 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl failed\n"));
1590 if (ok)
1592 struct Color32 *p;
1593 int k;
1594 UWORD *q;
1596 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set first 4 colors\n"));
1598 p = IBase->Colors;
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);
1607 if (ns.Depth >= 3)
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
1614 * reasons.
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,
1629 k + lastcol,
1630 p[k+4].red,
1631 p[k+4].green,
1632 p[k+4].blue,
1633 PEN_EXCLUSIVE);
1635 else
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
1649 if (ns.Depth < 9)
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,
1657 k + spritebase,
1658 p[k+7].red, p[k+7].green, p[k+7].blue));
1659 if (k + spritebase < numcolors)
1661 ObtainPen(screen->Screen.ViewPort.ColorMap,
1662 k + spritebase,
1663 p[k+7].red, p[k+7].green, p[k+7].blue,
1664 PEN_EXCLUSIVE);
1666 else
1668 /* Can't be allocated, but can still be set. */
1669 SetRGB32(&screen->Screen.ViewPort,
1670 k + spritebase,
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,
1683 colors,
1684 colors->Red,
1685 colors->Green,
1686 colors->Blue));
1687 SetRGB4(&screen->Screen.ViewPort,
1688 colors->ColorIndex,
1689 colors->Red,
1690 colors->Green,
1691 colors->Blue);
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"));
1703 COPY(LeftEdge);
1704 COPY(TopEdge);
1705 COPY(Width);
1706 COPY(Height);
1707 COPY(DetailPen);
1708 COPY(BlockPen);
1709 COPY(Font);
1710 COPY(DefaultTitle);
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);
1725 #ifdef __MORPHOS__
1726 screen->Screen.WBorTop = 2;
1727 screen->Screen.WBorLeft = 4;
1728 screen->Screen.WBorRight = 4;
1729 screen->Screen.WBorBottom = 2;
1730 #else
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 */
1735 #endif
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);
1742 #else
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},
1754 {TAG_DONE}
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,
1772 TAG_DONE);
1774 screen->Compositing = iscompositing ? TRUE : FALSE;
1776 else
1778 struct TagItem layerinfotags[] =
1780 {SA_CompositingLayers, FALSE},
1781 {TAG_DONE}
1783 screen->Compositing = FALSE;
1784 InitScreenLayerInfo(&screen->Screen,layerinfotags);
1786 #endif
1787 li_inited = TRUE;
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 */
1797 #ifdef __AROS__
1798 screen->DInfo.dri_Version = DRI_VERSION;
1799 #else
1800 GetDisplayInfoData(NULL, (APTR)&dispinfo, sizeof(dispinfo), DTAG_DISP, modeid);
1801 screen->DInfo.dri_Version = MOS_DRI_VERSION;
1802 #endif
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));
1817 if (sysfont == 0)
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;
1846 } /* if (ok) */
1848 if (ok)
1850 ULONG *dripens = NULL;
1852 switch (ns.Depth)
1854 case 1:
1855 dripens = (ULONG*)&IBase->DriPens2;
1856 break;
1858 case 2:
1859 dripens = (ULONG*)&IBase->DriPens4;
1860 break;
1862 default:
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;
1868 } else {
1869 dripens = (ULONG*)&IBase->DriPens8;
1871 break;
1874 /* set default values for pens */
1875 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Default Pens\n"));
1876 CopyMem(dripens,screen->Pens,sizeof(screen->Pens));
1878 if (ns.Depth > 1)
1880 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set NewLook\n"));
1881 screen->DInfo.dri_Flags |= DRIF_NEWLOOK;
1884 if (customdripens)
1886 WORD i;
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];
1924 UWORD mask;
1925 WORD i;
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,
1954 pen));
1956 ObtainPen(screen->Screen.ViewPort.ColorMap,
1957 pen,
1961 PENF_NO_SETCOLOR);
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 */
1970 if (!sharepens)
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,
1983 i));
1984 ObtainPen(screen->Screen.ViewPort.ColorMap,
1989 PENF_EXCLUSIVE | PENF_NO_SETCOLOR);
1993 } /* if (!sharepens) */
1998 if (ok)
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;
2007 } else {
2008 screen->DInfo.dri_Flags &= ~DRIF_DIRECTCOLOR;
2011 #ifdef SKINS
2012 if (!(screen->DInfo.dri_Colors = AllocMem(4 * DRIPEN_NUMDRIPENS,MEMF_PUBLIC)))
2013 ok = FALSE;
2015 if (ok)
2017 CopyMem(&defaultdricolors,screen->DInfo.dri_Colors,sizeof (defaultdricolors));
2018 memset(((UBYTE *) screen->DInfo.dri_Colors) + sizeof(defaultdricolors), 0, 4 * DRIPEN_NUMDRIPENS - sizeof(defaultdricolors));
2020 #endif
2022 if (ok)
2024 DEBUG_OPENSCREEN(dprintf("OpenScreen: allocating dri_Customize\n"));
2026 if ((screen->DInfo.dri_Customize = AllocMem(sizeof (struct IntuitionCustomize),MEMF_PUBLIC|MEMF_CLEAR)))
2028 #ifdef SKINS
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);
2041 #else
2042 /* AROS: Use less error-prone skinname handling */
2043 ok = int_LoadDecorator(skinname, screen, IntuitionBase);
2044 #endif
2046 else
2048 ok = FALSE;
2053 #ifdef SKINS
2054 if (ok)
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);
2068 #endif
2070 if (ok)
2072 struct TagItem sysi_tags[] =
2074 {SYSIA_Which, MENUCHECK },
2075 {SYSIA_DrawInfo, (IPTR)&screen->DInfo },
2076 {TAG_DONE }
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;
2093 #ifdef SKINS
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;
2097 #endif
2099 if (!screen->DInfo.dri_CheckMark || !screen->DInfo.dri_AmigaKey) ok = FALSE;
2102 if (ok)
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);
2126 if (ok)
2128 #define SDEPTH_HEIGHT (screen->Screen.BarHeight + 1)
2129 #ifdef IA_Screen
2130 #undef IA_Screen
2131 #endif
2132 #define IA_Screen (IA_Dummy + 0x1f) /* OS v44 includes!*/
2134 struct TagItem sdepth_tags[] =
2136 {GA_Image, 0 },
2137 {GA_Top, 0 },
2138 {GA_Height, SDEPTH_HEIGHT},
2139 {GA_SysGadget, TRUE },
2140 {GA_SysGType, GTYP_SDEPTH },
2141 {GA_RelVerify, TRUE },
2142 {TAG_DONE, 0UL }
2145 struct TagItem image_tags[] =
2147 {IA_Left , 0 },
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},
2154 {TAG_DONE }
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[] =
2176 {GA_RelRight, 0},
2177 {TAG_DONE }
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;
2186 } else {
2187 if (im) DisposeObject(im);
2190 #if DEBUG
2192 int i;
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]));
2198 #endif
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)))
2205 LOCKWINDOW;
2206 windowlock = TRUE;
2207 screen->WindowLock = TRUE;
2209 #endif
2211 int_CalcSkinInfo(&screen->Screen,IntuitionBase);
2212 #ifdef SKINS
2213 int_InitTitlebarBuffer(&screen->Screen,IntuitionBase);
2214 #endif
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"));
2225 #ifdef SKINS
2226 if (workbench)
2228 #if 1
2229 if (IBase->IControlPrefs.ic_Flags & (ICF_DISAPPEARINGTITLEBAR | ICF_NOWBTITLEBAR)) screen->SpecialFlags |= SF_AppearingBar;
2230 #else
2231 if (IBase->IControlPrefs.ic_Flags & ICF_NOWBTITLEBAR) screen->SpecialFlags |= SF_InvisibleBar;
2232 if (IBase->IControlPrefs.ic_Flags & ICF_DISAPPEARINGTITLEBAR) screen->SpecialFlags |= SF_AppearingBar;
2233 #endif
2235 #endif
2237 //jDc: ALL screens MUST have BarLayer!
2238 CreateScreenBar(&screen->Screen, IntuitionBase);
2240 if (!screen->Screen.BarLayer) ok = FALSE;
2243 if (ok)
2245 if ((ns.Type & SCREENTYPE) == CUSTOMSCREEN)
2247 screen->ShowPointer = showpointer;
2248 } else {
2249 screen->ShowPointer = TRUE;
2251 #ifdef SKINS
2252 GetAttr(POINTERA_SharedPointer, screen->IMonitorNode->Pointers[POINTERTYPE_INVISIBLE], (IPTR *)&screen->Pointer);
2253 #else
2254 GetAttr(POINTERA_SharedPointer, IBase->DefaultPointer, (IPTR *)&screen->Pointer);
2255 #endif
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
2264 if (ok)
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)))
2272 ok = FALSE;
2275 if (ok)
2277 struct OpenScreenActionMsg msg;
2279 msg.Screen = screen;
2280 msg.NewScreen = &ns;
2281 msg.List = list;
2283 DoSyncAction((APTR)int_openscreen,&msg.msg,IntuitionBase);
2285 ok = msg.Success;
2288 UnlockPubScreenList();
2291 } /* if (ok) */
2293 #ifdef USEWINDOWLOCK
2294 if (windowlock) UNLOCKWINDOW;
2295 #endif
2297 if (!ok)
2299 if (li_inited)
2301 DEBUG_OPENSCREEN(dprintf("OpenScreen: Get ThinLayerInfo\n"));
2302 ThinLayerInfo(&screen->Screen.LayerInfo);
2305 if (screen->Screen.ViewPort.ColorMap)
2307 #ifdef __MORPHOS__
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 &&
2315 tags[0].ti_Data)
2317 GfxFree((APTR)tags[0].ti_Data);
2319 #endif
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);
2334 #ifdef SKINS
2335 DisposeObject(screen->DInfo.dri_Customize->menutoggle);
2336 #endif
2337 FreeMem(screen->DInfo.dri_Customize,sizeof (struct IntuitionCustomize));
2339 #ifdef SKINS
2340 if (screen->DInfo.dri_Colors) FreeMem(screen->DInfo.dri_Colors,4 * DRIPEN_NUMDRIPENS);
2341 #endif
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));
2371 if (rp_inited)
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);
2379 screen = 0;
2381 } /* if (!ok) */
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);
2389 AROS_LIBFUNC_EXIT
2391 } /* OpenScreen */
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;
2402 ULONG lock = 0;
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"));
2425 if (!*ptr)
2426 IntuitionBase->ActiveScreen = &screen->Screen;
2427 while (*ptr)
2428 ptr = &(*ptr)->NextScreen;
2429 *ptr = &screen->Screen;
2431 else
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;
2454 if (msg->Success)
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;
2460 rmsg.lock = FALSE;
2461 int_RethinkDisplay(&rmsg,IntuitionBase);
2464 #ifdef SKINS
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);
2470 #endif
2472 if (!ILOCKCHECK(((struct IntuiActionMsg *)msg))) UnlockIBase(lock);
2474 D(bug("set active screen\n"));
2476 AddResourceToList(screen, RESOURCE_SCREEN, IntuitionBase);