diff options
Diffstat (limited to 'hw/vfb/InitOutput.c')
-rw-r--r-- | hw/vfb/InitOutput.c | 981 |
1 files changed, 981 insertions, 0 deletions
diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c new file mode 100644 index 000000000..c2334e745 --- /dev/null +++ b/hw/vfb/InitOutput.c @@ -0,0 +1,981 @@ +/* $Xorg: InitOutput.c,v 1.4 2001/02/09 02:04:45 xorgcvs Exp $ */ +/* + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#ifdef WIN32 +#include <X11/Xwinsock.h> +#endif +#include <stdio.h> +#include "X11/X.h" +#define NEED_EVENTS +#include "X11/Xproto.h" +#include "X11/Xos.h" +#include "scrnintstr.h" +#include "servermd.h" +#define PSZ 8 +#include "cfb.h" +#include "mibstore.h" +#include "colormapst.h" +#include "gcstruct.h" +#include "input.h" +#include "mipointer.h" +#include <sys/types.h> +#ifdef HAS_MMAP +#include <sys/mman.h> +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif +#endif /* HAS_MMAP */ +#include <sys/stat.h> +#include <errno.h> +#ifndef WIN32 +#include <sys/param.h> +#endif +#include <X11/XWDFile.h> +#ifdef HAS_SHM +#include <sys/ipc.h> +#include <sys/shm.h> +#endif /* HAS_SHM */ +#include "dix.h" +#include "miline.h" + +extern char *display; + +#define VFB_DEFAULT_WIDTH 1280 +#define VFB_DEFAULT_HEIGHT 1024 +#define VFB_DEFAULT_DEPTH 8 +#define VFB_DEFAULT_WHITEPIXEL 0 +#define VFB_DEFAULT_BLACKPIXEL 1 +#define VFB_DEFAULT_LINEBIAS 0 +#define XWD_WINDOW_NAME_LEN 60 + +typedef struct +{ + int scrnum; + int width; + int paddedWidth; + int height; + int depth; + int bitsPerPixel; + int sizeInBytes; + int ncolors; + char *pfbMemory; + XWDColor *pXWDCmap; + XWDFileHeader *pXWDHeader; + Pixel blackPixel; + Pixel whitePixel; + unsigned int lineBias; + +#ifdef HAS_MMAP + int mmap_fd; + char mmap_file[MAXPATHLEN]; +#endif + +#ifdef HAS_SHM + int shmid; +#endif +} vfbScreenInfo, *vfbScreenInfoPtr; + +static int vfbNumScreens; +static vfbScreenInfo vfbScreens[MAXSCREENS]; +static Bool vfbPixmapDepths[33]; +static char *pfbdir = NULL; +typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType; +static fbMemType fbmemtype = NORMAL_MEMORY_FB; +static char needswap = 0; +static int lastScreen = -1; + +#define swapcopy16(_dst, _src) \ + if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \ + else _dst = _src; + +#define swapcopy32(_dst, _src) \ + if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \ + else _dst = _src; + + +static void +vfbInitializePixmapDepths() +{ + int i; + vfbPixmapDepths[1] = TRUE; /* always need bitmaps */ + for (i = 2; i <= 32; i++) + vfbPixmapDepths[i] = FALSE; +} + +static void +vfbInitializeDefaultScreens() +{ + int i; + + for (i = 0; i < MAXSCREENS; i++) + { + vfbScreens[i].scrnum = i; + vfbScreens[i].width = VFB_DEFAULT_WIDTH; + vfbScreens[i].height = VFB_DEFAULT_HEIGHT; + vfbScreens[i].depth = VFB_DEFAULT_DEPTH; + vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL; + vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL; + vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS; + vfbScreens[i].pfbMemory = NULL; + } + vfbNumScreens = 1; +} + +static int +vfbBitsPerPixel(depth) + int depth; +{ + if (depth == 1) return 1; + else if (depth <= 8) return 8; + else if (depth <= 16) return 16; + else return 32; +} + +void +ddxGiveUp() +{ + int i; + + /* clean up the framebuffers */ + + switch (fbmemtype) + { +#ifdef HAS_MMAP + case MMAPPED_FILE_FB: + for (i = 0; i < vfbNumScreens; i++) + { + if (-1 == unlink(vfbScreens[i].mmap_file)) + { + perror("unlink"); + ErrorF("unlink %s failed, errno %d", + vfbScreens[i].mmap_file, errno); + } + } + break; +#endif /* HAS_MMAP */ + +#ifdef HAS_SHM + case SHARED_MEMORY_FB: + for (i = 0; i < vfbNumScreens; i++) + { + if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader)) + { + perror("shmdt"); + ErrorF("shmdt failed, errno %d", errno); + } + } + break; +#endif /* HAS_SHM */ + + case NORMAL_MEMORY_FB: + for (i = 0; i < vfbNumScreens; i++) + { + Xfree(vfbScreens[i].pXWDHeader); + } + break; + } +} + +void +AbortDDX() +{ + ddxGiveUp(); +} + +void +OsVendorInit() +{ +} + +void +ddxUseMsg() +{ + ErrorF("-screen scrn WxHxD set screen's width, height, depth\n"); + ErrorF("-pixdepths list-of-int support given pixmap depths\n"); + ErrorF("-linebias n adjust thin line pixelization\n"); + ErrorF("-blackpixel n pixel value for black\n"); + ErrorF("-whitepixel n pixel value for white\n"); + +#ifdef HAS_MMAP + ErrorF("-fbdir directory put framebuffers in mmap'ed files in directory\n"); +#endif + +#ifdef HAS_SHM + ErrorF("-shmem put framebuffers in shared memory\n"); +#endif +} + +int +ddxProcessArgument (argc, argv, i) + int argc; + char *argv[]; + int i; +{ + static Bool firstTime = TRUE; + + if (firstTime) + { + vfbInitializeDefaultScreens(); + vfbInitializePixmapDepths(); + firstTime = FALSE; + } + + if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */ + { + int screenNum; + if (i + 2 >= argc) UseMsg(); + screenNum = atoi(argv[i+1]); + if (screenNum < 0 || screenNum >= MAXSCREENS) + { + ErrorF("Invalid screen number %d\n", screenNum); + UseMsg(); + } + if (3 != sscanf(argv[i+2], "%dx%dx%d", + &vfbScreens[screenNum].width, + &vfbScreens[screenNum].height, + &vfbScreens[screenNum].depth)) + { + ErrorF("Invalid screen configuration %s\n", argv[i+2]); + UseMsg(); + } + + if (screenNum >= vfbNumScreens) + vfbNumScreens = screenNum + 1; + lastScreen = screenNum; + return 3; + } + + if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */ + { + int depth, ret = 1; + + if (++i >= argc) UseMsg(); + while ((i < argc) && (depth = atoi(argv[i++])) != 0) + { + if (depth < 0 || depth > 32) + { + ErrorF("Invalid pixmap depth %d\n", depth); + UseMsg(); + } + vfbPixmapDepths[depth] = TRUE; + ret++; + } + return ret; + } + + if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */ + { + Pixel pix; + if (++i >= argc) UseMsg(); + pix = atoi(argv[i]); + if (-1 == lastScreen) + { + int i; + for (i = 0; i < MAXSCREENS; i++) + { + vfbScreens[i].blackPixel = pix; + } + } + else + { + vfbScreens[lastScreen].blackPixel = pix; + } + return 2; + } + + if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */ + { + Pixel pix; + if (++i >= argc) UseMsg(); + pix = atoi(argv[i]); + if (-1 == lastScreen) + { + int i; + for (i = 0; i < MAXSCREENS; i++) + { + vfbScreens[i].whitePixel = pix; + } + } + else + { + vfbScreens[lastScreen].whitePixel = pix; + } + return 2; + } + + if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */ + { + unsigned int linebias; + if (++i >= argc) UseMsg(); + linebias = atoi(argv[i]); + if (-1 == lastScreen) + { + int i; + for (i = 0; i < MAXSCREENS; i++) + { + vfbScreens[i].lineBias = linebias; + } + } + else + { + vfbScreens[lastScreen].lineBias = linebias; + } + return 2; + } + +#ifdef HAS_MMAP + if (strcmp (argv[i], "-fbdir") == 0) /* -fbdir directory */ + { + if (++i >= argc) UseMsg(); + pfbdir = argv[i]; + fbmemtype = MMAPPED_FILE_FB; + return 2; + } +#endif /* HAS_MMAP */ + +#ifdef HAS_SHM + if (strcmp (argv[i], "-shmem") == 0) /* -shmem */ + { + fbmemtype = SHARED_MEMORY_FB; + return 1; + } +#endif + + return 0; +} + +#ifdef DDXTIME /* from ServerOSDefines */ +CARD32 +GetTimeInMillis() +{ + struct timeval tp; + + X_GETTIMEOFDAY(&tp); + return(tp.tv_sec * 1000) + (tp.tv_usec / 1000); +} +#endif + + +static Bool +vfbMultiDepthCreateGC(pGC) + GCPtr pGC; +{ + switch (vfbBitsPerPixel(pGC->depth)) + { + case 1: return mfbCreateGC (pGC); + case 8: return cfbCreateGC (pGC); + case 16: return cfb16CreateGC (pGC); + case 32: return cfb32CreateGC (pGC); + default: return FALSE; + } +} + +static void +vfbMultiDepthGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart) + DrawablePtr pDrawable; /* drawable from which to get bits */ + int wMax; /* largest value of all *pwidths */ + register DDXPointPtr ppt; /* points to start copying from */ + int *pwidth; /* list of number of bits to copy */ + int nspans; /* number of scanlines to copy */ + char *pdstStart; /* where to put the bits */ +{ + switch (pDrawable->bitsPerPixel) { + case 1: + mfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); + break; + case 8: + cfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); + break; + case 16: + cfb16GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); + break; + case 32: + cfb32GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart); + break; + } + return; +} + +static void +vfbMultiDepthGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine) + DrawablePtr pDrawable; + int sx, sy, w, h; + unsigned int format; + unsigned long planeMask; + char *pdstLine; +{ + switch (pDrawable->bitsPerPixel) + { + case 1: + mfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); + break; + case 8: + cfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); + break; + case 16: + cfb16GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); + break; + case 32: + cfb32GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine); + break; + } +} + +static ColormapPtr InstalledMaps[MAXSCREENS]; + +static int +vfbListInstalledColormaps(pScreen, pmaps) + ScreenPtr pScreen; + Colormap *pmaps; +{ + /* By the time we are processing requests, we can guarantee that there + * is always a colormap installed */ + *pmaps = InstalledMaps[pScreen->myNum]->mid; + return (1); +} + + +static void +vfbInstallColormap(pmap) + ColormapPtr pmap; +{ + int index = pmap->pScreen->myNum; + ColormapPtr oldpmap = InstalledMaps[index]; + + if (pmap != oldpmap) + { + int entries; + XWDFileHeader *pXWDHeader; + XWDColor *pXWDCmap; + VisualPtr pVisual; + Pixel * ppix; + xrgb * prgb; + xColorItem *defs; + int i; + + if(oldpmap != (ColormapPtr)None) + WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid); + /* Install pmap */ + InstalledMaps[index] = pmap; + WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid); + + entries = pmap->pVisual->ColormapEntries; + pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader; + pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap; + pVisual = pmap->pVisual; + + swapcopy32(pXWDHeader->visual_class, pVisual->class); + swapcopy32(pXWDHeader->red_mask, pVisual->redMask); + swapcopy32(pXWDHeader->green_mask, pVisual->greenMask); + swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask); + swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue); + swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries); + + ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel)); + prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb)); + defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem)); + + for (i = 0; i < entries; i++) ppix[i] = i; + /* XXX truecolor */ + QueryColors(pmap, entries, ppix, prgb); + + for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */ + defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */ + defs[i].red = prgb[i].red; + defs[i].green = prgb[i].green; + defs[i].blue = prgb[i].blue; + defs[i].flags = DoRed|DoGreen|DoBlue; + } + (*pmap->pScreen->StoreColors)(pmap, entries, defs); + + DEALLOCATE_LOCAL(ppix); + DEALLOCATE_LOCAL(prgb); + DEALLOCATE_LOCAL(defs); + } +} + +static void +vfbUninstallColormap(pmap) + ColormapPtr pmap; +{ + ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum]; + + if(pmap == curpmap) + { + if (pmap->mid != pmap->pScreen->defColormap) + { + curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap, + RT_COLORMAP); + (*pmap->pScreen->InstallColormap)(curpmap); + } + } +} + +static void +vfbStoreColors(pmap, ndef, pdefs) + ColormapPtr pmap; + int ndef; + xColorItem *pdefs; +{ + XWDColor *pXWDCmap; + int i; + + if (pmap != InstalledMaps[pmap->pScreen->myNum]) return; + + pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap; + + if ((pmap->pVisual->class | DynamicClass) == DirectColor) + return; + + for (i = 0; i < ndef; i++) + { + if (pdefs[i].flags & DoRed) + swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red); + if (pdefs[i].flags & DoGreen) + swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green); + if (pdefs[i].flags & DoBlue) + swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue); + } +} + +static Bool +vfbSaveScreen(pScreen, on) + ScreenPtr pScreen; + int on; +{ + return TRUE; +} + +#ifdef HAS_MMAP + +/* this flushes any changes to the screens out to the mmapped file */ +static void +vfbBlockHandler(blockData, pTimeout, pReadmask) + pointer blockData; + OSTimePtr pTimeout; + pointer pReadmask; +{ + int i; + + for (i = 0; i < vfbNumScreens; i++) + { +#ifdef MS_ASYNC + if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader, + (size_t)vfbScreens[i].sizeInBytes, MS_ASYNC)) +#else + /* silly NetBSD and who else? */ + if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader, + (size_t)vfbScreens[i].sizeInBytes)) +#endif + { + perror("msync"); + ErrorF("msync failed, errno %d", errno); + } + } +} + + +static void +vfbWakeupHandler(blockData, result, pReadmask) + pointer blockData; + int result; + pointer pReadmask; +{ +} + + +static void +vfbAllocateMmappedFramebuffer(pvfb) + vfbScreenInfoPtr pvfb; +{ +#define DUMMY_BUFFER_SIZE 65536 + char dummyBuffer[DUMMY_BUFFER_SIZE]; + int currentFileSize, writeThisTime; + + sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, pvfb->scrnum); + if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666))) + { + perror("open"); + ErrorF("open %s failed, errno %d", pvfb->mmap_file, errno); + return; + } + + /* Extend the file to be the proper size */ + + bzero(dummyBuffer, DUMMY_BUFFER_SIZE); + for (currentFileSize = 0; + currentFileSize < pvfb->sizeInBytes; + currentFileSize += writeThisTime) + { + writeThisTime = min(DUMMY_BUFFER_SIZE, + pvfb->sizeInBytes - currentFileSize); + if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime)) + { + perror("write"); + ErrorF("write %s failed, errno %d", pvfb->mmap_file, errno); + return; + } + } + + /* try to mmap the file */ + + pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes, + PROT_READ|PROT_WRITE, + MAP_FILE|MAP_SHARED, + pvfb->mmap_fd, 0); + if (-1 == (int)pvfb->pXWDHeader) + { + perror("mmap"); + ErrorF("mmap %s failed, errno %d", pvfb->mmap_file, errno); + pvfb->pXWDHeader = NULL; + return; + } + + if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler, + NULL)) + { + pvfb->pXWDHeader = NULL; + } +} +#endif /* HAS_MMAP */ + + +#ifdef HAS_SHM +static void +vfbAllocateSharedMemoryFramebuffer(pvfb) + vfbScreenInfoPtr pvfb; +{ + /* create the shared memory segment */ + + pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777); + if (pvfb->shmid < 0) + { + perror("shmget"); + ErrorF("shmget %d bytes failed, errno %d", pvfb->sizeInBytes, errno); + return; + } + + /* try to attach it */ + + pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0); + if (-1 == (int)pvfb->pXWDHeader) + { + perror("shmat"); + ErrorF("shmat failed, errno %d", errno); + pvfb->pXWDHeader = NULL; + return; + } + + ErrorF("screen %d shmid %d\n", pvfb->scrnum, pvfb->shmid); +} +#endif /* HAS_SHM */ + +static char * +vfbAllocateFramebufferMemory(pvfb) + vfbScreenInfoPtr pvfb; +{ + if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */ + + if (pvfb->bitsPerPixel == 1) + pvfb->sizeInBytes = (pvfb->paddedWidth * pvfb->height); + else + pvfb->sizeInBytes = pvfb->paddedWidth * pvfb->height * + (pvfb->bitsPerPixel/8); + + /* Calculate how many entries in colormap. This is rather bogus, because + * the visuals haven't even been set up yet, but we need to know because we + * have to allocate space in the file for the colormap. The number 10 + * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c. + */ + + if (pvfb->depth <= 10) + { /* single index colormaps */ + pvfb->ncolors = 1 << pvfb->depth; + } + else + { /* decomposed colormaps */ + int nplanes_per_color_component = pvfb->depth / 3; + if (pvfb->depth % 3) nplanes_per_color_component++; + pvfb->ncolors = 1 << nplanes_per_color_component; + } + + /* add extra bytes for XWDFileHeader, window name, and colormap */ + + pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN + + pvfb->ncolors * SIZEOF(XWDColor); + + pvfb->pXWDHeader = NULL; + switch (fbmemtype) + { +#ifdef HAS_MMAP + case MMAPPED_FILE_FB: vfbAllocateMmappedFramebuffer(pvfb); break; +#endif + +#ifdef HAS_SHM + case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break; +#endif + + case NORMAL_MEMORY_FB: + pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes); + break; + } + + if (pvfb->pXWDHeader) + { + pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader + + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN); + pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors); + return pvfb->pfbMemory; + } + else + return NULL; +} + + +static void +vfbWriteXWDFileHeader(pScreen) + ScreenPtr pScreen; +{ + vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum]; + XWDFileHeader *pXWDHeader = pvfb->pXWDHeader; + char hostname[XWD_WINDOW_NAME_LEN]; + VisualPtr pVisual; + unsigned long swaptest = 1; + int i; + + needswap = *(char *) &swaptest; + + pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader; + pXWDHeader->file_version = XWD_FILE_VERSION; + + pXWDHeader->pixmap_format = ZPixmap; + pXWDHeader->pixmap_depth = pvfb->depth; + pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height; + pXWDHeader->xoffset = 0; + pXWDHeader->byte_order = IMAGE_BYTE_ORDER; + pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER; +#ifndef INTERNAL_VS_EXTERNAL_PADDING + pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width; + pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT; + pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD; +#else + pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth; + pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO; + pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO; +#endif + pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel; + pXWDHeader->bytes_per_line = pvfb->paddedWidth; + pXWDHeader->ncolors = pvfb->ncolors; + + /* visual related fields are written when colormap is installed */ + + pXWDHeader->window_x = pXWDHeader->window_y = 0; + pXWDHeader->window_bdrwidth = 0; + + /* write xwd "window" name: Xvfb hostname:server.screen */ + + if (-1 == gethostname(hostname, sizeof(hostname))) + hostname[0] = 0; + else + hostname[XWD_WINDOW_NAME_LEN-1] = 0; + sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display, + pScreen->myNum); + + /* write colormap pixel slot values */ + + for (i = 0; i < pvfb->ncolors; i++) + { + pvfb->pXWDCmap[i].pixel = i; + } + + /* byte swap to most significant byte first */ + + if (needswap) + { + SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4); + for (i = 0; i < pvfb->ncolors; i++) + { + register char n; + swapl(&pvfb->pXWDCmap[i].pixel, n); + } + } +} + + +static Bool +vfbCursorOffScreen (ppScreen, x, y) + ScreenPtr *ppScreen; + int *x, *y; +{ + return FALSE; +} + +static void +vfbCrossScreen (pScreen, entering) + ScreenPtr pScreen; + Bool entering; +{ +} + +static miPointerScreenFuncRec vfbPointerCursorFuncs = +{ + vfbCursorOffScreen, + vfbCrossScreen, + miPointerWarpCursor +}; + +static Bool +vfbScreenInit(index, pScreen, argc, argv) + int index; + ScreenPtr pScreen; + int argc; + char ** argv; +{ + vfbScreenInfoPtr pvfb = &vfbScreens[index]; + int dpix = 100, dpiy = 100; + int ret; + char *pbits; + + pvfb->paddedWidth = PixmapBytePad(pvfb->width, pvfb->depth); + pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth); + pbits = vfbAllocateFramebufferMemory(pvfb); + if (!pbits) return FALSE; + + switch (pvfb->bitsPerPixel) + { + case 1: + ret = mfbScreenInit(pScreen, pbits, pvfb->width, pvfb->height, + dpix, dpiy, pvfb->paddedWidth * 8); + break; + case 8: + ret = cfbScreenInit(pScreen, pbits, pvfb->width, pvfb->height, + dpix, dpiy, pvfb->paddedWidth); + break; + case 16: + ret = cfb16ScreenInit(pScreen, pbits, pvfb->width, pvfb->height, + dpix, dpiy, pvfb->paddedWidth); + break; + case 32: + ret = cfb32ScreenInit(pScreen, pbits, pvfb->width, pvfb->height, + dpix, dpiy, pvfb->paddedWidth); + break; + default: + return FALSE; + } + + if (!ret) return FALSE; + + pScreen->CreateGC = vfbMultiDepthCreateGC; + pScreen->GetImage = vfbMultiDepthGetImage; + pScreen->GetSpans = vfbMultiDepthGetSpans; + + pScreen->InstallColormap = vfbInstallColormap; + pScreen->UninstallColormap = vfbUninstallColormap; + pScreen->ListInstalledColormaps = vfbListInstalledColormaps; + + pScreen->SaveScreen = vfbSaveScreen; + pScreen->StoreColors = vfbStoreColors; + + miDCInitialize(pScreen, &vfbPointerCursorFuncs); + + vfbWriteXWDFileHeader(pScreen); + + pScreen->blackPixel = pvfb->blackPixel; + pScreen->whitePixel = pvfb->whitePixel; + + if (pvfb->bitsPerPixel == 1) + { + ret = mfbCreateDefColormap(pScreen); + } + else + { + ret = cfbCreateDefColormap(pScreen); + } + + miSetZeroLineBias(pScreen, pvfb->lineBias); + + return ret; + +} /* end vfbScreenInit */ + + +void +InitOutput(screenInfo, argc, argv) + ScreenInfo *screenInfo; + int argc; + char **argv; +{ + int i; + int NumFormats = 0; + FILE *pf = stderr; + + /* initialize pixmap formats */ + + /* must have a pixmap depth to match every screen depth */ + for (i = 0; i < vfbNumScreens; i++) + { + vfbPixmapDepths[vfbScreens[i].depth] = TRUE; + } + + for (i = 1; i <= 32; i++) + { + if (vfbPixmapDepths[i]) + { + if (NumFormats >= MAXFORMATS) + FatalError ("MAXFORMATS is too small for this server\n"); + screenInfo->formats[NumFormats].depth = i; + screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i); + screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD; + NumFormats++; + } + } + + screenInfo->imageByteOrder = IMAGE_BYTE_ORDER; + screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + screenInfo->numPixmapFormats = NumFormats; + + /* initialize screens */ + + for (i = 0; i < vfbNumScreens; i++) + { + if (-1 == AddScreen(vfbScreenInit, argc, argv)) + { + FatalError("Couldn't add screen %d", i); + } + } + +} /* end InitOutput */ + +/* this is just to get the server to link on AIX */ +#ifdef AIXV3 +int SelectWaitTime = 10000; /* usec */ +#endif + |