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