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 43typedef struct _DevToConfig { 44 GDevRec GDev; 45 struct pci_device * pVideo; 46#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 47 sbusDevicePtr sVideo; 48#endif 49 int iDriver; 50} DevToConfigRec, *DevToConfigPtr; 51 52static DevToConfigPtr DevToConfig = NULL; 53static int nDevToConfig = 0, CurrentDriver; 54 55xf86MonPtr ConfiguredMonitor; 56Bool xf86DoConfigurePass1 = TRUE; 57static Bool foundMouse = FALSE; 58 59#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 60static char *DFLT_MOUSE_DEV = "/dev/sysmouse"; 61static char *DFLT_MOUSE_PROTO = "auto"; 62#elif defined(linux) 63static char DFLT_MOUSE_DEV[] = "/dev/input/mice"; 64static char DFLT_MOUSE_PROTO[] = "auto"; 65#else 66static char *DFLT_MOUSE_DEV = "/dev/mouse"; 67static char *DFLT_MOUSE_PROTO = "auto"; 68#endif 69 70/* 71 * This is called by the driver, either through xf86Match???Instances() or 72 * directly. We allocate a GDevRec and fill it in as much as we can, letting 73 * the caller fill in the rest and/or change it as it sees fit. 74 */ 75GDevPtr 76xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset) 77{ 78 int ret, i, j; 79 80 if (!xf86DoConfigure || !xf86DoConfigurePass1) 81 return NULL; 82 83 /* Check for duplicates */ 84 for (i = 0; i < nDevToConfig; i++) { 85 switch (bus) { 86 case BUS_PCI: 87 ret = xf86PciConfigure(busData, DevToConfig[i].pVideo); 88 break; 89#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 90 case BUS_SBUS: 91 ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo); 92 break; 93#endif 94#if defined(__arm32__) 95 case BUS_ISA: 96 break; 97#endif 98 default: 99 return NULL; 100 } 101 if (ret == 0) 102 goto out; 103 } 104 105 /* Allocate new structure occurrence */ 106 i = nDevToConfig++; 107 DevToConfig = 108 xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec)); 109 memset(DevToConfig + i, 0, sizeof(DevToConfigRec)); 110 111 DevToConfig[i].GDev.chipID = 112 DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1; 113 114 DevToConfig[i].iDriver = CurrentDriver; 115 116 /* Fill in what we know, converting the driver name to lower case */ 117 DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1); 118 for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++); 119 120 switch (bus) { 121 case BUS_PCI: 122 xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo, 123 &DevToConfig[i].GDev, &chipset); 124 DevToConfig[i].pVideo = busData; 125 break; 126#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 127 case BUS_SBUS: 128 xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo, 129 &DevToConfig[i].GDev); 130 DevToConfig[i].sVideo = busData; 131 break; 132#endif 133#if defined(__arm32__) 134 case BUS_ISA: 135 DevToConfig[i].GDev.busID = xnfalloc(6); 136 strcpy(DevToConfig[i].GDev.busID, "ISA"); 137 break; 138#endif 139 default: 140 break; 141 } 142 143 /* Get driver's available options */ 144 if (xf86DriverList[CurrentDriver]->AvailableOptions) 145 DevToConfig[i].GDev.options = (OptionInfoPtr) 146 (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset, 147 bus); 148 149 return &DevToConfig[i].GDev; 150 151out: 152 return NULL; 153} 154 155static XF86ConfInputPtr 156configureInputSection (void) 157{ 158 XF86ConfInputPtr mouse = NULL; 159 parsePrologue (XF86ConfInputPtr, XF86ConfInputRec) 160 161 ptr->inp_identifier = "Keyboard0"; 162 ptr->inp_driver = "kbd"; 163 ptr->list.next = NULL; 164#if defined(WSCONS_SUPPORT) && !defined(__i386__) && !defined(__amd64__) 165 ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst, 166 xstrdup("Protocol"), "wskbd"); 167 ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst, 168 xstrdup("Device"), "/dev/wskbd"); 169#endif 170 171 /* Crude mechanism to auto-detect mouse (os dependent) */ 172 { 173 int fd; 174#ifdef WSCONS_SUPPORT 175 fd = open("/dev/wsmouse", 0); 176 if (fd >= 0) { 177 DFLT_MOUSE_DEV = "/dev/wsmouse"; 178 DFLT_MOUSE_PROTO = "wsmouse"; 179 close(fd); 180 } else { 181 ErrorF("cannot open /dev/wsmouse\n"); 182 } 183#endif 184 185 fd = open(DFLT_MOUSE_DEV, 0); 186 if (fd != -1) { 187 foundMouse = TRUE; 188 close(fd); 189 } 190 } 191 192 mouse = calloc(1, sizeof(XF86ConfInputRec)); 193 mouse->inp_identifier = "Mouse0"; 194 mouse->inp_driver = "mouse"; 195 mouse->inp_option_lst = 196 xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"), 197 strdup(DFLT_MOUSE_PROTO)); 198 mouse->inp_option_lst = 199 xf86addNewOption(mouse->inp_option_lst, strdup("Device"), 200 strdup(DFLT_MOUSE_DEV)); 201 mouse->inp_option_lst = 202 xf86addNewOption(mouse->inp_option_lst, strdup("ZAxisMapping"), 203 strdup("4 5 6 7")); 204 ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse); 205 return ptr; 206} 207 208static XF86ConfScreenPtr 209configureScreenSection (int screennum) 210{ 211 int i; 212 int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ }; 213 parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec) 214 215 XNFasprintf(&ptr->scrn_identifier, "Screen%d", screennum); 216 XNFasprintf(&ptr->scrn_monitor_str, "Monitor%d", screennum); 217 XNFasprintf(&ptr->scrn_device_str, "Card%d", screennum); 218 219 for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++) 220 { 221 XF86ConfDisplayPtr display; 222 223 display = calloc(1, sizeof(XF86ConfDisplayRec)); 224 display->disp_depth = depths[i]; 225 display->disp_black.red = display->disp_white.red = -1; 226 display->disp_black.green = display->disp_white.green = -1; 227 display->disp_black.blue = display->disp_white.blue = -1; 228 ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem( 229 (glp)ptr->scrn_display_lst, (glp)display); 230 } 231 232 return ptr; 233} 234 235static const char* 236optionTypeToString(OptionValueType type) 237{ 238 switch (type) { 239 case OPTV_NONE: 240 return ""; 241 case OPTV_INTEGER: 242 return "<i>"; 243 case OPTV_STRING: 244 return "<str>"; 245 case OPTV_ANYSTR: 246 return "[<str>]"; 247 case OPTV_REAL: 248 return "<f>"; 249 case OPTV_BOOLEAN: 250 return "[<bool>]"; 251 case OPTV_FREQ: 252 return "<freq>"; 253 case OPTV_PERCENT: 254 return "<percent>"; 255 default: 256 return ""; 257 } 258} 259 260static XF86ConfDevicePtr 261configureDeviceSection (int screennum) 262{ 263 OptionInfoPtr p; 264 int i = 0; 265 parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec) 266 267 /* Move device info to parser structure */ 268 if (asprintf(&ptr->dev_identifier, "Card%d", screennum) == -1) 269 ptr->dev_identifier = NULL; 270 ptr->dev_chipset = DevToConfig[screennum].GDev.chipset; 271 ptr->dev_busid = DevToConfig[screennum].GDev.busID; 272 ptr->dev_driver = DevToConfig[screennum].GDev.driver; 273 ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac; 274 for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++) 275 ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i]; 276 ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam; 277 ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq; 278 ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase; 279 ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase; 280 ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase; 281 ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip; 282 for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++) 283 ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i]; 284 ptr->dev_clocks = i; 285 ptr->dev_chipid = DevToConfig[screennum].GDev.chipID; 286 ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev; 287 ptr->dev_irq = DevToConfig[screennum].GDev.irq; 288 289 /* Make sure older drivers don't segv */ 290 if (DevToConfig[screennum].GDev.options) { 291 /* Fill in the available driver options for people to use */ 292 const char *descrip = 293 " ### Available Driver options are:-\n" 294 " ### Values: <i>: integer, <f>: float, " 295 "<bool>: \"True\"/\"False\",\n" 296 " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n" 297 " ### <percent>: \"<f>%\"\n" 298 " ### [arg]: arg optional\n"; 299 ptr->dev_comment = strdup(descrip); 300 if (ptr->dev_comment) { 301 for (p = DevToConfig[screennum].GDev.options; 302 p->name != NULL; p++) { 303 char *p_e; 304 const char *prefix = " #Option "; 305 const char *middle = " \t# "; 306 const char *suffix = "\n"; 307 const char *opttype = optionTypeToString(p->type); 308 char *optname; 309 int len = strlen(ptr->dev_comment) + strlen(prefix) + 310 strlen(middle) + strlen(suffix) + 1; 311 312 if (asprintf(&optname, "\"%s\"", p->name) == -1) 313 break; 314 315 len += max(20, strlen(optname)); 316 len += strlen(opttype); 317 318 ptr->dev_comment = realloc(ptr->dev_comment, len); 319 if (!ptr->dev_comment) 320 break; 321 p_e = ptr->dev_comment + strlen(ptr->dev_comment); 322 sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle, 323 opttype, suffix); 324 free(optname); 325 } 326 } 327 } 328 329 return ptr; 330} 331 332static XF86ConfLayoutPtr 333configureLayoutSection (void) 334{ 335 int scrnum = 0; 336 parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec) 337 338 ptr->lay_identifier = "X.org Configured"; 339 340 { 341 XF86ConfInputrefPtr iptr; 342 343 iptr = malloc (sizeof (XF86ConfInputrefRec)); 344 iptr->list.next = NULL; 345 iptr->iref_option_lst = NULL; 346 iptr->iref_inputdev_str = "Mouse0"; 347 iptr->iref_option_lst = 348 xf86addNewOption (iptr->iref_option_lst, strdup("CorePointer"), NULL); 349 ptr->lay_input_lst = (XF86ConfInputrefPtr) 350 xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr); 351 } 352 353 { 354 XF86ConfInputrefPtr iptr; 355 356 iptr = malloc (sizeof (XF86ConfInputrefRec)); 357 iptr->list.next = NULL; 358 iptr->iref_option_lst = NULL; 359 iptr->iref_inputdev_str = "Keyboard0"; 360 iptr->iref_option_lst = 361 xf86addNewOption (iptr->iref_option_lst, strdup("CoreKeyboard"), NULL); 362 ptr->lay_input_lst = (XF86ConfInputrefPtr) 363 xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr); 364 } 365 366 for (scrnum = 0; scrnum < nDevToConfig; scrnum++) { 367 XF86ConfAdjacencyPtr aptr; 368 369 aptr = malloc (sizeof (XF86ConfAdjacencyRec)); 370 aptr->list.next = NULL; 371 aptr->adj_x = 0; 372 aptr->adj_y = 0; 373 aptr->adj_scrnum = scrnum; 374 XNFasprintf(&aptr->adj_screen_str, "Screen%d", scrnum); 375 if (scrnum == 0) { 376 aptr->adj_where = CONF_ADJ_ABSOLUTE; 377 aptr->adj_refscreen = NULL; 378 } 379 else { 380 aptr->adj_where = CONF_ADJ_RIGHTOF; 381 XNFasprintf(&aptr->adj_refscreen, "Screen%d", scrnum - 1); 382 } 383 ptr->lay_adjacency_lst = 384 (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst, 385 (glp)aptr); 386 } 387 388 return ptr; 389} 390 391static XF86ConfFlagsPtr 392configureFlagsSection (void) 393{ 394 parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec) 395 396 return ptr; 397} 398 399static XF86ConfModulePtr 400configureModuleSection (void) 401{ 402 char **elist, **el; 403 /* Find the list of extension & font modules. */ 404 const char *esubdirs[] = { 405 "extensions", 406 "fonts", 407 NULL 408 }; 409 parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec) 410 411 elist = LoaderListDirs(esubdirs, NULL); 412 if (elist) { 413 for (el = elist; *el; el++) { 414 XF86LoadPtr module; 415 416 module = calloc(1, sizeof(XF86LoadRec)); 417 module->load_name = *el; 418 ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem( 419 (glp)ptr->mod_load_lst, (glp)module); 420 } 421 free(elist); 422 } 423 424 return ptr; 425} 426 427static XF86ConfFilesPtr 428configureFilesSection (void) 429{ 430 parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec) 431 432 if (xf86ModulePath) 433 ptr->file_modulepath = strdup(xf86ModulePath); 434 if (defaultFontPath) 435 ptr->file_fontpath = strdup(defaultFontPath); 436 437 return ptr; 438} 439 440static XF86ConfMonitorPtr 441configureMonitorSection (int screennum) 442{ 443 parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec) 444 445 XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum); 446 ptr->mon_vendor = strdup("Monitor Vendor"); 447 ptr->mon_modelname = strdup("Monitor Model"); 448 449 return ptr; 450} 451 452/* Initialize Configure Monitor from Detailed Timing Block */ 453static void handle_detailed_input(struct detailed_monitor_section *det_mon, 454 void *data) 455{ 456 XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data; 457 458 switch (det_mon->type) { 459 case DS_NAME: 460 ptr->mon_modelname = realloc(ptr->mon_modelname, 461 strlen((char*)(det_mon->section.name)) + 462 1); 463 strcpy(ptr->mon_modelname, 464 (char*)(det_mon->section.name)); 465 break; 466 case DS_RANGES: 467 ptr->mon_hsync[ptr->mon_n_hsync].lo = 468 det_mon->section.ranges.min_h; 469 ptr->mon_hsync[ptr->mon_n_hsync].hi = 470 det_mon->section.ranges.max_h; 471 ptr->mon_n_vrefresh = 1; 472 ptr->mon_vrefresh[ptr->mon_n_hsync].lo = 473 det_mon->section.ranges.min_v; 474 ptr->mon_vrefresh[ptr->mon_n_hsync].hi = 475 det_mon->section.ranges.max_v; 476 ptr->mon_n_hsync++; 477 default: 478 break; 479 } 480} 481 482static XF86ConfMonitorPtr 483configureDDCMonitorSection (int screennum) 484{ 485 int len, mon_width, mon_height; 486#define displaySizeMaxLen 80 487 char displaySize_string[displaySizeMaxLen]; 488 int displaySizeLen; 489 490 parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec) 491 492 XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum); 493 ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name); 494 XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id); 495 496 /* features in centimetres, we want millimetres */ 497 mon_width = 10 * ConfiguredMonitor->features.hsize ; 498 mon_height = 10 * ConfiguredMonitor->features.vsize ; 499 500#ifdef CONFIGURE_DISPLAYSIZE 501 ptr->mon_width = mon_width; 502 ptr->mon_height = mon_height; 503#else 504 if (mon_width && mon_height) { 505 /* when values available add DisplaySize option AS A COMMENT */ 506 507 displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen, 508 "\t#DisplaySize\t%5d %5d\t# mm\n", 509 mon_width, mon_height); 510 511 if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) { 512 if (ptr->mon_comment) { 513 len = strlen(ptr->mon_comment); 514 } else { 515 len = 0; 516 } 517 if ((ptr->mon_comment = 518 realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) { 519 strcpy(ptr->mon_comment + len, displaySize_string); 520 } 521 } 522 } 523#endif /* def CONFIGURE_DISPLAYSIZE */ 524 525 xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input, 526 ptr); 527 528 if (ConfiguredMonitor->features.dpms) { 529 ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, strdup("DPMS"), NULL); 530 } 531 532 return ptr; 533} 534 535#if !defined(PATH_MAX) 536# define PATH_MAX 1024 537#endif 538 539void 540DoConfigure(void) 541{ 542 int i,j, screennum = -1; 543 char *home = NULL; 544 char filename[PATH_MAX]; 545 char *addslash = ""; 546 XF86ConfigPtr xf86config = NULL; 547 char **vlist, **vl; 548 int *dev2screen; 549 550 vlist = xf86DriverlistFromCompile(); 551 552 if (!vlist) { 553 ErrorF("Missing output drivers. Configuration failed.\n"); 554 goto bail; 555 } 556 557 ErrorF("List of video drivers:\n"); 558 for (vl = vlist; *vl; vl++) 559 ErrorF("\t%s\n", *vl); 560 561 /* Load all the drivers that were found. */ 562 xf86LoadModules(vlist, NULL); 563 564 free(vlist); 565 566 for (i = 0; i < xf86NumDrivers; i++) { 567 xorgHWFlags flags; 568 if (!xf86DriverList[i]->driverFunc 569 || !xf86DriverList[i]->driverFunc(NULL, 570 GET_REQUIRED_HW_INTERFACES, 571 &flags) 572 || NEED_IO_ENABLED(flags)) { 573 xorgHWAccess = TRUE; 574 break; 575 } 576 } 577 /* Enable full I/O access */ 578 if (xorgHWAccess) { 579 if(!xf86EnableIO()) 580 /* oops, we have failed */ 581 xorgHWAccess = FALSE; 582 } 583 584 /* Create XF86Config file structure */ 585 xf86config = calloc(1, sizeof(XF86ConfigRec)); 586 587 /* Call all of the probe functions, reporting the results. */ 588 for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) { 589 xorgHWFlags flags; 590 Bool found_screen; 591 DriverRec * const drv = xf86DriverList[CurrentDriver]; 592 593 if (!xorgHWAccess) { 594 if (!drv->driverFunc 595 || !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags ) 596 || NEED_IO_ENABLED(flags)) 597 continue; 598 } 599 600 found_screen = xf86CallDriverProbe( drv, TRUE ); 601 if ( found_screen && drv->Identify ) { 602 (*drv->Identify)(0); 603 } 604 } 605 606 if (nDevToConfig <= 0) { 607 ErrorF("No devices to configure. Configuration failed.\n"); 608 goto bail; 609 } 610 611 /* Add device, monitor and screen sections for detected devices */ 612 for (screennum = 0; screennum < nDevToConfig; screennum++) { 613 XF86ConfDevicePtr DevicePtr; 614 XF86ConfMonitorPtr MonitorPtr; 615 XF86ConfScreenPtr ScreenPtr; 616 617 DevicePtr = configureDeviceSection(screennum); 618 xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem( 619 (glp)xf86config->conf_device_lst, (glp)DevicePtr); 620 MonitorPtr = configureMonitorSection(screennum); 621 xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem( 622 (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr); 623 ScreenPtr = configureScreenSection(screennum); 624 xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem( 625 (glp)xf86config->conf_screen_lst, (glp)ScreenPtr); 626 } 627 628 xf86config->conf_files = configureFilesSection(); 629 xf86config->conf_modules = configureModuleSection(); 630 xf86config->conf_flags = configureFlagsSection(); 631 xf86config->conf_videoadaptor_lst = NULL; 632 xf86config->conf_modes_lst = NULL; 633 xf86config->conf_vendor_lst = NULL; 634 xf86config->conf_dri = NULL; 635 xf86config->conf_input_lst = configureInputSection(); 636 xf86config->conf_layout_lst = configureLayoutSection(); 637 638 home = getenv("HOME"); 639 if ((home == NULL) || (home[0] == '\0')) { 640 home = "/"; 641 } else { 642 /* Determine if trailing slash is present or needed */ 643 int l = strlen(home); 644 645 if (home[l-1] != '/') { 646 addslash = "/"; 647 } 648 } 649 650 snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new", 651 home, addslash); 652 653 if (xf86writeConfigFile(filename, xf86config) == 0) { 654 xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n", 655 filename, strerror(errno)); 656 goto bail; 657 } 658 659 xf86DoConfigurePass1 = FALSE; 660 /* Try to get DDC information filled in */ 661 xf86ConfigFile = filename; 662 if (xf86HandleConfigFile(FALSE) != CONFIG_OK) { 663 goto bail; 664 } 665 666 xf86DoConfigurePass1 = FALSE; 667 668 dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int)); 669 670 { 671 Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool)); 672 for (screennum = 0; screennum < nDevToConfig; screennum++) { 673 int k,l,n,oldNumScreens; 674 675 i = DevToConfig[screennum].iDriver; 676 677 if (driverProbed[i]) continue; 678 driverProbed[i] = TRUE; 679 680 oldNumScreens = xf86NumScreens; 681 682 xf86CallDriverProbe( xf86DriverList[i], FALSE ); 683 684 /* reorder */ 685 k = screennum > 0 ? screennum : 1; 686 for (l = oldNumScreens; l < xf86NumScreens; l++) { 687 /* is screen primary? */ 688 Bool primary = FALSE; 689 for (n = 0; n<xf86Screens[l]->numEntities; n++) { 690 if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) { 691 dev2screen[0] = l; 692 primary = TRUE; 693 break; 694 } 695 } 696 if (primary) continue; 697 /* not primary: assign it to next device of same driver */ 698 /* 699 * NOTE: we assume that devices in DevToConfig 700 * and xf86Screens[] have the same order except 701 * for the primary device which always comes first. 702 */ 703 for (; k < nDevToConfig; k++) { 704 if (DevToConfig[k].iDriver == i) { 705 dev2screen[k++] = l; 706 break; 707 } 708 } 709 } 710 } 711 free(driverProbed); 712 } 713 714 715 if (nDevToConfig != xf86NumScreens) { 716 ErrorF("Number of created screens does not match number of detected" 717 " devices.\n Configuration failed.\n"); 718 goto bail; 719 } 720 721 xf86PostProbe(); 722 723 for (j = 0; j < xf86NumScreens; j++) { 724 xf86Screens[j]->scrnIndex = j; 725 } 726 727 xf86freeMonitorList(xf86config->conf_monitor_lst); 728 xf86config->conf_monitor_lst = NULL; 729 xf86freeScreenList(xf86config->conf_screen_lst); 730 xf86config->conf_screen_lst = NULL; 731 for (j = 0; j < xf86NumScreens; j++) { 732 XF86ConfMonitorPtr MonitorPtr; 733 XF86ConfScreenPtr ScreenPtr; 734 735 ConfiguredMonitor = NULL; 736 737 if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]], 738 PROBE_DETECT) && 739 ConfiguredMonitor) { 740 MonitorPtr = configureDDCMonitorSection(j); 741 } else { 742 MonitorPtr = configureMonitorSection(j); 743 } 744 ScreenPtr = configureScreenSection(j); 745 xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem( 746 (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr); 747 xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem( 748 (glp)xf86config->conf_screen_lst, (glp)ScreenPtr); 749 } 750 751 if (xf86writeConfigFile(filename, xf86config) == 0) { 752 xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n", 753 filename, strerror(errno)); 754 goto bail; 755 } 756 757 ErrorF("\n"); 758 759 if (!foundMouse) { 760 ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n" 761 "Edit the file and correct the Device.\n"); 762 } else { 763 ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n" 764 "Please check your config if the mouse is still not\n" 765 "operational, as by default "__XSERVERNAME__ 766 " tries to autodetect\n" 767 "the protocol.\n",DFLT_MOUSE_DEV); 768 } 769 770 if (xf86NumScreens > 1) { 771 ErrorF("\n"__XSERVERNAME__ 772 " has configured a multihead system, please check your config.\n"); 773 } 774 775 ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename); 776 ErrorF("To test the server, run 'X -config %s'\n\n", filename); 777 778bail: 779 OsCleanup(TRUE); 780 AbortDDX(); 781 fflush(stderr); 782 exit(0); 783} 784