InitOutput.c revision ed6184df
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 "colormapst.h"
4505b261ecSmrg#include "gcstruct.h"
4605b261ecSmrg#include "input.h"
4705b261ecSmrg#include "mipointer.h"
4805b261ecSmrg#include "micmap.h"
4905b261ecSmrg#include <sys/types.h>
5035c4bbdfSmrg#ifdef HAVE_MMAP
5105b261ecSmrg#include <sys/mman.h>
5205b261ecSmrg#ifndef MAP_FILE
5305b261ecSmrg#define MAP_FILE 0
5405b261ecSmrg#endif
5535c4bbdfSmrg#endif                          /* HAVE_MMAP */
5605b261ecSmrg#include <sys/stat.h>
5705b261ecSmrg#include <errno.h>
5805b261ecSmrg#ifndef WIN32
5905b261ecSmrg#include <sys/param.h>
6005b261ecSmrg#endif
6105b261ecSmrg#include <X11/XWDFile.h>
6205b261ecSmrg#ifdef HAS_SHM
6305b261ecSmrg#include <sys/ipc.h>
6405b261ecSmrg#include <sys/shm.h>
6535c4bbdfSmrg#endif                          /* HAS_SHM */
6605b261ecSmrg#include "dix.h"
6705b261ecSmrg#include "miline.h"
6835c4bbdfSmrg#include "glx_extinit.h"
6935c4bbdfSmrg#include "randrstr.h"
7005b261ecSmrg
7105b261ecSmrg#define VFB_DEFAULT_WIDTH      1280
7205b261ecSmrg#define VFB_DEFAULT_HEIGHT     1024
731b5d61b8Smrg#define VFB_DEFAULT_DEPTH        24
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
7935c4bbdfSmrgtypedef struct {
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
9635c4bbdfSmrg#ifdef HAVE_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;
10835c4bbdfSmrg
1096747b715Smrgstatic vfbScreenInfo defaultScreenInfo = {
11035c4bbdfSmrg    .width = VFB_DEFAULT_WIDTH,
1116747b715Smrg    .height = VFB_DEFAULT_HEIGHT,
11235c4bbdfSmrg    .depth = VFB_DEFAULT_DEPTH,
1136747b715Smrg    .blackPixel = VFB_DEFAULT_BLACKPIXEL,
1146747b715Smrg    .whitePixel = VFB_DEFAULT_WHITEPIXEL,
1156747b715Smrg    .lineBias = VFB_DEFAULT_LINEBIAS,
1166747b715Smrg};
11735c4bbdfSmrg
11805b261ecSmrgstatic Bool vfbPixmapDepths[33];
11935c4bbdfSmrg
12035c4bbdfSmrg#ifdef HAVE_MMAP
12105b261ecSmrgstatic char *pfbdir = NULL;
12205b261ecSmrg#endif
12305b261ecSmrgtypedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
12405b261ecSmrgstatic fbMemType fbmemtype = NORMAL_MEMORY_FB;
12505b261ecSmrgstatic char needswap = 0;
12605b261ecSmrgstatic Bool Render = TRUE;
12705b261ecSmrg
12805b261ecSmrg#define swapcopy16(_dst, _src) \
12905b261ecSmrg    if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
13005b261ecSmrg    else _dst = _src;
13105b261ecSmrg
13205b261ecSmrg#define swapcopy32(_dst, _src) \
13305b261ecSmrg    if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
13405b261ecSmrg    else _dst = _src;
13505b261ecSmrg
13605b261ecSmrgstatic void
13705b261ecSmrgvfbInitializePixmapDepths(void)
13805b261ecSmrg{
13905b261ecSmrg    int i;
14035c4bbdfSmrg
14135c4bbdfSmrg    vfbPixmapDepths[1] = TRUE;  /* always need bitmaps */
14205b261ecSmrg    for (i = 2; i <= 32; i++)
14335c4bbdfSmrg        vfbPixmapDepths[i] = FALSE;
14405b261ecSmrg}
14505b261ecSmrg
14605b261ecSmrgstatic int
14705b261ecSmrgvfbBitsPerPixel(int depth)
14805b261ecSmrg{
14935c4bbdfSmrg    if (depth == 1)
15035c4bbdfSmrg        return 1;
15135c4bbdfSmrg    else if (depth <= 8)
15235c4bbdfSmrg        return 8;
15335c4bbdfSmrg    else if (depth <= 16)
15435c4bbdfSmrg        return 16;
15535c4bbdfSmrg    else
15635c4bbdfSmrg        return 32;
15705b261ecSmrg}
15805b261ecSmrg
159ed6184dfSmrgstatic void
160ed6184dfSmrgfreeScreenInfo(vfbScreenInfoPtr pvfb)
16105b261ecSmrg{
16235c4bbdfSmrg    switch (fbmemtype) {
16335c4bbdfSmrg#ifdef HAVE_MMAP
16405b261ecSmrg    case MMAPPED_FILE_FB:
165ed6184dfSmrg        if (-1 == unlink(pvfb->mmap_file)) {
166ed6184dfSmrg            perror("unlink");
167ed6184dfSmrg            ErrorF("unlink %s failed, %s",
168ed6184dfSmrg                   pvfb->mmap_file, strerror(errno));
16935c4bbdfSmrg        }
17005b261ecSmrg        break;
17135c4bbdfSmrg#else                           /* HAVE_MMAP */
17235c4bbdfSmrg    case MMAPPED_FILE_FB:
17335c4bbdfSmrg        break;
17435c4bbdfSmrg#endif                          /* HAVE_MMAP */
17535c4bbdfSmrg
17605b261ecSmrg#ifdef HAS_SHM
17705b261ecSmrg    case SHARED_MEMORY_FB:
178ed6184dfSmrg        if (-1 == shmdt((char *) pvfb->pXWDHeader)) {
179ed6184dfSmrg            perror("shmdt");
180ed6184dfSmrg            ErrorF("shmdt failed, %s", strerror(errno));
18135c4bbdfSmrg        }
18235c4bbdfSmrg        break;
18335c4bbdfSmrg#else                           /* HAS_SHM */
18405b261ecSmrg    case SHARED_MEMORY_FB:
18505b261ecSmrg        break;
18635c4bbdfSmrg#endif                          /* HAS_SHM */
18735c4bbdfSmrg
18805b261ecSmrg    case NORMAL_MEMORY_FB:
189ed6184dfSmrg        free(pvfb->pXWDHeader);
19035c4bbdfSmrg        break;
19105b261ecSmrg    }
19205b261ecSmrg}
19305b261ecSmrg
19405b261ecSmrgvoid
195ed6184dfSmrgddxGiveUp(enum ExitCode error)
19605b261ecSmrg{
197ed6184dfSmrg    int i;
198ed6184dfSmrg
199ed6184dfSmrg    /* clean up the framebuffers */
200ed6184dfSmrg    for (i = 0; i < vfbNumScreens; i++) {
201ed6184dfSmrg        freeScreenInfo(&vfbScreens[i]);
202ed6184dfSmrg    }
20305b261ecSmrg}
20405b261ecSmrg
2054642e01fSmrg#ifdef __APPLE__
20605b261ecSmrgvoid
20705b261ecSmrgDarwinHandleGUI(int argc, char *argv[])
20805b261ecSmrg{
20905b261ecSmrg}
21005b261ecSmrg#endif
21105b261ecSmrg
21205b261ecSmrgvoid
2136747b715SmrgOsVendorInit(void)
21405b261ecSmrg{
21505b261ecSmrg}
21605b261ecSmrg
21705b261ecSmrgvoid
21835c4bbdfSmrgOsVendorFatalError(const char *f, va_list args)
21905b261ecSmrg{
22005b261ecSmrg}
22105b261ecSmrg
22205b261ecSmrg#if defined(DDXBEFORERESET)
22335c4bbdfSmrgvoid
22435c4bbdfSmrgddxBeforeReset(void)
22505b261ecSmrg{
22605b261ecSmrg    return;
22705b261ecSmrg}
22805b261ecSmrg#endif
22905b261ecSmrg
2305a7dfde8Smrg#if INPUTTHREAD
2315a7dfde8Smrg/** This function is called in Xserver/os/inputthread.c when starting
2325a7dfde8Smrg    the input thread. */
2335a7dfde8Smrgvoid
2345a7dfde8SmrgddxInputThreadInit(void)
2355a7dfde8Smrg{
2365a7dfde8Smrg}
2375a7dfde8Smrg#endif
2385a7dfde8Smrg
23905b261ecSmrgvoid
2406747b715SmrgddxUseMsg(void)
24105b261ecSmrg{
24205b261ecSmrg    ErrorF("-screen scrn WxHxD     set screen's width, height, depth\n");
24305b261ecSmrg    ErrorF("-pixdepths list-of-int support given pixmap depths\n");
2446747b715Smrg    ErrorF("+/-render		   turn on/off RENDER extension support"
24535c4bbdfSmrg           "(default on)\n");
24605b261ecSmrg    ErrorF("-linebias n            adjust thin line pixelization\n");
24705b261ecSmrg    ErrorF("-blackpixel n          pixel value for black\n");
24805b261ecSmrg    ErrorF("-whitepixel n          pixel value for white\n");
24905b261ecSmrg
25035c4bbdfSmrg#ifdef HAVE_MMAP
25135c4bbdfSmrg    ErrorF
25235c4bbdfSmrg        ("-fbdir directory       put framebuffers in mmap'ed files in directory\n");
25305b261ecSmrg#endif
25405b261ecSmrg
25505b261ecSmrg#ifdef HAS_SHM
25605b261ecSmrg    ErrorF("-shmem                 put framebuffers in shared memory\n");
25705b261ecSmrg#endif
25805b261ecSmrg}
25905b261ecSmrg
26005b261ecSmrgint
26105b261ecSmrgddxProcessArgument(int argc, char *argv[], int i)
26205b261ecSmrg{
26305b261ecSmrg    static Bool firstTime = TRUE;
2646747b715Smrg    static int lastScreen = -1;
2656747b715Smrg    vfbScreenInfo *currentScreen;
26605b261ecSmrg
26735c4bbdfSmrg    if (firstTime) {
26835c4bbdfSmrg        vfbInitializePixmapDepths();
26905b261ecSmrg        firstTime = FALSE;
27005b261ecSmrg    }
27105b261ecSmrg
2726747b715Smrg    if (lastScreen == -1)
27335c4bbdfSmrg        currentScreen = &defaultScreenInfo;
2746747b715Smrg    else
27535c4bbdfSmrg        currentScreen = &vfbScreens[lastScreen];
2766747b715Smrg
27735c4bbdfSmrg    if (strcmp(argv[i], "-screen") == 0) {      /* -screen n WxHxD */
27835c4bbdfSmrg        int screenNum;
27935c4bbdfSmrg
28035c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(2);
28135c4bbdfSmrg        screenNum = atoi(argv[i + 1]);
28235c4bbdfSmrg        /* The protocol only has a CARD8 for number of screens in the
28335c4bbdfSmrg           connection setup block, so don't allow more than that. */
28435c4bbdfSmrg        if ((screenNum < 0) || (screenNum >= 255)) {
28535c4bbdfSmrg            ErrorF("Invalid screen number %d\n", screenNum);
28635c4bbdfSmrg            UseMsg();
28735c4bbdfSmrg            FatalError("Invalid screen number %d passed to -screen\n",
28835c4bbdfSmrg                       screenNum);
28935c4bbdfSmrg        }
29035c4bbdfSmrg
29135c4bbdfSmrg        if (vfbNumScreens <= screenNum) {
29235c4bbdfSmrg            vfbScreens =
29335c4bbdfSmrg                reallocarray(vfbScreens, screenNum + 1, sizeof(*vfbScreens));
29435c4bbdfSmrg            if (!vfbScreens)
29535c4bbdfSmrg                FatalError("Not enough memory for screen %d\n", screenNum);
29635c4bbdfSmrg            for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
29735c4bbdfSmrg                vfbScreens[vfbNumScreens] = defaultScreenInfo;
29835c4bbdfSmrg        }
29935c4bbdfSmrg
30035c4bbdfSmrg        if (3 != sscanf(argv[i + 2], "%dx%dx%d",
30135c4bbdfSmrg                        &vfbScreens[screenNum].width,
30235c4bbdfSmrg                        &vfbScreens[screenNum].height,
30335c4bbdfSmrg                        &vfbScreens[screenNum].depth)) {
30435c4bbdfSmrg            ErrorF("Invalid screen configuration %s\n", argv[i + 2]);
30535c4bbdfSmrg            UseMsg();
30635c4bbdfSmrg            FatalError("Invalid screen configuration %s for -screen %d\n",
30735c4bbdfSmrg                       argv[i + 2], screenNum);
30835c4bbdfSmrg        }
30935c4bbdfSmrg
31035c4bbdfSmrg        lastScreen = screenNum;
31135c4bbdfSmrg        return 3;
31235c4bbdfSmrg    }
31335c4bbdfSmrg
31435c4bbdfSmrg    if (strcmp(argv[i], "-pixdepths") == 0) {   /* -pixdepths list-of-depth */
31535c4bbdfSmrg        int depth, ret = 1;
31635c4bbdfSmrg
31735c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
31835c4bbdfSmrg        while ((++i < argc) && (depth = atoi(argv[i])) != 0) {
31935c4bbdfSmrg            if (depth < 0 || depth > 32) {
32035c4bbdfSmrg                ErrorF("Invalid pixmap depth %d\n", depth);
32135c4bbdfSmrg                UseMsg();
32235c4bbdfSmrg                FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
32335c4bbdfSmrg                           depth);
32435c4bbdfSmrg            }
32535c4bbdfSmrg            vfbPixmapDepths[depth] = TRUE;
32635c4bbdfSmrg            ret++;
32735c4bbdfSmrg        }
32835c4bbdfSmrg        return ret;
32935c4bbdfSmrg    }
33035c4bbdfSmrg
33135c4bbdfSmrg    if (strcmp(argv[i], "+render") == 0) {      /* +render */
33235c4bbdfSmrg        Render = TRUE;
33335c4bbdfSmrg        return 1;
33435c4bbdfSmrg    }
33535c4bbdfSmrg
33635c4bbdfSmrg    if (strcmp(argv[i], "-render") == 0) {      /* -render */
33735c4bbdfSmrg        Render = FALSE;
33805b261ecSmrg#ifdef COMPOSITE
33935c4bbdfSmrg        noCompositeExtension = TRUE;
34005b261ecSmrg#endif
34135c4bbdfSmrg        return 1;
34205b261ecSmrg    }
34305b261ecSmrg
34435c4bbdfSmrg    if (strcmp(argv[i], "-blackpixel") == 0) {  /* -blackpixel n */
34535c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
34635c4bbdfSmrg        currentScreen->blackPixel = atoi(argv[++i]);
34735c4bbdfSmrg        return 2;
34805b261ecSmrg    }
34905b261ecSmrg
35035c4bbdfSmrg    if (strcmp(argv[i], "-whitepixel") == 0) {  /* -whitepixel n */
35135c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
35235c4bbdfSmrg        currentScreen->whitePixel = atoi(argv[++i]);
35335c4bbdfSmrg        return 2;
35405b261ecSmrg    }
35505b261ecSmrg
35635c4bbdfSmrg    if (strcmp(argv[i], "-linebias") == 0) {    /* -linebias n */
35735c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
35835c4bbdfSmrg        currentScreen->lineBias = atoi(argv[++i]);
35935c4bbdfSmrg        return 2;
36005b261ecSmrg    }
36105b261ecSmrg
36235c4bbdfSmrg#ifdef HAVE_MMAP
36335c4bbdfSmrg    if (strcmp(argv[i], "-fbdir") == 0) {       /* -fbdir directory */
36435c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
36535c4bbdfSmrg        pfbdir = argv[++i];
36635c4bbdfSmrg        fbmemtype = MMAPPED_FILE_FB;
36735c4bbdfSmrg        return 2;
36805b261ecSmrg    }
36935c4bbdfSmrg#endif                          /* HAVE_MMAP */
37005b261ecSmrg
37105b261ecSmrg#ifdef HAS_SHM
37235c4bbdfSmrg    if (strcmp(argv[i], "-shmem") == 0) {       /* -shmem */
37335c4bbdfSmrg        fbmemtype = SHARED_MEMORY_FB;
37435c4bbdfSmrg        return 1;
37505b261ecSmrg    }
37605b261ecSmrg#endif
37705b261ecSmrg
37805b261ecSmrg    return 0;
37905b261ecSmrg}
38005b261ecSmrg
38105b261ecSmrgstatic void
38205b261ecSmrgvfbInstallColormap(ColormapPtr pmap)
38305b261ecSmrg{
38435c4bbdfSmrg    ColormapPtr oldpmap = GetInstalledmiColormap(pmap->pScreen);
38535c4bbdfSmrg
38635c4bbdfSmrg    if (pmap != oldpmap) {
38735c4bbdfSmrg        int entries;
38835c4bbdfSmrg        XWDFileHeader *pXWDHeader;
38935c4bbdfSmrg        VisualPtr pVisual;
39035c4bbdfSmrg        Pixel *ppix;
39135c4bbdfSmrg        xrgb *prgb;
39235c4bbdfSmrg        xColorItem *defs;
39335c4bbdfSmrg        int i;
39435c4bbdfSmrg
39535c4bbdfSmrg        miInstallColormap(pmap);
39635c4bbdfSmrg
39735c4bbdfSmrg        entries = pmap->pVisual->ColormapEntries;
39835c4bbdfSmrg        pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
39935c4bbdfSmrg        pVisual = pmap->pVisual;
40035c4bbdfSmrg
40135c4bbdfSmrg        swapcopy32(pXWDHeader->visual_class, pVisual->class);
40235c4bbdfSmrg        swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
40335c4bbdfSmrg        swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
40435c4bbdfSmrg        swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
40535c4bbdfSmrg        swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
40635c4bbdfSmrg        swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
40735c4bbdfSmrg
40835c4bbdfSmrg        ppix = xallocarray(entries, sizeof(Pixel));
40935c4bbdfSmrg        prgb = xallocarray(entries, sizeof(xrgb));
41035c4bbdfSmrg        defs = xallocarray(entries, sizeof(xColorItem));
41135c4bbdfSmrg
41235c4bbdfSmrg        for (i = 0; i < entries; i++)
41335c4bbdfSmrg            ppix[i] = i;
41435c4bbdfSmrg        /* XXX truecolor */
41535c4bbdfSmrg        QueryColors(pmap, entries, ppix, prgb, serverClient);
41635c4bbdfSmrg
41735c4bbdfSmrg        for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
41835c4bbdfSmrg            defs[i].pixel = ppix[i] & 0xff;     /* change pixel to index */
41935c4bbdfSmrg            defs[i].red = prgb[i].red;
42035c4bbdfSmrg            defs[i].green = prgb[i].green;
42135c4bbdfSmrg            defs[i].blue = prgb[i].blue;
42235c4bbdfSmrg            defs[i].flags = DoRed | DoGreen | DoBlue;
42335c4bbdfSmrg        }
42435c4bbdfSmrg        (*pmap->pScreen->StoreColors) (pmap, entries, defs);
42535c4bbdfSmrg
42635c4bbdfSmrg        free(ppix);
42735c4bbdfSmrg        free(prgb);
42835c4bbdfSmrg        free(defs);
42905b261ecSmrg    }
43005b261ecSmrg}
43105b261ecSmrg
43205b261ecSmrgstatic void
43335c4bbdfSmrgvfbStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs)
43405b261ecSmrg{
43505b261ecSmrg    XWDColor *pXWDCmap;
43605b261ecSmrg    int i;
43705b261ecSmrg
43835c4bbdfSmrg    if (pmap != GetInstalledmiColormap(pmap->pScreen)) {
43935c4bbdfSmrg        return;
44005b261ecSmrg    }
44105b261ecSmrg
44205b261ecSmrg    pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
44305b261ecSmrg
44435c4bbdfSmrg    if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
44535c4bbdfSmrg        return;
44635c4bbdfSmrg    }
44735c4bbdfSmrg
44835c4bbdfSmrg    for (i = 0; i < ndef; i++) {
44935c4bbdfSmrg        if (pdefs[i].flags & DoRed) {
45035c4bbdfSmrg            swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
45135c4bbdfSmrg        }
45235c4bbdfSmrg        if (pdefs[i].flags & DoGreen) {
45335c4bbdfSmrg            swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
45435c4bbdfSmrg        }
45535c4bbdfSmrg        if (pdefs[i].flags & DoBlue) {
45635c4bbdfSmrg            swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
45735c4bbdfSmrg        }
45805b261ecSmrg    }
45905b261ecSmrg}
46005b261ecSmrg
46135c4bbdfSmrg#ifdef HAVE_MMAP
46205b261ecSmrg
46305b261ecSmrg/* this flushes any changes to the screens out to the mmapped file */
46405b261ecSmrgstatic void
4651b5d61b8SmrgvfbBlockHandler(void *blockData, void *timeout)
46605b261ecSmrg{
46705b261ecSmrg    int i;
46805b261ecSmrg
46935c4bbdfSmrg    for (i = 0; i < vfbNumScreens; i++) {
47005b261ecSmrg#ifdef MS_ASYNC
47135c4bbdfSmrg        if (-1 == msync((caddr_t) vfbScreens[i].pXWDHeader,
47235c4bbdfSmrg                        (size_t) vfbScreens[i].sizeInBytes, MS_ASYNC))
47305b261ecSmrg#else
47435c4bbdfSmrg        /* silly NetBSD and who else? */
47535c4bbdfSmrg        if (-1 == msync((caddr_t) vfbScreens[i].pXWDHeader,
47635c4bbdfSmrg                        (size_t) vfbScreens[i].sizeInBytes))
47705b261ecSmrg#endif
47835c4bbdfSmrg        {
47935c4bbdfSmrg            perror("msync");
48035c4bbdfSmrg            ErrorF("msync failed, %s", strerror(errno));
48135c4bbdfSmrg        }
48205b261ecSmrg    }
48305b261ecSmrg}
48405b261ecSmrg
48505b261ecSmrgstatic void
4861b5d61b8SmrgvfbWakeupHandler(void *blockData, int result)
48705b261ecSmrg{
48805b261ecSmrg}
48905b261ecSmrg
49005b261ecSmrgstatic void
49105b261ecSmrgvfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
49205b261ecSmrg{
49305b261ecSmrg#define DUMMY_BUFFER_SIZE 65536
49405b261ecSmrg    char dummyBuffer[DUMMY_BUFFER_SIZE];
49505b261ecSmrg    int currentFileSize, writeThisTime;
49605b261ecSmrg
49735c4bbdfSmrg    snprintf(pvfb->mmap_file, sizeof(pvfb->mmap_file), "%s/Xvfb_screen%d",
49835c4bbdfSmrg             pfbdir, (int) (pvfb - vfbScreens));
49935c4bbdfSmrg    if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT | O_RDWR, 0666))) {
50035c4bbdfSmrg        perror("open");
50135c4bbdfSmrg        ErrorF("open %s failed, %s", pvfb->mmap_file, strerror(errno));
50235c4bbdfSmrg        return;
50305b261ecSmrg    }
50405b261ecSmrg
50505b261ecSmrg    /* Extend the file to be the proper size */
50605b261ecSmrg
5076747b715Smrg    memset(dummyBuffer, 0, DUMMY_BUFFER_SIZE);
50805b261ecSmrg    for (currentFileSize = 0;
50935c4bbdfSmrg         currentFileSize < pvfb->sizeInBytes;
51035c4bbdfSmrg         currentFileSize += writeThisTime) {
51135c4bbdfSmrg        writeThisTime = min(DUMMY_BUFFER_SIZE,
51235c4bbdfSmrg                            pvfb->sizeInBytes - currentFileSize);
51335c4bbdfSmrg        if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime)) {
51435c4bbdfSmrg            perror("write");
51535c4bbdfSmrg            ErrorF("write %s failed, %s", pvfb->mmap_file, strerror(errno));
51635c4bbdfSmrg            return;
51735c4bbdfSmrg        }
51805b261ecSmrg    }
51905b261ecSmrg
52005b261ecSmrg    /* try to mmap the file */
52105b261ecSmrg
52235c4bbdfSmrg    pvfb->pXWDHeader = (XWDFileHeader *) mmap((caddr_t) NULL, pvfb->sizeInBytes,
52335c4bbdfSmrg                                              PROT_READ | PROT_WRITE,
52435c4bbdfSmrg                                              MAP_FILE | MAP_SHARED,
52535c4bbdfSmrg                                              pvfb->mmap_fd, 0);
52635c4bbdfSmrg    if (-1 == (long) pvfb->pXWDHeader) {
52735c4bbdfSmrg        perror("mmap");
52835c4bbdfSmrg        ErrorF("mmap %s failed, %s", pvfb->mmap_file, strerror(errno));
52935c4bbdfSmrg        pvfb->pXWDHeader = NULL;
53035c4bbdfSmrg        return;
53105b261ecSmrg    }
53205b261ecSmrg
53305b261ecSmrg    if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
53435c4bbdfSmrg                                        NULL)) {
53535c4bbdfSmrg        pvfb->pXWDHeader = NULL;
53605b261ecSmrg    }
53705b261ecSmrg}
53835c4bbdfSmrg#endif                          /* HAVE_MMAP */
53905b261ecSmrg
54005b261ecSmrg#ifdef HAS_SHM
54105b261ecSmrgstatic void
54205b261ecSmrgvfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
54305b261ecSmrg{
54405b261ecSmrg    /* create the shared memory segment */
54505b261ecSmrg
54635c4bbdfSmrg    pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT | 0777);
54735c4bbdfSmrg    if (pvfb->shmid < 0) {
54835c4bbdfSmrg        perror("shmget");
54935c4bbdfSmrg        ErrorF("shmget %d bytes failed, %s", pvfb->sizeInBytes,
55035c4bbdfSmrg               strerror(errno));
55135c4bbdfSmrg        return;
55205b261ecSmrg    }
55305b261ecSmrg
55405b261ecSmrg    /* try to attach it */
55505b261ecSmrg
55635c4bbdfSmrg    pvfb->pXWDHeader = (XWDFileHeader *) shmat(pvfb->shmid, 0, 0);
55735c4bbdfSmrg    if (-1 == (long) pvfb->pXWDHeader) {
55835c4bbdfSmrg        perror("shmat");
55935c4bbdfSmrg        ErrorF("shmat failed, %s", strerror(errno));
56035c4bbdfSmrg        pvfb->pXWDHeader = NULL;
56135c4bbdfSmrg        return;
56205b261ecSmrg    }
56305b261ecSmrg
5646747b715Smrg    ErrorF("screen %d shmid %d\n", (int) (pvfb - vfbScreens), pvfb->shmid);
56505b261ecSmrg}
56635c4bbdfSmrg#endif                          /* HAS_SHM */
56705b261ecSmrg
56805b261ecSmrgstatic char *
56905b261ecSmrgvfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
57005b261ecSmrg{
57135c4bbdfSmrg    if (pvfb->pfbMemory)
57235c4bbdfSmrg        return pvfb->pfbMemory; /* already done */
57305b261ecSmrg
57405b261ecSmrg    pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
57505b261ecSmrg
57605b261ecSmrg    /* Calculate how many entries in colormap.  This is rather bogus, because
57705b261ecSmrg     * the visuals haven't even been set up yet, but we need to know because we
57805b261ecSmrg     * have to allocate space in the file for the colormap.  The number 10
57905b261ecSmrg     * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
58005b261ecSmrg     */
58105b261ecSmrg
58235c4bbdfSmrg    if (pvfb->depth <= 10) {    /* single index colormaps */
58335c4bbdfSmrg        pvfb->ncolors = 1 << pvfb->depth;
58405b261ecSmrg    }
58535c4bbdfSmrg    else {                      /* decomposed colormaps */
58635c4bbdfSmrg        int nplanes_per_color_component = pvfb->depth / 3;
58735c4bbdfSmrg
58835c4bbdfSmrg        if (pvfb->depth % 3)
58935c4bbdfSmrg            nplanes_per_color_component++;
59035c4bbdfSmrg        pvfb->ncolors = 1 << nplanes_per_color_component;
59105b261ecSmrg    }
59205b261ecSmrg
59305b261ecSmrg    /* add extra bytes for XWDFileHeader, window name, and colormap */
59405b261ecSmrg
59505b261ecSmrg    pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
59635c4bbdfSmrg        pvfb->ncolors * SIZEOF(XWDColor);
59705b261ecSmrg
59835c4bbdfSmrg    pvfb->pXWDHeader = NULL;
59935c4bbdfSmrg    switch (fbmemtype) {
60035c4bbdfSmrg#ifdef HAVE_MMAP
60135c4bbdfSmrg    case MMAPPED_FILE_FB:
60235c4bbdfSmrg        vfbAllocateMmappedFramebuffer(pvfb);
60335c4bbdfSmrg        break;
60405b261ecSmrg#else
60535c4bbdfSmrg    case MMAPPED_FILE_FB:
60635c4bbdfSmrg        break;
60705b261ecSmrg#endif
60805b261ecSmrg
60905b261ecSmrg#ifdef HAS_SHM
61035c4bbdfSmrg    case SHARED_MEMORY_FB:
61135c4bbdfSmrg        vfbAllocateSharedMemoryFramebuffer(pvfb);
61235c4bbdfSmrg        break;
61305b261ecSmrg#else
61435c4bbdfSmrg    case SHARED_MEMORY_FB:
61535c4bbdfSmrg        break;
61605b261ecSmrg#endif
61705b261ecSmrg
61805b261ecSmrg    case NORMAL_MEMORY_FB:
61935c4bbdfSmrg        pvfb->pXWDHeader = (XWDFileHeader *) malloc(pvfb->sizeInBytes);
62035c4bbdfSmrg        break;
62105b261ecSmrg    }
62205b261ecSmrg
62335c4bbdfSmrg    if (pvfb->pXWDHeader) {
62435c4bbdfSmrg        pvfb->pXWDCmap = (XWDColor *) ((char *) pvfb->pXWDHeader
62535c4bbdfSmrg                                       + SIZEOF(XWDheader) +
62635c4bbdfSmrg                                       XWD_WINDOW_NAME_LEN);
62735c4bbdfSmrg        pvfb->pfbMemory = (char *) (pvfb->pXWDCmap + pvfb->ncolors);
62805b261ecSmrg
62935c4bbdfSmrg        return pvfb->pfbMemory;
63005b261ecSmrg    }
631ed6184dfSmrg
632ed6184dfSmrg    return NULL;
63305b261ecSmrg}
63405b261ecSmrg
63505b261ecSmrgstatic void
63605b261ecSmrgvfbWriteXWDFileHeader(ScreenPtr pScreen)
63705b261ecSmrg{
63805b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
63905b261ecSmrg    XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
64005b261ecSmrg    char hostname[XWD_WINDOW_NAME_LEN];
64105b261ecSmrg    unsigned long swaptest = 1;
64205b261ecSmrg    int i;
64305b261ecSmrg
64405b261ecSmrg    needswap = *(char *) &swaptest;
64505b261ecSmrg
64635c4bbdfSmrg    pXWDHeader->header_size =
64735c4bbdfSmrg        (char *) pvfb->pXWDCmap - (char *) pvfb->pXWDHeader;
64805b261ecSmrg    pXWDHeader->file_version = XWD_FILE_VERSION;
64905b261ecSmrg
65005b261ecSmrg    pXWDHeader->pixmap_format = ZPixmap;
65105b261ecSmrg    pXWDHeader->pixmap_depth = pvfb->depth;
65205b261ecSmrg    pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
65305b261ecSmrg    pXWDHeader->xoffset = 0;
65405b261ecSmrg    pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
65505b261ecSmrg    pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
65605b261ecSmrg#ifndef INTERNAL_VS_EXTERNAL_PADDING
65705b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
65805b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
65905b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
66005b261ecSmrg#else
66105b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
66205b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
66305b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
66405b261ecSmrg#endif
66505b261ecSmrg    pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
66605b261ecSmrg    pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
66705b261ecSmrg    pXWDHeader->ncolors = pvfb->ncolors;
66805b261ecSmrg
66905b261ecSmrg    /* visual related fields are written when colormap is installed */
67005b261ecSmrg
67105b261ecSmrg    pXWDHeader->window_x = pXWDHeader->window_y = 0;
67205b261ecSmrg    pXWDHeader->window_bdrwidth = 0;
67305b261ecSmrg
67405b261ecSmrg    /* write xwd "window" name: Xvfb hostname:server.screen */
67505b261ecSmrg
67605b261ecSmrg    if (-1 == gethostname(hostname, sizeof(hostname)))
67735c4bbdfSmrg        hostname[0] = 0;
67805b261ecSmrg    else
67935c4bbdfSmrg        hostname[XWD_WINDOW_NAME_LEN - 1] = 0;
68035c4bbdfSmrg    sprintf((char *) (pXWDHeader + 1), "Xvfb %s:%s.%d", hostname, display,
68135c4bbdfSmrg            pScreen->myNum);
68205b261ecSmrg
68305b261ecSmrg    /* write colormap pixel slot values */
68405b261ecSmrg
68535c4bbdfSmrg    for (i = 0; i < pvfb->ncolors; i++) {
68635c4bbdfSmrg        pvfb->pXWDCmap[i].pixel = i;
68705b261ecSmrg    }
68805b261ecSmrg
68905b261ecSmrg    /* byte swap to most significant byte first */
69005b261ecSmrg
69135c4bbdfSmrg    if (needswap) {
69235c4bbdfSmrg        SwapLongs((CARD32 *) pXWDHeader, SIZEOF(XWDheader) / 4);
69335c4bbdfSmrg        for (i = 0; i < pvfb->ncolors; i++) {
69435c4bbdfSmrg            swapl(&pvfb->pXWDCmap[i].pixel);
69535c4bbdfSmrg        }
69605b261ecSmrg    }
69705b261ecSmrg}
69805b261ecSmrg
69905b261ecSmrgstatic Bool
70035c4bbdfSmrgvfbCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
70105b261ecSmrg{
70205b261ecSmrg    return FALSE;
70305b261ecSmrg}
70405b261ecSmrg
70505b261ecSmrgstatic void
70635c4bbdfSmrgvfbCrossScreen(ScreenPtr pScreen, Bool entering)
70705b261ecSmrg{
70805b261ecSmrg}
70905b261ecSmrg
71035c4bbdfSmrgstatic miPointerScreenFuncRec vfbPointerCursorFuncs = {
71105b261ecSmrg    vfbCursorOffScreen,
71205b261ecSmrg    vfbCrossScreen,
71305b261ecSmrg    miPointerWarpCursor
71405b261ecSmrg};
71505b261ecSmrg
71605b261ecSmrgstatic Bool
71735c4bbdfSmrgvfbCloseScreen(ScreenPtr pScreen)
71805b261ecSmrg{
71935c4bbdfSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
72035c4bbdfSmrg
72105b261ecSmrg    pScreen->CloseScreen = pvfb->closeScreen;
72205b261ecSmrg
72305b261ecSmrg    /*
72435c4bbdfSmrg     * fb overwrites miCloseScreen, so do this here
72505b261ecSmrg     */
72635c4bbdfSmrg    if (pScreen->devPrivate)
72735c4bbdfSmrg        (*pScreen->DestroyPixmap) (pScreen->devPrivate);
72835c4bbdfSmrg    pScreen->devPrivate = NULL;
72935c4bbdfSmrg
73035c4bbdfSmrg    return pScreen->CloseScreen(pScreen);
73135c4bbdfSmrg}
73235c4bbdfSmrg
73335c4bbdfSmrgstatic Bool
73435c4bbdfSmrgvfbRROutputValidateMode(ScreenPtr           pScreen,
73535c4bbdfSmrg                        RROutputPtr         output,
73635c4bbdfSmrg                        RRModePtr           mode)
73735c4bbdfSmrg{
73835c4bbdfSmrg    rrScrPriv(pScreen);
73935c4bbdfSmrg
74035c4bbdfSmrg    if (pScrPriv->minWidth <= mode->mode.width &&
74135c4bbdfSmrg        pScrPriv->maxWidth >= mode->mode.width &&
74235c4bbdfSmrg        pScrPriv->minHeight <= mode->mode.height &&
74335c4bbdfSmrg        pScrPriv->maxHeight >= mode->mode.height)
74435c4bbdfSmrg        return TRUE;
74535c4bbdfSmrg    else
74635c4bbdfSmrg        return FALSE;
74735c4bbdfSmrg}
74835c4bbdfSmrg
74935c4bbdfSmrgstatic Bool
75035c4bbdfSmrgvfbRRScreenSetSize(ScreenPtr  pScreen,
75135c4bbdfSmrg                   CARD16     width,
75235c4bbdfSmrg                   CARD16     height,
75335c4bbdfSmrg                   CARD32     mmWidth,
75435c4bbdfSmrg                   CARD32     mmHeight)
75535c4bbdfSmrg{
75635c4bbdfSmrg    // Prevent screen updates while we change things around
75735c4bbdfSmrg    SetRootClip(pScreen, ROOT_CLIP_NONE);
75835c4bbdfSmrg
75935c4bbdfSmrg    pScreen->width = width;
76035c4bbdfSmrg    pScreen->height = height;
76135c4bbdfSmrg    pScreen->mmWidth = mmWidth;
76235c4bbdfSmrg    pScreen->mmHeight = mmHeight;
76335c4bbdfSmrg
76435c4bbdfSmrg    // Restore the ability to update screen, now with new dimensions
76535c4bbdfSmrg    SetRootClip(pScreen, ROOT_CLIP_FULL);
76635c4bbdfSmrg
76735c4bbdfSmrg    RRScreenSizeNotify (pScreen);
76835c4bbdfSmrg    RRTellChanged(pScreen);
76935c4bbdfSmrg
77035c4bbdfSmrg    return TRUE;
77135c4bbdfSmrg}
77235c4bbdfSmrg
77335c4bbdfSmrgstatic Bool
77435c4bbdfSmrgvfbRRCrtcSet(ScreenPtr pScreen,
77535c4bbdfSmrg             RRCrtcPtr crtc,
77635c4bbdfSmrg             RRModePtr mode,
77735c4bbdfSmrg             int       x,
77835c4bbdfSmrg             int       y,
77935c4bbdfSmrg             Rotation  rotation,
78035c4bbdfSmrg             int       numOutput,
78135c4bbdfSmrg             RROutputPtr *outputs)
78235c4bbdfSmrg{
78335c4bbdfSmrg  return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutput, outputs);
78435c4bbdfSmrg}
78505b261ecSmrg
78635c4bbdfSmrgstatic Bool
78735c4bbdfSmrgvfbRRGetInfo(ScreenPtr pScreen, Rotation *rotations)
78835c4bbdfSmrg{
789ed6184dfSmrg    /* Don't support rotations */
790ed6184dfSmrg    *rotations = RR_Rotate_0;
791ed6184dfSmrg
79235c4bbdfSmrg    return TRUE;
79305b261ecSmrg}
79405b261ecSmrg
79505b261ecSmrgstatic Bool
79635c4bbdfSmrgvfbRandRInit(ScreenPtr pScreen)
79705b261ecSmrg{
79835c4bbdfSmrg    rrScrPrivPtr pScrPriv;
79935c4bbdfSmrg#if RANDR_12_INTERFACE
80035c4bbdfSmrg    RRModePtr  mode;
80135c4bbdfSmrg    RRCrtcPtr  crtc;
80235c4bbdfSmrg    RROutputPtr        output;
80335c4bbdfSmrg    xRRModeInfo modeInfo;
80435c4bbdfSmrg    char       name[64];
80535c4bbdfSmrg#endif
80635c4bbdfSmrg
80735c4bbdfSmrg    if (!RRScreenInit (pScreen))
80835c4bbdfSmrg       return FALSE;
80935c4bbdfSmrg    pScrPriv = rrGetScrPriv(pScreen);
81035c4bbdfSmrg    pScrPriv->rrGetInfo = vfbRRGetInfo;
81135c4bbdfSmrg#if RANDR_12_INTERFACE
81235c4bbdfSmrg    pScrPriv->rrCrtcSet = vfbRRCrtcSet;
81335c4bbdfSmrg    pScrPriv->rrScreenSetSize = vfbRRScreenSetSize;
81435c4bbdfSmrg    pScrPriv->rrOutputSetProperty = NULL;
81535c4bbdfSmrg#if RANDR_13_INTERFACE
81635c4bbdfSmrg    pScrPriv->rrOutputGetProperty = NULL;
81735c4bbdfSmrg#endif
81835c4bbdfSmrg    pScrPriv->rrOutputValidateMode = vfbRROutputValidateMode;
81935c4bbdfSmrg    pScrPriv->rrModeDestroy = NULL;
82035c4bbdfSmrg
82135c4bbdfSmrg    RRScreenSetSizeRange (pScreen,
82235c4bbdfSmrg                         1, 1,
82335c4bbdfSmrg                         pScreen->width, pScreen->height);
82435c4bbdfSmrg
82535c4bbdfSmrg    sprintf (name, "%dx%d", pScreen->width, pScreen->height);
82635c4bbdfSmrg    memset (&modeInfo, '\0', sizeof (modeInfo));
82735c4bbdfSmrg    modeInfo.width = pScreen->width;
82835c4bbdfSmrg    modeInfo.height = pScreen->height;
82935c4bbdfSmrg    modeInfo.nameLength = strlen (name);
83035c4bbdfSmrg
83135c4bbdfSmrg    mode = RRModeGet (&modeInfo, name);
83235c4bbdfSmrg    if (!mode)
83335c4bbdfSmrg       return FALSE;
83435c4bbdfSmrg
83535c4bbdfSmrg    crtc = RRCrtcCreate (pScreen, NULL);
83635c4bbdfSmrg    if (!crtc)
83735c4bbdfSmrg       return FALSE;
83835c4bbdfSmrg
839ed6184dfSmrg    /* This is to avoid xrandr to complain about the gamma missing */
840ed6184dfSmrg    RRCrtcGammaSetSize (crtc, 256);
841ed6184dfSmrg
84235c4bbdfSmrg    output = RROutputCreate (pScreen, "screen", 6, NULL);
84335c4bbdfSmrg    if (!output)
84435c4bbdfSmrg       return FALSE;
84535c4bbdfSmrg    if (!RROutputSetClones (output, NULL, 0))
84635c4bbdfSmrg       return FALSE;
84735c4bbdfSmrg    if (!RROutputSetModes (output, &mode, 1, 0))
84835c4bbdfSmrg       return FALSE;
84935c4bbdfSmrg    if (!RROutputSetCrtcs (output, &crtc, 1))
85035c4bbdfSmrg       return FALSE;
85135c4bbdfSmrg    if (!RROutputSetConnection (output, RR_Connected))
85235c4bbdfSmrg       return FALSE;
85335c4bbdfSmrg    RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output);
85435c4bbdfSmrg#endif
85535c4bbdfSmrg    return TRUE;
85635c4bbdfSmrg}
85735c4bbdfSmrg
85835c4bbdfSmrgstatic Bool
85935c4bbdfSmrgvfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
86035c4bbdfSmrg{
86135c4bbdfSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
86205b261ecSmrg    int dpix = monitorResolution, dpiy = monitorResolution;
86305b261ecSmrg    int ret;
86405b261ecSmrg    char *pbits;
8656747b715Smrg
86605b261ecSmrg    if (dpix == 0)
86735c4bbdfSmrg        dpix = 100;
86805b261ecSmrg
86905b261ecSmrg    if (dpiy == 0)
87035c4bbdfSmrg        dpiy = 100;
87105b261ecSmrg
87205b261ecSmrg    pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
87305b261ecSmrg    pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
87435c4bbdfSmrg    if (pvfb->bitsPerPixel >= 8)
87535c4bbdfSmrg        pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
87605b261ecSmrg    else
87735c4bbdfSmrg        pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
87805b261ecSmrg    pbits = vfbAllocateFramebufferMemory(pvfb);
87935c4bbdfSmrg    if (!pbits)
88035c4bbdfSmrg        return FALSE;
88105b261ecSmrg
88205b261ecSmrg    switch (pvfb->depth) {
88305b261ecSmrg    case 8:
88435c4bbdfSmrg        miSetVisualTypesAndMasks(8,
88535c4bbdfSmrg                                 ((1 << StaticGray) |
88635c4bbdfSmrg                                  (1 << GrayScale) |
88735c4bbdfSmrg                                  (1 << StaticColor) |
88835c4bbdfSmrg                                  (1 << PseudoColor) |
88935c4bbdfSmrg                                  (1 << TrueColor) |
89035c4bbdfSmrg                                  (1 << DirectColor)), 8, PseudoColor, 0, 0, 0);
89135c4bbdfSmrg        break;
89205b261ecSmrg    case 15:
89335c4bbdfSmrg        miSetVisualTypesAndMasks(15,
89435c4bbdfSmrg                                 ((1 << TrueColor) |
89535c4bbdfSmrg                                  (1 << DirectColor)),
89635c4bbdfSmrg                                 8, TrueColor, 0x7c00, 0x03e0, 0x001f);
89735c4bbdfSmrg        break;
89805b261ecSmrg    case 16:
89935c4bbdfSmrg        miSetVisualTypesAndMasks(16,
90035c4bbdfSmrg                                 ((1 << TrueColor) |
90135c4bbdfSmrg                                  (1 << DirectColor)),
90235c4bbdfSmrg                                 8, TrueColor, 0xf800, 0x07e0, 0x001f);
90335c4bbdfSmrg        break;
90405b261ecSmrg    case 24:
90535c4bbdfSmrg        miSetVisualTypesAndMasks(24,
90635c4bbdfSmrg                                 ((1 << TrueColor) |
90735c4bbdfSmrg                                  (1 << DirectColor)),
90835c4bbdfSmrg                                 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
90935c4bbdfSmrg        break;
9106747b715Smrg    case 30:
91135c4bbdfSmrg        miSetVisualTypesAndMasks(30,
91235c4bbdfSmrg                                 ((1 << TrueColor) |
91335c4bbdfSmrg                                  (1 << DirectColor)),
91435c4bbdfSmrg                                 10, TrueColor, 0x3ff00000, 0x000ffc00,
91535c4bbdfSmrg                                 0x000003ff);
91635c4bbdfSmrg        break;
917475c125cSmrg    default:
91835c4bbdfSmrg        return FALSE;
91905b261ecSmrg    }
92052397711Smrg
92135c4bbdfSmrg    miSetPixmapDepths();
92252397711Smrg
92305b261ecSmrg    ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
92435c4bbdfSmrg                       dpix, dpiy, pvfb->paddedWidth, pvfb->bitsPerPixel);
92535c4bbdfSmrg    if (ret && Render)
92635c4bbdfSmrg        fbPictureInit(pScreen, 0, 0);
92735c4bbdfSmrg
92835c4bbdfSmrg    if (!ret)
92935c4bbdfSmrg        return FALSE;
93005b261ecSmrg
93135c4bbdfSmrg    if (!vfbRandRInit(pScreen))
93235c4bbdfSmrg       return FALSE;
93305b261ecSmrg
93405b261ecSmrg    pScreen->InstallColormap = vfbInstallColormap;
93505b261ecSmrg    pScreen->StoreColors = vfbStoreColors;
93605b261ecSmrg
93705b261ecSmrg    miDCInitialize(pScreen, &vfbPointerCursorFuncs);
93805b261ecSmrg
93905b261ecSmrg    vfbWriteXWDFileHeader(pScreen);
94005b261ecSmrg
94105b261ecSmrg    pScreen->blackPixel = pvfb->blackPixel;
94205b261ecSmrg    pScreen->whitePixel = pvfb->whitePixel;
94305b261ecSmrg
94405b261ecSmrg    ret = fbCreateDefColormap(pScreen);
94505b261ecSmrg
94605b261ecSmrg    miSetZeroLineBias(pScreen, pvfb->lineBias);
94705b261ecSmrg
94805b261ecSmrg    pvfb->closeScreen = pScreen->CloseScreen;
94905b261ecSmrg    pScreen->CloseScreen = vfbCloseScreen;
95005b261ecSmrg
95105b261ecSmrg    return ret;
95205b261ecSmrg
95335c4bbdfSmrg}                               /* end vfbScreenInit */
95405b261ecSmrg
95505b261ecSmrgvoid
95635c4bbdfSmrgInitOutput(ScreenInfo * screen_info, int argc, char **argv)
95705b261ecSmrg{
95805b261ecSmrg    int i;
95905b261ecSmrg    int NumFormats = 0;
96005b261ecSmrg
96105b261ecSmrg    /* initialize pixmap formats */
96205b261ecSmrg
96305b261ecSmrg    /* must have a pixmap depth to match every screen depth */
96435c4bbdfSmrg    for (i = 0; i < vfbNumScreens; i++) {
96535c4bbdfSmrg        vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
96605b261ecSmrg    }
96705b261ecSmrg
96805b261ecSmrg    /* RENDER needs a good set of pixmaps. */
96905b261ecSmrg    if (Render) {
97035c4bbdfSmrg        vfbPixmapDepths[1] = TRUE;
97135c4bbdfSmrg        vfbPixmapDepths[4] = TRUE;
97235c4bbdfSmrg        vfbPixmapDepths[8] = TRUE;
97305b261ecSmrg#if 0
97435c4bbdfSmrg        vfbPixmapDepths[12] = TRUE;
97505b261ecSmrg#endif
97605b261ecSmrg/*	vfbPixmapDepths[15] = TRUE; */
97735c4bbdfSmrg        vfbPixmapDepths[16] = TRUE;
97835c4bbdfSmrg        vfbPixmapDepths[24] = TRUE;
97905b261ecSmrg#if 0
98035c4bbdfSmrg        vfbPixmapDepths[30] = TRUE;
98105b261ecSmrg#endif
98235c4bbdfSmrg        vfbPixmapDepths[32] = TRUE;
98305b261ecSmrg    }
98405b261ecSmrg
9851b5d61b8Smrg    xorgGlxCreateVendor();
9861b5d61b8Smrg
98735c4bbdfSmrg    for (i = 1; i <= 32; i++) {
98835c4bbdfSmrg        if (vfbPixmapDepths[i]) {
98935c4bbdfSmrg            if (NumFormats >= MAXFORMATS)
99035c4bbdfSmrg                FatalError("MAXFORMATS is too small for this server\n");
99135c4bbdfSmrg            screen_info->formats[NumFormats].depth = i;
99235c4bbdfSmrg            screen_info->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
99335c4bbdfSmrg            screen_info->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
99435c4bbdfSmrg            NumFormats++;
99535c4bbdfSmrg        }
99605b261ecSmrg    }
99705b261ecSmrg
99835c4bbdfSmrg    screen_info->imageByteOrder = IMAGE_BYTE_ORDER;
99935c4bbdfSmrg    screen_info->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
100035c4bbdfSmrg    screen_info->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
100135c4bbdfSmrg    screen_info->bitmapBitOrder = BITMAP_BIT_ORDER;
100235c4bbdfSmrg    screen_info->numPixmapFormats = NumFormats;
100305b261ecSmrg
100405b261ecSmrg    /* initialize screens */
100505b261ecSmrg
100635c4bbdfSmrg    if (vfbNumScreens < 1) {
100735c4bbdfSmrg        vfbScreens = &defaultScreenInfo;
100835c4bbdfSmrg        vfbNumScreens = 1;
10096747b715Smrg    }
101035c4bbdfSmrg    for (i = 0; i < vfbNumScreens; i++) {
101135c4bbdfSmrg        if (-1 == AddScreen(vfbScreenInit, argc, argv)) {
101235c4bbdfSmrg            FatalError("Couldn't add screen %d", i);
101335c4bbdfSmrg        }
101405b261ecSmrg    }
101505b261ecSmrg
101635c4bbdfSmrg}                               /* end InitOutput */
1017