InitOutput.c revision 4642e01f
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#define NEED_EVENTS
3905b261ecSmrg#include <X11/Xproto.h>
4005b261ecSmrg#include <X11/Xos.h>
4105b261ecSmrg#include "scrnintstr.h"
4205b261ecSmrg#include "servermd.h"
4305b261ecSmrg#define PSZ 8
4405b261ecSmrg#include "fb.h"
4505b261ecSmrg#include "mibstore.h"
4605b261ecSmrg#include "colormapst.h"
4705b261ecSmrg#include "gcstruct.h"
4805b261ecSmrg#include "input.h"
4905b261ecSmrg#include "mipointer.h"
5005b261ecSmrg#include "micmap.h"
5105b261ecSmrg#include <sys/types.h>
5205b261ecSmrg#ifdef HAS_MMAP
5305b261ecSmrg#include <sys/mman.h>
5405b261ecSmrg#ifndef MAP_FILE
5505b261ecSmrg#define MAP_FILE 0
5605b261ecSmrg#endif
5705b261ecSmrg#endif /* HAS_MMAP */
5805b261ecSmrg#include <sys/stat.h>
5905b261ecSmrg#include <errno.h>
6005b261ecSmrg#ifndef WIN32
6105b261ecSmrg#include <sys/param.h>
6205b261ecSmrg#endif
6305b261ecSmrg#include <X11/XWDFile.h>
6405b261ecSmrg#ifdef HAS_SHM
6505b261ecSmrg#include <sys/ipc.h>
6605b261ecSmrg#include <sys/shm.h>
6705b261ecSmrg#endif /* HAS_SHM */
6805b261ecSmrg#include "dix.h"
6905b261ecSmrg#include "miline.h"
7005b261ecSmrg
7105b261ecSmrg#define VFB_DEFAULT_WIDTH      1280
7205b261ecSmrg#define VFB_DEFAULT_HEIGHT     1024
7305b261ecSmrg#define VFB_DEFAULT_DEPTH         8
7405b261ecSmrg#define VFB_DEFAULT_WHITEPIXEL    1
7505b261ecSmrg#define VFB_DEFAULT_BLACKPIXEL    0
7605b261ecSmrg#define VFB_DEFAULT_LINEBIAS      0
7705b261ecSmrg#define XWD_WINDOW_NAME_LEN      60
7805b261ecSmrg
7905b261ecSmrgtypedef struct
8005b261ecSmrg{
8105b261ecSmrg    int scrnum;
8205b261ecSmrg    int width;
8305b261ecSmrg    int paddedBytesWidth;
8405b261ecSmrg    int paddedWidth;
8505b261ecSmrg    int height;
8605b261ecSmrg    int depth;
8705b261ecSmrg    int bitsPerPixel;
8805b261ecSmrg    int sizeInBytes;
8905b261ecSmrg    int ncolors;
9005b261ecSmrg    char *pfbMemory;
9105b261ecSmrg    XWDColor *pXWDCmap;
9205b261ecSmrg    XWDFileHeader *pXWDHeader;
9305b261ecSmrg    Pixel blackPixel;
9405b261ecSmrg    Pixel whitePixel;
9505b261ecSmrg    unsigned int lineBias;
9605b261ecSmrg    CloseScreenProcPtr closeScreen;
9705b261ecSmrg
9805b261ecSmrg#ifdef HAS_MMAP
9905b261ecSmrg    int mmap_fd;
10005b261ecSmrg    char mmap_file[MAXPATHLEN];
10105b261ecSmrg#endif
10205b261ecSmrg
10305b261ecSmrg#ifdef HAS_SHM
10405b261ecSmrg    int shmid;
10505b261ecSmrg#endif
10605b261ecSmrg} vfbScreenInfo, *vfbScreenInfoPtr;
10705b261ecSmrg
10805b261ecSmrgstatic int vfbNumScreens;
10905b261ecSmrgstatic vfbScreenInfo vfbScreens[MAXSCREENS];
11005b261ecSmrgstatic Bool vfbPixmapDepths[33];
11105b261ecSmrg#ifdef HAS_MMAP
11205b261ecSmrgstatic char *pfbdir = NULL;
11305b261ecSmrg#endif
11405b261ecSmrgtypedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
11505b261ecSmrgstatic fbMemType fbmemtype = NORMAL_MEMORY_FB;
11605b261ecSmrgstatic char needswap = 0;
11705b261ecSmrgstatic int lastScreen = -1;
11805b261ecSmrgstatic Bool Render = TRUE;
11905b261ecSmrg
12005b261ecSmrg#define swapcopy16(_dst, _src) \
12105b261ecSmrg    if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
12205b261ecSmrg    else _dst = _src;
12305b261ecSmrg
12405b261ecSmrg#define swapcopy32(_dst, _src) \
12505b261ecSmrg    if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
12605b261ecSmrg    else _dst = _src;
12705b261ecSmrg
12805b261ecSmrg
12905b261ecSmrgstatic void
13005b261ecSmrgvfbInitializePixmapDepths(void)
13105b261ecSmrg{
13205b261ecSmrg    int i;
13305b261ecSmrg    vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
13405b261ecSmrg    for (i = 2; i <= 32; i++)
13505b261ecSmrg	vfbPixmapDepths[i] = FALSE;
13605b261ecSmrg}
13705b261ecSmrg
13805b261ecSmrgstatic void
13905b261ecSmrgvfbInitializeDefaultScreens(void)
14005b261ecSmrg{
14105b261ecSmrg    int i;
14205b261ecSmrg
14305b261ecSmrg    for (i = 0; i < MAXSCREENS; i++)
14405b261ecSmrg    {
14505b261ecSmrg	vfbScreens[i].scrnum = i;
14605b261ecSmrg	vfbScreens[i].width  = VFB_DEFAULT_WIDTH;
14705b261ecSmrg	vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
14805b261ecSmrg	vfbScreens[i].depth  = VFB_DEFAULT_DEPTH;
14905b261ecSmrg	vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
15005b261ecSmrg	vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
15105b261ecSmrg	vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
15205b261ecSmrg	vfbScreens[i].pfbMemory = NULL;
15305b261ecSmrg    }
15405b261ecSmrg    vfbNumScreens = 1;
15505b261ecSmrg}
15605b261ecSmrg
15705b261ecSmrgstatic int
15805b261ecSmrgvfbBitsPerPixel(int depth)
15905b261ecSmrg{
16005b261ecSmrg    if (depth == 1) return 1;
16105b261ecSmrg    else if (depth <= 8) return 8;
16205b261ecSmrg    else if (depth <= 16) return 16;
16305b261ecSmrg    else return 32;
16405b261ecSmrg}
16505b261ecSmrg
16605b261ecSmrgvoid
16705b261ecSmrgddxGiveUp()
16805b261ecSmrg{
16905b261ecSmrg    int i;
17005b261ecSmrg
17105b261ecSmrg    /* clean up the framebuffers */
17205b261ecSmrg
17305b261ecSmrg    switch (fbmemtype)
17405b261ecSmrg    {
17505b261ecSmrg#ifdef HAS_MMAP
17605b261ecSmrg    case MMAPPED_FILE_FB:
17705b261ecSmrg	for (i = 0; i < vfbNumScreens; i++)
17805b261ecSmrg	{
17905b261ecSmrg	    if (-1 == unlink(vfbScreens[i].mmap_file))
18005b261ecSmrg	    {
18105b261ecSmrg		perror("unlink");
1824642e01fSmrg		ErrorF("unlink %s failed, %s",
1834642e01fSmrg		       vfbScreens[i].mmap_file, strerror(errno));
18405b261ecSmrg	    }
18505b261ecSmrg	}
18605b261ecSmrg	break;
18705b261ecSmrg#else /* HAS_MMAP */
18805b261ecSmrg    case MMAPPED_FILE_FB:
18905b261ecSmrg        break;
19005b261ecSmrg#endif /* HAS_MMAP */
19105b261ecSmrg
19205b261ecSmrg#ifdef HAS_SHM
19305b261ecSmrg    case SHARED_MEMORY_FB:
19405b261ecSmrg	for (i = 0; i < vfbNumScreens; i++)
19505b261ecSmrg	{
19605b261ecSmrg	    if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
19705b261ecSmrg	    {
19805b261ecSmrg		perror("shmdt");
1994642e01fSmrg		ErrorF("shmdt failed, %s", strerror(errno));
20005b261ecSmrg	    }
20105b261ecSmrg	}
20205b261ecSmrg	break;
20305b261ecSmrg#else /* HAS_SHM */
20405b261ecSmrg    case SHARED_MEMORY_FB:
20505b261ecSmrg        break;
20605b261ecSmrg#endif /* HAS_SHM */
20705b261ecSmrg
20805b261ecSmrg    case NORMAL_MEMORY_FB:
20905b261ecSmrg	for (i = 0; i < vfbNumScreens; i++)
21005b261ecSmrg	{
21105b261ecSmrg	    Xfree(vfbScreens[i].pXWDHeader);
21205b261ecSmrg	}
21305b261ecSmrg	break;
21405b261ecSmrg    }
21505b261ecSmrg}
21605b261ecSmrg
21705b261ecSmrgvoid
21805b261ecSmrgAbortDDX()
21905b261ecSmrg{
22005b261ecSmrg    ddxGiveUp();
22105b261ecSmrg}
22205b261ecSmrg
2234642e01fSmrg#ifdef __APPLE__
22405b261ecSmrgvoid
22505b261ecSmrgDarwinHandleGUI(int argc, char *argv[])
22605b261ecSmrg{
22705b261ecSmrg}
22805b261ecSmrg#endif
22905b261ecSmrg
23005b261ecSmrgvoid
23105b261ecSmrgOsVendorInit()
23205b261ecSmrg{
23305b261ecSmrg}
23405b261ecSmrg
23505b261ecSmrgvoid
23605b261ecSmrgOsVendorFatalError()
23705b261ecSmrg{
23805b261ecSmrg}
23905b261ecSmrg
24005b261ecSmrg#if defined(DDXBEFORERESET)
24105b261ecSmrgvoid ddxBeforeReset(void)
24205b261ecSmrg{
24305b261ecSmrg    return;
24405b261ecSmrg}
24505b261ecSmrg#endif
24605b261ecSmrg
24705b261ecSmrgvoid
24805b261ecSmrgddxUseMsg()
24905b261ecSmrg{
25005b261ecSmrg    ErrorF("-screen scrn WxHxD     set screen's width, height, depth\n");
25105b261ecSmrg    ErrorF("-pixdepths list-of-int support given pixmap depths\n");
25205b261ecSmrg#ifdef RENDER
25305b261ecSmrg    ErrorF("+/-render		   turn on/of RENDER extension support"
25405b261ecSmrg	   "(default on)\n");
25505b261ecSmrg#endif
25605b261ecSmrg    ErrorF("-linebias n            adjust thin line pixelization\n");
25705b261ecSmrg    ErrorF("-blackpixel n          pixel value for black\n");
25805b261ecSmrg    ErrorF("-whitepixel n          pixel value for white\n");
25905b261ecSmrg
26005b261ecSmrg#ifdef HAS_MMAP
26105b261ecSmrg    ErrorF("-fbdir directory       put framebuffers in mmap'ed files in directory\n");
26205b261ecSmrg#endif
26305b261ecSmrg
26405b261ecSmrg#ifdef HAS_SHM
26505b261ecSmrg    ErrorF("-shmem                 put framebuffers in shared memory\n");
26605b261ecSmrg#endif
26705b261ecSmrg}
26805b261ecSmrg
26905b261ecSmrgint
27005b261ecSmrgddxProcessArgument(int argc, char *argv[], int i)
27105b261ecSmrg{
27205b261ecSmrg    static Bool firstTime = TRUE;
27305b261ecSmrg
27405b261ecSmrg    if (firstTime)
27505b261ecSmrg    {
27605b261ecSmrg	vfbInitializeDefaultScreens();
27705b261ecSmrg	vfbInitializePixmapDepths();
27805b261ecSmrg        firstTime = FALSE;
27905b261ecSmrg    }
28005b261ecSmrg
28105b261ecSmrg#define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
28205b261ecSmrg    if (((i + num) >= argc) || (!argv[i + num])) {                      \
28305b261ecSmrg      ErrorF("Required argument to %s not specified\n", argv[i]);       \
28405b261ecSmrg      UseMsg();                                                         \
28505b261ecSmrg      FatalError("Required argument to %s not specified\n", argv[i]);   \
28605b261ecSmrg    }
28705b261ecSmrg
28805b261ecSmrg    if (strcmp (argv[i], "-screen") == 0)	/* -screen n WxHxD */
28905b261ecSmrg    {
29005b261ecSmrg	int screenNum;
29105b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(2);
29205b261ecSmrg	screenNum = atoi(argv[i+1]);
29305b261ecSmrg	if (screenNum < 0 || screenNum >= MAXSCREENS)
29405b261ecSmrg	{
29505b261ecSmrg	    ErrorF("Invalid screen number %d\n", screenNum);
29605b261ecSmrg	    UseMsg();
29705b261ecSmrg	    FatalError("Invalid screen number %d passed to -screen\n",
29805b261ecSmrg		       screenNum);
29905b261ecSmrg	}
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	if (screenNum >= vfbNumScreens)
31205b261ecSmrg	    vfbNumScreens = screenNum + 1;
31305b261ecSmrg	lastScreen = screenNum;
31405b261ecSmrg	return 3;
31505b261ecSmrg    }
31605b261ecSmrg
31705b261ecSmrg    if (strcmp (argv[i], "-pixdepths") == 0)	/* -pixdepths list-of-depth */
31805b261ecSmrg    {
31905b261ecSmrg	int depth, ret = 1;
32005b261ecSmrg
32105b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
32205b261ecSmrg	while ((++i < argc) && (depth = atoi(argv[i])) != 0)
32305b261ecSmrg	{
32405b261ecSmrg	    if (depth < 0 || depth > 32)
32505b261ecSmrg	    {
32605b261ecSmrg		ErrorF("Invalid pixmap depth %d\n", depth);
32705b261ecSmrg		UseMsg();
32805b261ecSmrg		FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
32905b261ecSmrg			   depth);
33005b261ecSmrg	    }
33105b261ecSmrg	    vfbPixmapDepths[depth] = TRUE;
33205b261ecSmrg	    ret++;
33305b261ecSmrg	}
33405b261ecSmrg	return ret;
33505b261ecSmrg    }
33605b261ecSmrg
33705b261ecSmrg    if (strcmp (argv[i], "+render") == 0)	/* +render */
33805b261ecSmrg    {
33905b261ecSmrg	Render = TRUE;
34005b261ecSmrg	return 1;
34105b261ecSmrg    }
34205b261ecSmrg
34305b261ecSmrg    if (strcmp (argv[i], "-render") == 0)	/* -render */
34405b261ecSmrg    {
34505b261ecSmrg	Render = FALSE;
34605b261ecSmrg#ifdef COMPOSITE
34705b261ecSmrg	noCompositeExtension = TRUE;
34805b261ecSmrg#endif
34905b261ecSmrg	return 1;
35005b261ecSmrg    }
35105b261ecSmrg
35205b261ecSmrg    if (strcmp (argv[i], "-blackpixel") == 0)	/* -blackpixel n */
35305b261ecSmrg    {
35405b261ecSmrg	Pixel pix;
35505b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
35605b261ecSmrg	pix = atoi(argv[++i]);
35705b261ecSmrg	if (-1 == lastScreen)
35805b261ecSmrg	{
35905b261ecSmrg	    int i;
36005b261ecSmrg	    for (i = 0; i < MAXSCREENS; i++)
36105b261ecSmrg	    {
36205b261ecSmrg		vfbScreens[i].blackPixel = pix;
36305b261ecSmrg	    }
36405b261ecSmrg	}
36505b261ecSmrg	else
36605b261ecSmrg	{
36705b261ecSmrg	    vfbScreens[lastScreen].blackPixel = pix;
36805b261ecSmrg	}
36905b261ecSmrg	return 2;
37005b261ecSmrg    }
37105b261ecSmrg
37205b261ecSmrg    if (strcmp (argv[i], "-whitepixel") == 0)	/* -whitepixel n */
37305b261ecSmrg    {
37405b261ecSmrg	Pixel pix;
37505b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
37605b261ecSmrg	pix = atoi(argv[++i]);
37705b261ecSmrg	if (-1 == lastScreen)
37805b261ecSmrg	{
37905b261ecSmrg	    int i;
38005b261ecSmrg	    for (i = 0; i < MAXSCREENS; i++)
38105b261ecSmrg	    {
38205b261ecSmrg		vfbScreens[i].whitePixel = pix;
38305b261ecSmrg	    }
38405b261ecSmrg	}
38505b261ecSmrg	else
38605b261ecSmrg	{
38705b261ecSmrg	    vfbScreens[lastScreen].whitePixel = pix;
38805b261ecSmrg	}
38905b261ecSmrg	return 2;
39005b261ecSmrg    }
39105b261ecSmrg
39205b261ecSmrg    if (strcmp (argv[i], "-linebias") == 0)	/* -linebias n */
39305b261ecSmrg    {
39405b261ecSmrg	unsigned int linebias;
39505b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
39605b261ecSmrg	linebias = atoi(argv[++i]);
39705b261ecSmrg	if (-1 == lastScreen)
39805b261ecSmrg	{
39905b261ecSmrg	    int i;
40005b261ecSmrg	    for (i = 0; i < MAXSCREENS; i++)
40105b261ecSmrg	    {
40205b261ecSmrg		vfbScreens[i].lineBias = linebias;
40305b261ecSmrg	    }
40405b261ecSmrg	}
40505b261ecSmrg	else
40605b261ecSmrg	{
40705b261ecSmrg	    vfbScreens[lastScreen].lineBias = linebias;
40805b261ecSmrg	}
40905b261ecSmrg	return 2;
41005b261ecSmrg    }
41105b261ecSmrg
41205b261ecSmrg#ifdef HAS_MMAP
41305b261ecSmrg    if (strcmp (argv[i], "-fbdir") == 0)	/* -fbdir directory */
41405b261ecSmrg    {
41505b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
41605b261ecSmrg	pfbdir = argv[++i];
41705b261ecSmrg	fbmemtype = MMAPPED_FILE_FB;
41805b261ecSmrg	return 2;
41905b261ecSmrg    }
42005b261ecSmrg#endif /* HAS_MMAP */
42105b261ecSmrg
42205b261ecSmrg#ifdef HAS_SHM
42305b261ecSmrg    if (strcmp (argv[i], "-shmem") == 0)	/* -shmem */
42405b261ecSmrg    {
42505b261ecSmrg	fbmemtype = SHARED_MEMORY_FB;
42605b261ecSmrg	return 1;
42705b261ecSmrg    }
42805b261ecSmrg#endif
42905b261ecSmrg
43005b261ecSmrg    return 0;
43105b261ecSmrg}
43205b261ecSmrg
43305b261ecSmrgstatic ColormapPtr InstalledMaps[MAXSCREENS];
43405b261ecSmrg
43505b261ecSmrgstatic int
43605b261ecSmrgvfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
43705b261ecSmrg{
43805b261ecSmrg    /* By the time we are processing requests, we can guarantee that there
43905b261ecSmrg     * is always a colormap installed */
44005b261ecSmrg    *pmaps = InstalledMaps[pScreen->myNum]->mid;
44105b261ecSmrg    return (1);
44205b261ecSmrg}
44305b261ecSmrg
44405b261ecSmrg
44505b261ecSmrgstatic void
44605b261ecSmrgvfbInstallColormap(ColormapPtr pmap)
44705b261ecSmrg{
44805b261ecSmrg    int index = pmap->pScreen->myNum;
44905b261ecSmrg    ColormapPtr oldpmap = InstalledMaps[index];
45005b261ecSmrg
45105b261ecSmrg    if (pmap != oldpmap)
45205b261ecSmrg    {
45305b261ecSmrg	int entries;
45405b261ecSmrg	XWDFileHeader *pXWDHeader;
45505b261ecSmrg	XWDColor *pXWDCmap;
45605b261ecSmrg	VisualPtr pVisual;
45705b261ecSmrg	Pixel *     ppix;
45805b261ecSmrg	xrgb *      prgb;
45905b261ecSmrg	xColorItem *defs;
46005b261ecSmrg	int i;
46105b261ecSmrg
46205b261ecSmrg	if(oldpmap != (ColormapPtr)None)
46305b261ecSmrg	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
46405b261ecSmrg	/* Install pmap */
46505b261ecSmrg	InstalledMaps[index] = pmap;
46605b261ecSmrg	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
46705b261ecSmrg
46805b261ecSmrg	entries = pmap->pVisual->ColormapEntries;
46905b261ecSmrg	pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
47005b261ecSmrg	pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
47105b261ecSmrg	pVisual = pmap->pVisual;
47205b261ecSmrg
47305b261ecSmrg	swapcopy32(pXWDHeader->visual_class, pVisual->class);
47405b261ecSmrg	swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
47505b261ecSmrg	swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
47605b261ecSmrg	swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
47705b261ecSmrg	swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
47805b261ecSmrg	swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
47905b261ecSmrg
4804642e01fSmrg	ppix = (Pixel *)xalloc(entries * sizeof(Pixel));
4814642e01fSmrg	prgb = (xrgb *)xalloc(entries * sizeof(xrgb));
4824642e01fSmrg	defs = (xColorItem *)xalloc(entries * sizeof(xColorItem));
48305b261ecSmrg
48405b261ecSmrg	for (i = 0; i < entries; i++)  ppix[i] = i;
48505b261ecSmrg	/* XXX truecolor */
48605b261ecSmrg	QueryColors(pmap, entries, ppix, prgb);
48705b261ecSmrg
48805b261ecSmrg	for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
48905b261ecSmrg	    defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
49005b261ecSmrg	    defs[i].red = prgb[i].red;
49105b261ecSmrg	    defs[i].green = prgb[i].green;
49205b261ecSmrg	    defs[i].blue = prgb[i].blue;
49305b261ecSmrg	    defs[i].flags =  DoRed|DoGreen|DoBlue;
49405b261ecSmrg	}
49505b261ecSmrg	(*pmap->pScreen->StoreColors)(pmap, entries, defs);
49605b261ecSmrg
4974642e01fSmrg	xfree(ppix);
4984642e01fSmrg	xfree(prgb);
4994642e01fSmrg	xfree(defs);
50005b261ecSmrg    }
50105b261ecSmrg}
50205b261ecSmrg
50305b261ecSmrgstatic void
50405b261ecSmrgvfbUninstallColormap(ColormapPtr pmap)
50505b261ecSmrg{
50605b261ecSmrg    ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
50705b261ecSmrg
50805b261ecSmrg    if(pmap == curpmap)
50905b261ecSmrg    {
51005b261ecSmrg	if (pmap->mid != pmap->pScreen->defColormap)
51105b261ecSmrg	{
51205b261ecSmrg	    curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
51305b261ecSmrg						   RT_COLORMAP);
51405b261ecSmrg	    (*pmap->pScreen->InstallColormap)(curpmap);
51505b261ecSmrg	}
51605b261ecSmrg    }
51705b261ecSmrg}
51805b261ecSmrg
51905b261ecSmrgstatic void
52005b261ecSmrgvfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
52105b261ecSmrg{
52205b261ecSmrg    XWDColor *pXWDCmap;
52305b261ecSmrg    int i;
52405b261ecSmrg
52505b261ecSmrg    if (pmap != InstalledMaps[pmap->pScreen->myNum])
52605b261ecSmrg    {
52705b261ecSmrg	return;
52805b261ecSmrg    }
52905b261ecSmrg
53005b261ecSmrg    pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
53105b261ecSmrg
53205b261ecSmrg    if ((pmap->pVisual->class | DynamicClass) == DirectColor)
53305b261ecSmrg    {
53405b261ecSmrg	return;
53505b261ecSmrg    }
53605b261ecSmrg
53705b261ecSmrg    for (i = 0; i < ndef; i++)
53805b261ecSmrg    {
53905b261ecSmrg	if (pdefs[i].flags & DoRed)
54005b261ecSmrg	{
54105b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
54205b261ecSmrg	}
54305b261ecSmrg	if (pdefs[i].flags & DoGreen)
54405b261ecSmrg	{
54505b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
54605b261ecSmrg	}
54705b261ecSmrg	if (pdefs[i].flags & DoBlue)
54805b261ecSmrg	{
54905b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
55005b261ecSmrg	}
55105b261ecSmrg    }
55205b261ecSmrg}
55305b261ecSmrg
55405b261ecSmrgstatic Bool
55505b261ecSmrgvfbSaveScreen(ScreenPtr pScreen, int on)
55605b261ecSmrg{
55705b261ecSmrg    return TRUE;
55805b261ecSmrg}
55905b261ecSmrg
56005b261ecSmrg#ifdef HAS_MMAP
56105b261ecSmrg
56205b261ecSmrg/* this flushes any changes to the screens out to the mmapped file */
56305b261ecSmrgstatic void
56405b261ecSmrgvfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
56505b261ecSmrg{
56605b261ecSmrg    int i;
56705b261ecSmrg
56805b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
56905b261ecSmrg    {
57005b261ecSmrg#ifdef MS_ASYNC
57105b261ecSmrg	if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
57205b261ecSmrg			(size_t)vfbScreens[i].sizeInBytes, MS_ASYNC))
57305b261ecSmrg#else
57405b261ecSmrg	/* silly NetBSD and who else? */
57505b261ecSmrg	if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
57605b261ecSmrg			(size_t)vfbScreens[i].sizeInBytes))
57705b261ecSmrg#endif
57805b261ecSmrg	{
57905b261ecSmrg	    perror("msync");
5804642e01fSmrg	    ErrorF("msync failed, %s", strerror(errno));
58105b261ecSmrg	}
58205b261ecSmrg    }
58305b261ecSmrg}
58405b261ecSmrg
58505b261ecSmrg
58605b261ecSmrgstatic void
58705b261ecSmrgvfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
58805b261ecSmrg{
58905b261ecSmrg}
59005b261ecSmrg
59105b261ecSmrg
59205b261ecSmrgstatic void
59305b261ecSmrgvfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
59405b261ecSmrg{
59505b261ecSmrg#define DUMMY_BUFFER_SIZE 65536
59605b261ecSmrg    char dummyBuffer[DUMMY_BUFFER_SIZE];
59705b261ecSmrg    int currentFileSize, writeThisTime;
59805b261ecSmrg
59905b261ecSmrg    sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, pvfb->scrnum);
60005b261ecSmrg    if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
60105b261ecSmrg    {
60205b261ecSmrg	perror("open");
6034642e01fSmrg	ErrorF("open %s failed, %s", pvfb->mmap_file, strerror(errno));
60405b261ecSmrg	return;
60505b261ecSmrg    }
60605b261ecSmrg
60705b261ecSmrg    /* Extend the file to be the proper size */
60805b261ecSmrg
60905b261ecSmrg    bzero(dummyBuffer, DUMMY_BUFFER_SIZE);
61005b261ecSmrg    for (currentFileSize = 0;
61105b261ecSmrg	 currentFileSize < pvfb->sizeInBytes;
61205b261ecSmrg	 currentFileSize += writeThisTime)
61305b261ecSmrg    {
61405b261ecSmrg	writeThisTime = min(DUMMY_BUFFER_SIZE,
61505b261ecSmrg			    pvfb->sizeInBytes - currentFileSize);
61605b261ecSmrg	if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime))
61705b261ecSmrg	{
61805b261ecSmrg	    perror("write");
6194642e01fSmrg	    ErrorF("write %s failed, %s", pvfb->mmap_file, strerror(errno));
62005b261ecSmrg	    return;
62105b261ecSmrg	}
62205b261ecSmrg    }
62305b261ecSmrg
62405b261ecSmrg    /* try to mmap the file */
62505b261ecSmrg
62605b261ecSmrg    pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes,
62705b261ecSmrg				    PROT_READ|PROT_WRITE,
62805b261ecSmrg				    MAP_FILE|MAP_SHARED,
62905b261ecSmrg				    pvfb->mmap_fd, 0);
63005b261ecSmrg    if (-1 == (long)pvfb->pXWDHeader)
63105b261ecSmrg    {
63205b261ecSmrg	perror("mmap");
6334642e01fSmrg	ErrorF("mmap %s failed, %s", pvfb->mmap_file, strerror(errno));
63405b261ecSmrg	pvfb->pXWDHeader = NULL;
63505b261ecSmrg	return;
63605b261ecSmrg    }
63705b261ecSmrg
63805b261ecSmrg    if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
63905b261ecSmrg					NULL))
64005b261ecSmrg    {
64105b261ecSmrg	pvfb->pXWDHeader = NULL;
64205b261ecSmrg    }
64305b261ecSmrg}
64405b261ecSmrg#endif /* HAS_MMAP */
64505b261ecSmrg
64605b261ecSmrg
64705b261ecSmrg#ifdef HAS_SHM
64805b261ecSmrgstatic void
64905b261ecSmrgvfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
65005b261ecSmrg{
65105b261ecSmrg    /* create the shared memory segment */
65205b261ecSmrg
65305b261ecSmrg    pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777);
65405b261ecSmrg    if (pvfb->shmid < 0)
65505b261ecSmrg    {
65605b261ecSmrg	perror("shmget");
6574642e01fSmrg	ErrorF("shmget %d bytes failed, %s", pvfb->sizeInBytes, strerror(errno));
65805b261ecSmrg	return;
65905b261ecSmrg    }
66005b261ecSmrg
66105b261ecSmrg    /* try to attach it */
66205b261ecSmrg
66305b261ecSmrg    pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0);
66405b261ecSmrg    if (-1 == (long)pvfb->pXWDHeader)
66505b261ecSmrg    {
66605b261ecSmrg	perror("shmat");
6674642e01fSmrg	ErrorF("shmat failed, %s", strerror(errno));
66805b261ecSmrg	pvfb->pXWDHeader = NULL;
66905b261ecSmrg	return;
67005b261ecSmrg    }
67105b261ecSmrg
67205b261ecSmrg    ErrorF("screen %d shmid %d\n", pvfb->scrnum, pvfb->shmid);
67305b261ecSmrg}
67405b261ecSmrg#endif /* HAS_SHM */
67505b261ecSmrg
67605b261ecSmrgstatic char *
67705b261ecSmrgvfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
67805b261ecSmrg{
67905b261ecSmrg    if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
68005b261ecSmrg
68105b261ecSmrg    pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
68205b261ecSmrg
68305b261ecSmrg    /* Calculate how many entries in colormap.  This is rather bogus, because
68405b261ecSmrg     * the visuals haven't even been set up yet, but we need to know because we
68505b261ecSmrg     * have to allocate space in the file for the colormap.  The number 10
68605b261ecSmrg     * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
68705b261ecSmrg     */
68805b261ecSmrg
68905b261ecSmrg    if (pvfb->depth <= 10)
69005b261ecSmrg    { /* single index colormaps */
69105b261ecSmrg	pvfb->ncolors = 1 << pvfb->depth;
69205b261ecSmrg    }
69305b261ecSmrg    else
69405b261ecSmrg    { /* decomposed colormaps */
69505b261ecSmrg	int nplanes_per_color_component = pvfb->depth / 3;
69605b261ecSmrg	if (pvfb->depth % 3) nplanes_per_color_component++;
69705b261ecSmrg	pvfb->ncolors = 1 << nplanes_per_color_component;
69805b261ecSmrg    }
69905b261ecSmrg
70005b261ecSmrg    /* add extra bytes for XWDFileHeader, window name, and colormap */
70105b261ecSmrg
70205b261ecSmrg    pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
70305b261ecSmrg		    pvfb->ncolors * SIZEOF(XWDColor);
70405b261ecSmrg
70505b261ecSmrg    pvfb->pXWDHeader = NULL;
70605b261ecSmrg    switch (fbmemtype)
70705b261ecSmrg    {
70805b261ecSmrg#ifdef HAS_MMAP
70905b261ecSmrg    case MMAPPED_FILE_FB:  vfbAllocateMmappedFramebuffer(pvfb); break;
71005b261ecSmrg#else
71105b261ecSmrg    case MMAPPED_FILE_FB: break;
71205b261ecSmrg#endif
71305b261ecSmrg
71405b261ecSmrg#ifdef HAS_SHM
71505b261ecSmrg    case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
71605b261ecSmrg#else
71705b261ecSmrg    case SHARED_MEMORY_FB: break;
71805b261ecSmrg#endif
71905b261ecSmrg
72005b261ecSmrg    case NORMAL_MEMORY_FB:
72105b261ecSmrg	pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
72205b261ecSmrg	break;
72305b261ecSmrg    }
72405b261ecSmrg
72505b261ecSmrg    if (pvfb->pXWDHeader)
72605b261ecSmrg    {
72705b261ecSmrg	pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
72805b261ecSmrg				+ SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
72905b261ecSmrg	pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
73005b261ecSmrg
73105b261ecSmrg	return pvfb->pfbMemory;
73205b261ecSmrg    }
73305b261ecSmrg    else
73405b261ecSmrg	return NULL;
73505b261ecSmrg}
73605b261ecSmrg
73705b261ecSmrg
73805b261ecSmrgstatic void
73905b261ecSmrgvfbWriteXWDFileHeader(ScreenPtr pScreen)
74005b261ecSmrg{
74105b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
74205b261ecSmrg    XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
74305b261ecSmrg    char hostname[XWD_WINDOW_NAME_LEN];
74405b261ecSmrg    unsigned long swaptest = 1;
74505b261ecSmrg    int i;
74605b261ecSmrg
74705b261ecSmrg    needswap = *(char *) &swaptest;
74805b261ecSmrg
74905b261ecSmrg    pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
75005b261ecSmrg    pXWDHeader->file_version = XWD_FILE_VERSION;
75105b261ecSmrg
75205b261ecSmrg    pXWDHeader->pixmap_format = ZPixmap;
75305b261ecSmrg    pXWDHeader->pixmap_depth = pvfb->depth;
75405b261ecSmrg    pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
75505b261ecSmrg    pXWDHeader->xoffset = 0;
75605b261ecSmrg    pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
75705b261ecSmrg    pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
75805b261ecSmrg#ifndef INTERNAL_VS_EXTERNAL_PADDING
75905b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
76005b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
76105b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
76205b261ecSmrg#else
76305b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
76405b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
76505b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
76605b261ecSmrg#endif
76705b261ecSmrg    pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
76805b261ecSmrg    pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
76905b261ecSmrg    pXWDHeader->ncolors = pvfb->ncolors;
77005b261ecSmrg
77105b261ecSmrg    /* visual related fields are written when colormap is installed */
77205b261ecSmrg
77305b261ecSmrg    pXWDHeader->window_x = pXWDHeader->window_y = 0;
77405b261ecSmrg    pXWDHeader->window_bdrwidth = 0;
77505b261ecSmrg
77605b261ecSmrg    /* write xwd "window" name: Xvfb hostname:server.screen */
77705b261ecSmrg
77805b261ecSmrg    if (-1 == gethostname(hostname, sizeof(hostname)))
77905b261ecSmrg	hostname[0] = 0;
78005b261ecSmrg    else
78105b261ecSmrg	hostname[XWD_WINDOW_NAME_LEN-1] = 0;
78205b261ecSmrg    sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
78305b261ecSmrg	    pScreen->myNum);
78405b261ecSmrg
78505b261ecSmrg    /* write colormap pixel slot values */
78605b261ecSmrg
78705b261ecSmrg    for (i = 0; i < pvfb->ncolors; i++)
78805b261ecSmrg    {
78905b261ecSmrg	pvfb->pXWDCmap[i].pixel = i;
79005b261ecSmrg    }
79105b261ecSmrg
79205b261ecSmrg    /* byte swap to most significant byte first */
79305b261ecSmrg
79405b261ecSmrg    if (needswap)
79505b261ecSmrg    {
79605b261ecSmrg	SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
79705b261ecSmrg	for (i = 0; i < pvfb->ncolors; i++)
79805b261ecSmrg	{
79905b261ecSmrg	    register char n;
80005b261ecSmrg	    swapl(&pvfb->pXWDCmap[i].pixel, n);
80105b261ecSmrg	}
80205b261ecSmrg    }
80305b261ecSmrg}
80405b261ecSmrg
80505b261ecSmrg
80605b261ecSmrgstatic Bool
80705b261ecSmrgvfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
80805b261ecSmrg{
80905b261ecSmrg    return FALSE;
81005b261ecSmrg}
81105b261ecSmrg
81205b261ecSmrgstatic void
81305b261ecSmrgvfbCrossScreen (ScreenPtr pScreen, Bool entering)
81405b261ecSmrg{
81505b261ecSmrg}
81605b261ecSmrg
81705b261ecSmrgstatic miPointerScreenFuncRec vfbPointerCursorFuncs =
81805b261ecSmrg{
81905b261ecSmrg    vfbCursorOffScreen,
82005b261ecSmrg    vfbCrossScreen,
82105b261ecSmrg    miPointerWarpCursor
82205b261ecSmrg};
82305b261ecSmrg
82405b261ecSmrgstatic Bool
82505b261ecSmrgvfbCloseScreen(int index, ScreenPtr pScreen)
82605b261ecSmrg{
82705b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[index];
82805b261ecSmrg    int i;
82905b261ecSmrg
83005b261ecSmrg    pScreen->CloseScreen = pvfb->closeScreen;
83105b261ecSmrg
83205b261ecSmrg    /*
83305b261ecSmrg     * XXX probably lots of stuff to clean.  For now,
83405b261ecSmrg     * clear InstalledMaps[] so that server reset works correctly.
83505b261ecSmrg     */
83605b261ecSmrg    for (i = 0; i < MAXSCREENS; i++)
83705b261ecSmrg	InstalledMaps[i] = NULL;
83805b261ecSmrg
83905b261ecSmrg    return pScreen->CloseScreen(index, pScreen);
84005b261ecSmrg}
84105b261ecSmrg
84205b261ecSmrgstatic Bool
84305b261ecSmrgvfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
84405b261ecSmrg{
84505b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[index];
84605b261ecSmrg    int dpix = monitorResolution, dpiy = monitorResolution;
84705b261ecSmrg    int ret;
84805b261ecSmrg    char *pbits;
84905b261ecSmrg
85005b261ecSmrg    if (dpix == 0)
85105b261ecSmrg      dpix = 100;
85205b261ecSmrg
85305b261ecSmrg    if (dpiy == 0)
85405b261ecSmrg      dpiy = 100;
85505b261ecSmrg
85605b261ecSmrg    pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
85705b261ecSmrg    pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
85805b261ecSmrg    if (pvfb->bitsPerPixel >= 8 )
85905b261ecSmrg	pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
86005b261ecSmrg    else
86105b261ecSmrg	pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
86205b261ecSmrg    pbits = vfbAllocateFramebufferMemory(pvfb);
86305b261ecSmrg    if (!pbits) return FALSE;
86405b261ecSmrg
86505b261ecSmrg    miSetPixmapDepths ();
86605b261ecSmrg
86705b261ecSmrg    switch (pvfb->depth) {
86805b261ecSmrg    case 8:
86905b261ecSmrg	miSetVisualTypesAndMasks (8,
87005b261ecSmrg				  ((1 << StaticGray) |
87105b261ecSmrg				   (1 << GrayScale) |
87205b261ecSmrg				   (1 << StaticColor) |
87305b261ecSmrg				   (1 << PseudoColor) |
87405b261ecSmrg				   (1 << TrueColor) |
87505b261ecSmrg				   (1 << DirectColor)),
87605b261ecSmrg				  8, PseudoColor, 0, 0, 0);
87705b261ecSmrg	break;
87805b261ecSmrg#if 0
87905b261ecSmrg    /* 12bit PseudoColor with 12bit color resolution
88005b261ecSmrg     * (to simulate SGI hardware and the 12bit PseudoColor emulation layer) */
88105b261ecSmrg    case 12:
88205b261ecSmrg	miSetVisualTypesAndMasks (12,
88305b261ecSmrg				  ((1 << StaticGray) |
88405b261ecSmrg				   (1 << GrayScale) |
88505b261ecSmrg				   (1 << StaticColor) |
88605b261ecSmrg				   (1 << PseudoColor) |
88705b261ecSmrg				   (1 << TrueColor) |
88805b261ecSmrg				   (1 << DirectColor)),
88905b261ecSmrg				  12, PseudoColor, 0, 0, 0);
89005b261ecSmrg	break;
89105b261ecSmrg#endif
89205b261ecSmrg    case 15:
89305b261ecSmrg	miSetVisualTypesAndMasks (15,
89405b261ecSmrg				  ((1 << TrueColor) |
89505b261ecSmrg				   (1 << DirectColor)),
89605b261ecSmrg				  8, TrueColor, 0x7c00, 0x03e0, 0x001f);
89705b261ecSmrg	break;
89805b261ecSmrg    case 16:
89905b261ecSmrg	miSetVisualTypesAndMasks (16,
90005b261ecSmrg				  ((1 << TrueColor) |
90105b261ecSmrg				   (1 << DirectColor)),
90205b261ecSmrg				  8, TrueColor, 0xf800, 0x07e0, 0x001f);
90305b261ecSmrg	break;
90405b261ecSmrg    case 24:
90505b261ecSmrg	miSetVisualTypesAndMasks (24,
90605b261ecSmrg				  ((1 << TrueColor) |
90705b261ecSmrg				   (1 << DirectColor)),
90805b261ecSmrg				  8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
90905b261ecSmrg	break;
91005b261ecSmrg#if 0
91105b261ecSmrg    /* 30bit TrueColor (to simulate Sun's XVR-1000/-4000 high quality
91205b261ecSmrg     * framebuffer series) */
91305b261ecSmrg    case 30:
91405b261ecSmrg	miSetVisualTypesAndMasks (30,
91505b261ecSmrg				  ((1 << TrueColor) |
91605b261ecSmrg				   (1 << DirectColor)),
91705b261ecSmrg				  10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff);
91805b261ecSmrg	break;
91905b261ecSmrg#endif
92005b261ecSmrg    }
92105b261ecSmrg
92205b261ecSmrg    ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
92305b261ecSmrg		       dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel);
92405b261ecSmrg#ifdef RENDER
92505b261ecSmrg    if (ret && Render)
92605b261ecSmrg	fbPictureInit (pScreen, 0, 0);
92705b261ecSmrg#endif
92805b261ecSmrg
92905b261ecSmrg    if (!ret) return FALSE;
93005b261ecSmrg
93105b261ecSmrg    miInitializeBackingStore(pScreen);
93205b261ecSmrg
93305b261ecSmrg    /*
93405b261ecSmrg     * Circumvent the backing store that was just initialised.  This amounts
93505b261ecSmrg     * to a truely bizarre way of initialising SaveDoomedAreas and friends.
93605b261ecSmrg     */
93705b261ecSmrg
93805b261ecSmrg    pScreen->InstallColormap = vfbInstallColormap;
93905b261ecSmrg    pScreen->UninstallColormap = vfbUninstallColormap;
94005b261ecSmrg    pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
94105b261ecSmrg
94205b261ecSmrg    pScreen->SaveScreen = vfbSaveScreen;
94305b261ecSmrg    pScreen->StoreColors = vfbStoreColors;
94405b261ecSmrg
94505b261ecSmrg    miDCInitialize(pScreen, &vfbPointerCursorFuncs);
94605b261ecSmrg
94705b261ecSmrg    vfbWriteXWDFileHeader(pScreen);
94805b261ecSmrg
94905b261ecSmrg    pScreen->blackPixel = pvfb->blackPixel;
95005b261ecSmrg    pScreen->whitePixel = pvfb->whitePixel;
95105b261ecSmrg
95205b261ecSmrg    ret = fbCreateDefColormap(pScreen);
95305b261ecSmrg
95405b261ecSmrg    miSetZeroLineBias(pScreen, pvfb->lineBias);
95505b261ecSmrg
95605b261ecSmrg    pvfb->closeScreen = pScreen->CloseScreen;
95705b261ecSmrg    pScreen->CloseScreen = vfbCloseScreen;
95805b261ecSmrg
95905b261ecSmrg    return ret;
96005b261ecSmrg
96105b261ecSmrg} /* end vfbScreenInit */
96205b261ecSmrg
96305b261ecSmrg
96405b261ecSmrgvoid
96505b261ecSmrgInitOutput(ScreenInfo *screenInfo, int argc, char **argv)
96605b261ecSmrg{
96705b261ecSmrg    int i;
96805b261ecSmrg    int NumFormats = 0;
96905b261ecSmrg
97005b261ecSmrg    /* initialize pixmap formats */
97105b261ecSmrg
97205b261ecSmrg    /* must have a pixmap depth to match every screen depth */
97305b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
97405b261ecSmrg    {
97505b261ecSmrg	vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
97605b261ecSmrg    }
97705b261ecSmrg
97805b261ecSmrg    /* RENDER needs a good set of pixmaps. */
97905b261ecSmrg    if (Render) {
98005b261ecSmrg	vfbPixmapDepths[1] = TRUE;
98105b261ecSmrg	vfbPixmapDepths[4] = TRUE;
98205b261ecSmrg	vfbPixmapDepths[8] = TRUE;
98305b261ecSmrg#if 0
98405b261ecSmrg	vfbPixmapDepths[12] = TRUE;
98505b261ecSmrg#endif
98605b261ecSmrg/*	vfbPixmapDepths[15] = TRUE; */
98705b261ecSmrg	vfbPixmapDepths[16] = TRUE;
98805b261ecSmrg	vfbPixmapDepths[24] = TRUE;
98905b261ecSmrg#if 0
99005b261ecSmrg	vfbPixmapDepths[30] = TRUE;
99105b261ecSmrg#endif
99205b261ecSmrg	vfbPixmapDepths[32] = TRUE;
99305b261ecSmrg    }
99405b261ecSmrg
99505b261ecSmrg    for (i = 1; i <= 32; i++)
99605b261ecSmrg    {
99705b261ecSmrg	if (vfbPixmapDepths[i])
99805b261ecSmrg	{
99905b261ecSmrg	    if (NumFormats >= MAXFORMATS)
100005b261ecSmrg		FatalError ("MAXFORMATS is too small for this server\n");
100105b261ecSmrg	    screenInfo->formats[NumFormats].depth = i;
100205b261ecSmrg	    screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
100305b261ecSmrg	    screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
100405b261ecSmrg	    NumFormats++;
100505b261ecSmrg	}
100605b261ecSmrg    }
100705b261ecSmrg
100805b261ecSmrg    screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
100905b261ecSmrg    screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
101005b261ecSmrg    screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
101105b261ecSmrg    screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
101205b261ecSmrg    screenInfo->numPixmapFormats = NumFormats;
101305b261ecSmrg
101405b261ecSmrg    /* initialize screens */
101505b261ecSmrg
101605b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
101705b261ecSmrg    {
101805b261ecSmrg	if (-1 == AddScreen(vfbScreenInit, argc, argv))
101905b261ecSmrg	{
102005b261ecSmrg	    FatalError("Couldn't add screen %d", i);
102105b261ecSmrg	}
102205b261ecSmrg    }
102305b261ecSmrg
102405b261ecSmrg} /* end InitOutput */
1025