fbscreen.c revision 05b261ec
105b261ecSmrg/* 205b261ecSmrg * Copyright © 1998 Keith Packard 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Keith Packard not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Keith Packard makes no 1105b261ecSmrg * representations about the suitability of this software for any purpose. It 1205b261ecSmrg * is provided "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg */ 2205b261ecSmrg 2305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2405b261ecSmrg#include <dix-config.h> 2505b261ecSmrg#endif 2605b261ecSmrg 2705b261ecSmrg#include "fb.h" 2805b261ecSmrg 2905b261ecSmrgBool 3005b261ecSmrgfbCloseScreen (int index, ScreenPtr pScreen) 3105b261ecSmrg{ 3205b261ecSmrg int d; 3305b261ecSmrg DepthPtr depths = pScreen->allowedDepths; 3405b261ecSmrg 3505b261ecSmrg for (d = 0; d < pScreen->numDepths; d++) 3605b261ecSmrg xfree (depths[d].vids); 3705b261ecSmrg xfree (depths); 3805b261ecSmrg xfree (pScreen->visuals); 3905b261ecSmrg xfree (pScreen->devPrivate); 4005b261ecSmrg#ifdef FB_SCREEN_PRIVATE 4105b261ecSmrg xfree (pScreen->devPrivates[fbScreenPrivateIndex].ptr); 4205b261ecSmrg#endif 4305b261ecSmrg return TRUE; 4405b261ecSmrg} 4505b261ecSmrg 4605b261ecSmrgBool 4705b261ecSmrgfbRealizeFont(ScreenPtr pScreen, FontPtr pFont) 4805b261ecSmrg{ 4905b261ecSmrg return (TRUE); 5005b261ecSmrg} 5105b261ecSmrg 5205b261ecSmrgBool 5305b261ecSmrgfbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont) 5405b261ecSmrg{ 5505b261ecSmrg return (TRUE); 5605b261ecSmrg} 5705b261ecSmrg 5805b261ecSmrgvoid 5905b261ecSmrgfbQueryBestSize (int class, 6005b261ecSmrg unsigned short *width, unsigned short *height, 6105b261ecSmrg ScreenPtr pScreen) 6205b261ecSmrg{ 6305b261ecSmrg unsigned short w; 6405b261ecSmrg 6505b261ecSmrg switch (class) { 6605b261ecSmrg case CursorShape: 6705b261ecSmrg if (*width > pScreen->width) 6805b261ecSmrg *width = pScreen->width; 6905b261ecSmrg if (*height > pScreen->height) 7005b261ecSmrg *height = pScreen->height; 7105b261ecSmrg break; 7205b261ecSmrg case TileShape: 7305b261ecSmrg case StippleShape: 7405b261ecSmrg w = *width; 7505b261ecSmrg if ((w & (w - 1)) && w < FB_UNIT) 7605b261ecSmrg { 7705b261ecSmrg for (w = 1; w < *width; w <<= 1) 7805b261ecSmrg ; 7905b261ecSmrg *width = w; 8005b261ecSmrg } 8105b261ecSmrg } 8205b261ecSmrg} 8305b261ecSmrg 8405b261ecSmrgPixmapPtr 8505b261ecSmrg_fbGetWindowPixmap (WindowPtr pWindow) 8605b261ecSmrg{ 8705b261ecSmrg return fbGetWindowPixmap (pWindow); 8805b261ecSmrg} 8905b261ecSmrg 9005b261ecSmrgvoid 9105b261ecSmrg_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap) 9205b261ecSmrg{ 9305b261ecSmrg#ifdef FB_NO_WINDOW_PIXMAPS 9405b261ecSmrg FatalError ("Attempted to set window pixmap without fb support\n"); 9505b261ecSmrg#else 9605b261ecSmrg pWindow->devPrivates[fbWinPrivateIndex].ptr = (pointer) pPixmap; 9705b261ecSmrg#endif 9805b261ecSmrg} 9905b261ecSmrg 10005b261ecSmrgBool 10105b261ecSmrgfbSetupScreen(ScreenPtr pScreen, 10205b261ecSmrg pointer pbits, /* pointer to screen bitmap */ 10305b261ecSmrg int xsize, /* in pixels */ 10405b261ecSmrg int ysize, 10505b261ecSmrg int dpix, /* dots per inch */ 10605b261ecSmrg int dpiy, 10705b261ecSmrg int width, /* pixel width of frame buffer */ 10805b261ecSmrg int bpp) /* bits per pixel for screen */ 10905b261ecSmrg{ 11005b261ecSmrg if (!fbAllocatePrivates(pScreen, (int *) 0)) 11105b261ecSmrg return FALSE; 11205b261ecSmrg pScreen->defColormap = FakeClientID(0); 11305b261ecSmrg /* let CreateDefColormap do whatever it wants for pixels */ 11405b261ecSmrg pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0; 11505b261ecSmrg pScreen->QueryBestSize = fbQueryBestSize; 11605b261ecSmrg /* SaveScreen */ 11705b261ecSmrg pScreen->GetImage = fbGetImage; 11805b261ecSmrg pScreen->GetSpans = fbGetSpans; 11905b261ecSmrg pScreen->CreateWindow = fbCreateWindow; 12005b261ecSmrg pScreen->DestroyWindow = fbDestroyWindow; 12105b261ecSmrg pScreen->PositionWindow = fbPositionWindow; 12205b261ecSmrg pScreen->ChangeWindowAttributes = fbChangeWindowAttributes; 12305b261ecSmrg pScreen->RealizeWindow = fbMapWindow; 12405b261ecSmrg pScreen->UnrealizeWindow = fbUnmapWindow; 12505b261ecSmrg pScreen->PaintWindowBackground = fbPaintWindow; 12605b261ecSmrg pScreen->PaintWindowBorder = fbPaintWindow; 12705b261ecSmrg pScreen->CopyWindow = fbCopyWindow; 12805b261ecSmrg pScreen->CreatePixmap = fbCreatePixmap; 12905b261ecSmrg pScreen->DestroyPixmap = fbDestroyPixmap; 13005b261ecSmrg pScreen->RealizeFont = fbRealizeFont; 13105b261ecSmrg pScreen->UnrealizeFont = fbUnrealizeFont; 13205b261ecSmrg pScreen->CreateGC = fbCreateGC; 13305b261ecSmrg pScreen->CreateColormap = fbInitializeColormap; 13405b261ecSmrg pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA; 13505b261ecSmrg pScreen->InstallColormap = fbInstallColormap; 13605b261ecSmrg pScreen->UninstallColormap = fbUninstallColormap; 13705b261ecSmrg pScreen->ListInstalledColormaps = fbListInstalledColormaps; 13805b261ecSmrg pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *))NoopDDA; 13905b261ecSmrg pScreen->ResolveColor = fbResolveColor; 14005b261ecSmrg pScreen->BitmapToRegion = fbPixmapToRegion; 14105b261ecSmrg 14205b261ecSmrg pScreen->GetWindowPixmap = _fbGetWindowPixmap; 14305b261ecSmrg pScreen->SetWindowPixmap = _fbSetWindowPixmap; 14405b261ecSmrg 14505b261ecSmrg pScreen->BackingStoreFuncs.SaveAreas = fbSaveAreas; 14605b261ecSmrg pScreen->BackingStoreFuncs.RestoreAreas = fbRestoreAreas; 14705b261ecSmrg pScreen->BackingStoreFuncs.SetClipmaskRgn = 0; 14805b261ecSmrg pScreen->BackingStoreFuncs.GetImagePixmap = 0; 14905b261ecSmrg pScreen->BackingStoreFuncs.GetSpansPixmap = 0; 15005b261ecSmrg 15105b261ecSmrg return TRUE; 15205b261ecSmrg} 15305b261ecSmrg 15405b261ecSmrg#ifdef FB_ACCESS_WRAPPER 15505b261ecSmrgBool 15605b261ecSmrgwfbFinishScreenInit(ScreenPtr pScreen, 15705b261ecSmrg pointer pbits, 15805b261ecSmrg int xsize, 15905b261ecSmrg int ysize, 16005b261ecSmrg int dpix, 16105b261ecSmrg int dpiy, 16205b261ecSmrg int width, 16305b261ecSmrg int bpp, 16405b261ecSmrg SetupWrapProcPtr setupWrap, 16505b261ecSmrg FinishWrapProcPtr finishWrap) 16605b261ecSmrg#else 16705b261ecSmrgBool 16805b261ecSmrgfbFinishScreenInit(ScreenPtr pScreen, 16905b261ecSmrg pointer pbits, 17005b261ecSmrg int xsize, 17105b261ecSmrg int ysize, 17205b261ecSmrg int dpix, 17305b261ecSmrg int dpiy, 17405b261ecSmrg int width, 17505b261ecSmrg int bpp) 17605b261ecSmrg#endif 17705b261ecSmrg{ 17805b261ecSmrg VisualPtr visuals; 17905b261ecSmrg DepthPtr depths; 18005b261ecSmrg int nvisuals; 18105b261ecSmrg int ndepths; 18205b261ecSmrg int rootdepth; 18305b261ecSmrg VisualID defaultVisual; 18405b261ecSmrg int imagebpp = bpp; 18505b261ecSmrg 18605b261ecSmrg#ifdef FB_DEBUG 18705b261ecSmrg int stride; 18805b261ecSmrg 18905b261ecSmrg ysize -= 2; 19005b261ecSmrg stride = (width * bpp) / 8; 19105b261ecSmrg fbSetBits ((FbStip *) pbits, 19205b261ecSmrg stride / sizeof (FbStip), FB_HEAD_BITS); 19305b261ecSmrg pbits = (void *) ((char *) pbits + stride); 19405b261ecSmrg fbSetBits ((FbStip *) ((char *) pbits + stride * ysize), 19505b261ecSmrg stride / sizeof (FbStip), FB_TAIL_BITS); 19605b261ecSmrg#endif 19705b261ecSmrg /* 19805b261ecSmrg * By default, a 24bpp screen will use 32bpp images, this avoids 19905b261ecSmrg * problems with many applications which just can't handle packed 20005b261ecSmrg * pixels. If you want real 24bit images, include a 24bpp 20105b261ecSmrg * format in the pixmap formats 20205b261ecSmrg */ 20305b261ecSmrg#ifdef FB_24_32BIT 20405b261ecSmrg if (bpp == 24) 20505b261ecSmrg { 20605b261ecSmrg int f; 20705b261ecSmrg 20805b261ecSmrg imagebpp = 32; 20905b261ecSmrg /* 21005b261ecSmrg * Check to see if we're advertising a 24bpp image format, 21105b261ecSmrg * in which case windows will use it in preference to a 32 bit 21205b261ecSmrg * format. 21305b261ecSmrg */ 21405b261ecSmrg for (f = 0; f < screenInfo.numPixmapFormats; f++) 21505b261ecSmrg { 21605b261ecSmrg if (screenInfo.formats[f].bitsPerPixel == 24) 21705b261ecSmrg { 21805b261ecSmrg imagebpp = 24; 21905b261ecSmrg break; 22005b261ecSmrg } 22105b261ecSmrg } 22205b261ecSmrg } 22305b261ecSmrg#endif 22405b261ecSmrg#ifdef FB_SCREEN_PRIVATE 22505b261ecSmrg if (imagebpp == 32) 22605b261ecSmrg { 22705b261ecSmrg fbGetScreenPrivate(pScreen)->win32bpp = bpp; 22805b261ecSmrg fbGetScreenPrivate(pScreen)->pix32bpp = bpp; 22905b261ecSmrg } 23005b261ecSmrg else 23105b261ecSmrg { 23205b261ecSmrg fbGetScreenPrivate(pScreen)->win32bpp = 32; 23305b261ecSmrg fbGetScreenPrivate(pScreen)->pix32bpp = 32; 23405b261ecSmrg } 23505b261ecSmrg#ifdef FB_ACCESS_WRAPPER 23605b261ecSmrg fbGetScreenPrivate(pScreen)->setupWrap = setupWrap; 23705b261ecSmrg fbGetScreenPrivate(pScreen)->finishWrap = finishWrap; 23805b261ecSmrg#endif 23905b261ecSmrg#endif 24005b261ecSmrg rootdepth = 0; 24105b261ecSmrg if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth, 24205b261ecSmrg &defaultVisual,((unsigned long)1<<(imagebpp-1)), 8)) 24305b261ecSmrg return FALSE; 24405b261ecSmrg if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, 24505b261ecSmrg rootdepth, ndepths, depths, 24605b261ecSmrg defaultVisual, nvisuals, visuals)) 24705b261ecSmrg return FALSE; 24805b261ecSmrg /* overwrite miCloseScreen with our own */ 24905b261ecSmrg pScreen->CloseScreen = fbCloseScreen; 25005b261ecSmrg#ifdef FB_24_32BIT 25105b261ecSmrg if (bpp == 24 && imagebpp == 32) 25205b261ecSmrg { 25305b261ecSmrg pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader; 25405b261ecSmrg pScreen->CreateScreenResources = fb24_32CreateScreenResources; 25505b261ecSmrg } 25605b261ecSmrg#endif 25705b261ecSmrg#if 0 25805b261ecSmrg /* leave backing store initialization to the enclosing code so 25905b261ecSmrg * it can choose the correct order of wrappers 26005b261ecSmrg */ 26105b261ecSmrg /* init backing store here so we can overwrite CloseScreen without stepping 26205b261ecSmrg * on the backing store wrapped version */ 26305b261ecSmrg fbInitializeBackingStore (pScreen); 26405b261ecSmrg#endif 26505b261ecSmrg return TRUE; 26605b261ecSmrg} 26705b261ecSmrg 26805b261ecSmrg/* dts * (inch/dot) * (25.4 mm / inch) = mm */ 26905b261ecSmrg#ifdef FB_ACCESS_WRAPPER 27005b261ecSmrgBool 27105b261ecSmrgwfbScreenInit(ScreenPtr pScreen, 27205b261ecSmrg pointer pbits, 27305b261ecSmrg int xsize, 27405b261ecSmrg int ysize, 27505b261ecSmrg int dpix, 27605b261ecSmrg int dpiy, 27705b261ecSmrg int width, 27805b261ecSmrg int bpp, 27905b261ecSmrg SetupWrapProcPtr setupWrap, 28005b261ecSmrg FinishWrapProcPtr finishWrap) 28105b261ecSmrg{ 28205b261ecSmrg if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)) 28305b261ecSmrg return FALSE; 28405b261ecSmrg if (!wfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, 28505b261ecSmrg width, bpp, setupWrap, finishWrap)) 28605b261ecSmrg return FALSE; 28705b261ecSmrg return TRUE; 28805b261ecSmrg} 28905b261ecSmrg#else 29005b261ecSmrgBool 29105b261ecSmrgfbScreenInit(ScreenPtr pScreen, 29205b261ecSmrg pointer pbits, 29305b261ecSmrg int xsize, 29405b261ecSmrg int ysize, 29505b261ecSmrg int dpix, 29605b261ecSmrg int dpiy, 29705b261ecSmrg int width, 29805b261ecSmrg int bpp) 29905b261ecSmrg{ 30005b261ecSmrg if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp)) 30105b261ecSmrg return FALSE; 30205b261ecSmrg if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, 30305b261ecSmrg width, bpp)) 30405b261ecSmrg return FALSE; 30505b261ecSmrg return TRUE; 30605b261ecSmrg} 30705b261ecSmrg#endif 308