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