Monitor.c revision 58cf2af7
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
64static 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
80static const xf86ConfigSymTabRec ModesTab[] = {
81    {ENDSECTION, "endsection"},
82    {IDENTIFIER, "identifier"},
83    {MODELINE, "modeline"},
84    {MODE, "mode"},
85    {-1, ""},
86};
87
88static 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
104static 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
118static void
119xf86freeModeLineList(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
132static XF86ConfModeLinePtr
133xf86parseModeLine(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
257static XF86ConfModeLinePtr
258xf86parseVerboseMode(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            free(xf86_lex_val.str);
273            xf86_lex_val.str = NULL;
274            break;
275        case DOTCLOCK:
276            if ((token = xf86getSubToken(&(ptr->ml_comment))) != NUMBER)
277                Error(NUMBER_MSG, "DotClock");
278            ptr->ml_clock = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
279            had_dotclock = 1;
280            break;
281        case HTIMINGS:
282            if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
283                ptr->ml_hdisplay = xf86_lex_val.num;
284            else
285                Error("Horizontal display expected");
286
287            if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
288                ptr->ml_hsyncstart = xf86_lex_val.num;
289            else
290                Error("Horizontal sync start expected");
291
292            if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
293                ptr->ml_hsyncend = xf86_lex_val.num;
294            else
295                Error("Horizontal sync end expected");
296
297            if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
298                ptr->ml_htotal = xf86_lex_val.num;
299            else
300                Error("Horizontal total expected");
301            had_htimings = 1;
302            break;
303        case VTIMINGS:
304            if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
305                ptr->ml_vdisplay = xf86_lex_val.num;
306            else
307                Error("Vertical display expected");
308
309            if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
310                ptr->ml_vsyncstart = xf86_lex_val.num;
311            else
312                Error("Vertical sync start expected");
313
314            if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
315                ptr->ml_vsyncend = xf86_lex_val.num;
316            else
317                Error("Vertical sync end expected");
318
319            if (xf86getSubToken(&(ptr->ml_comment)) == NUMBER)
320                ptr->ml_vtotal = xf86_lex_val.num;
321            else
322                Error("Vertical total expected");
323            had_vtimings = 1;
324            break;
325        case FLAGS:
326            token = xf86getSubToken(&(ptr->ml_comment));
327            if (token != STRING)
328                Error(QUOTE_MSG, "Flags");
329            while (token == STRING) {
330                token2 = xf86getStringToken(TimingTab);
331                switch (token2) {
332                case TT_INTERLACE:
333                    ptr->ml_flags |= XF86CONF_INTERLACE;
334                    break;
335                case TT_PHSYNC:
336                    ptr->ml_flags |= XF86CONF_PHSYNC;
337                    break;
338                case TT_NHSYNC:
339                    ptr->ml_flags |= XF86CONF_NHSYNC;
340                    break;
341                case TT_PVSYNC:
342                    ptr->ml_flags |= XF86CONF_PVSYNC;
343                    break;
344                case TT_NVSYNC:
345                    ptr->ml_flags |= XF86CONF_NVSYNC;
346                    break;
347                case TT_CSYNC:
348                    ptr->ml_flags |= XF86CONF_CSYNC;
349                    break;
350                case TT_PCSYNC:
351                    ptr->ml_flags |= XF86CONF_PCSYNC;
352                    break;
353                case TT_NCSYNC:
354                    ptr->ml_flags |= XF86CONF_NCSYNC;
355                    break;
356                case TT_DBLSCAN:
357                    ptr->ml_flags |= XF86CONF_DBLSCAN;
358                    break;
359                case EOF_TOKEN:
360                    Error(UNEXPECTED_EOF_MSG);
361                    break;
362                default:
363                    Error("Unknown flag string");
364                    break;
365                }
366                token = xf86getSubToken(&(ptr->ml_comment));
367            }
368            xf86unGetToken(token);
369            break;
370        case HSKEW:
371            if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
372                Error("Horizontal skew expected");
373            ptr->ml_flags |= XF86CONF_HSKEW;
374            ptr->ml_hskew = xf86_lex_val.num;
375            break;
376        case VSCAN:
377            if (xf86getSubToken(&(ptr->ml_comment)) != NUMBER)
378                Error("Vertical scan count expected");
379            ptr->ml_flags |= XF86CONF_VSCAN;
380            ptr->ml_vscan = xf86_lex_val.num;
381            break;
382        case EOF_TOKEN:
383            Error(UNEXPECTED_EOF_MSG);
384            break;
385        default:
386            Error("Unexpected token in verbose \"Mode\" entry\n");
387        }
388    }
389    if (!had_dotclock)
390        Error("the dotclock is missing");
391    if (!had_htimings)
392        Error("the horizontal timings are missing");
393    if (!had_vtimings)
394        Error("the vertical timings are missing");
395
396#ifdef DEBUG
397    printf("Verbose Mode parsed\n");
398#endif
399    return ptr;
400}
401
402#undef CLEANUP
403
404#define CLEANUP xf86freeMonitorList
405
406XF86ConfMonitorPtr
407xf86parseMonitorSection(void)
408{
409    int has_ident = FALSE;
410    int token;
411
412    parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec)
413
414        while ((token = xf86getToken(MonitorTab)) != ENDSECTION) {
415        switch (token) {
416        case COMMENT:
417            ptr->mon_comment = xf86addComment(ptr->mon_comment, xf86_lex_val.str);
418            free(xf86_lex_val.str);
419            xf86_lex_val.str = NULL;
420            break;
421        case IDENTIFIER:
422            if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
423                Error(QUOTE_MSG, "Identifier");
424            if (has_ident == TRUE)
425                Error(MULTIPLE_MSG, "Identifier");
426            ptr->mon_identifier = xf86_lex_val.str;
427            has_ident = TRUE;
428            break;
429        case VENDOR:
430            if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
431                Error(QUOTE_MSG, "Vendor");
432            ptr->mon_vendor = xf86_lex_val.str;
433            break;
434        case MODEL:
435            if (xf86getSubToken(&(ptr->mon_comment)) != STRING)
436                Error(QUOTE_MSG, "ModelName");
437            ptr->mon_modelname = xf86_lex_val.str;
438            break;
439        case MODE:
440            HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode,
441                        XF86ConfModeLinePtr);
442            break;
443        case MODELINE:
444            HANDLE_LIST(mon_modeline_lst, xf86parseModeLine,
445                        XF86ConfModeLinePtr);
446            break;
447        case DISPLAYSIZE:
448            if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
449                Error(DISPLAYSIZE_MSG);
450            ptr->mon_width = xf86_lex_val.realnum;
451            if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
452                Error(DISPLAYSIZE_MSG);
453            ptr->mon_height = xf86_lex_val.realnum;
454            break;
455
456        case HORIZSYNC:
457            if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
458                Error(HORIZSYNC_MSG);
459            do {
460                if (ptr->mon_n_hsync >= CONF_MAX_HSYNC)
461                    Error("Sorry. Too many horizontal sync intervals.");
462                ptr->mon_hsync[ptr->mon_n_hsync].lo = xf86_lex_val.realnum;
463                switch (token = xf86getSubToken(&(ptr->mon_comment))) {
464                case COMMA:
465                    ptr->mon_hsync[ptr->mon_n_hsync].hi =
466                        ptr->mon_hsync[ptr->mon_n_hsync].lo;
467                    break;
468                case DASH:
469                    if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER ||
470                        (float) xf86_lex_val.realnum <
471                        ptr->mon_hsync[ptr->mon_n_hsync].lo)
472                        Error(HORIZSYNC_MSG);
473                    ptr->mon_hsync[ptr->mon_n_hsync].hi = xf86_lex_val.realnum;
474                    if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA)
475                        break;
476                    ptr->mon_n_hsync++;
477                    goto HorizDone;
478                default:
479                    /* We cannot currently know if a '\n' was found,
480                     * or this is a real error
481                     */
482                    ptr->mon_hsync[ptr->mon_n_hsync].hi =
483                        ptr->mon_hsync[ptr->mon_n_hsync].lo;
484                    ptr->mon_n_hsync++;
485                    goto HorizDone;
486                }
487                ptr->mon_n_hsync++;
488            } while ((token = xf86getSubToken(&(ptr->mon_comment))) == NUMBER);
489 HorizDone:
490            xf86unGetToken(token);
491            break;
492
493        case VERTREFRESH:
494            if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER)
495                Error(VERTREFRESH_MSG);
496            do {
497                ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = xf86_lex_val.realnum;
498                switch (token = xf86getSubToken(&(ptr->mon_comment))) {
499                case COMMA:
500                    ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
501                        ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
502                    break;
503                case DASH:
504                    if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER ||
505                        (float) xf86_lex_val.realnum <
506                        ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo)
507                        Error(VERTREFRESH_MSG);
508                    ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = xf86_lex_val.realnum;
509                    if ((token = xf86getSubToken(&(ptr->mon_comment))) == COMMA)
510                        break;
511                    ptr->mon_n_vrefresh++;
512                    goto VertDone;
513                default:
514                    /* We cannot currently know if a '\n' was found,
515                     * or this is a real error
516                     */
517                    ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
518                        ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
519                    ptr->mon_n_vrefresh++;
520                    goto VertDone;
521                }
522                if (ptr->mon_n_vrefresh >= CONF_MAX_VREFRESH)
523                    Error("Sorry. Too many vertical refresh intervals.");
524                ptr->mon_n_vrefresh++;
525            } while ((token = xf86getSubToken(&(ptr->mon_comment))) == NUMBER);
526 VertDone:
527            xf86unGetToken(token);
528            break;
529
530        case GAMMA:
531            if (xf86getSubToken(&(ptr->mon_comment)) != NUMBER) {
532                Error(INVALID_GAMMA_MSG);
533            }
534            else {
535                ptr->mon_gamma_red = ptr->mon_gamma_green =
536                    ptr->mon_gamma_blue = xf86_lex_val.realnum;
537                if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) {
538                    ptr->mon_gamma_green = xf86_lex_val.realnum;
539                    if (xf86getSubToken(&(ptr->mon_comment)) == NUMBER) {
540                        ptr->mon_gamma_blue = xf86_lex_val.realnum;
541                    }
542                    else {
543                        Error(INVALID_GAMMA_MSG);
544                    }
545                }
546                else
547                    xf86unGetToken(token);
548            }
549            break;
550        case OPTION:
551            ptr->mon_option_lst = xf86parseOption(ptr->mon_option_lst);
552            break;
553        case USEMODES:
554        {
555            XF86ConfModesLinkPtr mptr;
556
557            if ((token = xf86getSubToken(&(ptr->mon_comment))) != STRING)
558                Error(QUOTE_MSG, "UseModes");
559
560            /* add to the end of the list of modes sections
561               referenced here */
562            mptr = calloc(1, sizeof(XF86ConfModesLinkRec));
563            mptr->list.next = NULL;
564            mptr->ml_modes_str = xf86_lex_val.str;
565            mptr->ml_modes = NULL;
566            ptr->mon_modes_sect_lst = (XF86ConfModesLinkPtr)
567                xf86addListItem((GenericListPtr) ptr->mon_modes_sect_lst,
568                                (GenericListPtr) mptr);
569        }
570            break;
571        case EOF_TOKEN:
572            Error(UNEXPECTED_EOF_MSG);
573            break;
574        default:
575            xf86parseError(INVALID_KEYWORD_MSG, xf86tokenString());
576            CLEANUP(ptr);
577            return NULL;
578            break;
579        }
580    }
581
582    if (!has_ident)
583        Error(NO_IDENT_MSG);
584
585#ifdef DEBUG
586    printf("Monitor section parsed\n");
587#endif
588    return ptr;
589}
590
591#undef CLEANUP
592#define CLEANUP xf86freeModesList
593
594XF86ConfModesPtr
595xf86parseModesSection(void)
596{
597    int has_ident = FALSE;
598    int token;
599
600    parsePrologue(XF86ConfModesPtr, XF86ConfModesRec)
601
602        while ((token = xf86getToken(ModesTab)) != ENDSECTION) {
603        switch (token) {
604        case COMMENT:
605            ptr->modes_comment = xf86addComment(ptr->modes_comment, xf86_lex_val.str);
606            free(xf86_lex_val.str);
607            xf86_lex_val.str = NULL;
608            break;
609        case IDENTIFIER:
610            if (xf86getSubToken(&(ptr->modes_comment)) != STRING)
611                Error(QUOTE_MSG, "Identifier");
612            if (has_ident == TRUE)
613                Error(MULTIPLE_MSG, "Identifier");
614            ptr->modes_identifier = xf86_lex_val.str;
615            has_ident = TRUE;
616            break;
617        case MODE:
618            HANDLE_LIST(mon_modeline_lst, xf86parseVerboseMode,
619                        XF86ConfModeLinePtr);
620            break;
621        case MODELINE:
622            HANDLE_LIST(mon_modeline_lst, xf86parseModeLine,
623                        XF86ConfModeLinePtr);
624            break;
625        default:
626            xf86parseError(INVALID_KEYWORD_MSG, xf86tokenString());
627            CLEANUP(ptr);
628            return NULL;
629            break;
630        }
631    }
632
633    if (!has_ident)
634        Error(NO_IDENT_MSG);
635
636#ifdef DEBUG
637    printf("Modes section parsed\n");
638#endif
639    return ptr;
640}
641
642#undef CLEANUP
643
644void
645xf86printMonitorSection(FILE * cf, XF86ConfMonitorPtr ptr)
646{
647    int i;
648    XF86ConfModeLinePtr mlptr;
649    XF86ConfModesLinkPtr mptr;
650
651    while (ptr) {
652        mptr = ptr->mon_modes_sect_lst;
653        fprintf(cf, "Section \"Monitor\"\n");
654        if (ptr->mon_comment)
655            fprintf(cf, "%s", ptr->mon_comment);
656        if (ptr->mon_identifier)
657            fprintf(cf, "\tIdentifier   \"%s\"\n", ptr->mon_identifier);
658        if (ptr->mon_vendor)
659            fprintf(cf, "\tVendorName   \"%s\"\n", ptr->mon_vendor);
660        if (ptr->mon_modelname)
661            fprintf(cf, "\tModelName    \"%s\"\n", ptr->mon_modelname);
662        while (mptr) {
663            fprintf(cf, "\tUseModes     \"%s\"\n", mptr->ml_modes_str);
664            mptr = mptr->list.next;
665        }
666        if (ptr->mon_width)
667            fprintf(cf, "\tDisplaySize  %d\t%d\n",
668                    ptr->mon_width, ptr->mon_height);
669        for (i = 0; i < ptr->mon_n_hsync; i++) {
670            fprintf(cf, "\tHorizSync    %2.1f - %2.1f\n",
671                    ptr->mon_hsync[i].lo, ptr->mon_hsync[i].hi);
672        }
673        for (i = 0; i < ptr->mon_n_vrefresh; i++) {
674            fprintf(cf, "\tVertRefresh  %2.1f - %2.1f\n",
675                    ptr->mon_vrefresh[i].lo, ptr->mon_vrefresh[i].hi);
676        }
677        if (ptr->mon_gamma_red) {
678            if (ptr->mon_gamma_red == ptr->mon_gamma_green
679                && ptr->mon_gamma_red == ptr->mon_gamma_blue) {
680                fprintf(cf, "\tGamma        %.4g\n", ptr->mon_gamma_red);
681            }
682            else {
683                fprintf(cf, "\tGamma        %.4g %.4g %.4g\n",
684                        ptr->mon_gamma_red,
685                        ptr->mon_gamma_green, ptr->mon_gamma_blue);
686            }
687        }
688        for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next) {
689            fprintf(cf, "\tModeLine     \"%s\" %2.1f ",
690                    mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
691            fprintf(cf, "%d %d %d %d %d %d %d %d",
692                    mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
693                    mlptr->ml_hsyncend, mlptr->ml_htotal,
694                    mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
695                    mlptr->ml_vsyncend, mlptr->ml_vtotal);
696            if (mlptr->ml_flags & XF86CONF_PHSYNC)
697                fprintf(cf, " +hsync");
698            if (mlptr->ml_flags & XF86CONF_NHSYNC)
699                fprintf(cf, " -hsync");
700            if (mlptr->ml_flags & XF86CONF_PVSYNC)
701                fprintf(cf, " +vsync");
702            if (mlptr->ml_flags & XF86CONF_NVSYNC)
703                fprintf(cf, " -vsync");
704            if (mlptr->ml_flags & XF86CONF_INTERLACE)
705                fprintf(cf, " interlace");
706            if (mlptr->ml_flags & XF86CONF_CSYNC)
707                fprintf(cf, " composite");
708            if (mlptr->ml_flags & XF86CONF_PCSYNC)
709                fprintf(cf, " +csync");
710            if (mlptr->ml_flags & XF86CONF_NCSYNC)
711                fprintf(cf, " -csync");
712            if (mlptr->ml_flags & XF86CONF_DBLSCAN)
713                fprintf(cf, " doublescan");
714            if (mlptr->ml_flags & XF86CONF_HSKEW)
715                fprintf(cf, " hskew %d", mlptr->ml_hskew);
716            if (mlptr->ml_flags & XF86CONF_BCAST)
717                fprintf(cf, " bcast");
718            fprintf(cf, "\n");
719        }
720        xf86printOptionList(cf, ptr->mon_option_lst, 1);
721        fprintf(cf, "EndSection\n\n");
722        ptr = ptr->list.next;
723    }
724}
725
726void
727xf86printModesSection(FILE * cf, XF86ConfModesPtr ptr)
728{
729    XF86ConfModeLinePtr mlptr;
730
731    while (ptr) {
732        fprintf(cf, "Section \"Modes\"\n");
733        if (ptr->modes_comment)
734            fprintf(cf, "%s", ptr->modes_comment);
735        if (ptr->modes_identifier)
736            fprintf(cf, "\tIdentifier     \"%s\"\n", ptr->modes_identifier);
737        for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next) {
738            fprintf(cf, "\tModeLine     \"%s\" %2.1f ",
739                    mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
740            fprintf(cf, "%d %d %d %d %d %d %d %d",
741                    mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
742                    mlptr->ml_hsyncend, mlptr->ml_htotal,
743                    mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
744                    mlptr->ml_vsyncend, mlptr->ml_vtotal);
745            if (mlptr->ml_flags & XF86CONF_PHSYNC)
746                fprintf(cf, " +hsync");
747            if (mlptr->ml_flags & XF86CONF_NHSYNC)
748                fprintf(cf, " -hsync");
749            if (mlptr->ml_flags & XF86CONF_PVSYNC)
750                fprintf(cf, " +vsync");
751            if (mlptr->ml_flags & XF86CONF_NVSYNC)
752                fprintf(cf, " -vsync");
753            if (mlptr->ml_flags & XF86CONF_INTERLACE)
754                fprintf(cf, " interlace");
755            if (mlptr->ml_flags & XF86CONF_CSYNC)
756                fprintf(cf, " composite");
757            if (mlptr->ml_flags & XF86CONF_PCSYNC)
758                fprintf(cf, " +csync");
759            if (mlptr->ml_flags & XF86CONF_NCSYNC)
760                fprintf(cf, " -csync");
761            if (mlptr->ml_flags & XF86CONF_DBLSCAN)
762                fprintf(cf, " doublescan");
763            if (mlptr->ml_flags & XF86CONF_HSKEW)
764                fprintf(cf, " hskew %d", mlptr->ml_hskew);
765            if (mlptr->ml_flags & XF86CONF_VSCAN)
766                fprintf(cf, " vscan %d", mlptr->ml_vscan);
767            if (mlptr->ml_flags & XF86CONF_BCAST)
768                fprintf(cf, " bcast");
769            if (mlptr->ml_comment)
770                fprintf(cf, "%s", mlptr->ml_comment);
771            else
772                fprintf(cf, "\n");
773        }
774        fprintf(cf, "EndSection\n\n");
775        ptr = ptr->list.next;
776    }
777}
778
779void
780xf86freeMonitorList(XF86ConfMonitorPtr ptr)
781{
782    XF86ConfMonitorPtr prev;
783
784    while (ptr) {
785        TestFree(ptr->mon_identifier);
786        TestFree(ptr->mon_vendor);
787        TestFree(ptr->mon_modelname);
788        TestFree(ptr->mon_comment);
789        xf86optionListFree(ptr->mon_option_lst);
790        xf86freeModeLineList(ptr->mon_modeline_lst);
791        prev = ptr;
792        ptr = ptr->list.next;
793        free(prev);
794    }
795}
796
797void
798xf86freeModesList(XF86ConfModesPtr ptr)
799{
800    XF86ConfModesPtr prev;
801
802    while (ptr) {
803        TestFree(ptr->modes_identifier);
804        TestFree(ptr->modes_comment);
805        xf86freeModeLineList(ptr->mon_modeline_lst);
806        prev = ptr;
807        ptr = ptr->list.next;
808        free(prev);
809    }
810}
811
812XF86ConfMonitorPtr
813xf86findMonitor(const char *ident, XF86ConfMonitorPtr p)
814{
815    while (p) {
816        if (xf86nameCompare(ident, p->mon_identifier) == 0)
817            return p;
818
819        p = p->list.next;
820    }
821    return NULL;
822}
823
824XF86ConfModesPtr
825xf86findModes(const char *ident, XF86ConfModesPtr p)
826{
827    while (p) {
828        if (xf86nameCompare(ident, p->modes_identifier) == 0)
829            return p;
830
831        p = p->list.next;
832    }
833    return NULL;
834}
835
836XF86ConfModeLinePtr
837xf86findModeLine(const char *ident, XF86ConfModeLinePtr p)
838{
839    while (p) {
840        if (xf86nameCompare(ident, p->ml_identifier) == 0)
841            return p;
842
843        p = p->list.next;
844    }
845    return NULL;
846}
847
848int
849xf86validateMonitor(XF86ConfigPtr p, XF86ConfScreenPtr screen)
850{
851    XF86ConfMonitorPtr monitor = screen->scrn_monitor;
852    XF86ConfModesLinkPtr modeslnk = monitor->mon_modes_sect_lst;
853    XF86ConfModesPtr modes;
854
855    while (modeslnk) {
856        modes = xf86findModes(modeslnk->ml_modes_str, p->conf_modes_lst);
857        if (!modes) {
858            xf86validationError(UNDEFINED_MODES_MSG,
859                                modeslnk->ml_modes_str,
860                                screen->scrn_identifier);
861            return FALSE;
862        }
863        modeslnk->ml_modes = modes;
864        modeslnk = modeslnk->list.next;
865    }
866    return TRUE;
867}
868