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