xref: /OK3568_Linux_fs/external/xserver/fb/fbscreen.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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