wip prep commit in lieu of gfx subsystem update changes.
[AROS.git] / workbench / libs / cgfx / alloccmodelisttaglist.c
blobab62cd5cb455a0fcbc8472a8a831dcb2e280e6f9
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <cybergraphx/cybergraphics.h>
11 #include <exec/memory.h>
12 #include <hidd/gfx.h>
13 #include <proto/cybergraphics.h>
14 #include <proto/graphics.h>
15 #include <proto/oop.h>
16 #include <proto/utility.h>
17 #include <stdio.h>
19 #include "cybergraphics_intern.h"
20 #include "gfxfuncsupport.h"
22 /*****************************************************************************
24 NAME */
25 #include <proto/cybergraphics.h>
27 AROS_LH1(struct List *, AllocCModeListTagList,
29 /* SYNOPSIS */
30 AROS_LHA(struct TagItem *, tags, A1),
32 /* LOCATION */
33 struct Library *, CyberGfxBase, 12, Cybergraphics)
35 /* FUNCTION
36 Retrieves a list of RTG screenmodes that match the criteria specified
37 in a taglist. The supported tags are as follows:
38 CYBRMREQ_MinWidth (ULONG) - the minimum acceptable display width
39 (defaults to 320).
40 CYBRMREQ_MaxWidth (ULONG) - the maximum acceptable display width.
41 (defaults to 1600).
42 CYBRMREQ_MinHeight (ULONG) - the minimum acceptable display
43 height (defaults to 240).
44 CYBRMREQ_MaxHeight (ULONG) - the maximum acceptable display
45 height (defaults to 1200).
46 CYBRMREQ_MinDepth (UWORD) - the minimum acceptable display depth
47 (defaults to 8).
48 CYBRMREQ_MaxDepth (UWORD) - the minimum acceptable display depth
49 (defaults to 32).
50 CYBRMREQ_CModelArray (UWORD *) - array of permitted pixel formats.
51 Any of the PIXFMT_#? constants may be specified (see
52 LockBitMapTagList()), and the array must be terminated by ~0.
53 By default, all pixel formats are acceptable.
55 INPUTS
56 tags - mode selection criteria (may be NULL).
58 RESULT
59 result - a list of matching screenmodes, or NULL if there are none.
61 NOTES
63 EXAMPLE
65 BUGS
67 SEE ALSO
68 FreeCModeList()
70 INTERNALS
71 The function relies on pixelformat object being passed in
72 DimensionInfo.reserved[1] by graphics.library/GetDisplayInfoData().
74 *****************************************************************************/
76 AROS_LIBFUNC_INIT
78 /* TODO: Implement Display mode attributes */
80 struct TagItem *tstate;
81 struct TagItem *tag;
83 ULONG minwidth = 320;
84 ULONG maxwidth = 1600;
85 ULONG minheight = 240;
86 ULONG maxheight = 1200;
87 ULONG mindepth = 8;
88 ULONG maxdepth = 32;
90 struct List *cybermlist = NULL;
92 UWORD *cmodelarray = NULL;
93 ULONG mode = INVALID_ID;
95 for (tstate = tags; (tag = NextTagItem(&tstate)); ) {
96 switch (tag->ti_Tag) {
97 case CYBRMREQ_MinWidth:
98 minwidth = (ULONG)tag->ti_Data;
99 break;
101 case CYBRMREQ_MaxWidth:
102 maxwidth = (ULONG)tag->ti_Data;
103 break;
105 case CYBRMREQ_MinHeight:
106 minheight = (ULONG)tag->ti_Data;
107 break;
109 case CYBRMREQ_MaxHeight:
110 maxheight = (ULONG)tag->ti_Data;
111 break;
113 case CYBRMREQ_MinDepth:
114 mindepth = (ULONG)tag->ti_Data;
115 break;
117 case CYBRMREQ_MaxDepth:
118 maxdepth = (ULONG)tag->ti_Data;
119 break;
121 case CYBRMREQ_CModelArray:
122 cmodelarray = (UWORD *)tag->ti_Data;
123 break;
125 default:
126 D(bug("!!! UNKNOWN TAG PASSED TO AllocCModeListTagList\n"));
127 break;
131 /* Allocate the exec list */
132 cybermlist = AllocMem(sizeof (struct List), MEMF_CLEAR);
133 if (NULL == cybermlist)
134 return NULL;
137 NEWLIST(cybermlist);
139 while ((mode = NextDisplayInfo(mode)) != INVALID_ID)
141 struct CyberModeNode *cmnode;
142 UWORD *cyberpixfmts;
143 ULONG width, height;
144 struct DimensionInfo info;
145 struct NameInfo name;
146 IPTR cyberpf;
147 OOP_Object *pf;
149 if (GetDisplayInfoData(NULL, (UBYTE *)&info, sizeof(info), DTAG_DIMS, mode) != sizeof(info)) {
150 /* This should never happen because NextDisplayInfo() should
151 only return valid modes
153 D(bug("!!! UNABLE TO GET MODE INFO IN AllocCModeListTagList() !!!\n"));
154 D(bug("!!! THIS SHOULD *NEVER* HAPPEN !!!\n"));
155 goto failexit;
158 if (GetDisplayInfoData(NULL, (UBYTE *)&name, sizeof(name), DTAG_NAME, mode) != sizeof(name)) {
159 D(bug("!!! UNABLE TO GET MODE NAME IN AllocCModeListTagList() !!!\n"));
160 D(bug("!!! THIS SHOULD *NEVER* HAPPEN !!!\n"));
161 goto failexit;
164 width = info.Nominal.MaxX - info.Nominal.MinX + 1;
165 height = info.Nominal.MaxY - info.Nominal.MinY + 1;
167 if ( width < minwidth
168 || width > maxwidth
169 || height < minheight
170 || height > maxheight) {
172 continue;
174 if (info.MaxDepth < mindepth || info.MaxDepth > maxdepth)
175 continue;
177 /* Get the gfxmode pixelf format */
178 pf = (OOP_Object *)info.reserved[1];
179 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &cyberpf);
180 /* ignore non-CGX modes */
181 if (cyberpf == -1)
182 continue;
184 /* Check whether the gfxmode is the correct pixel format */
185 if (NULL != cmodelarray)
187 BOOL found = FALSE;
189 for (cyberpixfmts = cmodelarray; *cyberpixfmts; cyberpixfmts ++) {
190 /* See if the stdpixfmt is present in the array */
191 if (*cyberpixfmts == cyberpf) {
192 found = TRUE;
193 break;
195 } /* for (each supplied pixelformat in the cmodelarray) */
197 if (!found)
198 continue; /* PixFmt not wanted, just continue with next node */
200 } /* if (cmodelarray supplied in the taglist) */
202 /* Allocate a cybergfx modeinfo struct */
203 cmnode = AllocMem(sizeof (struct CyberModeNode), MEMF_CLEAR);
204 if (NULL == cmnode)
205 goto failexit;
207 cmnode->Width = width;
208 cmnode->Height = height;
209 cmnode->Depth = info.MaxDepth;
210 cmnode->DisplayID = mode;
211 cmnode->DisplayTagList = NULL;
212 CopyMem("CGFX:", cmnode->ModeText, 5);
213 CopyMem(name.Name, cmnode->ModeText + 5, DISPLAYNAMELEN - 5);
215 /* Keep track of the node */
216 AddTail(cybermlist, (struct Node *)cmnode);
218 } /* for (modeids returned from the HIDD) */
220 return cybermlist;
222 failexit:
223 if (NULL != cybermlist)
224 FreeCModeList(cybermlist);
226 return NULL;
228 AROS_LIBFUNC_EXIT
229 } /* AllocCModeListTagList */