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