r4493@vps: verhaegs | 2007-04-19 14:44:00 -0400
[AROS.git] / rom / graphics / dispinfo.c
blobe1c3ea77cd60d4b37f55ce1c8f8474a79d1bab1c
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <proto/exec.h>
7 #include <proto/oop.h>
8 #include <proto/arossupport.h>
9 #include <proto/utility.h>
10 #include <proto/graphics.h>
12 #include <exec/lists.h>
13 #include <exec/memory.h>
15 #include <graphics/displayinfo.h>
16 #include <graphics/monitor.h>
18 #include <cybergraphx/cybergraphics.h>
20 #include <oop/oop.h>
22 #include <hidd/graphics.h>
24 #include <stdio.h>
25 #include <string.h>
27 #include "graphics_intern.h"
28 #include "graphics_internal.h"
29 #include "gfxfuncsupport.h"
30 #include "dispinfo.h"
32 #define DEBUG 0
33 #include <aros/debug.h>
35 HIDDT_ModeID get_hiddmode_for_amigamodeid(ULONG modeid, struct GfxBase *GfxBase)
37 return AMIGA_TO_HIDD_MODEID(modeid);
40 VOID destroy_dispinfo_db(APTR dispinfo_db, struct GfxBase *GfxBase)
42 struct displayinfo_db *db;
44 db = (struct displayinfo_db *)dispinfo_db;
46 ObtainSemaphore(&db->sema);
48 if (NULL != db->mspecs) {
49 FreeMem(db->mspecs, sizeof (struct MonitorSpec) * db->num_mspecs);
50 db->mspecs = NULL;
51 db->num_mspecs = 0;
54 ReleaseSemaphore(&db->sema);
56 FreeMem(db, sizeof (*db));
60 APTR build_dispinfo_db(struct GfxBase *GfxBase)
62 struct displayinfo_db *db;
63 ULONG numsyncs;
65 db = AllocMem(sizeof (struct displayinfo_db), MEMF_PUBLIC | MEMF_CLEAR);
66 if (NULL != db) {
68 InitSemaphore(&db->sema);
70 /* Get the number of possible modes in the gfxhidd */
71 OOP_GetAttr(SDD(GfxBase)->gfxhidd, aHidd_Gfx_NumSyncs, &numsyncs);
73 db->num_mspecs = numsyncs;
75 /* Allocate a table to hold all the monitorspecs */
76 db->mspecs = AllocMem(sizeof (struct MonitorSpec) * db->num_mspecs, MEMF_PUBLIC | MEMF_CLEAR);
77 if (NULL != db->mspecs) {
78 return (APTR)db;
80 destroy_dispinfo_db(db, GfxBase);
82 return NULL;
86 #warning Implement Display mode attributes in the below function
88 VOID driver_FreeCModeList(struct List *modeList, struct GfxBase *GfxBase)
90 struct CyberModeNode *node, *safe;
92 ForeachNodeSafe(modeList, node, safe) {
93 Remove((struct Node *)node);
94 FreeMem(node, sizeof (struct CyberModeNode));
97 FreeMem(modeList, sizeof (struct List));
100 APTR driver_AllocCModeListTagList(struct TagItem *taglist, struct GfxBase *GfxBase )
102 struct TagItem *tag, *tstate;
104 ULONG minwidth = 320;
105 ULONG maxwidth = 1600;
106 ULONG minheight = 240;
107 ULONG maxheight = 1200;
108 ULONG mindepth = 8;
109 ULONG maxdepth = 32;
111 struct List *cybermlist = NULL;
113 OOP_Object *gfxhidd;
115 UWORD *cmodelarray = NULL;
116 HIDDT_ModeID *hiddmodes = NULL, *hmptr;
117 struct TagItem querytags[] = { { TAG_DONE, 0UL } };
119 gfxhidd = SDD(GfxBase)->gfxhidd;
121 for (tstate = taglist; (tag = NextTagItem(&tstate)); ) {
122 switch (tag->ti_Tag) {
123 case CYBRMREQ_MinWidth:
124 minwidth = (ULONG)tag->ti_Data;
125 break;
127 case CYBRMREQ_MaxWidth:
128 maxwidth = (ULONG)tag->ti_Data;
129 break;
131 case CYBRMREQ_MinHeight:
132 minheight = (ULONG)tag->ti_Data;
133 break;
135 case CYBRMREQ_MaxHeight:
136 maxheight = (ULONG)tag->ti_Data;
137 break;
139 case CYBRMREQ_MinDepth:
140 mindepth = (ULONG)tag->ti_Data;
141 break;
143 case CYBRMREQ_MaxDepth:
144 maxdepth = (ULONG)tag->ti_Data;
145 break;
147 case CYBRMREQ_CModelArray:
148 cmodelarray = (UWORD *)tag->ti_Data;
149 break;
151 default:
152 D(bug("!!! UNKNOWN TAG PASSED TO AllocCModeListTagList\n"));
153 break;
157 /* Allocate the exec list */
158 cybermlist = AllocMem(sizeof (struct List), MEMF_CLEAR);
159 if (NULL == cybermlist)
160 return NULL;
163 NEWLIST(cybermlist);
165 /* Get all HIDD modes */
166 hiddmodes = HIDD_Gfx_QueryModeIDs(gfxhidd, querytags);
167 if (NULL == hiddmodes)
168 goto failexit;
171 for (hmptr = hiddmodes; *hmptr != vHidd_ModeID_Invalid; hmptr ++) {
173 struct CyberModeNode *cmnode;
174 UWORD *cyberpixfmts;
175 ULONG width, height, depth;
176 OOP_Object *sync, *pf;
178 if (!HIDD_Gfx_GetMode(gfxhidd, *hmptr, &sync, &pf)) {
179 /* This should never happen because HIDD_GfxWueryModeIDs() should
180 only return valid modes
182 D(bug("!!! UNABLE TO GET HIDD MODE INFO IN AllocCModeListTagList() !!!\n"));
183 D(bug("!!! THIS SHOULD *NEVER* HAPPEN !!!\n"));
184 goto failexit;
187 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
188 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
190 if ( width < minwidth
191 || width > maxwidth
192 || height < minheight
193 || height > maxheight) {
195 continue;
198 /* Get the pxifmt info */
199 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
201 if (depth < mindepth || depth > maxdepth)
202 continue;
204 /* Check whether the gfxmode is the correct pixel format */
205 if (NULL != cmodelarray) {
206 HIDDT_StdPixFmt stdpf;
207 UWORD cyberpf;
208 BOOL found = FALSE;
210 /* Get the gfxmode pixelf format */
211 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdpf);
213 cyberpf = hidd2cyber_pixfmt(stdpf, GfxBase);
214 if (cyberpf == (UWORD)-1)
215 continue; /* Unknown format */
217 for (cyberpixfmts = cmodelarray; *cyberpixfmts; cyberpixfmts ++) {
218 /* See if the stdpixfmt is present in the array */
219 if (*cyberpixfmts == cyberpf) {
220 found = TRUE;
221 break;
223 } /* for (each supplied pixelformat in the cmodelarray) */
225 if (!found)
226 continue; /* PixFmt not wanted, just continue with next node */
228 } /* if (cmodelarray supplied in the taglist) */
230 /* Allocate a cybergfx modeinfo struct */
231 cmnode = AllocMem(sizeof (struct CyberModeNode), MEMF_CLEAR);
232 if (NULL == cmnode)
233 goto failexit;
235 cmnode->Width = width;
236 cmnode->Height = height;
237 cmnode->Depth = depth;
238 cmnode->DisplayTagList = NULL;
240 snprintf( cmnode->ModeText
241 , DISPLAYNAMELEN
242 , "AROS: %ldx%ldx%ld"
243 , width, height, depth
246 /* Keep track of the node */
247 AddTail(cybermlist, (struct Node *)cmnode);
249 } /* for (modeids returned from the HIDD) */
251 return cybermlist;
253 failexit:
255 if (NULL != hiddmodes)
256 HIDD_Gfx_ReleaseModeIDs(gfxhidd, hiddmodes);
258 if (NULL != cybermlist)
259 driver_FreeCModeList(cybermlist, GfxBase);
262 return NULL;
269 ULONG driver_BestCModeIDTagList(struct TagItem *tags, struct GfxBase *GfxBase)
271 struct TagItem *tag, *tstate;
273 ULONG nominal_width, nominal_height, depth;
274 ULONG monitorid;
275 STRPTR boardname;
276 ULONG modeid;
278 nominal_width = 800;
279 nominal_height = 600;
280 depth = 8;
281 monitorid = 0;
282 boardname = "Blah";
284 for (tstate = tags; (tag = NextTagItem(&tstate)); ) {
285 switch (tag->ti_Tag) {
286 case CYBRBIDTG_Depth:
287 depth = tag->ti_Data;
288 break;
290 case CYBRBIDTG_NominalWidth:
291 nominal_width = tag->ti_Data;
292 break;
294 case CYBRBIDTG_NominalHeight:
295 nominal_height = tag->ti_Data;
296 break;
298 case CYBRBIDTG_MonitorID:
299 monitorid = tag->ti_Data;
300 break;
302 case CYBRBIDTG_BoardName:
303 boardname = (STRPTR)tag->ti_Data;
304 break;
306 default:
307 D(bug("!!! UNKOWN ATTR PASSED TO BestCModeIDTagList(): %x !!!\n", tag->ti_Tag));
308 break;
310 } /* switch () */
312 } /* for (each tag in the taglist) */
314 if (depth < 8 ) {
316 /* No request for a cgfx mode */
317 modeid = INVALID_ID;
319 } else {
320 /* Get the best modeid */
321 struct TagItem modetags[] = {
322 { BIDTAG_NominalWidth, nominal_width },
323 { BIDTAG_NominalHeight, nominal_height },
324 { BIDTAG_DesiredWidth, nominal_width },
325 { BIDTAG_DesiredHeight, nominal_height },
326 { BIDTAG_Depth, depth },
327 { BIDTAG_MonitorID, monitorid },
328 { TAG_DONE, 0UL }
331 modeid = BestModeIDA(modetags);
334 /* Use the data to select a mode */
335 return modeid;
339 ULONG driver_GetCyberIDAttr(ULONG attribute, ULONG id, struct GfxBase *GfxBase)
341 /* First lookup the pixfmt for the ID */
342 ULONG retval;
343 OOP_Object *sync, *pf;
344 HIDDT_ModeID hiddmode;
346 hiddmode = AMIGA_TO_HIDD_MODEID(id);
348 retval = (ULONG)-1;
350 if (HIDD_Gfx_GetMode(SDD(GfxBase)->gfxhidd, hiddmode, &sync, &pf)) {
351 ULONG depth;
352 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
354 if (depth < 8) {
355 D(bug("!!! TRYING TO GET ATTR FROM NON-CGFX MODE IN GetCyberIDAttr() !!!\n"));
356 retval = (ULONG)-1;
357 } else {
359 switch (attribute) {
360 case CYBRIDATTR_PIXFMT: {
361 HIDDT_StdPixFmt stdpf;
363 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdpf);
365 retval = hidd2cyber_pixfmt(stdpf, GfxBase);
366 if (-1 == retval) {
367 D(bug("!!! NO CGFX PIXFMT IN GetCyberIDAttr() !!!\n"));
369 break; }
371 case CYBRIDATTR_DEPTH:
372 retval = depth;
373 break;
375 case CYBRIDATTR_WIDTH:
376 OOP_GetAttr(sync, aHidd_Sync_HDisp, &retval);
377 break;
379 case CYBRIDATTR_HEIGHT:
380 OOP_GetAttr(sync, aHidd_Sync_VDisp, &retval);
381 break;
383 case CYBRIDATTR_BPPIX:
384 OOP_GetAttr(pf, aHidd_PixFmt_BytesPerPixel, &retval);
385 break;
387 default:
388 D(bug("!!! UNKONOW ATTRIBUTE IN GetCyberIDAttr(): %x !!!\n"
389 , attribute));
390 retval = (ULONG)-1;
391 break;
397 return retval;
401 BOOL driver_IsCyberModeID(ULONG modeid, struct GfxBase *GfxBase)
403 BOOL iscyber = FALSE;
404 HIDDT_ModeID hiddmode = 0;
405 OOP_Object *sync, *pf;
407 hiddmode = AMIGA_TO_HIDD_MODEID(hiddmode);
409 if (HIDD_Gfx_GetMode(SDD(GfxBase)->gfxhidd, hiddmode, &sync, &pf)) {
410 HIDDT_StdPixFmt stdpf;
412 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdpf);
413 if (((UWORD)-1) != hidd2cyber_pixfmt(stdpf, GfxBase)) {
414 iscyber = TRUE;
417 return iscyber;
421 HIDDT_ModeID get_best_resolution_and_depth(struct GfxBase *GfxBase)
423 HIDDT_ModeID ret = vHidd_ModeID_Invalid;
424 OOP_Object *gfxhidd;
425 HIDDT_ModeID *modes, *m;
426 struct TagItem querytags[] = { { TAG_DONE, 0UL } };
428 gfxhidd = SDD(GfxBase)->gfxhidd;
430 /* Query the gfxhidd for all modes */
431 modes = HIDD_Gfx_QueryModeIDs(gfxhidd, querytags);
432 if (NULL != modes) {
433 ULONG best_resolution = 0;
434 ULONG best_depth = 0;
436 for (m = modes; vHidd_ModeID_Invalid != *m; m ++) {
437 OOP_Object *sync, *pf;
438 IPTR depth;
439 HIDD_Gfx_GetMode(gfxhidd, *m, &sync, &pf);
441 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
442 if (depth >= best_depth) {
443 IPTR width, height;
444 ULONG res;
446 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
447 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
449 res = width * height;
450 if (res > best_resolution) {
451 ret = *m;
454 best_depth = depth;
459 HIDD_Gfx_ReleaseModeIDs(gfxhidd, modes);
462 return ret;