fbscreen.c revision 6747b715
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 (int index, ScreenPtr pScreen)
31{
32    int	    d;
33    DepthPtr	depths = pScreen->allowedDepths;
34
35    for (d = 0; d < pScreen->numDepths; d++)
36	free(depths[d].vids);
37    free(depths);
38    free(pScreen->visuals);
39    free(pScreen->devPrivate);
40    return TRUE;
41}
42
43Bool
44fbRealizeFont(ScreenPtr pScreen, FontPtr pFont)
45{
46    return TRUE;
47}
48
49Bool
50fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
51{
52    return TRUE;
53}
54
55void
56fbQueryBestSize (int class,
57		 unsigned short *width, unsigned short *height,
58		 ScreenPtr pScreen)
59{
60    unsigned short  w;
61
62    switch (class) {
63    case CursorShape:
64	if (*width > pScreen->width)
65	    *width = pScreen->width;
66	if (*height > pScreen->height)
67	    *height = pScreen->height;
68	break;
69    case TileShape:
70    case StippleShape:
71	w = *width;
72	if ((w & (w - 1)) && w < FB_UNIT)
73	{
74	    for (w = 1; w < *width; w <<= 1)
75		;
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(), pPixmap);
91}
92
93Bool
94fbSetupScreen(ScreenPtr	pScreen,
95	      pointer	pbits,		/* pointer to screen bitmap */
96	      int	xsize, 		/* in pixels */
97	      int	ysize,
98	      int	dpix,		/* dots per inch */
99	      int	dpiy,
100	      int	width,		/* pixel width of frame buffer */
101	      int	bpp)		/* bits per pixel for screen */
102{
103    if (!fbAllocatePrivates(pScreen, NULL))
104	return FALSE;
105    pScreen->defColormap = FakeClientID(0);
106    /* let CreateDefColormap do whatever it wants for pixels */
107    pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
108    pScreen->QueryBestSize = fbQueryBestSize;
109    /* SaveScreen */
110    pScreen->GetImage = fbGetImage;
111    pScreen->GetSpans = fbGetSpans;
112    pScreen->CreateWindow = fbCreateWindow;
113    pScreen->DestroyWindow = fbDestroyWindow;
114    pScreen->PositionWindow = fbPositionWindow;
115    pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
116    pScreen->RealizeWindow = fbMapWindow;
117    pScreen->UnrealizeWindow = fbUnmapWindow;
118    pScreen->CopyWindow = fbCopyWindow;
119    pScreen->CreatePixmap = fbCreatePixmap;
120    pScreen->DestroyPixmap = fbDestroyPixmap;
121    pScreen->RealizeFont = fbRealizeFont;
122    pScreen->UnrealizeFont = fbUnrealizeFont;
123    pScreen->CreateGC = fbCreateGC;
124    pScreen->CreateColormap = fbInitializeColormap;
125    pScreen->DestroyColormap = (void (*)(ColormapPtr))NoopDDA;
126    pScreen->InstallColormap = fbInstallColormap;
127    pScreen->UninstallColormap = fbUninstallColormap;
128    pScreen->ListInstalledColormaps = fbListInstalledColormaps;
129    pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *))NoopDDA;
130    pScreen->ResolveColor = fbResolveColor;
131    pScreen->BitmapToRegion = fbPixmapToRegion;
132
133    pScreen->GetWindowPixmap = _fbGetWindowPixmap;
134    pScreen->SetWindowPixmap = _fbSetWindowPixmap;
135
136    return TRUE;
137}
138
139#ifdef FB_ACCESS_WRAPPER
140Bool
141wfbFinishScreenInit(ScreenPtr		pScreen,
142		    pointer		pbits,
143		    int			xsize,
144		    int			ysize,
145		    int			dpix,
146		    int			dpiy,
147		    int			width,
148		    int			bpp,
149		    SetupWrapProcPtr	setupWrap,
150		    FinishWrapProcPtr	finishWrap)
151#else
152Bool
153fbFinishScreenInit(ScreenPtr	pScreen,
154		   pointer	pbits,
155		   int		xsize,
156		   int		ysize,
157		   int		dpix,
158		   int		dpiy,
159		   int		width,
160		   int		bpp)
161#endif
162{
163    VisualPtr	visuals;
164    DepthPtr	depths;
165    int		nvisuals;
166    int		ndepths;
167    int		rootdepth;
168    VisualID	defaultVisual;
169    int		imagebpp = bpp;
170
171#ifdef FB_DEBUG
172    int	stride;
173
174    ysize -= 2;
175    stride = (width * bpp) / 8;
176    fbSetBits ((FbStip *) pbits,
177	       stride / sizeof (FbStip), FB_HEAD_BITS);
178    pbits = (void *) ((char *) pbits + stride);
179    fbSetBits ((FbStip *) ((char *) pbits + stride * ysize),
180			   stride / sizeof (FbStip), FB_TAIL_BITS);
181#endif
182    /*
183     * By default, a 24bpp screen will use 32bpp images, this avoids
184     * problems with many applications which just can't handle packed
185     * pixels.  If you want real 24bit images, include a 24bpp
186     * format in the pixmap formats
187     */
188#ifdef FB_24_32BIT
189    if (bpp == 24)
190    {
191	int	f;
192
193	imagebpp = 32;
194	/*
195	 * Check to see if we're advertising a 24bpp image format,
196	 * in which case windows will use it in preference to a 32 bit
197	 * format.
198	 */
199	for (f = 0; f < screenInfo.numPixmapFormats; f++)
200	{
201	    if (screenInfo.formats[f].bitsPerPixel == 24)
202	    {
203		imagebpp = 24;
204		break;
205	    }
206	}
207    }
208#endif
209#ifdef FB_SCREEN_PRIVATE
210    if (imagebpp == 32)
211    {
212	fbGetScreenPrivate(pScreen)->win32bpp = bpp;
213	fbGetScreenPrivate(pScreen)->pix32bpp = bpp;
214    }
215    else
216    {
217	fbGetScreenPrivate(pScreen)->win32bpp = 32;
218	fbGetScreenPrivate(pScreen)->pix32bpp = 32;
219    }
220#ifdef FB_ACCESS_WRAPPER
221    fbGetScreenPrivate(pScreen)->setupWrap = setupWrap;
222    fbGetScreenPrivate(pScreen)->finishWrap = finishWrap;
223#endif
224#endif
225    rootdepth = 0;
226    if (!fbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
227			&defaultVisual,((unsigned long)1<<(imagebpp-1)), 8))
228    {
229	free(visuals);
230	free(depths);
231	return FALSE;
232    }
233    if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
234			rootdepth, ndepths, depths,
235			defaultVisual, nvisuals, visuals))
236	return FALSE;
237    /* overwrite miCloseScreen with our own */
238    pScreen->CloseScreen = fbCloseScreen;
239#ifdef FB_24_32BIT
240    if (bpp == 24 && imagebpp == 32)
241    {
242	pScreen->ModifyPixmapHeader = fb24_32ModifyPixmapHeader;
243	pScreen->CreateScreenResources = fb24_32CreateScreenResources;
244    }
245#endif
246    return TRUE;
247}
248
249/* dts * (inch/dot) * (25.4 mm / inch) = mm */
250#ifdef FB_ACCESS_WRAPPER
251Bool
252wfbScreenInit(ScreenPtr		pScreen,
253	      pointer		pbits,
254	      int		xsize,
255	      int		ysize,
256	      int		dpix,
257	      int		dpiy,
258	      int		width,
259	      int		bpp,
260	      SetupWrapProcPtr	setupWrap,
261	      FinishWrapProcPtr	finishWrap)
262{
263    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
264	return FALSE;
265    if (!wfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
266			     width, bpp, setupWrap, finishWrap))
267	return FALSE;
268    return TRUE;
269}
270#else
271Bool
272fbScreenInit(ScreenPtr	pScreen,
273	     pointer	pbits,
274	     int	xsize,
275	     int	ysize,
276	     int	dpix,
277	     int	dpiy,
278	     int	width,
279	     int	bpp)
280{
281    if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
282	return FALSE;
283    if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
284			    width, bpp))
285	return FALSE;
286    return TRUE;
287}
288#endif
289