define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / rom / graphics / getdisplayinfodata.c
blobb56480c84f30f261bf56479eba1a801f0d63fa4c
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics function GetDisplayInfoData()
6 Lang: english
7 */
8 #include <aros/debug.h>
9 #include <proto/graphics.h>
10 #include <graphics/displayinfo.h>
11 #include <hidd/graphics.h>
12 #include "dispinfo.h"
13 #include <proto/oop.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include "graphics_intern.h"
18 /****************************************************************************************/
20 struct size_check
22 ULONG struct_id;
23 ULONG struct_size;
24 STRPTR struct_name;
27 #define PRIV_DTAG_QHDR 0x80005000
29 static const struct size_check size_checks[] =
31 { DTAG_DISP, sizeof(struct DisplayInfo), "DisplayInfo" },
32 { DTAG_DIMS, sizeof(struct DimensionInfo), "DimensionInfo" },
33 { DTAG_MNTR, sizeof(struct MonitorInfo), "MonitorInfo" },
34 { DTAG_NAME, sizeof(struct NameInfo), "NameInfo" },
35 { DTAG_VEC, sizeof(struct VecInfo), "VecInfo" },
36 { PRIV_DTAG_QHDR, sizeof(struct QueryHeader), "QueryHeader" }
40 static BOOL check_sizes(ULONG tagID, ULONG size);
41 static ULONG compute_numbits(HIDDT_Pixel mask);
43 #define DLONGSZ (sizeof (ULONG) * 2)
44 #define DTAG_TO_IDX(dtag) (((dtag) & 0x0000F000) >> 12)
46 /*****************************************************************************
48 NAME */
49 #include <proto/graphics.h>
51 AROS_LH5(ULONG, GetDisplayInfoData,
53 /* SYNOPSIS */
54 AROS_LHA(DisplayInfoHandle, handle, A0),
55 AROS_LHA(UBYTE *, buf, A1),
56 AROS_LHA(ULONG, size, D0),
57 AROS_LHA(ULONG, tagID, D1),
58 AROS_LHA(ULONG, ID, D2),
60 /* LOCATION */
61 struct GfxBase *, GfxBase, 126, Graphics)
63 /* FUNCTION
64 Fills buffer with information about displayinfo handle.
66 INPUTS
67 handle - displayinfo handle
68 buf - pointer to destination buffer
69 size - buffer size in bytes
70 tagID - data chunk type
71 DTAG_DISP (DisplayInfo)
72 DTAG_DIMS (DimensionInfo)
73 DTAG_MNTR (MonitorInfo)
74 DTAG_NAME (NameInfo)
75 ID - displayinfo identifier, optionally used if handle is NULL
77 RESULT
78 result - if positive, number of bytes actually transferred
79 if zero, no information for ID was available
81 NOTES
83 EXAMPLE
85 BUGS
87 SEE ALSO
88 FindDisplayInfo(), NextDisplayInfo(), graphics/displayinfo.h
90 INTERNALS
92 HISTORY
95 ******************************************************************************/
97 AROS_LIBFUNC_INIT
99 struct QueryHeader *qh;
100 ULONG structsize;
101 OOP_Object *sync, *pf;
102 HIDDT_ModeID hiddmode;
103 ULONG modeid;
105 if (NULL == handle)
107 if ((ULONG)INVALID_ID != ID)
109 /* Check that ID is a valid modeid */
110 handle = FindDisplayInfo(ID);
112 else
114 D(bug("!!! INVALID MODE ID IN GetDisplayInfoData()\n"));
115 return 0;
119 if (NULL == handle)
121 D(bug("!!! COULD NOT GET HANDLE IN GetDisplayInfoData()\n"));
122 return 0;
125 modeid = (ULONG)handle;
126 hiddmode = (HIDDT_ModeID)AMIGA_TO_HIDD_MODEID(modeid);
128 /* Get mode info from the HIDD */
129 if (!HIDD_Gfx_GetMode(SDD(GfxBase)->gfxhidd, hiddmode, &sync, &pf))
131 D(bug("NO VALID MODE PASSED TO GetDisplayInfoData() !!!\n"));
132 return 0;
136 D(bug("GetDisplayInfoData(handle=%d, modeid=%x, tagID=%x)\n"
137 , (ULONG)handle, modeid, tagID));
140 /* Build the queryheader */
141 if (!check_sizes(tagID, size)) return 0;
143 memset(buf, 0, size);
145 /* Fill in the queryheader */
146 qh = (struct QueryHeader *)buf;
147 qh->StructID = tagID;
148 qh->DisplayID = modeid;
149 qh->SkipID = TAG_SKIP;
151 structsize = size_checks[DTAG_TO_IDX(tagID)].struct_size;
152 qh->Length = (structsize + (DLONGSZ - 1)) / DLONGSZ;
154 switch (tagID)
156 case DTAG_DISP:
158 struct DisplayInfo *di;
159 IPTR redmask, greenmask, bluemask;
161 di = (struct DisplayInfo *)buf;
163 /* All modes returned from the HIDD are available */
164 di->NotAvailable = FALSE;
166 /* Set the propertyflags */
167 di->PropertyFlags = DIPF_IS_FOREIGN | DIPF_IS_WB;
169 /* We simulate AGA. This field is really obsolete */
170 di->PaletteRange = 4096;
172 /* Compute red green and blue bits */
173 OOP_GetAttr(pf, aHidd_PixFmt_RedMask, &redmask);
174 OOP_GetAttr(pf, aHidd_PixFmt_GreenMask, &greenmask);
175 OOP_GetAttr(pf, aHidd_PixFmt_BlueMask, &bluemask);
177 di->RedBits = compute_numbits(redmask);
178 di->GreenBits = compute_numbits(greenmask);
179 di->BlueBits = compute_numbits(bluemask);
181 di->Resolution.x = 22;
182 di->Resolution.y = 22;
185 di->Resolution.x = ?;
186 di->Resolution.y = ?;
187 di->PixelSpeed = ?;
188 di->NumStdSprites = ?
189 di->SpriteResolution.x = ?;
190 di->SpriteResolution.y = ?;
193 break;
196 case DTAG_DIMS:
198 struct DimensionInfo *di;
199 IPTR depth, width, height;
201 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
202 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
203 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
205 di = (struct DimensionInfo *)buf;
206 di->MaxDepth = depth;
208 di->MinRasterWidth = width;
209 di->MinRasterHeight = height;
210 di->MaxRasterWidth = width;
211 di->MaxRasterHeight = height;
213 di->Nominal.MinX = 0;
214 di->Nominal.MinY = 0;
215 di->Nominal.MaxX = width - 1;
216 di->Nominal.MaxY = height - 1;
219 #warning What about the OSCAN stuff ??
220 di->MaxOScan = di->Nominal;
221 di->VideoOScan = di->Nominal;
222 di->TxtOScan = di->Nominal;
223 di->StdOScan = di->Nominal;
226 di->MaxOScan.MinX = di->Nominal.MinX;
227 di->MaxOScan.MinY = di->Nominal.MinY;
228 di->MaxOScan.MaxX = di->Nominal.MaxX;
229 di->MaxOScan.MaxY = di->Nominal.MaxY;
232 di->VideoOScan.MinX = di->Nominal.MinX;
233 di->VideoOScan.MinY = di->Nominal.MinY;
234 di->VideoOScan.MaxX = di->Nominal.MaxX;
235 di->VideoOScan.MaxY = di->Nominal.MaxY;
237 di->TxtOScan.MinX = di->Nominal.MinX;
238 di->TxtOScan.MinY = di->Nominal.MinY;
239 di->TxtOScan.MaxX = di->Nominal.MaxX;
240 di->TxtOScan.MaxY = di->Nominal.MaxY;
242 di->StdOScan.MinX = di->Nominal.MinX;
243 di->StdOScan.MinY = di->Nominal.MinY;
244 di->StdOScan.MaxX = di->Nominal.MaxX;
245 di->StdOScan.MaxY = di->Nominal.MaxY;
247 break;
250 case DTAG_MNTR:
252 struct MonitorInfo *mi;
253 struct MonitorSpec *mspc;
254 struct displayinfo_db *db;
255 ULONG majoridx;
257 db = (struct displayinfo_db *)SDD(GfxBase)->dispinfo_db;
259 ObtainSemaphoreShared(&db->sema);
260 majoridx = MAJORID2NUM(modeid);
261 if (majoridx >= db->num_mspecs)
263 D(bug("!!! INVALID MODE ID IN GetDisplayInfoData(DTAG_MNTR) !!!\n"));
264 ReleaseSemaphore(&db->sema);
265 return 0;
269 mi = (struct MonitorInfo *)buf;
271 mspc = &db->mspecs[majoridx];
274 mi->ViewPosition.X = ?;
275 mi->ViewPosition.Y = ?;
276 mi->ViewResolution.X = ?;
277 mi->ViewResolution.Y = ?;
278 mi->ViewPositionRange.MinX = ?;
279 mi->ViewPositionRange.MinY = ?;
280 mi->ViewPositionRange.MaxX = ?;
281 mi->ViewPositionRange.MaxY = ?;
282 mi->TotalRows = ?;
283 mi->TotalColorClocks = ?;
284 mi->MinRow = ?;
285 mi->MouseTicks.X = ?;
286 mi->MouseTicks.Y = ?;
287 mi->DefaultViewPosition.X = ?;
288 mi->DefaultViewPosition.Y = ?;
292 mi->Mspc = mspc;
293 mi->PreferredModeID = modeid;
294 mi->Compatibility = MCOMPAT_NOBODY;
296 /* Fill info into the monitorspec. It is by default set to all 0s */
297 mspc->ms_Node.xln_Pred = mspc->ms_Node.xln_Succ = NULL;
298 mspc->ms_Node.xln_Type = MONITOR_SPEC_TYPE;
299 mspc->ms_Node.xln_Name = "AROS.monitor";
300 mspc->total_rows = mi->TotalRows;
301 mspc->total_colorclocks = mi->TotalColorClocks;
302 mspc->min_row = mi->MinRow;
304 /* What to put in here ? */
305 mspc->ms_Flags = 0;
306 ReleaseSemaphore(&db->sema);
307 break;
310 case DTAG_NAME:
312 struct NameInfo *ni;
313 IPTR depth, width, height, stdpixfmt;
314 STRPTR sync_description;
316 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
317 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdpixfmt);
319 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
320 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
321 OOP_GetAttr(sync, aHidd_Sync_Description, (IPTR *)&sync_description);
322 ni = (struct NameInfo *)buf;
324 if (sync_description && sync_description[0] &&
325 (IS_REAL_STDPIXFMT(stdpixfmt) || (stdpixfmt == vHidd_StdPixFmt_Unknown)))
327 STRPTR pixfmt_name = "";
329 switch(stdpixfmt)
331 case vHidd_StdPixFmt_RGB16:
332 case vHidd_StdPixFmt_RGB15:
333 case vHidd_StdPixFmt_RGB24:
334 pixfmt_name = "RGB";
335 break;
337 case vHidd_StdPixFmt_RGB16_LE:
338 case vHidd_StdPixFmt_RGB15_LE:
339 pixfmt_name = "RGB PC";
340 break;
342 case vHidd_StdPixFmt_BGR24:
343 case vHidd_StdPixFmt_BGR16:
344 case vHidd_StdPixFmt_BGR15:
345 pixfmt_name = "BGR";
346 break;
348 case vHidd_StdPixFmt_BGR16_LE:
349 case vHidd_StdPixFmt_BGR15_LE:
350 pixfmt_name = "BGR PC";
351 break;
353 case vHidd_StdPixFmt_ARGB32:
354 pixfmt_name = "ARGB";
355 break;
357 case vHidd_StdPixFmt_BGRA32:
358 pixfmt_name = "BGRA";
359 break;
361 case vHidd_StdPixFmt_RGBA32:
362 pixfmt_name = "RGBA";
363 break;
365 case vHidd_StdPixFmt_0RGB32:
366 pixfmt_name = "0RGB";
367 break;
369 case vHidd_StdPixFmt_BGR032:
370 pixfmt_name = "BGR0";
371 break;
373 case vHidd_StdPixFmt_RGB032:
374 pixfmt_name = "RGB0";
375 break;
379 snprintf(ni->Name, DISPLAYNAMELEN, "%s %2dbit %s",
380 sync_description, (int)depth, pixfmt_name);
382 else
384 snprintf(ni->Name, DISPLAYNAMELEN, "AROS: %ldx%ldx%ld", width, height, depth);
386 break;
389 default:
390 D(bug("!!! UNKNOWN tagID IN CALL TO GetDisplayInfoData() !!!\n"));
391 break;
395 D(bug("GDID: %d\n", structsize));
397 return structsize;
399 AROS_LIBFUNC_EXIT
401 } /* GetDisplayInfoData */
403 /****************************************************************************************/
405 static BOOL check_sizes(ULONG tagID, ULONG size)
407 ULONG idx;
408 const struct size_check *sc;
410 idx = DTAG_TO_IDX(tagID);
412 if (idx > 5)
414 D(bug("!!! INVALID tagID TO GetDisplayInfoData"));
415 return FALSE;
418 sc = &size_checks[idx];
419 if (sc->struct_id != tagID)
421 D(bug("!!! INVALID tagID TO GetDisplayInfoData"));
422 return FALSE;
425 if (sc->struct_size > size)
427 D(bug("!!! NO SPACE FOR %s IN BUFFER SUPPLIED TO GetDisplayInfoData !!!\n"
428 , sc->struct_name));
429 return FALSE;
432 return TRUE;
435 /****************************************************************************************/
437 static ULONG compute_numbits(HIDDT_Pixel mask)
439 ULONG i;
440 ULONG numbits = 0;
442 for (i = 0; i <= 31; i ++)
444 if (mask & (1L << i)) numbits ++;
447 return numbits;
450 /****************************************************************************************/
453 /****************************************************************************************/