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