Example #1
0
/*
 * InitOutput --
 *	Initialize screenInfo for all actually accessible framebuffers.
 *      That includes vt-manager setup, querying all possible devices and
 *      collecting the pixmap formats.
 */
void
InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
{
    int                    i, j, k, scr_index, was_blocked = 0;
    char                   **modulelist;
    pointer                *optionlist;
    Pix24Flags		 screenpix24, pix24;
    MessageType		 pix24From = X_DEFAULT;
    Bool			 pix24Fail = FALSE;
    Bool			 autoconfig = FALSE;
    GDevPtr		 configured_device;

    xf86Initialising = TRUE;

    if (serverGeneration == 1) {
        if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
            xf86ServerName++;
        else
            xf86ServerName = argv[0];

        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 (!xf86DoConfigure && !xf86DoShowOptions) {
            switch (xf86HandleConfigFile(FALSE)) {
            case CONFIG_OK:
                break;
            case CONFIG_PARSE_ERROR:
                xf86Msg(X_ERROR, "Error parsing the config file\n");
                return;
            case CONFIG_NOFILE:
                autoconfig = TRUE;
                break;
            }
        }

        InstallSignalHandlers();

        /* Initialise the loader */
        LoaderInit();

        /* Tell the loader the default module search path */
        LoaderSetPath(xf86ModulePath);

        if (xf86Info.ignoreABI) {
            LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
        }

        if (xf86DoShowOptions)
            DoShowOptions();

        /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
        xf86BusProbe();

        if (xf86DoConfigure)
            DoConfigure();

        if (autoconfig) {
            if (!xf86AutoConfig()) {
                xf86Msg(X_ERROR, "Auto configuration failed\n");
                return;
            }
        }

#ifdef XF86PM
        xf86OSPMClose = xf86OSPMOpen();
#endif

        /* Load all modules specified explicitly in the config file */
        if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
            xf86LoadModules(modulelist, optionlist);
            free(modulelist);
            free(optionlist);
        }

        /* Load all driver modules specified in the config file */
        /* If there aren't any specified in the config file, autoconfig them */
        /* FIXME: Does not handle multiple active screen sections, but I'm not
         * sure if we really want to handle that case*/
        configured_device = xf86ConfigLayout.screens->screen->device;
        if ((!configured_device) || (!configured_device->driver)) {
            if (!autoConfigDevice(configured_device)) {
                xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
                return ;
            }
        }
        if ((modulelist = xf86DriverlistFromConfig())) {
            xf86LoadModules(modulelist, NULL);
            free(modulelist);
        }

        /* Load all input driver modules specified in the config file. */
        if ((modulelist = xf86InputDriverlistFromConfig())) {
            xf86LoadModules(modulelist, NULL);
            free(modulelist);
        }

        /*
         * 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? */

        /*
         * 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 and call the driverFunc to check
         * if HW access is required.  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++) {
            if (xf86DriverList[i]->Identify != NULL)
                xf86DriverList[i]->Identify(0);

            if (!xorgHWAccess || !xorgHWOpenConsole) {
                xorgHWFlags flags;
                if(!xf86DriverList[i]->driverFunc
                        || !xf86DriverList[i]->driverFunc(NULL,
                                GET_REQUIRED_HW_INTERFACES,
                                &flags))
                    flags = HW_IO;

                if(NEED_IO_ENABLED(flags))
                    xorgHWAccess = TRUE;
                if(!(flags & HW_SKIP_CONSOLE))
                    xorgHWOpenConsole = TRUE;
            }
        }

        if (xorgHWOpenConsole)
            xf86OpenConsole();
        else
            xf86Info.dontVTSwitch = TRUE;

        if (xf86BusConfig() == FALSE)
            return;

        xf86PostProbe();

        /*
         * 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++) {
            xf86VGAarbiterScrnInit(xf86Screens[i]);
            xf86VGAarbiterLock(xf86Screens[i]);
            if (xf86Screens[i]->PreInit &&
                    xf86Screens[i]->PreInit(xf86Screens[i], 0))
                xf86Screens[i]->configured = TRUE;
            xf86VGAarbiterUnlock(xf86Screens[i]);
        }
        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;
        }

        for (i = 0; i < xf86NumScreens; i++) {
            if (xf86Screens[i]->name == NULL) {
                XNFasprintf(&xf86Screens[i]->name, "screen%d", i);
                xf86MsgVerb(X_WARNING, 0,
                            "Screen driver %d has no name set, using `%s'.\n",
                            i, xf86Screens[i]->name);
            }
        }

        /* Remove (unload) drivers that are not required */
        for (i = 0; i < xf86NumDrivers; i++)
            if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
                xf86DeleteDriver(i);

        /*
         * 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?
         */
        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 (xf86Info.vtno >= 0 ) {
#define VT_ATOM_NAME         "XFree86_VT"
            Atom VTAtom=-1;
            CARD32  *VT = NULL;
            int  ret;

            /* This memory needs to stay available until the screen has been
            initialized, and we can create the property for real.
                */
            if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
                FatalError("Unable to make VT property - out of memory. Exiting...\n");
            }
            *VT = xf86Info.vtno;

            VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);

            for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
                ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
                                                     VTAtom, XA_INTEGER, 32,
                                                     1, VT );
                if (ret != Success)
                    xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
                               "Failed to register VT property\n");
            }
        }

        if (SeatId) {
            Atom SeatAtom;

            SeatAtom = MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE);

            for (i = 0; i < xf86NumScreens; i++) {
                int ret;

                ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
                                                     SeatAtom, XA_STRING, 8,
                                                     strlen(SeatId)+1, SeatId );
                if (ret != Success) {
                    xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
                               "Failed to register seat property\n");
                }
            }
        }

        /* 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;
            }
        }
    } else {
        /*
         * serverGeneration != 1; some OSs have to do things here, too.
         */
        if (xorgHWOpenConsole)
            xf86OpenConsole();

#ifdef XF86PM
        /*
          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(X_INFO, 3, "APM registered successfully\n");
#endif

        /* Make sure full I/O access is enabled */
        if (xorgHWAccess)
            xf86EnableIO();
    }

    /*
     * Use the previously collected parts to setup pScreenInfo
     */

    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
            ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
#endif
            xf86AccessEnter();
            was_blocked = xf86BlockSIGIO();
        }
    }

    for (i = 0; i < xf86NumScreens; i++)
        if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
            FatalError("Cannot register DDX private keys");

    if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
            !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
        FatalError("Cannot register DDX private keys");

    for (i = 0; i < xf86NumScreens; i++) {
        xf86VGAarbiterLock(xf86Screens[i]);
        /*
         * Almost everything uses these defaults, and many of those that
         * don't, will wrap them.
         */
        xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
#ifdef XFreeXDGA
        xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
#endif
        xf86Screens[i]->DPMSSet = NULL;
        xf86Screens[i]->LoadPalette = NULL;
        xf86Screens[i]->SetOverscan = NULL;
        xf86Screens[i]->DriverFunc = NULL;
        xf86Screens[i]->pScreen = NULL;
        scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
        xf86VGAarbiterUnlock(xf86Screens[i]);
        if (scr_index == i) {
            /*
             * Hook in our ScrnInfoRec, and initialise some other pScreen
             * fields.
             */
            dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
                          xf86ScreenKey, 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);
        }

        DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
               i, xf86Screens[i]->pScreen );
        DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
               i, xf86Screens[i]->pScreen->CreateWindow );

        dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
                      xf86CreateRootWindowKey,
                      xf86Screens[i]->pScreen->CreateWindow);
        xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;

        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);
        }
#ifdef RANDR
        if (!xf86Info.disableRandR)
            xf86RandRInit (screenInfo.screens[scr_index]);
        xf86Msg(xf86Info.randRFrom, "RandR %s\n",
                xf86Info.disableRandR ? "disabled" : "enabled");
#endif
    }

    xf86VGAarbiterWrapFunctions();
    xf86UnblockSIGIO(was_blocked);

    xf86InitOrigins();

    xf86Resetting = FALSE;
    xf86Initialising = FALSE;

    RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
                                   NULL);
}
Example #2
0
Bool
xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
		int depth24flags)
{
    int i;
    DispPtr disp;
    Pix24Flags pix24 = xf86Info.pixmap24;
    Bool nomatch = FALSE;

    scrp->bitsPerPixel = -1;
    scrp->depth = -1;
    scrp->pixmap24 = Pix24DontCare;
    scrp->bitsPerPixelFrom = X_DEFAULT;
    scrp->depthFrom = X_DEFAULT;

    if (xf86FbBpp > 0) {
	scrp->bitsPerPixel = xf86FbBpp;
	scrp->bitsPerPixelFrom = X_CMDLINE;
    }

    if (xf86Depth > 0) {
	scrp->depth = xf86Depth;
	scrp->depthFrom = X_CMDLINE;
    }

    if (xf86FbBpp < 0 && xf86Depth < 0) {
	if (scrp->confScreen->defaultfbbpp > 0) {
	    scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
	    scrp->bitsPerPixelFrom = X_CONFIG;
	}
	if (scrp->confScreen->defaultdepth > 0) {
	    scrp->depth = scrp->confScreen->defaultdepth;
	    scrp->depthFrom = X_CONFIG;
	}

	if (scrp->confScreen->defaultfbbpp <= 0 &&
	    scrp->confScreen->defaultdepth <= 0) {
	    /*
	     * Check for DefaultDepth and DefaultFbBpp options in the
	     * Device sections.
	     */
	    int i;
	    GDevPtr device;
	    Bool found = FALSE;

	    for (i = 0; i < scrp->numEntities; i++) {
		device = xf86GetDevFromEntity(scrp->entityList[i],
					      scrp->entityInstanceList[i]);
		if (device && device->options) {
		    if (xf86FindOption(device->options, "DefaultDepth")) {
			scrp->depth = xf86SetIntOption(device->options,
						       "DefaultDepth", -1);
			scrp->depthFrom = X_CONFIG;
			found = TRUE;
		    }
		    if (xf86FindOption(device->options, "DefaultFbBpp")) {
			scrp->bitsPerPixel = xf86SetIntOption(device->options,
							      "DefaultFbBpp",
							      -1);
			scrp->bitsPerPixelFrom = X_CONFIG;
			found = TRUE;
		    }
		}
		if (found)
		    break;
	    }
	}
    }

    /* If none of these is set, pick a default */
    if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
        if (fbbpp > 0 || depth > 0) {
	    if (fbbpp > 0)
		scrp->bitsPerPixel = fbbpp;
	    if (depth > 0)
		scrp->depth = depth;
	} else {
	    scrp->depth = GLOBAL_DEFAULT_DEPTH;
	}
    }

    /* If any are not given, determine a default for the others */

    if (scrp->bitsPerPixel < 0) {
	/* The depth must be set */
	if (scrp->depth > -1) {
	    if (scrp->depth == 1)
		scrp->bitsPerPixel = 1;
	    else if (scrp->depth <= 4)
		scrp->bitsPerPixel = 4;
	    else if (scrp->depth <= 8)
		scrp->bitsPerPixel = 8;
	    else if (scrp->depth <= 16)
		scrp->bitsPerPixel = 16;
	    else if (scrp->depth <= 24) {
		/*
		 * Figure out if a choice is possible based on the depth24
		 * and pix24 flags.
		 */
		/* Check pix24 first */
		if (pix24 != Pix24DontCare) {
		    if (pix24 == Pix24Use32) {
			if (DO_PIX32(depth24flags)) {
			    if (CHOOSE24FOR32(depth24flags))
				scrp->bitsPerPixel = 24;
			    else
				scrp->bitsPerPixel = 32;
			} else {
			    nomatch = TRUE;
			}
		    } else if (pix24 == Pix24Use24) {
			if (DO_PIX24(depth24flags)) {
			    if (CHOOSE32FOR24(depth24flags))
				scrp->bitsPerPixel = 32;
			    else
				scrp->bitsPerPixel = 24;
			} else {
			    nomatch = TRUE;
			}
		    }
		} else {
		    if (DO_PIX32(depth24flags)) {
			if (CHOOSE24FOR32(depth24flags))
			    scrp->bitsPerPixel = 24;
			else
			    scrp->bitsPerPixel = 32;
		    } else if (DO_PIX24(depth24flags)) {
			if (CHOOSE32FOR24(depth24flags))
			    scrp->bitsPerPixel = 32;
			else
			    scrp->bitsPerPixel = 24;
		    }
		}
	    } else if (scrp->depth <= 32)
		scrp->bitsPerPixel = 32;
	    else {
		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
			   "Specified depth (%d) is greater than 32\n",
			   scrp->depth);
		return FALSE;
	    }
	} else {
	    xf86DrvMsg(scrp->scrnIndex, X_ERROR,
			"xf86SetDepthBpp: internal error: depth and fbbpp"
			" are both not set\n");
	    return FALSE;
	}
	if (scrp->bitsPerPixel < 0) {
	    if (nomatch)
		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
			"Driver can't support depth 24 pixmap format (%d)\n",
			PIX24TOBPP(pix24));
	    else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
		     NoDepth24Support)
		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
			"Driver can't support depth 24\n");
	    else
		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
			"Can't find fbbpp for depth 24\n");
	    return FALSE;
	}
	scrp->bitsPerPixelFrom = X_PROBED;
    }

    if (scrp->depth <= 0) {
	/* bitsPerPixel is already set */
	switch (scrp->bitsPerPixel) {
	case 32:
	    scrp->depth = 24;
	    break;
	default:
	    /* 1, 4, 8, 16 and 24 */
	    scrp->depth = scrp->bitsPerPixel;
	    break;
	}
	scrp->depthFrom = X_PROBED;
    }

    /* Sanity checks */
    if (scrp->depth < 1 || scrp->depth > 32) {
	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
		   "Specified depth (%d) is not in the range 1-32\n",
		    scrp->depth);
	return FALSE;
    }
    switch (scrp->bitsPerPixel) {
    case 1:
    case 4:
    case 8:
    case 16:
    case 24:
    case 32:
	break;
    default:
	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
		   "Specified fbbpp (%d) is not a permitted value\n",
		   scrp->bitsPerPixel);
	return FALSE;
    }
    if (scrp->depth > scrp->bitsPerPixel) {
	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
		   "Specified depth (%d) is greater than the fbbpp (%d)\n",
		   scrp->depth, scrp->bitsPerPixel);
	return FALSE;
    }

    /* set scrp->pixmap24 if the driver isn't flexible */
    if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
	scrp->pixmap24 = Pix24Use24;
    }
    if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
	scrp->pixmap24 = Pix24Use32;
    }

    /*
     * Find the Display subsection matching the depth/fbbpp and initialise
     * scrp->display with it.
     */
    for (i = 0, disp = scrp->confScreen->displays;
	 i < scrp->confScreen->numdisplays; i++, disp++) {
	if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
	    || (disp->depth == scrp->depth && disp->fbbpp <= 0)
	    || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
	    scrp->display = disp;
	    break;
	}
    }

    /*
     * If an exact match can't be found, see if there is one with no
     * depth or fbbpp specified.
     */
    if (i == scrp->confScreen->numdisplays) {
	for (i = 0, disp = scrp->confScreen->displays;
	     i < scrp->confScreen->numdisplays; i++, disp++) {
	    if (disp->depth <= 0 && disp->fbbpp <= 0) {
		scrp->display = disp;
		break;
	    }
	}
    }

    /*
     * If all else fails, create a default one.
     */
    if (i == scrp->confScreen->numdisplays) {
	scrp->confScreen->numdisplays++;
	scrp->confScreen->displays =
		xnfrealloc(scrp->confScreen->displays,
			   scrp->confScreen->numdisplays * sizeof(DispRec));
	xf86DrvMsg(scrp->scrnIndex, X_INFO,
		   "Creating default Display subsection in Screen section\n"
		   "\t\"%s\" for depth/fbbpp %d/%d\n",
		   scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
	memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
	scrp->confScreen->displays[i].blackColour.red = -1;
	scrp->confScreen->displays[i].blackColour.green = -1;
	scrp->confScreen->displays[i].blackColour.blue = -1;
	scrp->confScreen->displays[i].whiteColour.red = -1;
	scrp->confScreen->displays[i].whiteColour.green = -1;
	scrp->confScreen->displays[i].whiteColour.blue = -1;
	scrp->confScreen->displays[i].defaultVisual = -1;
	scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
	scrp->confScreen->displays[i].modes[0] = NULL;
	scrp->confScreen->displays[i].depth = depth;
	scrp->confScreen->displays[i].fbbpp = fbbpp;
	scrp->display = &scrp->confScreen->displays[i];
    }

    /*
     * Setup defaults for the display-wide attributes the framebuffer will
     * need.  These defaults should eventually be set globally, and not
     * dependent on the screens.
     */
    scrp->imageByteOrder = IMAGE_BYTE_ORDER;
    scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
    if (scrp->depth < 8) {
	/* Planar modes need these settings */
	scrp->bitmapScanlineUnit = 8;
	scrp->bitmapBitOrder = MSBFirst;
    } else {
	scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
	scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
    }

    /*
     * If an unusual depth is required, add it to scrp->formats.  The formats
     * for the common depths are handled globally in InitOutput
     */
    switch (scrp->depth) {
    case 1:
    case 4:
    case 8:
    case 15:
    case 16:
    case 24:
	/* Common depths.  Nothing to do for them */
	break;
    default:
	if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
	    xf86DrvMsg(scrp->scrnIndex, X_ERROR,
		       "Can't add pixmap format for depth %d\n", scrp->depth);
	    return FALSE;
	}
    }

    /* Initialise the framebuffer format for this screen */
    scrp->fbFormat.depth = scrp->depth;
    scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
    scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;

    return TRUE;
}