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
29 /* per-screen private data */
30 static DevPrivateKeyRec fbScreenPrivKeyRec;
31
32 #define fbScreenPrivKey (&fbScreenPrivKeyRec)
33
34 typedef struct {
35 CloseScreenProcPtr CloseScreen;
36 } fbScreenRec, *fbScreenPtr;
37
38 #define fbGetScreenPriv(s) ((fbScreenPtr)(dixLookupPrivate(&(s)->devPrivates, fbScreenPrivKey)))
39
40 Bool
fbCloseScreen(ScreenPtr pScreen)41 fbCloseScreen(ScreenPtr pScreen)
42 {
43 int d;
44 DepthPtr depths = pScreen->allowedDepths;
45 fbScreenPtr pScreenPriv = fbGetScreenPriv(pScreen);
46
47 fbDestroyGlyphCache();
48 for (d = 0; d < pScreen->numDepths; d++)
49 free(depths[d].vids);
50 free(depths);
51 free(pScreen->visuals);
52
53 pScreen->CloseScreen = pScreenPriv->CloseScreen;
54 free(pScreenPriv);
55
56 return (*pScreen->CloseScreen) (pScreen);
57 }
58
59 Bool
fbRealizeFont(ScreenPtr pScreen,FontPtr pFont)60 fbRealizeFont(ScreenPtr pScreen, FontPtr pFont)
61 {
62 return TRUE;
63 }
64
65 Bool
fbUnrealizeFont(ScreenPtr pScreen,FontPtr pFont)66 fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
67 {
68 return TRUE;
69 }
70
71 void
fbQueryBestSize(int class,unsigned short * width,unsigned short * height,ScreenPtr pScreen)72 fbQueryBestSize(int class,
73 unsigned short *width, unsigned short *height,
74 ScreenPtr pScreen)
75 {
76 unsigned short w;
77
78 switch (class) {
79 case CursorShape:
80 if (*width > pScreen->width)
81 *width = pScreen->width;
82 if (*height > pScreen->height)
83 *height = pScreen->height;
84 break;
85 case TileShape:
86 case StippleShape:
87 w = *width;
88 if ((w & (w - 1)) && w < FB_UNIT) {
89 for (w = 1; w < *width; w <<= 1);
90 *width = w;
91 }
92 }
93 }
94
95 PixmapPtr
_fbGetWindowPixmap(WindowPtr pWindow)96 _fbGetWindowPixmap(WindowPtr pWindow)
97 {
98 return fbGetWindowPixmap(pWindow);
99 }
100
101 void
_fbSetWindowPixmap(WindowPtr pWindow,PixmapPtr pPixmap)102 _fbSetWindowPixmap(WindowPtr pWindow, PixmapPtr pPixmap)
103 {
104 dixSetPrivate(&pWindow->devPrivates, fbGetWinPrivateKey(pWindow), pPixmap);
105 }
106
107 Bool
fbSetupScreen(ScreenPtr pScreen,void * pbits,int xsize,int ysize,int dpix,int dpiy,int width,int bpp)108 fbSetupScreen(ScreenPtr pScreen, void *pbits, /* pointer to screen bitmap */
109 int xsize, /* in pixels */
110 int ysize, int dpix, /* dots per inch */
111 int dpiy, int width, /* pixel width of frame buffer */
112 int bpp)
113 { /* bits per pixel for screen */
114 fbScreenPtr pScreenPriv;
115
116 if (!fbAllocatePrivates(pScreen))
117 return FALSE;
118
119 if (!dixRegisterPrivateKey(&fbScreenPrivKeyRec, PRIVATE_SCREEN, 0))
120 return FALSE;
121
122 pScreenPriv = calloc(1, sizeof(fbScreenRec));
123 if (!pScreenPriv)
124 return FALSE;
125
126 dixSetPrivate(&pScreen->devPrivates, fbScreenPrivKey, pScreenPriv);
127
128 pScreen->defColormap = FakeClientID(0);
129 /* let CreateDefColormap do whatever it wants for pixels */
130 pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
131 pScreen->QueryBestSize = fbQueryBestSize;
132 /* SaveScreen */
133 pScreen->GetImage = fbGetImage;
134 pScreen->GetSpans = fbGetSpans;
135 pScreen->CreateWindow = fbCreateWindow;
136 pScreen->DestroyWindow = fbDestroyWindow;
137 pScreen->PositionWindow = fbPositionWindow;
138 pScreen->ChangeWindowAttributes = fbChangeWindowAttributes;
139 pScreen->RealizeWindow = fbRealizeWindow;
140 pScreen->UnrealizeWindow = fbUnrealizeWindow;
141 pScreen->CopyWindow = fbCopyWindow;
142 pScreen->CreatePixmap = fbCreatePixmap;
143 pScreen->DestroyPixmap = fbDestroyPixmap;
144 pScreen->RealizeFont = fbRealizeFont;
145 pScreen->UnrealizeFont = fbUnrealizeFont;
146 pScreen->CreateGC = fbCreateGC;
147 pScreen->CreateColormap = fbInitializeColormap;
148 pScreen->DestroyColormap = (void (*)(ColormapPtr)) NoopDDA;
149 pScreen->InstallColormap = fbInstallColormap;
150 pScreen->UninstallColormap = fbUninstallColormap;
151 pScreen->ListInstalledColormaps = fbListInstalledColormaps;
152 pScreen->StoreColors = (void (*)(ColormapPtr, int, xColorItem *)) NoopDDA;
153 pScreen->ResolveColor = fbResolveColor;
154 pScreen->BitmapToRegion = fbPixmapToRegion;
155
156 pScreen->GetWindowPixmap = _fbGetWindowPixmap;
157 pScreen->SetWindowPixmap = _fbSetWindowPixmap;
158
159 return TRUE;
160 }
161
162 #ifdef FB_ACCESS_WRAPPER
163 Bool
wfbFinishScreenInit(ScreenPtr pScreen,void * pbits,int xsize,int ysize,int dpix,int dpiy,int width,int bpp,SetupWrapProcPtr setupWrap,FinishWrapProcPtr finishWrap)164 wfbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
165 int dpix, int dpiy, int width, int bpp,
166 SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap)
167 #else
168 Bool
169 fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
170 int dpix, int dpiy, int width, int bpp)
171 #endif
172 {
173 VisualPtr visuals;
174 DepthPtr depths;
175 int nvisuals;
176 int ndepths;
177 int rootdepth;
178 VisualID defaultVisual;
179 fbScreenPtr pScreenPriv = fbGetScreenPriv(pScreen);
180
181 #ifdef FB_DEBUG
182 int stride;
183
184 ysize -= 2;
185 stride = (width * bpp) / 8;
186 fbSetBits((FbStip *) pbits, stride / sizeof(FbStip), FB_HEAD_BITS);
187 pbits = (void *) ((char *) pbits + stride);
188 fbSetBits((FbStip *) ((char *) pbits + stride * ysize),
189 stride / sizeof(FbStip), FB_TAIL_BITS);
190 #endif
191 /* fb requires power-of-two bpp */
192 if (Ones(bpp) != 1)
193 return FALSE;
194 #ifdef FB_ACCESS_WRAPPER
195 fbGetScreenPrivate(pScreen)->setupWrap = setupWrap;
196 fbGetScreenPrivate(pScreen)->finishWrap = finishWrap;
197 #endif
198 rootdepth = 0;
199 if (!fbInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
200 &defaultVisual, ((unsigned long) 1 << (bpp - 1)),
201 8))
202 return FALSE;
203 if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
204 rootdepth, ndepths, depths,
205 defaultVisual, nvisuals, visuals))
206 return FALSE;
207 /* overwrite miCloseScreen with our own */
208 pScreenPriv->CloseScreen = pScreen->CloseScreen;
209 pScreen->CloseScreen = fbCloseScreen;
210 return TRUE;
211 }
212
213 /* dts * (inch/dot) * (25.4 mm / inch) = mm */
214 #ifdef FB_ACCESS_WRAPPER
215 Bool
wfbScreenInit(ScreenPtr pScreen,void * pbits,int xsize,int ysize,int dpix,int dpiy,int width,int bpp,SetupWrapProcPtr setupWrap,FinishWrapProcPtr finishWrap)216 wfbScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
217 int dpix, int dpiy, int width, int bpp,
218 SetupWrapProcPtr setupWrap, FinishWrapProcPtr finishWrap)
219 {
220 if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
221 return FALSE;
222 if (!wfbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
223 width, bpp, setupWrap, finishWrap))
224 return FALSE;
225 return TRUE;
226 }
227 #else
228 Bool
fbScreenInit(ScreenPtr pScreen,void * pbits,int xsize,int ysize,int dpix,int dpiy,int width,int bpp)229 fbScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
230 int dpix, int dpiy, int width, int bpp)
231 {
232 if (!fbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width, bpp))
233 return FALSE;
234 if (!fbFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy,
235 width, bpp))
236 return FALSE;
237 return TRUE;
238 }
239 #endif
240