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