1706f2543Smrg/*
2706f2543Smrg *
3706f2543Smrg * Copyright (c) 1997  Metro Link Incorporated
4706f2543Smrg *
5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6706f2543Smrg * copy of this software and associated documentation files (the "Software"),
7706f2543Smrg * to deal in the Software without restriction, including without limitation
8706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
10706f2543Smrg * Software is furnished to do so, subject to the following conditions:
11706f2543Smrg *
12706f2543Smrg * The above copyright notice and this permission notice shall be included in
13706f2543Smrg * all copies or substantial portions of the Software.
14706f2543Smrg *
15706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18706f2543Smrg * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19706f2543Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20706f2543Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21706f2543Smrg * SOFTWARE.
22706f2543Smrg *
23706f2543Smrg * Except as contained in this notice, the name of the Metro Link shall not be
24706f2543Smrg * used in advertising or otherwise to promote the sale, use or other dealings
25706f2543Smrg * in this Software without prior written authorization from Metro Link.
26706f2543Smrg *
27706f2543Smrg */
28706f2543Smrg/*
29706f2543Smrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
30706f2543Smrg *
31706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
32706f2543Smrg * copy of this software and associated documentation files (the "Software"),
33706f2543Smrg * to deal in the Software without restriction, including without limitation
34706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
36706f2543Smrg * Software is furnished to do so, subject to the following conditions:
37706f2543Smrg *
38706f2543Smrg * The above copyright notice and this permission notice shall be included in
39706f2543Smrg * all copies or substantial portions of the Software.
40706f2543Smrg *
41706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
44706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
45706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE.
48706f2543Smrg *
49706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s)
50706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote
51706f2543Smrg * the sale, use or other dealings in this Software without prior written
52706f2543Smrg * authorization from the copyright holder(s) and author(s).
53706f2543Smrg */
54706f2543Smrg
55706f2543Smrg
56706f2543Smrg/* View/edit this file with tab stops set to 4 */
57706f2543Smrg
58706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
59706f2543Smrg#include <xorg-config.h>
60706f2543Smrg#endif
61706f2543Smrg
62706f2543Smrg#include "xf86Parser.h"
63706f2543Smrg#include "xf86tokens.h"
64706f2543Smrg#include "Configint.h"
65706f2543Smrg
66706f2543Smrgextern LexRec val;
67706f2543Smrg
68706f2543Smrgstatic xf86ConfigSymTabRec MonitorTab[] =
69706f2543Smrg{
70706f2543Smrg	{ENDSECTION, "endsection"},
71706f2543Smrg	{IDENTIFIER, "identifier"},
72706f2543Smrg	{VENDOR, "vendorname"},
73706f2543Smrg	{MODEL, "modelname"},
74706f2543Smrg	{USEMODES, "usemodes"},
75706f2543Smrg	{MODELINE, "modeline"},
76706f2543Smrg	{DISPLAYSIZE, "displaysize"},
77706f2543Smrg	{HORIZSYNC, "horizsync"},
78706f2543Smrg	{VERTREFRESH, "vertrefresh"},
79706f2543Smrg	{MODE, "mode"},
80706f2543Smrg	{GAMMA, "gamma"},
81706f2543Smrg	{OPTION, "option"},
82706f2543Smrg	{-1, ""},
83706f2543Smrg};
84706f2543Smrg
85706f2543Smrgstatic xf86ConfigSymTabRec ModesTab[] =
86706f2543Smrg{
87706f2543Smrg	{ENDSECTION, "endsection"},
88706f2543Smrg	{IDENTIFIER, "identifier"},
89706f2543Smrg	{MODELINE, "modeline"},
90706f2543Smrg	{MODE, "mode"},
91706f2543Smrg	{-1, ""},
92706f2543Smrg};
93706f2543Smrg
94706f2543Smrgstatic xf86ConfigSymTabRec TimingTab[] =
95706f2543Smrg{
96706f2543Smrg	{TT_INTERLACE, "interlace"},
97706f2543Smrg	{TT_PHSYNC, "+hsync"},
98706f2543Smrg	{TT_NHSYNC, "-hsync"},
99706f2543Smrg	{TT_PVSYNC, "+vsync"},
100706f2543Smrg	{TT_NVSYNC, "-vsync"},
101706f2543Smrg	{TT_CSYNC, "composite"},
102706f2543Smrg	{TT_PCSYNC, "+csync"},
103706f2543Smrg	{TT_NCSYNC, "-csync"},
104706f2543Smrg	{TT_DBLSCAN, "doublescan"},
105706f2543Smrg	{TT_HSKEW, "hskew"},
106706f2543Smrg	{TT_BCAST, "bcast"},
107706f2543Smrg	{TT_VSCAN, "vscan"},
108706f2543Smrg	{-1, ""},
109706f2543Smrg};
110706f2543Smrg
111706f2543Smrgstatic xf86ConfigSymTabRec ModeTab[] =
112706f2543Smrg{
113706f2543Smrg	{DOTCLOCK, "dotclock"},
114706f2543Smrg	{HTIMINGS, "htimings"},
115706f2543Smrg	{VTIMINGS, "vtimings"},
116706f2543Smrg	{FLAGS, "flags"},
117706f2543Smrg	{HSKEW, "hskew"},
118706f2543Smrg	{BCAST, "bcast"},
119706f2543Smrg	{VSCAN, "vscan"},
120706f2543Smrg	{ENDMODE, "endmode"},
121706f2543Smrg	{-1, ""},
122706f2543Smrg};
123706f2543Smrg
124706f2543Smrg#define CLEANUP xf86freeModeLineList
125706f2543Smrg
126706f2543Smrgstatic void
127706f2543Smrgxf86freeModeLineList (XF86ConfModeLinePtr ptr)
128706f2543Smrg{
129706f2543Smrg	XF86ConfModeLinePtr prev;
130706f2543Smrg	while (ptr)
131706f2543Smrg	{
132706f2543Smrg		TestFree (ptr->ml_identifier);
133706f2543Smrg		TestFree (ptr->ml_comment);
134706f2543Smrg		prev = ptr;
135706f2543Smrg		ptr = ptr->list.next;
136706f2543Smrg		free (prev);
137706f2543Smrg	}
138706f2543Smrg}
139706f2543Smrg
140706f2543Smrgstatic XF86ConfModeLinePtr
141706f2543Smrgxf86parseModeLine (void)
142706f2543Smrg{
143706f2543Smrg	int token;
144706f2543Smrg	parsePrologue (XF86ConfModeLinePtr, XF86ConfModeLineRec)
145706f2543Smrg
146706f2543Smrg	/* Identifier */
147706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != STRING)
148706f2543Smrg		Error ("ModeLine identifier expected", NULL);
149706f2543Smrg	ptr->ml_identifier = val.str;
150706f2543Smrg
151706f2543Smrg	/* DotClock */
152706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
153706f2543Smrg		Error ("ModeLine dotclock expected", NULL);
154706f2543Smrg	ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5);
155706f2543Smrg
156706f2543Smrg	/* HDisplay */
157706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
158706f2543Smrg		Error ("ModeLine Hdisplay expected", NULL);
159706f2543Smrg	ptr->ml_hdisplay = val.num;
160706f2543Smrg
161706f2543Smrg	/* HSyncStart */
162706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
163706f2543Smrg		Error ("ModeLine HSyncStart expected", NULL);
164706f2543Smrg	ptr->ml_hsyncstart = val.num;
165706f2543Smrg
166706f2543Smrg	/* HSyncEnd */
167706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
168706f2543Smrg		Error ("ModeLine HSyncEnd expected", NULL);
169706f2543Smrg	ptr->ml_hsyncend = val.num;
170706f2543Smrg
171706f2543Smrg	/* HTotal */
172706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
173706f2543Smrg		Error ("ModeLine HTotal expected", NULL);
174706f2543Smrg	ptr->ml_htotal = val.num;
175706f2543Smrg
176706f2543Smrg	/* VDisplay */
177706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
178706f2543Smrg		Error ("ModeLine Vdisplay expected", NULL);
179706f2543Smrg	ptr->ml_vdisplay = val.num;
180706f2543Smrg
181706f2543Smrg	/* VSyncStart */
182706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
183706f2543Smrg		Error ("ModeLine VSyncStart expected", NULL);
184706f2543Smrg	ptr->ml_vsyncstart = val.num;
185706f2543Smrg
186706f2543Smrg	/* VSyncEnd */
187706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
188706f2543Smrg		Error ("ModeLine VSyncEnd expected", NULL);
189706f2543Smrg	ptr->ml_vsyncend = val.num;
190706f2543Smrg
191706f2543Smrg	/* VTotal */
192706f2543Smrg	if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
193706f2543Smrg		Error ("ModeLine VTotal expected", NULL);
194706f2543Smrg	ptr->ml_vtotal = val.num;
195706f2543Smrg
196706f2543Smrg	token = xf86getSubTokenWithTab (&(ptr->ml_comment), TimingTab);
197706f2543Smrg	while ((token == TT_INTERLACE) || (token == TT_PHSYNC) ||
198706f2543Smrg		   (token == TT_NHSYNC) || (token == TT_PVSYNC) ||
199706f2543Smrg		   (token == TT_NVSYNC) || (token == TT_CSYNC) ||
200706f2543Smrg		   (token == TT_PCSYNC) || (token == TT_NCSYNC) ||
201706f2543Smrg		   (token == TT_DBLSCAN) || (token == TT_HSKEW) ||
202706f2543Smrg		   (token == TT_VSCAN) || (token == TT_BCAST))
203706f2543Smrg	{
204706f2543Smrg		switch (token)
205706f2543Smrg		{
206706f2543Smrg
207706f2543Smrg		case TT_INTERLACE:
208706f2543Smrg			ptr->ml_flags |= XF86CONF_INTERLACE;
209706f2543Smrg			break;
210706f2543Smrg		case TT_PHSYNC:
211706f2543Smrg			ptr->ml_flags |= XF86CONF_PHSYNC;
212706f2543Smrg			break;
213706f2543Smrg		case TT_NHSYNC:
214706f2543Smrg			ptr->ml_flags |= XF86CONF_NHSYNC;
215706f2543Smrg			break;
216706f2543Smrg		case TT_PVSYNC:
217706f2543Smrg			ptr->ml_flags |= XF86CONF_PVSYNC;
218706f2543Smrg			break;
219706f2543Smrg		case TT_NVSYNC:
220706f2543Smrg			ptr->ml_flags |= XF86CONF_NVSYNC;
221706f2543Smrg			break;
222706f2543Smrg		case TT_CSYNC:
223706f2543Smrg			ptr->ml_flags |= XF86CONF_CSYNC;
224706f2543Smrg			break;
225706f2543Smrg		case TT_PCSYNC:
226706f2543Smrg			ptr->ml_flags |= XF86CONF_PCSYNC;
227706f2543Smrg			break;
228706f2543Smrg		case TT_NCSYNC:
229706f2543Smrg			ptr->ml_flags |= XF86CONF_NCSYNC;
230706f2543Smrg			break;
231706f2543Smrg		case TT_DBLSCAN:
232706f2543Smrg			ptr->ml_flags |= XF86CONF_DBLSCAN;
233706f2543Smrg			break;
234706f2543Smrg		case TT_HSKEW:
235706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
236706f2543Smrg				Error (NUMBER_MSG, "Hskew");
237706f2543Smrg			ptr->ml_hskew = val.num;
238706f2543Smrg			ptr->ml_flags |= XF86CONF_HSKEW;
239706f2543Smrg			break;
240706f2543Smrg		case TT_BCAST:
241706f2543Smrg			ptr->ml_flags |= XF86CONF_BCAST;
242706f2543Smrg			break;
243706f2543Smrg		case TT_VSCAN:
244706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
245706f2543Smrg				Error (NUMBER_MSG, "Vscan");
246706f2543Smrg			ptr->ml_vscan = val.num;
247706f2543Smrg			ptr->ml_flags |= XF86CONF_VSCAN;
248706f2543Smrg			break;
249706f2543Smrg		case EOF_TOKEN:
250706f2543Smrg			Error (UNEXPECTED_EOF_MSG, NULL);
251706f2543Smrg			break;
252706f2543Smrg		default:
253706f2543Smrg			Error (INVALID_KEYWORD_MSG, xf86tokenString ());
254706f2543Smrg			break;
255706f2543Smrg		}
256706f2543Smrg		token = xf86getSubTokenWithTab (&(ptr->ml_comment), TimingTab);
257706f2543Smrg	}
258706f2543Smrg	xf86unGetToken (token);
259706f2543Smrg
260706f2543Smrg#ifdef DEBUG
261706f2543Smrg	printf ("ModeLine parsed\n");
262706f2543Smrg#endif
263706f2543Smrg	return ptr;
264706f2543Smrg}
265706f2543Smrg
266706f2543Smrgstatic XF86ConfModeLinePtr
267706f2543Smrgxf86parseVerboseMode (void)
268706f2543Smrg{
269706f2543Smrg	int token, token2;
270706f2543Smrg	int had_dotclock = 0, had_htimings = 0, had_vtimings = 0;
271706f2543Smrg	parsePrologue (XF86ConfModeLinePtr, XF86ConfModeLineRec)
272706f2543Smrg
273706f2543Smrg		if (xf86getSubToken (&(ptr->ml_comment)) != STRING)
274706f2543Smrg		Error ("Mode name expected", NULL);
275706f2543Smrg	ptr->ml_identifier = val.str;
276706f2543Smrg	while ((token = xf86getToken (ModeTab)) != ENDMODE)
277706f2543Smrg	{
278706f2543Smrg		switch (token)
279706f2543Smrg		{
280706f2543Smrg		case COMMENT:
281706f2543Smrg			ptr->ml_comment = xf86addComment(ptr->ml_comment, val.str);
282706f2543Smrg			break;
283706f2543Smrg		case DOTCLOCK:
284706f2543Smrg			if ((token = xf86getSubToken (&(ptr->ml_comment))) != NUMBER)
285706f2543Smrg				Error (NUMBER_MSG, "DotClock");
286706f2543Smrg			ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5);
287706f2543Smrg			had_dotclock = 1;
288706f2543Smrg			break;
289706f2543Smrg		case HTIMINGS:
290706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) == NUMBER)
291706f2543Smrg				ptr->ml_hdisplay = val.num;
292706f2543Smrg			else
293706f2543Smrg				Error ("Horizontal display expected", NULL);
294706f2543Smrg
295706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) == NUMBER)
296706f2543Smrg				ptr->ml_hsyncstart = val.num;
297706f2543Smrg			else
298706f2543Smrg				Error ("Horizontal sync start expected", NULL);
299706f2543Smrg
300706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) == NUMBER)
301706f2543Smrg				ptr->ml_hsyncend = val.num;
302706f2543Smrg			else
303706f2543Smrg				Error ("Horizontal sync end expected", NULL);
304706f2543Smrg
305706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) == NUMBER)
306706f2543Smrg				ptr->ml_htotal = val.num;
307706f2543Smrg			else
308706f2543Smrg				Error ("Horizontal total expected", NULL);
309706f2543Smrg			had_htimings = 1;
310706f2543Smrg			break;
311706f2543Smrg		case VTIMINGS:
312706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) == NUMBER)
313706f2543Smrg				ptr->ml_vdisplay = val.num;
314706f2543Smrg			else
315706f2543Smrg				Error ("Vertical display expected", NULL);
316706f2543Smrg
317706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) == NUMBER)
318706f2543Smrg				ptr->ml_vsyncstart = val.num;
319706f2543Smrg			else
320706f2543Smrg				Error ("Vertical sync start expected", NULL);
321706f2543Smrg
322706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) == NUMBER)
323706f2543Smrg				ptr->ml_vsyncend = val.num;
324706f2543Smrg			else
325706f2543Smrg				Error ("Vertical sync end expected", NULL);
326706f2543Smrg
327706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) == NUMBER)
328706f2543Smrg				ptr->ml_vtotal = val.num;
329706f2543Smrg			else
330706f2543Smrg				Error ("Vertical total expected", NULL);
331706f2543Smrg			had_vtimings = 1;
332706f2543Smrg			break;
333706f2543Smrg		case FLAGS:
334706f2543Smrg			token = xf86getSubToken (&(ptr->ml_comment));
335706f2543Smrg			if (token != STRING)
336706f2543Smrg				Error (QUOTE_MSG, "Flags");
337706f2543Smrg			while (token == STRING)
338706f2543Smrg			{
339706f2543Smrg				token2 = xf86getStringToken (TimingTab);
340706f2543Smrg				switch (token2)
341706f2543Smrg				{
342706f2543Smrg				case TT_INTERLACE:
343706f2543Smrg					ptr->ml_flags |= XF86CONF_INTERLACE;
344706f2543Smrg					break;
345706f2543Smrg				case TT_PHSYNC:
346706f2543Smrg					ptr->ml_flags |= XF86CONF_PHSYNC;
347706f2543Smrg					break;
348706f2543Smrg				case TT_NHSYNC:
349706f2543Smrg					ptr->ml_flags |= XF86CONF_NHSYNC;
350706f2543Smrg					break;
351706f2543Smrg				case TT_PVSYNC:
352706f2543Smrg					ptr->ml_flags |= XF86CONF_PVSYNC;
353706f2543Smrg					break;
354706f2543Smrg				case TT_NVSYNC:
355706f2543Smrg					ptr->ml_flags |= XF86CONF_NVSYNC;
356706f2543Smrg					break;
357706f2543Smrg				case TT_CSYNC:
358706f2543Smrg					ptr->ml_flags |= XF86CONF_CSYNC;
359706f2543Smrg					break;
360706f2543Smrg				case TT_PCSYNC:
361706f2543Smrg					ptr->ml_flags |= XF86CONF_PCSYNC;
362706f2543Smrg					break;
363706f2543Smrg				case TT_NCSYNC:
364706f2543Smrg					ptr->ml_flags |= XF86CONF_NCSYNC;
365706f2543Smrg					break;
366706f2543Smrg				case TT_DBLSCAN:
367706f2543Smrg					ptr->ml_flags |= XF86CONF_DBLSCAN;
368706f2543Smrg					break;
369706f2543Smrg				case EOF_TOKEN:
370706f2543Smrg					Error (UNEXPECTED_EOF_MSG, NULL);
371706f2543Smrg					break;
372706f2543Smrg				default:
373706f2543Smrg					Error ("Unknown flag string", NULL);
374706f2543Smrg					break;
375706f2543Smrg				}
376706f2543Smrg				token = xf86getSubToken (&(ptr->ml_comment));
377706f2543Smrg			}
378706f2543Smrg			xf86unGetToken (token);
379706f2543Smrg			break;
380706f2543Smrg		case HSKEW:
381706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
382706f2543Smrg				Error ("Horizontal skew expected", NULL);
383706f2543Smrg			ptr->ml_flags |= XF86CONF_HSKEW;
384706f2543Smrg			ptr->ml_hskew = val.num;
385706f2543Smrg			break;
386706f2543Smrg		case VSCAN:
387706f2543Smrg			if (xf86getSubToken (&(ptr->ml_comment)) != NUMBER)
388706f2543Smrg				Error ("Vertical scan count expected", NULL);
389706f2543Smrg			ptr->ml_flags |= XF86CONF_VSCAN;
390706f2543Smrg			ptr->ml_vscan = val.num;
391706f2543Smrg			break;
392706f2543Smrg		case EOF_TOKEN:
393706f2543Smrg			Error (UNEXPECTED_EOF_MSG, NULL);
394706f2543Smrg			break;
395706f2543Smrg		default:
396706f2543Smrg			Error ("Unexepcted token in verbose \"Mode\" entry\n", NULL);
397706f2543Smrg		}
398706f2543Smrg	}
399706f2543Smrg	if (!had_dotclock)
400706f2543Smrg		Error ("the dotclock is missing", NULL);
401706f2543Smrg	if (!had_htimings)
402706f2543Smrg		Error ("the horizontal timings are missing", NULL);
403706f2543Smrg	if (!had_vtimings)
404706f2543Smrg		Error ("the vertical timings are missing", NULL);
405706f2543Smrg
406706f2543Smrg#ifdef DEBUG
407706f2543Smrg	printf ("Verbose Mode parsed\n");
408706f2543Smrg#endif
409706f2543Smrg	return ptr;
410706f2543Smrg}
411706f2543Smrg
412706f2543Smrg#undef CLEANUP
413706f2543Smrg
414706f2543Smrg#define CLEANUP xf86freeMonitorList
415706f2543Smrg
416706f2543SmrgXF86ConfMonitorPtr
417706f2543Smrgxf86parseMonitorSection (void)
418706f2543Smrg{
419706f2543Smrg	int has_ident = FALSE;
420706f2543Smrg	int token;
421706f2543Smrg	parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
422706f2543Smrg
423706f2543Smrg		while ((token = xf86getToken (MonitorTab)) != ENDSECTION)
424706f2543Smrg	{
425706f2543Smrg		switch (token)
426706f2543Smrg		{
427706f2543Smrg		case COMMENT:
428706f2543Smrg			ptr->mon_comment = xf86addComment(ptr->mon_comment, val.str);
429706f2543Smrg			break;
430706f2543Smrg		case IDENTIFIER:
431706f2543Smrg			if (xf86getSubToken (&(ptr->mon_comment)) != STRING)
432706f2543Smrg				Error (QUOTE_MSG, "Identifier");
433706f2543Smrg			if (has_ident == TRUE)
434706f2543Smrg				Error (MULTIPLE_MSG, "Identifier");
435706f2543Smrg			ptr->mon_identifier = val.str;
436706f2543Smrg			has_ident = TRUE;
437706f2543Smrg			break;
438706f2543Smrg		case VENDOR:
439706f2543Smrg			if (xf86getSubToken (&(ptr->mon_comment)) != STRING)
440706f2543Smrg				Error (QUOTE_MSG, "Vendor");
441706f2543Smrg			ptr->mon_vendor = val.str;
442706f2543Smrg			break;
443706f2543Smrg		case MODEL:
444706f2543Smrg			if (xf86getSubToken (&(ptr->mon_comment)) != STRING)
445706f2543Smrg				Error (QUOTE_MSG, "ModelName");
446706f2543Smrg			ptr->mon_modelname = val.str;
447706f2543Smrg			break;
448706f2543Smrg		case MODE:
449706f2543Smrg			HANDLE_LIST (mon_modeline_lst, xf86parseVerboseMode,
450706f2543Smrg						 XF86ConfModeLinePtr);
451706f2543Smrg			break;
452706f2543Smrg		case MODELINE:
453706f2543Smrg			HANDLE_LIST (mon_modeline_lst, xf86parseModeLine,
454706f2543Smrg						 XF86ConfModeLinePtr);
455706f2543Smrg			break;
456706f2543Smrg		case DISPLAYSIZE:
457706f2543Smrg			if (xf86getSubToken (&(ptr->mon_comment)) != NUMBER)
458706f2543Smrg				Error (DISPLAYSIZE_MSG, NULL);
459706f2543Smrg			ptr->mon_width = val.realnum;
460706f2543Smrg			if (xf86getSubToken (&(ptr->mon_comment)) != NUMBER)
461706f2543Smrg				Error (DISPLAYSIZE_MSG, NULL);
462706f2543Smrg			ptr->mon_height = val.realnum;
463706f2543Smrg			break;
464706f2543Smrg
465706f2543Smrg		case HORIZSYNC:
466706f2543Smrg			if (xf86getSubToken (&(ptr->mon_comment)) != NUMBER)
467706f2543Smrg				Error (HORIZSYNC_MSG, NULL);
468706f2543Smrg			do {
469706f2543Smrg				if (ptr->mon_n_hsync >= CONF_MAX_HSYNC)
470706f2543Smrg					Error ("Sorry. Too many horizontal sync intervals.", NULL);
471706f2543Smrg				ptr->mon_hsync[ptr->mon_n_hsync].lo = val.realnum;
472706f2543Smrg				switch (token = xf86getSubToken (&(ptr->mon_comment)))
473706f2543Smrg				{
474706f2543Smrg					case COMMA:
475706f2543Smrg						ptr->mon_hsync[ptr->mon_n_hsync].hi =
476706f2543Smrg						ptr->mon_hsync[ptr->mon_n_hsync].lo;
477706f2543Smrg						break;
478706f2543Smrg					case DASH:
479706f2543Smrg						if (xf86getSubToken (&(ptr->mon_comment)) != NUMBER ||
480706f2543Smrg						    (float)val.realnum < ptr->mon_hsync[ptr->mon_n_hsync].lo)
481706f2543Smrg							Error (HORIZSYNC_MSG, NULL);
482706f2543Smrg						ptr->mon_hsync[ptr->mon_n_hsync].hi = val.realnum;
483706f2543Smrg						if ((token = xf86getSubToken (&(ptr->mon_comment))) == COMMA)
484706f2543Smrg							break;
485706f2543Smrg						ptr->mon_n_hsync++;
486706f2543Smrg						goto HorizDone;
487706f2543Smrg					default:
488706f2543Smrg						/* We cannot currently know if a '\n' was found,
489706f2543Smrg						 * or this is a real error
490706f2543Smrg						 */
491706f2543Smrg						ptr->mon_hsync[ptr->mon_n_hsync].hi =
492706f2543Smrg						ptr->mon_hsync[ptr->mon_n_hsync].lo;
493706f2543Smrg						ptr->mon_n_hsync++;
494706f2543Smrg						goto HorizDone;
495706f2543Smrg				}
496706f2543Smrg				ptr->mon_n_hsync++;
497706f2543Smrg			} while ((token = xf86getSubToken (&(ptr->mon_comment))) == NUMBER);
498706f2543SmrgHorizDone:
499706f2543Smrg			xf86unGetToken (token);
500706f2543Smrg			break;
501706f2543Smrg
502706f2543Smrg		case VERTREFRESH:
503706f2543Smrg			if (xf86getSubToken (&(ptr->mon_comment)) != NUMBER)
504706f2543Smrg				Error (VERTREFRESH_MSG, NULL);
505706f2543Smrg			do {
506706f2543Smrg				ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = val.realnum;
507706f2543Smrg				switch (token = xf86getSubToken (&(ptr->mon_comment)))
508706f2543Smrg				{
509706f2543Smrg					case COMMA:
510706f2543Smrg						ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
511706f2543Smrg						ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
512706f2543Smrg						break;
513706f2543Smrg					case DASH:
514706f2543Smrg						if (xf86getSubToken (&(ptr->mon_comment)) != NUMBER ||
515706f2543Smrg						    (float)val.realnum < ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo)
516706f2543Smrg							Error (VERTREFRESH_MSG, NULL);
517706f2543Smrg						ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = val.realnum;
518706f2543Smrg						if ((token = xf86getSubToken (&(ptr->mon_comment))) == COMMA)
519706f2543Smrg							break;
520706f2543Smrg						ptr->mon_n_vrefresh++;
521706f2543Smrg						goto VertDone;
522706f2543Smrg					default:
523706f2543Smrg						/* We cannot currently know if a '\n' was found,
524706f2543Smrg						 * or this is a real error
525706f2543Smrg						 */
526706f2543Smrg						ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
527706f2543Smrg						ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
528706f2543Smrg						ptr->mon_n_vrefresh++;
529706f2543Smrg						goto VertDone;
530706f2543Smrg				}
531706f2543Smrg				if (ptr->mon_n_vrefresh >= CONF_MAX_VREFRESH)
532706f2543Smrg					Error ("Sorry. Too many vertical refresh intervals.", NULL);
533706f2543Smrg				ptr->mon_n_vrefresh++;
534706f2543Smrg			} while ((token = xf86getSubToken (&(ptr->mon_comment))) == NUMBER);
535706f2543SmrgVertDone:
536706f2543Smrg			xf86unGetToken (token);
537706f2543Smrg			break;
538706f2543Smrg
539706f2543Smrg		case GAMMA:
540706f2543Smrg			if( xf86getSubToken (&(ptr->mon_comment)) != NUMBER )
541706f2543Smrg			{
542706f2543Smrg				Error (INVALID_GAMMA_MSG, NULL);
543706f2543Smrg			}
544706f2543Smrg			else
545706f2543Smrg			{
546706f2543Smrg				ptr->mon_gamma_red = ptr->mon_gamma_green =
547706f2543Smrg					ptr->mon_gamma_blue = val.realnum;
548706f2543Smrg				if( xf86getSubToken (&(ptr->mon_comment)) == NUMBER )
549706f2543Smrg				{
550706f2543Smrg					ptr->mon_gamma_green = val.realnum;
551706f2543Smrg					if( xf86getSubToken (&(ptr->mon_comment)) == NUMBER )
552706f2543Smrg					{
553706f2543Smrg						ptr->mon_gamma_blue = val.realnum;
554706f2543Smrg					}
555706f2543Smrg					else
556706f2543Smrg					{
557706f2543Smrg						Error (INVALID_GAMMA_MSG, NULL);
558706f2543Smrg					}
559706f2543Smrg				}
560706f2543Smrg				else
561706f2543Smrg					xf86unGetToken (token);
562706f2543Smrg			}
563706f2543Smrg			break;
564706f2543Smrg		case OPTION:
565706f2543Smrg			ptr->mon_option_lst = xf86parseOption(ptr->mon_option_lst);
566706f2543Smrg			break;
567706f2543Smrg		case USEMODES:
568706f2543Smrg		        {
569706f2543Smrg				XF86ConfModesLinkPtr mptr;
570706f2543Smrg
571706f2543Smrg				if ((token = xf86getSubToken (&(ptr->mon_comment))) != STRING)
572706f2543Smrg					Error (QUOTE_MSG, "UseModes");
573706f2543Smrg
574706f2543Smrg				/* add to the end of the list of modes sections
575706f2543Smrg				   referenced here */
576706f2543Smrg				mptr = calloc (1, sizeof (XF86ConfModesLinkRec));
577706f2543Smrg				mptr->list.next = NULL;
578706f2543Smrg				mptr->ml_modes_str = val.str;
579706f2543Smrg				mptr->ml_modes = NULL;
580706f2543Smrg				ptr->mon_modes_sect_lst = (XF86ConfModesLinkPtr)
581706f2543Smrg					xf86addListItem((GenericListPtr)ptr->mon_modes_sect_lst,
582706f2543Smrg						    (GenericListPtr)mptr);
583706f2543Smrg			}
584706f2543Smrg			break;
585706f2543Smrg		case EOF_TOKEN:
586706f2543Smrg			Error (UNEXPECTED_EOF_MSG, NULL);
587706f2543Smrg			break;
588706f2543Smrg		default:
589706f2543Smrg			xf86parseError (INVALID_KEYWORD_MSG, xf86tokenString ());
590706f2543Smrg			CLEANUP (ptr);
591706f2543Smrg			return NULL;
592706f2543Smrg			break;
593706f2543Smrg		}
594706f2543Smrg	}
595706f2543Smrg
596706f2543Smrg	if (!has_ident)
597706f2543Smrg		Error (NO_IDENT_MSG, NULL);
598706f2543Smrg
599706f2543Smrg#ifdef DEBUG
600706f2543Smrg	printf ("Monitor section parsed\n");
601706f2543Smrg#endif
602706f2543Smrg	return ptr;
603706f2543Smrg}
604706f2543Smrg
605706f2543Smrg#undef CLEANUP
606706f2543Smrg#define CLEANUP xf86freeModesList
607706f2543Smrg
608706f2543SmrgXF86ConfModesPtr
609706f2543Smrgxf86parseModesSection (void)
610706f2543Smrg{
611706f2543Smrg	int has_ident = FALSE;
612706f2543Smrg	int token;
613706f2543Smrg	parsePrologue (XF86ConfModesPtr, XF86ConfModesRec)
614706f2543Smrg
615706f2543Smrg	while ((token = xf86getToken (ModesTab)) != ENDSECTION)
616706f2543Smrg	{
617706f2543Smrg		switch (token)
618706f2543Smrg		{
619706f2543Smrg		case COMMENT:
620706f2543Smrg			ptr->modes_comment = xf86addComment(ptr->modes_comment, val.str);
621706f2543Smrg			break;
622706f2543Smrg		case IDENTIFIER:
623706f2543Smrg			if (xf86getSubToken (&(ptr->modes_comment)) != STRING)
624706f2543Smrg				Error (QUOTE_MSG, "Identifier");
625706f2543Smrg			if (has_ident == TRUE)
626706f2543Smrg				Error (MULTIPLE_MSG, "Identifier");
627706f2543Smrg			ptr->modes_identifier = val.str;
628706f2543Smrg			has_ident = TRUE;
629706f2543Smrg			break;
630706f2543Smrg		case MODE:
631706f2543Smrg			HANDLE_LIST (mon_modeline_lst, xf86parseVerboseMode,
632706f2543Smrg						 XF86ConfModeLinePtr);
633706f2543Smrg			break;
634706f2543Smrg		case MODELINE:
635706f2543Smrg			HANDLE_LIST (mon_modeline_lst, xf86parseModeLine,
636706f2543Smrg						 XF86ConfModeLinePtr);
637706f2543Smrg			break;
638706f2543Smrg		default:
639706f2543Smrg			xf86parseError (INVALID_KEYWORD_MSG, xf86tokenString ());
640706f2543Smrg			CLEANUP (ptr);
641706f2543Smrg			return NULL;
642706f2543Smrg			break;
643706f2543Smrg		}
644706f2543Smrg	}
645706f2543Smrg
646706f2543Smrg	if (!has_ident)
647706f2543Smrg		Error (NO_IDENT_MSG, NULL);
648706f2543Smrg
649706f2543Smrg#ifdef DEBUG
650706f2543Smrg	printf ("Modes section parsed\n");
651706f2543Smrg#endif
652706f2543Smrg	return ptr;
653706f2543Smrg}
654706f2543Smrg
655706f2543Smrg#undef CLEANUP
656706f2543Smrg
657706f2543Smrgvoid
658706f2543Smrgxf86printMonitorSection (FILE * cf, XF86ConfMonitorPtr ptr)
659706f2543Smrg{
660706f2543Smrg	int i;
661706f2543Smrg	XF86ConfModeLinePtr mlptr;
662706f2543Smrg	XF86ConfModesLinkPtr mptr;
663706f2543Smrg
664706f2543Smrg	while (ptr)
665706f2543Smrg	{
666706f2543Smrg		mptr = ptr->mon_modes_sect_lst;
667706f2543Smrg		fprintf (cf, "Section \"Monitor\"\n");
668706f2543Smrg		if (ptr->mon_comment)
669706f2543Smrg			fprintf (cf, "%s", ptr->mon_comment);
670706f2543Smrg		if (ptr->mon_identifier)
671706f2543Smrg			fprintf (cf, "\tIdentifier   \"%s\"\n", ptr->mon_identifier);
672706f2543Smrg		if (ptr->mon_vendor)
673706f2543Smrg			fprintf (cf, "\tVendorName   \"%s\"\n", ptr->mon_vendor);
674706f2543Smrg		if (ptr->mon_modelname)
675706f2543Smrg			fprintf (cf, "\tModelName    \"%s\"\n", ptr->mon_modelname);
676706f2543Smrg		while (mptr) {
677706f2543Smrg			fprintf (cf, "\tUseModes     \"%s\"\n", mptr->ml_modes_str);
678706f2543Smrg			mptr = mptr->list.next;
679706f2543Smrg		}
680706f2543Smrg		if (ptr->mon_width)
681706f2543Smrg			fprintf (cf, "\tDisplaySize  %d\t%d\n",
682706f2543Smrg					 ptr->mon_width,
683706f2543Smrg					 ptr->mon_height);
684706f2543Smrg		for (i = 0; i < ptr->mon_n_hsync; i++)
685706f2543Smrg		{
686706f2543Smrg			fprintf (cf, "\tHorizSync    %2.1f - %2.1f\n",
687706f2543Smrg					 ptr->mon_hsync[i].lo,
688706f2543Smrg					 ptr->mon_hsync[i].hi);
689706f2543Smrg		}
690706f2543Smrg		for (i = 0; i < ptr->mon_n_vrefresh; i++)
691706f2543Smrg		{
692706f2543Smrg			fprintf (cf, "\tVertRefresh  %2.1f - %2.1f\n",
693706f2543Smrg					 ptr->mon_vrefresh[i].lo,
694706f2543Smrg					 ptr->mon_vrefresh[i].hi);
695706f2543Smrg		}
696706f2543Smrg		if (ptr->mon_gamma_red) {
697706f2543Smrg			if (ptr->mon_gamma_red == ptr->mon_gamma_green
698706f2543Smrg				&& ptr->mon_gamma_red == ptr->mon_gamma_blue)
699706f2543Smrg			{
700706f2543Smrg				fprintf (cf, "\tGamma        %.4g\n",
701706f2543Smrg					ptr->mon_gamma_red);
702706f2543Smrg			} else {
703706f2543Smrg				fprintf (cf, "\tGamma        %.4g %.4g %.4g\n",
704706f2543Smrg					ptr->mon_gamma_red,
705706f2543Smrg					ptr->mon_gamma_green,
706706f2543Smrg					ptr->mon_gamma_blue);
707706f2543Smrg			}
708706f2543Smrg		}
709706f2543Smrg		for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next)
710706f2543Smrg		{
711706f2543Smrg			fprintf (cf, "\tModeLine     \"%s\" %2.1f ",
712706f2543Smrg					 mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
713706f2543Smrg			fprintf (cf, "%d %d %d %d %d %d %d %d",
714706f2543Smrg					 mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
715706f2543Smrg					 mlptr->ml_hsyncend, mlptr->ml_htotal,
716706f2543Smrg					 mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
717706f2543Smrg					 mlptr->ml_vsyncend, mlptr->ml_vtotal);
718706f2543Smrg			if (mlptr->ml_flags & XF86CONF_PHSYNC)
719706f2543Smrg				fprintf (cf, " +hsync");
720706f2543Smrg			if (mlptr->ml_flags & XF86CONF_NHSYNC)
721706f2543Smrg				fprintf (cf, " -hsync");
722706f2543Smrg			if (mlptr->ml_flags & XF86CONF_PVSYNC)
723706f2543Smrg				fprintf (cf, " +vsync");
724706f2543Smrg			if (mlptr->ml_flags & XF86CONF_NVSYNC)
725706f2543Smrg				fprintf (cf, " -vsync");
726706f2543Smrg			if (mlptr->ml_flags & XF86CONF_INTERLACE)
727706f2543Smrg				fprintf (cf, " interlace");
728706f2543Smrg			if (mlptr->ml_flags & XF86CONF_CSYNC)
729706f2543Smrg				fprintf (cf, " composite");
730706f2543Smrg			if (mlptr->ml_flags & XF86CONF_PCSYNC)
731706f2543Smrg				fprintf (cf, " +csync");
732706f2543Smrg			if (mlptr->ml_flags & XF86CONF_NCSYNC)
733706f2543Smrg				fprintf (cf, " -csync");
734706f2543Smrg			if (mlptr->ml_flags & XF86CONF_DBLSCAN)
735706f2543Smrg				fprintf (cf, " doublescan");
736706f2543Smrg			if (mlptr->ml_flags & XF86CONF_HSKEW)
737706f2543Smrg				fprintf (cf, " hskew %d", mlptr->ml_hskew);
738706f2543Smrg			if (mlptr->ml_flags & XF86CONF_BCAST)
739706f2543Smrg				fprintf (cf, " bcast");
740706f2543Smrg			fprintf (cf, "\n");
741706f2543Smrg		}
742706f2543Smrg		xf86printOptionList(cf, ptr->mon_option_lst, 1);
743706f2543Smrg		fprintf (cf, "EndSection\n\n");
744706f2543Smrg		ptr = ptr->list.next;
745706f2543Smrg	}
746706f2543Smrg}
747706f2543Smrg
748706f2543Smrgvoid
749706f2543Smrgxf86printModesSection (FILE * cf, XF86ConfModesPtr ptr)
750706f2543Smrg{
751706f2543Smrg	XF86ConfModeLinePtr mlptr;
752706f2543Smrg
753706f2543Smrg	while (ptr)
754706f2543Smrg	{
755706f2543Smrg		fprintf (cf, "Section \"Modes\"\n");
756706f2543Smrg		if (ptr->modes_comment)
757706f2543Smrg			fprintf (cf, "%s", ptr->modes_comment);
758706f2543Smrg		if (ptr->modes_identifier)
759706f2543Smrg			fprintf (cf, "\tIdentifier     \"%s\"\n", ptr->modes_identifier);
760706f2543Smrg		for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next)
761706f2543Smrg		{
762706f2543Smrg			fprintf (cf, "\tModeLine     \"%s\" %2.1f ",
763706f2543Smrg					 mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
764706f2543Smrg			fprintf (cf, "%d %d %d %d %d %d %d %d",
765706f2543Smrg					 mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
766706f2543Smrg					 mlptr->ml_hsyncend, mlptr->ml_htotal,
767706f2543Smrg					 mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
768706f2543Smrg					 mlptr->ml_vsyncend, mlptr->ml_vtotal);
769706f2543Smrg			if (mlptr->ml_flags & XF86CONF_PHSYNC)
770706f2543Smrg				fprintf (cf, " +hsync");
771706f2543Smrg			if (mlptr->ml_flags & XF86CONF_NHSYNC)
772706f2543Smrg				fprintf (cf, " -hsync");
773706f2543Smrg			if (mlptr->ml_flags & XF86CONF_PVSYNC)
774706f2543Smrg				fprintf (cf, " +vsync");
775706f2543Smrg			if (mlptr->ml_flags & XF86CONF_NVSYNC)
776706f2543Smrg				fprintf (cf, " -vsync");
777706f2543Smrg			if (mlptr->ml_flags & XF86CONF_INTERLACE)
778706f2543Smrg				fprintf (cf, " interlace");
779706f2543Smrg			if (mlptr->ml_flags & XF86CONF_CSYNC)
780706f2543Smrg				fprintf (cf, " composite");
781706f2543Smrg			if (mlptr->ml_flags & XF86CONF_PCSYNC)
782706f2543Smrg				fprintf (cf, " +csync");
783706f2543Smrg			if (mlptr->ml_flags & XF86CONF_NCSYNC)
784706f2543Smrg				fprintf (cf, " -csync");
785706f2543Smrg			if (mlptr->ml_flags & XF86CONF_DBLSCAN)
786706f2543Smrg				fprintf (cf, " doublescan");
787706f2543Smrg			if (mlptr->ml_flags & XF86CONF_HSKEW)
788706f2543Smrg				fprintf (cf, " hskew %d", mlptr->ml_hskew);
789706f2543Smrg			if (mlptr->ml_flags & XF86CONF_VSCAN)
790706f2543Smrg				fprintf (cf, " vscan %d", mlptr->ml_vscan);
791706f2543Smrg			if (mlptr->ml_flags & XF86CONF_BCAST)
792706f2543Smrg				fprintf (cf, " bcast");
793706f2543Smrg			if (mlptr->ml_comment)
794706f2543Smrg				fprintf (cf, "%s", mlptr->ml_comment);
795706f2543Smrg			else
796706f2543Smrg				fprintf (cf, "\n");
797706f2543Smrg		}
798706f2543Smrg		fprintf (cf, "EndSection\n\n");
799706f2543Smrg		ptr = ptr->list.next;
800706f2543Smrg	}
801706f2543Smrg}
802706f2543Smrg
803706f2543Smrgvoid
804706f2543Smrgxf86freeMonitorList (XF86ConfMonitorPtr ptr)
805706f2543Smrg{
806706f2543Smrg	XF86ConfMonitorPtr prev;
807706f2543Smrg
808706f2543Smrg	while (ptr)
809706f2543Smrg	{
810706f2543Smrg		TestFree (ptr->mon_identifier);
811706f2543Smrg		TestFree (ptr->mon_vendor);
812706f2543Smrg		TestFree (ptr->mon_modelname);
813706f2543Smrg		TestFree (ptr->mon_comment);
814706f2543Smrg		xf86optionListFree (ptr->mon_option_lst);
815706f2543Smrg		xf86freeModeLineList (ptr->mon_modeline_lst);
816706f2543Smrg		prev = ptr;
817706f2543Smrg		ptr = ptr->list.next;
818706f2543Smrg		free (prev);
819706f2543Smrg	}
820706f2543Smrg}
821706f2543Smrg
822706f2543Smrgvoid
823706f2543Smrgxf86freeModesList (XF86ConfModesPtr ptr)
824706f2543Smrg{
825706f2543Smrg	XF86ConfModesPtr prev;
826706f2543Smrg
827706f2543Smrg	while (ptr)
828706f2543Smrg	{
829706f2543Smrg		TestFree (ptr->modes_identifier);
830706f2543Smrg		TestFree (ptr->modes_comment);
831706f2543Smrg		xf86freeModeLineList (ptr->mon_modeline_lst);
832706f2543Smrg		prev = ptr;
833706f2543Smrg		ptr = ptr->list.next;
834706f2543Smrg		free (prev);
835706f2543Smrg	}
836706f2543Smrg}
837706f2543Smrg
838706f2543SmrgXF86ConfMonitorPtr
839706f2543Smrgxf86findMonitor (const char *ident, XF86ConfMonitorPtr p)
840706f2543Smrg{
841706f2543Smrg	while (p)
842706f2543Smrg	{
843706f2543Smrg		if (xf86nameCompare (ident, p->mon_identifier) == 0)
844706f2543Smrg			return p;
845706f2543Smrg
846706f2543Smrg		p = p->list.next;
847706f2543Smrg	}
848706f2543Smrg	return NULL;
849706f2543Smrg}
850706f2543Smrg
851706f2543SmrgXF86ConfModesPtr
852706f2543Smrgxf86findModes (const char *ident, XF86ConfModesPtr p)
853706f2543Smrg{
854706f2543Smrg	while (p)
855706f2543Smrg	{
856706f2543Smrg		if (xf86nameCompare (ident, p->modes_identifier) == 0)
857706f2543Smrg			return p;
858706f2543Smrg
859706f2543Smrg		p = p->list.next;
860706f2543Smrg	}
861706f2543Smrg	return NULL;
862706f2543Smrg}
863706f2543Smrg
864706f2543SmrgXF86ConfModeLinePtr
865706f2543Smrgxf86findModeLine (const char *ident, XF86ConfModeLinePtr p)
866706f2543Smrg{
867706f2543Smrg	while (p)
868706f2543Smrg	{
869706f2543Smrg		if (xf86nameCompare (ident, p->ml_identifier) == 0)
870706f2543Smrg			return p;
871706f2543Smrg
872706f2543Smrg		p = p->list.next;
873706f2543Smrg	}
874706f2543Smrg	return NULL;
875706f2543Smrg}
876706f2543Smrg
877706f2543Smrgint
878706f2543Smrgxf86validateMonitor (XF86ConfigPtr p, XF86ConfScreenPtr screen)
879706f2543Smrg{
880706f2543Smrg	XF86ConfMonitorPtr monitor = screen->scrn_monitor;
881706f2543Smrg	XF86ConfModesLinkPtr modeslnk = monitor->mon_modes_sect_lst;
882706f2543Smrg	XF86ConfModesPtr modes;
883706f2543Smrg	while(modeslnk)
884706f2543Smrg	{
885706f2543Smrg		modes = xf86findModes (modeslnk->ml_modes_str, p->conf_modes_lst);
886706f2543Smrg		if (!modes)
887706f2543Smrg		{
888706f2543Smrg			xf86validationError (UNDEFINED_MODES_MSG,
889706f2543Smrg					     modeslnk->ml_modes_str,
890706f2543Smrg					     screen->scrn_identifier);
891706f2543Smrg			return FALSE;
892706f2543Smrg		}
893706f2543Smrg		modeslnk->ml_modes = modes;
894706f2543Smrg		modeslnk = modeslnk->list.next;
895706f2543Smrg	}
896706f2543Smrg	return TRUE;
897706f2543Smrg}
898