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