xf86Config.c revision a1818c9d
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    /* ensure defaultFontPath contains "built-ins" */
616    start = strstr(temp_path, "built-ins");
617    end = start + strlen("built-ins");
618    if (start == NULL ||
619	!((start == temp_path || start[-1] == ',') && (!*end || *end == ','))) {
620	defaultFontPath = Xprintf("%s%sbuilt-ins",
621				  temp_path, *temp_path ? "," : "");
622	if (must_copy == TRUE) {
623	    if (defaultFontPath != NULL) {
624		must_copy = FALSE;
625	    }
626	} else {
627	    /* already made a copy of the font path */
628	    xfree(temp_path);
629	}
630    }
631    /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
632    temp_path = must_copy ? XNFstrdup(defaultFontPath) : defaultFontPath;
633    defaultFontPath = xf86ValidateFontPath(temp_path);
634    free(temp_path);
635
636    /* make fontpath more readable in the logfiles */
637    countDirs = 1;
638    temp_path = defaultFontPath;
639    while ((temp_path = index(temp_path, ',')) != NULL) {
640	countDirs++;
641	temp_path++;
642    }
643
644    log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
645    temp_path = log_buf;
646    start = defaultFontPath;
647    while((end = index(start, ',')) != NULL) {
648      size = (end - start) + 1;
649      *(temp_path++) = '\t';
650      strncpy(temp_path, start, size);
651      temp_path += size;
652      *(temp_path++) = '\n';
653      start += size;
654    }
655    /* copy last entry */
656    *(temp_path++) = '\t';
657    strcpy(temp_path, start);
658    xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
659    xfree(log_buf);
660
661
662  if (fileconf && fileconf->file_inputdevs) {
663      xf86InputDeviceList = fileconf->file_inputdevs;
664      xf86Msg(X_CONFIG, "Input device list set to \"%s\"\n",
665	  xf86InputDeviceList);
666  }
667
668
669  /* ModulePath */
670
671  if (fileconf) {
672    if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
673      xf86ModulePath = fileconf->file_modulepath;
674      xf86ModPathFrom = X_CONFIG;
675    }
676  }
677
678  xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
679
680  if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
681    XkbBaseDirectory = fileconf->file_xkbdir;
682    xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
683	    XkbBaseDirectory);
684  }
685#if 0
686  /* LogFile */
687  /*
688   * XXX The problem with this is that the log file is already open.
689   * One option might be to copy the exiting contents to the new location.
690   * and re-open it.  The down side is that the default location would
691   * already have been overwritten.  Another option would be to start with
692   * unique temporary location, then copy it once the correct name is known.
693   * A problem with this is what happens if the server exits before that
694   * happens.
695   */
696  if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
697    xf86LogFile = fileconf->file_logfile;
698    xf86LogFileFrom = X_CONFIG;
699  }
700#endif
701
702  return;
703}
704
705typedef enum {
706    FLAG_NOTRAPSIGNALS,
707    FLAG_DONTVTSWITCH,
708    FLAG_DONTZAP,
709    FLAG_DONTZOOM,
710    FLAG_DISABLEVIDMODE,
711    FLAG_ALLOWNONLOCAL,
712    FLAG_DISABLEMODINDEV,
713    FLAG_MODINDEVALLOWNONLOCAL,
714    FLAG_ALLOWMOUSEOPENFAIL,
715    FLAG_VTSYSREQ,
716    FLAG_XKBDISABLE,
717    FLAG_SAVER_BLANKTIME,
718    FLAG_DPMS_STANDBYTIME,
719    FLAG_DPMS_SUSPENDTIME,
720    FLAG_DPMS_OFFTIME,
721    FLAG_PIXMAP,
722    FLAG_PC98,
723    FLAG_NOPM,
724    FLAG_XINERAMA,
725    FLAG_LOG,
726    FLAG_RENDER_COLORMAP_MODE,
727    FLAG_HANDLE_SPECIAL_KEYS,
728    FLAG_RANDR,
729    FLAG_AIGLX,
730    FLAG_IGNORE_ABI,
731    FLAG_ALLOW_EMPTY_INPUT,
732    FLAG_USE_DEFAULT_FONT_PATH,
733    FLAG_AUTO_ADD_DEVICES,
734    FLAG_AUTO_ENABLE_DEVICES,
735    FLAG_GLX_VISUALS,
736    FLAG_DRI2,
737} FlagValues;
738
739static OptionInfoRec FlagOptions[] = {
740  { FLAG_NOTRAPSIGNALS,		"NoTrapSignals",		OPTV_BOOLEAN,
741	{0}, FALSE },
742  { FLAG_DONTVTSWITCH,		"DontVTSwitch",			OPTV_BOOLEAN,
743	{0}, FALSE },
744  { FLAG_DONTZAP,		"DontZap",			OPTV_BOOLEAN,
745	{0}, FALSE },
746  { FLAG_DONTZOOM,		"DontZoom",			OPTV_BOOLEAN,
747	{0}, FALSE },
748  { FLAG_DISABLEVIDMODE,	"DisableVidModeExtension",	OPTV_BOOLEAN,
749	{0}, FALSE },
750  { FLAG_ALLOWNONLOCAL,		"AllowNonLocalXvidtune",	OPTV_BOOLEAN,
751	{0}, FALSE },
752  { FLAG_DISABLEMODINDEV,	"DisableModInDev",		OPTV_BOOLEAN,
753	{0}, FALSE },
754  { FLAG_MODINDEVALLOWNONLOCAL,	"AllowNonLocalModInDev",	OPTV_BOOLEAN,
755	{0}, FALSE },
756  { FLAG_ALLOWMOUSEOPENFAIL,	"AllowMouseOpenFail",		OPTV_BOOLEAN,
757	{0}, FALSE },
758  { FLAG_VTSYSREQ,		"VTSysReq",			OPTV_BOOLEAN,
759	{0}, FALSE },
760  { FLAG_XKBDISABLE,		"XkbDisable",			OPTV_BOOLEAN,
761	{0}, FALSE },
762  { FLAG_SAVER_BLANKTIME,	"BlankTime"		,	OPTV_INTEGER,
763	{0}, FALSE },
764  { FLAG_DPMS_STANDBYTIME,	"StandbyTime",			OPTV_INTEGER,
765	{0}, FALSE },
766  { FLAG_DPMS_SUSPENDTIME,	"SuspendTime",			OPTV_INTEGER,
767	{0}, FALSE },
768  { FLAG_DPMS_OFFTIME,		"OffTime",			OPTV_INTEGER,
769	{0}, FALSE },
770  { FLAG_PIXMAP,		"Pixmap",			OPTV_INTEGER,
771	{0}, FALSE },
772  { FLAG_PC98,			"PC98",				OPTV_BOOLEAN,
773	{0}, FALSE },
774  { FLAG_NOPM,			"NoPM",				OPTV_BOOLEAN,
775	{0}, FALSE },
776  { FLAG_XINERAMA,		"Xinerama",			OPTV_BOOLEAN,
777	{0}, FALSE },
778  { FLAG_LOG,			"Log",				OPTV_STRING,
779	{0}, FALSE },
780  { FLAG_RENDER_COLORMAP_MODE,	"RenderColormapMode",		OPTV_STRING,
781        {0}, FALSE },
782  { FLAG_HANDLE_SPECIAL_KEYS,	"HandleSpecialKeys",		OPTV_STRING,
783        {0}, FALSE },
784  { FLAG_RANDR,			"RandR",			OPTV_BOOLEAN,
785	{0}, FALSE },
786  { FLAG_AIGLX,			"AIGLX",			OPTV_BOOLEAN,
787	{0}, FALSE },
788  { FLAG_ALLOW_EMPTY_INPUT,     "AllowEmptyInput",              OPTV_BOOLEAN,
789        {0}, FALSE },
790  { FLAG_IGNORE_ABI,		"IgnoreABI",			OPTV_BOOLEAN,
791	{0}, FALSE },
792  { FLAG_USE_DEFAULT_FONT_PATH,  "UseDefaultFontPath",		OPTV_BOOLEAN,
793	{0}, FALSE },
794  { FLAG_AUTO_ADD_DEVICES,       "AutoAddDevices",		OPTV_BOOLEAN,
795        {0}, TRUE },
796  { FLAG_AUTO_ENABLE_DEVICES,    "AutoEnableDevices",		OPTV_BOOLEAN,
797        {0}, TRUE },
798  { FLAG_GLX_VISUALS,		"GlxVisuals",			OPTV_STRING,
799        {0}, FALSE },
800  { FLAG_DRI2,			"DRI2",				OPTV_BOOLEAN,
801	{0}, FALSE },
802  { -1,				NULL,				OPTV_NONE,
803	{0}, FALSE },
804};
805
806#ifdef __i386__
807static Bool
808detectPC98(void)
809{
810#ifdef SUPPORT_PC98
811    unsigned char buf[2];
812
813    if (xf86ReadBIOS(0xf8000, 0xe80, buf, 2) != 2)
814	return FALSE;
815    if ((buf[0] == 0x98) && (buf[1] == 0x21))
816	return TRUE;
817    else
818	return FALSE;
819#else
820    return FALSE;
821#endif
822}
823#endif /* __i386__ */
824
825static Bool
826configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
827{
828    XF86OptionPtr optp, tmp;
829    int i;
830    Pix24Flags pix24 = Pix24DontCare;
831    Bool value;
832    MessageType from;
833    const char *s;
834#ifdef XKB
835    char *rules = "base";
836#endif
837
838    /*
839     * Merge the ServerLayout and ServerFlags options.  The former have
840     * precedence over the latter.
841     */
842    optp = NULL;
843    if (flagsconf && flagsconf->flg_option_lst)
844	optp = xf86optionListDup(flagsconf->flg_option_lst);
845    if (layoutopts) {
846	tmp = xf86optionListDup(layoutopts);
847	if (optp)
848	    optp = xf86optionListMerge(optp, tmp);
849	else
850	    optp = tmp;
851    }
852
853    xf86ProcessOptions(-1, optp, FlagOptions);
854
855    xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
856    xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
857    xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
858    xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
859
860    xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
861    if (xf86Info.ignoreABI) {
862	    xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
863    }
864
865    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
866        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
867                          &xf86Info.autoAddDevices);
868        from = X_CONFIG;
869    }
870    else {
871        from = X_DEFAULT;
872    }
873    xf86Msg(from, "%sutomatically adding devices\n",
874            xf86Info.autoAddDevices ? "A" : "Not a");
875
876    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
877        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
878                          &xf86Info.autoEnableDevices);
879        from = X_CONFIG;
880    }
881    else {
882        from = X_DEFAULT;
883    }
884    xf86Msg(from, "%sutomatically enabling devices\n",
885            xf86Info.autoEnableDevices ? "A" : "Not a");
886
887    /*
888     * Set things up based on the config file information.  Some of these
889     * settings may be overridden later when the command line options are
890     * checked.
891     */
892#ifdef XF86VIDMODE
893    if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
894	xf86Info.vidModeEnabled = !value;
895    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
896	xf86Info.vidModeAllowNonLocal = value;
897#endif
898
899    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
900	xf86Info.allowMouseOpenFail = value;
901
902    if (xf86GetOptValBool(FlagOptions, FLAG_VTSYSREQ, &value)) {
903#ifdef USE_VT_SYSREQ
904	xf86Info.vtSysreq = value;
905	xf86Msg(X_CONFIG, "VTSysReq %s\n", value ? "enabled" : "disabled");
906#else
907	if (value)
908	    xf86Msg(X_WARNING, "VTSysReq is not supported on this OS\n");
909#endif
910    }
911
912    if (xf86GetOptValBool(FlagOptions, FLAG_XKBDISABLE, &value)) {
913#ifdef XKB
914	noXkbExtension = value;
915	xf86Msg(X_CONFIG, "Xkb %s\n", value ? "disabled" : "enabled");
916#else
917	if (!value)
918	    xf86Msg(X_WARNING, "Xserver doesn't support XKB\n");
919#endif
920    }
921
922    xf86Info.pmFlag = TRUE;
923    if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
924	xf86Info.pmFlag = !value;
925    {
926	if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
927	    if (!xf86NameCmp(s,"flush")) {
928		xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
929		xf86Info.log = LogFlush;
930		LogSetParameter(XLOG_FLUSH, TRUE);
931	    } else if (!xf86NameCmp(s,"sync")) {
932		xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
933		xf86Info.log = LogSync;
934		LogSetParameter(XLOG_FLUSH, TRUE);
935		LogSetParameter(XLOG_SYNC, TRUE);
936	    } else {
937		xf86Msg(X_WARNING,"Unknown Log option\n");
938	    }
939        }
940    }
941
942#ifdef RENDER
943    {
944	if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
945	    int policy = PictureParseCmapPolicy (s);
946	    if (policy == PictureCmapPolicyInvalid)
947		xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
948	    else
949	    {
950		xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
951		PictureCmapPolicy = policy;
952	    }
953	}
954    }
955#endif
956    {
957	if ((s = xf86GetOptValString(FlagOptions, FLAG_HANDLE_SPECIAL_KEYS))) {
958	    if (!xf86NameCmp(s,"always")) {
959		xf86Msg(X_CONFIG, "Always handling special keys in DDX\n");
960		xf86Info.ddxSpecialKeys = SKAlways;
961	    } else if (!xf86NameCmp(s,"whenneeded")) {
962		xf86Msg(X_CONFIG, "Special keys handled in DDX only if needed\n");
963		xf86Info.ddxSpecialKeys = SKWhenNeeded;
964	    } else if (!xf86NameCmp(s,"never")) {
965		xf86Msg(X_CONFIG, "Never handling special keys in DDX\n");
966		xf86Info.ddxSpecialKeys = SKNever;
967	    } else {
968		xf86Msg(X_WARNING,"Unknown HandleSpecialKeys option\n");
969	    }
970        }
971    }
972#ifdef RANDR
973    xf86Info.disableRandR = FALSE;
974    xf86Info.randRFrom = X_DEFAULT;
975    if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
976	xf86Info.disableRandR = !value;
977	xf86Info.randRFrom = X_CONFIG;
978    }
979#endif
980
981    xf86Info.aiglx = TRUE;
982    xf86Info.aiglxFrom = X_DEFAULT;
983    if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
984	xf86Info.aiglx = value;
985	xf86Info.aiglxFrom = X_CONFIG;
986    }
987
988#ifdef GLXEXT
989    xf86Info.glxVisuals = XF86_GlxVisualsTypical;
990    xf86Info.glxVisualsFrom = X_DEFAULT;
991    if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
992	if (!xf86NameCmp(s, "minimal")) {
993	    xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
994	} else if (!xf86NameCmp(s, "typical")) {
995	    xf86Info.glxVisuals = XF86_GlxVisualsTypical;
996	} else if (!xf86NameCmp(s, "all")) {
997	    xf86Info.glxVisuals = XF86_GlxVisualsAll;
998	} else {
999	    xf86Msg(X_WARNING,"Unknown GlxVisuals option\n");
1000	}
1001    }
1002
1003    if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
1004	xf86Info.aiglx = value;
1005	xf86Info.aiglxFrom = X_CONFIG;
1006    }
1007#endif
1008
1009    /* AllowEmptyInput is automatically true if we're hotplugging */
1010    xf86Info.allowEmptyInput = (xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
1011    xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &xf86Info.allowEmptyInput);
1012
1013    /* AEI on? Then we're not using kbd, so use the evdev rules set. */
1014#ifdef XKB
1015#if defined(linux)
1016    if (xf86Info.allowEmptyInput)
1017        rules = "evdev";
1018#endif
1019    XkbSetRulesDflts(rules, "pc105", "us", NULL, NULL);
1020#endif
1021
1022    xf86Info.useDefaultFontPath = TRUE;
1023    xf86Info.useDefaultFontPathFrom = X_DEFAULT;
1024    if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
1025	xf86Info.useDefaultFontPath = value;
1026	xf86Info.useDefaultFontPathFrom = X_CONFIG;
1027    }
1028
1029/* Make sure that timers don't overflow CARD32's after multiplying */
1030#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
1031
1032    i = -1;
1033    xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
1034    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
1035	ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
1036    else if (i != -1)
1037	xf86ConfigError("BlankTime value %d outside legal range of 0 - %d minutes",
1038			i, MAX_TIME_IN_MIN);
1039
1040#ifdef DPMSExtension
1041    i = -1;
1042    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
1043    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
1044	DPMSStandbyTime = defaultDPMSStandbyTime = i * MILLI_PER_MIN;
1045    else if (i != -1)
1046	xf86ConfigError("StandbyTime value %d outside legal range of 0 - %d minutes",
1047			i, MAX_TIME_IN_MIN);
1048    i = -1;
1049    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
1050    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
1051	DPMSSuspendTime = defaultDPMSSuspendTime = i * MILLI_PER_MIN;
1052    else if (i != -1)
1053	xf86ConfigError("SuspendTime value %d outside legal range of 0 - %d minutes",
1054			i, MAX_TIME_IN_MIN);
1055    i = -1;
1056    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
1057    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
1058	DPMSOffTime = defaultDPMSOffTime = i * MILLI_PER_MIN;
1059    else if (i != -1)
1060	xf86ConfigError("OffTime value %d outside legal range of 0 - %d minutes",
1061			i, MAX_TIME_IN_MIN);
1062#endif
1063
1064    i = -1;
1065    xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
1066    switch (i) {
1067    case 24:
1068	pix24 = Pix24Use24;
1069	break;
1070    case 32:
1071	pix24 = Pix24Use32;
1072	break;
1073    case -1:
1074	break;
1075    default:
1076	xf86ConfigError("Pixmap option's value (%d) must be 24 or 32\n", i);
1077	return FALSE;
1078    }
1079    if (xf86Pix24 != Pix24DontCare) {
1080	xf86Info.pixmap24 = xf86Pix24;
1081	xf86Info.pix24From = X_CMDLINE;
1082    } else if (pix24 != Pix24DontCare) {
1083	xf86Info.pixmap24 = pix24;
1084	xf86Info.pix24From = X_CONFIG;
1085    } else {
1086	xf86Info.pixmap24 = Pix24DontCare;
1087	xf86Info.pix24From = X_DEFAULT;
1088    }
1089#ifdef __i386__
1090    if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
1091	xf86Info.pc98 = value;
1092	if (value) {
1093	    xf86Msg(X_CONFIG, "Japanese PC98 architecture\n");
1094	}
1095    } else
1096	if (detectPC98()) {
1097	    xf86Info.pc98 = TRUE;
1098	    xf86Msg(X_PROBED, "Japanese PC98 architecture\n");
1099	}
1100#endif
1101
1102#ifdef PANORAMIX
1103    from = X_DEFAULT;
1104    if (!noPanoramiXExtension)
1105      from = X_CMDLINE;
1106    else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
1107      noPanoramiXExtension = !value;
1108      from = X_CONFIG;
1109    }
1110    if (!noPanoramiXExtension)
1111      xf86Msg(from, "Xinerama: enabled\n");
1112#endif
1113
1114#ifdef DRI2
1115    xf86Info.dri2 = FALSE;
1116    xf86Info.dri2From = X_DEFAULT;
1117    if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
1118	xf86Info.dri2 = value;
1119	xf86Info.dri2From = X_CONFIG;
1120    }
1121#endif
1122
1123    return TRUE;
1124}
1125
1126Bool xf86DRI2Enabled(void)
1127{
1128    return xf86Info.dri2;
1129}
1130
1131/*
1132 * Locate the core input devices.  These can be specified/located in
1133 * the following ways, in order of priority:
1134 *
1135 *  1. The InputDevices named by the -pointer and -keyboard command line
1136 *     options.
1137 *  2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
1138 *     the active ServerLayout.
1139 *  3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
1140 *  4. The first InputDevices that use the 'mouse' and 'keyboard' or 'kbd'
1141 *     drivers.
1142 *  5. Default devices with an empty (default) configuration.  These defaults
1143 *     will reference the 'mouse' and 'keyboard' drivers.
1144 */
1145
1146static Bool
1147checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
1148{
1149    IDevPtr corePointer = NULL, coreKeyboard = NULL;
1150    Bool foundPointer = FALSE, foundKeyboard = FALSE;
1151    const char *pointerMsg = NULL, *keyboardMsg = NULL;
1152    IDevPtr *devs, /* iterator */
1153            indp;
1154    IDevRec Pointer, Keyboard;
1155    XF86ConfInputPtr confInput;
1156    XF86ConfInputRec defPtr, defKbd;
1157    int count = 0;
1158    MessageType from = X_DEFAULT;
1159    int found = 0;
1160
1161    /*
1162     * First check if a core pointer or core keyboard have been specified
1163     * in the active ServerLayout.  If more than one is specified for either,
1164     * remove the core attribute from the later ones.
1165     */
1166    for (devs = servlayoutp->inputs; devs && *devs; devs++) {
1167	pointer opt1 = NULL, opt2 = NULL;
1168        indp = *devs;
1169	if (indp->commonOptions &&
1170	    xf86CheckBoolOption(indp->commonOptions, "CorePointer", FALSE)) {
1171	    opt1 = indp->commonOptions;
1172	}
1173	if (indp->extraOptions &&
1174	    xf86CheckBoolOption(indp->extraOptions, "CorePointer", FALSE)) {
1175	    opt2 = indp->extraOptions;
1176	}
1177	if (opt1 || opt2) {
1178	    if (!corePointer) {
1179		corePointer = indp;
1180	    } else {
1181		if (opt1)
1182		    xf86ReplaceBoolOption(opt1, "CorePointer", FALSE);
1183		if (opt2)
1184		    xf86ReplaceBoolOption(opt2, "CorePointer", FALSE);
1185		xf86Msg(X_WARNING, "Duplicate core pointer devices.  "
1186			"Removing core pointer attribute from \"%s\"\n",
1187			indp->identifier);
1188	    }
1189	}
1190	opt1 = opt2 = NULL;
1191	if (indp->commonOptions &&
1192	    xf86CheckBoolOption(indp->commonOptions, "CoreKeyboard", FALSE)) {
1193	    opt1 = indp->commonOptions;
1194	}
1195	if (indp->extraOptions &&
1196	    xf86CheckBoolOption(indp->extraOptions, "CoreKeyboard", FALSE)) {
1197	    opt2 = indp->extraOptions;
1198	}
1199	if (opt1 || opt2) {
1200	    if (!coreKeyboard) {
1201		coreKeyboard = indp;
1202	    } else {
1203		if (opt1)
1204		    xf86ReplaceBoolOption(opt1, "CoreKeyboard", FALSE);
1205		if (opt2)
1206		    xf86ReplaceBoolOption(opt2, "CoreKeyboard", FALSE);
1207		xf86Msg(X_WARNING, "Duplicate core keyboard devices.  "
1208			"Removing core keyboard attribute from \"%s\"\n",
1209			indp->identifier);
1210	    }
1211	}
1212	count++;
1213    }
1214
1215    confInput = NULL;
1216
1217    /* 1. Check for the -pointer command line option. */
1218    if (xf86PointerName) {
1219	confInput = xf86findInput(xf86PointerName,
1220				  xf86configptr->conf_input_lst);
1221	if (!confInput) {
1222	    xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1223		    xf86PointerName);
1224	    return FALSE;
1225	}
1226	from = X_CMDLINE;
1227	/*
1228	 * If one was already specified in the ServerLayout, it needs to be
1229	 * removed.
1230	 */
1231	if (corePointer) {
1232	    for (devs = servlayoutp->inputs; devs && *devs; devs++)
1233		if (*devs == corePointer)
1234                {
1235                    xfree(*devs);
1236                    *devs = (IDevPtr)0x1; /* ensure we dont skip next loop*/
1237		    break;
1238                }
1239	    for (; devs && *devs; devs++)
1240		devs[0] = devs[1];
1241	    count--;
1242	}
1243	corePointer = NULL;
1244	foundPointer = TRUE;
1245    }
1246
1247    /* 2. ServerLayout-specified core pointer. */
1248    if (corePointer) {
1249	foundPointer = TRUE;
1250	from = X_CONFIG;
1251    }
1252
1253    /* 3. First core pointer device. */
1254    if (!foundPointer && (!xf86Info.allowEmptyInput || implicitLayout)) {
1255	XF86ConfInputPtr p;
1256
1257	for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1258	    if (p->inp_option_lst &&
1259		xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
1260		confInput = p;
1261		foundPointer = TRUE;
1262		from = X_DEFAULT;
1263		pointerMsg = "first core pointer device";
1264		break;
1265	    }
1266	}
1267    }
1268
1269    /* 4. First pointer with 'mouse' as the driver. */
1270    if (!foundPointer && !xf86Info.allowEmptyInput) {
1271	confInput = xf86findInput(CONF_IMPLICIT_POINTER,
1272				  xf86configptr->conf_input_lst);
1273	if (!confInput) {
1274	    confInput = xf86findInputByDriver("mouse",
1275					      xf86configptr->conf_input_lst);
1276	}
1277	if (confInput) {
1278	    foundPointer = TRUE;
1279	    from = X_DEFAULT;
1280	    pointerMsg = "first mouse device";
1281	}
1282    }
1283
1284    /* 5. Built-in default. */
1285    if (!foundPointer && !xf86Info.allowEmptyInput) {
1286	bzero(&defPtr, sizeof(defPtr));
1287	defPtr.inp_identifier = strdup("<default pointer>");
1288	defPtr.inp_driver = strdup("mouse");
1289	confInput = &defPtr;
1290	foundPointer = TRUE;
1291	from = X_DEFAULT;
1292	pointerMsg = "default mouse configuration";
1293    }
1294
1295    /* Add the core pointer device to the layout, and set it to Core. */
1296    if (foundPointer && confInput) {
1297	foundPointer = configInput(&Pointer, confInput, from);
1298        if (foundPointer) {
1299	    count++;
1300	    devs = xnfrealloc(servlayoutp->inputs,
1301			      (count + 1) * sizeof(IDevPtr));
1302            devs[count - 1] = xnfalloc(sizeof(IDevRec));
1303	    *devs[count - 1] = Pointer;
1304	    devs[count - 1]->extraOptions =
1305				xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
1306	    devs[count] = NULL;
1307	    servlayoutp->inputs = devs;
1308	}
1309    }
1310
1311    if (!foundPointer) {
1312	if (!xf86Info.allowEmptyInput) {
1313	    /* This shouldn't happen. */
1314	    xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
1315	    return FALSE;
1316	} else {
1317	    xf86Msg(X_INFO, "Cannot locate a core pointer device.\n");
1318	}
1319    }
1320
1321    /*
1322     * always synthesize a 'mouse' section configured to send core
1323     * events, unless a 'void' section is found, in which case the user
1324     * probably wants to run footless.
1325     *
1326     * If you're using an evdev keyboard and expect a default mouse
1327     * section ... deal.
1328     */
1329    for (devs = servlayoutp->inputs; devs && *devs; devs++) {
1330	if (!strcmp((*devs)->driver, "void") || !strcmp((*devs)->driver, "mouse") ||
1331            !strcmp((*devs)->driver, "vmmouse") || !strcmp((*devs)->driver, "evdev")) {
1332	    found = 1; break;
1333	}
1334    }
1335    if (!found && !xf86Info.allowEmptyInput) {
1336	xf86Msg(X_INFO, "No default mouse found, adding one\n");
1337	bzero(&defPtr, sizeof(defPtr));
1338	defPtr.inp_identifier = strdup("<default pointer>");
1339	defPtr.inp_driver = strdup("mouse");
1340	confInput = &defPtr;
1341	foundPointer = configInput(&Pointer, confInput, from);
1342        if (foundPointer) {
1343	    count++;
1344	    devs = xnfrealloc(servlayoutp->inputs,
1345			      (count + 1) * sizeof(IDevPtr));
1346            devs[count - 1] = xnfalloc(sizeof(IDevRec));
1347	    *devs[count - 1] = Pointer;
1348	    devs[count - 1]->extraOptions =
1349				xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
1350	    devs[count] = NULL;
1351	    servlayoutp->inputs = devs;
1352	}
1353    }
1354
1355    confInput = NULL;
1356
1357    /* 1. Check for the -keyboard command line option. */
1358    if (xf86KeyboardName) {
1359	confInput = xf86findInput(xf86KeyboardName,
1360				  xf86configptr->conf_input_lst);
1361	if (!confInput) {
1362	    xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1363		    xf86KeyboardName);
1364	    return FALSE;
1365	}
1366	from = X_CMDLINE;
1367	/*
1368	 * If one was already specified in the ServerLayout, it needs to be
1369	 * removed.
1370	 */
1371	if (coreKeyboard) {
1372	    for (devs = servlayoutp->inputs; devs && *devs; devs++)
1373		if (*devs == coreKeyboard)
1374                {
1375                    xfree(*devs);
1376                    *devs = (IDevPtr)0x1; /* ensure we dont skip next loop */
1377		    break;
1378                }
1379	    for (; devs && *devs; devs++)
1380		devs[0] = devs[1];
1381	    count--;
1382	}
1383	coreKeyboard = NULL;
1384	foundKeyboard = TRUE;
1385    }
1386
1387    /* 2. ServerLayout-specified core keyboard. */
1388    if (coreKeyboard) {
1389	foundKeyboard = TRUE;
1390	from = X_CONFIG;
1391    }
1392
1393    /* 3. First core keyboard device. */
1394    if (!foundKeyboard && (!xf86Info.allowEmptyInput || implicitLayout)) {
1395	XF86ConfInputPtr p;
1396
1397	for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1398	    if (p->inp_option_lst &&
1399		xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
1400		confInput = p;
1401		foundKeyboard = TRUE;
1402		from = X_DEFAULT;
1403		keyboardMsg = "first core keyboard device";
1404		break;
1405	    }
1406	}
1407    }
1408
1409    /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
1410    if (!foundKeyboard && !xf86Info.allowEmptyInput) {
1411	confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
1412				  xf86configptr->conf_input_lst);
1413	if (!confInput) {
1414	    confInput = xf86findInputByDriver("kbd",
1415					      xf86configptr->conf_input_lst);
1416	}
1417	if (confInput) {
1418	    foundKeyboard = TRUE;
1419	    from = X_DEFAULT;
1420	    keyboardMsg = "first keyboard device";
1421	}
1422    }
1423
1424    /* 5. Built-in default. */
1425    if (!foundKeyboard && !xf86Info.allowEmptyInput) {
1426	bzero(&defKbd, sizeof(defKbd));
1427	defKbd.inp_identifier = strdup("<default keyboard>");
1428	defKbd.inp_driver = strdup("kbd");
1429	confInput = &defKbd;
1430	foundKeyboard = TRUE;
1431	keyboardMsg = "default keyboard configuration";
1432	from = X_DEFAULT;
1433    }
1434
1435    /* Add the core keyboard device to the layout, and set it to Core. */
1436    if (foundKeyboard && confInput) {
1437	foundKeyboard = configInput(&Keyboard, confInput, from);
1438        if (foundKeyboard) {
1439	    count++;
1440	    devs = xnfrealloc(servlayoutp->inputs,
1441			      (count + 1) * sizeof(IDevPtr));
1442            devs[count - 1] = xnfalloc(sizeof(IDevRec));
1443	    *devs[count - 1] = Keyboard;
1444	    devs[count - 1]->extraOptions =
1445				xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
1446	    devs[count] = NULL;
1447	    servlayoutp->inputs = devs;
1448	}
1449    }
1450
1451    if (!foundKeyboard) {
1452	if (!xf86Info.allowEmptyInput) {
1453		/* This shouldn't happen. */
1454		xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
1455		return FALSE;
1456	} else {
1457		xf86Msg(X_INFO, "Cannot locate a core keyboard device.\n");
1458	}
1459    }
1460
1461    if (pointerMsg) {
1462	if (implicitLayout)
1463	    xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1464	            pointerMsg);
1465	else
1466	    xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
1467	            "explicitly in the layout.\n"
1468	            "\tUsing the %s.\n", pointerMsg);
1469    }
1470
1471    if (keyboardMsg) {
1472	if (implicitLayout)
1473	    xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1474	            keyboardMsg);
1475	else
1476	    xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
1477	            "explicitly in the layout.\n"
1478	            "\tUsing the %s.\n", keyboardMsg);
1479    }
1480
1481    if (xf86Info.allowEmptyInput && !(foundPointer && foundKeyboard)) {
1482#ifdef CONFIG_HAL
1483	xf86Msg(X_INFO, "The server relies on HAL to provide the list of "
1484	                "input devices.\n\tIf no devices become available, "
1485	                "reconfigure HAL or disable AllowEmptyInput.\n");
1486#else
1487	xf86Msg(X_INFO, "HAL is disabled and no input devices were configured.\n"
1488			"\tTry disabling AllowEmptyInput.\n");
1489#endif
1490    }
1491
1492    return TRUE;
1493}
1494
1495typedef enum {
1496    LAYOUT_ISOLATEDEVICE,
1497    LAYOUT_SINGLECARD
1498} LayoutValues;
1499
1500static OptionInfoRec LayoutOptions[] = {
1501  { LAYOUT_ISOLATEDEVICE,      "IsolateDevice",        OPTV_STRING,
1502       {0}, FALSE },
1503  { LAYOUT_SINGLECARD,         "SingleCard",           OPTV_BOOLEAN,
1504       {0}, FALSE },
1505  { -1,                                NULL,                   OPTV_NONE,
1506       {0}, FALSE },
1507};
1508
1509/*
1510 * figure out which layout is active, which screens are used in that layout,
1511 * which drivers and monitors are used in these screens
1512 */
1513static Bool
1514configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
1515	     char *default_layout)
1516{
1517    XF86ConfAdjacencyPtr adjp;
1518    XF86ConfInactivePtr idp;
1519    XF86ConfInputrefPtr irp;
1520    int count = 0;
1521    int scrnum;
1522    XF86ConfLayoutPtr l;
1523    MessageType from;
1524    screenLayoutPtr slp;
1525    GDevPtr gdp;
1526    IDevPtr* indp;
1527    int i = 0, j;
1528
1529    if (!servlayoutp)
1530	return FALSE;
1531
1532    /*
1533     * which layout section is the active one?
1534     *
1535     * If there is a -layout command line option, use that one, otherwise
1536     * pick the first one.
1537     */
1538    from = X_DEFAULT;
1539    if (xf86LayoutName != NULL)
1540	from = X_CMDLINE;
1541    else if (default_layout) {
1542	xf86LayoutName = default_layout;
1543	from = X_CONFIG;
1544    }
1545    if (xf86LayoutName != NULL) {
1546	if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
1547	    xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
1548		    xf86LayoutName);
1549	    return FALSE;
1550	}
1551	conf_layout = l;
1552    }
1553    xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
1554    adjp = conf_layout->lay_adjacency_lst;
1555
1556    /*
1557     * we know that each screen is referenced exactly once on the left side
1558     * of a layout statement in the Layout section. So to allocate the right
1559     * size for the array we do a quick walk of the list to figure out how
1560     * many sections we have
1561     */
1562    while (adjp) {
1563        count++;
1564        adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
1565    }
1566
1567#ifdef DEBUG
1568    ErrorF("Found %d screens in the layout section %s",
1569           count, conf_layout->lay_identifier);
1570#endif
1571    if (!count) /* alloc enough storage even if no screen is specified */
1572        count = 1;
1573
1574    slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
1575    slp[count].screen = NULL;
1576    /*
1577     * now that we have storage, loop over the list again and fill in our
1578     * data structure; at this point we do not fill in the adjacency
1579     * information as it is not clear if we need it at all
1580     */
1581    adjp = conf_layout->lay_adjacency_lst;
1582    count = 0;
1583    while (adjp) {
1584        slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
1585	if (adjp->adj_scrnum < 0)
1586	    scrnum = count;
1587	else
1588	    scrnum = adjp->adj_scrnum;
1589	if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
1590			  X_CONFIG)) {
1591	    xfree(slp);
1592	    return FALSE;
1593	}
1594	slp[count].x = adjp->adj_x;
1595	slp[count].y = adjp->adj_y;
1596	slp[count].refname = adjp->adj_refscreen;
1597	switch (adjp->adj_where) {
1598	case CONF_ADJ_OBSOLETE:
1599	    slp[count].where = PosObsolete;
1600	    slp[count].topname = adjp->adj_top_str;
1601	    slp[count].bottomname = adjp->adj_bottom_str;
1602	    slp[count].leftname = adjp->adj_left_str;
1603	    slp[count].rightname = adjp->adj_right_str;
1604	    break;
1605	case CONF_ADJ_ABSOLUTE:
1606	    slp[count].where = PosAbsolute;
1607	    break;
1608	case CONF_ADJ_RIGHTOF:
1609	    slp[count].where = PosRightOf;
1610	    break;
1611	case CONF_ADJ_LEFTOF:
1612	    slp[count].where = PosLeftOf;
1613	    break;
1614	case CONF_ADJ_ABOVE:
1615	    slp[count].where = PosAbove;
1616	    break;
1617	case CONF_ADJ_BELOW:
1618	    slp[count].where = PosBelow;
1619	    break;
1620	case CONF_ADJ_RELATIVE:
1621	    slp[count].where = PosRelative;
1622	    break;
1623	}
1624        count++;
1625        adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
1626    }
1627
1628    /* No screen was specified in the layout. take the first one from the
1629     * config file, or - if it is NULL - configScreen autogenerates one for
1630     * us */
1631    if (!count)
1632    {
1633        slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1634	if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
1635                          0, X_CONFIG)) {
1636	    xfree(slp[0].screen);
1637	    xfree(slp);
1638	    return FALSE;
1639	}
1640    }
1641
1642    /* XXX Need to tie down the upper left screen. */
1643
1644    /* Fill in the refscreen and top/bottom/left/right values */
1645    for (i = 0; i < count; i++) {
1646	for (j = 0; j < count; j++) {
1647	    if (slp[i].refname &&
1648		strcmp(slp[i].refname, slp[j].screen->id) == 0) {
1649		slp[i].refscreen = slp[j].screen;
1650	    }
1651	    if (slp[i].topname &&
1652		strcmp(slp[i].topname, slp[j].screen->id) == 0) {
1653		slp[i].top = slp[j].screen;
1654	    }
1655	    if (slp[i].bottomname &&
1656		strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
1657		slp[i].bottom = slp[j].screen;
1658	    }
1659	    if (slp[i].leftname &&
1660		strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
1661		slp[i].left = slp[j].screen;
1662	    }
1663	    if (slp[i].rightname &&
1664		strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
1665		slp[i].right = slp[j].screen;
1666	    }
1667	}
1668	if (slp[i].where != PosObsolete
1669	    && slp[i].where != PosAbsolute
1670	    && !slp[i].refscreen) {
1671	    xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
1672		     slp[i].refname);
1673	    slp[i].where = PosAbsolute;
1674	    slp[i].x = 0;
1675	    slp[i].y = 0;
1676	}
1677    }
1678
1679#ifdef LAYOUT_DEBUG
1680    ErrorF("Layout \"%s\"\n", conf_layout->lay_identifier);
1681    for (i = 0; i < count; i++) {
1682	ErrorF("Screen: \"%s\" (%d):\n", slp[i].screen->id,
1683	       slp[i].screen->screennum);
1684	switch (slp[i].where) {
1685	case PosObsolete:
1686	    ErrorF("\tObsolete format: \"%s\" \"%s\" \"%s\" \"%s\"\n",
1687		   slp[i].top, slp[i].bottom, slp[i].left, slp[i].right);
1688	    break;
1689	case PosAbsolute:
1690	    if (slp[i].x == -1)
1691		if (slp[i].screen->screennum == 0)
1692		    ErrorF("\tImplicitly left-most\n");
1693		else
1694		    ErrorF("\tImplicitly right of screen %d\n",
1695			   slp[i].screen->screennum - 1);
1696	    else
1697		ErrorF("\t%d %d\n", slp[i].x, slp[i].y);
1698	    break;
1699	case PosRightOf:
1700	    ErrorF("\tRight of \"%s\"\n", slp[i].refscreen->id);
1701	    break;
1702	case PosLeftOf:
1703	    ErrorF("\tLeft of \"%s\"\n", slp[i].refscreen->id);
1704	    break;
1705	case PosAbove:
1706	    ErrorF("\tAbove \"%s\"\n", slp[i].refscreen->id);
1707	    break;
1708	case PosBelow:
1709	    ErrorF("\tBelow \"%s\"\n", slp[i].refscreen->id);
1710	    break;
1711	case PosRelative:
1712	    ErrorF("\t%d %d relative to \"%s\"\n", slp[i].x, slp[i].y,
1713		   slp[i].refscreen->id);
1714	    break;
1715	}
1716    }
1717#endif
1718    /*
1719     * Count the number of inactive devices.
1720     */
1721    count = 0;
1722    idp = conf_layout->lay_inactive_lst;
1723    while (idp) {
1724        count++;
1725        idp = (XF86ConfInactivePtr)idp->list.next;
1726    }
1727#ifdef DEBUG
1728    ErrorF("Found %d inactive devices in the layout section %s",
1729           count, conf_layout->lay_identifier);
1730#endif
1731    gdp = xnfalloc((count + 1) * sizeof(GDevRec));
1732    gdp[count].identifier = NULL;
1733    idp = conf_layout->lay_inactive_lst;
1734    count = 0;
1735    while (idp) {
1736	if (!configDevice(&gdp[count], idp->inactive_device, FALSE)) {
1737	    xfree(gdp);
1738	    return FALSE;
1739	}
1740        count++;
1741        idp = (XF86ConfInactivePtr)idp->list.next;
1742    }
1743    /*
1744     * Count the number of input devices.
1745     */
1746    count = 0;
1747    irp = conf_layout->lay_input_lst;
1748    while (irp) {
1749        count++;
1750        irp = (XF86ConfInputrefPtr)irp->list.next;
1751    }
1752#ifdef DEBUG
1753    ErrorF("Found %d input devices in the layout section %s",
1754           count, conf_layout->lay_identifier);
1755#endif
1756    indp = xnfcalloc((count + 1), sizeof(IDevPtr));
1757    indp[count] = NULL;
1758    irp = conf_layout->lay_input_lst;
1759    count = 0;
1760    while (irp) {
1761        indp[count] = xnfalloc(sizeof(IDevRec));
1762	if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
1763            while(count--)
1764                xfree(indp[count]);
1765            xfree(indp);
1766            return FALSE;
1767	}
1768	indp[count]->extraOptions = irp->iref_option_lst;
1769        count++;
1770        irp = (XF86ConfInputrefPtr)irp->list.next;
1771    }
1772    servlayoutp->id = conf_layout->lay_identifier;
1773    servlayoutp->screens = slp;
1774    servlayoutp->inactives = gdp;
1775    servlayoutp->inputs = indp;
1776    servlayoutp->options = conf_layout->lay_option_lst;
1777    from = X_DEFAULT;
1778
1779    return TRUE;
1780}
1781
1782/*
1783 * No layout section, so find the first Screen section and set that up as
1784 * the only active screen.
1785 */
1786static Bool
1787configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen)
1788{
1789    MessageType from;
1790    XF86ConfScreenPtr s;
1791    screenLayoutPtr slp;
1792    IDevPtr *indp;
1793
1794    if (!servlayoutp)
1795	return FALSE;
1796
1797    /*
1798     * which screen section is the active one?
1799     *
1800     * If there is a -screen option, use that one, otherwise use the first
1801     * one.
1802     */
1803
1804    from = X_CONFIG;
1805    if (xf86ScreenName != NULL) {
1806	if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
1807	    xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
1808		    xf86ScreenName);
1809	    return FALSE;
1810	}
1811	conf_screen = s;
1812	from = X_CMDLINE;
1813    }
1814
1815    /* We have exactly one screen */
1816
1817    slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
1818    slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1819    slp[1].screen = NULL;
1820    if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
1821	xfree(slp);
1822	return FALSE;
1823    }
1824    servlayoutp->id = "(implicit)";
1825    servlayoutp->screens = slp;
1826    servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
1827    servlayoutp->options = NULL;
1828    /* Set up an empty input device list, then look for some core devices. */
1829    indp = xnfalloc(sizeof(IDevPtr));
1830    *indp = NULL;
1831    servlayoutp->inputs = indp;
1832
1833    return TRUE;
1834}
1835
1836static Bool
1837configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
1838{
1839    int count = 0;
1840    XF86ConfVideoPortPtr conf_port;
1841
1842    xf86Msg(X_CONFIG, "|   |-->VideoAdaptor \"%s\"\n",
1843	    conf_adaptor->va_identifier);
1844    adaptor->identifier = conf_adaptor->va_identifier;
1845    adaptor->options = conf_adaptor->va_option_lst;
1846    if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
1847	xf86Msg(X_CONFIG, "|   | Unsupported device type, skipping entry\n");
1848	return FALSE;
1849    }
1850
1851    /*
1852     * figure out how many videoport subsections there are and fill them in
1853     */
1854    conf_port = conf_adaptor->va_port_lst;
1855    while(conf_port) {
1856        count++;
1857        conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
1858    }
1859    adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
1860    adaptor->numports = count;
1861    count = 0;
1862    conf_port = conf_adaptor->va_port_lst;
1863    while(conf_port) {
1864	adaptor->ports[count].identifier = conf_port->vp_identifier;
1865	adaptor->ports[count].options = conf_port->vp_option_lst;
1866        count++;
1867        conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
1868    }
1869
1870    return TRUE;
1871}
1872
1873static Bool
1874configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
1875	     MessageType from)
1876{
1877    int count = 0;
1878    XF86ConfDisplayPtr dispptr;
1879    XF86ConfAdaptorLinkPtr conf_adaptor;
1880    Bool defaultMonitor = FALSE;
1881
1882    if (!conf_screen) {
1883        conf_screen = xnfcalloc(1, sizeof(XF86ConfScreenRec));
1884        conf_screen->scrn_identifier = "Default Screen Section";
1885        xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
1886    }
1887
1888    xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
1889	    scrnum);
1890    /*
1891     * now we fill in the elements of the screen
1892     */
1893    screenp->id         = conf_screen->scrn_identifier;
1894    screenp->screennum  = scrnum;
1895    screenp->defaultdepth = conf_screen->scrn_defaultdepth;
1896    screenp->defaultbpp = conf_screen->scrn_defaultbpp;
1897    screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
1898    screenp->monitor    = xnfcalloc(1, sizeof(MonRec));
1899    /* If no monitor is specified, create a default one. */
1900    if (!conf_screen->scrn_monitor) {
1901	XF86ConfMonitorRec defMon;
1902
1903	bzero(&defMon, sizeof(defMon));
1904	defMon.mon_identifier = "<default monitor>";
1905	/*
1906	 * TARGET_REFRESH_RATE may be defined to effectively limit the
1907	 * default resolution to the largest that has a "good" refresh
1908	 * rate.
1909	 */
1910#ifdef TARGET_REFRESH_RATE
1911	defMon.mon_option_lst = xf86ReplaceRealOption(defMon.mon_option_lst,
1912						      "TargetRefresh",
1913						      TARGET_REFRESH_RATE);
1914#endif
1915	if (!configMonitor(screenp->monitor, &defMon))
1916	    return FALSE;
1917	defaultMonitor = TRUE;
1918    } else {
1919	if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
1920	    return FALSE;
1921    }
1922    /* Configure the device. If there isn't one configured, attach to the
1923     * first inactive one that we can configure. If there's none that work,
1924     * set it to NULL so that the section can be autoconfigured later */
1925    screenp->device     = xnfcalloc(1, sizeof(GDevRec));
1926    if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
1927        conf_screen->scrn_device = xf86configptr->conf_device_lst;
1928	xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
1929		"\tUsing the first device section listed.\n", screenp->id);
1930    }
1931    if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
1932        screenp->device->myScreenSection = screenp;
1933    } else {
1934        screenp->device = NULL;
1935    }
1936    screenp->options = conf_screen->scrn_option_lst;
1937
1938    /*
1939     * figure out how many display subsections there are and fill them in
1940     */
1941    dispptr = conf_screen->scrn_display_lst;
1942    while(dispptr) {
1943        count++;
1944        dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
1945    }
1946    screenp->displays   = xnfalloc((count) * sizeof(DispRec));
1947    screenp->numdisplays = count;
1948
1949    /* Fill in the default Virtual size, if any */
1950    if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
1951	for (count = 0, dispptr = conf_screen->scrn_display_lst;
1952	     dispptr;
1953	     dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
1954	    screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
1955	    screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
1956	}
1957    }
1958
1959    /* Now do the per-Display Virtual sizes */
1960    count = 0;
1961    dispptr = conf_screen->scrn_display_lst;
1962    while(dispptr) {
1963        configDisplay(&(screenp->displays[count]),dispptr);
1964        count++;
1965        dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
1966    }
1967
1968    /*
1969     * figure out how many videoadaptor references there are and fill them in
1970     */
1971    conf_adaptor = conf_screen->scrn_adaptor_lst;
1972    while(conf_adaptor) {
1973        count++;
1974        conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
1975    }
1976    screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
1977    screenp->numxvadaptors = 0;
1978    conf_adaptor = conf_screen->scrn_adaptor_lst;
1979    while(conf_adaptor) {
1980        if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
1981			    conf_adaptor->al_adaptor))
1982    	    screenp->numxvadaptors++;
1983        conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
1984    }
1985
1986    if (defaultMonitor) {
1987	xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
1988		"\tUsing a default monitor configuration.\n", screenp->id);
1989    }
1990    return TRUE;
1991}
1992
1993typedef enum {
1994    MON_REDUCEDBLANKING,
1995    MON_MAX_PIX_CLOCK,
1996} MonitorValues;
1997
1998static OptionInfoRec MonitorOptions[] = {
1999  { MON_REDUCEDBLANKING,      "ReducedBlanking",        OPTV_BOOLEAN,
2000       {0}, FALSE },
2001  { MON_MAX_PIX_CLOCK,	      "MaxPixClock",		OPTV_FREQ,
2002       {0}, FALSE },
2003  { -1,                                NULL,                   OPTV_NONE,
2004       {0}, FALSE },
2005};
2006
2007static Bool
2008configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
2009{
2010    int count;
2011    DisplayModePtr mode,last = NULL;
2012    XF86ConfModeLinePtr cmodep;
2013    XF86ConfModesPtr modes;
2014    XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
2015    Gamma zeros = {0.0, 0.0, 0.0};
2016    float badgamma = 0.0;
2017    double maxPixClock;
2018
2019    xf86Msg(X_CONFIG, "|   |-->Monitor \"%s\"\n",
2020	    conf_monitor->mon_identifier);
2021    monitorp->id = conf_monitor->mon_identifier;
2022    monitorp->vendor = conf_monitor->mon_vendor;
2023    monitorp->model = conf_monitor->mon_modelname;
2024    monitorp->Modes = NULL;
2025    monitorp->Last = NULL;
2026    monitorp->gamma = zeros;
2027    monitorp->widthmm = conf_monitor->mon_width;
2028    monitorp->heightmm = conf_monitor->mon_height;
2029    monitorp->reducedblanking = FALSE;
2030    monitorp->maxPixClock = 0;
2031    monitorp->options = conf_monitor->mon_option_lst;
2032
2033    /*
2034     * fill in the monitor structure
2035     */
2036    for( count = 0 ;
2037	 count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
2038	 count++) {
2039        monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
2040        monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
2041    }
2042    monitorp->nHsync = count;
2043    for( count = 0 ;
2044	 count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
2045	 count++) {
2046        monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
2047        monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
2048    }
2049    monitorp->nVrefresh = count;
2050
2051    /*
2052     * first we collect the mode lines from the UseModes directive
2053     */
2054    while(modeslnk)
2055    {
2056        modes = xf86findModes (modeslnk->ml_modes_str,
2057			       xf86configptr->conf_modes_lst);
2058	modeslnk->ml_modes = modes;
2059
2060
2061	/* now add the modes found in the modes
2062	   section to the list of modes for this
2063	   monitor unless it has been added before
2064	   because we are reusing the same section
2065	   for another screen */
2066	if (xf86itemNotSublist(
2067			       (GenericListPtr)conf_monitor->mon_modeline_lst,
2068			       (GenericListPtr)modes->mon_modeline_lst)) {
2069	    conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
2070	        xf86addListItem(
2071				(GenericListPtr)conf_monitor->mon_modeline_lst,
2072				(GenericListPtr)modes->mon_modeline_lst);
2073	}
2074	modeslnk = modeslnk->list.next;
2075    }
2076
2077    /*
2078     * we need to hook in the mode lines now
2079     * here both data structures use lists, only our internal one
2080     * is double linked
2081     */
2082    cmodep = conf_monitor->mon_modeline_lst;
2083    while( cmodep ) {
2084        mode = xnfcalloc(1, sizeof(DisplayModeRec));
2085	mode->type       = 0;
2086        mode->Clock      = cmodep->ml_clock;
2087        mode->HDisplay   = cmodep->ml_hdisplay;
2088        mode->HSyncStart = cmodep->ml_hsyncstart;
2089        mode->HSyncEnd   = cmodep->ml_hsyncend;
2090        mode->HTotal     = cmodep->ml_htotal;
2091        mode->VDisplay   = cmodep->ml_vdisplay;
2092        mode->VSyncStart = cmodep->ml_vsyncstart;
2093        mode->VSyncEnd   = cmodep->ml_vsyncend;
2094        mode->VTotal     = cmodep->ml_vtotal;
2095        mode->Flags      = cmodep->ml_flags;
2096        mode->HSkew      = cmodep->ml_hskew;
2097        mode->VScan      = cmodep->ml_vscan;
2098        mode->name       = xnfstrdup(cmodep->ml_identifier);
2099        if( last ) {
2100            mode->prev = last;
2101            last->next = mode;
2102        }
2103        else {
2104            /*
2105             * this is the first mode
2106             */
2107            monitorp->Modes = mode;
2108            mode->prev = NULL;
2109        }
2110        last = mode;
2111        cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
2112    }
2113    if(last){
2114      last->next = NULL;
2115    }
2116    monitorp->Last = last;
2117
2118    /* add the (VESA) default modes */
2119    if (! addDefaultModes(monitorp) )
2120	return FALSE;
2121
2122    if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
2123	monitorp->gamma.red = conf_monitor->mon_gamma_red;
2124    if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
2125	monitorp->gamma.green = conf_monitor->mon_gamma_green;
2126    if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
2127	monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
2128
2129    /* Check that the gamma values are within range */
2130    if (monitorp->gamma.red > GAMMA_ZERO &&
2131	(monitorp->gamma.red < GAMMA_MIN ||
2132	 monitorp->gamma.red > GAMMA_MAX)) {
2133	badgamma = monitorp->gamma.red;
2134    } else if (monitorp->gamma.green > GAMMA_ZERO &&
2135	(monitorp->gamma.green < GAMMA_MIN ||
2136	 monitorp->gamma.green > GAMMA_MAX)) {
2137	badgamma = monitorp->gamma.green;
2138    } else if (monitorp->gamma.blue > GAMMA_ZERO &&
2139	(monitorp->gamma.blue < GAMMA_MIN ||
2140	 monitorp->gamma.blue > GAMMA_MAX)) {
2141	badgamma = monitorp->gamma.blue;
2142    }
2143    if (badgamma > GAMMA_ZERO) {
2144	xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
2145			badgamma, GAMMA_MIN, GAMMA_MAX);
2146	    return FALSE;
2147    }
2148
2149    xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
2150    xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
2151                      &monitorp->reducedblanking);
2152    if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
2153			  &maxPixClock) == TRUE) {
2154	monitorp->maxPixClock = (int) maxPixClock;
2155    }
2156
2157    return TRUE;
2158}
2159
2160static int
2161lookupVisual(const char *visname)
2162{
2163    int i;
2164
2165    if (!visname || !*visname)
2166	return -1;
2167
2168    for (i = 0; i <= DirectColor; i++) {
2169	if (!xf86nameCompare(visname, xf86VisualNames[i]))
2170	    break;
2171    }
2172
2173    if (i <= DirectColor)
2174	return i;
2175
2176    return -1;
2177}
2178
2179
2180static Bool
2181configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
2182{
2183    int count = 0;
2184    XF86ModePtr modep;
2185
2186    displayp->frameX0           = conf_display->disp_frameX0;
2187    displayp->frameY0           = conf_display->disp_frameY0;
2188    displayp->virtualX          = conf_display->disp_virtualX;
2189    displayp->virtualY          = conf_display->disp_virtualY;
2190    displayp->depth             = conf_display->disp_depth;
2191    displayp->fbbpp             = conf_display->disp_bpp;
2192    displayp->weight.red        = conf_display->disp_weight.red;
2193    displayp->weight.green      = conf_display->disp_weight.green;
2194    displayp->weight.blue       = conf_display->disp_weight.blue;
2195    displayp->blackColour.red   = conf_display->disp_black.red;
2196    displayp->blackColour.green = conf_display->disp_black.green;
2197    displayp->blackColour.blue  = conf_display->disp_black.blue;
2198    displayp->whiteColour.red   = conf_display->disp_white.red;
2199    displayp->whiteColour.green = conf_display->disp_white.green;
2200    displayp->whiteColour.blue  = conf_display->disp_white.blue;
2201    displayp->options           = conf_display->disp_option_lst;
2202    if (conf_display->disp_visual) {
2203	displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
2204	if (displayp->defaultVisual == -1) {
2205	    xf86ConfigError("Invalid visual name: \"%s\"",
2206			    conf_display->disp_visual);
2207	    return FALSE;
2208	}
2209    } else {
2210	displayp->defaultVisual = -1;
2211    }
2212
2213    /*
2214     * now hook in the modes
2215     */
2216    modep = conf_display->disp_mode_lst;
2217    while(modep) {
2218        count++;
2219        modep = (XF86ModePtr)modep->list.next;
2220    }
2221    displayp->modes = xnfalloc((count+1) * sizeof(char*));
2222    modep = conf_display->disp_mode_lst;
2223    count = 0;
2224    while(modep) {
2225        displayp->modes[count] = modep->mode_name;
2226        count++;
2227        modep = (XF86ModePtr)modep->list.next;
2228    }
2229    displayp->modes[count] = NULL;
2230
2231    return TRUE;
2232}
2233
2234static Bool
2235configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
2236{
2237    int i;
2238
2239    if (!conf_device) {
2240        return FALSE;
2241    }
2242
2243    if (active)
2244	xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
2245		conf_device->dev_identifier);
2246    else
2247	xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
2248		conf_device->dev_identifier);
2249
2250    devicep->identifier = conf_device->dev_identifier;
2251    devicep->vendor = conf_device->dev_vendor;
2252    devicep->board = conf_device->dev_board;
2253    devicep->chipset = conf_device->dev_chipset;
2254    devicep->ramdac = conf_device->dev_ramdac;
2255    devicep->driver = conf_device->dev_driver;
2256    devicep->active = active;
2257    devicep->videoRam = conf_device->dev_videoram;
2258    devicep->BiosBase = conf_device->dev_bios_base;
2259    devicep->MemBase = conf_device->dev_mem_base;
2260    devicep->IOBase = conf_device->dev_io_base;
2261    devicep->clockchip = conf_device->dev_clockchip;
2262    devicep->busID = conf_device->dev_busid;
2263    devicep->textClockFreq = conf_device->dev_textclockfreq;
2264    devicep->chipID = conf_device->dev_chipid;
2265    devicep->chipRev = conf_device->dev_chiprev;
2266    devicep->options = conf_device->dev_option_lst;
2267    devicep->irq = conf_device->dev_irq;
2268    devicep->screen = conf_device->dev_screen;
2269
2270    for (i = 0; i < MAXDACSPEEDS; i++) {
2271	if (i < CONF_MAXDACSPEEDS)
2272            devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
2273	else
2274	    devicep->dacSpeeds[i] = 0;
2275    }
2276    devicep->numclocks = conf_device->dev_clocks;
2277    if (devicep->numclocks > MAXCLOCKS)
2278	devicep->numclocks = MAXCLOCKS;
2279    for (i = 0; i < devicep->numclocks; i++) {
2280	devicep->clock[i] = conf_device->dev_clock[i];
2281    }
2282    devicep->claimed = FALSE;
2283
2284    return TRUE;
2285}
2286
2287#ifdef XF86DRI
2288static void
2289configDRI(XF86ConfDRIPtr drip)
2290{
2291    int                count = 0;
2292    XF86ConfBuffersPtr bufs;
2293    int                i;
2294    struct group       *grp;
2295
2296    xf86ConfigDRI.group      = -1;
2297    xf86ConfigDRI.mode       = 0;
2298    xf86ConfigDRI.bufs_count = 0;
2299    xf86ConfigDRI.bufs       = NULL;
2300
2301    if (drip) {
2302	if (drip->dri_group_name) {
2303	    if ((grp = getgrnam(drip->dri_group_name)))
2304		xf86ConfigDRI.group = grp->gr_gid;
2305	} else {
2306	    if (drip->dri_group >= 0)
2307		xf86ConfigDRI.group = drip->dri_group;
2308	}
2309	xf86ConfigDRI.mode = drip->dri_mode;
2310	for (bufs = drip->dri_buffers_lst; bufs; bufs = bufs->list.next)
2311	    ++count;
2312
2313	xf86ConfigDRI.bufs_count = count;
2314	xf86ConfigDRI.bufs = xnfalloc(count * sizeof(*xf86ConfigDRI.bufs));
2315
2316	for (i = 0, bufs = drip->dri_buffers_lst;
2317	     i < count;
2318	     i++, bufs = bufs->list.next) {
2319
2320	    xf86ConfigDRI.bufs[i].count = bufs->buf_count;
2321	    xf86ConfigDRI.bufs[i].size  = bufs->buf_size;
2322				/* FIXME: Flags not implemented.  These
2323                                   could be used, for example, to specify a
2324                                   contiguous block and/or write-combining
2325                                   cache policy. */
2326	    xf86ConfigDRI.bufs[i].flags = 0;
2327	}
2328    }
2329}
2330#endif
2331
2332static void
2333configExtensions(XF86ConfExtensionsPtr conf_ext)
2334{
2335    XF86OptionPtr o;
2336
2337    if (conf_ext && conf_ext->ext_option_lst) {
2338	for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
2339	    char *name   = xf86OptionName(o);
2340	    char *val    = xf86OptionValue(o);
2341	    char *n;
2342	    Bool  enable = TRUE;
2343
2344	    /* Handle "No<ExtensionName>" */
2345	    n = xf86NormalizeName(name);
2346	    if (strncmp(n, "no", 2) == 0) {
2347		name += 2;
2348		enable = FALSE;
2349	    }
2350
2351	    if (!val ||
2352		xf86NameCmp(val, "enable") == 0 ||
2353		xf86NameCmp(val, "enabled") == 0 ||
2354		xf86NameCmp(val, "on") == 0 ||
2355		xf86NameCmp(val, "1") == 0 ||
2356		xf86NameCmp(val, "yes") == 0 ||
2357		xf86NameCmp(val, "true") == 0) {
2358		/* NOTHING NEEDED -- enabling is handled below */
2359	    } else if (xf86NameCmp(val, "disable") == 0 ||
2360                       xf86NameCmp(val, "disabled") == 0 ||
2361		       xf86NameCmp(val, "off") == 0 ||
2362		       xf86NameCmp(val, "0") == 0 ||
2363		       xf86NameCmp(val, "no") == 0 ||
2364		       xf86NameCmp(val, "false") == 0) {
2365		enable = !enable;
2366	    } else {
2367		xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
2368		xfree(n);
2369		continue;
2370	    }
2371
2372	    if (EnableDisableExtension(name, enable)) {
2373		xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
2374			name, enable ? "enabled" : "disabled");
2375	    } else {
2376		xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
2377                        name);
2378	    }
2379	    xfree(n);
2380	}
2381    }
2382}
2383
2384static Bool
2385configInput(IDevPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
2386{
2387    xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
2388    inputp->identifier = conf_input->inp_identifier;
2389    inputp->driver = conf_input->inp_driver;
2390    inputp->commonOptions = conf_input->inp_option_lst;
2391    inputp->extraOptions = NULL;
2392
2393    return TRUE;
2394}
2395
2396static Bool
2397modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
2398{
2399    DisplayModePtr knownmodes = monitorp->Modes;
2400
2401    /* all I can think of is a linear search... */
2402    while(knownmodes != NULL)
2403    {
2404	if(!strcmp(mode->name, knownmodes->name) &&
2405	   !(knownmodes->type & M_T_DEFAULT))
2406	    return TRUE;
2407	knownmodes = knownmodes->next;
2408    }
2409    return FALSE;
2410}
2411
2412static Bool
2413addDefaultModes(MonPtr monitorp)
2414{
2415    DisplayModePtr mode;
2416    DisplayModePtr last = monitorp->Last;
2417    int i = 0;
2418
2419    for (i = 0; i < xf86NumDefaultModes; i++)
2420    {
2421	mode = xf86DuplicateMode(&xf86DefaultModes[i]);
2422	if (!modeIsPresent(mode, monitorp))
2423	{
2424	    monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
2425	    last = mode;
2426	} else {
2427	    xfree(mode);
2428	}
2429    }
2430    monitorp->Last = last;
2431
2432    return TRUE;
2433}
2434
2435static void
2436checkInput(serverLayoutPtr layout, Bool implicit_layout) {
2437    checkCoreInputDevices(layout, implicit_layout);
2438
2439    /* AllowEmptyInput and the "kbd" and "mouse" drivers are mutually
2440     * exclusive. Trawl the list for mouse/kbd devices and disable them.
2441     */
2442    if (xf86Info.allowEmptyInput && layout->inputs)
2443    {
2444        IDevPtr *dev = layout->inputs;
2445        BOOL warned = FALSE;
2446
2447        while(*dev)
2448        {
2449            if (strcmp((*dev)->driver, "kbd") == 0 ||
2450                strcmp((*dev)->driver, "mouse") == 0 ||
2451                strcmp((*dev)->driver, "vmmouse") == 0)
2452            {
2453                IDevPtr *current;
2454                if (!warned)
2455                {
2456                    xf86Msg(X_WARNING, "AllowEmptyInput is on, devices using "
2457                            "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
2458                    warned = TRUE;
2459                }
2460
2461                xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->identifier);
2462
2463                current = dev;
2464                xfree(*dev);
2465
2466                do {
2467                    *current = *(current + 1);
2468                    current++;
2469                } while(*current);
2470            } else
2471                dev++;
2472        }
2473    }
2474}
2475
2476/*
2477 * load the config file and fill the global data structure
2478 */
2479ConfigStatus
2480xf86HandleConfigFile(Bool autoconfig)
2481{
2482    const char *filename;
2483    char *searchpath;
2484    MessageType from = X_DEFAULT;
2485    char *scanptr;
2486    Bool singlecard = 0;
2487    Bool implicit_layout = FALSE;
2488
2489    if (!autoconfig) {
2490	if (getuid() == 0)
2491	    searchpath = ROOT_CONFIGPATH;
2492	else
2493	    searchpath = USER_CONFIGPATH;
2494
2495	if (xf86ConfigFile)
2496	    from = X_CMDLINE;
2497
2498	filename = xf86openConfigFile(searchpath, xf86ConfigFile, PROJECTROOT);
2499	if (filename) {
2500	    xf86MsgVerb(from, 0, "Using config file: \"%s\"\n", filename);
2501	    xf86ConfigFile = xnfstrdup(filename);
2502	} else {
2503	    if (xf86ConfigFile)
2504		xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
2505			xf86ConfigFile);
2506	    return CONFIG_NOFILE;
2507	}
2508    }
2509
2510    if ((xf86configptr = xf86readConfigFile ()) == NULL) {
2511	xf86Msg(X_ERROR, "Problem parsing the config file\n");
2512	return CONFIG_PARSE_ERROR;
2513    }
2514    xf86closeConfigFile ();
2515
2516    /* Initialise a few things. */
2517
2518    /*
2519     * now we convert part of the information contained in the parser
2520     * structures into our own structures.
2521     * The important part here is to figure out which Screen Sections
2522     * in the XF86Config file are active so that we can piece together
2523     * the modes that we need later down the road.
2524     * And while we are at it, we'll decode the rest of the stuff as well
2525     */
2526
2527    /* First check if a layout section is present, and if it is valid. */
2528
2529    if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
2530	if (xf86ScreenName == NULL) {
2531	    xf86Msg(X_DEFAULT,
2532		    "No Layout section.  Using the first Screen section.\n");
2533	}
2534	if (!configImpliedLayout(&xf86ConfigLayout,
2535				 xf86configptr->conf_screen_lst)) {
2536            xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2537	    return CONFIG_PARSE_ERROR;
2538	}
2539	implicit_layout = TRUE;
2540    } else {
2541	if (xf86configptr->conf_flags != NULL) {
2542	  char *dfltlayout = NULL;
2543 	  pointer optlist = xf86configptr->conf_flags->flg_option_lst;
2544
2545	  if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
2546	    dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
2547	  if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
2548			  dfltlayout)) {
2549	    xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2550	    return CONFIG_PARSE_ERROR;
2551	  }
2552	} else {
2553	  if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
2554			  NULL)) {
2555	    xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2556	    return CONFIG_PARSE_ERROR;
2557	  }
2558	}
2559    }
2560
2561    xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
2562
2563    if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
2564       ; /* IsolateDevice specified; overrides SingleCard */
2565    } else {
2566       xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
2567       if (singlecard)
2568           scanptr = xf86ConfigLayout.screens->screen->device->busID;
2569    }
2570    if (scanptr) {
2571       int bus, device, func;
2572       if (strncmp(scanptr, "PCI:", 4) != 0) {
2573           xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
2574                              "\tIgnoring IsolateDevice option.\n");
2575       } else if (sscanf(scanptr, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
2576           xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
2577           xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
2578           xf86IsolateDevice.dev = device;
2579           xf86IsolateDevice.func = func;
2580           xf86Msg(X_INFO,
2581                   "Isolating PCI bus \"%d:%d:%d\"\n", bus, device, func);
2582       }
2583    }
2584
2585    /* Now process everything else */
2586    if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
2587             ErrorF ("Problem when converting the config data structures\n");
2588             return CONFIG_PARSE_ERROR;
2589    }
2590
2591    configFiles(xf86configptr->conf_files);
2592    configExtensions(xf86configptr->conf_extensions);
2593#ifdef XF86DRI
2594    configDRI(xf86configptr->conf_dri);
2595#endif
2596
2597    checkInput(&xf86ConfigLayout, implicit_layout);
2598
2599    /*
2600     * Handle some command line options that can override some of the
2601     * ServerFlags settings.
2602     */
2603#ifdef XF86VIDMODE
2604    if (xf86VidModeDisabled)
2605	xf86Info.vidModeEnabled = FALSE;
2606    if (xf86VidModeAllowNonLocal)
2607	xf86Info.vidModeAllowNonLocal = TRUE;
2608#endif
2609
2610    if (xf86AllowMouseOpenFail)
2611	xf86Info.allowMouseOpenFail = TRUE;
2612
2613    return CONFIG_OK;
2614}
2615
2616Bool
2617xf86PathIsSafe(const char *path)
2618{
2619    return (xf86pathIsSafe(path) != 0);
2620}
2621