InitOutput.c revision 6747b715
105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright 1993, 1998  The Open Group
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included
1205b261ecSmrgin all copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1505b261ecSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1605b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1705b261ecSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
1805b261ecSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1905b261ecSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2005b261ecSmrgOTHER DEALINGS IN THE SOFTWARE.
2105b261ecSmrg
2205b261ecSmrgExcept as contained in this notice, the name of The Open Group shall
2305b261ecSmrgnot be used in advertising or otherwise to promote the sale, use or
2405b261ecSmrgother dealings in this Software without prior written authorization
2505b261ecSmrgfrom The Open Group.
2605b261ecSmrg
2705b261ecSmrg*/
2805b261ecSmrg
2905b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3005b261ecSmrg#include <dix-config.h>
3105b261ecSmrg#endif
3205b261ecSmrg
3305b261ecSmrg#if defined(WIN32)
3405b261ecSmrg#include <X11/Xwinsock.h>
3505b261ecSmrg#endif
3605b261ecSmrg#include <stdio.h>
3705b261ecSmrg#include <X11/X.h>
3805b261ecSmrg#include <X11/Xproto.h>
3905b261ecSmrg#include <X11/Xos.h>
4005b261ecSmrg#include "scrnintstr.h"
4105b261ecSmrg#include "servermd.h"
4205b261ecSmrg#define PSZ 8
4305b261ecSmrg#include "fb.h"
4405b261ecSmrg#include "mibstore.h"
4505b261ecSmrg#include "colormapst.h"
4605b261ecSmrg#include "gcstruct.h"
4705b261ecSmrg#include "input.h"
4805b261ecSmrg#include "mipointer.h"
4905b261ecSmrg#include "micmap.h"
5005b261ecSmrg#include <sys/types.h>
5105b261ecSmrg#ifdef HAS_MMAP
5205b261ecSmrg#include <sys/mman.h>
5305b261ecSmrg#ifndef MAP_FILE
5405b261ecSmrg#define MAP_FILE 0
5505b261ecSmrg#endif
5605b261ecSmrg#endif /* HAS_MMAP */
5705b261ecSmrg#include <sys/stat.h>
5805b261ecSmrg#include <errno.h>
5905b261ecSmrg#ifndef WIN32
6005b261ecSmrg#include <sys/param.h>
6105b261ecSmrg#endif
6205b261ecSmrg#include <X11/XWDFile.h>
6305b261ecSmrg#ifdef HAS_SHM
6405b261ecSmrg#include <sys/ipc.h>
6505b261ecSmrg#include <sys/shm.h>
6605b261ecSmrg#endif /* HAS_SHM */
6705b261ecSmrg#include "dix.h"
6805b261ecSmrg#include "miline.h"
6905b261ecSmrg
7005b261ecSmrg#define VFB_DEFAULT_WIDTH      1280
7105b261ecSmrg#define VFB_DEFAULT_HEIGHT     1024
7205b261ecSmrg#define VFB_DEFAULT_DEPTH         8
7305b261ecSmrg#define VFB_DEFAULT_WHITEPIXEL    1
7405b261ecSmrg#define VFB_DEFAULT_BLACKPIXEL    0
7505b261ecSmrg#define VFB_DEFAULT_LINEBIAS      0
7605b261ecSmrg#define XWD_WINDOW_NAME_LEN      60
7705b261ecSmrg
7805b261ecSmrgtypedef struct
7905b261ecSmrg{
8005b261ecSmrg    int width;
8105b261ecSmrg    int paddedBytesWidth;
8205b261ecSmrg    int paddedWidth;
8305b261ecSmrg    int height;
8405b261ecSmrg    int depth;
8505b261ecSmrg    int bitsPerPixel;
8605b261ecSmrg    int sizeInBytes;
8705b261ecSmrg    int ncolors;
8805b261ecSmrg    char *pfbMemory;
8905b261ecSmrg    XWDColor *pXWDCmap;
9005b261ecSmrg    XWDFileHeader *pXWDHeader;
9105b261ecSmrg    Pixel blackPixel;
9205b261ecSmrg    Pixel whitePixel;
9305b261ecSmrg    unsigned int lineBias;
9405b261ecSmrg    CloseScreenProcPtr closeScreen;
9505b261ecSmrg
9605b261ecSmrg#ifdef HAS_MMAP
9705b261ecSmrg    int mmap_fd;
9805b261ecSmrg    char mmap_file[MAXPATHLEN];
9905b261ecSmrg#endif
10005b261ecSmrg
10105b261ecSmrg#ifdef HAS_SHM
10205b261ecSmrg    int shmid;
10305b261ecSmrg#endif
10405b261ecSmrg} vfbScreenInfo, *vfbScreenInfoPtr;
10505b261ecSmrg
10605b261ecSmrgstatic int vfbNumScreens;
1076747b715Smrgstatic vfbScreenInfo *vfbScreens;
1086747b715Smrgstatic vfbScreenInfo defaultScreenInfo = {
1096747b715Smrg    .width  = VFB_DEFAULT_WIDTH,
1106747b715Smrg    .height = VFB_DEFAULT_HEIGHT,
1116747b715Smrg    .depth  = VFB_DEFAULT_DEPTH,
1126747b715Smrg    .blackPixel = VFB_DEFAULT_BLACKPIXEL,
1136747b715Smrg    .whitePixel = VFB_DEFAULT_WHITEPIXEL,
1146747b715Smrg    .lineBias = VFB_DEFAULT_LINEBIAS,
1156747b715Smrg};
11605b261ecSmrgstatic Bool vfbPixmapDepths[33];
11705b261ecSmrg#ifdef HAS_MMAP
11805b261ecSmrgstatic char *pfbdir = NULL;
11905b261ecSmrg#endif
12005b261ecSmrgtypedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
12105b261ecSmrgstatic fbMemType fbmemtype = NORMAL_MEMORY_FB;
12205b261ecSmrgstatic char needswap = 0;
12305b261ecSmrgstatic Bool Render = TRUE;
12405b261ecSmrg
12505b261ecSmrg#define swapcopy16(_dst, _src) \
12605b261ecSmrg    if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
12705b261ecSmrg    else _dst = _src;
12805b261ecSmrg
12905b261ecSmrg#define swapcopy32(_dst, _src) \
13005b261ecSmrg    if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
13105b261ecSmrg    else _dst = _src;
13205b261ecSmrg
13305b261ecSmrg
13405b261ecSmrgstatic void
13505b261ecSmrgvfbInitializePixmapDepths(void)
13605b261ecSmrg{
13705b261ecSmrg    int i;
13805b261ecSmrg    vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
13905b261ecSmrg    for (i = 2; i <= 32; i++)
14005b261ecSmrg	vfbPixmapDepths[i] = FALSE;
14105b261ecSmrg}
14205b261ecSmrg
14305b261ecSmrgstatic int
14405b261ecSmrgvfbBitsPerPixel(int depth)
14505b261ecSmrg{
14605b261ecSmrg    if (depth == 1) return 1;
14705b261ecSmrg    else if (depth <= 8) return 8;
14805b261ecSmrg    else if (depth <= 16) return 16;
14905b261ecSmrg    else return 32;
15005b261ecSmrg}
15105b261ecSmrg
15205b261ecSmrgvoid
1536747b715SmrgddxGiveUp(void)
15405b261ecSmrg{
15505b261ecSmrg    int i;
15605b261ecSmrg
15705b261ecSmrg    /* clean up the framebuffers */
15805b261ecSmrg
15905b261ecSmrg    switch (fbmemtype)
16005b261ecSmrg    {
16105b261ecSmrg#ifdef HAS_MMAP
16205b261ecSmrg    case MMAPPED_FILE_FB:
16305b261ecSmrg	for (i = 0; i < vfbNumScreens; i++)
16405b261ecSmrg	{
16505b261ecSmrg	    if (-1 == unlink(vfbScreens[i].mmap_file))
16605b261ecSmrg	    {
16705b261ecSmrg		perror("unlink");
1684642e01fSmrg		ErrorF("unlink %s failed, %s",
1694642e01fSmrg		       vfbScreens[i].mmap_file, strerror(errno));
17005b261ecSmrg	    }
17105b261ecSmrg	}
17205b261ecSmrg	break;
17305b261ecSmrg#else /* HAS_MMAP */
17405b261ecSmrg    case MMAPPED_FILE_FB:
17505b261ecSmrg        break;
17605b261ecSmrg#endif /* HAS_MMAP */
17705b261ecSmrg
17805b261ecSmrg#ifdef HAS_SHM
17905b261ecSmrg    case SHARED_MEMORY_FB:
18005b261ecSmrg	for (i = 0; i < vfbNumScreens; i++)
18105b261ecSmrg	{
18205b261ecSmrg	    if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
18305b261ecSmrg	    {
18405b261ecSmrg		perror("shmdt");
1854642e01fSmrg		ErrorF("shmdt failed, %s", strerror(errno));
18605b261ecSmrg	    }
18705b261ecSmrg	}
18805b261ecSmrg	break;
18905b261ecSmrg#else /* HAS_SHM */
19005b261ecSmrg    case SHARED_MEMORY_FB:
19105b261ecSmrg        break;
19205b261ecSmrg#endif /* HAS_SHM */
19305b261ecSmrg
19405b261ecSmrg    case NORMAL_MEMORY_FB:
19505b261ecSmrg	for (i = 0; i < vfbNumScreens; i++)
19605b261ecSmrg	{
1976747b715Smrg	    free(vfbScreens[i].pXWDHeader);
19805b261ecSmrg	}
19905b261ecSmrg	break;
20005b261ecSmrg    }
20105b261ecSmrg}
20205b261ecSmrg
20305b261ecSmrgvoid
2046747b715SmrgAbortDDX(void)
20505b261ecSmrg{
20605b261ecSmrg    ddxGiveUp();
20705b261ecSmrg}
20805b261ecSmrg
2094642e01fSmrg#ifdef __APPLE__
21005b261ecSmrgvoid
21105b261ecSmrgDarwinHandleGUI(int argc, char *argv[])
21205b261ecSmrg{
21305b261ecSmrg}
21405b261ecSmrg#endif
21505b261ecSmrg
21605b261ecSmrgvoid
2176747b715SmrgOsVendorInit(void)
21805b261ecSmrg{
21905b261ecSmrg}
22005b261ecSmrg
22105b261ecSmrgvoid
2226747b715SmrgOsVendorFatalError(void)
22305b261ecSmrg{
22405b261ecSmrg}
22505b261ecSmrg
22605b261ecSmrg#if defined(DDXBEFORERESET)
22705b261ecSmrgvoid ddxBeforeReset(void)
22805b261ecSmrg{
22905b261ecSmrg    return;
23005b261ecSmrg}
23105b261ecSmrg#endif
23205b261ecSmrg
23305b261ecSmrgvoid
2346747b715SmrgddxUseMsg(void)
23505b261ecSmrg{
23605b261ecSmrg    ErrorF("-screen scrn WxHxD     set screen's width, height, depth\n");
23705b261ecSmrg    ErrorF("-pixdepths list-of-int support given pixmap depths\n");
2386747b715Smrg    ErrorF("+/-render		   turn on/off RENDER extension support"
23905b261ecSmrg	   "(default on)\n");
24005b261ecSmrg    ErrorF("-linebias n            adjust thin line pixelization\n");
24105b261ecSmrg    ErrorF("-blackpixel n          pixel value for black\n");
24205b261ecSmrg    ErrorF("-whitepixel n          pixel value for white\n");
24305b261ecSmrg
24405b261ecSmrg#ifdef HAS_MMAP
24505b261ecSmrg    ErrorF("-fbdir directory       put framebuffers in mmap'ed files in directory\n");
24605b261ecSmrg#endif
24705b261ecSmrg
24805b261ecSmrg#ifdef HAS_SHM
24905b261ecSmrg    ErrorF("-shmem                 put framebuffers in shared memory\n");
25005b261ecSmrg#endif
25105b261ecSmrg}
25205b261ecSmrg
25305b261ecSmrgint
25405b261ecSmrgddxProcessArgument(int argc, char *argv[], int i)
25505b261ecSmrg{
25605b261ecSmrg    static Bool firstTime = TRUE;
2576747b715Smrg    static int lastScreen = -1;
2586747b715Smrg    vfbScreenInfo *currentScreen;
25905b261ecSmrg
26005b261ecSmrg    if (firstTime)
26105b261ecSmrg    {
26205b261ecSmrg	vfbInitializePixmapDepths();
26305b261ecSmrg        firstTime = FALSE;
26405b261ecSmrg    }
26505b261ecSmrg
2666747b715Smrg    if (lastScreen == -1)
2676747b715Smrg	currentScreen = &defaultScreenInfo;
2686747b715Smrg    else
2696747b715Smrg	currentScreen = &vfbScreens[lastScreen];
2706747b715Smrg
27105b261ecSmrg#define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
27205b261ecSmrg    if (((i + num) >= argc) || (!argv[i + num])) {                      \
27305b261ecSmrg      ErrorF("Required argument to %s not specified\n", argv[i]);       \
27405b261ecSmrg      UseMsg();                                                         \
27505b261ecSmrg      FatalError("Required argument to %s not specified\n", argv[i]);   \
27605b261ecSmrg    }
27705b261ecSmrg
27805b261ecSmrg    if (strcmp (argv[i], "-screen") == 0)	/* -screen n WxHxD */
27905b261ecSmrg    {
28005b261ecSmrg	int screenNum;
28105b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(2);
28205b261ecSmrg	screenNum = atoi(argv[i+1]);
2836747b715Smrg	if (screenNum < 0)
28405b261ecSmrg	{
28505b261ecSmrg	    ErrorF("Invalid screen number %d\n", screenNum);
28605b261ecSmrg	    UseMsg();
28705b261ecSmrg	    FatalError("Invalid screen number %d passed to -screen\n",
28805b261ecSmrg		       screenNum);
28905b261ecSmrg	}
2906747b715Smrg
2916747b715Smrg	if (vfbNumScreens <= screenNum)
2926747b715Smrg	{
2936747b715Smrg	    vfbScreens = realloc(vfbScreens, sizeof(*vfbScreens) * (screenNum + 1));
2946747b715Smrg	    if (!vfbScreens)
2956747b715Smrg		FatalError("Not enough memory for screen %d\n", screenNum);
2966747b715Smrg	    for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
2976747b715Smrg		vfbScreens[vfbNumScreens] = defaultScreenInfo;
2986747b715Smrg	}
2996747b715Smrg
30005b261ecSmrg	if (3 != sscanf(argv[i+2], "%dx%dx%d",
30105b261ecSmrg			&vfbScreens[screenNum].width,
30205b261ecSmrg			&vfbScreens[screenNum].height,
30305b261ecSmrg			&vfbScreens[screenNum].depth))
30405b261ecSmrg	{
30505b261ecSmrg	    ErrorF("Invalid screen configuration %s\n", argv[i+2]);
30605b261ecSmrg	    UseMsg();
30705b261ecSmrg	    FatalError("Invalid screen configuration %s for -screen %d\n",
30805b261ecSmrg		   argv[i+2], screenNum);
30905b261ecSmrg	}
31005b261ecSmrg
31105b261ecSmrg	lastScreen = screenNum;
31205b261ecSmrg	return 3;
31305b261ecSmrg    }
31405b261ecSmrg
31505b261ecSmrg    if (strcmp (argv[i], "-pixdepths") == 0)	/* -pixdepths list-of-depth */
31605b261ecSmrg    {
31705b261ecSmrg	int depth, ret = 1;
31805b261ecSmrg
31905b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
32005b261ecSmrg	while ((++i < argc) && (depth = atoi(argv[i])) != 0)
32105b261ecSmrg	{
32205b261ecSmrg	    if (depth < 0 || depth > 32)
32305b261ecSmrg	    {
32405b261ecSmrg		ErrorF("Invalid pixmap depth %d\n", depth);
32505b261ecSmrg		UseMsg();
32605b261ecSmrg		FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
32705b261ecSmrg			   depth);
32805b261ecSmrg	    }
32905b261ecSmrg	    vfbPixmapDepths[depth] = TRUE;
33005b261ecSmrg	    ret++;
33105b261ecSmrg	}
33205b261ecSmrg	return ret;
33305b261ecSmrg    }
33405b261ecSmrg
33505b261ecSmrg    if (strcmp (argv[i], "+render") == 0)	/* +render */
33605b261ecSmrg    {
33705b261ecSmrg	Render = TRUE;
33805b261ecSmrg	return 1;
33905b261ecSmrg    }
34005b261ecSmrg
34105b261ecSmrg    if (strcmp (argv[i], "-render") == 0)	/* -render */
34205b261ecSmrg    {
34305b261ecSmrg	Render = FALSE;
34405b261ecSmrg#ifdef COMPOSITE
34505b261ecSmrg	noCompositeExtension = TRUE;
34605b261ecSmrg#endif
34705b261ecSmrg	return 1;
34805b261ecSmrg    }
34905b261ecSmrg
35005b261ecSmrg    if (strcmp (argv[i], "-blackpixel") == 0)	/* -blackpixel n */
35105b261ecSmrg    {
35205b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
3536747b715Smrg	currentScreen->blackPixel = atoi(argv[++i]);
35405b261ecSmrg	return 2;
35505b261ecSmrg    }
35605b261ecSmrg
35705b261ecSmrg    if (strcmp (argv[i], "-whitepixel") == 0)	/* -whitepixel n */
35805b261ecSmrg    {
35905b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
3606747b715Smrg	currentScreen->whitePixel = atoi(argv[++i]);
36105b261ecSmrg	return 2;
36205b261ecSmrg    }
36305b261ecSmrg
36405b261ecSmrg    if (strcmp (argv[i], "-linebias") == 0)	/* -linebias n */
36505b261ecSmrg    {
36605b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
3676747b715Smrg	currentScreen->lineBias = atoi(argv[++i]);
36805b261ecSmrg	return 2;
36905b261ecSmrg    }
37005b261ecSmrg
37105b261ecSmrg#ifdef HAS_MMAP
37205b261ecSmrg    if (strcmp (argv[i], "-fbdir") == 0)	/* -fbdir directory */
37305b261ecSmrg    {
37405b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
37505b261ecSmrg	pfbdir = argv[++i];
37605b261ecSmrg	fbmemtype = MMAPPED_FILE_FB;
37705b261ecSmrg	return 2;
37805b261ecSmrg    }
37905b261ecSmrg#endif /* HAS_MMAP */
38005b261ecSmrg
38105b261ecSmrg#ifdef HAS_SHM
38205b261ecSmrg    if (strcmp (argv[i], "-shmem") == 0)	/* -shmem */
38305b261ecSmrg    {
38405b261ecSmrg	fbmemtype = SHARED_MEMORY_FB;
38505b261ecSmrg	return 1;
38605b261ecSmrg    }
38705b261ecSmrg#endif
38805b261ecSmrg
38905b261ecSmrg    return 0;
39005b261ecSmrg}
39105b261ecSmrg
3926747b715Smrgstatic DevPrivateKeyRec cmapScrPrivateKeyRec;
3936747b715Smrg#define cmapScrPrivateKey (&cmapScrPrivateKeyRec)
3946747b715Smrg
3956747b715Smrg#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
3966747b715Smrg#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
39705b261ecSmrg
39805b261ecSmrgstatic int
39905b261ecSmrgvfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
40005b261ecSmrg{
40105b261ecSmrg    /* By the time we are processing requests, we can guarantee that there
40205b261ecSmrg     * is always a colormap installed */
4036747b715Smrg    *pmaps = GetInstalledColormap(pScreen)->mid;
4046747b715Smrg    return 1;
40505b261ecSmrg}
40605b261ecSmrg
40705b261ecSmrg
40805b261ecSmrgstatic void
40905b261ecSmrgvfbInstallColormap(ColormapPtr pmap)
41005b261ecSmrg{
4116747b715Smrg    ColormapPtr oldpmap = GetInstalledColormap(pmap->pScreen);
41205b261ecSmrg
41305b261ecSmrg    if (pmap != oldpmap)
41405b261ecSmrg    {
41505b261ecSmrg	int entries;
41605b261ecSmrg	XWDFileHeader *pXWDHeader;
41705b261ecSmrg	XWDColor *pXWDCmap;
41805b261ecSmrg	VisualPtr pVisual;
41905b261ecSmrg	Pixel *     ppix;
42005b261ecSmrg	xrgb *      prgb;
42105b261ecSmrg	xColorItem *defs;
42205b261ecSmrg	int i;
42305b261ecSmrg
42405b261ecSmrg	if(oldpmap != (ColormapPtr)None)
42505b261ecSmrg	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
42605b261ecSmrg	/* Install pmap */
4276747b715Smrg	SetInstalledColormap(pmap->pScreen, pmap);
42805b261ecSmrg	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
42905b261ecSmrg
43005b261ecSmrg	entries = pmap->pVisual->ColormapEntries;
43105b261ecSmrg	pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
43205b261ecSmrg	pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
43305b261ecSmrg	pVisual = pmap->pVisual;
43405b261ecSmrg
43505b261ecSmrg	swapcopy32(pXWDHeader->visual_class, pVisual->class);
43605b261ecSmrg	swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
43705b261ecSmrg	swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
43805b261ecSmrg	swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
43905b261ecSmrg	swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
44005b261ecSmrg	swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
44105b261ecSmrg
4426747b715Smrg	ppix = (Pixel *)malloc(entries * sizeof(Pixel));
4436747b715Smrg	prgb = (xrgb *)malloc(entries * sizeof(xrgb));
4446747b715Smrg	defs = (xColorItem *)malloc(entries * sizeof(xColorItem));
44505b261ecSmrg
44605b261ecSmrg	for (i = 0; i < entries; i++)  ppix[i] = i;
44705b261ecSmrg	/* XXX truecolor */
4486747b715Smrg	QueryColors(pmap, entries, ppix, prgb, serverClient);
44905b261ecSmrg
45005b261ecSmrg	for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
45105b261ecSmrg	    defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
45205b261ecSmrg	    defs[i].red = prgb[i].red;
45305b261ecSmrg	    defs[i].green = prgb[i].green;
45405b261ecSmrg	    defs[i].blue = prgb[i].blue;
45505b261ecSmrg	    defs[i].flags =  DoRed|DoGreen|DoBlue;
45605b261ecSmrg	}
45705b261ecSmrg	(*pmap->pScreen->StoreColors)(pmap, entries, defs);
45805b261ecSmrg
4596747b715Smrg	free(ppix);
4606747b715Smrg	free(prgb);
4616747b715Smrg	free(defs);
46205b261ecSmrg    }
46305b261ecSmrg}
46405b261ecSmrg
46505b261ecSmrgstatic void
46605b261ecSmrgvfbUninstallColormap(ColormapPtr pmap)
46705b261ecSmrg{
4686747b715Smrg    ColormapPtr curpmap = GetInstalledColormap(pmap->pScreen);
46905b261ecSmrg
47005b261ecSmrg    if(pmap == curpmap)
47105b261ecSmrg    {
47205b261ecSmrg	if (pmap->mid != pmap->pScreen->defColormap)
47305b261ecSmrg	{
4746747b715Smrg	    dixLookupResourceByType((pointer *)&curpmap,
4756747b715Smrg				    pmap->pScreen->defColormap,
4766747b715Smrg				    RT_COLORMAP, serverClient,
4776747b715Smrg				    DixInstallAccess);
47805b261ecSmrg	    (*pmap->pScreen->InstallColormap)(curpmap);
47905b261ecSmrg	}
48005b261ecSmrg    }
48105b261ecSmrg}
48205b261ecSmrg
48305b261ecSmrgstatic void
48405b261ecSmrgvfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
48505b261ecSmrg{
48605b261ecSmrg    XWDColor *pXWDCmap;
48705b261ecSmrg    int i;
48805b261ecSmrg
4896747b715Smrg    if (pmap != GetInstalledColormap(pmap->pScreen))
49005b261ecSmrg    {
49105b261ecSmrg	return;
49205b261ecSmrg    }
49305b261ecSmrg
49405b261ecSmrg    pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
49505b261ecSmrg
49605b261ecSmrg    if ((pmap->pVisual->class | DynamicClass) == DirectColor)
49705b261ecSmrg    {
49805b261ecSmrg	return;
49905b261ecSmrg    }
50005b261ecSmrg
50105b261ecSmrg    for (i = 0; i < ndef; i++)
50205b261ecSmrg    {
50305b261ecSmrg	if (pdefs[i].flags & DoRed)
50405b261ecSmrg	{
50505b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
50605b261ecSmrg	}
50705b261ecSmrg	if (pdefs[i].flags & DoGreen)
50805b261ecSmrg	{
50905b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
51005b261ecSmrg	}
51105b261ecSmrg	if (pdefs[i].flags & DoBlue)
51205b261ecSmrg	{
51305b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
51405b261ecSmrg	}
51505b261ecSmrg    }
51605b261ecSmrg}
51705b261ecSmrg
51805b261ecSmrgstatic Bool
51905b261ecSmrgvfbSaveScreen(ScreenPtr pScreen, int on)
52005b261ecSmrg{
52105b261ecSmrg    return TRUE;
52205b261ecSmrg}
52305b261ecSmrg
52405b261ecSmrg#ifdef HAS_MMAP
52505b261ecSmrg
52605b261ecSmrg/* this flushes any changes to the screens out to the mmapped file */
52705b261ecSmrgstatic void
52805b261ecSmrgvfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
52905b261ecSmrg{
53005b261ecSmrg    int i;
53105b261ecSmrg
53205b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
53305b261ecSmrg    {
53405b261ecSmrg#ifdef MS_ASYNC
53505b261ecSmrg	if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
53605b261ecSmrg			(size_t)vfbScreens[i].sizeInBytes, MS_ASYNC))
53705b261ecSmrg#else
53805b261ecSmrg	/* silly NetBSD and who else? */
53905b261ecSmrg	if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
54005b261ecSmrg			(size_t)vfbScreens[i].sizeInBytes))
54105b261ecSmrg#endif
54205b261ecSmrg	{
54305b261ecSmrg	    perror("msync");
5444642e01fSmrg	    ErrorF("msync failed, %s", strerror(errno));
54505b261ecSmrg	}
54605b261ecSmrg    }
54705b261ecSmrg}
54805b261ecSmrg
54905b261ecSmrg
55005b261ecSmrgstatic void
55105b261ecSmrgvfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
55205b261ecSmrg{
55305b261ecSmrg}
55405b261ecSmrg
55505b261ecSmrg
55605b261ecSmrgstatic void
55705b261ecSmrgvfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
55805b261ecSmrg{
55905b261ecSmrg#define DUMMY_BUFFER_SIZE 65536
56005b261ecSmrg    char dummyBuffer[DUMMY_BUFFER_SIZE];
56105b261ecSmrg    int currentFileSize, writeThisTime;
56205b261ecSmrg
5636747b715Smrg    sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, (int) (pvfb - vfbScreens));
56405b261ecSmrg    if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
56505b261ecSmrg    {
56605b261ecSmrg	perror("open");
5674642e01fSmrg	ErrorF("open %s failed, %s", pvfb->mmap_file, strerror(errno));
56805b261ecSmrg	return;
56905b261ecSmrg    }
57005b261ecSmrg
57105b261ecSmrg    /* Extend the file to be the proper size */
57205b261ecSmrg
5736747b715Smrg    memset(dummyBuffer, 0, DUMMY_BUFFER_SIZE);
57405b261ecSmrg    for (currentFileSize = 0;
57505b261ecSmrg	 currentFileSize < pvfb->sizeInBytes;
57605b261ecSmrg	 currentFileSize += writeThisTime)
57705b261ecSmrg    {
57805b261ecSmrg	writeThisTime = min(DUMMY_BUFFER_SIZE,
57905b261ecSmrg			    pvfb->sizeInBytes - currentFileSize);
58005b261ecSmrg	if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime))
58105b261ecSmrg	{
58205b261ecSmrg	    perror("write");
5834642e01fSmrg	    ErrorF("write %s failed, %s", pvfb->mmap_file, strerror(errno));
58405b261ecSmrg	    return;
58505b261ecSmrg	}
58605b261ecSmrg    }
58705b261ecSmrg
58805b261ecSmrg    /* try to mmap the file */
58905b261ecSmrg
59005b261ecSmrg    pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes,
59105b261ecSmrg				    PROT_READ|PROT_WRITE,
59205b261ecSmrg				    MAP_FILE|MAP_SHARED,
59305b261ecSmrg				    pvfb->mmap_fd, 0);
59405b261ecSmrg    if (-1 == (long)pvfb->pXWDHeader)
59505b261ecSmrg    {
59605b261ecSmrg	perror("mmap");
5974642e01fSmrg	ErrorF("mmap %s failed, %s", pvfb->mmap_file, strerror(errno));
59805b261ecSmrg	pvfb->pXWDHeader = NULL;
59905b261ecSmrg	return;
60005b261ecSmrg    }
60105b261ecSmrg
60205b261ecSmrg    if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
60305b261ecSmrg					NULL))
60405b261ecSmrg    {
60505b261ecSmrg	pvfb->pXWDHeader = NULL;
60605b261ecSmrg    }
60705b261ecSmrg}
60805b261ecSmrg#endif /* HAS_MMAP */
60905b261ecSmrg
61005b261ecSmrg
61105b261ecSmrg#ifdef HAS_SHM
61205b261ecSmrgstatic void
61305b261ecSmrgvfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
61405b261ecSmrg{
61505b261ecSmrg    /* create the shared memory segment */
61605b261ecSmrg
61705b261ecSmrg    pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777);
61805b261ecSmrg    if (pvfb->shmid < 0)
61905b261ecSmrg    {
62005b261ecSmrg	perror("shmget");
6214642e01fSmrg	ErrorF("shmget %d bytes failed, %s", pvfb->sizeInBytes, strerror(errno));
62205b261ecSmrg	return;
62305b261ecSmrg    }
62405b261ecSmrg
62505b261ecSmrg    /* try to attach it */
62605b261ecSmrg
62705b261ecSmrg    pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0);
62805b261ecSmrg    if (-1 == (long)pvfb->pXWDHeader)
62905b261ecSmrg    {
63005b261ecSmrg	perror("shmat");
6314642e01fSmrg	ErrorF("shmat failed, %s", strerror(errno));
63205b261ecSmrg	pvfb->pXWDHeader = NULL;
63305b261ecSmrg	return;
63405b261ecSmrg    }
63505b261ecSmrg
6366747b715Smrg    ErrorF("screen %d shmid %d\n", (int) (pvfb - vfbScreens), pvfb->shmid);
63705b261ecSmrg}
63805b261ecSmrg#endif /* HAS_SHM */
63905b261ecSmrg
64005b261ecSmrgstatic char *
64105b261ecSmrgvfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
64205b261ecSmrg{
64305b261ecSmrg    if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
64405b261ecSmrg
64505b261ecSmrg    pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
64605b261ecSmrg
64705b261ecSmrg    /* Calculate how many entries in colormap.  This is rather bogus, because
64805b261ecSmrg     * the visuals haven't even been set up yet, but we need to know because we
64905b261ecSmrg     * have to allocate space in the file for the colormap.  The number 10
65005b261ecSmrg     * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
65105b261ecSmrg     */
65205b261ecSmrg
65305b261ecSmrg    if (pvfb->depth <= 10)
65405b261ecSmrg    { /* single index colormaps */
65505b261ecSmrg	pvfb->ncolors = 1 << pvfb->depth;
65605b261ecSmrg    }
65705b261ecSmrg    else
65805b261ecSmrg    { /* decomposed colormaps */
65905b261ecSmrg	int nplanes_per_color_component = pvfb->depth / 3;
66005b261ecSmrg	if (pvfb->depth % 3) nplanes_per_color_component++;
66105b261ecSmrg	pvfb->ncolors = 1 << nplanes_per_color_component;
66205b261ecSmrg    }
66305b261ecSmrg
66405b261ecSmrg    /* add extra bytes for XWDFileHeader, window name, and colormap */
66505b261ecSmrg
66605b261ecSmrg    pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
66705b261ecSmrg		    pvfb->ncolors * SIZEOF(XWDColor);
66805b261ecSmrg
66905b261ecSmrg    pvfb->pXWDHeader = NULL;
67005b261ecSmrg    switch (fbmemtype)
67105b261ecSmrg    {
67205b261ecSmrg#ifdef HAS_MMAP
67305b261ecSmrg    case MMAPPED_FILE_FB:  vfbAllocateMmappedFramebuffer(pvfb); break;
67405b261ecSmrg#else
67505b261ecSmrg    case MMAPPED_FILE_FB: break;
67605b261ecSmrg#endif
67705b261ecSmrg
67805b261ecSmrg#ifdef HAS_SHM
67905b261ecSmrg    case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
68005b261ecSmrg#else
68105b261ecSmrg    case SHARED_MEMORY_FB: break;
68205b261ecSmrg#endif
68305b261ecSmrg
68405b261ecSmrg    case NORMAL_MEMORY_FB:
6856747b715Smrg	pvfb->pXWDHeader = (XWDFileHeader *)malloc(pvfb->sizeInBytes);
68605b261ecSmrg	break;
68705b261ecSmrg    }
68805b261ecSmrg
68905b261ecSmrg    if (pvfb->pXWDHeader)
69005b261ecSmrg    {
69105b261ecSmrg	pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
69205b261ecSmrg				+ SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
69305b261ecSmrg	pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
69405b261ecSmrg
69505b261ecSmrg	return pvfb->pfbMemory;
69605b261ecSmrg    }
69705b261ecSmrg    else
69805b261ecSmrg	return NULL;
69905b261ecSmrg}
70005b261ecSmrg
70105b261ecSmrg
70205b261ecSmrgstatic void
70305b261ecSmrgvfbWriteXWDFileHeader(ScreenPtr pScreen)
70405b261ecSmrg{
70505b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
70605b261ecSmrg    XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
70705b261ecSmrg    char hostname[XWD_WINDOW_NAME_LEN];
70805b261ecSmrg    unsigned long swaptest = 1;
70905b261ecSmrg    int i;
71005b261ecSmrg
71105b261ecSmrg    needswap = *(char *) &swaptest;
71205b261ecSmrg
71305b261ecSmrg    pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
71405b261ecSmrg    pXWDHeader->file_version = XWD_FILE_VERSION;
71505b261ecSmrg
71605b261ecSmrg    pXWDHeader->pixmap_format = ZPixmap;
71705b261ecSmrg    pXWDHeader->pixmap_depth = pvfb->depth;
71805b261ecSmrg    pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
71905b261ecSmrg    pXWDHeader->xoffset = 0;
72005b261ecSmrg    pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
72105b261ecSmrg    pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
72205b261ecSmrg#ifndef INTERNAL_VS_EXTERNAL_PADDING
72305b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
72405b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
72505b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
72605b261ecSmrg#else
72705b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
72805b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
72905b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
73005b261ecSmrg#endif
73105b261ecSmrg    pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
73205b261ecSmrg    pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
73305b261ecSmrg    pXWDHeader->ncolors = pvfb->ncolors;
73405b261ecSmrg
73505b261ecSmrg    /* visual related fields are written when colormap is installed */
73605b261ecSmrg
73705b261ecSmrg    pXWDHeader->window_x = pXWDHeader->window_y = 0;
73805b261ecSmrg    pXWDHeader->window_bdrwidth = 0;
73905b261ecSmrg
74005b261ecSmrg    /* write xwd "window" name: Xvfb hostname:server.screen */
74105b261ecSmrg
74205b261ecSmrg    if (-1 == gethostname(hostname, sizeof(hostname)))
74305b261ecSmrg	hostname[0] = 0;
74405b261ecSmrg    else
74505b261ecSmrg	hostname[XWD_WINDOW_NAME_LEN-1] = 0;
74605b261ecSmrg    sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
74705b261ecSmrg	    pScreen->myNum);
74805b261ecSmrg
74905b261ecSmrg    /* write colormap pixel slot values */
75005b261ecSmrg
75105b261ecSmrg    for (i = 0; i < pvfb->ncolors; i++)
75205b261ecSmrg    {
75305b261ecSmrg	pvfb->pXWDCmap[i].pixel = i;
75405b261ecSmrg    }
75505b261ecSmrg
75605b261ecSmrg    /* byte swap to most significant byte first */
75705b261ecSmrg
75805b261ecSmrg    if (needswap)
75905b261ecSmrg    {
76005b261ecSmrg	SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
76105b261ecSmrg	for (i = 0; i < pvfb->ncolors; i++)
76205b261ecSmrg	{
76305b261ecSmrg	    register char n;
76405b261ecSmrg	    swapl(&pvfb->pXWDCmap[i].pixel, n);
76505b261ecSmrg	}
76605b261ecSmrg    }
76705b261ecSmrg}
76805b261ecSmrg
76905b261ecSmrg
77005b261ecSmrgstatic Bool
77105b261ecSmrgvfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
77205b261ecSmrg{
77305b261ecSmrg    return FALSE;
77405b261ecSmrg}
77505b261ecSmrg
77605b261ecSmrgstatic void
77705b261ecSmrgvfbCrossScreen (ScreenPtr pScreen, Bool entering)
77805b261ecSmrg{
77905b261ecSmrg}
78005b261ecSmrg
78105b261ecSmrgstatic miPointerScreenFuncRec vfbPointerCursorFuncs =
78205b261ecSmrg{
78305b261ecSmrg    vfbCursorOffScreen,
78405b261ecSmrg    vfbCrossScreen,
78505b261ecSmrg    miPointerWarpCursor
78605b261ecSmrg};
78705b261ecSmrg
78805b261ecSmrgstatic Bool
78905b261ecSmrgvfbCloseScreen(int index, ScreenPtr pScreen)
79005b261ecSmrg{
79105b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[index];
79205b261ecSmrg    int i;
79305b261ecSmrg
79405b261ecSmrg    pScreen->CloseScreen = pvfb->closeScreen;
79505b261ecSmrg
79605b261ecSmrg    /*
79705b261ecSmrg     * XXX probably lots of stuff to clean.  For now,
7986747b715Smrg     * clear installed colormaps so that server reset works correctly.
79905b261ecSmrg     */
8006747b715Smrg    for (i = 0; i < screenInfo.numScreens; i++)
8016747b715Smrg	SetInstalledColormap(screenInfo.screens[i], NULL);
80205b261ecSmrg
80305b261ecSmrg    return pScreen->CloseScreen(index, pScreen);
80405b261ecSmrg}
80505b261ecSmrg
80605b261ecSmrgstatic Bool
80705b261ecSmrgvfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
80805b261ecSmrg{
80905b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[index];
81005b261ecSmrg    int dpix = monitorResolution, dpiy = monitorResolution;
81105b261ecSmrg    int ret;
81205b261ecSmrg    char *pbits;
81305b261ecSmrg
8146747b715Smrg    if (!dixRegisterPrivateKey(&cmapScrPrivateKeyRec, PRIVATE_SCREEN, 0))
8156747b715Smrg	return FALSE;
8166747b715Smrg
81705b261ecSmrg    if (dpix == 0)
81805b261ecSmrg      dpix = 100;
81905b261ecSmrg
82005b261ecSmrg    if (dpiy == 0)
82105b261ecSmrg      dpiy = 100;
82205b261ecSmrg
82305b261ecSmrg    pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
82405b261ecSmrg    pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
82505b261ecSmrg    if (pvfb->bitsPerPixel >= 8 )
82605b261ecSmrg	pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
82705b261ecSmrg    else
82805b261ecSmrg	pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
82905b261ecSmrg    pbits = vfbAllocateFramebufferMemory(pvfb);
83005b261ecSmrg    if (!pbits) return FALSE;
83105b261ecSmrg
83205b261ecSmrg    switch (pvfb->depth) {
83305b261ecSmrg    case 8:
83405b261ecSmrg	miSetVisualTypesAndMasks (8,
83505b261ecSmrg				  ((1 << StaticGray) |
83605b261ecSmrg				   (1 << GrayScale) |
83705b261ecSmrg				   (1 << StaticColor) |
83805b261ecSmrg				   (1 << PseudoColor) |
83905b261ecSmrg				   (1 << TrueColor) |
84005b261ecSmrg				   (1 << DirectColor)),
84105b261ecSmrg				  8, PseudoColor, 0, 0, 0);
84205b261ecSmrg	break;
84305b261ecSmrg    case 15:
84405b261ecSmrg	miSetVisualTypesAndMasks (15,
84505b261ecSmrg				  ((1 << TrueColor) |
84605b261ecSmrg				   (1 << DirectColor)),
84705b261ecSmrg				  8, TrueColor, 0x7c00, 0x03e0, 0x001f);
84805b261ecSmrg	break;
84905b261ecSmrg    case 16:
85005b261ecSmrg	miSetVisualTypesAndMasks (16,
85105b261ecSmrg				  ((1 << TrueColor) |
85205b261ecSmrg				   (1 << DirectColor)),
85305b261ecSmrg				  8, TrueColor, 0xf800, 0x07e0, 0x001f);
85405b261ecSmrg	break;
85505b261ecSmrg    case 24:
85605b261ecSmrg	miSetVisualTypesAndMasks (24,
85705b261ecSmrg				  ((1 << TrueColor) |
85805b261ecSmrg				   (1 << DirectColor)),
85905b261ecSmrg				  8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
86005b261ecSmrg	break;
8616747b715Smrg    case 30:
8626747b715Smrg	miSetVisualTypesAndMasks (30,
8636747b715Smrg				  ((1 << TrueColor) |
8646747b715Smrg				   (1 << DirectColor)),
8656747b715Smrg				  10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff);
8666747b715Smrg	break;
86705b261ecSmrg    }
86852397711Smrg
86952397711Smrg    miSetPixmapDepths ();
87052397711Smrg
87105b261ecSmrg    ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
87205b261ecSmrg		       dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel);
87305b261ecSmrg    if (ret && Render)
87405b261ecSmrg	fbPictureInit (pScreen, 0, 0);
87505b261ecSmrg
87605b261ecSmrg    if (!ret) return FALSE;
87705b261ecSmrg
87805b261ecSmrg    miInitializeBackingStore(pScreen);
87905b261ecSmrg
88005b261ecSmrg    /*
88105b261ecSmrg     * Circumvent the backing store that was just initialised.  This amounts
88205b261ecSmrg     * to a truely bizarre way of initialising SaveDoomedAreas and friends.
88305b261ecSmrg     */
88405b261ecSmrg
88505b261ecSmrg    pScreen->InstallColormap = vfbInstallColormap;
88605b261ecSmrg    pScreen->UninstallColormap = vfbUninstallColormap;
88705b261ecSmrg    pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
88805b261ecSmrg
88905b261ecSmrg    pScreen->SaveScreen = vfbSaveScreen;
89005b261ecSmrg    pScreen->StoreColors = vfbStoreColors;
89105b261ecSmrg
89205b261ecSmrg    miDCInitialize(pScreen, &vfbPointerCursorFuncs);
89305b261ecSmrg
89405b261ecSmrg    vfbWriteXWDFileHeader(pScreen);
89505b261ecSmrg
89605b261ecSmrg    pScreen->blackPixel = pvfb->blackPixel;
89705b261ecSmrg    pScreen->whitePixel = pvfb->whitePixel;
89805b261ecSmrg
89905b261ecSmrg    ret = fbCreateDefColormap(pScreen);
90005b261ecSmrg
90105b261ecSmrg    miSetZeroLineBias(pScreen, pvfb->lineBias);
90205b261ecSmrg
90305b261ecSmrg    pvfb->closeScreen = pScreen->CloseScreen;
90405b261ecSmrg    pScreen->CloseScreen = vfbCloseScreen;
90505b261ecSmrg
90605b261ecSmrg    return ret;
90705b261ecSmrg
90805b261ecSmrg} /* end vfbScreenInit */
90905b261ecSmrg
91005b261ecSmrg
91105b261ecSmrgvoid
91205b261ecSmrgInitOutput(ScreenInfo *screenInfo, int argc, char **argv)
91305b261ecSmrg{
91405b261ecSmrg    int i;
91505b261ecSmrg    int NumFormats = 0;
91605b261ecSmrg
91705b261ecSmrg    /* initialize pixmap formats */
91805b261ecSmrg
91905b261ecSmrg    /* must have a pixmap depth to match every screen depth */
92005b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
92105b261ecSmrg    {
92205b261ecSmrg	vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
92305b261ecSmrg    }
92405b261ecSmrg
92505b261ecSmrg    /* RENDER needs a good set of pixmaps. */
92605b261ecSmrg    if (Render) {
92705b261ecSmrg	vfbPixmapDepths[1] = TRUE;
92805b261ecSmrg	vfbPixmapDepths[4] = TRUE;
92905b261ecSmrg	vfbPixmapDepths[8] = TRUE;
93005b261ecSmrg#if 0
93105b261ecSmrg	vfbPixmapDepths[12] = TRUE;
93205b261ecSmrg#endif
93305b261ecSmrg/*	vfbPixmapDepths[15] = TRUE; */
93405b261ecSmrg	vfbPixmapDepths[16] = TRUE;
93505b261ecSmrg	vfbPixmapDepths[24] = TRUE;
93605b261ecSmrg#if 0
93705b261ecSmrg	vfbPixmapDepths[30] = TRUE;
93805b261ecSmrg#endif
93905b261ecSmrg	vfbPixmapDepths[32] = TRUE;
94005b261ecSmrg    }
94105b261ecSmrg
94205b261ecSmrg    for (i = 1; i <= 32; i++)
94305b261ecSmrg    {
94405b261ecSmrg	if (vfbPixmapDepths[i])
94505b261ecSmrg	{
94605b261ecSmrg	    if (NumFormats >= MAXFORMATS)
94705b261ecSmrg		FatalError ("MAXFORMATS is too small for this server\n");
94805b261ecSmrg	    screenInfo->formats[NumFormats].depth = i;
94905b261ecSmrg	    screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
95005b261ecSmrg	    screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
95105b261ecSmrg	    NumFormats++;
95205b261ecSmrg	}
95305b261ecSmrg    }
95405b261ecSmrg
95505b261ecSmrg    screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
95605b261ecSmrg    screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
95705b261ecSmrg    screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
95805b261ecSmrg    screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
95905b261ecSmrg    screenInfo->numPixmapFormats = NumFormats;
96005b261ecSmrg
96105b261ecSmrg    /* initialize screens */
96205b261ecSmrg
9636747b715Smrg    if (vfbNumScreens < 1)
9646747b715Smrg    {
9656747b715Smrg	vfbScreens = &defaultScreenInfo;
9666747b715Smrg	vfbNumScreens = 1;
9676747b715Smrg    }
96805b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
96905b261ecSmrg    {
97005b261ecSmrg	if (-1 == AddScreen(vfbScreenInit, argc, argv))
97105b261ecSmrg	{
97205b261ecSmrg	    FatalError("Couldn't add screen %d", i);
97305b261ecSmrg	}
97405b261ecSmrg    }
97505b261ecSmrg
97605b261ecSmrg} /* end InitOutput */
977