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