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