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 propagate 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 static Bool
miSaveScreen(ScreenPtr pScreen,int on)128 miSaveScreen(ScreenPtr pScreen, int on)
129 {
130     return TRUE;
131 }
132 
133 void
miSourceValidate(DrawablePtr pDrawable,int x,int y,int w,int h,unsigned int subWindowMode)134 miSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
135                  unsigned int subWindowMode)
136 {
137 }
138 
139 
140 /* With the introduction of pixmap privates, the "screen pixmap" can no
141  * longer be created in miScreenInit, since all the modules that could
142  * possibly ask for pixmap private space have not been initialized at
143  * that time.  pScreen->CreateScreenResources is called after all
144  * possible private-requesting modules have been inited; we create the
145  * screen pixmap here.
146  */
147 Bool
miCreateScreenResources(ScreenPtr pScreen)148 miCreateScreenResources(ScreenPtr pScreen)
149 {
150     miScreenInitParmsPtr pScrInitParms;
151     void *value;
152 
153     pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
154 
155     /* if width is non-zero, pScreen->devPrivate will be a pixmap
156      * else it will just take the value pbits
157      */
158     if (pScrInitParms->width) {
159         PixmapPtr pPixmap;
160 
161         /* create a pixmap with no data, then redirect it to point to
162          * the screen
163          */
164         pPixmap =
165             (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
166         if (!pPixmap)
167             return FALSE;
168 
169         if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
170                                              pScreen->height,
171                                              pScreen->rootDepth,
172                                              BitsPerPixel(pScreen->rootDepth),
173                                              PixmapBytePad(pScrInitParms->width,
174                                                            pScreen->rootDepth),
175                                              pScrInitParms->pbits))
176             return FALSE;
177         value = (void *) pPixmap;
178     }
179     else {
180         value = pScrInitParms->pbits;
181     }
182     free(pScreen->devPrivate);  /* freeing miScreenInitParmsRec */
183     pScreen->devPrivate = value;        /* pPixmap or pbits */
184     return TRUE;
185 }
186 
187 Bool
miScreenDevPrivateInit(ScreenPtr pScreen,int width,void * pbits)188 miScreenDevPrivateInit(ScreenPtr pScreen, int width, void *pbits)
189 {
190     miScreenInitParmsPtr pScrInitParms;
191 
192     /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
193      * to the screen, until CreateScreenResources can put them in the
194      * screen pixmap.
195      */
196     pScrInitParms = malloc(sizeof(miScreenInitParmsRec));
197     if (!pScrInitParms)
198         return FALSE;
199     pScrInitParms->pbits = pbits;
200     pScrInitParms->width = width;
201     pScreen->devPrivate = (void *) pScrInitParms;
202     return TRUE;
203 }
204 
205 static PixmapPtr
miGetScreenPixmap(ScreenPtr pScreen)206 miGetScreenPixmap(ScreenPtr pScreen)
207 {
208     return (PixmapPtr) (pScreen->devPrivate);
209 }
210 
211 static void
miSetScreenPixmap(PixmapPtr pPix)212 miSetScreenPixmap(PixmapPtr pPix)
213 {
214     if (pPix)
215         pPix->drawable.pScreen->devPrivate = (void *) pPix;
216 }
217 
218 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)219 miScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
220              int xsize, int ysize,      /* in pixels */
221              int dpix, int dpiy,        /* dots per inch */
222              int width,         /* pixel width of frame buffer */
223              int rootDepth,     /* depth of root window */
224              int numDepths,     /* number of depths supported */
225              DepthRec * depths, /* supported depths */
226              VisualID rootVisual,       /* root visual */
227              int numVisuals,    /* number of visuals supported */
228              VisualRec * visuals        /* supported visuals */
229     )
230 {
231     pScreen->width = xsize;
232     pScreen->height = ysize;
233     pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
234     pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
235     pScreen->numDepths = numDepths;
236     pScreen->rootDepth = rootDepth;
237     pScreen->allowedDepths = depths;
238     pScreen->rootVisual = rootVisual;
239     /* defColormap */
240     pScreen->minInstalledCmaps = 1;
241     pScreen->maxInstalledCmaps = 1;
242     pScreen->backingStoreSupport = NotUseful;
243     pScreen->saveUnderSupport = NotUseful;
244     /* whitePixel, blackPixel */
245     pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
246     pScreen->CreateScreenResources = miCreateScreenResources;
247     pScreen->GetScreenPixmap = miGetScreenPixmap;
248     pScreen->SetScreenPixmap = miSetScreenPixmap;
249     pScreen->numVisuals = numVisuals;
250     pScreen->visuals = visuals;
251     if (width) {
252 #ifdef MITSHM
253         ShmRegisterFbFuncs(pScreen);
254 #endif
255         pScreen->CloseScreen = miCloseScreen;
256     }
257     /* else CloseScreen */
258     /* QueryBestSize */
259     pScreen->SaveScreen = miSaveScreen;
260     /* GetImage, GetSpans */
261     pScreen->SourceValidate = miSourceValidate;
262     /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
263     /* RealizeWindow, UnrealizeWindow */
264     pScreen->ValidateTree = miValidateTree;
265     pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
266     pScreen->WindowExposures = miWindowExposures;
267     /* CopyWindow */
268     pScreen->ClearToBackground = miClearToBackground;
269     pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
270     pScreen->RestackWindow = (RestackWindowProcPtr) 0;
271     pScreen->PaintWindow = miPaintWindow;
272     /* CreatePixmap, DestroyPixmap */
273     /* RealizeFont, UnrealizeFont */
274     /* CreateGC */
275     /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
276     /* ListInstalledColormaps, StoreColors, ResolveColor */
277     /* BitmapToRegion */
278     pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
279     pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
280     pScreen->MarkWindow = miMarkWindow;
281     pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
282     pScreen->MoveWindow = miMoveWindow;
283     pScreen->ResizeWindow = miResizeWindow;
284     pScreen->GetLayerWindow = miGetLayerWindow;
285     pScreen->HandleExposures = miHandleValidateExposures;
286     pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
287     pScreen->ChangeBorderWidth = miChangeBorderWidth;
288     pScreen->SetShape = miSetShape;
289     pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
290     pScreen->XYToWindow = miXYToWindow;
291 
292     miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
293 
294     return miScreenDevPrivateInit(pScreen, width, pbits);
295 }
296 
297 DevPrivateKeyRec miZeroLineScreenKeyRec;
298 
299 void
miSetZeroLineBias(ScreenPtr pScreen,unsigned int bias)300 miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
301 {
302     if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
303         return;
304 
305     dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
306                   (unsigned long *) (unsigned long) bias);
307 }
308