InitOutput.c revision 35c4bbdf
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
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
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
15905b261ecSmrgvoid
16035c4bbdfSmrgddxGiveUp(enum ExitCode error)
16105b261ecSmrg{
16205b261ecSmrg    int i;
16305b261ecSmrg
16405b261ecSmrg    /* clean up the framebuffers */
16505b261ecSmrg
16635c4bbdfSmrg    switch (fbmemtype) {
16735c4bbdfSmrg#ifdef HAVE_MMAP
16805b261ecSmrg    case MMAPPED_FILE_FB:
16935c4bbdfSmrg        for (i = 0; i < vfbNumScreens; i++) {
17035c4bbdfSmrg            if (-1 == unlink(vfbScreens[i].mmap_file)) {
17135c4bbdfSmrg                perror("unlink");
17235c4bbdfSmrg                ErrorF("unlink %s failed, %s",
17335c4bbdfSmrg                       vfbScreens[i].mmap_file, strerror(errno));
17435c4bbdfSmrg            }
17535c4bbdfSmrg        }
17605b261ecSmrg        break;
17735c4bbdfSmrg#else                           /* HAVE_MMAP */
17835c4bbdfSmrg    case MMAPPED_FILE_FB:
17935c4bbdfSmrg        break;
18035c4bbdfSmrg#endif                          /* HAVE_MMAP */
18135c4bbdfSmrg
18205b261ecSmrg#ifdef HAS_SHM
18305b261ecSmrg    case SHARED_MEMORY_FB:
18435c4bbdfSmrg        for (i = 0; i < vfbNumScreens; i++) {
18535c4bbdfSmrg            if (-1 == shmdt((char *) vfbScreens[i].pXWDHeader)) {
18635c4bbdfSmrg                perror("shmdt");
18735c4bbdfSmrg                ErrorF("shmdt failed, %s", strerror(errno));
18835c4bbdfSmrg            }
18935c4bbdfSmrg        }
19035c4bbdfSmrg        break;
19135c4bbdfSmrg#else                           /* HAS_SHM */
19205b261ecSmrg    case SHARED_MEMORY_FB:
19305b261ecSmrg        break;
19435c4bbdfSmrg#endif                          /* HAS_SHM */
19535c4bbdfSmrg
19605b261ecSmrg    case NORMAL_MEMORY_FB:
19735c4bbdfSmrg        for (i = 0; i < vfbNumScreens; i++) {
19835c4bbdfSmrg            free(vfbScreens[i].pXWDHeader);
19935c4bbdfSmrg        }
20035c4bbdfSmrg        break;
20105b261ecSmrg    }
20205b261ecSmrg}
20305b261ecSmrg
20405b261ecSmrgvoid
20535c4bbdfSmrgAbortDDX(enum ExitCode error)
20605b261ecSmrg{
20735c4bbdfSmrg    ddxGiveUp(error);
20805b261ecSmrg}
20905b261ecSmrg
2104642e01fSmrg#ifdef __APPLE__
21105b261ecSmrgvoid
21205b261ecSmrgDarwinHandleGUI(int argc, char *argv[])
21305b261ecSmrg{
21405b261ecSmrg}
21505b261ecSmrg#endif
21605b261ecSmrg
21705b261ecSmrgvoid
2186747b715SmrgOsVendorInit(void)
21905b261ecSmrg{
22005b261ecSmrg}
22105b261ecSmrg
22205b261ecSmrgvoid
22335c4bbdfSmrgOsVendorFatalError(const char *f, va_list args)
22405b261ecSmrg{
22505b261ecSmrg}
22605b261ecSmrg
22705b261ecSmrg#if defined(DDXBEFORERESET)
22835c4bbdfSmrgvoid
22935c4bbdfSmrgddxBeforeReset(void)
23005b261ecSmrg{
23105b261ecSmrg    return;
23205b261ecSmrg}
23305b261ecSmrg#endif
23405b261ecSmrg
23505b261ecSmrgvoid
2366747b715SmrgddxUseMsg(void)
23705b261ecSmrg{
23805b261ecSmrg    ErrorF("-screen scrn WxHxD     set screen's width, height, depth\n");
23905b261ecSmrg    ErrorF("-pixdepths list-of-int support given pixmap depths\n");
2406747b715Smrg    ErrorF("+/-render		   turn on/off RENDER extension support"
24135c4bbdfSmrg           "(default on)\n");
24205b261ecSmrg    ErrorF("-linebias n            adjust thin line pixelization\n");
24305b261ecSmrg    ErrorF("-blackpixel n          pixel value for black\n");
24405b261ecSmrg    ErrorF("-whitepixel n          pixel value for white\n");
24505b261ecSmrg
24635c4bbdfSmrg#ifdef HAVE_MMAP
24735c4bbdfSmrg    ErrorF
24835c4bbdfSmrg        ("-fbdir directory       put framebuffers in mmap'ed files in directory\n");
24905b261ecSmrg#endif
25005b261ecSmrg
25105b261ecSmrg#ifdef HAS_SHM
25205b261ecSmrg    ErrorF("-shmem                 put framebuffers in shared memory\n");
25305b261ecSmrg#endif
25405b261ecSmrg}
25505b261ecSmrg
25605b261ecSmrgint
25705b261ecSmrgddxProcessArgument(int argc, char *argv[], int i)
25805b261ecSmrg{
25905b261ecSmrg    static Bool firstTime = TRUE;
2606747b715Smrg    static int lastScreen = -1;
2616747b715Smrg    vfbScreenInfo *currentScreen;
26205b261ecSmrg
26335c4bbdfSmrg    if (firstTime) {
26435c4bbdfSmrg        vfbInitializePixmapDepths();
26505b261ecSmrg        firstTime = FALSE;
26605b261ecSmrg    }
26705b261ecSmrg
2686747b715Smrg    if (lastScreen == -1)
26935c4bbdfSmrg        currentScreen = &defaultScreenInfo;
2706747b715Smrg    else
27135c4bbdfSmrg        currentScreen = &vfbScreens[lastScreen];
2726747b715Smrg
27305b261ecSmrg#define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
27405b261ecSmrg    if (((i + num) >= argc) || (!argv[i + num])) {                      \
27505b261ecSmrg      ErrorF("Required argument to %s not specified\n", argv[i]);       \
27605b261ecSmrg      UseMsg();                                                         \
27705b261ecSmrg      FatalError("Required argument to %s not specified\n", argv[i]);   \
27805b261ecSmrg    }
27935c4bbdfSmrg
28035c4bbdfSmrg    if (strcmp(argv[i], "-screen") == 0) {      /* -screen n WxHxD */
28135c4bbdfSmrg        int screenNum;
28235c4bbdfSmrg
28335c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(2);
28435c4bbdfSmrg        screenNum = atoi(argv[i + 1]);
28535c4bbdfSmrg        /* The protocol only has a CARD8 for number of screens in the
28635c4bbdfSmrg           connection setup block, so don't allow more than that. */
28735c4bbdfSmrg        if ((screenNum < 0) || (screenNum >= 255)) {
28835c4bbdfSmrg            ErrorF("Invalid screen number %d\n", screenNum);
28935c4bbdfSmrg            UseMsg();
29035c4bbdfSmrg            FatalError("Invalid screen number %d passed to -screen\n",
29135c4bbdfSmrg                       screenNum);
29235c4bbdfSmrg        }
29335c4bbdfSmrg
29435c4bbdfSmrg        if (vfbNumScreens <= screenNum) {
29535c4bbdfSmrg            vfbScreens =
29635c4bbdfSmrg                reallocarray(vfbScreens, screenNum + 1, sizeof(*vfbScreens));
29735c4bbdfSmrg            if (!vfbScreens)
29835c4bbdfSmrg                FatalError("Not enough memory for screen %d\n", screenNum);
29935c4bbdfSmrg            for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
30035c4bbdfSmrg                vfbScreens[vfbNumScreens] = defaultScreenInfo;
30135c4bbdfSmrg        }
30235c4bbdfSmrg
30335c4bbdfSmrg        if (3 != sscanf(argv[i + 2], "%dx%dx%d",
30435c4bbdfSmrg                        &vfbScreens[screenNum].width,
30535c4bbdfSmrg                        &vfbScreens[screenNum].height,
30635c4bbdfSmrg                        &vfbScreens[screenNum].depth)) {
30735c4bbdfSmrg            ErrorF("Invalid screen configuration %s\n", argv[i + 2]);
30835c4bbdfSmrg            UseMsg();
30935c4bbdfSmrg            FatalError("Invalid screen configuration %s for -screen %d\n",
31035c4bbdfSmrg                       argv[i + 2], screenNum);
31135c4bbdfSmrg        }
31235c4bbdfSmrg
31335c4bbdfSmrg        lastScreen = screenNum;
31435c4bbdfSmrg        return 3;
31535c4bbdfSmrg    }
31635c4bbdfSmrg
31735c4bbdfSmrg    if (strcmp(argv[i], "-pixdepths") == 0) {   /* -pixdepths list-of-depth */
31835c4bbdfSmrg        int depth, ret = 1;
31935c4bbdfSmrg
32035c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
32135c4bbdfSmrg        while ((++i < argc) && (depth = atoi(argv[i])) != 0) {
32235c4bbdfSmrg            if (depth < 0 || depth > 32) {
32335c4bbdfSmrg                ErrorF("Invalid pixmap depth %d\n", depth);
32435c4bbdfSmrg                UseMsg();
32535c4bbdfSmrg                FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
32635c4bbdfSmrg                           depth);
32735c4bbdfSmrg            }
32835c4bbdfSmrg            vfbPixmapDepths[depth] = TRUE;
32935c4bbdfSmrg            ret++;
33035c4bbdfSmrg        }
33135c4bbdfSmrg        return ret;
33235c4bbdfSmrg    }
33335c4bbdfSmrg
33435c4bbdfSmrg    if (strcmp(argv[i], "+render") == 0) {      /* +render */
33535c4bbdfSmrg        Render = TRUE;
33635c4bbdfSmrg        return 1;
33735c4bbdfSmrg    }
33835c4bbdfSmrg
33935c4bbdfSmrg    if (strcmp(argv[i], "-render") == 0) {      /* -render */
34035c4bbdfSmrg        Render = FALSE;
34105b261ecSmrg#ifdef COMPOSITE
34235c4bbdfSmrg        noCompositeExtension = TRUE;
34305b261ecSmrg#endif
34435c4bbdfSmrg        return 1;
34505b261ecSmrg    }
34605b261ecSmrg
34735c4bbdfSmrg    if (strcmp(argv[i], "-blackpixel") == 0) {  /* -blackpixel n */
34835c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
34935c4bbdfSmrg        currentScreen->blackPixel = atoi(argv[++i]);
35035c4bbdfSmrg        return 2;
35105b261ecSmrg    }
35205b261ecSmrg
35335c4bbdfSmrg    if (strcmp(argv[i], "-whitepixel") == 0) {  /* -whitepixel n */
35435c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
35535c4bbdfSmrg        currentScreen->whitePixel = atoi(argv[++i]);
35635c4bbdfSmrg        return 2;
35705b261ecSmrg    }
35805b261ecSmrg
35935c4bbdfSmrg    if (strcmp(argv[i], "-linebias") == 0) {    /* -linebias n */
36035c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
36135c4bbdfSmrg        currentScreen->lineBias = atoi(argv[++i]);
36235c4bbdfSmrg        return 2;
36305b261ecSmrg    }
36405b261ecSmrg
36535c4bbdfSmrg#ifdef HAVE_MMAP
36635c4bbdfSmrg    if (strcmp(argv[i], "-fbdir") == 0) {       /* -fbdir directory */
36735c4bbdfSmrg        CHECK_FOR_REQUIRED_ARGUMENTS(1);
36835c4bbdfSmrg        pfbdir = argv[++i];
36935c4bbdfSmrg        fbmemtype = MMAPPED_FILE_FB;
37035c4bbdfSmrg        return 2;
37105b261ecSmrg    }
37235c4bbdfSmrg#endif                          /* HAVE_MMAP */
37305b261ecSmrg
37405b261ecSmrg#ifdef HAS_SHM
37535c4bbdfSmrg    if (strcmp(argv[i], "-shmem") == 0) {       /* -shmem */
37635c4bbdfSmrg        fbmemtype = SHARED_MEMORY_FB;
37735c4bbdfSmrg        return 1;
37805b261ecSmrg    }
37905b261ecSmrg#endif
38005b261ecSmrg
38105b261ecSmrg    return 0;
38205b261ecSmrg}
38305b261ecSmrg
38405b261ecSmrgstatic void
38505b261ecSmrgvfbInstallColormap(ColormapPtr pmap)
38605b261ecSmrg{
38735c4bbdfSmrg    ColormapPtr oldpmap = GetInstalledmiColormap(pmap->pScreen);
38835c4bbdfSmrg
38935c4bbdfSmrg    if (pmap != oldpmap) {
39035c4bbdfSmrg        int entries;
39135c4bbdfSmrg        XWDFileHeader *pXWDHeader;
39235c4bbdfSmrg        VisualPtr pVisual;
39335c4bbdfSmrg        Pixel *ppix;
39435c4bbdfSmrg        xrgb *prgb;
39535c4bbdfSmrg        xColorItem *defs;
39635c4bbdfSmrg        int i;
39735c4bbdfSmrg
39835c4bbdfSmrg        miInstallColormap(pmap);
39935c4bbdfSmrg
40035c4bbdfSmrg        entries = pmap->pVisual->ColormapEntries;
40135c4bbdfSmrg        pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
40235c4bbdfSmrg        pVisual = pmap->pVisual;
40335c4bbdfSmrg
40435c4bbdfSmrg        swapcopy32(pXWDHeader->visual_class, pVisual->class);
40535c4bbdfSmrg        swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
40635c4bbdfSmrg        swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
40735c4bbdfSmrg        swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
40835c4bbdfSmrg        swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
40935c4bbdfSmrg        swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
41035c4bbdfSmrg
41135c4bbdfSmrg        ppix = xallocarray(entries, sizeof(Pixel));
41235c4bbdfSmrg        prgb = xallocarray(entries, sizeof(xrgb));
41335c4bbdfSmrg        defs = xallocarray(entries, sizeof(xColorItem));
41435c4bbdfSmrg
41535c4bbdfSmrg        for (i = 0; i < entries; i++)
41635c4bbdfSmrg            ppix[i] = i;
41735c4bbdfSmrg        /* XXX truecolor */
41835c4bbdfSmrg        QueryColors(pmap, entries, ppix, prgb, serverClient);
41935c4bbdfSmrg
42035c4bbdfSmrg        for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
42135c4bbdfSmrg            defs[i].pixel = ppix[i] & 0xff;     /* change pixel to index */
42235c4bbdfSmrg            defs[i].red = prgb[i].red;
42335c4bbdfSmrg            defs[i].green = prgb[i].green;
42435c4bbdfSmrg            defs[i].blue = prgb[i].blue;
42535c4bbdfSmrg            defs[i].flags = DoRed | DoGreen | DoBlue;
42635c4bbdfSmrg        }
42735c4bbdfSmrg        (*pmap->pScreen->StoreColors) (pmap, entries, defs);
42835c4bbdfSmrg
42935c4bbdfSmrg        free(ppix);
43035c4bbdfSmrg        free(prgb);
43135c4bbdfSmrg        free(defs);
43205b261ecSmrg    }
43305b261ecSmrg}
43405b261ecSmrg
43505b261ecSmrgstatic void
43635c4bbdfSmrgvfbStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs)
43705b261ecSmrg{
43805b261ecSmrg    XWDColor *pXWDCmap;
43905b261ecSmrg    int i;
44005b261ecSmrg
44135c4bbdfSmrg    if (pmap != GetInstalledmiColormap(pmap->pScreen)) {
44235c4bbdfSmrg        return;
44305b261ecSmrg    }
44405b261ecSmrg
44505b261ecSmrg    pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
44605b261ecSmrg
44735c4bbdfSmrg    if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
44835c4bbdfSmrg        return;
44935c4bbdfSmrg    }
45035c4bbdfSmrg
45135c4bbdfSmrg    for (i = 0; i < ndef; i++) {
45235c4bbdfSmrg        if (pdefs[i].flags & DoRed) {
45335c4bbdfSmrg            swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
45435c4bbdfSmrg        }
45535c4bbdfSmrg        if (pdefs[i].flags & DoGreen) {
45635c4bbdfSmrg            swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
45735c4bbdfSmrg        }
45835c4bbdfSmrg        if (pdefs[i].flags & DoBlue) {
45935c4bbdfSmrg            swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
46035c4bbdfSmrg        }
46105b261ecSmrg    }
46205b261ecSmrg}
46305b261ecSmrg
46405b261ecSmrgstatic Bool
46505b261ecSmrgvfbSaveScreen(ScreenPtr pScreen, int on)
46605b261ecSmrg{
46705b261ecSmrg    return TRUE;
46805b261ecSmrg}
46905b261ecSmrg
47035c4bbdfSmrg#ifdef HAVE_MMAP
47105b261ecSmrg
47205b261ecSmrg/* this flushes any changes to the screens out to the mmapped file */
47305b261ecSmrgstatic void
47435c4bbdfSmrgvfbBlockHandler(void *blockData, OSTimePtr pTimeout, void *pReadmask)
47505b261ecSmrg{
47605b261ecSmrg    int i;
47705b261ecSmrg
47835c4bbdfSmrg    for (i = 0; i < vfbNumScreens; i++) {
47905b261ecSmrg#ifdef MS_ASYNC
48035c4bbdfSmrg        if (-1 == msync((caddr_t) vfbScreens[i].pXWDHeader,
48135c4bbdfSmrg                        (size_t) vfbScreens[i].sizeInBytes, MS_ASYNC))
48205b261ecSmrg#else
48335c4bbdfSmrg        /* silly NetBSD and who else? */
48435c4bbdfSmrg        if (-1 == msync((caddr_t) vfbScreens[i].pXWDHeader,
48535c4bbdfSmrg                        (size_t) vfbScreens[i].sizeInBytes))
48605b261ecSmrg#endif
48735c4bbdfSmrg        {
48835c4bbdfSmrg            perror("msync");
48935c4bbdfSmrg            ErrorF("msync failed, %s", strerror(errno));
49035c4bbdfSmrg        }
49105b261ecSmrg    }
49205b261ecSmrg}
49305b261ecSmrg
49405b261ecSmrgstatic void
49535c4bbdfSmrgvfbWakeupHandler(void *blockData, int result, void *pReadmask)
49605b261ecSmrg{
49705b261ecSmrg}
49805b261ecSmrg
49905b261ecSmrgstatic void
50005b261ecSmrgvfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
50105b261ecSmrg{
50205b261ecSmrg#define DUMMY_BUFFER_SIZE 65536
50305b261ecSmrg    char dummyBuffer[DUMMY_BUFFER_SIZE];
50405b261ecSmrg    int currentFileSize, writeThisTime;
50505b261ecSmrg
50635c4bbdfSmrg    snprintf(pvfb->mmap_file, sizeof(pvfb->mmap_file), "%s/Xvfb_screen%d",
50735c4bbdfSmrg             pfbdir, (int) (pvfb - vfbScreens));
50835c4bbdfSmrg    if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT | O_RDWR, 0666))) {
50935c4bbdfSmrg        perror("open");
51035c4bbdfSmrg        ErrorF("open %s failed, %s", pvfb->mmap_file, strerror(errno));
51135c4bbdfSmrg        return;
51205b261ecSmrg    }
51305b261ecSmrg
51405b261ecSmrg    /* Extend the file to be the proper size */
51505b261ecSmrg
5166747b715Smrg    memset(dummyBuffer, 0, DUMMY_BUFFER_SIZE);
51705b261ecSmrg    for (currentFileSize = 0;
51835c4bbdfSmrg         currentFileSize < pvfb->sizeInBytes;
51935c4bbdfSmrg         currentFileSize += writeThisTime) {
52035c4bbdfSmrg        writeThisTime = min(DUMMY_BUFFER_SIZE,
52135c4bbdfSmrg                            pvfb->sizeInBytes - currentFileSize);
52235c4bbdfSmrg        if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime)) {
52335c4bbdfSmrg            perror("write");
52435c4bbdfSmrg            ErrorF("write %s failed, %s", pvfb->mmap_file, strerror(errno));
52535c4bbdfSmrg            return;
52635c4bbdfSmrg        }
52705b261ecSmrg    }
52805b261ecSmrg
52905b261ecSmrg    /* try to mmap the file */
53005b261ecSmrg
53135c4bbdfSmrg    pvfb->pXWDHeader = (XWDFileHeader *) mmap((caddr_t) NULL, pvfb->sizeInBytes,
53235c4bbdfSmrg                                              PROT_READ | PROT_WRITE,
53335c4bbdfSmrg                                              MAP_FILE | MAP_SHARED,
53435c4bbdfSmrg                                              pvfb->mmap_fd, 0);
53535c4bbdfSmrg    if (-1 == (long) pvfb->pXWDHeader) {
53635c4bbdfSmrg        perror("mmap");
53735c4bbdfSmrg        ErrorF("mmap %s failed, %s", pvfb->mmap_file, strerror(errno));
53835c4bbdfSmrg        pvfb->pXWDHeader = NULL;
53935c4bbdfSmrg        return;
54005b261ecSmrg    }
54105b261ecSmrg
54205b261ecSmrg    if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
54335c4bbdfSmrg                                        NULL)) {
54435c4bbdfSmrg        pvfb->pXWDHeader = NULL;
54505b261ecSmrg    }
54605b261ecSmrg}
54735c4bbdfSmrg#endif                          /* HAVE_MMAP */
54805b261ecSmrg
54905b261ecSmrg#ifdef HAS_SHM
55005b261ecSmrgstatic void
55105b261ecSmrgvfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
55205b261ecSmrg{
55305b261ecSmrg    /* create the shared memory segment */
55405b261ecSmrg
55535c4bbdfSmrg    pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT | 0777);
55635c4bbdfSmrg    if (pvfb->shmid < 0) {
55735c4bbdfSmrg        perror("shmget");
55835c4bbdfSmrg        ErrorF("shmget %d bytes failed, %s", pvfb->sizeInBytes,
55935c4bbdfSmrg               strerror(errno));
56035c4bbdfSmrg        return;
56105b261ecSmrg    }
56205b261ecSmrg
56305b261ecSmrg    /* try to attach it */
56405b261ecSmrg
56535c4bbdfSmrg    pvfb->pXWDHeader = (XWDFileHeader *) shmat(pvfb->shmid, 0, 0);
56635c4bbdfSmrg    if (-1 == (long) pvfb->pXWDHeader) {
56735c4bbdfSmrg        perror("shmat");
56835c4bbdfSmrg        ErrorF("shmat failed, %s", strerror(errno));
56935c4bbdfSmrg        pvfb->pXWDHeader = NULL;
57035c4bbdfSmrg        return;
57105b261ecSmrg    }
57205b261ecSmrg
5736747b715Smrg    ErrorF("screen %d shmid %d\n", (int) (pvfb - vfbScreens), pvfb->shmid);
57405b261ecSmrg}
57535c4bbdfSmrg#endif                          /* HAS_SHM */
57605b261ecSmrg
57705b261ecSmrgstatic char *
57805b261ecSmrgvfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
57905b261ecSmrg{
58035c4bbdfSmrg    if (pvfb->pfbMemory)
58135c4bbdfSmrg        return pvfb->pfbMemory; /* already done */
58205b261ecSmrg
58305b261ecSmrg    pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
58405b261ecSmrg
58505b261ecSmrg    /* Calculate how many entries in colormap.  This is rather bogus, because
58605b261ecSmrg     * the visuals haven't even been set up yet, but we need to know because we
58705b261ecSmrg     * have to allocate space in the file for the colormap.  The number 10
58805b261ecSmrg     * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
58905b261ecSmrg     */
59005b261ecSmrg
59135c4bbdfSmrg    if (pvfb->depth <= 10) {    /* single index colormaps */
59235c4bbdfSmrg        pvfb->ncolors = 1 << pvfb->depth;
59305b261ecSmrg    }
59435c4bbdfSmrg    else {                      /* decomposed colormaps */
59535c4bbdfSmrg        int nplanes_per_color_component = pvfb->depth / 3;
59635c4bbdfSmrg
59735c4bbdfSmrg        if (pvfb->depth % 3)
59835c4bbdfSmrg            nplanes_per_color_component++;
59935c4bbdfSmrg        pvfb->ncolors = 1 << nplanes_per_color_component;
60005b261ecSmrg    }
60105b261ecSmrg
60205b261ecSmrg    /* add extra bytes for XWDFileHeader, window name, and colormap */
60305b261ecSmrg
60405b261ecSmrg    pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
60535c4bbdfSmrg        pvfb->ncolors * SIZEOF(XWDColor);
60605b261ecSmrg
60735c4bbdfSmrg    pvfb->pXWDHeader = NULL;
60835c4bbdfSmrg    switch (fbmemtype) {
60935c4bbdfSmrg#ifdef HAVE_MMAP
61035c4bbdfSmrg    case MMAPPED_FILE_FB:
61135c4bbdfSmrg        vfbAllocateMmappedFramebuffer(pvfb);
61235c4bbdfSmrg        break;
61305b261ecSmrg#else
61435c4bbdfSmrg    case MMAPPED_FILE_FB:
61535c4bbdfSmrg        break;
61605b261ecSmrg#endif
61705b261ecSmrg
61805b261ecSmrg#ifdef HAS_SHM
61935c4bbdfSmrg    case SHARED_MEMORY_FB:
62035c4bbdfSmrg        vfbAllocateSharedMemoryFramebuffer(pvfb);
62135c4bbdfSmrg        break;
62205b261ecSmrg#else
62335c4bbdfSmrg    case SHARED_MEMORY_FB:
62435c4bbdfSmrg        break;
62505b261ecSmrg#endif
62605b261ecSmrg
62705b261ecSmrg    case NORMAL_MEMORY_FB:
62835c4bbdfSmrg        pvfb->pXWDHeader = (XWDFileHeader *) malloc(pvfb->sizeInBytes);
62935c4bbdfSmrg        break;
63005b261ecSmrg    }
63105b261ecSmrg
63235c4bbdfSmrg    if (pvfb->pXWDHeader) {
63335c4bbdfSmrg        pvfb->pXWDCmap = (XWDColor *) ((char *) pvfb->pXWDHeader
63435c4bbdfSmrg                                       + SIZEOF(XWDheader) +
63535c4bbdfSmrg                                       XWD_WINDOW_NAME_LEN);
63635c4bbdfSmrg        pvfb->pfbMemory = (char *) (pvfb->pXWDCmap + pvfb->ncolors);
63705b261ecSmrg
63835c4bbdfSmrg        return pvfb->pfbMemory;
63905b261ecSmrg    }
64005b261ecSmrg    else
64135c4bbdfSmrg        return NULL;
64205b261ecSmrg}
64305b261ecSmrg
64405b261ecSmrgstatic void
64505b261ecSmrgvfbWriteXWDFileHeader(ScreenPtr pScreen)
64605b261ecSmrg{
64705b261ecSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
64805b261ecSmrg    XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
64905b261ecSmrg    char hostname[XWD_WINDOW_NAME_LEN];
65005b261ecSmrg    unsigned long swaptest = 1;
65105b261ecSmrg    int i;
65205b261ecSmrg
65305b261ecSmrg    needswap = *(char *) &swaptest;
65405b261ecSmrg
65535c4bbdfSmrg    pXWDHeader->header_size =
65635c4bbdfSmrg        (char *) pvfb->pXWDCmap - (char *) pvfb->pXWDHeader;
65705b261ecSmrg    pXWDHeader->file_version = XWD_FILE_VERSION;
65805b261ecSmrg
65905b261ecSmrg    pXWDHeader->pixmap_format = ZPixmap;
66005b261ecSmrg    pXWDHeader->pixmap_depth = pvfb->depth;
66105b261ecSmrg    pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
66205b261ecSmrg    pXWDHeader->xoffset = 0;
66305b261ecSmrg    pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
66405b261ecSmrg    pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
66505b261ecSmrg#ifndef INTERNAL_VS_EXTERNAL_PADDING
66605b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
66705b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
66805b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
66905b261ecSmrg#else
67005b261ecSmrg    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
67105b261ecSmrg    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
67205b261ecSmrg    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
67305b261ecSmrg#endif
67405b261ecSmrg    pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
67505b261ecSmrg    pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
67605b261ecSmrg    pXWDHeader->ncolors = pvfb->ncolors;
67705b261ecSmrg
67805b261ecSmrg    /* visual related fields are written when colormap is installed */
67905b261ecSmrg
68005b261ecSmrg    pXWDHeader->window_x = pXWDHeader->window_y = 0;
68105b261ecSmrg    pXWDHeader->window_bdrwidth = 0;
68205b261ecSmrg
68305b261ecSmrg    /* write xwd "window" name: Xvfb hostname:server.screen */
68405b261ecSmrg
68505b261ecSmrg    if (-1 == gethostname(hostname, sizeof(hostname)))
68635c4bbdfSmrg        hostname[0] = 0;
68705b261ecSmrg    else
68835c4bbdfSmrg        hostname[XWD_WINDOW_NAME_LEN - 1] = 0;
68935c4bbdfSmrg    sprintf((char *) (pXWDHeader + 1), "Xvfb %s:%s.%d", hostname, display,
69035c4bbdfSmrg            pScreen->myNum);
69105b261ecSmrg
69205b261ecSmrg    /* write colormap pixel slot values */
69305b261ecSmrg
69435c4bbdfSmrg    for (i = 0; i < pvfb->ncolors; i++) {
69535c4bbdfSmrg        pvfb->pXWDCmap[i].pixel = i;
69605b261ecSmrg    }
69705b261ecSmrg
69805b261ecSmrg    /* byte swap to most significant byte first */
69905b261ecSmrg
70035c4bbdfSmrg    if (needswap) {
70135c4bbdfSmrg        SwapLongs((CARD32 *) pXWDHeader, SIZEOF(XWDheader) / 4);
70235c4bbdfSmrg        for (i = 0; i < pvfb->ncolors; i++) {
70335c4bbdfSmrg            swapl(&pvfb->pXWDCmap[i].pixel);
70435c4bbdfSmrg        }
70505b261ecSmrg    }
70605b261ecSmrg}
70705b261ecSmrg
70805b261ecSmrgstatic Bool
70935c4bbdfSmrgvfbCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
71005b261ecSmrg{
71105b261ecSmrg    return FALSE;
71205b261ecSmrg}
71305b261ecSmrg
71405b261ecSmrgstatic void
71535c4bbdfSmrgvfbCrossScreen(ScreenPtr pScreen, Bool entering)
71605b261ecSmrg{
71705b261ecSmrg}
71805b261ecSmrg
71935c4bbdfSmrgstatic miPointerScreenFuncRec vfbPointerCursorFuncs = {
72005b261ecSmrg    vfbCursorOffScreen,
72105b261ecSmrg    vfbCrossScreen,
72205b261ecSmrg    miPointerWarpCursor
72305b261ecSmrg};
72405b261ecSmrg
72505b261ecSmrgstatic Bool
72635c4bbdfSmrgvfbCloseScreen(ScreenPtr pScreen)
72705b261ecSmrg{
72835c4bbdfSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
72935c4bbdfSmrg
73005b261ecSmrg    pScreen->CloseScreen = pvfb->closeScreen;
73105b261ecSmrg
73205b261ecSmrg    /*
73335c4bbdfSmrg     * fb overwrites miCloseScreen, so do this here
73405b261ecSmrg     */
73535c4bbdfSmrg    if (pScreen->devPrivate)
73635c4bbdfSmrg        (*pScreen->DestroyPixmap) (pScreen->devPrivate);
73735c4bbdfSmrg    pScreen->devPrivate = NULL;
73835c4bbdfSmrg
73935c4bbdfSmrg    return pScreen->CloseScreen(pScreen);
74035c4bbdfSmrg}
74135c4bbdfSmrg
74235c4bbdfSmrgstatic Bool
74335c4bbdfSmrgvfbRROutputValidateMode(ScreenPtr           pScreen,
74435c4bbdfSmrg                        RROutputPtr         output,
74535c4bbdfSmrg                        RRModePtr           mode)
74635c4bbdfSmrg{
74735c4bbdfSmrg    rrScrPriv(pScreen);
74835c4bbdfSmrg
74935c4bbdfSmrg    if (pScrPriv->minWidth <= mode->mode.width &&
75035c4bbdfSmrg        pScrPriv->maxWidth >= mode->mode.width &&
75135c4bbdfSmrg        pScrPriv->minHeight <= mode->mode.height &&
75235c4bbdfSmrg        pScrPriv->maxHeight >= mode->mode.height)
75335c4bbdfSmrg        return TRUE;
75435c4bbdfSmrg    else
75535c4bbdfSmrg        return FALSE;
75635c4bbdfSmrg}
75735c4bbdfSmrg
75835c4bbdfSmrgstatic Bool
75935c4bbdfSmrgvfbRRScreenSetSize(ScreenPtr  pScreen,
76035c4bbdfSmrg                   CARD16     width,
76135c4bbdfSmrg                   CARD16     height,
76235c4bbdfSmrg                   CARD32     mmWidth,
76335c4bbdfSmrg                   CARD32     mmHeight)
76435c4bbdfSmrg{
76535c4bbdfSmrg    // Prevent screen updates while we change things around
76635c4bbdfSmrg    SetRootClip(pScreen, ROOT_CLIP_NONE);
76735c4bbdfSmrg
76835c4bbdfSmrg    pScreen->width = width;
76935c4bbdfSmrg    pScreen->height = height;
77035c4bbdfSmrg    pScreen->mmWidth = mmWidth;
77135c4bbdfSmrg    pScreen->mmHeight = mmHeight;
77235c4bbdfSmrg
77335c4bbdfSmrg    // Restore the ability to update screen, now with new dimensions
77435c4bbdfSmrg    SetRootClip(pScreen, ROOT_CLIP_FULL);
77535c4bbdfSmrg
77635c4bbdfSmrg    RRScreenSizeNotify (pScreen);
77735c4bbdfSmrg    RRTellChanged(pScreen);
77835c4bbdfSmrg
77935c4bbdfSmrg    return TRUE;
78035c4bbdfSmrg}
78135c4bbdfSmrg
78235c4bbdfSmrgstatic Bool
78335c4bbdfSmrgvfbRRCrtcSet(ScreenPtr pScreen,
78435c4bbdfSmrg             RRCrtcPtr crtc,
78535c4bbdfSmrg             RRModePtr mode,
78635c4bbdfSmrg             int       x,
78735c4bbdfSmrg             int       y,
78835c4bbdfSmrg             Rotation  rotation,
78935c4bbdfSmrg             int       numOutput,
79035c4bbdfSmrg             RROutputPtr *outputs)
79135c4bbdfSmrg{
79235c4bbdfSmrg  return RRCrtcNotify(crtc, mode, x, y, rotation, NULL, numOutput, outputs);
79335c4bbdfSmrg}
79405b261ecSmrg
79535c4bbdfSmrgstatic Bool
79635c4bbdfSmrgvfbRRGetInfo(ScreenPtr pScreen, Rotation *rotations)
79735c4bbdfSmrg{
79835c4bbdfSmrg    return TRUE;
79905b261ecSmrg}
80005b261ecSmrg
80105b261ecSmrgstatic Bool
80235c4bbdfSmrgvfbRandRInit(ScreenPtr pScreen)
80305b261ecSmrg{
80435c4bbdfSmrg    rrScrPrivPtr pScrPriv;
80535c4bbdfSmrg#if RANDR_12_INTERFACE
80635c4bbdfSmrg    RRModePtr  mode;
80735c4bbdfSmrg    RRCrtcPtr  crtc;
80835c4bbdfSmrg    RROutputPtr        output;
80935c4bbdfSmrg    xRRModeInfo modeInfo;
81035c4bbdfSmrg    char       name[64];
81135c4bbdfSmrg#endif
81235c4bbdfSmrg
81335c4bbdfSmrg    if (!RRScreenInit (pScreen))
81435c4bbdfSmrg       return FALSE;
81535c4bbdfSmrg    pScrPriv = rrGetScrPriv(pScreen);
81635c4bbdfSmrg    pScrPriv->rrGetInfo = vfbRRGetInfo;
81735c4bbdfSmrg#if RANDR_12_INTERFACE
81835c4bbdfSmrg    pScrPriv->rrCrtcSet = vfbRRCrtcSet;
81935c4bbdfSmrg    pScrPriv->rrScreenSetSize = vfbRRScreenSetSize;
82035c4bbdfSmrg    pScrPriv->rrOutputSetProperty = NULL;
82135c4bbdfSmrg#if RANDR_13_INTERFACE
82235c4bbdfSmrg    pScrPriv->rrOutputGetProperty = NULL;
82335c4bbdfSmrg#endif
82435c4bbdfSmrg    pScrPriv->rrOutputValidateMode = vfbRROutputValidateMode;
82535c4bbdfSmrg    pScrPriv->rrModeDestroy = NULL;
82635c4bbdfSmrg
82735c4bbdfSmrg    RRScreenSetSizeRange (pScreen,
82835c4bbdfSmrg                         1, 1,
82935c4bbdfSmrg                         pScreen->width, pScreen->height);
83035c4bbdfSmrg
83135c4bbdfSmrg    sprintf (name, "%dx%d", pScreen->width, pScreen->height);
83235c4bbdfSmrg    memset (&modeInfo, '\0', sizeof (modeInfo));
83335c4bbdfSmrg    modeInfo.width = pScreen->width;
83435c4bbdfSmrg    modeInfo.height = pScreen->height;
83535c4bbdfSmrg    modeInfo.nameLength = strlen (name);
83635c4bbdfSmrg
83735c4bbdfSmrg    mode = RRModeGet (&modeInfo, name);
83835c4bbdfSmrg    if (!mode)
83935c4bbdfSmrg       return FALSE;
84035c4bbdfSmrg
84135c4bbdfSmrg    crtc = RRCrtcCreate (pScreen, NULL);
84235c4bbdfSmrg    if (!crtc)
84335c4bbdfSmrg       return FALSE;
84435c4bbdfSmrg
84535c4bbdfSmrg    output = RROutputCreate (pScreen, "screen", 6, NULL);
84635c4bbdfSmrg    if (!output)
84735c4bbdfSmrg       return FALSE;
84835c4bbdfSmrg    if (!RROutputSetClones (output, NULL, 0))
84935c4bbdfSmrg       return FALSE;
85035c4bbdfSmrg    if (!RROutputSetModes (output, &mode, 1, 0))
85135c4bbdfSmrg       return FALSE;
85235c4bbdfSmrg    if (!RROutputSetCrtcs (output, &crtc, 1))
85335c4bbdfSmrg       return FALSE;
85435c4bbdfSmrg    if (!RROutputSetConnection (output, RR_Connected))
85535c4bbdfSmrg       return FALSE;
85635c4bbdfSmrg    RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, NULL, 1, &output);
85735c4bbdfSmrg#endif
85835c4bbdfSmrg    return TRUE;
85935c4bbdfSmrg}
86035c4bbdfSmrg
86135c4bbdfSmrgstatic Bool
86235c4bbdfSmrgvfbScreenInit(ScreenPtr pScreen, int argc, char **argv)
86335c4bbdfSmrg{
86435c4bbdfSmrg    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
86505b261ecSmrg    int dpix = monitorResolution, dpiy = monitorResolution;
86605b261ecSmrg    int ret;
86705b261ecSmrg    char *pbits;
8686747b715Smrg
86905b261ecSmrg    if (dpix == 0)
87035c4bbdfSmrg        dpix = 100;
87105b261ecSmrg
87205b261ecSmrg    if (dpiy == 0)
87335c4bbdfSmrg        dpiy = 100;
87405b261ecSmrg
87505b261ecSmrg    pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
87605b261ecSmrg    pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
87735c4bbdfSmrg    if (pvfb->bitsPerPixel >= 8)
87835c4bbdfSmrg        pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
87905b261ecSmrg    else
88035c4bbdfSmrg        pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
88105b261ecSmrg    pbits = vfbAllocateFramebufferMemory(pvfb);
88235c4bbdfSmrg    if (!pbits)
88335c4bbdfSmrg        return FALSE;
88405b261ecSmrg
88505b261ecSmrg    switch (pvfb->depth) {
88605b261ecSmrg    case 8:
88735c4bbdfSmrg        miSetVisualTypesAndMasks(8,
88835c4bbdfSmrg                                 ((1 << StaticGray) |
88935c4bbdfSmrg                                  (1 << GrayScale) |
89035c4bbdfSmrg                                  (1 << StaticColor) |
89135c4bbdfSmrg                                  (1 << PseudoColor) |
89235c4bbdfSmrg                                  (1 << TrueColor) |
89335c4bbdfSmrg                                  (1 << DirectColor)), 8, PseudoColor, 0, 0, 0);
89435c4bbdfSmrg        break;
89505b261ecSmrg    case 15:
89635c4bbdfSmrg        miSetVisualTypesAndMasks(15,
89735c4bbdfSmrg                                 ((1 << TrueColor) |
89835c4bbdfSmrg                                  (1 << DirectColor)),
89935c4bbdfSmrg                                 8, TrueColor, 0x7c00, 0x03e0, 0x001f);
90035c4bbdfSmrg        break;
90105b261ecSmrg    case 16:
90235c4bbdfSmrg        miSetVisualTypesAndMasks(16,
90335c4bbdfSmrg                                 ((1 << TrueColor) |
90435c4bbdfSmrg                                  (1 << DirectColor)),
90535c4bbdfSmrg                                 8, TrueColor, 0xf800, 0x07e0, 0x001f);
90635c4bbdfSmrg        break;
90705b261ecSmrg    case 24:
90835c4bbdfSmrg        miSetVisualTypesAndMasks(24,
90935c4bbdfSmrg                                 ((1 << TrueColor) |
91035c4bbdfSmrg                                  (1 << DirectColor)),
91135c4bbdfSmrg                                 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
91235c4bbdfSmrg        break;
9136747b715Smrg    case 30:
91435c4bbdfSmrg        miSetVisualTypesAndMasks(30,
91535c4bbdfSmrg                                 ((1 << TrueColor) |
91635c4bbdfSmrg                                  (1 << DirectColor)),
91735c4bbdfSmrg                                 10, TrueColor, 0x3ff00000, 0x000ffc00,
91835c4bbdfSmrg                                 0x000003ff);
91935c4bbdfSmrg        break;
920475c125cSmrg    default:
92135c4bbdfSmrg        return FALSE;
92205b261ecSmrg    }
92352397711Smrg
92435c4bbdfSmrg    miSetPixmapDepths();
92552397711Smrg
92605b261ecSmrg    ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
92735c4bbdfSmrg                       dpix, dpiy, pvfb->paddedWidth, pvfb->bitsPerPixel);
92835c4bbdfSmrg    if (ret && Render)
92935c4bbdfSmrg        fbPictureInit(pScreen, 0, 0);
93035c4bbdfSmrg
93135c4bbdfSmrg    if (!ret)
93235c4bbdfSmrg        return FALSE;
93305b261ecSmrg
93435c4bbdfSmrg    if (!vfbRandRInit(pScreen))
93535c4bbdfSmrg       return FALSE;
93605b261ecSmrg
93705b261ecSmrg    pScreen->InstallColormap = vfbInstallColormap;
93805b261ecSmrg
93905b261ecSmrg    pScreen->SaveScreen = vfbSaveScreen;
94005b261ecSmrg    pScreen->StoreColors = vfbStoreColors;
94105b261ecSmrg
94205b261ecSmrg    miDCInitialize(pScreen, &vfbPointerCursorFuncs);
94305b261ecSmrg
94405b261ecSmrg    vfbWriteXWDFileHeader(pScreen);
94505b261ecSmrg
94605b261ecSmrg    pScreen->blackPixel = pvfb->blackPixel;
94705b261ecSmrg    pScreen->whitePixel = pvfb->whitePixel;
94805b261ecSmrg
94905b261ecSmrg    ret = fbCreateDefColormap(pScreen);
95005b261ecSmrg
95105b261ecSmrg    miSetZeroLineBias(pScreen, pvfb->lineBias);
95205b261ecSmrg
95305b261ecSmrg    pvfb->closeScreen = pScreen->CloseScreen;
95405b261ecSmrg    pScreen->CloseScreen = vfbCloseScreen;
95505b261ecSmrg
95605b261ecSmrg    return ret;
95705b261ecSmrg
95835c4bbdfSmrg}                               /* end vfbScreenInit */
95905b261ecSmrg
96035c4bbdfSmrgstatic const ExtensionModule vfbExtensions[] = {
96135c4bbdfSmrg#ifdef GLXEXT
96235c4bbdfSmrg    { GlxExtensionInit, "GLX", &noGlxExtension },
96335c4bbdfSmrg#endif
96435c4bbdfSmrg};
96535c4bbdfSmrg
96635c4bbdfSmrgstatic
96735c4bbdfSmrgvoid vfbExtensionInit(void)
96835c4bbdfSmrg{
96935c4bbdfSmrg    LoadExtensionList(vfbExtensions, ARRAY_SIZE(vfbExtensions), TRUE);
97035c4bbdfSmrg}
97105b261ecSmrg
97205b261ecSmrgvoid
97335c4bbdfSmrgInitOutput(ScreenInfo * screen_info, int argc, char **argv)
97405b261ecSmrg{
97505b261ecSmrg    int i;
97605b261ecSmrg    int NumFormats = 0;
97705b261ecSmrg
97835c4bbdfSmrg    if (serverGeneration == 1)
97935c4bbdfSmrg        vfbExtensionInit();
98035c4bbdfSmrg
98105b261ecSmrg    /* initialize pixmap formats */
98205b261ecSmrg
98305b261ecSmrg    /* must have a pixmap depth to match every screen depth */
98435c4bbdfSmrg    for (i = 0; i < vfbNumScreens; i++) {
98535c4bbdfSmrg        vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
98605b261ecSmrg    }
98705b261ecSmrg
98805b261ecSmrg    /* RENDER needs a good set of pixmaps. */
98905b261ecSmrg    if (Render) {
99035c4bbdfSmrg        vfbPixmapDepths[1] = TRUE;
99135c4bbdfSmrg        vfbPixmapDepths[4] = TRUE;
99235c4bbdfSmrg        vfbPixmapDepths[8] = TRUE;
99305b261ecSmrg#if 0
99435c4bbdfSmrg        vfbPixmapDepths[12] = TRUE;
99505b261ecSmrg#endif
99605b261ecSmrg/*	vfbPixmapDepths[15] = TRUE; */
99735c4bbdfSmrg        vfbPixmapDepths[16] = TRUE;
99835c4bbdfSmrg        vfbPixmapDepths[24] = TRUE;
99905b261ecSmrg#if 0
100035c4bbdfSmrg        vfbPixmapDepths[30] = TRUE;
100105b261ecSmrg#endif
100235c4bbdfSmrg        vfbPixmapDepths[32] = TRUE;
100305b261ecSmrg    }
100405b261ecSmrg
100535c4bbdfSmrg    for (i = 1; i <= 32; i++) {
100635c4bbdfSmrg        if (vfbPixmapDepths[i]) {
100735c4bbdfSmrg            if (NumFormats >= MAXFORMATS)
100835c4bbdfSmrg                FatalError("MAXFORMATS is too small for this server\n");
100935c4bbdfSmrg            screen_info->formats[NumFormats].depth = i;
101035c4bbdfSmrg            screen_info->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
101135c4bbdfSmrg            screen_info->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
101235c4bbdfSmrg            NumFormats++;
101335c4bbdfSmrg        }
101405b261ecSmrg    }
101505b261ecSmrg
101635c4bbdfSmrg    screen_info->imageByteOrder = IMAGE_BYTE_ORDER;
101735c4bbdfSmrg    screen_info->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
101835c4bbdfSmrg    screen_info->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
101935c4bbdfSmrg    screen_info->bitmapBitOrder = BITMAP_BIT_ORDER;
102035c4bbdfSmrg    screen_info->numPixmapFormats = NumFormats;
102105b261ecSmrg
102205b261ecSmrg    /* initialize screens */
102305b261ecSmrg
102435c4bbdfSmrg    if (vfbNumScreens < 1) {
102535c4bbdfSmrg        vfbScreens = &defaultScreenInfo;
102635c4bbdfSmrg        vfbNumScreens = 1;
10276747b715Smrg    }
102835c4bbdfSmrg    for (i = 0; i < vfbNumScreens; i++) {
102935c4bbdfSmrg        if (-1 == AddScreen(vfbScreenInit, argc, argv)) {
103035c4bbdfSmrg            FatalError("Couldn't add screen %d", i);
103135c4bbdfSmrg        }
103205b261ecSmrg    }
103305b261ecSmrg
103435c4bbdfSmrg}                               /* end InitOutput */
1035