105b261ecSmrg/*
205b261ecSmrg
305b261ecSmrgCopyright 1990, 1998  The Open Group
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included
1205b261ecSmrgin all copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1505b261ecSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1605b261ecSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1705b261ecSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
1805b261ecSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1905b261ecSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2005b261ecSmrgOTHER DEALINGS IN THE SOFTWARE.
2105b261ecSmrg
2205b261ecSmrgExcept as contained in this notice, the name of The Open Group shall
2305b261ecSmrgnot be used in advertising or otherwise to promote the sale, use or
2405b261ecSmrgother dealings in this Software without prior written authorization
2505b261ecSmrgfrom The Open Group.
2605b261ecSmrg
2705b261ecSmrg*/
2805b261ecSmrg
2905b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3005b261ecSmrg#include <dix-config.h>
3105b261ecSmrg#endif
3205b261ecSmrg
3305b261ecSmrg#include <X11/X.h>
3405b261ecSmrg#include "servermd.h"
3505b261ecSmrg#include "misc.h"
3605b261ecSmrg#include "mi.h"
3705b261ecSmrg#include "scrnintstr.h"
3805b261ecSmrg#include "pixmapstr.h"
3905b261ecSmrg#include "dix.h"
4005b261ecSmrg#include "miline.h"
4105b261ecSmrg#ifdef MITSHM
424202a189Smrg#include <X11/extensions/shm.h>
434202a189Smrg#include "shmint.h"
4405b261ecSmrg#endif
4505b261ecSmrg
465a112b11Smrg/* We use this structure to propagate some information from miScreenInit to
4705b261ecSmrg * miCreateScreenResources.  miScreenInit allocates the structure, fills it
48f7df2e56Smrg * in, and puts it into pScreen->devPrivate.  miCreateScreenResources
4905b261ecSmrg * extracts the info and frees the structure.  We could've accomplished the
5005b261ecSmrg * same thing by adding fields to the screen structure, but they would have
5105b261ecSmrg * ended up being redundant, and would have exposed this mi implementation
5205b261ecSmrg * detail to the whole server.
5305b261ecSmrg */
5405b261ecSmrg
55f7df2e56Smrgtypedef struct {
56f7df2e56Smrg    void *pbits;                /* pointer to framebuffer */
57f7df2e56Smrg    int width;                  /* delta to add to a framebuffer addr to move one row down */
5805b261ecSmrg} miScreenInitParmsRec, *miScreenInitParmsPtr;
5905b261ecSmrg
6005b261ecSmrg/* this plugs into pScreen->ModifyPixmapHeader */
614202a189SmrgBool
624642e01fSmrgmiModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
63f7df2e56Smrg                     int bitsPerPixel, int devKind, void *pPixData)
6405b261ecSmrg{
6505b261ecSmrg    if (!pPixmap)
66f7df2e56Smrg        return FALSE;
6705b261ecSmrg
6805b261ecSmrg    /*
6905b261ecSmrg     * If all arguments are specified, reinitialize everything (including
7005b261ecSmrg     * validated state).
7105b261ecSmrg     */
7205b261ecSmrg    if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
73f7df2e56Smrg        (devKind > 0) && pPixData) {
74f7df2e56Smrg        pPixmap->drawable.depth = depth;
75f7df2e56Smrg        pPixmap->drawable.bitsPerPixel = bitsPerPixel;
76f7df2e56Smrg        pPixmap->drawable.id = 0;
77f7df2e56Smrg        pPixmap->drawable.x = 0;
78f7df2e56Smrg        pPixmap->drawable.y = 0;
79f7df2e56Smrg        pPixmap->drawable.width = width;
80f7df2e56Smrg        pPixmap->drawable.height = height;
81f7df2e56Smrg        pPixmap->devKind = devKind;
82f7df2e56Smrg        pPixmap->refcnt = 1;
83f7df2e56Smrg        pPixmap->devPrivate.ptr = pPixData;
84f7df2e56Smrg    }
85f7df2e56Smrg    else {
86f7df2e56Smrg        /*
87f7df2e56Smrg         * Only modify specified fields, keeping all others intact.
88f7df2e56Smrg         */
89f7df2e56Smrg
90f7df2e56Smrg        if (width > 0)
91f7df2e56Smrg            pPixmap->drawable.width = width;
92f7df2e56Smrg
93f7df2e56Smrg        if (height > 0)
94f7df2e56Smrg            pPixmap->drawable.height = height;
95f7df2e56Smrg
96f7df2e56Smrg        if (depth > 0)
97f7df2e56Smrg            pPixmap->drawable.depth = depth;
98f7df2e56Smrg
99f7df2e56Smrg        if (bitsPerPixel > 0)
100f7df2e56Smrg            pPixmap->drawable.bitsPerPixel = bitsPerPixel;
101f7df2e56Smrg        else if ((bitsPerPixel < 0) && (depth > 0))
102f7df2e56Smrg            pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
103f7df2e56Smrg
104f7df2e56Smrg        /*
105f7df2e56Smrg         * CAVEAT:  Non-SI DDXen may use devKind and devPrivate fields for
106f7df2e56Smrg         *          other purposes.
107f7df2e56Smrg         */
108f7df2e56Smrg        if (devKind > 0)
109f7df2e56Smrg            pPixmap->devKind = devKind;
110f7df2e56Smrg        else if ((devKind < 0) && ((width > 0) || (depth > 0)))
111f7df2e56Smrg            pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
112f7df2e56Smrg                                             pPixmap->drawable.depth);
113f7df2e56Smrg
114f7df2e56Smrg        if (pPixData)
115f7df2e56Smrg            pPixmap->devPrivate.ptr = pPixData;
11605b261ecSmrg    }
1174202a189Smrg    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
11805b261ecSmrg    return TRUE;
11905b261ecSmrg}
12005b261ecSmrg
12105b261ecSmrgstatic Bool
122f7df2e56SmrgmiCloseScreen(ScreenPtr pScreen)
12305b261ecSmrg{
124f7df2e56Smrg    return ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate));
12505b261ecSmrg}
12605b261ecSmrg
1275a112b11Smrgstatic Bool
1285a112b11SmrgmiSaveScreen(ScreenPtr pScreen, int on)
1295a112b11Smrg{
1305a112b11Smrg    return TRUE;
1315a112b11Smrg}
1325a112b11Smrg
1334e185dc0Smrgvoid
1344e185dc0SmrgmiSourceValidate(DrawablePtr pDrawable, int x, int y, int w, int h,
1354e185dc0Smrg                 unsigned int subWindowMode)
1364e185dc0Smrg{
1374e185dc0Smrg}
1384e185dc0Smrg
1395a112b11Smrg
14005b261ecSmrg/* With the introduction of pixmap privates, the "screen pixmap" can no
14105b261ecSmrg * longer be created in miScreenInit, since all the modules that could
14205b261ecSmrg * possibly ask for pixmap private space have not been initialized at
14305b261ecSmrg * that time.  pScreen->CreateScreenResources is called after all
14405b261ecSmrg * possible private-requesting modules have been inited; we create the
14505b261ecSmrg * screen pixmap here.
14605b261ecSmrg */
1474202a189SmrgBool
1484642e01fSmrgmiCreateScreenResources(ScreenPtr pScreen)
14905b261ecSmrg{
15005b261ecSmrg    miScreenInitParmsPtr pScrInitParms;
151f7df2e56Smrg    void *value;
15205b261ecSmrg
153f7df2e56Smrg    pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
15405b261ecSmrg
15505b261ecSmrg    /* if width is non-zero, pScreen->devPrivate will be a pixmap
15605b261ecSmrg     * else it will just take the value pbits
15705b261ecSmrg     */
158f7df2e56Smrg    if (pScrInitParms->width) {
159f7df2e56Smrg        PixmapPtr pPixmap;
160f7df2e56Smrg
161f7df2e56Smrg        /* create a pixmap with no data, then redirect it to point to
162f7df2e56Smrg         * the screen
163f7df2e56Smrg         */
164f7df2e56Smrg        pPixmap =
165f7df2e56Smrg            (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0);
166f7df2e56Smrg        if (!pPixmap)
167f7df2e56Smrg            return FALSE;
168f7df2e56Smrg
169f7df2e56Smrg        if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width,
170f7df2e56Smrg                                             pScreen->height,
171f7df2e56Smrg                                             pScreen->rootDepth,
172f7df2e56Smrg                                             BitsPerPixel(pScreen->rootDepth),
173f7df2e56Smrg                                             PixmapBytePad(pScrInitParms->width,
174f7df2e56Smrg                                                           pScreen->rootDepth),
175f7df2e56Smrg                                             pScrInitParms->pbits))
176f7df2e56Smrg            return FALSE;
177f7df2e56Smrg        value = (void *) pPixmap;
17805b261ecSmrg    }
179f7df2e56Smrg    else {
180f7df2e56Smrg        value = pScrInitParms->pbits;
18105b261ecSmrg    }
182f7df2e56Smrg    free(pScreen->devPrivate);  /* freeing miScreenInitParmsRec */
183f7df2e56Smrg    pScreen->devPrivate = value;        /* pPixmap or pbits */
18405b261ecSmrg    return TRUE;
18505b261ecSmrg}
18605b261ecSmrg
18705b261ecSmrgBool
188f7df2e56SmrgmiScreenDevPrivateInit(ScreenPtr pScreen, int width, void *pbits)
18905b261ecSmrg{
19005b261ecSmrg    miScreenInitParmsPtr pScrInitParms;
19105b261ecSmrg
19205b261ecSmrg    /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
19305b261ecSmrg     * to the screen, until CreateScreenResources can put them in the
19405b261ecSmrg     * screen pixmap.
19505b261ecSmrg     */
1964202a189Smrg    pScrInitParms = malloc(sizeof(miScreenInitParmsRec));
19705b261ecSmrg    if (!pScrInitParms)
198f7df2e56Smrg        return FALSE;
19905b261ecSmrg    pScrInitParms->pbits = pbits;
20005b261ecSmrg    pScrInitParms->width = width;
201f7df2e56Smrg    pScreen->devPrivate = (void *) pScrInitParms;
20205b261ecSmrg    return TRUE;
20305b261ecSmrg}
20405b261ecSmrg
2054642e01fSmrgstatic PixmapPtr
2064642e01fSmrgmiGetScreenPixmap(ScreenPtr pScreen)
2074642e01fSmrg{
208f7df2e56Smrg    return (PixmapPtr) (pScreen->devPrivate);
2094642e01fSmrg}
2104642e01fSmrg
2114642e01fSmrgstatic void
2124642e01fSmrgmiSetScreenPixmap(PixmapPtr pPix)
2134642e01fSmrg{
2144642e01fSmrg    if (pPix)
215f7df2e56Smrg        pPix->drawable.pScreen->devPrivate = (void *) pPix;
2164642e01fSmrg}
2174642e01fSmrg
2184202a189SmrgBool
219f7df2e56SmrgmiScreenInit(ScreenPtr pScreen, void *pbits,  /* pointer to screen bits */
220f7df2e56Smrg             int xsize, int ysize,      /* in pixels */
221f7df2e56Smrg             int dpix, int dpiy,        /* dots per inch */
222f7df2e56Smrg             int width,         /* pixel width of frame buffer */
223f7df2e56Smrg             int rootDepth,     /* depth of root window */
224f7df2e56Smrg             int numDepths,     /* number of depths supported */
225f7df2e56Smrg             DepthRec * depths, /* supported depths */
226f7df2e56Smrg             VisualID rootVisual,       /* root visual */
227f7df2e56Smrg             int numVisuals,    /* number of visuals supported */
228f7df2e56Smrg             VisualRec * visuals        /* supported visuals */
2294642e01fSmrg    )
23005b261ecSmrg{
23105b261ecSmrg    pScreen->width = xsize;
23205b261ecSmrg    pScreen->height = ysize;
23305b261ecSmrg    pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
23405b261ecSmrg    pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
23505b261ecSmrg    pScreen->numDepths = numDepths;
23605b261ecSmrg    pScreen->rootDepth = rootDepth;
23705b261ecSmrg    pScreen->allowedDepths = depths;
23805b261ecSmrg    pScreen->rootVisual = rootVisual;
23905b261ecSmrg    /* defColormap */
24005b261ecSmrg    pScreen->minInstalledCmaps = 1;
24105b261ecSmrg    pScreen->maxInstalledCmaps = 1;
24205b261ecSmrg    pScreen->backingStoreSupport = NotUseful;
24305b261ecSmrg    pScreen->saveUnderSupport = NotUseful;
24405b261ecSmrg    /* whitePixel, blackPixel */
24505b261ecSmrg    pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
24605b261ecSmrg    pScreen->CreateScreenResources = miCreateScreenResources;
24705b261ecSmrg    pScreen->GetScreenPixmap = miGetScreenPixmap;
24805b261ecSmrg    pScreen->SetScreenPixmap = miSetScreenPixmap;
24905b261ecSmrg    pScreen->numVisuals = numVisuals;
25005b261ecSmrg    pScreen->visuals = visuals;
251f7df2e56Smrg    if (width) {
25205b261ecSmrg#ifdef MITSHM
253f7df2e56Smrg        ShmRegisterFbFuncs(pScreen);
25405b261ecSmrg#endif
255f7df2e56Smrg        pScreen->CloseScreen = miCloseScreen;
25605b261ecSmrg    }
25705b261ecSmrg    /* else CloseScreen */
2585a112b11Smrg    /* QueryBestSize */
2595a112b11Smrg    pScreen->SaveScreen = miSaveScreen;
2605a112b11Smrg    /* GetImage, GetSpans */
2614e185dc0Smrg    pScreen->SourceValidate = miSourceValidate;
26205b261ecSmrg    /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
26305b261ecSmrg    /* RealizeWindow, UnrealizeWindow */
26405b261ecSmrg    pScreen->ValidateTree = miValidateTree;
26505b261ecSmrg    pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
26605b261ecSmrg    pScreen->WindowExposures = miWindowExposures;
2674642e01fSmrg    /* CopyWindow */
26805b261ecSmrg    pScreen->ClearToBackground = miClearToBackground;
26905b261ecSmrg    pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
27005b261ecSmrg    pScreen->RestackWindow = (RestackWindowProcPtr) 0;
271f7df2e56Smrg    pScreen->PaintWindow = miPaintWindow;
27205b261ecSmrg    /* CreatePixmap, DestroyPixmap */
27305b261ecSmrg    /* RealizeFont, UnrealizeFont */
27405b261ecSmrg    /* CreateGC */
27505b261ecSmrg    /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
27605b261ecSmrg    /* ListInstalledColormaps, StoreColors, ResolveColor */
27705b261ecSmrg    /* BitmapToRegion */
278f7df2e56Smrg    pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
279f7df2e56Smrg    pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
28005b261ecSmrg    pScreen->MarkWindow = miMarkWindow;
28105b261ecSmrg    pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
28205b261ecSmrg    pScreen->MoveWindow = miMoveWindow;
283f7df2e56Smrg    pScreen->ResizeWindow = miResizeWindow;
28405b261ecSmrg    pScreen->GetLayerWindow = miGetLayerWindow;
28505b261ecSmrg    pScreen->HandleExposures = miHandleValidateExposures;
28605b261ecSmrg    pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
28705b261ecSmrg    pScreen->ChangeBorderWidth = miChangeBorderWidth;
28805b261ecSmrg    pScreen->SetShape = miSetShape;
28905b261ecSmrg    pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
290f7df2e56Smrg    pScreen->XYToWindow = miXYToWindow;
29105b261ecSmrg
29205b261ecSmrg    miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
29305b261ecSmrg
29405b261ecSmrg    return miScreenDevPrivateInit(pScreen, width, pbits);
29505b261ecSmrg}
29605b261ecSmrg
2974202a189SmrgDevPrivateKeyRec miZeroLineScreenKeyRec;
29805b261ecSmrg
2994202a189Smrgvoid
3004642e01fSmrgmiSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
30105b261ecSmrg{
3024202a189Smrg    if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
303f7df2e56Smrg        return;
3044202a189Smrg
305f7df2e56Smrg    dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
306f7df2e56Smrg                  (unsigned long *) (unsigned long) bias);
30705b261ecSmrg}
308