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