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