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);
103b2450a3aStsutsui    if (bpp > 1) {
104b2450a3aStsutsui	/* let CreateDefColormap do whatever it wants for pixels */
105b2450a3aStsutsui	pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
106b2450a3aStsutsui    }
10705b261ecSmrg    pScreen->QueryBestSize = fbQueryBestSize;
10805b261ecSmrg    /* SaveScreen */
10905b261ecSmrg    pScreen->GetImage = fbGetImage;
11005b261ecSmrg    pScreen->GetSpans = fbGetSpans;
11105b261ecSmrg    pScreen->CreateWindow = fbCreateWindow;
11205b261ecSmrg    pScreen->DestroyWindow = fbDestroyWindow;
11305b261ecSmrg    pScreen->PositionWindow = fbPositionWindow;
11405b261ecSmrg    pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
11535c4bbdfSmrg    pScreen->RealizeWindow = fbRealizeWindow;
11635c4bbdfSmrg    pScreen->UnrealizeWindow = fbUnrealizeWindow;
11705b261ecSmrg    pScreen->CopyWindow = fbCopyWindow;
11805b261ecSmrg    pScreen->CreatePixmap = fbCreatePixmap;
11905b261ecSmrg    pScreen->DestroyPixmap = fbDestroyPixmap;
12005b261ecSmrg    pScreen->RealizeFont = fbRealizeFont;
12105b261ecSmrg    pScreen->UnrealizeFont = fbUnrealizeFont;
12205b261ecSmrg    pScreen->CreateGC = fbCreateGC;
123b2450a3aStsutsui    if (bpp == 1) {
124b2450a3aStsutsui	pScreen->CreateColormap = mfbCreateColormap;
125b2450a3aStsutsui    } else {
126b2450a3aStsutsui	pScreen->CreateColormap = fbInitializeColormap;
127b2450a3aStsutsui    }
12835c4bbdfSmrg    pScreen->DestroyColormap = (void (*)(ColormapPtr)) NoopDDA;
12905b261ecSmrg    pScreen->InstallColormap = fbInstallColormap;
13005b261ecSmrg    pScreen->UninstallColormap = fbUninstallColormap;
13105b261ecSmrg    pScreen->ListInstalledColormaps = fbListInstalledColormaps;
13235c4bbdfSmrg    pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *)) NoopDDA;
13305b261ecSmrg    pScreen->ResolveColor = fbResolveColor;
13405b261ecSmrg    pScreen->BitmapToRegion = fbPixmapToRegion;
13535c4bbdfSmrg
13605b261ecSmrg    pScreen->GetWindowPixmap = _fbGetWindowPixmap;
13705b261ecSmrg    pScreen->SetWindowPixmap = _fbSetWindowPixmap;
13805b261ecSmrg
13905b261ecSmrg    return TRUE;
14005b261ecSmrg}
14105b261ecSmrg
14205b261ecSmrg#ifdef FB_ACCESS_WRAPPER
14305b261ecSmrgBool
1441b5d61b8SmrgwfbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
1451b5d61b8Smrg                    int dpix, int dpiy, int width, int bpp,
14635c4bbdfSmrg                    SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap)
14705b261ecSmrg#else
14805b261ecSmrgBool
1491b5d61b8SmrgfbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
1501b5d61b8Smrg                   int dpix, int dpiy, int width, int bpp)
15105b261ecSmrg#endif
15205b261ecSmrg{
15335c4bbdfSmrg    VisualPtr visuals;
15435c4bbdfSmrg    DepthPtr depths;
15535c4bbdfSmrg    int nvisuals;
15635c4bbdfSmrg    int ndepths;
15735c4bbdfSmrg    int rootdepth;
15835c4bbdfSmrg    VisualID defaultVisual;
15905b261ecSmrg
16005b261ecSmrg#ifdef FB_DEBUG
16135c4bbdfSmrg    int stride;
16235c4bbdfSmrg
16305b261ecSmrg    ysize -= 2;
16405b261ecSmrg    stride = (width * bpp) / 8;
16535c4bbdfSmrg    fbSetBits((FbStip *) pbits, stride / sizeof(FbStip), FB_HEAD_BITS);
16605b261ecSmrg    pbits = (void *) ((char *) pbits + stride);
16735c4bbdfSmrg    fbSetBits((FbStip *) ((char *) pbits + stride * ysize),
16835c4bbdfSmrg              stride / sizeof(FbStip), FB_TAIL_BITS);
16905b261ecSmrg#endif
1701b5d61b8Smrg    /* fb requires power-of-two bpp */
1711b5d61b8Smrg    if (Ones(bpp) != 1)
1721b5d61b8Smrg        return FALSE;
17305b261ecSmrg#ifdef FB_ACCESS_WRAPPER
17405b261ecSmrg    fbGetScreenPrivate(pScreen)->setupWrap = setupWrap;
17505b261ecSmrg    fbGetScreenPrivate(pScreen)->finishWrap = finishWrap;
17605b261ecSmrg#endif
17705b261ecSmrg    rootdepth = 0;
17835c4bbdfSmrg    if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
1791b5d61b8Smrg                       &defaultVisual, ((unsigned long) 1 << (bpp - 1)),
18035c4bbdfSmrg                       8))
18135c4bbdfSmrg        return FALSE;
18235c4bbdfSmrg    if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
18335c4bbdfSmrg                      rootdepth, ndepths, depths,
18435c4bbdfSmrg                      defaultVisual, nvisuals, visuals))
18535c4bbdfSmrg        return FALSE;
18605b261ecSmrg    /* overwrite miCloseScreen with our own */
18705b261ecSmrg    pScreen->CloseScreen = fbCloseScreen;
18805b261ecSmrg    return TRUE;
18905b261ecSmrg}
19005b261ecSmrg
19105b261ecSmrg/* dts * (inch/dot) * (25.4 mm / inch) = mm */
19205b261ecSmrg#ifdef FB_ACCESS_WRAPPER
19305b261ecSmrgBool
1941b5d61b8SmrgwfbScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
1951b5d61b8Smrg              int dpix, int dpiy, int width, int bpp,
1961b5d61b8Smrg              SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap)
19705b261ecSmrg{
19805b261ecSmrg    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
19935c4bbdfSmrg        return FALSE;
20005b261ecSmrg    if (!wfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
20135c4bbdfSmrg                             width, bpp, setupWrap, finishWrap))
20235c4bbdfSmrg        return FALSE;
20305b261ecSmrg    return TRUE;
20405b261ecSmrg}
20505b261ecSmrg#else
20605b261ecSmrgBool
2071b5d61b8SmrgfbScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
2081b5d61b8Smrg             int dpix, int dpiy, int width, int bpp)
20905b261ecSmrg{
21005b261ecSmrg    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
21135c4bbdfSmrg        return FALSE;
21235c4bbdfSmrg    if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
21335c4bbdfSmrg                            width, bpp))
21435c4bbdfSmrg        return FALSE;
21505b261ecSmrg    return TRUE;
21605b261ecSmrg}
21705b261ecSmrg#endif
218