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