Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / parser / Monitor.c
CommitLineData
a09e091a
JB
1/*
2 *
3 * Copyright (c) 1997 Metro Link Incorporated
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Except as contained in this notice, the name of the Metro Link shall not be
24 * used in advertising or otherwise to promote the sale, use or other dealings
25 * in this Software without prior written authorization from Metro Link.
26 *
27 */
28/*
29 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
30 *
31 * Permission is hereby granted, free of charge, to any person obtaining a
32 * copy of this software and associated documentation files (the "Software"),
33 * to deal in the Software without restriction, including without limitation
34 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35 * and/or sell copies of the Software, and to permit persons to whom the
36 * Software is furnished to do so, subject to the following conditions:
37 *
38 * The above copyright notice and this permission notice shall be included in
39 * all copies or substantial portions of the Software.
40 *
41 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
44 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
45 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47 * OTHER DEALINGS IN THE SOFTWARE.
48 *
49 * Except as contained in this notice, the name of the copyright holder(s)
50 * and author(s) shall not be used in advertising or otherwise to promote
51 * the sale, use or other dealings in this Software without prior written
52 * authorization from the copyright holder(s) and author(s).
53 */
54
55#ifdef HAVE_XORG_CONFIG_H
56#include <xorg-config.h>
57#endif
58
59#include "xf86Parser.h"
60#include "xf86tokens.h"
61#include "Configint.h"
62
63extern LexRec val;
64
65static xf86ConfigSymTabRec MonitorTab[] = {
66 {ENDSECTION, "endsection"},
67 {IDENTIFIER, "identifier"},
68 {VENDOR, "vendorname"},
69 {MODEL, "modelname"},
70 {USEMODES, "usemodes"},
71 {MODELINE, "modeline"},
72 {DISPLAYSIZE, "displaysize"},
73 {HORIZSYNC, "horizsync"},
74 {VERTREFRESH, "vertrefresh"},
75 {MODE, "mode"},
76 {GAMMA, "gamma"},
77 {OPTION, "option"},
78 {-1, ""},
79};
80
81static xf86ConfigSymTabRec ModesTab[] = {
82 {ENDSECTION, "endsection"},
83 {IDENTIFIER, "identifier"},
84 {MODELINE, "modeline"},
85 {MODE, "mode"},
86 {-1, ""},
87};
88
89static xf86ConfigSymTabRec TimingTab[] = {
90 {TT_INTERLACE, "interlace"},
91 {TT_PHSYNC, "+hsync"},
92 {TT_NHSYNC, "-hsync"},
93 {TT_PVSYNC, "+vsync"},
94 {TT_NVSYNC, "-vsync"},
95 {TT_CSYNC, "composite"},
96 {TT_PCSYNC, "+csync"},
97 {TT_NCSYNC, "-csync"},
98 {TT_DBLSCAN, "doublescan"},
99 {TT_HSKEW, "hskew"},
100 {TT_BCAST, "bcast"},
101 {TT_VSCAN, "vscan"},
102 {-1, ""},
103};
104
105static xf86ConfigSymTabRec ModeTab[] = {
106 {DOTCLOCK, "dotclock"},
107 {HTIMINGS, "htimings"},
108 {VTIMINGS, "vtimings"},
109 {FLAGS, "flags"},
110 {HSKEW, "hskew"},
111 {BCAST, "bcast"},
112 {VSCAN, "vscan"},
113 {ENDMODE, "endmode"},
114 {-1, ""},
115};
116
117#define CLEANUP xf86freeModeLineList
118
119static void
120xf86freeModeLineList(XF86ConfModeLinePtr ptr)
121{
122 XF86ConfModeLinePtr prev;
123
124 while (ptr) {
125 TestFree(ptr->ml_identifier);
126 TestFree(ptr->ml_comment);
127 prev = ptr;
128 ptr = ptr->list.next;
129 free(prev);
130 }
131}
132
133static XF86ConfModeLinePtr
134xf86parseModeLine(void)
135{
136 int token;
137
138 parsePrologue(XF86ConfModeLinePtr, XF86ConfModeLineRec)
139
140 /* Identifier */
141 if (xf86getSubToken(&(ptr->ml_comment)) != STRING)
142 Error("ModeLine identifier expected");
143 ptr->ml_identifier = val.str;
144
145 /* DotClock */
146 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
147 Error("ModeLine dotclock expected");
148 ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5);
149
150 /* HDisplay */
151 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
152 Error("ModeLine Hdisplay expected");
153 ptr->ml_hdisplay = val.num;
154
155 /* HSyncStart */
156 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
157 Error("ModeLine HSyncStart expected");
158 ptr->ml_hsyncstart = val.num;
159
160 /* HSyncEnd */
161 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
162 Error("ModeLine HSyncEnd expected");
163 ptr->ml_hsyncend = val.num;
164
165 /* HTotal */
166 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
167 Error("ModeLine HTotal expected");
168 ptr->ml_htotal = val.num;
169
170 /* VDisplay */
171 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
172 Error("ModeLine Vdisplay expected");
173 ptr->ml_vdisplay = val.num;
174
175 /* VSyncStart */
176 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
177 Error("ModeLine VSyncStart expected");
178 ptr->ml_vsyncstart = val.num;
179
180 /* VSyncEnd */
181 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
182 Error("ModeLine VSyncEnd expected");
183 ptr->ml_vsyncend = val.num;
184
185 /* VTotal */
186 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
187 Error("ModeLine VTotal expected");
188 ptr->ml_vtotal = val.num;
189
190 token = xf86getSubTokenWithTab(&(ptr->ml_comment), TimingTab);
191 while ((token == TT_INTERLACE) || (token == TT_PHSYNC) ||
192 (token == TT_NHSYNC) || (token == TT_PVSYNC) ||
193 (token == TT_NVSYNC) || (token == TT_CSYNC) ||
194 (token == TT_PCSYNC) || (token == TT_NCSYNC) ||
195 (token == TT_DBLSCAN) || (token == TT_HSKEW) ||
196 (token == TT_VSCAN) || (token == TT_BCAST)) {
197 switch (token) {
198
199 case TT_INTERLACE:
200 ptr->ml_flags |= XF86CONF_INTERLACE;
201 break;
202 case TT_PHSYNC:
203 ptr->ml_flags |= XF86CONF_PHSYNC;
204 break;
205 case TT_NHSYNC:
206 ptr->ml_flags |= XF86CONF_NHSYNC;
207 break;
208 case TT_PVSYNC:
209 ptr->ml_flags |= XF86CONF_PVSYNC;
210 break;
211 case TT_NVSYNC:
212 ptr->ml_flags |= XF86CONF_NVSYNC;
213 break;
214 case TT_CSYNC:
215 ptr->ml_flags |= XF86CONF_CSYNC;
216 break;
217 case TT_PCSYNC:
218 ptr->ml_flags |= XF86CONF_PCSYNC;
219 break;
220 case TT_NCSYNC:
221 ptr->ml_flags |= XF86CONF_NCSYNC;
222 break;
223 case TT_DBLSCAN:
224 ptr->ml_flags |= XF86CONF_DBLSCAN;
225 break;
226 case TT_HSKEW:
227 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
228 Error(NUMBER_MSG, "Hskew");
229 ptr->ml_hskew = val.num;
230 ptr->ml_flags |= XF86CONF_HSKEW;
231 break;
232 case TT_BCAST:
233 ptr->ml_flags |= XF86CONF_BCAST;
234 break;
235 case TT_VSCAN:
236 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
237 Error(NUMBER_MSG, "Vscan");
238 ptr->ml_vscan = val.num;
239 ptr->ml_flags |= XF86CONF_VSCAN;
240 break;
241 case EOF_TOKEN:
242 Error(UNEXPECTED_EOF_MSG);
243 break;
244 default:
245 Error(INVALID_KEYWORD_MSG, xf86tokenString());
246 break;
247 }
248 token = xf86getSubTokenWithTab(&(ptr->ml_comment), TimingTab);
249 }
250 xf86unGetToken(token);
251
252#ifdef DEBUG
253 printf("ModeLine parsed\n");
254#endif
255 return ptr;
256}
257
258static XF86ConfModeLinePtr
259xf86parseVerboseMode(void)
260{
261 int token, token2;
262 int had_dotclock = 0, had_htimings = 0, had_vtimings = 0;
263
264 parsePrologue(XF86ConfModeLinePtr, XF86ConfModeLineRec)
265
266 if (xf86getSubToken(&(ptr->ml_comment)) != STRING)
267 Error("Mode name expected");
268 ptr->ml_identifier = val.str;
269 while ((token = xf86getToken(ModeTab)) != ENDMODE) {
270 switch (token) {
271 case COMMENT:
272 ptr->ml_comment = xf86addComment(ptr->ml_comment, val.str);
273 break;
274 case DOTCLOCK:
275 if ((token = xf86getSubToken(&(ptr->ml_comment))) != NUMBER)
276 Error(NUMBER_MSG, "DotClock");
277 ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5);
278 had_dotclock = 1;
279 break;
280 case HTIMINGS:
281 if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
282 ptr->ml_hdisplay = val.num;
283 else
284 Error("Horizontal display expected");
285
286 if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
287 ptr->ml_hsyncstart = val.num;
288 else
289 Error("Horizontal sync start expected");
290
291 if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
292 ptr->ml_hsyncend = val.num;
293 else
294 Error("Horizontal sync end expected");
295
296 if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
297 ptr->ml_htotal = val.num;
298 else
299 Error("Horizontal total expected");
300 had_htimings = 1;
301 break;
302 case VTIMINGS:
303 if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
304 ptr->ml_vdisplay = val.num;
305 else
306 Error("Vertical display expected");
307
308 if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
309 ptr->ml_vsyncstart = val.num;
310 else
311 Error("Vertical sync start expected");
312
313 if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
314 ptr->ml_vsyncend = val.num;
315 else
316 Error("Vertical sync end expected");
317
318 if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
319 ptr->ml_vtotal = val.num;
320 else
321 Error("Vertical total expected");
322 had_vtimings = 1;
323 break;
324 case FLAGS:
325 token = xf86getSubToken(&(ptr->ml_comment));
326 if (token != STRING)
327 Error(QUOTE_MSG, "Flags");
328 while (token == STRING) {
329 token2 = xf86getStringToken(TimingTab);
330 switch (token2) {
331 case TT_INTERLACE:
332 ptr->ml_flags |= XF86CONF_INTERLACE;
333 break;
334 case TT_PHSYNC:
335 ptr->ml_flags |= XF86CONF_PHSYNC;
336 break;
337 case TT_NHSYNC:
338 ptr->ml_flags |= XF86CONF_NHSYNC;
339 break;
340 case TT_PVSYNC:
341 ptr->ml_flags |= XF86CONF_PVSYNC;
342 break;
343 case TT_NVSYNC:
344 ptr->ml_flags |= XF86CONF_NVSYNC;
345 break;
346 case TT_CSYNC:
347 ptr->ml_flags |= XF86CONF_CSYNC;
348 break;
349 case TT_PCSYNC:
350 ptr->ml_flags |= XF86CONF_PCSYNC;
351 break;
352 case TT_NCSYNC:
353 ptr->ml_flags |= XF86CONF_NCSYNC;
354 break;
355 case TT_DBLSCAN:
356 ptr->ml_flags |= XF86CONF_DBLSCAN;
357 break;
358 case EOF_TOKEN:
359 Error(UNEXPECTED_EOF_MSG);
360 break;
361 default:
362 Error("Unknown flag string");
363 break;
364 }
365 token = xf86getSubToken(&(ptr->ml_comment));
366 }
367 xf86unGetToken(token);
368 break;
369 case HSKEW:
370 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
371 Error("Horizontal skew expected");
372 ptr->ml_flags |= XF86CONF_HSKEW;
373 ptr->ml_hskew = val.num;
374 break;
375 case VSCAN:
376 if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
377 Error("Vertical scan count expected");
378 ptr->ml_flags |= XF86CONF_VSCAN;
379 ptr->ml_vscan = val.num;
380 break;
381 case EOF_TOKEN:
382 Error(UNEXPECTED_EOF_MSG);
383 break;
384 default:
385 Error("Unexepcted token in verbose \"Mode\" entry\n");
386 }
387 }
388 if (!had_dotclock)
389 Error("the dotclock is missing");
390 if (!had_htimings)
391 Error("the horizontal timings are missing");
392 if (!had_vtimings)
393 Error("the vertical timings are missing");
394
395#ifdef DEBUG
396 printf("Verbose Mode parsed\n");
397#endif
398 return ptr;
399}
400
401#undef CLEANUP
402
403#define CLEANUP xf86freeMonitorList
404
405XF86ConfMonitorPtr
406xf86parseMonitorSection(void)
407{
408 int has_ident = FALSE;
409 int token;
410
411 parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec)
412
413 while ((token = xf86getToken(MonitorTab)) != ENDSECTION) {
414 switch (token) {
415 case COMMENT:
416 ptr->mon_comment = xf86addComment(ptr->mon_comment, val.str);
417 break;
418 case IDENTIFIER:
419 if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
420 Error(QUOTE_MSG, "Identifier");
421 if (has_ident == TRUE)
422 Error(MULTIPLE_MSG, "Identifier");
423 ptr->mon_identifier = val.str;
424 has_ident = TRUE;
425 break;
426 case VENDOR:
427 if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
428 Error(QUOTE_MSG, "Vendor");
429 ptr->mon_vendor = val.str;
430 break;
431 case MODEL:
432 if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
433 Error(QUOTE_MSG, "ModelName");
434 ptr->mon_modelname = val.str;
435 break;
436 case MODE:
437 HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode,
438 XF86ConfModeLinePtr);
439 break;
440 case MODELINE:
441 HANDLE_LIST(mon_modeline_lst, xf86parseModeLine,
442 XF86ConfModeLinePtr);
443 break;
444 case DISPLAYSIZE:
445 if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
446 Error(DISPLAYSIZE_MSG);
447 ptr->mon_width = val.realnum;
448 if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
449 Error(DISPLAYSIZE_MSG);
450 ptr->mon_height = val.realnum;
451 break;
452
453 case HORIZSYNC:
454 if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
455 Error(HORIZSYNC_MSG);
456 do {
457 if (ptr->mon_n_hsync >= CONF_MAX_HSYNC)
458 Error("Sorry. Too many horizontal sync intervals.");
459 ptr->mon_hsync[ptr->mon_n_hsync].lo = val.realnum;
460 switch (token = xf86getSubToken(&(ptr->mon_comment))) {
461 case COMMA:
462 ptr->mon_hsync[ptr->mon_n_hsync].hi =
463 ptr->mon_hsync[ptr->mon_n_hsync].lo;
464 break;
465 case DASH:
466 if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER ||
467 (float) val.realnum <
468 ptr->mon_hsync[ptr->mon_n_hsync].lo)
469 Error(HORIZSYNC_MSG);
470 ptr->mon_hsync[ptr->mon_n_hsync].hi = val.realnum;
471 if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA)
472 break;
473 ptr->mon_n_hsync++;
474 goto HorizDone;
475 default:
476 /* We cannot currently know if a '\n' was found,
477 * or this is a real error
478 */
479 ptr->mon_hsync[ptr->mon_n_hsync].hi =
480 ptr->mon_hsync[ptr->mon_n_hsync].lo;
481 ptr->mon_n_hsync++;
482 goto HorizDone;
483 }
484 ptr->mon_n_hsync++;
485 } while ((token = xf86getSubToken(&(ptr->mon_comment))) == NUMBER);
486 HorizDone:
487 xf86unGetToken(token);
488 break;
489
490 case VERTREFRESH:
491 if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
492 Error(VERTREFRESH_MSG);
493 do {
494 ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = val.realnum;
495 switch (token = xf86getSubToken(&(ptr->mon_comment))) {
496 case COMMA:
497 ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
498 ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
499 break;
500 case DASH:
501 if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER ||
502 (float) val.realnum <
503 ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo)
504 Error(VERTREFRESH_MSG);
505 ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = val.realnum;
506 if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA)
507 break;
508 ptr->mon_n_vrefresh++;
509 goto VertDone;
510 default:
511 /* We cannot currently know if a '\n' was found,
512 * or this is a real error
513 */
514 ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
515 ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
516 ptr->mon_n_vrefresh++;
517 goto VertDone;
518 }
519 if (ptr->mon_n_vrefresh >= CONF_MAX_VREFRESH)
520 Error("Sorry. Too many vertical refresh intervals.");
521 ptr->mon_n_vrefresh++;
522 } while ((token = xf86getSubToken(&(ptr->mon_comment))) == NUMBER);
523 VertDone:
524 xf86unGetToken(token);
525 break;
526
527 case GAMMA:
528 if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER) {
529 Error(INVALID_GAMMA_MSG);
530 }
531 else {
532 ptr->mon_gamma_red = ptr->mon_gamma_green =
533 ptr->mon_gamma_blue = val.realnum;
534 if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) {
535 ptr->mon_gamma_green = val.realnum;
536 if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) {
537 ptr->mon_gamma_blue = val.realnum;
538 }
539 else {
540 Error(INVALID_GAMMA_MSG);
541 }
542 }
543 else
544 xf86unGetToken(token);
545 }
546 break;
547 case OPTION:
548 ptr->mon_option_lst = xf86parseOption(ptr->mon_option_lst);
549 break;
550 case USEMODES:
551 {
552 XF86ConfModesLinkPtr mptr;
553
554 if ((token = xf86getSubToken(&(ptr->mon_comment))) != STRING)
555 Error(QUOTE_MSG, "UseModes");
556
557 /* add to the end of the list of modes sections
558 referenced here */
559 mptr = calloc(1, sizeof(XF86ConfModesLinkRec));
560 mptr->list.next = NULL;
561 mptr->ml_modes_str = val.str;
562 mptr->ml_modes = NULL;
563 ptr->mon_modes_sect_lst = (XF86ConfModesLinkPtr)
564 xf86addListItem((GenericListPtr) ptr->mon_modes_sect_lst,
565 (GenericListPtr) mptr);
566 }
567 break;
568 case EOF_TOKEN:
569 Error(UNEXPECTED_EOF_MSG);
570 break;
571 default:
572 xf86parseError(INVALID_KEYWORD_MSG, xf86tokenString());
573 CLEANUP(ptr);
574 return NULL;
575 break;
576 }
577 }
578
579 if (!has_ident)
580 Error(NO_IDENT_MSG);
581
582#ifdef DEBUG
583 printf("Monitor section parsed\n");
584#endif
585 return ptr;
586}
587
588#undef CLEANUP
589#define CLEANUP xf86freeModesList
590
591XF86ConfModesPtr
592xf86parseModesSection(void)
593{
594 int has_ident = FALSE;
595 int token;
596
597 parsePrologue(XF86ConfModesPtr, XF86ConfModesRec)
598
599 while ((token = xf86getToken(ModesTab)) != ENDSECTION) {
600 switch (token) {
601 case COMMENT:
602 ptr->modes_comment = xf86addComment(ptr->modes_comment, val.str);
603 break;
604 case IDENTIFIER:
605 if (xf86getSubToken(&(ptr->modes_comment)) != STRING)
606 Error(QUOTE_MSG, "Identifier");
607 if (has_ident == TRUE)
608 Error(MULTIPLE_MSG, "Identifier");
609 ptr->modes_identifier = val.str;
610 has_ident = TRUE;
611 break;
612 case MODE:
613 HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode,
614 XF86ConfModeLinePtr);
615 break;
616 case MODELINE:
617 HANDLE_LIST(mon_modeline_lst, xf86parseModeLine,
618 XF86ConfModeLinePtr);
619 break;
620 default:
621 xf86parseError(INVALID_KEYWORD_MSG, xf86tokenString());
622 CLEANUP(ptr);
623 return NULL;
624 break;
625 }
626 }
627
628 if (!has_ident)
629 Error(NO_IDENT_MSG);
630
631#ifdef DEBUG
632 printf("Modes section parsed\n");
633#endif
634 return ptr;
635}
636
637#undef CLEANUP
638
639void
640xf86printMonitorSection(FILE * cf, XF86ConfMonitorPtr ptr)
641{
642 int i;
643 XF86ConfModeLinePtr mlptr;
644 XF86ConfModesLinkPtr mptr;
645
646 while (ptr) {
647 mptr = ptr->mon_modes_sect_lst;
648 fprintf(cf, "Section \"Monitor\"\n");
649 if (ptr->mon_comment)
650 fprintf(cf, "%s", ptr->mon_comment);
651 if (ptr->mon_identifier)
652 fprintf(cf, "\tIdentifier \"%s\"\n", ptr->mon_identifier);
653 if (ptr->mon_vendor)
654 fprintf(cf, "\tVendorName \"%s\"\n", ptr->mon_vendor);
655 if (ptr->mon_modelname)
656 fprintf(cf, "\tModelName \"%s\"\n", ptr->mon_modelname);
657 while (mptr) {
658 fprintf(cf, "\tUseModes \"%s\"\n", mptr->ml_modes_str);
659 mptr = mptr->list.next;
660 }
661 if (ptr->mon_width)
662 fprintf(cf, "\tDisplaySize %d\t%d\n",
663 ptr->mon_width, ptr->mon_height);
664 for (i = 0; i < ptr->mon_n_hsync; i++) {
665 fprintf(cf, "\tHorizSync %2.1f - %2.1f\n",
666 ptr->mon_hsync[i].lo, ptr->mon_hsync[i].hi);
667 }
668 for (i = 0; i < ptr->mon_n_vrefresh; i++) {
669 fprintf(cf, "\tVertRefresh %2.1f - %2.1f\n",
670 ptr->mon_vrefresh[i].lo, ptr->mon_vrefresh[i].hi);
671 }
672 if (ptr->mon_gamma_red) {
673 if (ptr->mon_gamma_red == ptr->mon_gamma_green
674 && ptr->mon_gamma_red == ptr->mon_gamma_blue) {
675 fprintf(cf, "\tGamma %.4g\n", ptr->mon_gamma_red);
676 }
677 else {
678 fprintf(cf, "\tGamma %.4g %.4g %.4g\n",
679 ptr->mon_gamma_red,
680 ptr->mon_gamma_green, ptr->mon_gamma_blue);
681 }
682 }
683 for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next) {
684 fprintf(cf, "\tModeLine \"%s\" %2.1f ",
685 mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
686 fprintf(cf, "%d %d %d %d %d %d %d %d",
687 mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
688 mlptr->ml_hsyncend, mlptr->ml_htotal,
689 mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
690 mlptr->ml_vsyncend, mlptr->ml_vtotal);
691 if (mlptr->ml_flags & XF86CONF_PHSYNC)
692 fprintf(cf, " +hsync");
693 if (mlptr->ml_flags & XF86CONF_NHSYNC)
694 fprintf(cf, " -hsync");
695 if (mlptr->ml_flags & XF86CONF_PVSYNC)
696 fprintf(cf, " +vsync");
697 if (mlptr->ml_flags & XF86CONF_NVSYNC)
698 fprintf(cf, " -vsync");
699 if (mlptr->ml_flags & XF86CONF_INTERLACE)
700 fprintf(cf, " interlace");
701 if (mlptr->ml_flags & XF86CONF_CSYNC)
702 fprintf(cf, " composite");
703 if (mlptr->ml_flags & XF86CONF_PCSYNC)
704 fprintf(cf, " +csync");
705 if (mlptr->ml_flags & XF86CONF_NCSYNC)
706 fprintf(cf, " -csync");
707 if (mlptr->ml_flags & XF86CONF_DBLSCAN)
708 fprintf(cf, " doublescan");
709 if (mlptr->ml_flags & XF86CONF_HSKEW)
710 fprintf(cf, " hskew %d", mlptr->ml_hskew);
711 if (mlptr->ml_flags & XF86CONF_BCAST)
712 fprintf(cf, " bcast");
713 fprintf(cf, "\n");
714 }
715 xf86printOptionList(cf, ptr->mon_option_lst, 1);
716 fprintf(cf, "EndSection\n\n");
717 ptr = ptr->list.next;
718 }
719}
720
721void
722xf86printModesSection(FILE * cf, XF86ConfModesPtr ptr)
723{
724 XF86ConfModeLinePtr mlptr;
725
726 while (ptr) {
727 fprintf(cf, "Section \"Modes\"\n");
728 if (ptr->modes_comment)
729 fprintf(cf, "%s", ptr->modes_comment);
730 if (ptr->modes_identifier)
731 fprintf(cf, "\tIdentifier \"%s\"\n", ptr->modes_identifier);
732 for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next) {
733 fprintf(cf, "\tModeLine \"%s\" %2.1f ",
734 mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
735 fprintf(cf, "%d %d %d %d %d %d %d %d",
736 mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
737 mlptr->ml_hsyncend, mlptr->ml_htotal,
738 mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
739 mlptr->ml_vsyncend, mlptr->ml_vtotal);
740 if (mlptr->ml_flags & XF86CONF_PHSYNC)
741 fprintf(cf, " +hsync");
742 if (mlptr->ml_flags & XF86CONF_NHSYNC)
743 fprintf(cf, " -hsync");
744 if (mlptr->ml_flags & XF86CONF_PVSYNC)
745 fprintf(cf, " +vsync");
746 if (mlptr->ml_flags & XF86CONF_NVSYNC)
747 fprintf(cf, " -vsync");
748 if (mlptr->ml_flags & XF86CONF_INTERLACE)
749 fprintf(cf, " interlace");
750 if (mlptr->ml_flags & XF86CONF_CSYNC)
751 fprintf(cf, " composite");
752 if (mlptr->ml_flags & XF86CONF_PCSYNC)
753 fprintf(cf, " +csync");
754 if (mlptr->ml_flags & XF86CONF_NCSYNC)
755 fprintf(cf, " -csync");
756 if (mlptr->ml_flags & XF86CONF_DBLSCAN)
757 fprintf(cf, " doublescan");
758 if (mlptr->ml_flags & XF86CONF_HSKEW)
759 fprintf(cf, " hskew %d", mlptr->ml_hskew);
760 if (mlptr->ml_flags & XF86CONF_VSCAN)
761 fprintf(cf, " vscan %d", mlptr->ml_vscan);
762 if (mlptr->ml_flags & XF86CONF_BCAST)
763 fprintf(cf, " bcast");
764 if (mlptr->ml_comment)
765 fprintf(cf, "%s", mlptr->ml_comment);
766 else
767 fprintf(cf, "\n");
768 }
769 fprintf(cf, "EndSection\n\n");
770 ptr = ptr->list.next;
771 }
772}
773
774void
775xf86freeMonitorList(XF86ConfMonitorPtr ptr)
776{
777 XF86ConfMonitorPtr prev;
778
779 while (ptr) {
780 TestFree(ptr->mon_identifier);
781 TestFree(ptr->mon_vendor);
782 TestFree(ptr->mon_modelname);
783 TestFree(ptr->mon_comment);
784 xf86optionListFree(ptr->mon_option_lst);
785 xf86freeModeLineList(ptr->mon_modeline_lst);
786 prev = ptr;
787 ptr = ptr->list.next;
788 free(prev);
789 }
790}
791
792void
793xf86freeModesList(XF86ConfModesPtr ptr)
794{
795 XF86ConfModesPtr prev;
796
797 while (ptr) {
798 TestFree(ptr->modes_identifier);
799 TestFree(ptr->modes_comment);
800 xf86freeModeLineList(ptr->mon_modeline_lst);
801 prev = ptr;
802 ptr = ptr->list.next;
803 free(prev);
804 }
805}
806
807XF86ConfMonitorPtr
808xf86findMonitor(const char *ident, XF86ConfMonitorPtr p)
809{
810 while (p) {
811 if (xf86nameCompare(ident, p->mon_identifier) == 0)
812 return p;
813
814 p = p->list.next;
815 }
816 return NULL;
817}
818
819XF86ConfModesPtr
820xf86findModes(const char *ident, XF86ConfModesPtr p)
821{
822 while (p) {
823 if (xf86nameCompare(ident, p->modes_identifier) == 0)
824 return p;
825
826 p = p->list.next;
827 }
828 return NULL;
829}
830
831XF86ConfModeLinePtr
832xf86findModeLine(const char *ident, XF86ConfModeLinePtr p)
833{
834 while (p) {
835 if (xf86nameCompare(ident, p->ml_identifier) == 0)
836 return p;
837
838 p = p->list.next;
839 }
840 return NULL;
841}
842
843int
844xf86validateMonitor(XF86ConfigPtr p, XF86ConfScreenPtr screen)
845{
846 XF86ConfMonitorPtr monitor = screen->scrn_monitor;
847 XF86ConfModesLinkPtr modeslnk = monitor->mon_modes_sect_lst;
848 XF86ConfModesPtr modes;
849
850 while (modeslnk) {
851 modes = xf86findModes(modeslnk->ml_modes_str, p->conf_modes_lst);
852 if (!modes) {
853 xf86validationError(UNDEFINED_MODES_MSG,
854 modeslnk->ml_modes_str,
855 screen->scrn_identifier);
856 return FALSE;
857 }
858 modeslnk->ml_modes = modes;
859 modeslnk = modeslnk->list.next;
860 }
861 return TRUE;
862}