grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / intuition / openscreen.c
blob455eab056167e07795fb45fa4bbed0eb186d27c0
1 /*
2 Copyright © 1995-2015, 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 if (!GetPrivIBase(IntuitionBase)->ScreenModePrefs)
324 SetDisplayDefaults(IntuitionBase);
326 ns.Width = GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Width;
327 ns.Height = GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Height;
328 ns.Depth = GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Depth;
329 modeid = GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_DisplayID;
331 if (GetPrivIBase(IntuitionBase)->ScreenModePrefs->smp_Control & SMF_AUTOSCROLL)
333 /* need to mark autoscroll */
334 ns.Type |= AUTOSCROLL;
336 #else
337 ns.Width = IBase->AmbientScreenMode.DisplayWidth;
338 ns.Height = IBase->AmbientScreenMode.DisplayHeight;
339 ns.Depth = IBase->AmbientScreenMode.DisplayDepth;
340 if (IBase->AmbientScreenMode.AutoScroll) ns.Type |= AUTOSCROLL;
341 displaywidth = IBase->AmbientScreenMode.ModeWidth;
342 displayheight = IBase->AmbientScreenMode.ModeHeight;
344 /* jDc: do NOT copy modeid of wb as that will not allow overloading depth param properly */
346 /* unless it's OpenWorkbench! */
348 if (workbench)
350 modeid = INVALID_ID; // we'll use the stored ID only in the worst case!
351 compositing = IBase->AmbientScreenMode.Compositing;
354 /* let's try to limit the new screen to the same monitor ambient would use */
355 /* but only if modeid is a weak one */
356 if ((modeid == INVALID_ID) || (ModeNotAvailable(modeid)) || !FindDisplayInfo(modeid))
358 if (IBase->AmbientScreenMode.ModeMonitor[0])
360 monitorname = IBase->AmbientScreenMode.ModeMonitor;
362 else
364 struct IMonitorNode *node = FindMonitorNode(IBase->AmbientScreenMode.ModeID,IntuitionBase);
366 if (node)
368 monitorname = node->MonitorName;
372 #endif
374 sysfont = 1;
375 sharepens = TRUE; /* not sure */
378 if ((pubname = (char*)GetTagData(SA_PubName, 0, tagList)))
380 /* Name of this public screen. */
381 struct PubScreenNode *oldpsn;
382 struct List *list;
384 list = LockPubScreenList();
386 if ((strcmp(pubname, "Workbench") == 0) || workbench)
388 if (IBase->WorkBench)
390 ok = FALSE;
393 workbench = TRUE;
395 else
397 /* jDc: LockPubScreen is not safe here as it does not lock
398 screens in private state so we could end up with two
399 screens with the same name */
400 oldpsn = (struct PubScreenNode *)FindName(list,(UBYTE*)pubname);
402 if (oldpsn)
404 SetError(OSERR_PUBNOTUNIQUE);
405 ok = FALSE;
409 UnlockPubScreenList();
411 if (ok)
413 screen->pubScrNode = AllocMem(sizeof(struct PubScreenNode), MEMF_CLEAR);
415 DEBUG_OPENSCREEN(dprintf("OpenScreen: pubScrNode 0x%lx\n",screen->pubScrNode));
417 if (screen->pubScrNode == NULL)
419 SetError(OSERR_NOMEM);
420 ok = FALSE;
423 if (ok && (screen->pubScrNode->psn_Node.ln_Name = AllocVec(MAXPUBSCREENNAME + 1,MEMF_ANY)))
425 UBYTE sigbit;
427 if ((ns.Type & SCREENTYPE) == CUSTOMSCREEN)
429 ns.Type &= ~SCREENTYPE;
430 ns.Type |= PUBLICSCREEN;
433 /* Always open public screens in private mode. */
434 screen->pubScrNode->psn_Flags |= PSNF_PRIVATE;
435 strcpy(screen->pubScrNode->psn_Node.ln_Name, pubname);
437 /* Task that should be signalled when the public screen loses
438 its last visitor window. */
440 screen->pubScrNode->psn_SigTask = (struct Task *)GetTagData(SA_PubTask, 0, tagList);
442 /* Signal bit number to use when signalling public screen
443 signal task. */
445 sigbit = GetTagData(SA_PubSig,(ULONG)-1,tagList);
447 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubSig 0x%lx\n",sigbit));
449 if (sigbit != (UBYTE)-1)
451 if (!screen->pubScrNode->psn_SigTask) screen->pubScrNode->psn_SigTask = FindTask(NULL);
452 screen->pubScrNode->psn_SigBit = sigbit;
454 else
456 /* do not signal with -1 ! */
457 screen->pubScrNode->psn_SigTask = NULL;
460 else
462 SetError(OSERR_NOMEM);
463 FreeMem(screen->pubScrNode, sizeof(struct PubScreenNode));
464 screen->pubScrNode = NULL;
465 ok = FALSE;
471 #ifdef SKINS
472 if (modeid != INVALID_ID)
474 /* modes can be on other monitors */
475 monitorname = NULL;
477 #endif
479 while((tag = NextTagItem ((struct TagItem **)&tagList)))
481 #if 1
482 DEBUG_OPENSCREEN(dprintf("OpenScreen: Tag 0x%08lx Data 0x%08lx\n",
483 tag->ti_Tag, tag->ti_Data));
484 #endif
485 switch(tag->ti_Tag)
487 case SA_CompositingFlags:
488 compflags = tag->ti_Data;
489 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_CompositingFlags 0x%p\n", compflags));
490 break;
491 case SA_AlphaPreCompositingHook:
492 compalphahook = (struct Hook *)tag->ti_Data;
493 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AlphaPreCompositingHook 0x%p\n", compalphahook));
494 break;
495 case SA_Left:
496 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Left %ld\n",tag->ti_Data));
497 ns.LeftEdge = tag->ti_Data;
498 break;
499 case SA_Top:
500 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Top %ld\n",tag->ti_Data));
501 ns.TopEdge = tag->ti_Data;
502 break;
503 case SA_Width:
504 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Width %ld\n",tag->ti_Data));
505 if ((tag->ti_Data != ~0) && (tag->ti_Data > 32767))
507 ok = FALSE;
509 ns.Width = tag->ti_Data;
510 break;
511 case SA_Height:
512 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Height %ld\n",tag->ti_Data));
513 if ((tag->ti_Data != ~0) && (tag->ti_Data > 32767))
515 ok = FALSE;
517 ns.Height = tag->ti_Data;
518 break;
519 case SA_Depth:
520 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Depth %ld\n",tag->ti_Data));
521 ns.Depth = tag->ti_Data;
522 break;
523 case SA_DetailPen:
524 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DetailPen %ld\n",tag->ti_Data));
525 ns.DetailPen = tag->ti_Data;
526 break;
527 case SA_BlockPen:
528 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BlockPen %ld\n",tag->ti_Data));
529 ns.BlockPen = tag->ti_Data;
530 break;
531 case SA_Type:
532 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Type 0x%lx\n",tag->ti_Data));
533 ns.Type &= ~SCREENTYPE;
534 ns.Type |= tag->ti_Data;
535 break;
537 case SA_Title:
538 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Title <%s>\n",tag->ti_Data));
539 ns.DefaultTitle = (UBYTE *)tag->ti_Data;
540 break;
542 case SA_Font:
543 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Font 0x%lx\n",tag->ti_Data));
544 ns.Font = (struct TextAttr *)tag->ti_Data;
545 break;
547 case SA_Colors32:
548 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors32 0x%lx\n",tag->ti_Data));
549 colors32 = (ULONG *)tag->ti_Data;
550 break;
552 case SA_Colors:
553 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors 0x%lx\n",tag->ti_Data));
554 colors = (struct ColorSpec *)tag->ti_Data;
555 break;
557 case SA_SysFont:
558 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SysFont 0x%lx\n",tag->ti_Data));
559 sysfont = (WORD)tag->ti_Data;
560 break;
562 case SA_BitMap:
563 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap 0x%lx\n",tag->ti_Data));
564 if(tag->ti_Data)
566 ns.Type |= CUSTOMBITMAP;
567 ns.CustomBitMap = (struct BitMap *)tag->ti_Data;
569 else
571 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap==NULL specified, custom BitMap use disabled\n"));
573 break;
575 case SA_BackFill:
576 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackFill Hook 0x%lx\n",tag->ti_Data));
577 layer_info_hook = (struct Hook *)tag->ti_Data;
578 break;
580 case SA_Quiet:
581 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Quiet 0x%lx\n",tag->ti_Data));
582 if (tag->ti_Data)
584 ns.Type |= SCREENQUIET;
586 else
588 ns.Type &= ~SCREENQUIET;
590 break;
592 case SA_ShowTitle:
593 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ShowTitle 0x%lx\n",tag->ti_Data));
594 if (tag->ti_Data)
596 ns.Type |= SHOWTITLE;
598 else
600 ns.Type &= ~SHOWTITLE;
602 break;
604 case SA_Pens:
605 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Pens 0x%lx\n",tag->ti_Data));
606 customdripens = (UWORD *)tag->ti_Data;
607 break;
609 case SA_SharePens:
610 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SharePens 0x%lx\n",tag->ti_Data));
611 sharepens = tag->ti_Data ? TRUE : FALSE;
612 if (tag->ti_Data)
614 ns.Type |= PENSHARED;
615 } else {
616 ns.Type &= ~PENSHARED;
618 break;
620 case SA_Interleaved:
621 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Interleaved 0x%lx\n",tag->ti_Data));
622 if (tag->ti_Data)
624 allocbitmapflags |= BMF_INTERLEAVED;
626 else
628 allocbitmapflags &= ~BMF_INTERLEAVED;
630 break;
632 case SA_Behind:
633 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Behind 0x%lx\n",tag->ti_Data));
634 if (tag->ti_Data)
636 ns.Type |= SCREENBEHIND;
638 else
640 ns.Type &= ~SCREENBEHIND;
642 break;
644 case SA_DClip:
645 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DClip 0x%lx\n",tag->ti_Data));
646 dclip = (struct Rectangle *)tag->ti_Data;
647 break;
649 case SA_Overscan:
650 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_OverScan 0x%lx\n",tag->ti_Data));
651 overscan = tag->ti_Data;
652 break;
654 case SA_DisplayID:
655 case SA_LikeWorkbench:
656 case SA_ErrorCode:
657 case SA_PubName:
658 case SA_PubSig:
659 case SA_PubTask:
661 * handled elsewhere
663 break;
665 case SA_AutoScroll:
666 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AutoScroll 0x%lx\n",tag->ti_Data));
667 if (tag->ti_Data)
669 ns.Type |= AUTOSCROLL;
671 else
673 ns.Type &= ~AUTOSCROLL;
675 break;
677 case SA_FullPalette:
678 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FullPalette 0x%lx\n",tag->ti_Data));
679 break;
680 case SA_ColorMapEntries:
681 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ColorMapEntries 0x%lx\n",tag->ti_Data));
682 numcolors = tag->ti_Data; /* AROS: Added support for this tag */
683 break;
684 case SA_Parent:
685 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Parent 0x%lx\n",tag->ti_Data));
686 break;
687 case SA_Draggable:
688 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Draggable 0x%lx\n",tag->ti_Data));
689 draggable = tag->ti_Data; /* AROS: Added support for this tag */
690 break;
691 case SA_Exclusive:
692 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Exclusive 0x%lx\n",tag->ti_Data));
693 break;
694 case SA_VideoControl:
695 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_VideoControl 0x%lx\n",tag->ti_Data));
696 vctl = tag->ti_Data; /* AROS: Added support for this tag */
697 break;
698 case SA_FrontChild:
699 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FrontChild 0x%lx\n",tag->ti_Data));
700 break;
701 case SA_BackChild:
702 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackChild 0x%lx\n",tag->ti_Data));
703 break;
704 case SA_MinimizeISG:
705 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_MinimizeISG 0x%lx\n",tag->ti_Data));
706 break;
708 case SA_MonitorName:
709 monitorname = (char*)tag->ti_Data;
710 break;
711 #ifndef __AROS__ /* AROS: Disable MorphOS-specific extensions and private stuff */
712 case SA_SkinName: /* TODO: Complete support for named skins and enable this tag. Value needed. */
713 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SkinName (%s)\n",(char *)tag->ti_Data));
714 skinname = (char *)tag->ti_Data;
715 break;
717 case SA_VesaFallback:
718 vesafallback = tag->ti_Data;
719 break;
721 case SA_ModeEditControl:
722 modecontrol = (ULONG*)tag->ti_Data;
723 break;
725 case SA_WindowLock: /* TODO: We also can support this private tag. In which situations we don't need locking ? */
726 dowindowlock = tag->ti_Data ? TRUE : FALSE;
727 break;
729 case SA_CompositingLayers:
730 compositing = tag->ti_Data ? TRUE : FALSE;
731 break;
732 #endif
733 case SA_ShowPointer:
734 showpointer = tag->ti_Data ? TRUE : FALSE;
735 break;
737 case SA_GammaControl:
738 gammacontrol = tag->ti_Data ? TRUE : FALSE;
739 break;
741 case SA_GammaRed:
742 gammared = (UBYTE*)tag->ti_Data;
743 break;
745 case SA_GammaBlue:
746 gammablue = (UBYTE*)tag->ti_Data;
747 break;
749 case SA_GammaGreen:
750 gammagreen = (UBYTE*)tag->ti_Data;
751 break;
753 case SA_3DSupport:
754 support3d = tag->ti_Data ? TRUE : FALSE;
755 break;
757 case SA_AdaptSize:
758 adaptsize = tag->ti_Data ? TRUE : FALSE;
759 break;
761 case SA_DisplayWidth:
762 displaywidth = (ULONG)tag->ti_Data;
763 break;
765 case SA_DisplayHeight:
766 displayheight = (ULONG)tag->ti_Data;
767 break;
769 case SA_ExactMatchMonitorName:
770 exactname = tag->ti_Data ? TRUE : FALSE;
771 break;
773 /* TODO: Missing SA_ Tags */
774 default:
775 DEBUG_OPENSCREEN(dprintf("OpenScreen: unknown tag 0x%lx data 0x%lx\n",
776 tag->ti_Tag,
777 tag->ti_Data));
778 break;
780 } /* switch (tag->ti_Tag) */
782 } /* while ((tag = NextTagItem (&tagList))) */
784 } /* if (tagList) */
786 DEBUG_OPENSCREEN(dprintf("OpenScreen: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
787 ns.LeftEdge, ns.TopEdge, ns.Width, ns.Height, ns.Depth, tagList));
789 requesteddepth = ns.Depth;
791 /* Fail if bogus size is requested - Piru/jDc */
792 if ((ns.Width < -1) || (ns.Height < -1))
794 DEBUG_OPENSCREEN(dprintf("!!! OpenScreen(): Width and/or Height negative !!!\n");)
795 ok = FALSE;
798 /* First Init the RastPort then get the BitPlanes!! */
800 #ifdef __MORPHOS__
801 #include "workaround.openscreen.c"
802 #endif
803 /* AROS: Use 3D support code */
804 if (support3d)
806 struct IMonitorNode *node = NULL;
807 ULONG depth = (ULONG)-1;
809 #ifndef __AROS__
810 /*AROS: We don't need these flags because we keep ModeID together with the BitMap */
811 screen->Support3D = TRUE;
812 allocbitmapflags |= BMF_3DTARGET;
813 #endif
814 /* check for SA_DisplayID or SA_MonitorName, this can also return other monitor
815 within the same class of monitors (ex radeon7k instead of 9k) */
816 if (monitorname || (modeid != INVALID_ID))
818 DEBUG_OPENSCREEN(dprintf("OpenScreen: 3d hunt modeid 0x%lx monname %s\n",modeid,monitorname ? monitorname : "none"));
819 node = FindBestMonitorNode(NULL,monitorname,modeid,IntuitionBase);
820 if (node) depth = FindBest3dDepth(ns.Depth,node,IntuitionBase);
823 /* no suitable depth? find a monitor with best 3d capabilities */
824 if ((depth == (ULONG)-1) && !exactname)
826 DEBUG_OPENSCREEN(dprintf("OpenScreen: found no suitable depth. monnode 0x%lx\n",node));
827 node = FindBest3dMonitor(NULL,IntuitionBase);
828 if (node) depth = FindBest3dDepth(ns.Depth,node,IntuitionBase);
831 /* found a usable depth? find a modeid with that depth within the monitor we found */
832 if (depth != (ULONG)-1)
834 DEBUG_OPENSCREEN(dprintf("OpenScreen: found suitable depth %d. monnode 0x%lx\n",depth,node));
835 ns.Depth = depth;
837 modeid = FindBestModeID(node->MonitorName,ns.Depth,(displaywidth) ? displaywidth : ns.Width,(displayheight) ? displayheight : ns.Height,IntuitionBase);
839 if (modeid == INVALID_ID)
841 DEBUG_OPENSCREEN(dprintf("OpenScreen: no 3d available, fail (1)!\n"));
842 ok = FALSE;
844 } else {
845 /* whoops, no 3d support at all, fail! */
846 DEBUG_OPENSCREEN(dprintf("OpenScreen: no 3d available, fail! (2)\n"));
847 ok = FALSE;
851 else if (monitorname)
853 ULONG newmodeid = INVALID_ID;
854 newmodeid = FindBestModeID(monitorname,ns.Depth,(displaywidth) ? displaywidth : ns.Width,(displayheight) ? displayheight : ns.Height,IntuitionBase);
855 if (newmodeid != INVALID_ID) modeid = newmodeid;
856 /* monitor not available and exactmatch requested ? */
857 if (exactname)
859 if (newmodeid == INVALID_ID)
861 dprintf("uhuh, no modeid!\n");
862 ok = FALSE;
864 else
866 // make sure this is the same monitor!
867 struct IMonitorNode *node = FindMonitorNode(newmodeid,IntuitionBase);
868 if (!node || strcmp(node->MonitorName,monitorname)) ok = FALSE;
871 DEBUG_OPENSCREEN(dprintf("OpenScreen: monname %s modeid %lx\n",monitorname,modeid));
874 #ifdef __MORPHOS__
875 /* Note: CGX patched ModeNotAvailable() alone doesn't return reliable results due to some fallback code for old apps. - Piru */
876 if ((modeid == INVALID_ID) || ModeNotAvailable(modeid) || !FindDisplayInfo(modeid))
878 struct TagItem bestmodetags[] =
880 {CYBRBIDTG_Depth,0},
881 {CYBRBIDTG_NominalWidth,0},
882 {CYBRBIDTG_NominalHeight,0},
883 {TAG_DONE}
886 if((modeid & 0xF00F0000) == 0x40020000)
888 modeid &= 0x40020000;
891 bestmodetags[0].ti_Data = (ns.Depth < 8) ? 8 : ns.Depth; /* jDc: helps finding a correct mode ;)*/
892 bestmodetags[1].ti_Data = (displaywidth) ? displaywidth : ns.Width;
893 bestmodetags[2].ti_Data = (displayheight) ? displayheight : ns.Height;
895 DEBUG_OPENSCREEN(dprintf("ns.Width %ld ns.Height %ld ns.Depth %ld !!\n",
896 (LONG) ns.Width, (LONG) ns.Height, (LONG) ns.Depth);)
898 modeid = BestCModeIDTagList(bestmodetags);
900 DEBUG_OPENSCREEN(dprintf("BestCModeIDTagList returned %ld\n",modeid);)
902 #endif
904 #ifdef SKINS
905 if ((workbench) && (IBase->EmergencyBoot.monitorname))
907 struct IMonitorNode *node;
908 ULONG depthid;
909 ULONG newmodeid;
911 node = FindBestMonitorNode(GetMonitorClass(IBase->EmergencyBoot.monitorname,IntuitionBase),IBase->EmergencyBoot.monitorname,INVALID_ID,IntuitionBase);
913 newmodeid = FakeWorkbenchMode(node,(ULONG*)&depthid,IBase->EmergencyBoot.baseresolution,IntuitionBase);
915 DEBUG_OPENSCREEN(dprintf("OpenScreen: Emergency Boot! %lx\n",modeid));
917 if (newmodeid != INVALID_ID)
919 modeid = newmodeid;
920 ns.Width = IBase->EmergencyBoot.baseresolution;
922 switch (ns.Width)
924 case 800:
925 ns.Height = 600;
926 break;
928 case 1024:
929 ns.Height = 768;
930 break;
932 default:
933 ns.Width = 640;
934 ns.Height = 480;
937 screen->VESAMode = ns.Width;
938 screen->VESAModeDepthID = depthid;
942 if (workbench && (((struct IIHData *)IBase->InputHandler->is_Data)->ActQualifier & IEQUALIFIER_CONTROL))
944 vesafallback = 1024;
947 if (vesafallback)
949 struct IMonitorNode *node = NULL;
950 ULONG depthid;
951 ULONG newmodeid;
953 if (monitorname) node = FindBestMonitorNode(GetMonitorClass(monitorname,IntuitionBase),monitorname,INVALID_ID,IntuitionBase);
955 newmodeid = FakeWorkbenchMode(node,(ULONG*)&depthid,vesafallback,IntuitionBase);
957 DEBUG_OPENSCREEN(dprintf("OpenScreen: vesa fallback %lx\n",modeid));
959 if (newmodeid != INVALID_ID)
961 modeid = newmodeid;
962 ns.Width = vesafallback;
964 switch (ns.Width)
966 case 800:
967 ns.Height = 600;
968 break;
970 case 1024:
971 ns.Height = 768;
972 break;
974 default:
975 ns.Width = 640;
976 ns.Height = 480;
979 screen->VESAMode = ns.Width;
980 screen->VESAModeDepthID = depthid;
984 if (modecontrol)
986 struct IMonitorNode *inode = FindMonitorNode(modeid,IntuitionBase);
987 modeid = FakeScreenMode(inode,ns.Depth,IntuitionBase);
989 DEBUG_OPENSCREEN(dprintf("OpenScreen: fake modeid %lx\n",modeid));
991 if (modeid != INVALID_ID)
993 switch (ns.Depth)
995 case 24: screen->VESAModeDepthID = ID_MD24; break;
996 case 16: screen->VESAModeDepthID = ID_MD16; break;
997 case 15: screen->VESAModeDepthID = ID_MD15; break;
998 default: screen->VESAModeDepthID = ID_MD08; break;
1001 screen->ModeControl = modecontrol;
1003 } else {
1004 DEBUG_OPENSCREEN(dprintf("OpenScreen: failed to init testmode!\n"));
1005 ok = FALSE;
1009 #endif
1012 * AROS: Got OpenScreenTags modeid without monitor, promote to chipset default
1013 * (if present).
1014 * We really need proper mode promotion support.
1016 if ((modeid & MONITOR_ID_MASK) == 0)
1018 if (GfxBase->DisplayFlags & PAL)
1019 modeid |= PAL_MONITOR_ID;
1020 else if (GfxBase->DisplayFlags & NTSC)
1021 modeid |= NTSC_MONITOR_ID;
1024 if (INVALID_ID == modeid)
1026 #ifndef __AROS__
1027 WORD bestwidth,bestheight;
1028 #endif
1029 modetags[0].ti_Data = ns.Depth;
1030 modetags[1].ti_Data = ns.Width;
1031 modetags[2].ti_Data = ns.Height;
1032 modetags[3].ti_Data = ns.Width;
1033 modetags[4].ti_Data = ns.Height;
1035 #ifdef __AROS__
1037 * AROS: We don't have FindBestWidthAndHeight().
1038 * TODO: Can we merge better here ?
1040 if (ns.Width == STDSCREENWIDTH || ns.Width == 0 || adaptsize) {modetags[1].ti_Tag = TAG_IGNORE; modetags[3].ti_Tag = TAG_IGNORE;}
1041 if (ns.Height == STDSCREENWIDTH || ns.Height == 0 || adaptsize) {modetags[2].ti_Tag = TAG_IGNORE; modetags[4].ti_Tag = TAG_IGNORE;}
1042 #else
1043 FindBestWidthAndHeight(&bestwidth,&bestheight,ns.Depth,IntuitionBase);
1045 if (ns.Width == STDSCREENWIDTH || ns.Width == 0 || adaptsize) {modetags[1].ti_Data = bestwidth; modetags[3].ti_Data = bestwidth;}
1046 if (ns.Height == STDSCREENWIDTH || ns.Height == 0 || adaptsize) {modetags[2].ti_Data = bestheight;modetags[4].ti_Data = bestheight;}
1048 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));
1049 #endif
1050 /* AROS: Support old-style HAM or EHB request */
1051 if (newScreen->ViewModes & (HAM | EXTRA_HALFBRITE))
1053 if (newScreen->ViewModes & HAM) modetags[5].ti_Data |= DIPF_IS_HAM;
1054 if (newScreen->ViewModes & EXTRA_HALFBRITE) modetags[5].ti_Data |= DIPF_IS_EXTRAHALFBRITE;
1056 else
1058 modetags[5].ti_Tag = TAG_IGNORE;
1061 modeid = BestModeIDA(modetags);
1063 #ifdef SKINS
1064 if (modeid == INVALID_ID && workbench)
1066 ULONG depthid;
1067 ULONG newmodeid = FakeWorkbenchMode(NULL,(ULONG*)&depthid,640,IntuitionBase);
1068 /* create an ID */
1070 DEBUG_OPENSCREEN(dprintf("OpenScreen: Vesa Fallback!\n"));
1072 if (newmodeid != INVALID_ID)
1074 modeid = newmodeid;
1075 ns.Width = 640;
1076 ns.Height = 480;
1078 screen->VESAMode = 640;
1079 screen->VESAModeDepthID = depthid;
1082 #endif
1084 if (INVALID_ID == modeid)
1086 // wtf? no monitors??
1087 D(bug("!!! OpenScreen(): Could not find any valid modeids. No graphics card? !!!\n"));
1088 SetError(OSERR_UNKNOWNMODE); /* AROS: Added error core setting, fixed MorphOS bug */
1089 ok = FALSE;
1093 DEBUG_OPENSCREEN(dprintf("OpenScreen: ModeID 0x%08lx\n", modeid));
1095 InitRastPort(&screen->Screen.RastPort);
1096 rp_inited = TRUE;
1097 success = FALSE;
1099 if (ok && (displayinfo = FindDisplayInfo(modeid)) != NULL &&
1100 GetDisplayInfoData(displayinfo, (APTR)&dimensions, sizeof(dimensions), DTAG_DIMS, modeid)
1101 #ifdef __AROS__ /* AROS: We don't need MonitorSpec, however we get DisplayInfo early to get the compositors bm hooks. */
1102 && GetDisplayInfoData(displayinfo, (APTR)&dispinfo, sizeof(dispinfo), DTAG_DISP, modeid)
1103 #else
1104 && GetDisplayInfoData(displayinfo, (APTR)&monitor, sizeof(monitor), DTAG_MNTR, modeid)
1105 #endif
1108 success = TRUE;
1109 #ifdef __AROS__ /* AROS: Get HIDD composition flags */
1110 screen->SpecialFlags = ((compflags & (dimensions.reserved[0] >> 16)) | (dimensions.reserved[0] & 0xFFFF)) << 8;
1111 screen->preAlphaCompHook = compalphahook;
1113 if (draggable) screen->SpecialFlags |= SF_Draggable;
1114 #else
1115 screen->Monitor = monitor.Mspc;
1116 #endif
1117 if (dclip == NULL)
1119 switch (overscan)
1121 case OSCAN_STANDARD:
1122 dclip = &dimensions.StdOScan;
1123 break;
1125 case OSCAN_MAX:
1126 dclip = &dimensions.MaxOScan;
1127 break;
1129 case OSCAN_VIDEO:
1130 dclip = &dimensions.VideoOScan;
1131 break;
1133 default:
1134 dclip = &dimensions.TxtOScan;
1135 break;
1139 if (ns.Width == STDSCREENWIDTH || ns.Width == 0 || adaptsize)
1140 ns.Width = dclip->MaxX - dclip->MinX + 1;
1141 /* AROS: Added raster size limit support */
1142 else if (ns.Width < dimensions.MinRasterWidth)
1143 ns.Width = dimensions.MinRasterWidth;
1144 else if (ns.Width > dimensions.MaxRasterWidth)
1145 ns.Width = dimensions.MaxRasterWidth;
1147 if (ns.Height == STDSCREENHEIGHT || ns.Height == 0 || adaptsize)
1148 ns.Height = dclip->MaxY - dclip->MinY + 1;
1149 /* AROS: Added raster size limit support */
1150 else if (ns.Height < dimensions.MinRasterHeight)
1151 ns.Height = dimensions.MinRasterHeight;
1152 else if (ns.Height > dimensions.MaxRasterHeight)
1153 ns.Height = dimensions.MaxRasterHeight;
1155 #ifndef __AROS__
1156 DEBUG_OPENSCREEN(dprintf("OpenScreen: Monitor 0x%lx Width %ld Height %ld\n",
1157 screen->Monitor, ns.Width, ns.Height));
1158 #endif
1160 if (ns.Type & CUSTOMBITMAP)
1162 struct BitMap *custombm;
1163 custombm = ns.CustomBitMap;
1164 #ifdef __AROS__ /* AROS: We don't have CGX in kickstart */
1165 /* FIXME: m68k Compositor needs to report that it can composit planar bitmaps */
1166 BOOL (*__IsCompositable) (struct BitMap *, DisplayInfoHandle, struct GfxBase *) = (APTR)dispinfo.reserved[0];
1167 BOOL (*__MakeDisplayable) (struct BitMap *, DisplayInfoHandle, struct GfxBase *) = (APTR)dispinfo.reserved[1];
1169 if (dispinfo.reserved[0])
1171 if (__IsCompositable(custombm, displayinfo, GfxBase))
1173 DEBUG_OPENSCREEN(dprintf("OpenScreen: Marking CustomBitMap 0x%lx as compositable\n", custombm));
1174 __MakeDisplayable(custombm, displayinfo, GfxBase);
1176 else
1178 custombm = NULL;
1181 else if ((!IS_HIDD_BM(custombm)) || (modeid != HIDD_BM_HIDDMODE(custombm)))
1183 custombm = NULL;
1185 #else
1186 if (IsCyberModeID(modeid) && custombm)
1188 int pixfmt = GetCyberIDAttr(CYBRIDATTR_PIXFMT,modeid);
1190 if(GetCyberMapAttr(custombm,CYBRMATTR_PIXFMT) != pixfmt)
1192 // incompatible formats !
1193 custombm = NULL;
1196 #endif
1197 if(custombm != NULL)
1199 screen->Screen.RastPort.BitMap = custombm;
1200 ns.Depth = GetBitMapAttr(ns.CustomBitMap,BMA_DEPTH);
1201 DEBUG_OPENSCREEN(dprintf("OpenScreen: CustomBitMap Depth %ld\n",
1202 ns.Depth));
1203 } else {
1204 ns.CustomBitMap = NULL;
1205 ns.Type &= ~CUSTOMBITMAP;
1207 } else {
1208 screen->Screen.RastPort.BitMap = NULL;
1211 if ((screen->IMonitorNode = FindMonitorNode(modeid,IntuitionBase)))
1213 DEBUG_OPENSCREEN(dprintf("OpenScreen: MonitorNode 0x%lx\n",
1214 screen->IMonitorNode));
1215 } else {
1216 DEBUG_OPENSCREEN(dprintf("OpenScreen: No MonitorNode\n"));
1217 ok = FALSE;
1220 if(ok && (screen->Screen.RastPort.BitMap == NULL))
1222 #ifdef __AROS__ /* AROS: BitMap needs ModeID */
1223 ULONG Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : ns.Depth;
1224 struct TagItem bmtags[] =
1226 {BMATags_DisplayID, modeid},
1227 {TAG_DONE , 0 }
1230 screen->Screen.RastPort.BitMap = AllocBitMap(ns.Width, ns.Height, Depth,
1231 allocbitmapflags | BMF_CHECKVALUE,
1232 (struct BitMap *)bmtags);
1233 #else
1234 struct BitMap *root = NULL;
1235 ULONG pixfmt;
1236 ULONG Depth;
1237 int retrycnt=1;
1238 ULONG stdwidth = dimensions.Nominal.MaxX - dimensions.Nominal.MinX + 1;
1239 ULONG stdheight = dimensions.Nominal.MaxY - dimensions.Nominal.MinY + 1;
1241 #ifdef USE8BITHACK
1242 Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : 8;
1243 #else
1244 Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : ns.Depth;
1245 #endif
1247 switch(Depth)
1249 case 15:
1250 pixfmt = PIXFMT_RGB15;
1251 break;
1252 case 16:
1253 pixfmt = PIXFMT_RGB16;
1254 break;
1255 case 24:
1256 pixfmt = PIXFMT_BGR24;
1257 break;
1258 case 32:
1259 pixfmt = PIXFMT_ARGB32;
1260 break;
1261 default:
1262 pixfmt = PIXFMT_LUT8;
1263 break;
1266 if (IsCyberModeID(modeid))
1268 pixfmt = GetCyberIDAttr(CYBRIDATTR_PIXFMT,modeid);
1271 DoMethod((Object*)screen->IMonitorNode,MM_GetRootBitMap,pixfmt,(ULONG)&root);
1273 DEBUG_OPENSCREEN(dprintf("OpenScreen: root BitMap 0x%lx\n",root));
1277 allocbitmapflags &= (BMF_DISPLAYABLE | BMF_INTERLEAVED | BMF_3DTARGET);
1279 if(root == NULL)
1281 allocbitmapflags |= (BMF_SPECIALFMT|/*BMF_CLEAR|*/BMF_DISPLAYABLE|BMF_MINPLANES);
1282 allocbitmapflags |= SHIFT_PIXFMT(pixfmt);
1284 else
1286 allocbitmapflags |= (/*BMF_CLEAR|*/BMF_DISPLAYABLE|BMF_MINPLANES);
1289 if((screen->Screen.RastPort.BitMap = AllocBitMap((ns.Width > stdwidth) ? ns.Width : stdwidth,
1290 (ns.Height > stdheight) ? ns.Height : stdheight,
1291 Depth,
1292 allocbitmapflags,
1293 root)) == NULL)
1295 root = NULL;
1298 while((screen->Screen.RastPort.BitMap == NULL) && (retrycnt--));
1299 #endif
1300 screen->AllocatedBitMap = screen->Screen.RastPort.BitMap;
1302 DEBUG_OPENSCREEN(dprintf("OpenScreen: allocated BitMap 0x%lx\n",screen->AllocatedBitMap));
1304 if (screen->Screen.RastPort.BitMap)
1306 UpdateScreenBitMap(&screen->Screen, IntuitionBase);
1307 #ifndef __AROS__
1309 * AROS: This seems to be not needed
1310 * TODO: Check if this is really true, test case needed
1312 if (Depth > 8)
1314 if (stdwidth > ns.Width)
1316 struct RastPort rport;
1318 InitRastPort(&rport);
1319 rport.BitMap = screen->AllocatedBitMap;
1320 SetRPAttrs(&rport,RPTAG_PenMode,FALSE,RPTAG_FgColor,0x0,TAG_DONE);
1322 RectFill(&rport,ns.Width,0,stdwidth - 1,ns.Height - 1);
1325 if (stdheight > ns.Height)
1327 struct RastPort rport;
1329 InitRastPort(&rport);
1330 rport.BitMap = screen->AllocatedBitMap;
1331 SetRPAttrs(&rport,RPTAG_PenMode,FALSE,RPTAG_FgColor,0x0,TAG_DONE);
1333 RectFill(&rport,0,ns.Height,ns.Width - 1,stdheight - 1);
1336 #endif
1340 DEBUG_OPENSCREEN(dprintf("OpenScreen: BitMap 0x%lx\n",
1341 screen->Screen.RastPort.BitMap));
1343 else
1345 DEBUG_OPENSCREEN(dprintf("OpenScreen: no displayinfo\n"));
1346 SetError(OSERR_UNKNOWNMODE); /* AROS: Added error code setting, fixed MorphOS bug */
1349 D(bug("got BitMap\n"));
1351 /* Init screen's viewport */
1352 InitVPort(&screen->Screen.ViewPort);
1354 /* Allocate a RasInfo struct in which we have a pointer
1355 to the struct BitMap, into which the driver can
1356 store its stuff. (Eg. pointer to a BitMap HIDD object)
1358 screen->Screen.ViewPort.RasInfo = AllocMem(sizeof(struct RasInfo), MEMF_ANY | MEMF_CLEAR);
1360 DEBUG_OPENSCREEN(dprintf("OpenScreen: RasInfo 0x%lx\n",
1361 screen->Screen.ViewPort.RasInfo));
1363 if (!success ||
1364 (screen->Screen.RastPort.BitMap == NULL) ||
1365 (screen->Screen.ViewPort.RasInfo == NULL))
1367 ok = FALSE;
1368 } else {
1369 /* Store pointer to BitMap, so we can get hold of it
1370 from withing LoadRGBxx() functions
1372 D(bug("got allocated stuff\n"));
1373 screen->Screen.ViewPort.RasInfo->BitMap = screen->Screen.RastPort.BitMap;
1376 if (ok)
1378 /* Read depth from the BitMap to avoid AttachPalExtra/ObtainPen getting
1379 * confused if cgx decided to allocate a higher depth BitMap than what
1380 * was asked.
1382 ns.Depth = GetBitMapAttr(screen->Screen.RastPort.BitMap,BMA_DEPTH);
1384 if (!numcolors) /* AROS: Added support for SA_ColorMapEntries */
1386 #ifdef USE8BITHACK
1387 numcolors = 256;
1388 #else
1389 numcolors = (ns.Depth <= 8) ? (1L << ns.Depth) : 256;
1390 #endif
1393 /* Get a color map structure. Sufficient colors?? */
1395 DEBUG_OPENSCREEN(dprintf("OpenScreen: Colormap Entries %ld\n",
1396 numcolors));
1397 if ((screen->Screen.ViewPort.ColorMap = GetColorMap(numcolors < 32 ? 32 : numcolors)) != NULL)
1399 if (0 == AttachPalExtra(screen->Screen.ViewPort.ColorMap,
1400 &screen->Screen.ViewPort))
1402 #if 0
1403 int i=0;
1404 char *alloclist;
1405 UWORD *refcnt;
1407 refcnt =(UWORD*) screen->Screen.ViewPort.ColorMap->PalExtra->pe_RefCnt;
1408 alloclist = (UBYTE *)(refcnt + screen->Screen.ViewPort.ColorMap->Count);
1410 DEBUG_OPENSCREEN(dprintf("OpenScreen: PalExtra alloclist 0x%lx Count %ld\n",alloclist,screen->Screen.ViewPort.ColorMap->Count));
1412 while(i < screen->Screen.ViewPort.ColorMap->Count)
1414 // initialize alloc list to -1,0,1,2,3,4
1416 DEBUG_OPENSCREEN(dprintf("OpenScreen: alloclist[%ld]=%ld\n",
1417 i,alloclist[i]));
1418 i++;
1420 #endif
1422 else
1424 ok = FALSE;
1427 else
1429 ok = FALSE;
1432 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%lx\n",
1433 screen->Screen.ViewPort.ColorMap));
1436 #ifdef __MORPHOS__
1439 ULONG pixfmt = -1;
1440 APTR handle = LockBitMapTags(screen->Screen.RastPort.BitMap,
1441 LBMI_PIXFMT,(ULONG)&pixfmt,TAG_DONE);
1443 if (handle)
1445 UnLockBitMap(handle);
1446 screen->PixelFormat = pixfmt;
1448 else
1450 screen->PixelFormat = -1;
1453 #endif
1454 screen->GammaControl.UseGammaControl = gammacontrol;
1455 screen->GammaControl.GammaTableR = gammared;
1456 screen->GammaControl.GammaTableG = gammagreen;
1457 screen->GammaControl.GammaTableB = gammablue;
1458 #ifndef __AROS__
1460 * AROS: This fragment seems to delay-load default gamma table for the monitor.
1461 * TODO: May be use this approach ?
1463 if (screen->IMonitorNode && !screen->IMonitorNode->GammaLoaded)
1465 int_SkinAction(SKA_LoadGamma,(ULONG *)screen->IMonitorNode,NULL,IntuitionBase);
1466 screen->IMonitorNode->GammaLoaded = TRUE;
1469 // no hotkey by default
1470 screen->RecallHotkey.ia_Key = 0xFF;
1471 #endif
1472 screen->ModeID = modeid;
1474 if (ok)
1476 struct ViewPortExtra *vpe = (struct ViewPortExtra *)GfxNew(VIEWPORT_EXTRA_TYPE);
1478 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPortExtra 0x%lx\n", vpe));
1480 ok = FALSE;
1482 if (vpe)
1484 struct TagItem tags[6];
1486 memcpy(&vpe->DisplayClip, dclip,sizeof(struct Rectangle));
1487 #ifdef __AROS__
1489 * AROS: Set ViewPort offset and get size from dclip.
1490 * CHECKME: MorphOS source code always sets ViewPort's DWidth and DHeight to
1491 * nominal size, while ViewPortExtra's DisplayClip is still set to OverScan
1492 * rectangle. Whose approach is correct ?
1494 screen->Screen.ViewPort.DxOffset = ns.LeftEdge;
1495 screen->Screen.ViewPort.DyOffset = ns.TopEdge;
1496 screen->Screen.ViewPort.DWidth = dclip->MaxX - dclip->MinX + 1;
1497 screen->Screen.ViewPort.DHeight = dclip->MaxY - dclip->MinY + 1;
1498 #else
1499 /* using vpe data for vesamode/modecontrol is not a good idea since the mode
1500 is changed on the fly and the actual data might not be what we'll use */
1502 if (screen->VESAMode)
1504 screen->Screen.ViewPort.DWidth = screen->VESAMode;
1506 switch (screen->VESAMode)
1508 case 800:
1509 screen->Screen.ViewPort.DHeight = 600;
1510 break;
1512 case 1024:
1513 screen->Screen.ViewPort.DHeight = 768;
1514 break;
1516 default:
1517 screen->Screen.ViewPort.DWidth = 640;
1518 screen->Screen.ViewPort.DHeight = 480;
1521 screen->VESAMode = ns.Width;
1522 } else if (screen->ModeControl) {
1523 screen->Screen.ViewPort.DWidth = ns.Width;
1524 screen->Screen.ViewPort.DHeight = ns.Height;
1525 } else {
1526 ULONG stdwidth = dimensions.Nominal.MaxX - dimensions.Nominal.MinX + 1;
1527 ULONG stdheight = dimensions.Nominal.MaxY - dimensions.Nominal.MinY + 1;
1529 screen->Screen.ViewPort.DWidth = min(ns.Width,stdwidth);
1530 screen->Screen.ViewPort.DHeight = min(ns.Height,stdheight);
1532 #endif
1533 tags[0].ti_Tag = VTAG_ATTACH_CM_SET;
1534 tags[0].ti_Data = (IPTR)&screen->Screen.ViewPort;
1535 tags[1].ti_Tag = VTAG_VIEWPORTEXTRA_SET;
1536 tags[1].ti_Data = (IPTR)vpe;
1537 tags[2].ti_Tag = VTAG_NORMAL_DISP_SET;
1538 tags[2].ti_Data = (IPTR)displayinfo;
1539 tags[3].ti_Tag = VTAG_VPMODEID_SET;
1540 tags[3].ti_Data = modeid;
1541 tags[4].ti_Tag = VTAG_SPEVEN_BASE_SET; /* AROS: Added sprite base and user-supplied tags */
1542 tags[5].ti_Tag = VTAG_NEXTBUF_CM; /* if vctl is 0, this will terminate the list */
1543 tags[5].ti_Data = vctl;
1546 * Originally we could always use palette entries 16-19 for
1547 * sprites, even if the screen has less than 32 colors. AROS may
1548 * run on hardware that does not allow this (e.g. VGA cards).
1549 * In this case we have to shift down sprite colors. Currently
1550 * we use 4 colors before last 4 colors. For example on VGA cards
1551 * with only 16 colors we use colors 9 - 12. Remember that last 4 colors
1552 * of the screen are always used by Intuition.
1553 * Remember that the first color of the sprite is always transparent. So actually
1554 * we use 3, not 4 colors.
1555 * Yes, sprites may look not as expected on screens with low color depth, but at
1556 * least they will be seen. It's better than nothing.
1558 * Note that because our base color number doesn't always divide by 16, we use MSB to store
1559 * the remainder (offset in the color bank). Yes, it's a bit hacky, but i have no better idea
1560 * at the moment.
1562 * FIXME: this mapping scheme assumes that we always have at least 16 colors.
1563 * For current display modes supported by AROS it's always true, but in future
1564 * we may support more display modes (for example monochrome ones), and we
1565 * should take into account that on screens with less than 11 colors this simply
1566 * won't work
1568 * TODO: I think we should have SpriteBase attribute for the BitMap which
1569 * defaults to acceptable value. We should just get its default value here.
1570 * The same attribute would be set by VideoControl() and MakeVPort() in order
1571 * to actually apply the value.
1573 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
1574 spritebase = 16;
1575 #else
1576 spritebase = (ns.Depth < 5) ? (1 << ns.Depth) - 8 : 16;
1577 #endif
1578 DEBUG_OPENSCREEN(bug("OpenScreen: spritebase is %u\n", spritebase));
1579 tags[4].ti_Data = ((spritebase & 0x0F) << 8 ) | (spritebase >> 4);
1581 if (VideoControl(screen->Screen.ViewPort.ColorMap, tags) == 0)
1583 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl ok\n"));
1584 ok = TRUE;
1586 else
1588 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl failed\n"));
1593 if (ok)
1595 struct Color32 *p;
1596 int k;
1597 UWORD *q;
1599 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set first 4 colors\n"));
1601 p = IBase->Colors;
1602 for (k = 0; k < 4 && k < numcolors; ++k)
1604 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB32 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1605 screen->Screen.ViewPort,
1606 k, p[k].red, p[k].green, p[k].blue));
1607 SetRGB32(&screen->Screen.ViewPort, k, p[k].red, p[k].green, p[k].blue);
1610 if (ns.Depth >= 3)
1613 * AROS: Use screen depth instead of 'numcolors' in order to calculate
1614 * numbers of last 4 colors of the screen.
1615 * This is necessary because we can have 8- or 16- color screen whose
1616 * ColorMap will still have 32 colors for AmigaOS(tm) compatibility
1617 * reasons.
1619 ULONG lastcol = ((ns.Depth > 8) ? 256 : (1 << ns.Depth)) - 4;
1621 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set last 4 colors\n"));
1623 for (k = 0; k < 4; ++k)
1625 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB32 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1626 screen->Screen.ViewPort,
1627 k + lastcol, p[k+4].red, p[k+4].green, p[k+4].blue));
1629 if (k + lastcol < numcolors)
1631 ObtainPen(screen->Screen.ViewPort.ColorMap,
1632 k + lastcol,
1633 p[k+4].red,
1634 p[k+4].green,
1635 p[k+4].blue,
1636 PEN_EXCLUSIVE);
1638 else
1640 SetRGB32(&screen->Screen.ViewPort, k + lastcol, p[k+4].red, p[k+4].green, p[k+4].blue);
1646 * AROS: AmigaOS(tm) 3.1-compatible mouse colors handling
1647 * 1. Allocate pens for the mouse pointer only on LUT screens.
1648 * On hi- and truecolor screens sprite colors come from colormap attached
1649 * to the sprite BitMap itself. See pointerclass::New() for details.
1650 * 2. Use 32-bit pointer colors instead of KS1.3 ActivePreferences->color17
1652 if (ns.Depth < 9)
1654 DEBUG_OPENSCREEN(dprintf("OpenScreen: Obtain Mousepointer colors\n"));
1656 for (k = 1; k < 4; ++k, ++q)
1658 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%P Pen %d R 0x%08X G 0x08X B 0x%08X\n",
1659 screen->Screen.ViewPort.ColorMap,
1660 k + spritebase,
1661 p[k+7].red, p[k+7].green, p[k+7].blue));
1662 if (k + spritebase < numcolors)
1664 ObtainPen(screen->Screen.ViewPort.ColorMap,
1665 k + spritebase,
1666 p[k+7].red, p[k+7].green, p[k+7].blue,
1667 PEN_EXCLUSIVE);
1669 else
1671 /* Can't be allocated, but can still be set. */
1672 SetRGB32(&screen->Screen.ViewPort,
1673 k + spritebase,
1674 p[k+7].red, p[k+7].green, p[k+7].blue);
1679 if (colors) /* if SA_Colors tag exists */
1681 DEBUG_OPENSCREEN(dprintf("OpenScreen: set SA_Colors 0x%lx\n",colors));
1682 for(; colors->ColorIndex != (WORD)~0; colors++)
1684 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB4 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1685 screen->Screen.ViewPort,
1686 colors,
1687 colors->Red,
1688 colors->Green,
1689 colors->Blue));
1690 SetRGB4(&screen->Screen.ViewPort,
1691 colors->ColorIndex,
1692 colors->Red,
1693 colors->Green,
1694 colors->Blue);
1698 if (colors32) /* if SA_Colors32 tag exists */
1700 DEBUG_OPENSCREEN(dprintf("OpenScreen: LoadRGB32 colors32 0x%lx\n",colors32));
1701 LoadRGB32(&screen->Screen.ViewPort, (const ULONG *)colors32);
1704 D(bug("Loaded colors\n"));
1706 COPY(LeftEdge);
1707 COPY(TopEdge);
1708 COPY(Width);
1709 COPY(Height);
1710 COPY(DetailPen);
1711 COPY(BlockPen);
1712 COPY(Font);
1713 COPY(DefaultTitle);
1715 //intui68k filters this
1716 screen->Screen.Flags = (ns.Type & ~NS_EXTENDED);
1718 /* Temporary hack */
1719 if (ns.Width >= 500 || ns.Height >= 300)
1720 screen->Screen.Flags |= SCREENHIRES;
1723 Copy the data from the rastport's BitMap
1724 to the screen's BitMap structure
1726 UpdateScreenBitMap(&screen->Screen, IntuitionBase);
1728 #ifdef __MORPHOS__
1729 screen->Screen.WBorTop = 2;
1730 screen->Screen.WBorLeft = 4;
1731 screen->Screen.WBorRight = 4;
1732 screen->Screen.WBorBottom = 2;
1733 #else
1734 screen->Screen.WBorTop = 6; /* Amiga default is 2 */
1735 screen->Screen.WBorLeft = 4;
1736 screen->Screen.WBorRight = 4;
1737 screen->Screen.WBorBottom = 4; /* Amiga default is 2 */
1738 #endif
1740 screen->Screen.Title = ns.DefaultTitle;
1742 DEBUG_OPENSCREEN(dprintf("OpenScreen: init layers\n"));
1743 #ifdef __AROS__ /* AROS: We have no compositing layers */
1744 InitLayers(&screen->Screen.LayerInfo);
1745 #else
1746 if (((struct Library *)LayersBase)->lib_Version >= 52 && compositing &&
1747 screen->IMonitorNode->Compositing)
1749 struct TagItem layerinfotags[] =
1751 {SA_Width,screen->Screen.Width},
1752 {SA_Height,screen->Screen.Height},
1753 {SA_PixelFormat,screen->PixelFormat},
1754 {MA_MemorySize,screen->IMonitorNode->BoardMemory},
1755 {LT_IgnoreMemoryChecks, IBase->LayerSettings.IgnoreMemoryChecks},
1756 {SA_CompositingLayers, TRUE},
1757 {TAG_DONE}
1759 ULONG iscompositing = FALSE;
1761 // make SA_CompositingLayers return TRUE (layers will ask)
1762 screen->Compositing = TRUE;
1763 InitScreenLayerInfo(&screen->Screen,layerinfotags);
1765 // validate if we're compositing
1766 LayersControlTags(&screen->Screen.LayerInfo,
1767 LT_GetCompositing,(ULONG)&iscompositing,
1769 // also set current layers settings
1770 LT_AllowDoubleBuffered, IBase->LayerSettings.AllowDoubleBuffered,
1771 LT_AllowTripleBuffered, IBase->LayerSettings.AllowTripleBuffered,
1772 LT_IgnoreMemoryChecks, IBase->LayerSettings.IgnoreMemoryChecks,
1773 LT_LoadBalancing, IBase->LayerSettings.LoadBalancing,
1775 TAG_DONE);
1777 screen->Compositing = iscompositing ? TRUE : FALSE;
1779 else
1781 struct TagItem layerinfotags[] =
1783 {SA_CompositingLayers, FALSE},
1784 {TAG_DONE}
1786 screen->Compositing = FALSE;
1787 InitScreenLayerInfo(&screen->Screen,layerinfotags);
1789 #endif
1790 li_inited = TRUE;
1792 if (NULL != layer_info_hook)
1794 DEBUG_OPENSCREEN(dprintf("OpenScreen: instal layerinfohook\n"));
1795 InstallLayerInfoHook(&screen->Screen.LayerInfo, layer_info_hook);
1797 D(bug("layers intited screen\n"));
1799 /* AROS: We have already obtained resolution data from DisplayInfo */
1800 #ifdef __AROS__
1801 screen->DInfo.dri_Version = DRI_VERSION;
1802 #else
1803 GetDisplayInfoData(NULL, (APTR)&dispinfo, sizeof(dispinfo), DTAG_DISP, modeid);
1804 screen->DInfo.dri_Version = MOS_DRI_VERSION;
1805 #endif
1806 screen->DInfo.dri_NumPens = NUMDRIPENS;
1807 screen->DInfo.dri_Pens = screen->Pens;
1808 /* dri_Depth is 8 on hi/true color screens like in AmigaOS with picasso96/cybergraphx */
1809 screen->DInfo.dri_Depth = (ns.Depth <= 8) ? ns.Depth : 8;
1810 /* AROS: Get resolution from DisplayInfo */
1811 screen->DInfo.dri_Resolution.X = dispinfo.Resolution.x;
1812 screen->DInfo.dri_Resolution.Y = dispinfo.Resolution.y;
1813 screen->DInfo.dri_Flags = 0;
1816 /* SA_SysFont overrides SA_Font! */
1818 DEBUG_OPENSCREEN(dprintf("OpenScreen: SysFont = %d, ns.Font = %p\n", sysfont, ns.Font));
1820 if (sysfont == 0)
1822 /* Is handled below */
1823 DEBUG_OPENSCREEN(dprintf("OpenScreen: skip SysFont for now\n"));
1824 } else if (sysfont == 1) {
1826 screen->DInfo.dri_Font = SafeReopenFont(IntuitionBase, &IBase->ScreenFont);
1828 if (screen->DInfo.dri_Font)
1830 screen->SysFont = TRUE;
1832 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set ScreenFont\n"));
1834 } else if (ns.Font) {
1835 screen->DInfo.dri_Font = OpenFont(ns.Font);
1836 DEBUG_OPENSCREEN(dprintf("OpenScreen: custom font 0x%lx\n",screen->DInfo.dri_Font));
1839 if (!screen->DInfo.dri_Font)
1841 /* GfxBase->DefaultFont is *not* always topaz 8. It
1842 can be set with the Font prefs program!! */
1844 screen->DInfo.dri_Font = SafeReopenFont(IntuitionBase, &GfxBase->DefaultFont);
1847 if (!screen->DInfo.dri_Font) ok = FALSE;
1849 } /* if (ok) */
1851 if (ok)
1853 ULONG *dripens = NULL;
1855 switch (ns.Depth)
1857 case 1:
1858 dripens = (ULONG*)&IBase->DriPens2;
1859 break;
1861 case 2:
1862 dripens = (ULONG*)&IBase->DriPens4;
1863 break;
1865 default:
1866 if (colors || colors32)
1868 /* jDc: apps are used to use non-std colors for pen # >=4
1869 dripens4 will be a good fallback for this */
1870 dripens = (ULONG*)&IBase->DriPens4;
1871 } else {
1872 dripens = (ULONG*)&IBase->DriPens8;
1874 break;
1877 /* set default values for pens */
1878 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Default Pens\n"));
1879 CopyMem(dripens,screen->Pens,sizeof(screen->Pens));
1881 if (ns.Depth > 1)
1883 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set NewLook\n"));
1884 screen->DInfo.dri_Flags |= DRIF_NEWLOOK;
1887 if (customdripens)
1889 WORD i;
1891 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Custom Pens\n"));
1892 screen->Pens[DETAILPEN] = screen->Screen.DetailPen;
1893 screen->Pens[BLOCKPEN] = screen->Screen.BlockPen;
1895 for(i = 0; (i < NUMDRIPENS) && (customdripens[i] != (UWORD)~0) && (screen->Pens[i] != (UWORD)~0); i++)
1897 DEBUG_OPENSCREEN(dprintf("OpenScreen: Pen[%ld] %ld --> %ld\n",i,screen->Pens[i],customdripens[i]));
1898 screen->Pens[i] = customdripens[i];
1903 * Let's do some broken software validation of the pens
1904 * so we may not run into a black desktop.
1907 DEBUG_OPENSCREEN(dprintf("OpenScreen: Check Default Pens if the make sense\n"));
1908 if (screen->Screen.DetailPen == screen->Screen.BlockPen)
1910 DEBUG_OPENSCREEN(dprintf("OpenScreen: DetailPen==BlockPen..correct\n"));
1911 screen->Screen.DetailPen = 0;
1912 screen->Screen.BlockPen = 1;
1913 } else if (screen->Screen.BlockPen == 0)
1915 DEBUG_OPENSCREEN(dprintf("OpenScreen: BlockPen==0..correct\n"));
1916 screen->Screen.BlockPen = screen->Screen.DetailPen;
1917 screen->Screen.DetailPen = 0;
1920 screen->Pens[DETAILPEN] = screen->Screen.DetailPen;
1921 screen->Pens[BLOCKPEN] = screen->Screen.BlockPen;
1923 /* Allocate shared/exclusive colors */
1926 BYTE color_alloced[256];
1927 UWORD mask;
1928 WORD i;
1930 /*for(i = 0; i < 256; i++)
1932 color_alloced[i] = FALSE;
1934 memclr(&color_alloced,256);
1936 /* Mouse pointer colors */
1938 color_alloced[17] = TRUE;
1939 color_alloced[18] = TRUE;
1940 color_alloced[19] = TRUE;
1942 /* Clamp the pen numbers. This makes sure that values such as -4 or -3
1943 won't result in random memory trashing, but rather index colours from
1944 the end of the shareable palette. - Piru */
1945 mask = screen->Screen.ViewPort.ColorMap->PalExtra->pe_SharableColors & 0xff;
1947 /* The Pens in the DrawInfo must be allocated as shared */
1949 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen DrawInfo Pens as shared\n"));
1950 for(i = 0; (i < NUMDRIPENS) && (screen->Pens[i] != (UWORD)~0); i++)
1952 int pen = screen->Pens[i] & mask;
1953 if (!color_alloced[pen])
1955 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1956 screen->Screen.ViewPort.ColorMap,
1957 pen));
1959 ObtainPen(screen->Screen.ViewPort.ColorMap,
1960 pen,
1964 PENF_NO_SETCOLOR);
1965 color_alloced[pen] = TRUE;
1968 DEBUG_OPENSCREEN(dprintf("OpenScreen: done\n"));
1970 /* If SA_SharePens is FALSE then allocate the rest of the colors
1971 in the colormap as exclusive */
1973 if (!sharepens)
1975 ULONG shnumcolors = (requesteddepth <= 8) ? (1L << requesteddepth) : 256;
1977 /* jDc: hack, colors above requested screen depth are not locked! */
1979 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen the remaining Pens as exclusive\n"));
1980 for(i = 0; i < shnumcolors; i++)
1982 if (!color_alloced[i])
1984 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1985 screen->Screen.ViewPort.ColorMap,
1986 i));
1987 ObtainPen(screen->Screen.ViewPort.ColorMap,
1992 PENF_EXCLUSIVE | PENF_NO_SETCOLOR);
1996 } /* if (!sharepens) */
2001 if (ok)
2003 screen->DInfo.dri_Screen = &screen->Screen; //useful sometimes ;)
2005 screen->realdepth = GetBitMapAttr( screen->Screen.RastPort.BitMap, BMA_DEPTH );
2007 if (screen->realdepth > 8)
2009 screen->DInfo.dri_Flags |= DRIF_DIRECTCOLOR;
2010 } else {
2011 screen->DInfo.dri_Flags &= ~DRIF_DIRECTCOLOR;
2014 #ifdef SKINS
2015 if (!(screen->DInfo.dri_Colors = AllocMem(4 * DRIPEN_NUMDRIPENS,MEMF_PUBLIC)))
2016 ok = FALSE;
2018 if (ok)
2020 CopyMem(&defaultdricolors,screen->DInfo.dri_Colors,sizeof (defaultdricolors));
2021 memset(((UBYTE *) screen->DInfo.dri_Colors) + sizeof(defaultdricolors), 0, 4 * DRIPEN_NUMDRIPENS - sizeof(defaultdricolors));
2023 #endif
2025 if (ok)
2027 DEBUG_OPENSCREEN(dprintf("OpenScreen: allocating dri_Customize\n"));
2029 if ((screen->DInfo.dri_Customize = AllocMem(sizeof (struct IntuitionCustomize),MEMF_PUBLIC|MEMF_CLEAR)))
2031 #ifdef SKINS
2032 struct IntuitionCustomize *ic;
2033 ic = screen->DInfo.dri_Customize;
2034 screen->DInfo.dri_Flags |= DRIF_SKINSSUPPORT;
2036 /* This initializes CustomizePrefs structure */
2038 if (skinname) strcpy(ic->skinname,skinname);
2040 InitSemaphore(&ic->InitLock);
2042 DEBUG_OPENSCREEN(dprintf("OpenScreen: load skin %s for screen %lx\n",ic->skinname,screen));
2043 int_SkinAction(SKA_LoadSkin,(ULONG*)&screen->DInfo,(struct Screen *)screen,IntuitionBase);
2044 #else
2045 /* AROS: Use less error-prone skinname handling */
2046 ok = int_LoadDecorator(skinname, screen, IntuitionBase);
2047 #endif
2049 else
2051 ok = FALSE;
2056 #ifdef SKINS
2057 if (ok)
2059 struct windowclassprefs *wcprefs;
2060 wcprefs = (struct windowclassprefs *)int_GetCustomPrefs(TYPE_WINDOWCLASS,&screen->DInfo,IntuitionBase);
2061 if (wcprefs->flags & WINDOWCLASS_PREFS_1TO1FRAMES)
2063 screen->Screen.WBorLeft = screen->Screen.WBorTop;
2064 screen->Screen.WBorRight = screen->Screen.WBorTop;
2065 screen->Screen.WBorBottom = screen->Screen.WBorTop;
2067 screen->Screen.WBorTop += wcprefs->titlebarincrement;
2068 int_FreeCustomPrefs(TYPE_WINDOWCLASS,&screen->DInfo,IntuitionBase);
2071 #endif
2073 if (ok)
2075 struct TagItem sysi_tags[] =
2077 {SYSIA_Which, MENUCHECK },
2078 {SYSIA_DrawInfo, (IPTR)&screen->DInfo },
2079 {TAG_DONE }
2082 screen->DInfo.dri_CheckMark = NewObjectA(NULL, "sysiclass", sysi_tags);
2083 DEBUG_OPENSCREEN(dprintf("OpenScreen: CheckMark 0x%lx\n",
2084 screen->DInfo.dri_CheckMark));
2086 sysi_tags[0].ti_Data = AMIGAKEY;
2088 screen->DInfo.dri_AmigaKey = NewObjectA(NULL, "sysiclass", sysi_tags);
2089 DEBUG_OPENSCREEN(dprintf("OpenScreen: AmigaKey 0x%lx\n",
2090 screen->DInfo.dri_AmigaKey));
2092 /* AROS: We also use submenu image */
2093 sysi_tags[0].ti_Data = SUBMENUIMAGE;
2094 screen->DInfo.dri_Customize->submenu = NewObjectA(NULL, "sysiclass", sysi_tags);
2095 if (!screen->DInfo.dri_Customize->submenu) ok =FALSE;
2096 #ifdef SKINS
2097 sysi_tags[0].ti_Data = MENUTOGGLEIMAGE;
2098 screen->DInfo.dri_Customize->menutoggle = NewObjectA(NULL, "sysiclass", sysi_tags);
2099 if (!screen->DInfo.dri_Customize->menutoggle) ok = FALSE;
2100 #endif
2102 if (!screen->DInfo.dri_CheckMark || !screen->DInfo.dri_AmigaKey) ok = FALSE;
2105 if (ok)
2107 SetFont(&screen->Screen.RastPort, screen->DInfo.dri_Font);
2109 AskFont(&screen->Screen.RastPort, (struct TextAttr *) &screen->textattr);
2111 screen->Screen.Font = (struct TextAttr *) &screen->textattr;
2113 DEBUG_OPENSCREEN(dprintf("OpenScreen: Font %s/%d\n",
2114 screen->textattr.tta_Name, screen->textattr.tta_YSize));
2116 screen->Screen.BarVBorder = 1;
2117 screen->Screen.BarHBorder = 5;
2118 screen->Screen.MenuVBorder = 2;
2119 screen->Screen.MenuHBorder = 4;
2121 screen->Screen.BarHeight = screen->DInfo.dri_Font->tf_YSize + screen->Screen.WBorTop-2 +
2122 screen->Screen.BarVBorder * 2; /* real layer will be 1 pixel higher! */
2125 * AROS: Get size information from decorator.
2126 * This has to be done before we create gadgets because here we may adjust BarHeight.
2128 ok = int_InitDecorator(&screen->Screen);
2129 if (ok)
2131 #define SDEPTH_HEIGHT (screen->Screen.BarHeight + 1)
2132 #ifdef IA_Screen
2133 #undef IA_Screen
2134 #endif
2135 #define IA_Screen (IA_Dummy + 0x1f) /* OS v44 includes!*/
2137 struct TagItem sdepth_tags[] =
2139 {GA_Image, 0 },
2140 {GA_Top, 0 },
2141 {GA_Height, SDEPTH_HEIGHT},
2142 {GA_SysGadget, TRUE },
2143 {GA_SysGType, GTYP_SDEPTH },
2144 {GA_RelVerify, TRUE },
2145 {TAG_DONE, 0UL }
2148 struct TagItem image_tags[] =
2150 {IA_Left , 0 },
2151 //{IA_Width , SDEPTH_WIDTH + 1 },
2152 {IA_Height , SDEPTH_HEIGHT },
2153 {SYSIA_Which , SDEPTHIMAGE },
2154 {SYSIA_DrawInfo , (IPTR)&screen->DInfo},
2155 {SYSIA_Size , screen->Screen.Flags & SCREENHIRES ?
2156 SYSISIZE_MEDRES : SYSISIZE_LOWRES},
2157 {TAG_DONE }
2160 struct Object *im = 0;
2162 if (!(screen->Screen.Flags & SCREENQUIET))
2164 im = NewObjectA(NULL, SYSICLASS, image_tags);
2167 sdepth_tags[0].ti_Data = (IPTR)im;
2169 screen->depthgadget = NewObjectA(IBase->windowsysiclass, NULL, sdepth_tags );
2171 DEBUG_OPENSCREEN(dprintf("OpenScreen: DepthGadget 0x%lx\n",
2172 screen->depthgadget));
2174 screen->Screen.FirstGadget = (struct Gadget *)screen->depthgadget;
2175 if (screen->Screen.FirstGadget)
2177 struct TagItem gadtags[] =
2179 {GA_RelRight, 0},
2180 {TAG_DONE }
2182 IPTR width; /* AROS: Changed from int to IPTR, 64-bit fix */
2184 GetAttr(GA_Width, screen->depthgadget, &width);
2186 gadtags[0].ti_Data = -width + 1;
2187 SetAttrsA(screen->depthgadget, gadtags);
2188 screen->Screen.FirstGadget->GadgetType |= GTYP_SCRGADGET;
2189 } else {
2190 if (im) DisposeObject(im);
2193 #if DEBUG
2195 int i;
2196 for (i=0;i<=screen->DInfo.dri_NumPens;i++)
2198 DEBUG_OPENSCREEN(dprintf("OpenScreen: dri_Pen[%ld] = %ld\n",i,screen->DInfo.dri_Pens[i]));
2201 #endif
2203 #ifdef USEWINDOWLOCK
2204 /* let's wait for user to finish window drag/size actions to avoid
2205 deadlocks and not break user's input */
2206 if (dowindowlock && (!(FindTask(NULL) == ((struct IIHData *)IBase->InputHandler->is_Data)->InputDeviceTask)))
2208 LOCKWINDOW;
2209 windowlock = TRUE;
2210 screen->WindowLock = TRUE;
2212 #endif
2214 int_CalcSkinInfo(&screen->Screen,IntuitionBase);
2215 #ifdef SKINS
2216 int_InitTitlebarBuffer(&screen->Screen,IntuitionBase);
2217 #endif
2218 D(bug("calling SetRast()\n"));
2220 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set background color Pen %ld\n",screen->Pens[BACKGROUNDPEN]));
2221 /* Set screen to background color */
2222 SetRast(&screen->Screen.RastPort, screen->Pens[BACKGROUNDPEN]);
2224 D(bug("SetRast() called\n"));
2226 DEBUG_OPENSCREEN(dprintf("OpenScreen: Creating screen bar\n"));
2228 #ifdef SKINS
2229 if (workbench)
2231 #if 1
2232 if (IBase->IControlPrefs.ic_Flags & (ICF_DISAPPEARINGTITLEBAR | ICF_NOWBTITLEBAR)) screen->SpecialFlags |= SF_AppearingBar;
2233 #else
2234 if (IBase->IControlPrefs.ic_Flags & ICF_NOWBTITLEBAR) screen->SpecialFlags |= SF_InvisibleBar;
2235 if (IBase->IControlPrefs.ic_Flags & ICF_DISAPPEARINGTITLEBAR) screen->SpecialFlags |= SF_AppearingBar;
2236 #endif
2238 #endif
2240 //jDc: ALL screens MUST have BarLayer!
2241 CreateScreenBar(&screen->Screen, IntuitionBase);
2243 if (!screen->Screen.BarLayer) ok = FALSE;
2246 if (ok)
2248 if ((ns.Type & SCREENTYPE) == CUSTOMSCREEN)
2250 screen->ShowPointer = showpointer;
2251 } else {
2252 screen->ShowPointer = TRUE;
2254 #ifdef SKINS
2255 GetAttr(POINTERA_SharedPointer, screen->IMonitorNode->Pointers[POINTERTYPE_INVISIBLE], (IPTR *)&screen->Pointer);
2256 #else
2257 GetAttr(POINTERA_SharedPointer, IBase->DefaultPointer, (IPTR *)&screen->Pointer);
2258 #endif
2259 ObtainSharedPointer(screen->Pointer, IntuitionBase);
2260 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sprite DefaultPtr 0x%lx\n",&screen->Pointer));
2264 ** jDc: better modify the screen list in sync with inputhandler, this for example allows us to scan the list
2265 ** without any locks when we are on input.device context
2267 if (ok)
2269 struct PubScreenNode *ps = NULL;
2270 struct List *list = LockPubScreenList();
2272 /* Additional dupe check, just to be sure */
2273 if (!workbench && screen->pubScrNode && (ps = (struct PubScreenNode *)FindName(list,screen->pubScrNode->psn_Node.ln_Name)))
2275 ok = FALSE;
2278 if (ok)
2280 struct OpenScreenActionMsg msg;
2282 msg.Screen = screen;
2283 msg.NewScreen = &ns;
2284 msg.List = list;
2286 DoSyncAction((APTR)int_openscreen,&msg.msg,IntuitionBase);
2288 ok = msg.Success;
2291 UnlockPubScreenList();
2294 } /* if (ok) */
2296 #ifdef USEWINDOWLOCK
2297 if (windowlock) UNLOCKWINDOW;
2298 #endif
2300 if (!ok)
2302 if (li_inited)
2304 DEBUG_OPENSCREEN(dprintf("OpenScreen: Get ThinLayerInfo\n"));
2305 ThinLayerInfo(&screen->Screen.LayerInfo);
2308 if (screen->Screen.ViewPort.ColorMap)
2310 #ifdef __MORPHOS__
2311 struct TagItem tags[2];
2313 tags[0].ti_Tag = VTAG_ATTACH_CM_GET;
2314 tags[0].ti_Data = 0;
2315 tags[1].ti_Tag = VTAG_END_CM;
2317 if (VideoControl(screen->Screen.ViewPort.ColorMap, tags) == 0 &&
2318 tags[0].ti_Data)
2320 GfxFree((APTR)tags[0].ti_Data);
2322 #endif
2324 FreeColorMap(screen->Screen.ViewPort.ColorMap);
2327 if (screen->Screen.BarLayer)
2329 DEBUG_OPENSCREEN(dprintf("OpenScreen: KillScreenBar\n"));
2330 KillScreenBar(&screen->Screen, IntuitionBase);
2333 if (screen->DInfo.dri_Customize)
2335 /* AROS: submenu image handling moved out of #ifdef */
2336 DisposeObject(screen->DInfo.dri_Customize->submenu);
2337 #ifdef SKINS
2338 DisposeObject(screen->DInfo.dri_Customize->menutoggle);
2339 #endif
2340 FreeMem(screen->DInfo.dri_Customize,sizeof (struct IntuitionCustomize));
2342 #ifdef SKINS
2343 if (screen->DInfo.dri_Colors) FreeMem(screen->DInfo.dri_Colors,4 * DRIPEN_NUMDRIPENS);
2344 #endif
2345 if (screen->DInfo.dri_AmigaKey)
2347 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose AmigaKey Object\n"));
2348 DisposeObject(screen->DInfo.dri_AmigaKey);
2350 if (screen->DInfo.dri_CheckMark)
2352 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose CheckMark Object\n"));
2353 DisposeObject(screen->DInfo.dri_CheckMark);
2356 if (screen->DInfo.dri_Font)
2358 DEBUG_OPENSCREEN(dprintf("OpenScreen: Close Font\n"));
2359 CloseFont(screen->DInfo.dri_Font);
2362 if (screen->AllocatedBitMap && !(ns.Type & CUSTOMBITMAP))
2364 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free BitMap\n"));
2365 FreeBitMap(screen->AllocatedBitMap);
2368 if (screen->Screen.ViewPort.RasInfo)
2370 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free RasInfo\n"));
2371 FreeMem(screen->Screen.ViewPort.RasInfo, sizeof (struct RasInfo));
2374 if (rp_inited)
2376 DEBUG_OPENSCREEN(dprintf("OpenScreen: Trash Rastport\n"));
2377 DeinitRastPort(&screen->Screen.RastPort);
2380 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free Screen\n"));
2381 DisposeObject((APTR)screen);
2382 screen = 0;
2384 } /* if (!ok) */
2386 DEBUG_OPENSCREEN(dprintf("OpenScreen: return 0x%lx\n", screen));
2388 FireScreenNotifyMessage((IPTR) screen, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
2390 ReturnPtr ("OpenScreen", struct Screen *, (struct Screen *)screen);
2392 AROS_LIBFUNC_EXIT
2394 } /* OpenScreen */
2396 VOID int_openscreen(struct OpenScreenActionMsg *msg,
2397 struct IntuitionBase *IntuitionBase)
2399 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
2400 struct IntScreen *screen = msg->Screen;
2401 struct NewScreen *ns = msg->NewScreen;
2402 struct List *list = msg->List;
2403 struct Screen *oldFirstScreen;
2404 struct RethinkDisplayActionMsg rmsg;
2405 ULONG lock = 0;
2407 DEBUG_OPENSCREEN(dprintf("OpenScreen: Checking for pubScrNode (0x%lx)\n",screen->pubScrNode));
2409 /* If this is a public screen, we link it into the intuition global
2410 public screen list */
2411 if (screen->pubScrNode != NULL)
2413 /* Set the pointer to ourselves */
2414 IS(screen)->pubScrNode->psn_Screen = &screen->Screen;
2416 DEBUG_OPENSCREEN(dprintf("OpenScreen: Add Screen to PubList\n"));
2417 AddTail(list, (struct Node *)IS(screen)->pubScrNode);
2420 if (!ILOCKCHECK(((struct IntuiActionMsg *)msg))) lock = LockIBase((IPTR)NULL);
2422 oldFirstScreen = IntuitionBase->FirstScreen;
2423 if (ns->Type & SCREENBEHIND)
2425 struct Screen **ptr = &IntuitionBase->FirstScreen;
2427 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sort Behind\n"));
2428 if (!*ptr)
2429 IntuitionBase->ActiveScreen = &screen->Screen;
2430 while (*ptr)
2431 ptr = &(*ptr)->NextScreen;
2432 *ptr = &screen->Screen;
2434 else
2436 screen->Screen.NextScreen = IntuitionBase->FirstScreen;
2437 IntuitionBase->FirstScreen =
2438 IntuitionBase->ActiveScreen = &screen->Screen;
2439 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set as ActiveScreen\n"));
2442 /* AROS: If it's the first screen being opened, activate its monitor */
2443 if (!oldFirstScreen)
2444 ActivateMonitor(screen->IMonitorNode, -1, -1, IntuitionBase);
2446 /* set the default pub screen */
2447 if (IBase->IControlPrefs.ic_Flags & ICF_DEFPUBSCREEN)
2449 if ((IntuitionBase->FirstScreen == &screen->Screen) && screen->pubScrNode && (screen->Screen.Flags & (PUBLICSCREEN | WBENCHSCREEN)))
2451 IBase->DefaultPubScreen = &screen->Screen;
2455 msg->Success = MakeVPort(&IntuitionBase->ViewLord, &screen->Screen.ViewPort) ? FALSE : TRUE;
2457 if (msg->Success)
2459 /* AROS: Put offsets validated by MakeVPort() back into screen structure */
2460 screen->Screen.LeftEdge = screen->Screen.ViewPort.DxOffset;
2461 screen->Screen.TopEdge = screen->Screen.ViewPort.DyOffset;
2463 rmsg.lock = FALSE;
2464 int_RethinkDisplay(&rmsg,IntuitionBase);
2467 #ifdef SKINS
2468 if (!(ns->Type & SCREENBEHIND))
2470 // workaround: do not send the event for SCREENBEHIND cause it'd reset the DPMS counter
2471 QueryBlankerEvent(BLANKEREVENT_SCREENDEPTH,(ULONG)screen->IMonitorNode,IntuitionBase);
2473 #endif
2475 if (!ILOCKCHECK(((struct IntuiActionMsg *)msg))) UnlockIBase(lock);
2477 D(bug("set active screen\n"));
2479 AddResourceToList(screen, RESOURCE_SCREEN, IntuitionBase);