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