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