xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

xf86Configure.c (28415B)


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