xf86Config.c (80708B)
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 * 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 * 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 ** 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 ** 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 ** 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 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 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 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 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 * 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 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 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 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 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 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 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 /* Loop through the entire device list and skip the primary device 1742 * assigned to the screen. This is important because there are two 1743 * cases where the assigned primary device is not the first device in 1744 * the device list. Firstly, if the first device in the list is assigned 1745 * to a different seat than this X server, it will not have been picked 1746 * by the previous FIND_SUITABLE. Secondly, if the device was explicitly 1747 * assigned in the config but there is still only one screen, this code 1748 * path is executed but the explicitly assigned device may not be the 1749 * first device in the list. */ 1750 XF86ConfDevicePtr ptmp, sdevice = xf86configptr->conf_device_lst; 1751 1752 for (i = 0; i < MAX_GPUDEVICES; i++) { 1753 if (!sdevice) 1754 break; 1755 1756 FIND_SUITABLE (XF86ConfDevicePtr, sdevice, ptmp); 1757 if (!ptmp) 1758 break; 1759 1760 /* skip the primary device on the screen */ 1761 if (ptmp != conf_screen->scrn_device) { 1762 conf_screen->scrn_gpu_devices[i] = ptmp; 1763 } else { 1764 sdevice = ptmp->list.next; 1765 i--; /* run the next iteration with the same index */ 1766 continue; 1767 } 1768 1769 screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec)); 1770 if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) { 1771 screenp->gpu_devices[i]->myScreenSection = screenp; 1772 } 1773 sdevice = conf_screen->scrn_gpu_devices[i]->list.next; 1774 } 1775 screenp->num_gpu_devices = i; 1776 1777 } else { 1778 for (i = 0; i < conf_screen->num_gpu_devices; i++) { 1779 screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec)); 1780 if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) { 1781 screenp->gpu_devices[i]->myScreenSection = screenp; 1782 } 1783 } 1784 screenp->num_gpu_devices = conf_screen->num_gpu_devices; 1785 } 1786 1787 screenp->options = conf_screen->scrn_option_lst; 1788 1789 /* 1790 * figure out how many display subsections there are and fill them in 1791 */ 1792 dispptr = conf_screen->scrn_display_lst; 1793 while (dispptr) { 1794 count++; 1795 dispptr = (XF86ConfDisplayPtr) dispptr->list.next; 1796 } 1797 screenp->displays = xnfallocarray(count, sizeof(DispPtr)); 1798 screenp->numdisplays = count; 1799 1800 for (count = 0, dispptr = conf_screen->scrn_display_lst; 1801 dispptr; 1802 dispptr = (XF86ConfDisplayPtr) dispptr->list.next, count++) { 1803 1804 /* Allocate individual Display records */ 1805 screenp->displays[count] = xnfcalloc(1, sizeof(DispRec)); 1806 1807 /* Fill in the default Virtual size, if any */ 1808 if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) { 1809 screenp->displays[count]->virtualX = conf_screen->scrn_virtualX; 1810 screenp->displays[count]->virtualY = conf_screen->scrn_virtualY; 1811 } 1812 1813 /* Now do the per-Display Virtual sizes */ 1814 configDisplay(screenp->displays[count], dispptr); 1815 } 1816 1817 /* 1818 * figure out how many videoadaptor references there are and fill them in 1819 */ 1820 count = 0; 1821 conf_adaptor = conf_screen->scrn_adaptor_lst; 1822 while (conf_adaptor) { 1823 count++; 1824 conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next; 1825 } 1826 screenp->xvadaptors = xnfallocarray(count, sizeof(confXvAdaptorRec)); 1827 screenp->numxvadaptors = 0; 1828 conf_adaptor = conf_screen->scrn_adaptor_lst; 1829 while (conf_adaptor) { 1830 if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]), 1831 conf_adaptor->al_adaptor)) 1832 screenp->numxvadaptors++; 1833 conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next; 1834 } 1835 1836 if (defaultMonitor) { 1837 xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n" 1838 "\tUsing a default monitor configuration.\n", screenp->id); 1839 } 1840 return TRUE; 1841 } 1842 1843 typedef enum { 1844 MON_REDUCEDBLANKING, 1845 MON_MAX_PIX_CLOCK, 1846 } MonitorValues; 1847 1848 static OptionInfoRec MonitorOptions[] = { 1849 {MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN, 1850 {0}, FALSE}, 1851 {MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ, 1852 {0}, FALSE}, 1853 {-1, NULL, OPTV_NONE, 1854 {0}, FALSE}, 1855 }; 1856 1857 static Bool 1858 configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor) 1859 { 1860 int count; 1861 DisplayModePtr mode, last = NULL; 1862 XF86ConfModeLinePtr cmodep; 1863 XF86ConfModesPtr modes; 1864 XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst; 1865 Gamma zeros = { 0.0, 0.0, 0.0 }; 1866 float badgamma = 0.0; 1867 double maxPixClock; 1868 1869 xf86Msg(X_CONFIG, "| |-->Monitor \"%s\"\n", conf_monitor->mon_identifier); 1870 monitorp->id = conf_monitor->mon_identifier; 1871 monitorp->vendor = conf_monitor->mon_vendor; 1872 monitorp->model = conf_monitor->mon_modelname; 1873 monitorp->Modes = NULL; 1874 monitorp->Last = NULL; 1875 monitorp->gamma = zeros; 1876 monitorp->widthmm = conf_monitor->mon_width; 1877 monitorp->heightmm = conf_monitor->mon_height; 1878 monitorp->reducedblanking = FALSE; 1879 monitorp->maxPixClock = 0; 1880 monitorp->options = conf_monitor->mon_option_lst; 1881 1882 /* 1883 * fill in the monitor structure 1884 */ 1885 for (count = 0; 1886 count < conf_monitor->mon_n_hsync && count < MAX_HSYNC; count++) { 1887 monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi; 1888 monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo; 1889 } 1890 monitorp->nHsync = count; 1891 for (count = 0; 1892 count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH; 1893 count++) { 1894 monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi; 1895 monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo; 1896 } 1897 monitorp->nVrefresh = count; 1898 1899 /* 1900 * first we collect the mode lines from the UseModes directive 1901 */ 1902 while (modeslnk) { 1903 modes = xf86findModes(modeslnk->ml_modes_str, 1904 xf86configptr->conf_modes_lst); 1905 modeslnk->ml_modes = modes; 1906 1907 /* now add the modes found in the modes 1908 section to the list of modes for this 1909 monitor unless it has been added before 1910 because we are reusing the same section 1911 for another screen */ 1912 if (xf86itemNotSublist((GenericListPtr) conf_monitor->mon_modeline_lst, 1913 (GenericListPtr) modes->mon_modeline_lst)) { 1914 conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr) 1915 xf86addListItem((GenericListPtr) conf_monitor->mon_modeline_lst, 1916 (GenericListPtr) modes->mon_modeline_lst); 1917 } 1918 modeslnk = modeslnk->list.next; 1919 } 1920 1921 /* 1922 * we need to hook in the mode lines now 1923 * here both data structures use lists, only our internal one 1924 * is double linked 1925 */ 1926 cmodep = conf_monitor->mon_modeline_lst; 1927 while (cmodep) { 1928 mode = xnfcalloc(1, sizeof(DisplayModeRec)); 1929 mode->type = 0; 1930 mode->Clock = cmodep->ml_clock; 1931 mode->HDisplay = cmodep->ml_hdisplay; 1932 mode->HSyncStart = cmodep->ml_hsyncstart; 1933 mode->HSyncEnd = cmodep->ml_hsyncend; 1934 mode->HTotal = cmodep->ml_htotal; 1935 mode->VDisplay = cmodep->ml_vdisplay; 1936 mode->VSyncStart = cmodep->ml_vsyncstart; 1937 mode->VSyncEnd = cmodep->ml_vsyncend; 1938 mode->VTotal = cmodep->ml_vtotal; 1939 mode->Flags = cmodep->ml_flags; 1940 mode->HSkew = cmodep->ml_hskew; 1941 mode->VScan = cmodep->ml_vscan; 1942 mode->name = xnfstrdup(cmodep->ml_identifier); 1943 if (last) { 1944 mode->prev = last; 1945 last->next = mode; 1946 } 1947 else { 1948 /* 1949 * this is the first mode 1950 */ 1951 monitorp->Modes = mode; 1952 mode->prev = NULL; 1953 } 1954 last = mode; 1955 cmodep = (XF86ConfModeLinePtr) cmodep->list.next; 1956 } 1957 if (last) { 1958 last->next = NULL; 1959 } 1960 monitorp->Last = last; 1961 1962 /* add the (VESA) default modes */ 1963 if (!addDefaultModes(monitorp)) 1964 return FALSE; 1965 1966 if (conf_monitor->mon_gamma_red > GAMMA_ZERO) 1967 monitorp->gamma.red = conf_monitor->mon_gamma_red; 1968 if (conf_monitor->mon_gamma_green > GAMMA_ZERO) 1969 monitorp->gamma.green = conf_monitor->mon_gamma_green; 1970 if (conf_monitor->mon_gamma_blue > GAMMA_ZERO) 1971 monitorp->gamma.blue = conf_monitor->mon_gamma_blue; 1972 1973 /* Check that the gamma values are within range */ 1974 if (monitorp->gamma.red > GAMMA_ZERO && 1975 (monitorp->gamma.red < GAMMA_MIN || monitorp->gamma.red > GAMMA_MAX)) { 1976 badgamma = monitorp->gamma.red; 1977 } 1978 else if (monitorp->gamma.green > GAMMA_ZERO && 1979 (monitorp->gamma.green < GAMMA_MIN || 1980 monitorp->gamma.green > GAMMA_MAX)) { 1981 badgamma = monitorp->gamma.green; 1982 } 1983 else if (monitorp->gamma.blue > GAMMA_ZERO && 1984 (monitorp->gamma.blue < GAMMA_MIN || 1985 monitorp->gamma.blue > GAMMA_MAX)) { 1986 badgamma = monitorp->gamma.blue; 1987 } 1988 if (badgamma > GAMMA_ZERO) { 1989 ErrorF("Gamma value %.f is out of range (%.2f - %.1f)\n", badgamma, 1990 GAMMA_MIN, GAMMA_MAX); 1991 return FALSE; 1992 } 1993 1994 xf86ProcessOptions(-1, monitorp->options, MonitorOptions); 1995 xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING, 1996 &monitorp->reducedblanking); 1997 if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ, 1998 &maxPixClock) == TRUE) { 1999 monitorp->maxPixClock = (int) maxPixClock; 2000 } 2001 2002 return TRUE; 2003 } 2004 2005 static int 2006 lookupVisual(const char *visname) 2007 { 2008 int i; 2009 2010 if (!visname || !*visname) 2011 return -1; 2012 2013 for (i = 0; i <= DirectColor; i++) { 2014 if (!xf86nameCompare(visname, xf86VisualNames[i])) 2015 break; 2016 } 2017 2018 if (i <= DirectColor) 2019 return i; 2020 2021 return -1; 2022 } 2023 2024 static Bool 2025 configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display) 2026 { 2027 int count = 0; 2028 XF86ModePtr modep; 2029 2030 displayp->frameX0 = conf_display->disp_frameX0; 2031 displayp->frameY0 = conf_display->disp_frameY0; 2032 displayp->virtualX = conf_display->disp_virtualX; 2033 displayp->virtualY = conf_display->disp_virtualY; 2034 displayp->depth = conf_display->disp_depth; 2035 displayp->fbbpp = conf_display->disp_bpp; 2036 displayp->weight.red = conf_display->disp_weight.red; 2037 displayp->weight.green = conf_display->disp_weight.green; 2038 displayp->weight.blue = conf_display->disp_weight.blue; 2039 displayp->blackColour.red = conf_display->disp_black.red; 2040 displayp->blackColour.green = conf_display->disp_black.green; 2041 displayp->blackColour.blue = conf_display->disp_black.blue; 2042 displayp->whiteColour.red = conf_display->disp_white.red; 2043 displayp->whiteColour.green = conf_display->disp_white.green; 2044 displayp->whiteColour.blue = conf_display->disp_white.blue; 2045 displayp->options = conf_display->disp_option_lst; 2046 if (conf_display->disp_visual) { 2047 displayp->defaultVisual = lookupVisual(conf_display->disp_visual); 2048 if (displayp->defaultVisual == -1) { 2049 ErrorF("Invalid visual name: \"%s\"\n", conf_display->disp_visual); 2050 return FALSE; 2051 } 2052 } 2053 else { 2054 displayp->defaultVisual = -1; 2055 } 2056 2057 /* 2058 * now hook in the modes 2059 */ 2060 modep = conf_display->disp_mode_lst; 2061 while (modep) { 2062 count++; 2063 modep = (XF86ModePtr) modep->list.next; 2064 } 2065 displayp->modes = xnfallocarray(count + 1, sizeof(char *)); 2066 modep = conf_display->disp_mode_lst; 2067 count = 0; 2068 while (modep) { 2069 displayp->modes[count] = modep->mode_name; 2070 count++; 2071 modep = (XF86ModePtr) modep->list.next; 2072 } 2073 displayp->modes[count] = NULL; 2074 2075 return TRUE; 2076 } 2077 2078 static Bool 2079 configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool gpu) 2080 { 2081 int i; 2082 2083 if (!conf_device) { 2084 return FALSE; 2085 } 2086 2087 if (active) { 2088 if (gpu) 2089 xf86Msg(X_CONFIG, "| |-->GPUDevice \"%s\"\n", 2090 conf_device->dev_identifier); 2091 else 2092 xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n", 2093 conf_device->dev_identifier); 2094 } else 2095 xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n", 2096 conf_device->dev_identifier); 2097 2098 devicep->identifier = conf_device->dev_identifier; 2099 devicep->vendor = conf_device->dev_vendor; 2100 devicep->board = conf_device->dev_board; 2101 devicep->chipset = conf_device->dev_chipset; 2102 devicep->ramdac = conf_device->dev_ramdac; 2103 devicep->driver = conf_device->dev_driver; 2104 devicep->active = active; 2105 devicep->videoRam = conf_device->dev_videoram; 2106 devicep->MemBase = conf_device->dev_mem_base; 2107 devicep->IOBase = conf_device->dev_io_base; 2108 devicep->clockchip = conf_device->dev_clockchip; 2109 devicep->busID = conf_device->dev_busid; 2110 devicep->chipID = conf_device->dev_chipid; 2111 devicep->chipRev = conf_device->dev_chiprev; 2112 devicep->options = conf_device->dev_option_lst; 2113 devicep->irq = conf_device->dev_irq; 2114 devicep->screen = conf_device->dev_screen; 2115 2116 for (i = 0; i < MAXDACSPEEDS; i++) { 2117 if (i < CONF_MAXDACSPEEDS) 2118 devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i]; 2119 else 2120 devicep->dacSpeeds[i] = 0; 2121 } 2122 devicep->numclocks = conf_device->dev_clocks; 2123 if (devicep->numclocks > MAXCLOCKS) 2124 devicep->numclocks = MAXCLOCKS; 2125 for (i = 0; i < devicep->numclocks; i++) { 2126 devicep->clock[i] = conf_device->dev_clock[i]; 2127 } 2128 devicep->claimed = FALSE; 2129 2130 return TRUE; 2131 } 2132 2133 static void 2134 configDRI(XF86ConfDRIPtr drip) 2135 { 2136 struct group *grp; 2137 2138 xf86ConfigDRI.group = -1; 2139 xf86ConfigDRI.mode = 0; 2140 2141 if (drip) { 2142 if (drip->dri_group_name) { 2143 if ((grp = getgrnam(drip->dri_group_name))) 2144 xf86ConfigDRI.group = grp->gr_gid; 2145 } 2146 else { 2147 if (drip->dri_group >= 0) 2148 xf86ConfigDRI.group = drip->dri_group; 2149 } 2150 xf86ConfigDRI.mode = drip->dri_mode; 2151 } 2152 } 2153 2154 static void 2155 configExtensions(XF86ConfExtensionsPtr conf_ext) 2156 { 2157 XF86OptionPtr o; 2158 2159 if (conf_ext && conf_ext->ext_option_lst) { 2160 for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) { 2161 char *name = xf86OptionName(o); 2162 char *val = xf86OptionValue(o); 2163 char *n; 2164 Bool enable = TRUE; 2165 2166 /* Handle "No<ExtensionName>" */ 2167 n = xf86NormalizeName(name); 2168 if (strncmp(n, "no", 2) == 0) { 2169 name += 2; 2170 enable = FALSE; 2171 } 2172 2173 if (!val || 2174 xf86NameCmp(val, "enable") == 0 || 2175 xf86NameCmp(val, "enabled") == 0 || 2176 xf86NameCmp(val, "on") == 0 || 2177 xf86NameCmp(val, "1") == 0 || 2178 xf86NameCmp(val, "yes") == 0 || xf86NameCmp(val, "true") == 0) { 2179 /* NOTHING NEEDED -- enabling is handled below */ 2180 } 2181 else if (xf86NameCmp(val, "disable") == 0 || 2182 xf86NameCmp(val, "disabled") == 0 || 2183 xf86NameCmp(val, "off") == 0 || 2184 xf86NameCmp(val, "0") == 0 || 2185 xf86NameCmp(val, "no") == 0 || 2186 xf86NameCmp(val, "false") == 0) { 2187 enable = !enable; 2188 } 2189 else { 2190 xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val); 2191 free(n); 2192 continue; 2193 } 2194 2195 if (EnableDisableExtension(name, enable)) { 2196 xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n", 2197 name, enable ? "enabled" : "disabled"); 2198 } 2199 else { 2200 xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n", 2201 name); 2202 } 2203 free(n); 2204 } 2205 } 2206 } 2207 2208 static Bool 2209 configInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from) 2210 { 2211 xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier); 2212 inputp->name = conf_input->inp_identifier; 2213 inputp->driver = conf_input->inp_driver; 2214 inputp->options = conf_input->inp_option_lst; 2215 inputp->attrs = NULL; 2216 2217 return TRUE; 2218 } 2219 2220 static Bool 2221 modeIsPresent(DisplayModePtr mode, MonPtr monitorp) 2222 { 2223 DisplayModePtr knownmodes = monitorp->Modes; 2224 2225 /* all I can think of is a linear search... */ 2226 while (knownmodes != NULL) { 2227 if (!strcmp(mode->name, knownmodes->name) && 2228 !(knownmodes->type & M_T_DEFAULT)) 2229 return TRUE; 2230 knownmodes = knownmodes->next; 2231 } 2232 return FALSE; 2233 } 2234 2235 static Bool 2236 addDefaultModes(MonPtr monitorp) 2237 { 2238 DisplayModePtr mode; 2239 DisplayModePtr last = monitorp->Last; 2240 int i = 0; 2241 2242 for (i = 0; i < xf86NumDefaultModes; i++) { 2243 mode = xf86DuplicateMode(&xf86DefaultModes[i]); 2244 if (!modeIsPresent(mode, monitorp)) { 2245 monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode); 2246 last = mode; 2247 } 2248 else { 2249 free(mode); 2250 } 2251 } 2252 monitorp->Last = last; 2253 2254 return TRUE; 2255 } 2256 2257 static void 2258 checkInput(serverLayoutPtr layout, Bool implicit_layout) 2259 { 2260 checkCoreInputDevices(layout, implicit_layout); 2261 2262 /* Unless we're forcing input devices, disable mouse/kbd devices in the 2263 * config. Otherwise the same physical device is added multiple times, 2264 * leading to duplicate events. 2265 */ 2266 if (!xf86Info.forceInputDevices && layout->inputs) { 2267 InputInfoPtr *dev = layout->inputs; 2268 BOOL warned = FALSE; 2269 2270 while (*dev) { 2271 if (strcmp((*dev)->driver, "kbd") == 0 || 2272 strcmp((*dev)->driver, "mouse") == 0 || 2273 strcmp((*dev)->driver, "vmmouse") == 0) { 2274 InputInfoPtr *current; 2275 2276 if (!warned) { 2277 xf86Msg(X_WARNING, "Hotplugging is on, devices using " 2278 "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n"); 2279 warned = TRUE; 2280 } 2281 2282 xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name); 2283 2284 current = dev; 2285 free(*dev); 2286 *dev = NULL; 2287 2288 do { 2289 *current = *(current + 1); 2290 current++; 2291 } while (*current); 2292 } 2293 else 2294 dev++; 2295 } 2296 } 2297 } 2298 2299 /* 2300 * load the config file and fill the global data structure 2301 */ 2302 ConfigStatus 2303 xf86HandleConfigFile(Bool autoconfig) 2304 { 2305 #ifdef XSERVER_LIBPCIACCESS 2306 const char *scanptr; 2307 Bool singlecard = 0; 2308 #endif 2309 Bool implicit_layout = FALSE; 2310 XF86ConfLayoutPtr layout; 2311 2312 if (!autoconfig) { 2313 char *filename, *dirname, *sysdirname; 2314 const char *filesearch, *dirsearch; 2315 MessageType filefrom = X_DEFAULT; 2316 MessageType dirfrom = X_DEFAULT; 2317 2318 if (!PrivsElevated()) { 2319 filesearch = ALL_CONFIGPATH; 2320 dirsearch = ALL_CONFIGDIRPATH; 2321 } 2322 else { 2323 filesearch = RESTRICTED_CONFIGPATH; 2324 dirsearch = RESTRICTED_CONFIGDIRPATH; 2325 } 2326 2327 if (xf86ConfigFile) 2328 filefrom = X_CMDLINE; 2329 if (xf86ConfigDir) 2330 dirfrom = X_CMDLINE; 2331 2332 xf86initConfigFiles(); 2333 sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL, 2334 PROJECTROOT); 2335 dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT); 2336 filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT); 2337 if (filename) { 2338 xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename); 2339 xf86ConfigFile = xnfstrdup(filename); 2340 } 2341 else { 2342 if (xf86ConfigFile) 2343 xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n", 2344 xf86ConfigFile); 2345 } 2346 if (dirname) { 2347 xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n", 2348 dirname); 2349 xf86ConfigDir = xnfstrdup(dirname); 2350 } 2351 else { 2352 if (xf86ConfigDir) 2353 xf86Msg(X_ERROR, 2354 "Unable to locate/open config directory: \"%s\"\n", 2355 xf86ConfigDir); 2356 } 2357 if (sysdirname) 2358 xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n", 2359 sysdirname); 2360 if (!filename && !dirname && !sysdirname) 2361 return CONFIG_NOFILE; 2362 2363 free(filename); 2364 free(dirname); 2365 free(sysdirname); 2366 } 2367 2368 if ((xf86configptr = xf86readConfigFile()) == NULL) { 2369 xf86Msg(X_ERROR, "Problem parsing the config file\n"); 2370 return CONFIG_PARSE_ERROR; 2371 } 2372 xf86closeConfigFile(); 2373 2374 /* Initialise a few things. */ 2375 2376 /* 2377 * now we convert part of the information contained in the parser 2378 * structures into our own structures. 2379 * The important part here is to figure out which Screen Sections 2380 * in the XF86Config file are active so that we can piece together 2381 * the modes that we need later down the road. 2382 * And while we are at it, we'll decode the rest of the stuff as well 2383 */ 2384 2385 /* First check if a layout section is present, and if it is valid. */ 2386 FIND_SUITABLE(XF86ConfLayoutPtr, xf86configptr->conf_layout_lst, layout); 2387 if (layout == NULL || xf86ScreenName != NULL) { 2388 XF86ConfScreenPtr screen; 2389 2390 if (xf86ScreenName == NULL) { 2391 xf86Msg(X_DEFAULT, 2392 "No Layout section. Using the first Screen section.\n"); 2393 } 2394 FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen); 2395 if (!configImpliedLayout(&xf86ConfigLayout, 2396 screen, 2397 xf86configptr)) { 2398 xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); 2399 return CONFIG_PARSE_ERROR; 2400 } 2401 implicit_layout = TRUE; 2402 } 2403 else { 2404 if (xf86configptr->conf_flags != NULL) { 2405 char *dfltlayout = NULL; 2406 void *optlist = xf86configptr->conf_flags->flg_option_lst; 2407 2408 if (optlist && xf86FindOption(optlist, "defaultserverlayout")) 2409 dfltlayout = 2410 xf86SetStrOption(optlist, "defaultserverlayout", NULL); 2411 if (!configLayout(&xf86ConfigLayout, layout, dfltlayout)) { 2412 xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); 2413 return CONFIG_PARSE_ERROR; 2414 } 2415 } 2416 else { 2417 if (!configLayout(&xf86ConfigLayout, layout, NULL)) { 2418 xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); 2419 return CONFIG_PARSE_ERROR; 2420 } 2421 } 2422 } 2423 2424 xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions); 2425 #ifdef XSERVER_LIBPCIACCESS 2426 if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) { 2427 ; /* IsolateDevice specified; overrides SingleCard */ 2428 } 2429 else { 2430 xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard); 2431 if (singlecard) 2432 scanptr = xf86ConfigLayout.screens->screen->device->busID; 2433 } 2434 if (scanptr) { 2435 if (strncmp(scanptr, "PCI:", 4) != 0) { 2436 xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n" 2437 "\tIgnoring IsolateDevice option.\n"); 2438 } 2439 else 2440 xf86PciIsolateDevice(scanptr); 2441 } 2442 #endif 2443 /* Now process everything else */ 2444 configServerFlags(xf86configptr->conf_flags, xf86ConfigLayout.options); 2445 configFiles(xf86configptr->conf_files); 2446 configExtensions(xf86configptr->conf_extensions); 2447 configDRI(xf86configptr->conf_dri); 2448 2449 checkInput(&xf86ConfigLayout, implicit_layout); 2450 2451 /* 2452 * Handle some command line options that can override some of the 2453 * ServerFlags settings. 2454 */ 2455 #ifdef XF86VIDMODE 2456 if (xf86VidModeDisabled) 2457 xf86Info.vidModeEnabled = FALSE; 2458 if (xf86VidModeAllowNonLocal) 2459 xf86Info.vidModeAllowNonLocal = TRUE; 2460 #endif 2461 2462 if (xf86AllowMouseOpenFail) 2463 xf86Info.allowMouseOpenFail = TRUE; 2464 2465 return CONFIG_OK; 2466 } 2467 2468 Bool 2469 xf86PathIsSafe(const char *path) 2470 { 2471 return (xf86pathIsSafe(path) != 0); 2472 }