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