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