Minor fixes to comments.
[AROS.git] / rom / graphics / dispinfo.c
blob16debf2e9b0259a2b632663f0239f64533b5c961
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <proto/alib.h>
7 #include <proto/exec.h>
8 #include <proto/oop.h>
9 #include <proto/arossupport.h>
10 #include <proto/utility.h>
11 #include <proto/graphics.h>
13 #include <exec/lists.h>
14 #include <exec/memory.h>
15 #include <exec/rawfmt.h>
17 #include <graphics/displayinfo.h>
18 #include <graphics/monitor.h>
20 #include <cybergraphx/cybergraphics.h>
22 #include <oop/oop.h>
24 #include <hidd/graphics.h>
26 #include <stddef.h>
27 #include <string.h>
29 #include "graphics_intern.h"
30 #include "gfxfuncsupport.h"
31 #include "dispinfo.h"
33 #define DEBUG 0
34 #include <aros/debug.h>
36 HIDDT_ModeID get_best_resolution_and_depth(struct monitor_driverdata *mdd, struct GfxBase *GfxBase)
38 HIDDT_ModeID ret = vHidd_ModeID_Invalid;
39 struct DisplayInfoHandle *dh;
40 ULONG best_resolution = 0;
41 ULONG best_depth = 0;
43 for (dh = mdd->modes; dh->id != vHidd_ModeID_Invalid; dh++) {
44 OOP_Object *sync, *pf;
45 IPTR depth;
47 HIDD_Gfx_GetMode(mdd->gfxhidd, dh->id, &sync, &pf);
48 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
50 if (depth >= best_depth) {
51 IPTR width, height;
52 ULONG res;
54 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
55 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
57 res = width * height;
58 if (res > best_resolution) {
59 ret = dh->id;
60 best_resolution = res;
62 best_depth = depth;
65 return ret;
68 void BestModeIDForMonitor(struct monitor_driverdata *mdd, ULONG dipf_musthave, ULONG dipf_mustnothave,
69 UBYTE redbits, UBYTE greenbits, UBYTE bluebits, UBYTE depth, STRPTR boardname,
70 UWORD nominal_width, UWORD nominal_height, UWORD desired_width, UWORD desired_height,
71 ULONG *found_id, UWORD *found_depth, UWORD *found_width, UWORD *found_height, struct GfxBase *GfxBase)
73 struct DisplayInfoHandle *dinfo;
74 struct DisplayInfo disp;
75 struct DimensionInfo dims;
77 if (boardname)
79 STRPTR name;
81 OOP_GetAttr(mdd->gfxhidd, aHidd_Gfx_DriverName, (IPTR *)&name);
82 if (strcmp(boardname, name))
83 return;
86 for (dinfo = mdd->modes; dinfo->id != vHidd_ModeID_Invalid; dinfo++)
88 UWORD gm_width, gm_height;
89 ULONG modeid = mdd->id | dinfo->id;
91 D(bug("[BestModeID] Checking ModeID 0x%08X... ", modeid));
93 if (GetDisplayInfoData(dinfo, (UBYTE *)&disp, sizeof(disp), DTAG_DISP, modeid) < offsetof(struct DisplayInfo, pad2))
95 D(bug("No DisplayInfo!\n"));
96 continue;
99 /* Filter out not available modes */
100 if (disp.NotAvailable)
102 D(bug("Not available: %u\n", disp.NotAvailable));
103 continue;
106 /* Filter out modes which do not meet out special needs */
107 if (disp.PropertyFlags & dipf_mustnothave)
109 D(bug("Has MustNotHave flags: 0x%08lX\n", disp.PropertyFlags));
110 continue;
112 if ((disp.PropertyFlags & dipf_musthave) != dipf_musthave)
114 D(bug("Does not have MustHave flags: 0x%08lX\n", disp.PropertyFlags));
115 continue;
118 if (GetDisplayInfoData(dinfo, (UBYTE *)&dims, sizeof(dims), DTAG_DIMS, modeid) < offsetof(struct DimensionInfo, MaxOScan))
120 D(bug("No DimensionInfo!\n"));
121 continue;
123 gm_width = dims.Nominal.MaxX - dims.Nominal.MinX + 1;
124 gm_height = dims.Nominal.MaxY - dims.Nominal.MinY + 1;
125 D(bug("%ux%ux%u", gm_width, gm_height, dims.MaxDepth));
127 /* FIXME: Take aspect ratio into account (nominal_width : nominal_height) */
129 /* Check if mode is not worse than requested */
130 if ( disp.RedBits >= redbits
131 && disp.GreenBits >= greenbits
132 && disp.BlueBits >= bluebits
133 && dims.MaxDepth >= depth
134 && gm_width >= desired_width
135 && gm_height >= desired_height)
137 /* Check if this mode matches closer than the one we already found */
138 if ((dims.MaxDepth <= *found_depth) &&
139 (gm_width <= *found_width) && (gm_height <= *found_height))
141 /* Remember the new mode only if something changed. This prevents unwanted
142 jumping to another display (several displays may have the same modes,
143 in this case the last display will be picked up without this check. */
144 if ((dims.MaxDepth < *found_depth) || (gm_width < *found_width) || (gm_height < *found_height))
146 *found_id = modeid;
147 *found_depth = dims.MaxDepth;
148 *found_width = gm_width;
149 *found_height = gm_height;
151 D(bug(" Match!\n"));
155 D(bug("\n"));
157 } /* for (each mode) */
160 /* Looks up a DriverData corresponding to a MonitorSpec */
161 struct monitor_driverdata *MonitorFromSpec(struct MonitorSpec *mspc, struct GfxBase *GfxBase)
163 struct monitor_driverdata *ret = NULL;
164 struct monitor_driverdata *mdd;
165 OOP_Object *drv;
167 if (!mspc)
168 return NULL;
171 * FIXME: NULL ms_Object will likely mean chipset MonitorSpec (they don't have 1:1 relation with sync objects)
172 * Process this correctly here. Or am i wrong ?
174 if (!mspc->ms_Object)
175 return NULL;
177 OOP_GetAttr((OOP_Object *)mspc->ms_Object, aHidd_Sync_GfxHidd, (IPTR *)&drv);
179 ObtainSemaphoreShared(&CDD(GfxBase)->displaydb_sem);
181 for (mdd = CDD(GfxBase)->monitors; mdd; mdd = mdd->next)
184 * Sync objects know nothing about fakegfx proxy class.
185 * They carry a pointer to a real driver object.
187 if (mdd->gfxhidd_orig == drv)
189 ret = mdd;
190 break;
194 ReleaseSemaphore(&CDD(GfxBase)->displaydb_sem);
196 return ret;