fbscreen.c revision 6747b715
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++)
366747b715Smrg	free(depths[d].vids);
376747b715Smrg    free(depths);
386747b715Smrg    free(pScreen->visuals);
396747b715Smrg    free(pScreen->devPrivate);
4005b261ecSmrg    return TRUE;
4105b261ecSmrg}
4205b261ecSmrg
4305b261ecSmrgBool
4405b261ecSmrgfbRealizeFont(ScreenPtr pScreen, FontPtr pFont)
4505b261ecSmrg{
466747b715Smrg    return TRUE;
4705b261ecSmrg}
4805b261ecSmrg
4905b261ecSmrgBool
5005b261ecSmrgfbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
5105b261ecSmrg{
526747b715Smrg    return TRUE;
5305b261ecSmrg}
5405b261ecSmrg
5505b261ecSmrgvoid
5605b261ecSmrgfbQueryBestSize (int class,
5705b261ecSmrg		 unsigned short *width, unsigned short *height,
5805b261ecSmrg		 ScreenPtr pScreen)
5905b261ecSmrg{
6005b261ecSmrg    unsigned short  w;
6105b261ecSmrg
6205b261ecSmrg    switch (class) {
6305b261ecSmrg    case CursorShape:
6405b261ecSmrg	if (*width > pScreen->width)
6505b261ecSmrg	    *width = pScreen->width;
6605b261ecSmrg	if (*height > pScreen->height)
6705b261ecSmrg	    *height = pScreen->height;
6805b261ecSmrg	break;
6905b261ecSmrg    case TileShape:
7005b261ecSmrg    case StippleShape:
7105b261ecSmrg	w = *width;
7205b261ecSmrg	if ((w & (w - 1)) && w < FB_UNIT)
7305b261ecSmrg	{
7405b261ecSmrg	    for (w = 1; w < *width; w <<= 1)
7505b261ecSmrg		;
7605b261ecSmrg	    *width = w;
7705b261ecSmrg	}
7805b261ecSmrg    }
7905b261ecSmrg}
8005b261ecSmrg
8105b261ecSmrgPixmapPtr
8205b261ecSmrg_fbGetWindowPixmap (WindowPtr pWindow)
8305b261ecSmrg{
8405b261ecSmrg    return fbGetWindowPixmap (pWindow);
8505b261ecSmrg}
8605b261ecSmrg
8705b261ecSmrgvoid
8805b261ecSmrg_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
8905b261ecSmrg{
904642e01fSmrg    dixSetPrivate(&pWindow->devPrivates, fbGetWinPrivateKey(), pPixmap);
9105b261ecSmrg}
9205b261ecSmrg
9305b261ecSmrgBool
9405b261ecSmrgfbSetupScreen(ScreenPtr	pScreen,
9505b261ecSmrg	      pointer	pbits,		/* pointer to screen bitmap */
9605b261ecSmrg	      int	xsize, 		/* in pixels */
9705b261ecSmrg	      int	ysize,
9805b261ecSmrg	      int	dpix,		/* dots per inch */
9905b261ecSmrg	      int	dpiy,
10005b261ecSmrg	      int	width,		/* pixel width of frame buffer */
10105b261ecSmrg	      int	bpp)		/* bits per pixel for screen */
10205b261ecSmrg{
1034642e01fSmrg    if (!fbAllocatePrivates(pScreen, NULL))
10405b261ecSmrg	return FALSE;
10505b261ecSmrg    pScreen->defColormap = FakeClientID(0);
10605b261ecSmrg    /* let CreateDefColormap do whatever it wants for pixels */
10705b261ecSmrg    pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
10805b261ecSmrg    pScreen->QueryBestSize = fbQueryBestSize;
10905b261ecSmrg    /* SaveScreen */
11005b261ecSmrg    pScreen->GetImage = fbGetImage;
11105b261ecSmrg    pScreen->GetSpans = fbGetSpans;
11205b261ecSmrg    pScreen->CreateWindow = fbCreateWindow;
11305b261ecSmrg    pScreen->DestroyWindow = fbDestroyWindow;
11405b261ecSmrg    pScreen->PositionWindow = fbPositionWindow;
11505b261ecSmrg    pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
11605b261ecSmrg    pScreen->RealizeWindow = fbMapWindow;
11705b261ecSmrg    pScreen->UnrealizeWindow = fbUnmapWindow;
11805b261ecSmrg    pScreen->CopyWindow = fbCopyWindow;
11905b261ecSmrg    pScreen->CreatePixmap = fbCreatePixmap;
12005b261ecSmrg    pScreen->DestroyPixmap = fbDestroyPixmap;
12105b261ecSmrg    pScreen->RealizeFont = fbRealizeFont;
12205b261ecSmrg    pScreen->UnrealizeFont = fbUnrealizeFont;
12305b261ecSmrg    pScreen->CreateGC = fbCreateGC;
12405b261ecSmrg    pScreen->CreateColormap = fbInitializeColormap;
12505b261ecSmrg    pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA;
12605b261ecSmrg    pScreen->InstallColormap = fbInstallColormap;
12705b261ecSmrg    pScreen->UninstallColormap = fbUninstallColormap;
12805b261ecSmrg    pScreen->ListInstalledColormaps = fbListInstalledColormaps;
12905b261ecSmrg    pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *))NoopDDA;
13005b261ecSmrg    pScreen->ResolveColor = fbResolveColor;
13105b261ecSmrg    pScreen->BitmapToRegion = fbPixmapToRegion;
13205b261ecSmrg
13305b261ecSmrg    pScreen->GetWindowPixmap = _fbGetWindowPixmap;
13405b261ecSmrg    pScreen->SetWindowPixmap = _fbSetWindowPixmap;
13505b261ecSmrg
13605b261ecSmrg    return TRUE;
13705b261ecSmrg}
13805b261ecSmrg
13905b261ecSmrg#ifdef FB_ACCESS_WRAPPER
14005b261ecSmrgBool
14105b261ecSmrgwfbFinishScreenInit(ScreenPtr		pScreen,
14205b261ecSmrg		    pointer		pbits,
14305b261ecSmrg		    int			xsize,
14405b261ecSmrg		    int			ysize,
14505b261ecSmrg		    int			dpix,
14605b261ecSmrg		    int			dpiy,
14705b261ecSmrg		    int			width,
14805b261ecSmrg		    int			bpp,
14905b261ecSmrg		    SetupWrapProcPtr	setupWrap,
15005b261ecSmrg		    FinishWrapProcPtr	finishWrap)
15105b261ecSmrg#else
15205b261ecSmrgBool
15305b261ecSmrgfbFinishScreenInit(ScreenPtr	pScreen,
15405b261ecSmrg		   pointer	pbits,
15505b261ecSmrg		   int		xsize,
15605b261ecSmrg		   int		ysize,
15705b261ecSmrg		   int		dpix,
15805b261ecSmrg		   int		dpiy,
15905b261ecSmrg		   int		width,
16005b261ecSmrg		   int		bpp)
16105b261ecSmrg#endif
16205b261ecSmrg{
16305b261ecSmrg    VisualPtr	visuals;
16405b261ecSmrg    DepthPtr	depths;
16505b261ecSmrg    int		nvisuals;
16605b261ecSmrg    int		ndepths;
16705b261ecSmrg    int		rootdepth;
16805b261ecSmrg    VisualID	defaultVisual;
16905b261ecSmrg    int		imagebpp = bpp;
17005b261ecSmrg
17105b261ecSmrg#ifdef FB_DEBUG
17205b261ecSmrg    int	stride;
17305b261ecSmrg
17405b261ecSmrg    ysize -= 2;
17505b261ecSmrg    stride = (width * bpp) / 8;
17605b261ecSmrg    fbSetBits ((FbStip *) pbits,
17705b261ecSmrg	       stride / sizeof (FbStip), FB_HEAD_BITS);
17805b261ecSmrg    pbits = (void *) ((char *) pbits + stride);
17905b261ecSmrg    fbSetBits ((FbStip *) ((char *) pbits + stride * ysize),
18005b261ecSmrg			   stride / sizeof (FbStip), FB_TAIL_BITS);
18105b261ecSmrg#endif
18205b261ecSmrg    /*
18305b261ecSmrg     * By default, a 24bpp screen will use 32bpp images, this avoids
18405b261ecSmrg     * problems with many applications which just can't handle packed
18505b261ecSmrg     * pixels.  If you want real 24bit images, include a 24bpp
18605b261ecSmrg     * format in the pixmap formats
18705b261ecSmrg     */
18805b261ecSmrg#ifdef FB_24_32BIT
18905b261ecSmrg    if (bpp == 24)
19005b261ecSmrg    {
19105b261ecSmrg	int	f;
19205b261ecSmrg
19305b261ecSmrg	imagebpp = 32;
19405b261ecSmrg	/*
19505b261ecSmrg	 * Check to see if we're advertising a 24bpp image format,
19605b261ecSmrg	 * in which case windows will use it in preference to a 32 bit
19705b261ecSmrg	 * format.
19805b261ecSmrg	 */
19905b261ecSmrg	for (f = 0; f < screenInfo.numPixmapFormats; f++)
20005b261ecSmrg	{
20105b261ecSmrg	    if (screenInfo.formats[f].bitsPerPixel == 24)
20205b261ecSmrg	    {
20305b261ecSmrg		imagebpp = 24;
20405b261ecSmrg		break;
20505b261ecSmrg	    }
20605b261ecSmrg	}
20705b261ecSmrg    }
20805b261ecSmrg#endif
20905b261ecSmrg#ifdef FB_SCREEN_PRIVATE
21005b261ecSmrg    if (imagebpp == 32)
21105b261ecSmrg    {
21205b261ecSmrg	fbGetScreenPrivate(pScreen)->win32bpp = bpp;
21305b261ecSmrg	fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
21405b261ecSmrg    }
21505b261ecSmrg    else
21605b261ecSmrg    {
21705b261ecSmrg	fbGetScreenPrivate(pScreen)->win32bpp = 32;
21805b261ecSmrg	fbGetScreenPrivate(pScreen)->pix32bpp = 32;
21905b261ecSmrg    }
22005b261ecSmrg#ifdef FB_ACCESS_WRAPPER
22105b261ecSmrg    fbGetScreenPrivate(pScreen)->setupWrap = setupWrap;
22205b261ecSmrg    fbGetScreenPrivate(pScreen)->finishWrap = finishWrap;
22305b261ecSmrg#endif
22405b261ecSmrg#endif
22505b261ecSmrg    rootdepth = 0;
22605b261ecSmrg    if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
22705b261ecSmrg			&defaultVisual,((unsigned long)1<<(imagebpp-1)), 8))
2286747b715Smrg    {
2296747b715Smrg	free(visuals);
2306747b715Smrg	free(depths);
23105b261ecSmrg	return FALSE;
2326747b715Smrg    }
23305b261ecSmrg    if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
23405b261ecSmrg			rootdepth, ndepths, depths,
23505b261ecSmrg			defaultVisual, nvisuals, visuals))
23605b261ecSmrg	return FALSE;
23705b261ecSmrg    /* overwrite miCloseScreen with our own */
23805b261ecSmrg    pScreen->CloseScreen = fbCloseScreen;
23905b261ecSmrg#ifdef FB_24_32BIT
24005b261ecSmrg    if (bpp == 24 && imagebpp == 32)
24105b261ecSmrg    {
24205b261ecSmrg	pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
24305b261ecSmrg	pScreen->CreateScreenResources = fb24_32CreateScreenResources;
24405b261ecSmrg    }
24505b261ecSmrg#endif
24605b261ecSmrg    return TRUE;
24705b261ecSmrg}
24805b261ecSmrg
24905b261ecSmrg/* dts * (inch/dot) * (25.4 mm / inch) = mm */
25005b261ecSmrg#ifdef FB_ACCESS_WRAPPER
25105b261ecSmrgBool
25205b261ecSmrgwfbScreenInit(ScreenPtr		pScreen,
25305b261ecSmrg	      pointer		pbits,
25405b261ecSmrg	      int		xsize,
25505b261ecSmrg	      int		ysize,
25605b261ecSmrg	      int		dpix,
25705b261ecSmrg	      int		dpiy,
25805b261ecSmrg	      int		width,
25905b261ecSmrg	      int		bpp,
26005b261ecSmrg	      SetupWrapProcPtr	setupWrap,
26105b261ecSmrg	      FinishWrapProcPtr	finishWrap)
26205b261ecSmrg{
26305b261ecSmrg    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
26405b261ecSmrg	return FALSE;
26505b261ecSmrg    if (!wfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
26605b261ecSmrg			     width, bpp, setupWrap, finishWrap))
26705b261ecSmrg	return FALSE;
26805b261ecSmrg    return TRUE;
26905b261ecSmrg}
27005b261ecSmrg#else
27105b261ecSmrgBool
27205b261ecSmrgfbScreenInit(ScreenPtr	pScreen,
27305b261ecSmrg	     pointer	pbits,
27405b261ecSmrg	     int	xsize,
27505b261ecSmrg	     int	ysize,
27605b261ecSmrg	     int	dpix,
27705b261ecSmrg	     int	dpiy,
27805b261ecSmrg	     int	width,
27905b261ecSmrg	     int	bpp)
28005b261ecSmrg{
28105b261ecSmrg    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
28205b261ecSmrg	return FALSE;
28305b261ecSmrg    if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
28405b261ecSmrg			    width, bpp))
28505b261ecSmrg	return FALSE;
28605b261ecSmrg    return TRUE;
28705b261ecSmrg}
28805b261ecSmrg#endif
289