Updated PCI IDs to latest snapshot.
[tangerine.git] / rom / graphics / dispinfo.c
blob2ab7191f545954bc4c30291133bdbd051592b5f6
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 IPTR 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 const struct TagItem *tstate;
103 struct TagItem *tag;
105 ULONG minwidth = 320;
106 ULONG maxwidth = 1600;
107 ULONG minheight = 240;
108 ULONG maxheight = 1200;
109 ULONG mindepth = 8;
110 ULONG maxdepth = 32;
112 struct List *cybermlist = NULL;
114 OOP_Object *gfxhidd;
116 UWORD *cmodelarray = NULL;
117 HIDDT_ModeID *hiddmodes = NULL, *hmptr;
118 struct TagItem querytags[] = { { TAG_DONE, 0UL } };
120 gfxhidd = SDD(GfxBase)->gfxhidd;
122 for (tstate = taglist; (tag = NextTagItem(&tstate)); ) {
123 switch (tag->ti_Tag) {
124 case CYBRMREQ_MinWidth:
125 minwidth = (ULONG)tag->ti_Data;
126 break;
128 case CYBRMREQ_MaxWidth:
129 maxwidth = (ULONG)tag->ti_Data;
130 break;
132 case CYBRMREQ_MinHeight:
133 minheight = (ULONG)tag->ti_Data;
134 break;
136 case CYBRMREQ_MaxHeight:
137 maxheight = (ULONG)tag->ti_Data;
138 break;
140 case CYBRMREQ_MinDepth:
141 mindepth = (ULONG)tag->ti_Data;
142 break;
144 case CYBRMREQ_MaxDepth:
145 maxdepth = (ULONG)tag->ti_Data;
146 break;
148 case CYBRMREQ_CModelArray:
149 cmodelarray = (UWORD *)tag->ti_Data;
150 break;
152 default:
153 D(bug("!!! UNKNOWN TAG PASSED TO AllocCModeListTagList\n"));
154 break;
158 /* Allocate the exec list */
159 cybermlist = AllocMem(sizeof (struct List), MEMF_CLEAR);
160 if (NULL == cybermlist)
161 return NULL;
164 NEWLIST(cybermlist);
166 /* Get all HIDD modes */
167 hiddmodes = HIDD_Gfx_QueryModeIDs(gfxhidd, querytags);
168 if (NULL == hiddmodes)
169 goto failexit;
172 for (hmptr = hiddmodes; *hmptr != vHidd_ModeID_Invalid; hmptr ++) {
174 struct CyberModeNode *cmnode;
175 UWORD *cyberpixfmts;
176 IPTR width, height, depth;
177 OOP_Object *sync, *pf;
179 if (!HIDD_Gfx_GetMode(gfxhidd, *hmptr, &sync, &pf)) {
180 /* This should never happen because HIDD_GfxWueryModeIDs() should
181 only return valid modes
183 D(bug("!!! UNABLE TO GET HIDD MODE INFO IN AllocCModeListTagList() !!!\n"));
184 D(bug("!!! THIS SHOULD *NEVER* HAPPEN !!!\n"));
185 goto failexit;
188 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
189 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
191 if ( width < minwidth
192 || width > maxwidth
193 || height < minheight
194 || height > maxheight) {
196 continue;
199 /* Get the pxifmt info */
200 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
202 if (depth < mindepth || depth > maxdepth)
203 continue;
205 /* Check whether the gfxmode is the correct pixel format */
206 if (NULL != cmodelarray) {
207 HIDDT_StdPixFmt stdpf;
208 UWORD cyberpf;
209 BOOL found = FALSE;
211 /* Get the gfxmode pixelf format */
212 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdpf);
214 cyberpf = hidd2cyber_pixfmt(stdpf, GfxBase);
215 if (cyberpf == (UWORD)-1)
216 continue; /* Unknown format */
218 for (cyberpixfmts = cmodelarray; *cyberpixfmts; cyberpixfmts ++) {
219 /* See if the stdpixfmt is present in the array */
220 if (*cyberpixfmts == cyberpf) {
221 found = TRUE;
222 break;
224 } /* for (each supplied pixelformat in the cmodelarray) */
226 if (!found)
227 continue; /* PixFmt not wanted, just continue with next node */
229 } /* if (cmodelarray supplied in the taglist) */
231 /* Allocate a cybergfx modeinfo struct */
232 cmnode = AllocMem(sizeof (struct CyberModeNode), MEMF_CLEAR);
233 if (NULL == cmnode)
234 goto failexit;
236 cmnode->Width = width;
237 cmnode->Height = height;
238 cmnode->Depth = depth;
239 cmnode->DisplayTagList = NULL;
241 snprintf( cmnode->ModeText
242 , DISPLAYNAMELEN
243 , "AROS: %ldx%ldx%ld"
244 , width, height, depth
247 /* Keep track of the node */
248 AddTail(cybermlist, (struct Node *)cmnode);
250 } /* for (modeids returned from the HIDD) */
252 return cybermlist;
254 failexit:
256 if (NULL != hiddmodes)
257 HIDD_Gfx_ReleaseModeIDs(gfxhidd, hiddmodes);
259 if (NULL != cybermlist)
260 driver_FreeCModeList(cybermlist, GfxBase);
263 return NULL;
270 ULONG driver_BestCModeIDTagList(struct TagItem *tags, struct GfxBase *GfxBase)
272 const struct TagItem *tstate;
273 struct TagItem *tag;
275 ULONG nominal_width, nominal_height, depth;
276 ULONG monitorid;
277 STRPTR boardname;
278 ULONG modeid;
280 nominal_width = 800;
281 nominal_height = 600;
282 depth = 8;
283 monitorid = 0;
284 boardname = "Blah";
286 for (tstate = tags; (tag = NextTagItem(&tstate)); ) {
287 switch (tag->ti_Tag) {
288 case CYBRBIDTG_Depth:
289 depth = tag->ti_Data;
290 break;
292 case CYBRBIDTG_NominalWidth:
293 nominal_width = tag->ti_Data;
294 break;
296 case CYBRBIDTG_NominalHeight:
297 nominal_height = tag->ti_Data;
298 break;
300 case CYBRBIDTG_MonitorID:
301 monitorid = tag->ti_Data;
302 break;
304 case CYBRBIDTG_BoardName:
305 boardname = (STRPTR)tag->ti_Data;
306 break;
308 default:
309 D(bug("!!! UNKOWN ATTR PASSED TO BestCModeIDTagList(): %x !!!\n", tag->ti_Tag));
310 break;
312 } /* switch () */
314 } /* for (each tag in the taglist) */
316 if (depth < 8 ) {
318 /* No request for a cgfx mode */
319 modeid = INVALID_ID;
321 } else {
322 /* Get the best modeid */
323 struct TagItem modetags[] = {
324 { BIDTAG_NominalWidth, nominal_width },
325 { BIDTAG_NominalHeight, nominal_height },
326 { BIDTAG_DesiredWidth, nominal_width },
327 { BIDTAG_DesiredHeight, nominal_height },
328 { BIDTAG_Depth, depth },
329 { BIDTAG_MonitorID, monitorid },
330 { TAG_DONE, 0UL }
333 modeid = BestModeIDA(modetags);
336 /* Use the data to select a mode */
337 return modeid;
341 ULONG driver_GetCyberIDAttr(ULONG attribute, ULONG id, struct GfxBase *GfxBase)
343 /* First lookup the pixfmt for the ID */
344 IPTR retval;
345 OOP_Object *sync, *pf;
346 HIDDT_ModeID hiddmode;
348 hiddmode = AMIGA_TO_HIDD_MODEID(id);
350 retval = (ULONG)-1;
352 if (HIDD_Gfx_GetMode(SDD(GfxBase)->gfxhidd, hiddmode, &sync, &pf)) {
353 IPTR depth;
354 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
356 if (depth < 8) {
357 D(bug("!!! TRYING TO GET ATTR FROM NON-CGFX MODE IN GetCyberIDAttr() !!!\n"));
358 retval = (ULONG)-1;
359 } else {
361 switch (attribute) {
362 case CYBRIDATTR_PIXFMT: {
363 HIDDT_StdPixFmt stdpf;
365 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdpf);
367 retval = hidd2cyber_pixfmt(stdpf, GfxBase);
368 if (-1 == retval) {
369 D(bug("!!! NO CGFX PIXFMT IN GetCyberIDAttr() !!!\n"));
371 break; }
373 case CYBRIDATTR_DEPTH:
374 retval = depth;
375 break;
377 case CYBRIDATTR_WIDTH:
378 OOP_GetAttr(sync, aHidd_Sync_HDisp, &retval);
379 break;
381 case CYBRIDATTR_HEIGHT:
382 OOP_GetAttr(sync, aHidd_Sync_VDisp, &retval);
383 break;
385 case CYBRIDATTR_BPPIX:
386 OOP_GetAttr(pf, aHidd_PixFmt_BytesPerPixel, &retval);
387 break;
389 default:
390 D(bug("!!! UNKONOW ATTRIBUTE IN GetCyberIDAttr(): %x !!!\n"
391 , attribute));
392 retval = (ULONG)-1;
393 break;
399 return retval;
403 BOOL driver_IsCyberModeID(ULONG modeid, struct GfxBase *GfxBase)
405 BOOL iscyber = FALSE;
406 HIDDT_ModeID hiddmode = 0;
407 OOP_Object *sync, *pf;
409 hiddmode = AMIGA_TO_HIDD_MODEID(modeid);
411 if (HIDD_Gfx_GetMode(SDD(GfxBase)->gfxhidd, hiddmode, &sync, &pf)) {
412 HIDDT_StdPixFmt stdpf;
414 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdpf);
415 if (((UWORD)-1) != hidd2cyber_pixfmt(stdpf, GfxBase)) {
416 iscyber = TRUE;
419 return iscyber;
423 HIDDT_ModeID get_best_resolution_and_depth(struct GfxBase *GfxBase)
425 HIDDT_ModeID ret = vHidd_ModeID_Invalid;
426 OOP_Object *gfxhidd;
427 HIDDT_ModeID *modes, *m;
428 struct TagItem querytags[] = { { TAG_DONE, 0UL } };
430 gfxhidd = SDD(GfxBase)->gfxhidd;
432 /* Query the gfxhidd for all modes */
433 modes = HIDD_Gfx_QueryModeIDs(gfxhidd, querytags);
435 if (NULL != modes) {
436 ULONG best_resolution = 0;
437 ULONG best_depth = 0;
439 for (m = modes; vHidd_ModeID_Invalid != *m; m ++) {
440 OOP_Object *sync, *pf;
441 IPTR depth;
442 HIDD_Gfx_GetMode(gfxhidd, *m, &sync, &pf);
444 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
445 if (depth >= best_depth) {
446 IPTR width, height;
447 ULONG res;
449 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
450 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
452 res = width * height;
453 if (res > best_resolution) {
454 ret = *m;
455 best_resolution = res;
458 best_depth = depth;
463 HIDD_Gfx_ReleaseModeIDs(gfxhidd, modes);
466 return ret;