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