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