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