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 defPtr.inp_driver = strdup("mouse"); 1119 confInput = &defPtr; 1120 foundPointer = TRUE; 1121 from = X_DEFAULT; 1122 pointerMsg = "default mouse configuration"; 1123 } 1124 1125 /* Add the core pointer device to the layout, and set it to Core. */ 1126 if (foundPointer && confInput) { 1127 Pointer = xf86AllocateInput(); 1128 if (Pointer) 1129 foundPointer = configInput(Pointer, confInput, from); 1130 if (foundPointer) { 1131 Pointer->options = xf86AddNewOption(Pointer->options, 1132 "CorePointer", "on"); 1133 Pointer->options = xf86AddNewOption(Pointer->options, 1134 "driver", 1135 confInput->inp_driver); 1136 Pointer->options = 1137 xf86AddNewOption(Pointer->options, "identifier", 1138 confInput->inp_identifier); 1139 servlayoutp->inputs = addDevice(servlayoutp->inputs, Pointer); 1140 } 1141 } 1142 1143 if (!foundPointer && xf86Info.forceInputDevices) { 1144 /* This shouldn't happen. */ 1145 xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n"); 1146 xf86DeleteInput(Pointer, 0); 1147 return FALSE; 1148 } 1149 1150 confInput = NULL; 1151 1152 /* 1. Check for the -keyboard command line option. */ 1153 if (xf86KeyboardName) { 1154 confInput = xf86findInput(xf86KeyboardName, 1155 xf86configptr->conf_input_lst); 1156 if (!confInput) { 1157 xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n", 1158 xf86KeyboardName); 1159 return FALSE; 1160 } 1161 from = X_CMDLINE; 1162 /* 1163 * If one was already specified in the ServerLayout, it needs to be 1164 * removed. 1165 */ 1166 if (coreKeyboard) { 1167 freeDevice(servlayoutp->inputs, coreKeyboard); 1168 coreKeyboard = NULL; 1169 } 1170 foundKeyboard = TRUE; 1171 } 1172 1173 /* 2. ServerLayout-specified core keyboard. */ 1174 if (coreKeyboard) { 1175 foundKeyboard = TRUE; 1176 from = X_CONFIG; 1177 } 1178 1179 /* 3. First core keyboard device. */ 1180 if (!foundKeyboard && (xf86Info.forceInputDevices || implicitLayout)) { 1181 XF86ConfInputPtr p; 1182 1183 for (p = xf86configptr->conf_input_lst; p; p = p->list.next) { 1184 if (p->inp_option_lst && 1185 xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) { 1186 confInput = p; 1187 foundKeyboard = TRUE; 1188 from = X_DEFAULT; 1189 keyboardMsg = "first core keyboard device"; 1190 break; 1191 } 1192 } 1193 } 1194 1195 /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */ 1196 if (!foundKeyboard && xf86Info.forceInputDevices) { 1197 confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD, 1198 xf86configptr->conf_input_lst); 1199 if (!confInput) { 1200 confInput = xf86findInputByDriver("kbd", 1201 xf86configptr->conf_input_lst); 1202 } 1203 if (confInput) { 1204 foundKeyboard = TRUE; 1205 from = X_DEFAULT; 1206 keyboardMsg = "first keyboard device"; 1207 } 1208 } 1209 1210 /* 5. Built-in default. */ 1211 if (!foundKeyboard && xf86Info.forceInputDevices) { 1212 memset(&defKbd, 0, sizeof(defKbd)); 1213 defKbd.inp_identifier = strdup("<default keyboard>"); 1214 defKbd.inp_driver = strdup("kbd"); 1215 confInput = &defKbd; 1216 foundKeyboard = TRUE; 1217 keyboardMsg = "default keyboard configuration"; 1218 from = X_DEFAULT; 1219 } 1220 1221 /* Add the core keyboard device to the layout, and set it to Core. */ 1222 if (foundKeyboard && confInput) { 1223 Keyboard = xf86AllocateInput(); 1224 if (Keyboard) 1225 foundKeyboard = configInput(Keyboard, confInput, from); 1226 if (foundKeyboard) { 1227 Keyboard->options = xf86AddNewOption(Keyboard->options, 1228 "CoreKeyboard", "on"); 1229 Keyboard->options = xf86AddNewOption(Keyboard->options, 1230 "driver", 1231 confInput->inp_driver); 1232 Keyboard->options = 1233 xf86AddNewOption(Keyboard->options, "identifier", 1234 confInput->inp_identifier); 1235 servlayoutp->inputs = addDevice(servlayoutp->inputs, Keyboard); 1236 } 1237 } 1238 1239 if (!foundKeyboard && xf86Info.forceInputDevices) { 1240 /* This shouldn't happen. */ 1241 xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n"); 1242 xf86DeleteInput(Keyboard, 0); 1243 return FALSE; 1244 } 1245 1246 if (pointerMsg) { 1247 if (implicitLayout) 1248 xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n", 1249 pointerMsg); 1250 else 1251 xf86Msg(X_DEFAULT, "The core pointer device wasn't specified " 1252 "explicitly in the layout.\n" 1253 "\tUsing the %s.\n", pointerMsg); 1254 } 1255 1256 if (keyboardMsg) { 1257 if (implicitLayout) 1258 xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n", 1259 keyboardMsg); 1260 else 1261 xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified " 1262 "explicitly in the layout.\n" 1263 "\tUsing the %s.\n", keyboardMsg); 1264 } 1265 1266 if (!xf86Info.forceInputDevices && !(foundPointer && foundKeyboard)) { 1267#if defined(CONFIG_HAL) || defined(CONFIG_UDEV) || defined(CONFIG_WSCONS) 1268 const char *config_backend; 1269 1270#if defined(CONFIG_HAL) 1271 config_backend = "HAL"; 1272#elif defined(CONFIG_UDEV) 1273 config_backend = "udev"; 1274#else 1275 config_backend = "wscons"; 1276#endif 1277 xf86Msg(X_INFO, "The server relies on %s to provide the list of " 1278 "input devices.\n\tIf no devices become available, " 1279 "reconfigure %s or disable AutoAddDevices.\n", 1280 config_backend, config_backend); 1281#else 1282 xf86Msg(X_WARNING, "Hotplugging requested but the server was " 1283 "compiled without a config backend. " 1284 "No input devices were configured, the server " 1285 "will start without any input devices.\n"); 1286#endif 1287 } 1288 1289 return TRUE; 1290} 1291 1292typedef enum { 1293 LAYOUT_ISOLATEDEVICE, 1294 LAYOUT_SINGLECARD 1295} LayoutValues; 1296 1297static OptionInfoRec LayoutOptions[] = { 1298 {LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING, 1299 {0}, FALSE}, 1300 {LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN, 1301 {0}, FALSE}, 1302 {-1, NULL, OPTV_NONE, 1303 {0}, FALSE}, 1304}; 1305 1306static Bool 1307configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp) 1308{ 1309 XF86ConfInputrefPtr irp; 1310 InputInfoPtr *indp; 1311 int count = 0; 1312 1313 /* 1314 * Count the number of input devices. 1315 */ 1316 irp = layout->lay_input_lst; 1317 while (irp) { 1318 count++; 1319 irp = (XF86ConfInputrefPtr) irp->list.next; 1320 } 1321 DebugF("Found %d input devices in the layout section %s\n", 1322 count, layout->lay_identifier); 1323 indp = xnfcalloc((count + 1), sizeof(InputInfoPtr)); 1324 indp[count] = NULL; 1325 irp = layout->lay_input_lst; 1326 count = 0; 1327 while (irp) { 1328 indp[count] = xf86AllocateInput(); 1329 if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) { 1330 do { 1331 free(indp[count]); 1332 } while (count--); 1333 free(indp); 1334 return FALSE; 1335 } 1336 indp[count]->options = xf86OptionListMerge(indp[count]->options, 1337 irp->iref_option_lst); 1338 count++; 1339 irp = (XF86ConfInputrefPtr) irp->list.next; 1340 } 1341 servlayoutp->inputs = indp; 1342 1343 return TRUE; 1344} 1345 1346/* 1347 * figure out which layout is active, which screens are used in that layout, 1348 * which drivers and monitors are used in these screens 1349 */ 1350static Bool 1351configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, 1352 char *default_layout) 1353{ 1354 XF86ConfAdjacencyPtr adjp; 1355 XF86ConfInactivePtr idp; 1356 int saved_count, count = 0; 1357 int scrnum; 1358 XF86ConfLayoutPtr l; 1359 MessageType from; 1360 screenLayoutPtr slp; 1361 GDevPtr gdp; 1362 int i = 0, j; 1363 1364 if (!servlayoutp) 1365 return FALSE; 1366 1367 /* 1368 * which layout section is the active one? 1369 * 1370 * If there is a -layout command line option, use that one, otherwise 1371 * pick the first one. 1372 */ 1373 from = X_DEFAULT; 1374 if (xf86LayoutName != NULL) 1375 from = X_CMDLINE; 1376 else if (default_layout) { 1377 xf86LayoutName = default_layout; 1378 from = X_CONFIG; 1379 } 1380 if (xf86LayoutName != NULL) { 1381 if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) { 1382 xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n", 1383 xf86LayoutName); 1384 return FALSE; 1385 } 1386 conf_layout = l; 1387 } 1388 xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier); 1389 adjp = conf_layout->lay_adjacency_lst; 1390 1391 /* 1392 * we know that each screen is referenced exactly once on the left side 1393 * of a layout statement in the Layout section. So to allocate the right 1394 * size for the array we do a quick walk of the list to figure out how 1395 * many sections we have 1396 */ 1397 while (adjp) { 1398 count++; 1399 adjp = (XF86ConfAdjacencyPtr) adjp->list.next; 1400 } 1401 1402 DebugF("Found %d screens in the layout section %s", 1403 count, conf_layout->lay_identifier); 1404 if (!count) /* alloc enough storage even if no screen is specified */ 1405 count = 1; 1406 1407 slp = xnfcalloc((count + 1), sizeof(screenLayoutRec)); 1408 slp[count].screen = NULL; 1409 /* 1410 * now that we have storage, loop over the list again and fill in our 1411 * data structure; at this point we do not fill in the adjacency 1412 * information as it is not clear if we need it at all 1413 */ 1414 adjp = conf_layout->lay_adjacency_lst; 1415 count = 0; 1416 while (adjp) { 1417 slp[count].screen = xnfcalloc(1, sizeof(confScreenRec)); 1418 if (adjp->adj_scrnum < 0) 1419 scrnum = count; 1420 else 1421 scrnum = adjp->adj_scrnum; 1422 if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum, 1423 X_CONFIG, (scrnum == 0 && !adjp->list.next))) { 1424 do { 1425 free(slp[count].screen); 1426 } while (count--); 1427 free(slp); 1428 return FALSE; 1429 } 1430 slp[count].x = adjp->adj_x; 1431 slp[count].y = adjp->adj_y; 1432 slp[count].refname = adjp->adj_refscreen; 1433 switch (adjp->adj_where) { 1434 case CONF_ADJ_OBSOLETE: 1435 slp[count].where = PosObsolete; 1436 slp[count].topname = adjp->adj_top_str; 1437 slp[count].bottomname = adjp->adj_bottom_str; 1438 slp[count].leftname = adjp->adj_left_str; 1439 slp[count].rightname = adjp->adj_right_str; 1440 break; 1441 case CONF_ADJ_ABSOLUTE: 1442 slp[count].where = PosAbsolute; 1443 break; 1444 case CONF_ADJ_RIGHTOF: 1445 slp[count].where = PosRightOf; 1446 break; 1447 case CONF_ADJ_LEFTOF: 1448 slp[count].where = PosLeftOf; 1449 break; 1450 case CONF_ADJ_ABOVE: 1451 slp[count].where = PosAbove; 1452 break; 1453 case CONF_ADJ_BELOW: 1454 slp[count].where = PosBelow; 1455 break; 1456 case CONF_ADJ_RELATIVE: 1457 slp[count].where = PosRelative; 1458 break; 1459 } 1460 count++; 1461 adjp = (XF86ConfAdjacencyPtr) adjp->list.next; 1462 } 1463 1464 /* No screen was specified in the layout. take the first one from the 1465 * config file, or - if it is NULL - configScreen autogenerates one for 1466 * us */ 1467 if (!count) { 1468 XF86ConfScreenPtr screen; 1469 1470 FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen); 1471 slp[0].screen = xnfcalloc(1, sizeof(confScreenRec)); 1472 if (!configScreen(slp[0].screen, screen, 1473 0, X_CONFIG, TRUE)) { 1474 free(slp[0].screen); 1475 free(slp); 1476 return FALSE; 1477 } 1478 } 1479 1480 /* XXX Need to tie down the upper left screen. */ 1481 1482 /* Fill in the refscreen and top/bottom/left/right values */ 1483 for (i = 0; i < count; i++) { 1484 for (j = 0; j < count; j++) { 1485 if (slp[i].refname && 1486 strcmp(slp[i].refname, slp[j].screen->id) == 0) { 1487 slp[i].refscreen = slp[j].screen; 1488 } 1489 if (slp[i].topname && 1490 strcmp(slp[i].topname, slp[j].screen->id) == 0) { 1491 slp[i].top = slp[j].screen; 1492 } 1493 if (slp[i].bottomname && 1494 strcmp(slp[i].bottomname, slp[j].screen->id) == 0) { 1495 slp[i].bottom = slp[j].screen; 1496 } 1497 if (slp[i].leftname && 1498 strcmp(slp[i].leftname, slp[j].screen->id) == 0) { 1499 slp[i].left = slp[j].screen; 1500 } 1501 if (slp[i].rightname && 1502 strcmp(slp[i].rightname, slp[j].screen->id) == 0) { 1503 slp[i].right = slp[j].screen; 1504 } 1505 } 1506 if (slp[i].where != PosObsolete 1507 && slp[i].where != PosAbsolute && !slp[i].refscreen) { 1508 xf86Msg(X_ERROR, "Screen %s doesn't exist: deleting placement\n", 1509 slp[i].refname); 1510 slp[i].where = PosAbsolute; 1511 slp[i].x = 0; 1512 slp[i].y = 0; 1513 } 1514 } 1515 1516 if (!count) 1517 saved_count = 1; 1518 else 1519 saved_count = count; 1520 /* 1521 * Count the number of inactive devices. 1522 */ 1523 count = 0; 1524 idp = conf_layout->lay_inactive_lst; 1525 while (idp) { 1526 count++; 1527 idp = (XF86ConfInactivePtr) idp->list.next; 1528 } 1529 DebugF("Found %d inactive devices in the layout section %s\n", 1530 count, conf_layout->lay_identifier); 1531 gdp = xnfallocarray(count + 1, sizeof(GDevRec)); 1532 gdp[count].identifier = NULL; 1533 idp = conf_layout->lay_inactive_lst; 1534 count = 0; 1535 while (idp) { 1536 if (!configDevice(&gdp[count], idp->inactive_device, FALSE, FALSE)) 1537 goto bail; 1538 count++; 1539 idp = (XF86ConfInactivePtr) idp->list.next; 1540 } 1541 1542 if (!configInputDevices(conf_layout, servlayoutp)) 1543 goto bail; 1544 1545 servlayoutp->id = conf_layout->lay_identifier; 1546 servlayoutp->screens = slp; 1547 servlayoutp->inactives = gdp; 1548 servlayoutp->options = conf_layout->lay_option_lst; 1549 from = X_DEFAULT; 1550 1551 return TRUE; 1552 1553 bail: 1554 do { 1555 free(slp[saved_count].screen); 1556 } while (saved_count--); 1557 free(slp); 1558 free(gdp); 1559 return FALSE; 1560} 1561 1562/* 1563 * No layout section, so find the first Screen section and set that up as 1564 * the only active screen. 1565 */ 1566static Bool 1567configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen, 1568 XF86ConfigPtr conf_ptr) 1569{ 1570 MessageType from; 1571 XF86ConfScreenPtr s; 1572 screenLayoutPtr slp; 1573 InputInfoPtr *indp; 1574 XF86ConfLayoutRec layout; 1575 1576 if (!servlayoutp) 1577 return FALSE; 1578 1579 /* 1580 * which screen section is the active one? 1581 * 1582 * If there is a -screen option, use that one, otherwise use the first 1583 * one. 1584 */ 1585 1586 from = X_CONFIG; 1587 if (xf86ScreenName != NULL) { 1588 if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) { 1589 xf86Msg(X_ERROR, "No Screen section called \"%s\"\n", 1590 xf86ScreenName); 1591 return FALSE; 1592 } 1593 conf_screen = s; 1594 from = X_CMDLINE; 1595 } 1596 1597 /* We have exactly one screen */ 1598 1599 slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec)); 1600 slp[0].screen = xnfcalloc(1, sizeof(confScreenRec)); 1601 slp[1].screen = NULL; 1602 if (!configScreen(slp[0].screen, conf_screen, 0, from, TRUE)) { 1603 free(slp); 1604 return FALSE; 1605 } 1606 servlayoutp->id = "(implicit)"; 1607 servlayoutp->screens = slp; 1608 servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec)); 1609 servlayoutp->options = NULL; 1610 1611 memset(&layout, 0, sizeof(layout)); 1612 layout.lay_identifier = servlayoutp->id; 1613 if (xf86layoutAddInputDevices(conf_ptr, &layout) > 0) { 1614 if (!configInputDevices(&layout, servlayoutp)) 1615 return FALSE; 1616 from = X_DEFAULT; 1617 } 1618 else { 1619 /* Set up an empty input device list, then look for some core devices. */ 1620 indp = xnfalloc(sizeof(InputInfoPtr)); 1621 *indp = NULL; 1622 servlayoutp->inputs = indp; 1623 } 1624 1625 return TRUE; 1626} 1627 1628static Bool 1629configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor) 1630{ 1631 int count = 0; 1632 XF86ConfVideoPortPtr conf_port; 1633 1634 xf86Msg(X_CONFIG, "| |-->VideoAdaptor \"%s\"\n", 1635 conf_adaptor->va_identifier); 1636 adaptor->identifier = conf_adaptor->va_identifier; 1637 adaptor->options = conf_adaptor->va_option_lst; 1638 if (conf_adaptor->va_busid || conf_adaptor->va_driver) { 1639 xf86Msg(X_CONFIG, "| | Unsupported device type, skipping entry\n"); 1640 return FALSE; 1641 } 1642 1643 /* 1644 * figure out how many videoport subsections there are and fill them in 1645 */ 1646 conf_port = conf_adaptor->va_port_lst; 1647 while (conf_port) { 1648 count++; 1649 conf_port = (XF86ConfVideoPortPtr) conf_port->list.next; 1650 } 1651 adaptor->ports = xnfallocarray(count, sizeof(confXvPortRec)); 1652 adaptor->numports = count; 1653 count = 0; 1654 conf_port = conf_adaptor->va_port_lst; 1655 while (conf_port) { 1656 adaptor->ports[count].identifier = conf_port->vp_identifier; 1657 adaptor->ports[count].options = conf_port->vp_option_lst; 1658 count++; 1659 conf_port = (XF86ConfVideoPortPtr) conf_port->list.next; 1660 } 1661 1662 return TRUE; 1663} 1664 1665static Bool 1666configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum, 1667 MessageType from, Bool auto_gpu_device) 1668{ 1669 int count = 0; 1670 XF86ConfDisplayPtr dispptr; 1671 XF86ConfAdaptorLinkPtr conf_adaptor; 1672 Bool defaultMonitor = FALSE; 1673 XF86ConfScreenRec local_conf_screen; 1674 int i; 1675 1676 if (!conf_screen) { 1677 memset(&local_conf_screen, 0, sizeof(local_conf_screen)); 1678 conf_screen = &local_conf_screen; 1679 conf_screen->scrn_identifier = "Default Screen Section"; 1680 xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n"); 1681 } 1682 1683 xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier, 1684 scrnum); 1685 /* 1686 * now we fill in the elements of the screen 1687 */ 1688 screenp->id = conf_screen->scrn_identifier; 1689 screenp->screennum = scrnum; 1690 screenp->defaultdepth = conf_screen->scrn_defaultdepth; 1691 screenp->defaultbpp = conf_screen->scrn_defaultbpp; 1692 screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp; 1693 screenp->monitor = xnfcalloc(1, sizeof(MonRec)); 1694 /* If no monitor is specified, create a default one. */ 1695 if (!conf_screen->scrn_monitor) { 1696 XF86ConfMonitorRec defMon; 1697 1698 memset(&defMon, 0, sizeof(defMon)); 1699 defMon.mon_identifier = "<default monitor>"; 1700 if (!configMonitor(screenp->monitor, &defMon)) 1701 return FALSE; 1702 defaultMonitor = TRUE; 1703 } 1704 else { 1705 if (!configMonitor(screenp->monitor, conf_screen->scrn_monitor)) 1706 return FALSE; 1707 } 1708 /* Configure the device. If there isn't one configured, attach to the 1709 * first inactive one that we can configure. If there's none that work, 1710 * set it to NULL so that the section can be autoconfigured later */ 1711 screenp->device = xnfcalloc(1, sizeof(GDevRec)); 1712 if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) { 1713 FIND_SUITABLE (XF86ConfDevicePtr, xf86configptr->conf_device_lst, conf_screen->scrn_device); 1714 xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n" 1715 "\tUsing the first device section listed.\n", screenp->id); 1716 } 1717 if (configDevice(screenp->device, conf_screen->scrn_device, TRUE, FALSE)) { 1718 screenp->device->myScreenSection = screenp; 1719 } 1720 else { 1721 screenp->device = NULL; 1722 } 1723 1724 if (auto_gpu_device && conf_screen->num_gpu_devices == 0 && 1725 xf86configptr->conf_device_lst) { 1726 XF86ConfDevicePtr sdevice = xf86configptr->conf_device_lst->list.next; 1727 1728 for (i = 0; i < MAX_GPUDEVICES; i++) { 1729 if (!sdevice) 1730 break; 1731 1732 FIND_SUITABLE (XF86ConfDevicePtr, sdevice, conf_screen->scrn_gpu_devices[i]); 1733 if (!conf_screen->scrn_gpu_devices[i]) 1734 break; 1735 screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec)); 1736 if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) { 1737 screenp->gpu_devices[i]->myScreenSection = screenp; 1738 } 1739 sdevice = conf_screen->scrn_gpu_devices[i]->list.next; 1740 } 1741 screenp->num_gpu_devices = i; 1742 1743 } else { 1744 for (i = 0; i < conf_screen->num_gpu_devices; i++) { 1745 screenp->gpu_devices[i] = xnfcalloc(1, sizeof(GDevRec)); 1746 if (configDevice(screenp->gpu_devices[i], conf_screen->scrn_gpu_devices[i], TRUE, TRUE)) { 1747 screenp->gpu_devices[i]->myScreenSection = screenp; 1748 } 1749 } 1750 screenp->num_gpu_devices = conf_screen->num_gpu_devices; 1751 } 1752 1753 screenp->options = conf_screen->scrn_option_lst; 1754 1755 /* 1756 * figure out how many display subsections there are and fill them in 1757 */ 1758 dispptr = conf_screen->scrn_display_lst; 1759 while (dispptr) { 1760 count++; 1761 dispptr = (XF86ConfDisplayPtr) dispptr->list.next; 1762 } 1763 screenp->displays = xnfallocarray(count, sizeof(DispPtr)); 1764 screenp->numdisplays = count; 1765 1766 for (count = 0, dispptr = conf_screen->scrn_display_lst; 1767 dispptr; 1768 dispptr = (XF86ConfDisplayPtr) dispptr->list.next, count++) { 1769 1770 /* Allocate individual Display records */ 1771 screenp->displays[count] = xnfcalloc(1, sizeof(DispRec)); 1772 1773 /* Fill in the default Virtual size, if any */ 1774 if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) { 1775 screenp->displays[count]->virtualX = conf_screen->scrn_virtualX; 1776 screenp->displays[count]->virtualY = conf_screen->scrn_virtualY; 1777 } 1778 1779 /* Now do the per-Display Virtual sizes */ 1780 configDisplay(screenp->displays[count], dispptr); 1781 } 1782 1783 /* 1784 * figure out how many videoadaptor references there are and fill them in 1785 */ 1786 count = 0; 1787 conf_adaptor = conf_screen->scrn_adaptor_lst; 1788 while (conf_adaptor) { 1789 count++; 1790 conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next; 1791 } 1792 screenp->xvadaptors = xnfallocarray(count, sizeof(confXvAdaptorRec)); 1793 screenp->numxvadaptors = 0; 1794 conf_adaptor = conf_screen->scrn_adaptor_lst; 1795 while (conf_adaptor) { 1796 if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]), 1797 conf_adaptor->al_adaptor)) 1798 screenp->numxvadaptors++; 1799 conf_adaptor = (XF86ConfAdaptorLinkPtr) conf_adaptor->list.next; 1800 } 1801 1802 if (defaultMonitor) { 1803 xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n" 1804 "\tUsing a default monitor configuration.\n", screenp->id); 1805 } 1806 return TRUE; 1807} 1808 1809typedef enum { 1810 MON_REDUCEDBLANKING, 1811 MON_MAX_PIX_CLOCK, 1812} MonitorValues; 1813 1814static OptionInfoRec MonitorOptions[] = { 1815 {MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN, 1816 {0}, FALSE}, 1817 {MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ, 1818 {0}, FALSE}, 1819 {-1, NULL, OPTV_NONE, 1820 {0}, FALSE}, 1821}; 1822 1823static Bool 1824configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor) 1825{ 1826 int count; 1827 DisplayModePtr mode, last = NULL; 1828 XF86ConfModeLinePtr cmodep; 1829 XF86ConfModesPtr modes; 1830 XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst; 1831 Gamma zeros = { 0.0, 0.0, 0.0 }; 1832 float badgamma = 0.0; 1833 double maxPixClock; 1834 1835 xf86Msg(X_CONFIG, "| |-->Monitor \"%s\"\n", conf_monitor->mon_identifier); 1836 monitorp->id = conf_monitor->mon_identifier; 1837 monitorp->vendor = conf_monitor->mon_vendor; 1838 monitorp->model = conf_monitor->mon_modelname; 1839 monitorp->Modes = NULL; 1840 monitorp->Last = NULL; 1841 monitorp->gamma = zeros; 1842 monitorp->widthmm = conf_monitor->mon_width; 1843 monitorp->heightmm = conf_monitor->mon_height; 1844 monitorp->reducedblanking = FALSE; 1845 monitorp->maxPixClock = 0; 1846 monitorp->options = conf_monitor->mon_option_lst; 1847 1848 /* 1849 * fill in the monitor structure 1850 */ 1851 for (count = 0; 1852 count < conf_monitor->mon_n_hsync && count < MAX_HSYNC; count++) { 1853 monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi; 1854 monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo; 1855 } 1856 monitorp->nHsync = count; 1857 for (count = 0; 1858 count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH; 1859 count++) { 1860 monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi; 1861 monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo; 1862 } 1863 monitorp->nVrefresh = count; 1864 1865 /* 1866 * first we collect the mode lines from the UseModes directive 1867 */ 1868 while (modeslnk) { 1869 modes = xf86findModes(modeslnk->ml_modes_str, 1870 xf86configptr->conf_modes_lst); 1871 modeslnk->ml_modes = modes; 1872 1873 /* now add the modes found in the modes 1874 section to the list of modes for this 1875 monitor unless it has been added before 1876 because we are reusing the same section 1877 for another screen */ 1878 if (xf86itemNotSublist((GenericListPtr) conf_monitor->mon_modeline_lst, 1879 (GenericListPtr) modes->mon_modeline_lst)) { 1880 conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr) 1881 xf86addListItem((GenericListPtr) conf_monitor->mon_modeline_lst, 1882 (GenericListPtr) modes->mon_modeline_lst); 1883 } 1884 modeslnk = modeslnk->list.next; 1885 } 1886 1887 /* 1888 * we need to hook in the mode lines now 1889 * here both data structures use lists, only our internal one 1890 * is double linked 1891 */ 1892 cmodep = conf_monitor->mon_modeline_lst; 1893 while (cmodep) { 1894 mode = xnfcalloc(1, sizeof(DisplayModeRec)); 1895 mode->type = 0; 1896 mode->Clock = cmodep->ml_clock; 1897 mode->HDisplay = cmodep->ml_hdisplay; 1898 mode->HSyncStart = cmodep->ml_hsyncstart; 1899 mode->HSyncEnd = cmodep->ml_hsyncend; 1900 mode->HTotal = cmodep->ml_htotal; 1901 mode->VDisplay = cmodep->ml_vdisplay; 1902 mode->VSyncStart = cmodep->ml_vsyncstart; 1903 mode->VSyncEnd = cmodep->ml_vsyncend; 1904 mode->VTotal = cmodep->ml_vtotal; 1905 mode->Flags = cmodep->ml_flags; 1906 mode->HSkew = cmodep->ml_hskew; 1907 mode->VScan = cmodep->ml_vscan; 1908 mode->name = xnfstrdup(cmodep->ml_identifier); 1909 if (last) { 1910 mode->prev = last; 1911 last->next = mode; 1912 } 1913 else { 1914 /* 1915 * this is the first mode 1916 */ 1917 monitorp->Modes = mode; 1918 mode->prev = NULL; 1919 } 1920 last = mode; 1921 cmodep = (XF86ConfModeLinePtr) cmodep->list.next; 1922 } 1923 if (last) { 1924 last->next = NULL; 1925 } 1926 monitorp->Last = last; 1927 1928 /* add the (VESA) default modes */ 1929 if (!addDefaultModes(monitorp)) 1930 return FALSE; 1931 1932 if (conf_monitor->mon_gamma_red > GAMMA_ZERO) 1933 monitorp->gamma.red = conf_monitor->mon_gamma_red; 1934 if (conf_monitor->mon_gamma_green > GAMMA_ZERO) 1935 monitorp->gamma.green = conf_monitor->mon_gamma_green; 1936 if (conf_monitor->mon_gamma_blue > GAMMA_ZERO) 1937 monitorp->gamma.blue = conf_monitor->mon_gamma_blue; 1938 1939 /* Check that the gamma values are within range */ 1940 if (monitorp->gamma.red > GAMMA_ZERO && 1941 (monitorp->gamma.red < GAMMA_MIN || monitorp->gamma.red > GAMMA_MAX)) { 1942 badgamma = monitorp->gamma.red; 1943 } 1944 else if (monitorp->gamma.green > GAMMA_ZERO && 1945 (monitorp->gamma.green < GAMMA_MIN || 1946 monitorp->gamma.green > GAMMA_MAX)) { 1947 badgamma = monitorp->gamma.green; 1948 } 1949 else if (monitorp->gamma.blue > GAMMA_ZERO && 1950 (monitorp->gamma.blue < GAMMA_MIN || 1951 monitorp->gamma.blue > GAMMA_MAX)) { 1952 badgamma = monitorp->gamma.blue; 1953 } 1954 if (badgamma > GAMMA_ZERO) { 1955 ErrorF("Gamma value %.f is out of range (%.2f - %.1f)\n", badgamma, 1956 GAMMA_MIN, GAMMA_MAX); 1957 return FALSE; 1958 } 1959 1960 xf86ProcessOptions(-1, monitorp->options, MonitorOptions); 1961 xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING, 1962 &monitorp->reducedblanking); 1963 if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ, 1964 &maxPixClock) == TRUE) { 1965 monitorp->maxPixClock = (int) maxPixClock; 1966 } 1967 1968 return TRUE; 1969} 1970 1971static int 1972lookupVisual(const char *visname) 1973{ 1974 int i; 1975 1976 if (!visname || !*visname) 1977 return -1; 1978 1979 for (i = 0; i <= DirectColor; i++) { 1980 if (!xf86nameCompare(visname, xf86VisualNames[i])) 1981 break; 1982 } 1983 1984 if (i <= DirectColor) 1985 return i; 1986 1987 return -1; 1988} 1989 1990static Bool 1991configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display) 1992{ 1993 int count = 0; 1994 XF86ModePtr modep; 1995 1996 displayp->frameX0 = conf_display->disp_frameX0; 1997 displayp->frameY0 = conf_display->disp_frameY0; 1998 displayp->virtualX = conf_display->disp_virtualX; 1999 displayp->virtualY = conf_display->disp_virtualY; 2000 displayp->depth = conf_display->disp_depth; 2001 displayp->fbbpp = conf_display->disp_bpp; 2002 displayp->weight.red = conf_display->disp_weight.red; 2003 displayp->weight.green = conf_display->disp_weight.green; 2004 displayp->weight.blue = conf_display->disp_weight.blue; 2005 displayp->blackColour.red = conf_display->disp_black.red; 2006 displayp->blackColour.green = conf_display->disp_black.green; 2007 displayp->blackColour.blue = conf_display->disp_black.blue; 2008 displayp->whiteColour.red = conf_display->disp_white.red; 2009 displayp->whiteColour.green = conf_display->disp_white.green; 2010 displayp->whiteColour.blue = conf_display->disp_white.blue; 2011 displayp->options = conf_display->disp_option_lst; 2012 if (conf_display->disp_visual) { 2013 displayp->defaultVisual = lookupVisual(conf_display->disp_visual); 2014 if (displayp->defaultVisual == -1) { 2015 ErrorF("Invalid visual name: \"%s\"\n", conf_display->disp_visual); 2016 return FALSE; 2017 } 2018 } 2019 else { 2020 displayp->defaultVisual = -1; 2021 } 2022 2023 /* 2024 * now hook in the modes 2025 */ 2026 modep = conf_display->disp_mode_lst; 2027 while (modep) { 2028 count++; 2029 modep = (XF86ModePtr) modep->list.next; 2030 } 2031 displayp->modes = xnfallocarray(count + 1, sizeof(char *)); 2032 modep = conf_display->disp_mode_lst; 2033 count = 0; 2034 while (modep) { 2035 displayp->modes[count] = modep->mode_name; 2036 count++; 2037 modep = (XF86ModePtr) modep->list.next; 2038 } 2039 displayp->modes[count] = NULL; 2040 2041 return TRUE; 2042} 2043 2044static Bool 2045configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active, Bool gpu) 2046{ 2047 int i; 2048 2049 if (!conf_device) { 2050 return FALSE; 2051 } 2052 2053 if (active) { 2054 if (gpu) 2055 xf86Msg(X_CONFIG, "| |-->GPUDevice \"%s\"\n", 2056 conf_device->dev_identifier); 2057 else 2058 xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n", 2059 conf_device->dev_identifier); 2060 } else 2061 xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n", 2062 conf_device->dev_identifier); 2063 2064 devicep->identifier = conf_device->dev_identifier; 2065 devicep->vendor = conf_device->dev_vendor; 2066 devicep->board = conf_device->dev_board; 2067 devicep->chipset = conf_device->dev_chipset; 2068 devicep->ramdac = conf_device->dev_ramdac; 2069 devicep->driver = conf_device->dev_driver; 2070 devicep->active = active; 2071 devicep->videoRam = conf_device->dev_videoram; 2072 devicep->MemBase = conf_device->dev_mem_base; 2073 devicep->IOBase = conf_device->dev_io_base; 2074 devicep->clockchip = conf_device->dev_clockchip; 2075 devicep->busID = conf_device->dev_busid; 2076 devicep->chipID = conf_device->dev_chipid; 2077 devicep->chipRev = conf_device->dev_chiprev; 2078 devicep->options = conf_device->dev_option_lst; 2079 devicep->irq = conf_device->dev_irq; 2080 devicep->screen = conf_device->dev_screen; 2081 2082 for (i = 0; i < MAXDACSPEEDS; i++) { 2083 if (i < CONF_MAXDACSPEEDS) 2084 devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i]; 2085 else 2086 devicep->dacSpeeds[i] = 0; 2087 } 2088 devicep->numclocks = conf_device->dev_clocks; 2089 if (devicep->numclocks > MAXCLOCKS) 2090 devicep->numclocks = MAXCLOCKS; 2091 for (i = 0; i < devicep->numclocks; i++) { 2092 devicep->clock[i] = conf_device->dev_clock[i]; 2093 } 2094 devicep->claimed = FALSE; 2095 2096 return TRUE; 2097} 2098 2099static void 2100configDRI(XF86ConfDRIPtr drip) 2101{ 2102 struct group *grp; 2103 2104 xf86ConfigDRI.group = -1; 2105 xf86ConfigDRI.mode = 0; 2106 2107 if (drip) { 2108 if (drip->dri_group_name) { 2109 if ((grp = getgrnam(drip->dri_group_name))) 2110 xf86ConfigDRI.group = grp->gr_gid; 2111 } 2112 else { 2113 if (drip->dri_group >= 0) 2114 xf86ConfigDRI.group = drip->dri_group; 2115 } 2116 xf86ConfigDRI.mode = drip->dri_mode; 2117 } 2118} 2119 2120static void 2121configExtensions(XF86ConfExtensionsPtr conf_ext) 2122{ 2123 XF86OptionPtr o; 2124 2125 if (conf_ext && conf_ext->ext_option_lst) { 2126 for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) { 2127 char *name = xf86OptionName(o); 2128 char *val = xf86OptionValue(o); 2129 char *n; 2130 Bool enable = TRUE; 2131 2132 /* Handle "No<ExtensionName>" */ 2133 n = xf86NormalizeName(name); 2134 if (strncmp(n, "no", 2) == 0) { 2135 name += 2; 2136 enable = FALSE; 2137 } 2138 2139 if (!val || 2140 xf86NameCmp(val, "enable") == 0 || 2141 xf86NameCmp(val, "enabled") == 0 || 2142 xf86NameCmp(val, "on") == 0 || 2143 xf86NameCmp(val, "1") == 0 || 2144 xf86NameCmp(val, "yes") == 0 || xf86NameCmp(val, "true") == 0) { 2145 /* NOTHING NEEDED -- enabling is handled below */ 2146 } 2147 else if (xf86NameCmp(val, "disable") == 0 || 2148 xf86NameCmp(val, "disabled") == 0 || 2149 xf86NameCmp(val, "off") == 0 || 2150 xf86NameCmp(val, "0") == 0 || 2151 xf86NameCmp(val, "no") == 0 || 2152 xf86NameCmp(val, "false") == 0) { 2153 enable = !enable; 2154 } 2155 else { 2156 xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val); 2157 free(n); 2158 continue; 2159 } 2160 2161 if (EnableDisableExtension(name, enable)) { 2162 xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n", 2163 name, enable ? "enabled" : "disabled"); 2164 } 2165 else { 2166 xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n", 2167 name); 2168 } 2169 free(n); 2170 } 2171 } 2172} 2173 2174static Bool 2175configInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from) 2176{ 2177 xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier); 2178 inputp->name = conf_input->inp_identifier; 2179 inputp->driver = conf_input->inp_driver; 2180 inputp->options = conf_input->inp_option_lst; 2181 inputp->attrs = NULL; 2182 2183 return TRUE; 2184} 2185 2186static Bool 2187modeIsPresent(DisplayModePtr mode, MonPtr monitorp) 2188{ 2189 DisplayModePtr knownmodes = monitorp->Modes; 2190 2191 /* all I can think of is a linear search... */ 2192 while (knownmodes != NULL) { 2193 if (!strcmp(mode->name, knownmodes->name) && 2194 !(knownmodes->type & M_T_DEFAULT)) 2195 return TRUE; 2196 knownmodes = knownmodes->next; 2197 } 2198 return FALSE; 2199} 2200 2201static Bool 2202addDefaultModes(MonPtr monitorp) 2203{ 2204 DisplayModePtr mode; 2205 DisplayModePtr last = monitorp->Last; 2206 int i = 0; 2207 2208 for (i = 0; i < xf86NumDefaultModes; i++) { 2209 mode = xf86DuplicateMode(&xf86DefaultModes[i]); 2210 if (!modeIsPresent(mode, monitorp)) { 2211 monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode); 2212 last = mode; 2213 } 2214 else { 2215 free(mode); 2216 } 2217 } 2218 monitorp->Last = last; 2219 2220 return TRUE; 2221} 2222 2223static void 2224checkInput(serverLayoutPtr layout, Bool implicit_layout) 2225{ 2226 checkCoreInputDevices(layout, implicit_layout); 2227 2228 /* Unless we're forcing input devices, disable mouse/kbd devices in the 2229 * config. Otherwise the same physical device is added multiple times, 2230 * leading to duplicate events. 2231 */ 2232 if (!xf86Info.forceInputDevices && layout->inputs) { 2233 InputInfoPtr *dev = layout->inputs; 2234 BOOL warned = FALSE; 2235 2236 while (*dev) { 2237 if (strcmp((*dev)->driver, "kbd") == 0 || 2238 strcmp((*dev)->driver, "mouse") == 0 || 2239 strcmp((*dev)->driver, "vmmouse") == 0) { 2240 InputInfoPtr *current; 2241 2242 if (!warned) { 2243 xf86Msg(X_WARNING, "Hotplugging is on, devices using " 2244 "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n"); 2245 warned = TRUE; 2246 } 2247 2248 xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name); 2249 2250 current = dev; 2251 free(*dev); 2252 *dev = NULL; 2253 2254 do { 2255 *current = *(current + 1); 2256 current++; 2257 } while (*current); 2258 } 2259 else 2260 dev++; 2261 } 2262 } 2263} 2264 2265/* 2266 * load the config file and fill the global data structure 2267 */ 2268ConfigStatus 2269xf86HandleConfigFile(Bool autoconfig) 2270{ 2271#ifdef XSERVER_LIBPCIACCESS 2272 const char *scanptr; 2273 Bool singlecard = 0; 2274#endif 2275 Bool implicit_layout = FALSE; 2276 XF86ConfLayoutPtr layout; 2277 2278 if (!autoconfig) { 2279 char *filename, *dirname, *sysdirname; 2280 const char *filesearch, *dirsearch; 2281 MessageType filefrom = X_DEFAULT; 2282 MessageType dirfrom = X_DEFAULT; 2283 2284 if (!PrivsElevated()) { 2285 filesearch = ALL_CONFIGPATH; 2286 dirsearch = ALL_CONFIGDIRPATH; 2287 } 2288 else { 2289 filesearch = RESTRICTED_CONFIGPATH; 2290 dirsearch = RESTRICTED_CONFIGDIRPATH; 2291 } 2292 2293 if (xf86ConfigFile) 2294 filefrom = X_CMDLINE; 2295 if (xf86ConfigDir) 2296 dirfrom = X_CMDLINE; 2297 2298 xf86initConfigFiles(); 2299 sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL, 2300 PROJECTROOT); 2301 dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT); 2302 filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT); 2303 if (filename) { 2304 xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename); 2305 xf86ConfigFile = xnfstrdup(filename); 2306 } 2307 else { 2308 if (xf86ConfigFile) 2309 xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n", 2310 xf86ConfigFile); 2311 } 2312 if (dirname) { 2313 xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n", 2314 dirname); 2315 xf86ConfigDir = xnfstrdup(dirname); 2316 } 2317 else { 2318 if (xf86ConfigDir) 2319 xf86Msg(X_ERROR, 2320 "Unable to locate/open config directory: \"%s\"\n", 2321 xf86ConfigDir); 2322 } 2323 if (sysdirname) 2324 xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n", 2325 sysdirname); 2326 if (!filename && !dirname && !sysdirname) 2327 return CONFIG_NOFILE; 2328 2329 free(filename); 2330 free(dirname); 2331 free(sysdirname); 2332 } 2333 2334 if ((xf86configptr = xf86readConfigFile()) == NULL) { 2335 xf86Msg(X_ERROR, "Problem parsing the config file\n"); 2336 return CONFIG_PARSE_ERROR; 2337 } 2338 xf86closeConfigFile(); 2339 2340 /* Initialise a few things. */ 2341 2342 /* 2343 * now we convert part of the information contained in the parser 2344 * structures into our own structures. 2345 * The important part here is to figure out which Screen Sections 2346 * in the XF86Config file are active so that we can piece together 2347 * the modes that we need later down the road. 2348 * And while we are at it, we'll decode the rest of the stuff as well 2349 */ 2350 2351 /* First check if a layout section is present, and if it is valid. */ 2352 FIND_SUITABLE(XF86ConfLayoutPtr, xf86configptr->conf_layout_lst, layout); 2353 if (layout == NULL || xf86ScreenName != NULL) { 2354 XF86ConfScreenPtr screen; 2355 2356 if (xf86ScreenName == NULL) { 2357 xf86Msg(X_DEFAULT, 2358 "No Layout section. Using the first Screen section.\n"); 2359 } 2360 FIND_SUITABLE (XF86ConfScreenPtr, xf86configptr->conf_screen_lst, screen); 2361 if (!configImpliedLayout(&xf86ConfigLayout, 2362 screen, 2363 xf86configptr)) { 2364 xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); 2365 return CONFIG_PARSE_ERROR; 2366 } 2367 implicit_layout = TRUE; 2368 } 2369 else { 2370 if (xf86configptr->conf_flags != NULL) { 2371 char *dfltlayout = NULL; 2372 void *optlist = xf86configptr->conf_flags->flg_option_lst; 2373 2374 if (optlist && xf86FindOption(optlist, "defaultserverlayout")) 2375 dfltlayout = 2376 xf86SetStrOption(optlist, "defaultserverlayout", NULL); 2377 if (!configLayout(&xf86ConfigLayout, layout, dfltlayout)) { 2378 xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); 2379 return CONFIG_PARSE_ERROR; 2380 } 2381 } 2382 else { 2383 if (!configLayout(&xf86ConfigLayout, layout, NULL)) { 2384 xf86Msg(X_ERROR, "Unable to determine the screen layout\n"); 2385 return CONFIG_PARSE_ERROR; 2386 } 2387 } 2388 } 2389 2390 xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions); 2391#ifdef XSERVER_LIBPCIACCESS 2392 if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) { 2393 ; /* IsolateDevice specified; overrides SingleCard */ 2394 } 2395 else { 2396 xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard); 2397 if (singlecard) 2398 scanptr = xf86ConfigLayout.screens->screen->device->busID; 2399 } 2400 if (scanptr) { 2401 if (strncmp(scanptr, "PCI:", 4) != 0) { 2402 xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n" 2403 "\tIgnoring IsolateDevice option.\n"); 2404 } 2405 else 2406 xf86PciIsolateDevice(scanptr); 2407 } 2408#endif 2409 /* Now process everything else */ 2410 configServerFlags(xf86configptr->conf_flags, xf86ConfigLayout.options); 2411 configFiles(xf86configptr->conf_files); 2412 configExtensions(xf86configptr->conf_extensions); 2413 configDRI(xf86configptr->conf_dri); 2414 2415 checkInput(&xf86ConfigLayout, implicit_layout); 2416 2417 /* 2418 * Handle some command line options that can override some of the 2419 * ServerFlags settings. 2420 */ 2421#ifdef XF86VIDMODE 2422 if (xf86VidModeDisabled) 2423 xf86Info.vidModeEnabled = FALSE; 2424 if (xf86VidModeAllowNonLocal) 2425 xf86Info.vidModeAllowNonLocal = TRUE; 2426#endif 2427 2428 if (xf86AllowMouseOpenFail) 2429 xf86Info.allowMouseOpenFail = TRUE; 2430 2431 return CONFIG_OK; 2432} 2433 2434Bool 2435xf86PathIsSafe(const char *path) 2436{ 2437 return (xf86pathIsSafe(path) != 0); 2438} 2439