e6b9cc79c2
Fixed FreeType module to build with FreeType versions older than 2.1.7. Fixed typo. Added vtSema to protect call of driver DPMS function. removed unneeded variable Modified RandR driver hook to reduce the number of function calls to one. Function is sufficiently generic to be extended in the future.
1014 lines
28 KiB
C
1014 lines
28 KiB
C
/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Configure.c,v 3.80 2003/10/08 14:58:27 dawes Exp $ */
|
|
/*
|
|
* 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
|
|
*
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include "X.h"
|
|
#include "Xmd.h"
|
|
#include "os.h"
|
|
#ifdef XFree86LOADER
|
|
#include "loaderProcs.h"
|
|
#endif
|
|
#include "xf86.h"
|
|
#include "xf86Config.h"
|
|
#include "xf86Priv.h"
|
|
#include "xf86PciData.h"
|
|
#define IN_XSERVER
|
|
#include "xf86Parser.h"
|
|
#include "xf86tokens.h"
|
|
#include "Configint.h"
|
|
#include "vbe.h"
|
|
#include "xf86DDC.h"
|
|
#if defined(__sparc__) && !defined(__OpenBSD__)
|
|
#include "xf86Bus.h"
|
|
#include "xf86Sbus.h"
|
|
#endif
|
|
#include "globals.h"
|
|
|
|
typedef struct _DevToConfig {
|
|
GDevRec GDev;
|
|
pciVideoPtr pVideo;
|
|
#if defined(__sparc__) && !defined(__OpenBSD__)
|
|
sbusDevicePtr sVideo;
|
|
#endif
|
|
int iDriver;
|
|
} DevToConfigRec, *DevToConfigPtr;
|
|
|
|
static DevToConfigPtr DevToConfig = NULL;
|
|
static int nDevToConfig = 0, CurrentDriver;
|
|
|
|
xf86MonPtr ConfiguredMonitor;
|
|
Bool xf86DoConfigurePass1 = TRUE;
|
|
Bool foundMouse = FALSE;
|
|
|
|
#if defined(__UNIXOS2__)
|
|
#define DFLT_MOUSE_DEV "mouse$"
|
|
#define DFLT_MOUSE_PROTO "OS2Mouse"
|
|
#elif defined(SCO)
|
|
static char *DFLT_MOUSE_PROTO = "OSMouse";
|
|
#elif defined(QNX4)
|
|
static char *DFLT_MOUSE_PROTO = "OSMouse";
|
|
static char *DFLT_MOUSE_DEV = "/dev/mouse";
|
|
#elif defined(__QNXNTO__)
|
|
static char *DFLT_MOUSE_PROTO = "OSMouse";
|
|
static char *DFLT_MOUSE_DEV = "/dev/devi/mouse0";
|
|
#elif defined(__FreeBSD__)
|
|
static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
|
|
static char *DFLT_MOUSE_PROTO = "auto";
|
|
#else
|
|
static char *DFLT_MOUSE_DEV = "/dev/mouse";
|
|
static char *DFLT_MOUSE_PROTO = "auto";
|
|
#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 i, j;
|
|
pciVideoPtr pVideo = NULL;
|
|
Bool isPrimary = FALSE;
|
|
|
|
if (xf86DoProbe || !xf86DoConfigure || !xf86DoConfigurePass1)
|
|
return NULL;
|
|
|
|
/* Check for duplicates */
|
|
switch (bus) {
|
|
case BUS_PCI:
|
|
pVideo = (pciVideoPtr) busData;
|
|
for (i = 0; i < nDevToConfig; i++)
|
|
if (DevToConfig[i].pVideo &&
|
|
(DevToConfig[i].pVideo->bus == pVideo->bus) &&
|
|
(DevToConfig[i].pVideo->device == pVideo->device) &&
|
|
(DevToConfig[i].pVideo->func == pVideo->func))
|
|
return NULL;
|
|
isPrimary = xf86IsPrimaryPci(pVideo);
|
|
break;
|
|
case BUS_ISA:
|
|
/*
|
|
* This needs to be revisited as it doesn't allow for non-PCI
|
|
* multihead.
|
|
*/
|
|
if (!xf86IsPrimaryIsa())
|
|
return NULL;
|
|
isPrimary = TRUE;
|
|
for (i = 0; i < nDevToConfig; i++)
|
|
if (!DevToConfig[i].pVideo)
|
|
return NULL;
|
|
break;
|
|
#if defined(__sparc__) && !defined(__OpenBSD__)
|
|
case BUS_SBUS:
|
|
for (i = 0; i < nDevToConfig; i++)
|
|
if (DevToConfig[i].sVideo &&
|
|
DevToConfig[i].sVideo->fbNum == ((sbusDevicePtr) busData)->fbNum)
|
|
return NULL;
|
|
break;
|
|
#endif
|
|
default:
|
|
return NULL;
|
|
}
|
|
|
|
/* Allocate new structure occurrence */
|
|
i = nDevToConfig++;
|
|
DevToConfig =
|
|
xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
|
|
#if 1 /* Doesn't work when a driver detects more than one adapter */
|
|
if ((i > 0) && isPrimary) {
|
|
memmove(DevToConfig + 1,DevToConfig,
|
|
(nDevToConfig - 1) * sizeof(DevToConfigRec));
|
|
i = 0;
|
|
}
|
|
#endif
|
|
memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
|
|
|
|
# define NewDevice DevToConfig[i]
|
|
|
|
NewDevice.GDev.chipID = NewDevice.GDev.chipRev = NewDevice.GDev.irq = -1;
|
|
|
|
NewDevice.iDriver = CurrentDriver;
|
|
|
|
/* Fill in what we know, converting the driver name to lower case */
|
|
NewDevice.GDev.driver = xnfalloc(strlen(driver) + 1);
|
|
for (j = 0; (NewDevice.GDev.driver[j] = tolower(driver[j])); j++);
|
|
|
|
switch (bus) {
|
|
case BUS_PCI: {
|
|
const char *VendorName;
|
|
const char *CardName;
|
|
char busnum[8];
|
|
|
|
NewDevice.pVideo = pVideo;
|
|
xf86FindPciNamesByDevice(pVideo->vendor, pVideo->chipType,
|
|
NOVENDOR, NOSUBSYS,
|
|
&VendorName, &CardName, NULL, NULL);
|
|
|
|
if (!VendorName) {
|
|
VendorName = xnfalloc(15);
|
|
sprintf((char*)VendorName, "Unknown Vendor");
|
|
}
|
|
|
|
if (!CardName) {
|
|
CardName = xnfalloc(14);
|
|
sprintf((char*)CardName, "Unknown Board");
|
|
}
|
|
|
|
NewDevice.GDev.identifier =
|
|
xnfalloc(strlen(VendorName) + strlen(CardName) + 2);
|
|
sprintf(NewDevice.GDev.identifier, "%s %s", VendorName, CardName);
|
|
|
|
NewDevice.GDev.vendor = (char *)VendorName;
|
|
NewDevice.GDev.board = (char *)CardName;
|
|
|
|
NewDevice.GDev.busID = xnfalloc(16);
|
|
xf86FormatPciBusNumber(pVideo->bus, busnum);
|
|
sprintf(NewDevice.GDev.busID, "PCI:%s:%d:%d",
|
|
busnum, pVideo->device, pVideo->func);
|
|
|
|
NewDevice.GDev.chipID = pVideo->chipType;
|
|
NewDevice.GDev.chipRev = pVideo->chipRev;
|
|
|
|
if (chipset < 0)
|
|
chipset = (pVideo->vendor << 16) | pVideo->chipType;
|
|
}
|
|
break;
|
|
case BUS_ISA:
|
|
NewDevice.GDev.identifier = "ISA Adapter";
|
|
NewDevice.GDev.busID = "ISA";
|
|
break;
|
|
#if defined(__sparc__) && !defined(__OpenBSD__)
|
|
case BUS_SBUS: {
|
|
char *promPath = NULL;
|
|
NewDevice.sVideo = (sbusDevicePtr) busData;
|
|
NewDevice.GDev.identifier = NewDevice.sVideo->descr;
|
|
if (sparcPromInit() >= 0) {
|
|
promPath = sparcPromNode2Pathname(&NewDevice.sVideo->node);
|
|
sparcPromClose();
|
|
}
|
|
if (promPath) {
|
|
NewDevice.GDev.busID = xnfalloc(strlen(promPath) + 6);
|
|
sprintf(NewDevice.GDev.busID, "SBUS:%s", promPath);
|
|
xfree(promPath);
|
|
} else {
|
|
NewDevice.GDev.busID = xnfalloc(12);
|
|
sprintf(NewDevice.GDev.busID, "SBUS:fb%d", NewDevice.sVideo->fbNum);
|
|
}
|
|
}
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* Get driver's available options */
|
|
if (xf86DriverList[CurrentDriver]->AvailableOptions)
|
|
NewDevice.GDev.options = (OptionInfoPtr)
|
|
(*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
|
|
bus);
|
|
|
|
return &NewDevice.GDev;
|
|
|
|
# undef NewDevice
|
|
}
|
|
|
|
/*
|
|
* Backwards compatibility
|
|
*/
|
|
GDevPtr
|
|
xf86AddDeviceToConfigure(const char *driver, pciVideoPtr pVideo, int chipset)
|
|
{
|
|
return xf86AddBusDeviceToConfigure(driver, pVideo ? BUS_PCI : BUS_ISA,
|
|
pVideo, chipset);
|
|
}
|
|
|
|
static XF86ConfInputPtr
|
|
configureInputSection (void)
|
|
{
|
|
XF86ConfInputPtr mouse = NULL;
|
|
parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
|
|
|
|
ptr->inp_identifier = "Keyboard0";
|
|
ptr->inp_driver = "keyboard";
|
|
ptr->list.next = NULL;
|
|
|
|
/* Crude mechanism to auto-detect mouse (os dependent) */
|
|
{
|
|
int fd;
|
|
#if 0 && defined linux
|
|
/* Our autodetection code can do a better job */
|
|
int len;
|
|
char path[32];
|
|
|
|
if ((len = readlink(DFLT_MOUSE_DEV, path, sizeof(path) - 1)) > 0) {
|
|
path[len] = '\0';
|
|
if (strstr(path, "psaux") != NULL)
|
|
DFLT_MOUSE_PROTO = "PS/2";
|
|
}
|
|
#endif
|
|
#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 = xf86confmalloc(sizeof(XF86ConfInputRec));
|
|
memset((XF86ConfInputPtr)mouse,0,sizeof(XF86ConfInputRec));
|
|
mouse->inp_identifier = "Mouse0";
|
|
mouse->inp_driver = "mouse";
|
|
mouse->inp_option_lst =
|
|
xf86addNewOption(mouse->inp_option_lst, "Protocol", DFLT_MOUSE_PROTO);
|
|
#ifndef SCO
|
|
mouse->inp_option_lst =
|
|
xf86addNewOption(mouse->inp_option_lst, "Device", DFLT_MOUSE_DEV);
|
|
#endif
|
|
ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
|
|
return ptr;
|
|
}
|
|
|
|
static XF86ConfDRIPtr
|
|
configureDRISection (void)
|
|
{
|
|
#ifdef NOTYET
|
|
parsePrologue (XF86ConfDRIPtr, XF86ConfDRIRec)
|
|
|
|
return ptr;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
static XF86ConfVendorPtr
|
|
configureVendorSection (void)
|
|
{
|
|
parsePrologue (XF86ConfVendorPtr, XF86ConfVendorRec)
|
|
|
|
return NULL;
|
|
#if 0
|
|
return ptr;
|
|
#endif
|
|
}
|
|
|
|
static XF86ConfScreenPtr
|
|
configureScreenSection (int screennum)
|
|
{
|
|
int i;
|
|
int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
|
|
parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
|
|
|
|
ptr->scrn_identifier = xf86confmalloc(18);
|
|
sprintf(ptr->scrn_identifier, "Screen%d", screennum);
|
|
ptr->scrn_monitor_str = xf86confmalloc(19);
|
|
sprintf(ptr->scrn_monitor_str, "Monitor%d", screennum);
|
|
ptr->scrn_device_str = xf86confmalloc(16);
|
|
sprintf(ptr->scrn_device_str, "Card%d", screennum);
|
|
|
|
for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
|
|
{
|
|
XF86ConfDisplayPtr display;
|
|
|
|
display = xf86confmalloc(sizeof(XF86ConfDisplayRec));
|
|
memset((XF86ConfDisplayPtr)display,0,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*
|
|
optionTypeToSting(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>";
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
static XF86ConfDevicePtr
|
|
configureDeviceSection (int screennum)
|
|
{
|
|
char identifier[16];
|
|
OptionInfoPtr p;
|
|
int i = 0;
|
|
#ifdef DO_FBDEV_PROBE
|
|
Bool foundFBDEV = FALSE;
|
|
#endif
|
|
parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
|
|
|
|
/* Move device info to parser structure */
|
|
sprintf(identifier, "Card%d", screennum);
|
|
ptr->dev_identifier = strdup(identifier);
|
|
/* ptr->dev_identifier = DevToConfig[screennum].GDev.identifier;*/
|
|
ptr->dev_vendor = DevToConfig[screennum].GDev.vendor;
|
|
ptr->dev_board = DevToConfig[screennum].GDev.board;
|
|
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"
|
|
" ### [arg]: arg optional\n";
|
|
ptr->dev_comment = xstrdup(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 = optionTypeToSting(p->type);
|
|
char *optname;
|
|
int len = strlen(ptr->dev_comment) + strlen(prefix) +
|
|
strlen(middle) + strlen(suffix) + 1;
|
|
|
|
optname = xalloc(strlen(p->name) + 2 + 1);
|
|
if (!optname)
|
|
break;
|
|
sprintf(optname, "\"%s\"", p->name);
|
|
|
|
len += max(20, strlen(optname));
|
|
len += strlen(opttype);
|
|
|
|
ptr->dev_comment = xrealloc(ptr->dev_comment, len);
|
|
if (!ptr->dev_comment)
|
|
break;
|
|
p_e = ptr->dev_comment + strlen(ptr->dev_comment);
|
|
sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
|
|
opttype, suffix);
|
|
xfree(optname);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef DO_FBDEV_PROBE
|
|
/* Crude mechanism to auto-detect fbdev (os dependent) */
|
|
/* Skip it for now. Options list it anyway, and we can't
|
|
* determine which screen/driver this belongs too anyway. */
|
|
{
|
|
int fd;
|
|
|
|
fd = open("/dev/fb0", 0);
|
|
if (fd != -1) {
|
|
foundFBDEV = TRUE;
|
|
close(fd);
|
|
}
|
|
}
|
|
|
|
if (foundFBDEV) {
|
|
XF86OptionPtr fbdev;
|
|
|
|
fbdev = xf86confmalloc(sizeof(XF86OptionRec));
|
|
memset((XF86OptionPtr)fbdev,0,sizeof(XF86OptionRec));
|
|
fbdev->opt_name = "UseFBDev";
|
|
fbdev->opt_val = "ON";
|
|
ptr->dev_option_lst = (XF86OptionPtr)xf86addListItem(
|
|
(glp)ptr->dev_option_lst, (glp)fbdev);
|
|
}
|
|
#endif
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static XF86ConfLayoutPtr
|
|
configureLayoutSection (void)
|
|
{
|
|
int scrnum = 0;
|
|
parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
|
|
|
|
ptr->lay_identifier = "X.org Configured";
|
|
|
|
{
|
|
XF86ConfInputrefPtr iptr;
|
|
|
|
iptr = xf86confmalloc (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, "CorePointer", NULL);
|
|
ptr->lay_input_lst = (XF86ConfInputrefPtr)
|
|
xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
|
|
}
|
|
|
|
{
|
|
XF86ConfInputrefPtr iptr;
|
|
|
|
iptr = xf86confmalloc (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, "CoreKeyboard", NULL);
|
|
ptr->lay_input_lst = (XF86ConfInputrefPtr)
|
|
xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
|
|
}
|
|
|
|
for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
|
|
XF86ConfAdjacencyPtr aptr;
|
|
|
|
aptr = xf86confmalloc (sizeof (XF86ConfAdjacencyRec));
|
|
aptr->list.next = NULL;
|
|
aptr->adj_x = 0;
|
|
aptr->adj_y = 0;
|
|
aptr->adj_scrnum = scrnum;
|
|
aptr->adj_screen_str = xnfalloc(18);
|
|
sprintf(aptr->adj_screen_str, "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);
|
|
sprintf(aptr->adj_refscreen, "Screen%d", scrnum - 1);
|
|
}
|
|
ptr->lay_adjacency_lst =
|
|
(XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
|
|
(glp)aptr);
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static XF86ConfModesPtr
|
|
configureModesSection (void)
|
|
{
|
|
#ifdef NOTYET
|
|
parsePrologue (XF86ConfModesPtr, XF86ConfModesRec)
|
|
|
|
return ptr;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
static XF86ConfVideoAdaptorPtr
|
|
configureVideoAdaptorSection (void)
|
|
{
|
|
parsePrologue (XF86ConfVideoAdaptorPtr, XF86ConfVideoAdaptorRec)
|
|
|
|
return NULL;
|
|
#if 0
|
|
return ptr;
|
|
#endif
|
|
}
|
|
|
|
static XF86ConfFlagsPtr
|
|
configureFlagsSection (void)
|
|
{
|
|
parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static XF86ConfModulePtr
|
|
configureModuleSection (void)
|
|
{
|
|
#ifdef XFree86LOADER
|
|
char **elist, **el;
|
|
/* Find the list of extension modules. */
|
|
const char *esubdirs[] = {
|
|
"extensions",
|
|
NULL
|
|
};
|
|
const char *fsubdirs[] = {
|
|
"fonts",
|
|
NULL
|
|
};
|
|
#endif
|
|
parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
|
|
|
|
#ifdef XFree86LOADER
|
|
elist = LoaderListDirs(esubdirs, NULL);
|
|
if (elist) {
|
|
for (el = elist; *el; el++) {
|
|
XF86LoadPtr module;
|
|
|
|
module = xf86confmalloc(sizeof(XF86LoadRec));
|
|
memset((XF86LoadPtr)module,0,sizeof(XF86LoadRec));
|
|
module->load_name = *el;
|
|
/* HACK, remove GLcore, glx, loads it as a submodule */
|
|
if (strcmp(*el, "GLcore"))
|
|
ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
|
|
(glp)ptr->mod_load_lst, (glp)module);
|
|
}
|
|
xfree(elist);
|
|
}
|
|
|
|
/* Process list of font backends separately to include only required ones */
|
|
elist = LoaderListDirs(fsubdirs, NULL);
|
|
if (elist) {
|
|
for (el = elist; *el; el++) {
|
|
XF86LoadPtr module;
|
|
|
|
module = xf86confmalloc(sizeof(XF86LoadRec));
|
|
memset((XF86LoadPtr)module,0,sizeof(XF86LoadRec));
|
|
module->load_name = *el;
|
|
|
|
/* Add only those font backends which are referenced by fontpath */
|
|
/* 'strstr(dFP,"/dir")' is meant as 'dFP =~ m(/dir\W)' */
|
|
if (defaultFontPath && (
|
|
(strcmp(*el, "freetype") == 0 &&
|
|
strstr(defaultFontPath, "/TTF")) ||
|
|
(strcmp(*el, "type1") == 0 &&
|
|
strstr(defaultFontPath, "/Type1")) ||
|
|
(strcmp(*el, "speedo") == 0 &&
|
|
strstr(defaultFontPath, "/Speedo"))))
|
|
ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
|
|
(glp)ptr->mod_load_lst, (glp)module);
|
|
}
|
|
xfree(elist);
|
|
}
|
|
#endif
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static XF86ConfFilesPtr
|
|
configureFilesSection (void)
|
|
{
|
|
parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
|
|
|
|
#ifdef XFree86LOADER
|
|
if (xf86ModulePath)
|
|
ptr->file_modulepath = strdup(xf86ModulePath);
|
|
#endif
|
|
if (defaultFontPath)
|
|
ptr->file_fontpath = strdup(defaultFontPath);
|
|
if (rgbPath)
|
|
ptr->file_rgbpath = strdup(rgbPath);
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static XF86ConfMonitorPtr
|
|
configureMonitorSection (int screennum)
|
|
{
|
|
parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
|
|
|
|
ptr->mon_identifier = xf86confmalloc(19);
|
|
sprintf(ptr->mon_identifier, "Monitor%d", screennum);
|
|
ptr->mon_vendor = strdup("Monitor Vendor");
|
|
ptr->mon_modelname = strdup("Monitor Model");
|
|
|
|
return ptr;
|
|
}
|
|
|
|
static XF86ConfMonitorPtr
|
|
configureDDCMonitorSection (int screennum)
|
|
{
|
|
int i = 0;
|
|
int len, mon_width, mon_height;
|
|
#define displaySizeMaxLen 80
|
|
char displaySize_string[displaySizeMaxLen];
|
|
int displaySizeLen;
|
|
|
|
parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
|
|
|
|
ptr->mon_identifier = xf86confmalloc(19);
|
|
sprintf(ptr->mon_identifier, "Monitor%d", screennum);
|
|
ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
|
|
ptr->mon_modelname = xf86confmalloc(12);
|
|
sprintf(ptr->mon_modelname, "%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 =
|
|
xf86confrealloc(ptr->mon_comment,
|
|
len+strlen(displaySize_string)))) {
|
|
strcpy(ptr->mon_comment + len, displaySize_string);
|
|
}
|
|
}
|
|
}
|
|
#endif /* def CONFIGURE_DISPLAYSIZE */
|
|
|
|
for (i=0;i<4;i++) {
|
|
switch (ConfiguredMonitor->det_mon[i].type) {
|
|
case DT:
|
|
case DS_STD_TIMINGS:
|
|
case DS_WHITE_P:
|
|
break;
|
|
case DS_NAME:
|
|
ptr->mon_modelname = xf86confrealloc(ptr->mon_modelname,
|
|
strlen((char*)(ConfiguredMonitor->det_mon[i].section.name))
|
|
+ 1);
|
|
strcpy(ptr->mon_modelname,
|
|
(char*)(ConfiguredMonitor->det_mon[i].section.name));
|
|
break;
|
|
case DS_ASCII_STR:
|
|
case DS_SERIAL:
|
|
case DS_RANGES:
|
|
ptr->mon_hsync[ptr->mon_n_hsync].lo =
|
|
ConfiguredMonitor->det_mon[i].section.ranges.min_h;
|
|
ptr->mon_hsync[ptr->mon_n_hsync].hi =
|
|
ConfiguredMonitor->det_mon[i].section.ranges.max_h;
|
|
ptr->mon_n_vrefresh = 1;
|
|
ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
|
|
ConfiguredMonitor->det_mon[i].section.ranges.min_v;
|
|
ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
|
|
ConfiguredMonitor->det_mon[i].section.ranges.max_v;
|
|
ptr->mon_n_hsync++;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ConfiguredMonitor->features.dpms) {
|
|
ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, "DPMS", NULL);
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
void
|
|
DoConfigure()
|
|
{
|
|
int i,j, screennum = -1;
|
|
char *home = NULL;
|
|
char *filename = NULL;
|
|
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);
|
|
|
|
#ifdef XFree86LOADER
|
|
/* Load all the drivers that were found. */
|
|
xf86LoadModules(vlist, NULL);
|
|
#endif /* XFree86LOADER */
|
|
|
|
xfree(vlist);
|
|
|
|
/* Disable PCI devices */
|
|
xf86ResourceBrokerInit();
|
|
xf86AccessInit();
|
|
xf86FindPrimaryDevice();
|
|
|
|
/* Create XF86Config file structure */
|
|
xf86config = malloc(sizeof(XF86ConfigRec));
|
|
memset ((XF86ConfigPtr)xf86config, 0, sizeof(XF86ConfigRec));
|
|
xf86config->conf_device_lst = NULL;
|
|
xf86config->conf_screen_lst = NULL;
|
|
xf86config->conf_monitor_lst = NULL;
|
|
|
|
/* Call all of the probe functions, reporting the results. */
|
|
for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
|
|
|
|
if (xf86DriverList[CurrentDriver]->Probe == NULL) continue;
|
|
|
|
if ((*xf86DriverList[CurrentDriver]->Probe)(
|
|
xf86DriverList[CurrentDriver], PROBE_DETECT) &&
|
|
xf86DriverList[CurrentDriver]->Identify)
|
|
(*xf86DriverList[CurrentDriver]->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 = configureVideoAdaptorSection();
|
|
xf86config->conf_modes_lst = configureModesSection();
|
|
xf86config->conf_vendor_lst = configureVendorSection();
|
|
xf86config->conf_dri = configureDRISection();
|
|
xf86config->conf_input_lst = configureInputSection();
|
|
xf86config->conf_layout_lst = configureLayoutSection();
|
|
|
|
if (!(home = getenv("HOME")))
|
|
home = "/";
|
|
{
|
|
#ifdef __UNIXOS2__
|
|
#define PATH_MAX 2048
|
|
#endif
|
|
#if defined(SCO) || defined(SCO325)
|
|
#define PATH_MAX 1024
|
|
#endif
|
|
const char* configfile = XF86CONFIGFILE".new";
|
|
char homebuf[PATH_MAX];
|
|
/* getenv might return R/O memory, as with OS/2 */
|
|
strncpy(homebuf,home,PATH_MAX-1);
|
|
homebuf[PATH_MAX-1] = '\0';
|
|
home = homebuf;
|
|
if (!(filename =
|
|
(char *)ALLOCATE_LOCAL(strlen(home) +
|
|
strlen(configfile) + 3)))
|
|
|
|
if (home[0] == '/' && home[1] == '\0')
|
|
home[0] = '\0';
|
|
#ifndef QNX4
|
|
sprintf(filename, "%s/%s", home,configfile);
|
|
#else
|
|
sprintf(filename, "//%d%s/%s", getnid(),home,configfile);
|
|
#endif
|
|
|
|
}
|
|
|
|
xf86writeConfigFile(filename, xf86config);
|
|
|
|
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;
|
|
|
|
(*xf86DriverList[i]->Probe)(xf86DriverList[i], 0);
|
|
|
|
/* 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;
|
|
}
|
|
}
|
|
}
|
|
xf86SetPciVideo(NULL,NONE);
|
|
}
|
|
xfree(driverProbed);
|
|
}
|
|
|
|
|
|
if (nDevToConfig != xf86NumScreens) {
|
|
ErrorF("Number of created screens does not match number of detected"
|
|
" devices.\n Configuration failed.\n");
|
|
goto bail;
|
|
}
|
|
|
|
xf86PostProbe();
|
|
xf86EntityInit();
|
|
|
|
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;
|
|
|
|
xf86EnableAccess(xf86Screens[dev2screen[j]]);
|
|
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);
|
|
}
|
|
|
|
xf86writeConfigFile(filename, xf86config);
|
|
|
|
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 {
|
|
#ifndef __UNIXOS2__ /* OS/2 definitely has a mouse */
|
|
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
|
|
}
|
|
#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:
|
|
OsCleanup(TRUE);
|
|
AbortDDX();
|
|
fflush(stderr);
|
|
exit(0);
|
|
}
|