105b261ecSmrg/******************************************************************************
235c4bbdfSmrg *
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:
1235c4bbdfSmrg *
1305b261ecSmrg * The above copyright notice and this permission notice shall be included
1405b261ecSmrg * in all copies or substantial portions of the Software.
1535c4bbdfSmrg *
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.
2335c4bbdfSmrg *
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.
2835c4bbdfSmrg *
2905b261ecSmrg *     Machine-independent DBE code
3005b261ecSmrg *
3105b261ecSmrg *****************************************************************************/
3205b261ecSmrg
3305b261ecSmrg/* INCLUDES */
3405b261ecSmrg
3505b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3605b261ecSmrg#include <dix-config.h>
3705b261ecSmrg#endif
3805b261ecSmrg
3905b261ecSmrg#include <X11/X.h>
4005b261ecSmrg#include <X11/Xproto.h>
4105b261ecSmrg#include "misc.h"
4205b261ecSmrg#include "os.h"
4305b261ecSmrg#include "windowstr.h"
4405b261ecSmrg#include "scrnintstr.h"
4505b261ecSmrg#include "pixmapstr.h"
4605b261ecSmrg#include "extnsionst.h"
4705b261ecSmrg#include "dixstruct.h"
4805b261ecSmrg#include "resource.h"
4905b261ecSmrg#include "opaque.h"
5005b261ecSmrg#include "dbestruct.h"
5105b261ecSmrg#include "regionstr.h"
5205b261ecSmrg#include "gcstruct.h"
5305b261ecSmrg#include "inputstr.h"
5405b261ecSmrg#include "midbe.h"
554642e01fSmrg#include "xace.h"
5605b261ecSmrg
5705b261ecSmrg#include <stdio.h>
5805b261ecSmrg
5905b261ecSmrg
6005b261ecSmrg/******************************************************************************
6105b261ecSmrg *
6205b261ecSmrg * DBE MI Procedure: miDbeGetVisualInfo
6305b261ecSmrg *
6405b261ecSmrg * Description:
6505b261ecSmrg *
6605b261ecSmrg *     This is the MI function for the DbeGetVisualInfo request.  This function
6705b261ecSmrg *     is called through pDbeScreenPriv->GetVisualInfo.  This function is also
6805b261ecSmrg *     called for the DbeAllocateBackBufferName request at the extension level;
6905b261ecSmrg *     it is called by ProcDbeAllocateBackBufferName() in dbe.c.
7005b261ecSmrg *
7105b261ecSmrg *     If memory allocation fails or we can not get the visual info, this
7205b261ecSmrg *     function returns FALSE.  Otherwise, it returns TRUE for success.
7305b261ecSmrg *
7405b261ecSmrg *****************************************************************************/
7505b261ecSmrg
7605b261ecSmrgstatic Bool
7735c4bbdfSmrgmiDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo * pScrVisInfo)
7805b261ecSmrg{
7935c4bbdfSmrg    register int i, j, k;
8035c4bbdfSmrg    register int count;
8135c4bbdfSmrg    DepthPtr pDepth;
8235c4bbdfSmrg    XdbeVisualInfo *visInfo;
8305b261ecSmrg
8405b261ecSmrg    /* Determine number of visuals for this screen. */
8535c4bbdfSmrg    for (i = 0, count = 0; i < pScreen->numDepths; i++) {
8605b261ecSmrg        count += pScreen->allowedDepths[i].numVids;
8705b261ecSmrg    }
8805b261ecSmrg
8905b261ecSmrg    /* Allocate an array of XdbeVisualInfo items. */
9035c4bbdfSmrg    if (!(visInfo = xallocarray(count, sizeof(XdbeVisualInfo)))) {
9135c4bbdfSmrg        return FALSE;           /* memory alloc failure */
9205b261ecSmrg    }
9305b261ecSmrg
9435c4bbdfSmrg    for (i = 0, k = 0; i < pScreen->numDepths; i++) {
9505b261ecSmrg        /* For each depth of this screen, get visual information. */
9605b261ecSmrg
9705b261ecSmrg        pDepth = &pScreen->allowedDepths[i];
9805b261ecSmrg
9935c4bbdfSmrg        for (j = 0; j < pDepth->numVids; j++) {
10005b261ecSmrg            /* For each visual for this depth of this screen, get visual ID
10105b261ecSmrg             * and visual depth.  Since this is MI code, we will always return
10205b261ecSmrg             * the same performance level for all visuals (0).  A higher
10305b261ecSmrg             * performance level value indicates higher performance.
10405b261ecSmrg             */
10535c4bbdfSmrg            visInfo[k].visual = pDepth->vids[j];
10635c4bbdfSmrg            visInfo[k].depth = pDepth->depth;
10705b261ecSmrg            visInfo[k].perflevel = 0;
10805b261ecSmrg            k++;
10905b261ecSmrg        }
11005b261ecSmrg    }
11105b261ecSmrg
11205b261ecSmrg    /* Record the number of visuals and point visual_depth to
11305b261ecSmrg     * the array of visual info.
11405b261ecSmrg     */
11535c4bbdfSmrg    pScrVisInfo->count = count;
11605b261ecSmrg    pScrVisInfo->visinfo = visInfo;
11705b261ecSmrg
11835c4bbdfSmrg    return TRUE;                /* success */
11905b261ecSmrg
12035c4bbdfSmrg}                               /* miDbeGetVisualInfo() */
12105b261ecSmrg
12205b261ecSmrg/******************************************************************************
12305b261ecSmrg *
12405b261ecSmrg * DBE MI Procedure: miAllocBackBufferName
12505b261ecSmrg *
12605b261ecSmrg * Description:
12705b261ecSmrg *
12805b261ecSmrg *     This is the MI function for the DbeAllocateBackBufferName request.
12905b261ecSmrg *
13005b261ecSmrg *****************************************************************************/
13105b261ecSmrg
13205b261ecSmrgstatic int
13305b261ecSmrgmiDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
13405b261ecSmrg{
13535c4bbdfSmrg    ScreenPtr pScreen;
13635c4bbdfSmrg    DbeWindowPrivPtr pDbeWindowPriv;
13735c4bbdfSmrg    DbeScreenPrivPtr pDbeScreenPriv;
13835c4bbdfSmrg    GCPtr pGC;
13935c4bbdfSmrg    xRectangle clearRect;
14035c4bbdfSmrg    int rc;
14105b261ecSmrg
14205b261ecSmrg    pScreen = pWin->drawable.pScreen;
14305b261ecSmrg    pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
14405b261ecSmrg
14535c4bbdfSmrg    if (pDbeWindowPriv->nBufferIDs == 0) {
14605b261ecSmrg        /* There is no buffer associated with the window.
14705b261ecSmrg         * We have to create the window priv priv.  Remember, the window
14805b261ecSmrg         * priv was created at the DIX level, so all we need to do is
14905b261ecSmrg         * create the priv priv and attach it to the priv.
15005b261ecSmrg         */
15105b261ecSmrg
15205b261ecSmrg        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
15305b261ecSmrg
15405b261ecSmrg        /* Get a front pixmap. */
15535c4bbdfSmrg        if (!(pDbeWindowPriv->pFrontBuffer =
15635c4bbdfSmrg              (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width,
15735c4bbdfSmrg                                        pDbeWindowPriv->height,
15835c4bbdfSmrg                                        pWin->drawable.depth, 0))) {
1596747b715Smrg            return BadAlloc;
16005b261ecSmrg        }
16105b261ecSmrg
16205b261ecSmrg        /* Get a back pixmap. */
16335c4bbdfSmrg        if (!(pDbeWindowPriv->pBackBuffer =
16435c4bbdfSmrg              (*pScreen->CreatePixmap) (pScreen, pDbeWindowPriv->width,
16535c4bbdfSmrg                                        pDbeWindowPriv->height,
16635c4bbdfSmrg                                        pWin->drawable.depth, 0))) {
16735c4bbdfSmrg            (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer);
1686747b715Smrg            return BadAlloc;
16905b261ecSmrg        }
17005b261ecSmrg
17135c4bbdfSmrg        /* Security creation/labeling check. */
17235c4bbdfSmrg        rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId,
17335c4bbdfSmrg                      dbeDrawableResType, pDbeWindowPriv->pBackBuffer,
17435c4bbdfSmrg                      RT_WINDOW, pWin, DixCreateAccess);
17505b261ecSmrg
17605b261ecSmrg        /* Make the back pixmap a DBE drawable resource. */
1774642e01fSmrg        if (rc != Success || !AddResource(bufId, dbeDrawableResType,
17835c4bbdfSmrg                                          pDbeWindowPriv->pBackBuffer)) {
17905b261ecSmrg            /* free the buffer and the drawable resource */
18005b261ecSmrg            FreeResource(bufId, RT_NONE);
1814642e01fSmrg            return (rc == Success) ? BadAlloc : rc;
18205b261ecSmrg        }
18305b261ecSmrg
18405b261ecSmrg        /* Clear the back buffer. */
18505b261ecSmrg        pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
18635c4bbdfSmrg        if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
18735c4bbdfSmrg            ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC);
18805b261ecSmrg            clearRect.x = clearRect.y = 0;
18935c4bbdfSmrg            clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width;
19035c4bbdfSmrg            clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height;
19135c4bbdfSmrg            (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv->
19235c4bbdfSmrg                                       pBackBuffer, pGC, 1, &clearRect);
19305b261ecSmrg        }
19405b261ecSmrg        FreeScratchGC(pGC);
19505b261ecSmrg
19635c4bbdfSmrg    }                           /* if no buffer associated with the window */
19705b261ecSmrg
19835c4bbdfSmrg    else {
19905b261ecSmrg        /* A buffer is already associated with the window.
20005b261ecSmrg         * Place the new buffer ID information at the head of the ID list.
20105b261ecSmrg         */
20205b261ecSmrg
20305b261ecSmrg        /* Associate the new ID with an existing pixmap. */
20405b261ecSmrg        if (!AddResource(bufId, dbeDrawableResType,
20535c4bbdfSmrg                         (void *) pDbeWindowPriv->pBackBuffer)) {
2066747b715Smrg            return BadAlloc;
20705b261ecSmrg        }
20805b261ecSmrg
20905b261ecSmrg    }
21005b261ecSmrg
2116747b715Smrg    return Success;
21205b261ecSmrg
21335c4bbdfSmrg}                               /* miDbeAllocBackBufferName() */
21405b261ecSmrg
21505b261ecSmrg/******************************************************************************
21605b261ecSmrg *
21705b261ecSmrg * DBE MI Procedure: miDbeAliasBuffers
21805b261ecSmrg *
21905b261ecSmrg * Description:
22005b261ecSmrg *
22105b261ecSmrg *     This function associates all XIDs of a buffer with the back pixmap
22205b261ecSmrg *     stored in the window priv.
22305b261ecSmrg *
22405b261ecSmrg *****************************************************************************/
22505b261ecSmrg
22605b261ecSmrgstatic void
22705b261ecSmrgmiDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)
22805b261ecSmrg{
22935c4bbdfSmrg    int i;
23005b261ecSmrg
23135c4bbdfSmrg    for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) {
23205b261ecSmrg        ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType,
23335c4bbdfSmrg                            (void *) pDbeWindowPriv->pBackBuffer);
23405b261ecSmrg    }
23505b261ecSmrg
23635c4bbdfSmrg}                               /* miDbeAliasBuffers() */
23705b261ecSmrg
23805b261ecSmrg/******************************************************************************
23905b261ecSmrg *
24005b261ecSmrg * DBE MI Procedure: miDbeSwapBuffers
24105b261ecSmrg *
24205b261ecSmrg * Description:
24305b261ecSmrg *
24405b261ecSmrg *     This is the MI function for the DbeSwapBuffers request.
24505b261ecSmrg *
24605b261ecSmrg *****************************************************************************/
24705b261ecSmrg
24805b261ecSmrgstatic int
24905b261ecSmrgmiDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo)
25005b261ecSmrg{
25135c4bbdfSmrg    DbeScreenPrivPtr pDbeScreenPriv;
25235c4bbdfSmrg    DbeWindowPrivPtr pDbeWindowPriv;
25335c4bbdfSmrg    GCPtr pGC;
25435c4bbdfSmrg    WindowPtr pWin;
25535c4bbdfSmrg    PixmapPtr pTmpBuffer;
25635c4bbdfSmrg    xRectangle clearRect;
25735c4bbdfSmrg
25835c4bbdfSmrg    pWin = swapInfo[0].pWindow;
25935c4bbdfSmrg    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
26035c4bbdfSmrg    pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
26105b261ecSmrg    pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
26205b261ecSmrg
26305b261ecSmrg    /*
26405b261ecSmrg     **********************************************************************
26505b261ecSmrg     ** Setup before swap.
26605b261ecSmrg     **********************************************************************
26705b261ecSmrg     */
26805b261ecSmrg
26935c4bbdfSmrg    switch (swapInfo[0].swapAction) {
27035c4bbdfSmrg    case XdbeUndefined:
27135c4bbdfSmrg        break;
27205b261ecSmrg
27335c4bbdfSmrg    case XdbeBackground:
27435c4bbdfSmrg        break;
27505b261ecSmrg
27635c4bbdfSmrg    case XdbeUntouched:
27735c4bbdfSmrg        ValidateGC((DrawablePtr) pDbeWindowPriv->pFrontBuffer, pGC);
27835c4bbdfSmrg        (*pGC->ops->CopyArea) ((DrawablePtr) pWin,
27935c4bbdfSmrg                               (DrawablePtr) pDbeWindowPriv->pFrontBuffer,
28035c4bbdfSmrg                               pGC, 0, 0, pWin->drawable.width,
28135c4bbdfSmrg                               pWin->drawable.height, 0, 0);
28235c4bbdfSmrg        break;
28305b261ecSmrg
28435c4bbdfSmrg    case XdbeCopied:
28535c4bbdfSmrg        break;
28605b261ecSmrg
28705b261ecSmrg    }
28805b261ecSmrg
28905b261ecSmrg    /*
29005b261ecSmrg     **********************************************************************
29105b261ecSmrg     ** Swap.
29205b261ecSmrg     **********************************************************************
29305b261ecSmrg     */
29405b261ecSmrg
29535c4bbdfSmrg    ValidateGC((DrawablePtr) pWin, pGC);
29635c4bbdfSmrg    (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer,
29735c4bbdfSmrg                           (DrawablePtr) pWin, pGC, 0, 0,
29835c4bbdfSmrg                           pWin->drawable.width, pWin->drawable.height, 0, 0);
29905b261ecSmrg
30005b261ecSmrg    /*
30105b261ecSmrg     **********************************************************************
30205b261ecSmrg     ** Tasks after swap.
30305b261ecSmrg     **********************************************************************
30405b261ecSmrg     */
30505b261ecSmrg
30635c4bbdfSmrg    switch (swapInfo[0].swapAction) {
30735c4bbdfSmrg    case XdbeUndefined:
30835c4bbdfSmrg        break;
30935c4bbdfSmrg
31035c4bbdfSmrg    case XdbeBackground:
31135c4bbdfSmrg        if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
31235c4bbdfSmrg            ValidateGC((DrawablePtr) pDbeWindowPriv->pBackBuffer, pGC);
31335c4bbdfSmrg            clearRect.x = 0;
31435c4bbdfSmrg            clearRect.y = 0;
31535c4bbdfSmrg            clearRect.width = pDbeWindowPriv->pBackBuffer->drawable.width;
31635c4bbdfSmrg            clearRect.height = pDbeWindowPriv->pBackBuffer->drawable.height;
31735c4bbdfSmrg            (*pGC->ops->PolyFillRect) ((DrawablePtr) pDbeWindowPriv->
31835c4bbdfSmrg                                       pBackBuffer, pGC, 1, &clearRect);
31935c4bbdfSmrg        }
32035c4bbdfSmrg        break;
32135c4bbdfSmrg
32235c4bbdfSmrg    case XdbeUntouched:
32335c4bbdfSmrg        /* Swap pixmap pointers. */
32435c4bbdfSmrg        pTmpBuffer = pDbeWindowPriv->pBackBuffer;
32535c4bbdfSmrg        pDbeWindowPriv->pBackBuffer = pDbeWindowPriv->pFrontBuffer;
32635c4bbdfSmrg        pDbeWindowPriv->pFrontBuffer = pTmpBuffer;
32735c4bbdfSmrg
32835c4bbdfSmrg        miDbeAliasBuffers(pDbeWindowPriv);
32935c4bbdfSmrg
33035c4bbdfSmrg        break;
33135c4bbdfSmrg
33235c4bbdfSmrg    case XdbeCopied:
33335c4bbdfSmrg        break;
33405b261ecSmrg
33505b261ecSmrg    }
33605b261ecSmrg
33705b261ecSmrg    /* Remove the swapped window from the swap information array and decrement
33805b261ecSmrg     * pNumWindows to indicate to the DIX level how many windows were actually
33905b261ecSmrg     * swapped.
34005b261ecSmrg     */
34105b261ecSmrg
34235c4bbdfSmrg    if (*pNumWindows > 1) {
34305b261ecSmrg        /* We were told to swap more than one window, but we only swapped the
34405b261ecSmrg         * first one.  Remove the first window in the list by moving the last
34505b261ecSmrg         * window to the beginning.
34605b261ecSmrg         */
34735c4bbdfSmrg        swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow;
34805b261ecSmrg        swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction;
34905b261ecSmrg
35005b261ecSmrg        /* Clear the last window information just to be safe. */
35135c4bbdfSmrg        swapInfo[*pNumWindows - 1].pWindow = (WindowPtr) NULL;
35205b261ecSmrg        swapInfo[*pNumWindows - 1].swapAction = 0;
35305b261ecSmrg    }
35435c4bbdfSmrg    else {
35505b261ecSmrg        /* Clear the window information just to be safe. */
35635c4bbdfSmrg        swapInfo[0].pWindow = (WindowPtr) NULL;
35705b261ecSmrg        swapInfo[0].swapAction = 0;
35805b261ecSmrg    }
35905b261ecSmrg
36005b261ecSmrg    (*pNumWindows)--;
36105b261ecSmrg
36205b261ecSmrg    FreeScratchGC(pGC);
36305b261ecSmrg
3646747b715Smrg    return Success;
36505b261ecSmrg
36635c4bbdfSmrg}                               /* miSwapBuffers() */
36705b261ecSmrg
36805b261ecSmrg/******************************************************************************
36905b261ecSmrg *
37005b261ecSmrg * DBE MI Procedure: miDbeWinPrivDelete
37105b261ecSmrg *
37205b261ecSmrg * Description:
37305b261ecSmrg *
37405b261ecSmrg *     This is the MI function for deleting the dbeWindowPrivResType resource.
37505b261ecSmrg *     This function is invoked indirectly by calling FreeResource() to free
37605b261ecSmrg *     the resources associated with a DBE buffer ID.  There are 5 ways that
37705b261ecSmrg *     miDbeWinPrivDelete() can be called by FreeResource().  They are:
37805b261ecSmrg *
37905b261ecSmrg *     - A DBE window is destroyed, in which case the DbeDestroyWindow()
38005b261ecSmrg *       wrapper is invoked.  The wrapper calls FreeResource() for all DBE
38105b261ecSmrg *       buffer IDs.
38205b261ecSmrg *
38305b261ecSmrg *     - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
38405b261ecSmrg *       after a buffer allocation failure.
38505b261ecSmrg *
38605b261ecSmrg *     - The PositionWindow wrapper, miDbePositionWindow(), calls
38705b261ecSmrg *       FreeResource() when it fails to create buffers of the new size.
38805b261ecSmrg *       FreeResource() is called for all DBE buffer IDs.
38905b261ecSmrg *
39005b261ecSmrg *     - FreeClientResources() calls FreeResource() when a client dies or the
39105b261ecSmrg *       the server resets.
39205b261ecSmrg *
39305b261ecSmrg *     When FreeResource() is called for a DBE buffer ID, the delete function
39405b261ecSmrg *     for the only other type of DBE resource, dbeDrawableResType, is also
39505b261ecSmrg *     invoked.  This delete function (DbeDrawableDelete) is a NOOP to make
39605b261ecSmrg *     resource deletion easier.  It is not guaranteed which delete function is
39705b261ecSmrg *     called first.  Hence, we will let miDbeWinPrivDelete() free all DBE
39805b261ecSmrg *     resources.
39935c4bbdfSmrg *
40005b261ecSmrg *     This function deletes/frees the following stuff associated with
40105b261ecSmrg *     the window private:
40205b261ecSmrg *
40305b261ecSmrg *     - the ID node in the ID list representing the passed in ID.
40405b261ecSmrg *
40505b261ecSmrg *     In addition, pDbeWindowPriv->nBufferIDs is decremented.
40605b261ecSmrg *
40705b261ecSmrg *     If this function is called for the last/only buffer ID for a window,
40805b261ecSmrg *     these are additionally deleted/freed:
40905b261ecSmrg *
41005b261ecSmrg *     - the front and back pixmaps
41105b261ecSmrg *     - the window priv itself
41205b261ecSmrg *
41305b261ecSmrg *****************************************************************************/
41405b261ecSmrg
41505b261ecSmrgstatic void
41605b261ecSmrgmiDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId)
41705b261ecSmrg{
41835c4bbdfSmrg    if (pDbeWindowPriv->nBufferIDs != 0) {
41905b261ecSmrg        /* We still have at least one more buffer ID associated with this
42005b261ecSmrg         * window.
42105b261ecSmrg         */
42205b261ecSmrg        return;
42305b261ecSmrg    }
42405b261ecSmrg
42505b261ecSmrg    /* We have no more buffer IDs associated with this window.  We need to
42605b261ecSmrg     * free some stuff.
42705b261ecSmrg     */
42805b261ecSmrg
42905b261ecSmrg    /* Destroy the front and back pixmaps. */
43035c4bbdfSmrg    if (pDbeWindowPriv->pFrontBuffer) {
43135c4bbdfSmrg        (*pDbeWindowPriv->pWindow->drawable.pScreen->
43235c4bbdfSmrg         DestroyPixmap) (pDbeWindowPriv->pFrontBuffer);
43305b261ecSmrg    }
43435c4bbdfSmrg    if (pDbeWindowPriv->pBackBuffer) {
43535c4bbdfSmrg        (*pDbeWindowPriv->pWindow->drawable.pScreen->
43635c4bbdfSmrg         DestroyPixmap) (pDbeWindowPriv->pBackBuffer);
43705b261ecSmrg    }
43835c4bbdfSmrg}                               /* miDbeWinPrivDelete() */
43905b261ecSmrg
44005b261ecSmrg/******************************************************************************
44105b261ecSmrg *
44205b261ecSmrg * DBE MI Procedure: miDbePositionWindow
44305b261ecSmrg *
44405b261ecSmrg * Description:
44505b261ecSmrg *
44635c4bbdfSmrg *     This function was cloned from miMbxPositionWindow() in mimultibuf.c.
44705b261ecSmrg *     This function resizes the buffer when the window is resized.
44805b261ecSmrg *
44905b261ecSmrg *****************************************************************************/
45005b261ecSmrg
45105b261ecSmrgstatic Bool
45205b261ecSmrgmiDbePositionWindow(WindowPtr pWin, int x, int y)
45305b261ecSmrg{
45435c4bbdfSmrg    ScreenPtr pScreen;
45535c4bbdfSmrg    DbeScreenPrivPtr pDbeScreenPriv;
45635c4bbdfSmrg    DbeWindowPrivPtr pDbeWindowPriv;
45735c4bbdfSmrg    int width, height;
45835c4bbdfSmrg    int dx, dy, dw, dh;
45935c4bbdfSmrg    int sourcex, sourcey;
46035c4bbdfSmrg    int destx, desty;
46135c4bbdfSmrg    int savewidth, saveheight;
46235c4bbdfSmrg    PixmapPtr pFrontBuffer;
46335c4bbdfSmrg    PixmapPtr pBackBuffer;
46435c4bbdfSmrg    Bool clear;
46535c4bbdfSmrg    GCPtr pGC;
46635c4bbdfSmrg    xRectangle clearRect;
46735c4bbdfSmrg    Bool ret;
46805b261ecSmrg
46905b261ecSmrg    /*
47005b261ecSmrg     **************************************************************************
47105b261ecSmrg     ** 1. Unwrap the member routine.
47205b261ecSmrg     **************************************************************************
47305b261ecSmrg     */
47435c4bbdfSmrg
47535c4bbdfSmrg    pScreen = pWin->drawable.pScreen;
47635c4bbdfSmrg    pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
47705b261ecSmrg    pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
47805b261ecSmrg
47905b261ecSmrg    /*
48005b261ecSmrg     **************************************************************************
48105b261ecSmrg     ** 2. Do any work necessary before the member routine is called.
48205b261ecSmrg     **
48305b261ecSmrg     **    In this case we do not need to do anything.
48405b261ecSmrg     **************************************************************************
48505b261ecSmrg     */
48635c4bbdfSmrg
48705b261ecSmrg    /*
48805b261ecSmrg     **************************************************************************
48905b261ecSmrg     ** 3. Call the member routine, saving its result if necessary.
49005b261ecSmrg     **************************************************************************
49105b261ecSmrg     */
49235c4bbdfSmrg
49335c4bbdfSmrg    ret = (*pScreen->PositionWindow) (pWin, x, y);
49405b261ecSmrg
49505b261ecSmrg    /*
49605b261ecSmrg     **************************************************************************
49705b261ecSmrg     ** 4. Rewrap the member routine, restoring the wrapper value first in case
49805b261ecSmrg     **    the wrapper (or something that it wrapped) change this value.
49905b261ecSmrg     **************************************************************************
50005b261ecSmrg     */
50105b261ecSmrg
50205b261ecSmrg    pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
50305b261ecSmrg    pScreen->PositionWindow = miDbePositionWindow;
50405b261ecSmrg
50505b261ecSmrg    /*
50605b261ecSmrg     **************************************************************************
50705b261ecSmrg     ** 5. Do any work necessary after the member routine has been called.
50805b261ecSmrg     **************************************************************************
50905b261ecSmrg     */
51035c4bbdfSmrg
51135c4bbdfSmrg    if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) {
51235c4bbdfSmrg        return ret;
51305b261ecSmrg    }
51405b261ecSmrg
51535c4bbdfSmrg    if (pDbeWindowPriv->width == pWin->drawable.width &&
51635c4bbdfSmrg        pDbeWindowPriv->height == pWin->drawable.height) {
51735c4bbdfSmrg        return ret;
51805b261ecSmrg    }
51905b261ecSmrg
52035c4bbdfSmrg    width = pWin->drawable.width;
52105b261ecSmrg    height = pWin->drawable.height;
52205b261ecSmrg
52305b261ecSmrg    dx = pWin->drawable.x - pDbeWindowPriv->x;
52405b261ecSmrg    dy = pWin->drawable.y - pDbeWindowPriv->y;
52535c4bbdfSmrg    dw = width - pDbeWindowPriv->width;
52605b261ecSmrg    dh = height - pDbeWindowPriv->height;
52705b261ecSmrg
52835c4bbdfSmrg    GravityTranslate(0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty);
52905b261ecSmrg
53035c4bbdfSmrg    clear = ((pDbeWindowPriv->width < (unsigned short) width) ||
53135c4bbdfSmrg             (pDbeWindowPriv->height < (unsigned short) height) ||
53205b261ecSmrg             (pWin->bitGravity == ForgetGravity));
53305b261ecSmrg
53405b261ecSmrg    sourcex = 0;
53505b261ecSmrg    sourcey = 0;
53635c4bbdfSmrg    savewidth = pDbeWindowPriv->width;
53705b261ecSmrg    saveheight = pDbeWindowPriv->height;
53805b261ecSmrg
53905b261ecSmrg    /* Clip rectangle to source and destination. */
54035c4bbdfSmrg    if (destx < 0) {
54135c4bbdfSmrg        savewidth += destx;
54235c4bbdfSmrg        sourcex -= destx;
54335c4bbdfSmrg        destx = 0;
54405b261ecSmrg    }
54505b261ecSmrg
54635c4bbdfSmrg    if (destx + savewidth > width) {
54735c4bbdfSmrg        savewidth = width - destx;
54805b261ecSmrg    }
54905b261ecSmrg
55035c4bbdfSmrg    if (desty < 0) {
55135c4bbdfSmrg        saveheight += desty;
55235c4bbdfSmrg        sourcey -= desty;
55335c4bbdfSmrg        desty = 0;
55405b261ecSmrg    }
55505b261ecSmrg
55635c4bbdfSmrg    if (desty + saveheight > height) {
55735c4bbdfSmrg        saveheight = height - desty;
55805b261ecSmrg    }
55905b261ecSmrg
56035c4bbdfSmrg    pDbeWindowPriv->width = width;
56105b261ecSmrg    pDbeWindowPriv->height = height;
56205b261ecSmrg    pDbeWindowPriv->x = pWin->drawable.x;
56305b261ecSmrg    pDbeWindowPriv->y = pWin->drawable.y;
56405b261ecSmrg
56535c4bbdfSmrg    pGC = GetScratchGC(pWin->drawable.depth, pScreen);
56635c4bbdfSmrg
56735c4bbdfSmrg    if (clear) {
56835c4bbdfSmrg        if ((*pDbeScreenPriv->SetupBackgroundPainter) (pWin, pGC)) {
56935c4bbdfSmrg            clearRect.x = 0;
57035c4bbdfSmrg            clearRect.y = 0;
57135c4bbdfSmrg            clearRect.width = width;
57235c4bbdfSmrg            clearRect.height = height;
57335c4bbdfSmrg        }
57435c4bbdfSmrg        else {
57535c4bbdfSmrg            clear = FALSE;
57635c4bbdfSmrg        }
57705b261ecSmrg    }
57805b261ecSmrg
57905b261ecSmrg    /* Create DBE buffer pixmaps equal to size of resized window. */
58035c4bbdfSmrg    pFrontBuffer = (*pScreen->CreatePixmap) (pScreen, width, height,
58135c4bbdfSmrg                                             pWin->drawable.depth, 0);
58205b261ecSmrg
58335c4bbdfSmrg    pBackBuffer = (*pScreen->CreatePixmap) (pScreen, width, height,
58435c4bbdfSmrg                                            pWin->drawable.depth, 0);
58505b261ecSmrg
58635c4bbdfSmrg    if (!pFrontBuffer || !pBackBuffer) {
58705b261ecSmrg        /* We failed at creating 1 or 2 of the pixmaps. */
58805b261ecSmrg
58935c4bbdfSmrg        if (pFrontBuffer) {
59035c4bbdfSmrg            (*pScreen->DestroyPixmap) (pFrontBuffer);
59105b261ecSmrg        }
59205b261ecSmrg
59335c4bbdfSmrg        if (pBackBuffer) {
59435c4bbdfSmrg            (*pScreen->DestroyPixmap) (pBackBuffer);
59505b261ecSmrg        }
59605b261ecSmrg
59705b261ecSmrg        /* Destroy all buffers for this window. */
59835c4bbdfSmrg        while (pDbeWindowPriv) {
59905b261ecSmrg            /* DbeWindowPrivDelete() will free the window private if there no
60005b261ecSmrg             * more buffer IDs associated with this window.
60105b261ecSmrg             */
60205b261ecSmrg            FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
60305b261ecSmrg            pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
60405b261ecSmrg        }
60505b261ecSmrg
60605b261ecSmrg        FreeScratchGC(pGC);
6076747b715Smrg        return FALSE;
60805b261ecSmrg    }
60905b261ecSmrg
61035c4bbdfSmrg    else {
61105b261ecSmrg        /* Clear out the new DBE buffer pixmaps. */
61205b261ecSmrg
61335c4bbdfSmrg        /* I suppose this could avoid quite a bit of work if
61435c4bbdfSmrg         * it computed the minimal area required.
61535c4bbdfSmrg         */
61635c4bbdfSmrg        ValidateGC(&pFrontBuffer->drawable, pGC);
61735c4bbdfSmrg        if (clear) {
61835c4bbdfSmrg            (*pGC->ops->PolyFillRect) ((DrawablePtr) pFrontBuffer, pGC, 1,
61935c4bbdfSmrg                                       &clearRect);
62035c4bbdfSmrg        }
62135c4bbdfSmrg        /* Copy the contents of the old front pixmap to the new one. */
62235c4bbdfSmrg        if (pWin->bitGravity != ForgetGravity) {
62335c4bbdfSmrg            (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pFrontBuffer,
62435c4bbdfSmrg				   (DrawablePtr) pFrontBuffer, pGC,
62535c4bbdfSmrg				   sourcex, sourcey, savewidth, saveheight,
62635c4bbdfSmrg                                   destx, desty);
6276747b715Smrg        }
6286747b715Smrg
62935c4bbdfSmrg        ValidateGC(&pBackBuffer->drawable, pGC);
63035c4bbdfSmrg        if (clear) {
63135c4bbdfSmrg            (*pGC->ops->PolyFillRect) ((DrawablePtr) pBackBuffer, pGC, 1,
63235c4bbdfSmrg                                       &clearRect);
63335c4bbdfSmrg        }
63435c4bbdfSmrg        /* Copy the contents of the old back pixmap to the new one. */
63535c4bbdfSmrg        if (pWin->bitGravity != ForgetGravity) {
63635c4bbdfSmrg            (*pGC->ops->CopyArea) ((DrawablePtr) pDbeWindowPriv->pBackBuffer,
63735c4bbdfSmrg				   (DrawablePtr) pBackBuffer, pGC,
63835c4bbdfSmrg                                   sourcex, sourcey, savewidth, saveheight,
63935c4bbdfSmrg                                   destx, desty);
64035c4bbdfSmrg        }
64105b261ecSmrg
64205b261ecSmrg        /* Destroy the old pixmaps, and point the DBE window priv to the new
64305b261ecSmrg         * pixmaps.
64405b261ecSmrg         */
64505b261ecSmrg
64635c4bbdfSmrg        (*pScreen->DestroyPixmap) (pDbeWindowPriv->pFrontBuffer);
64735c4bbdfSmrg        (*pScreen->DestroyPixmap) (pDbeWindowPriv->pBackBuffer);
64805b261ecSmrg
64935c4bbdfSmrg        pDbeWindowPriv->pFrontBuffer = pFrontBuffer;
65035c4bbdfSmrg        pDbeWindowPriv->pBackBuffer = pBackBuffer;
65105b261ecSmrg
65235c4bbdfSmrg        /* Make sure all XID are associated with the new back pixmap. */
65305b261ecSmrg        miDbeAliasBuffers(pDbeWindowPriv);
65405b261ecSmrg
65505b261ecSmrg        FreeScratchGC(pGC);
65605b261ecSmrg    }
65705b261ecSmrg
6586747b715Smrg    return ret;
65905b261ecSmrg
66035c4bbdfSmrg}                               /* miDbePositionWindow() */
66105b261ecSmrg
66205b261ecSmrg/******************************************************************************
66305b261ecSmrg *
66405b261ecSmrg * DBE MI Procedure: miDbeInit
66505b261ecSmrg *
66605b261ecSmrg * Description:
66705b261ecSmrg *
66805b261ecSmrg *     This is the MI initialization function called by DbeExtensionInit().
66905b261ecSmrg *
67005b261ecSmrg *****************************************************************************/
67105b261ecSmrg
67205b261ecSmrgBool
67305b261ecSmrgmiDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv)
67405b261ecSmrg{
67505b261ecSmrg    /* Wrap functions. */
67605b261ecSmrg    pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
67735c4bbdfSmrg    pScreen->PositionWindow = miDbePositionWindow;
67805b261ecSmrg
67905b261ecSmrg    /* Initialize the per-screen DBE function pointers. */
68035c4bbdfSmrg    pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo;
68135c4bbdfSmrg    pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName;
68235c4bbdfSmrg    pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers;
68335c4bbdfSmrg    pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete;
68405b261ecSmrg
6856747b715Smrg    return TRUE;
68605b261ecSmrg
68735c4bbdfSmrg}                               /* miDbeInit() */
688