xenocara/xserver/hw/xfree86/common/xf86Configure.c
matthieu 428261197a Upgrade to xorg-server 1.9.2.
Tested by ajacoutot@, krw@, shadchin@ and jasper@ on various configurations
including multihead with both zaphod and xrandr.
2010-12-05 15:36:02 +00:00

872 lines
25 KiB
C

/*
* Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Alan Hourihane not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Alan Hourihane makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Author: Alan Hourihane, alanh@fairlite.demon.co.uk
*
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include "xf86.h"
#include "xf86Config.h"
#include "xf86_OSlib.h"
#include "xf86Priv.h"
#define IN_XSERVER
#include "Configint.h"
#include "xf86DDC.h"
#if (defined(__sparc__) || defined(__sparc))
#include "xf86Bus.h"
#include "xf86Sbus.h"
#endif
typedef struct _DevToConfig {
GDevRec GDev;
struct pci_device * pVideo;
#if (defined(__sparc__) || defined(__sparc))
sbusDevicePtr sVideo;
#endif
int iDriver;
} DevToConfigRec, *DevToConfigPtr;
static DevToConfigPtr DevToConfig = NULL;
static int nDevToConfig = 0, CurrentDriver;
xf86MonPtr ConfiguredMonitor;
Bool xf86DoConfigurePass1 = TRUE;
static Bool foundMouse = FALSE;
#if defined(__SCO__)
static char *DFLT_MOUSE_PROTO = "OSMouse";
#elif defined(__UNIXWARE__)
static char *DFLT_MOUSE_PROTO = "OSMouse";
static char *DFLT_MOUSE_DEV = "/dev/mouse";
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
static char *DFLT_MOUSE_PROTO = "auto";
#elif defined(linux)
static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
static char DFLT_MOUSE_PROTO[] = "auto";
#else
static char *DFLT_MOUSE_DEV = "/dev/mouse";
static char *DFLT_MOUSE_PROTO = "auto";
#endif
static Bool
bus_pci_configure(void *busData)
{
int i;
struct pci_device * pVideo = NULL;
pVideo = (struct pci_device *) busData;
for (i = 0; i < nDevToConfig; i++)
if (DevToConfig[i].pVideo &&
(DevToConfig[i].pVideo->domain == pVideo->domain) &&
(DevToConfig[i].pVideo->bus == pVideo->bus) &&
(DevToConfig[i].pVideo->dev == pVideo->dev) &&
(DevToConfig[i].pVideo->func == pVideo->func))
return 0;
return 1;
}
static Bool
bus_sbus_configure(void *busData)
{
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
int i;
for (i = 0; i < nDevToConfig; i++)
if (DevToConfig[i].sVideo &&
DevToConfig[i].sVideo->fbNum == ((sbusDevicePtr) busData)->fbNum)
return 0;
#endif
return 1;
}
static void
bus_pci_newdev_configure(void *busData, int i, int *chipset)
{
char busnum[8];
struct pci_device * pVideo = NULL;
pVideo = (struct pci_device *) busData;
DevToConfig[i].pVideo = pVideo;
DevToConfig[i].GDev.busID = xnfalloc(16);
xf86FormatPciBusNumber(pVideo->bus, busnum);
snprintf(DevToConfig[i].GDev.busID, 16, "PCI:%s:%d:%d",
busnum, pVideo->dev, pVideo->func);
DevToConfig[i].GDev.chipID = pVideo->device_id;
DevToConfig[i].GDev.chipRev = pVideo->revision;
if (*chipset < 0) {
*chipset = (pVideo->vendor_id << 16) | pVideo->device_id;
}
}
static void
bus_sbus_newdev_configure(void *busData, int i)
{
#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
char *promPath = NULL;
size_t len;
DevToConfig[i].sVideo = (sbusDevicePtr) busData;
DevToConfig[i].GDev.identifier = DevToConfig[i].sVideo->descr;
if (sparcPromInit() >= 0) {
promPath = sparcPromNode2Pathname(&DevToConfig[i].sVideo->node);
sparcPromClose();
}
if (promPath) {
len = strlen(promPath) + 6;
DevToConfig[i].GDev.busID = xnfalloc(len);
snprintf(DevToConfig[i].GDev.busID, len, "SBUS:%s", promPath);
free(promPath);
} else {
NewDevice.GDev.busID = xnfalloc(12);
snprintf(DevToConfig[i].GDev.busID, 12, "SBUS:fb%d", NewDevice.sVideo->fbNum);
}
#endif
}
/*
* This is called by the driver, either through xf86Match???Instances() or
* directly. We allocate a GDevRec and fill it in as much as we can, letting
* the caller fill in the rest and/or change it as it sees fit.
*/
GDevPtr
xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
{
int ret, i, j;
if (!xf86DoConfigure || !xf86DoConfigurePass1)
return NULL;
/* Check for duplicates */
switch (bus) {
case BUS_PCI:
ret = bus_pci_configure(busData);
break;
case BUS_SBUS:
ret = bus_sbus_configure(busData);
break;
default:
return NULL;
}
if (ret == 0)
goto out;
/* Allocate new structure occurrence */
i = nDevToConfig++;
DevToConfig =
xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
DevToConfig[i].GDev.chipID =
DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
DevToConfig[i].iDriver = CurrentDriver;
/* Fill in what we know, converting the driver name to lower case */
DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++);
switch (bus) {
case BUS_PCI:
bus_pci_newdev_configure(busData, i, &chipset);
break;
case BUS_SBUS:
bus_sbus_newdev_configure(busData, i);
break;
default:
break;
}
/* Get driver's available options */
if (xf86DriverList[CurrentDriver]->AvailableOptions)
DevToConfig[i].GDev.options = (OptionInfoPtr)
(*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
bus);
return &DevToConfig[i].GDev;
out:
return NULL;
}
static XF86ConfInputPtr
configureInputSection (void)
{
XF86ConfInputPtr mouse = NULL;
parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
ptr->inp_identifier = "Keyboard0";
ptr->inp_driver = "kbd";
ptr->list.next = NULL;
/* Crude mechanism to auto-detect mouse (os dependent) */
{
int fd;
#ifdef WSCONS_SUPPORT
fd = open("/dev/wsmouse", 0);
if (fd >= 0) {
DFLT_MOUSE_DEV = "/dev/wsmouse";
DFLT_MOUSE_PROTO = "wsmouse";
close(fd);
} else {
ErrorF("cannot open /dev/wsmouse\n");
}
#endif
#ifndef __SCO__
fd = open(DFLT_MOUSE_DEV, 0);
if (fd != -1) {
foundMouse = TRUE;
close(fd);
}
#else
foundMouse = TRUE;
#endif
}
mouse = calloc(1, sizeof(XF86ConfInputRec));
mouse->inp_identifier = "Mouse0";
mouse->inp_driver = "mouse";
mouse->inp_option_lst =
xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"),
strdup(DFLT_MOUSE_PROTO));
#ifndef __SCO__
mouse->inp_option_lst =
xf86addNewOption(mouse->inp_option_lst, strdup("Device"),
strdup(DFLT_MOUSE_DEV));
#endif
mouse->inp_option_lst =
xf86addNewOption(mouse->inp_option_lst, strdup("ZAxisMapping"),
strdup("4 5 6 7"));
ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
return ptr;
}
static XF86ConfScreenPtr
configureScreenSection (int screennum)
{
int i;
int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
ptr->scrn_identifier = malloc(18);
snprintf(ptr->scrn_identifier, 18, "Screen%d", screennum);
ptr->scrn_monitor_str = malloc(19);
snprintf(ptr->scrn_monitor_str, 19, "Monitor%d", screennum);
ptr->scrn_device_str = malloc(16);
snprintf(ptr->scrn_device_str, 16, "Card%d", screennum);
for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
{
XF86ConfDisplayPtr display;
display = calloc(1, sizeof(XF86ConfDisplayRec));
display->disp_depth = depths[i];
display->disp_black.red = display->disp_white.red = -1;
display->disp_black.green = display->disp_white.green = -1;
display->disp_black.blue = display->disp_white.blue = -1;
ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
(glp)ptr->scrn_display_lst, (glp)display);
}
return ptr;
}
static const char*
optionTypeToString(OptionValueType type)
{
switch (type) {
case OPTV_NONE:
return "";
case OPTV_INTEGER:
return "<i>";
case OPTV_STRING:
return "<str>";
case OPTV_ANYSTR:
return "[<str>]";
case OPTV_REAL:
return "<f>";
case OPTV_BOOLEAN:
return "[<bool>]";
case OPTV_FREQ:
return "<freq>";
case OPTV_PERCENT:
return "<percent>";
default:
return "";
}
}
static XF86ConfDevicePtr
configureDeviceSection (int screennum)
{
char identifier[16];
OptionInfoPtr p;
int i = 0;
parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
/* Move device info to parser structure */
snprintf(identifier, sizeof(identifier), "Card%d", screennum);
ptr->dev_identifier = strdup(identifier);
ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
ptr->dev_busid = DevToConfig[screennum].GDev.busID;
ptr->dev_driver = DevToConfig[screennum].GDev.driver;
ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++)
ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
ptr->dev_clocks = i;
ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
ptr->dev_irq = DevToConfig[screennum].GDev.irq;
/* Make sure older drivers don't segv */
if (DevToConfig[screennum].GDev.options) {
/* Fill in the available driver options for people to use */
const char *descrip =
" ### Available Driver options are:-\n"
" ### Values: <i>: integer, <f>: float, "
"<bool>: \"True\"/\"False\",\n"
" ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n"
" ### <percent>: \"<f>%\"\n"
" ### [arg]: arg optional\n";
ptr->dev_comment = strdup(descrip);
if (ptr->dev_comment) {
for (p = DevToConfig[screennum].GDev.options;
p->name != NULL; p++) {
char *p_e;
const char *prefix = " #Option ";
const char *middle = " \t# ";
const char *suffix = "\n";
const char *opttype = optionTypeToString(p->type);
char *optname;
int len = strlen(ptr->dev_comment) + strlen(prefix) +
strlen(middle) + strlen(suffix) + 1;
int optlen = strlen(p->name) + 2 + 1;
optname = malloc(optlen);
if (!optname)
break;
snprintf(optname, optlen, "\"%s\"", p->name);
len += max(20, strlen(optname));
len += strlen(opttype);
ptr->dev_comment = realloc(ptr->dev_comment, len);
if (!ptr->dev_comment)
break;
p_e = ptr->dev_comment + strlen(ptr->dev_comment);
snprintf(p_e, len - (ptr->dev_comment - p_e),
"%s%-20s%s%s%s", prefix, optname, middle,
opttype, suffix);
free(optname);
}
}
}
return ptr;
}
static XF86ConfLayoutPtr
configureLayoutSection (void)
{
int scrnum = 0;
parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
ptr->lay_identifier = "X.org Configured";
{
XF86ConfInputrefPtr iptr;
iptr = malloc (sizeof (XF86ConfInputrefRec));
iptr->list.next = NULL;
iptr->iref_option_lst = NULL;
iptr->iref_inputdev_str = "Mouse0";
iptr->iref_option_lst =
xf86addNewOption (iptr->iref_option_lst, strdup("CorePointer"), NULL);
ptr->lay_input_lst = (XF86ConfInputrefPtr)
xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
}
{
XF86ConfInputrefPtr iptr;
iptr = malloc (sizeof (XF86ConfInputrefRec));
iptr->list.next = NULL;
iptr->iref_option_lst = NULL;
iptr->iref_inputdev_str = "Keyboard0";
iptr->iref_option_lst =
xf86addNewOption (iptr->iref_option_lst, strdup("CoreKeyboard"), NULL);
ptr->lay_input_lst = (XF86ConfInputrefPtr)
xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
}
for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
XF86ConfAdjacencyPtr aptr;
aptr = malloc (sizeof (XF86ConfAdjacencyRec));
aptr->list.next = NULL;
aptr->adj_x = 0;
aptr->adj_y = 0;
aptr->adj_scrnum = scrnum;
aptr->adj_screen_str = xnfalloc(18);
snprintf(aptr->adj_screen_str, 18, "Screen%d", scrnum);
if (scrnum == 0) {
aptr->adj_where = CONF_ADJ_ABSOLUTE;
aptr->adj_refscreen = NULL;
}
else {
aptr->adj_where = CONF_ADJ_RIGHTOF;
aptr->adj_refscreen = xnfalloc(18);
snprintf(aptr->adj_refscreen, 18, "Screen%d", scrnum - 1);
}
ptr->lay_adjacency_lst =
(XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
(glp)aptr);
}
return ptr;
}
static XF86ConfFlagsPtr
configureFlagsSection (void)
{
parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
return ptr;
}
static XF86ConfModulePtr
configureModuleSection (void)
{
char **elist, **el;
/* Find the list of extension & font modules. */
const char *esubdirs[] = {
"extensions",
"fonts",
NULL
};
parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
elist = LoaderListDirs(esubdirs, NULL);
if (elist) {
for (el = elist; *el; el++) {
XF86LoadPtr module;
module = calloc(1, sizeof(XF86LoadRec));
module->load_name = *el;
ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
(glp)ptr->mod_load_lst, (glp)module);
}
free(elist);
}
return ptr;
}
static XF86ConfFilesPtr
configureFilesSection (void)
{
parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
if (xf86ModulePath)
ptr->file_modulepath = strdup(xf86ModulePath);
if (defaultFontPath)
ptr->file_fontpath = strdup(defaultFontPath);
return ptr;
}
static XF86ConfMonitorPtr
configureMonitorSection (int screennum)
{
parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
ptr->mon_identifier = malloc(19);
snprintf(ptr->mon_identifier, 19, "Monitor%d", screennum);
ptr->mon_vendor = strdup("Monitor Vendor");
ptr->mon_modelname = strdup("Monitor Model");
return ptr;
}
/* Initialize Configure Monitor from Detailed Timing Block */
static void handle_detailed_input(struct detailed_monitor_section *det_mon,
void *data)
{
XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
switch (det_mon->type) {
case DS_NAME:
ptr->mon_modelname = realloc(ptr->mon_modelname,
strlen((char*)(det_mon->section.name)) +
1);
strcpy(ptr->mon_modelname,
(char*)(det_mon->section.name));
break;
case DS_RANGES:
ptr->mon_hsync[ptr->mon_n_hsync].lo =
det_mon->section.ranges.min_h;
ptr->mon_hsync[ptr->mon_n_hsync].hi =
det_mon->section.ranges.max_h;
ptr->mon_n_vrefresh = 1;
ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
det_mon->section.ranges.min_v;
ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
det_mon->section.ranges.max_v;
ptr->mon_n_hsync++;
default:
break;
}
}
static XF86ConfMonitorPtr
configureDDCMonitorSection (int screennum)
{
int len, mon_width, mon_height;
#define displaySizeMaxLen 80
char displaySize_string[displaySizeMaxLen];
int displaySizeLen;
parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
ptr->mon_identifier = malloc(19);
snprintf(ptr->mon_identifier, 19, "Monitor%d", screennum);
ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
ptr->mon_modelname = malloc(12);
snprintf(ptr->mon_modelname, 12, "%x", ConfiguredMonitor->vendor.prod_id);
/* features in centimetres, we want millimetres */
mon_width = 10 * ConfiguredMonitor->features.hsize ;
mon_height = 10 * ConfiguredMonitor->features.vsize ;
#ifdef CONFIGURE_DISPLAYSIZE
ptr->mon_width = mon_width;
ptr->mon_height = mon_height;
#else
if (mon_width && mon_height) {
/* when values available add DisplaySize option AS A COMMENT */
displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
"\t#DisplaySize\t%5d %5d\t# mm\n",
mon_width, mon_height);
if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
if (ptr->mon_comment) {
len = strlen(ptr->mon_comment);
} else {
len = 0;
}
if ((ptr->mon_comment =
realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
strcpy(ptr->mon_comment + len, displaySize_string);
}
}
}
#endif /* def CONFIGURE_DISPLAYSIZE */
xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
ptr);
if (ConfiguredMonitor->features.dpms) {
ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, strdup("DPMS"), NULL);
}
return ptr;
}
#if !defined(PATH_MAX)
# define PATH_MAX 1024
#endif
void
DoConfigure(void)
{
int i,j, screennum = -1;
char *home = NULL;
char filename[PATH_MAX];
char *addslash = "";
XF86ConfigPtr xf86config = NULL;
char **vlist, **vl;
int *dev2screen;
vlist = xf86DriverlistFromCompile();
if (!vlist) {
ErrorF("Missing output drivers. Configuration failed.\n");
goto bail;
}
ErrorF("List of video drivers:\n");
for (vl = vlist; *vl; vl++)
ErrorF("\t%s\n", *vl);
/* Load all the drivers that were found. */
xf86LoadModules(vlist, NULL);
free(vlist);
for (i = 0; i < xf86NumDrivers; i++) {
xorgHWFlags flags;
if (!xf86DriverList[i]->driverFunc
|| !xf86DriverList[i]->driverFunc(NULL,
GET_REQUIRED_HW_INTERFACES,
&flags)
|| NEED_IO_ENABLED(flags)) {
xorgHWAccess = TRUE;
break;
}
}
/* Enable full I/O access */
if (xorgHWAccess) {
if(!xf86EnableIO())
/* oops, we have failed */
xorgHWAccess = FALSE;
}
/* Create XF86Config file structure */
xf86config = calloc(1, sizeof(XF86ConfigRec));
/* Call all of the probe functions, reporting the results. */
for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
xorgHWFlags flags;
Bool found_screen;
DriverRec * const drv = xf86DriverList[CurrentDriver];
if (!xorgHWAccess) {
if (!drv->driverFunc
|| !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
|| NEED_IO_ENABLED(flags))
continue;
}
found_screen = xf86CallDriverProbe( drv, TRUE );
if ( found_screen && drv->Identify ) {
(*drv->Identify)(0);
}
}
if (nDevToConfig <= 0) {
ErrorF("No devices to configure. Configuration failed.\n");
goto bail;
}
/* Add device, monitor and screen sections for detected devices */
for (screennum = 0; screennum < nDevToConfig; screennum++) {
XF86ConfDevicePtr DevicePtr;
XF86ConfMonitorPtr MonitorPtr;
XF86ConfScreenPtr ScreenPtr;
DevicePtr = configureDeviceSection(screennum);
xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
(glp)xf86config->conf_device_lst, (glp)DevicePtr);
MonitorPtr = configureMonitorSection(screennum);
xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
(glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
ScreenPtr = configureScreenSection(screennum);
xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
(glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
}
xf86config->conf_files = configureFilesSection();
xf86config->conf_modules = configureModuleSection();
xf86config->conf_flags = configureFlagsSection();
xf86config->conf_videoadaptor_lst = NULL;
xf86config->conf_modes_lst = NULL;
xf86config->conf_vendor_lst = NULL;
xf86config->conf_dri = NULL;
xf86config->conf_input_lst = configureInputSection();
xf86config->conf_layout_lst = configureLayoutSection();
home = getenv("HOME");
if ((home == NULL) || (home[0] == '\0')) {
home = "/";
} else {
/* Determine if trailing slash is present or needed */
int l = strlen(home);
if (home[l-1] != '/') {
addslash = "/";
}
}
snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
home, addslash);
if (xf86writeConfigFile(filename, xf86config) == 0) {
xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
filename, strerror(errno));
goto bail;
}
xf86DoConfigurePass1 = FALSE;
/* Try to get DDC information filled in */
xf86ConfigFile = filename;
if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
goto bail;
}
xf86DoConfigurePass1 = FALSE;
dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
{
Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
for (screennum = 0; screennum < nDevToConfig; screennum++) {
int k,l,n,oldNumScreens;
i = DevToConfig[screennum].iDriver;
if (driverProbed[i]) continue;
driverProbed[i] = TRUE;
oldNumScreens = xf86NumScreens;
xf86CallDriverProbe( xf86DriverList[i], FALSE );
/* reorder */
k = screennum > 0 ? screennum : 1;
for (l = oldNumScreens; l < xf86NumScreens; l++) {
/* is screen primary? */
Bool primary = FALSE;
for (n = 0; n<xf86Screens[l]->numEntities; n++) {
if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
dev2screen[0] = l;
primary = TRUE;
break;
}
}
if (primary) continue;
/* not primary: assign it to next device of same driver */
/*
* NOTE: we assume that devices in DevToConfig
* and xf86Screens[] have the same order except
* for the primary device which always comes first.
*/
for (; k < nDevToConfig; k++) {
if (DevToConfig[k].iDriver == i) {
dev2screen[k++] = l;
break;
}
}
}
}
free(driverProbed);
}
if (nDevToConfig != xf86NumScreens) {
ErrorF("Number of created screens does not match number of detected"
" devices.\n Configuration failed.\n");
goto bail;
}
xf86PostProbe();
for (j = 0; j < xf86NumScreens; j++) {
xf86Screens[j]->scrnIndex = j;
}
xf86freeMonitorList(xf86config->conf_monitor_lst);
xf86config->conf_monitor_lst = NULL;
xf86freeScreenList(xf86config->conf_screen_lst);
xf86config->conf_screen_lst = NULL;
for (j = 0; j < xf86NumScreens; j++) {
XF86ConfMonitorPtr MonitorPtr;
XF86ConfScreenPtr ScreenPtr;
ConfiguredMonitor = NULL;
if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
PROBE_DETECT) &&
ConfiguredMonitor) {
MonitorPtr = configureDDCMonitorSection(j);
} else {
MonitorPtr = configureMonitorSection(j);
}
ScreenPtr = configureScreenSection(j);
xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
(glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
(glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
}
if (xf86writeConfigFile(filename, xf86config) == 0) {
xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
filename, strerror(errno));
goto bail;
}
ErrorF("\n");
#ifdef __SCO__
ErrorF("\n"__XSERVERNAME__
" is using the kernel event driver to access the mouse.\n"
"If you wish to use the internal "__XSERVERNAME__
" mouse drivers, please\n"
"edit the file and correct the Device.\n");
#else /* !__SCO__ */
if (!foundMouse) {
ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
"Edit the file and correct the Device.\n");
} else {
ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
"Please check your config if the mouse is still not\n"
"operational, as by default "__XSERVERNAME__
" tries to autodetect\n"
"the protocol.\n",DFLT_MOUSE_DEV);
}
#endif /* !__SCO__ */
if (xf86NumScreens > 1) {
ErrorF("\n"__XSERVERNAME__
" has configured a multihead system, please check your config.\n");
}
ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
ErrorF("To test the server, run 'X -config %s'\n\n", filename);
bail:
CloseWellKnownConnections();
OsCleanup(TRUE);
AbortDDX();
fflush(stderr);
exit(0);
}