135c4bbdfSmrg/*
235c4bbdfSmrg *
305b261ecSmrg * Copyright (c) 1997  Metro Link Incorporated
435c4bbdfSmrg *
505b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
635c4bbdfSmrg * copy of this software and associated documentation files (the "Software"),
705b261ecSmrg * to deal in the Software without restriction, including without limitation
805b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
905b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
1005b261ecSmrg * Software is furnished to do so, subject to the following conditions:
1135c4bbdfSmrg *
1205b261ecSmrg * The above copyright notice and this permission notice shall be included in
1305b261ecSmrg * all copies or substantial portions of the Software.
1435c4bbdfSmrg *
1505b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1605b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1705b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1805b261ecSmrg * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1905b261ecSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
2005b261ecSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2105b261ecSmrg * SOFTWARE.
2235c4bbdfSmrg *
2305b261ecSmrg * Except as contained in this notice, the name of the Metro Link shall not be
2405b261ecSmrg * used in advertising or otherwise to promote the sale, use or other dealings
2505b261ecSmrg * in this Software without prior written authorization from Metro Link.
2635c4bbdfSmrg *
2705b261ecSmrg */
2805b261ecSmrg/*
2905b261ecSmrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
3005b261ecSmrg *
3105b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
3205b261ecSmrg * copy of this software and associated documentation files (the "Software"),
3305b261ecSmrg * to deal in the Software without restriction, including without limitation
3405b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
3505b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
3605b261ecSmrg * Software is furnished to do so, subject to the following conditions:
3705b261ecSmrg *
3805b261ecSmrg * The above copyright notice and this permission notice shall be included in
3905b261ecSmrg * all copies or substantial portions of the Software.
4005b261ecSmrg *
4105b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4205b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4305b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
4405b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
4505b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
4605b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
4705b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE.
4805b261ecSmrg *
4905b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s)
5005b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote
5105b261ecSmrg * the sale, use or other dealings in this Software without prior written
5205b261ecSmrg * authorization from the copyright holder(s) and author(s).
5305b261ecSmrg */
5405b261ecSmrg
5505b261ecSmrg#ifdef HAVE_XORG_CONFIG_H
5605b261ecSmrg#include <xorg-config.h>
5705b261ecSmrg#endif
5805b261ecSmrg
5905b261ecSmrg#include "xf86Parser.h"
6005b261ecSmrg#include "xf86tokens.h"
6105b261ecSmrg#include "Configint.h"
6205b261ecSmrg
6305b261ecSmrg
641b5d61b8Smrgstatic const xf86ConfigSymTabRec DisplayTab[] = {
6535c4bbdfSmrg    {ENDSUBSECTION, "endsubsection"},
6635c4bbdfSmrg    {MODES, "modes"},
6735c4bbdfSmrg    {VIEWPORT, "viewport"},
6835c4bbdfSmrg    {VIRTUAL, "virtual"},
6935c4bbdfSmrg    {VISUAL, "visual"},
7035c4bbdfSmrg    {BLACK_TOK, "black"},
7135c4bbdfSmrg    {WHITE_TOK, "white"},
7235c4bbdfSmrg    {DEPTH, "depth"},
7335c4bbdfSmrg    {BPP, "fbbpp"},
7435c4bbdfSmrg    {WEIGHT, "weight"},
7535c4bbdfSmrg    {OPTION, "option"},
7635c4bbdfSmrg    {-1, ""},
7705b261ecSmrg};
7805b261ecSmrg
7935c4bbdfSmrgstatic void
8035c4bbdfSmrgxf86freeModeList(XF86ModePtr ptr)
8135c4bbdfSmrg{
8235c4bbdfSmrg    XF86ModePtr prev;
8335c4bbdfSmrg
8435c4bbdfSmrg    while (ptr) {
8535c4bbdfSmrg        TestFree(ptr->mode_name);
8635c4bbdfSmrg        prev = ptr;
8735c4bbdfSmrg        ptr = ptr->list.next;
8835c4bbdfSmrg        free(prev);
8935c4bbdfSmrg    }
9035c4bbdfSmrg}
9135c4bbdfSmrg
9235c4bbdfSmrgstatic void
9335c4bbdfSmrgxf86freeDisplayList(XF86ConfDisplayPtr ptr)
9435c4bbdfSmrg{
9535c4bbdfSmrg    XF86ConfDisplayPtr prev;
9635c4bbdfSmrg
9735c4bbdfSmrg    while (ptr) {
9835c4bbdfSmrg        xf86freeModeList(ptr->disp_mode_lst);
9935c4bbdfSmrg        xf86optionListFree(ptr->disp_option_lst);
10035c4bbdfSmrg        prev = ptr;
10135c4bbdfSmrg        ptr = ptr->list.next;
10235c4bbdfSmrg        free(prev);
10335c4bbdfSmrg    }
10435c4bbdfSmrg}
10535c4bbdfSmrg
10605b261ecSmrg#define CLEANUP xf86freeDisplayList
10705b261ecSmrg
10805b261ecSmrgstatic XF86ConfDisplayPtr
10935c4bbdfSmrgxf86parseDisplaySubSection(void)
11005b261ecSmrg{
11135c4bbdfSmrg    int token;
11235c4bbdfSmrg
11335c4bbdfSmrg    parsePrologue(XF86ConfDisplayPtr, XF86ConfDisplayRec)
11435c4bbdfSmrg
11535c4bbdfSmrg        ptr->disp_black.red = ptr->disp_black.green = ptr->disp_black.blue = -1;
11635c4bbdfSmrg    ptr->disp_white.red = ptr->disp_white.green = ptr->disp_white.blue = -1;
11735c4bbdfSmrg    ptr->disp_frameX0 = ptr->disp_frameY0 = -1;
11835c4bbdfSmrg    while ((token = xf86getToken(DisplayTab)) != ENDSUBSECTION) {
11935c4bbdfSmrg        switch (token) {
12035c4bbdfSmrg        case COMMENT:
12135c4bbdfSmrg            ptr->disp_comment = xf86addComment(ptr->disp_comment, xf86_lex_val.str);
12258cf2af7Smrg            free(xf86_lex_val.str);
12358cf2af7Smrg            xf86_lex_val.str = NULL;
12435c4bbdfSmrg            break;
12535c4bbdfSmrg        case VIEWPORT:
12635c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
12735c4bbdfSmrg                Error(VIEWPORT_MSG);
12835c4bbdfSmrg            ptr->disp_frameX0 = xf86_lex_val.num;
12935c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
13035c4bbdfSmrg                Error(VIEWPORT_MSG);
13135c4bbdfSmrg            ptr->disp_frameY0 = xf86_lex_val.num;
13235c4bbdfSmrg            break;
13335c4bbdfSmrg        case VIRTUAL:
13435c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
13535c4bbdfSmrg                Error(VIRTUAL_MSG);
13635c4bbdfSmrg            ptr->disp_virtualX = xf86_lex_val.num;
13735c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
13835c4bbdfSmrg                Error(VIRTUAL_MSG);
13935c4bbdfSmrg            ptr->disp_virtualY = xf86_lex_val.num;
14035c4bbdfSmrg            break;
14135c4bbdfSmrg        case DEPTH:
14235c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
14335c4bbdfSmrg                Error(NUMBER_MSG, "Display");
14435c4bbdfSmrg            ptr->disp_depth = xf86_lex_val.num;
14535c4bbdfSmrg            break;
14635c4bbdfSmrg        case BPP:
14735c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
14835c4bbdfSmrg                Error(NUMBER_MSG, "Display");
14935c4bbdfSmrg            ptr->disp_bpp = xf86_lex_val.num;
15035c4bbdfSmrg            break;
15135c4bbdfSmrg        case VISUAL:
15235c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != STRING)
15335c4bbdfSmrg                Error(QUOTE_MSG, "Display");
15435c4bbdfSmrg            ptr->disp_visual = xf86_lex_val.str;
15535c4bbdfSmrg            break;
15635c4bbdfSmrg        case WEIGHT:
15735c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
15835c4bbdfSmrg                Error(WEIGHT_MSG);
15935c4bbdfSmrg            ptr->disp_weight.red = xf86_lex_val.num;
16035c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
16135c4bbdfSmrg                Error(WEIGHT_MSG);
16235c4bbdfSmrg            ptr->disp_weight.green = xf86_lex_val.num;
16335c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
16435c4bbdfSmrg                Error(WEIGHT_MSG);
16535c4bbdfSmrg            ptr->disp_weight.blue = xf86_lex_val.num;
16635c4bbdfSmrg            break;
16735c4bbdfSmrg        case BLACK_TOK:
16835c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
16935c4bbdfSmrg                Error(BLACK_MSG);
17035c4bbdfSmrg            ptr->disp_black.red = xf86_lex_val.num;
17135c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
17235c4bbdfSmrg                Error(BLACK_MSG);
17335c4bbdfSmrg            ptr->disp_black.green = xf86_lex_val.num;
17435c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
17535c4bbdfSmrg                Error(BLACK_MSG);
17635c4bbdfSmrg            ptr->disp_black.blue = xf86_lex_val.num;
17735c4bbdfSmrg            break;
17835c4bbdfSmrg        case WHITE_TOK:
17935c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
18035c4bbdfSmrg                Error(WHITE_MSG);
18135c4bbdfSmrg            ptr->disp_white.red = xf86_lex_val.num;
18235c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
18335c4bbdfSmrg                Error(WHITE_MSG);
18435c4bbdfSmrg            ptr->disp_white.green = xf86_lex_val.num;
18535c4bbdfSmrg            if (xf86getSubToken(&(ptr->disp_comment)) != NUMBER)
18635c4bbdfSmrg                Error(WHITE_MSG);
18735c4bbdfSmrg            ptr->disp_white.blue = xf86_lex_val.num;
18835c4bbdfSmrg            break;
18935c4bbdfSmrg        case MODES:
19035c4bbdfSmrg        {
19135c4bbdfSmrg            XF86ModePtr mptr;
19235c4bbdfSmrg
19335c4bbdfSmrg            while ((token =
19435c4bbdfSmrg                    xf86getSubTokenWithTab(&(ptr->disp_comment),
19535c4bbdfSmrg                                           DisplayTab)) == STRING) {
19635c4bbdfSmrg                mptr = calloc(1, sizeof(XF86ModeRec));
19735c4bbdfSmrg                mptr->mode_name = xf86_lex_val.str;
19835c4bbdfSmrg                mptr->list.next = NULL;
19935c4bbdfSmrg                ptr->disp_mode_lst = (XF86ModePtr)
20035c4bbdfSmrg                    xf86addListItem((glp) ptr->disp_mode_lst, (glp) mptr);
20135c4bbdfSmrg            }
20235c4bbdfSmrg            xf86unGetToken(token);
20335c4bbdfSmrg        }
20435c4bbdfSmrg            break;
20535c4bbdfSmrg        case OPTION:
20635c4bbdfSmrg            ptr->disp_option_lst = xf86parseOption(ptr->disp_option_lst);
20735c4bbdfSmrg            break;
20835c4bbdfSmrg
20935c4bbdfSmrg        case EOF_TOKEN:
21035c4bbdfSmrg            Error(UNEXPECTED_EOF_MSG);
21135c4bbdfSmrg            break;
21235c4bbdfSmrg        default:
21335c4bbdfSmrg            Error(INVALID_KEYWORD_MSG, xf86tokenString());
21435c4bbdfSmrg            break;
21535c4bbdfSmrg        }
21635c4bbdfSmrg    }
21705b261ecSmrg
21805b261ecSmrg#ifdef DEBUG
21935c4bbdfSmrg    printf("Display subsection parsed\n");
22005b261ecSmrg#endif
22105b261ecSmrg
22235c4bbdfSmrg    return ptr;
22305b261ecSmrg}
22405b261ecSmrg
22505b261ecSmrg#undef CLEANUP
22605b261ecSmrg
2271b5d61b8Smrgstatic const xf86ConfigSymTabRec ScreenTab[] = {
22835c4bbdfSmrg    {ENDSECTION, "endsection"},
22935c4bbdfSmrg    {IDENTIFIER, "identifier"},
23035c4bbdfSmrg    {MATCHSEAT, "matchseat"},
23135c4bbdfSmrg    {OBSDRIVER, "driver"},
23235c4bbdfSmrg    {MDEVICE, "device"},
23335c4bbdfSmrg    {MONITOR, "monitor"},
23435c4bbdfSmrg    {VIDEOADAPTOR, "videoadaptor"},
23535c4bbdfSmrg    {SCREENNO, "screenno"},
23635c4bbdfSmrg    {SUBSECTION, "subsection"},
23735c4bbdfSmrg    {DEFAULTDEPTH, "defaultcolordepth"},
23835c4bbdfSmrg    {DEFAULTDEPTH, "defaultdepth"},
23935c4bbdfSmrg    {DEFAULTBPP, "defaultbpp"},
24035c4bbdfSmrg    {DEFAULTFBBPP, "defaultfbbpp"},
24135c4bbdfSmrg    {VIRTUAL, "virtual"},
24235c4bbdfSmrg    {OPTION, "option"},
24335c4bbdfSmrg    {GDEVICE, "gpudevice"},
24435c4bbdfSmrg    {-1, ""},
24505b261ecSmrg};
24605b261ecSmrg
24705b261ecSmrg#define CLEANUP xf86freeScreenList
24805b261ecSmrgXF86ConfScreenPtr
24935c4bbdfSmrgxf86parseScreenSection(void)
25005b261ecSmrg{
25135c4bbdfSmrg    int has_ident = FALSE;
25235c4bbdfSmrg    int has_driver = FALSE;
25335c4bbdfSmrg    int token;
25435c4bbdfSmrg
25535c4bbdfSmrg    parsePrologue(XF86ConfScreenPtr, XF86ConfScreenRec)
25635c4bbdfSmrg
25735c4bbdfSmrg        while ((token = xf86getToken(ScreenTab)) != ENDSECTION) {
25835c4bbdfSmrg        switch (token) {
25935c4bbdfSmrg        case COMMENT:
26035c4bbdfSmrg            ptr->scrn_comment = xf86addComment(ptr->scrn_comment, xf86_lex_val.str);
26158cf2af7Smrg            free(xf86_lex_val.str);
26258cf2af7Smrg            xf86_lex_val.str = NULL;
26335c4bbdfSmrg            break;
26435c4bbdfSmrg        case IDENTIFIER:
26535c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
26635c4bbdfSmrg                Error(QUOTE_MSG, "Identifier");
26735c4bbdfSmrg            ptr->scrn_identifier = xf86_lex_val.str;
26835c4bbdfSmrg            if (has_ident || has_driver)
26935c4bbdfSmrg                Error(ONLY_ONE_MSG, "Identifier or Driver");
27035c4bbdfSmrg            has_ident = TRUE;
27135c4bbdfSmrg            break;
27235c4bbdfSmrg        case MATCHSEAT:
27335c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
27435c4bbdfSmrg                Error(QUOTE_MSG, "MatchSeat");
27535c4bbdfSmrg            ptr->match_seat = xf86_lex_val.str;
27635c4bbdfSmrg            break;
27735c4bbdfSmrg        case OBSDRIVER:
27835c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
27935c4bbdfSmrg                Error(QUOTE_MSG, "Driver");
28035c4bbdfSmrg            ptr->scrn_obso_driver = xf86_lex_val.str;
28135c4bbdfSmrg            if (has_ident || has_driver)
28235c4bbdfSmrg                Error(ONLY_ONE_MSG, "Identifier or Driver");
28335c4bbdfSmrg            has_driver = TRUE;
28435c4bbdfSmrg            break;
28535c4bbdfSmrg        case DEFAULTDEPTH:
28635c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
28735c4bbdfSmrg                Error(NUMBER_MSG, "DefaultDepth");
28835c4bbdfSmrg            ptr->scrn_defaultdepth = xf86_lex_val.num;
28935c4bbdfSmrg            break;
29035c4bbdfSmrg        case DEFAULTBPP:
29135c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
29235c4bbdfSmrg                Error(NUMBER_MSG, "DefaultBPP");
29335c4bbdfSmrg            ptr->scrn_defaultbpp = xf86_lex_val.num;
29435c4bbdfSmrg            break;
29535c4bbdfSmrg        case DEFAULTFBBPP:
29635c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
29735c4bbdfSmrg                Error(NUMBER_MSG, "DefaultFbBPP");
29835c4bbdfSmrg            ptr->scrn_defaultfbbpp = xf86_lex_val.num;
29935c4bbdfSmrg            break;
30035c4bbdfSmrg        case MDEVICE:
30135c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
30235c4bbdfSmrg                Error(QUOTE_MSG, "Device");
30335c4bbdfSmrg            ptr->scrn_device_str = xf86_lex_val.str;
30435c4bbdfSmrg            break;
30535c4bbdfSmrg        case GDEVICE:
30635c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
30735c4bbdfSmrg                Error(QUOTE_MSG, "GPUDevice");
30835c4bbdfSmrg            if (ptr->num_gpu_devices == CONF_MAXGPUDEVICES)
30935c4bbdfSmrg                Error(GPU_DEVICE_TOO_MANY, CONF_MAXGPUDEVICES);
31035c4bbdfSmrg            ptr->scrn_gpu_device_str[ptr->num_gpu_devices++] = xf86_lex_val.str;
31135c4bbdfSmrg            break;
31235c4bbdfSmrg        case MONITOR:
31335c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
31435c4bbdfSmrg                Error(QUOTE_MSG, "Monitor");
31535c4bbdfSmrg            ptr->scrn_monitor_str = xf86_lex_val.str;
31635c4bbdfSmrg            break;
31735c4bbdfSmrg        case VIDEOADAPTOR:
31835c4bbdfSmrg        {
31935c4bbdfSmrg            XF86ConfAdaptorLinkPtr aptr;
32035c4bbdfSmrg
32135c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
32235c4bbdfSmrg                Error(QUOTE_MSG, "VideoAdaptor");
32335c4bbdfSmrg
32435c4bbdfSmrg            /* Don't allow duplicates */
32535c4bbdfSmrg            for (aptr = ptr->scrn_adaptor_lst; aptr;
32635c4bbdfSmrg                 aptr = (XF86ConfAdaptorLinkPtr) aptr->list.next)
32735c4bbdfSmrg                if (xf86nameCompare(xf86_lex_val.str, aptr->al_adaptor_str) == 0)
32835c4bbdfSmrg                    break;
32935c4bbdfSmrg
33035c4bbdfSmrg            if (aptr == NULL) {
33135c4bbdfSmrg                aptr = calloc(1, sizeof(XF86ConfAdaptorLinkRec));
33235c4bbdfSmrg                aptr->list.next = NULL;
33335c4bbdfSmrg                aptr->al_adaptor_str = xf86_lex_val.str;
33435c4bbdfSmrg                ptr->scrn_adaptor_lst = (XF86ConfAdaptorLinkPtr)
33535c4bbdfSmrg                    xf86addListItem((glp) ptr->scrn_adaptor_lst, (glp) aptr);
33635c4bbdfSmrg            }
33735c4bbdfSmrg        }
33835c4bbdfSmrg            break;
33935c4bbdfSmrg        case VIRTUAL:
34035c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
34135c4bbdfSmrg                Error(VIRTUAL_MSG);
34235c4bbdfSmrg            ptr->scrn_virtualX = xf86_lex_val.num;
34335c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != NUMBER)
34435c4bbdfSmrg                Error(VIRTUAL_MSG);
34535c4bbdfSmrg            ptr->scrn_virtualY = xf86_lex_val.num;
34635c4bbdfSmrg            break;
34735c4bbdfSmrg        case OPTION:
34835c4bbdfSmrg            ptr->scrn_option_lst = xf86parseOption(ptr->scrn_option_lst);
34935c4bbdfSmrg            break;
35035c4bbdfSmrg        case SUBSECTION:
35135c4bbdfSmrg            if (xf86getSubToken(&(ptr->scrn_comment)) != STRING)
35235c4bbdfSmrg                Error(QUOTE_MSG, "SubSection");
35335c4bbdfSmrg            {
35435c4bbdfSmrg                free(xf86_lex_val.str);
35535c4bbdfSmrg                HANDLE_LIST(scrn_display_lst, xf86parseDisplaySubSection,
35635c4bbdfSmrg                            XF86ConfDisplayPtr);
35735c4bbdfSmrg            }
35835c4bbdfSmrg            break;
35935c4bbdfSmrg        case EOF_TOKEN:
36035c4bbdfSmrg            Error(UNEXPECTED_EOF_MSG);
36135c4bbdfSmrg            break;
36235c4bbdfSmrg        default:
36335c4bbdfSmrg            Error(INVALID_KEYWORD_MSG, xf86tokenString());
36435c4bbdfSmrg            break;
36535c4bbdfSmrg        }
36635c4bbdfSmrg    }
36735c4bbdfSmrg
36835c4bbdfSmrg    if (!has_ident && !has_driver)
36935c4bbdfSmrg        Error(NO_IDENT_MSG);
37005b261ecSmrg
37105b261ecSmrg#ifdef DEBUG
37235c4bbdfSmrg    printf("Screen section parsed\n");
37305b261ecSmrg#endif
37405b261ecSmrg
37535c4bbdfSmrg    return ptr;
37605b261ecSmrg}
37705b261ecSmrg
37805b261ecSmrgvoid
37935c4bbdfSmrgxf86printScreenSection(FILE * cf, XF86ConfScreenPtr ptr)
38005b261ecSmrg{
38135c4bbdfSmrg    XF86ConfAdaptorLinkPtr aptr;
38235c4bbdfSmrg    XF86ConfDisplayPtr dptr;
38335c4bbdfSmrg    XF86ModePtr mptr;
38435c4bbdfSmrg    int i;
38535c4bbdfSmrg    while (ptr) {
38635c4bbdfSmrg        fprintf(cf, "Section \"Screen\"\n");
38735c4bbdfSmrg        if (ptr->scrn_comment)
38835c4bbdfSmrg            fprintf(cf, "%s", ptr->scrn_comment);
38935c4bbdfSmrg        if (ptr->scrn_identifier)
39035c4bbdfSmrg            fprintf(cf, "\tIdentifier \"%s\"\n", ptr->scrn_identifier);
39135c4bbdfSmrg        if (ptr->scrn_obso_driver)
39235c4bbdfSmrg            fprintf(cf, "\tDriver     \"%s\"\n", ptr->scrn_obso_driver);
39335c4bbdfSmrg        if (ptr->scrn_device_str)
39435c4bbdfSmrg            fprintf(cf, "\tDevice     \"%s\"\n", ptr->scrn_device_str);
39535c4bbdfSmrg        for (i = 0; i < ptr->num_gpu_devices; i++)
39635c4bbdfSmrg            if (ptr->scrn_gpu_device_str[i])
39735c4bbdfSmrg                fprintf(cf, "\tGPUDevice     \"%s\"\n", ptr->scrn_gpu_device_str[i]);
39835c4bbdfSmrg        if (ptr->scrn_monitor_str)
39935c4bbdfSmrg            fprintf(cf, "\tMonitor    \"%s\"\n", ptr->scrn_monitor_str);
40035c4bbdfSmrg        if (ptr->scrn_defaultdepth)
40135c4bbdfSmrg            fprintf(cf, "\tDefaultDepth     %d\n", ptr->scrn_defaultdepth);
40235c4bbdfSmrg        if (ptr->scrn_defaultbpp)
40335c4bbdfSmrg            fprintf(cf, "\tDefaultBPP     %d\n", ptr->scrn_defaultbpp);
40435c4bbdfSmrg        if (ptr->scrn_defaultfbbpp)
40535c4bbdfSmrg            fprintf(cf, "\tDefaultFbBPP     %d\n", ptr->scrn_defaultfbbpp);
40635c4bbdfSmrg        xf86printOptionList(cf, ptr->scrn_option_lst, 1);
40735c4bbdfSmrg        for (aptr = ptr->scrn_adaptor_lst; aptr; aptr = aptr->list.next) {
40835c4bbdfSmrg            fprintf(cf, "\tVideoAdaptor \"%s\"\n", aptr->al_adaptor_str);
40935c4bbdfSmrg        }
41035c4bbdfSmrg        if (ptr->scrn_virtualX && ptr->scrn_virtualY)
41135c4bbdfSmrg            fprintf(cf, "\tVirtual     %d %d\n",
41235c4bbdfSmrg                    ptr->scrn_virtualX, ptr->scrn_virtualY);
41335c4bbdfSmrg        for (dptr = ptr->scrn_display_lst; dptr; dptr = dptr->list.next) {
41435c4bbdfSmrg            fprintf(cf, "\tSubSection \"Display\"\n");
41535c4bbdfSmrg            if (dptr->disp_comment)
41635c4bbdfSmrg                fprintf(cf, "%s", dptr->disp_comment);
41735c4bbdfSmrg            if (dptr->disp_frameX0 >= 0 || dptr->disp_frameY0 >= 0) {
41835c4bbdfSmrg                fprintf(cf, "\t\tViewport   %d %d\n",
41935c4bbdfSmrg                        dptr->disp_frameX0, dptr->disp_frameY0);
42035c4bbdfSmrg            }
42135c4bbdfSmrg            if (dptr->disp_virtualX != 0 || dptr->disp_virtualY != 0) {
42235c4bbdfSmrg                fprintf(cf, "\t\tVirtual   %d %d\n",
42335c4bbdfSmrg                        dptr->disp_virtualX, dptr->disp_virtualY);
42435c4bbdfSmrg            }
42535c4bbdfSmrg            if (dptr->disp_depth) {
42635c4bbdfSmrg                fprintf(cf, "\t\tDepth     %d\n", dptr->disp_depth);
42735c4bbdfSmrg            }
42835c4bbdfSmrg            if (dptr->disp_bpp) {
42935c4bbdfSmrg                fprintf(cf, "\t\tFbBPP     %d\n", dptr->disp_bpp);
43035c4bbdfSmrg            }
43135c4bbdfSmrg            if (dptr->disp_visual) {
43235c4bbdfSmrg                fprintf(cf, "\t\tVisual    \"%s\"\n", dptr->disp_visual);
43335c4bbdfSmrg            }
43435c4bbdfSmrg            if (dptr->disp_weight.red != 0) {
43535c4bbdfSmrg                fprintf(cf, "\t\tWeight    %d %d %d\n",
43635c4bbdfSmrg                        dptr->disp_weight.red, dptr->disp_weight.green,
43735c4bbdfSmrg                        dptr->disp_weight.blue);
43835c4bbdfSmrg            }
43935c4bbdfSmrg            if (dptr->disp_black.red != -1) {
44035c4bbdfSmrg                fprintf(cf, "\t\tBlack     0x%04x 0x%04x 0x%04x\n",
44135c4bbdfSmrg                        dptr->disp_black.red, dptr->disp_black.green,
44235c4bbdfSmrg                        dptr->disp_black.blue);
44335c4bbdfSmrg            }
44435c4bbdfSmrg            if (dptr->disp_white.red != -1) {
44535c4bbdfSmrg                fprintf(cf, "\t\tWhite     0x%04x 0x%04x 0x%04x\n",
44635c4bbdfSmrg                        dptr->disp_white.red, dptr->disp_white.green,
44735c4bbdfSmrg                        dptr->disp_white.blue);
44835c4bbdfSmrg            }
44935c4bbdfSmrg            if (dptr->disp_mode_lst) {
45035c4bbdfSmrg                fprintf(cf, "\t\tModes   ");
45135c4bbdfSmrg            }
45235c4bbdfSmrg            for (mptr = dptr->disp_mode_lst; mptr; mptr = mptr->list.next) {
45335c4bbdfSmrg                fprintf(cf, " \"%s\"", mptr->mode_name);
45435c4bbdfSmrg            }
45535c4bbdfSmrg            if (dptr->disp_mode_lst) {
45635c4bbdfSmrg                fprintf(cf, "\n");
45735c4bbdfSmrg            }
45835c4bbdfSmrg            xf86printOptionList(cf, dptr->disp_option_lst, 2);
45935c4bbdfSmrg            fprintf(cf, "\tEndSubSection\n");
46035c4bbdfSmrg        }
46135c4bbdfSmrg        fprintf(cf, "EndSection\n\n");
46235c4bbdfSmrg        ptr = ptr->list.next;
46335c4bbdfSmrg    }
46405b261ecSmrg
46505b261ecSmrg}
46605b261ecSmrg
46735c4bbdfSmrgstatic void
46835c4bbdfSmrgxf86freeAdaptorLinkList(XF86ConfAdaptorLinkPtr ptr)
46905b261ecSmrg{
47035c4bbdfSmrg    XF86ConfAdaptorLinkPtr prev;
47135c4bbdfSmrg
47235c4bbdfSmrg    while (ptr) {
47335c4bbdfSmrg        TestFree(ptr->al_adaptor_str);
47435c4bbdfSmrg        prev = ptr;
47535c4bbdfSmrg        ptr = ptr->list.next;
47635c4bbdfSmrg        free(prev);
47735c4bbdfSmrg    }
47805b261ecSmrg}
47905b261ecSmrg
48005b261ecSmrgvoid
48135c4bbdfSmrgxf86freeScreenList(XF86ConfScreenPtr ptr)
48205b261ecSmrg{
48335c4bbdfSmrg    XF86ConfScreenPtr prev;
48435c4bbdfSmrg    int i;
48535c4bbdfSmrg    while (ptr) {
48635c4bbdfSmrg        TestFree(ptr->scrn_identifier);
48735c4bbdfSmrg        TestFree(ptr->scrn_monitor_str);
48835c4bbdfSmrg        TestFree(ptr->scrn_device_str);
48935c4bbdfSmrg        for (i = 0; i < ptr->num_gpu_devices; i++)
49035c4bbdfSmrg            TestFree(ptr->scrn_gpu_device_str[i]);
49135c4bbdfSmrg        TestFree(ptr->scrn_comment);
49235c4bbdfSmrg        xf86optionListFree(ptr->scrn_option_lst);
49335c4bbdfSmrg        xf86freeAdaptorLinkList(ptr->scrn_adaptor_lst);
49435c4bbdfSmrg        xf86freeDisplayList(ptr->scrn_display_lst);
49535c4bbdfSmrg        prev = ptr;
49635c4bbdfSmrg        ptr = ptr->list.next;
49735c4bbdfSmrg        free(prev);
49835c4bbdfSmrg    }
49905b261ecSmrg}
50005b261ecSmrg
50105b261ecSmrgint
50235c4bbdfSmrgxf86validateScreen(XF86ConfigPtr p)
50305b261ecSmrg{
50435c4bbdfSmrg    XF86ConfScreenPtr screen = p->conf_screen_lst;
50535c4bbdfSmrg    XF86ConfMonitorPtr monitor;
50635c4bbdfSmrg    XF86ConfAdaptorLinkPtr adaptor;
50735c4bbdfSmrg    int i;
50835c4bbdfSmrg
50935c4bbdfSmrg    while (screen) {
51035c4bbdfSmrg        if (screen->scrn_obso_driver && !screen->scrn_identifier)
51135c4bbdfSmrg            screen->scrn_identifier = screen->scrn_obso_driver;
51235c4bbdfSmrg
51335c4bbdfSmrg        monitor =
51435c4bbdfSmrg            xf86findMonitor(screen->scrn_monitor_str, p->conf_monitor_lst);
51535c4bbdfSmrg        if (screen->scrn_monitor_str) {
51635c4bbdfSmrg            if (monitor) {
51735c4bbdfSmrg                screen->scrn_monitor = monitor;
51835c4bbdfSmrg                if (!xf86validateMonitor(p, screen))
51935c4bbdfSmrg                    return FALSE;
52035c4bbdfSmrg            }
52135c4bbdfSmrg        }
52235c4bbdfSmrg
52335c4bbdfSmrg        screen->scrn_device =
52435c4bbdfSmrg            xf86findDevice(screen->scrn_device_str, p->conf_device_lst);
52535c4bbdfSmrg
52635c4bbdfSmrg        for (i = 0; i < screen->num_gpu_devices; i++) {
52735c4bbdfSmrg            screen->scrn_gpu_devices[i] =
52835c4bbdfSmrg                xf86findDevice(screen->scrn_gpu_device_str[i], p->conf_device_lst);
52935c4bbdfSmrg        }
53035c4bbdfSmrg        adaptor = screen->scrn_adaptor_lst;
53135c4bbdfSmrg        while (adaptor) {
53235c4bbdfSmrg            adaptor->al_adaptor =
53335c4bbdfSmrg                xf86findVideoAdaptor(adaptor->al_adaptor_str,
53435c4bbdfSmrg                                     p->conf_videoadaptor_lst);
53535c4bbdfSmrg            if (!adaptor->al_adaptor) {
53635c4bbdfSmrg                xf86validationError(UNDEFINED_ADAPTOR_MSG,
53735c4bbdfSmrg                                    adaptor->al_adaptor_str,
53835c4bbdfSmrg                                    screen->scrn_identifier);
53935c4bbdfSmrg                return FALSE;
54035c4bbdfSmrg            }
54135c4bbdfSmrg            else if (adaptor->al_adaptor->va_fwdref) {
54235c4bbdfSmrg                xf86validationError(ADAPTOR_REF_TWICE_MSG,
54335c4bbdfSmrg                                    adaptor->al_adaptor_str,
54435c4bbdfSmrg                                    adaptor->al_adaptor->va_fwdref);
54535c4bbdfSmrg                return FALSE;
54635c4bbdfSmrg            }
54735c4bbdfSmrg
54835c4bbdfSmrg            adaptor->al_adaptor->va_fwdref = strdup(screen->scrn_identifier);
54935c4bbdfSmrg            adaptor = adaptor->list.next;
55035c4bbdfSmrg        }
55135c4bbdfSmrg
55235c4bbdfSmrg        screen = screen->list.next;
55335c4bbdfSmrg    }
55435c4bbdfSmrg
55535c4bbdfSmrg    return TRUE;
55605b261ecSmrg}
55705b261ecSmrg
55805b261ecSmrgXF86ConfScreenPtr
55935c4bbdfSmrgxf86findScreen(const char *ident, XF86ConfScreenPtr p)
56005b261ecSmrg{
56135c4bbdfSmrg    while (p) {
56235c4bbdfSmrg        if (xf86nameCompare(ident, p->scrn_identifier) == 0)
56335c4bbdfSmrg            return p;
56405b261ecSmrg
56535c4bbdfSmrg        p = p->list.next;
56635c4bbdfSmrg    }
56735c4bbdfSmrg    return NULL;
56835c4bbdfSmrg}
569