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