summaryrefslogtreecommitdiff
path: root/hw/xfree86/common/xf86Init.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/common/xf86Init.c')
-rw-r--r--hw/xfree86/common/xf86Init.c1804
1 files changed, 1405 insertions, 399 deletions
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 864933a84..7c65ce888 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -1,138 +1,199 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Init.c,v 3.198 2003/02/26 09:21:38 dawes Exp $ */
+
/*
- * $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Init.c,v 3.66.2.2 1997/06/29 08:43:36 dawes Exp $
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ * Copyright 1991-1999 by The XFree86 Project, Inc.
*
- * 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 Thomas Roell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Thomas Roell makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
+ * Loosely based on code bearing the following copyright:
*
- * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THOMAS ROELL 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.
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
*/
-/* $Xorg: xf86Init.c,v 1.3 2000/08/17 19:50:29 cpqbld Exp $ */
-#ifndef X_NOT_STDC_ENV
#include <stdlib.h>
-#else
-extern int atoi();
-#endif
#define NEED_EVENTS
#include "X.h"
#include "Xmd.h"
#include "Xproto.h"
+#include "Xatom.h"
#include "input.h"
#include "servermd.h"
+#include "windowstr.h"
#include "scrnintstr.h"
#include "site.h"
+#include "mi.h"
#include "compiler.h"
+#ifdef XFree86LOADER
+#include "loaderProcs.h"
+#endif
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#define XF86_OS_PRIVS
#include "xf86.h"
-#include "xf86Procs.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
#include "xf86_OSlib.h"
#include "xf86Version.h"
+#include "xf86Date.h"
+#include "xf86Build.h"
#include "mipointer.h"
-
#ifdef XINPUT
#include "XI.h"
#include "XIproto.h"
-#include "xf86_Config.h"
-#include "xf86Xinput.h"
#else
#include "inputstr.h"
#endif
+#include "xf86DDC.h"
+#include "xf86Xinput.h"
+#include "xf86InPriv.h"
+#ifdef RENDER
+#include "picturestr.h"
+#endif
-#include "opaque.h"
+#include "globals.h"
#ifdef XTESTEXT1
#include "atKeynames.h"
extern int xtest_command_key;
#endif /* XTESTEXT1 */
-#ifdef __EMX__
-#define seteuid(x) /*nothing*/
-#define setruid(x) /*nothing*/
-#endif
-/* xf86Exiting is set while the screen is shutting down (even on a reset) */
-Bool xf86Exiting = FALSE;
-Bool xf86Resetting = FALSE;
-Bool xf86ProbeFailed = TRUE;
-Bool xf86FlipPixels = FALSE;
-#ifdef XF86VIDMODE
-Bool xf86VidModeEnabled = TRUE;
-Bool xf86VidModeAllowNonLocal = FALSE;
-#endif
-#ifdef XF86MISC
-Bool xf86MiscModInDevEnabled = TRUE;
-Bool xf86MiscModInDevAllowNonLocal = FALSE;
-#endif
-Bool xf86AllowMouseOpenFail = FALSE;
-PciProbeType xf86PCIFlags = PCIProbe1;
-Bool xf86ScreensOpen = FALSE;
-int xf86Verbose = 1;
-Bool xf86fpFlag = FALSE;
-Bool xf86coFlag = FALSE;
-Bool xf86sFlag = FALSE;
-Bool xf86ProbeOnly = FALSE;
-char xf86ConfigFile[PATH_MAX] = "";
-int xf86bpp = -1;
-xrgb xf86weight = { 0, 0, 0 } ; /* RGB weighting at 16 bpp */
-double xf86rGamma=1.0, xf86gGamma=1.0, xf86bGamma=1.0;
-unsigned char xf86rGammaMap[256], xf86gGammaMap[256], xf86bGammaMap[256];
-char *xf86ServerName = NULL;
-Bool xf86BestRefresh = FALSE;
-
-int vgaIOBase = 0x3d0;
-int vgaCRIndex = 0x3d4;
-int vgaCRReg = 0x3d5;
-
-static void xf86PrintBanner(
-#if NeedFunctionPrototypes
- void
-#endif
- );
-static void xf86PrintConfig(
-#if NeedFunctionPrototypes
- void
-#endif
- );
+/* forward declarations */
+
+static void xf86PrintBanner(void);
+static void xf86PrintMarkers(void);
+static void xf86RunVtInit(void);
+
#ifdef DO_CHECK_BETA
-void xf86CheckBeta(
-#if NeedFunctionPrototypes
- int,
- char *
-#endif
- );
static int extraDays = 0;
static char *expKey = NULL;
#endif
-extern ScrnInfoPtr xf86Screens[];
-extern int xf86MaxScreens;
-extern double pow();
-#ifdef USE_XF86_SERVERLOCK
-extern void xf86UnlockServer();
-#endif
-#ifdef __EMX__
+#ifdef __UNIXOS2__
extern void os2ServerVideoAccess();
#endif
-xf86InfoRec xf86Info;
-int xf86ScreenIndex;
+void (*xf86OSPMClose)(void) = NULL;
+
+#ifdef XFree86LOADER
+static char *baseModules[] = {
+ "bitmap",
+ "pcidata",
+ NULL
+};
+#endif
+
+/* Common pixmap formats */
+
+static PixmapFormatRec formats[MAXFORMATS] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 4, 8, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 15, 16, BITMAP_SCANLINE_PAD },
+ { 16, 16, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD },
+#ifdef RENDER
+ { 32, 32, BITMAP_SCANLINE_PAD },
+#endif
+};
+#ifdef RENDER
+static int numFormats = 7;
+#else
+static int numFormats = 6;
+#endif
+static Bool formatsDone = FALSE;
+
+InputDriverRec xf86KEYBOARD = {
+ 1,
+ "keyboard",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0
+};
+
+static Bool
+xf86CreateRootWindow(WindowPtr pWin)
+{
+ int ret = TRUE;
+ int err = Success;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PropertyPtr pRegProp, pOldRegProp;
+ CreateWindowProcPtr CreateWindow =
+ (CreateWindowProcPtr)(pScreen->devPrivates[xf86CreateRootWindowIndex].ptr);
+
+#ifdef DEBUG
+ ErrorF("xf86CreateRootWindow(%p)\n", pWin);
+#endif
+
+ if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
+ /* Can't find hook we are hung on */
+ xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
+ "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
+ xf86CreateRootWindow, pScreen->CreateWindow );
+ }
+
+ /* Unhook this function ... */
+ pScreen->CreateWindow = CreateWindow;
+ pScreen->devPrivates[xf86CreateRootWindowIndex].ptr = NULL;
+
+ /* ... and call the previous CreateWindow fuction, if any */
+ if (NULL!=pScreen->CreateWindow) {
+ ret = (*pScreen->CreateWindow)(pWin);
+ }
+
+ /* Now do our stuff */
+
+ if (xf86RegisteredPropertiesTable != NULL) {
+ if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
+ for (pRegProp = xf86RegisteredPropertiesTable[pScreen->myNum];
+ pRegProp != NULL && err==Success;
+ pRegProp = pRegProp->next )
+ {
+ Atom oldNameAtom = pRegProp->propertyName;
+ char *nameString;
+ /* propertyName was created before the screen existed,
+ * so the atom does not belong to any screen;
+ * we need to create a new atom with the same name.
+ */
+ nameString = NameForAtom(oldNameAtom);
+ pRegProp->propertyName = MakeAtom(nameString, strlen(nameString), TRUE);
+ err = ChangeWindowProperty(pWin,
+ pRegProp->propertyName, pRegProp->type,
+ pRegProp->format, PropModeReplace,
+ pRegProp->size, pRegProp->data,
+ FALSE
+ );
+ }
+
+ /* Look at err */
+ ret &= (err==Success);
+
+ /* free memory */
+ pOldRegProp = xf86RegisteredPropertiesTable[pScreen->myNum];
+ while (pOldRegProp!=NULL) {
+ pRegProp = pOldRegProp->next;
+ xfree(pOldRegProp);
+ pOldRegProp = pRegProp;
+ }
+ xf86RegisteredPropertiesTable[pScreen->myNum] = NULL;
+ } else {
+ xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
+ "non-root window %p (parent %p)\n", pWin, pWin->parent);
+ ret = FALSE;
+ }
+ }
+
+#ifdef DEBUG
+ ErrorF("xf86CreateRootWindow() returns %d\n", ret);
+#endif
+ return (ret);
+}
+
/*
* InitOutput --
@@ -142,23 +203,38 @@ int xf86ScreenIndex;
*/
void
-InitOutput(pScreenInfo, argc, argv)
- ScreenInfo *pScreenInfo;
- int argc;
- char **argv;
+InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
{
- int i, j, scr_index;
- static int numFormats = 0;
- static PixmapFormatRec formats[MAXFORMATS];
+ int i, j, k, scr_index;
static unsigned long generation = 0;
- int any_screens = 0;
-
-#ifdef __EMX__
+#ifdef XFree86LOADER
+ char **modulelist;
+ pointer *optionlist;
+#endif
+ screenLayoutPtr layout;
+ Pix24Flags screenpix24, pix24;
+ MessageType pix24From = X_DEFAULT;
+ Bool pix24Fail = FALSE;
+
+#ifdef __UNIXOS2__
os2ServerVideoAccess(); /* See if we have access to the screen before doing anything */
#endif
+ xf86Initialising = TRUE;
+
+ /* Do this early? */
+ if (generation != serverGeneration) {
+ xf86ScreenIndex = AllocateScreenPrivateIndex();
+ xf86CreateRootWindowIndex = AllocateScreenPrivateIndex();
+ xf86PixmapIndex = AllocatePixmapPrivateIndex();
+ xf86RegisteredPropertiesTable=NULL;
+ generation = serverGeneration;
+ }
+
if (serverGeneration == 1) {
+ pScreenInfo->numScreens = 0;
+
if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
xf86ServerName++;
else
@@ -169,119 +245,517 @@ InitOutput(pScreenInfo, argc, argv)
#endif
xf86PrintBanner();
+ xf86PrintMarkers();
+ if (xf86LogFile) {
+ time_t t;
+ const char *ct;
+ t = time(NULL);
+ ct = ctime(&t);
+ xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
+ xf86LogFile, ct);
+ }
+
+ /* Read and parse the config file */
+ if (!xf86DoProbe && !xf86DoConfigure) {
+ if (!xf86HandleConfigFile()) {
+ xf86Msg(X_ERROR, "Error from xf86HandleConfigFile()\n");
+ return;
+ }
+ }
- xf86PrintConfig();
+ /*
+ * Install signal handler for unexpected signals
+ */
+ xf86Info.caughtSignal=FALSE;
+ if (!xf86Info.notrapSignals) {
+ signal(SIGSEGV,xf86SigHandler);
+ signal(SIGILL,xf86SigHandler);
+#ifdef SIGEMT
+ signal(SIGEMT,xf86SigHandler);
+#endif
+ signal(SIGFPE,xf86SigHandler);
+#ifdef SIGBUS
+ signal(SIGBUS,xf86SigHandler);
+#endif
+#ifdef SIGSYS
+ signal(SIGSYS,xf86SigHandler);
+#endif
+#ifdef SIGXCPU
+ signal(SIGXCPU,xf86SigHandler);
+#endif
+#ifdef SIGXFSZ
+ signal(SIGXFSZ,xf86SigHandler);
+#endif
+#ifdef MEMDEBUG
+ signal(SIGUSR2,xf86SigMemDebug);
+#endif
+ }
xf86OpenConsole();
+ xf86OSPMClose = xf86OSPMOpen();
+
+ /* Run an external VT Init program if specified in the config file */
+ xf86RunVtInit();
+
+ /* Do this after XF86Config is read (it's normally in OsInit()) */
+ OsInitColors();
+
+ /* Enable full I/O access */
+ xf86EnableIO();
+
+#ifdef XFree86LOADER
+ /* Initialise the loader */
+ LoaderInit();
+
+ /* Tell the loader the default module search path */
+ LoaderSetPath(xf86ModulePath);
+
+#ifdef TESTING
+ {
+ char **list, **l;
+ const char *subdirs[] = {
+ "drivers",
+ NULL
+ };
+ const char *patlist[] = {
+ "(.*)_drv\\.so",
+ "(.*)_drv\\.o",
+ NULL
+ };
+ ErrorF("Getting module listing...\n");
+ list = LoaderListDirs(NULL, NULL);
+ if (list)
+ for (l = list; *l; l++)
+ ErrorF("module: %s\n", *l);
+ LoaderFreeDirList(list);
+ ErrorF("Getting video driver listing...\n");
+ list = LoaderListDirs(subdirs, NULL);
+ if (list)
+ for (l = list; *l; l++)
+ ErrorF("video driver: %s\n", *l);
+ LoaderFreeDirList(list);
+ ErrorF("Getting driver listing...\n");
+ list = LoaderListDirs(NULL, patlist);
+ if (list)
+ for (l = list; *l; l++)
+ ErrorF("video driver: %s\n", *l);
+ LoaderFreeDirList(list);
+ }
+#endif
+
+ /* Force load mandatory base modules */
+ if (!xf86LoadModules(baseModules, NULL))
+ FatalError("Unable to load required base modules, Exiting...\n");
+
+#endif
+
+ /* Do a general bus probe. This will be a PCI probe for x86 platforms */
+ xf86BusProbe();
+
+ if (xf86DoProbe)
+ DoProbe();
+
+ if (xf86DoConfigure)
+ DoConfigure();
+
+ /* Initialise the resource broker */
+ xf86ResourceBrokerInit();
+
+#ifdef XFree86LOADER
+ /* Load all modules specified explicitly in the config file */
+ if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
+ xf86LoadModules(modulelist, optionlist);
+ xfree(modulelist);
+ xfree(optionlist);
+ }
+
+ /* Load all driver modules specified in the config file */
+ if ((modulelist = xf86DriverlistFromConfig())) {
+ xf86LoadModules(modulelist, NULL);
+ xfree(modulelist);
+ }
+
+ /* Setup the builtin input drivers */
+ xf86AddInputDriver(&xf86KEYBOARD, NULL, 0);
+ /* Load all input driver modules specified in the config file. */
+ if ((modulelist = xf86InputDriverlistFromConfig())) {
+ xf86LoadModules(modulelist, NULL);
+ xfree(modulelist);
+ }
-#if !defined(AMOEBA) && !defined(MINIX)
/*
- * If VTInit was set, run that program with consoleFd as stdin and stdout
+ * It is expected that xf86AddDriver()/xf86AddInputDriver will be
+ * called for each driver as it is loaded. Those functions save the
+ * module pointers for drivers.
+ * XXX Nothing keeps track of them for other modules.
*/
+ /* XXX What do we do if not all of these could be loaded? */
+#endif
- if (xf86Info.vtinit) {
- switch(fork()) {
- case -1:
- FatalError("Fork failed for VTInit (%s)\n", strerror(errno));
- break;
- case 0: /* child */
- setuid(getuid());
- /* set stdin, stdout to the consoleFd */
- for (i = 0; i < 2; i++) {
- if (xf86Info.consoleFd != i) {
- close(i);
- dup(xf86Info.consoleFd);
- }
- }
- execl("/bin/sh", "sh", "-c", xf86Info.vtinit, NULL);
- ErrorF("Warning: exec of /bin/sh failed for VTInit (%s)\n",
- strerror(errno));
- exit(255);
- break;
- default: /* parent */
- wait(NULL);
+ /*
+ * At this point, xf86DriverList[] is all filled in with entries for
+ * each of the drivers to try and xf86NumDrivers has the number of
+ * drivers. If there are none, return now.
+ */
+
+ if (xf86NumDrivers == 0) {
+ xf86Msg(X_ERROR, "No drivers available.\n");
+ return;
+ }
+
+ /*
+ * Call each of the Identify functions. The Identify functions print
+ * out some identifying information, and anything else that might be
+ * needed at this early stage.
+ */
+
+ for (i = 0; i < xf86NumDrivers; i++)
+ /* The Identify function is mandatory, but if it isn't there continue */
+ if (xf86DriverList[i]->Identify != NULL)
+ xf86DriverList[i]->Identify(0);
+ else {
+ xf86Msg(X_WARNING, "Driver `%s' has no Identify function\n",
+ xf86DriverList[i]->driverName ? xf86DriverList[i]->driverName
+ : "noname");
}
+
+ /*
+ * Locate bus slot that had register IO enabled at server startup
+ */
+
+ xf86AccessInit();
+ xf86FindPrimaryDevice();
+
+ /*
+ * Now call each of the Probe functions. Each successful probe will
+ * result in an extra entry added to the xf86Screens[] list for each
+ * instance of the hardware found.
+ */
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ if (xf86DriverList[i]->Probe != NULL)
+ xf86DriverList[i]->Probe(xf86DriverList[i], PROBE_DEFAULT);
+ else {
+ xf86MsgVerb(X_WARNING, 0,
+ "Driver `%s' has no Probe function (ignoring)\n",
+ xf86DriverList[i]->driverName ? xf86DriverList[i]->driverName
+ : "noname");
+ }
+ xf86SetPciVideo(NULL,NONE);
}
-#endif /* !AMOEBA && !MINIX */
- /* Do this after XF86Config is read (it's normally in OsInit()) */
- OsInitColors();
+ /*
+ * If nothing was detected, return now.
+ */
- for (i=0; i<256; i++) {
- xf86rGammaMap[i] = (int)(pow(i/255.0,xf86rGamma)*255.0+0.5);
- xf86gGammaMap[i] = (int)(pow(i/255.0,xf86gGamma)*255.0+0.5);
- xf86bGammaMap[i] = (int)(pow(i/255.0,xf86bGamma)*255.0+0.5);
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR, "No devices detected.\n");
+ return;
}
- xf86Config(TRUE); /* Probe displays, and resolve modes */
+ /*
+ * Match up the screens found by the probes against those specified
+ * in the config file. Remove the ones that won't be used. Sort
+ * them in the order specified.
+ */
-#ifdef XKB
- xf86InitXkb();
-#endif
+ /*
+ * What is the best way to do this?
+ *
+ * For now, go through the screens allocated by the probes, and
+ * look for screen config entry which refers to the same device
+ * section as picked out by the probe.
+ *
+ */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
+ layout++) {
+ Bool found = FALSE;
+ for (j = 0; j < xf86Screens[i]->numEntities; j++) {
+
+ GDevPtr dev =
+ xf86GetDevFromEntity(xf86Screens[i]->entityList[j],
+ xf86Screens[i]->entityInstanceList[j]);
+
+ if (dev == layout->screen->device) {
+ /* A match has been found */
+ xf86Screens[i]->confScreen = layout->screen;
+ found = TRUE;
+ break;
+ }
+ }
+ if (found) break;
+ }
+ if (layout->screen == NULL) {
+ /* No match found */
+ xf86Msg(X_ERROR,
+ "Screen %d deleted because of no matching config section.\n", i);
+ xf86DeleteScreen(i--, 0);
+ }
+ }
/*
- * collect all possible formats
+ * If no screens left, return now.
*/
- formats[0].depth = 1;
- formats[0].bitsPerPixel = 1;
- formats[0].scanlinePad = BITMAP_SCANLINE_PAD;
- numFormats++;
-
- for ( i=0;
- i < xf86MaxScreens && xf86Screens[i] && xf86Screens[i]->configured;
- i++ )
- {
- /*
- * At least one probe function succeeded.
- */
- any_screens = 1;
- /*
- * add new pixmap format
- */
- for ( j=0; j < numFormats; j++ ) {
-
- if (formats[j].depth == xf86Screens[i]->depth &&
- formats[j].bitsPerPixel == xf86Screens[i]->bitsPerPixel)
- break; /* found */
- }
-
- if (j == numFormats) { /* not already there */
- formats[j].depth = xf86Screens[i]->depth;
- formats[j].bitsPerPixel = xf86Screens[i]->bitsPerPixel;
- formats[j].scanlinePad = BITMAP_SCANLINE_PAD;
- numFormats++;
- if ( numFormats > MAXFORMATS )
- FatalError( "Too many pixmap formats! Exiting\n" );
- }
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR,
+ "Device(s) detected, but none match those in the config file.\n");
+ return;
+ }
+
+ xf86PostProbe();
+ xf86EntityInit();
+
+ /*
+ * Sort the drivers to match the requested ording. Using a slow
+ * bubble sort.
+ */
+ for (j = 0; j < xf86NumScreens - 1; j++) {
+ for (i = 0; i < xf86NumScreens - j - 1; i++) {
+ if (xf86Screens[i + 1]->confScreen->screennum <
+ xf86Screens[i]->confScreen->screennum) {
+ ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
+ xf86Screens[i + 1] = xf86Screens[i];
+ xf86Screens[i] = tmpScrn;
+ }
+ }
+ }
+ /* Fix up the indexes */
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86Screens[i]->scrnIndex = i;
+ }
+
+ /*
+ * Call the driver's PreInit()'s to complete initialisation for the first
+ * generation.
+ */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86EnableAccess(xf86Screens[i]);
+ if (xf86Screens[i]->PreInit &&
+ xf86Screens[i]->PreInit(xf86Screens[i], 0))
+ xf86Screens[i]->configured = TRUE;
+ }
+ for (i = 0; i < xf86NumScreens; i++)
+ if (!xf86Screens[i]->configured)
+ xf86DeleteScreen(i--, 0);
+
+ /*
+ * If no screens left, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR,
+ "Screen(s) found, but none have a usable configuration.\n");
+ return;
+ }
+
+ /* This could be moved into a separate function */
+
+ /*
+ * Check that all screens have initialised the mandatory function
+ * entry points. Delete those which have not.
+ */
+
+#define WARN_SCREEN(func) \
+ xf86Msg(X_ERROR, "Driver `%s' has no %s function, deleting.\n", \
+ xf86Screens[i]->name, (warned++, func))
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ int warned = 0;
+ if (xf86Screens[i]->name == NULL) {
+ xf86Screens[i]->name = xnfalloc(strlen("screen") + 1 + 1);
+ if (i < 10)
+ sprintf(xf86Screens[i]->name, "screen%c", i + '0');
+ else
+ sprintf(xf86Screens[i]->name, "screen%c", i - 10 + 'A');
+ xf86MsgVerb(X_WARNING, 0,
+ "Screen driver %d has no name set, using `%s'.\n",
+ i, xf86Screens[i]->name);
}
- if (!any_screens)
- if (xf86ProbeFailed)
- ErrorF("\n *** None of the configured devices were detected.***\n\n");
- else
- ErrorF(
- "\n *** A configured device found, but display modes could not be resolved.***\n\n");
+ if (xf86Screens[i]->ScreenInit == NULL)
+ WARN_SCREEN("ScreenInit");
+ if (xf86Screens[i]->EnterVT == NULL)
+ WARN_SCREEN("EnterVT");
+ if (xf86Screens[i]->LeaveVT == NULL)
+ WARN_SCREEN("LeaveVT");
+ if (warned)
+ xf86DeleteScreen(i--, 0);
+ }
+
+ /*
+ * If no screens left, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR, "Screen(s) found, but drivers were unusable.\n");
+ return;
+ }
+
+ /* XXX Should this be before or after loading dependent modules? */
if (xf86ProbeOnly)
{
- xf86VTSema = FALSE;
+ OsCleanup();
AbortDDX();
fflush(stderr);
exit(0);
}
- }
- else {
+
+#ifdef XFree86LOADER
+ /* Remove (unload) drivers that are not required */
+ for (i = 0; i < xf86NumDrivers; i++)
+ if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
+ xf86DeleteDriver(i);
+#endif
+
+ /*
+ * At this stage we know how many screens there are.
+ */
+
+ for (i = 0; i < xf86NumScreens; i++)
+ xf86InitViewport(xf86Screens[i]);
+
+ /*
+ * Collect all pixmap formats and check for conflicts at the display
+ * level. Should we die here? Or just delete the offending screens?
+ * Also, should this be done for -probeonly?
+ */
+ screenpix24 = Pix24DontCare;
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->imageByteOrder !=
+ xf86Screens[0]->imageByteOrder)
+ FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
+ if (xf86Screens[i]->bitmapScanlinePad !=
+ xf86Screens[0]->bitmapScanlinePad)
+ FatalError("Inconsistent display bitmapScanlinePad. Exiting\n");
+ if (xf86Screens[i]->bitmapScanlineUnit !=
+ xf86Screens[0]->bitmapScanlineUnit)
+ FatalError("Inconsistent display bitmapScanlineUnit. Exiting\n");
+ if (xf86Screens[i]->bitmapBitOrder !=
+ xf86Screens[0]->bitmapBitOrder)
+ FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
+
+ /* Determine the depth 24 pixmap format the screens would like */
+ if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
+ if (screenpix24 == Pix24DontCare)
+ screenpix24 = xf86Screens[i]->pixmap24;
+ else if (screenpix24 != xf86Screens[i]->pixmap24)
+ FatalError("Inconsistent depth 24 pixmap format. Exiting\n");
+ }
+ }
+ /* check if screenpix24 is consistent with the config/cmdline */
+ if (xf86Info.pixmap24 != Pix24DontCare) {
+ pix24 = xf86Info.pixmap24;
+ pix24From = xf86Info.pix24From;
+ if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
+ pix24Fail = TRUE;
+ } else if (screenpix24 != Pix24DontCare) {
+ pix24 = screenpix24;
+ pix24From = X_PROBED;
+ } else
+ pix24 = Pix24Use32;
+
+ if (pix24Fail)
+ FatalError("Screen(s) can't use the required depth 24 pixmap format"
+ " (%d). Exiting\n", PIX24TOBPP(pix24));
+
+ /* Initialise the depth 24 format */
+ for (j = 0; j < numFormats && formats[j].depth != 24; j++)
+ ;
+ formats[j].bitsPerPixel = PIX24TOBPP(pix24);
+
+ /* Collect additional formats */
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (j = 0; j < xf86Screens[i]->numFormats; j++) {
+ for (k = 0; ; k++) {
+ if (k >= numFormats) {
+ if (k >= MAXFORMATS)
+ FatalError("Too many pixmap formats! Exiting\n");
+ formats[k] = xf86Screens[i]->formats[j];
+ numFormats++;
+ break;
+ }
+ if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
+ if ((formats[k].bitsPerPixel ==
+ xf86Screens[i]->formats[j].bitsPerPixel) &&
+ (formats[k].scanlinePad ==
+ xf86Screens[i]->formats[j].scanlinePad))
+ break;
+ FatalError("Inconsistent pixmap format for depth %d."
+ " Exiting\n", formats[k].depth);
+ }
+ }
+ }
+ }
+ formatsDone = TRUE;
+
+ /* If a screen uses depth 24, show what the pixmap format is */
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->depth == 24) {
+ xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
+ PIX24TOBPP(pix24));
+ break;
+ }
+ }
+
+#if BITMAP_SCANLINE_UNIT == 64
+ /*
+ * cfb24 doesn't currently work on architectures with a 64 bit
+ * BITMAP_SCANLINE_UNIT, so check for 24 bit pixel size for pixmaps
+ * or framebuffers.
+ */
+ {
+ Bool usesCfb24 = FALSE;
+
+ if (PIX24TOBPP(pix24) == 24)
+ usesCfb24 = TRUE;
+ for (i = 0; i < xf86NumScreens; i++)
+ if (xf86Screens[i]->bitsPerPixel == 24)
+ usesCfb24 = TRUE;
+ if (usesCfb24) {
+ FatalError("24-bit pixel size is not supported on systems with"
+ " 64-bit scanlines.\n");
+ }
+ }
+#endif
+
+#ifdef XKB
+ xf86InitXkb();
+#endif
+ /* set up the proper access funcs */
+ xf86PostPreInit();
+
+ AddCallback(&ServerGrabCallback, xf86GrabServerCallback, NULL);
+
+ } else {
/*
* serverGeneration != 1; some OSs have to do things here, too.
*/
xf86OpenConsole();
+
+ /*
+ should we reopen it here? We need to deal with an already opened
+ device. We could leave this to the OS layer. For now we simply
+ close it here
+ */
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
+ xf86MsgVerb(3,X_INFO,"APM registered successfully\n");
+
+ /* Make sure full I/O access is enabled */
+ xf86EnableIO();
}
+#if 0
/*
* Install signal handler for unexpected signals
*/
+ xf86Info.caughtSignal=FALSE;
if (!xf86Info.notrapSignals)
{
- xf86Info.caughtSignal=FALSE;
signal(SIGSEGV,xf86SigHandler);
signal(SIGILL,xf86SigHandler);
#ifdef SIGEMT
@@ -301,85 +775,146 @@ InitOutput(pScreenInfo, argc, argv)
signal(SIGXFSZ,xf86SigHandler);
#endif
}
-
+#endif
/*
- * Use the previous collected parts to setup pScreenInfo
+ * Use the previously collected parts to setup pScreenInfo
*/
- pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
- pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
- pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
- pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
- pScreenInfo->numPixmapFormats = numFormats;
- for ( i=0; i < numFormats; i++ ) pScreenInfo->formats[i] = formats[i];
-
- if (generation != serverGeneration)
- {
- xf86ScreenIndex = AllocateScreenPrivateIndex();
- generation = serverGeneration;
- }
-
- for ( i=0;
- i < xf86MaxScreens && xf86Screens[i] && xf86Screens[i]->configured;
- i++ )
- {
- /*
- * On a server-reset, we have explicitely to remap all stuff ...
- * (At startuptime this is implicitely done by probing the device
- */
- if (serverGeneration != 1)
- {
- xf86Resetting = TRUE;
- xf86Exiting = FALSE;
+ pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
+ pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
+ pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
+ pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
+ pScreenInfo->numPixmapFormats = numFormats;
+ for (i = 0; i < numFormats; i++)
+ pScreenInfo->formats[i] = formats[i];
+
+ /* Make sure the server's VT is active */
+
+ if (serverGeneration != 1) {
+ xf86Resetting = TRUE;
+ /* All screens are in the same state, so just check the first */
+ if (!xf86Screens[0]->vtSema) {
#ifdef HAS_USL_VTS
- if (!xf86VTSema)
- ioctl(xf86Info.consoleFd,VT_RELDISP,VT_ACKACQ);
+ ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
#endif
- xf86VTSema = TRUE;
- (xf86Screens[i]->EnterLeaveVT)(ENTER, i);
- xf86Resetting = FALSE;
- }
+ xf86AccessEnter();
+ xf86EnterServerState(SETUP);
+ }
+ }
#ifdef SCO
- else {
- /*
- * Under SCO we must ack that we got the console at startup,
- * I think this is the safest way to assure it
- */
- static int once = 1;
- if (once) {
- once = 0;
- if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
- ErrorF("VT_ACKACQ failed");
- }
- }
+ else {
+ /*
+ * Under SCO we must ack that we got the console at startup,
+ * I think this is the safest way to assure it.
+ */
+ static int once = 1;
+ if (once) {
+ once = 0;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
+ xf86Msg(X_WARNING, "VT_ACKACQ failed");
+ }
+ }
#endif /* SCO */
- scr_index = AddScreen(xf86Screens[i]->Init, argc, argv);
- if (scr_index > -1)
- {
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86EnableAccess(xf86Screens[i]);
+ /*
+ * Almost everything uses these defaults, and many of those that
+ * don't, will wrap them.
+ */
+ xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+ xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
+ scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
+ if (scr_index == i) {
+ /*
+ * Hook in our ScrnInfoRec, and initialise some other pScreen
+ * fields.
+ */
screenInfo.screens[scr_index]->devPrivates[xf86ScreenIndex].ptr
= (pointer)xf86Screens[i];
+ xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
+ /* The driver should set this, but make sure it is set anyway */
+ xf86Screens[i]->vtSema = TRUE;
+ } else {
+ /* This shouldn't normally happen */
+ FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
}
+#ifdef DEBUG
+ ErrorF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
+ i, xf86Screens[i]->pScreen );
+ ErrorF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
+ i, xf86Screens[i]->pScreen->CreateWindow );
+#endif
+
+ screenInfo.screens[scr_index]->devPrivates[xf86CreateRootWindowIndex].ptr
+ = (void*)(xf86Screens[i]->pScreen->CreateWindow);
+ xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
+
+#ifdef RENDER
+ if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
+ {
+ xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
+ PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
+ DDC ?
+ (DDC->features.input_type ?
+ SubPixelHorizontalRGB : SubPixelNone) :
+ SubPixelUnknown);
+ }
+#endif
+#ifdef RANDR
+ if (!xf86Info.disableRandR)
+ xf86RandRInit (screenInfo.screens[scr_index]);
+ xf86Msg(xf86Info.randRFrom, "RandR %s\n",
+ xf86Info.disableRandR ? "disabled" : "enabled");
+#endif
+#ifdef NOT_USED
/*
* Here we have to let the driver getting access of the VT. Note that
* this doesn't mean that the graphics board may access automatically
* the monitor. If the monitor is shared this is done in xf86CrossScreen!
*/
if (!xf86Info.sharedMonitor) (xf86Screens[i]->EnterLeaveMonitor)(ENTER);
- }
+#endif
+ }
-#ifndef AMOEBA
- RegisterBlockAndWakeupHandlers(xf86Block, xf86Wakeup, (void *)0);
+#ifdef XFree86LOADER
+ if ((serverGeneration == 1) && LoaderCheckUnresolved(LD_RESOLV_IFDONE)) {
+ /* For now, just a warning */
+ xf86Msg(X_WARNING, "Some symbols could not be resolved!\n");
+ }
#endif
+
+ xf86PostScreenInit();
+
+ xf86InitOrigins();
+
+ xf86Resetting = FALSE;
+ xf86Initialising = FALSE;
+
+ RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
+ NULL);
+}
+
+
+static InputDriverPtr
+MatchInput(IDevPtr pDev)
+{
+ int i;
+
+ for (i = 0; i < xf86NumInputDrivers; i++) {
+ if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
+ xf86NameCmp(pDev->driver, xf86InputDriverList[i]->driverName) == 0)
+ return xf86InputDriverList[i];
+ }
+ return NULL;
}
/*
* InitInput --
- * Initialize all supported input devices...what else is there
- * besides pointer and keyboard? Two DeviceRec's are allocated and
- * registered as the system pointer and keyboard devices.
+ * Initialize all supported input devices.
*/
void
@@ -387,129 +922,175 @@ InitInput(argc, argv)
int argc;
char **argv;
{
- xf86Info.vtRequestsPending = FALSE;
- xf86Info.inputPending = FALSE;
+ IDevPtr pDev;
+ InputDriverPtr pDrv;
+ InputInfoPtr pInfo;
+ static InputInfoPtr coreKeyboard = NULL, corePointer = NULL;
+
+ xf86Info.vtRequestsPending = FALSE;
+ xf86Info.inputPending = FALSE;
#ifdef XTESTEXT1
- xtest_command_key = KEY_Begin + MIN_KEYCODE;
+ xtest_command_key = KEY_Begin + MIN_KEYCODE;
#endif /* XTESTEXT1 */
- xf86Info.pKeyboard = AddInputDevice(xf86Info.kbdProc, TRUE);
- xf86Info.pMouse = AddInputDevice(xf86Info.mouseDev->mseProc, TRUE);
- RegisterKeyboardDevice((DevicePtr)xf86Info.pKeyboard);
- RegisterPointerDevice((DevicePtr)xf86Info.pMouse);
-
-#ifdef XINPUT
- (xf86Info.pMouse)->public.devicePrivate = xf86Info.mouseLocal;
-#if 0 /* Is this needed?? */
- ((LocalDevicePtr) xf86Info.mouseLocal)->dev = xf86Info.pMouse;
-#endif
-#else
- (xf86Info.pMouse)->public.devicePrivate = (pointer) xf86Info.mouseDev;
-#endif
-
-#ifdef XINPUT
- InitExtInput();
+ if (serverGeneration == 1) {
+ /* Call the PreInit function for each input device instance. */
+ for (pDev = xf86ConfigLayout.inputs; pDev && pDev->identifier; pDev++) {
+ /* XXX The keyboard driver is a special case for now. */
+ if (!xf86NameCmp(pDev->driver, "keyboard")) {
+ xf86Msg(X_INFO, "Keyboard \"%s\" handled by legacy driver\n",
+ pDev->identifier);
+ continue;
+ }
+ if ((pDrv = MatchInput(pDev)) == NULL) {
+ xf86Msg(X_ERROR, "No Input driver matching `%s'\n", pDev->driver);
+ /* XXX For now, just continue. */
+ continue;
+ }
+ if (!pDrv->PreInit) {
+ xf86MsgVerb(X_WARNING, 0,
+ "Input driver `%s' has no PreInit function (ignoring)\n",
+ pDrv->driverName);
+ continue;
+ }
+ pInfo = pDrv->PreInit(pDrv, pDev, 0);
+ if (!pInfo) {
+ xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n",
+ pDev->identifier);
+ continue;
+ } else if (!(pInfo->flags & XI86_CONFIGURED)) {
+ xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
+ pDev->identifier);
+ xf86DeleteInput(pInfo, 0);
+ continue;
+ }
+ if (pInfo->flags & XI86_CORE_KEYBOARD) {
+ if (coreKeyboard) {
+ xf86Msg(X_ERROR,
+ "Attempt to register more than one core keyboard (%s)\n",
+ pInfo->name);
+ pInfo->flags &= ~XI86_CORE_KEYBOARD;
+ } else {
+ if (!(pInfo->flags & XI86_KEYBOARD_CAPABLE)) {
+ /* XXX just a warning for now */
+ xf86Msg(X_WARNING,
+ "%s: does not have core keyboard capabilities\n",
+ pInfo->name);
+ }
+ coreKeyboard = pInfo;
+ }
+ }
+ if (pInfo->flags & XI86_CORE_POINTER) {
+ if (corePointer) {
+ xf86Msg(X_ERROR,
+ "Attempt to register more than one core pointer (%s)\n",
+ pInfo->name);
+ pInfo->flags &= ~XI86_CORE_POINTER;
+ } else {
+ if (!(pInfo->flags & XI86_POINTER_CAPABLE)) {
+ /* XXX just a warning for now */
+ xf86Msg(X_WARNING,
+ "%s: does not have core pointer capabilities\n",
+ pInfo->name);
+ }
+ corePointer = pInfo;
+ }
+ }
+ }
+ if (!corePointer) {
+ xf86Msg(X_WARNING, "No core pointer registered\n");
+ /* XXX register a dummy core pointer */
+ }
+#ifdef NEW_KBD
+ if (!coreKeyboard) {
+ xf86Msg(X_WARNING, "No core keyboard registered\n");
+ /* XXX register a dummy core keyboard */
+ }
#endif
+ }
+
+ /* Initialise all input devices. */
+ pInfo = xf86InputDevs;
+ while (pInfo) {
+ xf86ActivateDevice(pInfo);
+ pInfo = pInfo->next;
+ }
- miRegisterPointerDevice(screenInfo.screens[0], (DevicePtr) xf86Info.pMouse);
+ if (coreKeyboard) {
+ xf86Info.pKeyboard = coreKeyboard->dev;
+ xf86Info.kbdEvents = NULL; /* to prevent the internal keybord driver usage*/
+ }
+ else {
+ xf86Info.pKeyboard = AddInputDevice(xf86Info.kbdProc, TRUE);
+ }
+ if (corePointer)
+ xf86Info.pMouse = corePointer->dev;
+ RegisterKeyboardDevice(xf86Info.pKeyboard);
+
+ miRegisterPointerDevice(screenInfo.screens[0], xf86Info.pMouse);
#ifdef XINPUT
- xf86XinputFinalizeInit(xf86Info.pMouse);
xf86eqInit ((DevicePtr)xf86Info.pKeyboard, (DevicePtr)xf86Info.pMouse);
#else
- mieqInit (xf86Info.pKeyboard, xf86Info.pMouse);
+ mieqInit ((DevicePtr)xf86Info.pKeyboard, (DevicePtr)xf86Info.pMouse);
#endif
}
+#ifndef SET_STDERR_NONBLOCKING
+#define SET_STDERR_NONBLOCKING 1
+#endif
+
/*
* OsVendorInit --
* OS/Vendor-specific initialisations. Called from OsInit(), which
* is called by dix before establishing the well known sockets.
*/
-extern Bool OsDelayInitColors;
-
void
OsVendorInit()
{
+ static Bool beenHere = FALSE;
+
+ /* xf86WrapperInit() is called directly from OsInit() */
#ifdef SIGCHLD
signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */
#endif
-#ifdef USE_XF86_SERVERLOCK
- extern void xf86LockServer();
- static Bool been_here = FALSE;
-
- if (!been_here) {
- xf86LockServer();
- been_here = TRUE;
- }
-#endif
OsDelayInitColors = TRUE;
-}
-
-#ifdef DPMSExtension
-extern CARD16 DPMSPowerLevel;
-
-/*
- * DPMSSet --
- * Device dependent DPMS mode setting hook. This is called whenever
- * the DPMS mode is to be changed.
- */
-void
-DPMSSet(CARD16 level)
-{
- int i;
+#ifdef XFree86LOADER
+ loadableFonts = TRUE;
+#endif
- /* For each screen, set the power saver level */
- for (i = 0; i < screenInfo.numScreens; i++) {
- (XF86SCRNINFO(screenInfo.screens[i])->DPMSSet)(level);
- }
+ if (!beenHere)
+ xf86LogInit();
- DPMSPowerLevel = level;
-}
+#if SET_STDERR_NONBLOCKING
+ /* Set stderr to non-blocking. */
+#ifndef O_NONBLOCK
+#if defined(FNDELAY)
+#define O_NONBLOCK FNDELAY
+#elif defined(O_NDELAY)
+#define O_NONBLOCK O_NDELAY
+#endif
+#endif
-#if 0
-/*
- * DPMSGet --
- * Device dependent DPMS mode getting hook. This returns the current
- * DPMS mode, or -1 if DPMS is not supported.
- *
- * This should hook in to the appropriate driver-level function, which
- * will be added to the ScrnInfoRec.
- *
- * NOTES:
- * 1. the calling interface should be changed to specify which
- * screen to check.
- * 2. It isn't clear that this function is ever used.
- */
-CARD16
-DPMSGet(CARD16 *level)
-{
- int i;
+#ifdef O_NONBLOCK
+ if (!beenHere) {
+#if !defined(__EMX__)
+ if (geteuid() == 0 && getuid() != geteuid())
+#endif
+ {
+ int status;
- /* For each screen, set the power saver level */
- for (i = 0; i < screenInfo.numScreens; i++) {
- ;
+ status = fcntl(fileno(stderr), F_GETFL, 0);
+ if (status != -1) {
+ fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
+ }
}
-}
+ }
+#endif
#endif
-/*
- * DPMSSupported --
- * Return TRUE if any screen supports DPMS.
- */
-Bool
-DPMSSupported(void)
-{
- int i;
-
- /* For each screen, check if DPMS is supported */
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (XF86SCRNINFO(screenInfo.screens[i])->DPMSSet != (void (*)())NoopDDA)
- return TRUE;
- }
- return FALSE;
+ beenHere = TRUE;
}
-#endif /* DPMSExtension */
/*
* ddxGiveUp --
@@ -521,15 +1102,38 @@ DPMSSupported(void)
void
ddxGiveUp()
{
+ int i;
+
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ xf86OSPMClose = NULL;
+
+ xf86AccessLeaveState();
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ /*
+ * zero all access functions to
+ * trap calls when switched away.
+ */
+ xf86Screens[i]->vtSema = FALSE;
+ xf86Screens[i]->access = NULL;
+ xf86Screens[i]->busAccess = NULL;
+ }
+
#ifdef USE_XF86_SERVERLOCK
- xf86UnlockServer();
+ xf86UnlockServer();
#endif
+#ifdef XFreeXDGA
+ DGAShutdown();
+#endif
+
+ xf86CloseConsole();
- xf86CloseConsole();
+ xf86CloseLog();
- /* If an unexpected signal was caught, dump a core for debugging */
- if (xf86Info.caughtSignal)
- abort();
+ /* If an unexpected signal was caught, dump a core for debugging */
+ if (xf86Info.caughtSignal)
+ abort();
}
@@ -546,18 +1150,11 @@ AbortDDX()
{
int i;
-#if 0
- if (xf86Exiting)
- return;
-#endif
-
- xf86Exiting = TRUE;
-
/*
* try to deinitialize all input devices
*/
- if (xf86Info.pMouse) (xf86Info.mouseDev->mseProc)(xf86Info.pMouse, DEVICE_CLOSE);
- if (xf86Info.pKeyboard) (xf86Info.kbdProc)(xf86Info.pKeyboard, DEVICE_CLOSE);
+ if (xf86Info.pKeyboard)
+ (xf86Info.kbdProc)(xf86Info.pKeyboard, DEVICE_CLOSE);
/*
* try to restore the original video state
@@ -566,14 +1163,25 @@ AbortDDX()
/* Need the sleep when starting X from within another X session */
sleep(1);
#endif
- if (xf86VTSema && xf86ScreensOpen)
- for ( i=0;
- i < xf86MaxScreens && xf86Screens[i] && xf86Screens[i]->configured;
- i++ )
- (xf86Screens[i]->EnterLeaveVT)(LEAVE, i);
-
+ if (xf86Screens) {
+ if (xf86Screens[0]->vtSema)
+ xf86EnterServerState(SETUP);
+ for (i = 0; i < xf86NumScreens; i++)
+ if (xf86Screens[i]->vtSema) {
+ /*
+ * if we are aborting before ScreenInit() has finished
+ * we might not have been wrapped yet. Therefore enable
+ * screen explicitely.
+ */
+ xf86EnableAccess(xf86Screens[i]);
+ (xf86Screens[i]->LeaveVT)(i, 0);
+ }
+ }
+
+ xf86AccessLeave();
+
/*
- * This is needed for a abnormal server exit, since the normal exit stuff
+ * This is needed for an abnormal server exit, since the normal exit stuff
* MUST also be performed (i.e. the vt must be left in a defined state)
*/
ddxGiveUp();
@@ -583,7 +1191,11 @@ void
OsVendorFatalError()
{
ErrorF("\nWhen reporting a problem related to a server crash, please send\n"
- "the full server output, not just the last messages\n\n");
+ "the full server output, not just the last messages.\n");
+ if (xf86LogFile && xf86LogFileWasOpened)
+ ErrorF("This can be found in the log file \"%s\".\n", xf86LogFile);
+ ErrorF("Please report problems to %s.\n", BUILDERADDR);
+ ErrorF("\n");
}
/*
@@ -591,24 +1203,81 @@ OsVendorFatalError()
* Process device-dependent command line args. Returns 0 if argument is
* not device dependent, otherwise Count of number of elements of argv
* that are part of a device dependent commandline option.
+ *
*/
+
+
/* ARGSUSED */
int
-ddxProcessArgument (argc, argv, i)
- int argc;
- char *argv[];
- int i;
+ddxProcessArgument(int argc, char **argv, int i)
{
- if (getuid() == 0 && !strcmp(argv[i], "-xf86config"))
+ /*
+ * Note: can't use xalloc/xfree here because OsInit() hasn't been called
+ * yet. Use malloc/free instead.
+ */
+
+#ifdef DDXOSVERRORF
+ static Bool beenHere = FALSE;
+
+ if (!beenHere) {
+ /*
+ * This initialises our hook into VErrorF() for catching log messages
+ * that are generated before OsInit() is called.
+ */
+ OsVendorVErrorFProc = OsVendorVErrorF;
+ beenHere = TRUE;
+ }
+#endif
+
+ /* First the options that are only allowed for root */
+ if (getuid() == 0)
+ {
+ if (!strcmp(argv[i], "-modulepath"))
+ {
+ char *mp;
+ if (!argv[i + 1])
+ return 0;
+ mp = malloc(strlen(argv[i + 1]) + 1);
+ if (!mp)
+ FatalError("Can't allocate memory for ModulePath\n");
+ strcpy(mp, argv[i + 1]);
+ xf86ModulePath = mp;
+ xf86ModPathFrom = X_CMDLINE;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "-logfile"))
+ {
+ char *lf;
+ if (!argv[i + 1])
+ return 0;
+ lf = malloc(strlen(argv[i + 1]) + 1);
+ if (!lf)
+ FatalError("Can't allocate memory for LogFile\n");
+ strcpy(lf, argv[i + 1]);
+ xf86LogFile = lf;
+ xf86LogFileFrom = X_CMDLINE;
+ return 2;
+ }
+ }
+ if (!strcmp(argv[i], "-xf86config"))
{
- if (!argv[i+1])
+ if (!argv[i + 1])
return 0;
- if (strlen(argv[i+1]) >= PATH_MAX)
- FatalError("XF86Config path name too long\n");
- strcpy(xf86ConfigFile, argv[i+1]);
+ if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ FatalError("\nInvalid argument for -xf86config\n"
+ "\tFor non-root users, the file specified with -xf86config must be\n"
+ "\ta relative path and must not contain any \"..\" elements.\n"
+ "\tUsing default XF86Config search path.\n\n");
+ }
+ xf86ConfigFile = argv[i + 1];
return 2;
}
+ if (!strcmp(argv[i],"-showunresolved"))
+ {
+ xf86ShowUnresolved = TRUE;
+ return 1;
+ }
if (!strcmp(argv[i],"-probeonly"))
{
xf86ProbeOnly = TRUE;
@@ -622,7 +1291,7 @@ ddxProcessArgument (argc, argv, i)
#ifdef XF86VIDMODE
if (!strcmp(argv[i],"-disableVidMode"))
{
- xf86VidModeEnabled = FALSE;
+ xf86VidModeDisabled = TRUE;
return 1;
}
if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
@@ -634,7 +1303,7 @@ ddxProcessArgument (argc, argv, i)
#ifdef XF86MISC
if (!strcmp(argv[i],"-disableModInDev"))
{
- xf86MiscModInDevEnabled = FALSE;
+ xf86MiscModInDevDisabled = TRUE;
return 1;
}
if (!strcmp(argv[i],"-allowNonLocalModInDev"))
@@ -642,17 +1311,24 @@ ddxProcessArgument (argc, argv, i)
xf86MiscModInDevAllowNonLocal = TRUE;
return 1;
}
+#endif
if (!strcmp(argv[i],"-allowMouseOpenFail"))
{
xf86AllowMouseOpenFail = TRUE;
return 1;
}
-#endif
if (!strcmp(argv[i],"-bestRefresh"))
{
xf86BestRefresh = TRUE;
return 1;
}
+ if (!strcmp(argv[i],"-ignoreABI"))
+ {
+#ifdef XFree86LOADER
+ LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+#endif
+ return 1;
+ }
#ifdef DO_CHECK_BETA
if (!strcmp(argv[i],"-extendExpiry"))
{
@@ -663,8 +1339,34 @@ ddxProcessArgument (argc, argv, i)
#endif
if (!strcmp(argv[i],"-verbose"))
{
- if (!xf86Verbose++)
- xf86Verbose = 2;
+ if (++i < argc && argv[i])
+ {
+ char *end;
+ long val;
+ val = strtol(argv[i], &end, 0);
+ if (*end == '\0')
+ {
+ xf86Verbose = val;
+ return 2;
+ }
+ }
+ xf86Verbose++;
+ return 1;
+ }
+ if (!strcmp(argv[i],"-logverbose"))
+ {
+ if (++i < argc && argv[i])
+ {
+ char *end;
+ long val;
+ val = strtol(argv[i], &end, 0);
+ if (*end == '\0')
+ {
+ xf86LogVerbose = val;
+ return 2;
+ }
+ }
+ xf86LogVerbose++;
return 1;
}
if (!strcmp(argv[i],"-quiet"))
@@ -675,7 +1377,6 @@ ddxProcessArgument (argc, argv, i)
if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
{
xf86PrintBanner();
- xf86PrintConfig();
exit(0);
}
/* Notice the -fp flag, but allow it to pass to the dix layer */
@@ -690,26 +1391,72 @@ ddxProcessArgument (argc, argv, i)
xf86coFlag = TRUE;
return 0;
}
+ /* Notice the -bs flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-bs"))
+ {
+ xf86bsDisableFlag = TRUE;
+ return 0;
+ }
+ /* Notice the +bs flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "+bs"))
+ {
+ xf86bsEnableFlag = TRUE;
+ return 0;
+ }
/* Notice the -s flag, but allow it to pass to the dix layer */
if (!strcmp(argv[i], "-s"))
{
xf86sFlag = TRUE;
return 0;
}
-#ifndef XF86MONOVGA
if (!strcmp(argv[i], "-bpp"))
{
+ if (++i >= argc)
+ return 0;
+ ErrorF("The -bpp option is no longer supported.\n"
+ "\tUse -depth to set the color depth, and use -fbbpp if you really\n"
+ "\tneed to force a non-default framebuffer (hardware) pixel format.\n");
+ return 2;
+ }
+ if (!strcmp(argv[i], "-pixmap24"))
+ {
+ xf86Pix24 = Pix24Use24;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-pixmap32"))
+ {
+ xf86Pix24 = Pix24Use32;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-fbbpp"))
+ {
int bpp;
if (++i >= argc)
return 0;
if (sscanf(argv[i], "%d", &bpp) == 1)
{
- xf86bpp = bpp;
+ xf86FbBpp = bpp;
return 2;
}
else
{
- ErrorF("Invalid bpp\n");
+ ErrorF("Invalid fbbpp\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-depth"))
+ {
+ int depth;
+ if (++i >= argc)
+ return 0;
+ if (sscanf(argv[i], "%d", &depth) == 1)
+ {
+ xf86Depth = depth;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid depth\n");
return 0;
}
}
@@ -720,9 +1467,9 @@ ddxProcessArgument (argc, argv, i)
return 0;
if (sscanf(argv[i], "%1d%1d%1d", &red, &green, &blue) == 3)
{
- xf86weight.red = red;
- xf86weight.green = green;
- xf86weight.blue = blue;
+ xf86Weight.red = red;
+ xf86Weight.green = green;
+ xf86Weight.blue = blue;
return 2;
}
else
@@ -738,23 +1485,78 @@ ddxProcessArgument (argc, argv, i)
if (++i >= argc)
return 0;
if (sscanf(argv[i], "%lf", &gamma) == 1) {
- if (gamma < 0.1 || gamma > 10) {
- ErrorF("gamma out of range, only 0.1 < gamma_value < 10 is valid\n");
+ if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
+ ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f"
+ " is valid\n", GAMMA_MIN, GAMMA_MAX);
return 0;
}
- if (!strcmp(argv[i-1], "-gamma"))
- xf86rGamma = xf86gGamma = xf86bGamma = 1.0 / gamma;
- else if (!strcmp(argv[i-1], "-rgamma")) xf86rGamma = 1.0 / gamma;
- else if (!strcmp(argv[i-1], "-ggamma")) xf86gGamma = 1.0 / gamma;
- else if (!strcmp(argv[i-1], "-bgamma")) xf86bGamma = 1.0 / gamma;
+ if (!strcmp(argv[i-1], "-gamma"))
+ xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
+ else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
+ else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
+ else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
return 2;
}
}
-#endif /* XF86MONOVGA */
+ if (!strcmp(argv[i], "-layout"))
+ {
+ if (++i >= argc)
+ return 0;
+ xf86LayoutName = argv[i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-screen"))
+ {
+ if (++i >= argc)
+ return 0;
+ xf86ScreenName = argv[i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-pointer"))
+ {
+ if (++i >= argc)
+ return 0;
+ xf86PointerName = argv[i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-keyboard"))
+ {
+ if (++i >= argc)
+ return 0;
+ xf86KeyboardName = argv[i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-nosilk"))
+ {
+ xf86silkenMouseDisableFlag = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-scanpci"))
+ {
+ DoScanPci(argc, argv, i);
+ }
+ if (!strcmp(argv[i], "-probe"))
+ {
+ xf86DoProbe = TRUE;
+#if 0
+ DoProbe(argc, argv, i);
+#endif
+ return 1;
+ }
+ if (!strcmp(argv[i], "-configure"))
+ {
+ if (getuid() != 0) {
+ ErrorF("The '-configure' option can only be used by root.\n");
+ exit(1);
+ }
+ xf86DoConfigure = TRUE;
+ xf86AllowMouseOpenFail = TRUE;
+ return 1;
+ }
+ /* OS-specific processing */
return xf86ProcessArgument(argc, argv, i);
}
-
/*
* ddxUseMsg --
* Print out correct use of device dependent commandline options.
@@ -768,18 +1570,36 @@ ddxUseMsg()
ErrorF("\n");
ErrorF("Device Dependent Usage\n");
if (getuid() == 0)
+ {
ErrorF("-xf86config file specify a configuration file\n");
+ ErrorF("-modulepath paths specify the module search path\n");
+ ErrorF("-logfile file specify a log file name\n");
+ ErrorF("-configure probe for devices and write an XF86Config\n");
+ }
+ else
+ {
+ ErrorF("-xf86config file specify a configuration file, relative to the\n");
+ ErrorF(" XF86Config search path, only root can use absolute\n");
+ }
ErrorF("-probeonly probe for devices, then exit\n");
- ErrorF("-verbose verbose startup messages\n");
+ ErrorF("-scanpci execute the scanpci module and exit\n");
+ ErrorF("-verbose [n] verbose startup messages\n");
+ ErrorF("-logverbose [n] verbose log messages\n");
ErrorF("-quiet minimal startup messages\n");
-#ifndef XF86MONOVGA
- ErrorF("-bpp n set number of bits per pixel. Default: 8\n");
+ ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n");
+ ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n");
+ ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n");
+ ErrorF("-depth n set colour depth. Default: 8\n");
ErrorF("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n");
ErrorF("-rgamma f set gamma value for red phase\n");
ErrorF("-ggamma f set gamma value for green phase\n");
ErrorF("-bgamma f set gamma value for blue phase\n");
ErrorF("-weight nnn set RGB weighting at 16 bpp. Default: 565\n");
-#endif /* XF86MONOVGA */
+ ErrorF("-layout name specify the ServerLayout section name\n");
+ ErrorF("-screen name specify the Screen section name\n");
+ ErrorF("-keyboard name specify the core keyboard InputDevice name\n");
+ ErrorF("-pointer name specify the core pointer InputDevice name\n");
+ ErrorF("-nosilk disable Silken Mouse\n");
ErrorF("-flipPixels swap default black/white Pixel values\n");
#ifdef XF86VIDMODE
ErrorF("-disableVidMode disable mode adjustments with xvidtune\n");
@@ -791,44 +1611,230 @@ ddxUseMsg()
ErrorF(" from non-local clients\n");
ErrorF("-allowMouseOpenFail start server even if the mouse can't be initialized\n");
#endif
- ErrorF("-bestRefresh Chose modes with the best refresh rate\n");
- ErrorF(
- "-showconfig show which drivers are included in the server\n");
+ ErrorF("-bestRefresh choose modes with the best refresh rate\n");
+ ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
+ ErrorF("-version show the server version\n");
+ /* OS-specific usage */
xf86UseMsg();
ErrorF("\n");
}
#ifndef OSNAME
-#define OSNAME "unknown"
+#define OSNAME " unknown"
#endif
#ifndef OSVENDOR
#define OSVENDOR ""
#endif
+#ifndef PRE_RELEASE
+#define PRE_RELEASE XF86_VERSION_SNAP
+#endif
static void
xf86PrintBanner()
{
- ErrorF("\nXFree86 Version%s/ X Window System\n",XF86_VERSION);
- ErrorF("(protocol Version %d, revision %d, vendor release %d)\n",
- X_PROTOCOL, X_PROTOCOL_REVISION, VENDOR_RELEASE );
- ErrorF("Release Date: %s\n", XF86_DATE);
- ErrorF("\tIf the server is older than 6-12 months, or if your card is "
- "newer\n"
- "\tthan the above date, look for a newer version before "
- "reporting\n"
- "\tproblems. (see http://www.XFree86.Org/FAQ)\n");
- ErrorF("Operating System: %s %s\n", OSNAME, OSVENDOR);
+#if PRE_RELEASE
+ ErrorF("\n"
+ "This is a pre-release version of XFree86, and is not supported in any\n"
+ "way. Bugs may be reported to XFree86@XFree86.Org and patches submitted\n"
+ "to fixes@XFree86.Org. Before reporting bugs in pre-release versions,\n"
+ "please check the latest version in the XFree86 CVS repository\n"
+ "(http://www.XFree86.Org/cvs).\n");
+#endif
+ ErrorF("\nXFree86 Version %d.%d.%d", XF86_VERSION_MAJOR, XF86_VERSION_MINOR,
+ XF86_VERSION_PATCH);
+#if XF86_VERSION_SNAP > 0
+ ErrorF(".%d", XF86_VERSION_SNAP);
+#endif
+
+#if XF86_VERSION_SNAP >= 900
+ ErrorF(" (%d.%d.0 RC %d)", XF86_VERSION_MAJOR, XF86_VERSION_MINOR + 1,
+ XF86_VERSION_SNAP - 900);
+#endif
+
+#ifdef XF86_CUSTOM_VERSION
+ ErrorF(" (%s)", XF86_CUSTOM_VERSION);
+#endif
+ ErrorF("\nRelease Date: %s\n", XF86_DATE);
+ ErrorF("X Protocol Version %d, Revision %d, %s\n",
+ X_PROTOCOL, X_PROTOCOL_REVISION, XORG_RELEASE );
+ ErrorF("Build Operating System:%s%s\n", OSNAME, OSVENDOR);
+#ifdef BUILD_DATE
+ {
+ struct tm t;
+ char buf[100];
+
+ bzero(&t, sizeof(t));
+ bzero(buf, sizeof(buf));
+ t.tm_mday = BUILD_DATE % 100;
+ t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
+ t.tm_year = BUILD_DATE / 10000 - 1900;
+ if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
+ ErrorF("Build Date: %s\n", buf);
+ }
+#endif
+#if defined(BUILDERSTRING)
+ ErrorF("%s \n",BUILDERSTRING);
+#endif
+ ErrorF("\tBefore reporting problems, check http://www.XFree86.Org/\n"
+ "\tto make sure that you have the latest version.\n");
+#ifdef XFree86LOADER
+ ErrorF("Module Loader present\n");
+#endif
}
static void
-xf86PrintConfig()
+xf86PrintMarkers()
{
- int i;
+ /* Show what the marker symbols mean */
+ ErrorF("Markers: " X_PROBE_STRING " probed, "
+ X_CONFIG_STRING " from config file, "
+ X_DEFAULT_STRING " default setting,\n"
+ " " X_CMDLINE_STRING " from command line, "
+ X_NOTICE_STRING " notice, "
+ X_INFO_STRING " informational,\n"
+ " " X_WARNING_STRING " warning, "
+ X_ERROR_STRING " error, "
+ X_NOT_IMPLEMENTED_STRING " not implemented, "
+ X_UNKNOWN_STRING " unknown.\n");
+}
+
+static void
+xf86RunVtInit(void)
+{
+ int i;
+
+ /*
+ * If VTInit was set, run that program with consoleFd as stdin and stdout
+ */
+
+ if (xf86Info.vtinit) {
+ switch(fork()) {
+ case -1:
+ FatalError("xf86RunVtInit: fork failed (%s)\n", strerror(errno));
+ break;
+ case 0: /* child */
+ setuid(getuid());
+ /* set stdin, stdout to the consoleFd */
+ for (i = 0; i < 2; i++) {
+ if (xf86Info.consoleFd != i) {
+ close(i);
+ dup(xf86Info.consoleFd);
+ }
+ }
+ execl("/bin/sh", "sh", "-c", xf86Info.vtinit, (void *)NULL);
+ xf86Msg(X_WARNING, "exec of /bin/sh failed for VTInit (%s)\n",
+ strerror(errno));
+ exit(255);
+ break;
+ default: /* parent */
+ wait(NULL);
+ }
+ }
+}
+
+#ifdef XFree86LOADER
+/*
+ * xf86LoadModules iterates over a list that is being passed in.
+ */
+Bool
+xf86LoadModules(char **list, pointer *optlist)
+{
+ int errmaj, errmin;
+ pointer opt;
+ int i;
+ char *name;
+ Bool failed = FALSE;
+
+ if (!list)
+ return TRUE;
+
+ for (i = 0; list[i] != NULL; i++) {
+
+#ifndef NORMALISE_MODULE_NAME
+ name = xstrdup(list[i]);
+#else
+ /* Normalise the module name */
+ name = xf86NormalizeName(list[i]);
+#endif
+
+ /* Skip empty names */
+ if (name == NULL || *name == '\0')
+ continue;
+
+ if (optlist)
+ opt = optlist[i];
+ else
+ opt = NULL;
+
+ if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ failed = TRUE;
+ }
+ xfree(name);
+ }
+ return !failed;
+}
+
+#endif
+
+/* Pixmap format stuff */
- ErrorF("Configured drivers:\n");
- for (i = 0; i < xf86MaxScreens; i++)
- if (xf86Screens[i])
- (xf86Screens[i]->PrintIdent)();
+PixmapFormatPtr
+xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
+{
+ int i;
+ static PixmapFormatRec format; /* XXX not reentrant */
+
+ /*
+ * When the formats[] list initialisation isn't complete, check the
+ * depth 24 pixmap config/cmdline options and screen-specified formats.
+ */
+
+ if (!formatsDone) {
+ if (depth == 24) {
+ Pix24Flags pix24 = Pix24DontCare;
+
+ format.depth = 24;
+ format.scanlinePad = BITMAP_SCANLINE_PAD;
+ if (xf86Info.pixmap24 != Pix24DontCare)
+ pix24 = xf86Info.pixmap24;
+ else if (pScrn->pixmap24 != Pix24DontCare)
+ pix24 = pScrn->pixmap24;
+ if (pix24 == Pix24Use24)
+ format.bitsPerPixel = 24;
+ else
+ format.bitsPerPixel = 32;
+ return &format;
+ }
+ }
+
+ for (i = 0; i < numFormats; i++)
+ if (formats[i].depth == depth)
+ break;
+ if (i != numFormats)
+ return &formats[i];
+ else if (!formatsDone) {
+ /* Check for screen-specified formats */
+ for (i = 0; i < pScrn->numFormats; i++)
+ if (pScrn->formats[i].depth == depth)
+ break;
+ if (i != pScrn->numFormats)
+ return &pScrn->formats[i];
+ }
+ return NULL;
+}
+
+int
+xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
+{
+ PixmapFormatPtr format;
+
+
+ format = xf86GetPixFormat(pScrn, depth);
+ if (format)
+ return format->bitsPerPixel;
+ else
+ return 0;
}