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