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