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