xf86Config.c revision 45bb0b75
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            Pointer.fd = -1;
1234	    *devs[count - 1] = Pointer;
1235	    devs[count - 1]->options =
1236				xf86addNewOption(devs[count -1]->options,
1237				    xnfstrdup("CorePointer"), NULL);
1238	    devs[count] = NULL;
1239	    servlayoutp->inputs = devs;
1240	}
1241    }
1242
1243    if (!foundPointer && xf86Info.forceInputDevices) {
1244	/* This shouldn't happen. */
1245	xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
1246	return FALSE;
1247    }
1248
1249    /*
1250     * always synthesize a 'mouse' section configured to send core
1251     * events, unless a 'void' section is found, in which case the user
1252     * probably wants to run footless.
1253     *
1254     * If you're using an evdev keyboard and expect a default mouse
1255     * section ... deal.
1256     */
1257    for (devs = servlayoutp->inputs; devs && *devs; devs++) {
1258	const char **driver = mousedrivers;
1259	while(*driver) {
1260	    if (!strcmp((*devs)->driver, *driver)) {
1261		found = 1;
1262		break;
1263	    }
1264	    driver++;
1265	}
1266    }
1267    if (!found && xf86Info.forceInputDevices) {
1268	xf86Msg(X_INFO, "No default mouse found, adding one\n");
1269	memset(&defPtr, 0, sizeof(defPtr));
1270	defPtr.inp_identifier = strdup("<default pointer>");
1271	defPtr.inp_driver = strdup("mouse");
1272	confInput = &defPtr;
1273	foundPointer = configInput(&Pointer, confInput, from);
1274        if (foundPointer) {
1275	    count++;
1276	    devs = xnfrealloc(servlayoutp->inputs,
1277			      (count + 1) * sizeof(InputInfoPtr));
1278            devs[count - 1] = xnfalloc(sizeof(InputInfoRec));
1279            Pointer.fd = -1;
1280	    *devs[count - 1] = Pointer;
1281	    devs[count - 1]->options =
1282				xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
1283	    devs[count] = NULL;
1284	    servlayoutp->inputs = devs;
1285	}
1286    }
1287
1288    confInput = NULL;
1289
1290    /* 1. Check for the -keyboard command line option. */
1291    if (xf86KeyboardName) {
1292	confInput = xf86findInput(xf86KeyboardName,
1293				  xf86configptr->conf_input_lst);
1294	if (!confInput) {
1295	    xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1296		    xf86KeyboardName);
1297	    return FALSE;
1298	}
1299	from = X_CMDLINE;
1300	/*
1301	 * If one was already specified in the ServerLayout, it needs to be
1302	 * removed.
1303	 */
1304	if (coreKeyboard) {
1305	    for (devs = servlayoutp->inputs; devs && *devs; devs++)
1306		if (*devs == coreKeyboard)
1307                {
1308                    free(*devs);
1309                    *devs = (InputInfoPtr)0x1; /* ensure we dont skip next loop */
1310		    break;
1311                }
1312	    for (; devs && *devs; devs++)
1313		devs[0] = devs[1];
1314	    count--;
1315	}
1316	coreKeyboard = NULL;
1317	foundKeyboard = TRUE;
1318    }
1319
1320    /* 2. ServerLayout-specified core keyboard. */
1321    if (coreKeyboard) {
1322	foundKeyboard = TRUE;
1323	from = X_CONFIG;
1324    }
1325
1326    /* 3. First core keyboard device. */
1327    if (!foundKeyboard && (xf86Info.forceInputDevices || implicitLayout)) {
1328	XF86ConfInputPtr p;
1329
1330	for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1331	    if (p->inp_option_lst &&
1332		xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
1333		confInput = p;
1334		foundKeyboard = TRUE;
1335		from = X_DEFAULT;
1336		keyboardMsg = "first core keyboard device";
1337		break;
1338	    }
1339	}
1340    }
1341
1342    /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
1343    if (!foundKeyboard && xf86Info.forceInputDevices) {
1344	confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
1345				  xf86configptr->conf_input_lst);
1346	if (!confInput) {
1347	    confInput = xf86findInputByDriver("kbd",
1348					      xf86configptr->conf_input_lst);
1349	}
1350	if (confInput) {
1351	    foundKeyboard = TRUE;
1352	    from = X_DEFAULT;
1353	    keyboardMsg = "first keyboard device";
1354	}
1355    }
1356
1357    /* 5. Built-in default. */
1358    if (!foundKeyboard && xf86Info.forceInputDevices) {
1359	memset(&defKbd, 0, sizeof(defKbd));
1360	defKbd.inp_identifier = strdup("<default keyboard>");
1361	defKbd.inp_driver = strdup("kbd");
1362	confInput = &defKbd;
1363	foundKeyboard = TRUE;
1364	keyboardMsg = "default keyboard configuration";
1365	from = X_DEFAULT;
1366    }
1367
1368    /* Add the core keyboard device to the layout, and set it to Core. */
1369    if (foundKeyboard && confInput) {
1370	foundKeyboard = configInput(&Keyboard, confInput, from);
1371        if (foundKeyboard) {
1372	    count++;
1373	    devs = xnfrealloc(servlayoutp->inputs,
1374			      (count + 1) * sizeof(InputInfoPtr));
1375            devs[count - 1] = xnfalloc(sizeof(InputInfoRec));
1376            Keyboard.fd = -1;
1377	    *devs[count - 1] = Keyboard;
1378	    devs[count - 1]->options =
1379				xf86addNewOption(devs[count - 1]->options,
1380				    xnfstrdup("CoreKeyboard"), NULL);
1381	    devs[count] = NULL;
1382	    servlayoutp->inputs = devs;
1383	}
1384    }
1385
1386    if (!foundKeyboard && xf86Info.forceInputDevices) {
1387	/* This shouldn't happen. */
1388	xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
1389	return FALSE;
1390    }
1391
1392    if (pointerMsg) {
1393	if (implicitLayout)
1394	    xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1395	            pointerMsg);
1396	else
1397	    xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
1398	            "explicitly in the layout.\n"
1399	            "\tUsing the %s.\n", pointerMsg);
1400    }
1401
1402    if (keyboardMsg) {
1403	if (implicitLayout)
1404	    xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1405	            keyboardMsg);
1406	else
1407	    xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
1408	            "explicitly in the layout.\n"
1409	            "\tUsing the %s.\n", keyboardMsg);
1410    }
1411
1412    if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) {
1413#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
1414	const char *config_backend;
1415#if defined(CONFIG_HAL)
1416	config_backend = "HAL";
1417#else
1418	config_backend = "udev";
1419#endif
1420	xf86Msg(X_INFO, "The server relies on %s to provide the list of "
1421	                "input devices.\n\tIf no devices become available, "
1422	                "reconfigure %s or disable AutoAddDevices.\n",
1423			config_backend, config_backend);
1424#else
1425	xf86Msg(X_WARNING, "Hotplugging requested but the server was "
1426			   "compiled without a config backend. "
1427			   "No input devices were configured, the server "
1428			   "will start without any input devices.\n");
1429#endif
1430    }
1431
1432    return TRUE;
1433}
1434
1435typedef enum {
1436    LAYOUT_ISOLATEDEVICE,
1437    LAYOUT_SINGLECARD
1438} LayoutValues;
1439
1440static OptionInfoRec LayoutOptions[] = {
1441  { LAYOUT_ISOLATEDEVICE,      "IsolateDevice",        OPTV_STRING,
1442       {0}, FALSE },
1443  { LAYOUT_SINGLECARD,         "SingleCard",           OPTV_BOOLEAN,
1444       {0}, FALSE },
1445  { -1,                                NULL,                   OPTV_NONE,
1446       {0}, FALSE },
1447};
1448
1449static Bool
1450configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
1451{
1452    XF86ConfInputrefPtr irp;
1453    InputInfoPtr *indp;
1454    int count = 0;
1455
1456    /*
1457     * Count the number of input devices.
1458     */
1459    irp = layout->lay_input_lst;
1460    while (irp) {
1461	count++;
1462	irp = (XF86ConfInputrefPtr)irp->list.next;
1463    }
1464    DebugF("Found %d input devices in the layout section %s\n",
1465	    count, layout->lay_identifier);
1466    indp = xnfcalloc((count + 1), sizeof(InputInfoPtr));
1467    indp[count] = NULL;
1468    irp = layout->lay_input_lst;
1469    count = 0;
1470    while (irp) {
1471	indp[count] = xf86AllocateInput();
1472	if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
1473	    do {
1474		free(indp[count]);
1475	    } while(count--);
1476	    free(indp);
1477	    return FALSE;
1478	}
1479	indp[count]->options = xf86OptionListMerge(indp[count]->options,
1480						   irp->iref_option_lst);
1481	count++;
1482	irp = (XF86ConfInputrefPtr)irp->list.next;
1483    }
1484    servlayoutp->inputs = indp;
1485
1486    return TRUE;
1487}
1488
1489
1490/*
1491 * figure out which layout is active, which screens are used in that layout,
1492 * which drivers and monitors are used in these screens
1493 */
1494static Bool
1495configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
1496	     char *default_layout)
1497{
1498    XF86ConfAdjacencyPtr adjp;
1499    XF86ConfInactivePtr idp;
1500    int saved_count, count = 0;
1501    int scrnum;
1502    XF86ConfLayoutPtr l;
1503    MessageType from;
1504    screenLayoutPtr slp;
1505    GDevPtr gdp;
1506    int i = 0, j;
1507
1508    if (!servlayoutp)
1509	return FALSE;
1510
1511    /*
1512     * which layout section is the active one?
1513     *
1514     * If there is a -layout command line option, use that one, otherwise
1515     * pick the first one.
1516     */
1517    from = X_DEFAULT;
1518    if (xf86LayoutName != NULL)
1519	from = X_CMDLINE;
1520    else if (default_layout) {
1521	xf86LayoutName = default_layout;
1522	from = X_CONFIG;
1523    }
1524    if (xf86LayoutName != NULL) {
1525	if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
1526	    xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
1527		    xf86LayoutName);
1528	    return FALSE;
1529	}
1530	conf_layout = l;
1531    }
1532    xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
1533    adjp = conf_layout->lay_adjacency_lst;
1534
1535    /*
1536     * we know that each screen is referenced exactly once on the left side
1537     * of a layout statement in the Layout section. So to allocate the right
1538     * size for the array we do a quick walk of the list to figure out how
1539     * many sections we have
1540     */
1541    while (adjp) {
1542        count++;
1543        adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
1544    }
1545
1546    DebugF("Found %d screens in the layout section %s",
1547           count, conf_layout->lay_identifier);
1548    if (!count) /* alloc enough storage even if no screen is specified */
1549        count = 1;
1550
1551    slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
1552    slp[count].screen = NULL;
1553    /*
1554     * now that we have storage, loop over the list again and fill in our
1555     * data structure; at this point we do not fill in the adjacency
1556     * information as it is not clear if we need it at all
1557     */
1558    adjp = conf_layout->lay_adjacency_lst;
1559    count = 0;
1560    while (adjp) {
1561        slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
1562	if (adjp->adj_scrnum < 0)
1563	    scrnum = count;
1564	else
1565	    scrnum = adjp->adj_scrnum;
1566	if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
1567			  X_CONFIG)) {
1568	    do {
1569		free(slp[count].screen);
1570	    } while(count--);
1571	    free(slp);
1572	    return FALSE;
1573	}
1574	slp[count].x = adjp->adj_x;
1575	slp[count].y = adjp->adj_y;
1576	slp[count].refname = adjp->adj_refscreen;
1577	switch (adjp->adj_where) {
1578	case CONF_ADJ_OBSOLETE:
1579	    slp[count].where = PosObsolete;
1580	    slp[count].topname = adjp->adj_top_str;
1581	    slp[count].bottomname = adjp->adj_bottom_str;
1582	    slp[count].leftname = adjp->adj_left_str;
1583	    slp[count].rightname = adjp->adj_right_str;
1584	    break;
1585	case CONF_ADJ_ABSOLUTE:
1586	    slp[count].where = PosAbsolute;
1587	    break;
1588	case CONF_ADJ_RIGHTOF:
1589	    slp[count].where = PosRightOf;
1590	    break;
1591	case CONF_ADJ_LEFTOF:
1592	    slp[count].where = PosLeftOf;
1593	    break;
1594	case CONF_ADJ_ABOVE:
1595	    slp[count].where = PosAbove;
1596	    break;
1597	case CONF_ADJ_BELOW:
1598	    slp[count].where = PosBelow;
1599	    break;
1600	case CONF_ADJ_RELATIVE:
1601	    slp[count].where = PosRelative;
1602	    break;
1603	}
1604        count++;
1605        adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
1606    }
1607
1608    /* No screen was specified in the layout. take the first one from the
1609     * config file, or - if it is NULL - configScreen autogenerates one for
1610     * us */
1611    if (!count)
1612    {
1613        slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1614	if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
1615                          0, X_CONFIG)) {
1616	    free(slp[0].screen);
1617	    free(slp);
1618	    return FALSE;
1619	}
1620    }
1621
1622    /* XXX Need to tie down the upper left screen. */
1623
1624    /* Fill in the refscreen and top/bottom/left/right values */
1625    for (i = 0; i < count; i++) {
1626	for (j = 0; j < count; j++) {
1627	    if (slp[i].refname &&
1628		strcmp(slp[i].refname, slp[j].screen->id) == 0) {
1629		slp[i].refscreen = slp[j].screen;
1630	    }
1631	    if (slp[i].topname &&
1632		strcmp(slp[i].topname, slp[j].screen->id) == 0) {
1633		slp[i].top = slp[j].screen;
1634	    }
1635	    if (slp[i].bottomname &&
1636		strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
1637		slp[i].bottom = slp[j].screen;
1638	    }
1639	    if (slp[i].leftname &&
1640		strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
1641		slp[i].left = slp[j].screen;
1642	    }
1643	    if (slp[i].rightname &&
1644		strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
1645		slp[i].right = slp[j].screen;
1646	    }
1647	}
1648	if (slp[i].where != PosObsolete
1649	    && slp[i].where != PosAbsolute
1650	    && !slp[i].refscreen) {
1651	    xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
1652		     slp[i].refname);
1653	    slp[i].where = PosAbsolute;
1654	    slp[i].x = 0;
1655	    slp[i].y = 0;
1656	}
1657    }
1658
1659    if (!count)
1660	saved_count = 1;
1661    else
1662	saved_count = count;
1663    /*
1664     * Count the number of inactive devices.
1665     */
1666    count = 0;
1667    idp = conf_layout->lay_inactive_lst;
1668    while (idp) {
1669        count++;
1670        idp = (XF86ConfInactivePtr)idp->list.next;
1671    }
1672    DebugF("Found %d inactive devices in the layout section %s\n",
1673           count, conf_layout->lay_identifier);
1674    gdp = xnfalloc((count + 1) * sizeof(GDevRec));
1675    gdp[count].identifier = NULL;
1676    idp = conf_layout->lay_inactive_lst;
1677    count = 0;
1678    while (idp) {
1679	if (!configDevice(&gdp[count], idp->inactive_device, FALSE))
1680	    goto bail;
1681        count++;
1682        idp = (XF86ConfInactivePtr)idp->list.next;
1683    }
1684
1685    if (!configInputDevices(conf_layout, servlayoutp))
1686	goto bail;
1687
1688    servlayoutp->id = conf_layout->lay_identifier;
1689    servlayoutp->screens = slp;
1690    servlayoutp->inactives = gdp;
1691    servlayoutp->options = conf_layout->lay_option_lst;
1692    from = X_DEFAULT;
1693
1694    return TRUE;
1695
1696bail:
1697    do {
1698	free(slp[saved_count].screen);
1699    } while(saved_count--);
1700    free(slp);
1701    free(gdp);
1702    return FALSE;
1703}
1704
1705/*
1706 * No layout section, so find the first Screen section and set that up as
1707 * the only active screen.
1708 */
1709static Bool
1710configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
1711                    XF86ConfigPtr xf86configptr)
1712{
1713    MessageType from;
1714    XF86ConfScreenPtr s;
1715    screenLayoutPtr slp;
1716    InputInfoPtr *indp;
1717    XF86ConfLayoutRec layout;
1718
1719    if (!servlayoutp)
1720	return FALSE;
1721
1722    /*
1723     * which screen section is the active one?
1724     *
1725     * If there is a -screen option, use that one, otherwise use the first
1726     * one.
1727     */
1728
1729    from = X_CONFIG;
1730    if (xf86ScreenName != NULL) {
1731	if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
1732	    xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
1733		    xf86ScreenName);
1734	    return FALSE;
1735	}
1736	conf_screen = s;
1737	from = X_CMDLINE;
1738    }
1739
1740    /* We have exactly one screen */
1741
1742    slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
1743    slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1744    slp[1].screen = NULL;
1745    if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
1746	free(slp);
1747	return FALSE;
1748    }
1749    servlayoutp->id = "(implicit)";
1750    servlayoutp->screens = slp;
1751    servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
1752    servlayoutp->options = NULL;
1753
1754    memset(&layout, 0, sizeof(layout));
1755    layout.lay_identifier = servlayoutp->id;
1756    if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
1757	if (!configInputDevices(&layout, servlayoutp))
1758	    return FALSE;
1759	from = X_DEFAULT;
1760    } else {
1761	/* Set up an empty input device list, then look for some core devices. */
1762	indp = xnfalloc(sizeof(InputInfoPtr));
1763	*indp = NULL;
1764	servlayoutp->inputs = indp;
1765    }
1766
1767    return TRUE;
1768}
1769
1770static Bool
1771configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
1772{
1773    int count = 0;
1774    XF86ConfVideoPortPtr conf_port;
1775
1776    xf86Msg(X_CONFIG, "|   |-->VideoAdaptor \"%s\"\n",
1777	    conf_adaptor->va_identifier);
1778    adaptor->identifier = conf_adaptor->va_identifier;
1779    adaptor->options = conf_adaptor->va_option_lst;
1780    if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
1781	xf86Msg(X_CONFIG, "|   | Unsupported device type, skipping entry\n");
1782	return FALSE;
1783    }
1784
1785    /*
1786     * figure out how many videoport subsections there are and fill them in
1787     */
1788    conf_port = conf_adaptor->va_port_lst;
1789    while(conf_port) {
1790        count++;
1791        conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
1792    }
1793    adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
1794    adaptor->numports = count;
1795    count = 0;
1796    conf_port = conf_adaptor->va_port_lst;
1797    while(conf_port) {
1798	adaptor->ports[count].identifier = conf_port->vp_identifier;
1799	adaptor->ports[count].options = conf_port->vp_option_lst;
1800        count++;
1801        conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
1802    }
1803
1804    return TRUE;
1805}
1806
1807static Bool
1808configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
1809	     MessageType from)
1810{
1811    int count = 0;
1812    XF86ConfDisplayPtr dispptr;
1813    XF86ConfAdaptorLinkPtr conf_adaptor;
1814    Bool defaultMonitor = FALSE;
1815    XF86ConfScreenRec local_conf_screen;
1816
1817    if (!conf_screen) {
1818        memset(&local_conf_screen, 0, sizeof(local_conf_screen));
1819        conf_screen = &local_conf_screen;
1820        conf_screen->scrn_identifier = "Default Screen Section";
1821        xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
1822    }
1823
1824    xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
1825	    scrnum);
1826    /*
1827     * now we fill in the elements of the screen
1828     */
1829    screenp->id         = conf_screen->scrn_identifier;
1830    screenp->screennum  = scrnum;
1831    screenp->defaultdepth = conf_screen->scrn_defaultdepth;
1832    screenp->defaultbpp = conf_screen->scrn_defaultbpp;
1833    screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
1834    screenp->monitor    = xnfcalloc(1, sizeof(MonRec));
1835    /* If no monitor is specified, create a default one. */
1836    if (!conf_screen->scrn_monitor) {
1837	XF86ConfMonitorRec defMon;
1838
1839	memset(&defMon, 0, sizeof(defMon));
1840	defMon.mon_identifier = "<default monitor>";
1841	if (!configMonitor(screenp->monitor, &defMon))
1842	    return FALSE;
1843	defaultMonitor = TRUE;
1844    } else {
1845	if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
1846	    return FALSE;
1847    }
1848    /* Configure the device. If there isn't one configured, attach to the
1849     * first inactive one that we can configure. If there's none that work,
1850     * set it to NULL so that the section can be autoconfigured later */
1851    screenp->device     = xnfcalloc(1, sizeof(GDevRec));
1852    if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
1853        conf_screen->scrn_device = xf86configptr->conf_device_lst;
1854	xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
1855		"\tUsing the first device section listed.\n", screenp->id);
1856    }
1857    if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
1858        screenp->device->myScreenSection = screenp;
1859    } else {
1860        screenp->device = NULL;
1861    }
1862    screenp->options = conf_screen->scrn_option_lst;
1863
1864    /*
1865     * figure out how many display subsections there are and fill them in
1866     */
1867    dispptr = conf_screen->scrn_display_lst;
1868    while(dispptr) {
1869        count++;
1870        dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
1871    }
1872    screenp->displays   = xnfalloc((count) * sizeof(DispRec));
1873    screenp->numdisplays = count;
1874
1875    /* Fill in the default Virtual size, if any */
1876    if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
1877	for (count = 0, dispptr = conf_screen->scrn_display_lst;
1878	     dispptr;
1879	     dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
1880	    screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
1881	    screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
1882	}
1883    }
1884
1885    /* Now do the per-Display Virtual sizes */
1886    count = 0;
1887    dispptr = conf_screen->scrn_display_lst;
1888    while(dispptr) {
1889        configDisplay(&(screenp->displays[count]),dispptr);
1890        count++;
1891        dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
1892    }
1893
1894    /*
1895     * figure out how many videoadaptor references there are and fill them in
1896     */
1897    conf_adaptor = conf_screen->scrn_adaptor_lst;
1898    while(conf_adaptor) {
1899        count++;
1900        conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
1901    }
1902    screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
1903    screenp->numxvadaptors = 0;
1904    conf_adaptor = conf_screen->scrn_adaptor_lst;
1905    while(conf_adaptor) {
1906        if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
1907			    conf_adaptor->al_adaptor))
1908    	    screenp->numxvadaptors++;
1909        conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
1910    }
1911
1912    if (defaultMonitor) {
1913	xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
1914		"\tUsing a default monitor configuration.\n", screenp->id);
1915    }
1916    return TRUE;
1917}
1918
1919typedef enum {
1920    MON_REDUCEDBLANKING,
1921    MON_MAX_PIX_CLOCK,
1922} MonitorValues;
1923
1924static OptionInfoRec MonitorOptions[] = {
1925  { MON_REDUCEDBLANKING,      "ReducedBlanking",        OPTV_BOOLEAN,
1926       {0}, FALSE },
1927  { MON_MAX_PIX_CLOCK,	      "MaxPixClock",		OPTV_FREQ,
1928       {0}, FALSE },
1929  { -1,                                NULL,                   OPTV_NONE,
1930       {0}, FALSE },
1931};
1932
1933static Bool
1934configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
1935{
1936    int count;
1937    DisplayModePtr mode,last = NULL;
1938    XF86ConfModeLinePtr cmodep;
1939    XF86ConfModesPtr modes;
1940    XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
1941    Gamma zeros = {0.0, 0.0, 0.0};
1942    float badgamma = 0.0;
1943    double maxPixClock;
1944
1945    xf86Msg(X_CONFIG, "|   |-->Monitor \"%s\"\n",
1946	    conf_monitor->mon_identifier);
1947    monitorp->id = conf_monitor->mon_identifier;
1948    monitorp->vendor = conf_monitor->mon_vendor;
1949    monitorp->model = conf_monitor->mon_modelname;
1950    monitorp->Modes = NULL;
1951    monitorp->Last = NULL;
1952    monitorp->gamma = zeros;
1953    monitorp->widthmm = conf_monitor->mon_width;
1954    monitorp->heightmm = conf_monitor->mon_height;
1955    monitorp->reducedblanking = FALSE;
1956    monitorp->maxPixClock = 0;
1957    monitorp->options = conf_monitor->mon_option_lst;
1958
1959    /*
1960     * fill in the monitor structure
1961     */
1962    for( count = 0 ;
1963	 count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
1964	 count++) {
1965        monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
1966        monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
1967    }
1968    monitorp->nHsync = count;
1969    for( count = 0 ;
1970	 count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
1971	 count++) {
1972        monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
1973        monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
1974    }
1975    monitorp->nVrefresh = count;
1976
1977    /*
1978     * first we collect the mode lines from the UseModes directive
1979     */
1980    while(modeslnk)
1981    {
1982        modes = xf86findModes (modeslnk->ml_modes_str,
1983			       xf86configptr->conf_modes_lst);
1984	modeslnk->ml_modes = modes;
1985
1986
1987	/* now add the modes found in the modes
1988	   section to the list of modes for this
1989	   monitor unless it has been added before
1990	   because we are reusing the same section
1991	   for another screen */
1992	if (xf86itemNotSublist(
1993			       (GenericListPtr)conf_monitor->mon_modeline_lst,
1994			       (GenericListPtr)modes->mon_modeline_lst)) {
1995	    conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
1996	        xf86addListItem(
1997				(GenericListPtr)conf_monitor->mon_modeline_lst,
1998				(GenericListPtr)modes->mon_modeline_lst);
1999	}
2000	modeslnk = modeslnk->list.next;
2001    }
2002
2003    /*
2004     * we need to hook in the mode lines now
2005     * here both data structures use lists, only our internal one
2006     * is double linked
2007     */
2008    cmodep = conf_monitor->mon_modeline_lst;
2009    while( cmodep ) {
2010        mode = xnfcalloc(1, sizeof(DisplayModeRec));
2011	mode->type       = 0;
2012        mode->Clock      = cmodep->ml_clock;
2013        mode->HDisplay   = cmodep->ml_hdisplay;
2014        mode->HSyncStart = cmodep->ml_hsyncstart;
2015        mode->HSyncEnd   = cmodep->ml_hsyncend;
2016        mode->HTotal     = cmodep->ml_htotal;
2017        mode->VDisplay   = cmodep->ml_vdisplay;
2018        mode->VSyncStart = cmodep->ml_vsyncstart;
2019        mode->VSyncEnd   = cmodep->ml_vsyncend;
2020        mode->VTotal     = cmodep->ml_vtotal;
2021        mode->Flags      = cmodep->ml_flags;
2022        mode->HSkew      = cmodep->ml_hskew;
2023        mode->VScan      = cmodep->ml_vscan;
2024        mode->name       = xnfstrdup(cmodep->ml_identifier);
2025        if( last ) {
2026            mode->prev = last;
2027            last->next = mode;
2028        }
2029        else {
2030            /*
2031             * this is the first mode
2032             */
2033            monitorp->Modes = mode;
2034            mode->prev = NULL;
2035        }
2036        last = mode;
2037        cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
2038    }
2039    if(last){
2040      last->next = NULL;
2041    }
2042    monitorp->Last = last;
2043
2044    /* add the (VESA) default modes */
2045    if (! addDefaultModes(monitorp) )
2046	return FALSE;
2047
2048    if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
2049	monitorp->gamma.red = conf_monitor->mon_gamma_red;
2050    if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
2051	monitorp->gamma.green = conf_monitor->mon_gamma_green;
2052    if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
2053	monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
2054
2055    /* Check that the gamma values are within range */
2056    if (monitorp->gamma.red > GAMMA_ZERO &&
2057	(monitorp->gamma.red < GAMMA_MIN ||
2058	 monitorp->gamma.red > GAMMA_MAX)) {
2059	badgamma = monitorp->gamma.red;
2060    } else if (monitorp->gamma.green > GAMMA_ZERO &&
2061	(monitorp->gamma.green < GAMMA_MIN ||
2062	 monitorp->gamma.green > GAMMA_MAX)) {
2063	badgamma = monitorp->gamma.green;
2064    } else if (monitorp->gamma.blue > GAMMA_ZERO &&
2065	(monitorp->gamma.blue < GAMMA_MIN ||
2066	 monitorp->gamma.blue > GAMMA_MAX)) {
2067	badgamma = monitorp->gamma.blue;
2068    }
2069    if (badgamma > GAMMA_ZERO) {
2070	xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
2071			badgamma, GAMMA_MIN, GAMMA_MAX);
2072	    return FALSE;
2073    }
2074
2075    xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
2076    xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
2077                      &monitorp->reducedblanking);
2078    if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
2079			  &maxPixClock) == TRUE) {
2080	monitorp->maxPixClock = (int) maxPixClock;
2081    }
2082
2083    return TRUE;
2084}
2085
2086static int
2087lookupVisual(const char *visname)
2088{
2089    int i;
2090
2091    if (!visname || !*visname)
2092	return -1;
2093
2094    for (i = 0; i <= DirectColor; i++) {
2095	if (!xf86nameCompare(visname, xf86VisualNames[i]))
2096	    break;
2097    }
2098
2099    if (i <= DirectColor)
2100	return i;
2101
2102    return -1;
2103}
2104
2105
2106static Bool
2107configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
2108{
2109    int count = 0;
2110    XF86ModePtr modep;
2111
2112    displayp->frameX0           = conf_display->disp_frameX0;
2113    displayp->frameY0           = conf_display->disp_frameY0;
2114    displayp->virtualX          = conf_display->disp_virtualX;
2115    displayp->virtualY          = conf_display->disp_virtualY;
2116    displayp->depth             = conf_display->disp_depth;
2117    displayp->fbbpp             = conf_display->disp_bpp;
2118    displayp->weight.red        = conf_display->disp_weight.red;
2119    displayp->weight.green      = conf_display->disp_weight.green;
2120    displayp->weight.blue       = conf_display->disp_weight.blue;
2121    displayp->blackColour.red   = conf_display->disp_black.red;
2122    displayp->blackColour.green = conf_display->disp_black.green;
2123    displayp->blackColour.blue  = conf_display->disp_black.blue;
2124    displayp->whiteColour.red   = conf_display->disp_white.red;
2125    displayp->whiteColour.green = conf_display->disp_white.green;
2126    displayp->whiteColour.blue  = conf_display->disp_white.blue;
2127    displayp->options           = conf_display->disp_option_lst;
2128    if (conf_display->disp_visual) {
2129	displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
2130	if (displayp->defaultVisual == -1) {
2131	    xf86ConfigError("Invalid visual name: \"%s\"",
2132			    conf_display->disp_visual);
2133	    return FALSE;
2134	}
2135    } else {
2136	displayp->defaultVisual = -1;
2137    }
2138
2139    /*
2140     * now hook in the modes
2141     */
2142    modep = conf_display->disp_mode_lst;
2143    while(modep) {
2144        count++;
2145        modep = (XF86ModePtr)modep->list.next;
2146    }
2147    displayp->modes = xnfalloc((count+1) * sizeof(char*));
2148    modep = conf_display->disp_mode_lst;
2149    count = 0;
2150    while(modep) {
2151        displayp->modes[count] = modep->mode_name;
2152        count++;
2153        modep = (XF86ModePtr)modep->list.next;
2154    }
2155    displayp->modes[count] = NULL;
2156
2157    return TRUE;
2158}
2159
2160static Bool
2161configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
2162{
2163    int i;
2164
2165    if (!conf_device) {
2166        return FALSE;
2167    }
2168
2169    if (active)
2170	xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
2171		conf_device->dev_identifier);
2172    else
2173	xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
2174		conf_device->dev_identifier);
2175
2176    devicep->identifier = conf_device->dev_identifier;
2177    devicep->vendor = conf_device->dev_vendor;
2178    devicep->board = conf_device->dev_board;
2179    devicep->chipset = conf_device->dev_chipset;
2180    devicep->ramdac = conf_device->dev_ramdac;
2181    devicep->driver = conf_device->dev_driver;
2182    devicep->active = active;
2183    devicep->videoRam = conf_device->dev_videoram;
2184    devicep->BiosBase = conf_device->dev_bios_base;
2185    devicep->MemBase = conf_device->dev_mem_base;
2186    devicep->IOBase = conf_device->dev_io_base;
2187    devicep->clockchip = conf_device->dev_clockchip;
2188    devicep->busID = conf_device->dev_busid;
2189    devicep->textClockFreq = conf_device->dev_textclockfreq;
2190    devicep->chipID = conf_device->dev_chipid;
2191    devicep->chipRev = conf_device->dev_chiprev;
2192    devicep->options = conf_device->dev_option_lst;
2193    devicep->irq = conf_device->dev_irq;
2194    devicep->screen = conf_device->dev_screen;
2195
2196    for (i = 0; i < MAXDACSPEEDS; i++) {
2197	if (i < CONF_MAXDACSPEEDS)
2198            devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
2199	else
2200	    devicep->dacSpeeds[i] = 0;
2201    }
2202    devicep->numclocks = conf_device->dev_clocks;
2203    if (devicep->numclocks > MAXCLOCKS)
2204	devicep->numclocks = MAXCLOCKS;
2205    for (i = 0; i < devicep->numclocks; i++) {
2206	devicep->clock[i] = conf_device->dev_clock[i];
2207    }
2208    devicep->claimed = FALSE;
2209
2210    return TRUE;
2211}
2212
2213#ifdef XF86DRI
2214static void
2215configDRI(XF86ConfDRIPtr drip)
2216{
2217    struct group       *grp;
2218
2219    xf86ConfigDRI.group      = -1;
2220    xf86ConfigDRI.mode       = 0;
2221
2222    if (drip) {
2223	if (drip->dri_group_name) {
2224	    if ((grp = getgrnam(drip->dri_group_name)))
2225		xf86ConfigDRI.group = grp->gr_gid;
2226	} else {
2227	    if (drip->dri_group >= 0)
2228		xf86ConfigDRI.group = drip->dri_group;
2229	}
2230	xf86ConfigDRI.mode = drip->dri_mode;
2231    }
2232}
2233#endif
2234
2235static void
2236configExtensions(XF86ConfExtensionsPtr conf_ext)
2237{
2238    XF86OptionPtr o;
2239
2240    if (conf_ext && conf_ext->ext_option_lst) {
2241	for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
2242	    char *name   = xf86OptionName(o);
2243	    char *val    = xf86OptionValue(o);
2244	    char *n;
2245	    Bool  enable = TRUE;
2246
2247	    /* Handle "No<ExtensionName>" */
2248	    n = xf86NormalizeName(name);
2249	    if (strncmp(n, "no", 2) == 0) {
2250		name += 2;
2251		enable = FALSE;
2252	    }
2253
2254	    if (!val ||
2255		xf86NameCmp(val, "enable") == 0 ||
2256		xf86NameCmp(val, "enabled") == 0 ||
2257		xf86NameCmp(val, "on") == 0 ||
2258		xf86NameCmp(val, "1") == 0 ||
2259		xf86NameCmp(val, "yes") == 0 ||
2260		xf86NameCmp(val, "true") == 0) {
2261		/* NOTHING NEEDED -- enabling is handled below */
2262	    } else if (xf86NameCmp(val, "disable") == 0 ||
2263                       xf86NameCmp(val, "disabled") == 0 ||
2264		       xf86NameCmp(val, "off") == 0 ||
2265		       xf86NameCmp(val, "0") == 0 ||
2266		       xf86NameCmp(val, "no") == 0 ||
2267		       xf86NameCmp(val, "false") == 0) {
2268		enable = !enable;
2269	    } else {
2270		xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
2271		free(n);
2272		continue;
2273	    }
2274
2275	    if (EnableDisableExtension(name, enable)) {
2276		xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
2277			name, enable ? "enabled" : "disabled");
2278	    } else {
2279		xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
2280                        name);
2281	    }
2282	    free(n);
2283	}
2284    }
2285}
2286
2287static Bool
2288configInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
2289{
2290    xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
2291    inputp->name = conf_input->inp_identifier;
2292    inputp->driver = conf_input->inp_driver;
2293    inputp->options = conf_input->inp_option_lst;
2294    inputp->attrs = NULL;
2295
2296    return TRUE;
2297}
2298
2299static Bool
2300modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
2301{
2302    DisplayModePtr knownmodes = monitorp->Modes;
2303
2304    /* all I can think of is a linear search... */
2305    while(knownmodes != NULL)
2306    {
2307	if(!strcmp(mode->name, knownmodes->name) &&
2308	   !(knownmodes->type & M_T_DEFAULT))
2309	    return TRUE;
2310	knownmodes = knownmodes->next;
2311    }
2312    return FALSE;
2313}
2314
2315static Bool
2316addDefaultModes(MonPtr monitorp)
2317{
2318    DisplayModePtr mode;
2319    DisplayModePtr last = monitorp->Last;
2320    int i = 0;
2321
2322    for (i = 0; i < xf86NumDefaultModes; i++)
2323    {
2324	mode = xf86DuplicateMode(&xf86DefaultModes[i]);
2325	if (!modeIsPresent(mode, monitorp))
2326	{
2327	    monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
2328	    last = mode;
2329	} else {
2330	    free(mode);
2331	}
2332    }
2333    monitorp->Last = last;
2334
2335    return TRUE;
2336}
2337
2338static void
2339checkInput(serverLayoutPtr layout, Bool implicit_layout) {
2340    checkCoreInputDevices(layout, implicit_layout);
2341
2342    /* Unless we're forcing input devices, disable mouse/kbd devices in the
2343     * config. Otherwise the same physical device is added multiple times,
2344     * leading to duplicate events.
2345     */
2346    if (!xf86Info.forceInputDevices && layout->inputs)
2347    {
2348        InputInfoPtr *dev = layout->inputs;
2349        BOOL warned = FALSE;
2350
2351        while(*dev)
2352        {
2353            if (strcmp((*dev)->driver, "kbd") == 0 ||
2354                strcmp((*dev)->driver, "mouse") == 0 ||
2355                strcmp((*dev)->driver, "vmmouse") == 0)
2356            {
2357                InputInfoPtr *current;
2358                if (!warned)
2359                {
2360                    xf86Msg(X_WARNING, "Hotplugging is on, devices using "
2361                            "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
2362                    warned = TRUE;
2363                }
2364
2365                xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name);
2366
2367                current = dev;
2368                free(*dev);
2369
2370                do {
2371                    *current = *(current + 1);
2372                    current++;
2373                } while(*current);
2374            } else
2375                dev++;
2376        }
2377    }
2378}
2379
2380/*
2381 * load the config file and fill the global data structure
2382 */
2383ConfigStatus
2384xf86HandleConfigFile(Bool autoconfig)
2385{
2386    const char *filename, *dirname, *sysdirname;
2387    char *filesearch, *dirsearch;
2388    MessageType filefrom = X_DEFAULT;
2389    MessageType dirfrom = X_DEFAULT;
2390    char *scanptr;
2391    Bool singlecard = 0;
2392    Bool implicit_layout = FALSE;
2393
2394    if (!autoconfig) {
2395	if (getuid() == 0) {
2396	    filesearch = ROOT_CONFIGPATH;
2397	    dirsearch = ROOT_CONFIGDIRPATH;
2398	} else {
2399	    filesearch = USER_CONFIGPATH;
2400	    dirsearch = USER_CONFIGDIRPATH;
2401	}
2402
2403	if (xf86ConfigFile)
2404	    filefrom = X_CMDLINE;
2405	if (xf86ConfigDir)
2406	    dirfrom = X_CMDLINE;
2407
2408	xf86initConfigFiles();
2409	sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
2410					    PROJECTROOT);
2411	dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
2412	filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
2413	if (filename) {
2414	    xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
2415	    xf86ConfigFile = xnfstrdup(filename);
2416	} else {
2417	    if (xf86ConfigFile)
2418		xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
2419			xf86ConfigFile);
2420	}
2421	if (dirname) {
2422	    xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
2423			dirname);
2424	    xf86ConfigDir = xnfstrdup(dirname);
2425	} else {
2426	    if (xf86ConfigDir)
2427		xf86Msg(X_ERROR,
2428			"Unable to locate/open config directory: \"%s\"\n",
2429			xf86ConfigDir);
2430	}
2431	if (sysdirname)
2432	    xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
2433			sysdirname);
2434	if (!filename && !dirname && !sysdirname)
2435	    return CONFIG_NOFILE;
2436    }
2437
2438    if ((xf86configptr = xf86readConfigFile ()) == NULL) {
2439	xf86Msg(X_ERROR, "Problem parsing the config file\n");
2440	return CONFIG_PARSE_ERROR;
2441    }
2442    xf86closeConfigFile ();
2443
2444    /* Initialise a few things. */
2445
2446    /*
2447     * now we convert part of the information contained in the parser
2448     * structures into our own structures.
2449     * The important part here is to figure out which Screen Sections
2450     * in the XF86Config file are active so that we can piece together
2451     * the modes that we need later down the road.
2452     * And while we are at it, we'll decode the rest of the stuff as well
2453     */
2454
2455    /* First check if a layout section is present, and if it is valid. */
2456
2457    if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
2458	if (xf86ScreenName == NULL) {
2459	    xf86Msg(X_DEFAULT,
2460		    "No Layout section.  Using the first Screen section.\n");
2461	}
2462	if (!configImpliedLayout(&xf86ConfigLayout,
2463				 xf86configptr->conf_screen_lst,
2464				 xf86configptr)) {
2465            xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2466	    return CONFIG_PARSE_ERROR;
2467	}
2468	implicit_layout = TRUE;
2469    } else {
2470	if (xf86configptr->conf_flags != NULL) {
2471	  char *dfltlayout = NULL;
2472 	  pointer optlist = xf86configptr->conf_flags->flg_option_lst;
2473
2474	  if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
2475	    dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
2476	  if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
2477			  dfltlayout)) {
2478	    xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2479	    return CONFIG_PARSE_ERROR;
2480	  }
2481	} else {
2482	  if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
2483			  NULL)) {
2484	    xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2485	    return CONFIG_PARSE_ERROR;
2486	  }
2487	}
2488    }
2489
2490    xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
2491
2492    if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
2493       ; /* IsolateDevice specified; overrides SingleCard */
2494    } else {
2495       xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
2496       if (singlecard)
2497           scanptr = xf86ConfigLayout.screens->screen->device->busID;
2498    }
2499    if (scanptr) {
2500       if (strncmp(scanptr, "PCI:", 4) != 0) {
2501           xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
2502                              "\tIgnoring IsolateDevice option.\n");
2503       } else
2504           xf86PciIsolateDevice(scanptr);
2505    }
2506
2507    /* Now process everything else */
2508    if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
2509             ErrorF ("Problem when converting the config data structures\n");
2510             return CONFIG_PARSE_ERROR;
2511    }
2512
2513    configFiles(xf86configptr->conf_files);
2514    configExtensions(xf86configptr->conf_extensions);
2515#ifdef XF86DRI
2516    configDRI(xf86configptr->conf_dri);
2517#endif
2518
2519    checkInput(&xf86ConfigLayout, implicit_layout);
2520
2521    /*
2522     * Handle some command line options that can override some of the
2523     * ServerFlags settings.
2524     */
2525#ifdef XF86VIDMODE
2526    if (xf86VidModeDisabled)
2527	xf86Info.vidModeEnabled = FALSE;
2528    if (xf86VidModeAllowNonLocal)
2529	xf86Info.vidModeAllowNonLocal = TRUE;
2530#endif
2531
2532    if (xf86AllowMouseOpenFail)
2533	xf86Info.allowMouseOpenFail = TRUE;
2534
2535    return CONFIG_OK;
2536}
2537
2538Bool
2539xf86PathIsSafe(const char *path)
2540{
2541    return (xf86pathIsSafe(path) != 0);
2542}
2543