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