xf86Config.c revision dcbd449d
1/*
2 * Loosely based on code bearing the following copyright:
3 *
4 *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
5 */
6
7/*
8 * Copyright 1992-2003 by The XFree86 Project, Inc.
9 * Copyright 1997 by Metro Link, Inc.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
25 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
28 *
29 * Except as contained in this notice, the name of the copyright holder(s)
30 * and author(s) shall not be used in advertising or otherwise to promote
31 * the sale, use or other dealings in this Software without prior written
32 * authorization from the copyright holder(s) and author(s).
33 */
34
35/*
36 *
37 * Authors:
38 *	Dirk Hohndel <hohndel@XFree86.Org>
39 *	David Dawes <dawes@XFree86.Org>
40 *      Marc La France <tsi@XFree86.Org>
41 *      Egbert Eich <eich@XFree86.Org>
42 *      ... and others
43 */
44
45#ifdef HAVE_XORG_CONFIG_H
46#include <xorg-config.h>
47#endif
48
49#include <sys/types.h>
50#include <grp.h>
51
52#include "xf86.h"
53#include "xf86Modes.h"
54#include "xf86Parser.h"
55#include "xf86tokens.h"
56#include "xf86Config.h"
57#include "xf86Priv.h"
58#include "xf86_OSlib.h"
59#include "configProcs.h"
60#include "globals.h"
61#include "extension.h"
62#include "xf86pciBus.h"
63
64#include "xf86Xinput.h"
65
66#include "xkbsrv.h"
67
68#include "picture.h"
69
70/*
71 * These paths define the way the config file search is done.  The escape
72 * sequences are documented in parser/scan.c.
73 */
74#ifndef ALL_CONFIGPATH
75#define ALL_CONFIGPATH	"%A," "%R," \
76			"/etc/X11/%R," "%P/etc/X11/%R," \
77			"%E," "%F," \
78			"/etc/X11/%F," "%P/etc/X11/%F," \
79			"/etc/X11/%X," "/etc/%X," \
80			"%P/etc/X11/%X.%H," \
81			"%P/etc/X11/%X," \
82			"%P/lib/X11/%X.%H," \
83			"%P/lib/X11/%X"
84#endif
85#ifndef RESTRICTED_CONFIGPATH
86#define RESTRICTED_CONFIGPATH	"/etc/X11/%S," "%P/etc/X11/%S," \
87			"/etc/X11/%G," "%P/etc/X11/%G," \
88			"/etc/X11/%X," "/etc/%X," \
89			"%P/etc/X11/%X.%H," \
90			"%P/etc/X11/%X," \
91			"%P/lib/X11/%X.%H," \
92			"%P/lib/X11/%X"
93#endif
94#ifndef ALL_CONFIGDIRPATH
95#define ALL_CONFIGDIRPATH	"%A," "%R," \
96				"/etc/X11/%R," "%C/X11/%R," \
97				"/etc/X11/%X," "%C/X11/%X"
98#endif
99#ifndef RESTRICTED_CONFIGDIRPATH
100#define RESTRICTED_CONFIGDIRPATH	"/etc/X11/%R," "%C/X11/%R," \
101					"/etc/X11/%X," "%C/X11/%X"
102#endif
103#ifndef SYS_CONFIGDIRPATH
104#define SYS_CONFIGDIRPATH	"%D/X11/%X"
105#endif
106#ifndef PROJECTROOT
107#define PROJECTROOT	"/usr/X11R6"
108#endif
109
110static ModuleDefault ModuleDefaults[] = {
111#ifdef GLXEXT
112    {.name = "glx",.toLoad = TRUE,.load_opt = NULL},
113#endif
114#ifdef __CYGWIN__
115    /* load DIX modules used by drivers first */
116    {.name = "fb",.toLoad = TRUE,.load_opt = NULL},
117    {.name = "shadow",.toLoad = TRUE,.load_opt = NULL},
118#endif
119    {.name = NULL,.toLoad = FALSE,.load_opt = NULL}
120};
121
122/* Forward declarations */
123static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
124                         int scrnum, MessageType from, Bool auto_gpu_device);
125static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
126static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
127                         Bool active, Bool gpu);
128static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
129                        MessageType from);
130static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
131static Bool addDefaultModes(MonPtr monitorp);
132
133static void configDRI(XF86ConfDRIPtr drip);
134static void configExtensions(XF86ConfExtensionsPtr conf_ext);
135
136/*
137 * xf86GetPathElem --
138 *	Extract a single element from the font path string starting at
139 *	pnt.  The font path element will be returned, and pnt will be
140 *	updated to point to the start of the next element, or set to
141 *	NULL if there are no more.
142 */
143static char *
144xf86GetPathElem(char **pnt)
145{
146    char *p1;
147
148    p1 = *pnt;
149    *pnt = index(*pnt, ',');
150    if (*pnt != NULL) {
151        **pnt = '\0';
152        *pnt += 1;
153    }
154    return p1;
155}
156
157/*
158 * xf86ValidateFontPath --
159 *	Validates the user-specified font path.  Each element that
160 *	begins with a '/' is checked to make sure the directory exists.
161 *	If the directory exists, the existence of a file named 'fonts.dir'
162 *	is checked.  If either check fails, an error is printed and the
163 *	element is removed from the font path.
164 */
165
166#define DIR_FILE "/fonts.dir"
167static char *
168xf86ValidateFontPath(char *path)
169{
170    char *next, *tmp_path, *out_pnt, *path_elem, *p1, *dir_elem;
171    struct stat stat_buf;
172    int flag;
173    int dirlen;
174
175    tmp_path = calloc(1, strlen(path) + 1);
176    out_pnt = tmp_path;
177    path_elem = NULL;
178    next = path;
179    while (next != NULL) {
180        path_elem = xf86GetPathElem(&next);
181        if (*path_elem == '/') {
182            dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
183            if ((p1 = strchr(path_elem, ':')) != 0)
184                dirlen = p1 - path_elem;
185            else
186                dirlen = strlen(path_elem);
187            strlcpy(dir_elem, path_elem, dirlen + 1);
188            flag = stat(dir_elem, &stat_buf);
189            if (flag == 0)
190                if (!S_ISDIR(stat_buf.st_mode))
191                    flag = -1;
192            if (flag != 0) {
193                xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n",
194                        dir_elem);
195                xf86ErrorF("\tEntry deleted from font path.\n");
196                free(dir_elem);
197                continue;
198            }
199            else {
200                XNFasprintf(&p1, "%s%s", dir_elem, DIR_FILE);
201                flag = stat(p1, &stat_buf);
202                if (flag == 0)
203                    if (!S_ISREG(stat_buf.st_mode))
204                        flag = -1;
205                free(p1);
206                if (flag != 0) {
207                    xf86Msg(X_WARNING,
208                            "`fonts.dir' not found (or not valid) in \"%s\".\n",
209                            dir_elem);
210                    xf86ErrorF("\tEntry deleted from font path.\n");
211                    xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
212                    free(dir_elem);
213                    continue;
214                }
215            }
216            free(dir_elem);
217        }
218
219        /*
220         * Either an OK directory, or a font server name.  So add it to
221         * the path.
222         */
223        if (out_pnt != tmp_path)
224            *out_pnt++ = ',';
225        strcat(out_pnt, path_elem);
226        out_pnt += strlen(path_elem);
227    }
228    return tmp_path;
229}
230
231#define FIND_SUITABLE(pointertype, listhead, ptr)                                            \
232    do {                                                                                     \
233        pointertype _l, _p;                                                                  \
234                                                                                             \
235        for (_l = (listhead), _p = NULL; !_p && _l; _l = (pointertype)_l->list.next) {       \
236            if (!_l->match_seat || (SeatId && xf86nameCompare(_l->match_seat, SeatId) == 0)) \
237                _p = _l;                                                                     \
238        }                                                                                    \
239                                                                                             \
240        (ptr) = _p;                                                                          \
241    } while(0)
242
243/*
244 * use the datastructure that the parser provides and pick out the parts
245 * that we need at this point
246 */
247const char **
248xf86ModulelistFromConfig(void ***optlist)
249{
250    int count = 0, i = 0;
251    const char **modulearray;
252
253    const char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
254        "freetype", "type1",
255        NULL
256    };
257    void **optarray;
258    XF86LoadPtr modp;
259    Bool found;
260
261    /*
262     * make sure the config file has been parsed and that we have a
263     * ModulePath set; if no ModulePath was given, use the default
264     * ModulePath
265     */
266    if (xf86configptr == NULL) {
267        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
268        return NULL;
269    }
270
271    if (xf86configptr->conf_modules) {
272        /* Walk the disable list and let people know what we've parsed to
273         * not be loaded
274         */
275        modp = xf86configptr->conf_modules->mod_disable_lst;
276        while (modp) {
277            xf86Msg(X_WARNING,
278                    "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n",
279                    modp->load_name);
280            modp = (XF86LoadPtr) modp->list.next;
281        }
282        /*
283         * Walk the default settings table. For each module listed to be
284         * loaded, make sure it's in the mod_load_lst. If it's not, make
285         * sure it's not in the mod_no_load_lst. If it's not disabled,
286         * append it to mod_load_lst
287         */
288        for (i = 0; ModuleDefaults[i].name != NULL; i++) {
289            if (ModuleDefaults[i].toLoad == FALSE) {
290                xf86Msg(X_WARNING,
291                        "\"%s\" is not to be loaded by default. Skipping.\n",
292                        ModuleDefaults[i].name);
293                continue;
294            }
295            found = FALSE;
296            modp = xf86configptr->conf_modules->mod_load_lst;
297            while (modp) {
298                if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
299                    xf86Msg(X_INFO,
300                            "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n",
301                            ModuleDefaults[i].name);
302                    found = TRUE;
303                    break;
304                }
305                modp = (XF86LoadPtr) modp->list.next;
306            }
307            if (found == FALSE) {
308                modp = xf86configptr->conf_modules->mod_disable_lst;
309                while (modp) {
310                    if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
311                        xf86Msg(X_INFO,
312                                "\"%s\" will be loaded even though the default is to disable it.\n",
313                                ModuleDefaults[i].name);
314                        found = TRUE;
315                        break;
316                    }
317                    modp = (XF86LoadPtr) modp->list.next;
318                }
319            }
320            if (found == FALSE) {
321                XF86LoadPtr ptr = (XF86LoadPtr) xf86configptr->conf_modules;
322
323                xf86addNewLoadDirective(ptr, ModuleDefaults[i].name,
324                                        XF86_LOAD_MODULE,
325                                        ModuleDefaults[i].load_opt);
326                xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n",
327                        ModuleDefaults[i].name);
328            }
329        }
330    }
331    else {
332        xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
333        for (i = 0; ModuleDefaults[i].name != NULL; i++) {
334            if (ModuleDefaults[i].toLoad == TRUE) {
335                XF86LoadPtr ptr = (XF86LoadPtr) xf86configptr->conf_modules;
336
337                xf86addNewLoadDirective(ptr, ModuleDefaults[i].name,
338                                        XF86_LOAD_MODULE,
339                                        ModuleDefaults[i].load_opt);
340            }
341        }
342    }
343
344    /*
345     * Walk the list of modules in the "Module" section to determine how
346     * many we have.
347     */
348    modp = xf86configptr->conf_modules->mod_load_lst;
349    while (modp) {
350        for (i = 0; ignore[i]; i++) {
351            if (strcmp(modp->load_name, ignore[i]) == 0)
352                modp->ignore = 1;
353        }
354        if (!modp->ignore)
355            count++;
356        modp = (XF86LoadPtr) modp->list.next;
357    }
358
359    /*
360     * allocate the memory and walk the list again to fill in the pointers
361     */
362    modulearray = xnfallocarray(count + 1, sizeof(char *));
363    optarray = xnfallocarray(count + 1, sizeof(void *));
364    count = 0;
365    if (xf86configptr->conf_modules) {
366        modp = xf86configptr->conf_modules->mod_load_lst;
367        while (modp) {
368            if (!modp->ignore) {
369                modulearray[count] = modp->load_name;
370                optarray[count] = modp->load_opt;
371                count++;
372            }
373            modp = (XF86LoadPtr) modp->list.next;
374        }
375    }
376    modulearray[count] = NULL;
377    optarray[count] = NULL;
378    if (optlist)
379        *optlist = optarray;
380    else
381        free(optarray);
382    return modulearray;
383}
384
385const char **
386xf86DriverlistFromConfig(void)
387{
388    int count = 0;
389    int j, k;
390    const char **modulearray;
391    screenLayoutPtr slp;
392
393    /*
394     * make sure the config file has been parsed and that we have a
395     * ModulePath set; if no ModulePath was given, use the default
396     * ModulePath
397     */
398    if (xf86configptr == NULL) {
399        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
400        return NULL;
401    }
402
403    /*
404     * Walk the list of driver lines in active "Device" sections to
405     * determine now many implicitly loaded modules there are.
406     *
407     */
408    if (xf86ConfigLayout.screens) {
409        slp = xf86ConfigLayout.screens;
410        while (slp->screen) {
411            count++;
412            count += slp->screen->num_gpu_devices;
413            slp++;
414        }
415    }
416
417    /*
418     * Handle the set of inactive "Device" sections.
419     */
420    j = 0;
421    while (xf86ConfigLayout.inactives[j++].identifier)
422        count++;
423
424    if (count == 0)
425        return NULL;
426
427    /*
428     * allocate the memory and walk the list again to fill in the pointers
429     */
430    modulearray = xnfallocarray(count + 1, sizeof(char *));
431    count = 0;
432    slp = xf86ConfigLayout.screens;
433    while (slp->screen) {
434        modulearray[count] = slp->screen->device->driver;
435        count++;
436        for (k = 0; k < slp->screen->num_gpu_devices; k++) {
437            modulearray[count] = slp->screen->gpu_devices[k]->driver;
438            count++;
439        }
440        slp++;
441    }
442
443    j = 0;
444
445    while (xf86ConfigLayout.inactives[j].identifier)
446        modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
447
448    modulearray[count] = NULL;
449
450    /* Remove duplicates */
451    for (count = 0; modulearray[count] != NULL; count++) {
452        int i;
453
454        for (i = 0; i < count; i++)
455            if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
456                modulearray[count] = "";
457                break;
458            }
459    }
460    return modulearray;
461}
462
463const char **
464xf86InputDriverlistFromConfig(void)
465{
466    int count = 0;
467    const char **modulearray;
468    InputInfoPtr *idp;
469
470    /*
471     * make sure the config file has been parsed and that we have a
472     * ModulePath set; if no ModulePath was given, use the default
473     * ModulePath
474     */
475    if (xf86configptr == NULL) {
476        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
477        return NULL;
478    }
479
480    /*
481     * Walk the list of driver lines in active "InputDevice" sections to
482     * determine now many implicitly loaded modules there are.
483     */
484    if (xf86ConfigLayout.inputs) {
485        idp = xf86ConfigLayout.inputs;
486        while (*idp) {
487            count++;
488            idp++;
489        }
490    }
491
492    if (count == 0)
493        return NULL;
494
495    /*
496     * allocate the memory and walk the list again to fill in the pointers
497     */
498    modulearray = xnfallocarray(count + 1, sizeof(char *));
499    count = 0;
500    idp = xf86ConfigLayout.inputs;
501    while (idp && *idp) {
502        modulearray[count] = (*idp)->driver;
503        count++;
504        idp++;
505    }
506    modulearray[count] = NULL;
507
508    /* Remove duplicates */
509    for (count = 0; modulearray[count] != NULL; count++) {
510        int i;
511
512        for (i = 0; i < count; i++)
513            if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
514                modulearray[count] = "";
515                break;
516            }
517    }
518    return modulearray;
519}
520
521static int
522is_fallback(const char *s)
523{
524    /* later entries are less preferred */
525    const char *fallback[5] = { "modesetting", "fbdev", "vesa",  "wsfb", NULL };
526    int i;
527
528    for (i = 0; fallback[i]; i++)
529	if (strstr(s, fallback[i]))
530	    return i;
531
532    return -1;
533}
534
535static int
536driver_sort(const void *_l, const void *_r)
537{
538    const char *l = *(const char **)_l;
539    const char *r = *(const char **)_r;
540    int left = is_fallback(l);
541    int right = is_fallback(r);
542
543    /* neither is a fallback, asciibetize */
544    if (left == -1 && right == -1)
545	return strcmp(l, r);
546
547    /* left is a fallback */
548    if (left >= 0)
549	return 1;
550
551    /* right is a fallback */
552    if (right >= 0)
553	return -1;
554
555    /* both are fallbacks, which is worse */
556    return left - right;
557}
558
559static void
560fixup_video_driver_list(const char **drivers)
561{
562    const char **end;
563
564    /* walk to the end of the list */
565    for (end = drivers; *end && **end; end++);
566    end--;
567
568    qsort(drivers, end - drivers, sizeof(const char *), driver_sort);
569}
570
571static const char **
572GenerateDriverlist(const char *dirname)
573{
574    const char **ret;
575    const char *subdirs[] = { dirname, NULL };
576    static const char *patlist[] = { "(.*)_drv\\.so", NULL };
577    ret = LoaderListDirs(subdirs, patlist);
578
579    /* fix up the probe order for video drivers */
580    if (strstr(dirname, "drivers") && ret != NULL)
581        fixup_video_driver_list(ret);
582
583    return ret;
584}
585
586const char **
587xf86DriverlistFromCompile(void)
588{
589    static const char **driverlist = NULL;
590
591    if (!driverlist)
592        driverlist = GenerateDriverlist("drivers");
593
594    return driverlist;
595}
596
597static void
598configFiles(XF86ConfFilesPtr fileconf)
599{
600    MessageType pathFrom;
601    Bool must_copy;
602    int size, countDirs;
603    char *temp_path, *log_buf, *start, *end;
604
605    /* FontPath */
606    must_copy = TRUE;
607
608    temp_path = defaultFontPath ? (char *) defaultFontPath : (char *) "";
609    if (xf86fpFlag)
610        pathFrom = X_CMDLINE;
611    else if (fileconf && fileconf->file_fontpath) {
612        pathFrom = X_CONFIG;
613        if (xf86Info.useDefaultFontPath) {
614            char *new_font_path;
615            if (asprintf(&new_font_path, "%s%s%s", fileconf->file_fontpath,
616                         *temp_path ? "," : "", temp_path) == -1)
617                new_font_path = NULL;
618            else
619                must_copy = FALSE;
620            defaultFontPath = new_font_path;
621        }
622        else
623            defaultFontPath = fileconf->file_fontpath;
624    }
625    else
626        pathFrom = X_DEFAULT;
627    temp_path = defaultFontPath ? (char *) defaultFontPath : (char *) "";
628
629    /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
630    temp_path = must_copy ? xnfstrdup(defaultFontPath) : (char *) defaultFontPath;
631    defaultFontPath = xf86ValidateFontPath(temp_path);
632    free(temp_path);
633
634    /* make fontpath more readable in the logfiles */
635    countDirs = 1;
636    temp_path = (char *) defaultFontPath;
637    while ((temp_path = index(temp_path, ',')) != NULL) {
638        countDirs++;
639        temp_path++;
640    }
641
642    log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
643    temp_path = log_buf;
644    start = (char *) defaultFontPath;
645    while ((end = index(start, ',')) != NULL) {
646        size = (end - start) + 1;
647        *(temp_path++) = '\t';
648        strncpy(temp_path, start, size);
649        temp_path += size;
650        *(temp_path++) = '\n';
651        start += size;
652    }
653    /* copy last entry */
654    *(temp_path++) = '\t';
655    strcpy(temp_path, start);
656    xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
657    free(log_buf);
658
659    /* ModulePath */
660
661    if (fileconf) {
662        if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
663            xf86ModulePath = fileconf->file_modulepath;
664            xf86ModPathFrom = X_CONFIG;
665        }
666    }
667
668    xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
669
670    if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
671        XkbBaseDirectory = fileconf->file_xkbdir;
672        xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
673                XkbBaseDirectory);
674    }
675#if 0
676    /* LogFile */
677    /*
678     * XXX The problem with this is that the log file is already open.
679     * One option might be to copy the exiting contents to the new location.
680     * and re-open it.  The down side is that the default location would
681     * already have been overwritten.  Another option would be to start with
682     * unique temporary location, then copy it once the correct name is known.
683     * A problem with this is what happens if the server exits before that
684     * happens.
685     */
686    if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
687        xf86LogFile = fileconf->file_logfile;
688        xf86LogFileFrom = X_CONFIG;
689    }
690#endif
691
692    return;
693}
694
695typedef enum {
696    FLAG_NOTRAPSIGNALS,
697    FLAG_DONTVTSWITCH,
698    FLAG_DONTZAP,
699    FLAG_DONTZOOM,
700    FLAG_DISABLEVIDMODE,
701    FLAG_ALLOWNONLOCAL,
702    FLAG_ALLOWMOUSEOPENFAIL,
703    FLAG_SAVER_BLANKTIME,
704    FLAG_DPMS_STANDBYTIME,
705    FLAG_DPMS_SUSPENDTIME,
706    FLAG_DPMS_OFFTIME,
707    FLAG_PIXMAP,
708    FLAG_NOPM,
709    FLAG_XINERAMA,
710    FLAG_LOG,
711    FLAG_RENDER_COLORMAP_MODE,
712    FLAG_RANDR,
713    FLAG_AIGLX,
714    FLAG_IGNORE_ABI,
715    FLAG_ALLOW_EMPTY_INPUT,
716    FLAG_USE_DEFAULT_FONT_PATH,
717    FLAG_AUTO_ADD_DEVICES,
718    FLAG_AUTO_ENABLE_DEVICES,
719    FLAG_GLX_VISUALS,
720    FLAG_DRI2,
721    FLAG_USE_SIGIO,
722    FLAG_AUTO_ADD_GPU,
723    FLAG_MAX_CLIENTS,
724    FLAG_IGLX,
725} FlagValues;
726
727/**
728 * NOTE: the last value for each entry is NOT the default. It is set to TRUE
729 * if the parser found the option in the config file.
730 */
731static OptionInfoRec FlagOptions[] = {
732    {FLAG_NOTRAPSIGNALS, "NoTrapSignals", OPTV_BOOLEAN,
733     {0}, FALSE},
734    {FLAG_DONTVTSWITCH, "DontVTSwitch", OPTV_BOOLEAN,
735     {0}, FALSE},
736    {FLAG_DONTZAP, "DontZap", OPTV_BOOLEAN,
737     {0}, FALSE},
738    {FLAG_DONTZOOM, "DontZoom", OPTV_BOOLEAN,
739     {0}, FALSE},
740    {FLAG_DISABLEVIDMODE, "DisableVidModeExtension", OPTV_BOOLEAN,
741     {0}, FALSE},
742    {FLAG_ALLOWNONLOCAL, "AllowNonLocalXvidtune", OPTV_BOOLEAN,
743     {0}, FALSE},
744    {FLAG_ALLOWMOUSEOPENFAIL, "AllowMouseOpenFail", OPTV_BOOLEAN,
745     {0}, FALSE},
746    {FLAG_SAVER_BLANKTIME, "BlankTime", OPTV_INTEGER,
747     {0}, FALSE},
748    {FLAG_DPMS_STANDBYTIME, "StandbyTime", OPTV_INTEGER,
749     {0}, FALSE},
750    {FLAG_DPMS_SUSPENDTIME, "SuspendTime", OPTV_INTEGER,
751     {0}, FALSE},
752    {FLAG_DPMS_OFFTIME, "OffTime", OPTV_INTEGER,
753     {0}, FALSE},
754    {FLAG_PIXMAP, "Pixmap", OPTV_INTEGER,
755     {0}, FALSE},
756    {FLAG_NOPM, "NoPM", OPTV_BOOLEAN,
757     {0}, FALSE},
758    {FLAG_XINERAMA, "Xinerama", OPTV_BOOLEAN,
759     {0}, FALSE},
760    {FLAG_LOG, "Log", OPTV_STRING,
761     {0}, FALSE},
762    {FLAG_RENDER_COLORMAP_MODE, "RenderColormapMode", OPTV_STRING,
763     {0}, FALSE},
764    {FLAG_RANDR, "RandR", OPTV_BOOLEAN,
765     {0}, FALSE},
766    {FLAG_AIGLX, "AIGLX", OPTV_BOOLEAN,
767     {0}, FALSE},
768    {FLAG_IGNORE_ABI, "IgnoreABI", OPTV_BOOLEAN,
769     {0}, FALSE},
770    {FLAG_USE_DEFAULT_FONT_PATH, "UseDefaultFontPath", OPTV_BOOLEAN,
771     {0}, FALSE},
772    {FLAG_AUTO_ADD_DEVICES, "AutoAddDevices", OPTV_BOOLEAN,
773     {0}, FALSE},
774    {FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
775     {0}, FALSE},
776    {FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
777     {0}, FALSE},
778    {FLAG_DRI2, "DRI2", OPTV_BOOLEAN,
779     {0}, FALSE},
780    {FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
781     {0}, FALSE},
782    {FLAG_AUTO_ADD_GPU, "AutoAddGPU", OPTV_BOOLEAN,
783     {0}, FALSE},
784    {FLAG_MAX_CLIENTS, "MaxClients", OPTV_INTEGER,
785     {0}, FALSE },
786    {FLAG_IGLX, "IndirectGLX", OPTV_BOOLEAN,
787     {0}, FALSE},
788    {-1, NULL, OPTV_NONE,
789     {0}, FALSE},
790};
791
792static void
793configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
794{
795    XF86OptionPtr optp, tmp;
796    int i;
797    Pix24Flags pix24 = Pix24DontCare;
798    Bool value;
799    MessageType from;
800    const char *s;
801    XkbRMLVOSet set;
802    const char *rules;
803
804    /*
805     * Merge the ServerLayout and ServerFlags options.  The former have
806     * precedence over the latter.
807     */
808    optp = NULL;
809    if (flagsconf && flagsconf->flg_option_lst)
810        optp = xf86optionListDup(flagsconf->flg_option_lst);
811    if (layoutopts) {
812        tmp = xf86optionListDup(layoutopts);
813        if (optp)
814            optp = xf86optionListMerge(optp, tmp);
815        else
816            optp = tmp;
817    }
818
819    xf86ProcessOptions(-1, optp, FlagOptions);
820
821    xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
822    xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
823    xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
824    xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
825
826    xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
827    if (xf86Info.ignoreABI) {
828        xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
829    }
830
831    if (xf86SIGIOSupported()) {
832        xf86Info.useSIGIO =
833            xf86ReturnOptValBool(FlagOptions, FLAG_USE_SIGIO,
834                                 USE_SIGIO_BY_DEFAULT);
835        if (xf86IsOptionSet(FlagOptions, FLAG_USE_SIGIO)) {
836            from = X_CONFIG;
837        }
838        else {
839            from = X_DEFAULT;
840        }
841        if (!xf86Info.useSIGIO) {
842            xf86Msg(from, "Disabling SIGIO handlers for input devices\n");
843        }
844        else if (from == X_CONFIG) {
845            xf86Msg(from, "Enabling SIGIO handlers for input devices\n");
846        }
847    }
848    else {
849        xf86Info.useSIGIO = FALSE;
850    }
851
852    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
853        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
854                          &xf86Info.autoAddDevices);
855        from = X_CONFIG;
856    }
857    else {
858        from = X_DEFAULT;
859    }
860    xf86Msg(from, "%sutomatically adding devices\n",
861            xf86Info.autoAddDevices ? "A" : "Not a");
862
863    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
864        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
865                          &xf86Info.autoEnableDevices);
866        from = X_CONFIG;
867    }
868    else {
869        from = X_DEFAULT;
870    }
871    xf86Msg(from, "%sutomatically enabling devices\n",
872            xf86Info.autoEnableDevices ? "A" : "Not a");
873
874    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_GPU)) {
875        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_GPU,
876                          &xf86Info.autoAddGPU);
877        from = X_CONFIG;
878    }
879    else {
880        from = X_DEFAULT;
881    }
882    xf86Msg(from, "%sutomatically adding GPU devices\n",
883            xf86Info.autoAddGPU ? "A" : "Not a");
884    /*
885     * Set things up based on the config file information.  Some of these
886     * settings may be overridden later when the command line options are
887     * checked.
888     */
889#ifdef XF86VIDMODE
890    if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
891        xf86Info.vidModeEnabled = !value;
892    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
893        xf86Info.vidModeAllowNonLocal = value;
894#endif
895
896    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
897        xf86Info.allowMouseOpenFail = value;
898
899    xf86Info.pmFlag = TRUE;
900    if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
901        xf86Info.pmFlag = !value;
902    {
903        if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
904            if (!xf86NameCmp(s, "flush")) {
905                xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
906                LogSetParameter(XLOG_FLUSH, TRUE);
907            }
908            else if (!xf86NameCmp(s, "sync")) {
909                xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
910                LogSetParameter(XLOG_FLUSH, TRUE);
911                LogSetParameter(XLOG_SYNC, TRUE);
912            }
913            else {
914                xf86Msg(X_WARNING, "Unknown Log option\n");
915            }
916        }
917    }
918
919    {
920        if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))) {
921            int policy = PictureParseCmapPolicy(s);
922
923            if (policy == PictureCmapPolicyInvalid)
924                xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
925            else {
926                xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
927                PictureCmapPolicy = policy;
928            }
929        }
930    }
931
932#ifdef RANDR
933    xf86Info.disableRandR = FALSE;
934    xf86Info.randRFrom = X_DEFAULT;
935    if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
936        xf86Info.disableRandR = !value;
937        xf86Info.randRFrom = X_CONFIG;
938    }
939#endif
940
941    xf86Info.aiglx = TRUE;
942    xf86Info.aiglxFrom = X_DEFAULT;
943    if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
944        xf86Info.aiglx = value;
945        xf86Info.aiglxFrom = X_CONFIG;
946    }
947
948#ifdef GLXEXT
949    xf86Info.glxVisuals = XF86_GlxVisualsTypical;
950    xf86Info.glxVisualsFrom = X_DEFAULT;
951    if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
952        if (!xf86NameCmp(s, "minimal")) {
953            xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
954        }
955        else if (!xf86NameCmp(s, "typical")) {
956            xf86Info.glxVisuals = XF86_GlxVisualsTypical;
957        }
958        else if (!xf86NameCmp(s, "all")) {
959            xf86Info.glxVisuals = XF86_GlxVisualsAll;
960        }
961        else {
962            xf86Msg(X_WARNING, "Unknown GlxVisuals option\n");
963        }
964    }
965
966    if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
967        xf86Info.aiglx = value;
968        xf86Info.aiglxFrom = X_CONFIG;
969    }
970    if (xf86Info.iglxFrom != X_CMDLINE) {
971        if (xf86GetOptValBool(FlagOptions, FLAG_IGLX, &value)) {
972            enableIndirectGLX = value;
973            xf86Info.iglxFrom = X_CONFIG;
974        }
975    }
976#endif
977
978    /* if we're not hotplugging, force some input devices to exist */
979    xf86Info.forceInputDevices = !(xf86Info.autoAddDevices &&
980                                   xf86Info.autoEnableDevices);
981
982    /* when forcing input devices, we use kbd. otherwise evdev, so use the
983     * evdev rules set. */
984#if defined(linux)
985    if (!xf86Info.forceInputDevices)
986        rules = "evdev";
987    else
988#endif
989        rules = "base";
990
991    /* Xkb default options. */
992    XkbInitRules(&set, rules, "pc105", "us", NULL, NULL);
993    XkbSetRulesDflts(&set);
994    XkbFreeRMLVOSet(&set, FALSE);
995
996    xf86Info.useDefaultFontPath = TRUE;
997    if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
998        xf86Info.useDefaultFontPath = value;
999    }
1000
1001/* Make sure that timers don't overflow CARD32's after multiplying */
1002#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
1003
1004    i = -1;
1005    xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
1006    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
1007        ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
1008    else if (i != -1)
1009        ErrorF("BlankTime value %d outside legal range of 0 - %d minutes\n",
1010               i, MAX_TIME_IN_MIN);
1011
1012#ifdef DPMSExtension
1013    i = -1;
1014    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
1015    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
1016        DPMSStandbyTime = i * MILLI_PER_MIN;
1017    else if (i != -1)
1018        ErrorF("StandbyTime value %d outside legal range of 0 - %d minutes\n",
1019               i, MAX_TIME_IN_MIN);
1020    i = -1;
1021    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
1022    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
1023        DPMSSuspendTime = i * MILLI_PER_MIN;
1024    else if (i != -1)
1025        ErrorF("SuspendTime value %d outside legal range of 0 - %d minutes\n",
1026               i, MAX_TIME_IN_MIN);
1027    i = -1;
1028    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
1029    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
1030        DPMSOffTime = i * MILLI_PER_MIN;
1031    else if (i != -1)
1032        ErrorF("OffTime value %d outside legal range of 0 - %d minutes\n",
1033               i, MAX_TIME_IN_MIN);
1034#endif
1035
1036    i = -1;
1037    xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
1038    switch (i) {
1039    case 24:
1040        pix24 = Pix24Use24;
1041        break;
1042    case 32:
1043        pix24 = Pix24Use32;
1044        break;
1045    case -1:
1046        break;
1047    default:
1048        ErrorF("Pixmap option's value (%d) must be 24 or 32\n", i);
1049        break;
1050    }
1051    if (xf86Pix24 != Pix24DontCare) {
1052        xf86Info.pixmap24 = xf86Pix24;
1053        xf86Info.pix24From = X_CMDLINE;
1054    }
1055    else if (pix24 != Pix24DontCare) {
1056        xf86Info.pixmap24 = pix24;
1057        xf86Info.pix24From = X_CONFIG;
1058    }
1059    else {
1060        xf86Info.pixmap24 = Pix24DontCare;
1061        xf86Info.pix24From = X_DEFAULT;
1062    }
1063
1064#ifdef PANORAMIX
1065    from = X_DEFAULT;
1066    if (!noPanoramiXExtension)
1067        from = X_CMDLINE;
1068    else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
1069        noPanoramiXExtension = !value;
1070        from = X_CONFIG;
1071    }
1072    if (!noPanoramiXExtension)
1073        xf86Msg(from, "Xinerama: enabled\n");
1074#endif
1075
1076#ifdef DRI2
1077    xf86Info.dri2 = FALSE;
1078    xf86Info.dri2From = X_DEFAULT;
1079    if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
1080        xf86Info.dri2 = value;
1081        xf86Info.dri2From = X_CONFIG;
1082    }
1083#endif
1084
1085    from = X_DEFAULT;
1086    if (LimitClients != LIMITCLIENTS)
1087	from = X_CMDLINE;
1088    i = -1;
1089    if (xf86GetOptValInteger(FlagOptions, FLAG_MAX_CLIENTS, &i)) {
1090	if (i != 64 && i != 128 && i != 256 && i != 512)
1091		ErrorF("MaxClients must be one of 64, 128, 256 or 512\n");
1092	from = X_CONFIG;
1093	LimitClients = i;
1094    }
1095    xf86Msg(from, "Max clients allowed: %i, resource mask: 0x%x\n",
1096	    LimitClients, RESOURCE_ID_MASK);
1097}
1098
1099Bool
1100xf86DRI2Enabled(void)
1101{
1102    return xf86Info.dri2;
1103}
1104
1105/**
1106 * Search for the pInfo in the null-terminated list given and remove (and
1107 * free) it if present. All other devices are moved forward.
1108 */
1109static void
1110freeDevice(InputInfoPtr * list, InputInfoPtr pInfo)
1111{
1112    InputInfoPtr *devs;
1113
1114    for (devs = list; devs && *devs; devs++) {
1115        if (*devs == pInfo) {
1116            free(*devs);
1117            for (; devs && *devs; devs++)
1118                devs[0] = devs[1];
1119            break;
1120        }
1121    }
1122}
1123
1124/**
1125 * Append pInfo to the null-terminated list, allocating space as necessary.
1126 * pInfo is used as the last element.
1127 */
1128static InputInfoPtr *
1129addDevice(InputInfoPtr * list, InputInfoPtr pInfo)
1130{
1131    InputInfoPtr *devs;
1132    int count = 1;
1133
1134    for (devs = list; devs && *devs; devs++)
1135        count++;
1136
1137    list = xnfreallocarray(list, count + 1, sizeof(InputInfoPtr));
1138    list[count] = NULL;
1139
1140    list[count - 1] = pInfo;
1141    return list;
1142}
1143
1144/*
1145 * Locate the core input devices.  These can be specified/located in
1146 * the following ways, in order of priority:
1147 *
1148 *  1. The InputDevices named by the -pointer and -keyboard command line
1149 *     options.
1150 *  2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
1151 *     the active ServerLayout.
1152 *  3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
1153 *  4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
1154 *     driver (mouse, synaptics, evdev, vmmouse, void)
1155 *  5. Default devices with an empty (default) configuration.  These defaults
1156 *     will reference the 'mouse' and 'keyboard' drivers.
1157 */
1158
1159static Bool
1160checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
1161{
1162    InputInfoPtr corePointer = NULL, coreKeyboard = NULL;
1163    Bool foundPointer = FALSE, foundKeyboard = FALSE;
1164    const char *pointerMsg = NULL, *keyboardMsg = NULL;
1165    InputInfoPtr *devs,         /* iterator */
1166     indp;
1167    InputInfoPtr Pointer, Keyboard;
1168    XF86ConfInputPtr confInput;
1169    XF86ConfInputRec defPtr, defKbd;
1170    MessageType from = X_DEFAULT;
1171
1172    const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
1173        "void", NULL
1174    };
1175
1176    /*
1177     * First check if a core pointer or core keyboard have been specified
1178     * in the active ServerLayout.  If more than one is specified for either,
1179     * remove the core attribute from the later ones.
1180     */
1181    for (devs = servlayoutp->inputs; devs && *devs; devs++) {
1182        indp = *devs;
1183        if (indp->options &&
1184            xf86CheckBoolOption(indp->options, "CorePointer", FALSE)) {
1185            if (!corePointer) {
1186                corePointer = indp;
1187            }
1188        }
1189        if (indp->options &&
1190            xf86CheckBoolOption(indp->options, "CoreKeyboard", FALSE)) {
1191            if (!coreKeyboard) {
1192                coreKeyboard = indp;
1193            }
1194        }
1195    }
1196
1197    confInput = NULL;
1198
1199    /* 1. Check for the -pointer command line option. */
1200    if (xf86PointerName) {
1201        confInput = xf86findInput(xf86PointerName,
1202                                  xf86configptr->conf_input_lst);
1203        if (!confInput) {
1204            xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1205                    xf86PointerName);
1206            return FALSE;
1207        }
1208        from = X_CMDLINE;
1209        /*
1210         * If one was already specified in the ServerLayout, it needs to be
1211         * removed.
1212         */
1213        if (corePointer) {
1214            freeDevice(servlayoutp->inputs, corePointer);
1215            corePointer = NULL;
1216        }
1217        foundPointer = TRUE;
1218    }
1219
1220    /* 2. ServerLayout-specified core pointer. */
1221    if (corePointer) {
1222        foundPointer = TRUE;
1223        from = X_CONFIG;
1224    }
1225
1226    /* 3. First core pointer device. */
1227    if (!foundPointer && (xf86Info.forceInputDevices || implicitLayout)) {
1228        XF86ConfInputPtr p;
1229
1230        for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1231            if (p->inp_option_lst &&
1232                xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
1233                confInput = p;
1234                foundPointer = TRUE;
1235                from = X_DEFAULT;
1236                pointerMsg = "first core pointer device";
1237                break;
1238            }
1239        }
1240    }
1241
1242    /* 4. First pointer with an allowed mouse driver. */
1243    if (!foundPointer && xf86Info.forceInputDevices) {
1244        const char **driver = mousedrivers;
1245
1246        confInput = xf86findInput(CONF_IMPLICIT_POINTER,
1247                                  xf86configptr->conf_input_lst);
1248        while (*driver && !confInput) {
1249            confInput = xf86findInputByDriver(*driver,
1250                                              xf86configptr->conf_input_lst);
1251            driver++;
1252        }
1253        if (confInput) {
1254            foundPointer = TRUE;
1255            from = X_DEFAULT;
1256            pointerMsg = "first mouse device";
1257        }
1258    }
1259
1260    /* 5. Built-in default. */
1261    if (!foundPointer && xf86Info.forceInputDevices) {
1262        memset(&defPtr, 0, sizeof(defPtr));
1263        defPtr.inp_identifier = strdup("<default pointer>");
1264#if defined(__NetBSD__) && (defined(__i386__) || defined(__amd64__))
1265	if (xf86findDeviceByDriver("vmware", xf86configptr->conf_device_lst) ||
1266	    xf86findDeviceByDriver("vmwlegacy", xf86configptr->conf_device_lst)) {
1267		defPtr.inp_driver = strdup("vmmouse");
1268		defPtr.inp_option_lst = xf86addNewOption(defPtr.inp_option_lst, strdup("Protocol"), "wsmouse");
1269		defPtr.inp_option_lst = xf86addNewOption(defPtr.inp_option_lst, strdup("Device"), "/dev/wsmouse");
1270	} else {
1271#endif
1272        defPtr.inp_driver = strdup("mouse");
1273#if defined(__NetBSD__) && (defined(__i386__) || defined(__amd64__))
1274        }
1275#endif
1276        confInput = &defPtr;
1277        foundPointer = TRUE;
1278        from = X_DEFAULT;
1279        pointerMsg = "default mouse configuration";
1280    }
1281
1282    /* Add the core pointer device to the layout, and set it to Core. */
1283    if (foundPointer && confInput) {
1284        Pointer = xf86AllocateInput();
1285        if (Pointer)
1286            foundPointer = configInput(Pointer, confInput, from);
1287        if (foundPointer) {
1288            Pointer->options = xf86AddNewOption(Pointer->options,
1289                                                "CorePointer", "on");
1290            Pointer->options = xf86AddNewOption(Pointer->options,
1291                                                "driver",
1292                                                confInput->inp_driver);
1293            Pointer->options =
1294                xf86AddNewOption(Pointer->options, "identifier",
1295                                 confInput->inp_identifier);
1296            servlayoutp->inputs = addDevice(servlayoutp->inputs, Pointer);
1297        }
1298    }
1299
1300    if (!foundPointer && xf86Info.forceInputDevices) {
1301        /* This shouldn't happen. */
1302        xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
1303        xf86DeleteInput(Pointer, 0);
1304        return FALSE;
1305    }
1306
1307    confInput = NULL;
1308
1309    /* 1. Check for the -keyboard command line option. */
1310    if (xf86KeyboardName) {
1311        confInput = xf86findInput(xf86KeyboardName,
1312                                  xf86configptr->conf_input_lst);
1313        if (!confInput) {
1314            xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1315                    xf86KeyboardName);
1316            return FALSE;
1317        }
1318        from = X_CMDLINE;
1319        /*
1320         * If one was already specified in the ServerLayout, it needs to be
1321         * removed.
1322         */
1323        if (coreKeyboard) {
1324            freeDevice(servlayoutp->inputs, coreKeyboard);
1325            coreKeyboard = NULL;
1326        }
1327        foundKeyboard = TRUE;
1328    }
1329
1330    /* 2. ServerLayout-specified core keyboard. */
1331    if (coreKeyboard) {
1332        foundKeyboard = TRUE;
1333        from = X_CONFIG;
1334    }
1335
1336    /* 3. First core keyboard device. */
1337    if (!foundKeyboard && (xf86Info.forceInputDevices || implicitLayout)) {
1338        XF86ConfInputPtr p;
1339
1340        for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1341            if (p->inp_option_lst &&
1342                xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
1343                confInput = p;
1344                foundKeyboard = TRUE;
1345                from = X_DEFAULT;
1346                keyboardMsg = "first core keyboard device";
1347                break;
1348            }
1349        }
1350    }
1351
1352    /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
1353    if (!foundKeyboard && xf86Info.forceInputDevices) {
1354        confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
1355                                  xf86configptr->conf_input_lst);
1356        if (!confInput) {
1357            confInput = xf86findInputByDriver("kbd",
1358                                              xf86configptr->conf_input_lst);
1359        }
1360        if (confInput) {
1361            foundKeyboard = TRUE;
1362            from = X_DEFAULT;
1363            keyboardMsg = "first keyboard device";
1364        }
1365    }
1366
1367    /* 5. Built-in default. */
1368    if (!foundKeyboard && xf86Info.forceInputDevices) {
1369        memset(&defKbd, 0, sizeof(defKbd));
1370        defKbd.inp_identifier = strdup("<default keyboard>");
1371        defKbd.inp_driver = strdup("kbd");
1372        confInput = &defKbd;
1373        foundKeyboard = TRUE;
1374        keyboardMsg = "default keyboard configuration";
1375        from = X_DEFAULT;
1376    }
1377
1378    /* Add the core keyboard device to the layout, and set it to Core. */
1379    if (foundKeyboard && confInput) {
1380        Keyboard = xf86AllocateInput();
1381        if (Keyboard)
1382            foundKeyboard = configInput(Keyboard, confInput, from);
1383        if (foundKeyboard) {
1384            Keyboard->options = xf86AddNewOption(Keyboard->options,
1385                                                 "CoreKeyboard", "on");
1386            Keyboard->options = xf86AddNewOption(Keyboard->options,
1387                                                 "driver",
1388                                                 confInput->inp_driver);
1389            Keyboard->options =
1390                xf86AddNewOption(Keyboard->options, "identifier",
1391                                 confInput->inp_identifier);
1392            servlayoutp->inputs = addDevice(servlayoutp->inputs, Keyboard);
1393        }
1394    }
1395
1396    if (!foundKeyboard && xf86Info.forceInputDevices) {
1397        /* This shouldn't happen. */
1398        xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
1399        xf86DeleteInput(Keyboard, 0);
1400        return FALSE;
1401    }
1402
1403    if (pointerMsg) {
1404        if (implicitLayout)
1405            xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1406                    pointerMsg);
1407        else
1408            xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
1409                    "explicitly in the layout.\n"
1410                    "\tUsing the %s.\n", pointerMsg);
1411    }
1412
1413    if (keyboardMsg) {
1414        if (implicitLayout)
1415            xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1416                    keyboardMsg);
1417        else
1418            xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
1419                    "explicitly in the layout.\n"
1420                    "\tUsing the %s.\n", keyboardMsg);
1421    }
1422
1423    if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) {
1424#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS)
1425        const char *config_backend;
1426
1427#if defined(CONFIG_HAL)
1428        config_backend = "HAL";
1429#elif defined(CONFIG_UDEV)
1430        config_backend = "udev";
1431#else
1432        config_backend = "wscons";
1433#endif
1434        xf86Msg(X_INFO, "The server relies on %s to provide the list of "
1435                "input devices.\n\tIf no devices become available, "
1436                "reconfigure %s or disable AutoAddDevices.\n",
1437                config_backend, config_backend);
1438#else
1439        xf86Msg(X_WARNING, "Hotplugging requested but the server was "
1440                "compiled without a config backend. "
1441                "No input devices were configured, the server "
1442                "will start without any input devices.\n");
1443#endif
1444    }
1445
1446    return TRUE;
1447}
1448
1449typedef enum {
1450    LAYOUT_ISOLATEDEVICE,
1451    LAYOUT_SINGLECARD
1452} LayoutValues;
1453
1454static OptionInfoRec LayoutOptions[] = {
1455    {LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
1456     {0}, FALSE},
1457    {LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
1458     {0}, FALSE},
1459    {-1, NULL, OPTV_NONE,
1460     {0}, FALSE},
1461};
1462
1463static Bool
1464configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
1465{
1466    XF86ConfInputrefPtr irp;
1467    InputInfoPtr *indp;
1468    int count = 0;
1469
1470    /*
1471     * Count the number of input devices.
1472     */
1473    irp = layout->lay_input_lst;
1474    while (irp) {
1475        count++;
1476        irp = (XF86ConfInputrefPtr) irp->list.next;
1477    }
1478    DebugF("Found %d input devices in the layout section %s\n",
1479           count, layout->lay_identifier);
1480    indp = xnfcalloc((count + 1), sizeof(InputInfoPtr));
1481    indp[count] = NULL;
1482    irp = layout->lay_input_lst;
1483    count = 0;
1484    while (irp) {
1485        indp[count] = xf86AllocateInput();
1486        if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
1487            do {
1488                free(indp[count]);
1489            } while (count--);
1490            free(indp);
1491            return FALSE;
1492        }
1493        indp[count]->options = xf86OptionListMerge(indp[count]->options,
1494                                                   irp->iref_option_lst);
1495        count++;
1496        irp = (XF86ConfInputrefPtr) irp->list.next;
1497    }
1498    servlayoutp->inputs = indp;
1499
1500    return TRUE;
1501}
1502
1503/*
1504 * figure out which layout is active, which screens are used in that layout,
1505 * which drivers and monitors are used in these screens
1506 */
1507static Bool
1508configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
1509             char *default_layout)
1510{
1511    XF86ConfAdjacencyPtr adjp;
1512    XF86ConfInactivePtr idp;
1513    int saved_count, count = 0;
1514    int scrnum;
1515    XF86ConfLayoutPtr l;
1516    MessageType from;
1517    screenLayoutPtr slp;
1518    GDevPtr gdp;
1519    int i = 0, j;
1520
1521    if (!servlayoutp)
1522        return FALSE;
1523
1524    /*
1525     * which layout section is the active one?
1526     *
1527     * If there is a -layout command line option, use that one, otherwise
1528     * pick the first one.
1529     */
1530    from = X_DEFAULT;
1531    if (xf86LayoutName != NULL)
1532        from = X_CMDLINE;
1533    else if (default_layout) {
1534        xf86LayoutName = default_layout;
1535        from = X_CONFIG;
1536    }
1537    if (xf86LayoutName != NULL) {
1538        if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
1539            xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
1540                    xf86LayoutName);
1541            return FALSE;
1542        }
1543        conf_layout = l;
1544    }
1545    xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
1546    adjp = conf_layout->lay_adjacency_lst;
1547
1548    /*
1549     * we know that each screen is referenced exactly once on the left side
1550     * of a layout statement in the Layout section. So to allocate the right
1551     * size for the array we do a quick walk of the list to figure out how
1552     * many sections we have
1553     */
1554    while (adjp) {
1555        count++;
1556        adjp = (XF86ConfAdjacencyPtr) adjp->list.next;
1557    }
1558
1559    DebugF("Found %d screens in the layout section %s",
1560           count, conf_layout->lay_identifier);
1561    if (!count)                 /* alloc enough storage even if no screen is specified */
1562        count = 1;
1563
1564    slp = xnfcalloc((count + 1), sizeof(screenLayoutRec));
1565    slp[count].screen = NULL;
1566    /*
1567     * now that we have storage, loop over the list again and fill in our
1568     * data structure; at this point we do not fill in the adjacency
1569     * information as it is not clear if we need it at all
1570     */
1571    adjp = conf_layout->lay_adjacency_lst;
1572    count = 0;
1573    while (adjp) {
1574        slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
1575        if (adjp->adj_scrnum < 0)
1576            scrnum = count;
1577        else
1578            scrnum = adjp->adj_scrnum;
1579        if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
1580                          X_CONFIG, (scrnum == 0 && !adjp->list.next))) {
1581            do {
1582                free(slp[count].screen);
1583            } while (count--);
1584            free(slp);
1585            return FALSE;
1586        }
1587        slp[count].x = adjp->adj_x;
1588        slp[count].y = adjp->adj_y;
1589        slp[count].refname = adjp->adj_refscreen;
1590        switch (adjp->adj_where) {
1591        case CONF_ADJ_OBSOLETE:
1592            slp[count].where = PosObsolete;
1593            slp[count].topname = adjp->adj_top_str;
1594            slp[count].bottomname = adjp->adj_bottom_str;
1595            slp[count].leftname = adjp->adj_left_str;
1596            slp[count].rightname = adjp->adj_right_str;
1597            break;
1598        case CONF_ADJ_ABSOLUTE:
1599            slp[count].where = PosAbsolute;
1600            break;
1601        case CONF_ADJ_RIGHTOF:
1602            slp[count].where = PosRightOf;
1603            break;
1604        case CONF_ADJ_LEFTOF:
1605            slp[count].where = PosLeftOf;
1606            break;
1607        case CONF_ADJ_ABOVE:
1608            slp[count].where = PosAbove;
1609            break;
1610        case CONF_ADJ_BELOW:
1611            slp[count].where = PosBelow;
1612            break;
1613        case CONF_ADJ_RELATIVE:
1614            slp[count].where = PosRelative;
1615            break;
1616        }
1617        count++;
1618        adjp = (XF86ConfAdjacencyPtr) adjp->list.next;
1619    }
1620
1621    /* No screen was specified in the layout. take the first one from the
1622     * config file, or - if it is NULL - configScreen autogenerates one for
1623     * us */
1624    if (!count) {
1625        XF86ConfScreenPtr screen;
1626
1627        FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen);
1628        slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1629        if (!configScreen(slp[0].screen, screen,
1630                          0, X_CONFIG, TRUE)) {
1631            free(slp[0].screen);
1632            free(slp);
1633            return FALSE;
1634        }
1635    }
1636
1637    /* XXX Need to tie down the upper left screen. */
1638
1639    /* Fill in the refscreen and top/bottom/left/right values */
1640    for (i = 0; i < count; i++) {
1641        for (j = 0; j < count; j++) {
1642            if (slp[i].refname &&
1643                strcmp(slp[i].refname, slp[j].screen->id) == 0) {
1644                slp[i].refscreen = slp[j].screen;
1645            }
1646            if (slp[i].topname &&
1647                strcmp(slp[i].topname, slp[j].screen->id) == 0) {
1648                slp[i].top = slp[j].screen;
1649            }
1650            if (slp[i].bottomname &&
1651                strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
1652                slp[i].bottom = slp[j].screen;
1653            }
1654            if (slp[i].leftname &&
1655                strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
1656                slp[i].left = slp[j].screen;
1657            }
1658            if (slp[i].rightname &&
1659                strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
1660                slp[i].right = slp[j].screen;
1661            }
1662        }
1663        if (slp[i].where != PosObsolete
1664            && slp[i].where != PosAbsolute && !slp[i].refscreen) {
1665            xf86Msg(X_ERROR, "Screen %s doesn't exist: deleting placement\n",
1666                    slp[i].refname);
1667            slp[i].where = PosAbsolute;
1668            slp[i].x = 0;
1669            slp[i].y = 0;
1670        }
1671    }
1672
1673    if (!count)
1674        saved_count = 1;
1675    else
1676        saved_count = count;
1677    /*
1678     * Count the number of inactive devices.
1679     */
1680    count = 0;
1681    idp = conf_layout->lay_inactive_lst;
1682    while (idp) {
1683        count++;
1684        idp = (XF86ConfInactivePtr) idp->list.next;
1685    }
1686    DebugF("Found %d inactive devices in the layout section %s\n",
1687           count, conf_layout->lay_identifier);
1688    gdp = xnfallocarray(count + 1, sizeof(GDevRec));
1689    gdp[count].identifier = NULL;
1690    idp = conf_layout->lay_inactive_lst;
1691    count = 0;
1692    while (idp) {
1693        if (!configDevice(&gdp[count], idp->inactive_device, FALSE, FALSE))
1694            goto bail;
1695        count++;
1696        idp = (XF86ConfInactivePtr) idp->list.next;
1697    }
1698
1699    if (!configInputDevices(conf_layout, servlayoutp))
1700        goto bail;
1701
1702    servlayoutp->id = conf_layout->lay_identifier;
1703    servlayoutp->screens = slp;
1704    servlayoutp->inactives = gdp;
1705    servlayoutp->options = conf_layout->lay_option_lst;
1706    from = X_DEFAULT;
1707
1708    return TRUE;
1709
1710 bail:
1711    do {
1712        free(slp[saved_count].screen);
1713    } while (saved_count--);
1714    free(slp);
1715    free(gdp);
1716    return FALSE;
1717}
1718
1719/*
1720 * No layout section, so find the first Screen section and set that up as
1721 * the only active screen.
1722 */
1723static Bool
1724configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
1725                    XF86ConfigPtr conf_ptr)
1726{
1727    MessageType from;
1728    XF86ConfScreenPtr s;
1729    screenLayoutPtr slp;
1730    InputInfoPtr *indp;
1731    XF86ConfLayoutRec layout;
1732
1733    if (!servlayoutp)
1734        return FALSE;
1735
1736    /*
1737     * which screen section is the active one?
1738     *
1739     * If there is a -screen option, use that one, otherwise use the first
1740     * one.
1741     */
1742
1743    from = X_CONFIG;
1744    if (xf86ScreenName != NULL) {
1745        if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
1746            xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
1747                    xf86ScreenName);
1748            return FALSE;
1749        }
1750        conf_screen = s;
1751        from = X_CMDLINE;
1752    }
1753
1754    /* We have exactly one screen */
1755
1756    slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
1757    slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1758    slp[1].screen = NULL;
1759    if (!configScreen(slp[0].screen, conf_screen, 0, from, TRUE)) {
1760        free(slp);
1761        return FALSE;
1762    }
1763    servlayoutp->id = "(implicit)";
1764    servlayoutp->screens = slp;
1765    servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
1766    servlayoutp->options = NULL;
1767
1768    memset(&layout, 0, sizeof(layout));
1769    layout.lay_identifier = servlayoutp->id;
1770    if (xf86layoutAddInputDevices(conf_ptr, &layout) > 0) {
1771        if (!configInputDevices(&layout, servlayoutp))
1772            return FALSE;
1773        from = X_DEFAULT;
1774    }
1775    else {
1776        /* Set up an empty input device list, then look for some core devices. */
1777        indp = xnfalloc(sizeof(InputInfoPtr));
1778        *indp = NULL;
1779        servlayoutp->inputs = indp;
1780    }
1781
1782    return TRUE;
1783}
1784
1785static Bool
1786configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
1787{
1788    int count = 0;
1789    XF86ConfVideoPortPtr conf_port;
1790
1791    xf86Msg(X_CONFIG, "|   |-->VideoAdaptor \"%s\"\n",
1792            conf_adaptor->va_identifier);
1793    adaptor->identifier = conf_adaptor->va_identifier;
1794    adaptor->options = conf_adaptor->va_option_lst;
1795    if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
1796        xf86Msg(X_CONFIG, "|   | Unsupported device type, skipping entry\n");
1797        return FALSE;
1798    }
1799
1800    /*
1801     * figure out how many videoport subsections there are and fill them in
1802     */
1803    conf_port = conf_adaptor->va_port_lst;
1804    while (conf_port) {
1805        count++;
1806        conf_port = (XF86ConfVideoPortPtr) conf_port->list.next;
1807    }
1808    adaptor->ports = xnfallocarray(count, sizeof(confXvPortRec));
1809    adaptor->numports = count;
1810    count = 0;
1811    conf_port = conf_adaptor->va_port_lst;
1812    while (conf_port) {
1813        adaptor->ports[count].identifier = conf_port->vp_identifier;
1814        adaptor->ports[count].options = conf_port->vp_option_lst;
1815        count++;
1816        conf_port = (XF86ConfVideoPortPtr) conf_port->list.next;
1817    }
1818
1819    return TRUE;
1820}
1821
1822static Bool
1823configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
1824             MessageType from, Bool auto_gpu_device)
1825{
1826    int count = 0;
1827    XF86ConfDisplayPtr dispptr;
1828    XF86ConfAdaptorLinkPtr conf_adaptor;
1829    Bool defaultMonitor = FALSE;
1830    XF86ConfScreenRec local_conf_screen;
1831    int i;
1832
1833    if (!conf_screen) {
1834        memset(&local_conf_screen, 0, sizeof(local_conf_screen));
1835        conf_screen = &local_conf_screen;
1836        conf_screen->scrn_identifier = "Default Screen Section";
1837        xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
1838    }
1839
1840    xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
1841            scrnum);
1842    /*
1843     * now we fill in the elements of the screen
1844     */
1845    screenp->id = conf_screen->scrn_identifier;
1846    screenp->screennum = scrnum;
1847    screenp->defaultdepth = conf_screen->scrn_defaultdepth;
1848    screenp->defaultbpp = conf_screen->scrn_defaultbpp;
1849    screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
1850    screenp->monitor = xnfcalloc(1, sizeof(MonRec));
1851    /* If no monitor is specified, create a default one. */
1852    if (!conf_screen->scrn_monitor) {
1853        XF86ConfMonitorRec defMon;
1854
1855        memset(&defMon, 0, sizeof(defMon));
1856        defMon.mon_identifier = "<default monitor>";
1857        if (!configMonitor(screenp->monitor, &defMon))
1858            return FALSE;
1859        defaultMonitor = TRUE;
1860    }
1861    else {
1862        if (!configMonitor(screenp->monitor, conf_screen->scrn_monitor))
1863            return FALSE;
1864    }
1865    /* Configure the device. If there isn't one configured, attach to the
1866     * first inactive one that we can configure. If there's none that work,
1867     * set it to NULL so that the section can be autoconfigured later */
1868    screenp->device = xnfcalloc(1, sizeof(GDevRec));
1869    if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
1870        FIND_SUITABLE (XF86ConfDevicePtr, xf86configptr->conf_device_lst, conf_screen->scrn_device);
1871        xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
1872                "\tUsing the first device section listed.\n", screenp->id);
1873    }
1874    if (configDevice(screenp->device, conf_screen->scrn_device, TRUE, FALSE)) {
1875        screenp->device->myScreenSection = screenp;
1876    }
1877    else {
1878        screenp->device = NULL;
1879    }
1880
1881    if (auto_gpu_device && conf_screen->num_gpu_devices == 0 &&
1882        xf86configptr->conf_device_lst) {
1883        XF86ConfDevicePtr sdevice = xf86configptr->conf_device_lst->list.next;
1884
1885        for (i = 0; i < MAX_GPUDEVICES; i++) {
1886            if (!sdevice)
1887                break;
1888
1889            FIND_SUITABLE (XF86ConfDevicePtr, sdevice, conf_screen->scrn_gpu_devices[i]);
1890            if (!conf_screen->scrn_gpu_devices[i])
1891                break;
1892            screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
1893            if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
1894                screenp->gpu_devices[i]->myScreenSection = screenp;
1895            }
1896            sdevice = conf_screen->scrn_gpu_devices[i]->list.next;
1897        }
1898        screenp->num_gpu_devices = i;
1899
1900    } else {
1901        for (i = 0; i < conf_screen->num_gpu_devices; i++) {
1902            screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec));
1903            if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) {
1904                screenp->gpu_devices[i]->myScreenSection = screenp;
1905            }
1906        }
1907        screenp->num_gpu_devices = conf_screen->num_gpu_devices;
1908    }
1909
1910    screenp->options = conf_screen->scrn_option_lst;
1911
1912    /*
1913     * figure out how many display subsections there are and fill them in
1914     */
1915    dispptr = conf_screen->scrn_display_lst;
1916    while (dispptr) {
1917        count++;
1918        dispptr = (XF86ConfDisplayPtr) dispptr->list.next;
1919    }
1920    screenp->displays = xnfallocarray(count, sizeof(DispRec));
1921    screenp->numdisplays = count;
1922
1923    /* Fill in the default Virtual size, if any */
1924    if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
1925        for (count = 0, dispptr = conf_screen->scrn_display_lst;
1926             dispptr;
1927             dispptr = (XF86ConfDisplayPtr) dispptr->list.next, count++) {
1928            screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
1929            screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
1930        }
1931    }
1932
1933    /* Now do the per-Display Virtual sizes */
1934    count = 0;
1935    dispptr = conf_screen->scrn_display_lst;
1936    while (dispptr) {
1937        configDisplay(&(screenp->displays[count]), dispptr);
1938        count++;
1939        dispptr = (XF86ConfDisplayPtr) dispptr->list.next;
1940    }
1941
1942    /*
1943     * figure out how many videoadaptor references there are and fill them in
1944     */
1945    conf_adaptor = conf_screen->scrn_adaptor_lst;
1946    while (conf_adaptor) {
1947        count++;
1948        conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next;
1949    }
1950    screenp->xvadaptors = xnfallocarray(count, sizeof(confXvAdaptorRec));
1951    screenp->numxvadaptors = 0;
1952    conf_adaptor = conf_screen->scrn_adaptor_lst;
1953    while (conf_adaptor) {
1954        if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
1955                            conf_adaptor->al_adaptor))
1956            screenp->numxvadaptors++;
1957        conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next;
1958    }
1959
1960    if (defaultMonitor) {
1961        xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
1962                "\tUsing a default monitor configuration.\n", screenp->id);
1963    }
1964    return TRUE;
1965}
1966
1967typedef enum {
1968    MON_REDUCEDBLANKING,
1969    MON_MAX_PIX_CLOCK,
1970} MonitorValues;
1971
1972static OptionInfoRec MonitorOptions[] = {
1973    {MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN,
1974     {0}, FALSE},
1975    {MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ,
1976     {0}, FALSE},
1977    {-1, NULL, OPTV_NONE,
1978     {0}, FALSE},
1979};
1980
1981static Bool
1982configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
1983{
1984    int count;
1985    DisplayModePtr mode, last = NULL;
1986    XF86ConfModeLinePtr cmodep;
1987    XF86ConfModesPtr modes;
1988    XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
1989    Gamma zeros = { 0.0, 0.0, 0.0 };
1990    float badgamma = 0.0;
1991    double maxPixClock;
1992
1993    xf86Msg(X_CONFIG, "|   |-->Monitor \"%s\"\n", conf_monitor->mon_identifier);
1994    monitorp->id = conf_monitor->mon_identifier;
1995    monitorp->vendor = conf_monitor->mon_vendor;
1996    monitorp->model = conf_monitor->mon_modelname;
1997    monitorp->Modes = NULL;
1998    monitorp->Last = NULL;
1999    monitorp->gamma = zeros;
2000    monitorp->widthmm = conf_monitor->mon_width;
2001    monitorp->heightmm = conf_monitor->mon_height;
2002    monitorp->reducedblanking = FALSE;
2003    monitorp->maxPixClock = 0;
2004    monitorp->options = conf_monitor->mon_option_lst;
2005
2006    /*
2007     * fill in the monitor structure
2008     */
2009    for (count = 0;
2010         count < conf_monitor->mon_n_hsync && count < MAX_HSYNC; count++) {
2011        monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
2012        monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
2013    }
2014    monitorp->nHsync = count;
2015    for (count = 0;
2016         count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
2017         count++) {
2018        monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
2019        monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
2020    }
2021    monitorp->nVrefresh = count;
2022
2023    /*
2024     * first we collect the mode lines from the UseModes directive
2025     */
2026    while (modeslnk) {
2027        modes = xf86findModes(modeslnk->ml_modes_str,
2028                              xf86configptr->conf_modes_lst);
2029        modeslnk->ml_modes = modes;
2030
2031        /* now add the modes found in the modes
2032           section to the list of modes for this
2033           monitor unless it has been added before
2034           because we are reusing the same section
2035           for another screen */
2036        if (xf86itemNotSublist((GenericListPtr) conf_monitor->mon_modeline_lst,
2037                               (GenericListPtr) modes->mon_modeline_lst)) {
2038            conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
2039                xf86addListItem((GenericListPtr) conf_monitor->mon_modeline_lst,
2040                                (GenericListPtr) modes->mon_modeline_lst);
2041        }
2042        modeslnk = modeslnk->list.next;
2043    }
2044
2045    /*
2046     * we need to hook in the mode lines now
2047     * here both data structures use lists, only our internal one
2048     * is double linked
2049     */
2050    cmodep = conf_monitor->mon_modeline_lst;
2051    while (cmodep) {
2052        mode = xnfcalloc(1, sizeof(DisplayModeRec));
2053        mode->type = 0;
2054        mode->Clock = cmodep->ml_clock;
2055        mode->HDisplay = cmodep->ml_hdisplay;
2056        mode->HSyncStart = cmodep->ml_hsyncstart;
2057        mode->HSyncEnd = cmodep->ml_hsyncend;
2058        mode->HTotal = cmodep->ml_htotal;
2059        mode->VDisplay = cmodep->ml_vdisplay;
2060        mode->VSyncStart = cmodep->ml_vsyncstart;
2061        mode->VSyncEnd = cmodep->ml_vsyncend;
2062        mode->VTotal = cmodep->ml_vtotal;
2063        mode->Flags = cmodep->ml_flags;
2064        mode->HSkew = cmodep->ml_hskew;
2065        mode->VScan = cmodep->ml_vscan;
2066        mode->name = xnfstrdup(cmodep->ml_identifier);
2067        if (last) {
2068            mode->prev = last;
2069            last->next = mode;
2070        }
2071        else {
2072            /*
2073             * this is the first mode
2074             */
2075            monitorp->Modes = mode;
2076            mode->prev = NULL;
2077        }
2078        last = mode;
2079        cmodep = (XF86ConfModeLinePtr) cmodep->list.next;
2080    }
2081    if (last) {
2082        last->next = NULL;
2083    }
2084    monitorp->Last = last;
2085
2086    /* add the (VESA) default modes */
2087    if (!addDefaultModes(monitorp))
2088        return FALSE;
2089
2090    if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
2091        monitorp->gamma.red = conf_monitor->mon_gamma_red;
2092    if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
2093        monitorp->gamma.green = conf_monitor->mon_gamma_green;
2094    if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
2095        monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
2096
2097    /* Check that the gamma values are within range */
2098    if (monitorp->gamma.red > GAMMA_ZERO &&
2099        (monitorp->gamma.red < GAMMA_MIN || monitorp->gamma.red > GAMMA_MAX)) {
2100        badgamma = monitorp->gamma.red;
2101    }
2102    else if (monitorp->gamma.green > GAMMA_ZERO &&
2103             (monitorp->gamma.green < GAMMA_MIN ||
2104              monitorp->gamma.green > GAMMA_MAX)) {
2105        badgamma = monitorp->gamma.green;
2106    }
2107    else if (monitorp->gamma.blue > GAMMA_ZERO &&
2108             (monitorp->gamma.blue < GAMMA_MIN ||
2109              monitorp->gamma.blue > GAMMA_MAX)) {
2110        badgamma = monitorp->gamma.blue;
2111    }
2112    if (badgamma > GAMMA_ZERO) {
2113        ErrorF("Gamma value %.f is out of range (%.2f - %.1f)\n", badgamma,
2114               GAMMA_MIN, GAMMA_MAX);
2115        return FALSE;
2116    }
2117
2118    xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
2119    xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
2120                      &monitorp->reducedblanking);
2121    if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
2122                          &maxPixClock) == TRUE) {
2123        monitorp->maxPixClock = (int) maxPixClock;
2124    }
2125
2126    return TRUE;
2127}
2128
2129static int
2130lookupVisual(const char *visname)
2131{
2132    int i;
2133
2134    if (!visname || !*visname)
2135        return -1;
2136
2137    for (i = 0; i <= DirectColor; i++) {
2138        if (!xf86nameCompare(visname, xf86VisualNames[i]))
2139            break;
2140    }
2141
2142    if (i <= DirectColor)
2143        return i;
2144
2145    return -1;
2146}
2147
2148static Bool
2149configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
2150{
2151    int count = 0;
2152    XF86ModePtr modep;
2153
2154    displayp->frameX0 = conf_display->disp_frameX0;
2155    displayp->frameY0 = conf_display->disp_frameY0;
2156    displayp->virtualX = conf_display->disp_virtualX;
2157    displayp->virtualY = conf_display->disp_virtualY;
2158    displayp->depth = conf_display->disp_depth;
2159    displayp->fbbpp = conf_display->disp_bpp;
2160    displayp->weight.red = conf_display->disp_weight.red;
2161    displayp->weight.green = conf_display->disp_weight.green;
2162    displayp->weight.blue = conf_display->disp_weight.blue;
2163    displayp->blackColour.red = conf_display->disp_black.red;
2164    displayp->blackColour.green = conf_display->disp_black.green;
2165    displayp->blackColour.blue = conf_display->disp_black.blue;
2166    displayp->whiteColour.red = conf_display->disp_white.red;
2167    displayp->whiteColour.green = conf_display->disp_white.green;
2168    displayp->whiteColour.blue = conf_display->disp_white.blue;
2169    displayp->options = conf_display->disp_option_lst;
2170    if (conf_display->disp_visual) {
2171        displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
2172        if (displayp->defaultVisual == -1) {
2173            ErrorF("Invalid visual name: \"%s\"\n", conf_display->disp_visual);
2174            return FALSE;
2175        }
2176    }
2177    else {
2178        displayp->defaultVisual = -1;
2179    }
2180
2181    /*
2182     * now hook in the modes
2183     */
2184    modep = conf_display->disp_mode_lst;
2185    while (modep) {
2186        count++;
2187        modep = (XF86ModePtr) modep->list.next;
2188    }
2189    displayp->modes = xnfallocarray(count + 1, sizeof(char *));
2190    modep = conf_display->disp_mode_lst;
2191    count = 0;
2192    while (modep) {
2193        displayp->modes[count] = modep->mode_name;
2194        count++;
2195        modep = (XF86ModePtr) modep->list.next;
2196    }
2197    displayp->modes[count] = NULL;
2198
2199    return TRUE;
2200}
2201
2202static Bool
2203configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool gpu)
2204{
2205    int i;
2206
2207    if (!conf_device) {
2208        return FALSE;
2209    }
2210
2211    if (active) {
2212        if (gpu)
2213            xf86Msg(X_CONFIG, "|   |-->GPUDevice \"%s\"\n",
2214                    conf_device->dev_identifier);
2215        else
2216            xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
2217                    conf_device->dev_identifier);
2218    } else
2219        xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
2220                conf_device->dev_identifier);
2221
2222    devicep->identifier = conf_device->dev_identifier;
2223    devicep->vendor = conf_device->dev_vendor;
2224    devicep->board = conf_device->dev_board;
2225    devicep->chipset = conf_device->dev_chipset;
2226    devicep->ramdac = conf_device->dev_ramdac;
2227    devicep->driver = conf_device->dev_driver;
2228    devicep->active = active;
2229    devicep->videoRam = conf_device->dev_videoram;
2230    devicep->BiosBase = conf_device->dev_bios_base;
2231    devicep->MemBase = conf_device->dev_mem_base;
2232    devicep->IOBase = conf_device->dev_io_base;
2233    devicep->clockchip = conf_device->dev_clockchip;
2234    devicep->busID = conf_device->dev_busid;
2235    devicep->chipID = conf_device->dev_chipid;
2236    devicep->chipRev = conf_device->dev_chiprev;
2237    devicep->options = conf_device->dev_option_lst;
2238    devicep->irq = conf_device->dev_irq;
2239    devicep->screen = conf_device->dev_screen;
2240
2241    for (i = 0; i < MAXDACSPEEDS; i++) {
2242        if (i < CONF_MAXDACSPEEDS)
2243            devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
2244        else
2245            devicep->dacSpeeds[i] = 0;
2246    }
2247    devicep->numclocks = conf_device->dev_clocks;
2248    if (devicep->numclocks > MAXCLOCKS)
2249        devicep->numclocks = MAXCLOCKS;
2250    for (i = 0; i < devicep->numclocks; i++) {
2251        devicep->clock[i] = conf_device->dev_clock[i];
2252    }
2253    devicep->claimed = FALSE;
2254
2255    return TRUE;
2256}
2257
2258static void
2259configDRI(XF86ConfDRIPtr drip)
2260{
2261    struct group *grp;
2262
2263    xf86ConfigDRI.group = -1;
2264    xf86ConfigDRI.mode = 0;
2265
2266    if (drip) {
2267        if (drip->dri_group_name) {
2268            if ((grp = getgrnam(drip->dri_group_name)))
2269                xf86ConfigDRI.group = grp->gr_gid;
2270        }
2271        else {
2272            if (drip->dri_group >= 0)
2273                xf86ConfigDRI.group = drip->dri_group;
2274        }
2275        xf86ConfigDRI.mode = drip->dri_mode;
2276    }
2277}
2278
2279static void
2280configExtensions(XF86ConfExtensionsPtr conf_ext)
2281{
2282    XF86OptionPtr o;
2283
2284    if (conf_ext && conf_ext->ext_option_lst) {
2285        for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
2286            char *name = xf86OptionName(o);
2287            char *val = xf86OptionValue(o);
2288            char *n;
2289            Bool enable = TRUE;
2290
2291            /* Handle "No<ExtensionName>" */
2292            n = xf86NormalizeName(name);
2293            if (strncmp(n, "no", 2) == 0) {
2294                name += 2;
2295                enable = FALSE;
2296            }
2297
2298            if (!val ||
2299                xf86NameCmp(val, "enable") == 0 ||
2300                xf86NameCmp(val, "enabled") == 0 ||
2301                xf86NameCmp(val, "on") == 0 ||
2302                xf86NameCmp(val, "1") == 0 ||
2303                xf86NameCmp(val, "yes") == 0 || xf86NameCmp(val, "true") == 0) {
2304                /* NOTHING NEEDED -- enabling is handled below */
2305            }
2306            else if (xf86NameCmp(val, "disable") == 0 ||
2307                     xf86NameCmp(val, "disabled") == 0 ||
2308                     xf86NameCmp(val, "off") == 0 ||
2309                     xf86NameCmp(val, "0") == 0 ||
2310                     xf86NameCmp(val, "no") == 0 ||
2311                     xf86NameCmp(val, "false") == 0) {
2312                enable = !enable;
2313            }
2314            else {
2315                xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
2316                free(n);
2317                continue;
2318            }
2319
2320            if (EnableDisableExtension(name, enable)) {
2321                xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
2322                        name, enable ? "enabled" : "disabled");
2323            }
2324            else {
2325                xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
2326                        name);
2327            }
2328            free(n);
2329        }
2330    }
2331}
2332
2333static Bool
2334configInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
2335{
2336    xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
2337    inputp->name = conf_input->inp_identifier;
2338    inputp->driver = conf_input->inp_driver;
2339    inputp->options = conf_input->inp_option_lst;
2340    inputp->attrs = NULL;
2341
2342    return TRUE;
2343}
2344
2345static Bool
2346modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
2347{
2348    DisplayModePtr knownmodes = monitorp->Modes;
2349
2350    /* all I can think of is a linear search... */
2351    while (knownmodes != NULL) {
2352        if (!strcmp(mode->name, knownmodes->name) &&
2353            !(knownmodes->type & M_T_DEFAULT))
2354            return TRUE;
2355        knownmodes = knownmodes->next;
2356    }
2357    return FALSE;
2358}
2359
2360static Bool
2361addDefaultModes(MonPtr monitorp)
2362{
2363    DisplayModePtr mode;
2364    DisplayModePtr last = monitorp->Last;
2365    int i = 0;
2366
2367    for (i = 0; i < xf86NumDefaultModes; i++) {
2368        mode = xf86DuplicateMode(&xf86DefaultModes[i]);
2369        if (!modeIsPresent(mode, monitorp)) {
2370            monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
2371            last = mode;
2372        }
2373        else {
2374            free(mode);
2375        }
2376    }
2377    monitorp->Last = last;
2378
2379    return TRUE;
2380}
2381
2382static void
2383checkInput(serverLayoutPtr layout, Bool implicit_layout)
2384{
2385    checkCoreInputDevices(layout, implicit_layout);
2386
2387    /* Unless we're forcing input devices, disable mouse/kbd devices in the
2388     * config. Otherwise the same physical device is added multiple times,
2389     * leading to duplicate events.
2390     */
2391    if (!xf86Info.forceInputDevices && layout->inputs) {
2392        InputInfoPtr *dev = layout->inputs;
2393        BOOL warned = FALSE;
2394
2395        while (*dev) {
2396            if (strcmp((*dev)->driver, "kbd") == 0 ||
2397                strcmp((*dev)->driver, "mouse") == 0 ||
2398                strcmp((*dev)->driver, "vmmouse") == 0) {
2399                InputInfoPtr *current;
2400
2401                if (!warned) {
2402                    xf86Msg(X_WARNING, "Hotplugging is on, devices using "
2403                            "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
2404                    warned = TRUE;
2405                }
2406
2407                xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name);
2408
2409                current = dev;
2410                free(*dev);
2411                *dev = NULL;
2412
2413                do {
2414                    *current = *(current + 1);
2415                    current++;
2416                } while (*current);
2417            }
2418            else
2419                dev++;
2420        }
2421    }
2422}
2423
2424/*
2425 * load the config file and fill the global data structure
2426 */
2427ConfigStatus
2428xf86HandleConfigFile(Bool autoconfig)
2429{
2430    const char *scanptr;
2431    Bool singlecard = 0;
2432    Bool implicit_layout = FALSE;
2433    XF86ConfLayoutPtr layout;
2434
2435    if (!autoconfig) {
2436        char *filename, *dirname, *sysdirname;
2437        const char *filesearch, *dirsearch;
2438        MessageType filefrom = X_DEFAULT;
2439        MessageType dirfrom = X_DEFAULT;
2440
2441        if (!xf86PrivsElevated()) {
2442            filesearch = ALL_CONFIGPATH;
2443            dirsearch = ALL_CONFIGDIRPATH;
2444        }
2445        else {
2446            filesearch = RESTRICTED_CONFIGPATH;
2447            dirsearch = RESTRICTED_CONFIGDIRPATH;
2448        }
2449
2450        if (xf86ConfigFile)
2451            filefrom = X_CMDLINE;
2452        if (xf86ConfigDir)
2453            dirfrom = X_CMDLINE;
2454
2455        xf86initConfigFiles();
2456        sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
2457                                            PROJECTROOT);
2458        dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
2459        filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
2460        if (filename) {
2461            xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
2462            xf86ConfigFile = xnfstrdup(filename);
2463        }
2464        else {
2465            if (xf86ConfigFile)
2466                xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
2467                        xf86ConfigFile);
2468        }
2469        if (dirname) {
2470            xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
2471                        dirname);
2472            xf86ConfigDir = xnfstrdup(dirname);
2473        }
2474        else {
2475            if (xf86ConfigDir)
2476                xf86Msg(X_ERROR,
2477                        "Unable to locate/open config directory: \"%s\"\n",
2478                        xf86ConfigDir);
2479        }
2480        if (sysdirname)
2481            xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
2482                        sysdirname);
2483        if (!filename && !dirname && !sysdirname)
2484            return CONFIG_NOFILE;
2485
2486        free(filename);
2487        free(dirname);
2488        free(sysdirname);
2489    }
2490
2491    if ((xf86configptr = xf86readConfigFile()) == NULL) {
2492        xf86Msg(X_ERROR, "Problem parsing the config file\n");
2493        return CONFIG_PARSE_ERROR;
2494    }
2495    xf86closeConfigFile();
2496
2497    /* Initialise a few things. */
2498
2499    /*
2500     * now we convert part of the information contained in the parser
2501     * structures into our own structures.
2502     * The important part here is to figure out which Screen Sections
2503     * in the XF86Config file are active so that we can piece together
2504     * the modes that we need later down the road.
2505     * And while we are at it, we'll decode the rest of the stuff as well
2506     */
2507
2508    /* First check if a layout section is present, and if it is valid. */
2509    FIND_SUITABLE(XF86ConfLayoutPtr, xf86configptr->conf_layout_lst, layout);
2510    if (layout == NULL || xf86ScreenName != NULL) {
2511        XF86ConfScreenPtr screen;
2512
2513        if (xf86ScreenName == NULL) {
2514            xf86Msg(X_DEFAULT,
2515                    "No Layout section.  Using the first Screen section.\n");
2516        }
2517        FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen);
2518        if (!configImpliedLayout(&xf86ConfigLayout,
2519                                 screen,
2520                                 xf86configptr)) {
2521            xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2522            return CONFIG_PARSE_ERROR;
2523        }
2524        implicit_layout = TRUE;
2525    }
2526    else {
2527        if (xf86configptr->conf_flags != NULL) {
2528            char *dfltlayout = NULL;
2529            void *optlist = xf86configptr->conf_flags->flg_option_lst;
2530
2531            if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
2532                dfltlayout =
2533                    xf86SetStrOption(optlist, "defaultserverlayout", NULL);
2534            if (!configLayout(&xf86ConfigLayout, layout, dfltlayout)) {
2535                xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2536                return CONFIG_PARSE_ERROR;
2537            }
2538        }
2539        else {
2540            if (!configLayout(&xf86ConfigLayout, layout, NULL)) {
2541                xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2542                return CONFIG_PARSE_ERROR;
2543            }
2544        }
2545    }
2546
2547    xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
2548#ifdef XSERVER_LIBPCIACCESS
2549    if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
2550        ;                       /* IsolateDevice specified; overrides SingleCard */
2551    }
2552    else {
2553        xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
2554        if (singlecard)
2555            scanptr = xf86ConfigLayout.screens->screen->device->busID;
2556    }
2557    if (scanptr) {
2558        if (strncmp(scanptr, "PCI:", 4) != 0) {
2559            xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
2560                    "\tIgnoring IsolateDevice option.\n");
2561        }
2562        else
2563            xf86PciIsolateDevice(scanptr);
2564    }
2565#endif
2566    /* Now process everything else */
2567    configServerFlags(xf86configptr->conf_flags, xf86ConfigLayout.options);
2568    configFiles(xf86configptr->conf_files);
2569    configExtensions(xf86configptr->conf_extensions);
2570    configDRI(xf86configptr->conf_dri);
2571
2572    checkInput(&xf86ConfigLayout, implicit_layout);
2573
2574    /*
2575     * Handle some command line options that can override some of the
2576     * ServerFlags settings.
2577     */
2578#ifdef XF86VIDMODE
2579    if (xf86VidModeDisabled)
2580        xf86Info.vidModeEnabled = FALSE;
2581    if (xf86VidModeAllowNonLocal)
2582        xf86Info.vidModeAllowNonLocal = TRUE;
2583#endif
2584
2585    if (xf86AllowMouseOpenFail)
2586        xf86Info.allowMouseOpenFail = TRUE;
2587
2588    return CONFIG_OK;
2589}
2590
2591Bool
2592xf86PathIsSafe(const char *path)
2593{
2594    return (xf86pathIsSafe(path) != 0);
2595}
2596