xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xf86Config.c (80708B)


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