Imported Debian patch 1.11.4-0ubuntu3
[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             Pointer->options = xf86AddNewOption(Pointer->options,
1243                                                 "driver", confInput->inp_driver);
1244             Pointer->options = xf86AddNewOption(Pointer->options,
1245                                                 "identifier", confInput->inp_identifier);
1246             servlayoutp->inputs = addDevice(servlayoutp->inputs, Pointer);
1247         }
1248     }
1249
1250     if (!foundPointer && xf86Info.forceInputDevices) {
1251         /* This shouldn't happen. */
1252         xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
1253         xf86DeleteInput(Pointer, 0);
1254         return FALSE;
1255     }
1256
1257     confInput = NULL;
1258
1259     /* 1. Check for the -keyboard command line option. */
1260     if (xf86KeyboardName) {
1261         confInput = xf86findInput(xf86KeyboardName,
1262                                   xf86configptr->conf_input_lst);
1263         if (!confInput) {
1264             xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1265                     xf86KeyboardName);
1266             return FALSE;
1267         }
1268         from = X_CMDLINE;
1269         /*
1270          * If one was already specified in the ServerLayout, it needs to be
1271          * removed.
1272          */
1273         if (coreKeyboard) {
1274             freeDevice(servlayoutp->inputs, coreKeyboard);
1275             coreKeyboard = NULL;
1276         }
1277         foundKeyboard = TRUE;
1278     }
1279
1280     /* 2. ServerLayout-specified core keyboard. */
1281     if (coreKeyboard) {
1282         foundKeyboard = TRUE;
1283         from = X_CONFIG;
1284     }
1285
1286     /* 3. First core keyboard device. */
1287     if (!foundKeyboard && (xf86Info.forceInputDevices || implicitLayout)) {
1288         XF86ConfInputPtr p;
1289
1290         for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1291             if (p->inp_option_lst &&
1292                 xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
1293                 confInput = p;
1294                 foundKeyboard = TRUE;
1295                 from = X_DEFAULT;
1296                 keyboardMsg = "first core keyboard device";
1297                 break;
1298             }
1299         }
1300     }
1301
1302     /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
1303     if (!foundKeyboard && xf86Info.forceInputDevices) {
1304         confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
1305                                   xf86configptr->conf_input_lst);
1306         if (!confInput) {
1307             confInput = xf86findInputByDriver("kbd",
1308                                               xf86configptr->conf_input_lst);
1309         }
1310         if (confInput) {
1311             foundKeyboard = TRUE;
1312             from = X_DEFAULT;
1313             keyboardMsg = "first keyboard device";
1314         }
1315     }
1316
1317     /* 5. Built-in default. */
1318     if (!foundKeyboard && xf86Info.forceInputDevices) {
1319         memset(&defKbd, 0, sizeof(defKbd));
1320         defKbd.inp_identifier = strdup("<default keyboard>");
1321         defKbd.inp_driver = strdup("kbd");
1322         confInput = &defKbd;
1323         foundKeyboard = TRUE;
1324         keyboardMsg = "default keyboard configuration";
1325         from = X_DEFAULT;
1326     }
1327
1328     /* Add the core keyboard device to the layout, and set it to Core. */
1329     if (foundKeyboard && confInput) {
1330         Keyboard = xf86AllocateInput();
1331         if (Keyboard)
1332             foundKeyboard = configInput(Keyboard, confInput, from);
1333         if (foundKeyboard) {
1334             Keyboard->options = xf86AddNewOption(Keyboard->options,
1335                                                  "CoreKeyboard", "on");
1336             Keyboard->options = xf86AddNewOption(Keyboard->options,
1337                                                  "driver", confInput->inp_driver);
1338             Keyboard->options = xf86AddNewOption(Keyboard->options,
1339                                                  "identifier", confInput->inp_identifier);
1340             servlayoutp->inputs = addDevice(servlayoutp->inputs, Keyboard);
1341         }
1342     }
1343
1344     if (!foundKeyboard && xf86Info.forceInputDevices) {
1345         /* This shouldn't happen. */
1346         xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
1347         xf86DeleteInput(Keyboard, 0);
1348         return FALSE;
1349     }
1350
1351     if (pointerMsg) {
1352         if (implicitLayout)
1353             xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1354                     pointerMsg);
1355         else
1356             xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
1357                     "explicitly in the layout.\n"
1358                     "\tUsing the %s.\n", pointerMsg);
1359     }
1360
1361     if (keyboardMsg) {
1362         if (implicitLayout)
1363             xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1364                     keyboardMsg);
1365         else
1366             xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
1367                     "explicitly in the layout.\n"
1368                     "\tUsing the %s.\n", keyboardMsg);
1369     }
1370
1371     if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) {
1372 #if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
1373         const char *config_backend;
1374 #if defined(CONFIG_HAL)
1375         config_backend = "HAL";
1376 #else
1377         config_backend = "udev";
1378 #endif
1379         xf86Msg(X_INFO, "The server relies on %s to provide the list of "
1380                         "input devices.\n\tIf no devices become available, "
1381                         "reconfigure %s or disable AutoAddDevices.\n",
1382                         config_backend, config_backend);
1383 #else
1384         xf86Msg(X_WARNING, "Hotplugging requested but the server was "
1385                            "compiled without a config backend. "
1386                            "No input devices were configured, the server "
1387                            "will start without any input devices.\n");
1388 #endif
1389     }
1390
1391     return TRUE;
1392 }
1393
1394 typedef enum {
1395     LAYOUT_ISOLATEDEVICE,
1396     LAYOUT_SINGLECARD
1397 } LayoutValues;
1398
1399 static OptionInfoRec LayoutOptions[] = {
1400   { LAYOUT_ISOLATEDEVICE,      "IsolateDevice",        OPTV_STRING,
1401        {0}, FALSE },
1402   { LAYOUT_SINGLECARD,         "SingleCard",           OPTV_BOOLEAN,
1403        {0}, FALSE },
1404   { -1,                                NULL,                   OPTV_NONE,
1405        {0}, FALSE },
1406 };
1407
1408 static Bool
1409 configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
1410 {
1411     XF86ConfInputrefPtr irp;
1412     InputInfoPtr *indp;
1413     int count = 0;
1414
1415     /*
1416      * Count the number of input devices.
1417      */
1418     irp = layout->lay_input_lst;
1419     while (irp) {
1420         count++;
1421         irp = (XF86ConfInputrefPtr)irp->list.next;
1422     }
1423     DebugF("Found %d input devices in the layout section %s\n",
1424             count, layout->lay_identifier);
1425     indp = xnfcalloc((count + 1), sizeof(InputInfoPtr));
1426     indp[count] = NULL;
1427     irp = layout->lay_input_lst;
1428     count = 0;
1429     while (irp) {
1430         indp[count] = xf86AllocateInput();
1431         if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
1432             do {
1433                 free(indp[count]);
1434             } while(count--);
1435             free(indp);
1436             return FALSE;
1437         }
1438         indp[count]->options = xf86OptionListMerge(indp[count]->options,
1439                                                    irp->iref_option_lst);
1440         count++;
1441         irp = (XF86ConfInputrefPtr)irp->list.next;
1442     }
1443     servlayoutp->inputs = indp;
1444
1445     return TRUE;
1446 }
1447
1448
1449 /*
1450  * figure out which layout is active, which screens are used in that layout,
1451  * which drivers and monitors are used in these screens
1452  */
1453 static Bool
1454 configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
1455              char *default_layout)
1456 {
1457     XF86ConfAdjacencyPtr adjp;
1458     XF86ConfInactivePtr idp;
1459     int saved_count, count = 0;
1460     int scrnum;
1461     XF86ConfLayoutPtr l;
1462     MessageType from;
1463     screenLayoutPtr slp;
1464     GDevPtr gdp;
1465     int i = 0, j;
1466
1467     if (!servlayoutp)
1468         return FALSE;
1469
1470     /*
1471      * which layout section is the active one?
1472      *
1473      * If there is a -layout command line option, use that one, otherwise
1474      * pick the first one.
1475      */
1476     from = X_DEFAULT;
1477     if (xf86LayoutName != NULL)
1478         from = X_CMDLINE;
1479     else if (default_layout) {
1480         xf86LayoutName = default_layout;
1481         from = X_CONFIG;
1482     }
1483     if (xf86LayoutName != NULL) {
1484         if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
1485             xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
1486                     xf86LayoutName);
1487             return FALSE;
1488         }
1489         conf_layout = l;
1490     }
1491     xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
1492     adjp = conf_layout->lay_adjacency_lst;
1493
1494     /*
1495      * we know that each screen is referenced exactly once on the left side
1496      * of a layout statement in the Layout section. So to allocate the right
1497      * size for the array we do a quick walk of the list to figure out how
1498      * many sections we have
1499      */
1500     while (adjp) {
1501         count++;
1502         adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
1503     }
1504
1505     DebugF("Found %d screens in the layout section %s",
1506            count, conf_layout->lay_identifier);
1507     if (!count) /* alloc enough storage even if no screen is specified */
1508         count = 1;
1509
1510     slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
1511     slp[count].screen = NULL;
1512     /*
1513      * now that we have storage, loop over the list again and fill in our
1514      * data structure; at this point we do not fill in the adjacency
1515      * information as it is not clear if we need it at all
1516      */
1517     adjp = conf_layout->lay_adjacency_lst;
1518     count = 0;
1519     while (adjp) {
1520         slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
1521         if (adjp->adj_scrnum < 0)
1522             scrnum = count;
1523         else
1524             scrnum = adjp->adj_scrnum;
1525         if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
1526                           X_CONFIG)) {
1527             do {
1528                 free(slp[count].screen);
1529             } while(count--);
1530             free(slp);
1531             return FALSE;
1532         }
1533         slp[count].x = adjp->adj_x;
1534         slp[count].y = adjp->adj_y;
1535         slp[count].refname = adjp->adj_refscreen;
1536         switch (adjp->adj_where) {
1537         case CONF_ADJ_OBSOLETE:
1538             slp[count].where = PosObsolete;
1539             slp[count].topname = adjp->adj_top_str;
1540             slp[count].bottomname = adjp->adj_bottom_str;
1541             slp[count].leftname = adjp->adj_left_str;
1542             slp[count].rightname = adjp->adj_right_str;
1543             break;
1544         case CONF_ADJ_ABSOLUTE:
1545             slp[count].where = PosAbsolute;
1546             break;
1547         case CONF_ADJ_RIGHTOF:
1548             slp[count].where = PosRightOf;
1549             break;
1550         case CONF_ADJ_LEFTOF:
1551             slp[count].where = PosLeftOf;
1552             break;
1553         case CONF_ADJ_ABOVE:
1554             slp[count].where = PosAbove;
1555             break;
1556         case CONF_ADJ_BELOW:
1557             slp[count].where = PosBelow;
1558             break;
1559         case CONF_ADJ_RELATIVE:
1560             slp[count].where = PosRelative;
1561             break;
1562         }
1563         count++;
1564         adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
1565     }
1566
1567     /* No screen was specified in the layout. take the first one from the
1568      * config file, or - if it is NULL - configScreen autogenerates one for
1569      * us */
1570     if (!count)
1571     {
1572         slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1573         if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
1574                           0, X_CONFIG)) {
1575             free(slp[0].screen);
1576             free(slp);
1577             return FALSE;
1578         }
1579     }
1580
1581     /* XXX Need to tie down the upper left screen. */
1582
1583     /* Fill in the refscreen and top/bottom/left/right values */
1584     for (i = 0; i < count; i++) {
1585         for (j = 0; j < count; j++) {
1586             if (slp[i].refname &&
1587                 strcmp(slp[i].refname, slp[j].screen->id) == 0) {
1588                 slp[i].refscreen = slp[j].screen;
1589             }
1590             if (slp[i].topname &&
1591                 strcmp(slp[i].topname, slp[j].screen->id) == 0) {
1592                 slp[i].top = slp[j].screen;
1593             }
1594             if (slp[i].bottomname &&
1595                 strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
1596                 slp[i].bottom = slp[j].screen;
1597             }
1598             if (slp[i].leftname &&
1599                 strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
1600                 slp[i].left = slp[j].screen;
1601             }
1602             if (slp[i].rightname &&
1603                 strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
1604                 slp[i].right = slp[j].screen;
1605             }
1606         }
1607         if (slp[i].where != PosObsolete
1608             && slp[i].where != PosAbsolute
1609             && !slp[i].refscreen) {
1610             xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
1611                      slp[i].refname);
1612             slp[i].where = PosAbsolute;
1613             slp[i].x = 0;
1614             slp[i].y = 0;
1615         }
1616     }
1617
1618     if (!count)
1619         saved_count = 1;
1620     else
1621         saved_count = count;
1622     /*
1623      * Count the number of inactive devices.
1624      */
1625     count = 0;
1626     idp = conf_layout->lay_inactive_lst;
1627     while (idp) {
1628         count++;
1629         idp = (XF86ConfInactivePtr)idp->list.next;
1630     }
1631     DebugF("Found %d inactive devices in the layout section %s\n",
1632            count, conf_layout->lay_identifier);
1633     gdp = xnfalloc((count + 1) * sizeof(GDevRec));
1634     gdp[count].identifier = NULL;
1635     idp = conf_layout->lay_inactive_lst;
1636     count = 0;
1637     while (idp) {
1638         if (!configDevice(&gdp[count], idp->inactive_device, FALSE))
1639             goto bail;
1640         count++;
1641         idp = (XF86ConfInactivePtr)idp->list.next;
1642     }
1643
1644     if (!configInputDevices(conf_layout, servlayoutp))
1645         goto bail;
1646
1647     servlayoutp->id = conf_layout->lay_identifier;
1648     servlayoutp->screens = slp;
1649     servlayoutp->inactives = gdp;
1650     servlayoutp->options = conf_layout->lay_option_lst;
1651     from = X_DEFAULT;
1652
1653     return TRUE;
1654
1655 bail:
1656     do {
1657         free(slp[saved_count].screen);
1658     } while(saved_count--);
1659     free(slp);
1660     free(gdp);
1661     return FALSE;
1662 }
1663
1664 /*
1665  * No layout section, so find the first Screen section and set that up as
1666  * the only active screen.
1667  */
1668 static Bool
1669 configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
1670                     XF86ConfigPtr xf86configptr)
1671 {
1672     MessageType from;
1673     XF86ConfScreenPtr s;
1674     screenLayoutPtr slp;
1675     InputInfoPtr *indp;
1676     XF86ConfLayoutRec layout;
1677
1678     if (!servlayoutp)
1679         return FALSE;
1680
1681     /*
1682      * which screen section is the active one?
1683      *
1684      * If there is a -screen option, use that one, otherwise use the first
1685      * one.
1686      */
1687
1688     from = X_CONFIG;
1689     if (xf86ScreenName != NULL) {
1690         if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
1691             xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
1692                     xf86ScreenName);
1693             return FALSE;
1694         }
1695         conf_screen = s;
1696         from = X_CMDLINE;
1697     }
1698
1699     /* We have exactly one screen */
1700
1701     slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
1702     slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1703     slp[1].screen = NULL;
1704     if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
1705         free(slp);
1706         return FALSE;
1707     }
1708     servlayoutp->id = "(implicit)";
1709     servlayoutp->screens = slp;
1710     servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
1711     servlayoutp->options = NULL;
1712
1713     memset(&layout, 0, sizeof(layout));
1714     layout.lay_identifier = servlayoutp->id;
1715     if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
1716         if (!configInputDevices(&layout, servlayoutp))
1717             return FALSE;
1718         from = X_DEFAULT;
1719     } else {
1720         /* Set up an empty input device list, then look for some core devices. */
1721         indp = xnfalloc(sizeof(InputInfoPtr));
1722         *indp = NULL;
1723         servlayoutp->inputs = indp;
1724     }
1725
1726     return TRUE;
1727 }
1728
1729 static Bool
1730 configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
1731 {
1732     int count = 0;
1733     XF86ConfVideoPortPtr conf_port;
1734
1735     xf86Msg(X_CONFIG, "|   |-->VideoAdaptor \"%s\"\n",
1736             conf_adaptor->va_identifier);
1737     adaptor->identifier = conf_adaptor->va_identifier;
1738     adaptor->options = conf_adaptor->va_option_lst;
1739     if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
1740         xf86Msg(X_CONFIG, "|   | Unsupported device type, skipping entry\n");
1741         return FALSE;
1742     }
1743
1744     /*
1745      * figure out how many videoport subsections there are and fill them in
1746      */
1747     conf_port = conf_adaptor->va_port_lst;
1748     while(conf_port) {
1749         count++;
1750         conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
1751     }
1752     adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
1753     adaptor->numports = count;
1754     count = 0;
1755     conf_port = conf_adaptor->va_port_lst;
1756     while(conf_port) {
1757         adaptor->ports[count].identifier = conf_port->vp_identifier;
1758         adaptor->ports[count].options = conf_port->vp_option_lst;
1759         count++;
1760         conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
1761     }
1762
1763     return TRUE;
1764 }
1765
1766 static Bool
1767 configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
1768              MessageType from)
1769 {
1770     int count = 0;
1771     XF86ConfDisplayPtr dispptr;
1772     XF86ConfAdaptorLinkPtr conf_adaptor;
1773     Bool defaultMonitor = FALSE;
1774     XF86ConfScreenRec local_conf_screen;
1775
1776     if (!conf_screen) {
1777         memset(&local_conf_screen, 0, sizeof(local_conf_screen));
1778         conf_screen = &local_conf_screen;
1779         conf_screen->scrn_identifier = "Default Screen Section";
1780         xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
1781     }
1782
1783     xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
1784             scrnum);
1785     /*
1786      * now we fill in the elements of the screen
1787      */
1788     screenp->id         = conf_screen->scrn_identifier;
1789     screenp->screennum  = scrnum;
1790     screenp->defaultdepth = conf_screen->scrn_defaultdepth;
1791     screenp->defaultbpp = conf_screen->scrn_defaultbpp;
1792     screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
1793     screenp->monitor    = xnfcalloc(1, sizeof(MonRec));
1794     /* If no monitor is specified, create a default one. */
1795     if (!conf_screen->scrn_monitor) {
1796         XF86ConfMonitorRec defMon;
1797
1798         memset(&defMon, 0, sizeof(defMon));
1799         defMon.mon_identifier = "<default monitor>";
1800         if (!configMonitor(screenp->monitor, &defMon))
1801             return FALSE;
1802         defaultMonitor = TRUE;
1803     } else {
1804         if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
1805             return FALSE;
1806     }
1807     /* Configure the device. If there isn't one configured, attach to the
1808      * first inactive one that we can configure. If there's none that work,
1809      * set it to NULL so that the section can be autoconfigured later */
1810     screenp->device     = xnfcalloc(1, sizeof(GDevRec));
1811     if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
1812         conf_screen->scrn_device = xf86configptr->conf_device_lst;
1813         xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
1814                 "\tUsing the first device section listed.\n", screenp->id);
1815     }
1816     if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
1817         screenp->device->myScreenSection = screenp;
1818     } else {
1819         screenp->device = NULL;
1820     }
1821     screenp->options = conf_screen->scrn_option_lst;
1822     
1823     /*
1824      * figure out how many display subsections there are and fill them in
1825      */
1826     dispptr = conf_screen->scrn_display_lst;
1827     while(dispptr) {
1828         count++;
1829         dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
1830     }
1831     screenp->displays   = xnfalloc((count) * sizeof(DispRec));
1832     screenp->numdisplays = count;
1833     
1834     /* Fill in the default Virtual size, if any */
1835     if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
1836         for (count = 0, dispptr = conf_screen->scrn_display_lst;
1837              dispptr;
1838              dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
1839             screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
1840             screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
1841         }
1842     }
1843
1844     /* Now do the per-Display Virtual sizes */
1845     count = 0;
1846     dispptr = conf_screen->scrn_display_lst;
1847     while(dispptr) {
1848         configDisplay(&(screenp->displays[count]),dispptr);
1849         count++;
1850         dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
1851     }
1852
1853     /*
1854      * figure out how many videoadaptor references there are and fill them in
1855      */
1856     conf_adaptor = conf_screen->scrn_adaptor_lst;
1857     while(conf_adaptor) {
1858         count++;
1859         conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
1860     }
1861     screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
1862     screenp->numxvadaptors = 0;
1863     conf_adaptor = conf_screen->scrn_adaptor_lst;
1864     while(conf_adaptor) {
1865         if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
1866                             conf_adaptor->al_adaptor))
1867             screenp->numxvadaptors++;
1868         conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
1869     }
1870
1871     if (defaultMonitor) {
1872         xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
1873                 "\tUsing a default monitor configuration.\n", screenp->id);
1874     }
1875     return TRUE;
1876 }
1877
1878 typedef enum {
1879     MON_REDUCEDBLANKING,
1880     MON_MAX_PIX_CLOCK,
1881 } MonitorValues;
1882
1883 static OptionInfoRec MonitorOptions[] = {
1884   { MON_REDUCEDBLANKING,      "ReducedBlanking",        OPTV_BOOLEAN,
1885        {0}, FALSE },
1886   { MON_MAX_PIX_CLOCK,        "MaxPixClock",            OPTV_FREQ,
1887        {0}, FALSE },
1888   { -1,                                NULL,                   OPTV_NONE,
1889        {0}, FALSE },
1890 };
1891
1892 static Bool
1893 configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
1894 {
1895     int count;
1896     DisplayModePtr mode,last = NULL;
1897     XF86ConfModeLinePtr cmodep;
1898     XF86ConfModesPtr modes;
1899     XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
1900     Gamma zeros = {0.0, 0.0, 0.0};
1901     float badgamma = 0.0;
1902     double maxPixClock;
1903     
1904     xf86Msg(X_CONFIG, "|   |-->Monitor \"%s\"\n",
1905             conf_monitor->mon_identifier);
1906     monitorp->id = conf_monitor->mon_identifier;
1907     monitorp->vendor = conf_monitor->mon_vendor;
1908     monitorp->model = conf_monitor->mon_modelname;
1909     monitorp->Modes = NULL;
1910     monitorp->Last = NULL;
1911     monitorp->gamma = zeros;
1912     monitorp->widthmm = conf_monitor->mon_width;
1913     monitorp->heightmm = conf_monitor->mon_height;
1914     monitorp->reducedblanking = FALSE;
1915     monitorp->maxPixClock = 0;
1916     monitorp->options = conf_monitor->mon_option_lst;
1917
1918     /*
1919      * fill in the monitor structure
1920      */    
1921     for( count = 0 ;
1922          count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
1923          count++) {
1924         monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
1925         monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
1926     }
1927     monitorp->nHsync = count;
1928     for( count = 0 ;
1929          count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
1930          count++) {
1931         monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
1932         monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
1933     }
1934     monitorp->nVrefresh = count;
1935
1936     /*
1937      * first we collect the mode lines from the UseModes directive
1938      */
1939     while(modeslnk)
1940     {
1941         modes = xf86findModes (modeslnk->ml_modes_str, 
1942                                xf86configptr->conf_modes_lst);
1943         modeslnk->ml_modes = modes;
1944         
1945             
1946         /* now add the modes found in the modes
1947            section to the list of modes for this
1948            monitor unless it has been added before
1949            because we are reusing the same section 
1950            for another screen */
1951         if (xf86itemNotSublist(
1952                                (GenericListPtr)conf_monitor->mon_modeline_lst,
1953                                (GenericListPtr)modes->mon_modeline_lst)) {
1954             conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
1955                 xf86addListItem(
1956                                 (GenericListPtr)conf_monitor->mon_modeline_lst,
1957                                 (GenericListPtr)modes->mon_modeline_lst);
1958         }
1959         modeslnk = modeslnk->list.next;
1960     }
1961
1962     /*
1963      * we need to hook in the mode lines now
1964      * here both data structures use lists, only our internal one
1965      * is double linked
1966      */
1967     cmodep = conf_monitor->mon_modeline_lst;
1968     while( cmodep ) {
1969         mode = xnfcalloc(1, sizeof(DisplayModeRec));
1970         mode->type       = 0;
1971         mode->Clock      = cmodep->ml_clock;
1972         mode->HDisplay   = cmodep->ml_hdisplay;
1973         mode->HSyncStart = cmodep->ml_hsyncstart;
1974         mode->HSyncEnd   = cmodep->ml_hsyncend;
1975         mode->HTotal     = cmodep->ml_htotal;
1976         mode->VDisplay   = cmodep->ml_vdisplay;
1977         mode->VSyncStart = cmodep->ml_vsyncstart;
1978         mode->VSyncEnd   = cmodep->ml_vsyncend;
1979         mode->VTotal     = cmodep->ml_vtotal;
1980         mode->Flags      = cmodep->ml_flags;
1981         mode->HSkew      = cmodep->ml_hskew;
1982         mode->VScan      = cmodep->ml_vscan;
1983         mode->name       = xnfstrdup(cmodep->ml_identifier);
1984         if( last ) {
1985             mode->prev = last;
1986             last->next = mode;
1987         }
1988         else {
1989             /*
1990              * this is the first mode
1991              */
1992             monitorp->Modes = mode;
1993             mode->prev = NULL;
1994         }
1995         last = mode;
1996         cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
1997     }
1998     if(last){
1999       last->next = NULL;
2000     }
2001     monitorp->Last = last;
2002
2003     /* add the (VESA) default modes */
2004     if (! addDefaultModes(monitorp) )
2005         return FALSE;
2006
2007     if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
2008         monitorp->gamma.red = conf_monitor->mon_gamma_red;
2009     if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
2010         monitorp->gamma.green = conf_monitor->mon_gamma_green;
2011     if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
2012         monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
2013     
2014     /* Check that the gamma values are within range */
2015     if (monitorp->gamma.red > GAMMA_ZERO &&
2016         (monitorp->gamma.red < GAMMA_MIN ||
2017          monitorp->gamma.red > GAMMA_MAX)) {
2018         badgamma = monitorp->gamma.red;
2019     } else if (monitorp->gamma.green > GAMMA_ZERO &&
2020         (monitorp->gamma.green < GAMMA_MIN ||
2021          monitorp->gamma.green > GAMMA_MAX)) {
2022         badgamma = monitorp->gamma.green;
2023     } else if (monitorp->gamma.blue > GAMMA_ZERO &&
2024         (monitorp->gamma.blue < GAMMA_MIN ||
2025          monitorp->gamma.blue > GAMMA_MAX)) {
2026         badgamma = monitorp->gamma.blue;
2027     }
2028     if (badgamma > GAMMA_ZERO) {
2029         xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
2030                         badgamma, GAMMA_MIN, GAMMA_MAX);
2031             return FALSE;
2032     }
2033
2034     xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
2035     xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
2036                       &monitorp->reducedblanking);
2037     if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
2038                           &maxPixClock) == TRUE) {
2039         monitorp->maxPixClock = (int) maxPixClock;
2040     }
2041         
2042     return TRUE;
2043 }
2044
2045 static int
2046 lookupVisual(const char *visname)
2047 {
2048     int i;
2049
2050     if (!visname || !*visname)
2051         return -1;
2052
2053     for (i = 0; i <= DirectColor; i++) {
2054         if (!xf86nameCompare(visname, xf86VisualNames[i]))
2055             break;
2056     }
2057
2058     if (i <= DirectColor)
2059         return i;
2060
2061     return -1;
2062 }
2063
2064
2065 static Bool
2066 configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
2067 {
2068     int count = 0;
2069     XF86ModePtr modep;
2070     
2071     displayp->frameX0           = conf_display->disp_frameX0;
2072     displayp->frameY0           = conf_display->disp_frameY0;
2073     displayp->virtualX          = conf_display->disp_virtualX;
2074     displayp->virtualY          = conf_display->disp_virtualY;
2075     displayp->depth             = conf_display->disp_depth;
2076     displayp->fbbpp             = conf_display->disp_bpp;
2077     displayp->weight.red        = conf_display->disp_weight.red;
2078     displayp->weight.green      = conf_display->disp_weight.green;
2079     displayp->weight.blue       = conf_display->disp_weight.blue;
2080     displayp->blackColour.red   = conf_display->disp_black.red;
2081     displayp->blackColour.green = conf_display->disp_black.green;
2082     displayp->blackColour.blue  = conf_display->disp_black.blue;
2083     displayp->whiteColour.red   = conf_display->disp_white.red;
2084     displayp->whiteColour.green = conf_display->disp_white.green;
2085     displayp->whiteColour.blue  = conf_display->disp_white.blue;
2086     displayp->options           = conf_display->disp_option_lst;
2087     if (conf_display->disp_visual) {
2088         displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
2089         if (displayp->defaultVisual == -1) {
2090             xf86ConfigError("Invalid visual name: \"%s\"",
2091                             conf_display->disp_visual);
2092             return FALSE;
2093         }
2094     } else {
2095         displayp->defaultVisual = -1;
2096     }
2097         
2098     /*
2099      * now hook in the modes
2100      */
2101     modep = conf_display->disp_mode_lst;
2102     while(modep) {
2103         count++;
2104         modep = (XF86ModePtr)modep->list.next;
2105     }
2106     displayp->modes = xnfalloc((count+1) * sizeof(char*));
2107     modep = conf_display->disp_mode_lst;
2108     count = 0;
2109     while(modep) {
2110         displayp->modes[count] = modep->mode_name;
2111         count++;
2112         modep = (XF86ModePtr)modep->list.next;
2113     }
2114     displayp->modes[count] = NULL;
2115     
2116     return TRUE;
2117 }
2118
2119 static Bool
2120 configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
2121 {
2122     int i;
2123
2124     if (!conf_device) {
2125         return FALSE;
2126     }
2127
2128     if (active)
2129         xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
2130                 conf_device->dev_identifier);
2131     else
2132         xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
2133                 conf_device->dev_identifier);
2134
2135     devicep->identifier = conf_device->dev_identifier;
2136     devicep->vendor = conf_device->dev_vendor;
2137     devicep->board = conf_device->dev_board;
2138     devicep->chipset = conf_device->dev_chipset;
2139     devicep->ramdac = conf_device->dev_ramdac;
2140     devicep->driver = conf_device->dev_driver;
2141     devicep->active = active;
2142     devicep->videoRam = conf_device->dev_videoram;
2143     devicep->BiosBase = conf_device->dev_bios_base;
2144     devicep->MemBase = conf_device->dev_mem_base;
2145     devicep->IOBase = conf_device->dev_io_base;
2146     devicep->clockchip = conf_device->dev_clockchip;
2147     devicep->busID = conf_device->dev_busid;
2148     devicep->textClockFreq = conf_device->dev_textclockfreq;
2149     devicep->chipID = conf_device->dev_chipid;
2150     devicep->chipRev = conf_device->dev_chiprev;
2151     devicep->options = conf_device->dev_option_lst;
2152     devicep->irq = conf_device->dev_irq;
2153     devicep->screen = conf_device->dev_screen;
2154
2155     for (i = 0; i < MAXDACSPEEDS; i++) {
2156         if (i < CONF_MAXDACSPEEDS)
2157             devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
2158         else
2159             devicep->dacSpeeds[i] = 0;
2160     }
2161     devicep->numclocks = conf_device->dev_clocks;
2162     if (devicep->numclocks > MAXCLOCKS)
2163         devicep->numclocks = MAXCLOCKS;
2164     for (i = 0; i < devicep->numclocks; i++) {
2165         devicep->clock[i] = conf_device->dev_clock[i];
2166     }
2167     devicep->claimed = FALSE;
2168
2169     return TRUE;
2170 }
2171
2172 #ifdef XF86DRI
2173 static void
2174 configDRI(XF86ConfDRIPtr drip)
2175 {
2176     struct group       *grp;
2177
2178     xf86ConfigDRI.group      = -1;
2179     xf86ConfigDRI.mode       = 0;
2180
2181     if (drip) {
2182         if (drip->dri_group_name) {
2183             if ((grp = getgrnam(drip->dri_group_name)))
2184                 xf86ConfigDRI.group = grp->gr_gid;
2185         } else {
2186             if (drip->dri_group >= 0)
2187                 xf86ConfigDRI.group = drip->dri_group;
2188         }
2189         xf86ConfigDRI.mode = drip->dri_mode;
2190     }
2191 }
2192 #endif
2193
2194 static void
2195 configExtensions(XF86ConfExtensionsPtr conf_ext)
2196 {
2197     XF86OptionPtr o;
2198
2199     if (conf_ext && conf_ext->ext_option_lst) {
2200         for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
2201             char *name   = xf86OptionName(o);
2202             char *val    = xf86OptionValue(o);
2203             char *n;
2204             Bool  enable = TRUE;
2205
2206             /* Handle "No<ExtensionName>" */
2207             n = xf86NormalizeName(name);
2208             if (strncmp(n, "no", 2) == 0) {
2209                 name += 2;
2210                 enable = FALSE;
2211             }
2212
2213             if (!val ||
2214                 xf86NameCmp(val, "enable") == 0 ||
2215                 xf86NameCmp(val, "enabled") == 0 ||
2216                 xf86NameCmp(val, "on") == 0 ||
2217                 xf86NameCmp(val, "1") == 0 ||
2218                 xf86NameCmp(val, "yes") == 0 ||
2219                 xf86NameCmp(val, "true") == 0) {
2220                 /* NOTHING NEEDED -- enabling is handled below */
2221             } else if (xf86NameCmp(val, "disable") == 0 ||
2222                        xf86NameCmp(val, "disabled") == 0 ||
2223                        xf86NameCmp(val, "off") == 0 ||
2224                        xf86NameCmp(val, "0") == 0 ||
2225                        xf86NameCmp(val, "no") == 0 ||
2226                        xf86NameCmp(val, "false") == 0) {
2227                 enable = !enable;
2228             } else {
2229                 xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
2230                 free(n);
2231                 continue;
2232             }
2233
2234             if (EnableDisableExtension(name, enable)) {
2235                 xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
2236                         name, enable ? "enabled" : "disabled");
2237             } else {
2238                 xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
2239                         name);
2240             }
2241             free(n);
2242         }
2243     }
2244 }
2245
2246 static Bool
2247 configInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
2248 {
2249     xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
2250     inputp->name = conf_input->inp_identifier;
2251     inputp->driver = conf_input->inp_driver;
2252     inputp->options = conf_input->inp_option_lst;
2253     inputp->attrs = NULL;
2254
2255     return TRUE;
2256 }
2257
2258 static Bool
2259 modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
2260 {
2261     DisplayModePtr knownmodes = monitorp->Modes;
2262
2263     /* all I can think of is a linear search... */
2264     while(knownmodes != NULL)
2265     {
2266         if(!strcmp(mode->name, knownmodes->name) &&
2267            !(knownmodes->type & M_T_DEFAULT))
2268             return TRUE;
2269         knownmodes = knownmodes->next;
2270     }
2271     return FALSE;
2272 }
2273
2274 static Bool
2275 addDefaultModes(MonPtr monitorp)
2276 {
2277     DisplayModePtr mode;
2278     DisplayModePtr last = monitorp->Last;
2279     int i = 0;
2280
2281     for (i = 0; i < xf86NumDefaultModes; i++)
2282     {
2283         mode = xf86DuplicateMode(&xf86DefaultModes[i]);
2284         if (!modeIsPresent(mode, monitorp))
2285         {
2286             monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
2287             last = mode;
2288         } else {
2289             free(mode);
2290         }
2291     }
2292     monitorp->Last = last;
2293
2294     return TRUE;
2295 }
2296
2297 static void
2298 checkInput(serverLayoutPtr layout, Bool implicit_layout) {
2299     checkCoreInputDevices(layout, implicit_layout);
2300
2301     /* Unless we're forcing input devices, disable mouse/kbd devices in the
2302      * config. Otherwise the same physical device is added multiple times,
2303      * leading to duplicate events.
2304      */
2305     if (!xf86Info.forceInputDevices && layout->inputs)
2306     {
2307         InputInfoPtr *dev = layout->inputs;
2308         BOOL warned = FALSE;
2309
2310         while(*dev)
2311         {
2312             if (strcmp((*dev)->driver, "kbd") == 0 ||
2313                 strcmp((*dev)->driver, "mouse") == 0 ||
2314                 strcmp((*dev)->driver, "vmmouse") == 0)
2315             {
2316                 InputInfoPtr *current;
2317                 if (!warned)
2318                 {
2319                     xf86Msg(X_WARNING, "Hotplugging is on, devices using "
2320                             "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
2321                     warned = TRUE;
2322                 }
2323
2324                 xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name);
2325
2326                 current = dev;
2327                 free(*dev);
2328
2329                 do {
2330                     *current = *(current + 1);
2331                     current++;
2332                 } while(*current);
2333             } else
2334                 dev++;
2335         }
2336     }
2337 }
2338
2339 /*
2340  * load the config file and fill the global data structure
2341  */
2342 ConfigStatus
2343 xf86HandleConfigFile(Bool autoconfig)
2344 {
2345     const char *filename, *dirname, *sysdirname;
2346     char *filesearch, *dirsearch;
2347     MessageType filefrom = X_DEFAULT;
2348     MessageType dirfrom = X_DEFAULT;
2349     char *scanptr;
2350     Bool singlecard = 0;
2351     Bool implicit_layout = FALSE;
2352
2353     if (!autoconfig) {
2354         if (getuid() == 0) {
2355             filesearch = ROOT_CONFIGPATH;
2356             dirsearch = ROOT_CONFIGDIRPATH;
2357         } else {
2358             filesearch = USER_CONFIGPATH;
2359             dirsearch = USER_CONFIGDIRPATH;
2360         }
2361
2362         if (xf86ConfigFile)
2363             filefrom = X_CMDLINE;
2364         if (xf86ConfigDir)
2365             dirfrom = X_CMDLINE;
2366
2367         xf86initConfigFiles();
2368         sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
2369                                             PROJECTROOT);
2370         dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
2371         filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
2372         if (filename) {
2373             xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
2374             xf86ConfigFile = xnfstrdup(filename);
2375         } else {
2376             if (xf86ConfigFile)
2377                 xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
2378                         xf86ConfigFile);
2379         }
2380         if (dirname) {
2381             xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
2382                         dirname);
2383             xf86ConfigDir = xnfstrdup(dirname);
2384         } else {
2385             if (xf86ConfigDir)
2386                 xf86Msg(X_ERROR,
2387                         "Unable to locate/open config directory: \"%s\"\n",
2388                         xf86ConfigDir);
2389         }
2390         if (sysdirname)
2391             xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
2392                         sysdirname);
2393         if (!filename && !dirname && !sysdirname)
2394             return CONFIG_NOFILE;
2395     }
2396
2397     if ((xf86configptr = xf86readConfigFile ()) == NULL) {
2398         xf86Msg(X_ERROR, "Problem parsing the config file\n");
2399         return CONFIG_PARSE_ERROR;
2400     }
2401     xf86closeConfigFile ();
2402
2403     /* Initialise a few things. */
2404
2405     /*
2406      * now we convert part of the information contained in the parser
2407      * structures into our own structures.
2408      * The important part here is to figure out which Screen Sections
2409      * in the XF86Config file are active so that we can piece together
2410      * the modes that we need later down the road.
2411      * And while we are at it, we'll decode the rest of the stuff as well
2412      */
2413
2414     /* First check if a layout section is present, and if it is valid. */
2415
2416     if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
2417         if (xf86ScreenName == NULL) {
2418             xf86Msg(X_DEFAULT,
2419                     "No Layout section.  Using the first Screen section.\n");
2420         }
2421         if (!configImpliedLayout(&xf86ConfigLayout,
2422                                  xf86configptr->conf_screen_lst,
2423                                  xf86configptr)) {
2424             xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2425             return CONFIG_PARSE_ERROR;
2426         }
2427         implicit_layout = TRUE;
2428     } else {
2429         if (xf86configptr->conf_flags != NULL) {
2430           char *dfltlayout = NULL;
2431           pointer optlist = xf86configptr->conf_flags->flg_option_lst;
2432         
2433           if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
2434             dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
2435           if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
2436                           dfltlayout)) {
2437             xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2438             return CONFIG_PARSE_ERROR;
2439           }
2440         } else {
2441           if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
2442                           NULL)) {
2443             xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2444             return CONFIG_PARSE_ERROR;
2445           }
2446         }
2447     }
2448
2449     xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
2450
2451     if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
2452        ; /* IsolateDevice specified; overrides SingleCard */
2453     } else {
2454        xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
2455        if (singlecard)
2456            scanptr = xf86ConfigLayout.screens->screen->device->busID;
2457     }
2458     if (scanptr) {
2459        if (strncmp(scanptr, "PCI:", 4) != 0) {
2460            xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
2461                               "\tIgnoring IsolateDevice option.\n");
2462        } else
2463            xf86PciIsolateDevice(scanptr);
2464     }
2465
2466     /* Now process everything else */
2467     if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
2468              ErrorF ("Problem when converting the config data structures\n");
2469              return CONFIG_PARSE_ERROR;
2470     }
2471
2472     configFiles(xf86configptr->conf_files);
2473     configExtensions(xf86configptr->conf_extensions);
2474 #ifdef XF86DRI
2475     configDRI(xf86configptr->conf_dri);
2476 #endif
2477
2478     checkInput(&xf86ConfigLayout, implicit_layout);
2479
2480     /*
2481      * Handle some command line options that can override some of the
2482      * ServerFlags settings.
2483      */
2484 #ifdef XF86VIDMODE
2485     if (xf86VidModeDisabled)
2486         xf86Info.vidModeEnabled = FALSE;
2487     if (xf86VidModeAllowNonLocal)
2488         xf86Info.vidModeAllowNonLocal = TRUE;
2489 #endif
2490
2491     if (xf86AllowMouseOpenFail)
2492         xf86Info.allowMouseOpenFail = TRUE;
2493
2494     return CONFIG_OK;
2495 }
2496
2497 Bool
2498 xf86PathIsSafe(const char *path)
2499 {
2500     return (xf86pathIsSafe(path) != 0);
2501 }