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 typedef struct {
56     void *pbits;                /* pointer to framebuffer */
57     int width;                  /* delta to add to a framebuffer addr to move one row down */
58 } miScreenInitParmsRec, *miScreenInitParmsPtr;
59 
60 /* this plugs into pScreen->ModifyPixmapHeader */
61 Bool
miModifyPixmapHeader(PixmapPtr pPixmap,int width,int height,int depth,int bitsPerPixel,int devKind,void * pPixData)62 miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
63                      int bitsPerPixel, int devKind, void *pPixData)
64 {
65     if (!pPixmap)
66         return FALSE;
67 
68     /*
69      * If all arguments are specified, reinitialize everything (including
70      * validated state).
71      */
72     if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
73         (devKind > 0) && pPixData) {
74         pPixmap->drawable.depth = depth;
75         pPixmap->drawable.bitsPerPixel = bitsPerPixel;
76         pPixmap->drawable.id = 0;
77         pPixmap->drawable.x = 0;
78         pPixmap->drawable.y = 0;
79         pPixmap->drawable.width = width;
80         pPixmap->drawable.height = height;
81         pPixmap->devKind = devKind;
82         pPixmap->refcnt = 1;
83         pPixmap->devPrivate.ptr = pPixData;
84     }
85     else {
86         /*
87          * Only modify specified fields, keeping all others intact.
88          */
89 
90         if (width > 0)
91             pPixmap->drawable.width = width;
92 
93         if (height > 0)
94             pPixmap->drawable.height = height;
95 
96         if (depth > 0)
97             pPixmap->drawable.depth = depth;
98 
99         if (bitsPerPixel > 0)
100             pPixmap->drawable.bitsPerPixel = bitsPerPixel;
101         else if ((bitsPerPixel < 0) && (depth > 0))
102             pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
103 
104         /*
105          * CAVEAT:  Non-SI DDXen may use devKind and devPrivate fields for
106          *          other purposes.
107          */
108         if (devKind > 0)
109             pPixmap->devKind = devKind;
110         else if ((devKind < 0) && ((width > 0) || (depth > 0)))
111             pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
112                                              pPixmap->drawable.depth);
113 
114         if (pPixData)
115             pPixmap->devPrivate.ptr = pPixData;
116     }
117     pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
118     return TRUE;
119 }
120 
121 static Bool
miCloseScreen(ScreenPtr pScreen)122 miCloseScreen(ScreenPtr pScreen)
123 {
124     return ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate));
125 }
126 
127 void
miSourceValidate(DrawablePtr pDrawable,int x,int y,int w,int h,unsigned int subWindowMode)128 miSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
129                  unsigned int subWindowMode)
130 {
131 }
132 
133 /* With the introduction of pixmap privates, the "screen pixmap" can no
134  * longer be created in miScreenInit, since all the modules that could
135  * possibly ask for pixmap private space have not been initialized at
136  * that time.  pScreen->CreateScreenResources is called after all
137  * possible private-requesting modules have been inited; we create the
138  * screen pixmap here.
139  */
140 Bool
miCreateScreenResources(ScreenPtr pScreen)141 miCreateScreenResources(ScreenPtr pScreen)
142 {
143     miScreenInitParmsPtr pScrInitParms;
144     void *value;
145 
146     pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
147 
148     /* if width is non-zero, pScreen->devPrivate will be a pixmap
149      * else it will just take the value pbits
150      */
151     if (pScrInitParms->width) {
152         PixmapPtr pPixmap;
153 
154         /* create a pixmap with no data, then redirect it to point to
155          * the screen
156          */
157         pPixmap =
158             (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
159         if (!pPixmap)
160             return FALSE;
161 
162         if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
163                                              pScreen->height,
164                                              pScreen->rootDepth,
165                                              BitsPerPixel(pScreen->rootDepth),
166                                              PixmapBytePad(pScrInitParms->width,
167                                                            pScreen->rootDepth),
168                                              pScrInitParms->pbits))
169             return FALSE;
170         value = (void *) pPixmap;
171     }
172     else {
173         value = pScrInitParms->pbits;
174     }
175     free(pScreen->devPrivate);  /* freeing miScreenInitParmsRec */
176     pScreen->devPrivate = value;        /* pPixmap or pbits */
177     return TRUE;
178 }
179 
180 Bool
miScreenDevPrivateInit(ScreenPtr pScreen,int width,void * pbits)181 miScreenDevPrivateInit(ScreenPtr pScreen, int width, void *pbits)
182 {
183     miScreenInitParmsPtr pScrInitParms;
184 
185     /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
186      * to the screen, until CreateScreenResources can put them in the
187      * screen pixmap.
188      */
189     pScrInitParms = malloc(sizeof(miScreenInitParmsRec));
190     if (!pScrInitParms)
191         return FALSE;
192     pScrInitParms->pbits = pbits;
193     pScrInitParms->width = width;
194     pScreen->devPrivate = (void *) pScrInitParms;
195     return TRUE;
196 }
197 
198 static PixmapPtr
miGetScreenPixmap(ScreenPtr pScreen)199 miGetScreenPixmap(ScreenPtr pScreen)
200 {
201     return (PixmapPtr) (pScreen->devPrivate);
202 }
203 
204 static void
miSetScreenPixmap(PixmapPtr pPix)205 miSetScreenPixmap(PixmapPtr pPix)
206 {
207     if (pPix)
208         pPix->drawable.pScreen->devPrivate = (void *) pPix;
209 }
210 
211 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)212 miScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
213              int xsize, int ysize,      /* in pixels */
214              int dpix, int dpiy,        /* dots per inch */
215              int width,         /* pixel width of frame buffer */
216              int rootDepth,     /* depth of root window */
217              int numDepths,     /* number of depths supported */
218              DepthRec * depths, /* supported depths */
219              VisualID rootVisual,       /* root visual */
220              int numVisuals,    /* number of visuals supported */
221              VisualRec * visuals        /* supported visuals */
222     )
223 {
224     pScreen->width = xsize;
225     pScreen->height = ysize;
226     pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
227     pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
228     pScreen->numDepths = numDepths;
229     pScreen->rootDepth = rootDepth;
230     pScreen->allowedDepths = depths;
231     pScreen->rootVisual = rootVisual;
232     /* defColormap */
233     pScreen->minInstalledCmaps = 1;
234     pScreen->maxInstalledCmaps = 1;
235     pScreen->backingStoreSupport = NotUseful;
236     pScreen->saveUnderSupport = NotUseful;
237     /* whitePixel, blackPixel */
238     pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
239     pScreen->CreateScreenResources = miCreateScreenResources;
240     pScreen->GetScreenPixmap = miGetScreenPixmap;
241     pScreen->SetScreenPixmap = miSetScreenPixmap;
242     pScreen->numVisuals = numVisuals;
243     pScreen->visuals = visuals;
244     if (width) {
245 #ifdef MITSHM
246         ShmRegisterFbFuncs(pScreen);
247 #endif
248         pScreen->CloseScreen = miCloseScreen;
249     }
250     /* else CloseScreen */
251     /* QueryBestSize, SaveScreen, GetImage, GetSpans */
252     pScreen->SourceValidate = miSourceValidate;
253     /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
254     /* RealizeWindow, UnrealizeWindow */
255     pScreen->ValidateTree = miValidateTree;
256     pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
257     pScreen->WindowExposures = miWindowExposures;
258     /* CopyWindow */
259     pScreen->ClearToBackground = miClearToBackground;
260     pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
261     pScreen->RestackWindow = (RestackWindowProcPtr) 0;
262     pScreen->PaintWindow = miPaintWindow;
263     /* CreatePixmap, DestroyPixmap */
264     /* RealizeFont, UnrealizeFont */
265     /* CreateGC */
266     /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
267     /* ListInstalledColormaps, StoreColors, ResolveColor */
268     /* BitmapToRegion */
269     pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
270     pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
271     pScreen->MarkWindow = miMarkWindow;
272     pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
273     pScreen->MoveWindow = miMoveWindow;
274     pScreen->ResizeWindow = miResizeWindow;
275     pScreen->GetLayerWindow = miGetLayerWindow;
276     pScreen->HandleExposures = miHandleValidateExposures;
277     pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
278     pScreen->ChangeBorderWidth = miChangeBorderWidth;
279     pScreen->SetShape = miSetShape;
280     pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
281     pScreen->XYToWindow = miXYToWindow;
282 
283     miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
284 
285     return miScreenDevPrivateInit(pScreen, width, pbits);
286 }
287 
288 DevPrivateKeyRec miZeroLineScreenKeyRec;
289 
290 void
miSetZeroLineBias(ScreenPtr pScreen,unsigned int bias)291 miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
292 {
293     if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
294         return;
295 
296     dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
297                   (unsigned long *) (unsigned long) bias);
298 }
299