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