105b261ecSmrg/*
205b261ecSmrg * Loosely based on code bearing the following copyright:
305b261ecSmrg *
405b261ecSmrg *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
505b261ecSmrg */
605b261ecSmrg
705b261ecSmrg/*
805b261ecSmrg * Copyright 1992-2003 by The XFree86 Project, Inc.
905b261ecSmrg * Copyright 1997 by Metro Link, Inc.
1005b261ecSmrg *
1105b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
1205b261ecSmrg * copy of this software and associated documentation files (the "Software"),
1305b261ecSmrg * to deal in the Software without restriction, including without limitation
1405b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1505b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
1605b261ecSmrg * Software is furnished to do so, subject to the following conditions:
1705b261ecSmrg *
1805b261ecSmrg * The above copyright notice and this permission notice shall be included in
1905b261ecSmrg * all copies or substantial portions of the Software.
2005b261ecSmrg *
2105b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2205b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2305b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2405b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2505b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2605b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2705b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE.
2805b261ecSmrg *
2905b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s)
3005b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote
3105b261ecSmrg * the sale, use or other dealings in this Software without prior written
3205b261ecSmrg * authorization from the copyright holder(s) and author(s).
3305b261ecSmrg */
3405b261ecSmrg
3505b261ecSmrg/*
3605b261ecSmrg *
3705b261ecSmrg * Authors:
3805b261ecSmrg *	Dirk Hohndel <hohndel@XFree86.Org>
3905b261ecSmrg *	David Dawes <dawes@XFree86.Org>
4005b261ecSmrg *      Marc La France <tsi@XFree86.Org>
4105b261ecSmrg *      Egbert Eich <eich@XFree86.Org>
4205b261ecSmrg *      ... and others
4305b261ecSmrg */
4405b261ecSmrg
4505b261ecSmrg#ifdef HAVE_XORG_CONFIG_H
4605b261ecSmrg#include <xorg-config.h>
4705b261ecSmrg#endif
4805b261ecSmrg
4905b261ecSmrg#include <sys/types.h>
5005b261ecSmrg#include <grp.h>
5105b261ecSmrg
5205b261ecSmrg#include "xf86.h"
53188eae84Sprlw#include "xf86Modes.h"
5405b261ecSmrg#include "xf86Parser.h"
5505b261ecSmrg#include "xf86tokens.h"
5605b261ecSmrg#include "xf86Config.h"
5705b261ecSmrg#include "xf86Priv.h"
5805b261ecSmrg#include "xf86_OSlib.h"
5905b261ecSmrg#include "configProcs.h"
6005b261ecSmrg#include "globals.h"
6105b261ecSmrg#include "extension.h"
6265b04b38Smrg#include "xf86pciBus.h"
6305b261ecSmrg#include "xf86Xinput.h"
647e31ba66Smrg#include "loaderProcs.h"
6505b261ecSmrg
664202a189Smrg#include "xkbsrv.h"
6705b261ecSmrg#include "picture.h"
687e31ba66Smrg#ifdef DPMSExtension
697e31ba66Smrg#include "dpmsproc.h"
707e31ba66Smrg#endif
7105b261ecSmrg
7205b261ecSmrg/*
7305b261ecSmrg * These paths define the way the config file search is done.  The escape
7405b261ecSmrg * sequences are documented in parser/scan.c.
7505b261ecSmrg */
76f7df2e56Smrg#ifndef ALL_CONFIGPATH
77f7df2e56Smrg#define ALL_CONFIGPATH	"%A," "%R," \
7805b261ecSmrg			"/etc/X11/%R," "%P/etc/X11/%R," \
7905b261ecSmrg			"%E," "%F," \
8005b261ecSmrg			"/etc/X11/%F," "%P/etc/X11/%F," \
8165b04b38Smrg			"/etc/X11/%X," "/etc/%X," \
8265b04b38Smrg			"%P/etc/X11/%X.%H," \
8305b261ecSmrg			"%P/etc/X11/%X," \
8465b04b38Smrg			"%P/lib/X11/%X.%H," \
8505b261ecSmrg			"%P/lib/X11/%X"
8605b261ecSmrg#endif
87f7df2e56Smrg#ifndef RESTRICTED_CONFIGPATH
88f7df2e56Smrg#define RESTRICTED_CONFIGPATH	"/etc/X11/%S," "%P/etc/X11/%S," \
8905b261ecSmrg			"/etc/X11/%G," "%P/etc/X11/%G," \
9065b04b38Smrg			"/etc/X11/%X," "/etc/%X," \
9165b04b38Smrg			"%P/etc/X11/%X.%H," \
9205b261ecSmrg			"%P/etc/X11/%X," \
9365b04b38Smrg			"%P/lib/X11/%X.%H," \
9405b261ecSmrg			"%P/lib/X11/%X"
9505b261ecSmrg#endif
96f7df2e56Smrg#ifndef ALL_CONFIGDIRPATH
97f7df2e56Smrg#define ALL_CONFIGDIRPATH	"%A," "%R," \
984202a189Smrg				"/etc/X11/%R," "%C/X11/%R," \
994202a189Smrg				"/etc/X11/%X," "%C/X11/%X"
1004202a189Smrg#endif
101f7df2e56Smrg#ifndef RESTRICTED_CONFIGDIRPATH
102f7df2e56Smrg#define RESTRICTED_CONFIGDIRPATH	"/etc/X11/%R," "%C/X11/%R," \
103f7df2e56Smrg					"/etc/X11/%X," "%C/X11/%X"
1044202a189Smrg#endif
1054202a189Smrg#ifndef SYS_CONFIGDIRPATH
106f7df2e56Smrg#define SYS_CONFIGDIRPATH	"%D/X11/%X"
1074202a189Smrg#endif
10805b261ecSmrg#ifndef PROJECTROOT
10905b261ecSmrg#define PROJECTROOT	"/usr/X11R6"
11005b261ecSmrg#endif
11105b261ecSmrg
112637ac9abSmrgstatic ModuleDefault ModuleDefaults[] = {
1134202a189Smrg#ifdef GLXEXT
114f7df2e56Smrg    {.name = "glx",.toLoad = TRUE,.load_opt = NULL},
1154202a189Smrg#endif
116f7df2e56Smrg#ifdef __CYGWIN__
117f7df2e56Smrg    /* load DIX modules used by drivers first */
118f7df2e56Smrg    {.name = "fb",.toLoad = TRUE,.load_opt = NULL},
119f7df2e56Smrg    {.name = "shadow",.toLoad = TRUE,.load_opt = NULL},
120637ac9abSmrg#endif
121f7df2e56Smrg    {.name = NULL,.toLoad = FALSE,.load_opt = NULL}
122637ac9abSmrg};
123637ac9abSmrg
12405b261ecSmrg/* Forward declarations */
12505b261ecSmrgstatic Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
126f7df2e56Smrg                         int scrnum, MessageType from, Bool auto_gpu_device);
12705b261ecSmrgstatic Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
12805b261ecSmrgstatic Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
129f7df2e56Smrg                         Bool active, Bool gpu);
13065b04b38Smrgstatic Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
131f7df2e56Smrg                        MessageType from);
13205b261ecSmrgstatic Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
13305b261ecSmrgstatic Bool addDefaultModes(MonPtr monitorp);
134f7df2e56Smrg
13505b261ecSmrgstatic void configDRI(XF86ConfDRIPtr drip);
13605b261ecSmrgstatic void configExtensions(XF86ConfExtensionsPtr conf_ext);
13705b261ecSmrg
13805b261ecSmrg/*
13905b261ecSmrg * xf86GetPathElem --
14005b261ecSmrg *	Extract a single element from the font path string starting at
14105b261ecSmrg *	pnt.  The font path element will be returned, and pnt will be
14205b261ecSmrg *	updated to point to the start of the next element, or set to
14305b261ecSmrg *	NULL if there are no more.
14405b261ecSmrg */
14505b261ecSmrgstatic char *
14605b261ecSmrgxf86GetPathElem(char **pnt)
14705b261ecSmrg{
148f7df2e56Smrg    char *p1;
149f7df2e56Smrg
150f7df2e56Smrg    p1 = *pnt;
151f7df2e56Smrg    *pnt = index(*pnt, ',');
152f7df2e56Smrg    if (*pnt != NULL) {
153f7df2e56Smrg        **pnt = '\0';
154f7df2e56Smrg        *pnt += 1;
155f7df2e56Smrg    }
156f7df2e56Smrg    return p1;
15705b261ecSmrg}
15805b261ecSmrg
15905b261ecSmrg/*
16005b261ecSmrg * xf86ValidateFontPath --
16105b261ecSmrg *	Validates the user-specified font path.  Each element that
16205b261ecSmrg *	begins with a '/' is checked to make sure the directory exists.
16305b261ecSmrg *	If the directory exists, the existence of a file named 'fonts.dir'
16405b261ecSmrg *	is checked.  If either check fails, an error is printed and the
16505b261ecSmrg *	element is removed from the font path.
16605b261ecSmrg */
16705b261ecSmrg
16805b261ecSmrg#define DIR_FILE "/fonts.dir"
16905b261ecSmrgstatic char *
17005b261ecSmrgxf86ValidateFontPath(char *path)
17105b261ecSmrg{
172f7df2e56Smrg    char *next, *tmp_path, *out_pnt, *path_elem, *p1, *dir_elem;
173f7df2e56Smrg    struct stat stat_buf;
174f7df2e56Smrg    int flag;
175f7df2e56Smrg    int dirlen;
176f7df2e56Smrg
177f7df2e56Smrg    tmp_path = calloc(1, strlen(path) + 1);
178f7df2e56Smrg    out_pnt = tmp_path;
179f7df2e56Smrg    path_elem = NULL;
180f7df2e56Smrg    next = path;
181f7df2e56Smrg    while (next != NULL) {
182f7df2e56Smrg        path_elem = xf86GetPathElem(&next);
183f7df2e56Smrg        if (*path_elem == '/') {
184f7df2e56Smrg            dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
185f7df2e56Smrg            if ((p1 = strchr(path_elem, ':')) != 0)
186f7df2e56Smrg                dirlen = p1 - path_elem;
187f7df2e56Smrg            else
188f7df2e56Smrg                dirlen = strlen(path_elem);
189f7df2e56Smrg            strlcpy(dir_elem, path_elem, dirlen + 1);
190f7df2e56Smrg            flag = stat(dir_elem, &stat_buf);
191f7df2e56Smrg            if (flag == 0)
192f7df2e56Smrg                if (!S_ISDIR(stat_buf.st_mode))
193f7df2e56Smrg                    flag = -1;
194f7df2e56Smrg            if (flag != 0) {
195f7df2e56Smrg                xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n",
196f7df2e56Smrg                        dir_elem);
197f7df2e56Smrg                xf86ErrorF("\tEntry deleted from font path.\n");
198f7df2e56Smrg                free(dir_elem);
199f7df2e56Smrg                continue;
200f7df2e56Smrg            }
201f7df2e56Smrg            else {
202f7df2e56Smrg                XNFasprintf(&p1, "%s%s", dir_elem, DIR_FILE);
203f7df2e56Smrg                flag = stat(p1, &stat_buf);
204f7df2e56Smrg                if (flag == 0)
205f7df2e56Smrg                    if (!S_ISREG(stat_buf.st_mode))
206f7df2e56Smrg                        flag = -1;
207f7df2e56Smrg                free(p1);
208f7df2e56Smrg                if (flag != 0) {
209f7df2e56Smrg                    xf86Msg(X_WARNING,
210f7df2e56Smrg                            "`fonts.dir' not found (or not valid) in \"%s\".\n",
211f7df2e56Smrg                            dir_elem);
212f7df2e56Smrg                    xf86ErrorF("\tEntry deleted from font path.\n");
213f7df2e56Smrg                    xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
214f7df2e56Smrg                    free(dir_elem);
215f7df2e56Smrg                    continue;
216f7df2e56Smrg                }
217f7df2e56Smrg            }
218f7df2e56Smrg            free(dir_elem);
219f7df2e56Smrg        }
22005b261ecSmrg
221f7df2e56Smrg        /*
222f7df2e56Smrg         * Either an OK directory, or a font server name.  So add it to
223f7df2e56Smrg         * the path.
224f7df2e56Smrg         */
225f7df2e56Smrg        if (out_pnt != tmp_path)
226f7df2e56Smrg            *out_pnt++ = ',';
227f7df2e56Smrg        strcat(out_pnt, path_elem);
228f7df2e56Smrg        out_pnt += strlen(path_elem);
229f7df2e56Smrg    }
230f7df2e56Smrg    return tmp_path;
23105b261ecSmrg}
23205b261ecSmrg
233f7df2e56Smrg#define FIND_SUITABLE(pointertype, listhead, ptr)                                            \
234f7df2e56Smrg    do {                                                                                     \
235f7df2e56Smrg        pointertype _l, _p;                                                                  \
236f7df2e56Smrg                                                                                             \
237f7df2e56Smrg        for (_l = (listhead), _p = NULL; !_p && _l; _l = (pointertype)_l->list.next) {       \
238f7df2e56Smrg            if (!_l->match_seat || (SeatId && xf86nameCompare(_l->match_seat, SeatId) == 0)) \
239f7df2e56Smrg                _p = _l;                                                                     \
240f7df2e56Smrg        }                                                                                    \
241f7df2e56Smrg                                                                                             \
242f7df2e56Smrg        (ptr) = _p;                                                                          \
243f7df2e56Smrg    } while(0)
24405b261ecSmrg
24505b261ecSmrg/*
24605b261ecSmrg * use the datastructure that the parser provides and pick out the parts
24705b261ecSmrg * that we need at this point
24805b261ecSmrg */
249f7df2e56Smrgconst char **
250f7df2e56Smrgxf86ModulelistFromConfig(void ***optlist)
25105b261ecSmrg{
25205b261ecSmrg    int count = 0, i = 0;
253f7df2e56Smrg    const char **modulearray;
254f7df2e56Smrg
255f7df2e56Smrg    const char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
256f7df2e56Smrg        "freetype", "type1",
257f7df2e56Smrg        NULL
258f7df2e56Smrg    };
259f7df2e56Smrg    void **optarray;
26005b261ecSmrg    XF86LoadPtr modp;
26105b261ecSmrg    Bool found;
262f7df2e56Smrg
26305b261ecSmrg    /*
26405b261ecSmrg     * make sure the config file has been parsed and that we have a
26505b261ecSmrg     * ModulePath set; if no ModulePath was given, use the default
26605b261ecSmrg     * ModulePath
26705b261ecSmrg     */
26805b261ecSmrg    if (xf86configptr == NULL) {
26905b261ecSmrg        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
27005b261ecSmrg        return NULL;
27105b261ecSmrg    }
272f7df2e56Smrg
27305b261ecSmrg    if (xf86configptr->conf_modules) {
27405b261ecSmrg        /* Walk the disable list and let people know what we've parsed to
275f7df2e56Smrg         * not be loaded
27605b261ecSmrg         */
27705b261ecSmrg        modp = xf86configptr->conf_modules->mod_disable_lst;
27805b261ecSmrg        while (modp) {
279f7df2e56Smrg            xf86Msg(X_WARNING,
280f7df2e56Smrg                    "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n",
281f7df2e56Smrg                    modp->load_name);
282f7df2e56Smrg            modp = (XF86LoadPtr) modp->list.next;
28305b261ecSmrg        }
28405b261ecSmrg        /*
28505b261ecSmrg         * Walk the default settings table. For each module listed to be
28605b261ecSmrg         * loaded, make sure it's in the mod_load_lst. If it's not, make
28705b261ecSmrg         * sure it's not in the mod_no_load_lst. If it's not disabled,
28805b261ecSmrg         * append it to mod_load_lst
28905b261ecSmrg         */
290f7df2e56Smrg        for (i = 0; ModuleDefaults[i].name != NULL; i++) {
29105b261ecSmrg            if (ModuleDefaults[i].toLoad == FALSE) {
292f7df2e56Smrg                xf86Msg(X_WARNING,
293f7df2e56Smrg                        "\"%s\" is not to be loaded by default. Skipping.\n",
294f7df2e56Smrg                        ModuleDefaults[i].name);
29505b261ecSmrg                continue;
29605b261ecSmrg            }
29705b261ecSmrg            found = FALSE;
29805b261ecSmrg            modp = xf86configptr->conf_modules->mod_load_lst;
29905b261ecSmrg            while (modp) {
30005b261ecSmrg                if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
301f7df2e56Smrg                    xf86Msg(X_INFO,
302f7df2e56Smrg                            "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n",
303f7df2e56Smrg                            ModuleDefaults[i].name);
30405b261ecSmrg                    found = TRUE;
30505b261ecSmrg                    break;
30605b261ecSmrg                }
307f7df2e56Smrg                modp = (XF86LoadPtr) modp->list.next;
30805b261ecSmrg            }
30905b261ecSmrg            if (found == FALSE) {
31005b261ecSmrg                modp = xf86configptr->conf_modules->mod_disable_lst;
31105b261ecSmrg                while (modp) {
31205b261ecSmrg                    if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
313f7df2e56Smrg                        xf86Msg(X_INFO,
314f7df2e56Smrg                                "\"%s\" will be loaded even though the default is to disable it.\n",
315f7df2e56Smrg                                ModuleDefaults[i].name);
31605b261ecSmrg                        found = TRUE;
31705b261ecSmrg                        break;
31805b261ecSmrg                    }
319f7df2e56Smrg                    modp = (XF86LoadPtr) modp->list.next;
32005b261ecSmrg                }
32105b261ecSmrg            }
32205b261ecSmrg            if (found == FALSE) {
323f7df2e56Smrg                XF86LoadPtr ptr = (XF86LoadPtr) xf86configptr->conf_modules;
324f7df2e56Smrg
325f7df2e56Smrg                xf86addNewLoadDirective(ptr, ModuleDefaults[i].name,
326f7df2e56Smrg                                        XF86_LOAD_MODULE,
327f7df2e56Smrg                                        ModuleDefaults[i].load_opt);
328f7df2e56Smrg                xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n",
329f7df2e56Smrg                        ModuleDefaults[i].name);
33005b261ecSmrg            }
331f7df2e56Smrg        }
332f7df2e56Smrg    }
333f7df2e56Smrg    else {
334f7df2e56Smrg        xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
335f7df2e56Smrg        for (i = 0; ModuleDefaults[i].name != NULL; i++) {
336f7df2e56Smrg            if (ModuleDefaults[i].toLoad == TRUE) {
337f7df2e56Smrg                XF86LoadPtr ptr = (XF86LoadPtr) xf86configptr->conf_modules;
338f7df2e56Smrg
339f7df2e56Smrg                xf86addNewLoadDirective(ptr, ModuleDefaults[i].name,
340f7df2e56Smrg                                        XF86_LOAD_MODULE,
341f7df2e56Smrg                                        ModuleDefaults[i].load_opt);
342f7df2e56Smrg            }
343f7df2e56Smrg        }
344f7df2e56Smrg    }
345f7df2e56Smrg
346f7df2e56Smrg    /*
347f7df2e56Smrg     * Walk the list of modules in the "Module" section to determine how
348f7df2e56Smrg     * many we have.
349f7df2e56Smrg     */
350f7df2e56Smrg    modp = xf86configptr->conf_modules->mod_load_lst;
351f7df2e56Smrg    while (modp) {
352f7df2e56Smrg        for (i = 0; ignore[i]; i++) {
353f7df2e56Smrg            if (strcmp(modp->load_name, ignore[i]) == 0)
354f7df2e56Smrg                modp->ignore = 1;
355f7df2e56Smrg        }
356f7df2e56Smrg        if (!modp->ignore)
357f7df2e56Smrg            count++;
358f7df2e56Smrg        modp = (XF86LoadPtr) modp->list.next;
359f7df2e56Smrg    }
36005b261ecSmrg
36105b261ecSmrg    /*
36205b261ecSmrg     * allocate the memory and walk the list again to fill in the pointers
36305b261ecSmrg     */
364f7df2e56Smrg    modulearray = xnfallocarray(count + 1, sizeof(char *));
365f7df2e56Smrg    optarray = xnfallocarray(count + 1, sizeof(void *));
36605b261ecSmrg    count = 0;
36705b261ecSmrg    if (xf86configptr->conf_modules) {
368f7df2e56Smrg        modp = xf86configptr->conf_modules->mod_load_lst;
369f7df2e56Smrg        while (modp) {
37005b261ecSmrg            if (!modp->ignore) {
371f7df2e56Smrg                modulearray[count] = modp->load_name;
372f7df2e56Smrg                optarray[count] = modp->load_opt;
373f7df2e56Smrg                count++;
37405b261ecSmrg            }
375f7df2e56Smrg            modp = (XF86LoadPtr) modp->list.next;
376f7df2e56Smrg        }
37705b261ecSmrg    }
37805b261ecSmrg    modulearray[count] = NULL;
37905b261ecSmrg    optarray[count] = NULL;
38005b261ecSmrg    if (optlist)
381f7df2e56Smrg        *optlist = optarray;
38205b261ecSmrg    else
383f7df2e56Smrg        free(optarray);
38405b261ecSmrg    return modulearray;
38505b261ecSmrg}
38605b261ecSmrg
387f7df2e56Smrgconst char **
3884202a189Smrgxf86DriverlistFromConfig(void)
38905b261ecSmrg{
39005b261ecSmrg    int count = 0;
391f7df2e56Smrg    int j, k;
392f7df2e56Smrg    const char **modulearray;
39305b261ecSmrg    screenLayoutPtr slp;
394f7df2e56Smrg
39505b261ecSmrg    /*
39605b261ecSmrg     * make sure the config file has been parsed and that we have a
39705b261ecSmrg     * ModulePath set; if no ModulePath was given, use the default
39805b261ecSmrg     * ModulePath
39905b261ecSmrg     */
40005b261ecSmrg    if (xf86configptr == NULL) {
40105b261ecSmrg        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
40205b261ecSmrg        return NULL;
40305b261ecSmrg    }
404f7df2e56Smrg
40505b261ecSmrg    /*
40605b261ecSmrg     * Walk the list of driver lines in active "Device" sections to
40705b261ecSmrg     * determine now many implicitly loaded modules there are.
40805b261ecSmrg     *
40905b261ecSmrg     */
41005b261ecSmrg    if (xf86ConfigLayout.screens) {
41105b261ecSmrg        slp = xf86ConfigLayout.screens;
412f7df2e56Smrg        while (slp->screen) {
413f7df2e56Smrg            count++;
414f7df2e56Smrg            count += slp->screen->num_gpu_devices;
415f7df2e56Smrg            slp++;
41605b261ecSmrg        }
41705b261ecSmrg    }
41805b261ecSmrg
41905b261ecSmrg    /*
42005b261ecSmrg     * Handle the set of inactive "Device" sections.
42105b261ecSmrg     */
42205b261ecSmrg    j = 0;
42305b261ecSmrg    while (xf86ConfigLayout.inactives[j++].identifier)
424f7df2e56Smrg        count++;
42505b261ecSmrg
42605b261ecSmrg    if (count == 0)
427f7df2e56Smrg        return NULL;
42805b261ecSmrg
42905b261ecSmrg    /*
43005b261ecSmrg     * allocate the memory and walk the list again to fill in the pointers
43105b261ecSmrg     */
432f7df2e56Smrg    modulearray = xnfallocarray(count + 1, sizeof(char *));
43305b261ecSmrg    count = 0;
43405b261ecSmrg    slp = xf86ConfigLayout.screens;
43505b261ecSmrg    while (slp->screen) {
436f7df2e56Smrg        modulearray[count] = slp->screen->device->driver;
437f7df2e56Smrg        count++;
438f7df2e56Smrg        for (k = 0; k < slp->screen->num_gpu_devices; k++) {
439f7df2e56Smrg            modulearray[count] = slp->screen->gpu_devices[k]->driver;
440f7df2e56Smrg            count++;
441f7df2e56Smrg        }
442f7df2e56Smrg        slp++;
44305b261ecSmrg    }
44405b261ecSmrg
44505b261ecSmrg    j = 0;
44605b261ecSmrg
447f7df2e56Smrg    while (xf86ConfigLayout.inactives[j].identifier)
448f7df2e56Smrg        modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
44905b261ecSmrg
45005b261ecSmrg    modulearray[count] = NULL;
45105b261ecSmrg
45205b261ecSmrg    /* Remove duplicates */
45305b261ecSmrg    for (count = 0; modulearray[count] != NULL; count++) {
454f7df2e56Smrg        int i;
45505b261ecSmrg
456f7df2e56Smrg        for (i = 0; i < count; i++)
457f7df2e56Smrg            if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
458f7df2e56Smrg                modulearray[count] = "";
459f7df2e56Smrg                break;
460f7df2e56Smrg            }
46105b261ecSmrg    }
46205b261ecSmrg    return modulearray;
46305b261ecSmrg}
46405b261ecSmrg
465f7df2e56Smrgconst char **
4664202a189Smrgxf86InputDriverlistFromConfig(void)
46705b261ecSmrg{
46805b261ecSmrg    int count = 0;
469f7df2e56Smrg    const char **modulearray;
47065b04b38Smrg    InputInfoPtr *idp;
47165b04b38Smrg
47205b261ecSmrg    /*
47305b261ecSmrg     * make sure the config file has been parsed and that we have a
47405b261ecSmrg     * ModulePath set; if no ModulePath was given, use the default
47505b261ecSmrg     * ModulePath
47605b261ecSmrg     */
47705b261ecSmrg    if (xf86configptr == NULL) {
47805b261ecSmrg        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
47905b261ecSmrg        return NULL;
48005b261ecSmrg    }
481f7df2e56Smrg
48205b261ecSmrg    /*
48305b261ecSmrg     * Walk the list of driver lines in active "InputDevice" sections to
48405b261ecSmrg     * determine now many implicitly loaded modules there are.
48505b261ecSmrg     */
48605b261ecSmrg    if (xf86ConfigLayout.inputs) {
48705b261ecSmrg        idp = xf86ConfigLayout.inputs;
48805b261ecSmrg        while (*idp) {
489f7df2e56Smrg            count++;
490f7df2e56Smrg            idp++;
49105b261ecSmrg        }
49205b261ecSmrg    }
49305b261ecSmrg
49405b261ecSmrg    if (count == 0)
495f7df2e56Smrg        return NULL;
49605b261ecSmrg
49705b261ecSmrg    /*
49805b261ecSmrg     * allocate the memory and walk the list again to fill in the pointers
49905b261ecSmrg     */
500f7df2e56Smrg    modulearray = xnfallocarray(count + 1, sizeof(char *));
50105b261ecSmrg    count = 0;
50205b261ecSmrg    idp = xf86ConfigLayout.inputs;
50305b261ecSmrg    while (idp && *idp) {
50405b261ecSmrg        modulearray[count] = (*idp)->driver;
505f7df2e56Smrg        count++;
506f7df2e56Smrg        idp++;
50705b261ecSmrg    }
50805b261ecSmrg    modulearray[count] = NULL;
50905b261ecSmrg
51005b261ecSmrg    /* Remove duplicates */
51105b261ecSmrg    for (count = 0; modulearray[count] != NULL; count++) {
512f7df2e56Smrg        int i;
51305b261ecSmrg
514f7df2e56Smrg        for (i = 0; i < count; i++)
515f7df2e56Smrg            if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
516f7df2e56Smrg                modulearray[count] = "";
517f7df2e56Smrg                break;
518f7df2e56Smrg            }
51905b261ecSmrg    }
52005b261ecSmrg    return modulearray;
52105b261ecSmrg}
52205b261ecSmrg
52305b261ecSmrgstatic void
52405b261ecSmrgconfigFiles(XF86ConfFilesPtr fileconf)
52505b261ecSmrg{
526f7df2e56Smrg    MessageType pathFrom;
527f7df2e56Smrg    Bool must_copy;
528f7df2e56Smrg    int size, countDirs;
529f7df2e56Smrg    char *temp_path, *log_buf, *start, *end;
530637ac9abSmrg
531637ac9abSmrg    /* FontPath */
532637ac9abSmrg    must_copy = TRUE;
533637ac9abSmrg
534f7df2e56Smrg    temp_path = defaultFontPath ? (char *) defaultFontPath : (char *) "";
535637ac9abSmrg    if (xf86fpFlag)
536f7df2e56Smrg        pathFrom = X_CMDLINE;
537637ac9abSmrg    else if (fileconf && fileconf->file_fontpath) {
538f7df2e56Smrg        pathFrom = X_CONFIG;
539f7df2e56Smrg        if (xf86Info.useDefaultFontPath) {
540f7df2e56Smrg            char *new_font_path;
541f7df2e56Smrg            if (asprintf(&new_font_path, "%s%s%s", fileconf->file_fontpath,
542f7df2e56Smrg                         *temp_path ? "," : "", temp_path) == -1)
543f7df2e56Smrg                new_font_path = NULL;
544f7df2e56Smrg            else
545f7df2e56Smrg                must_copy = FALSE;
546f7df2e56Smrg            defaultFontPath = new_font_path;
547f7df2e56Smrg        }
548f7df2e56Smrg        else
549f7df2e56Smrg            defaultFontPath = fileconf->file_fontpath;
55005b261ecSmrg    }
551637ac9abSmrg    else
552f7df2e56Smrg        pathFrom = X_DEFAULT;
553f7df2e56Smrg    temp_path = defaultFontPath ? (char *) defaultFontPath : (char *) "";
554637ac9abSmrg
555637ac9abSmrg    /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
556f7df2e56Smrg    temp_path = must_copy ? xnfstrdup(defaultFontPath) : (char *) defaultFontPath;
557637ac9abSmrg    defaultFontPath = xf86ValidateFontPath(temp_path);
558637ac9abSmrg    free(temp_path);
559637ac9abSmrg
560637ac9abSmrg    /* make fontpath more readable in the logfiles */
561637ac9abSmrg    countDirs = 1;
562f7df2e56Smrg    temp_path = (char *) defaultFontPath;
563637ac9abSmrg    while ((temp_path = index(temp_path, ',')) != NULL) {
564f7df2e56Smrg        countDirs++;
565f7df2e56Smrg        temp_path++;
566637ac9abSmrg    }
567637ac9abSmrg
568637ac9abSmrg    log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
56905b261ecSmrg    temp_path = log_buf;
570f7df2e56Smrg    start = (char *) defaultFontPath;
571f7df2e56Smrg    while ((end = index(start, ',')) != NULL) {
572f7df2e56Smrg        size = (end - start) + 1;
573f7df2e56Smrg        *(temp_path++) = '\t';
574f7df2e56Smrg        strncpy(temp_path, start, size);
575f7df2e56Smrg        temp_path += size;
576f7df2e56Smrg        *(temp_path++) = '\n';
577f7df2e56Smrg        start += size;
57805b261ecSmrg    }
57905b261ecSmrg    /* copy last entry */
58005b261ecSmrg    *(temp_path++) = '\t';
58105b261ecSmrg    strcpy(temp_path, start);
58205b261ecSmrg    xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
5834202a189Smrg    free(log_buf);
58405b261ecSmrg
585f7df2e56Smrg    /* ModulePath */
586f7df2e56Smrg
587f7df2e56Smrg    if (fileconf) {
588f7df2e56Smrg        if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
589f7df2e56Smrg            xf86ModulePath = fileconf->file_modulepath;
590f7df2e56Smrg            xf86ModPathFrom = X_CONFIG;
591f7df2e56Smrg        }
59205b261ecSmrg    }
59305b261ecSmrg
594f7df2e56Smrg    xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
59505b261ecSmrg
596f7df2e56Smrg    if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
597f7df2e56Smrg        XkbBaseDirectory = fileconf->file_xkbdir;
598f7df2e56Smrg        xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
599f7df2e56Smrg                XkbBaseDirectory);
600f7df2e56Smrg    }
60105b261ecSmrg#if 0
602f7df2e56Smrg    /* LogFile */
603f7df2e56Smrg    /*
604f7df2e56Smrg     * XXX The problem with this is that the log file is already open.
605f7df2e56Smrg     * One option might be to copy the exiting contents to the new location.
606f7df2e56Smrg     * and re-open it.  The down side is that the default location would
607f7df2e56Smrg     * already have been overwritten.  Another option would be to start with
608f7df2e56Smrg     * unique temporary location, then copy it once the correct name is known.
609f7df2e56Smrg     * A problem with this is what happens if the server exits before that
610f7df2e56Smrg     * happens.
611f7df2e56Smrg     */
612f7df2e56Smrg    if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
613f7df2e56Smrg        xf86LogFile = fileconf->file_logfile;
614f7df2e56Smrg        xf86LogFileFrom = X_CONFIG;
615f7df2e56Smrg    }
61605b261ecSmrg#endif
61705b261ecSmrg
618f7df2e56Smrg    return;
61905b261ecSmrg}
62005b261ecSmrg
62105b261ecSmrgtypedef enum {
62205b261ecSmrg    FLAG_DONTVTSWITCH,
62305b261ecSmrg    FLAG_DONTZAP,
62405b261ecSmrg    FLAG_DONTZOOM,
62505b261ecSmrg    FLAG_DISABLEVIDMODE,
62605b261ecSmrg    FLAG_ALLOWNONLOCAL,
62705b261ecSmrg    FLAG_ALLOWMOUSEOPENFAIL,
62805b261ecSmrg    FLAG_SAVER_BLANKTIME,
62905b261ecSmrg    FLAG_DPMS_STANDBYTIME,
63005b261ecSmrg    FLAG_DPMS_SUSPENDTIME,
63105b261ecSmrg    FLAG_DPMS_OFFTIME,
63205b261ecSmrg    FLAG_NOPM,
63305b261ecSmrg    FLAG_XINERAMA,
63405b261ecSmrg    FLAG_LOG,
63505b261ecSmrg    FLAG_RENDER_COLORMAP_MODE,
63605b261ecSmrg    FLAG_IGNORE_ABI,
63705b261ecSmrg    FLAG_ALLOW_EMPTY_INPUT,
63805b261ecSmrg    FLAG_USE_DEFAULT_FONT_PATH,
63905b261ecSmrg    FLAG_AUTO_ADD_DEVICES,
64005b261ecSmrg    FLAG_AUTO_ENABLE_DEVICES,
641637ac9abSmrg    FLAG_GLX_VISUALS,
642637ac9abSmrg    FLAG_DRI2,
643f7df2e56Smrg    FLAG_USE_SIGIO,
644f7df2e56Smrg    FLAG_AUTO_ADD_GPU,
6455a112b11Smrg    FLAG_AUTO_BIND_GPU,
646f7df2e56Smrg    FLAG_MAX_CLIENTS,
647f7df2e56Smrg    FLAG_IGLX,
6487e31ba66Smrg    FLAG_DEBUG,
649875c6e4fSmrg    FLAG_ALLOW_BYTE_SWAPPED_CLIENTS,
65005b261ecSmrg} FlagValues;
6514202a189Smrg
6524202a189Smrg/**
6534202a189Smrg * NOTE: the last value for each entry is NOT the default. It is set to TRUE
6544202a189Smrg * if the parser found the option in the config file.
6554202a189Smrg */
65605b261ecSmrgstatic OptionInfoRec FlagOptions[] = {
657f7df2e56Smrg    {FLAG_DONTVTSWITCH, "DontVTSwitch", OPTV_BOOLEAN,
658f7df2e56Smrg     {0}, FALSE},
659f7df2e56Smrg    {FLAG_DONTZAP, "DontZap", OPTV_BOOLEAN,
660f7df2e56Smrg     {0}, FALSE},
661f7df2e56Smrg    {FLAG_DONTZOOM, "DontZoom", OPTV_BOOLEAN,
662f7df2e56Smrg     {0}, FALSE},
663f7df2e56Smrg    {FLAG_DISABLEVIDMODE, "DisableVidModeExtension", OPTV_BOOLEAN,
664f7df2e56Smrg     {0}, FALSE},
665f7df2e56Smrg    {FLAG_ALLOWNONLOCAL, "AllowNonLocalXvidtune", OPTV_BOOLEAN,
666f7df2e56Smrg     {0}, FALSE},
667f7df2e56Smrg    {FLAG_ALLOWMOUSEOPENFAIL, "AllowMouseOpenFail", OPTV_BOOLEAN,
668f7df2e56Smrg     {0}, FALSE},
669f7df2e56Smrg    {FLAG_SAVER_BLANKTIME, "BlankTime", OPTV_INTEGER,
670f7df2e56Smrg     {0}, FALSE},
671f7df2e56Smrg    {FLAG_DPMS_STANDBYTIME, "StandbyTime", OPTV_INTEGER,
672f7df2e56Smrg     {0}, FALSE},
673f7df2e56Smrg    {FLAG_DPMS_SUSPENDTIME, "SuspendTime", OPTV_INTEGER,
674f7df2e56Smrg     {0}, FALSE},
675f7df2e56Smrg    {FLAG_DPMS_OFFTIME, "OffTime", OPTV_INTEGER,
676f7df2e56Smrg     {0}, FALSE},
677f7df2e56Smrg    {FLAG_NOPM, "NoPM", OPTV_BOOLEAN,
678f7df2e56Smrg     {0}, FALSE},
679f7df2e56Smrg    {FLAG_XINERAMA, "Xinerama", OPTV_BOOLEAN,
680f7df2e56Smrg     {0}, FALSE},
681f7df2e56Smrg    {FLAG_LOG, "Log", OPTV_STRING,
682f7df2e56Smrg     {0}, FALSE},
683f7df2e56Smrg    {FLAG_RENDER_COLORMAP_MODE, "RenderColormapMode", OPTV_STRING,
684f7df2e56Smrg     {0}, FALSE},
685f7df2e56Smrg    {FLAG_IGNORE_ABI, "IgnoreABI", OPTV_BOOLEAN,
686f7df2e56Smrg     {0}, FALSE},
687f7df2e56Smrg    {FLAG_USE_DEFAULT_FONT_PATH, "UseDefaultFontPath", OPTV_BOOLEAN,
688f7df2e56Smrg     {0}, FALSE},
689f7df2e56Smrg    {FLAG_AUTO_ADD_DEVICES, "AutoAddDevices", OPTV_BOOLEAN,
690f7df2e56Smrg     {0}, FALSE},
691f7df2e56Smrg    {FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
692f7df2e56Smrg     {0}, FALSE},
693f7df2e56Smrg    {FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
694f7df2e56Smrg     {0}, FALSE},
695f7df2e56Smrg    {FLAG_DRI2, "DRI2", OPTV_BOOLEAN,
696f7df2e56Smrg     {0}, FALSE},
697f7df2e56Smrg    {FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
698f7df2e56Smrg     {0}, FALSE},
699f7df2e56Smrg    {FLAG_AUTO_ADD_GPU, "AutoAddGPU", OPTV_BOOLEAN,
700f7df2e56Smrg     {0}, FALSE},
7015a112b11Smrg    {FLAG_AUTO_BIND_GPU, "AutoBindGPU", OPTV_BOOLEAN,
7025a112b11Smrg     {0}, FALSE},
703f7df2e56Smrg    {FLAG_MAX_CLIENTS, "MaxClients", OPTV_INTEGER,
704f7df2e56Smrg     {0}, FALSE },
705f7df2e56Smrg    {FLAG_IGLX, "IndirectGLX", OPTV_BOOLEAN,
706f7df2e56Smrg     {0}, FALSE},
7077e31ba66Smrg    {FLAG_DEBUG, "Debug", OPTV_STRING,
7087e31ba66Smrg     {0}, FALSE},
709875c6e4fSmrg    {FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, "AllowByteSwappedClients", OPTV_BOOLEAN,
710875c6e4fSmrg     {0}, FALSE},
711f7df2e56Smrg    {-1, NULL, OPTV_NONE,
712f7df2e56Smrg     {0}, FALSE},
71305b261ecSmrg};
71405b261ecSmrg
715f7df2e56Smrgstatic void
71605b261ecSmrgconfigServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
71705b261ecSmrg{
71805b261ecSmrg    XF86OptionPtr optp, tmp;
71905b261ecSmrg    int i;
72005b261ecSmrg    Bool value;
72105b261ecSmrg    MessageType from;
722637ac9abSmrg    const char *s;
7234202a189Smrg    XkbRMLVOSet set;
724f7df2e56Smrg    const char *rules;
72505b261ecSmrg
72605b261ecSmrg    /*
72705b261ecSmrg     * Merge the ServerLayout and ServerFlags options.  The former have
72805b261ecSmrg     * precedence over the latter.
72905b261ecSmrg     */
73005b261ecSmrg    optp = NULL;
73105b261ecSmrg    if (flagsconf && flagsconf->flg_option_lst)
732f7df2e56Smrg        optp = xf86optionListDup(flagsconf->flg_option_lst);
73305b261ecSmrg    if (layoutopts) {
734f7df2e56Smrg        tmp = xf86optionListDup(layoutopts);
735f7df2e56Smrg        if (optp)
736f7df2e56Smrg            optp = xf86optionListMerge(optp, tmp);
737f7df2e56Smrg        else
738f7df2e56Smrg            optp = tmp;
73905b261ecSmrg    }
74005b261ecSmrg
74105b261ecSmrg    xf86ProcessOptions(-1, optp, FlagOptions);
74205b261ecSmrg
74305b261ecSmrg    xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
744a1818c9dSmrg    xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
74505b261ecSmrg    xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
74605b261ecSmrg
74705b261ecSmrg    xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
74805b261ecSmrg    if (xf86Info.ignoreABI) {
749f7df2e56Smrg        xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
75005b261ecSmrg    }
75105b261ecSmrg
752875c6e4fSmrg    xf86GetOptValBool(FlagOptions, FLAG_ALLOW_BYTE_SWAPPED_CLIENTS, &AllowByteSwappedClients);
753875c6e4fSmrg    if (AllowByteSwappedClients) {
754875c6e4fSmrg        xf86Msg(X_CONFIG, "Allowing byte-swapped clients\n");
755875c6e4fSmrg    }
756875c6e4fSmrg    else {
757875c6e4fSmrg        xf86Msg(X_CONFIG, "Prohibiting byte-swapped clients\n");
758875c6e4fSmrg    }
759875c6e4fSmrg
76005b261ecSmrg    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
76105b261ecSmrg        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
76205b261ecSmrg                          &xf86Info.autoAddDevices);
76305b261ecSmrg        from = X_CONFIG;
76405b261ecSmrg    }
76505b261ecSmrg    else {
76605b261ecSmrg        from = X_DEFAULT;
76705b261ecSmrg    }
76805b261ecSmrg    xf86Msg(from, "%sutomatically adding devices\n",
76905b261ecSmrg            xf86Info.autoAddDevices ? "A" : "Not a");
77005b261ecSmrg
77105b261ecSmrg    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
77205b261ecSmrg        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
77305b261ecSmrg                          &xf86Info.autoEnableDevices);
77405b261ecSmrg        from = X_CONFIG;
77505b261ecSmrg    }
77605b261ecSmrg    else {
77705b261ecSmrg        from = X_DEFAULT;
77805b261ecSmrg    }
77905b261ecSmrg    xf86Msg(from, "%sutomatically enabling devices\n",
78005b261ecSmrg            xf86Info.autoEnableDevices ? "A" : "Not a");
78105b261ecSmrg
782f7df2e56Smrg    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_GPU)) {
783f7df2e56Smrg        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_GPU,
784f7df2e56Smrg                          &xf86Info.autoAddGPU);
785f7df2e56Smrg        from = X_CONFIG;
786f7df2e56Smrg    }
787f7df2e56Smrg    else {
788f7df2e56Smrg        from = X_DEFAULT;
789f7df2e56Smrg    }
790f7df2e56Smrg    xf86Msg(from, "%sutomatically adding GPU devices\n",
791f7df2e56Smrg            xf86Info.autoAddGPU ? "A" : "Not a");
7925a112b11Smrg
7935a112b11Smrg    if (xf86AutoBindGPUDisabled) {
7945a112b11Smrg        xf86Info.autoBindGPU = FALSE;
7955a112b11Smrg        from = X_CMDLINE;
7965a112b11Smrg    }
7975a112b11Smrg    else if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_BIND_GPU)) {
7985a112b11Smrg        xf86GetOptValBool(FlagOptions, FLAG_AUTO_BIND_GPU,
7995a112b11Smrg                          &xf86Info.autoBindGPU);
8005a112b11Smrg        from = X_CONFIG;
8015a112b11Smrg    }
8025a112b11Smrg    else {
8035a112b11Smrg        from = X_DEFAULT;
8045a112b11Smrg    }
8055a112b11Smrg    xf86Msg(from, "%sutomatically binding GPU devices\n",
8065a112b11Smrg            xf86Info.autoBindGPU ? "A" : "Not a");
8075a112b11Smrg
80805b261ecSmrg    /*
80905b261ecSmrg     * Set things up based on the config file information.  Some of these
81005b261ecSmrg     * settings may be overridden later when the command line options are
81105b261ecSmrg     * checked.
81205b261ecSmrg     */
81305b261ecSmrg#ifdef XF86VIDMODE
81405b261ecSmrg    if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
815f7df2e56Smrg        xf86Info.vidModeEnabled = !value;
81605b261ecSmrg    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
817f7df2e56Smrg        xf86Info.vidModeAllowNonLocal = value;
81805b261ecSmrg#endif
81905b261ecSmrg
82005b261ecSmrg    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
821f7df2e56Smrg        xf86Info.allowMouseOpenFail = value;
82205b261ecSmrg
82305b261ecSmrg    xf86Info.pmFlag = TRUE;
824f7df2e56Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
825f7df2e56Smrg        xf86Info.pmFlag = !value;
82605b261ecSmrg    {
827f7df2e56Smrg        if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
828f7df2e56Smrg            if (!xf86NameCmp(s, "flush")) {
829f7df2e56Smrg                xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
830f7df2e56Smrg                LogSetParameter(XLOG_FLUSH, TRUE);
831f7df2e56Smrg            }
832f7df2e56Smrg            else if (!xf86NameCmp(s, "sync")) {
833f7df2e56Smrg                xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
834f7df2e56Smrg                LogSetParameter(XLOG_FLUSH, TRUE);
835f7df2e56Smrg                LogSetParameter(XLOG_SYNC, TRUE);
836f7df2e56Smrg            }
837f7df2e56Smrg            else {
838f7df2e56Smrg                xf86Msg(X_WARNING, "Unknown Log option\n");
839f7df2e56Smrg            }
840f7df2e56Smrg        }
841f7df2e56Smrg    }
842f7df2e56Smrg
84305b261ecSmrg    {
844f7df2e56Smrg        if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))) {
845f7df2e56Smrg            int policy = PictureParseCmapPolicy(s);
846f7df2e56Smrg
847f7df2e56Smrg            if (policy == PictureCmapPolicyInvalid)
848f7df2e56Smrg                xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
849f7df2e56Smrg            else {
850f7df2e56Smrg                xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
851f7df2e56Smrg                PictureCmapPolicy = policy;
852f7df2e56Smrg            }
853f7df2e56Smrg        }
85405b261ecSmrg    }
8554202a189Smrg
856637ac9abSmrg#ifdef GLXEXT
857637ac9abSmrg    xf86Info.glxVisuals = XF86_GlxVisualsTypical;
858637ac9abSmrg    xf86Info.glxVisualsFrom = X_DEFAULT;
859637ac9abSmrg    if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
860f7df2e56Smrg        if (!xf86NameCmp(s, "minimal")) {
861f7df2e56Smrg            xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
862f7df2e56Smrg        }
863f7df2e56Smrg        else if (!xf86NameCmp(s, "typical")) {
864f7df2e56Smrg            xf86Info.glxVisuals = XF86_GlxVisualsTypical;
865f7df2e56Smrg        }
866f7df2e56Smrg        else if (!xf86NameCmp(s, "all")) {
867f7df2e56Smrg            xf86Info.glxVisuals = XF86_GlxVisualsAll;
868f7df2e56Smrg        }
869f7df2e56Smrg        else {
870f7df2e56Smrg            xf86Msg(X_WARNING, "Unknown GlxVisuals option\n");
871f7df2e56Smrg        }
872637ac9abSmrg    }
873637ac9abSmrg
874f7df2e56Smrg    if (xf86Info.iglxFrom != X_CMDLINE) {
875f7df2e56Smrg        if (xf86GetOptValBool(FlagOptions, FLAG_IGLX, &value)) {
876f7df2e56Smrg            enableIndirectGLX = value;
877f7df2e56Smrg            xf86Info.iglxFrom = X_CONFIG;
878f7df2e56Smrg        }
879637ac9abSmrg    }
880637ac9abSmrg#endif
881637ac9abSmrg
8827e31ba66Smrg    xf86Info.debug = xf86GetOptValString(FlagOptions, FLAG_DEBUG);
8837e31ba66Smrg
88465b04b38Smrg    /* if we're not hotplugging, force some input devices to exist */
885f7df2e56Smrg    xf86Info.forceInputDevices = !(xf86Info.autoAddDevices &&
886f7df2e56Smrg                                   xf86Info.autoEnableDevices);
887637ac9abSmrg
88865b04b38Smrg    /* when forcing input devices, we use kbd. otherwise evdev, so use the
88965b04b38Smrg     * evdev rules set. */
8907e31ba66Smrg#if defined(__linux__)
89165b04b38Smrg    if (!xf86Info.forceInputDevices)
892f7df2e56Smrg        rules = "evdev";
893f7df2e56Smrg    else
894637ac9abSmrg#endif
895f7df2e56Smrg        rules = "base";
896f7df2e56Smrg
897f7df2e56Smrg    /* Xkb default options. */
898f7df2e56Smrg    XkbInitRules(&set, rules, "pc105", "us", NULL, NULL);
8994202a189Smrg    XkbSetRulesDflts(&set);
900f7df2e56Smrg    XkbFreeRMLVOSet(&set, FALSE);
90105b261ecSmrg
90205b261ecSmrg    xf86Info.useDefaultFontPath = TRUE;
90305b261ecSmrg    if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
904f7df2e56Smrg        xf86Info.useDefaultFontPath = value;
90505b261ecSmrg    }
90605b261ecSmrg
90705b261ecSmrg/* Make sure that timers don't overflow CARD32's after multiplying */
90805b261ecSmrg#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
90905b261ecSmrg
91005b261ecSmrg    i = -1;
91105b261ecSmrg    xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
91205b261ecSmrg    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
913f7df2e56Smrg        ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
91405b261ecSmrg    else if (i != -1)
915f7df2e56Smrg        ErrorF("BlankTime value %d outside legal range of 0 - %d minutes\n",
916f7df2e56Smrg               i, MAX_TIME_IN_MIN);
91705b261ecSmrg
91805b261ecSmrg#ifdef DPMSExtension
91905b261ecSmrg    i = -1;
92005b261ecSmrg    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
92105b261ecSmrg    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
922f7df2e56Smrg        DPMSStandbyTime = i * MILLI_PER_MIN;
92305b261ecSmrg    else if (i != -1)
924f7df2e56Smrg        ErrorF("StandbyTime value %d outside legal range of 0 - %d minutes\n",
925f7df2e56Smrg               i, MAX_TIME_IN_MIN);
92605b261ecSmrg    i = -1;
92705b261ecSmrg    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
92805b261ecSmrg    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
929f7df2e56Smrg        DPMSSuspendTime = i * MILLI_PER_MIN;
93005b261ecSmrg    else if (i != -1)
931f7df2e56Smrg        ErrorF("SuspendTime value %d outside legal range of 0 - %d minutes\n",
932f7df2e56Smrg               i, MAX_TIME_IN_MIN);
93305b261ecSmrg    i = -1;
93405b261ecSmrg    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
93505b261ecSmrg    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
936f7df2e56Smrg        DPMSOffTime = i * MILLI_PER_MIN;
93705b261ecSmrg    else if (i != -1)
938f7df2e56Smrg        ErrorF("OffTime value %d outside legal range of 0 - %d minutes\n",
939f7df2e56Smrg               i, MAX_TIME_IN_MIN);
94005b261ecSmrg#endif
94105b261ecSmrg
94205b261ecSmrg#ifdef PANORAMIX
94305b261ecSmrg    from = X_DEFAULT;
94405b261ecSmrg    if (!noPanoramiXExtension)
945f7df2e56Smrg        from = X_CMDLINE;
94605b261ecSmrg    else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
947f7df2e56Smrg        noPanoramiXExtension = !value;
948f7df2e56Smrg        from = X_CONFIG;
94905b261ecSmrg    }
95005b261ecSmrg    if (!noPanoramiXExtension)
951f7df2e56Smrg        xf86Msg(from, "Xinerama: enabled\n");
95205b261ecSmrg#endif
95305b261ecSmrg
954637ac9abSmrg#ifdef DRI2
955637ac9abSmrg    xf86Info.dri2 = FALSE;
956637ac9abSmrg    xf86Info.dri2From = X_DEFAULT;
957637ac9abSmrg    if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
958f7df2e56Smrg        xf86Info.dri2 = value;
959f7df2e56Smrg        xf86Info.dri2From = X_CONFIG;
960637ac9abSmrg    }
961637ac9abSmrg#endif
962637ac9abSmrg
963f7df2e56Smrg    from = X_DEFAULT;
964f7df2e56Smrg    if (LimitClients != LIMITCLIENTS)
965f7df2e56Smrg	from = X_CMDLINE;
966f7df2e56Smrg    i = -1;
967f7df2e56Smrg    if (xf86GetOptValInteger(FlagOptions, FLAG_MAX_CLIENTS, &i)) {
9687e31ba66Smrg        if (Ones(i) != 1 || i < 64 || i > 2048) {
9697e31ba66Smrg	    ErrorF("MaxClients must be one of 64, 128, 256, 512, 1024, or 2048\n");
9707e31ba66Smrg        } else {
9717e31ba66Smrg            from = X_CONFIG;
9727e31ba66Smrg            LimitClients = i;
9737e31ba66Smrg        }
974f7df2e56Smrg    }
975f7df2e56Smrg    xf86Msg(from, "Max clients allowed: %i, resource mask: 0x%x\n",
976f7df2e56Smrg	    LimitClients, RESOURCE_ID_MASK);
97705b261ecSmrg}
97805b261ecSmrg
979f7df2e56SmrgBool
980f7df2e56Smrgxf86DRI2Enabled(void)
981637ac9abSmrg{
982637ac9abSmrg    return xf86Info.dri2;
983637ac9abSmrg}
984637ac9abSmrg
985f7df2e56Smrg/**
986f7df2e56Smrg * Search for the pInfo in the null-terminated list given and remove (and
987f7df2e56Smrg * free) it if present. All other devices are moved forward.
988f7df2e56Smrg */
989f7df2e56Smrgstatic void
990f7df2e56SmrgfreeDevice(InputInfoPtr * list, InputInfoPtr pInfo)
991f7df2e56Smrg{
992f7df2e56Smrg    InputInfoPtr *devs;
993f7df2e56Smrg
994f7df2e56Smrg    for (devs = list; devs && *devs; devs++) {
995f7df2e56Smrg        if (*devs == pInfo) {
996f7df2e56Smrg            free(*devs);
997f7df2e56Smrg            for (; devs && *devs; devs++)
998f7df2e56Smrg                devs[0] = devs[1];
999f7df2e56Smrg            break;
1000f7df2e56Smrg        }
1001f7df2e56Smrg    }
1002f7df2e56Smrg}
1003f7df2e56Smrg
1004f7df2e56Smrg/**
1005f7df2e56Smrg * Append pInfo to the null-terminated list, allocating space as necessary.
1006f7df2e56Smrg * pInfo is used as the last element.
1007f7df2e56Smrg */
1008f7df2e56Smrgstatic InputInfoPtr *
1009f7df2e56SmrgaddDevice(InputInfoPtr * list, InputInfoPtr pInfo)
1010f7df2e56Smrg{
1011f7df2e56Smrg    InputInfoPtr *devs;
1012f7df2e56Smrg    int count = 1;
1013f7df2e56Smrg
1014f7df2e56Smrg    for (devs = list; devs && *devs; devs++)
1015f7df2e56Smrg        count++;
1016f7df2e56Smrg
1017f7df2e56Smrg    list = xnfreallocarray(list, count + 1, sizeof(InputInfoPtr));
1018f7df2e56Smrg    list[count] = NULL;
1019f7df2e56Smrg
1020f7df2e56Smrg    list[count - 1] = pInfo;
1021f7df2e56Smrg    return list;
1022f7df2e56Smrg}
1023f7df2e56Smrg
102405b261ecSmrg/*
102505b261ecSmrg * Locate the core input devices.  These can be specified/located in
102605b261ecSmrg * the following ways, in order of priority:
102705b261ecSmrg *
102805b261ecSmrg *  1. The InputDevices named by the -pointer and -keyboard command line
102905b261ecSmrg *     options.
103005b261ecSmrg *  2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
103105b261ecSmrg *     the active ServerLayout.
103205b261ecSmrg *  3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
10334202a189Smrg *  4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
10344202a189Smrg *     driver (mouse, synaptics, evdev, vmmouse, void)
103505b261ecSmrg *  5. Default devices with an empty (default) configuration.  These defaults
103605b261ecSmrg *     will reference the 'mouse' and 'keyboard' drivers.
103705b261ecSmrg */
103805b261ecSmrg
103905b261ecSmrgstatic Bool
104005b261ecSmrgcheckCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
104105b261ecSmrg{
104265b04b38Smrg    InputInfoPtr corePointer = NULL, coreKeyboard = NULL;
104305b261ecSmrg    Bool foundPointer = FALSE, foundKeyboard = FALSE;
104405b261ecSmrg    const char *pointerMsg = NULL, *keyboardMsg = NULL;
1045f7df2e56Smrg    InputInfoPtr *devs,         /* iterator */
1046f7df2e56Smrg     indp;
1047f7df2e56Smrg    InputInfoPtr Pointer, Keyboard;
104805b261ecSmrg    XF86ConfInputPtr confInput;
104905b261ecSmrg    XF86ConfInputRec defPtr, defKbd;
105005b261ecSmrg    MessageType from = X_DEFAULT;
1051f7df2e56Smrg
10524202a189Smrg    const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
1053f7df2e56Smrg        "void", NULL
1054f7df2e56Smrg    };
105505b261ecSmrg
105605b261ecSmrg    /*
105705b261ecSmrg     * First check if a core pointer or core keyboard have been specified
105805b261ecSmrg     * in the active ServerLayout.  If more than one is specified for either,
105905b261ecSmrg     * remove the core attribute from the later ones.
106005b261ecSmrg     */
106105b261ecSmrg    for (devs = servlayoutp->inputs; devs && *devs; devs++) {
1062637ac9abSmrg        indp = *devs;
1063f7df2e56Smrg        if (indp->options &&
1064f7df2e56Smrg            xf86CheckBoolOption(indp->options, "CorePointer", FALSE)) {
1065f7df2e56Smrg            if (!corePointer) {
1066f7df2e56Smrg                corePointer = indp;
1067f7df2e56Smrg            }
1068f7df2e56Smrg        }
1069f7df2e56Smrg        if (indp->options &&
1070f7df2e56Smrg            xf86CheckBoolOption(indp->options, "CoreKeyboard", FALSE)) {
1071f7df2e56Smrg            if (!coreKeyboard) {
1072f7df2e56Smrg                coreKeyboard = indp;
1073f7df2e56Smrg            }
1074f7df2e56Smrg        }
107505b261ecSmrg    }
107605b261ecSmrg
107705b261ecSmrg    confInput = NULL;
107805b261ecSmrg
107905b261ecSmrg    /* 1. Check for the -pointer command line option. */
108005b261ecSmrg    if (xf86PointerName) {
1081f7df2e56Smrg        confInput = xf86findInput(xf86PointerName,
1082f7df2e56Smrg                                  xf86configptr->conf_input_lst);
1083f7df2e56Smrg        if (!confInput) {
1084f7df2e56Smrg            xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1085f7df2e56Smrg                    xf86PointerName);
1086f7df2e56Smrg            return FALSE;
1087f7df2e56Smrg        }
1088f7df2e56Smrg        from = X_CMDLINE;
1089f7df2e56Smrg        /*
1090f7df2e56Smrg         * If one was already specified in the ServerLayout, it needs to be
1091f7df2e56Smrg         * removed.
1092f7df2e56Smrg         */
1093f7df2e56Smrg        if (corePointer) {
1094f7df2e56Smrg            freeDevice(servlayoutp->inputs, corePointer);
1095f7df2e56Smrg            corePointer = NULL;
1096f7df2e56Smrg        }
1097f7df2e56Smrg        foundPointer = TRUE;
109805b261ecSmrg    }
109905b261ecSmrg
110005b261ecSmrg    /* 2. ServerLayout-specified core pointer. */
110105b261ecSmrg    if (corePointer) {
1102f7df2e56Smrg        foundPointer = TRUE;
1103f7df2e56Smrg        from = X_CONFIG;
110405b261ecSmrg    }
110505b261ecSmrg
110605b261ecSmrg    /* 3. First core pointer device. */
110765b04b38Smrg    if (!foundPointer && (xf86Info.forceInputDevices || implicitLayout)) {
1108f7df2e56Smrg        XF86ConfInputPtr p;
1109f7df2e56Smrg
1110f7df2e56Smrg        for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1111f7df2e56Smrg            if (p->inp_option_lst &&
1112f7df2e56Smrg                xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
1113f7df2e56Smrg                confInput = p;
1114f7df2e56Smrg                foundPointer = TRUE;
1115f7df2e56Smrg                from = X_DEFAULT;
1116f7df2e56Smrg                pointerMsg = "first core pointer device";
1117f7df2e56Smrg                break;
1118f7df2e56Smrg            }
1119f7df2e56Smrg        }
112005b261ecSmrg    }
112105b261ecSmrg
11224202a189Smrg    /* 4. First pointer with an allowed mouse driver. */
112365b04b38Smrg    if (!foundPointer && xf86Info.forceInputDevices) {
1124f7df2e56Smrg        const char **driver = mousedrivers;
1125f7df2e56Smrg
1126f7df2e56Smrg        confInput = xf86findInput(CONF_IMPLICIT_POINTER,
1127f7df2e56Smrg                                  xf86configptr->conf_input_lst);
1128f7df2e56Smrg        while (*driver && !confInput) {
1129f7df2e56Smrg            confInput = xf86findInputByDriver(*driver,
1130f7df2e56Smrg                                              xf86configptr->conf_input_lst);
1131f7df2e56Smrg            driver++;
1132f7df2e56Smrg        }
1133f7df2e56Smrg        if (confInput) {
1134f7df2e56Smrg            foundPointer = TRUE;
1135f7df2e56Smrg            from = X_DEFAULT;
1136f7df2e56Smrg            pointerMsg = "first mouse device";
1137f7df2e56Smrg        }
113805b261ecSmrg    }
113905b261ecSmrg
114005b261ecSmrg    /* 5. Built-in default. */
114165b04b38Smrg    if (!foundPointer && xf86Info.forceInputDevices) {
1142f7df2e56Smrg        memset(&defPtr, 0, sizeof(defPtr));
1143f7df2e56Smrg        defPtr.inp_identifier = strdup("<default pointer>");
114423e2f35bSjmcneill#if defined(__NetBSD__) && (defined(__i386__) || defined(__amd64__))
114523e2f35bSjmcneill	if (xf86findDeviceByDriver("vmware", xf86configptr->conf_device_lst) ||
114623e2f35bSjmcneill	    xf86findDeviceByDriver("vmwlegacy", xf86configptr->conf_device_lst)) {
114723e2f35bSjmcneill		defPtr.inp_driver = strdup("vmmouse");
114823e2f35bSjmcneill		defPtr.inp_option_lst = xf86addNewOption(defPtr.inp_option_lst, strdup("Protocol"), "wsmouse");
114923e2f35bSjmcneill		defPtr.inp_option_lst = xf86addNewOption(defPtr.inp_option_lst, strdup("Device"), "/dev/wsmouse");
1150f7df2e56Smrg	} else {
1151f7df2e56Smrg#endif
1152f7df2e56Smrg        defPtr.inp_driver = strdup("mouse");
1153dcbd449dSsnj#if defined(__NetBSD__) && (defined(__i386__) || defined(__amd64__))
1154dcbd449dSsnj        }
1155dcbd449dSsnj#endif
1156f7df2e56Smrg        confInput = &defPtr;
1157f7df2e56Smrg        foundPointer = TRUE;
1158f7df2e56Smrg        from = X_DEFAULT;
1159f7df2e56Smrg        pointerMsg = "default mouse configuration";
116005b261ecSmrg    }
116105b261ecSmrg
116205b261ecSmrg    /* Add the core pointer device to the layout, and set it to Core. */
116305b261ecSmrg    if (foundPointer && confInput) {
1164f7df2e56Smrg        Pointer = xf86AllocateInput();
1165f7df2e56Smrg        if (Pointer)
1166f7df2e56Smrg            foundPointer = configInput(Pointer, confInput, from);
116705b261ecSmrg        if (foundPointer) {
1168f7df2e56Smrg            Pointer->options = xf86AddNewOption(Pointer->options,
1169f7df2e56Smrg                                                "CorePointer", "on");
1170f7df2e56Smrg            Pointer->options = xf86AddNewOption(Pointer->options,
1171f7df2e56Smrg                                                "driver",
1172f7df2e56Smrg                                                confInput->inp_driver);
1173f7df2e56Smrg            Pointer->options =
1174f7df2e56Smrg                xf86AddNewOption(Pointer->options, "identifier",
1175f7df2e56Smrg                                 confInput->inp_identifier);
1176f7df2e56Smrg            servlayoutp->inputs = addDevice(servlayoutp->inputs, Pointer);
1177f7df2e56Smrg        }
117805b261ecSmrg    }
117905b261ecSmrg
118065b04b38Smrg    if (!foundPointer && xf86Info.forceInputDevices) {
1181f7df2e56Smrg        /* This shouldn't happen. */
1182f7df2e56Smrg        xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
1183f7df2e56Smrg        xf86DeleteInput(Pointer, 0);
1184f7df2e56Smrg        return FALSE;
118505b261ecSmrg    }
118605b261ecSmrg
118705b261ecSmrg    confInput = NULL;
118805b261ecSmrg
118905b261ecSmrg    /* 1. Check for the -keyboard command line option. */
119005b261ecSmrg    if (xf86KeyboardName) {
1191f7df2e56Smrg        confInput = xf86findInput(xf86KeyboardName,
1192f7df2e56Smrg                                  xf86configptr->conf_input_lst);
1193f7df2e56Smrg        if (!confInput) {
1194f7df2e56Smrg            xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1195f7df2e56Smrg                    xf86KeyboardName);
1196f7df2e56Smrg            return FALSE;
1197f7df2e56Smrg        }
1198f7df2e56Smrg        from = X_CMDLINE;
1199f7df2e56Smrg        /*
1200f7df2e56Smrg         * If one was already specified in the ServerLayout, it needs to be
1201f7df2e56Smrg         * removed.
1202f7df2e56Smrg         */
1203f7df2e56Smrg        if (coreKeyboard) {
1204f7df2e56Smrg            freeDevice(servlayoutp->inputs, coreKeyboard);
1205f7df2e56Smrg            coreKeyboard = NULL;
1206f7df2e56Smrg        }
1207f7df2e56Smrg        foundKeyboard = TRUE;
120805b261ecSmrg    }
120905b261ecSmrg
121005b261ecSmrg    /* 2. ServerLayout-specified core keyboard. */
121105b261ecSmrg    if (coreKeyboard) {
1212f7df2e56Smrg        foundKeyboard = TRUE;
1213f7df2e56Smrg        from = X_CONFIG;
121405b261ecSmrg    }
121505b261ecSmrg
121605b261ecSmrg    /* 3. First core keyboard device. */
121765b04b38Smrg    if (!foundKeyboard && (xf86Info.forceInputDevices || implicitLayout)) {
1218f7df2e56Smrg        XF86ConfInputPtr p;
1219f7df2e56Smrg
1220f7df2e56Smrg        for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1221f7df2e56Smrg            if (p->inp_option_lst &&
1222f7df2e56Smrg                xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
1223f7df2e56Smrg                confInput = p;
1224f7df2e56Smrg                foundKeyboard = TRUE;
1225f7df2e56Smrg                from = X_DEFAULT;
1226f7df2e56Smrg                keyboardMsg = "first core keyboard device";
1227f7df2e56Smrg                break;
1228f7df2e56Smrg            }
1229f7df2e56Smrg        }
123005b261ecSmrg    }
123105b261ecSmrg
123205b261ecSmrg    /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
123365b04b38Smrg    if (!foundKeyboard && xf86Info.forceInputDevices) {
1234f7df2e56Smrg        confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
1235f7df2e56Smrg                                  xf86configptr->conf_input_lst);
1236f7df2e56Smrg        if (!confInput) {
1237f7df2e56Smrg            confInput = xf86findInputByDriver("kbd",
1238f7df2e56Smrg                                              xf86configptr->conf_input_lst);
1239f7df2e56Smrg        }
1240f7df2e56Smrg        if (confInput) {
1241f7df2e56Smrg            foundKeyboard = TRUE;
1242f7df2e56Smrg            from = X_DEFAULT;
1243f7df2e56Smrg            keyboardMsg = "first keyboard device";
1244f7df2e56Smrg        }
124505b261ecSmrg    }
124605b261ecSmrg
124705b261ecSmrg    /* 5. Built-in default. */
124865b04b38Smrg    if (!foundKeyboard && xf86Info.forceInputDevices) {
1249f7df2e56Smrg        memset(&defKbd, 0, sizeof(defKbd));
1250f7df2e56Smrg        defKbd.inp_identifier = strdup("<default keyboard>");
1251f7df2e56Smrg        defKbd.inp_driver = strdup("kbd");
1252f7df2e56Smrg        confInput = &defKbd;
1253f7df2e56Smrg        foundKeyboard = TRUE;
1254f7df2e56Smrg        keyboardMsg = "default keyboard configuration";
1255f7df2e56Smrg        from = X_DEFAULT;
125605b261ecSmrg    }
125705b261ecSmrg
125805b261ecSmrg    /* Add the core keyboard device to the layout, and set it to Core. */
125905b261ecSmrg    if (foundKeyboard && confInput) {
1260f7df2e56Smrg        Keyboard = xf86AllocateInput();
1261f7df2e56Smrg        if (Keyboard)
1262f7df2e56Smrg            foundKeyboard = configInput(Keyboard, confInput, from);
126305b261ecSmrg        if (foundKeyboard) {
1264f7df2e56Smrg            Keyboard->options = xf86AddNewOption(Keyboard->options,
1265f7df2e56Smrg                                                 "CoreKeyboard", "on");
1266f7df2e56Smrg            Keyboard->options = xf86AddNewOption(Keyboard->options,
1267f7df2e56Smrg                                                 "driver",
1268f7df2e56Smrg                                                 confInput->inp_driver);
1269f7df2e56Smrg            Keyboard->options =
1270f7df2e56Smrg                xf86AddNewOption(Keyboard->options, "identifier",
1271f7df2e56Smrg                                 confInput->inp_identifier);
1272f7df2e56Smrg            servlayoutp->inputs = addDevice(servlayoutp->inputs, Keyboard);
1273f7df2e56Smrg        }
127405b261ecSmrg    }
127505b261ecSmrg
127665b04b38Smrg    if (!foundKeyboard && xf86Info.forceInputDevices) {
1277f7df2e56Smrg        /* This shouldn't happen. */
1278f7df2e56Smrg        xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
1279f7df2e56Smrg        xf86DeleteInput(Keyboard, 0);
1280f7df2e56Smrg        return FALSE;
128105b261ecSmrg    }
128205b261ecSmrg
128305b261ecSmrg    if (pointerMsg) {
1284f7df2e56Smrg        if (implicitLayout)
1285f7df2e56Smrg            xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1286f7df2e56Smrg                    pointerMsg);
1287f7df2e56Smrg        else
1288f7df2e56Smrg            xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
1289f7df2e56Smrg                    "explicitly in the layout.\n"
1290f7df2e56Smrg                    "\tUsing the %s.\n", pointerMsg);
129105b261ecSmrg    }
129205b261ecSmrg
129305b261ecSmrg    if (keyboardMsg) {
1294f7df2e56Smrg        if (implicitLayout)
1295f7df2e56Smrg            xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1296f7df2e56Smrg                    keyboardMsg);
1297f7df2e56Smrg        else
1298f7df2e56Smrg            xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
1299f7df2e56Smrg                    "explicitly in the layout.\n"
1300f7df2e56Smrg                    "\tUsing the %s.\n", keyboardMsg);
1301637ac9abSmrg    }
1302637ac9abSmrg
130365b04b38Smrg    if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) {
1304f7df2e56Smrg#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS)
1305f7df2e56Smrg        const char *config_backend;
1306f7df2e56Smrg
13074202a189Smrg#if defined(CONFIG_HAL)
1308f7df2e56Smrg        config_backend = "HAL";
1309f7df2e56Smrg#elif defined(CONFIG_UDEV)
1310f7df2e56Smrg        config_backend = "udev";
13114202a189Smrg#else
1312f7df2e56Smrg        config_backend = "wscons";
13134202a189Smrg#endif
1314f7df2e56Smrg        xf86Msg(X_INFO, "The server relies on %s to provide the list of "
1315f7df2e56Smrg                "input devices.\n\tIf no devices become available, "
1316f7df2e56Smrg                "reconfigure %s or disable AutoAddDevices.\n",
1317f7df2e56Smrg                config_backend, config_backend);
1318637ac9abSmrg#else
1319f7df2e56Smrg        xf86Msg(X_WARNING, "Hotplugging requested but the server was "
1320f7df2e56Smrg                "compiled without a config backend. "
1321f7df2e56Smrg                "No input devices were configured, the server "
1322f7df2e56Smrg                "will start without any input devices.\n");
1323637ac9abSmrg#endif
132405b261ecSmrg    }
132505b261ecSmrg
132605b261ecSmrg    return TRUE;
132705b261ecSmrg}
132805b261ecSmrg
132905b261ecSmrgtypedef enum {
133005b261ecSmrg    LAYOUT_ISOLATEDEVICE,
133105b261ecSmrg    LAYOUT_SINGLECARD
133205b261ecSmrg} LayoutValues;
133305b261ecSmrg
133405b261ecSmrgstatic OptionInfoRec LayoutOptions[] = {
1335f7df2e56Smrg    {LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
1336f7df2e56Smrg     {0}, FALSE},
1337f7df2e56Smrg    {LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
1338f7df2e56Smrg     {0}, FALSE},
1339f7df2e56Smrg    {-1, NULL, OPTV_NONE,
1340f7df2e56Smrg     {0}, FALSE},
134105b261ecSmrg};
134205b261ecSmrg
13434202a189Smrgstatic Bool
13444202a189SmrgconfigInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
13454202a189Smrg{
13464202a189Smrg    XF86ConfInputrefPtr irp;
134765b04b38Smrg    InputInfoPtr *indp;
13484202a189Smrg    int count = 0;
13494202a189Smrg
13504202a189Smrg    /*
13514202a189Smrg     * Count the number of input devices.
13524202a189Smrg     */
13534202a189Smrg    irp = layout->lay_input_lst;
13544202a189Smrg    while (irp) {
1355f7df2e56Smrg        count++;
1356f7df2e56Smrg        irp = (XF86ConfInputrefPtr) irp->list.next;
13574202a189Smrg    }
13584202a189Smrg    DebugF("Found %d input devices in the layout section %s\n",
1359f7df2e56Smrg           count, layout->lay_identifier);
136065b04b38Smrg    indp = xnfcalloc((count + 1), sizeof(InputInfoPtr));
13614202a189Smrg    indp[count] = NULL;
13624202a189Smrg    irp = layout->lay_input_lst;
13634202a189Smrg    count = 0;
13644202a189Smrg    while (irp) {
1365f7df2e56Smrg        indp[count] = xf86AllocateInput();
1366f7df2e56Smrg        if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
1367f7df2e56Smrg            do {
1368f7df2e56Smrg                free(indp[count]);
1369f7df2e56Smrg            } while (count--);
1370f7df2e56Smrg            free(indp);
1371f7df2e56Smrg            return FALSE;
1372f7df2e56Smrg        }
1373f7df2e56Smrg        indp[count]->options = xf86OptionListMerge(indp[count]->options,
1374f7df2e56Smrg                                                   irp->iref_option_lst);
1375f7df2e56Smrg        count++;
1376f7df2e56Smrg        irp = (XF86ConfInputrefPtr) irp->list.next;
13774202a189Smrg    }
13784202a189Smrg    servlayoutp->inputs = indp;
13794202a189Smrg
13804202a189Smrg    return TRUE;
13814202a189Smrg}
13824202a189Smrg
138305b261ecSmrg/*
138405b261ecSmrg * figure out which layout is active, which screens are used in that layout,
138505b261ecSmrg * which drivers and monitors are used in these screens
138605b261ecSmrg */
138705b261ecSmrgstatic Bool
138805b261ecSmrgconfigLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
1389f7df2e56Smrg             char *default_layout)
139005b261ecSmrg{
139105b261ecSmrg    XF86ConfAdjacencyPtr adjp;
139205b261ecSmrg    XF86ConfInactivePtr idp;
139365b04b38Smrg    int saved_count, count = 0;
139405b261ecSmrg    int scrnum;
139505b261ecSmrg    XF86ConfLayoutPtr l;
139605b261ecSmrg    MessageType from;
139705b261ecSmrg    screenLayoutPtr slp;
139805b261ecSmrg    GDevPtr gdp;
139905b261ecSmrg    int i = 0, j;
140005b261ecSmrg
140105b261ecSmrg    if (!servlayoutp)
1402f7df2e56Smrg        return FALSE;
140305b261ecSmrg
140405b261ecSmrg    /*
140505b261ecSmrg     * which layout section is the active one?
140605b261ecSmrg     *
140705b261ecSmrg     * If there is a -layout command line option, use that one, otherwise
140805b261ecSmrg     * pick the first one.
140905b261ecSmrg     */
141005b261ecSmrg    from = X_DEFAULT;
141105b261ecSmrg    if (xf86LayoutName != NULL)
1412f7df2e56Smrg        from = X_CMDLINE;
141305b261ecSmrg    else if (default_layout) {
1414f7df2e56Smrg        xf86LayoutName = default_layout;
1415f7df2e56Smrg        from = X_CONFIG;
141605b261ecSmrg    }
141705b261ecSmrg    if (xf86LayoutName != NULL) {
1418f7df2e56Smrg        if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
1419f7df2e56Smrg            xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
1420f7df2e56Smrg                    xf86LayoutName);
1421f7df2e56Smrg            return FALSE;
1422f7df2e56Smrg        }
1423f7df2e56Smrg        conf_layout = l;
142405b261ecSmrg    }
142505b261ecSmrg    xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
142605b261ecSmrg    adjp = conf_layout->lay_adjacency_lst;
142705b261ecSmrg
142805b261ecSmrg    /*
142905b261ecSmrg     * we know that each screen is referenced exactly once on the left side
143005b261ecSmrg     * of a layout statement in the Layout section. So to allocate the right
143105b261ecSmrg     * size for the array we do a quick walk of the list to figure out how
143205b261ecSmrg     * many sections we have
143305b261ecSmrg     */
143405b261ecSmrg    while (adjp) {
143505b261ecSmrg        count++;
1436f7df2e56Smrg        adjp = (XF86ConfAdjacencyPtr) adjp->list.next;
143705b261ecSmrg    }
1438637ac9abSmrg
14394202a189Smrg    DebugF("Found %d screens in the layout section %s",
144005b261ecSmrg           count, conf_layout->lay_identifier);
1441f7df2e56Smrg    if (!count)                 /* alloc enough storage even if no screen is specified */
1442637ac9abSmrg        count = 1;
1443637ac9abSmrg
1444f7df2e56Smrg    slp = xnfcalloc((count + 1), sizeof(screenLayoutRec));
144505b261ecSmrg    slp[count].screen = NULL;
144605b261ecSmrg    /*
144705b261ecSmrg     * now that we have storage, loop over the list again and fill in our
144805b261ecSmrg     * data structure; at this point we do not fill in the adjacency
144905b261ecSmrg     * information as it is not clear if we need it at all
145005b261ecSmrg     */
145105b261ecSmrg    adjp = conf_layout->lay_adjacency_lst;
145205b261ecSmrg    count = 0;
145305b261ecSmrg    while (adjp) {
145405b261ecSmrg        slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
1455f7df2e56Smrg        if (adjp->adj_scrnum < 0)
1456f7df2e56Smrg            scrnum = count;
1457f7df2e56Smrg        else
1458f7df2e56Smrg            scrnum = adjp->adj_scrnum;
1459f7df2e56Smrg        if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
1460f7df2e56Smrg                          X_CONFIG, (scrnum == 0 && !adjp->list.next))) {
1461f7df2e56Smrg            do {
1462f7df2e56Smrg                free(slp[count].screen);
1463f7df2e56Smrg            } while (count--);
1464f7df2e56Smrg            free(slp);
1465f7df2e56Smrg            return FALSE;
1466f7df2e56Smrg        }
1467f7df2e56Smrg        slp[count].x = adjp->adj_x;
1468f7df2e56Smrg        slp[count].y = adjp->adj_y;
1469f7df2e56Smrg        slp[count].refname = adjp->adj_refscreen;
1470f7df2e56Smrg        switch (adjp->adj_where) {
1471f7df2e56Smrg        case CONF_ADJ_OBSOLETE:
1472f7df2e56Smrg            slp[count].where = PosObsolete;
1473f7df2e56Smrg            slp[count].topname = adjp->adj_top_str;
1474f7df2e56Smrg            slp[count].bottomname = adjp->adj_bottom_str;
1475f7df2e56Smrg            slp[count].leftname = adjp->adj_left_str;
1476f7df2e56Smrg            slp[count].rightname = adjp->adj_right_str;
1477f7df2e56Smrg            break;
1478f7df2e56Smrg        case CONF_ADJ_ABSOLUTE:
1479f7df2e56Smrg            slp[count].where = PosAbsolute;
1480f7df2e56Smrg            break;
1481f7df2e56Smrg        case CONF_ADJ_RIGHTOF:
1482f7df2e56Smrg            slp[count].where = PosRightOf;
1483f7df2e56Smrg            break;
1484f7df2e56Smrg        case CONF_ADJ_LEFTOF:
1485f7df2e56Smrg            slp[count].where = PosLeftOf;
1486f7df2e56Smrg            break;
1487f7df2e56Smrg        case CONF_ADJ_ABOVE:
1488f7df2e56Smrg            slp[count].where = PosAbove;
1489f7df2e56Smrg            break;
1490f7df2e56Smrg        case CONF_ADJ_BELOW:
1491f7df2e56Smrg            slp[count].where = PosBelow;
1492f7df2e56Smrg            break;
1493f7df2e56Smrg        case CONF_ADJ_RELATIVE:
1494f7df2e56Smrg            slp[count].where = PosRelative;
1495f7df2e56Smrg            break;
1496f7df2e56Smrg        }
149705b261ecSmrg        count++;
1498f7df2e56Smrg        adjp = (XF86ConfAdjacencyPtr) adjp->list.next;
149905b261ecSmrg    }
150005b261ecSmrg
1501637ac9abSmrg    /* No screen was specified in the layout. take the first one from the
1502637ac9abSmrg     * config file, or - if it is NULL - configScreen autogenerates one for
1503637ac9abSmrg     * us */
1504f7df2e56Smrg    if (!count) {
1505f7df2e56Smrg        XF86ConfScreenPtr screen;
1506f7df2e56Smrg
1507f7df2e56Smrg        FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen);
1508637ac9abSmrg        slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1509f7df2e56Smrg        if (!configScreen(slp[0].screen, screen,
1510f7df2e56Smrg                          0, X_CONFIG, TRUE)) {
1511f7df2e56Smrg            free(slp[0].screen);
1512f7df2e56Smrg            free(slp);
1513f7df2e56Smrg            return FALSE;
1514f7df2e56Smrg        }
1515637ac9abSmrg    }
1516637ac9abSmrg
151705b261ecSmrg    /* XXX Need to tie down the upper left screen. */
151805b261ecSmrg
151905b261ecSmrg    /* Fill in the refscreen and top/bottom/left/right values */
152005b261ecSmrg    for (i = 0; i < count; i++) {
1521f7df2e56Smrg        for (j = 0; j < count; j++) {
1522f7df2e56Smrg            if (slp[i].refname &&
1523f7df2e56Smrg                strcmp(slp[i].refname, slp[j].screen->id) == 0) {
1524f7df2e56Smrg                slp[i].refscreen = slp[j].screen;
1525f7df2e56Smrg            }
1526f7df2e56Smrg            if (slp[i].topname &&
1527f7df2e56Smrg                strcmp(slp[i].topname, slp[j].screen->id) == 0) {
1528f7df2e56Smrg                slp[i].top = slp[j].screen;
1529f7df2e56Smrg            }
1530f7df2e56Smrg            if (slp[i].bottomname &&
1531f7df2e56Smrg                strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
1532f7df2e56Smrg                slp[i].bottom = slp[j].screen;
1533f7df2e56Smrg            }
1534f7df2e56Smrg            if (slp[i].leftname &&
1535f7df2e56Smrg                strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
1536f7df2e56Smrg                slp[i].left = slp[j].screen;
1537f7df2e56Smrg            }
1538f7df2e56Smrg            if (slp[i].rightname &&
1539f7df2e56Smrg                strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
1540f7df2e56Smrg                slp[i].right = slp[j].screen;
1541f7df2e56Smrg            }
1542f7df2e56Smrg        }
1543f7df2e56Smrg        if (slp[i].where != PosObsolete
1544f7df2e56Smrg            && slp[i].where != PosAbsolute && !slp[i].refscreen) {
1545f7df2e56Smrg            xf86Msg(X_ERROR, "Screen %s doesn't exist: deleting placement\n",
1546f7df2e56Smrg                    slp[i].refname);
1547f7df2e56Smrg            slp[i].where = PosAbsolute;
1548f7df2e56Smrg            slp[i].x = 0;
1549f7df2e56Smrg            slp[i].y = 0;
1550f7df2e56Smrg        }
155105b261ecSmrg    }
155205b261ecSmrg
155365b04b38Smrg    if (!count)
1554f7df2e56Smrg        saved_count = 1;
155565b04b38Smrg    else
1556f7df2e56Smrg        saved_count = count;
155705b261ecSmrg    /*
155805b261ecSmrg     * Count the number of inactive devices.
155905b261ecSmrg     */
156005b261ecSmrg    count = 0;
156105b261ecSmrg    idp = conf_layout->lay_inactive_lst;
156205b261ecSmrg    while (idp) {
156305b261ecSmrg        count++;
1564f7df2e56Smrg        idp = (XF86ConfInactivePtr) idp->list.next;
156505b261ecSmrg    }
15664202a189Smrg    DebugF("Found %d inactive devices in the layout section %s\n",
156705b261ecSmrg           count, conf_layout->lay_identifier);
1568f7df2e56Smrg    gdp = xnfallocarray(count + 1, sizeof(GDevRec));
156905b261ecSmrg    gdp[count].identifier = NULL;
157005b261ecSmrg    idp = conf_layout->lay_inactive_lst;
157105b261ecSmrg    count = 0;
157205b261ecSmrg    while (idp) {
1573f7df2e56Smrg        if (!configDevice(&gdp[count], idp->inactive_device, FALSE, FALSE))
1574f7df2e56Smrg            goto bail;
157505b261ecSmrg        count++;
1576f7df2e56Smrg        idp = (XF86ConfInactivePtr) idp->list.next;
157705b261ecSmrg    }
15784202a189Smrg
15794202a189Smrg    if (!configInputDevices(conf_layout, servlayoutp))
1580f7df2e56Smrg        goto bail;
15814202a189Smrg
158205b261ecSmrg    servlayoutp->id = conf_layout->lay_identifier;
158305b261ecSmrg    servlayoutp->screens = slp;
158405b261ecSmrg    servlayoutp->inactives = gdp;
158505b261ecSmrg    servlayoutp->options = conf_layout->lay_option_lst;
158605b261ecSmrg    from = X_DEFAULT;
158705b261ecSmrg
158805b261ecSmrg    return TRUE;
158965b04b38Smrg
1590f7df2e56Smrg bail:
159165b04b38Smrg    do {
1592f7df2e56Smrg        free(slp[saved_count].screen);
1593f7df2e56Smrg    } while (saved_count--);
159465b04b38Smrg    free(slp);
159565b04b38Smrg    free(gdp);
159665b04b38Smrg    return FALSE;
159705b261ecSmrg}
159805b261ecSmrg
159905b261ecSmrg/*
160005b261ecSmrg * No layout section, so find the first Screen section and set that up as
160105b261ecSmrg * the only active screen.
160205b261ecSmrg */
160305b261ecSmrgstatic Bool
16044202a189SmrgconfigImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
1605f7df2e56Smrg                    XF86ConfigPtr conf_ptr)
160605b261ecSmrg{
160705b261ecSmrg    MessageType from;
160805b261ecSmrg    XF86ConfScreenPtr s;
160905b261ecSmrg    screenLayoutPtr slp;
161065b04b38Smrg    InputInfoPtr *indp;
16114202a189Smrg    XF86ConfLayoutRec layout;
161205b261ecSmrg
161305b261ecSmrg    if (!servlayoutp)
1614f7df2e56Smrg        return FALSE;
161505b261ecSmrg
161605b261ecSmrg    /*
161705b261ecSmrg     * which screen section is the active one?
161805b261ecSmrg     *
161905b261ecSmrg     * If there is a -screen option, use that one, otherwise use the first
162005b261ecSmrg     * one.
162105b261ecSmrg     */
162205b261ecSmrg
162305b261ecSmrg    from = X_CONFIG;
162405b261ecSmrg    if (xf86ScreenName != NULL) {
1625f7df2e56Smrg        if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
1626f7df2e56Smrg            xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
1627f7df2e56Smrg                    xf86ScreenName);
1628f7df2e56Smrg            return FALSE;
1629f7df2e56Smrg        }
1630f7df2e56Smrg        conf_screen = s;
1631f7df2e56Smrg        from = X_CMDLINE;
163205b261ecSmrg    }
163305b261ecSmrg
163405b261ecSmrg    /* We have exactly one screen */
163505b261ecSmrg
163605b261ecSmrg    slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
163705b261ecSmrg    slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
163805b261ecSmrg    slp[1].screen = NULL;
1639f7df2e56Smrg    if (!configScreen(slp[0].screen, conf_screen, 0, from, TRUE)) {
1640f7df2e56Smrg        free(slp);
1641f7df2e56Smrg        return FALSE;
164205b261ecSmrg    }
164305b261ecSmrg    servlayoutp->id = "(implicit)";
164405b261ecSmrg    servlayoutp->screens = slp;
164505b261ecSmrg    servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
164605b261ecSmrg    servlayoutp->options = NULL;
16474202a189Smrg
16484202a189Smrg    memset(&layout, 0, sizeof(layout));
16494202a189Smrg    layout.lay_identifier = servlayoutp->id;
1650f7df2e56Smrg    if (xf86layoutAddInputDevices(conf_ptr, &layout) > 0) {
1651f7df2e56Smrg        if (!configInputDevices(&layout, servlayoutp))
1652f7df2e56Smrg            return FALSE;
1653f7df2e56Smrg        from = X_DEFAULT;
1654f7df2e56Smrg    }
1655f7df2e56Smrg    else {
1656f7df2e56Smrg        /* Set up an empty input device list, then look for some core devices. */
1657f7df2e56Smrg        indp = xnfalloc(sizeof(InputInfoPtr));
1658f7df2e56Smrg        *indp = NULL;
1659f7df2e56Smrg        servlayoutp->inputs = indp;
16604202a189Smrg    }
1661637ac9abSmrg
166205b261ecSmrg    return TRUE;
166305b261ecSmrg}
166405b261ecSmrg
166505b261ecSmrgstatic Bool
166605b261ecSmrgconfigXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
166705b261ecSmrg{
166805b261ecSmrg    int count = 0;
166905b261ecSmrg    XF86ConfVideoPortPtr conf_port;
167005b261ecSmrg
167105b261ecSmrg    xf86Msg(X_CONFIG, "|   |-->VideoAdaptor \"%s\"\n",
1672f7df2e56Smrg            conf_adaptor->va_identifier);
167305b261ecSmrg    adaptor->identifier = conf_adaptor->va_identifier;
167405b261ecSmrg    adaptor->options = conf_adaptor->va_option_lst;
167505b261ecSmrg    if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
1676f7df2e56Smrg        xf86Msg(X_CONFIG, "|   | Unsupported device type, skipping entry\n");
1677f7df2e56Smrg        return FALSE;
167805b261ecSmrg    }
167905b261ecSmrg
168005b261ecSmrg    /*
168105b261ecSmrg     * figure out how many videoport subsections there are and fill them in
168205b261ecSmrg     */
168305b261ecSmrg    conf_port = conf_adaptor->va_port_lst;
1684f7df2e56Smrg    while (conf_port) {
168505b261ecSmrg        count++;
1686f7df2e56Smrg        conf_port = (XF86ConfVideoPortPtr) conf_port->list.next;
168705b261ecSmrg    }
1688f7df2e56Smrg    adaptor->ports = xnfallocarray(count, sizeof(confXvPortRec));
168905b261ecSmrg    adaptor->numports = count;
169005b261ecSmrg    count = 0;
169105b261ecSmrg    conf_port = conf_adaptor->va_port_lst;
1692f7df2e56Smrg    while (conf_port) {
1693f7df2e56Smrg        adaptor->ports[count].identifier = conf_port->vp_identifier;
1694f7df2e56Smrg        adaptor->ports[count].options = conf_port->vp_option_lst;
169505b261ecSmrg        count++;
1696f7df2e56Smrg        conf_port = (XF86ConfVideoPortPtr) conf_port->list.next;
169705b261ecSmrg    }
169805b261ecSmrg
169905b261ecSmrg    return TRUE;
170005b261ecSmrg}
170105b261ecSmrg
170205b261ecSmrgstatic Bool
170305b261ecSmrgconfigScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
1704f7df2e56Smrg             MessageType from, Bool auto_gpu_device)
170505b261ecSmrg{
170605b261ecSmrg    int count = 0;
170705b261ecSmrg    XF86ConfDisplayPtr dispptr;
170805b261ecSmrg    XF86ConfAdaptorLinkPtr conf_adaptor;
170905b261ecSmrg    Bool defaultMonitor = FALSE;
171065b04b38Smrg    XF86ConfScreenRec local_conf_screen;
1711f7df2e56Smrg    int i;
171205b261ecSmrg
1713637ac9abSmrg    if (!conf_screen) {
171465b04b38Smrg        memset(&local_conf_screen, 0, sizeof(local_conf_screen));
171565b04b38Smrg        conf_screen = &local_conf_screen;
1716637ac9abSmrg        conf_screen->scrn_identifier = "Default Screen Section";
1717637ac9abSmrg        xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
1718637ac9abSmrg    }
1719637ac9abSmrg
172005b261ecSmrg    xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
1721f7df2e56Smrg            scrnum);
172205b261ecSmrg    /*
172305b261ecSmrg     * now we fill in the elements of the screen
172405b261ecSmrg     */
1725f7df2e56Smrg    screenp->id = conf_screen->scrn_identifier;
1726f7df2e56Smrg    screenp->screennum = scrnum;
172705b261ecSmrg    screenp->defaultdepth = conf_screen->scrn_defaultdepth;
172805b261ecSmrg    screenp->defaultbpp = conf_screen->scrn_defaultbpp;
172905b261ecSmrg    screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
1730f7df2e56Smrg    screenp->monitor = xnfcalloc(1, sizeof(MonRec));
173105b261ecSmrg    /* If no monitor is specified, create a default one. */
173205b261ecSmrg    if (!conf_screen->scrn_monitor) {
1733f7df2e56Smrg        XF86ConfMonitorRec defMon;
173405b261ecSmrg
1735f7df2e56Smrg        memset(&defMon, 0, sizeof(defMon));
1736f7df2e56Smrg        defMon.mon_identifier = "<default monitor>";
1737f7df2e56Smrg        if (!configMonitor(screenp->monitor, &defMon))
1738f7df2e56Smrg            return FALSE;
1739f7df2e56Smrg        defaultMonitor = TRUE;
1740f7df2e56Smrg    }
1741f7df2e56Smrg    else {
1742f7df2e56Smrg        if (!configMonitor(screenp->monitor, conf_screen->scrn_monitor))
1743f7df2e56Smrg            return FALSE;
174405b261ecSmrg    }
1745637ac9abSmrg    /* Configure the device. If there isn't one configured, attach to the
1746637ac9abSmrg     * first inactive one that we can configure. If there's none that work,
1747637ac9abSmrg     * set it to NULL so that the section can be autoconfigured later */
1748f7df2e56Smrg    screenp->device = xnfcalloc(1, sizeof(GDevRec));
1749637ac9abSmrg    if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
1750f7df2e56Smrg        FIND_SUITABLE (XF86ConfDevicePtr, xf86configptr->conf_device_lst, conf_screen->scrn_device);
1751f7df2e56Smrg        xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
1752f7df2e56Smrg                "\tUsing the first device section listed.\n", screenp->id);
1753637ac9abSmrg    }
1754f7df2e56Smrg    if (configDevice(screenp->device, conf_screen->scrn_device, TRUE, FALSE)) {
1755637ac9abSmrg        screenp->device->myScreenSection = screenp;
1756f7df2e56Smrg    }
1757f7df2e56Smrg    else {
1758637ac9abSmrg        screenp->device = NULL;
1759637ac9abSmrg    }
1760f7df2e56Smrg
1761f7df2e56Smrg    if (auto_gpu_device && conf_screen->num_gpu_devices == 0 &&
1762f7df2e56Smrg        xf86configptr->conf_device_lst) {
17635a112b11Smrg        /* Loop through the entire device list and skip the primary device
17645a112b11Smrg         * assigned to the screen. This is important because there are two
17655a112b11Smrg         * cases where the assigned primary device is not the first device in
17665a112b11Smrg         * the device list. Firstly, if the first device in the list is assigned
17675a112b11Smrg         * to a different seat than this X server, it will not have been picked
17685a112b11Smrg         * by the previous FIND_SUITABLE. Secondly, if the device was explicitly
17695a112b11Smrg         * assigned in the config but there is still only one screen, this code
17705a112b11Smrg         * path is executed but the explicitly assigned device may not be the
17715a112b11Smrg         * first device in the list. */
17725a112b11Smrg        XF86ConfDevicePtr ptmp, sdevice = xf86configptr->conf_device_lst;
1773f7df2e56Smrg
1774f7df2e56Smrg        for (i = 0; i < MAX_GPUDEVICES; i++) {
1775f7df2e56Smrg            if (!sdevice)
1776f7df2e56Smrg                break;
1777f7df2e56Smrg
17785a112b11Smrg            FIND_SUITABLE (XF86ConfDevicePtr, sdevice, ptmp);
17795a112b11Smrg            if (!ptmp)
1780f7df2e56Smrg                break;
17815a112b11Smrg
17825a112b11Smrg            /* skip the primary device on the screen */
17835a112b11Smrg            if (ptmp != conf_screen->scrn_device) {
17845a112b11Smrg                conf_screen->scrn_gpu_devices[i] = ptmp;
17855a112b11Smrg            } else {
17865a112b11Smrg                sdevice = ptmp->list.next;
17875a112b11Smrg                i--; /* run the next iteration with the same index */
17885a112b11Smrg                continue;
17895a112b11Smrg            }
17905a112b11Smrg
1791f7df2e56Smrg            screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
1792f7df2e56Smrg            if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
1793f7df2e56Smrg                screenp->gpu_devices[i]->myScreenSection = screenp;
1794f7df2e56Smrg            }
1795f7df2e56Smrg            sdevice = conf_screen->scrn_gpu_devices[i]->list.next;
1796f7df2e56Smrg        }
1797f7df2e56Smrg        screenp->num_gpu_devices = i;
1798f7df2e56Smrg
1799f7df2e56Smrg    } else {
1800f7df2e56Smrg        for (i = 0; i < conf_screen->num_gpu_devices; i++) {
1801f7df2e56Smrg            screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
1802f7df2e56Smrg            if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
1803f7df2e56Smrg                screenp->gpu_devices[i]->myScreenSection = screenp;
1804f7df2e56Smrg            }
1805f7df2e56Smrg        }
1806f7df2e56Smrg        screenp->num_gpu_devices = conf_screen->num_gpu_devices;
1807f7df2e56Smrg    }
1808f7df2e56Smrg
180905b261ecSmrg    screenp->options = conf_screen->scrn_option_lst;
1810f7df2e56Smrg
181105b261ecSmrg    /*
181205b261ecSmrg     * figure out how many display subsections there are and fill them in
181305b261ecSmrg     */
181405b261ecSmrg    dispptr = conf_screen->scrn_display_lst;
1815f7df2e56Smrg    while (dispptr) {
181605b261ecSmrg        count++;
1817f7df2e56Smrg        dispptr = (XF86ConfDisplayPtr) dispptr->list.next;
181805b261ecSmrg    }
1819d44ca368Smrg    screenp->displays = xnfallocarray(count, sizeof(DispPtr));
182005b261ecSmrg    screenp->numdisplays = count;
1821f7df2e56Smrg
1822d44ca368Smrg    for (count = 0, dispptr = conf_screen->scrn_display_lst;
1823d44ca368Smrg         dispptr;
1824d44ca368Smrg         dispptr = (XF86ConfDisplayPtr) dispptr->list.next, count++) {
1825d44ca368Smrg
1826d44ca368Smrg        /* Allocate individual Display records */
1827d44ca368Smrg        screenp->displays[count] = xnfcalloc(1, sizeof(DispRec));
1828d44ca368Smrg
1829d44ca368Smrg        /* Fill in the default Virtual size, if any */
1830d44ca368Smrg        if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
1831d44ca368Smrg            screenp->displays[count]->virtualX = conf_screen->scrn_virtualX;
1832d44ca368Smrg            screenp->displays[count]->virtualY = conf_screen->scrn_virtualY;
1833f7df2e56Smrg        }
1834637ac9abSmrg
1835d44ca368Smrg        /* Now do the per-Display Virtual sizes */
1836d44ca368Smrg        configDisplay(screenp->displays[count], dispptr);
183705b261ecSmrg    }
183805b261ecSmrg
183905b261ecSmrg    /*
184005b261ecSmrg     * figure out how many videoadaptor references there are and fill them in
184105b261ecSmrg     */
1842d44ca368Smrg    count = 0;
184305b261ecSmrg    conf_adaptor = conf_screen->scrn_adaptor_lst;
1844f7df2e56Smrg    while (conf_adaptor) {
184505b261ecSmrg        count++;
1846f7df2e56Smrg        conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next;
184705b261ecSmrg    }
1848f7df2e56Smrg    screenp->xvadaptors = xnfallocarray(count, sizeof(confXvAdaptorRec));
184905b261ecSmrg    screenp->numxvadaptors = 0;
185005b261ecSmrg    conf_adaptor = conf_screen->scrn_adaptor_lst;
1851f7df2e56Smrg    while (conf_adaptor) {
185205b261ecSmrg        if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
1853f7df2e56Smrg                            conf_adaptor->al_adaptor))
1854f7df2e56Smrg            screenp->numxvadaptors++;
1855f7df2e56Smrg        conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next;
185605b261ecSmrg    }
185705b261ecSmrg
185805b261ecSmrg    if (defaultMonitor) {
1859f7df2e56Smrg        xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
1860f7df2e56Smrg                "\tUsing a default monitor configuration.\n", screenp->id);
186105b261ecSmrg    }
186205b261ecSmrg    return TRUE;
186305b261ecSmrg}
186405b261ecSmrg
186505b261ecSmrgtypedef enum {
186605b261ecSmrg    MON_REDUCEDBLANKING,
186705b261ecSmrg    MON_MAX_PIX_CLOCK,
186805b261ecSmrg} MonitorValues;
186905b261ecSmrg
187005b261ecSmrgstatic OptionInfoRec MonitorOptions[] = {
1871f7df2e56Smrg    {MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN,
1872f7df2e56Smrg     {0}, FALSE},
1873f7df2e56Smrg    {MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ,
1874f7df2e56Smrg     {0}, FALSE},
1875f7df2e56Smrg    {-1, NULL, OPTV_NONE,
1876f7df2e56Smrg     {0}, FALSE},
187705b261ecSmrg};
187805b261ecSmrg
187905b261ecSmrgstatic Bool
188005b261ecSmrgconfigMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
188105b261ecSmrg{
188205b261ecSmrg    int count;
1883f7df2e56Smrg    DisplayModePtr mode, last = NULL;
188405b261ecSmrg    XF86ConfModeLinePtr cmodep;
188505b261ecSmrg    XF86ConfModesPtr modes;
188605b261ecSmrg    XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
1887f7df2e56Smrg    Gamma zeros = { 0.0, 0.0, 0.0 };
188805b261ecSmrg    float badgamma = 0.0;
1889637ac9abSmrg    double maxPixClock;
1890f7df2e56Smrg
1891f7df2e56Smrg    xf86Msg(X_CONFIG, "|   |-->Monitor \"%s\"\n", conf_monitor->mon_identifier);
189205b261ecSmrg    monitorp->id = conf_monitor->mon_identifier;
189305b261ecSmrg    monitorp->vendor = conf_monitor->mon_vendor;
189405b261ecSmrg    monitorp->model = conf_monitor->mon_modelname;
189505b261ecSmrg    monitorp->Modes = NULL;
189605b261ecSmrg    monitorp->Last = NULL;
189705b261ecSmrg    monitorp->gamma = zeros;
189805b261ecSmrg    monitorp->widthmm = conf_monitor->mon_width;
189905b261ecSmrg    monitorp->heightmm = conf_monitor->mon_height;
190005b261ecSmrg    monitorp->reducedblanking = FALSE;
190105b261ecSmrg    monitorp->maxPixClock = 0;
190205b261ecSmrg    monitorp->options = conf_monitor->mon_option_lst;
190305b261ecSmrg
190405b261ecSmrg    /*
190505b261ecSmrg     * fill in the monitor structure
1906f7df2e56Smrg     */
1907f7df2e56Smrg    for (count = 0;
1908f7df2e56Smrg         count < conf_monitor->mon_n_hsync && count < MAX_HSYNC; count++) {
190905b261ecSmrg        monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
191005b261ecSmrg        monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
191105b261ecSmrg    }
191205b261ecSmrg    monitorp->nHsync = count;
1913f7df2e56Smrg    for (count = 0;
1914f7df2e56Smrg         count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
1915f7df2e56Smrg         count++) {
191605b261ecSmrg        monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
191705b261ecSmrg        monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
191805b261ecSmrg    }
191905b261ecSmrg    monitorp->nVrefresh = count;
192005b261ecSmrg
192105b261ecSmrg    /*
192205b261ecSmrg     * first we collect the mode lines from the UseModes directive
192305b261ecSmrg     */
1924f7df2e56Smrg    while (modeslnk) {
1925f7df2e56Smrg        modes = xf86findModes(modeslnk->ml_modes_str,
1926f7df2e56Smrg                              xf86configptr->conf_modes_lst);
1927f7df2e56Smrg        modeslnk->ml_modes = modes;
1928f7df2e56Smrg
1929f7df2e56Smrg        /* now add the modes found in the modes
1930f7df2e56Smrg           section to the list of modes for this
1931f7df2e56Smrg           monitor unless it has been added before
1932f7df2e56Smrg           because we are reusing the same section
1933f7df2e56Smrg           for another screen */
1934f7df2e56Smrg        if (xf86itemNotSublist((GenericListPtr) conf_monitor->mon_modeline_lst,
1935f7df2e56Smrg                               (GenericListPtr) modes->mon_modeline_lst)) {
1936f7df2e56Smrg            conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
1937f7df2e56Smrg                xf86addListItem((GenericListPtr) conf_monitor->mon_modeline_lst,
1938f7df2e56Smrg                                (GenericListPtr) modes->mon_modeline_lst);
1939f7df2e56Smrg        }
1940f7df2e56Smrg        modeslnk = modeslnk->list.next;
194105b261ecSmrg    }
194205b261ecSmrg
194305b261ecSmrg    /*
194405b261ecSmrg     * we need to hook in the mode lines now
194505b261ecSmrg     * here both data structures use lists, only our internal one
194605b261ecSmrg     * is double linked
194705b261ecSmrg     */
194805b261ecSmrg    cmodep = conf_monitor->mon_modeline_lst;
1949f7df2e56Smrg    while (cmodep) {
1950637ac9abSmrg        mode = xnfcalloc(1, sizeof(DisplayModeRec));
1951f7df2e56Smrg        mode->type = 0;
1952f7df2e56Smrg        mode->Clock = cmodep->ml_clock;
1953f7df2e56Smrg        mode->HDisplay = cmodep->ml_hdisplay;
195405b261ecSmrg        mode->HSyncStart = cmodep->ml_hsyncstart;
1955f7df2e56Smrg        mode->HSyncEnd = cmodep->ml_hsyncend;
1956f7df2e56Smrg        mode->HTotal = cmodep->ml_htotal;
1957f7df2e56Smrg        mode->VDisplay = cmodep->ml_vdisplay;
195805b261ecSmrg        mode->VSyncStart = cmodep->ml_vsyncstart;
1959f7df2e56Smrg        mode->VSyncEnd = cmodep->ml_vsyncend;
1960f7df2e56Smrg        mode->VTotal = cmodep->ml_vtotal;
1961f7df2e56Smrg        mode->Flags = cmodep->ml_flags;
1962f7df2e56Smrg        mode->HSkew = cmodep->ml_hskew;
1963f7df2e56Smrg        mode->VScan = cmodep->ml_vscan;
1964f7df2e56Smrg        mode->name = xnfstrdup(cmodep->ml_identifier);
1965f7df2e56Smrg        if (last) {
196605b261ecSmrg            mode->prev = last;
196705b261ecSmrg            last->next = mode;
196805b261ecSmrg        }
196905b261ecSmrg        else {
197005b261ecSmrg            /*
197105b261ecSmrg             * this is the first mode
197205b261ecSmrg             */
197305b261ecSmrg            monitorp->Modes = mode;
197405b261ecSmrg            mode->prev = NULL;
197505b261ecSmrg        }
197605b261ecSmrg        last = mode;
1977f7df2e56Smrg        cmodep = (XF86ConfModeLinePtr) cmodep->list.next;
197805b261ecSmrg    }
1979f7df2e56Smrg    if (last) {
1980f7df2e56Smrg        last->next = NULL;
198105b261ecSmrg    }
198205b261ecSmrg    monitorp->Last = last;
198305b261ecSmrg
198405b261ecSmrg    /* add the (VESA) default modes */
1985f7df2e56Smrg    if (!addDefaultModes(monitorp))
1986f7df2e56Smrg        return FALSE;
198705b261ecSmrg
198805b261ecSmrg    if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
1989f7df2e56Smrg        monitorp->gamma.red = conf_monitor->mon_gamma_red;
199005b261ecSmrg    if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
1991f7df2e56Smrg        monitorp->gamma.green = conf_monitor->mon_gamma_green;
199205b261ecSmrg    if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
1993f7df2e56Smrg        monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
1994f7df2e56Smrg
199505b261ecSmrg    /* Check that the gamma values are within range */
199605b261ecSmrg    if (monitorp->gamma.red > GAMMA_ZERO &&
1997f7df2e56Smrg        (monitorp->gamma.red < GAMMA_MIN || monitorp->gamma.red > GAMMA_MAX)) {
1998f7df2e56Smrg        badgamma = monitorp->gamma.red;
1999f7df2e56Smrg    }
2000f7df2e56Smrg    else if (monitorp->gamma.green > GAMMA_ZERO &&
2001f7df2e56Smrg             (monitorp->gamma.green < GAMMA_MIN ||
2002f7df2e56Smrg              monitorp->gamma.green > GAMMA_MAX)) {
2003f7df2e56Smrg        badgamma = monitorp->gamma.green;
2004f7df2e56Smrg    }
2005f7df2e56Smrg    else if (monitorp->gamma.blue > GAMMA_ZERO &&
2006f7df2e56Smrg             (monitorp->gamma.blue < GAMMA_MIN ||
2007f7df2e56Smrg              monitorp->gamma.blue > GAMMA_MAX)) {
2008f7df2e56Smrg        badgamma = monitorp->gamma.blue;
200905b261ecSmrg    }
201005b261ecSmrg    if (badgamma > GAMMA_ZERO) {
2011f7df2e56Smrg        ErrorF("Gamma value %.f is out of range (%.2f - %.1f)\n", badgamma,
2012f7df2e56Smrg               GAMMA_MIN, GAMMA_MAX);
2013f7df2e56Smrg        return FALSE;
201405b261ecSmrg    }
201505b261ecSmrg
201605b261ecSmrg    xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
201705b261ecSmrg    xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
201805b261ecSmrg                      &monitorp->reducedblanking);
2019637ac9abSmrg    if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
2020f7df2e56Smrg                          &maxPixClock) == TRUE) {
2021f7df2e56Smrg        monitorp->maxPixClock = (int) maxPixClock;
2022637ac9abSmrg    }
2023f7df2e56Smrg
202405b261ecSmrg    return TRUE;
202505b261ecSmrg}
202605b261ecSmrg
202705b261ecSmrgstatic int
202805b261ecSmrglookupVisual(const char *visname)
202905b261ecSmrg{
203005b261ecSmrg    int i;
203105b261ecSmrg
203205b261ecSmrg    if (!visname || !*visname)
2033f7df2e56Smrg        return -1;
203405b261ecSmrg
203505b261ecSmrg    for (i = 0; i <= DirectColor; i++) {
2036f7df2e56Smrg        if (!xf86nameCompare(visname, xf86VisualNames[i]))
2037f7df2e56Smrg            break;
203805b261ecSmrg    }
203905b261ecSmrg
204005b261ecSmrg    if (i <= DirectColor)
2041f7df2e56Smrg        return i;
204205b261ecSmrg
204305b261ecSmrg    return -1;
204405b261ecSmrg}
204505b261ecSmrg
204605b261ecSmrgstatic Bool
204705b261ecSmrgconfigDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
204805b261ecSmrg{
204905b261ecSmrg    int count = 0;
205005b261ecSmrg    XF86ModePtr modep;
2051f7df2e56Smrg
2052f7df2e56Smrg    displayp->frameX0 = conf_display->disp_frameX0;
2053f7df2e56Smrg    displayp->frameY0 = conf_display->disp_frameY0;
2054f7df2e56Smrg    displayp->virtualX = conf_display->disp_virtualX;
2055f7df2e56Smrg    displayp->virtualY = conf_display->disp_virtualY;
2056f7df2e56Smrg    displayp->depth = conf_display->disp_depth;
2057f7df2e56Smrg    displayp->fbbpp = conf_display->disp_bpp;
2058f7df2e56Smrg    displayp->weight.red = conf_display->disp_weight.red;
2059f7df2e56Smrg    displayp->weight.green = conf_display->disp_weight.green;
2060f7df2e56Smrg    displayp->weight.blue = conf_display->disp_weight.blue;
2061f7df2e56Smrg    displayp->blackColour.red = conf_display->disp_black.red;
206205b261ecSmrg    displayp->blackColour.green = conf_display->disp_black.green;
2063f7df2e56Smrg    displayp->blackColour.blue = conf_display->disp_black.blue;
2064f7df2e56Smrg    displayp->whiteColour.red = conf_display->disp_white.red;
206505b261ecSmrg    displayp->whiteColour.green = conf_display->disp_white.green;
2066f7df2e56Smrg    displayp->whiteColour.blue = conf_display->disp_white.blue;
2067f7df2e56Smrg    displayp->options = conf_display->disp_option_lst;
206805b261ecSmrg    if (conf_display->disp_visual) {
2069f7df2e56Smrg        displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
2070f7df2e56Smrg        if (displayp->defaultVisual == -1) {
2071f7df2e56Smrg            ErrorF("Invalid visual name: \"%s\"\n", conf_display->disp_visual);
2072f7df2e56Smrg            return FALSE;
2073f7df2e56Smrg        }
2074f7df2e56Smrg    }
2075f7df2e56Smrg    else {
2076f7df2e56Smrg        displayp->defaultVisual = -1;
207705b261ecSmrg    }
2078f7df2e56Smrg
207905b261ecSmrg    /*
208005b261ecSmrg     * now hook in the modes
208105b261ecSmrg     */
208205b261ecSmrg    modep = conf_display->disp_mode_lst;
2083f7df2e56Smrg    while (modep) {
208405b261ecSmrg        count++;
2085f7df2e56Smrg        modep = (XF86ModePtr) modep->list.next;
208605b261ecSmrg    }
2087f7df2e56Smrg    displayp->modes = xnfallocarray(count + 1, sizeof(char *));
208805b261ecSmrg    modep = conf_display->disp_mode_lst;
208905b261ecSmrg    count = 0;
2090f7df2e56Smrg    while (modep) {
209105b261ecSmrg        displayp->modes[count] = modep->mode_name;
209205b261ecSmrg        count++;
2093f7df2e56Smrg        modep = (XF86ModePtr) modep->list.next;
209405b261ecSmrg    }
209505b261ecSmrg    displayp->modes[count] = NULL;
2096f7df2e56Smrg
209705b261ecSmrg    return TRUE;
209805b261ecSmrg}
209905b261ecSmrg
210005b261ecSmrgstatic Bool
2101f7df2e56SmrgconfigDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool gpu)
210205b261ecSmrg{
210305b261ecSmrg    int i;
210405b261ecSmrg
2105637ac9abSmrg    if (!conf_device) {
2106637ac9abSmrg        return FALSE;
2107637ac9abSmrg    }
2108637ac9abSmrg
2109f7df2e56Smrg    if (active) {
2110f7df2e56Smrg        if (gpu)
2111f7df2e56Smrg            xf86Msg(X_CONFIG, "|   |-->GPUDevice \"%s\"\n",
2112f7df2e56Smrg                    conf_device->dev_identifier);
2113f7df2e56Smrg        else
2114f7df2e56Smrg            xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
2115f7df2e56Smrg                    conf_device->dev_identifier);
2116f7df2e56Smrg    } else
2117f7df2e56Smrg        xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
2118f7df2e56Smrg                conf_device->dev_identifier);
2119637ac9abSmrg
212005b261ecSmrg    devicep->identifier = conf_device->dev_identifier;
212105b261ecSmrg    devicep->vendor = conf_device->dev_vendor;
212205b261ecSmrg    devicep->board = conf_device->dev_board;
212305b261ecSmrg    devicep->chipset = conf_device->dev_chipset;
212405b261ecSmrg    devicep->ramdac = conf_device->dev_ramdac;
212505b261ecSmrg    devicep->driver = conf_device->dev_driver;
212605b261ecSmrg    devicep->active = active;
212705b261ecSmrg    devicep->videoRam = conf_device->dev_videoram;
212805b261ecSmrg    devicep->MemBase = conf_device->dev_mem_base;
212905b261ecSmrg    devicep->IOBase = conf_device->dev_io_base;
213005b261ecSmrg    devicep->clockchip = conf_device->dev_clockchip;
213105b261ecSmrg    devicep->busID = conf_device->dev_busid;
213205b261ecSmrg    devicep->chipID = conf_device->dev_chipid;
213305b261ecSmrg    devicep->chipRev = conf_device->dev_chiprev;
213405b261ecSmrg    devicep->options = conf_device->dev_option_lst;
213505b261ecSmrg    devicep->irq = conf_device->dev_irq;
213605b261ecSmrg    devicep->screen = conf_device->dev_screen;
213705b261ecSmrg
213805b261ecSmrg    for (i = 0; i < MAXDACSPEEDS; i++) {
2139f7df2e56Smrg        if (i < CONF_MAXDACSPEEDS)
214005b261ecSmrg            devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
2141f7df2e56Smrg        else
2142f7df2e56Smrg            devicep->dacSpeeds[i] = 0;
214305b261ecSmrg    }
214405b261ecSmrg    devicep->numclocks = conf_device->dev_clocks;
214505b261ecSmrg    if (devicep->numclocks > MAXCLOCKS)
2146f7df2e56Smrg        devicep->numclocks = MAXCLOCKS;
214705b261ecSmrg    for (i = 0; i < devicep->numclocks; i++) {
2148f7df2e56Smrg        devicep->clock[i] = conf_device->dev_clock[i];
214905b261ecSmrg    }
215005b261ecSmrg    devicep->claimed = FALSE;
215105b261ecSmrg
215205b261ecSmrg    return TRUE;
215305b261ecSmrg}
215405b261ecSmrg
215505b261ecSmrgstatic void
215605b261ecSmrgconfigDRI(XF86ConfDRIPtr drip)
215705b261ecSmrg{
2158f7df2e56Smrg    struct group *grp;
215905b261ecSmrg
2160f7df2e56Smrg    xf86ConfigDRI.group = -1;
2161f7df2e56Smrg    xf86ConfigDRI.mode = 0;
216205b261ecSmrg
216305b261ecSmrg    if (drip) {
2164f7df2e56Smrg        if (drip->dri_group_name) {
2165f7df2e56Smrg            if ((grp = getgrnam(drip->dri_group_name)))
2166f7df2e56Smrg                xf86ConfigDRI.group = grp->gr_gid;
2167f7df2e56Smrg        }
2168f7df2e56Smrg        else {
2169f7df2e56Smrg            if (drip->dri_group >= 0)
2170f7df2e56Smrg                xf86ConfigDRI.group = drip->dri_group;
2171f7df2e56Smrg        }
2172f7df2e56Smrg        xf86ConfigDRI.mode = drip->dri_mode;
217305b261ecSmrg    }
217405b261ecSmrg}
217505b261ecSmrg
217605b261ecSmrgstatic void
217705b261ecSmrgconfigExtensions(XF86ConfExtensionsPtr conf_ext)
217805b261ecSmrg{
217905b261ecSmrg    XF86OptionPtr o;
218005b261ecSmrg
218105b261ecSmrg    if (conf_ext && conf_ext->ext_option_lst) {
2182f7df2e56Smrg        for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
2183f7df2e56Smrg            char *name = xf86OptionName(o);
2184f7df2e56Smrg            char *val = xf86OptionValue(o);
2185f7df2e56Smrg            char *n;
2186f7df2e56Smrg            Bool enable = TRUE;
2187f7df2e56Smrg
2188f7df2e56Smrg            /* Handle "No<ExtensionName>" */
2189f7df2e56Smrg            n = xf86NormalizeName(name);
2190f7df2e56Smrg            if (strncmp(n, "no", 2) == 0) {
2191f7df2e56Smrg                name += 2;
2192f7df2e56Smrg                enable = FALSE;
2193f7df2e56Smrg            }
2194f7df2e56Smrg
2195f7df2e56Smrg            if (!val ||
2196f7df2e56Smrg                xf86NameCmp(val, "enable") == 0 ||
2197f7df2e56Smrg                xf86NameCmp(val, "enabled") == 0 ||
2198f7df2e56Smrg                xf86NameCmp(val, "on") == 0 ||
2199f7df2e56Smrg                xf86NameCmp(val, "1") == 0 ||
2200f7df2e56Smrg                xf86NameCmp(val, "yes") == 0 || xf86NameCmp(val, "true") == 0) {
2201f7df2e56Smrg                /* NOTHING NEEDED -- enabling is handled below */
2202f7df2e56Smrg            }
2203f7df2e56Smrg            else if (xf86NameCmp(val, "disable") == 0 ||
2204f7df2e56Smrg                     xf86NameCmp(val, "disabled") == 0 ||
2205f7df2e56Smrg                     xf86NameCmp(val, "off") == 0 ||
2206f7df2e56Smrg                     xf86NameCmp(val, "0") == 0 ||
2207f7df2e56Smrg                     xf86NameCmp(val, "no") == 0 ||
2208f7df2e56Smrg                     xf86NameCmp(val, "false") == 0) {
2209f7df2e56Smrg                enable = !enable;
2210f7df2e56Smrg            }
2211f7df2e56Smrg            else {
2212f7df2e56Smrg                xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
2213f7df2e56Smrg                free(n);
2214f7df2e56Smrg                continue;
2215f7df2e56Smrg            }
2216f7df2e56Smrg
2217f7df2e56Smrg            if (EnableDisableExtension(name, enable)) {
2218f7df2e56Smrg                xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
2219f7df2e56Smrg                        name, enable ? "enabled" : "disabled");
2220f7df2e56Smrg            }
2221f7df2e56Smrg            else {
2222f7df2e56Smrg                xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
222305b261ecSmrg                        name);
2224f7df2e56Smrg            }
2225f7df2e56Smrg            free(n);
2226f7df2e56Smrg        }
222705b261ecSmrg    }
222805b261ecSmrg}
222905b261ecSmrg
223005b261ecSmrgstatic Bool
223165b04b38SmrgconfigInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
223205b261ecSmrg{
223305b261ecSmrg    xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
223465b04b38Smrg    inputp->name = conf_input->inp_identifier;
223505b261ecSmrg    inputp->driver = conf_input->inp_driver;
223665b04b38Smrg    inputp->options = conf_input->inp_option_lst;
22374202a189Smrg    inputp->attrs = NULL;
223805b261ecSmrg
223905b261ecSmrg    return TRUE;
224005b261ecSmrg}
224105b261ecSmrg
224205b261ecSmrgstatic Bool
2243637ac9abSmrgmodeIsPresent(DisplayModePtr mode, MonPtr monitorp)
224405b261ecSmrg{
224505b261ecSmrg    DisplayModePtr knownmodes = monitorp->Modes;
224605b261ecSmrg
224705b261ecSmrg    /* all I can think of is a linear search... */
2248f7df2e56Smrg    while (knownmodes != NULL) {
2249f7df2e56Smrg        if (!strcmp(mode->name, knownmodes->name) &&
2250f7df2e56Smrg            !(knownmodes->type & M_T_DEFAULT))
2251f7df2e56Smrg            return TRUE;
2252f7df2e56Smrg        knownmodes = knownmodes->next;
225305b261ecSmrg    }
225405b261ecSmrg    return FALSE;
225505b261ecSmrg}
225605b261ecSmrg
225705b261ecSmrgstatic Bool
225805b261ecSmrgaddDefaultModes(MonPtr monitorp)
225905b261ecSmrg{
226005b261ecSmrg    DisplayModePtr mode;
226105b261ecSmrg    DisplayModePtr last = monitorp->Last;
226205b261ecSmrg    int i = 0;
226305b261ecSmrg
2264f7df2e56Smrg    for (i = 0; i < xf86NumDefaultModes; i++) {
2265f7df2e56Smrg        mode = xf86DuplicateMode(&xf86DefaultModes[i]);
2266f7df2e56Smrg        if (!modeIsPresent(mode, monitorp)) {
2267f7df2e56Smrg            monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
2268f7df2e56Smrg            last = mode;
2269f7df2e56Smrg        }
2270f7df2e56Smrg        else {
2271f7df2e56Smrg            free(mode);
2272f7df2e56Smrg        }
227305b261ecSmrg    }
227405b261ecSmrg    monitorp->Last = last;
227505b261ecSmrg
227605b261ecSmrg    return TRUE;
227705b261ecSmrg}
227805b261ecSmrg
227905b261ecSmrgstatic void
2280f7df2e56SmrgcheckInput(serverLayoutPtr layout, Bool implicit_layout)
2281f7df2e56Smrg{
2282637ac9abSmrg    checkCoreInputDevices(layout, implicit_layout);
2283637ac9abSmrg
228465b04b38Smrg    /* Unless we're forcing input devices, disable mouse/kbd devices in the
228565b04b38Smrg     * config. Otherwise the same physical device is added multiple times,
228665b04b38Smrg     * leading to duplicate events.
2287637ac9abSmrg     */
2288f7df2e56Smrg    if (!xf86Info.forceInputDevices && layout->inputs) {
228965b04b38Smrg        InputInfoPtr *dev = layout->inputs;
2290637ac9abSmrg        BOOL warned = FALSE;
2291637ac9abSmrg
2292f7df2e56Smrg        while (*dev) {
2293637ac9abSmrg            if (strcmp((*dev)->driver, "kbd") == 0 ||
2294637ac9abSmrg                strcmp((*dev)->driver, "mouse") == 0 ||
2295f7df2e56Smrg                strcmp((*dev)->driver, "vmmouse") == 0) {
229665b04b38Smrg                InputInfoPtr *current;
2297f7df2e56Smrg
2298f7df2e56Smrg                if (!warned) {
229965b04b38Smrg                    xf86Msg(X_WARNING, "Hotplugging is on, devices using "
2300637ac9abSmrg                            "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
2301637ac9abSmrg                    warned = TRUE;
2302637ac9abSmrg                }
2303637ac9abSmrg
230465b04b38Smrg                xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name);
2305637ac9abSmrg
2306637ac9abSmrg                current = dev;
23074202a189Smrg                free(*dev);
2308f7df2e56Smrg                *dev = NULL;
2309637ac9abSmrg
2310637ac9abSmrg                do {
2311637ac9abSmrg                    *current = *(current + 1);
2312637ac9abSmrg                    current++;
2313f7df2e56Smrg                } while (*current);
2314f7df2e56Smrg            }
2315f7df2e56Smrg            else
2316637ac9abSmrg                dev++;
2317637ac9abSmrg        }
2318637ac9abSmrg    }
231905b261ecSmrg}
232005b261ecSmrg
232105b261ecSmrg/*
232205b261ecSmrg * load the config file and fill the global data structure
232305b261ecSmrg */
232405b261ecSmrgConfigStatus
232505b261ecSmrgxf86HandleConfigFile(Bool autoconfig)
232605b261ecSmrg{
23277e31ba66Smrg#ifdef XSERVER_LIBPCIACCESS
2328f7df2e56Smrg    const char *scanptr;
232905b261ecSmrg    Bool singlecard = 0;
23307e31ba66Smrg#endif
2331637ac9abSmrg    Bool implicit_layout = FALSE;
2332f7df2e56Smrg    XF86ConfLayoutPtr layout;
233305b261ecSmrg
233405b261ecSmrg    if (!autoconfig) {
2335f7df2e56Smrg        char *filename, *dirname, *sysdirname;
2336f7df2e56Smrg        const char *filesearch, *dirsearch;
2337f7df2e56Smrg        MessageType filefrom = X_DEFAULT;
2338f7df2e56Smrg        MessageType dirfrom = X_DEFAULT;
2339f7df2e56Smrg
23407e31ba66Smrg        if (!PrivsElevated()) {
2341f7df2e56Smrg            filesearch = ALL_CONFIGPATH;
2342f7df2e56Smrg            dirsearch = ALL_CONFIGDIRPATH;
2343f7df2e56Smrg        }
2344f7df2e56Smrg        else {
2345f7df2e56Smrg            filesearch = RESTRICTED_CONFIGPATH;
2346f7df2e56Smrg            dirsearch = RESTRICTED_CONFIGDIRPATH;
2347f7df2e56Smrg        }
2348f7df2e56Smrg
2349f7df2e56Smrg        if (xf86ConfigFile)
2350f7df2e56Smrg            filefrom = X_CMDLINE;
2351f7df2e56Smrg        if (xf86ConfigDir)
2352f7df2e56Smrg            dirfrom = X_CMDLINE;
2353f7df2e56Smrg
2354f7df2e56Smrg        xf86initConfigFiles();
2355f7df2e56Smrg        sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
2356f7df2e56Smrg                                            PROJECTROOT);
2357f7df2e56Smrg        dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
2358f7df2e56Smrg        filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
2359f7df2e56Smrg        if (filename) {
2360f7df2e56Smrg            xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
2361f7df2e56Smrg            xf86ConfigFile = xnfstrdup(filename);
2362f7df2e56Smrg        }
2363f7df2e56Smrg        else {
2364f7df2e56Smrg            if (xf86ConfigFile)
2365f7df2e56Smrg                xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
2366f7df2e56Smrg                        xf86ConfigFile);
2367f7df2e56Smrg        }
2368f7df2e56Smrg        if (dirname) {
2369f7df2e56Smrg            xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
2370f7df2e56Smrg                        dirname);
2371f7df2e56Smrg            xf86ConfigDir = xnfstrdup(dirname);
2372f7df2e56Smrg        }
2373f7df2e56Smrg        else {
2374f7df2e56Smrg            if (xf86ConfigDir)
2375f7df2e56Smrg                xf86Msg(X_ERROR,
2376f7df2e56Smrg                        "Unable to locate/open config directory: \"%s\"\n",
2377f7df2e56Smrg                        xf86ConfigDir);
2378f7df2e56Smrg        }
2379f7df2e56Smrg        if (sysdirname)
2380f7df2e56Smrg            xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
2381f7df2e56Smrg                        sysdirname);
2382f7df2e56Smrg        if (!filename && !dirname && !sysdirname)
2383f7df2e56Smrg            return CONFIG_NOFILE;
2384f7df2e56Smrg
2385f7df2e56Smrg        free(filename);
2386f7df2e56Smrg        free(dirname);
2387f7df2e56Smrg        free(sysdirname);
238805b261ecSmrg    }
23894202a189Smrg
2390f7df2e56Smrg    if ((xf86configptr = xf86readConfigFile()) == NULL) {
2391f7df2e56Smrg        xf86Msg(X_ERROR, "Problem parsing the config file\n");
2392f7df2e56Smrg        return CONFIG_PARSE_ERROR;
239305b261ecSmrg    }
2394f7df2e56Smrg    xf86closeConfigFile();
239505b261ecSmrg
239605b261ecSmrg    /* Initialise a few things. */
239705b261ecSmrg
239805b261ecSmrg    /*
239905b261ecSmrg     * now we convert part of the information contained in the parser
240005b261ecSmrg     * structures into our own structures.
240105b261ecSmrg     * The important part here is to figure out which Screen Sections
240205b261ecSmrg     * in the XF86Config file are active so that we can piece together
240305b261ecSmrg     * the modes that we need later down the road.
240405b261ecSmrg     * And while we are at it, we'll decode the rest of the stuff as well
240505b261ecSmrg     */
240605b261ecSmrg
240705b261ecSmrg    /* First check if a layout section is present, and if it is valid. */
2408f7df2e56Smrg    FIND_SUITABLE(XF86ConfLayoutPtr, xf86configptr->conf_layout_lst, layout);
2409f7df2e56Smrg    if (layout == NULL || xf86ScreenName != NULL) {
2410f7df2e56Smrg        XF86ConfScreenPtr screen;
241105b261ecSmrg
2412f7df2e56Smrg        if (xf86ScreenName == NULL) {
2413f7df2e56Smrg            xf86Msg(X_DEFAULT,
2414f7df2e56Smrg                    "No Layout section.  Using the first Screen section.\n");
2415f7df2e56Smrg        }
2416f7df2e56Smrg        FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen);
2417f7df2e56Smrg        if (!configImpliedLayout(&xf86ConfigLayout,
2418f7df2e56Smrg                                 screen,
2419f7df2e56Smrg                                 xf86configptr)) {
242005b261ecSmrg            xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2421f7df2e56Smrg            return CONFIG_PARSE_ERROR;
2422f7df2e56Smrg        }
2423f7df2e56Smrg        implicit_layout = TRUE;
2424f7df2e56Smrg    }
2425f7df2e56Smrg    else {
2426f7df2e56Smrg        if (xf86configptr->conf_flags != NULL) {
2427f7df2e56Smrg            char *dfltlayout = NULL;
2428f7df2e56Smrg            void *optlist = xf86configptr->conf_flags->flg_option_lst;
2429f7df2e56Smrg
2430f7df2e56Smrg            if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
2431f7df2e56Smrg                dfltlayout =
2432f7df2e56Smrg                    xf86SetStrOption(optlist, "defaultserverlayout", NULL);
2433f7df2e56Smrg            if (!configLayout(&xf86ConfigLayout, layout, dfltlayout)) {
2434f7df2e56Smrg                xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2435f7df2e56Smrg                return CONFIG_PARSE_ERROR;
2436f7df2e56Smrg            }
2437f7df2e56Smrg        }
2438f7df2e56Smrg        else {
2439f7df2e56Smrg            if (!configLayout(&xf86ConfigLayout, layout, NULL)) {
2440f7df2e56Smrg                xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2441f7df2e56Smrg                return CONFIG_PARSE_ERROR;
2442f7df2e56Smrg            }
2443f7df2e56Smrg        }
244405b261ecSmrg    }
244505b261ecSmrg
244605b261ecSmrg    xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
2447f7df2e56Smrg#ifdef XSERVER_LIBPCIACCESS
244805b261ecSmrg    if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
2449f7df2e56Smrg        ;                       /* IsolateDevice specified; overrides SingleCard */
2450f7df2e56Smrg    }
2451f7df2e56Smrg    else {
2452f7df2e56Smrg        xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
2453f7df2e56Smrg        if (singlecard)
2454f7df2e56Smrg            scanptr = xf86ConfigLayout.screens->screen->device->busID;
245505b261ecSmrg    }
245605b261ecSmrg    if (scanptr) {
2457f7df2e56Smrg        if (strncmp(scanptr, "PCI:", 4) != 0) {
2458f7df2e56Smrg            xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
2459f7df2e56Smrg                    "\tIgnoring IsolateDevice option.\n");
2460f7df2e56Smrg        }
2461f7df2e56Smrg        else
2462f7df2e56Smrg            xf86PciIsolateDevice(scanptr);
246305b261ecSmrg    }
2464f7df2e56Smrg#endif
246505b261ecSmrg    /* Now process everything else */
2466f7df2e56Smrg    configServerFlags(xf86configptr->conf_flags, xf86ConfigLayout.options);
246705b261ecSmrg    configFiles(xf86configptr->conf_files);
246805b261ecSmrg    configExtensions(xf86configptr->conf_extensions);
246905b261ecSmrg    configDRI(xf86configptr->conf_dri);
247005b261ecSmrg
2471637ac9abSmrg    checkInput(&xf86ConfigLayout, implicit_layout);
247205b261ecSmrg
247305b261ecSmrg    /*
247405b261ecSmrg     * Handle some command line options that can override some of the
247505b261ecSmrg     * ServerFlags settings.
247605b261ecSmrg     */
247705b261ecSmrg#ifdef XF86VIDMODE
247805b261ecSmrg    if (xf86VidModeDisabled)
2479f7df2e56Smrg        xf86Info.vidModeEnabled = FALSE;
248005b261ecSmrg    if (xf86VidModeAllowNonLocal)
2481f7df2e56Smrg        xf86Info.vidModeAllowNonLocal = TRUE;
248205b261ecSmrg#endif
248305b261ecSmrg
248405b261ecSmrg    if (xf86AllowMouseOpenFail)
2485f7df2e56Smrg        xf86Info.allowMouseOpenFail = TRUE;
248605b261ecSmrg
248705b261ecSmrg    return CONFIG_OK;
248805b261ecSmrg}
248905b261ecSmrg
249005b261ecSmrgBool
249105b261ecSmrgxf86PathIsSafe(const char *path)
249205b261ecSmrg{
249305b261ecSmrg    return (xf86pathIsSafe(path) != 0);
249405b261ecSmrg}
2495