diff options
Diffstat (limited to 'hw/xfree86/common/xf86Init.c')
-rw-r--r-- | hw/xfree86/common/xf86Init.c | 1804 |
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; } |