Autodoc formatting fixed.
[AROS.git] / rom / graphics / dispinfo.c
blob3df7fe5191b72ebccdd4fdce33cb4e09468c6ee5
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <proto/alib.h>
9 #include <proto/exec.h>
10 #include <proto/oop.h>
11 #include <proto/arossupport.h>
12 #include <proto/utility.h>
13 #include <proto/graphics.h>
15 #include <exec/lists.h>
16 #include <exec/memory.h>
17 #include <exec/rawfmt.h>
19 #include <graphics/displayinfo.h>
20 #include <graphics/monitor.h>
22 #include <cybergraphx/cybergraphics.h>
24 #include <oop/oop.h>
26 #include <hidd/graphics.h>
28 #include <stddef.h>
29 #include <string.h>
31 #include "graphics_intern.h"
32 #include "gfxfuncsupport.h"
33 #include "dispinfo.h"
35 HIDDT_ModeID get_best_resolution_and_depth(struct monitor_driverdata *mdd, struct GfxBase *GfxBase)
37 HIDDT_ModeID ret = vHidd_ModeID_Invalid;
38 struct DisplayInfoHandle *dh;
39 ULONG best_resolution = 0;
40 ULONG best_depth = 0;
42 for (dh = mdd->modes; dh->id != vHidd_ModeID_Invalid; dh++) {
43 OOP_Object *sync, *pf;
44 IPTR depth;
46 HIDD_Gfx_GetMode(mdd->gfxhidd, dh->id, &sync, &pf);
47 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
49 if (depth >= best_depth) {
50 IPTR width, height;
51 ULONG res;
53 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
54 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
56 res = width * height;
57 if (res > best_resolution) {
58 ret = dh->id;
59 best_resolution = res;
61 best_depth = depth;
64 return ret;
67 void BestModeIDForMonitor(struct monitor_driverdata *mdd, ULONG dipf_musthave, ULONG dipf_mustnothave,
68 UBYTE redbits, UBYTE greenbits, UBYTE bluebits, UBYTE depth, STRPTR boardname,
69 UWORD nominal_width, UWORD nominal_height, UWORD desired_width, UWORD desired_height,
70 ULONG *found_id, UWORD *found_depth, UWORD *found_width, UWORD *found_height, struct GfxBase *GfxBase)
72 struct DisplayInfoHandle *dinfo;
73 struct DisplayInfo disp;
74 struct DimensionInfo dims;
76 if (boardname)
78 STRPTR name;
80 OOP_GetAttr(mdd->gfxhidd, aHidd_Gfx_DriverName, (IPTR *)&name);
81 if (strcmp(boardname, name))
82 return;
85 for (dinfo = mdd->modes; dinfo->id != vHidd_ModeID_Invalid; dinfo++)
87 UWORD gm_width, gm_height;
88 ULONG modeid = mdd->id | dinfo->id;
90 D(bug("[BestModeID] Checking ModeID 0x%08X... ", modeid));
92 if (GetDisplayInfoData(dinfo, (UBYTE *)&disp, sizeof(disp), DTAG_DISP, modeid) < offsetof(struct DisplayInfo, pad2))
94 D(bug("No DisplayInfo!\n"));
95 continue;
98 /* Filter out not available modes */
99 if (disp.NotAvailable)
101 D(bug("Not available: %u\n", disp.NotAvailable));
102 continue;
105 /* Filter out modes which do not meet out special needs */
106 if (disp.PropertyFlags & dipf_mustnothave)
108 D(bug("Has MustNotHave flags: 0x%08lX\n", disp.PropertyFlags));
109 continue;
111 if ((disp.PropertyFlags & dipf_musthave) != dipf_musthave)
113 D(bug("Does not have MustHave flags: 0x%08lX\n", disp.PropertyFlags));
114 continue;
117 if (GetDisplayInfoData(dinfo, (UBYTE *)&dims, sizeof(dims), DTAG_DIMS, modeid) < offsetof(struct DimensionInfo, MaxOScan))
119 D(bug("No DimensionInfo!\n"));
120 continue;
122 gm_width = dims.Nominal.MaxX - dims.Nominal.MinX + 1;
123 gm_height = dims.Nominal.MaxY - dims.Nominal.MinY + 1;
124 D(bug("%ux%ux%u", gm_width, gm_height, dims.MaxDepth));
126 /* FIXME: Take aspect ratio into account (nominal_width : nominal_height) */
128 /* Check if mode is not worse than requested */
129 if ( disp.RedBits >= redbits
130 && disp.GreenBits >= greenbits
131 && disp.BlueBits >= bluebits
132 && dims.MaxDepth >= depth
133 && gm_width >= desired_width
134 && gm_height >= desired_height)
136 /* Check if this mode matches closer than the one we already found */
137 if ((dims.MaxDepth <= *found_depth) &&
138 (gm_width <= *found_width) && (gm_height <= *found_height))
140 /* Remember the new mode only if something changed. This prevents unwanted
141 jumping to another display (several displays may have the same modes,
142 in this case the last display will be picked up without this check. */
143 if ((dims.MaxDepth < *found_depth) || (gm_width < *found_width) || (gm_height < *found_height))
145 *found_id = modeid;
146 *found_depth = dims.MaxDepth;
147 *found_width = gm_width;
148 *found_height = gm_height;
150 D(bug(" Match!\n"));
154 D(bug("\n"));
156 } /* for (each mode) */
159 /* Looks up a DriverData corresponding to a MonitorSpec */
160 struct monitor_driverdata *MonitorFromSpec(struct MonitorSpec *mspc, struct GfxBase *GfxBase)
162 struct monitor_driverdata *ret = NULL;
163 struct monitor_driverdata *mdd;
164 OOP_Object *drv;
166 if (!mspc)
167 return NULL;
170 * FIXME: NULL ms_Object will likely mean chipset MonitorSpec (they don't have 1:1 relation with sync objects)
171 * Process this correctly here. Or am i wrong ?
173 if (!mspc->ms_Object)
174 return NULL;
176 OOP_GetAttr((OOP_Object *)mspc->ms_Object, aHidd_Sync_GfxHidd, (IPTR *)&drv);
178 ObtainSemaphoreShared(&CDD(GfxBase)->displaydb_sem);
180 for (mdd = CDD(GfxBase)->monitors; mdd; mdd = mdd->next)
183 * Sync objects know nothing about fakegfx proxy class.
184 * They carry a pointer to a real driver object.
186 if (mdd->gfxhidd_orig == drv)
188 ret = mdd;
189 break;
193 ReleaseSemaphore(&CDD(GfxBase)->displaydb_sem);
195 return ret;