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