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