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