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