InitOutput.c revision 05b261ec
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");
18205b261ecSmrg		ErrorF("unlink %s failed, errno %d",
18305b261ecSmrg		       vfbScreens[i].mmap_file, 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");
19905b261ecSmrg		ErrorF("shmdt failed, errno %d", 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
22305b261ecSmrg#ifdef __DARWIN__
22405b261ecSmrgvoid
22505b261ecSmrgDarwinHandleGUI(int argc, char *argv[])
22605b261ecSmrg{
22705b261ecSmrg}
22805b261ecSmrg
22905b261ecSmrgvoid GlxExtensionInit();
23005b261ecSmrgvoid GlxWrapInitVisuals(void *procPtr);
23105b261ecSmrg
23205b261ecSmrgvoid
23305b261ecSmrgDarwinGlxExtensionInit()
23405b261ecSmrg{
23505b261ecSmrg    GlxExtensionInit();
23605b261ecSmrg}
23705b261ecSmrg
23805b261ecSmrgvoid
23905b261ecSmrgDarwinGlxWrapInitVisuals(
24005b261ecSmrg    void *procPtr)
24105b261ecSmrg{
24205b261ecSmrg    GlxWrapInitVisuals(procPtr);
24305b261ecSmrg}
24405b261ecSmrg#endif
24505b261ecSmrg
24605b261ecSmrgvoid
24705b261ecSmrgOsVendorInit()
24805b261ecSmrg{
24905b261ecSmrg}
25005b261ecSmrg
25105b261ecSmrgvoid
25205b261ecSmrgOsVendorFatalError()
25305b261ecSmrg{
25405b261ecSmrg}
25505b261ecSmrg
25605b261ecSmrg#if defined(DDXBEFORERESET)
25705b261ecSmrgvoid ddxBeforeReset(void)
25805b261ecSmrg{
25905b261ecSmrg    return;
26005b261ecSmrg}
26105b261ecSmrg#endif
26205b261ecSmrg
26305b261ecSmrgvoid
26405b261ecSmrgddxUseMsg()
26505b261ecSmrg{
26605b261ecSmrg    ErrorF("-screen scrn WxHxD     set screen's width, height, depth\n");
26705b261ecSmrg    ErrorF("-pixdepths list-of-int support given pixmap depths\n");
26805b261ecSmrg#ifdef RENDER
26905b261ecSmrg    ErrorF("+/-render		   turn on/of RENDER extension support"
27005b261ecSmrg	   "(default on)\n");
27105b261ecSmrg#endif
27205b261ecSmrg    ErrorF("-linebias n            adjust thin line pixelization\n");
27305b261ecSmrg    ErrorF("-blackpixel n          pixel value for black\n");
27405b261ecSmrg    ErrorF("-whitepixel n          pixel value for white\n");
27505b261ecSmrg
27605b261ecSmrg#ifdef HAS_MMAP
27705b261ecSmrg    ErrorF("-fbdir directory       put framebuffers in mmap'ed files in directory\n");
27805b261ecSmrg#endif
27905b261ecSmrg
28005b261ecSmrg#ifdef HAS_SHM
28105b261ecSmrg    ErrorF("-shmem                 put framebuffers in shared memory\n");
28205b261ecSmrg#endif
28305b261ecSmrg}
28405b261ecSmrg
28505b261ecSmrg/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
28605b261ecSmrgvoid ddxInitGlobals(void)
28705b261ecSmrg{
28805b261ecSmrg}
28905b261ecSmrg
29005b261ecSmrgint
29105b261ecSmrgddxProcessArgument(int argc, char *argv[], int i)
29205b261ecSmrg{
29305b261ecSmrg    static Bool firstTime = TRUE;
29405b261ecSmrg
29505b261ecSmrg    if (firstTime)
29605b261ecSmrg    {
29705b261ecSmrg	vfbInitializeDefaultScreens();
29805b261ecSmrg	vfbInitializePixmapDepths();
29905b261ecSmrg        firstTime = FALSE;
30005b261ecSmrg    }
30105b261ecSmrg
30205b261ecSmrg#define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
30305b261ecSmrg    if (((i + num) >= argc) || (!argv[i + num])) {                      \
30405b261ecSmrg      ErrorF("Required argument to %s not specified\n", argv[i]);       \
30505b261ecSmrg      UseMsg();                                                         \
30605b261ecSmrg      FatalError("Required argument to %s not specified\n", argv[i]);   \
30705b261ecSmrg    }
30805b261ecSmrg
30905b261ecSmrg    if (strcmp (argv[i], "-screen") == 0)	/* -screen n WxHxD */
31005b261ecSmrg    {
31105b261ecSmrg	int screenNum;
31205b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(2);
31305b261ecSmrg	screenNum = atoi(argv[i+1]);
31405b261ecSmrg	if (screenNum < 0 || screenNum >= MAXSCREENS)
31505b261ecSmrg	{
31605b261ecSmrg	    ErrorF("Invalid screen number %d\n", screenNum);
31705b261ecSmrg	    UseMsg();
31805b261ecSmrg	    FatalError("Invalid screen number %d passed to -screen\n",
31905b261ecSmrg		       screenNum);
32005b261ecSmrg	}
32105b261ecSmrg	if (3 != sscanf(argv[i+2], "%dx%dx%d",
32205b261ecSmrg			&vfbScreens[screenNum].width,
32305b261ecSmrg			&vfbScreens[screenNum].height,
32405b261ecSmrg			&vfbScreens[screenNum].depth))
32505b261ecSmrg	{
32605b261ecSmrg	    ErrorF("Invalid screen configuration %s\n", argv[i+2]);
32705b261ecSmrg	    UseMsg();
32805b261ecSmrg	    FatalError("Invalid screen configuration %s for -screen %d\n",
32905b261ecSmrg		   argv[i+2], screenNum);
33005b261ecSmrg	}
33105b261ecSmrg
33205b261ecSmrg	if (screenNum >= vfbNumScreens)
33305b261ecSmrg	    vfbNumScreens = screenNum + 1;
33405b261ecSmrg	lastScreen = screenNum;
33505b261ecSmrg	return 3;
33605b261ecSmrg    }
33705b261ecSmrg
33805b261ecSmrg    if (strcmp (argv[i], "-pixdepths") == 0)	/* -pixdepths list-of-depth */
33905b261ecSmrg    {
34005b261ecSmrg	int depth, ret = 1;
34105b261ecSmrg
34205b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
34305b261ecSmrg	while ((++i < argc) && (depth = atoi(argv[i])) != 0)
34405b261ecSmrg	{
34505b261ecSmrg	    if (depth < 0 || depth > 32)
34605b261ecSmrg	    {
34705b261ecSmrg		ErrorF("Invalid pixmap depth %d\n", depth);
34805b261ecSmrg		UseMsg();
34905b261ecSmrg		FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
35005b261ecSmrg			   depth);
35105b261ecSmrg	    }
35205b261ecSmrg	    vfbPixmapDepths[depth] = TRUE;
35305b261ecSmrg	    ret++;
35405b261ecSmrg	}
35505b261ecSmrg	return ret;
35605b261ecSmrg    }
35705b261ecSmrg
35805b261ecSmrg    if (strcmp (argv[i], "+render") == 0)	/* +render */
35905b261ecSmrg    {
36005b261ecSmrg	Render = TRUE;
36105b261ecSmrg	return 1;
36205b261ecSmrg    }
36305b261ecSmrg
36405b261ecSmrg    if (strcmp (argv[i], "-render") == 0)	/* -render */
36505b261ecSmrg    {
36605b261ecSmrg	Render = FALSE;
36705b261ecSmrg#ifdef COMPOSITE
36805b261ecSmrg	noCompositeExtension = TRUE;
36905b261ecSmrg#endif
37005b261ecSmrg	return 1;
37105b261ecSmrg    }
37205b261ecSmrg
37305b261ecSmrg    if (strcmp (argv[i], "-blackpixel") == 0)	/* -blackpixel n */
37405b261ecSmrg    {
37505b261ecSmrg	Pixel pix;
37605b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
37705b261ecSmrg	pix = atoi(argv[++i]);
37805b261ecSmrg	if (-1 == lastScreen)
37905b261ecSmrg	{
38005b261ecSmrg	    int i;
38105b261ecSmrg	    for (i = 0; i < MAXSCREENS; i++)
38205b261ecSmrg	    {
38305b261ecSmrg		vfbScreens[i].blackPixel = pix;
38405b261ecSmrg	    }
38505b261ecSmrg	}
38605b261ecSmrg	else
38705b261ecSmrg	{
38805b261ecSmrg	    vfbScreens[lastScreen].blackPixel = pix;
38905b261ecSmrg	}
39005b261ecSmrg	return 2;
39105b261ecSmrg    }
39205b261ecSmrg
39305b261ecSmrg    if (strcmp (argv[i], "-whitepixel") == 0)	/* -whitepixel n */
39405b261ecSmrg    {
39505b261ecSmrg	Pixel pix;
39605b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
39705b261ecSmrg	pix = atoi(argv[++i]);
39805b261ecSmrg	if (-1 == lastScreen)
39905b261ecSmrg	{
40005b261ecSmrg	    int i;
40105b261ecSmrg	    for (i = 0; i < MAXSCREENS; i++)
40205b261ecSmrg	    {
40305b261ecSmrg		vfbScreens[i].whitePixel = pix;
40405b261ecSmrg	    }
40505b261ecSmrg	}
40605b261ecSmrg	else
40705b261ecSmrg	{
40805b261ecSmrg	    vfbScreens[lastScreen].whitePixel = pix;
40905b261ecSmrg	}
41005b261ecSmrg	return 2;
41105b261ecSmrg    }
41205b261ecSmrg
41305b261ecSmrg    if (strcmp (argv[i], "-linebias") == 0)	/* -linebias n */
41405b261ecSmrg    {
41505b261ecSmrg	unsigned int linebias;
41605b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
41705b261ecSmrg	linebias = atoi(argv[++i]);
41805b261ecSmrg	if (-1 == lastScreen)
41905b261ecSmrg	{
42005b261ecSmrg	    int i;
42105b261ecSmrg	    for (i = 0; i < MAXSCREENS; i++)
42205b261ecSmrg	    {
42305b261ecSmrg		vfbScreens[i].lineBias = linebias;
42405b261ecSmrg	    }
42505b261ecSmrg	}
42605b261ecSmrg	else
42705b261ecSmrg	{
42805b261ecSmrg	    vfbScreens[lastScreen].lineBias = linebias;
42905b261ecSmrg	}
43005b261ecSmrg	return 2;
43105b261ecSmrg    }
43205b261ecSmrg
43305b261ecSmrg#ifdef HAS_MMAP
43405b261ecSmrg    if (strcmp (argv[i], "-fbdir") == 0)	/* -fbdir directory */
43505b261ecSmrg    {
43605b261ecSmrg	CHECK_FOR_REQUIRED_ARGUMENTS(1);
43705b261ecSmrg	pfbdir = argv[++i];
43805b261ecSmrg	fbmemtype = MMAPPED_FILE_FB;
43905b261ecSmrg	return 2;
44005b261ecSmrg    }
44105b261ecSmrg#endif /* HAS_MMAP */
44205b261ecSmrg
44305b261ecSmrg#ifdef HAS_SHM
44405b261ecSmrg    if (strcmp (argv[i], "-shmem") == 0)	/* -shmem */
44505b261ecSmrg    {
44605b261ecSmrg	fbmemtype = SHARED_MEMORY_FB;
44705b261ecSmrg	return 1;
44805b261ecSmrg    }
44905b261ecSmrg#endif
45005b261ecSmrg
45105b261ecSmrg    return 0;
45205b261ecSmrg}
45305b261ecSmrg
45405b261ecSmrgstatic ColormapPtr InstalledMaps[MAXSCREENS];
45505b261ecSmrg
45605b261ecSmrgstatic int
45705b261ecSmrgvfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
45805b261ecSmrg{
45905b261ecSmrg    /* By the time we are processing requests, we can guarantee that there
46005b261ecSmrg     * is always a colormap installed */
46105b261ecSmrg    *pmaps = InstalledMaps[pScreen->myNum]->mid;
46205b261ecSmrg    return (1);
46305b261ecSmrg}
46405b261ecSmrg
46505b261ecSmrg
46605b261ecSmrgstatic void
46705b261ecSmrgvfbInstallColormap(ColormapPtr pmap)
46805b261ecSmrg{
46905b261ecSmrg    int index = pmap->pScreen->myNum;
47005b261ecSmrg    ColormapPtr oldpmap = InstalledMaps[index];
47105b261ecSmrg
47205b261ecSmrg    if (pmap != oldpmap)
47305b261ecSmrg    {
47405b261ecSmrg	int entries;
47505b261ecSmrg	XWDFileHeader *pXWDHeader;
47605b261ecSmrg	XWDColor *pXWDCmap;
47705b261ecSmrg	VisualPtr pVisual;
47805b261ecSmrg	Pixel *     ppix;
47905b261ecSmrg	xrgb *      prgb;
48005b261ecSmrg	xColorItem *defs;
48105b261ecSmrg	int i;
48205b261ecSmrg
48305b261ecSmrg	if(oldpmap != (ColormapPtr)None)
48405b261ecSmrg	    WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
48505b261ecSmrg	/* Install pmap */
48605b261ecSmrg	InstalledMaps[index] = pmap;
48705b261ecSmrg	WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
48805b261ecSmrg
48905b261ecSmrg	entries = pmap->pVisual->ColormapEntries;
49005b261ecSmrg	pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
49105b261ecSmrg	pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
49205b261ecSmrg	pVisual = pmap->pVisual;
49305b261ecSmrg
49405b261ecSmrg	swapcopy32(pXWDHeader->visual_class, pVisual->class);
49505b261ecSmrg	swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
49605b261ecSmrg	swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
49705b261ecSmrg	swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
49805b261ecSmrg	swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
49905b261ecSmrg	swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
50005b261ecSmrg
50105b261ecSmrg	ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel));
50205b261ecSmrg	prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb));
50305b261ecSmrg	defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
50405b261ecSmrg
50505b261ecSmrg	for (i = 0; i < entries; i++)  ppix[i] = i;
50605b261ecSmrg	/* XXX truecolor */
50705b261ecSmrg	QueryColors(pmap, entries, ppix, prgb);
50805b261ecSmrg
50905b261ecSmrg	for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
51005b261ecSmrg	    defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
51105b261ecSmrg	    defs[i].red = prgb[i].red;
51205b261ecSmrg	    defs[i].green = prgb[i].green;
51305b261ecSmrg	    defs[i].blue = prgb[i].blue;
51405b261ecSmrg	    defs[i].flags =  DoRed|DoGreen|DoBlue;
51505b261ecSmrg	}
51605b261ecSmrg	(*pmap->pScreen->StoreColors)(pmap, entries, defs);
51705b261ecSmrg
51805b261ecSmrg	DEALLOCATE_LOCAL(ppix);
51905b261ecSmrg	DEALLOCATE_LOCAL(prgb);
52005b261ecSmrg	DEALLOCATE_LOCAL(defs);
52105b261ecSmrg    }
52205b261ecSmrg}
52305b261ecSmrg
52405b261ecSmrgstatic void
52505b261ecSmrgvfbUninstallColormap(ColormapPtr pmap)
52605b261ecSmrg{
52705b261ecSmrg    ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
52805b261ecSmrg
52905b261ecSmrg    if(pmap == curpmap)
53005b261ecSmrg    {
53105b261ecSmrg	if (pmap->mid != pmap->pScreen->defColormap)
53205b261ecSmrg	{
53305b261ecSmrg	    curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
53405b261ecSmrg						   RT_COLORMAP);
53505b261ecSmrg	    (*pmap->pScreen->InstallColormap)(curpmap);
53605b261ecSmrg	}
53705b261ecSmrg    }
53805b261ecSmrg}
53905b261ecSmrg
54005b261ecSmrgstatic void
54105b261ecSmrgvfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
54205b261ecSmrg{
54305b261ecSmrg    XWDColor *pXWDCmap;
54405b261ecSmrg    int i;
54505b261ecSmrg
54605b261ecSmrg    if (pmap != InstalledMaps[pmap->pScreen->myNum])
54705b261ecSmrg    {
54805b261ecSmrg	return;
54905b261ecSmrg    }
55005b261ecSmrg
55105b261ecSmrg    pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
55205b261ecSmrg
55305b261ecSmrg    if ((pmap->pVisual->class | DynamicClass) == DirectColor)
55405b261ecSmrg    {
55505b261ecSmrg	return;
55605b261ecSmrg    }
55705b261ecSmrg
55805b261ecSmrg    for (i = 0; i < ndef; i++)
55905b261ecSmrg    {
56005b261ecSmrg	if (pdefs[i].flags & DoRed)
56105b261ecSmrg	{
56205b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
56305b261ecSmrg	}
56405b261ecSmrg	if (pdefs[i].flags & DoGreen)
56505b261ecSmrg	{
56605b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
56705b261ecSmrg	}
56805b261ecSmrg	if (pdefs[i].flags & DoBlue)
56905b261ecSmrg	{
57005b261ecSmrg	    swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
57105b261ecSmrg	}
57205b261ecSmrg    }
57305b261ecSmrg}
57405b261ecSmrg
57505b261ecSmrgstatic Bool
57605b261ecSmrgvfbSaveScreen(ScreenPtr pScreen, int on)
57705b261ecSmrg{
57805b261ecSmrg    return TRUE;
57905b261ecSmrg}
58005b261ecSmrg
58105b261ecSmrg#ifdef HAS_MMAP
58205b261ecSmrg
58305b261ecSmrg/* this flushes any changes to the screens out to the mmapped file */
58405b261ecSmrgstatic void
58505b261ecSmrgvfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
58605b261ecSmrg{
58705b261ecSmrg    int i;
58805b261ecSmrg
58905b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
59005b261ecSmrg    {
59105b261ecSmrg#ifdef MS_ASYNC
59205b261ecSmrg	if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
59305b261ecSmrg			(size_t)vfbScreens[i].sizeInBytes, MS_ASYNC))
59405b261ecSmrg#else
59505b261ecSmrg	/* silly NetBSD and who else? */
59605b261ecSmrg	if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
59705b261ecSmrg			(size_t)vfbScreens[i].sizeInBytes))
59805b261ecSmrg#endif
59905b261ecSmrg	{
60005b261ecSmrg	    perror("msync");
60105b261ecSmrg	    ErrorF("msync failed, errno %d", errno);
60205b261ecSmrg	}
60305b261ecSmrg    }
60405b261ecSmrg}
60505b261ecSmrg
60605b261ecSmrg
60705b261ecSmrgstatic void
60805b261ecSmrgvfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
60905b261ecSmrg{
61005b261ecSmrg}
61105b261ecSmrg
61205b261ecSmrg
61305b261ecSmrgstatic void
61405b261ecSmrgvfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
61505b261ecSmrg{
61605b261ecSmrg#define DUMMY_BUFFER_SIZE 65536
61705b261ecSmrg    char dummyBuffer[DUMMY_BUFFER_SIZE];
61805b261ecSmrg    int currentFileSize, writeThisTime;
61905b261ecSmrg
62005b261ecSmrg    sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, pvfb->scrnum);
62105b261ecSmrg    if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
62205b261ecSmrg    {
62305b261ecSmrg	perror("open");
62405b261ecSmrg	ErrorF("open %s failed, errno %d", pvfb->mmap_file, errno);
62505b261ecSmrg	return;
62605b261ecSmrg    }
62705b261ecSmrg
62805b261ecSmrg    /* Extend the file to be the proper size */
62905b261ecSmrg
63005b261ecSmrg    bzero(dummyBuffer, DUMMY_BUFFER_SIZE);
63105b261ecSmrg    for (currentFileSize = 0;
63205b261ecSmrg	 currentFileSize < pvfb->sizeInBytes;
63305b261ecSmrg	 currentFileSize += writeThisTime)
63405b261ecSmrg    {
63505b261ecSmrg	writeThisTime = min(DUMMY_BUFFER_SIZE,
63605b261ecSmrg			    pvfb->sizeInBytes - currentFileSize);
63705b261ecSmrg	if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime))
63805b261ecSmrg	{
63905b261ecSmrg	    perror("write");
64005b261ecSmrg	    ErrorF("write %s failed, errno %d", pvfb->mmap_file, errno);
64105b261ecSmrg	    return;
64205b261ecSmrg	}
64305b261ecSmrg    }
64405b261ecSmrg
64505b261ecSmrg    /* try to mmap the file */
64605b261ecSmrg
64705b261ecSmrg    pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes,
64805b261ecSmrg				    PROT_READ|PROT_WRITE,
64905b261ecSmrg				    MAP_FILE|MAP_SHARED,
65005b261ecSmrg				    pvfb->mmap_fd, 0);
65105b261ecSmrg    if (-1 == (long)pvfb->pXWDHeader)
65205b261ecSmrg    {
65305b261ecSmrg	perror("mmap");
65405b261ecSmrg	ErrorF("mmap %s failed, errno %d", pvfb->mmap_file, errno);
65505b261ecSmrg	pvfb->pXWDHeader = NULL;
65605b261ecSmrg	return;
65705b261ecSmrg    }
65805b261ecSmrg
65905b261ecSmrg    if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
66005b261ecSmrg					NULL))
66105b261ecSmrg    {
66205b261ecSmrg	pvfb->pXWDHeader = NULL;
66305b261ecSmrg    }
66405b261ecSmrg}
66505b261ecSmrg#endif /* HAS_MMAP */
66605b261ecSmrg
66705b261ecSmrg
66805b261ecSmrg#ifdef HAS_SHM
66905b261ecSmrgstatic void
67005b261ecSmrgvfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
67105b261ecSmrg{
67205b261ecSmrg    /* create the shared memory segment */
67305b261ecSmrg
67405b261ecSmrg    pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777);
67505b261ecSmrg    if (pvfb->shmid < 0)
67605b261ecSmrg    {
67705b261ecSmrg	perror("shmget");
67805b261ecSmrg	ErrorF("shmget %d bytes failed, errno %d", pvfb->sizeInBytes, errno);
67905b261ecSmrg	return;
68005b261ecSmrg    }
68105b261ecSmrg
68205b261ecSmrg    /* try to attach it */
68305b261ecSmrg
68405b261ecSmrg    pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0);
68505b261ecSmrg    if (-1 == (long)pvfb->pXWDHeader)
68605b261ecSmrg    {
68705b261ecSmrg	perror("shmat");
68805b261ecSmrg	ErrorF("shmat failed, errno %d", errno);
68905b261ecSmrg	pvfb->pXWDHeader = NULL;
69005b261ecSmrg	return;
69105b261ecSmrg    }
69205b261ecSmrg
69305b261ecSmrg    ErrorF("screen %d shmid %d\n", pvfb->scrnum, pvfb->shmid);
69405b261ecSmrg}
69505b261ecSmrg#endif /* HAS_SHM */
69605b261ecSmrg
69705b261ecSmrgstatic char *
69805b261ecSmrgvfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
69905b261ecSmrg{
70005b261ecSmrg    if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
70105b261ecSmrg
70205b261ecSmrg    pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
70305b261ecSmrg
70405b261ecSmrg    /* Calculate how many entries in colormap.  This is rather bogus, because
70505b261ecSmrg     * the visuals haven't even been set up yet, but we need to know because we
70605b261ecSmrg     * have to allocate space in the file for the colormap.  The number 10
70705b261ecSmrg     * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
70805b261ecSmrg     */
70905b261ecSmrg
71005b261ecSmrg    if (pvfb->depth <= 10)
71105b261ecSmrg    { /* single index colormaps */
71205b261ecSmrg	pvfb->ncolors = 1 << pvfb->depth;
71305b261ecSmrg    }
71405b261ecSmrg    else
71505b261ecSmrg    { /* decomposed colormaps */
71605b261ecSmrg	int nplanes_per_color_component = pvfb->depth / 3;
71705b261ecSmrg	if (pvfb->depth % 3) nplanes_per_color_component++;
71805b261ecSmrg	pvfb->ncolors = 1 << nplanes_per_color_component;
71905b261ecSmrg    }
72005b261ecSmrg
72105b261ecSmrg    /* add extra bytes for XWDFileHeader, window name, and colormap */
72205b261ecSmrg
72305b261ecSmrg    pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
72405b261ecSmrg		    pvfb->ncolors * SIZEOF(XWDColor);
72505b261ecSmrg
72605b261ecSmrg    pvfb->pXWDHeader = NULL;
72705b261ecSmrg    switch (fbmemtype)
72805b261ecSmrg    {
72905b261ecSmrg#ifdef HAS_MMAP
73005b261ecSmrg    case MMAPPED_FILE_FB:  vfbAllocateMmappedFramebuffer(pvfb); break;
73105b261ecSmrg#else
73205b261ecSmrg    case MMAPPED_FILE_FB: break;
73305b261ecSmrg#endif
73405b261ecSmrg
73505b261ecSmrg#ifdef HAS_SHM
73605b261ecSmrg    case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
73705b261ecSmrg#else
73805b261ecSmrg    case SHARED_MEMORY_FB: break;
73905b261ecSmrg#endif
74005b261ecSmrg
74105b261ecSmrg    case NORMAL_MEMORY_FB:
74205b261ecSmrg	pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
74305b261ecSmrg	break;
74405b261ecSmrg    }
74505b261ecSmrg
74605b261ecSmrg    if (pvfb->pXWDHeader)
74705b261ecSmrg    {
74805b261ecSmrg	pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
74905b261ecSmrg				+ SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
75005b261ecSmrg	pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
75105b261ecSmrg
75205b261ecSmrg	return pvfb->pfbMemory;
75305b261ecSmrg    }
75405b261ecSmrg    else
75505b261ecSmrg	return NULL;
75605b261ecSmrg}
75705b261ecSmrg
75805b261ecSmrg
75905b261ecSmrgstatic void
76005b261ecSmrgvfbWriteXWDFileHeader(ScreenPtr pScreen)
76105b261ecSmrg{
76205b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
76305b261ecSmrg    XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
76405b261ecSmrg    char hostname[XWD_WINDOW_NAME_LEN];
76505b261ecSmrg    unsigned long swaptest = 1;
76605b261ecSmrg    int i;
76705b261ecSmrg
76805b261ecSmrg    needswap = *(char *) &swaptest;
76905b261ecSmrg
77005b261ecSmrg    pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
77105b261ecSmrg    pXWDHeader->file_version = XWD_FILE_VERSION;
77205b261ecSmrg
77305b261ecSmrg    pXWDHeader->pixmap_format = ZPixmap;
77405b261ecSmrg    pXWDHeader->pixmap_depth = pvfb->depth;
77505b261ecSmrg    pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
77605b261ecSmrg    pXWDHeader->xoffset = 0;
77705b261ecSmrg    pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
77805b261ecSmrg    pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
77905b261ecSmrg#ifndef INTERNAL_VS_EXTERNAL_PADDING
78005b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
78105b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
78205b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
78305b261ecSmrg#else
78405b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
78505b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
78605b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
78705b261ecSmrg#endif
78805b261ecSmrg    pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
78905b261ecSmrg    pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
79005b261ecSmrg    pXWDHeader->ncolors = pvfb->ncolors;
79105b261ecSmrg
79205b261ecSmrg    /* visual related fields are written when colormap is installed */
79305b261ecSmrg
79405b261ecSmrg    pXWDHeader->window_x = pXWDHeader->window_y = 0;
79505b261ecSmrg    pXWDHeader->window_bdrwidth = 0;
79605b261ecSmrg
79705b261ecSmrg    /* write xwd "window" name: Xvfb hostname:server.screen */
79805b261ecSmrg
79905b261ecSmrg    if (-1 == gethostname(hostname, sizeof(hostname)))
80005b261ecSmrg	hostname[0] = 0;
80105b261ecSmrg    else
80205b261ecSmrg	hostname[XWD_WINDOW_NAME_LEN-1] = 0;
80305b261ecSmrg    sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
80405b261ecSmrg	    pScreen->myNum);
80505b261ecSmrg
80605b261ecSmrg    /* write colormap pixel slot values */
80705b261ecSmrg
80805b261ecSmrg    for (i = 0; i < pvfb->ncolors; i++)
80905b261ecSmrg    {
81005b261ecSmrg	pvfb->pXWDCmap[i].pixel = i;
81105b261ecSmrg    }
81205b261ecSmrg
81305b261ecSmrg    /* byte swap to most significant byte first */
81405b261ecSmrg
81505b261ecSmrg    if (needswap)
81605b261ecSmrg    {
81705b261ecSmrg	SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
81805b261ecSmrg	for (i = 0; i < pvfb->ncolors; i++)
81905b261ecSmrg	{
82005b261ecSmrg	    register char n;
82105b261ecSmrg	    swapl(&pvfb->pXWDCmap[i].pixel, n);
82205b261ecSmrg	}
82305b261ecSmrg    }
82405b261ecSmrg}
82505b261ecSmrg
82605b261ecSmrg
82705b261ecSmrgstatic Bool
82805b261ecSmrgvfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
82905b261ecSmrg{
83005b261ecSmrg    return FALSE;
83105b261ecSmrg}
83205b261ecSmrg
83305b261ecSmrgstatic void
83405b261ecSmrgvfbCrossScreen (ScreenPtr pScreen, Bool entering)
83505b261ecSmrg{
83605b261ecSmrg}
83705b261ecSmrg
83805b261ecSmrgstatic miPointerScreenFuncRec vfbPointerCursorFuncs =
83905b261ecSmrg{
84005b261ecSmrg    vfbCursorOffScreen,
84105b261ecSmrg    vfbCrossScreen,
84205b261ecSmrg    miPointerWarpCursor
84305b261ecSmrg};
84405b261ecSmrg
84505b261ecSmrgstatic Bool
84605b261ecSmrgvfbCloseScreen(int index, ScreenPtr pScreen)
84705b261ecSmrg{
84805b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[index];
84905b261ecSmrg    int i;
85005b261ecSmrg
85105b261ecSmrg    pScreen->CloseScreen = pvfb->closeScreen;
85205b261ecSmrg
85305b261ecSmrg    /*
85405b261ecSmrg     * XXX probably lots of stuff to clean.  For now,
85505b261ecSmrg     * clear InstalledMaps[] so that server reset works correctly.
85605b261ecSmrg     */
85705b261ecSmrg    for (i = 0; i < MAXSCREENS; i++)
85805b261ecSmrg	InstalledMaps[i] = NULL;
85905b261ecSmrg
86005b261ecSmrg    return pScreen->CloseScreen(index, pScreen);
86105b261ecSmrg}
86205b261ecSmrg
86305b261ecSmrgstatic Bool
86405b261ecSmrgvfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
86505b261ecSmrg{
86605b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[index];
86705b261ecSmrg    int dpix = monitorResolution, dpiy = monitorResolution;
86805b261ecSmrg    int ret;
86905b261ecSmrg    char *pbits;
87005b261ecSmrg
87105b261ecSmrg    if (dpix == 0)
87205b261ecSmrg      dpix = 100;
87305b261ecSmrg
87405b261ecSmrg    if (dpiy == 0)
87505b261ecSmrg      dpiy = 100;
87605b261ecSmrg
87705b261ecSmrg    pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
87805b261ecSmrg    pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
87905b261ecSmrg    if (pvfb->bitsPerPixel >= 8 )
88005b261ecSmrg	pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
88105b261ecSmrg    else
88205b261ecSmrg	pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
88305b261ecSmrg    pbits = vfbAllocateFramebufferMemory(pvfb);
88405b261ecSmrg    if (!pbits) return FALSE;
88505b261ecSmrg
88605b261ecSmrg    miSetPixmapDepths ();
88705b261ecSmrg
88805b261ecSmrg    switch (pvfb->depth) {
88905b261ecSmrg    case 8:
89005b261ecSmrg	miSetVisualTypesAndMasks (8,
89105b261ecSmrg				  ((1 << StaticGray) |
89205b261ecSmrg				   (1 << GrayScale) |
89305b261ecSmrg				   (1 << StaticColor) |
89405b261ecSmrg				   (1 << PseudoColor) |
89505b261ecSmrg				   (1 << TrueColor) |
89605b261ecSmrg				   (1 << DirectColor)),
89705b261ecSmrg				  8, PseudoColor, 0, 0, 0);
89805b261ecSmrg	break;
89905b261ecSmrg#if 0
90005b261ecSmrg    /* 12bit PseudoColor with 12bit color resolution
90105b261ecSmrg     * (to simulate SGI hardware and the 12bit PseudoColor emulation layer) */
90205b261ecSmrg    case 12:
90305b261ecSmrg	miSetVisualTypesAndMasks (12,
90405b261ecSmrg				  ((1 << StaticGray) |
90505b261ecSmrg				   (1 << GrayScale) |
90605b261ecSmrg				   (1 << StaticColor) |
90705b261ecSmrg				   (1 << PseudoColor) |
90805b261ecSmrg				   (1 << TrueColor) |
90905b261ecSmrg				   (1 << DirectColor)),
91005b261ecSmrg				  12, PseudoColor, 0, 0, 0);
91105b261ecSmrg	break;
91205b261ecSmrg#endif
91305b261ecSmrg    case 15:
91405b261ecSmrg	miSetVisualTypesAndMasks (15,
91505b261ecSmrg				  ((1 << TrueColor) |
91605b261ecSmrg				   (1 << DirectColor)),
91705b261ecSmrg				  8, TrueColor, 0x7c00, 0x03e0, 0x001f);
91805b261ecSmrg	break;
91905b261ecSmrg    case 16:
92005b261ecSmrg	miSetVisualTypesAndMasks (16,
92105b261ecSmrg				  ((1 << TrueColor) |
92205b261ecSmrg				   (1 << DirectColor)),
92305b261ecSmrg				  8, TrueColor, 0xf800, 0x07e0, 0x001f);
92405b261ecSmrg	break;
92505b261ecSmrg    case 24:
92605b261ecSmrg	miSetVisualTypesAndMasks (24,
92705b261ecSmrg				  ((1 << TrueColor) |
92805b261ecSmrg				   (1 << DirectColor)),
92905b261ecSmrg				  8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
93005b261ecSmrg	break;
93105b261ecSmrg#if 0
93205b261ecSmrg    /* 30bit TrueColor (to simulate Sun's XVR-1000/-4000 high quality
93305b261ecSmrg     * framebuffer series) */
93405b261ecSmrg    case 30:
93505b261ecSmrg	miSetVisualTypesAndMasks (30,
93605b261ecSmrg				  ((1 << TrueColor) |
93705b261ecSmrg				   (1 << DirectColor)),
93805b261ecSmrg				  10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff);
93905b261ecSmrg	break;
94005b261ecSmrg#endif
94105b261ecSmrg    }
94205b261ecSmrg
94305b261ecSmrg    ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
94405b261ecSmrg		       dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel);
94505b261ecSmrg#ifdef RENDER
94605b261ecSmrg    if (ret && Render)
94705b261ecSmrg	fbPictureInit (pScreen, 0, 0);
94805b261ecSmrg#endif
94905b261ecSmrg
95005b261ecSmrg    if (!ret) return FALSE;
95105b261ecSmrg
95205b261ecSmrg    miInitializeBackingStore(pScreen);
95305b261ecSmrg
95405b261ecSmrg    /*
95505b261ecSmrg     * Circumvent the backing store that was just initialised.  This amounts
95605b261ecSmrg     * to a truely bizarre way of initialising SaveDoomedAreas and friends.
95705b261ecSmrg     */
95805b261ecSmrg
95905b261ecSmrg    pScreen->InstallColormap = vfbInstallColormap;
96005b261ecSmrg    pScreen->UninstallColormap = vfbUninstallColormap;
96105b261ecSmrg    pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
96205b261ecSmrg
96305b261ecSmrg    pScreen->SaveScreen = vfbSaveScreen;
96405b261ecSmrg    pScreen->StoreColors = vfbStoreColors;
96505b261ecSmrg
96605b261ecSmrg    miDCInitialize(pScreen, &vfbPointerCursorFuncs);
96705b261ecSmrg
96805b261ecSmrg    vfbWriteXWDFileHeader(pScreen);
96905b261ecSmrg
97005b261ecSmrg    pScreen->blackPixel = pvfb->blackPixel;
97105b261ecSmrg    pScreen->whitePixel = pvfb->whitePixel;
97205b261ecSmrg
97305b261ecSmrg    ret = fbCreateDefColormap(pScreen);
97405b261ecSmrg
97505b261ecSmrg    miSetZeroLineBias(pScreen, pvfb->lineBias);
97605b261ecSmrg
97705b261ecSmrg    pvfb->closeScreen = pScreen->CloseScreen;
97805b261ecSmrg    pScreen->CloseScreen = vfbCloseScreen;
97905b261ecSmrg
98005b261ecSmrg    return ret;
98105b261ecSmrg
98205b261ecSmrg} /* end vfbScreenInit */
98305b261ecSmrg
98405b261ecSmrg
98505b261ecSmrgvoid
98605b261ecSmrgInitOutput(ScreenInfo *screenInfo, int argc, char **argv)
98705b261ecSmrg{
98805b261ecSmrg    int i;
98905b261ecSmrg    int NumFormats = 0;
99005b261ecSmrg
99105b261ecSmrg    /* initialize pixmap formats */
99205b261ecSmrg
99305b261ecSmrg    /* must have a pixmap depth to match every screen depth */
99405b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
99505b261ecSmrg    {
99605b261ecSmrg	vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
99705b261ecSmrg    }
99805b261ecSmrg
99905b261ecSmrg    /* RENDER needs a good set of pixmaps. */
100005b261ecSmrg    if (Render) {
100105b261ecSmrg	vfbPixmapDepths[1] = TRUE;
100205b261ecSmrg	vfbPixmapDepths[4] = TRUE;
100305b261ecSmrg	vfbPixmapDepths[8] = TRUE;
100405b261ecSmrg#if 0
100505b261ecSmrg	vfbPixmapDepths[12] = TRUE;
100605b261ecSmrg#endif
100705b261ecSmrg/*	vfbPixmapDepths[15] = TRUE; */
100805b261ecSmrg	vfbPixmapDepths[16] = TRUE;
100905b261ecSmrg	vfbPixmapDepths[24] = TRUE;
101005b261ecSmrg#if 0
101105b261ecSmrg	vfbPixmapDepths[30] = TRUE;
101205b261ecSmrg#endif
101305b261ecSmrg	vfbPixmapDepths[32] = TRUE;
101405b261ecSmrg    }
101505b261ecSmrg
101605b261ecSmrg    for (i = 1; i <= 32; i++)
101705b261ecSmrg    {
101805b261ecSmrg	if (vfbPixmapDepths[i])
101905b261ecSmrg	{
102005b261ecSmrg	    if (NumFormats >= MAXFORMATS)
102105b261ecSmrg		FatalError ("MAXFORMATS is too small for this server\n");
102205b261ecSmrg	    screenInfo->formats[NumFormats].depth = i;
102305b261ecSmrg	    screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
102405b261ecSmrg	    screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
102505b261ecSmrg	    NumFormats++;
102605b261ecSmrg	}
102705b261ecSmrg    }
102805b261ecSmrg
102905b261ecSmrg    screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
103005b261ecSmrg    screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
103105b261ecSmrg    screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
103205b261ecSmrg    screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
103305b261ecSmrg    screenInfo->numPixmapFormats = NumFormats;
103405b261ecSmrg
103505b261ecSmrg    /* initialize screens */
103605b261ecSmrg
103705b261ecSmrg    for (i = 0; i < vfbNumScreens; i++)
103805b261ecSmrg    {
103905b261ecSmrg	if (-1 == AddScreen(vfbScreenInit, argc, argv))
104005b261ecSmrg	{
104105b261ecSmrg	    FatalError("Couldn't add screen %d", i);
104205b261ecSmrg	}
104305b261ecSmrg    }
104405b261ecSmrg
104505b261ecSmrg} /* end InitOutput */
104605b261ecSmrg
104705b261ecSmrg/* this is just to get the server to link on AIX */
104805b261ecSmrg#ifdef AIXV3
104905b261ecSmrgint SelectWaitTime = 10000; /* usec */
105005b261ecSmrg#endif
1051