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