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