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