dbe.c revision 0b0d8713
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 *     DIX DBE code
3005b261ecSmrg *
3105b261ecSmrg *****************************************************************************/
3205b261ecSmrg
3305b261ecSmrg
3405b261ecSmrg/* INCLUDES */
3505b261ecSmrg
3605b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3705b261ecSmrg#include <dix-config.h>
3805b261ecSmrg#endif
3905b261ecSmrg
4005b261ecSmrg#include <string.h>
4105b261ecSmrg#if HAVE_STDINT_H
4205b261ecSmrg#include <stdint.h>
4305b261ecSmrg#elif !defined(UINT32_MAX)
4405b261ecSmrg#define UINT32_MAX 0xffffffffU
4505b261ecSmrg#endif
4605b261ecSmrg
4705b261ecSmrg#include <X11/X.h>
4805b261ecSmrg#include <X11/Xproto.h>
4905b261ecSmrg#include "scrnintstr.h"
5005b261ecSmrg#include "extnsionst.h"
5105b261ecSmrg#include "gcstruct.h"
5205b261ecSmrg#include "dixstruct.h"
5305b261ecSmrg#define NEED_DBE_PROTOCOL
5405b261ecSmrg#include "dbestruct.h"
5505b261ecSmrg#include "midbe.h"
564642e01fSmrg#include "xace.h"
5705b261ecSmrg
5805b261ecSmrg/* GLOBALS */
5905b261ecSmrg
606747b715Smrg/* These are globals for use by DDX */
616747b715SmrgDevPrivateKeyRec dbeScreenPrivKeyRec;
626747b715SmrgDevPrivateKeyRec dbeWindowPrivKeyRec;
6305b261ecSmrg
646747b715Smrg/* These are globals for use by DDX */
656747b715SmrgRESTYPE	dbeDrawableResType;
666747b715SmrgRESTYPE	dbeWindowPrivResType;
6705b261ecSmrg
6805b261ecSmrg/* Used to generate DBE's BadBuffer error. */
6905b261ecSmrgstatic int	dbeErrorBase;
7005b261ecSmrg
7105b261ecSmrg/******************************************************************************
7205b261ecSmrg *
7305b261ecSmrg * DBE DIX Procedure: DbeStubScreen
7405b261ecSmrg *
7505b261ecSmrg * Description:
7605b261ecSmrg *
7705b261ecSmrg *     This is function stubs the function pointers in the given DBE screen
7805b261ecSmrg *     private and increments the number of stubbed screens.
7905b261ecSmrg *
8005b261ecSmrg *****************************************************************************/
8105b261ecSmrg
8205b261ecSmrgstatic void
8305b261ecSmrgDbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
8405b261ecSmrg{
8505b261ecSmrg    /* Stub DIX. */
8605b261ecSmrg    pDbeScreenPriv->SetupBackgroundPainter = NULL;
8705b261ecSmrg
8805b261ecSmrg    /* Do not unwrap PositionWindow nor DestroyWindow.  If the DDX
8905b261ecSmrg     * initialization function failed, we assume that it did not wrap
9005b261ecSmrg     * PositionWindow.  Also, DestroyWindow is only wrapped if the DDX
9105b261ecSmrg     * initialization function succeeded.
9205b261ecSmrg     */
9305b261ecSmrg
9405b261ecSmrg    /* Stub DDX. */
9505b261ecSmrg    pDbeScreenPriv->GetVisualInfo       = NULL;
9605b261ecSmrg    pDbeScreenPriv->AllocBackBufferName = NULL;
9705b261ecSmrg    pDbeScreenPriv->SwapBuffers         = NULL;
9805b261ecSmrg    pDbeScreenPriv->BeginIdiom          = NULL;
9905b261ecSmrg    pDbeScreenPriv->EndIdiom            = NULL;
10005b261ecSmrg    pDbeScreenPriv->WinPrivDelete       = NULL;
10105b261ecSmrg    pDbeScreenPriv->ResetProc           = NULL;
10205b261ecSmrg
10305b261ecSmrg    (*nStubbedScreens)++;
10405b261ecSmrg
10505b261ecSmrg} /* DbeStubScreen() */
10605b261ecSmrg
10705b261ecSmrg
10805b261ecSmrg
10905b261ecSmrg/******************************************************************************
11005b261ecSmrg *
11105b261ecSmrg * DBE DIX Procedure: ProcDbeGetVersion
11205b261ecSmrg *
11305b261ecSmrg * Description:
11405b261ecSmrg *
11505b261ecSmrg *     This function is for processing a DbeGetVersion request.
11605b261ecSmrg *     This request returns the major and minor version numbers of this
11705b261ecSmrg *     extension.
11805b261ecSmrg *
11905b261ecSmrg * Return Values:
12005b261ecSmrg *
12105b261ecSmrg *     Success
12205b261ecSmrg *
12305b261ecSmrg *****************************************************************************/
12405b261ecSmrg
12505b261ecSmrgstatic int
12605b261ecSmrgProcDbeGetVersion(ClientPtr client)
12705b261ecSmrg{
12805b261ecSmrg    /* REQUEST(xDbeGetVersionReq); */
12905b261ecSmrg    xDbeGetVersionReply	rep;
13005b261ecSmrg    register int	n;
13105b261ecSmrg
13205b261ecSmrg
13305b261ecSmrg    REQUEST_SIZE_MATCH(xDbeGetVersionReq);
13405b261ecSmrg
13505b261ecSmrg    rep.type           = X_Reply;
13605b261ecSmrg    rep.length         = 0;
13705b261ecSmrg    rep.sequenceNumber = client->sequence;
13805b261ecSmrg    rep.majorVersion   = DBE_MAJOR_VERSION;
13905b261ecSmrg    rep.minorVersion   = DBE_MINOR_VERSION;
14005b261ecSmrg
14105b261ecSmrg    if (client->swapped)
14205b261ecSmrg    {
14305b261ecSmrg        swaps(&rep.sequenceNumber, n);
14405b261ecSmrg    }
14505b261ecSmrg
14605b261ecSmrg    WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep);
14705b261ecSmrg
1486747b715Smrg    return Success;
14905b261ecSmrg
15005b261ecSmrg} /* ProcDbeGetVersion() */
15105b261ecSmrg
15205b261ecSmrg
15305b261ecSmrg/******************************************************************************
15405b261ecSmrg *
15505b261ecSmrg * DBE DIX Procedure: ProcDbeAllocateBackBufferName
15605b261ecSmrg *
15705b261ecSmrg * Description:
15805b261ecSmrg *
15905b261ecSmrg *     This function is for processing a DbeAllocateBackBufferName request.
16005b261ecSmrg *     This request allocates a drawable ID used to refer to the back buffer
16105b261ecSmrg *     of a window.
16205b261ecSmrg *
16305b261ecSmrg * Return Values:
16405b261ecSmrg *
16505b261ecSmrg *     BadAlloc    - server can not allocate resources
16605b261ecSmrg *     BadIDChoice - id is out of range for client; id is already in use
16705b261ecSmrg *     BadMatch    - window is not an InputOutput window;
16805b261ecSmrg *                   visual of window is not on list returned by
16905b261ecSmrg *                   DBEGetVisualInfo;
17005b261ecSmrg *     BadValue    - invalid swap action is specified
17105b261ecSmrg *     BadWindow   - window is not a valid window
17205b261ecSmrg *     Success
17305b261ecSmrg *
17405b261ecSmrg *****************************************************************************/
17505b261ecSmrg
17605b261ecSmrgstatic int
17705b261ecSmrgProcDbeAllocateBackBufferName(ClientPtr client)
17805b261ecSmrg{
17905b261ecSmrg    REQUEST(xDbeAllocateBackBufferNameReq);
18005b261ecSmrg    WindowPtr			pWin;
18105b261ecSmrg    DbeScreenPrivPtr		pDbeScreenPriv;
18205b261ecSmrg    DbeWindowPrivPtr		pDbeWindowPriv;
18305b261ecSmrg    XdbeScreenVisualInfo	scrVisInfo;
18405b261ecSmrg    register int		i;
18505b261ecSmrg    Bool			visualMatched = FALSE;
18605b261ecSmrg    xDbeSwapAction		swapAction;
18705b261ecSmrg    VisualID			visual;
18805b261ecSmrg    int				status;
1894642e01fSmrg    int				add_index;
19005b261ecSmrg
19105b261ecSmrg
19205b261ecSmrg    REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
19305b261ecSmrg
19405b261ecSmrg    /* The window must be valid. */
1954642e01fSmrg    status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
19605b261ecSmrg    if (status != Success)
19705b261ecSmrg	return status;
19805b261ecSmrg
19905b261ecSmrg    /* The window must be InputOutput. */
20005b261ecSmrg    if (pWin->drawable.class != InputOutput)
20105b261ecSmrg    {
2026747b715Smrg	return BadMatch;
20305b261ecSmrg    }
20405b261ecSmrg
20505b261ecSmrg    /* The swap action must be valid. */
20605b261ecSmrg    swapAction = stuff->swapAction;	/* use local var for performance. */
20705b261ecSmrg    if ((swapAction != XdbeUndefined ) &&
20805b261ecSmrg        (swapAction != XdbeBackground) &&
20905b261ecSmrg        (swapAction != XdbeUntouched ) &&
21005b261ecSmrg        (swapAction != XdbeCopied    ))
21105b261ecSmrg    {
2126747b715Smrg        return BadValue;
21305b261ecSmrg    }
21405b261ecSmrg
21505b261ecSmrg    /* The id must be in range and not already in use. */
21605b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->buffer, client);
21705b261ecSmrg
21805b261ecSmrg    /* The visual of the window must be in the list returned by
21905b261ecSmrg     * GetVisualInfo.
22005b261ecSmrg     */
22105b261ecSmrg    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
22205b261ecSmrg    if (!pDbeScreenPriv->GetVisualInfo)
2236747b715Smrg	return BadMatch; /* screen doesn't support double buffering */
22405b261ecSmrg
22505b261ecSmrg    if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo))
22605b261ecSmrg    {
22705b261ecSmrg        /* GetVisualInfo() failed to allocate visual info data. */
2286747b715Smrg        return BadAlloc;
22905b261ecSmrg    }
23005b261ecSmrg
23105b261ecSmrg    /* See if the window's visual is on the list. */
23205b261ecSmrg    visual = wVisual(pWin);
23305b261ecSmrg    for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++)
23405b261ecSmrg    {
23505b261ecSmrg        if (scrVisInfo.visinfo[i].visual == visual)
23605b261ecSmrg	{
23705b261ecSmrg	    visualMatched = TRUE;
23805b261ecSmrg	}
23905b261ecSmrg    }
24005b261ecSmrg
24105b261ecSmrg    /* Free what was allocated by the GetVisualInfo() call above. */
2426747b715Smrg    free(scrVisInfo.visinfo);
24305b261ecSmrg
24405b261ecSmrg    if (!visualMatched)
24505b261ecSmrg    {
2466747b715Smrg	return BadMatch;
24705b261ecSmrg    }
24805b261ecSmrg
24905b261ecSmrg    if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL)
25005b261ecSmrg    {
25105b261ecSmrg        /* There is no buffer associated with the window.
25205b261ecSmrg         * Allocate a window priv.
25305b261ecSmrg         */
25405b261ecSmrg
2556747b715Smrg        pDbeWindowPriv = dixAllocateObjectWithPrivates(DbeWindowPrivRec, PRIVATE_DBE_WINDOW);
2564642e01fSmrg	if (!pDbeWindowPriv)
2576747b715Smrg            return BadAlloc;
25805b261ecSmrg
25905b261ecSmrg        /* Fill out window priv information. */
26005b261ecSmrg        pDbeWindowPriv->pWindow      = pWin;
26105b261ecSmrg        pDbeWindowPriv->width        = pWin->drawable.width;
26205b261ecSmrg        pDbeWindowPriv->height       = pWin->drawable.height;
26305b261ecSmrg        pDbeWindowPriv->x            = pWin->drawable.x;
26405b261ecSmrg        pDbeWindowPriv->y            = pWin->drawable.y;
26505b261ecSmrg        pDbeWindowPriv->nBufferIDs   = 0;
26605b261ecSmrg
26705b261ecSmrg        /* Set the buffer ID array pointer to the initial (static) array). */
26805b261ecSmrg        pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
26905b261ecSmrg
27005b261ecSmrg        /* Initialize the buffer ID list. */
27105b261ecSmrg        pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
27205b261ecSmrg        pDbeWindowPriv->IDs[0] = stuff->buffer;
2734642e01fSmrg
2744642e01fSmrg        add_index = 0;
2754642e01fSmrg        for (i = 0; i < DBE_INIT_MAX_IDS; i++)
27605b261ecSmrg        {
27705b261ecSmrg            pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
27805b261ecSmrg        }
27905b261ecSmrg
28005b261ecSmrg        /* Actually connect the window priv to the window. */
2814642e01fSmrg        dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
28205b261ecSmrg
28305b261ecSmrg    } /* if -- There is no buffer associated with the window. */
28405b261ecSmrg
28505b261ecSmrg    else
28605b261ecSmrg    {
28705b261ecSmrg        /* A buffer is already associated with the window.
28805b261ecSmrg         * Add the new buffer ID to the array, reallocating the array memory
28905b261ecSmrg         * if necessary.
29005b261ecSmrg         */
29105b261ecSmrg
29205b261ecSmrg        /* Determine if there is a free element in the ID array. */
29305b261ecSmrg        for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++)
29405b261ecSmrg        {
29505b261ecSmrg            if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT)
29605b261ecSmrg            {
29705b261ecSmrg                /* There is still room in the ID array. */
29805b261ecSmrg                break;
29905b261ecSmrg            }
30005b261ecSmrg        }
30105b261ecSmrg
30205b261ecSmrg        if (i == pDbeWindowPriv->maxAvailableIDs)
30305b261ecSmrg        {
30405b261ecSmrg            /* No more room in the ID array -- reallocate another array. */
30505b261ecSmrg            XID	*pIDs;
30605b261ecSmrg
30705b261ecSmrg            /* Setup an array pointer for the realloc operation below. */
30805b261ecSmrg            if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
30905b261ecSmrg            {
31005b261ecSmrg                /* We will malloc a new array. */
31105b261ecSmrg                pIDs = NULL;
31205b261ecSmrg            }
31305b261ecSmrg            else
31405b261ecSmrg            {
31505b261ecSmrg                /* We will realloc a new array. */
31605b261ecSmrg                pIDs = pDbeWindowPriv->IDs;
31705b261ecSmrg            }
31805b261ecSmrg
31905b261ecSmrg            /* malloc/realloc a new array and initialize all elements to 0. */
3206747b715Smrg            pDbeWindowPriv->IDs = (XID *)realloc(pIDs,
32105b261ecSmrg                (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID));
32205b261ecSmrg            if (!pDbeWindowPriv->IDs)
32305b261ecSmrg            {
3246747b715Smrg                return BadAlloc;
32505b261ecSmrg            }
32605b261ecSmrg            memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
32705b261ecSmrg                   (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
32805b261ecSmrg                    pDbeWindowPriv->nBufferIDs) * sizeof(XID));
32905b261ecSmrg
33005b261ecSmrg            if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
33105b261ecSmrg            {
33205b261ecSmrg                /* We just went from using the initial (static) array to a
33305b261ecSmrg                 * newly allocated array.  Copy the IDs from the initial array
33405b261ecSmrg                 * to the new array.
33505b261ecSmrg                 */
33605b261ecSmrg                memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
33705b261ecSmrg                       DBE_INIT_MAX_IDS * sizeof(XID));
33805b261ecSmrg            }
33905b261ecSmrg
34005b261ecSmrg            pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
34105b261ecSmrg        }
34205b261ecSmrg
3434642e01fSmrg	add_index = i;
34405b261ecSmrg
34505b261ecSmrg    } /* else -- A buffer is already associated with the window. */
34605b261ecSmrg
34705b261ecSmrg
34805b261ecSmrg    /* Call the DDX routine to allocate the back buffer. */
34905b261ecSmrg    status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer,
35005b261ecSmrg                                                    stuff->swapAction);
35105b261ecSmrg
3524642e01fSmrg    if (status == Success)
35305b261ecSmrg    {
3544642e01fSmrg	pDbeWindowPriv->IDs[add_index] = stuff->buffer;
3554642e01fSmrg        if (!AddResource(stuff->buffer, dbeWindowPrivResType,
3564642e01fSmrg                         (pointer)pDbeWindowPriv))
3574642e01fSmrg	{
3584642e01fSmrg            pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
3594642e01fSmrg
3604642e01fSmrg            if (pDbeWindowPriv->nBufferIDs == 0) {
3614642e01fSmrg                status = BadAlloc;
3624642e01fSmrg                goto out_free;
3634642e01fSmrg            }
3644642e01fSmrg        }
3654642e01fSmrg    } else {
36605b261ecSmrg        /* The DDX buffer allocation routine failed for the first buffer of
36705b261ecSmrg         * this window.
36805b261ecSmrg         */
3694642e01fSmrg        if (pDbeWindowPriv->nBufferIDs == 0) {
3704642e01fSmrg            goto out_free;
3714642e01fSmrg        }
37205b261ecSmrg    }
37305b261ecSmrg
37405b261ecSmrg    /* Increment the number of buffers (XIDs) associated with this window. */
37505b261ecSmrg    pDbeWindowPriv->nBufferIDs++;
37605b261ecSmrg
37705b261ecSmrg    /* Set swap action on all calls. */
37805b261ecSmrg    pDbeWindowPriv->swapAction = stuff->swapAction;
37905b261ecSmrg
3806747b715Smrg    return status;
38105b261ecSmrg
3824642e01fSmrgout_free:
3834642e01fSmrg    dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
3846747b715Smrg    free(pDbeWindowPriv);
3856747b715Smrg    return status;
3864642e01fSmrg
38705b261ecSmrg} /* ProcDbeAllocateBackBufferName() */
38805b261ecSmrg
38905b261ecSmrg
39005b261ecSmrg/******************************************************************************
39105b261ecSmrg *
39205b261ecSmrg * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
39305b261ecSmrg *
39405b261ecSmrg * Description:
39505b261ecSmrg *
39605b261ecSmrg *     This function is for processing a DbeDeallocateBackBufferName request.
39705b261ecSmrg *     This request frees a drawable ID that was obtained by a
39805b261ecSmrg *     DbeAllocateBackBufferName request.
39905b261ecSmrg *
40005b261ecSmrg * Return Values:
40105b261ecSmrg *
40205b261ecSmrg *     BadBuffer - buffer to deallocate is not associated with a window
40305b261ecSmrg *     Success
40405b261ecSmrg *
40505b261ecSmrg *****************************************************************************/
40605b261ecSmrg
40705b261ecSmrgstatic int
40805b261ecSmrgProcDbeDeallocateBackBufferName(ClientPtr client)
40905b261ecSmrg{
41005b261ecSmrg    REQUEST(xDbeDeallocateBackBufferNameReq);
41105b261ecSmrg    DbeWindowPrivPtr	pDbeWindowPriv;
4126747b715Smrg    int			rc, i;
4136747b715Smrg    pointer val;
41405b261ecSmrg
41505b261ecSmrg
41605b261ecSmrg    REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
41705b261ecSmrg
41805b261ecSmrg    /* Buffer name must be valid */
4196747b715Smrg    rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
4206747b715Smrg				 dbeWindowPrivResType, client,
4216747b715Smrg				 DixDestroyAccess);
4226747b715Smrg    if (rc != Success)
4236747b715Smrg	return rc;
4246747b715Smrg
4256747b715Smrg    rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType,
4266747b715Smrg				 client, DixDestroyAccess);
4276747b715Smrg    if (rc != Success)
4286747b715Smrg	return rc;
42905b261ecSmrg
43005b261ecSmrg    /* Make sure that the id is valid for the window.
43105b261ecSmrg     * This is paranoid code since we already looked up the ID by type
43205b261ecSmrg     * above.
43305b261ecSmrg     */
43405b261ecSmrg
43505b261ecSmrg    for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
43605b261ecSmrg    {
43705b261ecSmrg        /* Loop through the ID list to find the ID. */
43805b261ecSmrg        if (pDbeWindowPriv->IDs[i] == stuff->buffer)
43905b261ecSmrg        {
44005b261ecSmrg            break;
44105b261ecSmrg        }
44205b261ecSmrg    }
44305b261ecSmrg
44405b261ecSmrg    if (i == pDbeWindowPriv->nBufferIDs)
44505b261ecSmrg    {
44605b261ecSmrg        /* We did not find the ID in the ID list. */
44705b261ecSmrg        client->errorValue = stuff->buffer;
4486747b715Smrg        return dbeErrorBase + DbeBadBuffer;
44905b261ecSmrg    }
45005b261ecSmrg
45105b261ecSmrg    FreeResource(stuff->buffer, RT_NONE);
45205b261ecSmrg
4536747b715Smrg    return Success;
45405b261ecSmrg
45505b261ecSmrg} /* ProcDbeDeallocateBackBufferName() */
45605b261ecSmrg
45705b261ecSmrg
45805b261ecSmrg/******************************************************************************
45905b261ecSmrg *
46005b261ecSmrg * DBE DIX Procedure: ProcDbeSwapBuffers
46105b261ecSmrg *
46205b261ecSmrg * Description:
46305b261ecSmrg *
46405b261ecSmrg *     This function is for processing a DbeSwapBuffers request.
46505b261ecSmrg *     This request swaps the buffers for all windows listed, applying the
46605b261ecSmrg *     appropriate swap action for each window.
46705b261ecSmrg *
46805b261ecSmrg * Return Values:
46905b261ecSmrg *
47005b261ecSmrg *     BadAlloc  - local allocation failed; this return value is not defined
47105b261ecSmrg *                 by the protocol
47205b261ecSmrg *     BadMatch  - a window in request is not double-buffered; a window in
47305b261ecSmrg *                 request is listed more than once
47405b261ecSmrg *     BadValue  - invalid swap action is specified; no swap action is
47505b261ecSmrg *                 specified
47605b261ecSmrg *     BadWindow - a window in request is not valid
47705b261ecSmrg *     Success
47805b261ecSmrg *
47905b261ecSmrg *****************************************************************************/
48005b261ecSmrg
48105b261ecSmrgstatic int
48205b261ecSmrgProcDbeSwapBuffers(ClientPtr client)
48305b261ecSmrg{
48405b261ecSmrg    REQUEST(xDbeSwapBuffersReq);
48505b261ecSmrg    WindowPtr		pWin;
48605b261ecSmrg    DbeScreenPrivPtr	pDbeScreenPriv;
48705b261ecSmrg    DbeSwapInfoPtr	swapInfo;
48805b261ecSmrg    xDbeSwapInfo	*dbeSwapInfo;
48905b261ecSmrg    int			error;
4900b0d8713Smrg    unsigned int i, j;
4910b0d8713Smrg    unsigned int nStuff;
49205b261ecSmrg
49305b261ecSmrg
49405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
49505b261ecSmrg    nStuff = stuff->n;	/* use local variable for performance. */
49605b261ecSmrg
49705b261ecSmrg    if (nStuff == 0)
49805b261ecSmrg    {
4990b0d8713Smrg        REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
5006747b715Smrg        return Success;
50105b261ecSmrg    }
50205b261ecSmrg
50305b261ecSmrg    if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
50405b261ecSmrg	    return BadAlloc;
5050b0d8713Smrg    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
50605b261ecSmrg
50705b261ecSmrg    /* Get to the swap info appended to the end of the request. */
50805b261ecSmrg    dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
50905b261ecSmrg
51005b261ecSmrg    /* Allocate array to record swap information. */
5116747b715Smrg    swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec));
51205b261ecSmrg    if (swapInfo == NULL)
51305b261ecSmrg    {
5146747b715Smrg        return BadAlloc;
51505b261ecSmrg    }
51605b261ecSmrg
51705b261ecSmrg
51805b261ecSmrg    for (i = 0; i < nStuff; i++)
51905b261ecSmrg    {
52005b261ecSmrg        /* Check all windows to swap. */
52105b261ecSmrg
52205b261ecSmrg        /* Each window must be a valid window - BadWindow. */
52305b261ecSmrg	error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client,
52405b261ecSmrg				DixWriteAccess);
52505b261ecSmrg	if (error != Success) {
5266747b715Smrg            free(swapInfo);
52705b261ecSmrg	    return error;
52805b261ecSmrg        }
52905b261ecSmrg
53005b261ecSmrg        /* Each window must be double-buffered - BadMatch. */
53105b261ecSmrg        if (DBE_WINDOW_PRIV(pWin) == NULL)
53205b261ecSmrg        {
5336747b715Smrg            free(swapInfo);
5346747b715Smrg            return BadMatch;
53505b261ecSmrg        }
53605b261ecSmrg
53705b261ecSmrg        /* Each window must only be specified once - BadMatch. */
53805b261ecSmrg        for (j = i + 1; j < nStuff; j++)
53905b261ecSmrg        {
54005b261ecSmrg            if (dbeSwapInfo[i].window == dbeSwapInfo[j].window)
54105b261ecSmrg            {
5426747b715Smrg                free(swapInfo);
5436747b715Smrg                return BadMatch;
54405b261ecSmrg	    }
54505b261ecSmrg        }
54605b261ecSmrg
54705b261ecSmrg        /* Each swap action must be valid - BadValue. */
54805b261ecSmrg        if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) &&
54905b261ecSmrg            (dbeSwapInfo[i].swapAction != XdbeBackground) &&
55005b261ecSmrg            (dbeSwapInfo[i].swapAction != XdbeUntouched ) &&
55105b261ecSmrg            (dbeSwapInfo[i].swapAction != XdbeCopied    ))
55205b261ecSmrg        {
5536747b715Smrg            free(swapInfo);
5546747b715Smrg            return BadValue;
55505b261ecSmrg        }
55605b261ecSmrg
55705b261ecSmrg        /* Everything checks out OK.  Fill in the swap info array. */
55805b261ecSmrg        swapInfo[i].pWindow    = pWin;
55905b261ecSmrg        swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;
56005b261ecSmrg
56105b261ecSmrg    } /* for (i = 0; i < nStuff; i++) */
56205b261ecSmrg
56305b261ecSmrg
56405b261ecSmrg    /* Call the DDX routine to perform the swap(s).  The DDX routine should
56505b261ecSmrg     * scan the swap list (swap info), swap any buffers that it knows how to
56605b261ecSmrg     * handle, delete them from the list, and update nStuff to indicate how
56705b261ecSmrg     * many windows it did not handle.
56805b261ecSmrg     *
56905b261ecSmrg     * This scheme allows a range of sophistication in the DDX SwapBuffers()
57005b261ecSmrg     * implementation.  Naive implementations could just swap the first buffer
57105b261ecSmrg     * in the list, move the last buffer to the front, decrement nStuff, and
57205b261ecSmrg     * return.  The next level of sophistication could be to scan the whole
57305b261ecSmrg     * list for windows on the same screen.  Up another level, the DDX routine
57405b261ecSmrg     * could deal with cross-screen synchronization.
57505b261ecSmrg     */
57605b261ecSmrg
57705b261ecSmrg    while (nStuff > 0)
57805b261ecSmrg    {
57905b261ecSmrg        pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
58005b261ecSmrg        error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo);
58105b261ecSmrg        if (error != Success)
58205b261ecSmrg        {
5836747b715Smrg            free(swapInfo);
5846747b715Smrg            return error;
58505b261ecSmrg        }
58605b261ecSmrg    }
58705b261ecSmrg
5886747b715Smrg    free(swapInfo);
5896747b715Smrg    return Success;
59005b261ecSmrg
59105b261ecSmrg} /* ProcDbeSwapBuffers() */
59205b261ecSmrg
59305b261ecSmrg
59405b261ecSmrg/******************************************************************************
59505b261ecSmrg *
59605b261ecSmrg * DBE DIX Procedure: ProcDbeBeginIdiom
59705b261ecSmrg *
59805b261ecSmrg * Description:
59905b261ecSmrg *
60005b261ecSmrg *     This function is for processing a DbeBeginIdiom request.
60105b261ecSmrg *     This request informs the server that a complex swap will immediately
60205b261ecSmrg *     follow this request.
60305b261ecSmrg *
60405b261ecSmrg * Return Values:
60505b261ecSmrg *
60605b261ecSmrg *     Success
60705b261ecSmrg *
60805b261ecSmrg *****************************************************************************/
60905b261ecSmrg
61005b261ecSmrgstatic int
61105b261ecSmrgProcDbeBeginIdiom(ClientPtr client)
61205b261ecSmrg{
61305b261ecSmrg    /* REQUEST(xDbeBeginIdiomReq); */
61405b261ecSmrg    DbeScreenPrivPtr	pDbeScreenPriv;
61505b261ecSmrg    register int	i;
61605b261ecSmrg
61705b261ecSmrg
61805b261ecSmrg    REQUEST_SIZE_MATCH(xDbeBeginIdiomReq);
61905b261ecSmrg
62005b261ecSmrg    for (i = 0; i < screenInfo.numScreens; i++)
62105b261ecSmrg    {
62205b261ecSmrg        pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]);
62305b261ecSmrg
62405b261ecSmrg        /* Call the DDX begin idiom procedure if there is one. */
62505b261ecSmrg        if (pDbeScreenPriv->BeginIdiom)
62605b261ecSmrg        {
62705b261ecSmrg           (*pDbeScreenPriv->BeginIdiom)(client);
62805b261ecSmrg        }
62905b261ecSmrg    }
63005b261ecSmrg
6316747b715Smrg    return Success;
63205b261ecSmrg
63305b261ecSmrg} /* ProcDbeBeginIdiom() */
63405b261ecSmrg
63505b261ecSmrg
63605b261ecSmrg/******************************************************************************
63705b261ecSmrg *
63805b261ecSmrg * DBE DIX Procedure: ProcDbeGetVisualInfo
63905b261ecSmrg *
64005b261ecSmrg * Description:
64105b261ecSmrg *
64205b261ecSmrg *     This function is for processing a ProcDbeGetVisualInfo request.
64305b261ecSmrg *     This request returns information about which visuals support
64405b261ecSmrg *     double buffering.
64505b261ecSmrg *
64605b261ecSmrg * Return Values:
64705b261ecSmrg *
64805b261ecSmrg *     BadDrawable - value in screen specifiers is not a valid drawable
64905b261ecSmrg *     Success
65005b261ecSmrg *
65105b261ecSmrg *****************************************************************************/
65205b261ecSmrg
65305b261ecSmrgstatic int
65405b261ecSmrgProcDbeGetVisualInfo(ClientPtr client)
65505b261ecSmrg{
65605b261ecSmrg    REQUEST(xDbeGetVisualInfoReq);
65705b261ecSmrg    DbeScreenPrivPtr		pDbeScreenPriv;
65805b261ecSmrg    xDbeGetVisualInfoReply	rep;
65905b261ecSmrg    Drawable			*drawables;
66005b261ecSmrg    DrawablePtr			*pDrawables = NULL;
66105b261ecSmrg    register int		i, j, n, rc;
66205b261ecSmrg    register int		count;  /* number of visual infos in reply */
66305b261ecSmrg    register int		length; /* length of reply */
66405b261ecSmrg    ScreenPtr			pScreen;
66505b261ecSmrg    XdbeScreenVisualInfo	*pScrVisInfo;
66605b261ecSmrg
66705b261ecSmrg
66805b261ecSmrg    REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
66905b261ecSmrg
67005b261ecSmrg    if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
67105b261ecSmrg	    return BadAlloc;
67205b261ecSmrg    /* Make sure any specified drawables are valid. */
67305b261ecSmrg    if (stuff->n != 0)
67405b261ecSmrg    {
6756747b715Smrg        if (!(pDrawables = (DrawablePtr *)malloc(stuff->n *
67605b261ecSmrg                                                 sizeof(DrawablePtr))))
67705b261ecSmrg        {
6786747b715Smrg            return BadAlloc;
67905b261ecSmrg        }
68005b261ecSmrg
68105b261ecSmrg        drawables = (Drawable *)&stuff[1];
68205b261ecSmrg
68305b261ecSmrg        for (i = 0; i < stuff->n; i++)
68405b261ecSmrg        {
68505b261ecSmrg	    rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0,
6864642e01fSmrg				   DixGetAttrAccess);
68705b261ecSmrg	    if (rc != Success) {
6886747b715Smrg                free(pDrawables);
68905b261ecSmrg                return rc;
69005b261ecSmrg            }
69105b261ecSmrg        }
69205b261ecSmrg    }
69305b261ecSmrg
69405b261ecSmrg    count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
6959ace9065Smrg    if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo))))
69605b261ecSmrg    {
6976747b715Smrg        free(pDrawables);
69805b261ecSmrg
6996747b715Smrg        return BadAlloc;
70005b261ecSmrg    }
70105b261ecSmrg
70205b261ecSmrg    length = 0;
70305b261ecSmrg
70405b261ecSmrg    for (i = 0; i < count; i++)
70505b261ecSmrg    {
70605b261ecSmrg        pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
70705b261ecSmrg                                    pDrawables[i]->pScreen;
70805b261ecSmrg        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
70905b261ecSmrg
7104642e01fSmrg	rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
7119ace9065Smrg        if (rc != Success)
7129ace9065Smrg            goto freeScrVisInfo;
7139ace9065Smrg
7149ace9065Smrg        if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
71505b261ecSmrg        {
71605b261ecSmrg            /* We failed to alloc pScrVisInfo[i].visinfo. */
7179ace9065Smrg            rc = BadAlloc;
71805b261ecSmrg
71905b261ecSmrg            /* Free visinfos that we allocated for previous screen infos.*/
7209ace9065Smrg            goto freeScrVisInfo;
72105b261ecSmrg        }
72205b261ecSmrg
72305b261ecSmrg        /* Account for n, number of xDbeVisInfo items in list. */
72405b261ecSmrg        length += sizeof(CARD32);
72505b261ecSmrg
72605b261ecSmrg        /* Account for n xDbeVisInfo items */
72705b261ecSmrg        length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
72805b261ecSmrg    }
72905b261ecSmrg
73005b261ecSmrg    rep.type           = X_Reply;
73105b261ecSmrg    rep.sequenceNumber = client->sequence;
7326747b715Smrg    rep.length         = bytes_to_int32(length);
73305b261ecSmrg    rep.m              = count;
73405b261ecSmrg
73505b261ecSmrg    if (client->swapped)
73605b261ecSmrg    {
73705b261ecSmrg        swaps(&rep.sequenceNumber, n);
73805b261ecSmrg        swapl(&rep.length, n);
73905b261ecSmrg        swapl(&rep.m, n);
74005b261ecSmrg    }
74105b261ecSmrg
74205b261ecSmrg    /* Send off reply. */
74305b261ecSmrg    WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep);
74405b261ecSmrg
74505b261ecSmrg    for (i = 0; i < count; i++)
74605b261ecSmrg    {
74705b261ecSmrg        CARD32	data32;
74805b261ecSmrg
74905b261ecSmrg        /* For each screen in the reply, send off the visual info */
75005b261ecSmrg
75105b261ecSmrg        /* Send off number of visuals. */
75205b261ecSmrg        data32 = (CARD32)pScrVisInfo[i].count;
75305b261ecSmrg
75405b261ecSmrg        if (client->swapped)
75505b261ecSmrg        {
75605b261ecSmrg            swapl(&data32, n);
75705b261ecSmrg        }
75805b261ecSmrg
75905b261ecSmrg        WriteToClient(client, sizeof(CARD32), (char *)&data32);
76005b261ecSmrg
76105b261ecSmrg        /* Now send off visual info items. */
76205b261ecSmrg        for (j = 0; j < pScrVisInfo[i].count; j++)
76305b261ecSmrg        {
76405b261ecSmrg            xDbeVisInfo		visInfo;
76505b261ecSmrg
76605b261ecSmrg            /* Copy the data in the client data structure to a protocol
76705b261ecSmrg             * data structure.  We will send data to the client from the
76805b261ecSmrg             * protocol data structure.
76905b261ecSmrg             */
77005b261ecSmrg
77105b261ecSmrg            visInfo.visualID  = (CARD32)pScrVisInfo[i].visinfo[j].visual;
77205b261ecSmrg            visInfo.depth     = (CARD8) pScrVisInfo[i].visinfo[j].depth;
77305b261ecSmrg            visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;
77405b261ecSmrg
77505b261ecSmrg            if (client->swapped)
77605b261ecSmrg            {
77705b261ecSmrg                swapl(&visInfo.visualID, n);
77805b261ecSmrg
77905b261ecSmrg                /* We do not need to swap depth and perfLevel since they are
78005b261ecSmrg                 * already 1 byte quantities.
78105b261ecSmrg                 */
78205b261ecSmrg            }
78305b261ecSmrg
78405b261ecSmrg            /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
78505b261ecSmrg            WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID);
78605b261ecSmrg        }
78705b261ecSmrg    }
78805b261ecSmrg
7899ace9065Smrg    rc = Success;
7909ace9065Smrg
7919ace9065Smrg  freeScrVisInfo:
79205b261ecSmrg    /* Clean up memory. */
79305b261ecSmrg    for (i = 0; i < count; i++)
79405b261ecSmrg    {
7956747b715Smrg        free(pScrVisInfo[i].visinfo);
79605b261ecSmrg    }
7976747b715Smrg    free(pScrVisInfo);
79805b261ecSmrg
7996747b715Smrg    free(pDrawables);
80005b261ecSmrg
8019ace9065Smrg    return rc;
80205b261ecSmrg
80305b261ecSmrg} /* ProcDbeGetVisualInfo() */
80405b261ecSmrg
80505b261ecSmrg
80605b261ecSmrg/******************************************************************************
80705b261ecSmrg *
80805b261ecSmrg * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
80905b261ecSmrg *
81005b261ecSmrg * Description:
81105b261ecSmrg *
81205b261ecSmrg *     This function is for processing a ProcDbeGetbackBufferAttributes
81305b261ecSmrg *     request.  This request returns information about a back buffer.
81405b261ecSmrg *
81505b261ecSmrg * Return Values:
81605b261ecSmrg *
81705b261ecSmrg *     Success
81805b261ecSmrg *
81905b261ecSmrg *****************************************************************************/
82005b261ecSmrg
82105b261ecSmrgstatic int
82205b261ecSmrgProcDbeGetBackBufferAttributes(ClientPtr client)
82305b261ecSmrg{
82405b261ecSmrg    REQUEST(xDbeGetBackBufferAttributesReq);
82505b261ecSmrg    xDbeGetBackBufferAttributesReply	rep;
82605b261ecSmrg    DbeWindowPrivPtr			pDbeWindowPriv;
8276747b715Smrg    int					rc, n;
82805b261ecSmrg
82905b261ecSmrg
83005b261ecSmrg    REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
83105b261ecSmrg
8326747b715Smrg    rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
8336747b715Smrg				 dbeWindowPrivResType, client,
8346747b715Smrg				 DixGetAttrAccess);
8356747b715Smrg    if (rc == Success)
83605b261ecSmrg    {
8376747b715Smrg        rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
83805b261ecSmrg    }
83905b261ecSmrg    else
84005b261ecSmrg    {
8416747b715Smrg        rep.attributes = None;
84205b261ecSmrg    }
84305b261ecSmrg
84405b261ecSmrg    rep.type           = X_Reply;
84505b261ecSmrg    rep.sequenceNumber = client->sequence;
84605b261ecSmrg    rep.length         = 0;
84705b261ecSmrg
84805b261ecSmrg    if (client->swapped)
84905b261ecSmrg    {
85005b261ecSmrg        swaps(&rep.sequenceNumber, n);
85105b261ecSmrg        swapl(&rep.length, n);
85205b261ecSmrg        swapl(&rep.attributes, n);
85305b261ecSmrg    }
85405b261ecSmrg
85505b261ecSmrg    WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
85605b261ecSmrg                  (char *)&rep);
8576747b715Smrg    return Success;
85805b261ecSmrg
85905b261ecSmrg} /* ProcDbeGetbackBufferAttributes() */
86005b261ecSmrg
86105b261ecSmrg
86205b261ecSmrg/******************************************************************************
86305b261ecSmrg *
86405b261ecSmrg * DBE DIX Procedure: ProcDbeDispatch
86505b261ecSmrg *
86605b261ecSmrg * Description:
86705b261ecSmrg *
86805b261ecSmrg *     This function dispatches DBE requests.
86905b261ecSmrg *
87005b261ecSmrg *****************************************************************************/
87105b261ecSmrg
87205b261ecSmrgstatic int
87305b261ecSmrgProcDbeDispatch(ClientPtr client)
87405b261ecSmrg{
87505b261ecSmrg    REQUEST(xReq);
87605b261ecSmrg
87705b261ecSmrg
87805b261ecSmrg    switch (stuff->data)
87905b261ecSmrg    {
88005b261ecSmrg        case X_DbeGetVersion:
88105b261ecSmrg            return(ProcDbeGetVersion(client));
88205b261ecSmrg
88305b261ecSmrg        case X_DbeAllocateBackBufferName:
88405b261ecSmrg            return(ProcDbeAllocateBackBufferName(client));
88505b261ecSmrg
88605b261ecSmrg        case X_DbeDeallocateBackBufferName:
88705b261ecSmrg            return(ProcDbeDeallocateBackBufferName(client));
88805b261ecSmrg
88905b261ecSmrg        case X_DbeSwapBuffers:
89005b261ecSmrg            return(ProcDbeSwapBuffers(client));
89105b261ecSmrg
89205b261ecSmrg        case X_DbeBeginIdiom:
89305b261ecSmrg            return(ProcDbeBeginIdiom(client));
89405b261ecSmrg
89505b261ecSmrg        case X_DbeEndIdiom:
8966747b715Smrg            return Success;
89705b261ecSmrg
89805b261ecSmrg        case X_DbeGetVisualInfo:
89905b261ecSmrg            return(ProcDbeGetVisualInfo(client));
90005b261ecSmrg
90105b261ecSmrg        case X_DbeGetBackBufferAttributes:
90205b261ecSmrg            return(ProcDbeGetBackBufferAttributes(client));
90305b261ecSmrg
90405b261ecSmrg        default:
9056747b715Smrg            return BadRequest;
90605b261ecSmrg    }
90705b261ecSmrg
90805b261ecSmrg} /* ProcDbeDispatch() */
90905b261ecSmrg
91005b261ecSmrg
91105b261ecSmrg/******************************************************************************
91205b261ecSmrg *
91305b261ecSmrg * DBE DIX Procedure: SProcDbeGetVersion
91405b261ecSmrg *
91505b261ecSmrg * Description:
91605b261ecSmrg *
91705b261ecSmrg *     This function is for processing a DbeGetVersion request on a swapped
91805b261ecSmrg *     server.  This request returns the major and minor version numbers of
91905b261ecSmrg *     this extension.
92005b261ecSmrg *
92105b261ecSmrg * Return Values:
92205b261ecSmrg *
92305b261ecSmrg *     Success
92405b261ecSmrg *
92505b261ecSmrg *****************************************************************************/
92605b261ecSmrg
92705b261ecSmrgstatic int
92805b261ecSmrgSProcDbeGetVersion(ClientPtr client)
92905b261ecSmrg{
93005b261ecSmrg    REQUEST(xDbeGetVersionReq);
93105b261ecSmrg    register int	n;
93205b261ecSmrg
93305b261ecSmrg
93405b261ecSmrg    swaps(&stuff->length, n);
93505b261ecSmrg    return(ProcDbeGetVersion(client));
93605b261ecSmrg
93705b261ecSmrg} /* SProcDbeGetVersion() */
93805b261ecSmrg
93905b261ecSmrg
94005b261ecSmrg/******************************************************************************
94105b261ecSmrg *
94205b261ecSmrg * DBE DIX Procedure: SProcDbeAllocateBackBufferName
94305b261ecSmrg *
94405b261ecSmrg * Description:
94505b261ecSmrg *
94605b261ecSmrg *     This function is for processing a DbeAllocateBackBufferName request on
94705b261ecSmrg *     a swapped server.  This request allocates a drawable ID used to refer
94805b261ecSmrg *     to the back buffer of a window.
94905b261ecSmrg *
95005b261ecSmrg * Return Values:
95105b261ecSmrg *
95205b261ecSmrg *     BadAlloc    - server can not allocate resources
95305b261ecSmrg *     BadIDChoice - id is out of range for client; id is already in use
95405b261ecSmrg *     BadMatch    - window is not an InputOutput window;
95505b261ecSmrg *                   visual of window is not on list returned by
95605b261ecSmrg *                   DBEGetVisualInfo;
95705b261ecSmrg *     BadValue    - invalid swap action is specified
95805b261ecSmrg *     BadWindow   - window is not a valid window
95905b261ecSmrg *     Success
96005b261ecSmrg *
96105b261ecSmrg *****************************************************************************/
96205b261ecSmrg
96305b261ecSmrgstatic int
96405b261ecSmrgSProcDbeAllocateBackBufferName(ClientPtr client)
96505b261ecSmrg{
96605b261ecSmrg    REQUEST(xDbeAllocateBackBufferNameReq);
96705b261ecSmrg    register int	n;
96805b261ecSmrg
96905b261ecSmrg    swaps(&stuff->length, n);
97005b261ecSmrg    REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
97105b261ecSmrg
97205b261ecSmrg    swapl(&stuff->window, n);
97305b261ecSmrg    swapl(&stuff->buffer, n);
97405b261ecSmrg    /* stuff->swapAction is a byte.  We do not need to swap this field. */
97505b261ecSmrg
97605b261ecSmrg    return(ProcDbeAllocateBackBufferName(client));
97705b261ecSmrg
97805b261ecSmrg} /* SProcDbeAllocateBackBufferName() */
97905b261ecSmrg
98005b261ecSmrg
98105b261ecSmrg/******************************************************************************
98205b261ecSmrg *
98305b261ecSmrg * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
98405b261ecSmrg *
98505b261ecSmrg * Description:
98605b261ecSmrg *
98705b261ecSmrg *     This function is for processing a DbeDeallocateBackBufferName request
98805b261ecSmrg *     on a swapped server.  This request frees a drawable ID that was
98905b261ecSmrg *     obtained by a DbeAllocateBackBufferName request.
99005b261ecSmrg *
99105b261ecSmrg * Return Values:
99205b261ecSmrg *
99305b261ecSmrg *     BadBuffer - buffer to deallocate is not associated with a window
99405b261ecSmrg *     Success
99505b261ecSmrg *
99605b261ecSmrg *****************************************************************************/
99705b261ecSmrg
99805b261ecSmrgstatic int
99905b261ecSmrgSProcDbeDeallocateBackBufferName(ClientPtr client)
100005b261ecSmrg{
100105b261ecSmrg    REQUEST (xDbeDeallocateBackBufferNameReq);
100205b261ecSmrg    register int	n;
100305b261ecSmrg
100405b261ecSmrg
100505b261ecSmrg    swaps(&stuff->length, n);
100605b261ecSmrg    REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
100705b261ecSmrg
100805b261ecSmrg    swapl(&stuff->buffer, n);
100905b261ecSmrg
101005b261ecSmrg    return(ProcDbeDeallocateBackBufferName(client));
101105b261ecSmrg
101205b261ecSmrg} /* SProcDbeDeallocateBackBufferName() */
101305b261ecSmrg
101405b261ecSmrg
101505b261ecSmrg/******************************************************************************
101605b261ecSmrg *
101705b261ecSmrg * DBE DIX Procedure: SProcDbeSwapBuffers
101805b261ecSmrg *
101905b261ecSmrg * Description:
102005b261ecSmrg *
102105b261ecSmrg *     This function is for processing a DbeSwapBuffers request on a swapped
102205b261ecSmrg *     server.  This request swaps the buffers for all windows listed,
102305b261ecSmrg *     applying the appropriate swap action for each window.
102405b261ecSmrg *
102505b261ecSmrg * Return Values:
102605b261ecSmrg *
102705b261ecSmrg *     BadMatch  - a window in request is not double-buffered; a window in
102805b261ecSmrg *                 request is listed more than once; all windows in request do
102905b261ecSmrg *                 not have the same root
103005b261ecSmrg *     BadValue  - invalid swap action is specified
103105b261ecSmrg *     BadWindow - a window in request is not valid
103205b261ecSmrg *     Success
103305b261ecSmrg *
103405b261ecSmrg *****************************************************************************/
103505b261ecSmrg
103605b261ecSmrgstatic int
103705b261ecSmrgSProcDbeSwapBuffers(ClientPtr client)
103805b261ecSmrg{
103905b261ecSmrg    REQUEST(xDbeSwapBuffersReq);
10400b0d8713Smrg    unsigned int	i, n;
104105b261ecSmrg    xDbeSwapInfo	*pSwapInfo;
104205b261ecSmrg
104305b261ecSmrg
104405b261ecSmrg    swaps(&stuff->length, n);
104505b261ecSmrg    REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
104605b261ecSmrg
104705b261ecSmrg    swapl(&stuff->n, n);
10480b0d8713Smrg    if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
10490b0d8713Smrg        return BadAlloc;
10500b0d8713Smrg    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
105105b261ecSmrg
105205b261ecSmrg    if (stuff->n != 0)
105305b261ecSmrg    {
105405b261ecSmrg        pSwapInfo = (xDbeSwapInfo *)stuff+1;
105505b261ecSmrg
105605b261ecSmrg        /* The swap info following the fix part of this request is a window(32)
105705b261ecSmrg         * followed by a 1 byte swap action and then 3 pad bytes.  We only need
105805b261ecSmrg         * to swap the window information.
105905b261ecSmrg         */
106005b261ecSmrg        for (i = 0; i < stuff->n; i++)
106105b261ecSmrg        {
106205b261ecSmrg            swapl(&pSwapInfo->window, n);
106305b261ecSmrg        }
106405b261ecSmrg    }
106505b261ecSmrg
106605b261ecSmrg    return(ProcDbeSwapBuffers(client));
106705b261ecSmrg
106805b261ecSmrg} /* SProcDbeSwapBuffers() */
106905b261ecSmrg
107005b261ecSmrg
107105b261ecSmrg/******************************************************************************
107205b261ecSmrg *
107305b261ecSmrg * DBE DIX Procedure: SProcDbeBeginIdiom
107405b261ecSmrg *
107505b261ecSmrg * Description:
107605b261ecSmrg *
107705b261ecSmrg *     This function is for processing a DbeBeginIdiom request on a swapped
107805b261ecSmrg *     server.  This request informs the server that a complex swap will
107905b261ecSmrg *     immediately follow this request.
108005b261ecSmrg *
108105b261ecSmrg * Return Values:
108205b261ecSmrg *
108305b261ecSmrg *     Success
108405b261ecSmrg *
108505b261ecSmrg *****************************************************************************/
108605b261ecSmrg
108705b261ecSmrgstatic int
108805b261ecSmrgSProcDbeBeginIdiom(ClientPtr client)
108905b261ecSmrg{
109005b261ecSmrg    REQUEST(xDbeBeginIdiomReq);
109105b261ecSmrg    register int	n;
109205b261ecSmrg
109305b261ecSmrg    swaps(&stuff->length, n);
109405b261ecSmrg    return(ProcDbeBeginIdiom(client));
109505b261ecSmrg
109605b261ecSmrg} /* SProcDbeBeginIdiom() */
109705b261ecSmrg
109805b261ecSmrg
109905b261ecSmrg/******************************************************************************
110005b261ecSmrg *
110105b261ecSmrg * DBE DIX Procedure: SProcDbeGetVisualInfo
110205b261ecSmrg *
110305b261ecSmrg * Description:
110405b261ecSmrg *
110505b261ecSmrg *     This function is for processing a ProcDbeGetVisualInfo request on a
110605b261ecSmrg *     swapped server.  This request returns information about which visuals
110705b261ecSmrg *     support double buffering.
110805b261ecSmrg *
110905b261ecSmrg * Return Values:
111005b261ecSmrg *
111105b261ecSmrg *     BadDrawable - value in screen specifiers is not a valid drawable
111205b261ecSmrg *     Success
111305b261ecSmrg *
111405b261ecSmrg *****************************************************************************/
111505b261ecSmrg
111605b261ecSmrgstatic int
111705b261ecSmrgSProcDbeGetVisualInfo(ClientPtr client)
111805b261ecSmrg{
111905b261ecSmrg    REQUEST(xDbeGetVisualInfoReq);
112005b261ecSmrg    register int	n;
112105b261ecSmrg
112205b261ecSmrg
112305b261ecSmrg    swaps(&stuff->length, n);
112405b261ecSmrg    REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
112505b261ecSmrg
112605b261ecSmrg    swapl(&stuff->n, n);
112705b261ecSmrg    SwapRestL(stuff);
112805b261ecSmrg
112905b261ecSmrg    return(ProcDbeGetVisualInfo(client));
113005b261ecSmrg
113105b261ecSmrg} /* SProcDbeGetVisualInfo() */
113205b261ecSmrg
113305b261ecSmrg
113405b261ecSmrg/******************************************************************************
113505b261ecSmrg *
113605b261ecSmrg * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
113705b261ecSmrg *
113805b261ecSmrg * Description:
113905b261ecSmrg *
114005b261ecSmrg *     This function is for processing a ProcDbeGetbackBufferAttributes
114105b261ecSmrg *     request on a swapped server.  This request returns information about a
114205b261ecSmrg *     back buffer.
114305b261ecSmrg *
114405b261ecSmrg * Return Values:
114505b261ecSmrg *
114605b261ecSmrg *     Success
114705b261ecSmrg *
114805b261ecSmrg *****************************************************************************/
114905b261ecSmrg
115005b261ecSmrgstatic int
115105b261ecSmrgSProcDbeGetBackBufferAttributes(ClientPtr client)
115205b261ecSmrg{
115305b261ecSmrg    REQUEST (xDbeGetBackBufferAttributesReq);
115405b261ecSmrg    register int	n;
115505b261ecSmrg
115605b261ecSmrg    swaps(&stuff->length, n);
115705b261ecSmrg    REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
115805b261ecSmrg
115905b261ecSmrg    swapl(&stuff->buffer, n);
116005b261ecSmrg
116105b261ecSmrg    return(ProcDbeGetBackBufferAttributes(client));
116205b261ecSmrg
116305b261ecSmrg} /* SProcDbeGetBackBufferAttributes() */
116405b261ecSmrg
116505b261ecSmrg
116605b261ecSmrg/******************************************************************************
116705b261ecSmrg *
116805b261ecSmrg * DBE DIX Procedure: SProcDbeDispatch
116905b261ecSmrg *
117005b261ecSmrg * Description:
117105b261ecSmrg *
117205b261ecSmrg *     This function dispatches DBE requests on a swapped server.
117305b261ecSmrg *
117405b261ecSmrg *****************************************************************************/
117505b261ecSmrg
117605b261ecSmrgstatic int
117705b261ecSmrgSProcDbeDispatch(ClientPtr client)
117805b261ecSmrg{
117905b261ecSmrg    REQUEST(xReq);
118005b261ecSmrg
118105b261ecSmrg
118205b261ecSmrg    switch (stuff->data)
118305b261ecSmrg    {
118405b261ecSmrg        case X_DbeGetVersion:
118505b261ecSmrg            return(SProcDbeGetVersion(client));
118605b261ecSmrg
118705b261ecSmrg        case X_DbeAllocateBackBufferName:
118805b261ecSmrg            return(SProcDbeAllocateBackBufferName(client));
118905b261ecSmrg
119005b261ecSmrg        case X_DbeDeallocateBackBufferName:
119105b261ecSmrg            return(SProcDbeDeallocateBackBufferName(client));
119205b261ecSmrg
119305b261ecSmrg        case X_DbeSwapBuffers:
119405b261ecSmrg            return(SProcDbeSwapBuffers(client));
119505b261ecSmrg
119605b261ecSmrg        case X_DbeBeginIdiom:
119705b261ecSmrg            return(SProcDbeBeginIdiom(client));
119805b261ecSmrg
119905b261ecSmrg        case X_DbeEndIdiom:
12006747b715Smrg            return Success;
120105b261ecSmrg
120205b261ecSmrg        case X_DbeGetVisualInfo:
120305b261ecSmrg            return(SProcDbeGetVisualInfo(client));
120405b261ecSmrg
120505b261ecSmrg        case X_DbeGetBackBufferAttributes:
120605b261ecSmrg            return(SProcDbeGetBackBufferAttributes(client));
120705b261ecSmrg
120805b261ecSmrg        default:
12096747b715Smrg            return BadRequest;
121005b261ecSmrg    }
121105b261ecSmrg
121205b261ecSmrg} /* SProcDbeDispatch() */
121305b261ecSmrg
121405b261ecSmrg
121505b261ecSmrg/******************************************************************************
121605b261ecSmrg *
121705b261ecSmrg * DBE DIX Procedure: DbeSetupBackgroundPainter
121805b261ecSmrg *
121905b261ecSmrg * Description:
122005b261ecSmrg *
122105b261ecSmrg *     This function sets up pGC to clear pixmaps.
122205b261ecSmrg *
122305b261ecSmrg * Return Values:
122405b261ecSmrg *
122505b261ecSmrg *     TRUE  - setup was successful
122605b261ecSmrg *     FALSE - the window's background state is NONE
122705b261ecSmrg *
122805b261ecSmrg *****************************************************************************/
122905b261ecSmrg
123005b261ecSmrgstatic Bool
123105b261ecSmrgDbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
123205b261ecSmrg{
12336747b715Smrg    ChangeGCVal	gcvalues[4];
123405b261ecSmrg    int		ts_x_origin, ts_y_origin;
123505b261ecSmrg    PixUnion	background;
123605b261ecSmrg    int		backgroundState;
123705b261ecSmrg    Mask	gcmask;
123805b261ecSmrg
123905b261ecSmrg
124005b261ecSmrg    /* First take care of any ParentRelative stuff by altering the
124105b261ecSmrg     * tile/stipple origin to match the coordinates of the upper-left
124205b261ecSmrg     * corner of the first ancestor without a ParentRelative background.
124305b261ecSmrg     * This coordinate is, of course, negative.
124405b261ecSmrg     */
124505b261ecSmrg    ts_x_origin = ts_y_origin = 0;
124605b261ecSmrg    while (pWin->backgroundState == ParentRelative)
124705b261ecSmrg    {
124805b261ecSmrg        ts_x_origin -= pWin->origin.x;
124905b261ecSmrg        ts_y_origin -= pWin->origin.y;
125005b261ecSmrg
125105b261ecSmrg        pWin = pWin->parent;
125205b261ecSmrg    }
125305b261ecSmrg    backgroundState = pWin->backgroundState;
125405b261ecSmrg    background      = pWin->background;
125505b261ecSmrg
125605b261ecSmrg    switch (backgroundState)
125705b261ecSmrg    {
125805b261ecSmrg        case BackgroundPixel:
12596747b715Smrg            gcvalues[0].val = background.pixel;
12606747b715Smrg            gcvalues[1].val = FillSolid;
126105b261ecSmrg            gcmask = GCForeground|GCFillStyle;
126205b261ecSmrg            break;
126305b261ecSmrg
126405b261ecSmrg        case BackgroundPixmap:
12656747b715Smrg            gcvalues[0].val = FillTiled;
12666747b715Smrg            gcvalues[1].ptr = background.pixmap;
12676747b715Smrg            gcvalues[2].val = ts_x_origin;
12686747b715Smrg            gcvalues[3].val = ts_y_origin;
126905b261ecSmrg            gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
127005b261ecSmrg            break;
127105b261ecSmrg
127205b261ecSmrg        default:
127305b261ecSmrg            /* pWin->backgroundState == None */
12746747b715Smrg            return FALSE;
127505b261ecSmrg    }
127605b261ecSmrg
12776747b715Smrg    return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0;
127805b261ecSmrg} /* DbeSetupBackgroundPainter() */
127905b261ecSmrg
128005b261ecSmrg
128105b261ecSmrg/******************************************************************************
128205b261ecSmrg *
128305b261ecSmrg * DBE DIX Procedure: DbeDrawableDelete
128405b261ecSmrg *
128505b261ecSmrg * Description:
128605b261ecSmrg *
128705b261ecSmrg *     This is the resource delete function for dbeDrawableResType.
128805b261ecSmrg *     It is registered when the drawable resource type is created in
128905b261ecSmrg *     DbeExtensionInit().
129005b261ecSmrg *
129105b261ecSmrg *     To make resource deletion simple, we do not do anything in this function
129205b261ecSmrg *     and leave all resource deleteion to DbeWindowPrivDelete(), which will
129305b261ecSmrg *     eventually be called or already has been called.  Deletion functions are
129405b261ecSmrg *     not guaranteed to be called in any particular order.
129505b261ecSmrg *
129605b261ecSmrg *****************************************************************************/
129705b261ecSmrgstatic int
129805b261ecSmrgDbeDrawableDelete(pointer pDrawable, XID id)
129905b261ecSmrg{
13006747b715Smrg    return Success;
130105b261ecSmrg
130205b261ecSmrg} /* DbeDrawableDelete() */
130305b261ecSmrg
130405b261ecSmrg
130505b261ecSmrg/******************************************************************************
130605b261ecSmrg *
130705b261ecSmrg * DBE DIX Procedure: DbeWindowPrivDelete
130805b261ecSmrg *
130905b261ecSmrg * Description:
131005b261ecSmrg *
131105b261ecSmrg *     This is the resource delete function for dbeWindowPrivResType.
131205b261ecSmrg *     It is registered when the drawable resource type is created in
131305b261ecSmrg *     DbeExtensionInit().
131405b261ecSmrg *
131505b261ecSmrg *****************************************************************************/
131605b261ecSmrgstatic int
131705b261ecSmrgDbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
131805b261ecSmrg{
131905b261ecSmrg    DbeScreenPrivPtr	pDbeScreenPriv;
132005b261ecSmrg    DbeWindowPrivPtr	pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv;
132105b261ecSmrg    int			i;
132205b261ecSmrg
132305b261ecSmrg
132405b261ecSmrg    /*
132505b261ecSmrg     **************************************************************************
132605b261ecSmrg     ** Remove the buffer ID from the ID array.
132705b261ecSmrg     **************************************************************************
132805b261ecSmrg     */
132905b261ecSmrg
133005b261ecSmrg    /* Find the ID in the ID array. */
133105b261ecSmrg    i = 0;
133205b261ecSmrg    while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id))
133305b261ecSmrg    {
133405b261ecSmrg        i++;
133505b261ecSmrg    }
133605b261ecSmrg
133705b261ecSmrg    if (i == pDbeWindowPriv->nBufferIDs)
133805b261ecSmrg    {
133905b261ecSmrg        /* We did not find the ID in the array.  We should never get here. */
13406747b715Smrg        return BadValue;
134105b261ecSmrg    }
134205b261ecSmrg
134305b261ecSmrg    /* Remove the ID from the array. */
134405b261ecSmrg
134505b261ecSmrg    if (i < (pDbeWindowPriv->nBufferIDs - 1))
134605b261ecSmrg    {
134705b261ecSmrg        /* Compress the buffer ID array, overwriting the ID in the process. */
134805b261ecSmrg        memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1],
134905b261ecSmrg            (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
135005b261ecSmrg    }
135105b261ecSmrg    else
135205b261ecSmrg    {
135305b261ecSmrg        /* We are removing the last ID in the array, in which case, the
135405b261ecSmrg         * assignement below is all that we need to do.
135505b261ecSmrg         */
135605b261ecSmrg    }
135705b261ecSmrg    pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
135805b261ecSmrg
135905b261ecSmrg    pDbeWindowPriv->nBufferIDs--;
136005b261ecSmrg
136105b261ecSmrg    /* If an extended array was allocated, then check to see if the remaining
136205b261ecSmrg     * buffer IDs will fit in the static array.
136305b261ecSmrg     */
136405b261ecSmrg
136505b261ecSmrg    if ((pDbeWindowPriv->maxAvailableIDs >  DBE_INIT_MAX_IDS) &&
136605b261ecSmrg        (pDbeWindowPriv->nBufferIDs      == DBE_INIT_MAX_IDS))
136705b261ecSmrg    {
136805b261ecSmrg        /* Copy the IDs back into the static array. */
136905b261ecSmrg        memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
137005b261ecSmrg               DBE_INIT_MAX_IDS * sizeof(XID));
137105b261ecSmrg
137205b261ecSmrg        /* Free the extended array; use the static array. */
13736747b715Smrg        free(pDbeWindowPriv->IDs);
137405b261ecSmrg        pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
137505b261ecSmrg        pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
137605b261ecSmrg    }
137705b261ecSmrg
137805b261ecSmrg
137905b261ecSmrg    /*
138005b261ecSmrg     **************************************************************************
138105b261ecSmrg     ** Perform DDX level tasks.
138205b261ecSmrg     **************************************************************************
138305b261ecSmrg     */
138405b261ecSmrg
138505b261ecSmrg    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(
138605b261ecSmrg                         (DbeWindowPrivPtr)pDbeWindowPriv);
138705b261ecSmrg    (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id);
138805b261ecSmrg
138905b261ecSmrg
139005b261ecSmrg    /*
139105b261ecSmrg     **************************************************************************
139205b261ecSmrg     ** Perform miscellaneous tasks if this is the last buffer associated
139305b261ecSmrg     ** with the window.
139405b261ecSmrg     **************************************************************************
139505b261ecSmrg     */
139605b261ecSmrg
139705b261ecSmrg    if (pDbeWindowPriv->nBufferIDs == 0)
139805b261ecSmrg    {
139905b261ecSmrg        /* Reset the DBE window priv pointer. */
14004642e01fSmrg	dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey,
14014642e01fSmrg		      NULL);
140205b261ecSmrg
140305b261ecSmrg        /* We are done with the window priv. */
14046747b715Smrg	dixFreeObjectWithPrivates(pDbeWindowPriv, PRIVATE_DBE_WINDOW);
140505b261ecSmrg    }
140605b261ecSmrg
14076747b715Smrg    return Success;
140805b261ecSmrg
140905b261ecSmrg} /* DbeWindowPrivDelete() */
141005b261ecSmrg
141105b261ecSmrg
141205b261ecSmrg/******************************************************************************
141305b261ecSmrg *
141405b261ecSmrg * DBE DIX Procedure: DbeResetProc
141505b261ecSmrg *
141605b261ecSmrg * Description:
141705b261ecSmrg *
141805b261ecSmrg *     This routine is called at the end of every server generation.
141905b261ecSmrg *     It deallocates any memory reserved for the extension and performs any
142005b261ecSmrg *     other tasks related to shutting down the extension.
142105b261ecSmrg *
142205b261ecSmrg *****************************************************************************/
142305b261ecSmrgstatic void
142405b261ecSmrgDbeResetProc(ExtensionEntry *extEntry)
142505b261ecSmrg{
142605b261ecSmrg    int			i;
142705b261ecSmrg    ScreenPtr		pScreen;
142805b261ecSmrg    DbeScreenPrivPtr	pDbeScreenPriv;
142905b261ecSmrg
143005b261ecSmrg    for (i = 0; i < screenInfo.numScreens; i++)
143105b261ecSmrg    {
143205b261ecSmrg	pScreen = screenInfo.screens[i];
143305b261ecSmrg	pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
143405b261ecSmrg
143505b261ecSmrg	if (pDbeScreenPriv)
143605b261ecSmrg	{
143705b261ecSmrg            /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/
143805b261ecSmrg            pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
143905b261ecSmrg
144005b261ecSmrg	    if (pDbeScreenPriv->ResetProc)
144105b261ecSmrg		(*pDbeScreenPriv->ResetProc)(pScreen);
144205b261ecSmrg
14436747b715Smrg	    free(pDbeScreenPriv);
144405b261ecSmrg	}
144505b261ecSmrg    }
144605b261ecSmrg} /* DbeResetProc() */
144705b261ecSmrg
144805b261ecSmrg
144905b261ecSmrg/******************************************************************************
145005b261ecSmrg *
145105b261ecSmrg * DBE DIX Procedure: DbeDestroyWindow
145205b261ecSmrg *
145305b261ecSmrg * Description:
145405b261ecSmrg *
145505b261ecSmrg *     This is the wrapper for pScreen->DestroyWindow.
145605b261ecSmrg *     This function frees buffer resources for a window before it is
145705b261ecSmrg *     destroyed.
145805b261ecSmrg *
145905b261ecSmrg *****************************************************************************/
146005b261ecSmrg
146105b261ecSmrgstatic Bool
146205b261ecSmrgDbeDestroyWindow(WindowPtr pWin)
146305b261ecSmrg{
146405b261ecSmrg    DbeScreenPrivPtr	pDbeScreenPriv;
146505b261ecSmrg    DbeWindowPrivPtr	pDbeWindowPriv;
146605b261ecSmrg    ScreenPtr		pScreen;
146705b261ecSmrg    Bool		ret;
146805b261ecSmrg
146905b261ecSmrg
147005b261ecSmrg    /*
147105b261ecSmrg     **************************************************************************
147205b261ecSmrg     ** 1. Unwrap the member routine.
147305b261ecSmrg     **************************************************************************
147405b261ecSmrg     */
147505b261ecSmrg
147605b261ecSmrg    pScreen                = pWin->drawable.pScreen;
147705b261ecSmrg    pDbeScreenPriv         = DBE_SCREEN_PRIV(pScreen);
147805b261ecSmrg    pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
147905b261ecSmrg
148005b261ecSmrg    /*
148105b261ecSmrg     **************************************************************************
148205b261ecSmrg     ** 2. Do any work necessary before the member routine is called.
148305b261ecSmrg     **
148405b261ecSmrg     **    Call the window priv delete function for all buffer IDs associated
148505b261ecSmrg     **    with this window.
148605b261ecSmrg     **************************************************************************
148705b261ecSmrg     */
148805b261ecSmrg
148905b261ecSmrg    if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
149005b261ecSmrg    {
149105b261ecSmrg        while (pDbeWindowPriv)
149205b261ecSmrg        {
149305b261ecSmrg            /* *DbeWinPrivDelete() will free the window private and set it to
149405b261ecSmrg             * NULL if there are no more buffer IDs associated with this
149505b261ecSmrg             * window.
149605b261ecSmrg             */
149705b261ecSmrg            FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
149805b261ecSmrg            pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
149905b261ecSmrg        }
150005b261ecSmrg    }
150105b261ecSmrg
150205b261ecSmrg    /*
150305b261ecSmrg     **************************************************************************
150405b261ecSmrg     ** 3. Call the member routine, saving its result if necessary.
150505b261ecSmrg     **************************************************************************
150605b261ecSmrg     */
150705b261ecSmrg
150805b261ecSmrg    ret = (*pScreen->DestroyWindow)(pWin);
150905b261ecSmrg
151005b261ecSmrg    /*
151105b261ecSmrg     **************************************************************************
151205b261ecSmrg     ** 4. Rewrap the member routine, restoring the wrapper value first in case
151305b261ecSmrg     **    the wrapper (or something that it wrapped) change this value.
151405b261ecSmrg     **************************************************************************
151505b261ecSmrg     */
151605b261ecSmrg
151705b261ecSmrg    pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
151805b261ecSmrg    pScreen->DestroyWindow = DbeDestroyWindow;
151905b261ecSmrg
152005b261ecSmrg    /*
152105b261ecSmrg     **************************************************************************
152205b261ecSmrg     ** 5. Do any work necessary after the member routine has been called.
152305b261ecSmrg     **
152405b261ecSmrg     **    In this case we do not need to do anything.
152505b261ecSmrg     **************************************************************************
152605b261ecSmrg     */
152705b261ecSmrg
15286747b715Smrg    return ret;
152905b261ecSmrg
153005b261ecSmrg} /* DbeDestroyWindow() */
153105b261ecSmrg
153205b261ecSmrg
153305b261ecSmrg/******************************************************************************
153405b261ecSmrg *
153505b261ecSmrg * DBE DIX Procedure: DbeExtensionInit
153605b261ecSmrg *
153705b261ecSmrg * Description:
153805b261ecSmrg *
153905b261ecSmrg *     Called from InitExtensions in main()
154005b261ecSmrg *
154105b261ecSmrg *****************************************************************************/
154205b261ecSmrg
154305b261ecSmrgvoid
154405b261ecSmrgDbeExtensionInit(void)
154505b261ecSmrg{
154605b261ecSmrg    ExtensionEntry	*extEntry;
154705b261ecSmrg    register int	i, j;
154805b261ecSmrg    ScreenPtr		pScreen = NULL;
154905b261ecSmrg    DbeScreenPrivPtr	pDbeScreenPriv;
155005b261ecSmrg    int			nStubbedScreens = 0;
155105b261ecSmrg    Bool		ddxInitSuccess;
155205b261ecSmrg
155305b261ecSmrg#ifdef PANORAMIX
155405b261ecSmrg    if(!noPanoramiXExtension) return;
155505b261ecSmrg#endif
155605b261ecSmrg
155705b261ecSmrg    /* Create the resource types. */
155805b261ecSmrg    dbeDrawableResType =
15596747b715Smrg        CreateNewResourceType(DbeDrawableDelete, "dbeDrawable");
15606747b715Smrg    if (!dbeDrawableResType)
15616747b715Smrg	return;
15626747b715Smrg    dbeDrawableResType |= RC_DRAWABLE;
15636747b715Smrg
156405b261ecSmrg    dbeWindowPrivResType =
15656747b715Smrg        CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow");
15666747b715Smrg    if (!dbeWindowPrivResType)
15676747b715Smrg	return;
15686747b715Smrg
15696747b715Smrg    if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0))
15706747b715Smrg	return;
15716747b715Smrg
15726747b715Smrg    if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0))
15734642e01fSmrg	return;
157405b261ecSmrg
157505b261ecSmrg    for (i = 0; i < screenInfo.numScreens; i++)
157605b261ecSmrg    {
157705b261ecSmrg        /* For each screen, set up DBE screen privates and init DIX and DDX
157805b261ecSmrg         * interface.
157905b261ecSmrg         */
158005b261ecSmrg
158105b261ecSmrg	pScreen = screenInfo.screens[i];
158205b261ecSmrg
15836747b715Smrg	if (!(pDbeScreenPriv = malloc (sizeof (DbeScreenPrivRec))))
158405b261ecSmrg	{
158505b261ecSmrg            /* If we can not alloc a window or screen private,
158605b261ecSmrg             * then free any privates that we already alloc'ed and return
158705b261ecSmrg             */
158805b261ecSmrg
158905b261ecSmrg	    for (j = 0; j < i; j++)
159005b261ecSmrg	    {
15916747b715Smrg		free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates,
15924642e01fSmrg				       dbeScreenPrivKey));
15934642e01fSmrg		dixSetPrivate(&screenInfo.screens[j]->devPrivates,
15944642e01fSmrg			      dbeScreenPrivKey, NULL);
159505b261ecSmrg	    }
159605b261ecSmrg	    return;
159705b261ecSmrg	}
159805b261ecSmrg
15994642e01fSmrg	dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv);
160005b261ecSmrg
160105b261ecSmrg        {
16024642e01fSmrg            /* We don't have DDX support for DBE anymore */
160305b261ecSmrg
160405b261ecSmrg#ifndef DISABLE_MI_DBE_BY_DEFAULT
160505b261ecSmrg            /* Setup DIX. */
160605b261ecSmrg            pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
160705b261ecSmrg
160805b261ecSmrg            /* Setup DDX. */
160905b261ecSmrg            ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
161005b261ecSmrg
161105b261ecSmrg            /* DDX DBE initialization may have the side affect of
161205b261ecSmrg             * reallocating pDbeScreenPriv, so we need to update it.
161305b261ecSmrg             */
161405b261ecSmrg            pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
161505b261ecSmrg
161605b261ecSmrg            if (ddxInitSuccess)
161705b261ecSmrg            {
161805b261ecSmrg                /* Wrap DestroyWindow.  The DDX initialization function
161905b261ecSmrg                 * already wrapped PositionWindow for us.
162005b261ecSmrg                 */
162105b261ecSmrg
162205b261ecSmrg                pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
162305b261ecSmrg                pScreen->DestroyWindow        = DbeDestroyWindow;
162405b261ecSmrg            }
162505b261ecSmrg            else
162605b261ecSmrg            {
162705b261ecSmrg                /* DDX initialization failed.  Stub the screen. */
162805b261ecSmrg                DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
162905b261ecSmrg            }
163005b261ecSmrg#else
163105b261ecSmrg            DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
163205b261ecSmrg#endif
163305b261ecSmrg
16344642e01fSmrg        }
163505b261ecSmrg
163605b261ecSmrg    } /* for (i = 0; i < screenInfo.numScreens; i++) */
163705b261ecSmrg
163805b261ecSmrg
163905b261ecSmrg    if (nStubbedScreens == screenInfo.numScreens)
164005b261ecSmrg    {
164105b261ecSmrg	/* All screens stubbed.  Clean up and return. */
164205b261ecSmrg
164305b261ecSmrg        for (i = 0; i < screenInfo.numScreens; i++)
164405b261ecSmrg        {
16456747b715Smrg		free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates,
16464642e01fSmrg				       dbeScreenPrivKey));
16474642e01fSmrg		dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL);
164805b261ecSmrg        }
164905b261ecSmrg        return;
165005b261ecSmrg    }
165105b261ecSmrg
165205b261ecSmrg
165305b261ecSmrg    /* Now add the extension. */
165405b261ecSmrg    extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
165505b261ecSmrg                            DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
165605b261ecSmrg                            DbeResetProc, StandardMinorOpcode);
165705b261ecSmrg
165805b261ecSmrg    dbeErrorBase = extEntry->errorBase;
16596747b715Smrg    SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer);
16606747b715Smrg    SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer);
166105b261ecSmrg
166205b261ecSmrg} /* DbeExtensionInit() */
166305b261ecSmrg
1664