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