xf86Configure.c (28415B)
1 /* 2 * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales. 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Alan Hourihane not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Alan Hourihane makes no representations 11 * about the suitability of this software for any purpose. It is provided 12 * "as is" without express or implied warranty. 13 * 14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 23 * 24 */ 25 26 #ifdef HAVE_XORG_CONFIG_H 27 #include <xorg-config.h> 28 #endif 29 30 #include "xf86.h" 31 #include "xf86Config.h" 32 #include "xf86_OSlib.h" 33 #include "xf86Priv.h" 34 #define IN_XSERVER 35 #include "Configint.h" 36 #include "xf86DDC.h" 37 #include "xf86pciBus.h" 38 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 39 #include "xf86Bus.h" 40 #include "xf86Sbus.h" 41 #endif 42 #include "misc.h" 43 #include "loaderProcs.h" 44 45 typedef struct _DevToConfig { 46 GDevRec GDev; 47 struct pci_device *pVideo; 48 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 49 sbusDevicePtr sVideo; 50 #endif 51 int iDriver; 52 } DevToConfigRec, *DevToConfigPtr; 53 54 static DevToConfigPtr DevToConfig = NULL; 55 static int nDevToConfig = 0, CurrentDriver; 56 57 xf86MonPtr ConfiguredMonitor; 58 Bool xf86DoConfigurePass1 = TRUE; 59 static Bool foundMouse = FALSE; 60 61 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 62 static const char *DFLT_MOUSE_DEV = "/dev/sysmouse"; 63 static const char *DFLT_MOUSE_PROTO = "auto"; 64 #elif defined(__linux__) 65 static const char *DFLT_MOUSE_DEV = "/dev/input/mice"; 66 static const char *DFLT_MOUSE_PROTO = "auto"; 67 #elif defined(WSCONS_SUPPORT) 68 static const char *DFLT_MOUSE_DEV = "/dev/wsmouse"; 69 static const char *DFLT_MOUSE_PROTO = "wsmouse"; 70 #else 71 static const char *DFLT_MOUSE_DEV = "/dev/mouse"; 72 static const char *DFLT_MOUSE_PROTO = "auto"; 73 #endif 74 75 /* 76 * This is called by the driver, either through xf86Match???Instances() or 77 * directly. We allocate a GDevRec and fill it in as much as we can, letting 78 * the caller fill in the rest and/or change it as it sees fit. 79 */ 80 GDevPtr 81 xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, 82 int chipset) 83 { 84 int ret, i, j; 85 char *lower_driver; 86 87 if (!xf86DoConfigure || !xf86DoConfigurePass1) 88 return NULL; 89 90 /* Check for duplicates */ 91 for (i = 0; i < nDevToConfig; i++) { 92 switch (bus) { 93 #ifdef XSERVER_LIBPCIACCESS 94 case BUS_PCI: 95 ret = xf86PciConfigure(busData, DevToConfig[i].pVideo); 96 break; 97 #endif 98 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 99 case BUS_SBUS: 100 ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo); 101 break; 102 #endif 103 default: 104 return NULL; 105 } 106 if (ret == 0) 107 goto out; 108 } 109 110 /* Allocate new structure occurrence */ 111 i = nDevToConfig++; 112 DevToConfig = 113 xnfreallocarray(DevToConfig, nDevToConfig, sizeof(DevToConfigRec)); 114 memset(DevToConfig + i, 0, sizeof(DevToConfigRec)); 115 116 DevToConfig[i].GDev.chipID = 117 DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1; 118 119 DevToConfig[i].iDriver = CurrentDriver; 120 121 /* Fill in what we know, converting the driver name to lower case */ 122 lower_driver = xnfalloc(strlen(driver) + 1); 123 for (j = 0; (lower_driver[j] = tolower(driver[j])); j++); 124 DevToConfig[i].GDev.driver = lower_driver; 125 126 switch (bus) { 127 #ifdef XSERVER_LIBPCIACCESS 128 case BUS_PCI: 129 DevToConfig[i].pVideo = busData; 130 xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo, 131 &DevToConfig[i].GDev, &chipset); 132 break; 133 #endif 134 #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 135 case BUS_SBUS: 136 DevToConfig[i].sVideo = busData; 137 xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo, 138 &DevToConfig[i].GDev); 139 break; 140 #endif 141 default: 142 break; 143 } 144 145 /* Get driver's available options */ 146 if (xf86DriverList[CurrentDriver]->AvailableOptions) 147 DevToConfig[i].GDev.options = (OptionInfoPtr) 148 (*xf86DriverList[CurrentDriver]->AvailableOptions) (chipset, bus); 149 150 return &DevToConfig[i].GDev; 151 152 out: 153 return NULL; 154 } 155 156 static XF86ConfInputPtr 157 configureInputSection(void) 158 { 159 XF86ConfInputPtr mouse = NULL; 160 161 parsePrologue(XF86ConfInputPtr, XF86ConfInputRec); 162 163 ptr->inp_identifier = xnfstrdup("Keyboard0"); 164 ptr->inp_driver = xnfstrdup("kbd"); 165 ptr->list.next = NULL; 166 167 /* Crude mechanism to auto-detect mouse (os dependent) */ 168 { 169 int fd; 170 171 fd = open(DFLT_MOUSE_DEV, 0); 172 if (fd != -1) { 173 foundMouse = TRUE; 174 close(fd); 175 } 176 } 177 178 mouse = calloc(1, sizeof(XF86ConfInputRec)); 179 mouse->inp_identifier = xnfstrdup("Mouse0"); 180 mouse->inp_driver = xnfstrdup("mouse"); 181 mouse->inp_option_lst = 182 xf86addNewOption(mouse->inp_option_lst, xnfstrdup("Protocol"), 183 xnfstrdup(DFLT_MOUSE_PROTO)); 184 mouse->inp_option_lst = 185 xf86addNewOption(mouse->inp_option_lst, xnfstrdup("Device"), 186 xnfstrdup(DFLT_MOUSE_DEV)); 187 mouse->inp_option_lst = 188 xf86addNewOption(mouse->inp_option_lst, xnfstrdup("ZAxisMapping"), 189 xnfstrdup("4 5 6 7")); 190 ptr = (XF86ConfInputPtr) xf86addListItem((glp) ptr, (glp) mouse); 191 return ptr; 192 } 193 194 static XF86ConfScreenPtr 195 configureScreenSection(int screennum) 196 { 197 int i; 198 int depths[] = { 1, 4, 8, 15, 16, 24 /*, 32 */ }; 199 char *tmp; 200 parsePrologue(XF86ConfScreenPtr, XF86ConfScreenRec); 201 202 XNFasprintf(&tmp, "Screen%d", screennum); 203 ptr->scrn_identifier = tmp; 204 XNFasprintf(&tmp, "Monitor%d", screennum); 205 ptr->scrn_monitor_str = tmp; 206 XNFasprintf(&tmp, "Card%d", screennum); 207 ptr->scrn_device_str = tmp; 208 209 for (i = 0; i < ARRAY_SIZE(depths); i++) { 210 XF86ConfDisplayPtr conf_display; 211 212 conf_display = calloc(1, sizeof(XF86ConfDisplayRec)); 213 conf_display->disp_depth = depths[i]; 214 conf_display->disp_black.red = conf_display->disp_white.red = -1; 215 conf_display->disp_black.green = conf_display->disp_white.green = -1; 216 conf_display->disp_black.blue = conf_display->disp_white.blue = -1; 217 ptr->scrn_display_lst = (XF86ConfDisplayPtr) xf86addListItem((glp) ptr-> 218 scrn_display_lst, 219 (glp) 220 conf_display); 221 } 222 223 return ptr; 224 } 225 226 static const char * 227 optionTypeToString(OptionValueType type) 228 { 229 switch (type) { 230 case OPTV_NONE: 231 return ""; 232 case OPTV_INTEGER: 233 return "<i>"; 234 case OPTV_STRING: 235 return "<str>"; 236 case OPTV_ANYSTR: 237 return "[<str>]"; 238 case OPTV_REAL: 239 return "<f>"; 240 case OPTV_BOOLEAN: 241 return "[<bool>]"; 242 case OPTV_FREQ: 243 return "<freq>"; 244 case OPTV_PERCENT: 245 return "<percent>"; 246 default: 247 return ""; 248 } 249 } 250 251 static XF86ConfDevicePtr 252 configureDeviceSection(int screennum) 253 { 254 OptionInfoPtr p; 255 int i = 0; 256 char *identifier; 257 258 parsePrologue(XF86ConfDevicePtr, XF86ConfDeviceRec); 259 260 /* Move device info to parser structure */ 261 if (asprintf(&identifier, "Card%d", screennum) == -1) 262 identifier = NULL; 263 ptr->dev_identifier = identifier; 264 ptr->dev_chipset = DevToConfig[screennum].GDev.chipset; 265 ptr->dev_busid = DevToConfig[screennum].GDev.busID; 266 ptr->dev_driver = DevToConfig[screennum].GDev.driver; 267 ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac; 268 for (i = 0; i < MAXDACSPEEDS; i++) 269 ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i]; 270 ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam; 271 ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase; 272 ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase; 273 ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip; 274 for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); 275 i++) 276 ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i]; 277 ptr->dev_clocks = i; 278 ptr->dev_chipid = DevToConfig[screennum].GDev.chipID; 279 ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev; 280 ptr->dev_irq = DevToConfig[screennum].GDev.irq; 281 282 /* Make sure older drivers don't segv */ 283 if (DevToConfig[screennum].GDev.options) { 284 /* Fill in the available driver options for people to use */ 285 const char *descrip = 286 " ### Available Driver options are:-\n" 287 " ### Values: <i>: integer, <f>: float, " 288 "<bool>: \"True\"/\"False\",\n" 289 " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n" 290 " ### <percent>: \"<f>%\"\n" 291 " ### [arg]: arg optional\n"; 292 ptr->dev_comment = xnfstrdup(descrip); 293 if (ptr->dev_comment) { 294 for (p = DevToConfig[screennum].GDev.options; p->name != NULL; p++) { 295 char *p_e; 296 const char *prefix = " #Option "; 297 const char *middle = " \t# "; 298 const char *suffix = "\n"; 299 const char *opttype = optionTypeToString(p->type); 300 char *optname; 301 int len = strlen(ptr->dev_comment) + strlen(prefix) + 302 strlen(middle) + strlen(suffix) + 1; 303 304 if (asprintf(&optname, "\"%s\"", p->name) == -1) 305 break; 306 307 len += max(20, strlen(optname)); 308 len += strlen(opttype); 309 310 ptr->dev_comment = realloc(ptr->dev_comment, len); 311 if (!ptr->dev_comment) 312 break; 313 p_e = ptr->dev_comment + strlen(ptr->dev_comment); 314 sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle, 315 opttype, suffix); 316 free(optname); 317 } 318 } 319 } 320 321 return ptr; 322 } 323 324 static XF86ConfLayoutPtr 325 configureLayoutSection(void) 326 { 327 int scrnum = 0; 328 329 parsePrologue(XF86ConfLayoutPtr, XF86ConfLayoutRec); 330 331 ptr->lay_identifier = "X.org Configured"; 332 333 { 334 XF86ConfInputrefPtr iptr; 335 336 iptr = malloc(sizeof(XF86ConfInputrefRec)); 337 iptr->list.next = NULL; 338 iptr->iref_option_lst = NULL; 339 iptr->iref_inputdev_str = xnfstrdup("Mouse0"); 340 iptr->iref_option_lst = 341 xf86addNewOption(iptr->iref_option_lst, xnfstrdup("CorePointer"), 342 NULL); 343 ptr->lay_input_lst = (XF86ConfInputrefPtr) 344 xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr); 345 } 346 347 { 348 XF86ConfInputrefPtr iptr; 349 350 iptr = malloc(sizeof(XF86ConfInputrefRec)); 351 iptr->list.next = NULL; 352 iptr->iref_option_lst = NULL; 353 iptr->iref_inputdev_str = xnfstrdup("Keyboard0"); 354 iptr->iref_option_lst = 355 xf86addNewOption(iptr->iref_option_lst, xnfstrdup("CoreKeyboard"), 356 NULL); 357 ptr->lay_input_lst = (XF86ConfInputrefPtr) 358 xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr); 359 } 360 361 for (scrnum = 0; scrnum < nDevToConfig; scrnum++) { 362 XF86ConfAdjacencyPtr aptr; 363 char *tmp; 364 365 aptr = malloc(sizeof(XF86ConfAdjacencyRec)); 366 aptr->list.next = NULL; 367 aptr->adj_x = 0; 368 aptr->adj_y = 0; 369 aptr->adj_scrnum = scrnum; 370 XNFasprintf(&tmp, "Screen%d", scrnum); 371 aptr->adj_screen_str = tmp; 372 if (scrnum == 0) { 373 aptr->adj_where = CONF_ADJ_ABSOLUTE; 374 aptr->adj_refscreen = NULL; 375 } 376 else { 377 aptr->adj_where = CONF_ADJ_RIGHTOF; 378 XNFasprintf(&tmp, "Screen%d", scrnum - 1); 379 aptr->adj_refscreen = tmp; 380 } 381 ptr->lay_adjacency_lst = 382 (XF86ConfAdjacencyPtr) xf86addListItem((glp) ptr->lay_adjacency_lst, 383 (glp) aptr); 384 } 385 386 return ptr; 387 } 388 389 static XF86ConfFlagsPtr 390 configureFlagsSection(void) 391 { 392 parsePrologue(XF86ConfFlagsPtr, XF86ConfFlagsRec); 393 394 return ptr; 395 } 396 397 static XF86ConfModulePtr 398 configureModuleSection(void) 399 { 400 const char **elist, **el; 401 402 parsePrologue(XF86ConfModulePtr, XF86ConfModuleRec); 403 404 elist = LoaderListDir("extensions", NULL); 405 if (elist) { 406 for (el = elist; *el; el++) { 407 XF86LoadPtr module; 408 409 module = calloc(1, sizeof(XF86LoadRec)); 410 module->load_name = *el; 411 ptr->mod_load_lst = (XF86LoadPtr) xf86addListItem((glp) ptr-> 412 mod_load_lst, 413 (glp) module); 414 } 415 free(elist); 416 } 417 418 return ptr; 419 } 420 421 static XF86ConfFilesPtr 422 configureFilesSection(void) 423 { 424 parsePrologue(XF86ConfFilesPtr, XF86ConfFilesRec); 425 426 if (xf86ModulePath) 427 ptr->file_modulepath = xnfstrdup(xf86ModulePath); 428 if (defaultFontPath) 429 ptr->file_fontpath = xnfstrdup(defaultFontPath); 430 431 return ptr; 432 } 433 434 static XF86ConfMonitorPtr 435 configureMonitorSection(int screennum) 436 { 437 char *tmp; 438 parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec); 439 440 XNFasprintf(&tmp, "Monitor%d", screennum); 441 ptr->mon_identifier = tmp; 442 ptr->mon_vendor = xnfstrdup("Monitor Vendor"); 443 ptr->mon_modelname = xnfstrdup("Monitor Model"); 444 445 return ptr; 446 } 447 448 /* Initialize Configure Monitor from Detailed Timing Block */ 449 static void 450 handle_detailed_input(struct detailed_monitor_section *det_mon, void *data) 451 { 452 XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data; 453 454 switch (det_mon->type) { 455 case DS_NAME: 456 ptr->mon_modelname = realloc(ptr->mon_modelname, 457 strlen((char *) (det_mon->section.name)) + 458 1); 459 strcpy(ptr->mon_modelname, (char *) (det_mon->section.name)); 460 break; 461 case DS_RANGES: 462 ptr->mon_hsync[ptr->mon_n_hsync].lo = det_mon->section.ranges.min_h; 463 ptr->mon_hsync[ptr->mon_n_hsync].hi = det_mon->section.ranges.max_h; 464 ptr->mon_n_vrefresh = 1; 465 ptr->mon_vrefresh[ptr->mon_n_hsync].lo = det_mon->section.ranges.min_v; 466 ptr->mon_vrefresh[ptr->mon_n_hsync].hi = det_mon->section.ranges.max_v; 467 ptr->mon_n_hsync++; 468 default: 469 break; 470 } 471 } 472 473 static XF86ConfMonitorPtr 474 configureDDCMonitorSection(int screennum) 475 { 476 int len, mon_width, mon_height; 477 478 #define displaySizeMaxLen 80 479 char displaySize_string[displaySizeMaxLen]; 480 int displaySizeLen; 481 char *tmp; 482 483 parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec); 484 485 XNFasprintf(&tmp, "Monitor%d", screennum); 486 ptr->mon_identifier = tmp; 487 ptr->mon_vendor = xnfstrdup(ConfiguredMonitor->vendor.name); 488 XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id); 489 490 /* features in centimetres, we want millimetres */ 491 mon_width = 10 * ConfiguredMonitor->features.hsize; 492 mon_height = 10 * ConfiguredMonitor->features.vsize; 493 494 #ifdef CONFIGURE_DISPLAYSIZE 495 ptr->mon_width = mon_width; 496 ptr->mon_height = mon_height; 497 #else 498 if (mon_width && mon_height) { 499 /* when values available add DisplaySize option AS A COMMENT */ 500 501 displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen, 502 "\t#DisplaySize\t%5d %5d\t# mm\n", 503 mon_width, mon_height); 504 505 if (displaySizeLen > 0 && displaySizeLen < displaySizeMaxLen) { 506 if (ptr->mon_comment) { 507 len = strlen(ptr->mon_comment); 508 } 509 else { 510 len = 0; 511 } 512 if ((ptr->mon_comment = 513 realloc(ptr->mon_comment, 514 len + strlen(displaySize_string) + 1))) { 515 strcpy(ptr->mon_comment + len, displaySize_string); 516 } 517 } 518 } 519 #endif /* def CONFIGURE_DISPLAYSIZE */ 520 521 xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input, ptr); 522 523 if (ConfiguredMonitor->features.dpms) { 524 ptr->mon_option_lst = 525 xf86addNewOption(ptr->mon_option_lst, xnfstrdup("DPMS"), NULL); 526 } 527 528 return ptr; 529 } 530 531 static int 532 is_fallback(const char *s) 533 { 534 /* later entries are less preferred */ 535 const char *fallback[5] = { "modesetting", "fbdev", "vesa", "wsfb", NULL }; 536 int i; 537 538 for (i = 0; fallback[i]; i++) 539 if (strstr(s, fallback[i])) 540 return i; 541 542 return -1; 543 } 544 545 static int 546 driver_sort(const void *_l, const void *_r) 547 { 548 const char *l = *(const char **)_l; 549 const char *r = *(const char **)_r; 550 int left = is_fallback(l); 551 int right = is_fallback(r); 552 553 /* neither is a fallback, asciibetize */ 554 if (left == -1 && right == -1) 555 return strcmp(l, r); 556 557 /* left is a fallback, right is not */ 558 if (left >= 0 && right == -1) 559 return 1; 560 561 /* right is a fallback, left is not */ 562 if (right >= 0 && left == -1) 563 return -1; 564 565 /* both are fallbacks, decide which is worse */ 566 return left - right; 567 } 568 569 static void 570 fixup_video_driver_list(const char **drivers) 571 { 572 const char **end; 573 574 /* walk to the end of the list */ 575 for (end = drivers; *end && **end; end++); 576 577 qsort(drivers, end - drivers, sizeof(const char *), driver_sort); 578 } 579 580 static const char ** 581 GenerateDriverList(void) 582 { 583 const char **ret; 584 static const char *patlist[] = { "(.*)_drv\\.so", NULL }; 585 ret = LoaderListDir("drivers", patlist); 586 587 /* fix up the probe order for video drivers */ 588 if (ret != NULL) 589 fixup_video_driver_list(ret); 590 591 return ret; 592 } 593 594 void 595 DoConfigure(void) 596 { 597 int i, j, screennum = -1; 598 const char *home = NULL; 599 char filename[PATH_MAX]; 600 const char *addslash = ""; 601 XF86ConfigPtr xf86config = NULL; 602 const char **vlist, **vl; 603 int *dev2screen; 604 605 vlist = GenerateDriverList(); 606 607 if (!vlist) { 608 ErrorF("Missing output drivers. Configuration failed.\n"); 609 goto bail; 610 } 611 612 ErrorF("List of video drivers:\n"); 613 for (vl = vlist; *vl; vl++) 614 ErrorF("\t%s\n", *vl); 615 616 /* Load all the drivers that were found. */ 617 xf86LoadModules(vlist, NULL); 618 619 free(vlist); 620 621 xorgHWAccess = xf86EnableIO(); 622 623 /* Create XF86Config file structure */ 624 xf86config = calloc(1, sizeof(XF86ConfigRec)); 625 626 /* Call all of the probe functions, reporting the results. */ 627 for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) { 628 Bool found_screen; 629 DriverRec *const drv = xf86DriverList[CurrentDriver]; 630 631 found_screen = xf86CallDriverProbe(drv, TRUE); 632 if (found_screen && drv->Identify) { 633 (*drv->Identify) (0); 634 } 635 } 636 637 if (nDevToConfig <= 0) { 638 ErrorF("No devices to configure. Configuration failed.\n"); 639 goto bail; 640 } 641 642 /* Add device, monitor and screen sections for detected devices */ 643 for (screennum = 0; screennum < nDevToConfig; screennum++) { 644 XF86ConfDevicePtr device_ptr; 645 XF86ConfMonitorPtr monitor_ptr; 646 XF86ConfScreenPtr screen_ptr; 647 648 device_ptr = configureDeviceSection(screennum); 649 xf86config->conf_device_lst = (XF86ConfDevicePtr) xf86addListItem((glp) 650 xf86config-> 651 conf_device_lst, 652 (glp) 653 device_ptr); 654 monitor_ptr = configureMonitorSection(screennum); 655 xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) monitor_ptr); 656 screen_ptr = configureScreenSection(screennum); 657 xf86config->conf_screen_lst = (XF86ConfScreenPtr) xf86addListItem((glp) 658 xf86config-> 659 conf_screen_lst, 660 (glp) 661 screen_ptr); 662 } 663 664 xf86config->conf_files = configureFilesSection(); 665 xf86config->conf_modules = configureModuleSection(); 666 xf86config->conf_flags = configureFlagsSection(); 667 xf86config->conf_videoadaptor_lst = NULL; 668 xf86config->conf_modes_lst = NULL; 669 xf86config->conf_vendor_lst = NULL; 670 xf86config->conf_dri = NULL; 671 xf86config->conf_input_lst = configureInputSection(); 672 xf86config->conf_layout_lst = configureLayoutSection(); 673 674 home = getenv("HOME"); 675 if ((home == NULL) || (home[0] == '\0')) { 676 home = "/"; 677 } 678 else { 679 /* Determine if trailing slash is present or needed */ 680 int l = strlen(home); 681 682 if (home[l - 1] != '/') { 683 addslash = "/"; 684 } 685 } 686 687 snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new", 688 home, addslash); 689 690 if (xf86writeConfigFile(filename, xf86config) == 0) { 691 xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n", 692 filename, strerror(errno)); 693 goto bail; 694 } 695 696 xf86DoConfigurePass1 = FALSE; 697 /* Try to get DDC information filled in */ 698 xf86ConfigFile = filename; 699 if (xf86HandleConfigFile(FALSE) != CONFIG_OK) { 700 goto bail; 701 } 702 703 xf86DoConfigurePass1 = FALSE; 704 705 dev2screen = xnfcalloc(nDevToConfig, sizeof(int)); 706 707 { 708 Bool *driverProbed = xnfcalloc(xf86NumDrivers, sizeof(Bool)); 709 710 for (screennum = 0; screennum < nDevToConfig; screennum++) { 711 int k, l, n, oldNumScreens; 712 713 i = DevToConfig[screennum].iDriver; 714 715 if (driverProbed[i]) 716 continue; 717 driverProbed[i] = TRUE; 718 719 oldNumScreens = xf86NumScreens; 720 721 xf86CallDriverProbe(xf86DriverList[i], FALSE); 722 723 /* reorder */ 724 k = screennum > 0 ? screennum : 1; 725 for (l = oldNumScreens; l < xf86NumScreens; l++) { 726 /* is screen primary? */ 727 Bool primary = FALSE; 728 729 for (n = 0; n < xf86Screens[l]->numEntities; n++) { 730 if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) { 731 dev2screen[0] = l; 732 primary = TRUE; 733 break; 734 } 735 } 736 if (primary) 737 continue; 738 /* not primary: assign it to next device of same driver */ 739 /* 740 * NOTE: we assume that devices in DevToConfig 741 * and xf86Screens[] have the same order except 742 * for the primary device which always comes first. 743 */ 744 for (; k < nDevToConfig; k++) { 745 if (DevToConfig[k].iDriver == i) { 746 dev2screen[k++] = l; 747 break; 748 } 749 } 750 } 751 } 752 free(driverProbed); 753 } 754 755 if (nDevToConfig != xf86NumScreens) { 756 ErrorF("Number of created screens does not match number of detected" 757 " devices.\n Configuration failed.\n"); 758 goto bail; 759 } 760 761 xf86PostProbe(); 762 763 for (j = 0; j < xf86NumScreens; j++) { 764 xf86Screens[j]->scrnIndex = j; 765 } 766 767 xf86freeMonitorList(xf86config->conf_monitor_lst); 768 xf86config->conf_monitor_lst = NULL; 769 xf86freeScreenList(xf86config->conf_screen_lst); 770 xf86config->conf_screen_lst = NULL; 771 for (j = 0; j < xf86NumScreens; j++) { 772 XF86ConfMonitorPtr monitor_ptr; 773 XF86ConfScreenPtr screen_ptr; 774 775 ConfiguredMonitor = NULL; 776 777 if ((*xf86Screens[dev2screen[j]]->PreInit) && 778 (*xf86Screens[dev2screen[j]]->PreInit) (xf86Screens[dev2screen[j]], 779 PROBE_DETECT) && 780 ConfiguredMonitor) { 781 monitor_ptr = configureDDCMonitorSection(j); 782 } 783 else { 784 monitor_ptr = configureMonitorSection(j); 785 } 786 screen_ptr = configureScreenSection(j); 787 788 xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) monitor_ptr); 789 xf86config->conf_screen_lst = (XF86ConfScreenPtr) xf86addListItem((glp) 790 xf86config-> 791 conf_screen_lst, 792 (glp) 793 screen_ptr); 794 } 795 796 if (xf86writeConfigFile(filename, xf86config) == 0) { 797 xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n", 798 filename, strerror(errno)); 799 goto bail; 800 } 801 802 ErrorF("\n"); 803 804 if (!foundMouse) { 805 ErrorF("\n" __XSERVERNAME__ " is not able to detect your mouse.\n" 806 "Edit the file and correct the Device.\n"); 807 } 808 else { 809 ErrorF("\n" __XSERVERNAME__ " detected your mouse at device %s.\n" 810 "Please check your config if the mouse is still not\n" 811 "operational, as by default " __XSERVERNAME__ 812 " tries to autodetect\n" "the protocol.\n", DFLT_MOUSE_DEV); 813 } 814 815 if (xf86NumScreens > 1) { 816 ErrorF("\n" __XSERVERNAME__ 817 " has configured a multihead system, please check your config.\n"); 818 } 819 820 ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE, filename); 821 ErrorF("To test the server, run 'X -config %s'\n\n", filename); 822 823 bail: 824 OsCleanup(TRUE); 825 ddxGiveUp(EXIT_ERR_CONFIGURE); 826 fflush(stderr); 827 exit(0); 828 } 829 830 /* Xorg -showopts: 831 * For each driver module installed, print out the list 832 * of options and their argument types, then exit 833 * 834 * Author: Marcus Schaefer, ms@suse.de 835 */ 836 837 void 838 DoShowOptions(void) 839 { 840 int i = 0; 841 const char **vlist = NULL; 842 char *pSymbol = 0; 843 XF86ModuleData *initData = 0; 844 845 if (!(vlist = GenerateDriverList())) { 846 ErrorF("Missing output drivers\n"); 847 goto bail; 848 } 849 xf86LoadModules(vlist, 0); 850 free(vlist); 851 for (i = 0; i < xf86NumDrivers; i++) { 852 if (xf86DriverList[i]->AvailableOptions) { 853 const OptionInfoRec *pOption = 854 (*xf86DriverList[i]->AvailableOptions) (0, 0); 855 if (!pOption) { 856 ErrorF("(EE) Couldn't read option table for %s driver\n", 857 xf86DriverList[i]->driverName); 858 continue; 859 } 860 XNFasprintf(&pSymbol, "%sModuleData", 861 xf86DriverList[i]->driverName); 862 initData = LoaderSymbol(pSymbol); 863 if (initData) { 864 XF86ModuleVersionInfo *vers = initData->vers; 865 const OptionInfoRec *p; 866 867 ErrorF("Driver[%d]:%s[%s] {\n", 868 i, xf86DriverList[i]->driverName, vers->vendor); 869 for (p = pOption; p->name != NULL; p++) { 870 ErrorF("\t%s:%s\n", p->name, optionTypeToString(p->type)); 871 } 872 ErrorF("}\n"); 873 } 874 } 875 } 876 bail: 877 OsCleanup(TRUE); 878 ddxGiveUp(EXIT_ERR_DRIVERS); 879 fflush(stderr); 880 exit(0); 881 }