midbe.c revision 05b261ec
105b261ecSmrg/******************************************************************************
205b261ecSmrg *
305b261ecSmrg * Copyright (c) 1994, 1995  Hewlett-Packard Company
405b261ecSmrg *
505b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining
605b261ecSmrg * a copy of this software and associated documentation files (the
705b261ecSmrg * "Software"), to deal in the Software without restriction, including
805b261ecSmrg * without limitation the rights to use, copy, modify, merge, publish,
905b261ecSmrg * distribute, sublicense, and/or sell copies of the Software, and to
1005b261ecSmrg * permit persons to whom the Software is furnished to do so, subject to
1105b261ecSmrg * the following conditions:
1205b261ecSmrg *
1305b261ecSmrg * The above copyright notice and this permission notice shall be included
1405b261ecSmrg * in all copies or substantial portions of the Software.
1505b261ecSmrg *
1605b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1705b261ecSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1805b261ecSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1905b261ecSmrg * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
2005b261ecSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2105b261ecSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
2205b261ecSmrg * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2305b261ecSmrg *
2405b261ecSmrg * Except as contained in this notice, the name of the Hewlett-Packard
2505b261ecSmrg * Company shall not be used in advertising or otherwise to promote the
2605b261ecSmrg * sale, use or other dealings in this Software without prior written
2705b261ecSmrg * authorization from the Hewlett-Packard Company.
2805b261ecSmrg *
2905b261ecSmrg *     Machine-independent DBE code
3005b261ecSmrg *
3105b261ecSmrg *****************************************************************************/
3205b261ecSmrg
3305b261ecSmrg
3405b261ecSmrg/* INCLUDES */
3505b261ecSmrg
3605b261ecSmrg#define NEED_REPLIES
3705b261ecSmrg#define NEED_EVENTS
3805b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3905b261ecSmrg#include <dix-config.h>
4005b261ecSmrg#endif
4105b261ecSmrg
4205b261ecSmrg#include <X11/X.h>
4305b261ecSmrg#include <X11/Xproto.h>
4405b261ecSmrg#include "misc.h"
4505b261ecSmrg#include "os.h"
4605b261ecSmrg#include "windowstr.h"
4705b261ecSmrg#include "scrnintstr.h"
4805b261ecSmrg#include "pixmapstr.h"
4905b261ecSmrg#include "extnsionst.h"
5005b261ecSmrg#include "dixstruct.h"
5105b261ecSmrg#include "resource.h"
5205b261ecSmrg#include "opaque.h"
5305b261ecSmrg#include "dbestruct.h"
5405b261ecSmrg#include "midbestr.h"
5505b261ecSmrg#include "regionstr.h"
5605b261ecSmrg#include "gcstruct.h"
5705b261ecSmrg#include "inputstr.h"
5805b261ecSmrg#include "midbe.h"
5905b261ecSmrg
6005b261ecSmrg#include <stdio.h>
6105b261ecSmrg
6205b261ecSmrgstatic int	miDbePrivPrivGeneration  =  0;
6305b261ecSmrgstatic int	miDbeWindowPrivPrivIndex = -1;
6405b261ecSmrgstatic RESTYPE	dbeDrawableResType;
6505b261ecSmrgstatic RESTYPE	dbeWindowPrivResType;
6605b261ecSmrgstatic int	dbeScreenPrivIndex = -1;
6705b261ecSmrgstatic int	dbeWindowPrivIndex = -1;
6805b261ecSmrg
6905b261ecSmrg
7005b261ecSmrg/******************************************************************************
7105b261ecSmrg *
7205b261ecSmrg * DBE MI Procedure: miDbeGetVisualInfo
7305b261ecSmrg *
7405b261ecSmrg * Description:
7505b261ecSmrg *
7605b261ecSmrg *     This is the MI function for the DbeGetVisualInfo request.  This function
7705b261ecSmrg *     is called through pDbeScreenPriv->GetVisualInfo.  This function is also
7805b261ecSmrg *     called for the DbeAllocateBackBufferName request at the extension level;
7905b261ecSmrg *     it is called by ProcDbeAllocateBackBufferName() in dbe.c.
8005b261ecSmrg *
8105b261ecSmrg *     If memory allocation fails or we can not get the visual info, this
8205b261ecSmrg *     function returns FALSE.  Otherwise, it returns TRUE for success.
8305b261ecSmrg *
8405b261ecSmrg *****************************************************************************/
8505b261ecSmrg
8605b261ecSmrgstatic Bool
8705b261ecSmrgmiDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo *pScrVisInfo)
8805b261ecSmrg{
8905b261ecSmrg    register int	i, j, k;
9005b261ecSmrg    register int	count;
9105b261ecSmrg    DepthPtr		pDepth;
9205b261ecSmrg    XdbeVisualInfo	*visInfo;
9305b261ecSmrg
9405b261ecSmrg
9505b261ecSmrg    /* Determine number of visuals for this screen. */
9605b261ecSmrg    for (i = 0, count = 0; i < pScreen->numDepths; i++)
9705b261ecSmrg    {
9805b261ecSmrg        count += pScreen->allowedDepths[i].numVids;
9905b261ecSmrg    }
10005b261ecSmrg
10105b261ecSmrg    /* Allocate an array of XdbeVisualInfo items. */
10205b261ecSmrg    if (!(visInfo = (XdbeVisualInfo *)xalloc(count * sizeof(XdbeVisualInfo))))
10305b261ecSmrg    {
10405b261ecSmrg        return(FALSE); /* memory alloc failure */
10505b261ecSmrg    }
10605b261ecSmrg
10705b261ecSmrg    for (i = 0, k = 0; i < pScreen->numDepths; i++)
10805b261ecSmrg    {
10905b261ecSmrg        /* For each depth of this screen, get visual information. */
11005b261ecSmrg
11105b261ecSmrg        pDepth = &pScreen->allowedDepths[i];
11205b261ecSmrg
11305b261ecSmrg        for (j = 0; j < pDepth->numVids; j++)
11405b261ecSmrg        {
11505b261ecSmrg            /* For each visual for this depth of this screen, get visual ID
11605b261ecSmrg             * and visual depth.  Since this is MI code, we will always return
11705b261ecSmrg             * the same performance level for all visuals (0).  A higher
11805b261ecSmrg             * performance level value indicates higher performance.
11905b261ecSmrg             */
12005b261ecSmrg            visInfo[k].visual    = pDepth->vids[j];
12105b261ecSmrg            visInfo[k].depth     = pDepth->depth;
12205b261ecSmrg            visInfo[k].perflevel = 0;
12305b261ecSmrg            k++;
12405b261ecSmrg        }
12505b261ecSmrg    }
12605b261ecSmrg
12705b261ecSmrg    /* Record the number of visuals and point visual_depth to
12805b261ecSmrg     * the array of visual info.
12905b261ecSmrg     */
13005b261ecSmrg    pScrVisInfo->count   = count;
13105b261ecSmrg    pScrVisInfo->visinfo = visInfo;
13205b261ecSmrg
13305b261ecSmrg    return(TRUE); /* success */
13405b261ecSmrg
13505b261ecSmrg} /* miDbeGetVisualInfo() */
13605b261ecSmrg
13705b261ecSmrg
13805b261ecSmrg/******************************************************************************
13905b261ecSmrg *
14005b261ecSmrg * DBE MI Procedure: miAllocBackBufferName
14105b261ecSmrg *
14205b261ecSmrg * Description:
14305b261ecSmrg *
14405b261ecSmrg *     This is the MI function for the DbeAllocateBackBufferName request.
14505b261ecSmrg *
14605b261ecSmrg *****************************************************************************/
14705b261ecSmrg
14805b261ecSmrgstatic int
14905b261ecSmrgmiDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
15005b261ecSmrg{
15105b261ecSmrg    ScreenPtr			pScreen;
15205b261ecSmrg    DbeWindowPrivPtr		pDbeWindowPriv;
15305b261ecSmrg    MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv;
15405b261ecSmrg    DbeScreenPrivPtr		pDbeScreenPriv;
15505b261ecSmrg    GCPtr			pGC;
15605b261ecSmrg    xRectangle			clearRect;
15705b261ecSmrg
15805b261ecSmrg
15905b261ecSmrg    pScreen = pWin->drawable.pScreen;
16005b261ecSmrg    pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
16105b261ecSmrg
16205b261ecSmrg    if (pDbeWindowPriv->nBufferIDs == 0)
16305b261ecSmrg    {
16405b261ecSmrg        /* There is no buffer associated with the window.
16505b261ecSmrg         * We have to create the window priv priv.  Remember, the window
16605b261ecSmrg         * priv was created at the DIX level, so all we need to do is
16705b261ecSmrg         * create the priv priv and attach it to the priv.
16805b261ecSmrg         */
16905b261ecSmrg
17005b261ecSmrg        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
17105b261ecSmrg
17205b261ecSmrg        /* Setup the window priv priv. */
17305b261ecSmrg        pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
17405b261ecSmrg        pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv;
17505b261ecSmrg
17605b261ecSmrg        /* Get a front pixmap. */
17705b261ecSmrg        if (!(pDbeWindowPrivPriv->pFrontBuffer =
17805b261ecSmrg            (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
17905b261ecSmrg                                     pDbeWindowPriv->height,
18005b261ecSmrg                                     pWin->drawable.depth)))
18105b261ecSmrg        {
18205b261ecSmrg            return(BadAlloc);
18305b261ecSmrg        }
18405b261ecSmrg
18505b261ecSmrg        /* Get a back pixmap. */
18605b261ecSmrg        if (!(pDbeWindowPrivPriv->pBackBuffer =
18705b261ecSmrg            (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
18805b261ecSmrg                                     pDbeWindowPriv->height,
18905b261ecSmrg                                     pWin->drawable.depth)))
19005b261ecSmrg        {
19105b261ecSmrg            (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
19205b261ecSmrg            return(BadAlloc);
19305b261ecSmrg        }
19405b261ecSmrg
19505b261ecSmrg
19605b261ecSmrg        /* Make the back pixmap a DBE drawable resource. */
19705b261ecSmrg        if (!AddResource(bufId, dbeDrawableResType,
19805b261ecSmrg            (pointer)pDbeWindowPrivPriv->pBackBuffer))
19905b261ecSmrg        {
20005b261ecSmrg            /* free the buffer and the drawable resource */
20105b261ecSmrg            FreeResource(bufId, RT_NONE);
20205b261ecSmrg            return(BadAlloc);
20305b261ecSmrg        }
20405b261ecSmrg
20505b261ecSmrg
20605b261ecSmrg        /* Attach the priv priv to the priv. */
20705b261ecSmrg	pDbeWindowPriv->devPrivates[miDbeWindowPrivPrivIndex].ptr =
20805b261ecSmrg            (pointer)pDbeWindowPrivPriv;
20905b261ecSmrg
21005b261ecSmrg
21105b261ecSmrg        /* Clear the back buffer. */
21205b261ecSmrg        pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
21305b261ecSmrg        if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
21405b261ecSmrg        {
21505b261ecSmrg            ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
21605b261ecSmrg            clearRect.x = clearRect.y = 0;
21705b261ecSmrg            clearRect.width  = pDbeWindowPrivPriv->pBackBuffer->drawable.width;
21805b261ecSmrg            clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height;
21905b261ecSmrg            (*pGC->ops->PolyFillRect)(
22005b261ecSmrg                (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC, 1,
22105b261ecSmrg                &clearRect);
22205b261ecSmrg        }
22305b261ecSmrg        FreeScratchGC(pGC);
22405b261ecSmrg
22505b261ecSmrg    } /* if no buffer associated with the window */
22605b261ecSmrg
22705b261ecSmrg    else
22805b261ecSmrg    {
22905b261ecSmrg        /* A buffer is already associated with the window.
23005b261ecSmrg         * Place the new buffer ID information at the head of the ID list.
23105b261ecSmrg         */
23205b261ecSmrg
23305b261ecSmrg        /* Associate the new ID with an existing pixmap. */
23405b261ecSmrg        pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
23505b261ecSmrg        if (!AddResource(bufId, dbeDrawableResType,
23605b261ecSmrg                         (pointer)pDbeWindowPrivPriv->pBackBuffer))
23705b261ecSmrg        {
23805b261ecSmrg            return(BadAlloc);
23905b261ecSmrg        }
24005b261ecSmrg
24105b261ecSmrg    }
24205b261ecSmrg
24305b261ecSmrg    return(Success);
24405b261ecSmrg
24505b261ecSmrg} /* miDbeAllocBackBufferName() */
24605b261ecSmrg
24705b261ecSmrg
24805b261ecSmrg/******************************************************************************
24905b261ecSmrg *
25005b261ecSmrg * DBE MI Procedure: miDbeAliasBuffers
25105b261ecSmrg *
25205b261ecSmrg * Description:
25305b261ecSmrg *
25405b261ecSmrg *     This function associates all XIDs of a buffer with the back pixmap
25505b261ecSmrg *     stored in the window priv.
25605b261ecSmrg *
25705b261ecSmrg *****************************************************************************/
25805b261ecSmrg
25905b261ecSmrgstatic void
26005b261ecSmrgmiDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)
26105b261ecSmrg{
26205b261ecSmrg    int				i;
26305b261ecSmrg    MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv =
26405b261ecSmrg                                    MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
26505b261ecSmrg
26605b261ecSmrg    for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
26705b261ecSmrg    {
26805b261ecSmrg        ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType,
26905b261ecSmrg                            (pointer)pDbeWindowPrivPriv->pBackBuffer);
27005b261ecSmrg    }
27105b261ecSmrg
27205b261ecSmrg} /* miDbeAliasBuffers() */
27305b261ecSmrg
27405b261ecSmrg
27505b261ecSmrg/******************************************************************************
27605b261ecSmrg *
27705b261ecSmrg * DBE MI Procedure: miDbeSwapBuffers
27805b261ecSmrg *
27905b261ecSmrg * Description:
28005b261ecSmrg *
28105b261ecSmrg *     This is the MI function for the DbeSwapBuffers request.
28205b261ecSmrg *
28305b261ecSmrg *****************************************************************************/
28405b261ecSmrg
28505b261ecSmrgstatic int
28605b261ecSmrgmiDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo)
28705b261ecSmrg{
28805b261ecSmrg    DbeScreenPrivPtr		pDbeScreenPriv;
28905b261ecSmrg    GCPtr		    	pGC;
29005b261ecSmrg    WindowPtr		    	pWin;
29105b261ecSmrg    MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv;
29205b261ecSmrg    PixmapPtr			pTmpBuffer;
29305b261ecSmrg    xRectangle			clearRect;
29405b261ecSmrg
29505b261ecSmrg
29605b261ecSmrg    pWin               = swapInfo[0].pWindow;
29705b261ecSmrg    pDbeScreenPriv     = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
29805b261ecSmrg    pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin);
29905b261ecSmrg    pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
30005b261ecSmrg
30105b261ecSmrg    /*
30205b261ecSmrg     **********************************************************************
30305b261ecSmrg     ** Setup before swap.
30405b261ecSmrg     **********************************************************************
30505b261ecSmrg     */
30605b261ecSmrg
30705b261ecSmrg    switch(swapInfo[0].swapAction)
30805b261ecSmrg    {
30905b261ecSmrg        case XdbeUndefined:
31005b261ecSmrg            break;
31105b261ecSmrg
31205b261ecSmrg        case XdbeBackground:
31305b261ecSmrg            break;
31405b261ecSmrg
31505b261ecSmrg        case XdbeUntouched:
31605b261ecSmrg            ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, pGC);
31705b261ecSmrg            (*pGC->ops->CopyArea)((DrawablePtr)pWin,
31805b261ecSmrg                                  (DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
31905b261ecSmrg                                  pGC, 0, 0, pWin->drawable.width,
32005b261ecSmrg                                  pWin->drawable.height, 0, 0);
32105b261ecSmrg            break;
32205b261ecSmrg
32305b261ecSmrg        case XdbeCopied:
32405b261ecSmrg            break;
32505b261ecSmrg
32605b261ecSmrg    }
32705b261ecSmrg
32805b261ecSmrg    /*
32905b261ecSmrg     **********************************************************************
33005b261ecSmrg     ** Swap.
33105b261ecSmrg     **********************************************************************
33205b261ecSmrg     */
33305b261ecSmrg
33405b261ecSmrg    ValidateGC((DrawablePtr)pWin, pGC);
33505b261ecSmrg    (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
33605b261ecSmrg                          (DrawablePtr)pWin, pGC, 0, 0,
33705b261ecSmrg                          pWin->drawable.width, pWin->drawable.height,
33805b261ecSmrg                          0, 0);
33905b261ecSmrg
34005b261ecSmrg    /*
34105b261ecSmrg     **********************************************************************
34205b261ecSmrg     ** Tasks after swap.
34305b261ecSmrg     **********************************************************************
34405b261ecSmrg     */
34505b261ecSmrg
34605b261ecSmrg    switch(swapInfo[0].swapAction)
34705b261ecSmrg    {
34805b261ecSmrg        case XdbeUndefined:
34905b261ecSmrg            break;
35005b261ecSmrg
35105b261ecSmrg        case XdbeBackground:
35205b261ecSmrg            if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
35305b261ecSmrg            {
35405b261ecSmrg                ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
35505b261ecSmrg                clearRect.x = 0;
35605b261ecSmrg                clearRect.y = 0;
35705b261ecSmrg                clearRect.width =
35805b261ecSmrg                    pDbeWindowPrivPriv->pBackBuffer->drawable.width;
35905b261ecSmrg                clearRect.height =
36005b261ecSmrg                    pDbeWindowPrivPriv->pBackBuffer->drawable.height;
36105b261ecSmrg                (*pGC->ops->PolyFillRect)(
36205b261ecSmrg				(DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
36305b261ecSmrg				pGC, 1, &clearRect);
36405b261ecSmrg	    }
36505b261ecSmrg            break;
36605b261ecSmrg
36705b261ecSmrg        case XdbeUntouched:
36805b261ecSmrg            /* Swap pixmap pointers. */
36905b261ecSmrg            pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer;
37005b261ecSmrg            pDbeWindowPrivPriv->pBackBuffer =
37105b261ecSmrg                pDbeWindowPrivPriv->pFrontBuffer;
37205b261ecSmrg            pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer;
37305b261ecSmrg
37405b261ecSmrg            miDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv);
37505b261ecSmrg
37605b261ecSmrg            break;
37705b261ecSmrg
37805b261ecSmrg        case XdbeCopied:
37905b261ecSmrg            break;
38005b261ecSmrg
38105b261ecSmrg    }
38205b261ecSmrg
38305b261ecSmrg    /* Remove the swapped window from the swap information array and decrement
38405b261ecSmrg     * pNumWindows to indicate to the DIX level how many windows were actually
38505b261ecSmrg     * swapped.
38605b261ecSmrg     */
38705b261ecSmrg
38805b261ecSmrg    if (*pNumWindows > 1)
38905b261ecSmrg    {
39005b261ecSmrg        /* We were told to swap more than one window, but we only swapped the
39105b261ecSmrg         * first one.  Remove the first window in the list by moving the last
39205b261ecSmrg         * window to the beginning.
39305b261ecSmrg         */
39405b261ecSmrg        swapInfo[0].pWindow    = swapInfo[*pNumWindows - 1].pWindow;
39505b261ecSmrg        swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction;
39605b261ecSmrg
39705b261ecSmrg        /* Clear the last window information just to be safe. */
39805b261ecSmrg        swapInfo[*pNumWindows - 1].pWindow    = (WindowPtr)NULL;
39905b261ecSmrg        swapInfo[*pNumWindows - 1].swapAction = 0;
40005b261ecSmrg    }
40105b261ecSmrg    else
40205b261ecSmrg    {
40305b261ecSmrg        /* Clear the window information just to be safe. */
40405b261ecSmrg        swapInfo[0].pWindow    = (WindowPtr)NULL;
40505b261ecSmrg        swapInfo[0].swapAction = 0;
40605b261ecSmrg    }
40705b261ecSmrg
40805b261ecSmrg    (*pNumWindows)--;
40905b261ecSmrg
41005b261ecSmrg    FreeScratchGC(pGC);
41105b261ecSmrg
41205b261ecSmrg    return(Success);
41305b261ecSmrg
41405b261ecSmrg} /* miSwapBuffers() */
41505b261ecSmrg
41605b261ecSmrg
41705b261ecSmrg/******************************************************************************
41805b261ecSmrg *
41905b261ecSmrg * DBE MI Procedure: miDbeWinPrivDelete
42005b261ecSmrg *
42105b261ecSmrg * Description:
42205b261ecSmrg *
42305b261ecSmrg *     This is the MI function for deleting the dbeWindowPrivResType resource.
42405b261ecSmrg *     This function is invoked indirectly by calling FreeResource() to free
42505b261ecSmrg *     the resources associated with a DBE buffer ID.  There are 5 ways that
42605b261ecSmrg *     miDbeWinPrivDelete() can be called by FreeResource().  They are:
42705b261ecSmrg *
42805b261ecSmrg *     - A DBE window is destroyed, in which case the DbeDestroyWindow()
42905b261ecSmrg *       wrapper is invoked.  The wrapper calls FreeResource() for all DBE
43005b261ecSmrg *       buffer IDs.
43105b261ecSmrg *
43205b261ecSmrg *     - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
43305b261ecSmrg *       after a buffer allocation failure.
43405b261ecSmrg *
43505b261ecSmrg *     - The PositionWindow wrapper, miDbePositionWindow(), calls
43605b261ecSmrg *       FreeResource() when it fails to create buffers of the new size.
43705b261ecSmrg *       FreeResource() is called for all DBE buffer IDs.
43805b261ecSmrg *
43905b261ecSmrg *     - FreeClientResources() calls FreeResource() when a client dies or the
44005b261ecSmrg *       the server resets.
44105b261ecSmrg *
44205b261ecSmrg *     When FreeResource() is called for a DBE buffer ID, the delete function
44305b261ecSmrg *     for the only other type of DBE resource, dbeDrawableResType, is also
44405b261ecSmrg *     invoked.  This delete function (DbeDrawableDelete) is a NOOP to make
44505b261ecSmrg *     resource deletion easier.  It is not guaranteed which delete function is
44605b261ecSmrg *     called first.  Hence, we will let miDbeWinPrivDelete() free all DBE
44705b261ecSmrg *     resources.
44805b261ecSmrg *
44905b261ecSmrg *     This function deletes/frees the following stuff associated with
45005b261ecSmrg *     the window private:
45105b261ecSmrg *
45205b261ecSmrg *     - the ID node in the ID list representing the passed in ID.
45305b261ecSmrg *
45405b261ecSmrg *     In addition, pDbeWindowPriv->nBufferIDs is decremented.
45505b261ecSmrg *
45605b261ecSmrg *     If this function is called for the last/only buffer ID for a window,
45705b261ecSmrg *     these are additionally deleted/freed:
45805b261ecSmrg *
45905b261ecSmrg *     - the front and back pixmaps
46005b261ecSmrg *     - the window priv itself
46105b261ecSmrg *
46205b261ecSmrg *****************************************************************************/
46305b261ecSmrg
46405b261ecSmrgstatic void
46505b261ecSmrgmiDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId)
46605b261ecSmrg{
46705b261ecSmrg    MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv;
46805b261ecSmrg
46905b261ecSmrg
47005b261ecSmrg    if (pDbeWindowPriv->nBufferIDs != 0)
47105b261ecSmrg    {
47205b261ecSmrg        /* We still have at least one more buffer ID associated with this
47305b261ecSmrg         * window.
47405b261ecSmrg         */
47505b261ecSmrg        return;
47605b261ecSmrg    }
47705b261ecSmrg
47805b261ecSmrg
47905b261ecSmrg    /* We have no more buffer IDs associated with this window.  We need to
48005b261ecSmrg     * free some stuff.
48105b261ecSmrg     */
48205b261ecSmrg
48305b261ecSmrg    pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
48405b261ecSmrg
48505b261ecSmrg    /* Destroy the front and back pixmaps. */
48605b261ecSmrg    if (pDbeWindowPrivPriv->pFrontBuffer)
48705b261ecSmrg    {
48805b261ecSmrg        (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
48905b261ecSmrg            pDbeWindowPrivPriv->pFrontBuffer);
49005b261ecSmrg    }
49105b261ecSmrg    if (pDbeWindowPrivPriv->pBackBuffer)
49205b261ecSmrg    {
49305b261ecSmrg        (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
49405b261ecSmrg            pDbeWindowPrivPriv->pBackBuffer);
49505b261ecSmrg    }
49605b261ecSmrg
49705b261ecSmrg} /* miDbeWinPrivDelete() */
49805b261ecSmrg
49905b261ecSmrg
50005b261ecSmrg/******************************************************************************
50105b261ecSmrg *
50205b261ecSmrg * DBE MI Procedure: miDbePositionWindow
50305b261ecSmrg *
50405b261ecSmrg * Description:
50505b261ecSmrg *
50605b261ecSmrg *     This function was cloned from miMbxPositionWindow() in mimultibuf.c.
50705b261ecSmrg *     This function resizes the buffer when the window is resized.
50805b261ecSmrg *
50905b261ecSmrg *****************************************************************************/
51005b261ecSmrg
51105b261ecSmrgstatic Bool
51205b261ecSmrgmiDbePositionWindow(WindowPtr pWin, int x, int y)
51305b261ecSmrg{
51405b261ecSmrg    ScreenPtr			pScreen;
51505b261ecSmrg    DbeScreenPrivPtr		pDbeScreenPriv;
51605b261ecSmrg    DbeWindowPrivPtr		pDbeWindowPriv;
51705b261ecSmrg    int				width, height;
51805b261ecSmrg    int				dx, dy, dw, dh;
51905b261ecSmrg    int				sourcex, sourcey;
52005b261ecSmrg    int				destx, desty;
52105b261ecSmrg    int				savewidth, saveheight;
52205b261ecSmrg    PixmapPtr			pFrontBuffer;
52305b261ecSmrg    PixmapPtr			pBackBuffer;
52405b261ecSmrg    Bool			clear;
52505b261ecSmrg    GCPtr			pGC;
52605b261ecSmrg    xRectangle			clearRect;
52705b261ecSmrg    Bool			ret;
52805b261ecSmrg
52905b261ecSmrg
53005b261ecSmrg    /*
53105b261ecSmrg     **************************************************************************
53205b261ecSmrg     ** 1. Unwrap the member routine.
53305b261ecSmrg     **************************************************************************
53405b261ecSmrg     */
53505b261ecSmrg
53605b261ecSmrg    pScreen                 = pWin->drawable.pScreen;
53705b261ecSmrg    pDbeScreenPriv          = DBE_SCREEN_PRIV(pScreen);
53805b261ecSmrg    pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
53905b261ecSmrg
54005b261ecSmrg    /*
54105b261ecSmrg     **************************************************************************
54205b261ecSmrg     ** 2. Do any work necessary before the member routine is called.
54305b261ecSmrg     **
54405b261ecSmrg     **    In this case we do not need to do anything.
54505b261ecSmrg     **************************************************************************
54605b261ecSmrg     */
54705b261ecSmrg
54805b261ecSmrg    /*
54905b261ecSmrg     **************************************************************************
55005b261ecSmrg     ** 3. Call the member routine, saving its result if necessary.
55105b261ecSmrg     **************************************************************************
55205b261ecSmrg     */
55305b261ecSmrg
55405b261ecSmrg    ret = (*pScreen->PositionWindow)(pWin, x, y);
55505b261ecSmrg
55605b261ecSmrg    /*
55705b261ecSmrg     **************************************************************************
55805b261ecSmrg     ** 4. Rewrap the member routine, restoring the wrapper value first in case
55905b261ecSmrg     **    the wrapper (or something that it wrapped) change this value.
56005b261ecSmrg     **************************************************************************
56105b261ecSmrg     */
56205b261ecSmrg
56305b261ecSmrg    pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
56405b261ecSmrg    pScreen->PositionWindow = miDbePositionWindow;
56505b261ecSmrg
56605b261ecSmrg    /*
56705b261ecSmrg     **************************************************************************
56805b261ecSmrg     ** 5. Do any work necessary after the member routine has been called.
56905b261ecSmrg     **************************************************************************
57005b261ecSmrg     */
57105b261ecSmrg
57205b261ecSmrg    if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
57305b261ecSmrg    {
57405b261ecSmrg	return(ret);
57505b261ecSmrg    }
57605b261ecSmrg
57705b261ecSmrg    if (pDbeWindowPriv->width  == pWin->drawable.width &&
57805b261ecSmrg        pDbeWindowPriv->height == pWin->drawable.height)
57905b261ecSmrg    {
58005b261ecSmrg	return(ret);
58105b261ecSmrg    }
58205b261ecSmrg
58305b261ecSmrg    width  = pWin->drawable.width;
58405b261ecSmrg    height = pWin->drawable.height;
58505b261ecSmrg
58605b261ecSmrg    dx = pWin->drawable.x - pDbeWindowPriv->x;
58705b261ecSmrg    dy = pWin->drawable.y - pDbeWindowPriv->y;
58805b261ecSmrg    dw = width  - pDbeWindowPriv->width;
58905b261ecSmrg    dh = height - pDbeWindowPriv->height;
59005b261ecSmrg
59105b261ecSmrg    GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty);
59205b261ecSmrg
59305b261ecSmrg    clear = ((pDbeWindowPriv->width  < (unsigned short)width ) ||
59405b261ecSmrg             (pDbeWindowPriv->height < (unsigned short)height) ||
59505b261ecSmrg             (pWin->bitGravity == ForgetGravity));
59605b261ecSmrg
59705b261ecSmrg    sourcex = 0;
59805b261ecSmrg    sourcey = 0;
59905b261ecSmrg    savewidth  = pDbeWindowPriv->width;
60005b261ecSmrg    saveheight = pDbeWindowPriv->height;
60105b261ecSmrg
60205b261ecSmrg    /* Clip rectangle to source and destination. */
60305b261ecSmrg    if (destx < 0)
60405b261ecSmrg    {
60505b261ecSmrg	savewidth += destx;
60605b261ecSmrg	sourcex   -= destx;
60705b261ecSmrg	destx      = 0;
60805b261ecSmrg    }
60905b261ecSmrg
61005b261ecSmrg    if (destx + savewidth > width)
61105b261ecSmrg    {
61205b261ecSmrg	savewidth = width - destx;
61305b261ecSmrg    }
61405b261ecSmrg
61505b261ecSmrg    if (desty < 0)
61605b261ecSmrg    {
61705b261ecSmrg	saveheight += desty;
61805b261ecSmrg	sourcey    -= desty;
61905b261ecSmrg	desty       = 0;
62005b261ecSmrg    }
62105b261ecSmrg
62205b261ecSmrg    if (desty + saveheight > height)
62305b261ecSmrg    {
62405b261ecSmrg	saveheight = height - desty;
62505b261ecSmrg    }
62605b261ecSmrg
62705b261ecSmrg    pDbeWindowPriv->width  = width;
62805b261ecSmrg    pDbeWindowPriv->height = height;
62905b261ecSmrg    pDbeWindowPriv->x = pWin->drawable.x;
63005b261ecSmrg    pDbeWindowPriv->y = pWin->drawable.y;
63105b261ecSmrg
63205b261ecSmrg    pGC = GetScratchGC (pWin->drawable.depth, pScreen);
63305b261ecSmrg
63405b261ecSmrg    if (clear)
63505b261ecSmrg    {
63605b261ecSmrg	if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
63705b261ecSmrg	{
63805b261ecSmrg	    clearRect.x = 0;
63905b261ecSmrg	    clearRect.y = 0;
64005b261ecSmrg	    clearRect.width  = width;
64105b261ecSmrg	    clearRect.height = height;
64205b261ecSmrg	}
64305b261ecSmrg	else
64405b261ecSmrg	{
64505b261ecSmrg	    clear = FALSE;
64605b261ecSmrg	}
64705b261ecSmrg    }
64805b261ecSmrg
64905b261ecSmrg    /* Create DBE buffer pixmaps equal to size of resized window. */
65005b261ecSmrg    pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
65105b261ecSmrg					    pWin->drawable.depth);
65205b261ecSmrg
65305b261ecSmrg    pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
65405b261ecSmrg					   pWin->drawable.depth);
65505b261ecSmrg
65605b261ecSmrg    if (!pFrontBuffer || !pBackBuffer)
65705b261ecSmrg    {
65805b261ecSmrg        /* We failed at creating 1 or 2 of the pixmaps. */
65905b261ecSmrg
66005b261ecSmrg        if (pFrontBuffer)
66105b261ecSmrg        {
66205b261ecSmrg	    (*pScreen->DestroyPixmap)(pFrontBuffer);
66305b261ecSmrg        }
66405b261ecSmrg
66505b261ecSmrg        if (pBackBuffer)
66605b261ecSmrg        {
66705b261ecSmrg	    (*pScreen->DestroyPixmap)(pBackBuffer);
66805b261ecSmrg        }
66905b261ecSmrg
67005b261ecSmrg        /* Destroy all buffers for this window. */
67105b261ecSmrg        while (pDbeWindowPriv)
67205b261ecSmrg        {
67305b261ecSmrg            /* DbeWindowPrivDelete() will free the window private if there no
67405b261ecSmrg             * more buffer IDs associated with this window.
67505b261ecSmrg             */
67605b261ecSmrg            FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
67705b261ecSmrg            pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
67805b261ecSmrg        }
67905b261ecSmrg
68005b261ecSmrg        FreeScratchGC(pGC);
68105b261ecSmrg        return(FALSE);
68205b261ecSmrg    }
68305b261ecSmrg
68405b261ecSmrg    else
68505b261ecSmrg    {
68605b261ecSmrg        /* Clear out the new DBE buffer pixmaps. */
68705b261ecSmrg
68805b261ecSmrg        MiDbeWindowPrivPrivPtr	pDbeWindowPrivPriv;
68905b261ecSmrg
69005b261ecSmrg
69105b261ecSmrg        pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
69205b261ecSmrg        ValidateGC((DrawablePtr)pFrontBuffer, pGC);
69305b261ecSmrg
69405b261ecSmrg	/* I suppose this could avoid quite a bit of work if
69505b261ecSmrg	 * it computed the minimal area required.
69605b261ecSmrg	 */
69705b261ecSmrg	if (clear)
69805b261ecSmrg        {
69905b261ecSmrg	    (*pGC->ops->PolyFillRect)((DrawablePtr)pFrontBuffer, pGC, 1,
70005b261ecSmrg				      &clearRect);
70105b261ecSmrg	    (*pGC->ops->PolyFillRect)((DrawablePtr)pBackBuffer , pGC, 1,
70205b261ecSmrg				      &clearRect);
70305b261ecSmrg        }
70405b261ecSmrg
70505b261ecSmrg        /* Copy the contents of the old DBE pixmaps to the new pixmaps. */
70605b261ecSmrg	if (pWin->bitGravity != ForgetGravity)
70705b261ecSmrg	{
70805b261ecSmrg	    (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
70905b261ecSmrg                                  (DrawablePtr)pFrontBuffer, pGC, sourcex,
71005b261ecSmrg                                  sourcey, savewidth, saveheight, destx, desty);
71105b261ecSmrg	    (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
71205b261ecSmrg                                  (DrawablePtr)pBackBuffer, pGC, sourcex,
71305b261ecSmrg                                  sourcey, savewidth, saveheight, destx, desty);
71405b261ecSmrg	}
71505b261ecSmrg
71605b261ecSmrg        /* Destroy the old pixmaps, and point the DBE window priv to the new
71705b261ecSmrg         * pixmaps.
71805b261ecSmrg         */
71905b261ecSmrg
72005b261ecSmrg	(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
72105b261ecSmrg	(*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer);
72205b261ecSmrg
72305b261ecSmrg        pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer;
72405b261ecSmrg        pDbeWindowPrivPriv->pBackBuffer  = pBackBuffer;
72505b261ecSmrg
72605b261ecSmrg	/* Make sure all XID are associated with the new back pixmap. */
72705b261ecSmrg        miDbeAliasBuffers(pDbeWindowPriv);
72805b261ecSmrg
72905b261ecSmrg        FreeScratchGC(pGC);
73005b261ecSmrg    }
73105b261ecSmrg
73205b261ecSmrg    return(ret);
73305b261ecSmrg
73405b261ecSmrg} /* miDbePositionWindow() */
73505b261ecSmrg
73605b261ecSmrg
73705b261ecSmrg/******************************************************************************
73805b261ecSmrg *
73905b261ecSmrg * DBE MI Procedure: miDbeResetProc
74005b261ecSmrg *
74105b261ecSmrg * Description:
74205b261ecSmrg *
74305b261ecSmrg *     This function is called from DbeResetProc(), which is called at the end
74405b261ecSmrg *     of every server generation.  This function peforms any MI-specific
74505b261ecSmrg *     shutdown tasks.
74605b261ecSmrg *
74705b261ecSmrg *****************************************************************************/
74805b261ecSmrg
74905b261ecSmrgstatic void
75005b261ecSmrgmiDbeResetProc(ScreenPtr pScreen)
75105b261ecSmrg{
75205b261ecSmrg    DbeScreenPrivPtr    pDbeScreenPriv;
75305b261ecSmrg
75405b261ecSmrg
75505b261ecSmrg    pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
75605b261ecSmrg
75705b261ecSmrg    /* Unwrap wrappers */
75805b261ecSmrg    pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
75905b261ecSmrg
76005b261ecSmrg} /* miDbeResetProc() */
76105b261ecSmrg
76205b261ecSmrg
76305b261ecSmrg/******************************************************************************
76405b261ecSmrg *
76505b261ecSmrg * DBE MI Procedure: miDbeInit
76605b261ecSmrg *
76705b261ecSmrg * Description:
76805b261ecSmrg *
76905b261ecSmrg *     This is the MI initialization function called by DbeExtensionInit().
77005b261ecSmrg *
77105b261ecSmrg *****************************************************************************/
77205b261ecSmrg
77305b261ecSmrgBool
77405b261ecSmrgmiDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv)
77505b261ecSmrg{
77605b261ecSmrg    /* Copy resource types created by DIX */
77705b261ecSmrg    dbeDrawableResType   = pDbeScreenPriv->dbeDrawableResType;
77805b261ecSmrg    dbeWindowPrivResType = pDbeScreenPriv->dbeWindowPrivResType;
77905b261ecSmrg
78005b261ecSmrg    /* Copy private indices created by DIX */
78105b261ecSmrg    dbeScreenPrivIndex = pDbeScreenPriv->dbeScreenPrivIndex;
78205b261ecSmrg    dbeWindowPrivIndex = pDbeScreenPriv->dbeWindowPrivIndex;
78305b261ecSmrg
78405b261ecSmrg    /* Reset the window priv privs if generations do not match. */
78505b261ecSmrg    if (miDbePrivPrivGeneration != serverGeneration)
78605b261ecSmrg    {
78705b261ecSmrg        /*
78805b261ecSmrg         **********************************************************************
78905b261ecSmrg         ** Allocate the window priv priv.
79005b261ecSmrg         **********************************************************************
79105b261ecSmrg         */
79205b261ecSmrg
79305b261ecSmrg        miDbeWindowPrivPrivIndex = (*pDbeScreenPriv->AllocWinPrivPrivIndex)();
79405b261ecSmrg
79505b261ecSmrg        /* Make sure we only do this code once. */
79605b261ecSmrg	miDbePrivPrivGeneration = serverGeneration;
79705b261ecSmrg
79805b261ecSmrg    } /* if -- Reset priv privs. */
79905b261ecSmrg
80005b261ecSmrg    if (!(*pDbeScreenPriv->AllocWinPrivPriv)(pScreen,
80105b261ecSmrg        miDbeWindowPrivPrivIndex, sizeof(MiDbeWindowPrivPrivRec)))
80205b261ecSmrg    {
80305b261ecSmrg        return(FALSE);
80405b261ecSmrg    }
80505b261ecSmrg
80605b261ecSmrg    /* Wrap functions. */
80705b261ecSmrg    pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
80805b261ecSmrg    pScreen->PositionWindow        = miDbePositionWindow;
80905b261ecSmrg
81005b261ecSmrg    /* Initialize the per-screen DBE function pointers. */
81105b261ecSmrg    pDbeScreenPriv->GetVisualInfo         = miDbeGetVisualInfo;
81205b261ecSmrg    pDbeScreenPriv->AllocBackBufferName   = miDbeAllocBackBufferName;
81305b261ecSmrg    pDbeScreenPriv->SwapBuffers           = miDbeSwapBuffers;
81405b261ecSmrg    pDbeScreenPriv->BeginIdiom            = 0;
81505b261ecSmrg    pDbeScreenPriv->EndIdiom              = 0;
81605b261ecSmrg    pDbeScreenPriv->ResetProc             = miDbeResetProc;
81705b261ecSmrg    pDbeScreenPriv->WinPrivDelete         = miDbeWinPrivDelete;
81805b261ecSmrg
81905b261ecSmrg    return(TRUE);
82005b261ecSmrg
82105b261ecSmrg} /* miDbeInit() */
822