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