105b261ecSmrg/* 205b261ecSmrg * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales. 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Alan Hourihane not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Alan Hourihane makes no representations 1105b261ecSmrg * about the suitability of this software for any purpose. It is provided 1205b261ecSmrg * "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg * 2205b261ecSmrg * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 2305b261ecSmrg * 2405b261ecSmrg */ 2505b261ecSmrg 2605b261ecSmrg#ifdef HAVE_XORG_CONFIG_H 2705b261ecSmrg#include <xorg-config.h> 2805b261ecSmrg#endif 2905b261ecSmrg 3005b261ecSmrg#include "xf86.h" 3105b261ecSmrg#include "xf86Config.h" 3205b261ecSmrg#include "xf86_OSlib.h" 3305b261ecSmrg#include "xf86Priv.h" 3405b261ecSmrg#define IN_XSERVER 3505b261ecSmrg#include "Configint.h" 3605b261ecSmrg#include "xf86DDC.h" 3765b04b38Smrg#include "xf86pciBus.h" 3805b261ecSmrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 3905b261ecSmrg#include "xf86Bus.h" 4005b261ecSmrg#include "xf86Sbus.h" 4105b261ecSmrg#endif 42f7df2e56Smrg#include "misc.h" 437e31ba66Smrg#include "loaderProcs.h" 4405b261ecSmrg 4505b261ecSmrgtypedef struct _DevToConfig { 4605b261ecSmrg GDevRec GDev; 47f7df2e56Smrg struct pci_device *pVideo; 4805b261ecSmrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 4905b261ecSmrg sbusDevicePtr sVideo; 5005b261ecSmrg#endif 5105b261ecSmrg int iDriver; 5205b261ecSmrg} DevToConfigRec, *DevToConfigPtr; 5305b261ecSmrg 5405b261ecSmrgstatic DevToConfigPtr DevToConfig = NULL; 5505b261ecSmrgstatic int nDevToConfig = 0, CurrentDriver; 5605b261ecSmrg 574202a189Smrgxf86MonPtr ConfiguredMonitor; 5805b261ecSmrgBool xf86DoConfigurePass1 = TRUE; 5905b261ecSmrgstatic Bool foundMouse = FALSE; 6005b261ecSmrg 6165b04b38Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 62f7df2e56Smrgstatic const char *DFLT_MOUSE_DEV = "/dev/sysmouse"; 63f7df2e56Smrgstatic const char *DFLT_MOUSE_PROTO = "auto"; 647e31ba66Smrg#elif defined(__linux__) 65f7df2e56Smrgstatic const char *DFLT_MOUSE_DEV = "/dev/input/mice"; 66f7df2e56Smrgstatic const char *DFLT_MOUSE_PROTO = "auto"; 67f7df2e56Smrg#elif defined(WSCONS_SUPPORT) 68f7df2e56Smrgstatic const char *DFLT_MOUSE_DEV = "/dev/wsmouse"; 69f7df2e56Smrgstatic const char *DFLT_MOUSE_PROTO = "wsmouse"; 7005b261ecSmrg#else 71f7df2e56Smrgstatic const char *DFLT_MOUSE_DEV = "/dev/mouse"; 72f7df2e56Smrgstatic const char *DFLT_MOUSE_PROTO = "auto"; 7305b261ecSmrg#endif 7405b261ecSmrg 754202a189Smrg/* 764202a189Smrg * This is called by the driver, either through xf86Match???Instances() or 774202a189Smrg * directly. We allocate a GDevRec and fill it in as much as we can, letting 784202a189Smrg * the caller fill in the rest and/or change it as it sees fit. 794202a189Smrg */ 804202a189SmrgGDevPtr 81f7df2e56Smrgxf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, 82f7df2e56Smrg int chipset) 834202a189Smrg{ 844202a189Smrg int ret, i, j; 85f7df2e56Smrg char *lower_driver; 864202a189Smrg 874202a189Smrg if (!xf86DoConfigure || !xf86DoConfigurePass1) 88f7df2e56Smrg return NULL; 894202a189Smrg 904202a189Smrg /* Check for duplicates */ 91f7df2e56Smrg for (i = 0; i < nDevToConfig; i++) { 9265b04b38Smrg switch (bus) { 93f7df2e56Smrg#ifdef XSERVER_LIBPCIACCESS 94f7df2e56Smrg case BUS_PCI: 95f7df2e56Smrg ret = xf86PciConfigure(busData, DevToConfig[i].pVideo); 96f7df2e56Smrg break; 97f7df2e56Smrg#endif 9865b04b38Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 99f7df2e56Smrg case BUS_SBUS: 100f7df2e56Smrg ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo); 101f7df2e56Smrg break; 10265b04b38Smrg#endif 1030623337fSmrg#if defined(__arm32__) || defined(__arm__) 104f7df2e56Smrg case BUS_ISA: 105f7df2e56Smrg break; 106eec908bbSmrg#endif 107f7df2e56Smrg default: 108f7df2e56Smrg return NULL; 10965b04b38Smrg } 11065b04b38Smrg if (ret == 0) 11165b04b38Smrg goto out; 112fcca736fSmacallan } 1134202a189Smrg 1144202a189Smrg /* Allocate new structure occurrence */ 1154202a189Smrg i = nDevToConfig++; 1164202a189Smrg DevToConfig = 117f7df2e56Smrg xnfreallocarray(DevToConfig, nDevToConfig, sizeof(DevToConfigRec)); 1184202a189Smrg memset(DevToConfig + i, 0, sizeof(DevToConfigRec)); 1194202a189Smrg 1204202a189Smrg DevToConfig[i].GDev.chipID = 121f7df2e56Smrg DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1; 1224202a189Smrg 1234202a189Smrg DevToConfig[i].iDriver = CurrentDriver; 1244202a189Smrg 1254202a189Smrg /* Fill in what we know, converting the driver name to lower case */ 126f7df2e56Smrg lower_driver = xnfalloc(strlen(driver) + 1); 127f7df2e56Smrg for (j = 0; (lower_driver[j] = tolower(driver[j])); j++); 128f7df2e56Smrg DevToConfig[i].GDev.driver = lower_driver; 1294202a189Smrg 1304202a189Smrg switch (bus) { 131f7df2e56Smrg#ifdef XSERVER_LIBPCIACCESS 132f7df2e56Smrg case BUS_PCI: 133f7df2e56Smrg DevToConfig[i].pVideo = busData; 134f7df2e56Smrg xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo, 135f7df2e56Smrg &DevToConfig[i].GDev, &chipset); 136f7df2e56Smrg break; 137f7df2e56Smrg#endif 13865b04b38Smrg#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) 139f7df2e56Smrg case BUS_SBUS: 140f7df2e56Smrg DevToConfig[i].sVideo = busData; 141f7df2e56Smrg xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo, 142f7df2e56Smrg &DevToConfig[i].GDev); 143f7df2e56Smrg break; 14465b04b38Smrg#endif 1450623337fSmrg#if defined(__arm32__) || defined(__arm__) 146f7df2e56Smrg case BUS_ISA: 147f7df2e56Smrg DevToConfig[i].GDev.busID = xnfalloc(6); 1480d6c9d2dSjoerg strcpy((char *)DevToConfig[i].GDev.busID, "ISA"); 149f7df2e56Smrg break; 150eec908bbSmrg#endif 151f7df2e56Smrg default: 152f7df2e56Smrg break; 15305b261ecSmrg } 15405b261ecSmrg 15505b261ecSmrg /* Get driver's available options */ 15605b261ecSmrg if (xf86DriverList[CurrentDriver]->AvailableOptions) 157f7df2e56Smrg DevToConfig[i].GDev.options = (OptionInfoPtr) 158f7df2e56Smrg (*xf86DriverList[CurrentDriver]->AvailableOptions) (chipset, bus); 15905b261ecSmrg 1604202a189Smrg return &DevToConfig[i].GDev; 16105b261ecSmrg 162f7df2e56Smrg out: 1634202a189Smrg return NULL; 16405b261ecSmrg} 16505b261ecSmrg 16605b261ecSmrgstatic XF86ConfInputPtr 167f7df2e56SmrgconfigureInputSection(void) 16805b261ecSmrg{ 16905b261ecSmrg XF86ConfInputPtr mouse = NULL; 17005b261ecSmrg 1717e31ba66Smrg parsePrologue(XF86ConfInputPtr, XF86ConfInputRec); 172f7df2e56Smrg 173f7df2e56Smrg ptr->inp_identifier = xnfstrdup("Keyboard0"); 174f7df2e56Smrg ptr->inp_driver = xnfstrdup("kbd"); 17505b261ecSmrg ptr->list.next = NULL; 1769cf0a3efSmacallan#if defined(WSCONS_SUPPORT) && !defined(__i386__) && !defined(__amd64__) 1779cf0a3efSmacallan ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst, 1789cf0a3efSmacallan xstrdup("Protocol"), "wskbd"); 1799cf0a3efSmacallan ptr->inp_option_lst = xf86addNewOption(ptr->inp_option_lst, 1809cf0a3efSmacallan xstrdup("Device"), "/dev/wskbd"); 1819cf0a3efSmacallan#endif 18205b261ecSmrg 18305b261ecSmrg /* Crude mechanism to auto-detect mouse (os dependent) */ 184f7df2e56Smrg { 185f7df2e56Smrg int fd; 18605b261ecSmrg 187f7df2e56Smrg fd = open(DFLT_MOUSE_DEV, 0); 188f7df2e56Smrg if (fd != -1) { 189f7df2e56Smrg foundMouse = TRUE; 190f7df2e56Smrg close(fd); 191f7df2e56Smrg } 19205b261ecSmrg } 19305b261ecSmrg 1944202a189Smrg mouse = calloc(1, sizeof(XF86ConfInputRec)); 195f7df2e56Smrg mouse->inp_identifier = xnfstrdup("Mouse0"); 196f7df2e56Smrg mouse->inp_driver = xnfstrdup("mouse"); 197f7df2e56Smrg mouse->inp_option_lst = 198f7df2e56Smrg xf86addNewOption(mouse->inp_option_lst, xnfstrdup("Protocol"), 199f7df2e56Smrg xnfstrdup(DFLT_MOUSE_PROTO)); 200f7df2e56Smrg mouse->inp_option_lst = 201f7df2e56Smrg xf86addNewOption(mouse->inp_option_lst, xnfstrdup("Device"), 202f7df2e56Smrg xnfstrdup(DFLT_MOUSE_DEV)); 203f7df2e56Smrg mouse->inp_option_lst = 204f7df2e56Smrg xf86addNewOption(mouse->inp_option_lst, xnfstrdup("ZAxisMapping"), 205f7df2e56Smrg xnfstrdup("4 5 6 7")); 206f7df2e56Smrg ptr = (XF86ConfInputPtr) xf86addListItem((glp) ptr, (glp) mouse); 20705b261ecSmrg return ptr; 20805b261ecSmrg} 20905b261ecSmrg 21005b261ecSmrgstatic XF86ConfScreenPtr 211f7df2e56SmrgconfigureScreenSection(int screennum) 21205b261ecSmrg{ 21305b261ecSmrg int i; 214f7df2e56Smrg int depths[] = { 1, 4, 8, 15, 16, 24 /*, 32 */ }; 215f7df2e56Smrg char *tmp; 2167e31ba66Smrg parsePrologue(XF86ConfScreenPtr, XF86ConfScreenRec); 217f7df2e56Smrg 218f7df2e56Smrg XNFasprintf(&tmp, "Screen%d", screennum); 219f7df2e56Smrg ptr->scrn_identifier = tmp; 220f7df2e56Smrg XNFasprintf(&tmp, "Monitor%d", screennum); 221f7df2e56Smrg ptr->scrn_monitor_str = tmp; 222f7df2e56Smrg XNFasprintf(&tmp, "Card%d", screennum); 223f7df2e56Smrg ptr->scrn_device_str = tmp; 224f7df2e56Smrg 2257e31ba66Smrg for (i = 0; i < ARRAY_SIZE(depths); i++) { 226f7df2e56Smrg XF86ConfDisplayPtr conf_display; 227f7df2e56Smrg 228f7df2e56Smrg conf_display = calloc(1, sizeof(XF86ConfDisplayRec)); 229f7df2e56Smrg conf_display->disp_depth = depths[i]; 230f7df2e56Smrg conf_display->disp_black.red = conf_display->disp_white.red = -1; 231f7df2e56Smrg conf_display->disp_black.green = conf_display->disp_white.green = -1; 232f7df2e56Smrg conf_display->disp_black.blue = conf_display->disp_white.blue = -1; 233f7df2e56Smrg ptr->scrn_display_lst = (XF86ConfDisplayPtr) xf86addListItem((glp) ptr-> 234f7df2e56Smrg scrn_display_lst, 235f7df2e56Smrg (glp) 236f7df2e56Smrg conf_display); 23705b261ecSmrg } 23805b261ecSmrg 23905b261ecSmrg return ptr; 24005b261ecSmrg} 24105b261ecSmrg 242f7df2e56Smrgstatic const char * 2434202a189SmrgoptionTypeToString(OptionValueType type) 24405b261ecSmrg{ 24505b261ecSmrg switch (type) { 24605b261ecSmrg case OPTV_NONE: 24705b261ecSmrg return ""; 24805b261ecSmrg case OPTV_INTEGER: 24905b261ecSmrg return "<i>"; 25005b261ecSmrg case OPTV_STRING: 25105b261ecSmrg return "<str>"; 25205b261ecSmrg case OPTV_ANYSTR: 253f7df2e56Smrg return "[<str>]"; 25405b261ecSmrg case OPTV_REAL: 25505b261ecSmrg return "<f>"; 25605b261ecSmrg case OPTV_BOOLEAN: 25705b261ecSmrg return "[<bool>]"; 25805b261ecSmrg case OPTV_FREQ: 25905b261ecSmrg return "<freq>"; 2604202a189Smrg case OPTV_PERCENT: 2614202a189Smrg return "<percent>"; 26205b261ecSmrg default: 26305b261ecSmrg return ""; 26405b261ecSmrg } 26505b261ecSmrg} 26605b261ecSmrg 26705b261ecSmrgstatic XF86ConfDevicePtr 268f7df2e56SmrgconfigureDeviceSection(int screennum) 26905b261ecSmrg{ 27005b261ecSmrg OptionInfoPtr p; 27105b261ecSmrg int i = 0; 272f7df2e56Smrg char *identifier; 273f7df2e56Smrg 2747e31ba66Smrg parsePrologue(XF86ConfDevicePtr, XF86ConfDeviceRec); 27505b261ecSmrg 2767e31ba66Smrg /* Move device info to parser structure */ 277f7df2e56Smrg if (asprintf(&identifier, "Card%d", screennum) == -1) 278f7df2e56Smrg identifier = NULL; 279f7df2e56Smrg ptr->dev_identifier = identifier; 28005b261ecSmrg ptr->dev_chipset = DevToConfig[screennum].GDev.chipset; 28105b261ecSmrg ptr->dev_busid = DevToConfig[screennum].GDev.busID; 28205b261ecSmrg ptr->dev_driver = DevToConfig[screennum].GDev.driver; 28305b261ecSmrg ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac; 284f7df2e56Smrg for (i = 0; i < MAXDACSPEEDS; i++) 28505b261ecSmrg ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i]; 28605b261ecSmrg ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam; 28705b261ecSmrg ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase; 28805b261ecSmrg ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase; 28905b261ecSmrg ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip; 290f7df2e56Smrg for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); 291f7df2e56Smrg i++) 29205b261ecSmrg ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i]; 29305b261ecSmrg ptr->dev_clocks = i; 29405b261ecSmrg ptr->dev_chipid = DevToConfig[screennum].GDev.chipID; 29505b261ecSmrg ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev; 29605b261ecSmrg ptr->dev_irq = DevToConfig[screennum].GDev.irq; 29705b261ecSmrg 29805b261ecSmrg /* Make sure older drivers don't segv */ 29905b261ecSmrg if (DevToConfig[screennum].GDev.options) { 300f7df2e56Smrg /* Fill in the available driver options for people to use */ 301f7df2e56Smrg const char *descrip = 302f7df2e56Smrg " ### Available Driver options are:-\n" 303f7df2e56Smrg " ### Values: <i>: integer, <f>: float, " 304f7df2e56Smrg "<bool>: \"True\"/\"False\",\n" 305f7df2e56Smrg " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n" 306f7df2e56Smrg " ### <percent>: \"<f>%\"\n" 307f7df2e56Smrg " ### [arg]: arg optional\n"; 308f7df2e56Smrg ptr->dev_comment = xnfstrdup(descrip); 309f7df2e56Smrg if (ptr->dev_comment) { 310f7df2e56Smrg for (p = DevToConfig[screennum].GDev.options; p->name != NULL; p++) { 311f7df2e56Smrg char *p_e; 312f7df2e56Smrg const char *prefix = " #Option "; 313f7df2e56Smrg const char *middle = " \t# "; 314f7df2e56Smrg const char *suffix = "\n"; 315f7df2e56Smrg const char *opttype = optionTypeToString(p->type); 316f7df2e56Smrg char *optname; 317f7df2e56Smrg int len = strlen(ptr->dev_comment) + strlen(prefix) + 318f7df2e56Smrg strlen(middle) + strlen(suffix) + 1; 319f7df2e56Smrg 320f7df2e56Smrg if (asprintf(&optname, "\"%s\"", p->name) == -1) 321f7df2e56Smrg break; 322f7df2e56Smrg 323f7df2e56Smrg len += max(20, strlen(optname)); 324f7df2e56Smrg len += strlen(opttype); 325f7df2e56Smrg 326f7df2e56Smrg ptr->dev_comment = realloc(ptr->dev_comment, len); 327d566a54bSmrg if (!ptr->dev_comment) { 328d566a54bSmrg free(optname); 329f7df2e56Smrg break; 330d566a54bSmrg } 331f7df2e56Smrg p_e = ptr->dev_comment + strlen(ptr->dev_comment); 332f7df2e56Smrg sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle, 333f7df2e56Smrg opttype, suffix); 334f7df2e56Smrg free(optname); 335f7df2e56Smrg } 336f7df2e56Smrg } 33705b261ecSmrg } 33805b261ecSmrg 33905b261ecSmrg return ptr; 34005b261ecSmrg} 34105b261ecSmrg 34205b261ecSmrgstatic XF86ConfLayoutPtr 343f7df2e56SmrgconfigureLayoutSection(void) 34405b261ecSmrg{ 34505b261ecSmrg int scrnum = 0; 34605b261ecSmrg 3477e31ba66Smrg parsePrologue(XF86ConfLayoutPtr, XF86ConfLayoutRec); 348f7df2e56Smrg 3497e31ba66Smrg ptr->lay_identifier = "X.org Configured"; 35005b261ecSmrg 35105b261ecSmrg { 352f7df2e56Smrg XF86ConfInputrefPtr iptr; 353f7df2e56Smrg 354f7df2e56Smrg iptr = malloc(sizeof(XF86ConfInputrefRec)); 355f7df2e56Smrg iptr->list.next = NULL; 356f7df2e56Smrg iptr->iref_option_lst = NULL; 357f7df2e56Smrg iptr->iref_inputdev_str = xnfstrdup("Mouse0"); 358f7df2e56Smrg iptr->iref_option_lst = 359f7df2e56Smrg xf86addNewOption(iptr->iref_option_lst, xnfstrdup("CorePointer"), 360f7df2e56Smrg NULL); 361f7df2e56Smrg ptr->lay_input_lst = (XF86ConfInputrefPtr) 362f7df2e56Smrg xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr); 36305b261ecSmrg } 36405b261ecSmrg 36505b261ecSmrg { 366f7df2e56Smrg XF86ConfInputrefPtr iptr; 367f7df2e56Smrg 368f7df2e56Smrg iptr = malloc(sizeof(XF86ConfInputrefRec)); 369f7df2e56Smrg iptr->list.next = NULL; 370f7df2e56Smrg iptr->iref_option_lst = NULL; 371f7df2e56Smrg iptr->iref_inputdev_str = xnfstrdup("Keyboard0"); 372f7df2e56Smrg iptr->iref_option_lst = 373f7df2e56Smrg xf86addNewOption(iptr->iref_option_lst, xnfstrdup("CoreKeyboard"), 374f7df2e56Smrg NULL); 375f7df2e56Smrg ptr->lay_input_lst = (XF86ConfInputrefPtr) 376f7df2e56Smrg xf86addListItem((glp) ptr->lay_input_lst, (glp) iptr); 37705b261ecSmrg } 37805b261ecSmrg 379f7df2e56Smrg for (scrnum = 0; scrnum < nDevToConfig; scrnum++) { 380f7df2e56Smrg XF86ConfAdjacencyPtr aptr; 381f7df2e56Smrg char *tmp; 382f7df2e56Smrg 383f7df2e56Smrg aptr = malloc(sizeof(XF86ConfAdjacencyRec)); 384f7df2e56Smrg aptr->list.next = NULL; 385f7df2e56Smrg aptr->adj_x = 0; 386f7df2e56Smrg aptr->adj_y = 0; 387f7df2e56Smrg aptr->adj_scrnum = scrnum; 388f7df2e56Smrg XNFasprintf(&tmp, "Screen%d", scrnum); 389f7df2e56Smrg aptr->adj_screen_str = tmp; 390f7df2e56Smrg if (scrnum == 0) { 391f7df2e56Smrg aptr->adj_where = CONF_ADJ_ABSOLUTE; 392f7df2e56Smrg aptr->adj_refscreen = NULL; 393f7df2e56Smrg } 394f7df2e56Smrg else { 395f7df2e56Smrg aptr->adj_where = CONF_ADJ_RIGHTOF; 396f7df2e56Smrg XNFasprintf(&tmp, "Screen%d", scrnum - 1); 397f7df2e56Smrg aptr->adj_refscreen = tmp; 398f7df2e56Smrg } 399f7df2e56Smrg ptr->lay_adjacency_lst = 400f7df2e56Smrg (XF86ConfAdjacencyPtr) xf86addListItem((glp) ptr->lay_adjacency_lst, 401f7df2e56Smrg (glp) aptr); 40205b261ecSmrg } 40305b261ecSmrg 40405b261ecSmrg return ptr; 40505b261ecSmrg} 40605b261ecSmrg 40705b261ecSmrgstatic XF86ConfFlagsPtr 408f7df2e56SmrgconfigureFlagsSection(void) 40905b261ecSmrg{ 4107e31ba66Smrg parsePrologue(XF86ConfFlagsPtr, XF86ConfFlagsRec); 41105b261ecSmrg 4127e31ba66Smrg return ptr; 41305b261ecSmrg} 41405b261ecSmrg 41505b261ecSmrgstatic XF86ConfModulePtr 416f7df2e56SmrgconfigureModuleSection(void) 41705b261ecSmrg{ 418f7df2e56Smrg const char **elist, **el; 419f7df2e56Smrg 4207e31ba66Smrg parsePrologue(XF86ConfModulePtr, XF86ConfModuleRec); 42105b261ecSmrg 4227e31ba66Smrg elist = LoaderListDir("extensions", NULL); 42305b261ecSmrg if (elist) { 424f7df2e56Smrg for (el = elist; *el; el++) { 425f7df2e56Smrg XF86LoadPtr module; 426f7df2e56Smrg 427f7df2e56Smrg module = calloc(1, sizeof(XF86LoadRec)); 428f7df2e56Smrg module->load_name = *el; 429f7df2e56Smrg ptr->mod_load_lst = (XF86LoadPtr) xf86addListItem((glp) ptr-> 430f7df2e56Smrg mod_load_lst, 431f7df2e56Smrg (glp) module); 432f7df2e56Smrg } 433f7df2e56Smrg free(elist); 43405b261ecSmrg } 43505b261ecSmrg 43605b261ecSmrg return ptr; 43705b261ecSmrg} 43805b261ecSmrg 43905b261ecSmrgstatic XF86ConfFilesPtr 440f7df2e56SmrgconfigureFilesSection(void) 44105b261ecSmrg{ 4427e31ba66Smrg parsePrologue(XF86ConfFilesPtr, XF86ConfFilesRec); 443f7df2e56Smrg 4447e31ba66Smrg if (xf86ModulePath) 445f7df2e56Smrg ptr->file_modulepath = xnfstrdup(xf86ModulePath); 446f7df2e56Smrg if (defaultFontPath) 447f7df2e56Smrg ptr->file_fontpath = xnfstrdup(defaultFontPath); 44805b261ecSmrg 44905b261ecSmrg return ptr; 45005b261ecSmrg} 45105b261ecSmrg 45205b261ecSmrgstatic XF86ConfMonitorPtr 453f7df2e56SmrgconfigureMonitorSection(int screennum) 45405b261ecSmrg{ 455f7df2e56Smrg char *tmp; 4567e31ba66Smrg parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec); 45705b261ecSmrg 458f7df2e56Smrg XNFasprintf(&tmp, "Monitor%d", screennum); 459f7df2e56Smrg ptr->mon_identifier = tmp; 460f7df2e56Smrg ptr->mon_vendor = xnfstrdup("Monitor Vendor"); 461f7df2e56Smrg ptr->mon_modelname = xnfstrdup("Monitor Model"); 46205b261ecSmrg 46305b261ecSmrg return ptr; 46405b261ecSmrg} 46505b261ecSmrg 4664202a189Smrg/* Initialize Configure Monitor from Detailed Timing Block */ 467f7df2e56Smrgstatic void 468f7df2e56Smrghandle_detailed_input(struct detailed_monitor_section *det_mon, void *data) 4694202a189Smrg{ 4704202a189Smrg XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data; 4714202a189Smrg 4724202a189Smrg switch (det_mon->type) { 4734202a189Smrg case DS_NAME: 4744202a189Smrg ptr->mon_modelname = realloc(ptr->mon_modelname, 475f7df2e56Smrg strlen((char *) (det_mon->section.name)) + 4764202a189Smrg 1); 477f7df2e56Smrg strcpy(ptr->mon_modelname, (char *) (det_mon->section.name)); 4784202a189Smrg break; 4794202a189Smrg case DS_RANGES: 480f7df2e56Smrg ptr->mon_hsync[ptr->mon_n_hsync].lo = det_mon->section.ranges.min_h; 481f7df2e56Smrg ptr->mon_hsync[ptr->mon_n_hsync].hi = det_mon->section.ranges.max_h; 4824202a189Smrg ptr->mon_n_vrefresh = 1; 483f7df2e56Smrg ptr->mon_vrefresh[ptr->mon_n_hsync].lo = det_mon->section.ranges.min_v; 484f7df2e56Smrg ptr->mon_vrefresh[ptr->mon_n_hsync].hi = det_mon->section.ranges.max_v; 4854202a189Smrg ptr->mon_n_hsync++; 4864202a189Smrg default: 4874202a189Smrg break; 4884202a189Smrg } 4894202a189Smrg} 4904202a189Smrg 49105b261ecSmrgstatic XF86ConfMonitorPtr 492f7df2e56SmrgconfigureDDCMonitorSection(int screennum) 49305b261ecSmrg{ 49405b261ecSmrg int len, mon_width, mon_height; 495f7df2e56Smrg 49605b261ecSmrg#define displaySizeMaxLen 80 49705b261ecSmrg char displaySize_string[displaySizeMaxLen]; 49805b261ecSmrg int displaySizeLen; 499f7df2e56Smrg char *tmp; 50005b261ecSmrg 5017e31ba66Smrg parsePrologue(XF86ConfMonitorPtr, XF86ConfMonitorRec); 50205b261ecSmrg 503f7df2e56Smrg XNFasprintf(&tmp, "Monitor%d", screennum); 504f7df2e56Smrg ptr->mon_identifier = tmp; 505f7df2e56Smrg ptr->mon_vendor = xnfstrdup(ConfiguredMonitor->vendor.name); 50665b04b38Smrg XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id); 50705b261ecSmrg 50805b261ecSmrg /* features in centimetres, we want millimetres */ 509f7df2e56Smrg mon_width = 10 * ConfiguredMonitor->features.hsize; 510f7df2e56Smrg mon_height = 10 * ConfiguredMonitor->features.vsize; 51105b261ecSmrg 51205b261ecSmrg#ifdef CONFIGURE_DISPLAYSIZE 513f7df2e56Smrg ptr->mon_width = mon_width; 51405b261ecSmrg ptr->mon_height = mon_height; 51505b261ecSmrg#else 51605b261ecSmrg if (mon_width && mon_height) { 517f7df2e56Smrg /* when values available add DisplaySize option AS A COMMENT */ 518f7df2e56Smrg 519f7df2e56Smrg displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen, 520f7df2e56Smrg "\t#DisplaySize\t%5d %5d\t# mm\n", 521f7df2e56Smrg mon_width, mon_height); 522f7df2e56Smrg 523f7df2e56Smrg if (displaySizeLen > 0 && displaySizeLen < displaySizeMaxLen) { 524f7df2e56Smrg if (ptr->mon_comment) { 525f7df2e56Smrg len = strlen(ptr->mon_comment); 526f7df2e56Smrg } 527f7df2e56Smrg else { 528f7df2e56Smrg len = 0; 529f7df2e56Smrg } 530f7df2e56Smrg if ((ptr->mon_comment = 531f7df2e56Smrg realloc(ptr->mon_comment, 532f7df2e56Smrg len + strlen(displaySize_string) + 1))) { 533f7df2e56Smrg strcpy(ptr->mon_comment + len, displaySize_string); 534f7df2e56Smrg } 535f7df2e56Smrg } 53605b261ecSmrg } 537f7df2e56Smrg#endif /* def CONFIGURE_DISPLAYSIZE */ 53805b261ecSmrg 539f7df2e56Smrg xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input, ptr); 54005b261ecSmrg 54105b261ecSmrg if (ConfiguredMonitor->features.dpms) { 542f7df2e56Smrg ptr->mon_option_lst = 543f7df2e56Smrg xf86addNewOption(ptr->mon_option_lst, xnfstrdup("DPMS"), NULL); 54405b261ecSmrg } 54505b261ecSmrg 54605b261ecSmrg return ptr; 54705b261ecSmrg} 54805b261ecSmrg 5497e31ba66Smrgstatic int 5507e31ba66Smrgis_fallback(const char *s) 5517e31ba66Smrg{ 5527e31ba66Smrg /* later entries are less preferred */ 5537e31ba66Smrg const char *fallback[5] = { "modesetting", "fbdev", "vesa", "wsfb", NULL }; 5547e31ba66Smrg int i; 5557e31ba66Smrg 5567e31ba66Smrg for (i = 0; fallback[i]; i++) 5577e31ba66Smrg if (strstr(s, fallback[i])) 5587e31ba66Smrg return i; 5597e31ba66Smrg 5607e31ba66Smrg return -1; 5617e31ba66Smrg} 5627e31ba66Smrg 5637e31ba66Smrgstatic int 5647e31ba66Smrgdriver_sort(const void *_l, const void *_r) 5657e31ba66Smrg{ 5667e31ba66Smrg const char *l = *(const char **)_l; 5677e31ba66Smrg const char *r = *(const char **)_r; 5687e31ba66Smrg int left = is_fallback(l); 5697e31ba66Smrg int right = is_fallback(r); 5707e31ba66Smrg 5717e31ba66Smrg /* neither is a fallback, asciibetize */ 5727e31ba66Smrg if (left == -1 && right == -1) 5737e31ba66Smrg return strcmp(l, r); 5747e31ba66Smrg 5757e31ba66Smrg /* left is a fallback, right is not */ 5767e31ba66Smrg if (left >= 0 && right == -1) 5777e31ba66Smrg return 1; 5787e31ba66Smrg 5797e31ba66Smrg /* right is a fallback, left is not */ 5807e31ba66Smrg if (right >= 0 && left == -1) 5817e31ba66Smrg return -1; 5827e31ba66Smrg 5837e31ba66Smrg /* both are fallbacks, decide which is worse */ 5847e31ba66Smrg return left - right; 5857e31ba66Smrg} 5867e31ba66Smrg 5877e31ba66Smrgstatic void 5887e31ba66Smrgfixup_video_driver_list(const char **drivers) 5897e31ba66Smrg{ 5907e31ba66Smrg const char **end; 5917e31ba66Smrg 5927e31ba66Smrg /* walk to the end of the list */ 5937e31ba66Smrg for (end = drivers; *end && **end; end++); 5947e31ba66Smrg 5957e31ba66Smrg qsort(drivers, end - drivers, sizeof(const char *), driver_sort); 5967e31ba66Smrg} 5977e31ba66Smrg 5987e31ba66Smrgstatic const char ** 5997e31ba66SmrgGenerateDriverList(void) 6007e31ba66Smrg{ 6017e31ba66Smrg const char **ret; 6027e31ba66Smrg static const char *patlist[] = { "(.*)_drv\\.so", NULL }; 6037e31ba66Smrg ret = LoaderListDir("drivers", patlist); 6047e31ba66Smrg 6057e31ba66Smrg /* fix up the probe order for video drivers */ 6067e31ba66Smrg if (ret != NULL) 6077e31ba66Smrg fixup_video_driver_list(ret); 6087e31ba66Smrg 6097e31ba66Smrg return ret; 6107e31ba66Smrg} 6117e31ba66Smrg 61205b261ecSmrgvoid 6134642e01fSmrgDoConfigure(void) 61405b261ecSmrg{ 615f7df2e56Smrg int i, j, screennum = -1; 616f7df2e56Smrg const char *home = NULL; 6174642e01fSmrg char filename[PATH_MAX]; 618f7df2e56Smrg const char *addslash = ""; 61905b261ecSmrg XF86ConfigPtr xf86config = NULL; 620f7df2e56Smrg const char **vlist, **vl; 62105b261ecSmrg int *dev2screen; 62205b261ecSmrg 6237e31ba66Smrg vlist = GenerateDriverList(); 62405b261ecSmrg 62505b261ecSmrg if (!vlist) { 626f7df2e56Smrg ErrorF("Missing output drivers. Configuration failed.\n"); 627f7df2e56Smrg goto bail; 62805b261ecSmrg } 62905b261ecSmrg 63005b261ecSmrg ErrorF("List of video drivers:\n"); 63105b261ecSmrg for (vl = vlist; *vl; vl++) 632f7df2e56Smrg ErrorF("\t%s\n", *vl); 63305b261ecSmrg 63405b261ecSmrg /* Load all the drivers that were found. */ 63505b261ecSmrg xf86LoadModules(vlist, NULL); 63605b261ecSmrg 6374202a189Smrg free(vlist); 63805b261ecSmrg 639f7df2e56Smrg xorgHWAccess = xf86EnableIO(); 64005b261ecSmrg 64105b261ecSmrg /* Create XF86Config file structure */ 6424642e01fSmrg xf86config = calloc(1, sizeof(XF86ConfigRec)); 64305b261ecSmrg 64405b261ecSmrg /* Call all of the probe functions, reporting the results. */ 645f7df2e56Smrg for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) { 646f7df2e56Smrg Bool found_screen; 647f7df2e56Smrg DriverRec *const drv = xf86DriverList[CurrentDriver]; 648f7df2e56Smrg 649f7df2e56Smrg found_screen = xf86CallDriverProbe(drv, TRUE); 650f7df2e56Smrg if (found_screen && drv->Identify) { 651f7df2e56Smrg (*drv->Identify) (0); 652f7df2e56Smrg } 65305b261ecSmrg } 65405b261ecSmrg 65505b261ecSmrg if (nDevToConfig <= 0) { 656f7df2e56Smrg ErrorF("No devices to configure. Configuration failed.\n"); 657f7df2e56Smrg goto bail; 65805b261ecSmrg } 65905b261ecSmrg 66005b261ecSmrg /* Add device, monitor and screen sections for detected devices */ 661f7df2e56Smrg for (screennum = 0; screennum < nDevToConfig; screennum++) { 662f7df2e56Smrg XF86ConfDevicePtr device_ptr; 663f7df2e56Smrg XF86ConfMonitorPtr monitor_ptr; 664f7df2e56Smrg XF86ConfScreenPtr screen_ptr; 665f7df2e56Smrg 666f7df2e56Smrg device_ptr = configureDeviceSection(screennum); 667f7df2e56Smrg xf86config->conf_device_lst = (XF86ConfDevicePtr) xf86addListItem((glp) 668f7df2e56Smrg xf86config-> 669f7df2e56Smrg conf_device_lst, 670f7df2e56Smrg (glp) 671f7df2e56Smrg device_ptr); 672f7df2e56Smrg monitor_ptr = configureMonitorSection(screennum); 673f7df2e56Smrg xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) monitor_ptr); 674f7df2e56Smrg screen_ptr = configureScreenSection(screennum); 675f7df2e56Smrg xf86config->conf_screen_lst = (XF86ConfScreenPtr) xf86addListItem((glp) 676f7df2e56Smrg xf86config-> 677f7df2e56Smrg conf_screen_lst, 678f7df2e56Smrg (glp) 679f7df2e56Smrg screen_ptr); 68005b261ecSmrg } 68105b261ecSmrg 68205b261ecSmrg xf86config->conf_files = configureFilesSection(); 68305b261ecSmrg xf86config->conf_modules = configureModuleSection(); 68405b261ecSmrg xf86config->conf_flags = configureFlagsSection(); 68505b261ecSmrg xf86config->conf_videoadaptor_lst = NULL; 68605b261ecSmrg xf86config->conf_modes_lst = NULL; 68705b261ecSmrg xf86config->conf_vendor_lst = NULL; 68805b261ecSmrg xf86config->conf_dri = NULL; 68905b261ecSmrg xf86config->conf_input_lst = configureInputSection(); 69005b261ecSmrg xf86config->conf_layout_lst = configureLayoutSection(); 69105b261ecSmrg 6924642e01fSmrg home = getenv("HOME"); 6934642e01fSmrg if ((home == NULL) || (home[0] == '\0')) { 694f7df2e56Smrg home = "/"; 695f7df2e56Smrg } 696f7df2e56Smrg else { 697f7df2e56Smrg /* Determine if trailing slash is present or needed */ 698f7df2e56Smrg int l = strlen(home); 699f7df2e56Smrg 700f7df2e56Smrg if (home[l - 1] != '/') { 701f7df2e56Smrg addslash = "/"; 702f7df2e56Smrg } 70305b261ecSmrg } 70405b261ecSmrg 7054642e01fSmrg snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new", 706f7df2e56Smrg home, addslash); 7074642e01fSmrg 7084642e01fSmrg if (xf86writeConfigFile(filename, xf86config) == 0) { 709f7df2e56Smrg xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n", 710f7df2e56Smrg filename, strerror(errno)); 711f7df2e56Smrg goto bail; 7124642e01fSmrg } 71305b261ecSmrg 71405b261ecSmrg xf86DoConfigurePass1 = FALSE; 71505b261ecSmrg /* Try to get DDC information filled in */ 71605b261ecSmrg xf86ConfigFile = filename; 71705b261ecSmrg if (xf86HandleConfigFile(FALSE) != CONFIG_OK) { 718f7df2e56Smrg goto bail; 71905b261ecSmrg } 72005b261ecSmrg 72105b261ecSmrg xf86DoConfigurePass1 = FALSE; 722f7df2e56Smrg 7237e31ba66Smrg dev2screen = xnfcalloc(nDevToConfig, sizeof(int)); 72405b261ecSmrg 72505b261ecSmrg { 726f7df2e56Smrg Bool *driverProbed = xnfcalloc(xf86NumDrivers, sizeof(Bool)); 727f7df2e56Smrg 728f7df2e56Smrg for (screennum = 0; screennum < nDevToConfig; screennum++) { 729f7df2e56Smrg int k, l, n, oldNumScreens; 730f7df2e56Smrg 731f7df2e56Smrg i = DevToConfig[screennum].iDriver; 732f7df2e56Smrg 733f7df2e56Smrg if (driverProbed[i]) 734f7df2e56Smrg continue; 735f7df2e56Smrg driverProbed[i] = TRUE; 736f7df2e56Smrg 737f7df2e56Smrg oldNumScreens = xf86NumScreens; 738f7df2e56Smrg 739f7df2e56Smrg xf86CallDriverProbe(xf86DriverList[i], FALSE); 740f7df2e56Smrg 741f7df2e56Smrg /* reorder */ 742f7df2e56Smrg k = screennum > 0 ? screennum : 1; 743f7df2e56Smrg for (l = oldNumScreens; l < xf86NumScreens; l++) { 744f7df2e56Smrg /* is screen primary? */ 745f7df2e56Smrg Bool primary = FALSE; 746f7df2e56Smrg 747f7df2e56Smrg for (n = 0; n < xf86Screens[l]->numEntities; n++) { 748f7df2e56Smrg if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) { 749f7df2e56Smrg dev2screen[0] = l; 750f7df2e56Smrg primary = TRUE; 751f7df2e56Smrg break; 752f7df2e56Smrg } 753f7df2e56Smrg } 754f7df2e56Smrg if (primary) 755f7df2e56Smrg continue; 756f7df2e56Smrg /* not primary: assign it to next device of same driver */ 757f7df2e56Smrg /* 758f7df2e56Smrg * NOTE: we assume that devices in DevToConfig 759f7df2e56Smrg * and xf86Screens[] have the same order except 760f7df2e56Smrg * for the primary device which always comes first. 761f7df2e56Smrg */ 762f7df2e56Smrg for (; k < nDevToConfig; k++) { 763f7df2e56Smrg if (DevToConfig[k].iDriver == i) { 764f7df2e56Smrg dev2screen[k++] = l; 765f7df2e56Smrg break; 766f7df2e56Smrg } 767f7df2e56Smrg } 768f7df2e56Smrg } 769f7df2e56Smrg } 770f7df2e56Smrg free(driverProbed); 77105b261ecSmrg } 77205b261ecSmrg 77305b261ecSmrg if (nDevToConfig != xf86NumScreens) { 774f7df2e56Smrg ErrorF("Number of created screens does not match number of detected" 775f7df2e56Smrg " devices.\n Configuration failed.\n"); 776f7df2e56Smrg goto bail; 77705b261ecSmrg } 77805b261ecSmrg 77905b261ecSmrg xf86PostProbe(); 78005b261ecSmrg 78105b261ecSmrg for (j = 0; j < xf86NumScreens; j++) { 782f7df2e56Smrg xf86Screens[j]->scrnIndex = j; 78305b261ecSmrg } 78405b261ecSmrg 78505b261ecSmrg xf86freeMonitorList(xf86config->conf_monitor_lst); 78605b261ecSmrg xf86config->conf_monitor_lst = NULL; 78705b261ecSmrg xf86freeScreenList(xf86config->conf_screen_lst); 78805b261ecSmrg xf86config->conf_screen_lst = NULL; 78905b261ecSmrg for (j = 0; j < xf86NumScreens; j++) { 790f7df2e56Smrg XF86ConfMonitorPtr monitor_ptr; 791f7df2e56Smrg XF86ConfScreenPtr screen_ptr; 792f7df2e56Smrg 793f7df2e56Smrg ConfiguredMonitor = NULL; 794f7df2e56Smrg 7957e31ba66Smrg if ((*xf86Screens[dev2screen[j]]->PreInit) && 7967e31ba66Smrg (*xf86Screens[dev2screen[j]]->PreInit) (xf86Screens[dev2screen[j]], 797f7df2e56Smrg PROBE_DETECT) && 798f7df2e56Smrg ConfiguredMonitor) { 799f7df2e56Smrg monitor_ptr = configureDDCMonitorSection(j); 800f7df2e56Smrg } 801f7df2e56Smrg else { 802f7df2e56Smrg monitor_ptr = configureMonitorSection(j); 803f7df2e56Smrg } 804f7df2e56Smrg screen_ptr = configureScreenSection(j); 805f7df2e56Smrg 806f7df2e56Smrg xf86config->conf_monitor_lst = (XF86ConfMonitorPtr) xf86addListItem((glp) xf86config->conf_monitor_lst, (glp) monitor_ptr); 807f7df2e56Smrg xf86config->conf_screen_lst = (XF86ConfScreenPtr) xf86addListItem((glp) 808f7df2e56Smrg xf86config-> 809f7df2e56Smrg conf_screen_lst, 810f7df2e56Smrg (glp) 811f7df2e56Smrg screen_ptr); 81205b261ecSmrg } 81305b261ecSmrg 8144642e01fSmrg if (xf86writeConfigFile(filename, xf86config) == 0) { 815f7df2e56Smrg xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n", 816f7df2e56Smrg filename, strerror(errno)); 817f7df2e56Smrg goto bail; 8184642e01fSmrg } 81905b261ecSmrg 82005b261ecSmrg ErrorF("\n"); 82105b261ecSmrg 82205b261ecSmrg if (!foundMouse) { 823f7df2e56Smrg ErrorF("\n" __XSERVERNAME__ " is not able to detect your mouse.\n" 824f7df2e56Smrg "Edit the file and correct the Device.\n"); 825f7df2e56Smrg } 826f7df2e56Smrg else { 827f7df2e56Smrg ErrorF("\n" __XSERVERNAME__ " detected your mouse at device %s.\n" 828f7df2e56Smrg "Please check your config if the mouse is still not\n" 829f7df2e56Smrg "operational, as by default " __XSERVERNAME__ 830f7df2e56Smrg " tries to autodetect\n" "the protocol.\n", DFLT_MOUSE_DEV); 83105b261ecSmrg } 83205b261ecSmrg 83305b261ecSmrg if (xf86NumScreens > 1) { 834f7df2e56Smrg ErrorF("\n" __XSERVERNAME__ 835f7df2e56Smrg " has configured a multihead system, please check your config.\n"); 83605b261ecSmrg } 83705b261ecSmrg 838f7df2e56Smrg ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE, filename); 83905b261ecSmrg ErrorF("To test the server, run 'X -config %s'\n\n", filename); 84005b261ecSmrg 841f7df2e56Smrg bail: 842f7df2e56Smrg OsCleanup(TRUE); 8435a112b11Smrg ddxGiveUp(EXIT_ERR_CONFIGURE); 844f7df2e56Smrg fflush(stderr); 845f7df2e56Smrg exit(0); 846f7df2e56Smrg} 847f7df2e56Smrg 848f7df2e56Smrg/* Xorg -showopts: 849f7df2e56Smrg * For each driver module installed, print out the list 850f7df2e56Smrg * of options and their argument types, then exit 851f7df2e56Smrg * 852f7df2e56Smrg * Author: Marcus Schaefer, ms@suse.de 853f7df2e56Smrg */ 854f7df2e56Smrg 855f7df2e56Smrgvoid 856f7df2e56SmrgDoShowOptions(void) 857f7df2e56Smrg{ 858f7df2e56Smrg int i = 0; 859f7df2e56Smrg const char **vlist = NULL; 860f7df2e56Smrg char *pSymbol = 0; 861f7df2e56Smrg XF86ModuleData *initData = 0; 862f7df2e56Smrg 8637e31ba66Smrg if (!(vlist = GenerateDriverList())) { 864f7df2e56Smrg ErrorF("Missing output drivers\n"); 865f7df2e56Smrg goto bail; 866f7df2e56Smrg } 867f7df2e56Smrg xf86LoadModules(vlist, 0); 868f7df2e56Smrg free(vlist); 869f7df2e56Smrg for (i = 0; i < xf86NumDrivers; i++) { 870f7df2e56Smrg if (xf86DriverList[i]->AvailableOptions) { 871f7df2e56Smrg const OptionInfoRec *pOption = 872f7df2e56Smrg (*xf86DriverList[i]->AvailableOptions) (0, 0); 873f7df2e56Smrg if (!pOption) { 874f7df2e56Smrg ErrorF("(EE) Couldn't read option table for %s driver\n", 875f7df2e56Smrg xf86DriverList[i]->driverName); 876f7df2e56Smrg continue; 877f7df2e56Smrg } 878f7df2e56Smrg XNFasprintf(&pSymbol, "%sModuleData", 879f7df2e56Smrg xf86DriverList[i]->driverName); 880f7df2e56Smrg initData = LoaderSymbol(pSymbol); 881f7df2e56Smrg if (initData) { 882f7df2e56Smrg XF86ModuleVersionInfo *vers = initData->vers; 883f7df2e56Smrg const OptionInfoRec *p; 884f7df2e56Smrg 885f7df2e56Smrg ErrorF("Driver[%d]:%s[%s] {\n", 886f7df2e56Smrg i, xf86DriverList[i]->driverName, vers->vendor); 887f7df2e56Smrg for (p = pOption; p->name != NULL; p++) { 888f7df2e56Smrg ErrorF("\t%s:%s\n", p->name, optionTypeToString(p->type)); 889f7df2e56Smrg } 890f7df2e56Smrg ErrorF("}\n"); 891f7df2e56Smrg } 892f7df2e56Smrg } 893f7df2e56Smrg } 894f7df2e56Smrg bail: 89505b261ecSmrg OsCleanup(TRUE); 8965a112b11Smrg ddxGiveUp(EXIT_ERR_DRIVERS); 89705b261ecSmrg fflush(stderr); 89805b261ecSmrg exit(0); 89905b261ecSmrg} 900