miscrinit.c revision 4202a189
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
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 */
634202a189SmrgBool
644642e01fSmrgmiModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
654642e01fSmrg                     int bitsPerPixel, int devKind, pointer pPixData)
6605b261ecSmrg{
6705b261ecSmrg    if (!pPixmap)
6805b261ecSmrg	return FALSE;
6905b261ecSmrg
7005b261ecSmrg    /*
7105b261ecSmrg     * If all arguments are specified, reinitialize everything (including
7205b261ecSmrg     * validated state).
7305b261ecSmrg     */
7405b261ecSmrg    if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
7505b261ecSmrg	(devKind > 0) && pPixData) {
7605b261ecSmrg	pPixmap->drawable.depth = depth;
7705b261ecSmrg	pPixmap->drawable.bitsPerPixel = bitsPerPixel;
7805b261ecSmrg	pPixmap->drawable.id = 0;
7905b261ecSmrg	pPixmap->drawable.x = 0;
8005b261ecSmrg	pPixmap->drawable.y = 0;
8105b261ecSmrg	pPixmap->drawable.width = width;
8205b261ecSmrg	pPixmap->drawable.height = height;
8305b261ecSmrg	pPixmap->devKind = devKind;
8405b261ecSmrg	pPixmap->refcnt = 1;
8505b261ecSmrg	pPixmap->devPrivate.ptr = pPixData;
8605b261ecSmrg    } else {
8705b261ecSmrg	/*
8805b261ecSmrg	 * Only modify specified fields, keeping all others intact.
8905b261ecSmrg	 */
9005b261ecSmrg
9105b261ecSmrg	if (width > 0)
9205b261ecSmrg	    pPixmap->drawable.width = width;
9305b261ecSmrg
9405b261ecSmrg	if (height > 0)
9505b261ecSmrg	    pPixmap->drawable.height = height;
9605b261ecSmrg
9705b261ecSmrg	if (depth > 0)
9805b261ecSmrg	    pPixmap->drawable.depth = depth;
9905b261ecSmrg
10005b261ecSmrg	if (bitsPerPixel > 0)
10105b261ecSmrg	    pPixmap->drawable.bitsPerPixel = bitsPerPixel;
10205b261ecSmrg	else if ((bitsPerPixel < 0) && (depth > 0))
10305b261ecSmrg	    pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
10405b261ecSmrg
10505b261ecSmrg	/*
10605b261ecSmrg	 * CAVEAT:  Non-SI DDXen may use devKind and devPrivate fields for
10705b261ecSmrg	 *          other purposes.
10805b261ecSmrg	 */
10905b261ecSmrg	if (devKind > 0)
11005b261ecSmrg	    pPixmap->devKind = devKind;
11105b261ecSmrg	else if ((devKind < 0) && ((width > 0) || (depth > 0)))
11205b261ecSmrg	    pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
11305b261ecSmrg		pPixmap->drawable.depth);
11405b261ecSmrg
11505b261ecSmrg	if (pPixData)
11605b261ecSmrg	    pPixmap->devPrivate.ptr = pPixData;
11705b261ecSmrg    }
1184202a189Smrg    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
11905b261ecSmrg    return TRUE;
12005b261ecSmrg}
12105b261ecSmrg
12205b261ecSmrgstatic Bool
12305b261ecSmrgmiCloseScreen (int iScreen, ScreenPtr pScreen)
12405b261ecSmrg{
12505b261ecSmrg    return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate));
12605b261ecSmrg}
12705b261ecSmrg
12805b261ecSmrg/* With the introduction of pixmap privates, the "screen pixmap" can no
12905b261ecSmrg * longer be created in miScreenInit, since all the modules that could
13005b261ecSmrg * possibly ask for pixmap private space have not been initialized at
13105b261ecSmrg * that time.  pScreen->CreateScreenResources is called after all
13205b261ecSmrg * possible private-requesting modules have been inited; we create the
13305b261ecSmrg * screen pixmap here.
13405b261ecSmrg */
1354202a189SmrgBool
1364642e01fSmrgmiCreateScreenResources(ScreenPtr pScreen)
13705b261ecSmrg{
13805b261ecSmrg    miScreenInitParmsPtr pScrInitParms;
13905b261ecSmrg    pointer value;
14005b261ecSmrg
14105b261ecSmrg    pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
14205b261ecSmrg
14305b261ecSmrg    /* if width is non-zero, pScreen->devPrivate will be a pixmap
14405b261ecSmrg     * else it will just take the value pbits
14505b261ecSmrg     */
14605b261ecSmrg    if (pScrInitParms->width)
14705b261ecSmrg    {
14805b261ecSmrg	PixmapPtr pPixmap;
14905b261ecSmrg
15005b261ecSmrg	/* create a pixmap with no data, then redirect it to point to
15105b261ecSmrg	 * the screen
15205b261ecSmrg	 */
1534642e01fSmrg	pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
15405b261ecSmrg	if (!pPixmap)
15505b261ecSmrg	    return FALSE;
15605b261ecSmrg
15705b261ecSmrg	if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
15805b261ecSmrg		    pScreen->height, pScreen->rootDepth,
15905b261ecSmrg		    BitsPerPixel(pScreen->rootDepth),
16005b261ecSmrg		    PixmapBytePad(pScrInitParms->width, pScreen->rootDepth),
16105b261ecSmrg		    pScrInitParms->pbits))
16205b261ecSmrg	    return FALSE;
16305b261ecSmrg	value = (pointer)pPixmap;
16405b261ecSmrg    }
16505b261ecSmrg    else
16605b261ecSmrg    {
16705b261ecSmrg	value = pScrInitParms->pbits;
16805b261ecSmrg    }
1694202a189Smrg    free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
17005b261ecSmrg    pScreen->devPrivate = value; /* pPixmap or pbits */
17105b261ecSmrg    return TRUE;
17205b261ecSmrg}
17305b261ecSmrg
17405b261ecSmrgBool
1754642e01fSmrgmiScreenDevPrivateInit(ScreenPtr pScreen, int width, pointer pbits)
17605b261ecSmrg{
17705b261ecSmrg    miScreenInitParmsPtr pScrInitParms;
17805b261ecSmrg
17905b261ecSmrg    /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
18005b261ecSmrg     * to the screen, until CreateScreenResources can put them in the
18105b261ecSmrg     * screen pixmap.
18205b261ecSmrg     */
1834202a189Smrg    pScrInitParms = malloc(sizeof(miScreenInitParmsRec));
18405b261ecSmrg    if (!pScrInitParms)
18505b261ecSmrg	return FALSE;
18605b261ecSmrg    pScrInitParms->pbits = pbits;
18705b261ecSmrg    pScrInitParms->width = width;
18805b261ecSmrg    pScreen->devPrivate = (pointer)pScrInitParms;
18905b261ecSmrg    return TRUE;
19005b261ecSmrg}
19105b261ecSmrg
1924642e01fSmrgstatic PixmapPtr
1934642e01fSmrgmiGetScreenPixmap(ScreenPtr pScreen)
1944642e01fSmrg{
1954642e01fSmrg    return (PixmapPtr)(pScreen->devPrivate);
1964642e01fSmrg}
1974642e01fSmrg
1984642e01fSmrgstatic void
1994642e01fSmrgmiSetScreenPixmap(PixmapPtr pPix)
2004642e01fSmrg{
2014642e01fSmrg    if (pPix)
2024642e01fSmrg	pPix->drawable.pScreen->devPrivate = (pointer)pPix;
2034642e01fSmrg}
2044642e01fSmrg
2054202a189SmrgBool
2064642e01fSmrgmiScreenInit(
2074642e01fSmrg    ScreenPtr pScreen,
2084642e01fSmrg    pointer pbits,		/* pointer to screen bits */
2094642e01fSmrg    int xsize, int ysize,	/* in pixels */
2104642e01fSmrg    int dpix, int dpiy,		/* dots per inch */
2114642e01fSmrg    int width,			/* pixel width of frame buffer */
2124642e01fSmrg    int rootDepth,		/* depth of root window */
2134642e01fSmrg    int numDepths,		/* number of depths supported */
2144642e01fSmrg    DepthRec *depths,		/* supported depths */
2154642e01fSmrg    VisualID rootVisual,	/* root visual */
2164642e01fSmrg    int numVisuals,		/* number of visuals supported */
2174642e01fSmrg    VisualRec *visuals		/* supported visuals */
2184642e01fSmrg    )
21905b261ecSmrg{
22005b261ecSmrg    pScreen->width = xsize;
22105b261ecSmrg    pScreen->height = ysize;
22205b261ecSmrg    pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
22305b261ecSmrg    pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
22405b261ecSmrg    pScreen->numDepths = numDepths;
22505b261ecSmrg    pScreen->rootDepth = rootDepth;
22605b261ecSmrg    pScreen->allowedDepths = depths;
22705b261ecSmrg    pScreen->rootVisual = rootVisual;
22805b261ecSmrg    /* defColormap */
22905b261ecSmrg    pScreen->minInstalledCmaps = 1;
23005b261ecSmrg    pScreen->maxInstalledCmaps = 1;
23105b261ecSmrg    pScreen->backingStoreSupport = NotUseful;
23205b261ecSmrg    pScreen->saveUnderSupport = NotUseful;
23305b261ecSmrg    /* whitePixel, blackPixel */
23405b261ecSmrg    pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
23505b261ecSmrg    pScreen->CreateScreenResources = miCreateScreenResources;
23605b261ecSmrg    pScreen->GetScreenPixmap = miGetScreenPixmap;
23705b261ecSmrg    pScreen->SetScreenPixmap = miSetScreenPixmap;
23805b261ecSmrg    pScreen->numVisuals = numVisuals;
23905b261ecSmrg    pScreen->visuals = visuals;
24005b261ecSmrg    if (width)
24105b261ecSmrg    {
24205b261ecSmrg#ifdef MITSHM
24305b261ecSmrg	ShmRegisterFbFuncs(pScreen);
24405b261ecSmrg#endif
24505b261ecSmrg	pScreen->CloseScreen = miCloseScreen;
24605b261ecSmrg    }
24705b261ecSmrg    /* else CloseScreen */
24805b261ecSmrg    /* QueryBestSize, SaveScreen, GetImage, GetSpans */
24905b261ecSmrg    pScreen->SourceValidate = (SourceValidateProcPtr) 0;
25005b261ecSmrg    /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
25105b261ecSmrg    /* RealizeWindow, UnrealizeWindow */
25205b261ecSmrg    pScreen->ValidateTree = miValidateTree;
25305b261ecSmrg    pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0;
25405b261ecSmrg    pScreen->WindowExposures = miWindowExposures;
2554642e01fSmrg    /* CopyWindow */
25605b261ecSmrg    pScreen->ClearToBackground = miClearToBackground;
25705b261ecSmrg    pScreen->ClipNotify = (ClipNotifyProcPtr) 0;
25805b261ecSmrg    pScreen->RestackWindow = (RestackWindowProcPtr) 0;
25905b261ecSmrg    /* CreatePixmap, DestroyPixmap */
26005b261ecSmrg    /* RealizeFont, UnrealizeFont */
26105b261ecSmrg    /* CreateGC */
26205b261ecSmrg    /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
26305b261ecSmrg    /* ListInstalledColormaps, StoreColors, ResolveColor */
26405b261ecSmrg    /* BitmapToRegion */
26505b261ecSmrg    pScreen->SendGraphicsExpose = miSendGraphicsExpose;
26605b261ecSmrg    pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
26705b261ecSmrg    pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
26805b261ecSmrg    pScreen->blockData = (pointer)0;
26905b261ecSmrg    pScreen->wakeupData = (pointer)0;
27005b261ecSmrg    pScreen->MarkWindow = miMarkWindow;
27105b261ecSmrg    pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
2724642e01fSmrg    pScreen->ChangeSaveUnder = NULL;
2734642e01fSmrg    pScreen->PostChangeSaveUnder = NULL;
27405b261ecSmrg    pScreen->MoveWindow = miMoveWindow;
27505b261ecSmrg    pScreen->ResizeWindow = miSlideAndSizeWindow;
27605b261ecSmrg    pScreen->GetLayerWindow = miGetLayerWindow;
27705b261ecSmrg    pScreen->HandleExposures = miHandleValidateExposures;
27805b261ecSmrg    pScreen->ReparentWindow = (ReparentWindowProcPtr) 0;
27905b261ecSmrg    pScreen->ChangeBorderWidth = miChangeBorderWidth;
28005b261ecSmrg    pScreen->SetShape = miSetShape;
28105b261ecSmrg    pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
28205b261ecSmrg
28305b261ecSmrg    pScreen->SaveDoomedAreas = 0;
28405b261ecSmrg    pScreen->RestoreAreas = 0;
28505b261ecSmrg    pScreen->ExposeCopy = 0;
28605b261ecSmrg    pScreen->TranslateBackingStore = 0;
28705b261ecSmrg    pScreen->ClearBackingStore = 0;
28805b261ecSmrg    pScreen->DrawGuarantee = 0;
28905b261ecSmrg
29005b261ecSmrg    miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
29105b261ecSmrg
29205b261ecSmrg    return miScreenDevPrivateInit(pScreen, width, pbits);
29305b261ecSmrg}
29405b261ecSmrg
2954202a189Smrgstatic DevPrivateKeyRec privateKeyRec;
2964202a189Smrg#define privateKey (&privateKeyRec)
29705b261ecSmrg
2984642e01fSmrgDevPrivateKey
2994202a189SmrgmiAllocateGCPrivateIndex(void)
30005b261ecSmrg{
3014202a189Smrg    if (!dixRegisterPrivateKey(&privateKeyRec, PRIVATE_GC, 0))
3024202a189Smrg	return NULL;
3034642e01fSmrg    return privateKey;
30405b261ecSmrg}
30505b261ecSmrg
3064202a189SmrgDevPrivateKeyRec miZeroLineScreenKeyRec;
30705b261ecSmrg
3084202a189Smrgvoid
3094642e01fSmrgmiSetZeroLineBias(ScreenPtr pScreen, unsigned int bias)
31005b261ecSmrg{
3114202a189Smrg    if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0))
3124202a189Smrg	return;
3134202a189Smrg
3144202a189Smrg    dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey,
3154202a189Smrg					(unsigned long *)(unsigned long)bias);
31605b261ecSmrg}
317