miscrinit.c revision 05b261ec
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
4205b261ecSmrg#define _XSHM_SERVER_
4305b261ecSmrg#include <X11/extensions/XShm.h>
4405b261ecSmrg#endif
4505b261ecSmrg
4605b261ecSmrg/* We use this structure to propogate some information from miScreenInit to
4705b261ecSmrg * miCreateScreenResources.  miScreenInit allocates the structure, fills it
4805b261ecSmrg * 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
5505b261ecSmrgtypedef struct
5605b261ecSmrg{
5705b261ecSmrg    pointer pbits; /* pointer to framebuffer */
5805b261ecSmrg    int width;    /* delta to add to a framebuffer addr to move one row down */
5905b261ecSmrg} miScreenInitParmsRec, *miScreenInitParmsPtr;
6005b261ecSmrg
6105b261ecSmrg
6205b261ecSmrg/* this plugs into pScreen->ModifyPixmapHeader */
6305b261ecSmrg_X_EXPORT Bool
6405b261ecSmrgmiModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind,
6505b261ecSmrg		     pPixData)
6605b261ecSmrg    PixmapPtr   pPixmap;
6705b261ecSmrg    int		width;
6805b261ecSmrg    int		height;
6905b261ecSmrg    int		depth;
7005b261ecSmrg    int		bitsPerPixel;
7105b261ecSmrg    int		devKind;
7205b261ecSmrg    pointer     pPixData;
7305b261ecSmrg{
7405b261ecSmrg    if (!pPixmap)
7505b261ecSmrg	return FALSE;
7605b261ecSmrg
7705b261ecSmrg    /*
7805b261ecSmrg     * If all arguments are specified, reinitialize everything (including
7905b261ecSmrg     * validated state).
8005b261ecSmrg     */
8105b261ecSmrg    if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
8205b261ecSmrg	(devKind > 0) && pPixData) {
8305b261ecSmrg	pPixmap->drawable.depth = depth;
8405b261ecSmrg	pPixmap->drawable.bitsPerPixel = bitsPerPixel;
8505b261ecSmrg	pPixmap->drawable.id = 0;
8605b261ecSmrg	pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
8705b261ecSmrg	pPixmap->drawable.x = 0;
8805b261ecSmrg	pPixmap->drawable.y = 0;
8905b261ecSmrg	pPixmap->drawable.width = width;
9005b261ecSmrg	pPixmap->drawable.height = height;
9105b261ecSmrg	pPixmap->devKind = devKind;
9205b261ecSmrg	pPixmap->refcnt = 1;
9305b261ecSmrg	pPixmap->devPrivate.ptr = pPixData;
9405b261ecSmrg    } else {
9505b261ecSmrg	/*
9605b261ecSmrg	 * Only modify specified fields, keeping all others intact.
9705b261ecSmrg	 */
9805b261ecSmrg
9905b261ecSmrg	if (width > 0)
10005b261ecSmrg	    pPixmap->drawable.width = width;
10105b261ecSmrg
10205b261ecSmrg	if (height > 0)
10305b261ecSmrg	    pPixmap->drawable.height = height;
10405b261ecSmrg
10505b261ecSmrg	if (depth > 0)
10605b261ecSmrg	    pPixmap->drawable.depth = depth;
10705b261ecSmrg
10805b261ecSmrg	if (bitsPerPixel > 0)
10905b261ecSmrg	    pPixmap->drawable.bitsPerPixel = bitsPerPixel;
11005b261ecSmrg	else if ((bitsPerPixel < 0) && (depth > 0))
11105b261ecSmrg	    pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
11205b261ecSmrg
11305b261ecSmrg	/*
11405b261ecSmrg	 * CAVEAT:  Non-SI DDXen may use devKind and devPrivate fields for
11505b261ecSmrg	 *          other purposes.
11605b261ecSmrg	 */
11705b261ecSmrg	if (devKind > 0)
11805b261ecSmrg	    pPixmap->devKind = devKind;
11905b261ecSmrg	else if ((devKind < 0) && ((width > 0) || (depth > 0)))
12005b261ecSmrg	    pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
12105b261ecSmrg		pPixmap->drawable.depth);
12205b261ecSmrg
12305b261ecSmrg	if (pPixData)
12405b261ecSmrg	    pPixmap->devPrivate.ptr = pPixData;
12505b261ecSmrg    }
12605b261ecSmrg    return TRUE;
12705b261ecSmrg}
12805b261ecSmrg
12905b261ecSmrgstatic Bool
13005b261ecSmrgmiCloseScreen (int iScreen, ScreenPtr pScreen)
13105b261ecSmrg{
13205b261ecSmrg    return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate));
13305b261ecSmrg}
13405b261ecSmrg
13505b261ecSmrg/* With the introduction of pixmap privates, the "screen pixmap" can no
13605b261ecSmrg * longer be created in miScreenInit, since all the modules that could
13705b261ecSmrg * possibly ask for pixmap private space have not been initialized at
13805b261ecSmrg * that time.  pScreen->CreateScreenResources is called after all
13905b261ecSmrg * possible private-requesting modules have been inited; we create the
14005b261ecSmrg * screen pixmap here.
14105b261ecSmrg */
14205b261ecSmrg_X_EXPORT Bool
14305b261ecSmrgmiCreateScreenResources(pScreen)
14405b261ecSmrg    ScreenPtr pScreen;
14505b261ecSmrg{
14605b261ecSmrg    miScreenInitParmsPtr pScrInitParms;
14705b261ecSmrg    pointer value;
14805b261ecSmrg
14905b261ecSmrg    pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
15005b261ecSmrg
15105b261ecSmrg    /* if width is non-zero, pScreen->devPrivate will be a pixmap
15205b261ecSmrg     * else it will just take the value pbits
15305b261ecSmrg     */
15405b261ecSmrg    if (pScrInitParms->width)
15505b261ecSmrg    {
15605b261ecSmrg	PixmapPtr pPixmap;
15705b261ecSmrg
15805b261ecSmrg	/* create a pixmap with no data, then redirect it to point to
15905b261ecSmrg	 * the screen
16005b261ecSmrg	 */
16105b261ecSmrg	pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
16205b261ecSmrg	if (!pPixmap)
16305b261ecSmrg	    return FALSE;
16405b261ecSmrg
16505b261ecSmrg	if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
16605b261ecSmrg		    pScreen->height, pScreen->rootDepth,
16705b261ecSmrg		    BitsPerPixel(pScreen->rootDepth),
16805b261ecSmrg		    PixmapBytePad(pScrInitParms->width, pScreen->rootDepth),
16905b261ecSmrg		    pScrInitParms->pbits))
17005b261ecSmrg	    return FALSE;
17105b261ecSmrg	value = (pointer)pPixmap;
17205b261ecSmrg    }
17305b261ecSmrg    else
17405b261ecSmrg    {
17505b261ecSmrg	value = pScrInitParms->pbits;
17605b261ecSmrg    }
17705b261ecSmrg    xfree(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
17805b261ecSmrg    pScreen->devPrivate = value; /* pPixmap or pbits */
17905b261ecSmrg    return TRUE;
18005b261ecSmrg}
18105b261ecSmrg
18205b261ecSmrgBool
18305b261ecSmrgmiScreenDevPrivateInit(pScreen, width, pbits)
18405b261ecSmrg    ScreenPtr pScreen;
18505b261ecSmrg    int width;
18605b261ecSmrg    pointer pbits;
18705b261ecSmrg{
18805b261ecSmrg    miScreenInitParmsPtr pScrInitParms;
18905b261ecSmrg
19005b261ecSmrg    /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
19105b261ecSmrg     * to the screen, until CreateScreenResources can put them in the
19205b261ecSmrg     * screen pixmap.
19305b261ecSmrg     */
19405b261ecSmrg    pScrInitParms = (miScreenInitParmsPtr)xalloc(sizeof(miScreenInitParmsRec));
19505b261ecSmrg    if (!pScrInitParms)
19605b261ecSmrg	return FALSE;
19705b261ecSmrg    pScrInitParms->pbits = pbits;
19805b261ecSmrg    pScrInitParms->width = width;
19905b261ecSmrg    pScreen->devPrivate = (pointer)pScrInitParms;
20005b261ecSmrg    return TRUE;
20105b261ecSmrg}
20205b261ecSmrg
20305b261ecSmrg_X_EXPORT Bool
20405b261ecSmrgmiScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
20505b261ecSmrg	     rootDepth, numDepths, depths, rootVisual, numVisuals, visuals)
20605b261ecSmrg    ScreenPtr pScreen;
20705b261ecSmrg    pointer pbits;		/* pointer to screen bits */
20805b261ecSmrg    int xsize, ysize;		/* in pixels */
20905b261ecSmrg    int dpix, dpiy;		/* dots per inch */
21005b261ecSmrg    int width;			/* pixel width of frame buffer */
21105b261ecSmrg    int rootDepth;		/* depth of root window */
21205b261ecSmrg    int numDepths;		/* number of depths supported */
21305b261ecSmrg    DepthRec *depths;		/* supported depths */
21405b261ecSmrg    VisualID rootVisual;	/* root visual */
21505b261ecSmrg    int numVisuals;		/* number of visuals supported */
21605b261ecSmrg    VisualRec *visuals;		/* supported visuals */
21705b261ecSmrg{
21805b261ecSmrg    pScreen->width = xsize;
21905b261ecSmrg    pScreen->height = ysize;
22005b261ecSmrg    pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
22105b261ecSmrg    pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
22205b261ecSmrg    pScreen->numDepths = numDepths;
22305b261ecSmrg    pScreen->rootDepth = rootDepth;
22405b261ecSmrg    pScreen->allowedDepths = depths;
22505b261ecSmrg    pScreen->rootVisual = rootVisual;
22605b261ecSmrg    /* defColormap */
22705b261ecSmrg    pScreen->minInstalledCmaps = 1;
22805b261ecSmrg    pScreen->maxInstalledCmaps = 1;
22905b261ecSmrg    pScreen->backingStoreSupport = NotUseful;
23005b261ecSmrg    pScreen->saveUnderSupport = NotUseful;
23105b261ecSmrg    /* whitePixel, blackPixel */
23205b261ecSmrg    pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
23305b261ecSmrg    pScreen->CreateScreenResources = miCreateScreenResources;
23405b261ecSmrg    pScreen->GetScreenPixmap = miGetScreenPixmap;
23505b261ecSmrg    pScreen->SetScreenPixmap = miSetScreenPixmap;
23605b261ecSmrg    pScreen->numVisuals = numVisuals;
23705b261ecSmrg    pScreen->visuals = visuals;
23805b261ecSmrg    if (width)
23905b261ecSmrg    {
24005b261ecSmrg#ifdef MITSHM
24105b261ecSmrg	ShmRegisterFbFuncs(pScreen);
24205b261ecSmrg#endif
24305b261ecSmrg	pScreen->CloseScreen = miCloseScreen;
24405b261ecSmrg    }
24505b261ecSmrg    /* else CloseScreen */
24605b261ecSmrg    /* QueryBestSize, SaveScreen, GetImage, GetSpans */
24705b261ecSmrg    pScreen->PointerNonInterestBox = (PointerNonInterestBoxProcPtr) 0;
24805b261ecSmrg    pScreen->SourceValidate = (SourceValidateProcPtr) 0;
24905b261ecSmrg    /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
25005b261ecSmrg    /* RealizeWindow, UnrealizeWindow */
25105b261ecSmrg    pScreen->ValidateTree = miValidateTree;
25205b261ecSmrg    pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
25305b261ecSmrg    pScreen->WindowExposures = miWindowExposures;
25405b261ecSmrg    /* PaintWindowBackground, PaintWindowBorder, CopyWindow */
25505b261ecSmrg    pScreen->ClearToBackground = miClearToBackground;
25605b261ecSmrg    pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
25705b261ecSmrg    pScreen->RestackWindow = (RestackWindowProcPtr) 0;
25805b261ecSmrg    /* CreatePixmap, DestroyPixmap */
25905b261ecSmrg    /* RealizeFont, UnrealizeFont */
26005b261ecSmrg    /* CreateGC */
26105b261ecSmrg    /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
26205b261ecSmrg    /* ListInstalledColormaps, StoreColors, ResolveColor */
26305b261ecSmrg    /* BitmapToRegion */
26405b261ecSmrg    pScreen->SendGraphicsExpose = miSendGraphicsExpose;
26505b261ecSmrg    pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
26605b261ecSmrg    pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
26705b261ecSmrg    pScreen->blockData = (pointer)0;
26805b261ecSmrg    pScreen->wakeupData = (pointer)0;
26905b261ecSmrg    pScreen->MarkWindow = miMarkWindow;
27005b261ecSmrg    pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
27105b261ecSmrg    pScreen->ChangeSaveUnder = miChangeSaveUnder;
27205b261ecSmrg    pScreen->PostChangeSaveUnder = miPostChangeSaveUnder;
27305b261ecSmrg    pScreen->MoveWindow = miMoveWindow;
27405b261ecSmrg    pScreen->ResizeWindow = miSlideAndSizeWindow;
27505b261ecSmrg    pScreen->GetLayerWindow = miGetLayerWindow;
27605b261ecSmrg    pScreen->HandleExposures = miHandleValidateExposures;
27705b261ecSmrg    pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
27805b261ecSmrg    pScreen->ChangeBorderWidth = miChangeBorderWidth;
27905b261ecSmrg#ifdef SHAPE
28005b261ecSmrg    pScreen->SetShape = miSetShape;
28105b261ecSmrg#endif
28205b261ecSmrg    pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
28305b261ecSmrg
28405b261ecSmrg    pScreen->SaveDoomedAreas = 0;
28505b261ecSmrg    pScreen->RestoreAreas = 0;
28605b261ecSmrg    pScreen->ExposeCopy = 0;
28705b261ecSmrg    pScreen->TranslateBackingStore = 0;
28805b261ecSmrg    pScreen->ClearBackingStore = 0;
28905b261ecSmrg    pScreen->DrawGuarantee = 0;
29005b261ecSmrg
29105b261ecSmrg    miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
29205b261ecSmrg
29305b261ecSmrg    return miScreenDevPrivateInit(pScreen, width, pbits);
29405b261ecSmrg}
29505b261ecSmrg
29605b261ecSmrg_X_EXPORT int
29705b261ecSmrgmiAllocateGCPrivateIndex()
29805b261ecSmrg{
29905b261ecSmrg    static int privateIndex = -1;
30005b261ecSmrg    static unsigned long miGeneration = 0;
30105b261ecSmrg
30205b261ecSmrg    if (miGeneration != serverGeneration)
30305b261ecSmrg    {
30405b261ecSmrg	privateIndex = AllocateGCPrivateIndex();
30505b261ecSmrg	miGeneration = serverGeneration;
30605b261ecSmrg    }
30705b261ecSmrg    return privateIndex;
30805b261ecSmrg}
30905b261ecSmrg
31005b261ecSmrg_X_EXPORT int miZeroLineScreenIndex;
31105b261ecSmrgstatic unsigned int miZeroLineGeneration = 0;
31205b261ecSmrg
31305b261ecSmrg_X_EXPORT void
31405b261ecSmrgmiSetZeroLineBias(pScreen, bias)
31505b261ecSmrg    ScreenPtr pScreen;
31605b261ecSmrg    unsigned int bias;
31705b261ecSmrg{
31805b261ecSmrg    if (miZeroLineGeneration != serverGeneration)
31905b261ecSmrg    {
32005b261ecSmrg	miZeroLineScreenIndex = AllocateScreenPrivateIndex();
32105b261ecSmrg	miZeroLineGeneration = serverGeneration;
32205b261ecSmrg    }
32305b261ecSmrg    if (miZeroLineScreenIndex >= 0)
32405b261ecSmrg	pScreen->devPrivates[miZeroLineScreenIndex].uval = bias;
32505b261ecSmrg}
32605b261ecSmrg
32705b261ecSmrg_X_EXPORT PixmapPtr
32805b261ecSmrgmiGetScreenPixmap(pScreen)
32905b261ecSmrg    ScreenPtr pScreen;
33005b261ecSmrg{
33105b261ecSmrg    return (PixmapPtr)(pScreen->devPrivate);
33205b261ecSmrg}
33305b261ecSmrg
33405b261ecSmrg_X_EXPORT void
33505b261ecSmrgmiSetScreenPixmap(pPix)
33605b261ecSmrg    PixmapPtr pPix;
33705b261ecSmrg{
33805b261ecSmrg    if (pPix)
33905b261ecSmrg	pPix->drawable.pScreen->devPrivate = (pointer)pPix;
34005b261ecSmrg}
341