2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Graphics function BestModeIDA()
9 #include <aros/debug.h>
10 #include <cybergraphx/cybergraphics.h>
11 #include <graphics/modeid.h>
12 #include <hidd/graphics.h>
13 #include <proto/graphics.h>
14 #include <proto/utility.h>
15 #include <proto/oop.h>
19 #include "graphics_intern.h"
20 #include "gfxfuncsupport.h"
23 /*****************************************************************************
26 #include <proto/graphics.h>
28 AROS_LH1(ULONG
, BestModeIDA
,
31 AROS_LHA(struct TagItem
*, TagItems
, A0
),
34 struct GfxBase
*, GfxBase
, 175, Graphics
)
39 TagItems - pointer to an array of TagItems
42 BIDTAG_ViewPort (struct ViewPort *) - Viewport for which a mode is searched. Default: NULL
43 BIDTAG_MonitorID (ULONG) - Returned ID must use this monitor
44 BIDTAG_SourceID (ULONG) - Use this ModeID instead of a ViewPort.
45 DIPFMustHave mask is made up of the
46 ((DisplayInfo->PropertyFlags of this ID & SPECIAL_FLAGS) |
49 if BIDTAG_ViewPort was passed: VPModeID(vp), else the
50 DIPFMustHave and DIPFMustNotHave are unchanged.
51 BIDTAG_Depth (UBYTE) - Minimal depth. Default:
52 if BIDTAG_ViewPort is passed: vp->RasInfo->BitMap->Depth,
54 BIDTAG_NominalWidth (UWORD),
55 BIDTAG_NominalHeight (UWORD) - Aspect radio. Default:
56 if BIDTAG_SourceID: SourceID NominalDimensionInfo
57 if BIDTAG_ViewPort: vp->DWidth and vp->DHeight
59 BIDTAG_DesiredWidth (UWORD) - Width. Default: DIBTAG_NominalWidth.
60 BIDTAG_DesiredHeight (UWORD) - Height. Default: BIDTAG_NominalHeight.
61 BIDTAG_RedBits (UBYTE),
62 BIDTAG_GreenBits (UBYTE),
63 BIDTAG_BlueBits (UBYTE) - Bits per gun the mode must support. Default: 4
64 BIDTAG_DIPFMustHave (ULONG) - DIPF flags the resulting mode must have
65 BIDTAG_DIPFMustNotHave (ULONG) - DIPF flags the resulting mode must not have
68 ID - ID of the best mode to use, or INVALID_ID if a match
78 graphics/modeid.h, graphics/displayinfo.h
81 This function also processes CYBRBIDTG_BoardName tag. This is private
82 to AROS, do not rely on it!
86 ******************************************************************************/
90 struct TagItem
*tag
, *tstate
= TagItems
;
91 UWORD desired_width
, desired_height
;
92 struct DisplayInfoHandle
*dinfo
;
93 struct DisplayInfo disp
;
94 struct DimensionInfo dims
;
95 struct monitor_driverdata
*monitor
;
96 struct ViewPort
*vp
= NULL
;
97 ULONG dipf_musthave
= 0;
98 ULONG dipf_mustnothave
= SPECIAL_FLAGS
;
99 ULONG monitorid
= INVALID_ID
;
103 ULONG sourceid
= INVALID_ID
;
104 UWORD nominal_width
= 640;
105 UWORD nominal_height
= 200;
107 STRPTR boardname
= NULL
;
108 ULONG found_id
= INVALID_ID
;
109 UWORD found_depth
= -1;
110 UWORD found_width
= -1;
111 UWORD found_height
= -1;
113 /* Obtain default monitor driver */
114 monitor
= MonitorFromSpec(GfxBase
->default_monitor
, GfxBase
);
116 /* Get defaults which can be overriden */
117 while ((tag
= NextTagItem(&tstate
)))
121 case BIDTAG_DIPFMustHave
:
122 dipf_musthave
= tag
->ti_Data
;
125 case BIDTAG_DIPFMustNotHave
:
126 dipf_mustnothave
= tag
->ti_Data
;
129 case BIDTAG_MonitorID
:
130 monitorid
= tag
->ti_Data
;
134 redbits
= tag
->ti_Data
;
137 case BIDTAG_BlueBits
:
138 bluebits
= tag
->ti_Data
;
141 case BIDTAG_ViewPort
:
142 /* If we got ViewPort, obtain some more defaults from it */
143 vp
= (struct ViewPort
*)tag
->ti_Data
;
144 nominal_width
= vp
->DWidth
;
145 nominal_height
= vp
->DHeight
;
146 sourceid
= GetVPModeID(vp
);
147 depth
= GET_BM_DEPTH(vp
->RasInfo
->BitMap
);
148 monitor
= GET_VP_DRIVERDATA(vp
);
151 /* Offer some help to cybergraphics.library */
152 case CYBRBIDTG_BoardName
:
153 boardname
= (STRPTR
)tag
->ti_Data
;
158 /* Then process SourceID, it overrides ViewPort size and mode and specifies current monitor */
159 sourceid
= GetTagData(BIDTAG_SourceID
, sourceid
, TagItems
);
160 if (sourceid
!= INVALID_ID
)
162 /* Patch musthave flags */
163 if (GetDisplayInfoData(NULL
, (UBYTE
*)&disp
, sizeof(disp
), DTAG_DISP
, sourceid
) >= offsetof(struct DisplayInfo
, Resolution
))
164 dipf_musthave
|= (disp
.PropertyFlags
& SPECIAL_FLAGS
);
168 /* Override monitor and nominal size from source ID only if there was no ViewPort specified */
169 dinfo
= FindDisplayInfo(sourceid
);
171 monitor
= dinfo
->drv
;
173 if (GetDisplayInfoData(dinfo
, (UBYTE
*)&dims
, sizeof(dims
), DTAG_DIMS
, sourceid
) >= offsetof(struct DimensionInfo
, MaxOScan
))
175 nominal_width
= dims
.Nominal
.MaxX
- dims
.Nominal
.MinX
+ 1;
176 nominal_height
= dims
.Nominal
.MaxY
- dims
.Nominal
.MinY
+ 1;
181 /* Get high-priority parameters */
182 nominal_width
= GetTagData(BIDTAG_NominalWidth
, nominal_width
, TagItems
);
183 nominal_height
= GetTagData(BIDTAG_NominalHeight
, nominal_height
, TagItems
);
184 desired_width
= GetTagData(BIDTAG_DesiredWidth
, nominal_width
, TagItems
);
185 desired_height
= GetTagData(BIDTAG_DesiredHeight
, nominal_height
, TagItems
);
186 depth
= GetTagData(BIDTAG_Depth
, depth
, TagItems
);
188 /* Exclude flags in MustHave from MustNotHave (CHECKME: if this correct?) */
189 dipf_mustnothave
&= ~dipf_musthave
;
190 /* Mask out bit 12 in monitorid because the user may (and will) pass in IDs defined in include/graphics/modeid.h
191 (like PAL_MONITOR_ID, VGA_MONITOR_ID, etc) which have bit 12 set) */
192 if (monitorid
!= INVALID_ID
)
193 monitorid
&= AROS_MONITOR_ID_MASK
;
195 D(bug("[BestModeIDA] Desired mode: %dx%dx%d, MonitorID 0x%08lX, MustHave 0x%08lX, MustNotHave 0x%08lX\n",
196 desired_width
, desired_height
, depth
, monitorid
, dipf_musthave
, dipf_mustnothave
));
198 /* OK, now we try to search for a mode that has the supplied charateristics. */
199 ObtainSemaphoreShared(&CDD(GfxBase
)->displaydb_sem
);
201 /* First we try to search in preferred monitor (if present) */
203 BestModeIDForMonitor(monitor
, dipf_musthave
, dipf_mustnothave
, redbits
, greenbits
, bluebits
,
204 depth
, boardname
, nominal_width
, nominal_height
, desired_width
, desired_height
,
205 &found_id
, &found_depth
, &found_width
, &found_height
, GfxBase
);
207 /* And if nothing was found there, check other monitors */
208 if (found_id
== INVALID_ID
)
210 struct monitor_driverdata
*mdd
;
212 for (mdd
= CDD(GfxBase
)->monitors
; mdd
; mdd
= mdd
->next
)
215 BestModeIDForMonitor(mdd
, dipf_musthave
, dipf_mustnothave
, redbits
, greenbits
, bluebits
,
216 depth
, boardname
, nominal_width
, nominal_height
, desired_width
, desired_height
,
217 &found_id
, &found_depth
, &found_width
, &found_height
, GfxBase
);
221 ReleaseSemaphore(&CDD(GfxBase
)->displaydb_sem
);
223 D(bug("[BestModeIDA] Returning mode ID 0x%08lX\n", found_id
));