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