miscrinit.c revision f7df2e56
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#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
55typedef 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 */
61Bool
62miModifyPixmapHeader(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
121static Bool
122miCloseScreen(ScreenPtr pScreen)
123{
124    return ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate));
125}
126
127/* With the introduction of pixmap privates, the "screen pixmap" can no
128 * longer be created in miScreenInit, since all the modules that could
129 * possibly ask for pixmap private space have not been initialized at
130 * that time.  pScreen->CreateScreenResources is called after all
131 * possible private-requesting modules have been inited; we create the
132 * screen pixmap here.
133 */
134Bool
135miCreateScreenResources(ScreenPtr pScreen)
136{
137    miScreenInitParmsPtr pScrInitParms;
138    void *value;
139
140    pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
141
142    /* if width is non-zero, pScreen->devPrivate will be a pixmap
143     * else it will just take the value pbits
144     */
145    if (pScrInitParms->width) {
146        PixmapPtr pPixmap;
147
148        /* create a pixmap with no data, then redirect it to point to
149         * the screen
150         */
151        pPixmap =
152            (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
153        if (!pPixmap)
154            return FALSE;
155
156        if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
157                                             pScreen->height,
158                                             pScreen->rootDepth,
159                                             BitsPerPixel(pScreen->rootDepth),
160                                             PixmapBytePad(pScrInitParms->width,
161                                                           pScreen->rootDepth),
162                                             pScrInitParms->pbits))
163            return FALSE;
164        value = (void *) pPixmap;
165    }
166    else {
167        value = pScrInitParms->pbits;
168    }
169    free(pScreen->devPrivate);  /* freeing miScreenInitParmsRec */
170    pScreen->devPrivate = value;        /* pPixmap or pbits */
171    return TRUE;
172}
173
174Bool
175miScreenDevPrivateInit(ScreenPtr pScreen, int width, void *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 = malloc(sizeof(miScreenInitParmsRec));
184    if (!pScrInitParms)
185        return FALSE;
186    pScrInitParms->pbits = pbits;
187    pScrInitParms->width = width;
188    pScreen->devPrivate = (void *) 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 = (void *) pPix;
203}
204
205Bool
206miScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
207             int xsize, int ysize,      /* in pixels */
208             int dpix, int dpiy,        /* dots per inch */
209             int width,         /* pixel width of frame buffer */
210             int rootDepth,     /* depth of root window */
211             int numDepths,     /* number of depths supported */
212             DepthRec * depths, /* supported depths */
213             VisualID rootVisual,       /* root visual */
214             int numVisuals,    /* number of visuals supported */
215             VisualRec * visuals        /* supported visuals */
216    )
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#ifdef MITSHM
240        ShmRegisterFbFuncs(pScreen);
241#endif
242        pScreen->CloseScreen = miCloseScreen;
243    }
244    /* else CloseScreen */
245    /* QueryBestSize, SaveScreen, GetImage, GetSpans */
246    pScreen->SourceValidate = (SourceValidateProcPtr) 0;
247    /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
248    /* RealizeWindow, UnrealizeWindow */
249    pScreen->ValidateTree = miValidateTree;
250    pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
251    pScreen->WindowExposures = miWindowExposures;
252    /* CopyWindow */
253    pScreen->ClearToBackground = miClearToBackground;
254    pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
255    pScreen->RestackWindow = (RestackWindowProcPtr) 0;
256    pScreen->PaintWindow = miPaintWindow;
257    /* CreatePixmap, DestroyPixmap */
258    /* RealizeFont, UnrealizeFont */
259    /* CreateGC */
260    /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
261    /* ListInstalledColormaps, StoreColors, ResolveColor */
262    /* BitmapToRegion */
263    pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
264    pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
265    pScreen->MarkWindow = miMarkWindow;
266    pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
267    pScreen->MoveWindow = miMoveWindow;
268    pScreen->ResizeWindow = miResizeWindow;
269    pScreen->GetLayerWindow = miGetLayerWindow;
270    pScreen->HandleExposures = miHandleValidateExposures;
271    pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
272    pScreen->ChangeBorderWidth = miChangeBorderWidth;
273    pScreen->SetShape = miSetShape;
274    pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
275    pScreen->XYToWindow = miXYToWindow;
276
277    miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
278
279    return miScreenDevPrivateInit(pScreen, width, pbits);
280}
281
282DevPrivateKeyRec miZeroLineScreenKeyRec;
283
284void
285miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
286{
287    if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
288        return;
289
290    dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
291                  (unsigned long *) (unsigned long) bias);
292}
293