xref: /OK3568_Linux_fs/external/xserver/mi/miscrinit.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2 
3 Copyright 1990, 1998  The Open Group
4 
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10 
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21 
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
25 from The Open Group.
26 
27 */
28 
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
31 #endif
32 
33 #include <X11/X.h>
34 #include "servermd.h"
35 #include "misc.h"
36 #include "mi.h"
37 #include "scrnintstr.h"
38 #include "pixmapstr.h"
39 #include "dix.h"
40 #include "miline.h"
41 #ifdef MITSHM
42 #include <X11/extensions/shm.h>
43 #include "shmint.h"
44 #endif
45 
46 /* We use this structure to propogate some information from miScreenInit to
47  * miCreateScreenResources.  miScreenInit allocates the structure, fills it
48  * in, and puts it into pScreen->devPrivate.  miCreateScreenResources
49  * extracts the info and frees the structure.  We could've accomplished the
50  * same thing by adding fields to the screen structure, but they would have
51  * ended up being redundant, and would have exposed this mi implementation
52  * detail to the whole server.
53  */
54 
55 /* per-screen private data */
56 static DevPrivateKeyRec miScreenPrivKeyRec;
57 
58 #define miScreenPrivKey (&miScreenPrivKeyRec)
59 
60 typedef struct {
61     CloseScreenProcPtr CloseScreen;
62 } miScreenRec, *miScreenPtr;
63 
64 #define miGetScreenPriv(s) ((miScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miScreenPrivKey)))
65 
66 typedef struct {
67     void *pbits;                /* pointer to framebuffer */
68     int width;                  /* delta to add to a framebuffer addr to move one row down */
69 } miScreenInitParmsRec, *miScreenInitParmsPtr;
70 
71 /* this plugs into pScreen->ModifyPixmapHeader */
72 Bool
miModifyPixmapHeader(PixmapPtr pPixmap,int width,int height,int depth,int bitsPerPixel,int devKind,void * pPixData)73 miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
74                      int bitsPerPixel, int devKind, void *pPixData)
75 {
76     if (!pPixmap)
77         return FALSE;
78 
79     /*
80      * If all arguments are specified, reinitialize everything (including
81      * validated state).
82      */
83     if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
84         (devKind > 0) && pPixData) {
85         pPixmap->drawable.depth = depth;
86         pPixmap->drawable.bitsPerPixel = bitsPerPixel;
87         pPixmap->drawable.id = 0;
88         pPixmap->drawable.x = 0;
89         pPixmap->drawable.y = 0;
90         pPixmap->drawable.width = width;
91         pPixmap->drawable.height = height;
92         pPixmap->devKind = devKind;
93         pPixmap->refcnt = 1;
94         pPixmap->devPrivate.ptr = pPixData;
95     }
96     else {
97         /*
98          * Only modify specified fields, keeping all others intact.
99          */
100 
101         if (width > 0)
102             pPixmap->drawable.width = width;
103 
104         if (height > 0)
105             pPixmap->drawable.height = height;
106 
107         if (depth > 0)
108             pPixmap->drawable.depth = depth;
109 
110         if (bitsPerPixel > 0)
111             pPixmap->drawable.bitsPerPixel = bitsPerPixel;
112         else if ((bitsPerPixel < 0) && (depth > 0))
113             pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
114 
115         /*
116          * CAVEAT:  Non-SI DDXen may use devKind and devPrivate fields for
117          *          other purposes.
118          */
119         if (devKind > 0)
120             pPixmap->devKind = devKind;
121         else if ((devKind < 0) && ((width > 0) || (depth > 0)))
122             pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
123                                              pPixmap->drawable.depth);
124 
125         if (pPixData)
126             pPixmap->devPrivate.ptr = pPixData;
127     }
128     pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
129     return TRUE;
130 }
131 
132 static Bool
miCloseScreen(ScreenPtr pScreen)133 miCloseScreen(ScreenPtr pScreen)
134 {
135     miScreenPtr pScreenPriv = miGetScreenPriv(pScreen);
136 
137     if (pScreen->devPrivate) {
138         ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate));
139         pScreen->devPrivate = NULL;
140     }
141 
142     pScreen->CloseScreen = pScreenPriv->CloseScreen;
143 
144     free(pScreenPriv);
145 
146     if (pScreen->CloseScreen)
147         return (*pScreen->CloseScreen) (pScreen);
148 
149     return TRUE;
150 }
151 
152 void
miSourceValidate(DrawablePtr pDrawable,int x,int y,int w,int h,unsigned int subWindowMode)153 miSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
154                  unsigned int subWindowMode)
155 {
156 }
157 
158 /* With the introduction of pixmap privates, the "screen pixmap" can no
159  * longer be created in miScreenInit, since all the modules that could
160  * possibly ask for pixmap private space have not been initialized at
161  * that time.  pScreen->CreateScreenResources is called after all
162  * possible private-requesting modules have been inited; we create the
163  * screen pixmap here.
164  */
165 Bool
miCreateScreenResources(ScreenPtr pScreen)166 miCreateScreenResources(ScreenPtr pScreen)
167 {
168     miScreenInitParmsPtr pScrInitParms;
169     void *value;
170 
171     pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
172 
173     /* if width is non-zero, pScreen->devPrivate will be a pixmap
174      * else it will just take the value pbits
175      */
176     if (pScrInitParms->width) {
177         PixmapPtr pPixmap;
178 
179         /* create a pixmap with no data, then redirect it to point to
180          * the screen
181          */
182         pPixmap =
183             (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
184         if (!pPixmap)
185             return FALSE;
186 
187         if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
188                                              pScreen->height,
189                                              pScreen->rootDepth,
190                                              BitsPerPixel(pScreen->rootDepth),
191                                              PixmapBytePad(pScrInitParms->width,
192                                                            pScreen->rootDepth),
193                                              pScrInitParms->pbits))
194             return FALSE;
195         value = (void *) pPixmap;
196     }
197     else {
198         value = pScrInitParms->pbits;
199     }
200     free(pScreen->devPrivate);  /* freeing miScreenInitParmsRec */
201     pScreen->devPrivate = value;        /* pPixmap or pbits */
202     return TRUE;
203 }
204 
205 Bool
miScreenDevPrivateInit(ScreenPtr pScreen,int width,void * pbits)206 miScreenDevPrivateInit(ScreenPtr pScreen, int width, void *pbits)
207 {
208     miScreenInitParmsPtr pScrInitParms;
209 
210     /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
211      * to the screen, until CreateScreenResources can put them in the
212      * screen pixmap.
213      */
214     pScrInitParms = malloc(sizeof(miScreenInitParmsRec));
215     if (!pScrInitParms)
216         return FALSE;
217     pScrInitParms->pbits = pbits;
218     pScrInitParms->width = width;
219     pScreen->devPrivate = (void *) pScrInitParms;
220     return TRUE;
221 }
222 
223 static PixmapPtr
miGetScreenPixmap(ScreenPtr pScreen)224 miGetScreenPixmap(ScreenPtr pScreen)
225 {
226     return (PixmapPtr) (pScreen->devPrivate);
227 }
228 
229 static void
miSetScreenPixmap(PixmapPtr pPix)230 miSetScreenPixmap(PixmapPtr pPix)
231 {
232     if (pPix)
233         pPix->drawable.pScreen->devPrivate = (void *) pPix;
234 }
235 
236 Bool
miScreenInit(ScreenPtr pScreen,void * pbits,int xsize,int ysize,int dpix,int dpiy,int width,int rootDepth,int numDepths,DepthRec * depths,VisualID rootVisual,int numVisuals,VisualRec * visuals)237 miScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
238              int xsize, int ysize,      /* in pixels */
239              int dpix, int dpiy,        /* dots per inch */
240              int width,         /* pixel width of frame buffer */
241              int rootDepth,     /* depth of root window */
242              int numDepths,     /* number of depths supported */
243              DepthRec * depths, /* supported depths */
244              VisualID rootVisual,       /* root visual */
245              int numVisuals,    /* number of visuals supported */
246              VisualRec * visuals        /* supported visuals */
247     )
248 {
249     miScreenPtr pScreenPriv;
250 
251     if (!dixRegisterPrivateKey(&miScreenPrivKeyRec, PRIVATE_SCREEN, 0))
252         return FALSE;
253 
254     pScreenPriv = calloc(1, sizeof(miScreenRec));
255     if (!pScreenPriv)
256         return FALSE;
257 
258     dixSetPrivate(&pScreen->devPrivates, miScreenPrivKey, pScreenPriv);
259 
260     pScreen->width = xsize;
261     pScreen->height = ysize;
262     pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
263     pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
264     pScreen->numDepths = numDepths;
265     pScreen->rootDepth = rootDepth;
266     pScreen->allowedDepths = depths;
267     pScreen->rootVisual = rootVisual;
268     /* defColormap */
269     pScreen->minInstalledCmaps = 1;
270     pScreen->maxInstalledCmaps = 1;
271     pScreen->backingStoreSupport = NotUseful;
272     pScreen->saveUnderSupport = NotUseful;
273     /* whitePixel, blackPixel */
274     pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
275     pScreen->CreateScreenResources = miCreateScreenResources;
276     pScreen->GetScreenPixmap = miGetScreenPixmap;
277     pScreen->SetScreenPixmap = miSetScreenPixmap;
278     pScreen->numVisuals = numVisuals;
279     pScreen->visuals = visuals;
280     if (width) {
281 #ifdef MITSHM
282         ShmRegisterFbFuncs(pScreen);
283 #endif
284         pScreenPriv->CloseScreen = pScreen->CloseScreen;
285         pScreen->CloseScreen = miCloseScreen;
286     }
287     /* else CloseScreen */
288     /* QueryBestSize, SaveScreen, GetImage, GetSpans */
289     pScreen->SourceValidate = miSourceValidate;
290     /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
291     /* RealizeWindow, UnrealizeWindow */
292     pScreen->ValidateTree = miValidateTree;
293     pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
294     pScreen->WindowExposures = miWindowExposures;
295     /* CopyWindow */
296     pScreen->ClearToBackground = miClearToBackground;
297     pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
298     pScreen->RestackWindow = (RestackWindowProcPtr) 0;
299     pScreen->PaintWindow = miPaintWindow;
300     /* CreatePixmap, DestroyPixmap */
301     /* RealizeFont, UnrealizeFont */
302     /* CreateGC */
303     /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
304     /* ListInstalledColormaps, StoreColors, ResolveColor */
305     /* BitmapToRegion */
306     pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
307     pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
308     pScreen->MarkWindow = miMarkWindow;
309     pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
310     pScreen->MoveWindow = miMoveWindow;
311     pScreen->ResizeWindow = miResizeWindow;
312     pScreen->GetLayerWindow = miGetLayerWindow;
313     pScreen->HandleExposures = miHandleValidateExposures;
314     pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
315     pScreen->ChangeBorderWidth = miChangeBorderWidth;
316     pScreen->SetShape = miSetShape;
317     pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
318     pScreen->XYToWindow = miXYToWindow;
319 
320     miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
321 
322     return miScreenDevPrivateInit(pScreen, width, pbits);
323 }
324 
325 DevPrivateKeyRec miZeroLineScreenKeyRec;
326 
327 void
miSetZeroLineBias(ScreenPtr pScreen,unsigned int bias)328 miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
329 {
330     if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
331         return;
332 
333     dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
334                   (unsigned long *) (unsigned long) bias);
335 }
336