1706f2543Smrg/*
2706f2543Smrg * Loosely based on code bearing the following copyright:
3706f2543Smrg *
4706f2543Smrg *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
5706f2543Smrg */
6706f2543Smrg
7706f2543Smrg/*
8706f2543Smrg * Copyright 1992-2003 by The XFree86 Project, Inc.
9706f2543Smrg * Copyright 1997 by Metro Link, Inc.
10706f2543Smrg *
11706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
12706f2543Smrg * copy of this software and associated documentation files (the "Software"),
13706f2543Smrg * to deal in the Software without restriction, including without limitation
14706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
16706f2543Smrg * Software is furnished to do so, subject to the following conditions:
17706f2543Smrg *
18706f2543Smrg * The above copyright notice and this permission notice shall be included in
19706f2543Smrg * all copies or substantial portions of the Software.
20706f2543Smrg *
21706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
25706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE.
28706f2543Smrg *
29706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s)
30706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote
31706f2543Smrg * the sale, use or other dealings in this Software without prior written
32706f2543Smrg * authorization from the copyright holder(s) and author(s).
33706f2543Smrg */
34706f2543Smrg
35706f2543Smrg/*
36706f2543Smrg *
37706f2543Smrg * Authors:
38706f2543Smrg *	Dirk Hohndel <hohndel@XFree86.Org>
39706f2543Smrg *	David Dawes <dawes@XFree86.Org>
40706f2543Smrg *      Marc La France <tsi@XFree86.Org>
41706f2543Smrg *      Egbert Eich <eich@XFree86.Org>
42706f2543Smrg *      ... and others
43706f2543Smrg */
44706f2543Smrg
45706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
46706f2543Smrg#include <xorg-config.h>
47706f2543Smrg#endif
48706f2543Smrg
49706f2543Smrg#ifdef XF86DRI
50706f2543Smrg#include <sys/types.h>
51706f2543Smrg#include <grp.h>
52706f2543Smrg#endif
53706f2543Smrg
54706f2543Smrg#include "xf86.h"
55706f2543Smrg#include "xf86Modes.h"
56706f2543Smrg#include "xf86Parser.h"
57706f2543Smrg#include "xf86tokens.h"
58706f2543Smrg#include "xf86Config.h"
59706f2543Smrg#include "xf86Priv.h"
60706f2543Smrg#include "xf86_OSlib.h"
61706f2543Smrg#include "configProcs.h"
62706f2543Smrg#include "globals.h"
63706f2543Smrg#include "extension.h"
64706f2543Smrg#include "xf86pciBus.h"
65706f2543Smrg
66706f2543Smrg#include "xf86Xinput.h"
67706f2543Smrg
68706f2543Smrg#include "xkbsrv.h"
69706f2543Smrg
70706f2543Smrg#include "picture.h"
71706f2543Smrg
72706f2543Smrg/*
73706f2543Smrg * These paths define the way the config file search is done.  The escape
74706f2543Smrg * sequences are documented in parser/scan.c.
75706f2543Smrg */
76706f2543Smrg#ifndef ROOT_CONFIGPATH
77706f2543Smrg#define ROOT_CONFIGPATH	"%A," "%R," \
78706f2543Smrg			"/etc/X11/%R," "%P/etc/X11/%R," \
79706f2543Smrg			"%E," "%F," \
80706f2543Smrg			"/etc/X11/%F," "%P/etc/X11/%F," \
81706f2543Smrg			"/etc/X11/%X," "/etc/%X," \
82706f2543Smrg			"%P/etc/X11/%X.%H," \
83706f2543Smrg			"%P/etc/X11/%X," \
84706f2543Smrg			"%P/lib/X11/%X.%H," \
85706f2543Smrg			"%P/lib/X11/%X"
86706f2543Smrg#endif
87706f2543Smrg#ifndef USER_CONFIGPATH
88706f2543Smrg#define USER_CONFIGPATH	"/etc/X11/%S," "%P/etc/X11/%S," \
89706f2543Smrg			"/etc/X11/%G," "%P/etc/X11/%G," \
90706f2543Smrg			"/etc/X11/%X," "/etc/%X," \
91706f2543Smrg			"%P/etc/X11/%X.%H," \
92706f2543Smrg			"%P/etc/X11/%X," \
93706f2543Smrg			"%P/lib/X11/%X.%H," \
94706f2543Smrg			"%P/lib/X11/%X"
95706f2543Smrg#endif
96706f2543Smrg#ifndef ROOT_CONFIGDIRPATH
97706f2543Smrg#define ROOT_CONFIGDIRPATH	"%A," "%R," \
98706f2543Smrg				"/etc/X11/%R," "%C/X11/%R," \
99706f2543Smrg				"/etc/X11/%X," "%C/X11/%X"
100706f2543Smrg#endif
101706f2543Smrg#ifndef USER_CONFIGDIRPATH
102706f2543Smrg#define USER_CONFIGDIRPATH	"/etc/X11/%R," "%C/X11/%R," \
103706f2543Smrg				"/etc/X11/%X," "%C/X11/%X"
104706f2543Smrg#endif
105706f2543Smrg#ifndef SYS_CONFIGDIRPATH
106706f2543Smrg#define SYS_CONFIGDIRPATH	"/usr/share/X11/%X," "%D/X11/%X"
107706f2543Smrg#endif
108706f2543Smrg#ifndef PROJECTROOT
109706f2543Smrg#define PROJECTROOT	"/usr/X11R6"
110706f2543Smrg#endif
111706f2543Smrg
112706f2543Smrgstatic ModuleDefault ModuleDefaults[] = {
113706f2543Smrg    {.name = "extmod",   .toLoad = TRUE,    .load_opt=NULL},
114706f2543Smrg#ifdef DBE
115706f2543Smrg    {.name = "dbe",      .toLoad = TRUE,    .load_opt=NULL},
116706f2543Smrg#endif
117706f2543Smrg#ifdef GLXEXT
118706f2543Smrg    {.name = "glx",      .toLoad = TRUE,    .load_opt=NULL},
119706f2543Smrg#endif
120706f2543Smrg#ifdef XRECORD
121706f2543Smrg    {.name = "record",   .toLoad = TRUE,    .load_opt=NULL},
122706f2543Smrg#endif
123706f2543Smrg#ifdef XF86DRI
124706f2543Smrg    {.name = "dri",      .toLoad = TRUE,    .load_opt=NULL},
125706f2543Smrg#endif
126706f2543Smrg#ifdef DRI2
127706f2543Smrg    {.name = "dri2",     .toLoad = TRUE,    .load_opt=NULL},
128706f2543Smrg#endif
129706f2543Smrg    {.name = NULL,       .toLoad = FALSE,   .load_opt=NULL}
130706f2543Smrg};
131706f2543Smrg
132706f2543Smrg
133706f2543Smrg/* Forward declarations */
134706f2543Smrgstatic Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
135706f2543Smrg			 int scrnum, MessageType from);
136706f2543Smrgstatic Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
137706f2543Smrgstatic Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
138706f2543Smrg			 Bool active);
139706f2543Smrgstatic Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
140706f2543Smrg			MessageType from);
141706f2543Smrgstatic Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
142706f2543Smrgstatic Bool addDefaultModes(MonPtr monitorp);
143706f2543Smrg#ifdef XF86DRI
144706f2543Smrgstatic void configDRI(XF86ConfDRIPtr drip);
145706f2543Smrg#endif
146706f2543Smrgstatic void configExtensions(XF86ConfExtensionsPtr conf_ext);
147706f2543Smrg
148706f2543Smrg/*
149706f2543Smrg * xf86GetPathElem --
150706f2543Smrg *	Extract a single element from the font path string starting at
151706f2543Smrg *	pnt.  The font path element will be returned, and pnt will be
152706f2543Smrg *	updated to point to the start of the next element, or set to
153706f2543Smrg *	NULL if there are no more.
154706f2543Smrg */
155706f2543Smrgstatic char *
156706f2543Smrgxf86GetPathElem(char **pnt)
157706f2543Smrg{
158706f2543Smrg  char *p1;
159706f2543Smrg
160706f2543Smrg  p1 = *pnt;
161706f2543Smrg  *pnt = index(*pnt, ',');
162706f2543Smrg  if (*pnt != NULL) {
163706f2543Smrg    **pnt = '\0';
164706f2543Smrg    *pnt += 1;
165706f2543Smrg  }
166706f2543Smrg  return p1;
167706f2543Smrg}
168706f2543Smrg
169706f2543Smrg/*
170706f2543Smrg * xf86ValidateFontPath --
171706f2543Smrg *	Validates the user-specified font path.  Each element that
172706f2543Smrg *	begins with a '/' is checked to make sure the directory exists.
173706f2543Smrg *	If the directory exists, the existence of a file named 'fonts.dir'
174706f2543Smrg *	is checked.  If either check fails, an error is printed and the
175706f2543Smrg *	element is removed from the font path.
176706f2543Smrg */
177706f2543Smrg
178706f2543Smrg#define DIR_FILE "/fonts.dir"
179706f2543Smrgstatic char *
180706f2543Smrgxf86ValidateFontPath(char *path)
181706f2543Smrg{
182706f2543Smrg  char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem;
183706f2543Smrg  struct stat stat_buf;
184706f2543Smrg  int flag;
185706f2543Smrg  int dirlen;
186706f2543Smrg
187706f2543Smrg  tmp_path = calloc(1,strlen(path)+1);
188706f2543Smrg  out_pnt = tmp_path;
189706f2543Smrg  path_elem = NULL;
190706f2543Smrg  next = path;
191706f2543Smrg  while (next != NULL) {
192706f2543Smrg    path_elem = xf86GetPathElem(&next);
193706f2543Smrg    if (*path_elem == '/') {
194706f2543Smrg      dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
195706f2543Smrg      if ((p1 = strchr(path_elem, ':')) != 0)
196706f2543Smrg	dirlen = p1 - path_elem;
197706f2543Smrg      else
198706f2543Smrg	dirlen = strlen(path_elem);
199706f2543Smrg      strncpy(dir_elem, path_elem, dirlen);
200706f2543Smrg      dir_elem[dirlen] = '\0';
201706f2543Smrg      flag = stat(dir_elem, &stat_buf);
202706f2543Smrg      if (flag == 0)
203706f2543Smrg	if (!S_ISDIR(stat_buf.st_mode))
204706f2543Smrg	  flag = -1;
205706f2543Smrg      if (flag != 0) {
206706f2543Smrg        xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n", dir_elem);
207706f2543Smrg	xf86ErrorF("\tEntry deleted from font path.\n");
208706f2543Smrg	free(dir_elem);
209706f2543Smrg	continue;
210706f2543Smrg      }
211706f2543Smrg      else {
212706f2543Smrg	XNFasprintf(&p1, "%s%s", dir_elem, DIR_FILE);
213706f2543Smrg	flag = stat(p1, &stat_buf);
214706f2543Smrg	if (flag == 0)
215706f2543Smrg	  if (!S_ISREG(stat_buf.st_mode))
216706f2543Smrg	    flag = -1;
217706f2543Smrg	free(p1);
218706f2543Smrg	if (flag != 0) {
219706f2543Smrg	  xf86Msg(X_WARNING,
220706f2543Smrg		  "`fonts.dir' not found (or not valid) in \"%s\".\n",
221706f2543Smrg		  dir_elem);
222706f2543Smrg	  xf86ErrorF("\tEntry deleted from font path.\n");
223706f2543Smrg	  xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
224706f2543Smrg	  free(dir_elem);
225706f2543Smrg	  continue;
226706f2543Smrg	}
227706f2543Smrg      }
228706f2543Smrg      free(dir_elem);
229706f2543Smrg    }
230706f2543Smrg
231706f2543Smrg    /*
232706f2543Smrg     * Either an OK directory, or a font server name.  So add it to
233706f2543Smrg     * the path.
234706f2543Smrg     */
235706f2543Smrg    if (out_pnt != tmp_path)
236706f2543Smrg      *out_pnt++ = ',';
237706f2543Smrg    strcat(out_pnt, path_elem);
238706f2543Smrg    out_pnt += strlen(path_elem);
239706f2543Smrg  }
240706f2543Smrg  return tmp_path;
241706f2543Smrg}
242706f2543Smrg
243706f2543Smrg
244706f2543Smrg/*
245706f2543Smrg * use the datastructure that the parser provides and pick out the parts
246706f2543Smrg * that we need at this point
247706f2543Smrg */
248706f2543Smrgchar **
249706f2543Smrgxf86ModulelistFromConfig(pointer **optlist)
250706f2543Smrg{
251706f2543Smrg    int count = 0, i = 0;
252706f2543Smrg    char **modulearray;
253706f2543Smrg    char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
254706f2543Smrg		       "freetype", "type1",
255706f2543Smrg		       NULL };
256706f2543Smrg    pointer *optarray;
257706f2543Smrg    XF86LoadPtr modp;
258706f2543Smrg    Bool found;
259706f2543Smrg
260706f2543Smrg    /*
261706f2543Smrg     * make sure the config file has been parsed and that we have a
262706f2543Smrg     * ModulePath set; if no ModulePath was given, use the default
263706f2543Smrg     * ModulePath
264706f2543Smrg     */
265706f2543Smrg    if (xf86configptr == NULL) {
266706f2543Smrg        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
267706f2543Smrg        return NULL;
268706f2543Smrg    }
269706f2543Smrg
270706f2543Smrg    if (xf86configptr->conf_modules) {
271706f2543Smrg        /* Walk the disable list and let people know what we've parsed to
272706f2543Smrg         * not be loaded
273706f2543Smrg         */
274706f2543Smrg        modp = xf86configptr->conf_modules->mod_disable_lst;
275706f2543Smrg        while (modp) {
276706f2543Smrg            xf86Msg(X_WARNING, "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n", modp->load_name);
277706f2543Smrg	        modp = (XF86LoadPtr) modp->list.next;
278706f2543Smrg        }
279706f2543Smrg        /*
280706f2543Smrg         * Walk the default settings table. For each module listed to be
281706f2543Smrg         * loaded, make sure it's in the mod_load_lst. If it's not, make
282706f2543Smrg         * sure it's not in the mod_no_load_lst. If it's not disabled,
283706f2543Smrg         * append it to mod_load_lst
284706f2543Smrg         */
285706f2543Smrg         for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
286706f2543Smrg            if (ModuleDefaults[i].toLoad == FALSE) {
287706f2543Smrg                xf86Msg(X_WARNING, "\"%s\" is not to be loaded by default. Skipping.\n", ModuleDefaults[i].name);
288706f2543Smrg                continue;
289706f2543Smrg            }
290706f2543Smrg            found = FALSE;
291706f2543Smrg            modp = xf86configptr->conf_modules->mod_load_lst;
292706f2543Smrg            while (modp) {
293706f2543Smrg                if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
294706f2543Smrg                    xf86Msg(X_INFO, "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n", ModuleDefaults[i].name);
295706f2543Smrg                    found = TRUE;
296706f2543Smrg                    break;
297706f2543Smrg                }
298706f2543Smrg	        modp = (XF86LoadPtr) modp->list.next;
299706f2543Smrg            }
300706f2543Smrg            if (found == FALSE) {
301706f2543Smrg                modp = xf86configptr->conf_modules->mod_disable_lst;
302706f2543Smrg                while (modp) {
303706f2543Smrg                    if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
304706f2543Smrg                        xf86Msg(X_INFO, "\"%s\" will be loaded even though the default is to disable it.\n", ModuleDefaults[i].name);
305706f2543Smrg                        found = TRUE;
306706f2543Smrg                        break;
307706f2543Smrg                    }
308706f2543Smrg	                modp = (XF86LoadPtr) modp->list.next;
309706f2543Smrg                }
310706f2543Smrg            }
311706f2543Smrg            if (found == FALSE) {
312706f2543Smrg		XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
313706f2543Smrg                xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
314706f2543Smrg                xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n", ModuleDefaults[i].name);
315706f2543Smrg            }
316706f2543Smrg         }
317706f2543Smrg    } else {
318706f2543Smrg	xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
319706f2543Smrg	for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
320706f2543Smrg	    if (ModuleDefaults[i].toLoad == TRUE) {
321706f2543Smrg		XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
322706f2543Smrg		xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
323706f2543Smrg	    }
324706f2543Smrg	}
325706f2543Smrg    }
326706f2543Smrg
327706f2543Smrg	    /*
328706f2543Smrg	     * Walk the list of modules in the "Module" section to determine how
329706f2543Smrg	     * many we have.
330706f2543Smrg	    */
331706f2543Smrg	    modp = xf86configptr->conf_modules->mod_load_lst;
332706f2543Smrg	    while (modp) {
333706f2543Smrg                for (i = 0; ignore[i]; i++) {
334706f2543Smrg                    if (strcmp(modp->load_name, ignore[i]) == 0)
335706f2543Smrg                        modp->ignore = 1;
336706f2543Smrg                }
337706f2543Smrg                if (!modp->ignore)
338706f2543Smrg	            count++;
339706f2543Smrg	        modp = (XF86LoadPtr) modp->list.next;
340706f2543Smrg	    }
341706f2543Smrg
342706f2543Smrg    /*
343706f2543Smrg     * allocate the memory and walk the list again to fill in the pointers
344706f2543Smrg     */
345706f2543Smrg    modulearray = xnfalloc((count + 1) * sizeof(char*));
346706f2543Smrg    optarray = xnfalloc((count + 1) * sizeof(pointer));
347706f2543Smrg    count = 0;
348706f2543Smrg    if (xf86configptr->conf_modules) {
349706f2543Smrg	    modp = xf86configptr->conf_modules->mod_load_lst;
350706f2543Smrg	    while (modp) {
351706f2543Smrg            if (!modp->ignore) {
352706f2543Smrg	            modulearray[count] = modp->load_name;
353706f2543Smrg	            optarray[count] = modp->load_opt;
354706f2543Smrg	            count++;
355706f2543Smrg            }
356706f2543Smrg	        modp = (XF86LoadPtr) modp->list.next;
357706f2543Smrg	    }
358706f2543Smrg    }
359706f2543Smrg    modulearray[count] = NULL;
360706f2543Smrg    optarray[count] = NULL;
361706f2543Smrg    if (optlist)
362706f2543Smrg	    *optlist = optarray;
363706f2543Smrg    else
364706f2543Smrg	    free(optarray);
365706f2543Smrg    return modulearray;
366706f2543Smrg}
367706f2543Smrg
368706f2543Smrg
369706f2543Smrgchar **
370706f2543Smrgxf86DriverlistFromConfig(void)
371706f2543Smrg{
372706f2543Smrg    int count = 0;
373706f2543Smrg    int j;
374706f2543Smrg    char **modulearray;
375706f2543Smrg    screenLayoutPtr slp;
376706f2543Smrg
377706f2543Smrg    /*
378706f2543Smrg     * make sure the config file has been parsed and that we have a
379706f2543Smrg     * ModulePath set; if no ModulePath was given, use the default
380706f2543Smrg     * ModulePath
381706f2543Smrg     */
382706f2543Smrg    if (xf86configptr == NULL) {
383706f2543Smrg        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
384706f2543Smrg        return NULL;
385706f2543Smrg    }
386706f2543Smrg
387706f2543Smrg    /*
388706f2543Smrg     * Walk the list of driver lines in active "Device" sections to
389706f2543Smrg     * determine now many implicitly loaded modules there are.
390706f2543Smrg     *
391706f2543Smrg     */
392706f2543Smrg    if (xf86ConfigLayout.screens) {
393706f2543Smrg        slp = xf86ConfigLayout.screens;
394706f2543Smrg        while ((slp++)->screen) {
395706f2543Smrg	    count++;
396706f2543Smrg        }
397706f2543Smrg    }
398706f2543Smrg
399706f2543Smrg    /*
400706f2543Smrg     * Handle the set of inactive "Device" sections.
401706f2543Smrg     */
402706f2543Smrg    j = 0;
403706f2543Smrg    while (xf86ConfigLayout.inactives[j++].identifier)
404706f2543Smrg	count++;
405706f2543Smrg
406706f2543Smrg    if (count == 0)
407706f2543Smrg	return NULL;
408706f2543Smrg
409706f2543Smrg    /*
410706f2543Smrg     * allocate the memory and walk the list again to fill in the pointers
411706f2543Smrg     */
412706f2543Smrg    modulearray = xnfalloc((count + 1) * sizeof(char*));
413706f2543Smrg    count = 0;
414706f2543Smrg    slp = xf86ConfigLayout.screens;
415706f2543Smrg    while (slp->screen) {
416706f2543Smrg	modulearray[count] = slp->screen->device->driver;
417706f2543Smrg	count++;
418706f2543Smrg	slp++;
419706f2543Smrg    }
420706f2543Smrg
421706f2543Smrg    j = 0;
422706f2543Smrg
423706f2543Smrg    while (xf86ConfigLayout.inactives[j].identifier)
424706f2543Smrg	modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
425706f2543Smrg
426706f2543Smrg    modulearray[count] = NULL;
427706f2543Smrg
428706f2543Smrg    /* Remove duplicates */
429706f2543Smrg    for (count = 0; modulearray[count] != NULL; count++) {
430706f2543Smrg	int i;
431706f2543Smrg
432706f2543Smrg	for (i = 0; i < count; i++)
433706f2543Smrg	    if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
434706f2543Smrg		modulearray[count] = "";
435706f2543Smrg		break;
436706f2543Smrg	    }
437706f2543Smrg    }
438706f2543Smrg    return modulearray;
439706f2543Smrg}
440706f2543Smrg
441706f2543Smrgchar **
442706f2543Smrgxf86InputDriverlistFromConfig(void)
443706f2543Smrg{
444706f2543Smrg    int count = 0;
445706f2543Smrg    char **modulearray;
446706f2543Smrg    InputInfoPtr *idp;
447706f2543Smrg
448706f2543Smrg    /*
449706f2543Smrg     * make sure the config file has been parsed and that we have a
450706f2543Smrg     * ModulePath set; if no ModulePath was given, use the default
451706f2543Smrg     * ModulePath
452706f2543Smrg     */
453706f2543Smrg    if (xf86configptr == NULL) {
454706f2543Smrg        xf86Msg(X_ERROR, "Cannot access global config data structure\n");
455706f2543Smrg        return NULL;
456706f2543Smrg    }
457706f2543Smrg
458706f2543Smrg    /*
459706f2543Smrg     * Walk the list of driver lines in active "InputDevice" sections to
460706f2543Smrg     * determine now many implicitly loaded modules there are.
461706f2543Smrg     */
462706f2543Smrg    if (xf86ConfigLayout.inputs) {
463706f2543Smrg        idp = xf86ConfigLayout.inputs;
464706f2543Smrg        while (*idp) {
465706f2543Smrg	    count++;
466706f2543Smrg	    idp++;
467706f2543Smrg        }
468706f2543Smrg    }
469706f2543Smrg
470706f2543Smrg    if (count == 0)
471706f2543Smrg	return NULL;
472706f2543Smrg
473706f2543Smrg    /*
474706f2543Smrg     * allocate the memory and walk the list again to fill in the pointers
475706f2543Smrg     */
476706f2543Smrg    modulearray = xnfalloc((count + 1) * sizeof(char*));
477706f2543Smrg    count = 0;
478706f2543Smrg    idp = xf86ConfigLayout.inputs;
479706f2543Smrg    while (idp && *idp) {
480706f2543Smrg        modulearray[count] = (*idp)->driver;
481706f2543Smrg	count++;
482706f2543Smrg	idp++;
483706f2543Smrg    }
484706f2543Smrg    modulearray[count] = NULL;
485706f2543Smrg
486706f2543Smrg    /* Remove duplicates */
487706f2543Smrg    for (count = 0; modulearray[count] != NULL; count++) {
488706f2543Smrg	int i;
489706f2543Smrg
490706f2543Smrg	for (i = 0; i < count; i++)
491706f2543Smrg	    if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
492706f2543Smrg		modulearray[count] = "";
493706f2543Smrg		break;
494706f2543Smrg	    }
495706f2543Smrg    }
496706f2543Smrg    return modulearray;
497706f2543Smrg}
498706f2543Smrg
499706f2543Smrgstatic void
500706f2543Smrgfixup_video_driver_list(char **drivers)
501706f2543Smrg{
502706f2543Smrg    static const char *fallback[4] = { "vesa", "fbdev", "wsfb", NULL };
503706f2543Smrg    char **end, **drv;
504706f2543Smrg    char *x;
505706f2543Smrg    int i;
506706f2543Smrg
507706f2543Smrg    /* walk to the end of the list */
508706f2543Smrg    for (end = drivers; *end && **end; end++) ;
509706f2543Smrg    end--;
510706f2543Smrg
511706f2543Smrg    /*
512706f2543Smrg     * for each of the fallback drivers, if we find it in the list,
513706f2543Smrg     * swap it with the last available non-fallback driver.
514706f2543Smrg     */
515706f2543Smrg    for (i = 0; fallback[i]; i++) {
516706f2543Smrg        for (drv = drivers; drv != end; drv++) {
517706f2543Smrg            if (strstr(*drv, fallback[i])) {
518706f2543Smrg                x = *drv; *drv = *end; *end = x;
519706f2543Smrg                end--;
520706f2543Smrg                break;
521706f2543Smrg            }
522706f2543Smrg        }
523706f2543Smrg    }
524706f2543Smrg}
525706f2543Smrg
526706f2543Smrgstatic char **
527706f2543SmrgGenerateDriverlist(char * dirname)
528706f2543Smrg{
529706f2543Smrg    char **ret;
530706f2543Smrg    const char *subdirs[] = { dirname, NULL };
531706f2543Smrg    static const char *patlist[] = {"(.*)_drv\\.so$", NULL};
532706f2543Smrg    ret = LoaderListDirs(subdirs, patlist);
533706f2543Smrg
534706f2543Smrg    /* fix up the probe order for video drivers */
535706f2543Smrg    if (strstr(dirname, "drivers") && ret != NULL)
536706f2543Smrg        fixup_video_driver_list(ret);
537706f2543Smrg
538706f2543Smrg    return ret;
539706f2543Smrg}
540706f2543Smrg
541706f2543Smrgchar **
542706f2543Smrgxf86DriverlistFromCompile(void)
543706f2543Smrg{
544706f2543Smrg    static char **driverlist = NULL;
545706f2543Smrg
546706f2543Smrg    if (!driverlist)
547706f2543Smrg        driverlist = GenerateDriverlist("drivers");
548706f2543Smrg
549706f2543Smrg    return driverlist;
550706f2543Smrg}
551706f2543Smrg
552706f2543Smrg/*
553706f2543Smrg * xf86ConfigError --
554706f2543Smrg *      Print a READABLE ErrorMessage!!!  All information that is
555706f2543Smrg *      available is printed.
556706f2543Smrg */
557706f2543Smrgstatic void
558706f2543Smrgxf86ConfigError(char *msg, ...)
559706f2543Smrg{
560706f2543Smrg    va_list ap;
561706f2543Smrg
562706f2543Smrg    ErrorF("\nConfig Error:\n");
563706f2543Smrg    va_start(ap, msg);
564706f2543Smrg    VErrorF(msg, ap);
565706f2543Smrg    va_end(ap);
566706f2543Smrg    ErrorF("\n");
567706f2543Smrg    return;
568706f2543Smrg}
569706f2543Smrg
570706f2543Smrgstatic void
571706f2543SmrgconfigFiles(XF86ConfFilesPtr fileconf)
572706f2543Smrg{
573706f2543Smrg    MessageType	 pathFrom;
574706f2543Smrg    Bool	 must_copy;
575706f2543Smrg    int		 size, countDirs;
576706f2543Smrg    char	*temp_path, *log_buf, *start, *end;
577706f2543Smrg
578706f2543Smrg    /* FontPath */
579706f2543Smrg    must_copy = TRUE;
580706f2543Smrg
581706f2543Smrg    temp_path = defaultFontPath ? defaultFontPath : "";
582706f2543Smrg    if (xf86fpFlag)
583706f2543Smrg	pathFrom = X_CMDLINE;
584706f2543Smrg    else if (fileconf && fileconf->file_fontpath) {
585706f2543Smrg	pathFrom = X_CONFIG;
586706f2543Smrg	if (xf86Info.useDefaultFontPath) {
587706f2543Smrg	    if (asprintf(&defaultFontPath, "%s%s%s", fileconf->file_fontpath,
588706f2543Smrg			 *temp_path ? "," : "", temp_path) == -1)
589706f2543Smrg		defaultFontPath = NULL;
590706f2543Smrg	    else
591706f2543Smrg		must_copy = FALSE;
592706f2543Smrg	}
593706f2543Smrg	else
594706f2543Smrg	    defaultFontPath = fileconf->file_fontpath;
595706f2543Smrg    }
596706f2543Smrg    else
597706f2543Smrg	pathFrom = X_DEFAULT;
598706f2543Smrg    temp_path = defaultFontPath ? defaultFontPath : "";
599706f2543Smrg
600706f2543Smrg    /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
601706f2543Smrg    temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
602706f2543Smrg    defaultFontPath = xf86ValidateFontPath(temp_path);
603706f2543Smrg    free(temp_path);
604706f2543Smrg
605706f2543Smrg    /* make fontpath more readable in the logfiles */
606706f2543Smrg    countDirs = 1;
607706f2543Smrg    temp_path = defaultFontPath;
608706f2543Smrg    while ((temp_path = index(temp_path, ',')) != NULL) {
609706f2543Smrg	countDirs++;
610706f2543Smrg	temp_path++;
611706f2543Smrg    }
612706f2543Smrg
613706f2543Smrg    log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
614706f2543Smrg    temp_path = log_buf;
615706f2543Smrg    start = defaultFontPath;
616706f2543Smrg    while((end = index(start, ',')) != NULL) {
617706f2543Smrg      size = (end - start) + 1;
618706f2543Smrg      *(temp_path++) = '\t';
619706f2543Smrg      strncpy(temp_path, start, size);
620706f2543Smrg      temp_path += size;
621706f2543Smrg      *(temp_path++) = '\n';
622706f2543Smrg      start += size;
623706f2543Smrg    }
624706f2543Smrg    /* copy last entry */
625706f2543Smrg    *(temp_path++) = '\t';
626706f2543Smrg    strcpy(temp_path, start);
627706f2543Smrg    xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
628706f2543Smrg    free(log_buf);
629706f2543Smrg
630706f2543Smrg  /* ModulePath */
631706f2543Smrg
632706f2543Smrg  if (fileconf) {
633706f2543Smrg    if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
634706f2543Smrg      xf86ModulePath = fileconf->file_modulepath;
635706f2543Smrg      xf86ModPathFrom = X_CONFIG;
636706f2543Smrg    }
637706f2543Smrg  }
638706f2543Smrg
639706f2543Smrg  xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
640706f2543Smrg
641706f2543Smrg  if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
642706f2543Smrg    XkbBaseDirectory = fileconf->file_xkbdir;
643706f2543Smrg    xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
644706f2543Smrg	    XkbBaseDirectory);
645706f2543Smrg  }
646706f2543Smrg#if 0
647706f2543Smrg  /* LogFile */
648706f2543Smrg  /*
649706f2543Smrg   * XXX The problem with this is that the log file is already open.
650706f2543Smrg   * One option might be to copy the exiting contents to the new location.
651706f2543Smrg   * and re-open it.  The down side is that the default location would
652706f2543Smrg   * already have been overwritten.  Another option would be to start with
653706f2543Smrg   * unique temporary location, then copy it once the correct name is known.
654706f2543Smrg   * A problem with this is what happens if the server exits before that
655706f2543Smrg   * happens.
656706f2543Smrg   */
657706f2543Smrg  if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
658706f2543Smrg    xf86LogFile = fileconf->file_logfile;
659706f2543Smrg    xf86LogFileFrom = X_CONFIG;
660706f2543Smrg  }
661706f2543Smrg#endif
662706f2543Smrg
663706f2543Smrg  return;
664706f2543Smrg}
665706f2543Smrg
666706f2543Smrgtypedef enum {
667706f2543Smrg    FLAG_NOTRAPSIGNALS,
668706f2543Smrg    FLAG_DONTVTSWITCH,
669706f2543Smrg    FLAG_DONTZAP,
670706f2543Smrg    FLAG_DONTZOOM,
671706f2543Smrg    FLAG_DISABLEVIDMODE,
672706f2543Smrg    FLAG_ALLOWNONLOCAL,
673706f2543Smrg    FLAG_ALLOWMOUSEOPENFAIL,
674706f2543Smrg    FLAG_VTSYSREQ,
675706f2543Smrg    FLAG_SAVER_BLANKTIME,
676706f2543Smrg    FLAG_DPMS_STANDBYTIME,
677706f2543Smrg    FLAG_DPMS_SUSPENDTIME,
678706f2543Smrg    FLAG_DPMS_OFFTIME,
679706f2543Smrg    FLAG_PIXMAP,
680706f2543Smrg    FLAG_PC98,
681706f2543Smrg    FLAG_NOPM,
682706f2543Smrg    FLAG_XINERAMA,
683706f2543Smrg    FLAG_LOG,
684706f2543Smrg    FLAG_RENDER_COLORMAP_MODE,
685706f2543Smrg    FLAG_RANDR,
686706f2543Smrg    FLAG_AIGLX,
687706f2543Smrg    FLAG_IGNORE_ABI,
688706f2543Smrg    FLAG_ALLOW_EMPTY_INPUT,
689706f2543Smrg    FLAG_USE_DEFAULT_FONT_PATH,
690706f2543Smrg    FLAG_AUTO_ADD_DEVICES,
691706f2543Smrg    FLAG_AUTO_ENABLE_DEVICES,
692706f2543Smrg    FLAG_GLX_VISUALS,
693706f2543Smrg    FLAG_DRI2,
694706f2543Smrg    FLAG_USE_SIGIO
695706f2543Smrg} FlagValues;
696706f2543Smrg
697706f2543Smrg/**
698706f2543Smrg * NOTE: the last value for each entry is NOT the default. It is set to TRUE
699706f2543Smrg * if the parser found the option in the config file.
700706f2543Smrg */
701706f2543Smrgstatic OptionInfoRec FlagOptions[] = {
702706f2543Smrg  { FLAG_NOTRAPSIGNALS,		"NoTrapSignals",		OPTV_BOOLEAN,
703706f2543Smrg	{0}, FALSE },
704706f2543Smrg  { FLAG_DONTVTSWITCH,		"DontVTSwitch",			OPTV_BOOLEAN,
705706f2543Smrg	{0}, FALSE },
706706f2543Smrg  { FLAG_DONTZAP,		"DontZap",			OPTV_BOOLEAN,
707706f2543Smrg	{0}, FALSE },
708706f2543Smrg  { FLAG_DONTZOOM,		"DontZoom",			OPTV_BOOLEAN,
709706f2543Smrg	{0}, FALSE },
710706f2543Smrg  { FLAG_DISABLEVIDMODE,	"DisableVidModeExtension",	OPTV_BOOLEAN,
711706f2543Smrg	{0}, FALSE },
712706f2543Smrg  { FLAG_ALLOWNONLOCAL,		"AllowNonLocalXvidtune",	OPTV_BOOLEAN,
713706f2543Smrg	{0}, FALSE },
714706f2543Smrg  { FLAG_ALLOWMOUSEOPENFAIL,	"AllowMouseOpenFail",		OPTV_BOOLEAN,
715706f2543Smrg	{0}, FALSE },
716706f2543Smrg  { FLAG_VTSYSREQ,		"VTSysReq",			OPTV_BOOLEAN,
717706f2543Smrg	{0}, FALSE },
718706f2543Smrg  { FLAG_SAVER_BLANKTIME,	"BlankTime"		,	OPTV_INTEGER,
719706f2543Smrg	{0}, FALSE },
720706f2543Smrg  { FLAG_DPMS_STANDBYTIME,	"StandbyTime",			OPTV_INTEGER,
721706f2543Smrg	{0}, FALSE },
722706f2543Smrg  { FLAG_DPMS_SUSPENDTIME,	"SuspendTime",			OPTV_INTEGER,
723706f2543Smrg	{0}, FALSE },
724706f2543Smrg  { FLAG_DPMS_OFFTIME,		"OffTime",			OPTV_INTEGER,
725706f2543Smrg	{0}, FALSE },
726706f2543Smrg  { FLAG_PIXMAP,		"Pixmap",			OPTV_INTEGER,
727706f2543Smrg	{0}, FALSE },
728706f2543Smrg  { FLAG_PC98,			"PC98",				OPTV_BOOLEAN,
729706f2543Smrg	{0}, FALSE },
730706f2543Smrg  { FLAG_NOPM,			"NoPM",				OPTV_BOOLEAN,
731706f2543Smrg	{0}, FALSE },
732706f2543Smrg  { FLAG_XINERAMA,		"Xinerama",			OPTV_BOOLEAN,
733706f2543Smrg	{0}, FALSE },
734706f2543Smrg  { FLAG_LOG,			"Log",				OPTV_STRING,
735706f2543Smrg	{0}, FALSE },
736706f2543Smrg  { FLAG_RENDER_COLORMAP_MODE,	"RenderColormapMode",		OPTV_STRING,
737706f2543Smrg        {0}, FALSE },
738706f2543Smrg  { FLAG_RANDR,			"RandR",			OPTV_BOOLEAN,
739706f2543Smrg	{0}, FALSE },
740706f2543Smrg  { FLAG_AIGLX,			"AIGLX",			OPTV_BOOLEAN,
741706f2543Smrg	{0}, FALSE },
742706f2543Smrg  { FLAG_IGNORE_ABI,		"IgnoreABI",			OPTV_BOOLEAN,
743706f2543Smrg	{0}, FALSE },
744706f2543Smrg  { FLAG_USE_DEFAULT_FONT_PATH,  "UseDefaultFontPath",		OPTV_BOOLEAN,
745706f2543Smrg	{0}, FALSE },
746706f2543Smrg  { FLAG_AUTO_ADD_DEVICES,       "AutoAddDevices",		OPTV_BOOLEAN,
747706f2543Smrg        {0}, FALSE },
748706f2543Smrg  { FLAG_AUTO_ENABLE_DEVICES,    "AutoEnableDevices",		OPTV_BOOLEAN,
749706f2543Smrg        {0}, FALSE },
750706f2543Smrg  { FLAG_GLX_VISUALS,		"GlxVisuals",			OPTV_STRING,
751706f2543Smrg        {0}, FALSE },
752706f2543Smrg  { FLAG_DRI2,			"DRI2",				OPTV_BOOLEAN,
753706f2543Smrg	{0}, FALSE },
754706f2543Smrg  { FLAG_USE_SIGIO,		"UseSIGIO",			OPTV_BOOLEAN,
755706f2543Smrg	{0}, FALSE },
756706f2543Smrg  { -1,				NULL,				OPTV_NONE,
757706f2543Smrg	{0}, FALSE },
758706f2543Smrg};
759706f2543Smrg
760706f2543Smrg#ifdef SUPPORT_PC98
761706f2543Smrgstatic Bool
762706f2543SmrgdetectPC98(void)
763706f2543Smrg{
764706f2543Smrg    unsigned char buf[2];
765706f2543Smrg
766706f2543Smrg    if (xf86ReadBIOS(0xf8000, 0xe80, buf, 2) != 2)
767706f2543Smrg	return FALSE;
768706f2543Smrg    if ((buf[0] == 0x98) && (buf[1] == 0x21))
769706f2543Smrg	return TRUE;
770706f2543Smrg    else
771706f2543Smrg	return FALSE;
772706f2543Smrg}
773706f2543Smrg#endif
774706f2543Smrg
775706f2543Smrgstatic Bool
776706f2543SmrgconfigServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
777706f2543Smrg{
778706f2543Smrg    XF86OptionPtr optp, tmp;
779706f2543Smrg    int i;
780706f2543Smrg    Pix24Flags pix24 = Pix24DontCare;
781706f2543Smrg    Bool value;
782706f2543Smrg    MessageType from;
783706f2543Smrg    const char *s;
784706f2543Smrg    XkbRMLVOSet set;
785706f2543Smrg    /* Default options. */
786706f2543Smrg    set.rules = "base";
787706f2543Smrg    set.model = "pc105";
788706f2543Smrg    set.layout = "us";
789706f2543Smrg    set.variant = NULL;
790706f2543Smrg    set.options = NULL;
791706f2543Smrg
792706f2543Smrg    /*
793706f2543Smrg     * Merge the ServerLayout and ServerFlags options.  The former have
794706f2543Smrg     * precedence over the latter.
795706f2543Smrg     */
796706f2543Smrg    optp = NULL;
797706f2543Smrg    if (flagsconf && flagsconf->flg_option_lst)
798706f2543Smrg	optp = xf86optionListDup(flagsconf->flg_option_lst);
799706f2543Smrg    if (layoutopts) {
800706f2543Smrg	tmp = xf86optionListDup(layoutopts);
801706f2543Smrg	if (optp)
802706f2543Smrg	    optp = xf86optionListMerge(optp, tmp);
803706f2543Smrg	else
804706f2543Smrg	    optp = tmp;
805706f2543Smrg    }
806706f2543Smrg
807706f2543Smrg    xf86ProcessOptions(-1, optp, FlagOptions);
808706f2543Smrg
809706f2543Smrg    xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
810706f2543Smrg    xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
811706f2543Smrg    xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
812706f2543Smrg    xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
813706f2543Smrg
814706f2543Smrg    xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
815706f2543Smrg    if (xf86Info.ignoreABI) {
816706f2543Smrg	    xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
817706f2543Smrg    }
818706f2543Smrg
819706f2543Smrg    if (xf86SIGIOSupported()) {
820706f2543Smrg	xf86Info.useSIGIO = xf86ReturnOptValBool(FlagOptions, FLAG_USE_SIGIO, USE_SIGIO_BY_DEFAULT);
821706f2543Smrg	if (xf86IsOptionSet(FlagOptions, FLAG_USE_SIGIO)) {
822706f2543Smrg	    from = X_CONFIG;
823706f2543Smrg	} else {
824706f2543Smrg	    from = X_DEFAULT;
825706f2543Smrg	}
826706f2543Smrg	if (!xf86Info.useSIGIO) {
827706f2543Smrg	    xf86Msg(from, "Disabling SIGIO handlers for input devices\n");
828706f2543Smrg	} else if (from == X_CONFIG) {
829706f2543Smrg	    xf86Msg(from, "Enabling SIGIO handlers for input devices\n");
830706f2543Smrg	}
831706f2543Smrg    } else {
832706f2543Smrg	xf86Info.useSIGIO = FALSE;
833706f2543Smrg    }
834706f2543Smrg
835706f2543Smrg    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
836706f2543Smrg        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
837706f2543Smrg                          &xf86Info.autoAddDevices);
838706f2543Smrg        from = X_CONFIG;
839706f2543Smrg    }
840706f2543Smrg    else {
841706f2543Smrg        from = X_DEFAULT;
842706f2543Smrg    }
843706f2543Smrg    xf86Msg(from, "%sutomatically adding devices\n",
844706f2543Smrg            xf86Info.autoAddDevices ? "A" : "Not a");
845706f2543Smrg
846706f2543Smrg    if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
847706f2543Smrg        xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
848706f2543Smrg                          &xf86Info.autoEnableDevices);
849706f2543Smrg        from = X_CONFIG;
850706f2543Smrg    }
851706f2543Smrg    else {
852706f2543Smrg        from = X_DEFAULT;
853706f2543Smrg    }
854706f2543Smrg    xf86Msg(from, "%sutomatically enabling devices\n",
855706f2543Smrg            xf86Info.autoEnableDevices ? "A" : "Not a");
856706f2543Smrg
857706f2543Smrg    /*
858706f2543Smrg     * Set things up based on the config file information.  Some of these
859706f2543Smrg     * settings may be overridden later when the command line options are
860706f2543Smrg     * checked.
861706f2543Smrg     */
862706f2543Smrg#ifdef XF86VIDMODE
863706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
864706f2543Smrg	xf86Info.vidModeEnabled = !value;
865706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
866706f2543Smrg	xf86Info.vidModeAllowNonLocal = value;
867706f2543Smrg#endif
868706f2543Smrg
869706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
870706f2543Smrg	xf86Info.allowMouseOpenFail = value;
871706f2543Smrg
872706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_VTSYSREQ, &value)) {
873706f2543Smrg#ifdef USE_VT_SYSREQ
874706f2543Smrg	xf86Info.vtSysreq = value;
875706f2543Smrg	xf86Msg(X_CONFIG, "VTSysReq %s\n", value ? "enabled" : "disabled");
876706f2543Smrg#else
877706f2543Smrg	if (value)
878706f2543Smrg	    xf86Msg(X_WARNING, "VTSysReq is not supported on this OS\n");
879706f2543Smrg#endif
880706f2543Smrg    }
881706f2543Smrg
882706f2543Smrg    xf86Info.pmFlag = TRUE;
883706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
884706f2543Smrg	xf86Info.pmFlag = !value;
885706f2543Smrg    {
886706f2543Smrg	if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
887706f2543Smrg	    if (!xf86NameCmp(s,"flush")) {
888706f2543Smrg		xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
889706f2543Smrg		xf86Info.log = LogFlush;
890706f2543Smrg		LogSetParameter(XLOG_FLUSH, TRUE);
891706f2543Smrg	    } else if (!xf86NameCmp(s,"sync")) {
892706f2543Smrg		xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
893706f2543Smrg		xf86Info.log = LogSync;
894706f2543Smrg		LogSetParameter(XLOG_FLUSH, TRUE);
895706f2543Smrg		LogSetParameter(XLOG_SYNC, TRUE);
896706f2543Smrg	    } else {
897706f2543Smrg		xf86Msg(X_WARNING,"Unknown Log option\n");
898706f2543Smrg	    }
899706f2543Smrg        }
900706f2543Smrg    }
901706f2543Smrg
902706f2543Smrg    {
903706f2543Smrg	if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
904706f2543Smrg	    int policy = PictureParseCmapPolicy (s);
905706f2543Smrg	    if (policy == PictureCmapPolicyInvalid)
906706f2543Smrg		xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
907706f2543Smrg	    else
908706f2543Smrg	    {
909706f2543Smrg		xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
910706f2543Smrg		PictureCmapPolicy = policy;
911706f2543Smrg	    }
912706f2543Smrg	}
913706f2543Smrg    }
914706f2543Smrg
915706f2543Smrg#ifdef RANDR
916706f2543Smrg    xf86Info.disableRandR = FALSE;
917706f2543Smrg    xf86Info.randRFrom = X_DEFAULT;
918706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
919706f2543Smrg	xf86Info.disableRandR = !value;
920706f2543Smrg	xf86Info.randRFrom = X_CONFIG;
921706f2543Smrg    }
922706f2543Smrg#endif
923706f2543Smrg
924706f2543Smrg    xf86Info.aiglx = TRUE;
925706f2543Smrg    xf86Info.aiglxFrom = X_DEFAULT;
926706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
927706f2543Smrg	xf86Info.aiglx = value;
928706f2543Smrg	xf86Info.aiglxFrom = X_CONFIG;
929706f2543Smrg    }
930706f2543Smrg
931706f2543Smrg#ifdef GLXEXT
932706f2543Smrg    xf86Info.glxVisuals = XF86_GlxVisualsTypical;
933706f2543Smrg    xf86Info.glxVisualsFrom = X_DEFAULT;
934706f2543Smrg    if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
935706f2543Smrg	if (!xf86NameCmp(s, "minimal")) {
936706f2543Smrg	    xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
937706f2543Smrg	} else if (!xf86NameCmp(s, "typical")) {
938706f2543Smrg	    xf86Info.glxVisuals = XF86_GlxVisualsTypical;
939706f2543Smrg	} else if (!xf86NameCmp(s, "all")) {
940706f2543Smrg	    xf86Info.glxVisuals = XF86_GlxVisualsAll;
941706f2543Smrg	} else {
942706f2543Smrg	    xf86Msg(X_WARNING,"Unknown GlxVisuals option\n");
943706f2543Smrg	}
944706f2543Smrg    }
945706f2543Smrg
946706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
947706f2543Smrg	xf86Info.aiglx = value;
948706f2543Smrg	xf86Info.aiglxFrom = X_CONFIG;
949706f2543Smrg    }
950706f2543Smrg#endif
951706f2543Smrg
952706f2543Smrg    /* if we're not hotplugging, force some input devices to exist */
953706f2543Smrg    xf86Info.forceInputDevices = !(xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
954706f2543Smrg
955706f2543Smrg    /* when forcing input devices, we use kbd. otherwise evdev, so use the
956706f2543Smrg     * evdev rules set. */
957706f2543Smrg#if defined(linux)
958706f2543Smrg    if (!xf86Info.forceInputDevices)
959706f2543Smrg        set.rules = "evdev";
960706f2543Smrg#endif
961706f2543Smrg    XkbSetRulesDflts(&set);
962706f2543Smrg
963706f2543Smrg    xf86Info.useDefaultFontPath = TRUE;
964706f2543Smrg    xf86Info.useDefaultFontPathFrom = X_DEFAULT;
965706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
966706f2543Smrg	xf86Info.useDefaultFontPath = value;
967706f2543Smrg	xf86Info.useDefaultFontPathFrom = X_CONFIG;
968706f2543Smrg    }
969706f2543Smrg
970706f2543Smrg/* Make sure that timers don't overflow CARD32's after multiplying */
971706f2543Smrg#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
972706f2543Smrg
973706f2543Smrg    i = -1;
974706f2543Smrg    xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
975706f2543Smrg    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
976706f2543Smrg	ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
977706f2543Smrg    else if (i != -1)
978706f2543Smrg	xf86ConfigError("BlankTime value %d outside legal range of 0 - %d minutes",
979706f2543Smrg			i, MAX_TIME_IN_MIN);
980706f2543Smrg
981706f2543Smrg#ifdef DPMSExtension
982706f2543Smrg    i = -1;
983706f2543Smrg    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
984706f2543Smrg    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
985706f2543Smrg	DPMSStandbyTime = i * MILLI_PER_MIN;
986706f2543Smrg    else if (i != -1)
987706f2543Smrg	xf86ConfigError("StandbyTime value %d outside legal range of 0 - %d minutes",
988706f2543Smrg			i, MAX_TIME_IN_MIN);
989706f2543Smrg    i = -1;
990706f2543Smrg    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
991706f2543Smrg    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
992706f2543Smrg	DPMSSuspendTime = i * MILLI_PER_MIN;
993706f2543Smrg    else if (i != -1)
994706f2543Smrg	xf86ConfigError("SuspendTime value %d outside legal range of 0 - %d minutes",
995706f2543Smrg			i, MAX_TIME_IN_MIN);
996706f2543Smrg    i = -1;
997706f2543Smrg    xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
998706f2543Smrg    if ((i >= 0) && (i < MAX_TIME_IN_MIN))
999706f2543Smrg	DPMSOffTime = i * MILLI_PER_MIN;
1000706f2543Smrg    else if (i != -1)
1001706f2543Smrg	xf86ConfigError("OffTime value %d outside legal range of 0 - %d minutes",
1002706f2543Smrg			i, MAX_TIME_IN_MIN);
1003706f2543Smrg#endif
1004706f2543Smrg
1005706f2543Smrg    i = -1;
1006706f2543Smrg    xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
1007706f2543Smrg    switch (i) {
1008706f2543Smrg    case 24:
1009706f2543Smrg	pix24 = Pix24Use24;
1010706f2543Smrg	break;
1011706f2543Smrg    case 32:
1012706f2543Smrg	pix24 = Pix24Use32;
1013706f2543Smrg	break;
1014706f2543Smrg    case -1:
1015706f2543Smrg	break;
1016706f2543Smrg    default:
1017706f2543Smrg	xf86ConfigError("Pixmap option's value (%d) must be 24 or 32\n", i);
1018706f2543Smrg	return FALSE;
1019706f2543Smrg    }
1020706f2543Smrg    if (xf86Pix24 != Pix24DontCare) {
1021706f2543Smrg	xf86Info.pixmap24 = xf86Pix24;
1022706f2543Smrg	xf86Info.pix24From = X_CMDLINE;
1023706f2543Smrg    } else if (pix24 != Pix24DontCare) {
1024706f2543Smrg	xf86Info.pixmap24 = pix24;
1025706f2543Smrg	xf86Info.pix24From = X_CONFIG;
1026706f2543Smrg    } else {
1027706f2543Smrg	xf86Info.pixmap24 = Pix24DontCare;
1028706f2543Smrg	xf86Info.pix24From = X_DEFAULT;
1029706f2543Smrg    }
1030706f2543Smrg#ifdef SUPPORT_PC98
1031706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
1032706f2543Smrg	xf86Info.pc98 = value;
1033706f2543Smrg	if (value) {
1034706f2543Smrg	    xf86Msg(X_CONFIG, "Japanese PC98 architecture\n");
1035706f2543Smrg	}
1036706f2543Smrg    } else
1037706f2543Smrg	if (detectPC98()) {
1038706f2543Smrg	    xf86Info.pc98 = TRUE;
1039706f2543Smrg	    xf86Msg(X_PROBED, "Japanese PC98 architecture\n");
1040706f2543Smrg	}
1041706f2543Smrg#endif
1042706f2543Smrg
1043706f2543Smrg#ifdef PANORAMIX
1044706f2543Smrg    from = X_DEFAULT;
1045706f2543Smrg    if (!noPanoramiXExtension)
1046706f2543Smrg      from = X_CMDLINE;
1047706f2543Smrg    else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
1048706f2543Smrg      noPanoramiXExtension = !value;
1049706f2543Smrg      from = X_CONFIG;
1050706f2543Smrg    }
1051706f2543Smrg    if (!noPanoramiXExtension)
1052706f2543Smrg      xf86Msg(from, "Xinerama: enabled\n");
1053706f2543Smrg#endif
1054706f2543Smrg
1055706f2543Smrg#ifdef DRI2
1056706f2543Smrg    xf86Info.dri2 = FALSE;
1057706f2543Smrg    xf86Info.dri2From = X_DEFAULT;
1058706f2543Smrg    if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
1059706f2543Smrg	xf86Info.dri2 = value;
1060706f2543Smrg	xf86Info.dri2From = X_CONFIG;
1061706f2543Smrg    }
1062706f2543Smrg#endif
1063706f2543Smrg
1064706f2543Smrg    return TRUE;
1065706f2543Smrg}
1066706f2543Smrg
1067706f2543SmrgBool xf86DRI2Enabled(void)
1068706f2543Smrg{
1069706f2543Smrg    return xf86Info.dri2;
1070706f2543Smrg}
1071706f2543Smrg
1072706f2543Smrg/*
1073706f2543Smrg * Locate the core input devices.  These can be specified/located in
1074706f2543Smrg * the following ways, in order of priority:
1075706f2543Smrg *
1076706f2543Smrg *  1. The InputDevices named by the -pointer and -keyboard command line
1077706f2543Smrg *     options.
1078706f2543Smrg *  2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
1079706f2543Smrg *     the active ServerLayout.
1080706f2543Smrg *  3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
1081706f2543Smrg *  4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
1082706f2543Smrg *     driver (mouse, synaptics, evdev, vmmouse, void)
1083706f2543Smrg *  5. Default devices with an empty (default) configuration.  These defaults
1084706f2543Smrg *     will reference the 'mouse' and 'keyboard' drivers.
1085706f2543Smrg */
1086706f2543Smrg
1087706f2543Smrgstatic Bool
1088706f2543SmrgcheckCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
1089706f2543Smrg{
1090706f2543Smrg    InputInfoPtr corePointer = NULL, coreKeyboard = NULL;
1091706f2543Smrg    Bool foundPointer = FALSE, foundKeyboard = FALSE;
1092706f2543Smrg    const char *pointerMsg = NULL, *keyboardMsg = NULL;
1093706f2543Smrg    InputInfoPtr *devs, /* iterator */
1094706f2543Smrg            indp;
1095706f2543Smrg    InputInfoRec Pointer = {}, Keyboard = {};
1096706f2543Smrg    XF86ConfInputPtr confInput;
1097706f2543Smrg    XF86ConfInputRec defPtr, defKbd;
1098706f2543Smrg    int count = 0;
1099706f2543Smrg    MessageType from = X_DEFAULT;
1100706f2543Smrg    int found = 0;
1101706f2543Smrg    const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
1102706f2543Smrg				   "void", NULL };
1103706f2543Smrg
1104706f2543Smrg    /*
1105706f2543Smrg     * First check if a core pointer or core keyboard have been specified
1106706f2543Smrg     * in the active ServerLayout.  If more than one is specified for either,
1107706f2543Smrg     * remove the core attribute from the later ones.
1108706f2543Smrg     */
1109706f2543Smrg    for (devs = servlayoutp->inputs; devs && *devs; devs++) {
1110706f2543Smrg        indp = *devs;
1111706f2543Smrg	if (indp->options &&
1112706f2543Smrg	    xf86CheckBoolOption(indp->options, "CorePointer", FALSE)) {
1113706f2543Smrg	    if (!corePointer) {
1114706f2543Smrg		corePointer = indp;
1115706f2543Smrg	    } else {
1116706f2543Smrg		    xf86ReplaceBoolOption(indp->options, "CorePointer", FALSE);
1117706f2543Smrg		xf86Msg(X_WARNING, "Duplicate core pointer devices.  "
1118706f2543Smrg			"Removing core pointer attribute from \"%s\"\n",
1119706f2543Smrg			indp->name);
1120706f2543Smrg	    }
1121706f2543Smrg	}
1122706f2543Smrg	if (indp->options &&
1123706f2543Smrg	    xf86CheckBoolOption(indp->options, "CoreKeyboard", FALSE)) {
1124706f2543Smrg	    if (!coreKeyboard) {
1125706f2543Smrg		coreKeyboard = indp;
1126706f2543Smrg	    } else {
1127706f2543Smrg		    xf86ReplaceBoolOption(indp->options, "CoreKeyboard", FALSE);
1128706f2543Smrg		xf86Msg(X_WARNING, "Duplicate core keyboard devices.  "
1129706f2543Smrg			"Removing core keyboard attribute from \"%s\"\n",
1130706f2543Smrg			indp->name);
1131706f2543Smrg	    }
1132706f2543Smrg	}
1133706f2543Smrg	count++;
1134706f2543Smrg    }
1135706f2543Smrg
1136706f2543Smrg    confInput = NULL;
1137706f2543Smrg
1138706f2543Smrg    /* 1. Check for the -pointer command line option. */
1139706f2543Smrg    if (xf86PointerName) {
1140706f2543Smrg	confInput = xf86findInput(xf86PointerName,
1141706f2543Smrg				  xf86configptr->conf_input_lst);
1142706f2543Smrg	if (!confInput) {
1143706f2543Smrg	    xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1144706f2543Smrg		    xf86PointerName);
1145706f2543Smrg	    return FALSE;
1146706f2543Smrg	}
1147706f2543Smrg	from = X_CMDLINE;
1148706f2543Smrg	/*
1149706f2543Smrg	 * If one was already specified in the ServerLayout, it needs to be
1150706f2543Smrg	 * removed.
1151706f2543Smrg	 */
1152706f2543Smrg	if (corePointer) {
1153706f2543Smrg	    for (devs = servlayoutp->inputs; devs && *devs; devs++)
1154706f2543Smrg		if (*devs == corePointer)
1155706f2543Smrg                {
1156706f2543Smrg                    free(*devs);
1157706f2543Smrg                    *devs = (InputInfoPtr)0x1; /* ensure we dont skip next loop*/
1158706f2543Smrg		    break;
1159706f2543Smrg                }
1160706f2543Smrg	    for (; devs && *devs; devs++)
1161706f2543Smrg		devs[0] = devs[1];
1162706f2543Smrg	    count--;
1163706f2543Smrg	}
1164706f2543Smrg	corePointer = NULL;
1165706f2543Smrg	foundPointer = TRUE;
1166706f2543Smrg    }
1167706f2543Smrg
1168706f2543Smrg    /* 2. ServerLayout-specified core pointer. */
1169706f2543Smrg    if (corePointer) {
1170706f2543Smrg	foundPointer = TRUE;
1171706f2543Smrg	from = X_CONFIG;
1172706f2543Smrg    }
1173706f2543Smrg
1174706f2543Smrg    /* 3. First core pointer device. */
1175706f2543Smrg    if (!foundPointer && (xf86Info.forceInputDevices || implicitLayout)) {
1176706f2543Smrg	XF86ConfInputPtr p;
1177706f2543Smrg
1178706f2543Smrg	for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1179706f2543Smrg	    if (p->inp_option_lst &&
1180706f2543Smrg		xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
1181706f2543Smrg		confInput = p;
1182706f2543Smrg		foundPointer = TRUE;
1183706f2543Smrg		from = X_DEFAULT;
1184706f2543Smrg		pointerMsg = "first core pointer device";
1185706f2543Smrg		break;
1186706f2543Smrg	    }
1187706f2543Smrg	}
1188706f2543Smrg    }
1189706f2543Smrg
1190706f2543Smrg    /* 4. First pointer with an allowed mouse driver. */
1191706f2543Smrg    if (!foundPointer && xf86Info.forceInputDevices) {
1192706f2543Smrg	const char **driver = mousedrivers;
1193706f2543Smrg	confInput = xf86findInput(CONF_IMPLICIT_POINTER,
1194706f2543Smrg				  xf86configptr->conf_input_lst);
1195706f2543Smrg	while (*driver && !confInput) {
1196706f2543Smrg	    confInput = xf86findInputByDriver(*driver,
1197706f2543Smrg					      xf86configptr->conf_input_lst);
1198706f2543Smrg	    driver++;
1199706f2543Smrg	}
1200706f2543Smrg	if (confInput) {
1201706f2543Smrg	    foundPointer = TRUE;
1202706f2543Smrg	    from = X_DEFAULT;
1203706f2543Smrg	    pointerMsg = "first mouse device";
1204706f2543Smrg	}
1205706f2543Smrg    }
1206706f2543Smrg
1207706f2543Smrg    /* 5. Built-in default. */
1208706f2543Smrg    if (!foundPointer && xf86Info.forceInputDevices) {
1209706f2543Smrg	memset(&defPtr, 0, sizeof(defPtr));
1210706f2543Smrg	defPtr.inp_identifier = strdup("<default pointer>");
1211706f2543Smrg#if defined(__NetBSD__) && (defined(__i386__) || defined(__amd64__))
1212706f2543Smrg	if (xf86findDeviceByDriver("vmware", xf86configptr->conf_device_lst) ||
1213706f2543Smrg	    xf86findDeviceByDriver("vmwlegacy", xf86configptr->conf_device_lst)) {
1214706f2543Smrg		defPtr.inp_driver = strdup("vmmouse");
1215706f2543Smrg		defPtr.inp_option_lst = xf86addNewOption(defPtr.inp_option_lst, strdup("Protocol"), "wsmouse");
1216706f2543Smrg		defPtr.inp_option_lst = xf86addNewOption(defPtr.inp_option_lst, strdup("Device"), "/dev/wsmouse");
1217706f2543Smrg	} else
1218706f2543Smrg#endif
1219706f2543Smrg	defPtr.inp_driver = strdup("mouse");
1220706f2543Smrg	confInput = &defPtr;
1221706f2543Smrg	foundPointer = TRUE;
1222706f2543Smrg	from = X_DEFAULT;
1223706f2543Smrg	pointerMsg = "default mouse configuration";
1224706f2543Smrg    }
1225706f2543Smrg
1226706f2543Smrg    /* Add the core pointer device to the layout, and set it to Core. */
1227706f2543Smrg    if (foundPointer && confInput) {
1228706f2543Smrg	foundPointer = configInput(&Pointer, confInput, from);
1229706f2543Smrg        if (foundPointer) {
1230706f2543Smrg	    count++;
1231706f2543Smrg	    devs = xnfrealloc(servlayoutp->inputs,
1232706f2543Smrg			      (count + 1) * sizeof(InputInfoPtr));
1233706f2543Smrg            devs[count - 1] = xnfalloc(sizeof(InputInfoRec));
1234706f2543Smrg            Pointer.fd = -1;
1235706f2543Smrg	    *devs[count - 1] = Pointer;
1236706f2543Smrg	    devs[count - 1]->options =
1237706f2543Smrg				xf86addNewOption(devs[count -1]->options,
1238706f2543Smrg				    xnfstrdup("CorePointer"), NULL);
1239706f2543Smrg	    devs[count] = NULL;
1240706f2543Smrg	    servlayoutp->inputs = devs;
1241706f2543Smrg	}
1242706f2543Smrg    }
1243706f2543Smrg
1244706f2543Smrg    if (!foundPointer && xf86Info.forceInputDevices) {
1245706f2543Smrg	/* This shouldn't happen. */
1246706f2543Smrg	xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
1247706f2543Smrg	return FALSE;
1248706f2543Smrg    }
1249706f2543Smrg
1250706f2543Smrg    /*
1251706f2543Smrg     * always synthesize a 'mouse' section configured to send core
1252706f2543Smrg     * events, unless a 'void' section is found, in which case the user
1253706f2543Smrg     * probably wants to run footless.
1254706f2543Smrg     *
1255706f2543Smrg     * If you're using an evdev keyboard and expect a default mouse
1256706f2543Smrg     * section ... deal.
1257706f2543Smrg     */
1258706f2543Smrg    for (devs = servlayoutp->inputs; devs && *devs; devs++) {
1259706f2543Smrg	const char **driver = mousedrivers;
1260706f2543Smrg	while(*driver) {
1261706f2543Smrg	    if (!strcmp((*devs)->driver, *driver)) {
1262706f2543Smrg		found = 1;
1263706f2543Smrg		break;
1264706f2543Smrg	    }
1265706f2543Smrg	    driver++;
1266706f2543Smrg	}
1267706f2543Smrg    }
1268706f2543Smrg    if (!found && xf86Info.forceInputDevices) {
1269706f2543Smrg	xf86Msg(X_INFO, "No default mouse found, adding one\n");
1270706f2543Smrg	memset(&defPtr, 0, sizeof(defPtr));
1271706f2543Smrg	defPtr.inp_identifier = strdup("<default pointer>");
1272706f2543Smrg	defPtr.inp_driver = strdup("mouse");
1273706f2543Smrg	confInput = &defPtr;
1274706f2543Smrg	foundPointer = configInput(&Pointer, confInput, from);
1275706f2543Smrg        if (foundPointer) {
1276706f2543Smrg	    count++;
1277706f2543Smrg	    devs = xnfrealloc(servlayoutp->inputs,
1278706f2543Smrg			      (count + 1) * sizeof(InputInfoPtr));
1279706f2543Smrg            devs[count - 1] = xnfalloc(sizeof(InputInfoRec));
1280706f2543Smrg            Pointer.fd = -1;
1281706f2543Smrg	    *devs[count - 1] = Pointer;
1282706f2543Smrg	    devs[count - 1]->options =
1283706f2543Smrg				xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
1284706f2543Smrg	    devs[count] = NULL;
1285706f2543Smrg	    servlayoutp->inputs = devs;
1286706f2543Smrg	}
1287706f2543Smrg    }
1288706f2543Smrg
1289706f2543Smrg    confInput = NULL;
1290706f2543Smrg
1291706f2543Smrg    /* 1. Check for the -keyboard command line option. */
1292706f2543Smrg    if (xf86KeyboardName) {
1293706f2543Smrg	confInput = xf86findInput(xf86KeyboardName,
1294706f2543Smrg				  xf86configptr->conf_input_lst);
1295706f2543Smrg	if (!confInput) {
1296706f2543Smrg	    xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
1297706f2543Smrg		    xf86KeyboardName);
1298706f2543Smrg	    return FALSE;
1299706f2543Smrg	}
1300706f2543Smrg	from = X_CMDLINE;
1301706f2543Smrg	/*
1302706f2543Smrg	 * If one was already specified in the ServerLayout, it needs to be
1303706f2543Smrg	 * removed.
1304706f2543Smrg	 */
1305706f2543Smrg	if (coreKeyboard) {
1306706f2543Smrg	    for (devs = servlayoutp->inputs; devs && *devs; devs++)
1307706f2543Smrg		if (*devs == coreKeyboard)
1308706f2543Smrg                {
1309706f2543Smrg                    free(*devs);
1310706f2543Smrg                    *devs = (InputInfoPtr)0x1; /* ensure we dont skip next loop */
1311706f2543Smrg		    break;
1312706f2543Smrg                }
1313706f2543Smrg	    for (; devs && *devs; devs++)
1314706f2543Smrg		devs[0] = devs[1];
1315706f2543Smrg	    count--;
1316706f2543Smrg	}
1317706f2543Smrg	coreKeyboard = NULL;
1318706f2543Smrg	foundKeyboard = TRUE;
1319706f2543Smrg    }
1320706f2543Smrg
1321706f2543Smrg    /* 2. ServerLayout-specified core keyboard. */
1322706f2543Smrg    if (coreKeyboard) {
1323706f2543Smrg	foundKeyboard = TRUE;
1324706f2543Smrg	from = X_CONFIG;
1325706f2543Smrg    }
1326706f2543Smrg
1327706f2543Smrg    /* 3. First core keyboard device. */
1328706f2543Smrg    if (!foundKeyboard && (xf86Info.forceInputDevices || implicitLayout)) {
1329706f2543Smrg	XF86ConfInputPtr p;
1330706f2543Smrg
1331706f2543Smrg	for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
1332706f2543Smrg	    if (p->inp_option_lst &&
1333706f2543Smrg		xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
1334706f2543Smrg		confInput = p;
1335706f2543Smrg		foundKeyboard = TRUE;
1336706f2543Smrg		from = X_DEFAULT;
1337706f2543Smrg		keyboardMsg = "first core keyboard device";
1338706f2543Smrg		break;
1339706f2543Smrg	    }
1340706f2543Smrg	}
1341706f2543Smrg    }
1342706f2543Smrg
1343706f2543Smrg    /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
1344706f2543Smrg    if (!foundKeyboard && xf86Info.forceInputDevices) {
1345706f2543Smrg	confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
1346706f2543Smrg				  xf86configptr->conf_input_lst);
1347706f2543Smrg	if (!confInput) {
1348706f2543Smrg	    confInput = xf86findInputByDriver("kbd",
1349706f2543Smrg					      xf86configptr->conf_input_lst);
1350706f2543Smrg	}
1351706f2543Smrg	if (confInput) {
1352706f2543Smrg	    foundKeyboard = TRUE;
1353706f2543Smrg	    from = X_DEFAULT;
1354706f2543Smrg	    keyboardMsg = "first keyboard device";
1355706f2543Smrg	}
1356706f2543Smrg    }
1357706f2543Smrg
1358706f2543Smrg    /* 5. Built-in default. */
1359706f2543Smrg    if (!foundKeyboard && xf86Info.forceInputDevices) {
1360706f2543Smrg	memset(&defKbd, 0, sizeof(defKbd));
1361706f2543Smrg	defKbd.inp_identifier = strdup("<default keyboard>");
1362706f2543Smrg	defKbd.inp_driver = strdup("kbd");
1363706f2543Smrg	confInput = &defKbd;
1364706f2543Smrg	foundKeyboard = TRUE;
1365706f2543Smrg	keyboardMsg = "default keyboard configuration";
1366706f2543Smrg	from = X_DEFAULT;
1367706f2543Smrg    }
1368706f2543Smrg
1369706f2543Smrg    /* Add the core keyboard device to the layout, and set it to Core. */
1370706f2543Smrg    if (foundKeyboard && confInput) {
1371706f2543Smrg	foundKeyboard = configInput(&Keyboard, confInput, from);
1372706f2543Smrg        if (foundKeyboard) {
1373706f2543Smrg	    count++;
1374706f2543Smrg	    devs = xnfrealloc(servlayoutp->inputs,
1375706f2543Smrg			      (count + 1) * sizeof(InputInfoPtr));
1376706f2543Smrg            devs[count - 1] = xnfalloc(sizeof(InputInfoRec));
1377706f2543Smrg            Keyboard.fd = -1;
1378706f2543Smrg	    *devs[count - 1] = Keyboard;
1379706f2543Smrg	    devs[count - 1]->options =
1380706f2543Smrg				xf86addNewOption(devs[count - 1]->options,
1381706f2543Smrg				    xnfstrdup("CoreKeyboard"), NULL);
1382706f2543Smrg	    devs[count] = NULL;
1383706f2543Smrg	    servlayoutp->inputs = devs;
1384706f2543Smrg	}
1385706f2543Smrg    }
1386706f2543Smrg
1387706f2543Smrg    if (!foundKeyboard && xf86Info.forceInputDevices) {
1388706f2543Smrg	/* This shouldn't happen. */
1389706f2543Smrg	xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
1390706f2543Smrg	return FALSE;
1391706f2543Smrg    }
1392706f2543Smrg
1393706f2543Smrg    if (pointerMsg) {
1394706f2543Smrg	if (implicitLayout)
1395706f2543Smrg	    xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1396706f2543Smrg	            pointerMsg);
1397706f2543Smrg	else
1398706f2543Smrg	    xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
1399706f2543Smrg	            "explicitly in the layout.\n"
1400706f2543Smrg	            "\tUsing the %s.\n", pointerMsg);
1401706f2543Smrg    }
1402706f2543Smrg
1403706f2543Smrg    if (keyboardMsg) {
1404706f2543Smrg	if (implicitLayout)
1405706f2543Smrg	    xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
1406706f2543Smrg	            keyboardMsg);
1407706f2543Smrg	else
1408706f2543Smrg	    xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
1409706f2543Smrg	            "explicitly in the layout.\n"
1410706f2543Smrg	            "\tUsing the %s.\n", keyboardMsg);
1411706f2543Smrg    }
1412706f2543Smrg
1413706f2543Smrg    if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) {
1414706f2543Smrg#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
1415706f2543Smrg	const char *config_backend;
1416706f2543Smrg#if defined(CONFIG_HAL)
1417706f2543Smrg	config_backend = "HAL";
1418706f2543Smrg#else
1419706f2543Smrg	config_backend = "udev";
1420706f2543Smrg#endif
1421706f2543Smrg	xf86Msg(X_INFO, "The server relies on %s to provide the list of "
1422706f2543Smrg	                "input devices.\n\tIf no devices become available, "
1423706f2543Smrg	                "reconfigure %s or disable AutoAddDevices.\n",
1424706f2543Smrg			config_backend, config_backend);
1425706f2543Smrg#else
1426706f2543Smrg	xf86Msg(X_WARNING, "Hotplugging requested but the server was "
1427706f2543Smrg			   "compiled without a config backend. "
1428706f2543Smrg			   "No input devices were configured, the server "
1429706f2543Smrg			   "will start without any input devices.\n");
1430706f2543Smrg#endif
1431706f2543Smrg    }
1432706f2543Smrg
1433706f2543Smrg    return TRUE;
1434706f2543Smrg}
1435706f2543Smrg
1436706f2543Smrgtypedef enum {
1437706f2543Smrg    LAYOUT_ISOLATEDEVICE,
1438706f2543Smrg    LAYOUT_SINGLECARD
1439706f2543Smrg} LayoutValues;
1440706f2543Smrg
1441706f2543Smrgstatic OptionInfoRec LayoutOptions[] = {
1442706f2543Smrg  { LAYOUT_ISOLATEDEVICE,      "IsolateDevice",        OPTV_STRING,
1443706f2543Smrg       {0}, FALSE },
1444706f2543Smrg  { LAYOUT_SINGLECARD,         "SingleCard",           OPTV_BOOLEAN,
1445706f2543Smrg       {0}, FALSE },
1446706f2543Smrg  { -1,                                NULL,                   OPTV_NONE,
1447706f2543Smrg       {0}, FALSE },
1448706f2543Smrg};
1449706f2543Smrg
1450706f2543Smrgstatic Bool
1451706f2543SmrgconfigInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
1452706f2543Smrg{
1453706f2543Smrg    XF86ConfInputrefPtr irp;
1454706f2543Smrg    InputInfoPtr *indp;
1455706f2543Smrg    int count = 0;
1456706f2543Smrg
1457706f2543Smrg    /*
1458706f2543Smrg     * Count the number of input devices.
1459706f2543Smrg     */
1460706f2543Smrg    irp = layout->lay_input_lst;
1461706f2543Smrg    while (irp) {
1462706f2543Smrg	count++;
1463706f2543Smrg	irp = (XF86ConfInputrefPtr)irp->list.next;
1464706f2543Smrg    }
1465706f2543Smrg    DebugF("Found %d input devices in the layout section %s\n",
1466706f2543Smrg	    count, layout->lay_identifier);
1467706f2543Smrg    indp = xnfcalloc((count + 1), sizeof(InputInfoPtr));
1468706f2543Smrg    indp[count] = NULL;
1469706f2543Smrg    irp = layout->lay_input_lst;
1470706f2543Smrg    count = 0;
1471706f2543Smrg    while (irp) {
1472706f2543Smrg	indp[count] = xf86AllocateInput();
1473706f2543Smrg	if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
1474706f2543Smrg	    do {
1475706f2543Smrg		free(indp[count]);
1476706f2543Smrg	    } while(count--);
1477706f2543Smrg	    free(indp);
1478706f2543Smrg	    return FALSE;
1479706f2543Smrg	}
1480706f2543Smrg	indp[count]->options = xf86OptionListMerge(indp[count]->options,
1481706f2543Smrg						   irp->iref_option_lst);
1482706f2543Smrg	count++;
1483706f2543Smrg	irp = (XF86ConfInputrefPtr)irp->list.next;
1484706f2543Smrg    }
1485706f2543Smrg    servlayoutp->inputs = indp;
1486706f2543Smrg
1487706f2543Smrg    return TRUE;
1488706f2543Smrg}
1489706f2543Smrg
1490706f2543Smrg
1491706f2543Smrg/*
1492706f2543Smrg * figure out which layout is active, which screens are used in that layout,
1493706f2543Smrg * which drivers and monitors are used in these screens
1494706f2543Smrg */
1495706f2543Smrgstatic Bool
1496706f2543SmrgconfigLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
1497706f2543Smrg	     char *default_layout)
1498706f2543Smrg{
1499706f2543Smrg    XF86ConfAdjacencyPtr adjp;
1500706f2543Smrg    XF86ConfInactivePtr idp;
1501706f2543Smrg    int saved_count, count = 0;
1502706f2543Smrg    int scrnum;
1503706f2543Smrg    XF86ConfLayoutPtr l;
1504706f2543Smrg    MessageType from;
1505706f2543Smrg    screenLayoutPtr slp;
1506706f2543Smrg    GDevPtr gdp;
1507706f2543Smrg    int i = 0, j;
1508706f2543Smrg
1509706f2543Smrg    if (!servlayoutp)
1510706f2543Smrg	return FALSE;
1511706f2543Smrg
1512706f2543Smrg    /*
1513706f2543Smrg     * which layout section is the active one?
1514706f2543Smrg     *
1515706f2543Smrg     * If there is a -layout command line option, use that one, otherwise
1516706f2543Smrg     * pick the first one.
1517706f2543Smrg     */
1518706f2543Smrg    from = X_DEFAULT;
1519706f2543Smrg    if (xf86LayoutName != NULL)
1520706f2543Smrg	from = X_CMDLINE;
1521706f2543Smrg    else if (default_layout) {
1522706f2543Smrg	xf86LayoutName = default_layout;
1523706f2543Smrg	from = X_CONFIG;
1524706f2543Smrg    }
1525706f2543Smrg    if (xf86LayoutName != NULL) {
1526706f2543Smrg	if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
1527706f2543Smrg	    xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
1528706f2543Smrg		    xf86LayoutName);
1529706f2543Smrg	    return FALSE;
1530706f2543Smrg	}
1531706f2543Smrg	conf_layout = l;
1532706f2543Smrg    }
1533706f2543Smrg    xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
1534706f2543Smrg    adjp = conf_layout->lay_adjacency_lst;
1535706f2543Smrg
1536706f2543Smrg    /*
1537706f2543Smrg     * we know that each screen is referenced exactly once on the left side
1538706f2543Smrg     * of a layout statement in the Layout section. So to allocate the right
1539706f2543Smrg     * size for the array we do a quick walk of the list to figure out how
1540706f2543Smrg     * many sections we have
1541706f2543Smrg     */
1542706f2543Smrg    while (adjp) {
1543706f2543Smrg        count++;
1544706f2543Smrg        adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
1545706f2543Smrg    }
1546706f2543Smrg
1547706f2543Smrg    DebugF("Found %d screens in the layout section %s",
1548706f2543Smrg           count, conf_layout->lay_identifier);
1549706f2543Smrg    if (!count) /* alloc enough storage even if no screen is specified */
1550706f2543Smrg        count = 1;
1551706f2543Smrg
1552706f2543Smrg    slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
1553706f2543Smrg    slp[count].screen = NULL;
1554706f2543Smrg    /*
1555706f2543Smrg     * now that we have storage, loop over the list again and fill in our
1556706f2543Smrg     * data structure; at this point we do not fill in the adjacency
1557706f2543Smrg     * information as it is not clear if we need it at all
1558706f2543Smrg     */
1559706f2543Smrg    adjp = conf_layout->lay_adjacency_lst;
1560706f2543Smrg    count = 0;
1561706f2543Smrg    while (adjp) {
1562706f2543Smrg        slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
1563706f2543Smrg	if (adjp->adj_scrnum < 0)
1564706f2543Smrg	    scrnum = count;
1565706f2543Smrg	else
1566706f2543Smrg	    scrnum = adjp->adj_scrnum;
1567706f2543Smrg	if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
1568706f2543Smrg			  X_CONFIG)) {
1569706f2543Smrg	    do {
1570706f2543Smrg		free(slp[count].screen);
1571706f2543Smrg	    } while(count--);
1572706f2543Smrg	    free(slp);
1573706f2543Smrg	    return FALSE;
1574706f2543Smrg	}
1575706f2543Smrg	slp[count].x = adjp->adj_x;
1576706f2543Smrg	slp[count].y = adjp->adj_y;
1577706f2543Smrg	slp[count].refname = adjp->adj_refscreen;
1578706f2543Smrg	switch (adjp->adj_where) {
1579706f2543Smrg	case CONF_ADJ_OBSOLETE:
1580706f2543Smrg	    slp[count].where = PosObsolete;
1581706f2543Smrg	    slp[count].topname = adjp->adj_top_str;
1582706f2543Smrg	    slp[count].bottomname = adjp->adj_bottom_str;
1583706f2543Smrg	    slp[count].leftname = adjp->adj_left_str;
1584706f2543Smrg	    slp[count].rightname = adjp->adj_right_str;
1585706f2543Smrg	    break;
1586706f2543Smrg	case CONF_ADJ_ABSOLUTE:
1587706f2543Smrg	    slp[count].where = PosAbsolute;
1588706f2543Smrg	    break;
1589706f2543Smrg	case CONF_ADJ_RIGHTOF:
1590706f2543Smrg	    slp[count].where = PosRightOf;
1591706f2543Smrg	    break;
1592706f2543Smrg	case CONF_ADJ_LEFTOF:
1593706f2543Smrg	    slp[count].where = PosLeftOf;
1594706f2543Smrg	    break;
1595706f2543Smrg	case CONF_ADJ_ABOVE:
1596706f2543Smrg	    slp[count].where = PosAbove;
1597706f2543Smrg	    break;
1598706f2543Smrg	case CONF_ADJ_BELOW:
1599706f2543Smrg	    slp[count].where = PosBelow;
1600706f2543Smrg	    break;
1601706f2543Smrg	case CONF_ADJ_RELATIVE:
1602706f2543Smrg	    slp[count].where = PosRelative;
1603706f2543Smrg	    break;
1604706f2543Smrg	}
1605706f2543Smrg        count++;
1606706f2543Smrg        adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
1607706f2543Smrg    }
1608706f2543Smrg
1609706f2543Smrg    /* No screen was specified in the layout. take the first one from the
1610706f2543Smrg     * config file, or - if it is NULL - configScreen autogenerates one for
1611706f2543Smrg     * us */
1612706f2543Smrg    if (!count)
1613706f2543Smrg    {
1614706f2543Smrg        slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1615706f2543Smrg	if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
1616706f2543Smrg                          0, X_CONFIG)) {
1617706f2543Smrg	    free(slp[0].screen);
1618706f2543Smrg	    free(slp);
1619706f2543Smrg	    return FALSE;
1620706f2543Smrg	}
1621706f2543Smrg    }
1622706f2543Smrg
1623706f2543Smrg    /* XXX Need to tie down the upper left screen. */
1624706f2543Smrg
1625706f2543Smrg    /* Fill in the refscreen and top/bottom/left/right values */
1626706f2543Smrg    for (i = 0; i < count; i++) {
1627706f2543Smrg	for (j = 0; j < count; j++) {
1628706f2543Smrg	    if (slp[i].refname &&
1629706f2543Smrg		strcmp(slp[i].refname, slp[j].screen->id) == 0) {
1630706f2543Smrg		slp[i].refscreen = slp[j].screen;
1631706f2543Smrg	    }
1632706f2543Smrg	    if (slp[i].topname &&
1633706f2543Smrg		strcmp(slp[i].topname, slp[j].screen->id) == 0) {
1634706f2543Smrg		slp[i].top = slp[j].screen;
1635706f2543Smrg	    }
1636706f2543Smrg	    if (slp[i].bottomname &&
1637706f2543Smrg		strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
1638706f2543Smrg		slp[i].bottom = slp[j].screen;
1639706f2543Smrg	    }
1640706f2543Smrg	    if (slp[i].leftname &&
1641706f2543Smrg		strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
1642706f2543Smrg		slp[i].left = slp[j].screen;
1643706f2543Smrg	    }
1644706f2543Smrg	    if (slp[i].rightname &&
1645706f2543Smrg		strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
1646706f2543Smrg		slp[i].right = slp[j].screen;
1647706f2543Smrg	    }
1648706f2543Smrg	}
1649706f2543Smrg	if (slp[i].where != PosObsolete
1650706f2543Smrg	    && slp[i].where != PosAbsolute
1651706f2543Smrg	    && !slp[i].refscreen) {
1652706f2543Smrg	    xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
1653706f2543Smrg		     slp[i].refname);
1654706f2543Smrg	    slp[i].where = PosAbsolute;
1655706f2543Smrg	    slp[i].x = 0;
1656706f2543Smrg	    slp[i].y = 0;
1657706f2543Smrg	}
1658706f2543Smrg    }
1659706f2543Smrg
1660706f2543Smrg    if (!count)
1661706f2543Smrg	saved_count = 1;
1662706f2543Smrg    else
1663706f2543Smrg	saved_count = count;
1664706f2543Smrg    /*
1665706f2543Smrg     * Count the number of inactive devices.
1666706f2543Smrg     */
1667706f2543Smrg    count = 0;
1668706f2543Smrg    idp = conf_layout->lay_inactive_lst;
1669706f2543Smrg    while (idp) {
1670706f2543Smrg        count++;
1671706f2543Smrg        idp = (XF86ConfInactivePtr)idp->list.next;
1672706f2543Smrg    }
1673706f2543Smrg    DebugF("Found %d inactive devices in the layout section %s\n",
1674706f2543Smrg           count, conf_layout->lay_identifier);
1675706f2543Smrg    gdp = xnfalloc((count + 1) * sizeof(GDevRec));
1676706f2543Smrg    gdp[count].identifier = NULL;
1677706f2543Smrg    idp = conf_layout->lay_inactive_lst;
1678706f2543Smrg    count = 0;
1679706f2543Smrg    while (idp) {
1680706f2543Smrg	if (!configDevice(&gdp[count], idp->inactive_device, FALSE))
1681706f2543Smrg	    goto bail;
1682706f2543Smrg        count++;
1683706f2543Smrg        idp = (XF86ConfInactivePtr)idp->list.next;
1684706f2543Smrg    }
1685706f2543Smrg
1686706f2543Smrg    if (!configInputDevices(conf_layout, servlayoutp))
1687706f2543Smrg	goto bail;
1688706f2543Smrg
1689706f2543Smrg    servlayoutp->id = conf_layout->lay_identifier;
1690706f2543Smrg    servlayoutp->screens = slp;
1691706f2543Smrg    servlayoutp->inactives = gdp;
1692706f2543Smrg    servlayoutp->options = conf_layout->lay_option_lst;
1693706f2543Smrg    from = X_DEFAULT;
1694706f2543Smrg
1695706f2543Smrg    return TRUE;
1696706f2543Smrg
1697706f2543Smrgbail:
1698706f2543Smrg    do {
1699706f2543Smrg	free(slp[saved_count].screen);
1700706f2543Smrg    } while(saved_count--);
1701706f2543Smrg    free(slp);
1702706f2543Smrg    free(gdp);
1703706f2543Smrg    return FALSE;
1704706f2543Smrg}
1705706f2543Smrg
1706706f2543Smrg/*
1707706f2543Smrg * No layout section, so find the first Screen section and set that up as
1708706f2543Smrg * the only active screen.
1709706f2543Smrg */
1710706f2543Smrgstatic Bool
1711706f2543SmrgconfigImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
1712706f2543Smrg                    XF86ConfigPtr xf86configptr)
1713706f2543Smrg{
1714706f2543Smrg    MessageType from;
1715706f2543Smrg    XF86ConfScreenPtr s;
1716706f2543Smrg    screenLayoutPtr slp;
1717706f2543Smrg    InputInfoPtr *indp;
1718706f2543Smrg    XF86ConfLayoutRec layout;
1719706f2543Smrg
1720706f2543Smrg    if (!servlayoutp)
1721706f2543Smrg	return FALSE;
1722706f2543Smrg
1723706f2543Smrg    /*
1724706f2543Smrg     * which screen section is the active one?
1725706f2543Smrg     *
1726706f2543Smrg     * If there is a -screen option, use that one, otherwise use the first
1727706f2543Smrg     * one.
1728706f2543Smrg     */
1729706f2543Smrg
1730706f2543Smrg    from = X_CONFIG;
1731706f2543Smrg    if (xf86ScreenName != NULL) {
1732706f2543Smrg	if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
1733706f2543Smrg	    xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
1734706f2543Smrg		    xf86ScreenName);
1735706f2543Smrg	    return FALSE;
1736706f2543Smrg	}
1737706f2543Smrg	conf_screen = s;
1738706f2543Smrg	from = X_CMDLINE;
1739706f2543Smrg    }
1740706f2543Smrg
1741706f2543Smrg    /* We have exactly one screen */
1742706f2543Smrg
1743706f2543Smrg    slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
1744706f2543Smrg    slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
1745706f2543Smrg    slp[1].screen = NULL;
1746706f2543Smrg    if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
1747706f2543Smrg	free(slp);
1748706f2543Smrg	return FALSE;
1749706f2543Smrg    }
1750706f2543Smrg    servlayoutp->id = "(implicit)";
1751706f2543Smrg    servlayoutp->screens = slp;
1752706f2543Smrg    servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
1753706f2543Smrg    servlayoutp->options = NULL;
1754706f2543Smrg
1755706f2543Smrg    memset(&layout, 0, sizeof(layout));
1756706f2543Smrg    layout.lay_identifier = servlayoutp->id;
1757706f2543Smrg    if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
1758706f2543Smrg	if (!configInputDevices(&layout, servlayoutp))
1759706f2543Smrg	    return FALSE;
1760706f2543Smrg	from = X_DEFAULT;
1761706f2543Smrg    } else {
1762706f2543Smrg	/* Set up an empty input device list, then look for some core devices. */
1763706f2543Smrg	indp = xnfalloc(sizeof(InputInfoPtr));
1764706f2543Smrg	*indp = NULL;
1765706f2543Smrg	servlayoutp->inputs = indp;
1766706f2543Smrg    }
1767706f2543Smrg
1768706f2543Smrg    return TRUE;
1769706f2543Smrg}
1770706f2543Smrg
1771706f2543Smrgstatic Bool
1772706f2543SmrgconfigXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
1773706f2543Smrg{
1774706f2543Smrg    int count = 0;
1775706f2543Smrg    XF86ConfVideoPortPtr conf_port;
1776706f2543Smrg
1777706f2543Smrg    xf86Msg(X_CONFIG, "|   |-->VideoAdaptor \"%s\"\n",
1778706f2543Smrg	    conf_adaptor->va_identifier);
1779706f2543Smrg    adaptor->identifier = conf_adaptor->va_identifier;
1780706f2543Smrg    adaptor->options = conf_adaptor->va_option_lst;
1781706f2543Smrg    if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
1782706f2543Smrg	xf86Msg(X_CONFIG, "|   | Unsupported device type, skipping entry\n");
1783706f2543Smrg	return FALSE;
1784706f2543Smrg    }
1785706f2543Smrg
1786706f2543Smrg    /*
1787706f2543Smrg     * figure out how many videoport subsections there are and fill them in
1788706f2543Smrg     */
1789706f2543Smrg    conf_port = conf_adaptor->va_port_lst;
1790706f2543Smrg    while(conf_port) {
1791706f2543Smrg        count++;
1792706f2543Smrg        conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
1793706f2543Smrg    }
1794706f2543Smrg    adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
1795706f2543Smrg    adaptor->numports = count;
1796706f2543Smrg    count = 0;
1797706f2543Smrg    conf_port = conf_adaptor->va_port_lst;
1798706f2543Smrg    while(conf_port) {
1799706f2543Smrg	adaptor->ports[count].identifier = conf_port->vp_identifier;
1800706f2543Smrg	adaptor->ports[count].options = conf_port->vp_option_lst;
1801706f2543Smrg        count++;
1802706f2543Smrg        conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
1803706f2543Smrg    }
1804706f2543Smrg
1805706f2543Smrg    return TRUE;
1806706f2543Smrg}
1807706f2543Smrg
1808706f2543Smrgstatic Bool
1809706f2543SmrgconfigScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
1810706f2543Smrg	     MessageType from)
1811706f2543Smrg{
1812706f2543Smrg    int count = 0;
1813706f2543Smrg    XF86ConfDisplayPtr dispptr;
1814706f2543Smrg    XF86ConfAdaptorLinkPtr conf_adaptor;
1815706f2543Smrg    Bool defaultMonitor = FALSE;
1816706f2543Smrg    XF86ConfScreenRec local_conf_screen;
1817706f2543Smrg
1818706f2543Smrg    if (!conf_screen) {
1819706f2543Smrg        memset(&local_conf_screen, 0, sizeof(local_conf_screen));
1820706f2543Smrg        conf_screen = &local_conf_screen;
1821706f2543Smrg        conf_screen->scrn_identifier = "Default Screen Section";
1822706f2543Smrg        xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
1823706f2543Smrg    }
1824706f2543Smrg
1825706f2543Smrg    xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
1826706f2543Smrg	    scrnum);
1827706f2543Smrg    /*
1828706f2543Smrg     * now we fill in the elements of the screen
1829706f2543Smrg     */
1830706f2543Smrg    screenp->id         = conf_screen->scrn_identifier;
1831706f2543Smrg    screenp->screennum  = scrnum;
1832706f2543Smrg    screenp->defaultdepth = conf_screen->scrn_defaultdepth;
1833706f2543Smrg    screenp->defaultbpp = conf_screen->scrn_defaultbpp;
1834706f2543Smrg    screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
1835706f2543Smrg    screenp->monitor    = xnfcalloc(1, sizeof(MonRec));
1836706f2543Smrg    /* If no monitor is specified, create a default one. */
1837706f2543Smrg    if (!conf_screen->scrn_monitor) {
1838706f2543Smrg	XF86ConfMonitorRec defMon;
1839706f2543Smrg
1840706f2543Smrg	memset(&defMon, 0, sizeof(defMon));
1841706f2543Smrg	defMon.mon_identifier = "<default monitor>";
1842706f2543Smrg	if (!configMonitor(screenp->monitor, &defMon))
1843706f2543Smrg	    return FALSE;
1844706f2543Smrg	defaultMonitor = TRUE;
1845706f2543Smrg    } else {
1846706f2543Smrg	if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
1847706f2543Smrg	    return FALSE;
1848706f2543Smrg    }
1849706f2543Smrg    /* Configure the device. If there isn't one configured, attach to the
1850706f2543Smrg     * first inactive one that we can configure. If there's none that work,
1851706f2543Smrg     * set it to NULL so that the section can be autoconfigured later */
1852706f2543Smrg    screenp->device     = xnfcalloc(1, sizeof(GDevRec));
1853706f2543Smrg    if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
1854706f2543Smrg        conf_screen->scrn_device = xf86configptr->conf_device_lst;
1855706f2543Smrg	xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
1856706f2543Smrg		"\tUsing the first device section listed.\n", screenp->id);
1857706f2543Smrg    }
1858706f2543Smrg    if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
1859706f2543Smrg        screenp->device->myScreenSection = screenp;
1860706f2543Smrg    } else {
1861706f2543Smrg        screenp->device = NULL;
1862706f2543Smrg    }
1863706f2543Smrg    screenp->options = conf_screen->scrn_option_lst;
1864706f2543Smrg
1865706f2543Smrg    /*
1866706f2543Smrg     * figure out how many display subsections there are and fill them in
1867706f2543Smrg     */
1868706f2543Smrg    dispptr = conf_screen->scrn_display_lst;
1869706f2543Smrg    while(dispptr) {
1870706f2543Smrg        count++;
1871706f2543Smrg        dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
1872706f2543Smrg    }
1873706f2543Smrg    screenp->displays   = xnfalloc((count) * sizeof(DispRec));
1874706f2543Smrg    screenp->numdisplays = count;
1875706f2543Smrg
1876706f2543Smrg    /* Fill in the default Virtual size, if any */
1877706f2543Smrg    if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
1878706f2543Smrg	for (count = 0, dispptr = conf_screen->scrn_display_lst;
1879706f2543Smrg	     dispptr;
1880706f2543Smrg	     dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
1881706f2543Smrg	    screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
1882706f2543Smrg	    screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
1883706f2543Smrg	}
1884706f2543Smrg    }
1885706f2543Smrg
1886706f2543Smrg    /* Now do the per-Display Virtual sizes */
1887706f2543Smrg    count = 0;
1888706f2543Smrg    dispptr = conf_screen->scrn_display_lst;
1889706f2543Smrg    while(dispptr) {
1890706f2543Smrg        configDisplay(&(screenp->displays[count]),dispptr);
1891706f2543Smrg        count++;
1892706f2543Smrg        dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
1893706f2543Smrg    }
1894706f2543Smrg
1895706f2543Smrg    /*
1896706f2543Smrg     * figure out how many videoadaptor references there are and fill them in
1897706f2543Smrg     */
1898706f2543Smrg    conf_adaptor = conf_screen->scrn_adaptor_lst;
1899706f2543Smrg    while(conf_adaptor) {
1900706f2543Smrg        count++;
1901706f2543Smrg        conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
1902706f2543Smrg    }
1903706f2543Smrg    screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
1904706f2543Smrg    screenp->numxvadaptors = 0;
1905706f2543Smrg    conf_adaptor = conf_screen->scrn_adaptor_lst;
1906706f2543Smrg    while(conf_adaptor) {
1907706f2543Smrg        if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
1908706f2543Smrg			    conf_adaptor->al_adaptor))
1909706f2543Smrg    	    screenp->numxvadaptors++;
1910706f2543Smrg        conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
1911706f2543Smrg    }
1912706f2543Smrg
1913706f2543Smrg    if (defaultMonitor) {
1914706f2543Smrg	xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
1915706f2543Smrg		"\tUsing a default monitor configuration.\n", screenp->id);
1916706f2543Smrg    }
1917706f2543Smrg    return TRUE;
1918706f2543Smrg}
1919706f2543Smrg
1920706f2543Smrgtypedef enum {
1921706f2543Smrg    MON_REDUCEDBLANKING,
1922706f2543Smrg    MON_MAX_PIX_CLOCK,
1923706f2543Smrg} MonitorValues;
1924706f2543Smrg
1925706f2543Smrgstatic OptionInfoRec MonitorOptions[] = {
1926706f2543Smrg  { MON_REDUCEDBLANKING,      "ReducedBlanking",        OPTV_BOOLEAN,
1927706f2543Smrg       {0}, FALSE },
1928706f2543Smrg  { MON_MAX_PIX_CLOCK,	      "MaxPixClock",		OPTV_FREQ,
1929706f2543Smrg       {0}, FALSE },
1930706f2543Smrg  { -1,                                NULL,                   OPTV_NONE,
1931706f2543Smrg       {0}, FALSE },
1932706f2543Smrg};
1933706f2543Smrg
1934706f2543Smrgstatic Bool
1935706f2543SmrgconfigMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
1936706f2543Smrg{
1937706f2543Smrg    int count;
1938706f2543Smrg    DisplayModePtr mode,last = NULL;
1939706f2543Smrg    XF86ConfModeLinePtr cmodep;
1940706f2543Smrg    XF86ConfModesPtr modes;
1941706f2543Smrg    XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
1942706f2543Smrg    Gamma zeros = {0.0, 0.0, 0.0};
1943706f2543Smrg    float badgamma = 0.0;
1944706f2543Smrg    double maxPixClock;
1945706f2543Smrg
1946706f2543Smrg    xf86Msg(X_CONFIG, "|   |-->Monitor \"%s\"\n",
1947706f2543Smrg	    conf_monitor->mon_identifier);
1948706f2543Smrg    monitorp->id = conf_monitor->mon_identifier;
1949706f2543Smrg    monitorp->vendor = conf_monitor->mon_vendor;
1950706f2543Smrg    monitorp->model = conf_monitor->mon_modelname;
1951706f2543Smrg    monitorp->Modes = NULL;
1952706f2543Smrg    monitorp->Last = NULL;
1953706f2543Smrg    monitorp->gamma = zeros;
1954706f2543Smrg    monitorp->widthmm = conf_monitor->mon_width;
1955706f2543Smrg    monitorp->heightmm = conf_monitor->mon_height;
1956706f2543Smrg    monitorp->reducedblanking = FALSE;
1957706f2543Smrg    monitorp->maxPixClock = 0;
1958706f2543Smrg    monitorp->options = conf_monitor->mon_option_lst;
1959706f2543Smrg
1960706f2543Smrg    /*
1961706f2543Smrg     * fill in the monitor structure
1962706f2543Smrg     */
1963706f2543Smrg    for( count = 0 ;
1964706f2543Smrg	 count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
1965706f2543Smrg	 count++) {
1966706f2543Smrg        monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
1967706f2543Smrg        monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
1968706f2543Smrg    }
1969706f2543Smrg    monitorp->nHsync = count;
1970706f2543Smrg    for( count = 0 ;
1971706f2543Smrg	 count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
1972706f2543Smrg	 count++) {
1973706f2543Smrg        monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
1974706f2543Smrg        monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
1975706f2543Smrg    }
1976706f2543Smrg    monitorp->nVrefresh = count;
1977706f2543Smrg
1978706f2543Smrg    /*
1979706f2543Smrg     * first we collect the mode lines from the UseModes directive
1980706f2543Smrg     */
1981706f2543Smrg    while(modeslnk)
1982706f2543Smrg    {
1983706f2543Smrg        modes = xf86findModes (modeslnk->ml_modes_str,
1984706f2543Smrg			       xf86configptr->conf_modes_lst);
1985706f2543Smrg	modeslnk->ml_modes = modes;
1986706f2543Smrg
1987706f2543Smrg
1988706f2543Smrg	/* now add the modes found in the modes
1989706f2543Smrg	   section to the list of modes for this
1990706f2543Smrg	   monitor unless it has been added before
1991706f2543Smrg	   because we are reusing the same section
1992706f2543Smrg	   for another screen */
1993706f2543Smrg	if (xf86itemNotSublist(
1994706f2543Smrg			       (GenericListPtr)conf_monitor->mon_modeline_lst,
1995706f2543Smrg			       (GenericListPtr)modes->mon_modeline_lst)) {
1996706f2543Smrg	    conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
1997706f2543Smrg	        xf86addListItem(
1998706f2543Smrg				(GenericListPtr)conf_monitor->mon_modeline_lst,
1999706f2543Smrg				(GenericListPtr)modes->mon_modeline_lst);
2000706f2543Smrg	}
2001706f2543Smrg	modeslnk = modeslnk->list.next;
2002706f2543Smrg    }
2003706f2543Smrg
2004706f2543Smrg    /*
2005706f2543Smrg     * we need to hook in the mode lines now
2006706f2543Smrg     * here both data structures use lists, only our internal one
2007706f2543Smrg     * is double linked
2008706f2543Smrg     */
2009706f2543Smrg    cmodep = conf_monitor->mon_modeline_lst;
2010706f2543Smrg    while( cmodep ) {
2011706f2543Smrg        mode = xnfcalloc(1, sizeof(DisplayModeRec));
2012706f2543Smrg	mode->type       = 0;
2013706f2543Smrg        mode->Clock      = cmodep->ml_clock;
2014706f2543Smrg        mode->HDisplay   = cmodep->ml_hdisplay;
2015706f2543Smrg        mode->HSyncStart = cmodep->ml_hsyncstart;
2016706f2543Smrg        mode->HSyncEnd   = cmodep->ml_hsyncend;
2017706f2543Smrg        mode->HTotal     = cmodep->ml_htotal;
2018706f2543Smrg        mode->VDisplay   = cmodep->ml_vdisplay;
2019706f2543Smrg        mode->VSyncStart = cmodep->ml_vsyncstart;
2020706f2543Smrg        mode->VSyncEnd   = cmodep->ml_vsyncend;
2021706f2543Smrg        mode->VTotal     = cmodep->ml_vtotal;
2022706f2543Smrg        mode->Flags      = cmodep->ml_flags;
2023706f2543Smrg        mode->HSkew      = cmodep->ml_hskew;
2024706f2543Smrg        mode->VScan      = cmodep->ml_vscan;
2025706f2543Smrg        mode->name       = xnfstrdup(cmodep->ml_identifier);
2026706f2543Smrg        if( last ) {
2027706f2543Smrg            mode->prev = last;
2028706f2543Smrg            last->next = mode;
2029706f2543Smrg        }
2030706f2543Smrg        else {
2031706f2543Smrg            /*
2032706f2543Smrg             * this is the first mode
2033706f2543Smrg             */
2034706f2543Smrg            monitorp->Modes = mode;
2035706f2543Smrg            mode->prev = NULL;
2036706f2543Smrg        }
2037706f2543Smrg        last = mode;
2038706f2543Smrg        cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
2039706f2543Smrg    }
2040706f2543Smrg    if(last){
2041706f2543Smrg      last->next = NULL;
2042706f2543Smrg    }
2043706f2543Smrg    monitorp->Last = last;
2044706f2543Smrg
2045706f2543Smrg    /* add the (VESA) default modes */
2046706f2543Smrg    if (! addDefaultModes(monitorp) )
2047706f2543Smrg	return FALSE;
2048706f2543Smrg
2049706f2543Smrg    if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
2050706f2543Smrg	monitorp->gamma.red = conf_monitor->mon_gamma_red;
2051706f2543Smrg    if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
2052706f2543Smrg	monitorp->gamma.green = conf_monitor->mon_gamma_green;
2053706f2543Smrg    if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
2054706f2543Smrg	monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
2055706f2543Smrg
2056706f2543Smrg    /* Check that the gamma values are within range */
2057706f2543Smrg    if (monitorp->gamma.red > GAMMA_ZERO &&
2058706f2543Smrg	(monitorp->gamma.red < GAMMA_MIN ||
2059706f2543Smrg	 monitorp->gamma.red > GAMMA_MAX)) {
2060706f2543Smrg	badgamma = monitorp->gamma.red;
2061706f2543Smrg    } else if (monitorp->gamma.green > GAMMA_ZERO &&
2062706f2543Smrg	(monitorp->gamma.green < GAMMA_MIN ||
2063706f2543Smrg	 monitorp->gamma.green > GAMMA_MAX)) {
2064706f2543Smrg	badgamma = monitorp->gamma.green;
2065706f2543Smrg    } else if (monitorp->gamma.blue > GAMMA_ZERO &&
2066706f2543Smrg	(monitorp->gamma.blue < GAMMA_MIN ||
2067706f2543Smrg	 monitorp->gamma.blue > GAMMA_MAX)) {
2068706f2543Smrg	badgamma = monitorp->gamma.blue;
2069706f2543Smrg    }
2070706f2543Smrg    if (badgamma > GAMMA_ZERO) {
2071706f2543Smrg	xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
2072706f2543Smrg			badgamma, GAMMA_MIN, GAMMA_MAX);
2073706f2543Smrg	    return FALSE;
2074706f2543Smrg    }
2075706f2543Smrg
2076706f2543Smrg    xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
2077706f2543Smrg    xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
2078706f2543Smrg                      &monitorp->reducedblanking);
2079706f2543Smrg    if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
2080706f2543Smrg			  &maxPixClock) == TRUE) {
2081706f2543Smrg	monitorp->maxPixClock = (int) maxPixClock;
2082706f2543Smrg    }
2083706f2543Smrg
2084706f2543Smrg    return TRUE;
2085706f2543Smrg}
2086706f2543Smrg
2087706f2543Smrgstatic int
2088706f2543SmrglookupVisual(const char *visname)
2089706f2543Smrg{
2090706f2543Smrg    int i;
2091706f2543Smrg
2092706f2543Smrg    if (!visname || !*visname)
2093706f2543Smrg	return -1;
2094706f2543Smrg
2095706f2543Smrg    for (i = 0; i <= DirectColor; i++) {
2096706f2543Smrg	if (!xf86nameCompare(visname, xf86VisualNames[i]))
2097706f2543Smrg	    break;
2098706f2543Smrg    }
2099706f2543Smrg
2100706f2543Smrg    if (i <= DirectColor)
2101706f2543Smrg	return i;
2102706f2543Smrg
2103706f2543Smrg    return -1;
2104706f2543Smrg}
2105706f2543Smrg
2106706f2543Smrg
2107706f2543Smrgstatic Bool
2108706f2543SmrgconfigDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
2109706f2543Smrg{
2110706f2543Smrg    int count = 0;
2111706f2543Smrg    XF86ModePtr modep;
2112706f2543Smrg
2113706f2543Smrg    displayp->frameX0           = conf_display->disp_frameX0;
2114706f2543Smrg    displayp->frameY0           = conf_display->disp_frameY0;
2115706f2543Smrg    displayp->virtualX          = conf_display->disp_virtualX;
2116706f2543Smrg    displayp->virtualY          = conf_display->disp_virtualY;
2117706f2543Smrg    displayp->depth             = conf_display->disp_depth;
2118706f2543Smrg    displayp->fbbpp             = conf_display->disp_bpp;
2119706f2543Smrg    displayp->weight.red        = conf_display->disp_weight.red;
2120706f2543Smrg    displayp->weight.green      = conf_display->disp_weight.green;
2121706f2543Smrg    displayp->weight.blue       = conf_display->disp_weight.blue;
2122706f2543Smrg    displayp->blackColour.red   = conf_display->disp_black.red;
2123706f2543Smrg    displayp->blackColour.green = conf_display->disp_black.green;
2124706f2543Smrg    displayp->blackColour.blue  = conf_display->disp_black.blue;
2125706f2543Smrg    displayp->whiteColour.red   = conf_display->disp_white.red;
2126706f2543Smrg    displayp->whiteColour.green = conf_display->disp_white.green;
2127706f2543Smrg    displayp->whiteColour.blue  = conf_display->disp_white.blue;
2128706f2543Smrg    displayp->options           = conf_display->disp_option_lst;
2129706f2543Smrg    if (conf_display->disp_visual) {
2130706f2543Smrg	displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
2131706f2543Smrg	if (displayp->defaultVisual == -1) {
2132706f2543Smrg	    xf86ConfigError("Invalid visual name: \"%s\"",
2133706f2543Smrg			    conf_display->disp_visual);
2134706f2543Smrg	    return FALSE;
2135706f2543Smrg	}
2136706f2543Smrg    } else {
2137706f2543Smrg	displayp->defaultVisual = -1;
2138706f2543Smrg    }
2139706f2543Smrg
2140706f2543Smrg    /*
2141706f2543Smrg     * now hook in the modes
2142706f2543Smrg     */
2143706f2543Smrg    modep = conf_display->disp_mode_lst;
2144706f2543Smrg    while(modep) {
2145706f2543Smrg        count++;
2146706f2543Smrg        modep = (XF86ModePtr)modep->list.next;
2147706f2543Smrg    }
2148706f2543Smrg    displayp->modes = xnfalloc((count+1) * sizeof(char*));
2149706f2543Smrg    modep = conf_display->disp_mode_lst;
2150706f2543Smrg    count = 0;
2151706f2543Smrg    while(modep) {
2152706f2543Smrg        displayp->modes[count] = modep->mode_name;
2153706f2543Smrg        count++;
2154706f2543Smrg        modep = (XF86ModePtr)modep->list.next;
2155706f2543Smrg    }
2156706f2543Smrg    displayp->modes[count] = NULL;
2157706f2543Smrg
2158706f2543Smrg    return TRUE;
2159706f2543Smrg}
2160706f2543Smrg
2161706f2543Smrgstatic Bool
2162706f2543SmrgconfigDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
2163706f2543Smrg{
2164706f2543Smrg    int i;
2165706f2543Smrg
2166706f2543Smrg    if (!conf_device) {
2167706f2543Smrg        return FALSE;
2168706f2543Smrg    }
2169706f2543Smrg
2170706f2543Smrg    if (active)
2171706f2543Smrg	xf86Msg(X_CONFIG, "|   |-->Device \"%s\"\n",
2172706f2543Smrg		conf_device->dev_identifier);
2173706f2543Smrg    else
2174706f2543Smrg	xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
2175706f2543Smrg		conf_device->dev_identifier);
2176706f2543Smrg
2177706f2543Smrg    devicep->identifier = conf_device->dev_identifier;
2178706f2543Smrg    devicep->vendor = conf_device->dev_vendor;
2179706f2543Smrg    devicep->board = conf_device->dev_board;
2180706f2543Smrg    devicep->chipset = conf_device->dev_chipset;
2181706f2543Smrg    devicep->ramdac = conf_device->dev_ramdac;
2182706f2543Smrg    devicep->driver = conf_device->dev_driver;
2183706f2543Smrg    devicep->active = active;
2184706f2543Smrg    devicep->videoRam = conf_device->dev_videoram;
2185706f2543Smrg    devicep->BiosBase = conf_device->dev_bios_base;
2186706f2543Smrg    devicep->MemBase = conf_device->dev_mem_base;
2187706f2543Smrg    devicep->IOBase = conf_device->dev_io_base;
2188706f2543Smrg    devicep->clockchip = conf_device->dev_clockchip;
2189706f2543Smrg    devicep->busID = conf_device->dev_busid;
2190706f2543Smrg    devicep->textClockFreq = conf_device->dev_textclockfreq;
2191706f2543Smrg    devicep->chipID = conf_device->dev_chipid;
2192706f2543Smrg    devicep->chipRev = conf_device->dev_chiprev;
2193706f2543Smrg    devicep->options = conf_device->dev_option_lst;
2194706f2543Smrg    devicep->irq = conf_device->dev_irq;
2195706f2543Smrg    devicep->screen = conf_device->dev_screen;
2196706f2543Smrg
2197706f2543Smrg    for (i = 0; i < MAXDACSPEEDS; i++) {
2198706f2543Smrg	if (i < CONF_MAXDACSPEEDS)
2199706f2543Smrg            devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
2200706f2543Smrg	else
2201706f2543Smrg	    devicep->dacSpeeds[i] = 0;
2202706f2543Smrg    }
2203706f2543Smrg    devicep->numclocks = conf_device->dev_clocks;
2204706f2543Smrg    if (devicep->numclocks > MAXCLOCKS)
2205706f2543Smrg	devicep->numclocks = MAXCLOCKS;
2206706f2543Smrg    for (i = 0; i < devicep->numclocks; i++) {
2207706f2543Smrg	devicep->clock[i] = conf_device->dev_clock[i];
2208706f2543Smrg    }
2209706f2543Smrg    devicep->claimed = FALSE;
2210706f2543Smrg
2211706f2543Smrg    return TRUE;
2212706f2543Smrg}
2213706f2543Smrg
2214706f2543Smrg#ifdef XF86DRI
2215706f2543Smrgstatic void
2216706f2543SmrgconfigDRI(XF86ConfDRIPtr drip)
2217706f2543Smrg{
2218706f2543Smrg    struct group       *grp;
2219706f2543Smrg
2220706f2543Smrg    xf86ConfigDRI.group      = -1;
2221706f2543Smrg    xf86ConfigDRI.mode       = 0;
2222706f2543Smrg
2223706f2543Smrg    if (drip) {
2224706f2543Smrg	if (drip->dri_group_name) {
2225706f2543Smrg	    if ((grp = getgrnam(drip->dri_group_name)))
2226706f2543Smrg		xf86ConfigDRI.group = grp->gr_gid;
2227706f2543Smrg	} else {
2228706f2543Smrg	    if (drip->dri_group >= 0)
2229706f2543Smrg		xf86ConfigDRI.group = drip->dri_group;
2230706f2543Smrg	}
2231706f2543Smrg	xf86ConfigDRI.mode = drip->dri_mode;
2232706f2543Smrg    }
2233706f2543Smrg}
2234706f2543Smrg#endif
2235706f2543Smrg
2236706f2543Smrgstatic void
2237706f2543SmrgconfigExtensions(XF86ConfExtensionsPtr conf_ext)
2238706f2543Smrg{
2239706f2543Smrg    XF86OptionPtr o;
2240706f2543Smrg
2241706f2543Smrg    if (conf_ext && conf_ext->ext_option_lst) {
2242706f2543Smrg	for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
2243706f2543Smrg	    char *name   = xf86OptionName(o);
2244706f2543Smrg	    char *val    = xf86OptionValue(o);
2245706f2543Smrg	    char *n;
2246706f2543Smrg	    Bool  enable = TRUE;
2247706f2543Smrg
2248706f2543Smrg	    /* Handle "No<ExtensionName>" */
2249706f2543Smrg	    n = xf86NormalizeName(name);
2250706f2543Smrg	    if (strncmp(n, "no", 2) == 0) {
2251706f2543Smrg		name += 2;
2252706f2543Smrg		enable = FALSE;
2253706f2543Smrg	    }
2254706f2543Smrg
2255706f2543Smrg	    if (!val ||
2256706f2543Smrg		xf86NameCmp(val, "enable") == 0 ||
2257706f2543Smrg		xf86NameCmp(val, "enabled") == 0 ||
2258706f2543Smrg		xf86NameCmp(val, "on") == 0 ||
2259706f2543Smrg		xf86NameCmp(val, "1") == 0 ||
2260706f2543Smrg		xf86NameCmp(val, "yes") == 0 ||
2261706f2543Smrg		xf86NameCmp(val, "true") == 0) {
2262706f2543Smrg		/* NOTHING NEEDED -- enabling is handled below */
2263706f2543Smrg	    } else if (xf86NameCmp(val, "disable") == 0 ||
2264706f2543Smrg                       xf86NameCmp(val, "disabled") == 0 ||
2265706f2543Smrg		       xf86NameCmp(val, "off") == 0 ||
2266706f2543Smrg		       xf86NameCmp(val, "0") == 0 ||
2267706f2543Smrg		       xf86NameCmp(val, "no") == 0 ||
2268706f2543Smrg		       xf86NameCmp(val, "false") == 0) {
2269706f2543Smrg		enable = !enable;
2270706f2543Smrg	    } else {
2271706f2543Smrg		xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
2272706f2543Smrg		free(n);
2273706f2543Smrg		continue;
2274706f2543Smrg	    }
2275706f2543Smrg
2276706f2543Smrg	    if (EnableDisableExtension(name, enable)) {
2277706f2543Smrg		xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
2278706f2543Smrg			name, enable ? "enabled" : "disabled");
2279706f2543Smrg	    } else {
2280706f2543Smrg		xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
2281706f2543Smrg                        name);
2282706f2543Smrg	    }
2283706f2543Smrg	    free(n);
2284706f2543Smrg	}
2285706f2543Smrg    }
2286706f2543Smrg}
2287706f2543Smrg
2288706f2543Smrgstatic Bool
2289706f2543SmrgconfigInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
2290706f2543Smrg{
2291706f2543Smrg    xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
2292706f2543Smrg    inputp->name = conf_input->inp_identifier;
2293706f2543Smrg    inputp->driver = conf_input->inp_driver;
2294706f2543Smrg    inputp->options = conf_input->inp_option_lst;
2295706f2543Smrg    inputp->attrs = NULL;
2296706f2543Smrg
2297706f2543Smrg    return TRUE;
2298706f2543Smrg}
2299706f2543Smrg
2300706f2543Smrgstatic Bool
2301706f2543SmrgmodeIsPresent(DisplayModePtr mode, MonPtr monitorp)
2302706f2543Smrg{
2303706f2543Smrg    DisplayModePtr knownmodes = monitorp->Modes;
2304706f2543Smrg
2305706f2543Smrg    /* all I can think of is a linear search... */
2306706f2543Smrg    while(knownmodes != NULL)
2307706f2543Smrg    {
2308706f2543Smrg	if(!strcmp(mode->name, knownmodes->name) &&
2309706f2543Smrg	   !(knownmodes->type & M_T_DEFAULT))
2310706f2543Smrg	    return TRUE;
2311706f2543Smrg	knownmodes = knownmodes->next;
2312706f2543Smrg    }
2313706f2543Smrg    return FALSE;
2314706f2543Smrg}
2315706f2543Smrg
2316706f2543Smrgstatic Bool
2317706f2543SmrgaddDefaultModes(MonPtr monitorp)
2318706f2543Smrg{
2319706f2543Smrg    DisplayModePtr mode;
2320706f2543Smrg    DisplayModePtr last = monitorp->Last;
2321706f2543Smrg    int i = 0;
2322706f2543Smrg
2323706f2543Smrg    for (i = 0; i < xf86NumDefaultModes; i++)
2324706f2543Smrg    {
2325706f2543Smrg	mode = xf86DuplicateMode(&xf86DefaultModes[i]);
2326706f2543Smrg	if (!modeIsPresent(mode, monitorp))
2327706f2543Smrg	{
2328706f2543Smrg	    monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
2329706f2543Smrg	    last = mode;
2330706f2543Smrg	} else {
2331706f2543Smrg	    free(mode);
2332706f2543Smrg	}
2333706f2543Smrg    }
2334706f2543Smrg    monitorp->Last = last;
2335706f2543Smrg
2336706f2543Smrg    return TRUE;
2337706f2543Smrg}
2338706f2543Smrg
2339706f2543Smrgstatic void
2340706f2543SmrgcheckInput(serverLayoutPtr layout, Bool implicit_layout) {
2341706f2543Smrg    checkCoreInputDevices(layout, implicit_layout);
2342706f2543Smrg
2343706f2543Smrg    /* Unless we're forcing input devices, disable mouse/kbd devices in the
2344706f2543Smrg     * config. Otherwise the same physical device is added multiple times,
2345706f2543Smrg     * leading to duplicate events.
2346706f2543Smrg     */
2347706f2543Smrg    if (!xf86Info.forceInputDevices && layout->inputs)
2348706f2543Smrg    {
2349706f2543Smrg        InputInfoPtr *dev = layout->inputs;
2350706f2543Smrg        BOOL warned = FALSE;
2351706f2543Smrg
2352706f2543Smrg        while(*dev)
2353706f2543Smrg        {
2354706f2543Smrg            if (strcmp((*dev)->driver, "kbd") == 0 ||
2355706f2543Smrg                strcmp((*dev)->driver, "mouse") == 0 ||
2356706f2543Smrg                strcmp((*dev)->driver, "vmmouse") == 0)
2357706f2543Smrg            {
2358706f2543Smrg                InputInfoPtr *current;
2359706f2543Smrg                if (!warned)
2360706f2543Smrg                {
2361706f2543Smrg                    xf86Msg(X_WARNING, "Hotplugging is on, devices using "
2362706f2543Smrg                            "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
2363706f2543Smrg                    warned = TRUE;
2364706f2543Smrg                }
2365706f2543Smrg
2366706f2543Smrg                xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name);
2367706f2543Smrg
2368706f2543Smrg                current = dev;
2369706f2543Smrg                free(*dev);
2370706f2543Smrg
2371706f2543Smrg                do {
2372706f2543Smrg                    *current = *(current + 1);
2373706f2543Smrg                    current++;
2374706f2543Smrg                } while(*current);
2375706f2543Smrg            } else
2376706f2543Smrg                dev++;
2377706f2543Smrg        }
2378706f2543Smrg    }
2379706f2543Smrg}
2380706f2543Smrg
2381706f2543Smrg/*
2382706f2543Smrg * load the config file and fill the global data structure
2383706f2543Smrg */
2384706f2543SmrgConfigStatus
2385706f2543Smrgxf86HandleConfigFile(Bool autoconfig)
2386706f2543Smrg{
2387706f2543Smrg    const char *filename, *dirname, *sysdirname;
2388706f2543Smrg    char *filesearch, *dirsearch;
2389706f2543Smrg    MessageType filefrom = X_DEFAULT;
2390706f2543Smrg    MessageType dirfrom = X_DEFAULT;
2391706f2543Smrg    char *scanptr;
2392706f2543Smrg    Bool singlecard = 0;
2393706f2543Smrg    Bool implicit_layout = FALSE;
2394706f2543Smrg
2395706f2543Smrg    if (!autoconfig) {
2396706f2543Smrg	if (getuid() == 0) {
2397706f2543Smrg	    filesearch = ROOT_CONFIGPATH;
2398706f2543Smrg	    dirsearch = ROOT_CONFIGDIRPATH;
2399706f2543Smrg	} else {
2400706f2543Smrg	    filesearch = USER_CONFIGPATH;
2401706f2543Smrg	    dirsearch = USER_CONFIGDIRPATH;
2402706f2543Smrg	}
2403706f2543Smrg
2404706f2543Smrg	if (xf86ConfigFile)
2405706f2543Smrg	    filefrom = X_CMDLINE;
2406706f2543Smrg	if (xf86ConfigDir)
2407706f2543Smrg	    dirfrom = X_CMDLINE;
2408706f2543Smrg
2409706f2543Smrg	xf86initConfigFiles();
2410706f2543Smrg	sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
2411706f2543Smrg					    PROJECTROOT);
2412706f2543Smrg	dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
2413706f2543Smrg	filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
2414706f2543Smrg	if (filename) {
2415706f2543Smrg	    xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
2416706f2543Smrg	    xf86ConfigFile = xnfstrdup(filename);
2417706f2543Smrg	} else {
2418706f2543Smrg	    if (xf86ConfigFile)
2419706f2543Smrg		xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
2420706f2543Smrg			xf86ConfigFile);
2421706f2543Smrg	}
2422706f2543Smrg	if (dirname) {
2423706f2543Smrg	    xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
2424706f2543Smrg			dirname);
2425706f2543Smrg	    xf86ConfigDir = xnfstrdup(dirname);
2426706f2543Smrg	} else {
2427706f2543Smrg	    if (xf86ConfigDir)
2428706f2543Smrg		xf86Msg(X_ERROR,
2429706f2543Smrg			"Unable to locate/open config directory: \"%s\"\n",
2430706f2543Smrg			xf86ConfigDir);
2431706f2543Smrg	}
2432706f2543Smrg	if (sysdirname)
2433706f2543Smrg	    xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
2434706f2543Smrg			sysdirname);
2435706f2543Smrg	if (!filename && !dirname && !sysdirname)
2436706f2543Smrg	    return CONFIG_NOFILE;
2437706f2543Smrg    }
2438706f2543Smrg
2439706f2543Smrg    if ((xf86configptr = xf86readConfigFile ()) == NULL) {
2440706f2543Smrg	xf86Msg(X_ERROR, "Problem parsing the config file\n");
2441706f2543Smrg	return CONFIG_PARSE_ERROR;
2442706f2543Smrg    }
2443706f2543Smrg    xf86closeConfigFile ();
2444706f2543Smrg
2445706f2543Smrg    /* Initialise a few things. */
2446706f2543Smrg
2447706f2543Smrg    /*
2448706f2543Smrg     * now we convert part of the information contained in the parser
2449706f2543Smrg     * structures into our own structures.
2450706f2543Smrg     * The important part here is to figure out which Screen Sections
2451706f2543Smrg     * in the XF86Config file are active so that we can piece together
2452706f2543Smrg     * the modes that we need later down the road.
2453706f2543Smrg     * And while we are at it, we'll decode the rest of the stuff as well
2454706f2543Smrg     */
2455706f2543Smrg
2456706f2543Smrg    /* First check if a layout section is present, and if it is valid. */
2457706f2543Smrg
2458706f2543Smrg    if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
2459706f2543Smrg	if (xf86ScreenName == NULL) {
2460706f2543Smrg	    xf86Msg(X_DEFAULT,
2461706f2543Smrg		    "No Layout section.  Using the first Screen section.\n");
2462706f2543Smrg	}
2463706f2543Smrg	if (!configImpliedLayout(&xf86ConfigLayout,
2464706f2543Smrg				 xf86configptr->conf_screen_lst,
2465706f2543Smrg				 xf86configptr)) {
2466706f2543Smrg            xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2467706f2543Smrg	    return CONFIG_PARSE_ERROR;
2468706f2543Smrg	}
2469706f2543Smrg	implicit_layout = TRUE;
2470706f2543Smrg    } else {
2471706f2543Smrg	if (xf86configptr->conf_flags != NULL) {
2472706f2543Smrg	  char *dfltlayout = NULL;
2473706f2543Smrg 	  pointer optlist = xf86configptr->conf_flags->flg_option_lst;
2474706f2543Smrg
2475706f2543Smrg	  if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
2476706f2543Smrg	    dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
2477706f2543Smrg	  if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
2478706f2543Smrg			  dfltlayout)) {
2479706f2543Smrg	    xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2480706f2543Smrg	    return CONFIG_PARSE_ERROR;
2481706f2543Smrg	  }
2482706f2543Smrg	} else {
2483706f2543Smrg	  if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
2484706f2543Smrg			  NULL)) {
2485706f2543Smrg	    xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
2486706f2543Smrg	    return CONFIG_PARSE_ERROR;
2487706f2543Smrg	  }
2488706f2543Smrg	}
2489706f2543Smrg    }
2490706f2543Smrg
2491706f2543Smrg    xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
2492706f2543Smrg
2493706f2543Smrg    if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
2494706f2543Smrg       ; /* IsolateDevice specified; overrides SingleCard */
2495706f2543Smrg    } else {
2496706f2543Smrg       xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
2497706f2543Smrg       if (singlecard)
2498706f2543Smrg           scanptr = xf86ConfigLayout.screens->screen->device->busID;
2499706f2543Smrg    }
2500706f2543Smrg    if (scanptr) {
2501706f2543Smrg       if (strncmp(scanptr, "PCI:", 4) != 0) {
2502706f2543Smrg           xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
2503706f2543Smrg                              "\tIgnoring IsolateDevice option.\n");
2504706f2543Smrg       } else
2505706f2543Smrg           xf86PciIsolateDevice(scanptr);
2506706f2543Smrg    }
2507706f2543Smrg
2508706f2543Smrg    /* Now process everything else */
2509706f2543Smrg    if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
2510706f2543Smrg             ErrorF ("Problem when converting the config data structures\n");
2511706f2543Smrg             return CONFIG_PARSE_ERROR;
2512706f2543Smrg    }
2513706f2543Smrg
2514706f2543Smrg    configFiles(xf86configptr->conf_files);
2515706f2543Smrg    configExtensions(xf86configptr->conf_extensions);
2516706f2543Smrg#ifdef XF86DRI
2517706f2543Smrg    configDRI(xf86configptr->conf_dri);
2518706f2543Smrg#endif
2519706f2543Smrg
2520706f2543Smrg    checkInput(&xf86ConfigLayout, implicit_layout);
2521706f2543Smrg
2522706f2543Smrg    /*
2523706f2543Smrg     * Handle some command line options that can override some of the
2524706f2543Smrg     * ServerFlags settings.
2525706f2543Smrg     */
2526706f2543Smrg#ifdef XF86VIDMODE
2527706f2543Smrg    if (xf86VidModeDisabled)
2528706f2543Smrg	xf86Info.vidModeEnabled = FALSE;
2529706f2543Smrg    if (xf86VidModeAllowNonLocal)
2530706f2543Smrg	xf86Info.vidModeAllowNonLocal = TRUE;
2531706f2543Smrg#endif
2532706f2543Smrg
2533706f2543Smrg    if (xf86AllowMouseOpenFail)
2534706f2543Smrg	xf86Info.allowMouseOpenFail = TRUE;
2535706f2543Smrg
2536706f2543Smrg    return CONFIG_OK;
2537706f2543Smrg}
2538706f2543Smrg
2539706f2543SmrgBool
2540706f2543Smrgxf86PathIsSafe(const char *path)
2541706f2543Smrg{
2542706f2543Smrg    return (xf86pathIsSafe(path) != 0);
2543706f2543Smrg}
2544