fbscreen.c revision 35c4bbdf
1/*
2 * Copyright © 1998 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Keith Packard makes no
11 * representations about the suitability of this software for any purpose.  It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_DIX_CONFIG_H
24#include <dix-config.h>
25#endif
26
27#include "fb.h"
28
29Bool
30fbCloseScreen(ScreenPtr pScreen)
31{
32    int d;
33    DepthPtr depths = pScreen->allowedDepths;
34
35    fbDestroyGlyphCache();
36    for (d = 0; d < pScreen->numDepths; d++)
37        free(depths[d].vids);
38    free(depths);
39    free(pScreen->visuals);
40    if (pScreen->devPrivate)
41        FreePixmap((PixmapPtr)pScreen->devPrivate);
42    return TRUE;
43}
44
45Bool
46fbRealizeFont(ScreenPtr pScreen, FontPtr pFont)
47{
48    return TRUE;
49}
50
51Bool
52fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
53{
54    return TRUE;
55}
56
57void
58fbQueryBestSize(int class,
59                unsigned short *width, unsigned short *height,
60                ScreenPtr pScreen)
61{
62    unsigned short w;
63
64    switch (class) {
65    case CursorShape:
66        if (*width > pScreen->width)
67            *width = pScreen->width;
68        if (*height > pScreen->height)
69            *height = pScreen->height;
70        break;
71    case TileShape:
72    case StippleShape:
73        w = *width;
74        if ((w & (w - 1)) && w < FB_UNIT) {
75            for (w = 1; w < *width; w <<= 1);
76            *width = w;
77        }
78    }
79}
80
81PixmapPtr
82_fbGetWindowPixmap(WindowPtr pWindow)
83{
84    return fbGetWindowPixmap(pWindow);
85}
86
87void
88_fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap)
89{
90    dixSetPrivate(&pWindow->devPrivates, fbGetWinPrivateKey(pWindow), pPixmap);
91}
92
93Bool
94fbSetupScreen(ScreenPtr pScreen, void *pbits, /* pointer to screen bitmap */
95              int xsize,        /* in pixels */
96              int ysize, int dpix,      /* dots per inch */
97              int dpiy, int width,      /* pixel width of frame buffer */
98              int bpp)
99{                               /* bits per pixel for screen */
100    if (!fbAllocatePrivates(pScreen))
101        return FALSE;
102    pScreen->defColormap = FakeClientID(0);
103    /* let CreateDefColormap do whatever it wants for pixels */
104    pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
105    pScreen->QueryBestSize = fbQueryBestSize;
106    /* SaveScreen */
107    pScreen->GetImage = fbGetImage;
108    pScreen->GetSpans = fbGetSpans;
109    pScreen->CreateWindow = fbCreateWindow;
110    pScreen->DestroyWindow = fbDestroyWindow;
111    pScreen->PositionWindow = fbPositionWindow;
112    pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
113    pScreen->RealizeWindow = fbRealizeWindow;
114    pScreen->UnrealizeWindow = fbUnrealizeWindow;
115    pScreen->CopyWindow = fbCopyWindow;
116    pScreen->CreatePixmap = fbCreatePixmap;
117    pScreen->DestroyPixmap = fbDestroyPixmap;
118    pScreen->RealizeFont = fbRealizeFont;
119    pScreen->UnrealizeFont = fbUnrealizeFont;
120    pScreen->CreateGC = fbCreateGC;
121    pScreen->CreateColormap = fbInitializeColormap;
122    pScreen->DestroyColormap = (void (*)(ColormapPtr)) NoopDDA;
123    pScreen->InstallColormap = fbInstallColormap;
124    pScreen->UninstallColormap = fbUninstallColormap;
125    pScreen->ListInstalledColormaps = fbListInstalledColormaps;
126    pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *)) NoopDDA;
127    pScreen->ResolveColor = fbResolveColor;
128    pScreen->BitmapToRegion = fbPixmapToRegion;
129
130    pScreen->GetWindowPixmap = _fbGetWindowPixmap;
131    pScreen->SetWindowPixmap = _fbSetWindowPixmap;
132
133    return TRUE;
134}
135
136#ifdef FB_ACCESS_WRAPPER
137Bool
138wfbFinishScreenInit(ScreenPtr pScreen,
139                    void *pbits,
140                    int xsize,
141                    int ysize,
142                    int dpix,
143                    int dpiy,
144                    int width,
145                    int bpp,
146                    SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap)
147#else
148Bool
149fbFinishScreenInit(ScreenPtr pScreen,
150                   void *pbits,
151                   int xsize, int ysize, int dpix, int dpiy, int width, int bpp)
152#endif
153{
154    VisualPtr visuals;
155    DepthPtr depths;
156    int nvisuals;
157    int ndepths;
158    int rootdepth;
159    VisualID defaultVisual;
160    int imagebpp = bpp;
161
162#ifdef FB_DEBUG
163    int stride;
164
165    ysize -= 2;
166    stride = (width * bpp) / 8;
167    fbSetBits((FbStip *) pbits, stride / sizeof(FbStip), FB_HEAD_BITS);
168    pbits = (void *) ((char *) pbits + stride);
169    fbSetBits((FbStip *) ((char *) pbits + stride * ysize),
170              stride / sizeof(FbStip), FB_TAIL_BITS);
171#endif
172    /*
173     * By default, a 24bpp screen will use 32bpp images, this avoids
174     * problems with many applications which just can't handle packed
175     * pixels.  If you want real 24bit images, include a 24bpp
176     * format in the pixmap formats
177     */
178    if (bpp == 24) {
179        int f;
180
181        imagebpp = 32;
182        /*
183         * Check to see if we're advertising a 24bpp image format,
184         * in which case windows will use it in preference to a 32 bit
185         * format.
186         */
187        for (f = 0; f < screenInfo.numPixmapFormats; f++) {
188            if (screenInfo.formats[f].bitsPerPixel == 24) {
189                imagebpp = 24;
190                break;
191            }
192        }
193    }
194    if (imagebpp == 32) {
195        fbGetScreenPrivate(pScreen)->win32bpp = bpp;
196        fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
197    }
198    else {
199        fbGetScreenPrivate(pScreen)->win32bpp = 32;
200        fbGetScreenPrivate(pScreen)->pix32bpp = 32;
201    }
202#ifdef FB_ACCESS_WRAPPER
203    fbGetScreenPrivate(pScreen)->setupWrap = setupWrap;
204    fbGetScreenPrivate(pScreen)->finishWrap = finishWrap;
205#endif
206    rootdepth = 0;
207    if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
208                       &defaultVisual, ((unsigned long) 1 << (imagebpp - 1)),
209                       8))
210        return FALSE;
211    if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
212                      rootdepth, ndepths, depths,
213                      defaultVisual, nvisuals, visuals))
214        return FALSE;
215    /* overwrite miCloseScreen with our own */
216    pScreen->CloseScreen = fbCloseScreen;
217    if (bpp == 24 && imagebpp == 32) {
218        pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
219        pScreen->CreateScreenResources = fb24_32CreateScreenResources;
220    }
221    return TRUE;
222}
223
224/* dts * (inch/dot) * (25.4 mm / inch) = mm */
225#ifdef FB_ACCESS_WRAPPER
226Bool
227wfbScreenInit(ScreenPtr pScreen,
228              void *pbits,
229              int xsize,
230              int ysize,
231              int dpix,
232              int dpiy,
233              int width,
234              int bpp, SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap)
235{
236    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
237        return FALSE;
238    if (!wfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
239                             width, bpp, setupWrap, finishWrap))
240        return FALSE;
241    return TRUE;
242}
243#else
244Bool
245fbScreenInit(ScreenPtr pScreen,
246             void *pbits,
247             int xsize, int ysize, int dpix, int dpiy, int width, int bpp)
248{
249    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
250        return FALSE;
251    if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
252                            width, bpp))
253        return FALSE;
254    return TRUE;
255}
256#endif
257