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