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