Trust uboot's device list only if it does not look suspicious.
[AROS.git] / test / gfxinfo.c
blob72fd810c98fce5b34cfcf08e7b967c241fd0bd8b
1 /* A very hacky testcase which dumps lots of graphics subsystem internal things.
2 Please do not rely on the information you obtain using this program! Remember
3 that it some of things it will print are really private and internal! Do not
4 use techniques used by this program in common user software! */
6 /* Define this if you have no CGX SDK for some reason. You'll miss one bit of information then.
7 #define NO_CGX_API */
9 #ifdef __amigaos4__
10 #define __USE_INLINE__
11 #endif
13 #include <graphics/gfxbase.h>
14 #include <graphics/displayinfo.h>
15 #include <proto/dos.h>
16 #define __USE_BASETYPE__ // For __amigaos4__
17 #include <proto/exec.h>
18 #include <proto/graphics.h>
19 #undef __USE_BASETYPE__
21 #include <stdio.h>
22 #include <string.h>
24 #ifndef NO_CGX_API
25 #include <proto/cybergraphics.h>
26 #endif
28 #ifndef __AROS__
29 #define IPTR ULONG
30 #endif
32 struct myargs
34 IPTR nospecs;
35 IPTR nomodes;
36 IPTR allspecs;
37 IPTR displaydb;
40 /* This stuff is made static in order to reduce stack usage */
41 static struct myargs args = {FALSE, FALSE, FALSE, FALSE};
42 static struct NameInfo ni;
43 static struct DisplayInfo di;
44 static struct DimensionInfo dims;
45 static struct MonitorInfo mon;
47 int __nocommandline = 1;
49 static void PrintList(struct List *l)
51 printf(" lh_Head %p\n", l->lh_Head);
52 printf(" lh_Tail %p\n", l->lh_Tail);
53 printf(" lh_TailPred %p\n", l->lh_TailPred);
54 printf(" lh_Type %u\n", l->lh_Type);
57 static void PrintName(char *name, struct ExtendedNode *n)
59 printf("%s %p", name, n);
60 if (n)
61 printf(" %s", n->xln_Name);
62 printf("\n");
65 static void PrintNode(char *name, struct ExtendedNode *n)
67 char *nodename = "<no name>";
69 if (n->xln_Name)
70 nodename = n->xln_Name;
71 printf("%s %p %s\n", name, n, nodename);
72 printf(" xln_Succ %p\n", n->xln_Succ);
73 printf(" xln_Pred %p\n", n->xln_Pred);
74 printf(" xln_Type %d\n", n->xln_Type);
75 printf(" xln_Pri %d\n", n->xln_Pri);
76 printf(" xln_Subsystem %d\n", n->xln_Subsystem);
77 printf(" xln_Subtype %d\n", n->xln_Subtype);
78 printf(" xln_Library %p\n", (void *)n->xln_Library);
79 printf(" xln_Init %p\n", n->xln_Init);
82 static inline void PrintPoint(char *name, Point *p)
84 printf("%s (%u, %u)\n", name, p->x, p->y);
87 static inline void PrintRectangle(char *name, struct Rectangle *r)
89 printf("%s (%d, %d) - (%d, %d)\n", name, r->MinX, r->MinY, r->MaxX, r->MaxY);
92 static inline void PrintASI(char *name, struct AnalogSignalInterval *sig)
94 printf("%s Start %u Stop %u\n", name, sig->asi_Start, sig->asi_Stop);
97 static void PrintMonitorSpec(struct MonitorSpec *mspc)
99 PrintNode("MonitorSpec", &mspc->ms_Node);
100 printf (" ms_Flags 0x%04X\n", mspc->ms_Flags);
101 printf (" ratioh %d\n" , (int)mspc->ratioh);
102 printf (" ratiov %d\n" , (int)mspc->ratiov);
103 printf (" total_rows %u\n" , mspc->total_rows);
104 printf (" total_colorclocks %u\n" , mspc->total_colorclocks);
105 printf (" DeniseMaxDisplayColumn %u\n" , mspc->DeniseMaxDisplayColumn);
106 printf (" BeamCon0 0x%04X\n", mspc->BeamCon0);
107 printf (" min_row %u\n" , mspc->min_row);
108 printf (" ms_Special %p\n" , mspc->ms_Special);
109 printf (" ms_OpenCount %u\n" , mspc->ms_OpenCount);
110 printf (" ms_transform %p\n" , mspc->ms_transform);
111 printf (" ms_translate %p\n" , mspc->ms_translate);
112 printf (" ms_scale %p\n" , mspc->ms_scale);
113 printf (" ms_xoffset %u\n" , mspc->ms_xoffset);
114 printf (" ms_yoffset %u\n" , mspc->ms_yoffset);
115 PrintRectangle(" ms_LegalView " , &mspc->ms_LegalView);
116 printf (" ms_maxoscan %p\n" , mspc->ms_maxoscan);
117 printf (" ms_videoscan %p\n" , mspc->ms_videoscan);
118 printf (" DeniseMinDisplayColumn %u\n" , mspc->DeniseMinDisplayColumn);
119 printf (" DisplayCompatible 0x%08X\n", (unsigned)mspc->DisplayCompatible);
120 printf (" DisplayInfoDataBase %p\n" , &mspc->DisplayInfoDataBase);
121 PrintList(&mspc->DisplayInfoDataBase);
122 printf (" ms_MrgCop %p\n" , mspc->ms_MrgCop);
123 printf (" ms_LoadView %p\n" , mspc->ms_LoadView);
124 if (GfxBase->LibNode.lib_Version > 38)
125 printf (" ms_KillView %p\n" , mspc->ms_KillView);
127 if (mspc->ms_Special) {
128 PrintNode("SpecialMonitor", &mspc->ms_Special->spm_Node);
129 printf (" spm_Flags 0x%04X\n", mspc->ms_Special->spm_Flags);
130 printf (" do_monitor %p\n" , mspc->ms_Special->do_monitor);
131 printf (" reserved1 %p\n" , mspc->ms_Special->reserved1);
132 printf (" reserved2 %p\n" , mspc->ms_Special->reserved2);
133 printf (" reserved3 %p\n" , mspc->ms_Special->reserved3);
134 PrintASI (" hblank " , &mspc->ms_Special->hblank);
135 PrintASI (" vblank " , &mspc->ms_Special->vblank);
136 PrintASI (" hsync " , &mspc->ms_Special->hsync);
137 PrintASI (" vsync " , &mspc->ms_Special->vsync);
140 if (args.displaydb) {
141 /* We don't use DisplayInfoDataBaseSemaphore here because it may be
142 not initialized in fake MonitorSpecs.
143 What is done here is actually hack. Noone will ever need in
144 a common software. I examined many systems and these lists
145 were either empty or not initialized at all. However
146 there can be a theoretical possibility that something uses them. */
147 struct Node *n = mspc->DisplayInfoDataBase.lh_Head;
149 if (n && mspc->DisplayInfoDataBase.lh_TailPred) {
150 printf("DisplayInfoDataBase\n");
151 for (; n->ln_Succ; n = n->ln_Succ) {
152 printf(" Node %p %s\n", n, n->ln_Name);
153 printf(" ln_Type %d\n", n->ln_Type);
154 printf(" ln_Pri %d\n", n->ln_Pri);
160 int main(void)
162 struct Library *CyberGfxBase;
163 #ifdef __amigaos4__
164 struct CyberGfxIFace *ICyberGfx;
165 #endif
166 struct Library *P96Base;
167 struct RDArgs *rda;
168 struct MonitorSpec *mspc;
169 ULONG modeid = INVALID_ID;
171 rda = ReadArgs("NOSPECS/S,NOMODES/S,FORCESPECS/S,DISPLAYDB/S", (IPTR *)&args, NULL);
172 if (!rda) {
173 printf("You may supply the following switches:\n"
174 "NOSPECS - Do not list MonitorSpecs in GfxBase\n"
175 "NOMODES - Do not list Mode IDs\n"
176 "FORCESPECS - When listing Mode IDs, list MonitorSpec contents even if this MonitorSpec\n"
177 " is found in the GfxBase list. Use this in conjunction with NOSPECS to get\n"
178 " a valid information\n"
179 "DISPLAYDB - attempt to list internal nodes of DisplayInfoDataBase lists inside MonitorSpecs.\n"
180 " May crash or output garbage since it is not proven yet that these nodes actually\n"
181 " have names.\n");
182 return RETURN_FAIL;
185 CyberGfxBase = OpenLibrary("cybergraphics.library", 0);
186 P96Base = OpenLibrary("Picasso96API.library", 0);
188 printf("******** System information ********\n\n");
189 printf ("graphics.library v%u.%u\n", GfxBase->LibNode.lib_Version, GfxBase->LibNode.lib_Revision);
190 if (CyberGfxBase)
192 printf("cybergraphics.library v%u.%u\n", CyberGfxBase->lib_Version, CyberGfxBase->lib_Revision);
193 #ifdef __amigaos4__
194 ICyberGfx = (struct CyberGfxIFace *)GetInterface((struct Library *)CyberGfxBase, "main", 1, NULL);
195 #endif
197 if (P96Base)
198 printf("Picasso96API.library v%u.%u\n", P96Base->lib_Version, P96Base->lib_Revision);
199 printf("\n");
201 printf("GfxBase %p\n", GfxBase);
202 printf (" DisplayFlags 0x%04X\n", GfxBase->DisplayFlags);
203 printf (" ChipRevBits0 0x%02X\n", GfxBase->ChipRevBits0);
204 printf (" MemType 0x%02X\n", GfxBase->MemType);
205 printf (" monitor_id 0x%04X\n", GfxBase->monitor_id);
206 PrintName(" current_monitor" , &GfxBase->current_monitor->ms_Node);
207 PrintName(" default_monitor" , &GfxBase->default_monitor->ms_Node);
208 printf (" WantChips 0x%02X\n", GfxBase->WantChips);
209 printf (" BoardMemType 0x%02X\n", GfxBase->BoardMemType);
210 printf (" Bugs 0x%02X\n", GfxBase->Bugs);
211 PrintName(" natural_monitor" , &GfxBase->natural_monitor->ms_Node);
212 printf (" GfxFlags 0x%04X\n", GfxBase->GfxFlags);
213 printf ("\n");
215 printf("CyberGfxBase %p\n", CyberGfxBase);
216 printf("P96Base %p\n", P96Base);
218 if (!args.nospecs) {
219 printf("*********** MonitorSpecs ***********\n\n");
221 /* It's a good idea to lock this semaphore. It seems to be present in all OSes
222 (at least in AmigaOS v3, MorphOS and AROS)
223 However at least on AmigaOS v3 we can't call NextDisplayInfo() and such
224 while the lock is held. */
225 ObtainSemaphoreShared(GfxBase->MonitorListSemaphore);
226 for (mspc = (struct MonitorSpec *)GfxBase->MonitorList.lh_Head; mspc->ms_Node.xln_Succ; mspc = (struct MonitorSpec *)mspc->ms_Node.xln_Succ) {
227 PrintMonitorSpec(mspc);
228 printf("\n");
230 ReleaseSemaphore(GfxBase->MonitorListSemaphore);
233 if (!args.nomodes) {
234 printf("*********** Display modes **********\n\n");
235 for (;;) {
236 ULONG len;
238 modeid = NextDisplayInfo(modeid);
239 if (modeid == INVALID_ID)
240 break;
242 printf("ModeID 0x%08X ", (unsigned)modeid);
243 memset(&ni, 0, sizeof(ni));
244 len = GetDisplayInfoData(NULL, (UBYTE *)&ni, sizeof(ni), DTAG_NAME, modeid);
245 if (len > 0)
246 printf("%s\n", ni.Name);
247 else
248 printf("no NameInfo\n");
250 printf("DisplayInfo handle: %p\n", FindDisplayInfo(modeid));
251 #ifndef NO_CGX_API
252 if (CyberGfxBase)
253 printf("IsCyberModeID: %d\n", IsCyberModeID(modeid));
254 #endif
256 memset(&di, 0, sizeof(di));
257 len = GetDisplayInfoData(NULL, (UBYTE *)&di, sizeof(di), DTAG_DISP, modeid);
258 if (len > 0) {
259 printf ("DisplayInfo (%u bytes)\n", (unsigned)len);
260 printf (" NotAvailable 0x%04X\n", di.NotAvailable);
261 printf (" PropertyFlags 0x%08X\n", (unsigned)di.PropertyFlags);
262 PrintPoint(" Resolution " , &di.Resolution);
263 printf (" PixelSpeed %u\n" , di.PixelSpeed);
264 printf (" NumStdSprites %u\n" , di.NumStdSprites);
265 printf (" PaletteRange %u\n" , di.PaletteRange);
266 PrintPoint(" SpriteResolution" , &di.SpriteResolution);
267 printf (" RedBits %u\n" , di.RedBits);
268 printf (" GreenBits %u\n" , di.GreenBits);
269 printf (" BlueBits %u\n" , di.BlueBits);
270 } else
271 printf("No DisplayInfo\n");
273 memset(&dims, 0, sizeof(dims));
274 len = GetDisplayInfoData(NULL, (UBYTE *)&dims, sizeof(dims), DTAG_DIMS, modeid);
275 if (len > 0) {
276 printf ("DimensionInfo (%u bytes)\n", (unsigned)len);
277 printf (" MaxDepth %u\n", dims.MaxDepth);
278 printf (" MinRasterWidth %u\n", dims.MinRasterWidth);
279 printf (" MinRasterHeight %u\n", dims.MinRasterHeight);
280 printf (" MaxRasterWidth %u\n", dims.MaxRasterWidth);
281 printf (" MaxRasterHeight %u\n", dims.MaxRasterHeight);
282 PrintRectangle(" Nominal " , &dims.Nominal);
283 PrintRectangle(" MaxOScan " , &dims.MaxOScan);
284 PrintRectangle(" VideoOScan " , &dims.VideoOScan);
285 PrintRectangle(" TxtOScan " , &dims.TxtOScan);
286 PrintRectangle(" StdOScan " , &dims.StdOScan);
287 } else
288 printf("No DimensionInfo\n");
290 memset(&mon, 0, sizeof(mon));
291 len = GetDisplayInfoData(NULL, (UBYTE *)&mon, sizeof(mon), DTAG_MNTR, modeid);
292 if (len > 0) {
293 printf ("MonitorInfo (%u bytes)\n", (unsigned)len);
294 PrintName (" Mspc " , &mon.Mspc->ms_Node);
295 PrintPoint (" ViewPosition " , &mon.ViewPosition);
296 PrintPoint (" ViewResolution " , &mon.ViewResolution);
297 PrintRectangle(" ViewPositionRange " , &mon.ViewPositionRange);
298 printf (" TotalRows %u\n" , mon.TotalRows);
299 printf (" TotalColorClocks %u\n" , mon.TotalColorClocks);
300 printf (" MinRow %u\n" , mon.MinRow);
301 printf (" Compatibility %d\n" , mon.Compatibility);
302 PrintPoint (" MouseTicks " , &mon.MouseTicks);
303 PrintPoint (" DefaultViewPosition" , &mon.DefaultViewPosition);
304 printf (" PreferredModeID 0x%08X\n", (unsigned)mon.PreferredModeID);
306 if (args.allspecs)
307 mspc = NULL;
308 else {
309 ObtainSemaphoreShared(GfxBase->MonitorListSemaphore);
310 for (mspc = (struct MonitorSpec *)GfxBase->MonitorList.lh_Head; mspc->ms_Node.xln_Succ; mspc = (struct MonitorSpec *)mspc->ms_Node.xln_Succ) {
311 if (mspc == mon.Mspc)
312 break;
314 ReleaseSemaphore(GfxBase->MonitorListSemaphore);
316 if ((mspc != mon.Mspc) && mon.Mspc)
317 PrintMonitorSpec(mon.Mspc);
319 } else
320 printf("No MonitorInfo\n");
322 printf("\n");
326 printf("*************** End ****************\n");
327 if (P96Base)
328 CloseLibrary(P96Base);
329 if (CyberGfxBase)
330 CloseLibrary(CyberGfxBase);
332 FreeArgs(rda);
333 return 0;