dont try to convert the pixfmt while calculating the "shade"
[AROS.git] / rom / intuition / openscreen.c
blob5e17124cb17b659d3e98f57adce9b8176050d30e
1 /*
2 Copyright © 1995-2013, 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 <exec/memory.h>
24 #include <utility/tagitem.h>
25 #include <intuition/screens.h>
26 #include <intuition/intuition.h>
27 #include <intuition/imageclass.h>
28 #include <intuition/gadgetclass.h>
29 #include <intuition/monitorclass.h>
30 #include <graphics/modeid.h>
31 #include <graphics/videocontrol.h>
32 #include <graphics/displayinfo.h>
33 #include <graphics/rpattr.h>
34 #include <prefs/screenmode.h>
35 #include <proto/input.h>
36 #include <proto/dos.h>
37 #include <proto/exec.h>
38 #include <proto/graphics.h>
39 #include <proto/layers.h>
40 #include <proto/utility.h>
41 #include <proto/intuition.h>
42 #ifdef __MORPHOS__
43 #include <proto/cybergraphics.h>
44 #include <cybergraphx/cybergraphics.h>
45 #else
46 #include <hidd/graphics.h>
47 #endif
48 #include "intuition_intern.h"
49 #include "intuition_customize.h"
50 #include "intuition_extend.h"
51 #include "inputhandler.h"
52 #include "inputhandler_support.h"
53 #include "inputhandler_actions.h"
54 #include "menus.h"
55 #include "monitorclass_intern.h"
56 #include "monitorclass_private.h"
58 // disabled as it causes compatibility issues
59 //#define USE8BITHACK
61 #ifndef DEBUG_OpenScreen
62 #define DEBUG_OpenScreen 0
63 #endif
64 #undef DEBUG
65 #if DEBUG_OpenScreen
66 #define DEBUG 1
67 #endif
68 #include <aros/debug.h>
70 struct OpenScreenActionMsg
72 struct IntuiActionMsg msg;
73 struct IntScreen *Screen;
74 struct NewScreen *NewScreen;
75 struct List *List;
76 BOOL Success;
79 VOID int_openscreen(struct OpenScreenActionMsg *msg,struct IntuitionBase *IntuitionBase);
81 #ifdef SKINS
82 extern const ULONG defaultdricolors[DRIPEN_NUMDRIPENS];
83 #endif
85 #if DEBUG
86 #undef THIS_FILE
87 static const char THIS_FILE[] = __FILE__;
88 #endif
90 /*****************************************************************************
92 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 DimensionInfo.reserved[0]
118 by graphics.library/GetDisplayInfoData(). Keep this in sync when modifying
119 the code.
121 HISTORY
122 29-10-95 digulla automatically created from
123 intuition_lib.fd and clib/intuition_protos.h
125 *****************************************************************************/
127 AROS_LIBFUNC_INIT
129 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
130 struct LayersBase *LayersBase = GetPrivIBase(IntuitionBase)->LayersBase;
131 struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
132 struct NewScreen ns;
133 struct TagItem *tag, *tagList;
134 struct IntScreen *screen;
135 int success;
136 struct Hook *layer_info_hook = NULL;
137 struct ColorSpec *colors = NULL;
138 ULONG *errorPtr; /* Store error at user specified location */
139 UWORD *customdripens = NULL;
140 ULONG *colors32 = NULL;
141 WORD sysfont = -1;
142 BOOL ok = TRUE, rp_inited = FALSE, li_inited = FALSE, sharepens = FALSE;
143 #ifdef USEWINDOWLOCK
144 BOOL windowlock = FALSE;
145 BOOL dowindowlock = TRUE;
146 #endif
147 struct Rectangle *dclip = NULL;
148 LONG overscan = OSCAN_TEXT;
149 DisplayInfoHandle displayinfo = NULL;
150 struct DisplayInfo dispinfo;
151 struct DimensionInfo dimensions;
152 #ifdef __MORPHOS__
153 struct MonitorInfo monitor;
154 #endif
155 ULONG allocbitmapflags = BMF_DISPLAYABLE;
156 char *skinname = 0;
157 #ifdef SKINS
158 ULONG vesafallback = 0;
159 ULONG *modecontrol = 0;
160 BOOL compositing = FALSE;
161 #endif
162 IPTR vctl = 0;
163 char *monitorname = 0;
164 BOOL exactname = FALSE;
165 BOOL showpointer = TRUE;
166 BOOL gammacontrol = FALSE;
167 UBYTE *gammared = NULL, *gammablue = NULL, *gammagreen = NULL;
168 BOOL support3d = FALSE;
169 BOOL adaptsize = FALSE;
170 ULONG displaywidth = 0;
171 ULONG displayheight = 0;
172 //ULONG lock;
173 WORD numcolors = 0;
174 UWORD spritebase;
175 BOOL workbench = FALSE;
176 ULONG requesteddepth = 1;
177 BOOL draggable = TRUE;
178 ULONG compflags = COMPF_ABOVE; // Default to AmigaOS like behaviour.
179 struct Hook *compalphahook = NULL;
181 struct TagItem modetags[] =
183 { BIDTAG_Depth , 0UL },
184 { BIDTAG_DesiredWidth , 0UL },
185 { BIDTAG_DesiredHeight, 0UL },
186 { BIDTAG_NominalWidth , 0UL },
187 { BIDTAG_NominalHeight, 0UL },
188 { BIDTAG_DIPFMustHave , 0UL },
189 { TAG_DONE }
192 ULONG modeid = INVALID_ID;
194 ASSERT_VALID_PTR_ROMOK(newScreen);
197 #define COPY(x) screen->Screen.x = ns.x
198 #define SetError(x) if (errorPtr != NULL) *errorPtr = x;
200 D(bug("OpenScreen (%p = { Left=%d Top=%d Width=%d Height=%d Depth=%d })\n"
201 , newScreen
202 , newScreen->LeftEdge
203 , newScreen->TopEdge
204 , newScreen->Width
205 , newScreen->Height
206 , newScreen->Depth
209 FireScreenNotifyMessage((IPTR) newScreen, SNOTIFY_BEFORE_OPENSCREEN, IntuitionBase);
210 ns = *newScreen;
212 if (newScreen->Type & NS_EXTENDED)
214 tagList = ((struct ExtNewScreen *)newScreen)->Extension;
215 } else {
216 tagList = NULL;
219 DEBUG_OPENSCREEN(dprintf("OpenScreen: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
220 ns.LeftEdge, ns.TopEdge, ns.Width, ns.Height, ns.Depth, tagList));
222 #ifdef __MORPHOS__
223 if (!CyberGfxBase)
225 struct Library *lib = ComplainOpenLibrary(COMPLAIN_CYBERGFX,FALSE,IntuitionBase);
226 Forbid();
227 if (!CyberGfxBase)
229 CyberGfxBase = lib;
230 Permit();
232 else
234 Permit();
235 CloseLibrary(lib);
238 if (!CyberGfxBase)
240 FireScreenNotifyMessage(0, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
241 return NULL;
244 if (!LocaleBase)
246 struct Library *lib = ComplainOpenLibrary(COMPLAIN_LOCALE,FALSE,IntuitionBase);
247 Forbid();
248 if (!LocaleBase)
250 LocaleBase = lib;
251 Permit();
252 OpenintuitionCatalog(IntuitionBase);
254 else
256 Permit();
257 CloseLibrary(lib);
261 if (!CGXSystemBase)
263 struct Library *lib = ComplainOpenLibrary(COMPLAIN_CGXSYSTEM,FALSE,IntuitionBase);
264 Forbid();
265 if (!CGXSystemBase)
267 CGXSystemBase = lib;
268 Permit();
270 else
272 Permit();
273 CloseLibrary(lib);
276 #endif
278 screen = NewObjectA(IBase->screenclass,0,0);
280 DEBUG_OPENSCREEN(dprintf("OpenScreen: screen 0x%lx\n", screen));
282 /* Do this really early to be able to report errors */
283 errorPtr = (ULONG *)GetTagData((Tag)SA_ErrorCode, (IPTR)NULL, (struct TagItem *)tagList);
285 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ErrorCode 0x%lx\n",errorPtr));
287 if (screen == NULL)
289 SetError(OSERR_NOMEM);
290 ok = FALSE;
293 if (ok && tagList)
295 char *pubname = NULL;
297 modeid = GetTagData(SA_DisplayID,INVALID_ID, tagList);
298 #ifndef __AROS__
300 * AROS: MorphOS private tag temporarily disabled. Used by OpenWorkbench().
301 * Information from MorphOS intuition.notes file:
303 * Added SA_OpenWorkbench to fix the OpenScreen handling for this special case, fixes
304 * the problem with autoscroll promoting to a bigger res than the one selected in prefs
306 * CHECKME: May be we also need this ?
308 workbench = GetTagData(SA_OpenWorkbench,FALSE,tagList);
310 if (workbench)
312 compositing = TRUE;
314 #endif
316 DEBUG_OPENSCREEN(dprintf("OpenScreen: modeid from taglist: %lx\n",modeid));
318 if (GetTagData(SA_LikeWorkbench, FALSE, tagList))
320 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_LikeWorkbench\n"));
322 #ifndef SKINS
324 * AROS: Use oldstyle ScreenModePrefs structure.
325 * CHECKME: Can we merge better ?
327 ns.Width = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Width;
328 ns.Height = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Height;
329 ns.Depth = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Depth;
330 modeid = GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_DisplayID;
332 if (GetPrivIBase(IntuitionBase)->ScreenModePrefs.smp_Control & SMF_AUTOSCROLL)
334 /* need to mark autoscroll */
335 ns.Type |= AUTOSCROLL;
337 #else
338 ns.Width = IBase->AmbientScreenMode.DisplayWidth;
339 ns.Height = IBase->AmbientScreenMode.DisplayHeight;
340 ns.Depth = IBase->AmbientScreenMode.DisplayDepth;
341 if (IBase->AmbientScreenMode.AutoScroll) ns.Type |= AUTOSCROLL;
342 displaywidth = IBase->AmbientScreenMode.ModeWidth;
343 displayheight = IBase->AmbientScreenMode.ModeHeight;
345 /* jDc: do NOT copy modeid of wb as that will not allow overloading depth param properly */
347 /* unless it's OpenWorkbench! */
349 if (workbench)
351 modeid = INVALID_ID; // we'll use the stored ID only in the worst case!
352 compositing = IBase->AmbientScreenMode.Compositing;
355 /* let's try to limit the new screen to the same monitor ambient would use */
356 /* but only if modeid is a weak one */
357 if ((modeid == INVALID_ID) || (ModeNotAvailable(modeid)) || !FindDisplayInfo(modeid))
359 if (IBase->AmbientScreenMode.ModeMonitor[0])
361 monitorname = IBase->AmbientScreenMode.ModeMonitor;
363 else
365 struct IMonitorNode *node = FindMonitorNode(IBase->AmbientScreenMode.ModeID,IntuitionBase);
367 if (node)
369 monitorname = node->MonitorName;
373 #endif
375 sysfont = 1;
376 sharepens = TRUE; /* not sure */
379 if ((pubname = (char*)GetTagData(SA_PubName, 0, tagList)))
381 /* Name of this public screen. */
382 struct PubScreenNode *oldpsn;
383 struct List *list;
385 list = LockPubScreenList();
387 if ((strcmp(pubname, "Workbench") == 0) || workbench)
389 if (IBase->WorkBench)
391 ok = FALSE;
394 workbench = TRUE;
396 else
398 /* jDc: LockPubScreen is not safe here as it does not lock
399 screens in private state so we could end up with two
400 screens with the same name */
401 oldpsn = (struct PubScreenNode *)FindName(list,(UBYTE*)pubname);
403 if (oldpsn)
405 SetError(OSERR_PUBNOTUNIQUE);
406 ok = FALSE;
410 UnlockPubScreenList();
412 if (ok)
414 screen->pubScrNode = AllocMem(sizeof(struct PubScreenNode), MEMF_CLEAR);
416 DEBUG_OPENSCREEN(dprintf("OpenScreen: pubScrNode 0x%lx\n",screen->pubScrNode));
418 if (screen->pubScrNode == NULL)
420 SetError(OSERR_NOMEM);
421 ok = FALSE;
424 if (ok && (screen->pubScrNode->psn_Node.ln_Name = AllocVec(MAXPUBSCREENNAME + 1,MEMF_ANY)))
426 UBYTE sigbit;
428 if ((ns.Type & SCREENTYPE) == CUSTOMSCREEN)
430 ns.Type &= ~SCREENTYPE;
431 ns.Type |= PUBLICSCREEN;
434 /* Always open public screens in private mode. */
435 screen->pubScrNode->psn_Flags |= PSNF_PRIVATE;
436 strcpy(screen->pubScrNode->psn_Node.ln_Name, pubname);
438 /* Task that should be signalled when the public screen loses
439 its last visitor window. */
441 screen->pubScrNode->psn_SigTask = (struct Task *)GetTagData(SA_PubTask, 0, tagList);
443 /* Signal bit number to use when signalling public screen
444 signal task. */
446 sigbit = GetTagData(SA_PubSig,(ULONG)-1,tagList);
448 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_PubSig 0x%lx\n",sigbit));
450 if (sigbit != (UBYTE)-1)
452 if (!screen->pubScrNode->psn_SigTask) screen->pubScrNode->psn_SigTask = FindTask(NULL);
453 screen->pubScrNode->psn_SigBit = sigbit;
455 else
457 /* do not signal with -1 ! */
458 screen->pubScrNode->psn_SigTask = NULL;
461 else
463 SetError(OSERR_NOMEM);
464 FreeMem(screen->pubScrNode, sizeof(struct PubScreenNode));
465 screen->pubScrNode = NULL;
466 ok = FALSE;
472 #ifdef SKINS
473 if (modeid != INVALID_ID)
475 /* modes can be on other monitors */
476 monitorname = NULL;
478 #endif
480 while((tag = NextTagItem ((struct TagItem **)&tagList)))
482 #if 1
483 DEBUG_OPENSCREEN(dprintf("OpenScreen: Tag 0x%08lx Data 0x%08lx\n",
484 tag->ti_Tag, tag->ti_Data));
485 #endif
486 switch(tag->ti_Tag)
488 case SA_CompositingFlags:
489 compflags = tag->ti_Data;
490 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_CompositingFlags 0x%p\n", compflags));
491 break;
492 case SA_AlphaPreCompositHook:
493 compalphahook = (struct Hook *)tag->ti_Data;
494 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AlphaPreCompositHook 0x%p\n", compalphahook));
495 break;
496 case SA_Left:
497 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Left %ld\n",tag->ti_Data));
498 ns.LeftEdge = tag->ti_Data;
499 break;
500 case SA_Top:
501 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Top %ld\n",tag->ti_Data));
502 ns.TopEdge = tag->ti_Data;
503 break;
504 case SA_Width:
505 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Width %ld\n",tag->ti_Data));
506 if ((tag->ti_Data != ~0) && (tag->ti_Data > 32767))
508 ok = FALSE;
510 ns.Width = tag->ti_Data;
511 break;
512 case SA_Height:
513 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Height %ld\n",tag->ti_Data));
514 if ((tag->ti_Data != ~0) && (tag->ti_Data > 32767))
516 ok = FALSE;
518 ns.Height = tag->ti_Data;
519 break;
520 case SA_Depth:
521 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Depth %ld\n",tag->ti_Data));
522 ns.Depth = tag->ti_Data;
523 break;
524 case SA_DetailPen:
525 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DetailPen %ld\n",tag->ti_Data));
526 ns.DetailPen = tag->ti_Data;
527 break;
528 case SA_BlockPen:
529 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BlockPen %ld\n",tag->ti_Data));
530 ns.BlockPen = tag->ti_Data;
531 break;
532 case SA_Type:
533 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Type 0x%lx\n",tag->ti_Data));
534 ns.Type &= ~SCREENTYPE;
535 ns.Type |= tag->ti_Data;
536 break;
538 case SA_Title:
539 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Title <%s>\n",tag->ti_Data));
540 ns.DefaultTitle = (UBYTE *)tag->ti_Data;
541 break;
543 case SA_Font:
544 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Font 0x%lx\n",tag->ti_Data));
545 ns.Font = (struct TextAttr *)tag->ti_Data;
546 break;
548 case SA_Colors32:
549 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors32 0x%lx\n",tag->ti_Data));
550 colors32 = (ULONG *)tag->ti_Data;
551 break;
553 case SA_Colors:
554 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Colors 0x%lx\n",tag->ti_Data));
555 colors = (struct ColorSpec *)tag->ti_Data;
556 break;
558 case SA_SysFont:
559 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SysFont 0x%lx\n",tag->ti_Data));
560 sysfont = (WORD)tag->ti_Data;
561 break;
563 case SA_BitMap:
564 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap 0x%lx\n",tag->ti_Data));
565 if(tag->ti_Data)
567 ns.Type |= CUSTOMBITMAP;
568 ns.CustomBitMap = (struct BitMap *)tag->ti_Data;
570 else
572 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BitMap==NULL specified, custom BitMap use disabled\n"));
574 break;
576 case SA_BackFill:
577 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackFill Hook 0x%lx\n",tag->ti_Data));
578 layer_info_hook = (struct Hook *)tag->ti_Data;
579 break;
581 case SA_Quiet:
582 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Quiet 0x%lx\n",tag->ti_Data));
583 if (tag->ti_Data)
585 ns.Type |= SCREENQUIET;
587 else
589 ns.Type &= ~SCREENQUIET;
591 break;
593 case SA_ShowTitle:
594 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ShowTitle 0x%lx\n",tag->ti_Data));
595 if (tag->ti_Data)
597 ns.Type |= SHOWTITLE;
599 else
601 ns.Type &= ~SHOWTITLE;
603 break;
605 case SA_Pens:
606 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Pens 0x%lx\n",tag->ti_Data));
607 customdripens = (UWORD *)tag->ti_Data;
608 break;
610 case SA_SharePens:
611 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SharePens 0x%lx\n",tag->ti_Data));
612 sharepens = tag->ti_Data ? TRUE : FALSE;
613 if (tag->ti_Data)
615 ns.Type |= PENSHARED;
616 } else {
617 ns.Type &= ~PENSHARED;
619 break;
621 case SA_Interleaved:
622 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Interleaved 0x%lx\n",tag->ti_Data));
623 if (tag->ti_Data)
625 allocbitmapflags |= BMF_INTERLEAVED;
627 else
629 allocbitmapflags &= ~BMF_INTERLEAVED;
631 break;
633 case SA_Behind:
634 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Behind 0x%lx\n",tag->ti_Data));
635 if (tag->ti_Data)
637 ns.Type |= SCREENBEHIND;
639 else
641 ns.Type &= ~SCREENBEHIND;
643 break;
645 case SA_DClip:
646 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_DClip 0x%lx\n",tag->ti_Data));
647 dclip = (struct Rectangle *)tag->ti_Data;
648 break;
650 case SA_Overscan:
651 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_OverScan 0x%lx\n",tag->ti_Data));
652 overscan = tag->ti_Data;
653 break;
655 case SA_DisplayID:
656 case SA_LikeWorkbench:
657 case SA_ErrorCode:
658 case SA_PubName:
659 case SA_PubSig:
660 case SA_PubTask:
662 * handled elsewhere
664 break;
666 case SA_AutoScroll:
667 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_AutoScroll 0x%lx\n",tag->ti_Data));
668 if (tag->ti_Data)
670 ns.Type |= AUTOSCROLL;
672 else
674 ns.Type &= ~AUTOSCROLL;
676 break;
678 case SA_FullPalette:
679 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FullPalette 0x%lx\n",tag->ti_Data));
680 break;
681 case SA_ColorMapEntries:
682 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_ColorMapEntries 0x%lx\n",tag->ti_Data));
683 numcolors = tag->ti_Data; /* AROS: Added support for this tag */
684 break;
685 case SA_Parent:
686 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Parent 0x%lx\n",tag->ti_Data));
687 break;
688 case SA_Draggable:
689 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Draggable 0x%lx\n",tag->ti_Data));
690 draggable = tag->ti_Data; /* AROS: Added support for this tag */
691 break;
692 case SA_Exclusive:
693 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_Exclusive 0x%lx\n",tag->ti_Data));
694 break;
695 case SA_VideoControl:
696 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_VideoControl 0x%lx\n",tag->ti_Data));
697 vctl = tag->ti_Data; /* AROS: Added support for this tag */
698 break;
699 case SA_FrontChild:
700 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_FrontChild 0x%lx\n",tag->ti_Data));
701 break;
702 case SA_BackChild:
703 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_BackChild 0x%lx\n",tag->ti_Data));
704 break;
705 case SA_MinimizeISG:
706 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_MinimizeISG 0x%lx\n",tag->ti_Data));
707 break;
709 case SA_MonitorName:
710 monitorname = (char*)tag->ti_Data;
711 break;
712 #ifndef __AROS__ /* AROS: Disable MorphOS-specific extensions and private stuff */
713 case SA_SkinName: /* TODO: Complete support for named skins and enable this tag. Value needed. */
714 DEBUG_OPENSCREEN(dprintf("OpenScreen: SA_SkinName (%s)\n",(char *)tag->ti_Data));
715 skinname = (char *)tag->ti_Data;
716 break;
718 case SA_VesaFallback:
719 vesafallback = tag->ti_Data;
720 break;
722 case SA_ModeEditControl:
723 modecontrol = (ULONG*)tag->ti_Data;
724 break;
726 case SA_WindowLock: /* TODO: We also can support this private tag. In which situations we don't need locking ? */
727 dowindowlock = tag->ti_Data ? TRUE : FALSE;
728 break;
730 case SA_CompositingLayers:
731 compositing = tag->ti_Data ? TRUE : FALSE;
732 break;
733 #endif
734 case SA_ShowPointer:
735 showpointer = tag->ti_Data ? TRUE : FALSE;
736 break;
738 case SA_GammaControl:
739 gammacontrol = tag->ti_Data ? TRUE : FALSE;
740 break;
742 case SA_GammaRed:
743 gammared = (UBYTE*)tag->ti_Data;
744 break;
746 case SA_GammaBlue:
747 gammablue = (UBYTE*)tag->ti_Data;
748 break;
750 case SA_GammaGreen:
751 gammagreen = (UBYTE*)tag->ti_Data;
752 break;
754 case SA_3DSupport:
755 support3d = tag->ti_Data ? TRUE : FALSE;
756 break;
758 case SA_AdaptSize:
759 adaptsize = tag->ti_Data ? TRUE : FALSE;
760 break;
762 case SA_DisplayWidth:
763 displaywidth = (ULONG)tag->ti_Data;
764 break;
766 case SA_DisplayHeight:
767 displayheight = (ULONG)tag->ti_Data;
768 break;
770 case SA_ExactMatchMonitorName:
771 exactname = tag->ti_Data ? TRUE : FALSE;
772 break;
774 /* TODO: Missing SA_ Tags */
775 default:
776 DEBUG_OPENSCREEN(dprintf("OpenScreen: unknown tag 0x%lx data 0x%lx\n",
777 tag->ti_Tag,
778 tag->ti_Data));
779 break;
781 } /* switch (tag->ti_Tag) */
783 } /* while ((tag = NextTagItem (&tagList))) */
785 } /* if (tagList) */
787 DEBUG_OPENSCREEN(dprintf("OpenScreen: Left %d Top %d Width %d Height %d Depth %d Tags 0x%lx\n",
788 ns.LeftEdge, ns.TopEdge, ns.Width, ns.Height, ns.Depth, tagList));
790 requesteddepth = ns.Depth;
792 /* Fail if bogus size is requested - Piru/jDc */
793 if ((ns.Width < -1) || (ns.Height < -1))
795 DEBUG_OPENSCREEN(dprintf("!!! OpenScreen(): Width and/or Height negative !!!\n");)
796 ok = FALSE;
799 /* First Init the RastPort then get the BitPlanes!! */
801 #ifdef __MORPHOS__
802 #include "workaround.openscreen.c"
803 #endif
804 /* AROS: Use 3D support code */
805 if (support3d)
807 struct IMonitorNode *node = NULL;
808 ULONG depth = (ULONG)-1;
810 #ifndef __AROS__
811 /*AROS: We don't need these flags because we keep ModeID together with the BitMap */
812 screen->Support3D = TRUE;
813 allocbitmapflags |= BMF_3DTARGET;
814 #endif
815 /* check for SA_DisplayID or SA_MonitorName, this can also return other monitor
816 within the same class of monitors (ex radeon7k instead of 9k) */
817 if (monitorname || (modeid != INVALID_ID))
819 DEBUG_OPENSCREEN(dprintf("OpenScreen: 3d hunt modeid 0x%lx monname %s\n",modeid,monitorname ? monitorname : "none"));
820 node = FindBestMonitorNode(NULL,monitorname,modeid,IntuitionBase);
821 if (node) depth = FindBest3dDepth(ns.Depth,node,IntuitionBase);
824 /* no suitable depth? find a monitor with best 3d capabilities */
825 if ((depth == (ULONG)-1) && !exactname)
827 DEBUG_OPENSCREEN(dprintf("OpenScreen: found no suitable depth. monnode 0x%lx\n",node));
828 node = FindBest3dMonitor(NULL,IntuitionBase);
829 if (node) depth = FindBest3dDepth(ns.Depth,node,IntuitionBase);
832 /* found a usable depth? find a modeid with that depth within the monitor we found */
833 if (depth != (ULONG)-1)
835 DEBUG_OPENSCREEN(dprintf("OpenScreen: found suitable depth %d. monnode 0x%lx\n",depth,node));
836 ns.Depth = depth;
838 modeid = FindBestModeID(node->MonitorName,ns.Depth,(displaywidth) ? displaywidth : ns.Width,(displayheight) ? displayheight : ns.Height,IntuitionBase);
840 if (modeid == INVALID_ID)
842 DEBUG_OPENSCREEN(dprintf("OpenScreen: no 3d available, fail (1)!\n"));
843 ok = FALSE;
845 } else {
846 /* whoops, no 3d support at all, fail! */
847 DEBUG_OPENSCREEN(dprintf("OpenScreen: no 3d available, fail! (2)\n"));
848 ok = FALSE;
852 else if (monitorname)
854 ULONG newmodeid = INVALID_ID;
855 newmodeid = FindBestModeID(monitorname,ns.Depth,(displaywidth) ? displaywidth : ns.Width,(displayheight) ? displayheight : ns.Height,IntuitionBase);
856 if (newmodeid != INVALID_ID) modeid = newmodeid;
857 /* monitor not available and exactmatch requested ? */
858 if (exactname)
860 if (newmodeid == INVALID_ID)
862 dprintf("uhuh, no modeid!\n");
863 ok = FALSE;
865 else
867 // make sure this is the same monitor!
868 struct IMonitorNode *node = FindMonitorNode(newmodeid,IntuitionBase);
869 if (!node || strcmp(node->MonitorName,monitorname)) ok = FALSE;
872 DEBUG_OPENSCREEN(dprintf("OpenScreen: monname %s modeid %lx\n",monitorname,modeid));
875 #ifdef __MORPHOS__
876 /* Note: CGX patched ModeNotAvailable() alone doesn't return reliable results due to some fallback code for old apps. - Piru */
877 if ((modeid == INVALID_ID) || ModeNotAvailable(modeid) || !FindDisplayInfo(modeid))
879 struct TagItem bestmodetags[] =
881 {CYBRBIDTG_Depth,0},
882 {CYBRBIDTG_NominalWidth,0},
883 {CYBRBIDTG_NominalHeight,0},
884 {TAG_DONE}
887 if((modeid & 0xF00F0000) == 0x40020000)
889 modeid &= 0x40020000;
892 bestmodetags[0].ti_Data = (ns.Depth < 8) ? 8 : ns.Depth; /* jDc: helps finding a correct mode ;)*/
893 bestmodetags[1].ti_Data = (displaywidth) ? displaywidth : ns.Width;
894 bestmodetags[2].ti_Data = (displayheight) ? displayheight : ns.Height;
896 DEBUG_OPENSCREEN(dprintf("ns.Width %ld ns.Height %ld ns.Depth %ld !!\n",
897 (LONG) ns.Width, (LONG) ns.Height, (LONG) ns.Depth);)
899 modeid = BestCModeIDTagList(bestmodetags);
901 DEBUG_OPENSCREEN(dprintf("BestCModeIDTagList returned %ld\n",modeid);)
903 #endif
905 #ifdef SKINS
906 if ((workbench) && (IBase->EmergencyBoot.monitorname))
908 struct IMonitorNode *node;
909 ULONG depthid;
910 ULONG newmodeid;
912 node = FindBestMonitorNode(GetMonitorClass(IBase->EmergencyBoot.monitorname,IntuitionBase),IBase->EmergencyBoot.monitorname,INVALID_ID,IntuitionBase);
914 newmodeid = FakeWorkbenchMode(node,(ULONG*)&depthid,IBase->EmergencyBoot.baseresolution,IntuitionBase);
916 DEBUG_OPENSCREEN(dprintf("OpenScreen: Emergency Boot! %lx\n",modeid));
918 if (newmodeid != INVALID_ID)
920 modeid = newmodeid;
921 ns.Width = IBase->EmergencyBoot.baseresolution;
923 switch (ns.Width)
925 case 800:
926 ns.Height = 600;
927 break;
929 case 1024:
930 ns.Height = 768;
931 break;
933 default:
934 ns.Width = 640;
935 ns.Height = 480;
938 screen->VESAMode = ns.Width;
939 screen->VESAModeDepthID = depthid;
943 if (workbench && (((struct IIHData *)IBase->InputHandler->is_Data)->ActQualifier & IEQUALIFIER_CONTROL))
945 vesafallback = 1024;
948 if (vesafallback)
950 struct IMonitorNode *node = NULL;
951 ULONG depthid;
952 ULONG newmodeid;
954 if (monitorname) node = FindBestMonitorNode(GetMonitorClass(monitorname,IntuitionBase),monitorname,INVALID_ID,IntuitionBase);
956 newmodeid = FakeWorkbenchMode(node,(ULONG*)&depthid,vesafallback,IntuitionBase);
958 DEBUG_OPENSCREEN(dprintf("OpenScreen: vesa fallback %lx\n",modeid));
960 if (newmodeid != INVALID_ID)
962 modeid = newmodeid;
963 ns.Width = vesafallback;
965 switch (ns.Width)
967 case 800:
968 ns.Height = 600;
969 break;
971 case 1024:
972 ns.Height = 768;
973 break;
975 default:
976 ns.Width = 640;
977 ns.Height = 480;
980 screen->VESAMode = ns.Width;
981 screen->VESAModeDepthID = depthid;
985 if (modecontrol)
987 struct IMonitorNode *inode = FindMonitorNode(modeid,IntuitionBase);
988 modeid = FakeScreenMode(inode,ns.Depth,IntuitionBase);
990 DEBUG_OPENSCREEN(dprintf("OpenScreen: fake modeid %lx\n",modeid));
992 if (modeid != INVALID_ID)
994 switch (ns.Depth)
996 case 24: screen->VESAModeDepthID = ID_MD24; break;
997 case 16: screen->VESAModeDepthID = ID_MD16; break;
998 case 15: screen->VESAModeDepthID = ID_MD15; break;
999 default: screen->VESAModeDepthID = ID_MD08; break;
1002 screen->ModeControl = modecontrol;
1004 } else {
1005 DEBUG_OPENSCREEN(dprintf("OpenScreen: failed to init testmode!\n"));
1006 ok = FALSE;
1010 #endif
1013 * AROS: Got OpenScreenTags modeid without monitor, promote to chipset default
1014 * (if present).
1015 * We really need proper mode promotion support.
1017 if ((modeid & MONITOR_ID_MASK) == 0)
1019 if (GfxBase->DisplayFlags & PAL)
1020 modeid |= PAL_MONITOR_ID;
1021 else if (GfxBase->DisplayFlags & NTSC)
1022 modeid |= NTSC_MONITOR_ID;
1025 if (INVALID_ID == modeid)
1027 #ifndef __AROS__
1028 WORD bestwidth,bestheight;
1029 #endif
1030 modetags[0].ti_Data = ns.Depth;
1031 modetags[1].ti_Data = ns.Width;
1032 modetags[2].ti_Data = ns.Height;
1033 modetags[3].ti_Data = ns.Width;
1034 modetags[4].ti_Data = ns.Height;
1036 #ifdef __AROS__
1038 * AROS: We don't have FindBestWidthAndHeight().
1039 * TODO: Can we merge better here ?
1041 if (ns.Width == STDSCREENWIDTH || ns.Width == 0 || adaptsize) {modetags[1].ti_Tag = TAG_IGNORE; modetags[3].ti_Tag = TAG_IGNORE;}
1042 if (ns.Height == STDSCREENWIDTH || ns.Height == 0 || adaptsize) {modetags[2].ti_Tag = TAG_IGNORE; modetags[4].ti_Tag = TAG_IGNORE;}
1043 #else
1044 FindBestWidthAndHeight(&bestwidth,&bestheight,ns.Depth,IntuitionBase);
1046 if (ns.Width == STDSCREENWIDTH || ns.Width == 0 || adaptsize) {modetags[1].ti_Data = bestwidth; modetags[3].ti_Data = bestwidth;}
1047 if (ns.Height == STDSCREENWIDTH || ns.Height == 0 || adaptsize) {modetags[2].ti_Data = bestheight;modetags[4].ti_Data = bestheight;}
1049 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));
1050 #endif
1051 /* AROS: Support old-style HAM or EHB request */
1052 if (newScreen->ViewModes & (HAM | EXTRA_HALFBRITE))
1054 if (newScreen->ViewModes & HAM) modetags[5].ti_Data |= DIPF_IS_HAM;
1055 if (newScreen->ViewModes & EXTRA_HALFBRITE) modetags[5].ti_Data |= DIPF_IS_EXTRAHALFBRITE;
1057 else
1059 modetags[5].ti_Tag = TAG_IGNORE;
1062 modeid = BestModeIDA(modetags);
1064 #ifdef SKINS
1065 if (modeid == INVALID_ID && workbench)
1067 ULONG depthid;
1068 ULONG newmodeid = FakeWorkbenchMode(NULL,(ULONG*)&depthid,640,IntuitionBase);
1069 /* create an ID */
1071 DEBUG_OPENSCREEN(dprintf("OpenScreen: Vesa Fallback!\n"));
1073 if (newmodeid != INVALID_ID)
1075 modeid = newmodeid;
1076 ns.Width = 640;
1077 ns.Height = 480;
1079 screen->VESAMode = 640;
1080 screen->VESAModeDepthID = depthid;
1083 #endif
1085 if (INVALID_ID == modeid)
1087 // wtf? no monitors??
1088 D(bug("!!! OpenScreen(): Could not find any valid modeids. No graphics card? !!!\n"));
1089 SetError(OSERR_UNKNOWNMODE); /* AROS: Added error core setting, fixed MorphOS bug */
1090 ok = FALSE;
1094 DEBUG_OPENSCREEN(dprintf("OpenScreen: ModeID 0x%08lx\n", modeid));
1096 InitRastPort(&screen->Screen.RastPort);
1097 rp_inited = TRUE;
1098 success = FALSE;
1100 if (ok && (displayinfo = FindDisplayInfo(modeid)) != NULL &&
1101 GetDisplayInfoData(displayinfo, (APTR)&dimensions, sizeof(dimensions), DTAG_DIMS, modeid)
1102 #ifdef __AROS__ /* AROS: We don't need MonitorSpec, however we get DisplayInfo early to get the compositors bm hooks. */
1103 && GetDisplayInfoData(displayinfo, (APTR)&dispinfo, sizeof(dispinfo), DTAG_DISP, modeid)
1104 #else
1105 && GetDisplayInfoData(displayinfo, (APTR)&monitor, sizeof(monitor), DTAG_MNTR, modeid)
1106 #endif
1109 success = TRUE;
1110 #ifdef __AROS__ /* AROS: Get HIDD composition flags */
1111 screen->SpecialFlags = ((compflags & (dimensions.reserved[0] >> 16)) | (dimensions.reserved[0] & 0xFFFF)) << 8;
1112 screen->preAlphaCompHook = compalphahook;
1114 if (draggable) screen->SpecialFlags |= SF_Draggable;
1115 #else
1116 screen->Monitor = monitor.Mspc;
1117 #endif
1118 if (dclip == NULL)
1120 switch (overscan)
1122 case OSCAN_STANDARD:
1123 dclip = &dimensions.StdOScan;
1124 break;
1126 case OSCAN_MAX:
1127 dclip = &dimensions.MaxOScan;
1128 break;
1130 case OSCAN_VIDEO:
1131 dclip = &dimensions.VideoOScan;
1132 break;
1134 default:
1135 dclip = &dimensions.TxtOScan;
1136 break;
1140 if (ns.Width == STDSCREENWIDTH || ns.Width == 0 || adaptsize)
1141 ns.Width = dclip->MaxX - dclip->MinX + 1;
1142 /* AROS: Added raster size limit support */
1143 #if (0)
1144 else if (ns.Width < dimensions.MinRasterWidth)
1145 ns.Width = dimensions.MinRasterWidth;
1146 else if (ns.Width > dimensions.MaxRasterWidth)
1147 ns.Width = dimensions.MaxRasterWidth;
1148 #endif
1149 if (ns.Height == STDSCREENHEIGHT || ns.Height == 0 || adaptsize)
1150 ns.Height = dclip->MaxY - dclip->MinY + 1;
1151 /* AROS: Added raster size limit support */
1152 #if (0)
1153 else if (ns.Height < dimensions.MinRasterHeight)
1154 ns.Height = dimensions.MinRasterHeight;
1155 else if (ns.Height > dimensions.MaxRasterHeight)
1156 ns.Height = dimensions.MaxRasterHeight;
1157 DEBUG_OPENSCREEN(dprintf("OpenScreen: Monitor 0x%lx Width %ld Height %ld\n",
1158 screen->Monitor, ns.Width, ns.Height));
1159 #endif
1161 if (ns.Type & CUSTOMBITMAP)
1163 struct BitMap *custombm;
1164 custombm = ns.CustomBitMap;
1165 #ifdef __AROS__ /* AROS: We don't have CGX in kickstart */
1166 /* FIXME: m68k Compositor needs to report that it can composit planar bitmaps */
1167 BOOL (*__IsCompositable) (struct BitMap *, DisplayInfoHandle, struct GfxBase *) = (APTR)dispinfo.reserved[0];
1168 BOOL (*__MakeDisplayable) (struct BitMap *, DisplayInfoHandle, struct GfxBase *) = (APTR)dispinfo.reserved[1];
1170 if (dispinfo.reserved[0])
1172 if (__IsCompositable(custombm, displayinfo, GfxBase))
1174 DEBUG_OPENSCREEN(dprintf("OpenScreen: Marking CustomBitMap 0x%lx as compositable\n", custombm));
1175 __MakeDisplayable(custombm, displayinfo, GfxBase);
1177 else
1179 custombm = NULL;
1182 else if ((!IS_HIDD_BM(custombm)) || (modeid != HIDD_BM_HIDDMODE(custombm)))
1184 custombm = NULL;
1186 #else
1187 if (IsCyberModeID(modeid) && custombm)
1189 int pixfmt = GetCyberIDAttr(CYBRIDATTR_PIXFMT,modeid);
1191 if(GetCyberMapAttr(custombm,CYBRMATTR_PIXFMT) != pixfmt)
1193 // incompatible formats !
1194 custombm = NULL;
1197 #endif
1198 if(custombm != NULL)
1200 screen->Screen.RastPort.BitMap = custombm;
1201 ns.Depth = GetBitMapAttr(ns.CustomBitMap,BMA_DEPTH);
1202 DEBUG_OPENSCREEN(dprintf("OpenScreen: CustomBitMap Depth %ld\n",
1203 ns.Depth));
1204 } else {
1205 ns.CustomBitMap = NULL;
1206 ns.Type &= ~CUSTOMBITMAP;
1208 } else {
1209 screen->Screen.RastPort.BitMap = NULL;
1212 if ((screen->IMonitorNode = FindMonitorNode(modeid,IntuitionBase)))
1214 DEBUG_OPENSCREEN(dprintf("OpenScreen: MonitorNode 0x%lx\n",
1215 screen->IMonitorNode));
1216 } else {
1217 DEBUG_OPENSCREEN(dprintf("OpenScreen: No MonitorNode\n"));
1218 ok = FALSE;
1221 if(ok && (screen->Screen.RastPort.BitMap == NULL))
1223 #ifdef __AROS__ /* AROS: BitMap needs ModeID */
1224 ULONG Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : ns.Depth;
1225 struct TagItem bmtags[] =
1227 {BMATags_DisplayID, modeid},
1228 {TAG_DONE , 0 }
1231 screen->Screen.RastPort.BitMap = AllocBitMap(ns.Width, ns.Height, Depth,
1232 allocbitmapflags | BMF_CHECKVALUE,
1233 (struct BitMap *)bmtags);
1234 #else
1235 struct BitMap *root = NULL;
1236 ULONG pixfmt;
1237 ULONG Depth;
1238 int retrycnt=1;
1239 ULONG stdwidth = dimensions.Nominal.MaxX - dimensions.Nominal.MinX + 1;
1240 ULONG stdheight = dimensions.Nominal.MaxY - dimensions.Nominal.MinY + 1;
1242 #ifdef USE8BITHACK
1243 Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : 8;
1244 #else
1245 Depth = (dimensions.MaxDepth > 8) ? dimensions.MaxDepth : ns.Depth;
1246 #endif
1248 switch(Depth)
1250 case 15:
1251 pixfmt = PIXFMT_RGB15;
1252 break;
1253 case 16:
1254 pixfmt = PIXFMT_RGB16;
1255 break;
1256 case 24:
1257 pixfmt = PIXFMT_BGR24;
1258 break;
1259 case 32:
1260 pixfmt = PIXFMT_ARGB32;
1261 break;
1262 default:
1263 pixfmt = PIXFMT_LUT8;
1264 break;
1267 if (IsCyberModeID(modeid))
1269 pixfmt = GetCyberIDAttr(CYBRIDATTR_PIXFMT,modeid);
1272 DoMethod((Object*)screen->IMonitorNode,MM_GetRootBitMap,pixfmt,(ULONG)&root);
1274 DEBUG_OPENSCREEN(dprintf("OpenScreen: root BitMap 0x%lx\n",root));
1278 allocbitmapflags &= (BMF_DISPLAYABLE | BMF_INTERLEAVED | BMF_3DTARGET);
1280 if(root == NULL)
1282 allocbitmapflags |= (BMF_SPECIALFMT|/*BMF_CLEAR|*/BMF_DISPLAYABLE|BMF_MINPLANES);
1283 allocbitmapflags |= SHIFT_PIXFMT(pixfmt);
1285 else
1287 allocbitmapflags |= (/*BMF_CLEAR|*/BMF_DISPLAYABLE|BMF_MINPLANES);
1290 if((screen->Screen.RastPort.BitMap = AllocBitMap((ns.Width > stdwidth) ? ns.Width : stdwidth,
1291 (ns.Height > stdheight) ? ns.Height : stdheight,
1292 Depth,
1293 allocbitmapflags,
1294 root)) == NULL)
1296 root = NULL;
1299 while((screen->Screen.RastPort.BitMap == NULL) && (retrycnt--));
1300 #endif
1301 screen->AllocatedBitMap = screen->Screen.RastPort.BitMap;
1303 DEBUG_OPENSCREEN(dprintf("OpenScreen: allocated BitMap 0x%lx\n",screen->AllocatedBitMap));
1305 if (screen->Screen.RastPort.BitMap)
1307 UpdateScreenBitMap(&screen->Screen, IntuitionBase);
1308 #ifndef __AROS__
1310 * AROS: This seems to be not needed
1311 * TODO: Check if this is really true, test case needed
1313 if (Depth > 8)
1315 if (stdwidth > ns.Width)
1317 struct RastPort rport;
1319 InitRastPort(&rport);
1320 rport.BitMap = screen->AllocatedBitMap;
1321 SetRPAttrs(&rport,RPTAG_PenMode,FALSE,RPTAG_FgColor,0x0,TAG_DONE);
1323 RectFill(&rport,ns.Width,0,stdwidth - 1,ns.Height - 1);
1326 if (stdheight > ns.Height)
1328 struct RastPort rport;
1330 InitRastPort(&rport);
1331 rport.BitMap = screen->AllocatedBitMap;
1332 SetRPAttrs(&rport,RPTAG_PenMode,FALSE,RPTAG_FgColor,0x0,TAG_DONE);
1334 RectFill(&rport,0,ns.Height,ns.Width - 1,stdheight - 1);
1337 #endif
1341 DEBUG_OPENSCREEN(dprintf("OpenScreen: BitMap 0x%lx\n",
1342 screen->Screen.RastPort.BitMap));
1344 else
1346 DEBUG_OPENSCREEN(dprintf("OpenScreen: no displayinfo\n"));
1347 SetError(OSERR_UNKNOWNMODE); /* AROS: Added error code setting, fixed MorphOS bug */
1350 D(bug("got BitMap\n"));
1352 /* Init screen's viewport */
1353 InitVPort(&screen->Screen.ViewPort);
1355 /* Allocate a RasInfo struct in which we have a pointer
1356 to the struct BitMap, into which the driver can
1357 store its stuff. (Eg. pointer to a BitMap HIDD object)
1359 screen->Screen.ViewPort.RasInfo = AllocMem(sizeof(struct RasInfo), MEMF_ANY | MEMF_CLEAR);
1361 DEBUG_OPENSCREEN(dprintf("OpenScreen: RasInfo 0x%lx\n",
1362 screen->Screen.ViewPort.RasInfo));
1364 if (!success ||
1365 (screen->Screen.RastPort.BitMap == NULL) ||
1366 (screen->Screen.ViewPort.RasInfo == NULL))
1368 ok = FALSE;
1369 } else {
1370 /* Store pointer to BitMap, so we can get hold of it
1371 from withing LoadRGBxx() functions
1373 D(bug("got allocated stuff\n"));
1374 screen->Screen.ViewPort.RasInfo->BitMap = screen->Screen.RastPort.BitMap;
1377 if (ok)
1379 /* Read depth from the BitMap to avoid AttachPalExtra/ObtainPen getting
1380 * confused if cgx decided to allocate a higher depth BitMap than what
1381 * was asked.
1383 ns.Depth = GetBitMapAttr(screen->Screen.RastPort.BitMap,BMA_DEPTH);
1385 if (!numcolors) /* AROS: Added support for SA_ColorMapEntries */
1387 #ifdef USE8BITHACK
1388 numcolors = 256;
1389 #else
1390 numcolors = (ns.Depth <= 8) ? (1L << ns.Depth) : 256;
1391 #endif
1394 /* Get a color map structure. Sufficient colors?? */
1396 DEBUG_OPENSCREEN(dprintf("OpenScreen: Colormap Entries %ld\n",
1397 numcolors));
1398 if ((screen->Screen.ViewPort.ColorMap = GetColorMap(numcolors < 32 ? 32 : numcolors)) != NULL)
1400 if (0 == AttachPalExtra(screen->Screen.ViewPort.ColorMap,
1401 &screen->Screen.ViewPort))
1403 #if 0
1404 int i=0;
1405 char *alloclist;
1406 UWORD *refcnt;
1408 refcnt =(UWORD*) screen->Screen.ViewPort.ColorMap->PalExtra->pe_RefCnt;
1409 alloclist = (UBYTE *)(refcnt + screen->Screen.ViewPort.ColorMap->Count);
1411 DEBUG_OPENSCREEN(dprintf("OpenScreen: PalExtra alloclist 0x%lx Count %ld\n",alloclist,screen->Screen.ViewPort.ColorMap->Count));
1413 while(i < screen->Screen.ViewPort.ColorMap->Count)
1415 // initialize alloc list to -1,0,1,2,3,4
1417 DEBUG_OPENSCREEN(dprintf("OpenScreen: alloclist[%ld]=%ld\n",
1418 i,alloclist[i]));
1419 i++;
1421 #endif
1423 else
1425 ok = FALSE;
1428 else
1430 ok = FALSE;
1433 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%lx\n",
1434 screen->Screen.ViewPort.ColorMap));
1437 #ifdef __MORPHOS__
1440 ULONG pixfmt = -1;
1441 APTR handle = LockBitMapTags(screen->Screen.RastPort.BitMap,
1442 LBMI_PIXFMT,(ULONG)&pixfmt,TAG_DONE);
1444 if (handle)
1446 UnLockBitMap(handle);
1447 screen->PixelFormat = pixfmt;
1449 else
1451 screen->PixelFormat = -1;
1454 #endif
1455 screen->GammaControl.UseGammaControl = gammacontrol;
1456 screen->GammaControl.GammaTableR = gammared;
1457 screen->GammaControl.GammaTableG = gammagreen;
1458 screen->GammaControl.GammaTableB = gammablue;
1459 #ifndef __AROS__
1461 * AROS: This fragment seems to delay-load default gamma table for the monitor.
1462 * TODO: May be use this approach ?
1464 if (screen->IMonitorNode && !screen->IMonitorNode->GammaLoaded)
1466 int_SkinAction(SKA_LoadGamma,(ULONG *)screen->IMonitorNode,NULL,IntuitionBase);
1467 screen->IMonitorNode->GammaLoaded = TRUE;
1470 // no hotkey by default
1471 screen->RecallHotkey.ia_Key = 0xFF;
1472 #endif
1473 screen->ModeID = modeid;
1475 if (ok)
1477 struct ViewPortExtra *vpe = (struct ViewPortExtra *)GfxNew(VIEWPORT_EXTRA_TYPE);
1479 DEBUG_OPENSCREEN(dprintf("OpenScreen: ViewPortExtra 0x%lx\n", vpe));
1481 ok = FALSE;
1483 if (vpe)
1485 struct TagItem tags[6];
1487 memcpy(&vpe->DisplayClip, dclip,sizeof(struct Rectangle));
1488 #ifdef __AROS__
1490 * AROS: Set ViewPort offset and get size from dclip.
1491 * CHECKME: MorphOS source code always sets ViewPort's DWidth and DHeight to
1492 * nominal size, while ViewPortExtra's DisplayClip is still set to OverScan
1493 * rectangle. Whose approach is correct ?
1495 screen->Screen.ViewPort.DxOffset = ns.LeftEdge;
1496 screen->Screen.ViewPort.DyOffset = ns.TopEdge;
1497 screen->Screen.ViewPort.DWidth = dclip->MaxX - dclip->MinX + 1;
1498 screen->Screen.ViewPort.DHeight = dclip->MaxY - dclip->MinY + 1;
1499 #else
1500 /* using vpe data for vesamode/modecontrol is not a good idea since the mode
1501 is changed all the fly and the actual data might not be what we'll use */
1503 if (screen->VESAMode)
1505 screen->Screen.ViewPort.DWidth = screen->VESAMode;
1507 switch (screen->VESAMode)
1509 case 800:
1510 screen->Screen.ViewPort.DHeight = 600;
1511 break;
1513 case 1024:
1514 screen->Screen.ViewPort.DHeight = 768;
1515 break;
1517 default:
1518 screen->Screen.ViewPort.DWidth = 640;
1519 screen->Screen.ViewPort.DHeight = 480;
1522 screen->VESAMode = ns.Width;
1523 } else if (screen->ModeControl) {
1524 screen->Screen.ViewPort.DWidth = ns.Width;
1525 screen->Screen.ViewPort.DHeight = ns.Height;
1526 } else {
1527 ULONG stdwidth = dimensions.Nominal.MaxX - dimensions.Nominal.MinX + 1;
1528 ULONG stdheight = dimensions.Nominal.MaxY - dimensions.Nominal.MinY + 1;
1530 screen->Screen.ViewPort.DWidth = min(ns.Width,stdwidth);
1531 screen->Screen.ViewPort.DHeight = min(ns.Height,stdheight);
1533 #endif
1534 tags[0].ti_Tag = VTAG_ATTACH_CM_SET;
1535 tags[0].ti_Data = (IPTR)&screen->Screen.ViewPort;
1536 tags[1].ti_Tag = VTAG_VIEWPORTEXTRA_SET;
1537 tags[1].ti_Data = (IPTR)vpe;
1538 tags[2].ti_Tag = VTAG_NORMAL_DISP_SET;
1539 tags[2].ti_Data = (IPTR)displayinfo;
1540 tags[3].ti_Tag = VTAG_VPMODEID_SET;
1541 tags[3].ti_Data = modeid;
1542 tags[4].ti_Tag = VTAG_SPEVEN_BASE_SET; /* AROS: Added sprite base and user-supplied tags */
1543 tags[5].ti_Tag = VTAG_NEXTBUF_CM; /* if vctl is 0, this will terminate the list */
1544 tags[5].ti_Data = vctl;
1547 * Originally we could always use palette entries 16-19 for
1548 * sprites, even if the screen has less than 32 colors. AROS may
1549 * run on hardware that does not allow this (e.g. VGA cards).
1550 * In this case we have to shift down sprite colors. Currently
1551 * we use 4 colors before last 4 colors. For example on VGA cards
1552 * with only 16 colors we use colors 9 - 12. Remember that last 4 colors
1553 * of the screen are always used by Intuition.
1554 * Remember that the first color of the sprite is always transparent. So actually
1555 * we use 3, not 4 colors.
1556 * Yes, sprites may look not as expected on screens with low color depth, but at
1557 * least they will be seen. It's better than nothing.
1559 * Note that because our base color number doesn't always divide by 16, we use MSB to store
1560 * the remainder (offset in the color bank). Yes, it's a bit hacky, but i have no better idea
1561 * at the moment.
1563 * FIXME: this mapping scheme assumes that we always have at least 16 colors.
1564 * For current display modes supported by AROS it's always true, but in future
1565 * we may support more display modes (for example monochrome ones), and we
1566 * should take into account that on screens with less than 11 colors this simply
1567 * won't work
1569 * TODO: I think we should have SpriteBase attribute for the BitMap which
1570 * defaults to acceptable value. We should just get its default value here.
1571 * The same attribute would be set by VideoControl() and MakeVPort() in order
1572 * to actually apply the value.
1574 #if (AROS_FLAVOUR & AROS_FLAVOUR_BINCOMPAT)
1575 spritebase = 16;
1576 #else
1577 spritebase = (ns.Depth < 5) ? (1 << ns.Depth) - 8 : 16;
1578 #endif
1579 DEBUG_OPENSCREEN(bug("OpenScreen: spritebase is %u\n", spritebase));
1580 tags[4].ti_Data = ((spritebase & 0x0F) << 8 ) | (spritebase >> 4);
1582 if (VideoControl(screen->Screen.ViewPort.ColorMap, tags) == 0)
1584 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl ok\n"));
1585 ok = TRUE;
1587 else
1589 DEBUG_OPENSCREEN(dprintf("OpenScreen: VideoControl failed\n"));
1594 if (ok)
1596 struct Color32 *p;
1597 int k;
1598 UWORD *q;
1600 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set first 4 colors\n"));
1602 p = IBase->Colors;
1603 for (k = 0; k < 4 && k < numcolors; ++k)
1605 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB32 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1606 screen->Screen.ViewPort,
1607 k, p[k].red, p[k].green, p[k].blue));
1608 SetRGB32(&screen->Screen.ViewPort, k, p[k].red, p[k].green, p[k].blue);
1611 if (ns.Depth >= 3)
1614 * AROS: Use screen depth instead of 'numcolors' in order to calculate
1615 * numbers of last 4 colors of the screen.
1616 * This is necessary because we can have 8- or 16- color screen whose
1617 * ColorMap will still have 32 colors for AmigaOS(tm) compatibility
1618 * reasons.
1620 ULONG lastcol = ((ns.Depth > 8) ? 256 : (1 << ns.Depth)) - 4;
1622 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set last 4 colors\n"));
1624 for (k = 0; k < 4; ++k)
1626 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB32 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1627 screen->Screen.ViewPort,
1628 k + lastcol, p[k+4].red, p[k+4].green, p[k+4].blue));
1630 if (k + lastcol < numcolors)
1632 ObtainPen(screen->Screen.ViewPort.ColorMap,
1633 k + lastcol,
1634 p[k+4].red,
1635 p[k+4].green,
1636 p[k+4].blue,
1637 PEN_EXCLUSIVE);
1639 else
1641 SetRGB32(&screen->Screen.ViewPort, k + lastcol, p[k+4].red, p[k+4].green, p[k+4].blue);
1647 * AROS: AmigaOS(tm) 3.1-compatible mouse colors handling
1648 * 1. Allocate pens for the mouse pointer only on LUT screens.
1649 * On hi- and truecolor screens sprite colors come from colormap attached
1650 * to the sprite BitMap itself. See pointerclass::New() for details.
1651 * 2. Use 32-bit pointer colors instead of KS1.3 ActivePreferences->color17
1653 if (ns.Depth < 9)
1655 DEBUG_OPENSCREEN(dprintf("OpenScreen: Obtain Mousepointer colors\n"));
1657 for (k = 1; k < 4; ++k, ++q)
1659 DEBUG_OPENSCREEN(dprintf("OpenScreen: ColorMap 0x%P Pen %d R 0x%08X G 0x08X B 0x%08X\n",
1660 screen->Screen.ViewPort.ColorMap,
1661 k + spritebase,
1662 p[k+7].red, p[k+7].green, p[k+7].blue));
1663 if (k + spritebase < numcolors)
1665 ObtainPen(screen->Screen.ViewPort.ColorMap,
1666 k + spritebase,
1667 p[k+7].red, p[k+7].green, p[k+7].blue,
1668 PEN_EXCLUSIVE);
1670 else
1672 /* Can't be allocated, but can still be set. */
1673 SetRGB32(&screen->Screen.ViewPort,
1674 k + spritebase,
1675 p[k+7].red, p[k+7].green, p[k+7].blue);
1680 if (colors) /* if SA_Colors tag exists */
1682 DEBUG_OPENSCREEN(dprintf("OpenScreen: set SA_Colors 0x%lx\n",colors));
1683 for(; colors->ColorIndex != (WORD)~0; colors++)
1685 DEBUG_OPENSCREEN(dprintf("OpenScreen: SetRGB4 Viewport 0x%lx Index %ld R 0x%lx G 0x%lx B 0x%lx\n",
1686 screen->Screen.ViewPort,
1687 colors,
1688 colors->Red,
1689 colors->Green,
1690 colors->Blue));
1691 SetRGB4(&screen->Screen.ViewPort,
1692 colors->ColorIndex,
1693 colors->Red,
1694 colors->Green,
1695 colors->Blue);
1699 if (colors32) /* if SA_Colors32 tag exists */
1701 DEBUG_OPENSCREEN(dprintf("OpenScreen: LoadRGB32 colors32 0x%lx\n",colors32));
1702 LoadRGB32(&screen->Screen.ViewPort, (const ULONG *)colors32);
1705 D(bug("Loaded colors\n"));
1707 COPY(LeftEdge);
1708 COPY(TopEdge);
1709 COPY(Width);
1710 COPY(Height);
1711 COPY(DetailPen);
1712 COPY(BlockPen);
1713 COPY(Font);
1714 COPY(DefaultTitle);
1716 //intui68k filters this
1717 screen->Screen.Flags = (ns.Type & ~NS_EXTENDED);
1719 /* Temporary hack */
1720 if (ns.Width >= 500 || ns.Height >= 300)
1721 screen->Screen.Flags |= SCREENHIRES;
1724 Copy the data from the rastport's BitMap
1725 to the screen's BitMap structure
1727 UpdateScreenBitMap(&screen->Screen, IntuitionBase);
1729 #ifdef __MORPHOS__
1730 screen->Screen.WBorTop = 2;
1731 screen->Screen.WBorLeft = 4;
1732 screen->Screen.WBorRight = 4;
1733 screen->Screen.WBorBottom = 2;
1734 #else
1735 screen->Screen.WBorTop = 6; /* Amiga default is 2 */
1736 screen->Screen.WBorLeft = 4;
1737 screen->Screen.WBorRight = 4;
1738 screen->Screen.WBorBottom = 4; /* Amiga default is 2 */
1739 #endif
1741 screen->Screen.Title = ns.DefaultTitle;
1743 DEBUG_OPENSCREEN(dprintf("OpenScreen: init layers\n"));
1744 #ifdef __AROS__ /* AROS: We have no compositing layers */
1745 InitLayers(&screen->Screen.LayerInfo);
1746 #else
1747 if (((struct Library *)LayersBase)->lib_Version >= 52 && compositing &&
1748 screen->IMonitorNode->Compositing)
1750 struct TagItem layerinfotags[] =
1752 {SA_Width,screen->Screen.Width},
1753 {SA_Height,screen->Screen.Height},
1754 {SA_PixelFormat,screen->PixelFormat},
1755 {MA_MemorySize,screen->IMonitorNode->BoardMemory},
1756 {LT_IgnoreMemoryChecks, IBase->LayerSettings.IgnoreMemoryChecks},
1757 {SA_CompositingLayers, TRUE},
1758 {TAG_DONE}
1760 ULONG iscompositing = FALSE;
1762 // make SA_CompositingLayers return TRUE (layers will ask)
1763 screen->Compositing = TRUE;
1764 InitScreenLayerInfo(&screen->Screen,layerinfotags);
1766 // validate if we're compositing
1767 LayersControlTags(&screen->Screen.LayerInfo,
1768 LT_GetCompositing,(ULONG)&iscompositing,
1770 // also set current layers settings
1771 LT_AllowDoubleBuffered, IBase->LayerSettings.AllowDoubleBuffered,
1772 LT_AllowTripleBuffered, IBase->LayerSettings.AllowTripleBuffered,
1773 LT_IgnoreMemoryChecks, IBase->LayerSettings.IgnoreMemoryChecks,
1774 LT_LoadBalancing, IBase->LayerSettings.LoadBalancing,
1776 TAG_DONE);
1778 screen->Compositing = iscompositing ? TRUE : FALSE;
1780 else
1782 struct TagItem layerinfotags[] =
1784 {SA_CompositingLayers, FALSE},
1785 {TAG_DONE}
1787 screen->Compositing = FALSE;
1788 InitScreenLayerInfo(&screen->Screen,layerinfotags);
1790 #endif
1791 li_inited = TRUE;
1793 if (NULL != layer_info_hook)
1795 DEBUG_OPENSCREEN(dprintf("OpenScreen: instal layerinfohook\n"));
1796 InstallLayerInfoHook(&screen->Screen.LayerInfo, layer_info_hook);
1798 D(bug("layers intited screen\n"));
1800 /* AROS: We have already obtained resolution data from DisplayInfo */
1801 #ifdef __AROS__
1802 screen->DInfo.dri_Version = DRI_VERSION;
1803 #else
1804 GetDisplayInfoData(NULL, (APTR)&dispinfo, sizeof(dispinfo), DTAG_DISP, modeid);
1805 screen->DInfo.dri_Version = MOS_DRI_VERSION;
1806 #endif
1807 screen->DInfo.dri_NumPens = NUMDRIPENS;
1808 screen->DInfo.dri_Pens = screen->Pens;
1809 /* dri_Depth is 8 on hi/true color screens like in AmigaOS with picasso96/cybergraphx */
1810 screen->DInfo.dri_Depth = (ns.Depth <= 8) ? ns.Depth : 8;
1811 /* AROS: Get resolution from DisplayInfo */
1812 screen->DInfo.dri_Resolution.X = dispinfo.Resolution.x;
1813 screen->DInfo.dri_Resolution.Y = dispinfo.Resolution.y;
1814 screen->DInfo.dri_Flags = 0;
1817 /* SA_SysFont overrides SA_Font! */
1819 DEBUG_OPENSCREEN(dprintf("OpenScreen: SysFont = %d, ns.Font = %p\n", sysfont, ns.Font));
1821 if (sysfont == 0)
1823 /* Is handled below */
1824 DEBUG_OPENSCREEN(dprintf("OpenScreen: skip SysFont for now\n"));
1825 } else if (sysfont == 1) {
1827 screen->DInfo.dri_Font = SafeReopenFont(IntuitionBase, &IBase->ScreenFont);
1829 if (screen->DInfo.dri_Font)
1831 screen->SysFont = TRUE;
1833 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set ScreenFont\n"));
1835 } else if (ns.Font) {
1836 screen->DInfo.dri_Font = OpenFont(ns.Font);
1837 DEBUG_OPENSCREEN(dprintf("OpenScreen: custom font 0x%lx\n",screen->DInfo.dri_Font));
1840 if (!screen->DInfo.dri_Font)
1842 /* GfxBase->DefaultFont is *not* always topaz 8. It
1843 can be set with the Font prefs program!! */
1845 screen->DInfo.dri_Font = SafeReopenFont(IntuitionBase, &GfxBase->DefaultFont);
1848 if (!screen->DInfo.dri_Font) ok = FALSE;
1850 } /* if (ok) */
1852 if (ok)
1854 ULONG *dripens = NULL;
1856 switch (ns.Depth)
1858 case 1:
1859 dripens = (ULONG*)&IBase->DriPens2;
1860 break;
1862 case 2:
1863 dripens = (ULONG*)&IBase->DriPens4;
1864 break;
1866 default:
1867 if (colors || colors32)
1869 /* jDc: apps are used to use non-std colors for pen # >=4
1870 dripens4 will be a good fallback for this */
1871 dripens = (ULONG*)&IBase->DriPens4;
1872 } else {
1873 dripens = (ULONG*)&IBase->DriPens8;
1875 break;
1878 /* set default values for pens */
1879 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Default Pens\n"));
1880 CopyMem(dripens,screen->Pens,sizeof(screen->Pens));
1882 if (ns.Depth > 1)
1884 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set NewLook\n"));
1885 screen->DInfo.dri_Flags |= DRIF_NEWLOOK;
1888 if (customdripens)
1890 WORD i;
1892 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set Custom Pens\n"));
1893 screen->Pens[DETAILPEN] = screen->Screen.DetailPen;
1894 screen->Pens[BLOCKPEN] = screen->Screen.BlockPen;
1896 for(i = 0; (i < NUMDRIPENS) && (customdripens[i] != (UWORD)~0) && (screen->Pens[i] != (UWORD)~0); i++)
1898 DEBUG_OPENSCREEN(dprintf("OpenScreen: Pen[%ld] %ld --> %ld\n",i,screen->Pens[i],customdripens[i]));
1899 screen->Pens[i] = customdripens[i];
1904 * Let's do some broken software validation of the pens
1905 * so we may not run into a black desktop.
1908 DEBUG_OPENSCREEN(dprintf("OpenScreen: Check Default Pens if the make sense\n"));
1909 if (screen->Screen.DetailPen == screen->Screen.BlockPen)
1911 DEBUG_OPENSCREEN(dprintf("OpenScreen: DetailPen==BlockPen..correct\n"));
1912 screen->Screen.DetailPen = 0;
1913 screen->Screen.BlockPen = 1;
1914 } else if (screen->Screen.BlockPen == 0)
1916 DEBUG_OPENSCREEN(dprintf("OpenScreen: BlockPen==0..correct\n"));
1917 screen->Screen.BlockPen = screen->Screen.DetailPen;
1918 screen->Screen.DetailPen = 0;
1921 screen->Pens[DETAILPEN] = screen->Screen.DetailPen;
1922 screen->Pens[BLOCKPEN] = screen->Screen.BlockPen;
1924 /* Allocate shared/exclusive colors */
1927 BYTE color_alloced[256];
1928 UWORD mask;
1929 WORD i;
1931 /*for(i = 0; i < 256; i++)
1933 color_alloced[i] = FALSE;
1935 memclr(&color_alloced,256);
1937 /* Mouse pointer colors */
1939 color_alloced[17] = TRUE;
1940 color_alloced[18] = TRUE;
1941 color_alloced[19] = TRUE;
1943 /* Clamp the pen numbers. This makes sure that values such as -4 or -3
1944 won't result in random memory trashing, but rather index colours from
1945 the end of the shareable palette. - Piru */
1946 mask = screen->Screen.ViewPort.ColorMap->PalExtra->pe_SharableColors & 0xff;
1948 /* The Pens in the DrawInfo must be allocated as shared */
1950 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen DrawInfo Pens as shared\n"));
1951 for(i = 0; (i < NUMDRIPENS) && (screen->Pens[i] != (UWORD)~0); i++)
1953 int pen = screen->Pens[i] & mask;
1954 if (!color_alloced[pen])
1956 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1957 screen->Screen.ViewPort.ColorMap,
1958 pen));
1960 ObtainPen(screen->Screen.ViewPort.ColorMap,
1961 pen,
1965 PENF_NO_SETCOLOR);
1966 color_alloced[pen] = TRUE;
1969 DEBUG_OPENSCREEN(dprintf("OpenScreen: done\n"));
1971 /* If SA_SharePens is FALSE then allocate the rest of the colors
1972 in the colormap as exclusive */
1974 if (!sharepens)
1976 ULONG shnumcolors = (requesteddepth <= 8) ? (1L << requesteddepth) : 256;
1978 /* jDc: hack, colors above requested screen depth are not locked! */
1980 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen the remaining Pens as exclusive\n"));
1981 for(i = 0; i < shnumcolors; i++)
1983 if (!color_alloced[i])
1985 DEBUG_OPENSCREEN(dprintf("OpenScreen: ObtainPen ColorMap 0x%lx Pen %ld\n",
1986 screen->Screen.ViewPort.ColorMap,
1987 i));
1988 ObtainPen(screen->Screen.ViewPort.ColorMap,
1993 PENF_EXCLUSIVE | PENF_NO_SETCOLOR);
1997 } /* if (!sharepens) */
2002 if (ok)
2004 screen->DInfo.dri_Screen = &screen->Screen; //useful sometimes ;)
2006 screen->realdepth = GetBitMapAttr( screen->Screen.RastPort.BitMap, BMA_DEPTH );
2008 if (screen->realdepth > 8)
2010 screen->DInfo.dri_Flags |= DRIF_DIRECTCOLOR;
2011 } else {
2012 screen->DInfo.dri_Flags &= ~DRIF_DIRECTCOLOR;
2015 #ifdef SKINS
2016 if (!(screen->DInfo.dri_Colors = AllocMem(4 * DRIPEN_NUMDRIPENS,MEMF_PUBLIC)))
2017 ok = FALSE;
2019 if (ok)
2021 CopyMem(&defaultdricolors,screen->DInfo.dri_Colors,sizeof (defaultdricolors));
2022 memset(((UBYTE *) screen->DInfo.dri_Colors) + sizeof(defaultdricolors), 0, 4 * DRIPEN_NUMDRIPENS - sizeof(defaultdricolors));
2024 #endif
2026 if (ok)
2028 DEBUG_OPENSCREEN(dprintf("OpenScreen: allocating dri_Customize\n"));
2030 if ((screen->DInfo.dri_Customize = AllocMem(sizeof (struct IntuitionCustomize),MEMF_PUBLIC|MEMF_CLEAR)))
2032 #ifdef SKINS
2033 struct IntuitionCustomize *ic;
2034 ic = screen->DInfo.dri_Customize;
2035 screen->DInfo.dri_Flags |= DRIF_SKINSSUPPORT;
2037 /* This initializes CustomizePrefs structure */
2039 if (skinname) strcpy(ic->skinname,skinname);
2041 InitSemaphore(&ic->InitLock);
2043 DEBUG_OPENSCREEN(dprintf("OpenScreen: load skin %s for screen %lx\n",ic->skinname,screen));
2044 int_SkinAction(SKA_LoadSkin,(ULONG*)&screen->DInfo,(struct Screen *)screen,IntuitionBase);
2045 #else
2046 /* AROS: Use less error-prone skinname handling */
2047 ok = int_LoadDecorator(skinname, screen, IntuitionBase);
2048 #endif
2050 else
2052 ok = FALSE;
2057 #ifdef SKINS
2058 if (ok)
2060 struct windowclassprefs *wcprefs;
2061 wcprefs = (struct windowclassprefs *)int_GetCustomPrefs(TYPE_WINDOWCLASS,&screen->DInfo,IntuitionBase);
2062 if (wcprefs->flags & WINDOWCLASS_PREFS_1TO1FRAMES)
2064 screen->Screen.WBorLeft = screen->Screen.WBorTop;
2065 screen->Screen.WBorRight = screen->Screen.WBorTop;
2066 screen->Screen.WBorBottom = screen->Screen.WBorTop;
2068 screen->Screen.WBorTop += wcprefs->titlebarincrement;
2069 int_FreeCustomPrefs(TYPE_WINDOWCLASS,&screen->DInfo,IntuitionBase);
2072 #endif
2074 if (ok)
2076 struct TagItem sysi_tags[] =
2078 {SYSIA_Which, MENUCHECK },
2079 {SYSIA_DrawInfo, (IPTR)&screen->DInfo },
2080 {TAG_DONE }
2083 screen->DInfo.dri_CheckMark = NewObjectA(NULL, "sysiclass", sysi_tags);
2084 DEBUG_OPENSCREEN(dprintf("OpenScreen: CheckMark 0x%lx\n",
2085 screen->DInfo.dri_CheckMark));
2087 sysi_tags[0].ti_Data = AMIGAKEY;
2089 screen->DInfo.dri_AmigaKey = NewObjectA(NULL, "sysiclass", sysi_tags);
2090 DEBUG_OPENSCREEN(dprintf("OpenScreen: AmigaKey 0x%lx\n",
2091 screen->DInfo.dri_AmigaKey));
2093 /* AROS: We also use submenu image */
2094 sysi_tags[0].ti_Data = SUBMENUIMAGE;
2095 screen->DInfo.dri_Customize->submenu = NewObjectA(NULL, "sysiclass", sysi_tags);
2096 if (!screen->DInfo.dri_Customize->submenu) ok =FALSE;
2097 #ifdef SKINS
2098 sysi_tags[0].ti_Data = MENUTOGGLEIMAGE;
2099 screen->DInfo.dri_Customize->menutoggle = NewObjectA(NULL, "sysiclass", sysi_tags);
2100 if (!screen->DInfo.dri_Customize->menutoggle) ok = FALSE;
2101 #endif
2103 if (!screen->DInfo.dri_CheckMark || !screen->DInfo.dri_AmigaKey) ok = FALSE;
2106 if (ok)
2108 SetFont(&screen->Screen.RastPort, screen->DInfo.dri_Font);
2110 AskFont(&screen->Screen.RastPort, (struct TextAttr *) &screen->textattr);
2112 screen->Screen.Font = (struct TextAttr *) &screen->textattr;
2114 DEBUG_OPENSCREEN(dprintf("OpenScreen: Font %s/%d\n",
2115 screen->textattr.tta_Name, screen->textattr.tta_YSize));
2117 screen->Screen.BarVBorder = 1;
2118 screen->Screen.BarHBorder = 5;
2119 screen->Screen.MenuVBorder = 2;
2120 screen->Screen.MenuHBorder = 4;
2122 screen->Screen.BarHeight = screen->DInfo.dri_Font->tf_YSize + screen->Screen.WBorTop-2 +
2123 screen->Screen.BarVBorder * 2; /* real layer will be 1 pixel higher! */
2126 * AROS: Get size information from decorator.
2127 * This has to be done before we create gadgets because here we may adjust BarHeight.
2129 ok = int_InitDecorator(&screen->Screen);
2130 if (ok)
2132 #define SDEPTH_HEIGHT (screen->Screen.BarHeight + 1)
2133 #ifdef IA_Screen
2134 #undef IA_Screen
2135 #endif
2136 #define IA_Screen (IA_Dummy + 0x1f) /* OS v44 includes!*/
2138 struct TagItem sdepth_tags[] =
2140 {GA_Image, 0 },
2141 {GA_Top, 0 },
2142 {GA_Height, SDEPTH_HEIGHT},
2143 {GA_SysGadget, TRUE },
2144 {GA_SysGType, GTYP_SDEPTH },
2145 {GA_RelVerify, TRUE },
2146 {TAG_DONE, 0UL }
2149 struct TagItem image_tags[] =
2151 {IA_Left , 0 },
2152 //{IA_Width , SDEPTH_WIDTH + 1 },
2153 {IA_Height , SDEPTH_HEIGHT },
2154 {SYSIA_Which , SDEPTHIMAGE },
2155 {SYSIA_DrawInfo , (IPTR)&screen->DInfo},
2156 {SYSIA_Size , screen->Screen.Flags & SCREENHIRES ?
2157 SYSISIZE_MEDRES : SYSISIZE_LOWRES},
2158 {TAG_DONE }
2161 struct Object *im = 0;
2163 if (!(screen->Screen.Flags & SCREENQUIET))
2165 im = NewObjectA(NULL, SYSICLASS, image_tags);
2168 sdepth_tags[0].ti_Data = (IPTR)im;
2170 screen->depthgadget = NewObjectA(IBase->windowsysiclass, NULL, sdepth_tags );
2172 DEBUG_OPENSCREEN(dprintf("OpenScreen: DepthGadget 0x%lx\n",
2173 screen->depthgadget));
2175 screen->Screen.FirstGadget = (struct Gadget *)screen->depthgadget;
2176 if (screen->Screen.FirstGadget)
2178 struct TagItem gadtags[] =
2180 {GA_RelRight, 0},
2181 {TAG_DONE }
2183 IPTR width; /* AROS: Changed from int to IPTR, 64-bit fix */
2185 GetAttr(GA_Width, screen->depthgadget, &width);
2187 gadtags[0].ti_Data = -width + 1;
2188 SetAttrsA(screen->depthgadget, gadtags);
2189 screen->Screen.FirstGadget->GadgetType |= GTYP_SCRGADGET;
2190 } else {
2191 if (im) DisposeObject(im);
2194 #if DEBUG
2196 int i;
2197 for (i=0;i<=screen->DInfo.dri_NumPens;i++)
2199 DEBUG_OPENSCREEN(dprintf("OpenScreen: dri_Pen[%ld] = %ld\n",i,screen->DInfo.dri_Pens[i]));
2202 #endif
2204 #ifdef USEWINDOWLOCK
2205 /* let's wait for user to finish window drag/size actions to avoid
2206 deadlocks and not break user's input */
2207 if (dowindowlock && (!(FindTask(NULL) == ((struct IIHData *)IBase->InputHandler->is_Data)->InputDeviceTask)))
2209 LOCKWINDOW;
2210 windowlock = TRUE;
2211 screen->WindowLock = TRUE;
2213 #endif
2215 int_CalcSkinInfo(&screen->Screen,IntuitionBase);
2216 #ifdef SKINS
2217 int_InitTitlebarBuffer(&screen->Screen,IntuitionBase);
2218 #endif
2219 D(bug("calling SetRast()\n"));
2221 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set background color Pen %ld\n",screen->Pens[BACKGROUNDPEN]));
2222 /* Set screen to background color */
2223 SetRast(&screen->Screen.RastPort, screen->Pens[BACKGROUNDPEN]);
2225 D(bug("SetRast() called\n"));
2227 DEBUG_OPENSCREEN(dprintf("OpenScreen: Creating screen bar\n"));
2229 #ifdef SKINS
2230 if (workbench)
2232 #if 1
2233 if (IBase->IControlPrefs.ic_Flags & (ICF_DISAPPEARINGTITLEBAR | ICF_NOWBTITLEBAR)) screen->SpecialFlags |= SF_AppearingBar;
2234 #else
2235 if (IBase->IControlPrefs.ic_Flags & ICF_NOWBTITLEBAR) screen->SpecialFlags |= SF_InvisibleBar;
2236 if (IBase->IControlPrefs.ic_Flags & ICF_DISAPPEARINGTITLEBAR) screen->SpecialFlags |= SF_AppearingBar;
2237 #endif
2239 #endif
2241 //jDc: ALL screens MUST have BarLayer!
2242 CreateScreenBar(&screen->Screen, IntuitionBase);
2244 if (!screen->Screen.BarLayer) ok = FALSE;
2247 if (ok)
2249 if ((ns.Type & SCREENTYPE) == CUSTOMSCREEN)
2251 screen->ShowPointer = showpointer;
2252 } else {
2253 screen->ShowPointer = TRUE;
2255 #ifdef SKINS
2256 GetAttr(POINTERA_SharedPointer, screen->IMonitorNode->Pointers[POINTERTYPE_INVISIBLE], (IPTR *)&screen->Pointer);
2257 #else
2258 GetAttr(POINTERA_SharedPointer, IBase->DefaultPointer, (IPTR *)&screen->Pointer);
2259 #endif
2260 ObtainSharedPointer(screen->Pointer, IntuitionBase);
2261 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sprite DefaultPtr 0x%lx\n",&screen->Pointer));
2265 ** jDc: better modify the screen list in sync with inputhandler, this for example allows us to scan the list
2266 ** without any locks when we are on input.device context
2268 if (ok)
2270 struct PubScreenNode *ps = NULL;
2271 struct List *list = LockPubScreenList();
2273 /* Additional dupe check, just to be sure */
2274 if (!workbench && screen->pubScrNode && (ps = (struct PubScreenNode *)FindName(list,screen->pubScrNode->psn_Node.ln_Name)))
2276 ok = FALSE;
2279 if (ok)
2281 struct OpenScreenActionMsg msg;
2283 msg.Screen = screen;
2284 msg.NewScreen = &ns;
2285 msg.List = list;
2287 DoSyncAction((APTR)int_openscreen,&msg.msg,IntuitionBase);
2289 ok = msg.Success;
2292 UnlockPubScreenList();
2295 } /* if (ok) */
2297 #ifdef USEWINDOWLOCK
2298 if (windowlock) UNLOCKWINDOW;
2299 #endif
2301 if (!ok)
2303 if (li_inited)
2305 DEBUG_OPENSCREEN(dprintf("OpenScreen: Get ThinLayerInfo\n"));
2306 ThinLayerInfo(&screen->Screen.LayerInfo);
2309 if (screen->Screen.ViewPort.ColorMap)
2311 #ifdef __MORPHOS__
2312 struct TagItem tags[2];
2314 tags[0].ti_Tag = VTAG_ATTACH_CM_GET;
2315 tags[0].ti_Data = 0;
2316 tags[1].ti_Tag = VTAG_END_CM;
2318 if (VideoControl(screen->Screen.ViewPort.ColorMap, tags) == 0 &&
2319 tags[0].ti_Data)
2321 GfxFree((APTR)tags[0].ti_Data);
2323 #endif
2325 FreeColorMap(screen->Screen.ViewPort.ColorMap);
2328 if (screen->Screen.BarLayer)
2330 DEBUG_OPENSCREEN(dprintf("OpenScreen: KillScreenBar\n"));
2331 KillScreenBar(&screen->Screen, IntuitionBase);
2334 if (screen->DInfo.dri_Customize)
2336 /* AROS: submenu image handling moved out of #ifdef */
2337 DisposeObject(screen->DInfo.dri_Customize->submenu);
2338 #ifdef SKINS
2339 DisposeObject(screen->DInfo.dri_Customize->menutoggle);
2340 #endif
2341 FreeMem(screen->DInfo.dri_Customize,sizeof (struct IntuitionCustomize));
2343 #ifdef SKINS
2344 if (screen->DInfo.dri_Colors) FreeMem(screen->DInfo.dri_Colors,4 * DRIPEN_NUMDRIPENS);
2345 #endif
2346 if (screen->DInfo.dri_AmigaKey)
2348 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose AmigaKey Object\n"));
2349 DisposeObject(screen->DInfo.dri_AmigaKey);
2351 if (screen->DInfo.dri_CheckMark)
2353 DEBUG_OPENSCREEN(dprintf("OpenScreen: Dispose CheckMark Object\n"));
2354 DisposeObject(screen->DInfo.dri_CheckMark);
2357 if (screen->DInfo.dri_Font)
2359 DEBUG_OPENSCREEN(dprintf("OpenScreen: Close Font\n"));
2360 CloseFont(screen->DInfo.dri_Font);
2363 if (screen->AllocatedBitMap && !(ns.Type & CUSTOMBITMAP))
2365 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free BitMap\n"));
2366 FreeBitMap(screen->AllocatedBitMap);
2369 if (screen->Screen.ViewPort.RasInfo)
2371 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free RasInfo\n"));
2372 FreeMem(screen->Screen.ViewPort.RasInfo, sizeof (struct RasInfo));
2375 if (rp_inited)
2377 DEBUG_OPENSCREEN(dprintf("OpenScreen: Trash Rastport\n"));
2378 DeinitRastPort(&screen->Screen.RastPort);
2381 DEBUG_OPENSCREEN(dprintf("OpenScreen: Free Screen\n"));
2382 DisposeObject((APTR)screen);
2383 screen = 0;
2385 } /* if (!ok) */
2387 DEBUG_OPENSCREEN(dprintf("OpenScreen: return 0x%lx\n", screen));
2389 FireScreenNotifyMessage((IPTR) screen, SNOTIFY_AFTER_OPENSCREEN, IntuitionBase);
2391 ReturnPtr ("OpenScreen", struct Screen *, (struct Screen *)screen);
2393 AROS_LIBFUNC_EXIT
2395 } /* OpenScreen */
2397 VOID int_openscreen(struct OpenScreenActionMsg *msg,
2398 struct IntuitionBase *IntuitionBase)
2400 struct GfxBase *GfxBase = GetPrivIBase(IntuitionBase)->GfxBase;
2401 struct IntScreen *screen = msg->Screen;
2402 struct NewScreen *ns = msg->NewScreen;
2403 struct List *list = msg->List;
2404 struct Screen *oldFirstScreen;
2405 struct RethinkDisplayActionMsg rmsg;
2406 ULONG lock = 0;
2408 DEBUG_OPENSCREEN(dprintf("OpenScreen: Checking for pubScrNode (0x%lx)\n",screen->pubScrNode));
2410 /* If this is a public screen, we link it into the intuition global
2411 public screen list */
2412 if (screen->pubScrNode != NULL)
2414 /* Set the pointer to ourselves */
2415 IS(screen)->pubScrNode->psn_Screen = &screen->Screen;
2417 DEBUG_OPENSCREEN(dprintf("OpenScreen: Add Screen to PubList\n"));
2418 AddTail(list, (struct Node *)IS(screen)->pubScrNode);
2421 if (!ILOCKCHECK(((struct IntuiActionMsg *)msg))) lock = LockIBase((IPTR)NULL);
2423 oldFirstScreen = IntuitionBase->FirstScreen;
2424 if (ns->Type & SCREENBEHIND)
2426 struct Screen **ptr = &IntuitionBase->FirstScreen;
2428 DEBUG_OPENSCREEN(dprintf("OpenScreen: Sort Behind\n"));
2429 if (!*ptr)
2430 IntuitionBase->ActiveScreen = &screen->Screen;
2431 while (*ptr)
2432 ptr = &(*ptr)->NextScreen;
2433 *ptr = &screen->Screen;
2435 else
2437 screen->Screen.NextScreen = IntuitionBase->FirstScreen;
2438 IntuitionBase->FirstScreen =
2439 IntuitionBase->ActiveScreen = &screen->Screen;
2440 DEBUG_OPENSCREEN(dprintf("OpenScreen: Set as ActiveScreen\n"));
2443 /* AROS: If it's the first screen being opened, activate its monitor */
2444 if (!oldFirstScreen)
2445 ActivateMonitor(screen->IMonitorNode, -1, -1, IntuitionBase);
2447 /* set the default pub screen */
2448 if (IBase->IControlPrefs.ic_Flags & ICF_DEFPUBSCREEN)
2450 if ((IntuitionBase->FirstScreen == &screen->Screen) && screen->pubScrNode && (screen->Screen.Flags & (PUBLICSCREEN | WBENCHSCREEN)))
2452 IBase->DefaultPubScreen = &screen->Screen;
2456 msg->Success = MakeVPort(&IntuitionBase->ViewLord, &screen->Screen.ViewPort) ? FALSE : TRUE;
2458 if (msg->Success)
2460 /* AROS: Put offsets validated by MakeVPort() back into screen structure */
2461 screen->Screen.LeftEdge = screen->Screen.ViewPort.DxOffset;
2462 screen->Screen.TopEdge = screen->Screen.ViewPort.DyOffset;
2464 rmsg.lock = FALSE;
2465 int_RethinkDisplay(&rmsg,IntuitionBase);
2468 #ifdef SKINS
2469 if (!(ns->Type & SCREENBEHIND))
2471 // workaround: do not send the event for SCREENBEHIND cause it'd reset the DPMS counter
2472 QueryBlankerEvent(BLANKEREVENT_SCREENDEPTH,(ULONG)screen->IMonitorNode,IntuitionBase);
2474 #endif
2476 if (!ILOCKCHECK(((struct IntuiActionMsg *)msg))) UnlockIBase(lock);
2478 D(bug("set active screen\n"));
2480 AddResourceToList(screen, RESOURCE_SCREEN, IntuitionBase);