miscrinit.c revision 5a112b11
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 propagate 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
127static Bool
128miSaveScreen(ScreenPtr pScreen, int on)
129{
130    return TRUE;
131}
132
133void
134miSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
135                 unsigned int subWindowMode)
136{
137}
138
139
140/* With the introduction of pixmap privates, the "screen pixmap" can no
141 * longer be created in miScreenInit, since all the modules that could
142 * possibly ask for pixmap private space have not been initialized at
143 * that time.  pScreen->CreateScreenResources is called after all
144 * possible private-requesting modules have been inited; we create the
145 * screen pixmap here.
146 */
147Bool
148miCreateScreenResources(ScreenPtr pScreen)
149{
150    miScreenInitParmsPtr pScrInitParms;
151    void *value;
152
153    pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
154
155    /* if width is non-zero, pScreen->devPrivate will be a pixmap
156     * else it will just take the value pbits
157     */
158    if (pScrInitParms->width) {
159        PixmapPtr pPixmap;
160
161        /* create a pixmap with no data, then redirect it to point to
162         * the screen
163         */
164        pPixmap =
165            (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
166        if (!pPixmap)
167            return FALSE;
168
169        if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
170                                             pScreen->height,
171                                             pScreen->rootDepth,
172                                             BitsPerPixel(pScreen->rootDepth),
173                                             PixmapBytePad(pScrInitParms->width,
174                                                           pScreen->rootDepth),
175                                             pScrInitParms->pbits))
176            return FALSE;
177        value = (void *) pPixmap;
178    }
179    else {
180        value = pScrInitParms->pbits;
181    }
182    free(pScreen->devPrivate);  /* freeing miScreenInitParmsRec */
183    pScreen->devPrivate = value;        /* pPixmap or pbits */
184    return TRUE;
185}
186
187Bool
188miScreenDevPrivateInit(ScreenPtr pScreen, int width, void *pbits)
189{
190    miScreenInitParmsPtr pScrInitParms;
191
192    /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
193     * to the screen, until CreateScreenResources can put them in the
194     * screen pixmap.
195     */
196    pScrInitParms = malloc(sizeof(miScreenInitParmsRec));
197    if (!pScrInitParms)
198        return FALSE;
199    pScrInitParms->pbits = pbits;
200    pScrInitParms->width = width;
201    pScreen->devPrivate = (void *) pScrInitParms;
202    return TRUE;
203}
204
205static PixmapPtr
206miGetScreenPixmap(ScreenPtr pScreen)
207{
208    return (PixmapPtr) (pScreen->devPrivate);
209}
210
211static void
212miSetScreenPixmap(PixmapPtr pPix)
213{
214    if (pPix)
215        pPix->drawable.pScreen->devPrivate = (void *) pPix;
216}
217
218Bool
219miScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
220             int xsize, int ysize,      /* in pixels */
221             int dpix, int dpiy,        /* dots per inch */
222             int width,         /* pixel width of frame buffer */
223             int rootDepth,     /* depth of root window */
224             int numDepths,     /* number of depths supported */
225             DepthRec * depths, /* supported depths */
226             VisualID rootVisual,       /* root visual */
227             int numVisuals,    /* number of visuals supported */
228             VisualRec * visuals        /* supported visuals */
229    )
230{
231    pScreen->width = xsize;
232    pScreen->height = ysize;
233    pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
234    pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
235    pScreen->numDepths = numDepths;
236    pScreen->rootDepth = rootDepth;
237    pScreen->allowedDepths = depths;
238    pScreen->rootVisual = rootVisual;
239    /* defColormap */
240    pScreen->minInstalledCmaps = 1;
241    pScreen->maxInstalledCmaps = 1;
242    pScreen->backingStoreSupport = NotUseful;
243    pScreen->saveUnderSupport = NotUseful;
244    /* whitePixel, blackPixel */
245    pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
246    pScreen->CreateScreenResources = miCreateScreenResources;
247    pScreen->GetScreenPixmap = miGetScreenPixmap;
248    pScreen->SetScreenPixmap = miSetScreenPixmap;
249    pScreen->numVisuals = numVisuals;
250    pScreen->visuals = visuals;
251    if (width) {
252#ifdef MITSHM
253        ShmRegisterFbFuncs(pScreen);
254#endif
255        pScreen->CloseScreen = miCloseScreen;
256    }
257    /* else CloseScreen */
258    /* QueryBestSize */
259    pScreen->SaveScreen = miSaveScreen;
260    /* GetImage, GetSpans */
261    pScreen->SourceValidate = miSourceValidate;
262    /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
263    /* RealizeWindow, UnrealizeWindow */
264    pScreen->ValidateTree = miValidateTree;
265    pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
266    pScreen->WindowExposures = miWindowExposures;
267    /* CopyWindow */
268    pScreen->ClearToBackground = miClearToBackground;
269    pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
270    pScreen->RestackWindow = (RestackWindowProcPtr) 0;
271    pScreen->PaintWindow = miPaintWindow;
272    /* CreatePixmap, DestroyPixmap */
273    /* RealizeFont, UnrealizeFont */
274    /* CreateGC */
275    /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
276    /* ListInstalledColormaps, StoreColors, ResolveColor */
277    /* BitmapToRegion */
278    pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
279    pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
280    pScreen->MarkWindow = miMarkWindow;
281    pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
282    pScreen->MoveWindow = miMoveWindow;
283    pScreen->ResizeWindow = miResizeWindow;
284    pScreen->GetLayerWindow = miGetLayerWindow;
285    pScreen->HandleExposures = miHandleValidateExposures;
286    pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
287    pScreen->ChangeBorderWidth = miChangeBorderWidth;
288    pScreen->SetShape = miSetShape;
289    pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
290    pScreen->XYToWindow = miXYToWindow;
291
292    miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
293
294    return miScreenDevPrivateInit(pScreen, width, pbits);
295}
296
297DevPrivateKeyRec miZeroLineScreenKeyRec;
298
299void
300miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
301{
302    if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
303        return;
304
305    dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
306                  (unsigned long *) (unsigned long) bias);
307}
308