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