Added missing properties.
[AROS.git] / rom / graphics / bestmodeida.c
blobc22760f4391d0e13d075934e2ffce72c47ad327a
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics function BestModeIDA()
6 Lang: english
7 */
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>
17 #include <stddef.h>
19 #include "graphics_intern.h"
20 #include "gfxfuncsupport.h"
21 #include "dispinfo.h"
23 /*****************************************************************************
25 NAME */
26 #include <proto/graphics.h>
28 AROS_LH1(ULONG, BestModeIDA,
30 /* SYNOPSIS */
31 AROS_LHA(struct TagItem *, TagItems, A0),
33 /* LOCATION */
34 struct GfxBase *, GfxBase, 175, Graphics)
36 /* FUNCTION
38 INPUTS
39 TagItems - pointer to an array of TagItems
41 TAGS
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) |
47 DIPFMustHave flags).
48 Default:
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,
53 else 1.
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
58 or 640 x 200.
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
67 RESULT
68 ID - ID of the best mode to use, or INVALID_ID if a match
69 could not be found
71 NOTES
73 EXAMPLE
75 BUGS
77 SEE ALSO
78 graphics/modeid.h, graphics/displayinfo.h
80 INTERNALS
81 This function also processes CYBRBIDTG_BoardName tag. This is private
82 to AROS, do not rely on it!
84 HISTORY
86 ******************************************************************************/
88 AROS_LIBFUNC_INIT
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;
100 UBYTE redbits = 4;
101 UBYTE greenbits = 4;
102 UBYTE bluebits = 4;
103 ULONG sourceid = INVALID_ID;
104 UWORD nominal_width = 640;
105 UWORD nominal_height = 200;
106 UBYTE depth = 1;
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)))
119 switch (tag->ti_Tag)
121 case BIDTAG_DIPFMustHave:
122 dipf_musthave = tag->ti_Data;
123 break;
125 case BIDTAG_DIPFMustNotHave:
126 dipf_mustnothave = tag->ti_Data;
127 break;
129 case BIDTAG_MonitorID:
130 monitorid = tag->ti_Data;
131 break;
133 case BIDTAG_RedBits:
134 redbits = tag->ti_Data;
135 break;
137 case BIDTAG_BlueBits:
138 bluebits = tag->ti_Data;
139 break;
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);
149 break;
151 /* Offer some help to cybergraphics.library */
152 case CYBRBIDTG_BoardName:
153 boardname = (STRPTR)tag->ti_Data;
154 break;
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);
166 if (!vp)
168 /* Override monitor and nominal size from source ID only if there was no ViewPort specified */
169 dinfo = FindDisplayInfo(sourceid);
170 if (dinfo)
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) */
202 if (monitor)
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)
214 if (mdd != monitor)
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));
224 return found_id;
226 AROS_LIBFUNC_EXIT
227 } /* BestModeIDA */