fbscreen.c revision 35c4bbdf
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
3035c4bbdfSmrgfbCloseScreen(ScreenPtr pScreen)
3105b261ecSmrg{
3235c4bbdfSmrg    int d;
3335c4bbdfSmrg    DepthPtr depths = pScreen->allowedDepths;
3405b261ecSmrg
3535c4bbdfSmrg    fbDestroyGlyphCache();
3605b261ecSmrg    for (d = 0; d < pScreen->numDepths; d++)
3735c4bbdfSmrg        free(depths[d].vids);
386747b715Smrg    free(depths);
396747b715Smrg    free(pScreen->visuals);
4035c4bbdfSmrg    if (pScreen->devPrivate)
4135c4bbdfSmrg        FreePixmap((PixmapPtr)pScreen->devPrivate);
4205b261ecSmrg    return TRUE;
4305b261ecSmrg}
4405b261ecSmrg
4505b261ecSmrgBool
4605b261ecSmrgfbRealizeFont(ScreenPtr pScreen, FontPtr pFont)
4705b261ecSmrg{
486747b715Smrg    return TRUE;
4905b261ecSmrg}
5005b261ecSmrg
5105b261ecSmrgBool
5205b261ecSmrgfbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
5305b261ecSmrg{
546747b715Smrg    return TRUE;
5505b261ecSmrg}
5605b261ecSmrg
5705b261ecSmrgvoid
5835c4bbdfSmrgfbQueryBestSize(int class,
5935c4bbdfSmrg                unsigned short *width, unsigned short *height,
6035c4bbdfSmrg                ScreenPtr pScreen)
6105b261ecSmrg{
6235c4bbdfSmrg    unsigned short w;
6335c4bbdfSmrg
6405b261ecSmrg    switch (class) {
6505b261ecSmrg    case CursorShape:
6635c4bbdfSmrg        if (*width > pScreen->width)
6735c4bbdfSmrg            *width = pScreen->width;
6835c4bbdfSmrg        if (*height > pScreen->height)
6935c4bbdfSmrg            *height = pScreen->height;
7035c4bbdfSmrg        break;
7105b261ecSmrg    case TileShape:
7205b261ecSmrg    case StippleShape:
7335c4bbdfSmrg        w = *width;
7435c4bbdfSmrg        if ((w & (w - 1)) && w < FB_UNIT) {
7535c4bbdfSmrg            for (w = 1; w < *width; w <<= 1);
7635c4bbdfSmrg            *width = w;
7735c4bbdfSmrg        }
7805b261ecSmrg    }
7905b261ecSmrg}
8005b261ecSmrg
8105b261ecSmrgPixmapPtr
8235c4bbdfSmrg_fbGetWindowPixmap(WindowPtr pWindow)
8305b261ecSmrg{
8435c4bbdfSmrg    return fbGetWindowPixmap(pWindow);
8505b261ecSmrg}
8605b261ecSmrg
8705b261ecSmrgvoid
8835c4bbdfSmrg_fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap)
8905b261ecSmrg{
9035c4bbdfSmrg    dixSetPrivate(&pWindow->devPrivates, fbGetWinPrivateKey(pWindow), pPixmap);
9105b261ecSmrg}
9205b261ecSmrg
9305b261ecSmrgBool
9435c4bbdfSmrgfbSetupScreen(ScreenPtr pScreen, void *pbits, /* pointer to screen bitmap */
9535c4bbdfSmrg              int xsize,        /* in pixels */
9635c4bbdfSmrg              int ysize, int dpix,      /* dots per inch */
9735c4bbdfSmrg              int dpiy, int width,      /* pixel width of frame buffer */
9835c4bbdfSmrg              int bpp)
9935c4bbdfSmrg{                               /* bits per pixel for screen */
10035c4bbdfSmrg    if (!fbAllocatePrivates(pScreen))
10135c4bbdfSmrg        return FALSE;
10205b261ecSmrg    pScreen->defColormap = FakeClientID(0);
10335c4bbdfSmrg    /* let CreateDefColormap do whatever it wants for pixels */
10405b261ecSmrg    pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
10505b261ecSmrg    pScreen->QueryBestSize = fbQueryBestSize;
10605b261ecSmrg    /* SaveScreen */
10705b261ecSmrg    pScreen->GetImage = fbGetImage;
10805b261ecSmrg    pScreen->GetSpans = fbGetSpans;
10905b261ecSmrg    pScreen->CreateWindow = fbCreateWindow;
11005b261ecSmrg    pScreen->DestroyWindow = fbDestroyWindow;
11105b261ecSmrg    pScreen->PositionWindow = fbPositionWindow;
11205b261ecSmrg    pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
11335c4bbdfSmrg    pScreen->RealizeWindow = fbRealizeWindow;
11435c4bbdfSmrg    pScreen->UnrealizeWindow = fbUnrealizeWindow;
11505b261ecSmrg    pScreen->CopyWindow = fbCopyWindow;
11605b261ecSmrg    pScreen->CreatePixmap = fbCreatePixmap;
11705b261ecSmrg    pScreen->DestroyPixmap = fbDestroyPixmap;
11805b261ecSmrg    pScreen->RealizeFont = fbRealizeFont;
11905b261ecSmrg    pScreen->UnrealizeFont = fbUnrealizeFont;
12005b261ecSmrg    pScreen->CreateGC = fbCreateGC;
12105b261ecSmrg    pScreen->CreateColormap = fbInitializeColormap;
12235c4bbdfSmrg    pScreen->DestroyColormap = (void (*)(ColormapPtr)) NoopDDA;
12305b261ecSmrg    pScreen->InstallColormap = fbInstallColormap;
12405b261ecSmrg    pScreen->UninstallColormap = fbUninstallColormap;
12505b261ecSmrg    pScreen->ListInstalledColormaps = fbListInstalledColormaps;
12635c4bbdfSmrg    pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *)) NoopDDA;
12705b261ecSmrg    pScreen->ResolveColor = fbResolveColor;
12805b261ecSmrg    pScreen->BitmapToRegion = fbPixmapToRegion;
12935c4bbdfSmrg
13005b261ecSmrg    pScreen->GetWindowPixmap = _fbGetWindowPixmap;
13105b261ecSmrg    pScreen->SetWindowPixmap = _fbSetWindowPixmap;
13205b261ecSmrg
13305b261ecSmrg    return TRUE;
13405b261ecSmrg}
13505b261ecSmrg
13605b261ecSmrg#ifdef FB_ACCESS_WRAPPER
13705b261ecSmrgBool
13835c4bbdfSmrgwfbFinishScreenInit(ScreenPtr pScreen,
13935c4bbdfSmrg                    void *pbits,
14035c4bbdfSmrg                    int xsize,
14135c4bbdfSmrg                    int ysize,
14235c4bbdfSmrg                    int dpix,
14335c4bbdfSmrg                    int dpiy,
14435c4bbdfSmrg                    int width,
14535c4bbdfSmrg                    int bpp,
14635c4bbdfSmrg                    SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap)
14705b261ecSmrg#else
14805b261ecSmrgBool
14935c4bbdfSmrgfbFinishScreenInit(ScreenPtr pScreen,
15035c4bbdfSmrg                   void *pbits,
15135c4bbdfSmrg                   int xsize, int ysize, int dpix, int dpiy, int width, int bpp)
15205b261ecSmrg#endif
15305b261ecSmrg{
15435c4bbdfSmrg    VisualPtr visuals;
15535c4bbdfSmrg    DepthPtr depths;
15635c4bbdfSmrg    int nvisuals;
15735c4bbdfSmrg    int ndepths;
15835c4bbdfSmrg    int rootdepth;
15935c4bbdfSmrg    VisualID defaultVisual;
16035c4bbdfSmrg    int imagebpp = bpp;
16105b261ecSmrg
16205b261ecSmrg#ifdef FB_DEBUG
16335c4bbdfSmrg    int stride;
16435c4bbdfSmrg
16505b261ecSmrg    ysize -= 2;
16605b261ecSmrg    stride = (width * bpp) / 8;
16735c4bbdfSmrg    fbSetBits((FbStip *) pbits, stride / sizeof(FbStip), FB_HEAD_BITS);
16805b261ecSmrg    pbits = (void *) ((char *) pbits + stride);
16935c4bbdfSmrg    fbSetBits((FbStip *) ((char *) pbits + stride * ysize),
17035c4bbdfSmrg              stride / sizeof(FbStip), FB_TAIL_BITS);
17105b261ecSmrg#endif
17205b261ecSmrg    /*
17305b261ecSmrg     * By default, a 24bpp screen will use 32bpp images, this avoids
17405b261ecSmrg     * problems with many applications which just can't handle packed
17505b261ecSmrg     * pixels.  If you want real 24bit images, include a 24bpp
17605b261ecSmrg     * format in the pixmap formats
17705b261ecSmrg     */
17835c4bbdfSmrg    if (bpp == 24) {
17935c4bbdfSmrg        int f;
18035c4bbdfSmrg
18135c4bbdfSmrg        imagebpp = 32;
18235c4bbdfSmrg        /*
18335c4bbdfSmrg         * Check to see if we're advertising a 24bpp image format,
18435c4bbdfSmrg         * in which case windows will use it in preference to a 32 bit
18535c4bbdfSmrg         * format.
18635c4bbdfSmrg         */
18735c4bbdfSmrg        for (f = 0; f < screenInfo.numPixmapFormats; f++) {
18835c4bbdfSmrg            if (screenInfo.formats[f].bitsPerPixel == 24) {
18935c4bbdfSmrg                imagebpp = 24;
19035c4bbdfSmrg                break;
19135c4bbdfSmrg            }
19235c4bbdfSmrg        }
19305b261ecSmrg    }
19435c4bbdfSmrg    if (imagebpp == 32) {
19535c4bbdfSmrg        fbGetScreenPrivate(pScreen)->win32bpp = bpp;
19635c4bbdfSmrg        fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
19705b261ecSmrg    }
19835c4bbdfSmrg    else {
19935c4bbdfSmrg        fbGetScreenPrivate(pScreen)->win32bpp = 32;
20035c4bbdfSmrg        fbGetScreenPrivate(pScreen)->pix32bpp = 32;
20105b261ecSmrg    }
20205b261ecSmrg#ifdef FB_ACCESS_WRAPPER
20305b261ecSmrg    fbGetScreenPrivate(pScreen)->setupWrap = setupWrap;
20405b261ecSmrg    fbGetScreenPrivate(pScreen)->finishWrap = finishWrap;
20505b261ecSmrg#endif
20605b261ecSmrg    rootdepth = 0;
20735c4bbdfSmrg    if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
20835c4bbdfSmrg                       &defaultVisual, ((unsigned long) 1 << (imagebpp - 1)),
20935c4bbdfSmrg                       8))
21035c4bbdfSmrg        return FALSE;
21135c4bbdfSmrg    if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
21235c4bbdfSmrg                      rootdepth, ndepths, depths,
21335c4bbdfSmrg                      defaultVisual, nvisuals, visuals))
21435c4bbdfSmrg        return FALSE;
21505b261ecSmrg    /* overwrite miCloseScreen with our own */
21605b261ecSmrg    pScreen->CloseScreen = fbCloseScreen;
21735c4bbdfSmrg    if (bpp == 24 && imagebpp == 32) {
21835c4bbdfSmrg        pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
21935c4bbdfSmrg        pScreen->CreateScreenResources = fb24_32CreateScreenResources;
22005b261ecSmrg    }
22105b261ecSmrg    return TRUE;
22205b261ecSmrg}
22305b261ecSmrg
22405b261ecSmrg/* dts * (inch/dot) * (25.4 mm / inch) = mm */
22505b261ecSmrg#ifdef FB_ACCESS_WRAPPER
22605b261ecSmrgBool
22735c4bbdfSmrgwfbScreenInit(ScreenPtr pScreen,
22835c4bbdfSmrg              void *pbits,
22935c4bbdfSmrg              int xsize,
23035c4bbdfSmrg              int ysize,
23135c4bbdfSmrg              int dpix,
23235c4bbdfSmrg              int dpiy,
23335c4bbdfSmrg              int width,
23435c4bbdfSmrg              int bpp, SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap)
23505b261ecSmrg{
23605b261ecSmrg    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
23735c4bbdfSmrg        return FALSE;
23805b261ecSmrg    if (!wfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
23935c4bbdfSmrg                             width, bpp, setupWrap, finishWrap))
24035c4bbdfSmrg        return FALSE;
24105b261ecSmrg    return TRUE;
24205b261ecSmrg}
24305b261ecSmrg#else
24405b261ecSmrgBool
24535c4bbdfSmrgfbScreenInit(ScreenPtr pScreen,
24635c4bbdfSmrg             void *pbits,
24735c4bbdfSmrg             int xsize, int ysize, int dpix, int dpiy, int width, int bpp)
24805b261ecSmrg{
24905b261ecSmrg    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
25035c4bbdfSmrg        return FALSE;
25135c4bbdfSmrg    if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
25235c4bbdfSmrg                            width, bpp))
25335c4bbdfSmrg        return FALSE;
25405b261ecSmrg    return TRUE;
25505b261ecSmrg}
25605b261ecSmrg#endif
257