105b261ecSmrg/******************************************************************************
2f7df2e56Smrg *
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:
12f7df2e56Smrg *
1305b261ecSmrg * The above copyright notice and this permission notice shall be included
1405b261ecSmrg * in all copies or substantial portions of the Software.
15f7df2e56Smrg *
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.
23f7df2e56Smrg *
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.
28f7df2e56Smrg *
2905b261ecSmrg *     DIX DBE code
3005b261ecSmrg *
3105b261ecSmrg *****************************************************************************/
3205b261ecSmrg
3305b261ecSmrg/* INCLUDES */
3405b261ecSmrg
3505b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
3605b261ecSmrg#include <dix-config.h>
3705b261ecSmrg#endif
3805b261ecSmrg
3905b261ecSmrg#include <string.h>
4005b261ecSmrg#include <stdint.h>
4105b261ecSmrg#include <X11/X.h>
4205b261ecSmrg#include <X11/Xproto.h>
4305b261ecSmrg#include "scrnintstr.h"
4405b261ecSmrg#include "extnsionst.h"
45f7df2e56Smrg#include "extinit.h"
4605b261ecSmrg#include "gcstruct.h"
4705b261ecSmrg#include "dixstruct.h"
4805b261ecSmrg#define NEED_DBE_PROTOCOL
4905b261ecSmrg#include "dbestruct.h"
5005b261ecSmrg#include "midbe.h"
514642e01fSmrg#include "xace.h"
5205b261ecSmrg
5305b261ecSmrg/* GLOBALS */
5405b261ecSmrg
556747b715Smrg/* These are globals for use by DDX */
566747b715SmrgDevPrivateKeyRec dbeScreenPrivKeyRec;
576747b715SmrgDevPrivateKeyRec dbeWindowPrivKeyRec;
5805b261ecSmrg
596747b715Smrg/* These are globals for use by DDX */
60f7df2e56SmrgRESTYPE dbeDrawableResType;
61f7df2e56SmrgRESTYPE dbeWindowPrivResType;
6205b261ecSmrg
6305b261ecSmrg/* Used to generate DBE's BadBuffer error. */
64f7df2e56Smrgstatic int dbeErrorBase;
6505b261ecSmrg
6605b261ecSmrg/******************************************************************************
6705b261ecSmrg *
6805b261ecSmrg * DBE DIX Procedure: DbeStubScreen
6905b261ecSmrg *
7005b261ecSmrg * Description:
7105b261ecSmrg *
7205b261ecSmrg *     This is function stubs the function pointers in the given DBE screen
7305b261ecSmrg *     private and increments the number of stubbed screens.
7405b261ecSmrg *
7505b261ecSmrg *****************************************************************************/
7605b261ecSmrg
7705b261ecSmrgstatic void
7805b261ecSmrgDbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
7905b261ecSmrg{
8005b261ecSmrg    /* Stub DIX. */
8105b261ecSmrg    pDbeScreenPriv->SetupBackgroundPainter = NULL;
8205b261ecSmrg
8305b261ecSmrg    /* Do not unwrap PositionWindow nor DestroyWindow.  If the DDX
8405b261ecSmrg     * initialization function failed, we assume that it did not wrap
8505b261ecSmrg     * PositionWindow.  Also, DestroyWindow is only wrapped if the DDX
8605b261ecSmrg     * initialization function succeeded.
8705b261ecSmrg     */
8805b261ecSmrg
8905b261ecSmrg    /* Stub DDX. */
90f7df2e56Smrg    pDbeScreenPriv->GetVisualInfo = NULL;
9105b261ecSmrg    pDbeScreenPriv->AllocBackBufferName = NULL;
92f7df2e56Smrg    pDbeScreenPriv->SwapBuffers = NULL;
93f7df2e56Smrg    pDbeScreenPriv->WinPrivDelete = NULL;
9405b261ecSmrg
9505b261ecSmrg    (*nStubbedScreens)++;
9605b261ecSmrg
97f7df2e56Smrg}                               /* DbeStubScreen() */
9805b261ecSmrg
9905b261ecSmrg/******************************************************************************
10005b261ecSmrg *
10105b261ecSmrg * DBE DIX Procedure: ProcDbeGetVersion
10205b261ecSmrg *
10305b261ecSmrg * Description:
10405b261ecSmrg *
10505b261ecSmrg *     This function is for processing a DbeGetVersion request.
10605b261ecSmrg *     This request returns the major and minor version numbers of this
10705b261ecSmrg *     extension.
10805b261ecSmrg *
10905b261ecSmrg * Return Values:
11005b261ecSmrg *
11105b261ecSmrg *     Success
11205b261ecSmrg *
11305b261ecSmrg *****************************************************************************/
11405b261ecSmrg
11505b261ecSmrgstatic int
11605b261ecSmrgProcDbeGetVersion(ClientPtr client)
11705b261ecSmrg{
11805b261ecSmrg    /* REQUEST(xDbeGetVersionReq); */
119f7df2e56Smrg    xDbeGetVersionReply rep = {
120f7df2e56Smrg        .type = X_Reply,
121f7df2e56Smrg        .sequenceNumber = client->sequence,
122f7df2e56Smrg        .length = 0,
123f7df2e56Smrg        .majorVersion = DBE_MAJOR_VERSION,
124f7df2e56Smrg        .minorVersion = DBE_MINOR_VERSION
125f7df2e56Smrg    };
12605b261ecSmrg
12705b261ecSmrg    REQUEST_SIZE_MATCH(xDbeGetVersionReq);
12805b261ecSmrg
129f7df2e56Smrg    if (client->swapped) {
130f7df2e56Smrg        swaps(&rep.sequenceNumber);
13105b261ecSmrg    }
13205b261ecSmrg
133f7df2e56Smrg    WriteToClient(client, sizeof(xDbeGetVersionReply), &rep);
13405b261ecSmrg
1356747b715Smrg    return Success;
13605b261ecSmrg
137f7df2e56Smrg}                               /* ProcDbeGetVersion() */
13805b261ecSmrg
13905b261ecSmrg/******************************************************************************
14005b261ecSmrg *
14105b261ecSmrg * DBE DIX Procedure: ProcDbeAllocateBackBufferName
14205b261ecSmrg *
14305b261ecSmrg * Description:
14405b261ecSmrg *
14505b261ecSmrg *     This function is for processing a DbeAllocateBackBufferName request.
14605b261ecSmrg *     This request allocates a drawable ID used to refer to the back buffer
14705b261ecSmrg *     of a window.
14805b261ecSmrg *
14905b261ecSmrg * Return Values:
15005b261ecSmrg *
15105b261ecSmrg *     BadAlloc    - server can not allocate resources
15205b261ecSmrg *     BadIDChoice - id is out of range for client; id is already in use
15305b261ecSmrg *     BadMatch    - window is not an InputOutput window;
15405b261ecSmrg *                   visual of window is not on list returned by
155f7df2e56Smrg *                   DBEGetVisualInfo;
15605b261ecSmrg *     BadValue    - invalid swap action is specified
15705b261ecSmrg *     BadWindow   - window is not a valid window
15805b261ecSmrg *     Success
15905b261ecSmrg *
16005b261ecSmrg *****************************************************************************/
16105b261ecSmrg
16205b261ecSmrgstatic int
16305b261ecSmrgProcDbeAllocateBackBufferName(ClientPtr client)
16405b261ecSmrg{
16505b261ecSmrg    REQUEST(xDbeAllocateBackBufferNameReq);
166f7df2e56Smrg    WindowPtr pWin;
167f7df2e56Smrg    DbeScreenPrivPtr pDbeScreenPriv;
168f7df2e56Smrg    DbeWindowPrivPtr pDbeWindowPriv;
169f7df2e56Smrg    XdbeScreenVisualInfo scrVisInfo;
170f7df2e56Smrg    register int i;
171f7df2e56Smrg    Bool visualMatched = FALSE;
172f7df2e56Smrg    xDbeSwapAction swapAction;
173f7df2e56Smrg    VisualID visual;
174f7df2e56Smrg    int status;
175f7df2e56Smrg    int add_index;
17605b261ecSmrg
17705b261ecSmrg    REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
17805b261ecSmrg
17905b261ecSmrg    /* The window must be valid. */
1804642e01fSmrg    status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
18105b261ecSmrg    if (status != Success)
182f7df2e56Smrg        return status;
18305b261ecSmrg
18405b261ecSmrg    /* The window must be InputOutput. */
185f7df2e56Smrg    if (pWin->drawable.class != InputOutput) {
186f7df2e56Smrg        return BadMatch;
18705b261ecSmrg    }
18805b261ecSmrg
18905b261ecSmrg    /* The swap action must be valid. */
190f7df2e56Smrg    swapAction = stuff->swapAction;     /* use local var for performance. */
191f7df2e56Smrg    if ((swapAction != XdbeUndefined) &&
19205b261ecSmrg        (swapAction != XdbeBackground) &&
193f7df2e56Smrg        (swapAction != XdbeUntouched) && (swapAction != XdbeCopied)) {
1946747b715Smrg        return BadValue;
19505b261ecSmrg    }
19605b261ecSmrg
19705b261ecSmrg    /* The id must be in range and not already in use. */
19805b261ecSmrg    LEGAL_NEW_RESOURCE(stuff->buffer, client);
19905b261ecSmrg
20005b261ecSmrg    /* The visual of the window must be in the list returned by
20105b261ecSmrg     * GetVisualInfo.
20205b261ecSmrg     */
20305b261ecSmrg    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
20405b261ecSmrg    if (!pDbeScreenPriv->GetVisualInfo)
205f7df2e56Smrg        return BadMatch;        /* screen doesn't support double buffering */
20605b261ecSmrg
207f7df2e56Smrg    if (!(*pDbeScreenPriv->GetVisualInfo) (pWin->drawable.pScreen, &scrVisInfo)) {
20805b261ecSmrg        /* GetVisualInfo() failed to allocate visual info data. */
2096747b715Smrg        return BadAlloc;
21005b261ecSmrg    }
21105b261ecSmrg
21205b261ecSmrg    /* See if the window's visual is on the list. */
21305b261ecSmrg    visual = wVisual(pWin);
214f7df2e56Smrg    for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++) {
215f7df2e56Smrg        if (scrVisInfo.visinfo[i].visual == visual) {
216f7df2e56Smrg            visualMatched = TRUE;
217f7df2e56Smrg        }
21805b261ecSmrg    }
21905b261ecSmrg
22005b261ecSmrg    /* Free what was allocated by the GetVisualInfo() call above. */
2216747b715Smrg    free(scrVisInfo.visinfo);
22205b261ecSmrg
223f7df2e56Smrg    if (!visualMatched) {
224f7df2e56Smrg        return BadMatch;
22505b261ecSmrg    }
22605b261ecSmrg
227f7df2e56Smrg    if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL) {
22805b261ecSmrg        /* There is no buffer associated with the window.
22905b261ecSmrg         * Allocate a window priv.
23005b261ecSmrg         */
23105b261ecSmrg
232f7df2e56Smrg        pDbeWindowPriv = calloc(1, sizeof(DbeWindowPrivRec));
233f7df2e56Smrg        if (!pDbeWindowPriv)
2346747b715Smrg            return BadAlloc;
23505b261ecSmrg
23605b261ecSmrg        /* Fill out window priv information. */
237f7df2e56Smrg        pDbeWindowPriv->pWindow = pWin;
238f7df2e56Smrg        pDbeWindowPriv->width = pWin->drawable.width;
239f7df2e56Smrg        pDbeWindowPriv->height = pWin->drawable.height;
240f7df2e56Smrg        pDbeWindowPriv->x = pWin->drawable.x;
241f7df2e56Smrg        pDbeWindowPriv->y = pWin->drawable.y;
242f7df2e56Smrg        pDbeWindowPriv->nBufferIDs = 0;
24305b261ecSmrg
24405b261ecSmrg        /* Set the buffer ID array pointer to the initial (static) array). */
24505b261ecSmrg        pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
24605b261ecSmrg
247f7df2e56Smrg        /* Initialize the buffer ID list. */
24805b261ecSmrg        pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
24905b261ecSmrg        pDbeWindowPriv->IDs[0] = stuff->buffer;
2504642e01fSmrg
2514642e01fSmrg        add_index = 0;
252f7df2e56Smrg        for (i = 0; i < DBE_INIT_MAX_IDS; i++) {
25305b261ecSmrg            pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
25405b261ecSmrg        }
25505b261ecSmrg
25605b261ecSmrg        /* Actually connect the window priv to the window. */
2574642e01fSmrg        dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
25805b261ecSmrg
259f7df2e56Smrg    }                           /* if -- There is no buffer associated with the window. */
26005b261ecSmrg
261f7df2e56Smrg    else {
26205b261ecSmrg        /* A buffer is already associated with the window.
26305b261ecSmrg         * Add the new buffer ID to the array, reallocating the array memory
26405b261ecSmrg         * if necessary.
26505b261ecSmrg         */
26605b261ecSmrg
26705b261ecSmrg        /* Determine if there is a free element in the ID array. */
268f7df2e56Smrg        for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++) {
269f7df2e56Smrg            if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT) {
27005b261ecSmrg                /* There is still room in the ID array. */
27105b261ecSmrg                break;
27205b261ecSmrg            }
27305b261ecSmrg        }
274f7df2e56Smrg
275f7df2e56Smrg        if (i == pDbeWindowPriv->maxAvailableIDs) {
27605b261ecSmrg            /* No more room in the ID array -- reallocate another array. */
277f7df2e56Smrg            XID *pIDs;
27805b261ecSmrg
27905b261ecSmrg            /* Setup an array pointer for the realloc operation below. */
280f7df2e56Smrg            if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) {
28105b261ecSmrg                /* We will malloc a new array. */
28205b261ecSmrg                pIDs = NULL;
28305b261ecSmrg            }
284f7df2e56Smrg            else {
28505b261ecSmrg                /* We will realloc a new array. */
28605b261ecSmrg                pIDs = pDbeWindowPriv->IDs;
28705b261ecSmrg            }
28805b261ecSmrg
28905b261ecSmrg            /* malloc/realloc a new array and initialize all elements to 0. */
290f7df2e56Smrg            pDbeWindowPriv->IDs =
291f7df2e56Smrg                reallocarray(pIDs,
292f7df2e56Smrg                             pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS,
293f7df2e56Smrg                             sizeof(XID));
294f7df2e56Smrg            if (!pDbeWindowPriv->IDs) {
2956747b715Smrg                return BadAlloc;
29605b261ecSmrg            }
29705b261ecSmrg            memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
29805b261ecSmrg                   (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
29905b261ecSmrg                    pDbeWindowPriv->nBufferIDs) * sizeof(XID));
30005b261ecSmrg
301f7df2e56Smrg            if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) {
30205b261ecSmrg                /* We just went from using the initial (static) array to a
30305b261ecSmrg                 * newly allocated array.  Copy the IDs from the initial array
30405b261ecSmrg                 * to the new array.
30505b261ecSmrg                 */
30605b261ecSmrg                memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
30705b261ecSmrg                       DBE_INIT_MAX_IDS * sizeof(XID));
30805b261ecSmrg            }
30905b261ecSmrg
31005b261ecSmrg            pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
31105b261ecSmrg        }
31205b261ecSmrg
313f7df2e56Smrg        add_index = i;
31405b261ecSmrg
315f7df2e56Smrg    }                           /* else -- A buffer is already associated with the window. */
31605b261ecSmrg
31705b261ecSmrg    /* Call the DDX routine to allocate the back buffer. */
318f7df2e56Smrg    status = (*pDbeScreenPriv->AllocBackBufferName) (pWin, stuff->buffer,
319f7df2e56Smrg                                                     stuff->swapAction);
32005b261ecSmrg
321f7df2e56Smrg    if (status == Success) {
322f7df2e56Smrg        pDbeWindowPriv->IDs[add_index] = stuff->buffer;
3234642e01fSmrg        if (!AddResource(stuff->buffer, dbeWindowPrivResType,
324f7df2e56Smrg                         (void *) pDbeWindowPriv)) {
3254642e01fSmrg            pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
3264642e01fSmrg
3274642e01fSmrg            if (pDbeWindowPriv->nBufferIDs == 0) {
3284642e01fSmrg                status = BadAlloc;
3294642e01fSmrg                goto out_free;
3304642e01fSmrg            }
3314642e01fSmrg        }
332f7df2e56Smrg    }
333f7df2e56Smrg    else {
33405b261ecSmrg        /* The DDX buffer allocation routine failed for the first buffer of
33505b261ecSmrg         * this window.
33605b261ecSmrg         */
3374642e01fSmrg        if (pDbeWindowPriv->nBufferIDs == 0) {
3384642e01fSmrg            goto out_free;
3394642e01fSmrg        }
34005b261ecSmrg    }
34105b261ecSmrg
34205b261ecSmrg    /* Increment the number of buffers (XIDs) associated with this window. */
34305b261ecSmrg    pDbeWindowPriv->nBufferIDs++;
34405b261ecSmrg
34505b261ecSmrg    /* Set swap action on all calls. */
34605b261ecSmrg    pDbeWindowPriv->swapAction = stuff->swapAction;
34705b261ecSmrg
3486747b715Smrg    return status;
34905b261ecSmrg
350f7df2e56Smrg out_free:
3514642e01fSmrg    dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
3526747b715Smrg    free(pDbeWindowPriv);
3536747b715Smrg    return status;
3544642e01fSmrg
355f7df2e56Smrg}                               /* ProcDbeAllocateBackBufferName() */
35605b261ecSmrg
35705b261ecSmrg/******************************************************************************
35805b261ecSmrg *
35905b261ecSmrg * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
36005b261ecSmrg *
36105b261ecSmrg * Description:
36205b261ecSmrg *
36305b261ecSmrg *     This function is for processing a DbeDeallocateBackBufferName request.
36405b261ecSmrg *     This request frees a drawable ID that was obtained by a
36505b261ecSmrg *     DbeAllocateBackBufferName request.
36605b261ecSmrg *
36705b261ecSmrg * Return Values:
36805b261ecSmrg *
36905b261ecSmrg *     BadBuffer - buffer to deallocate is not associated with a window
37005b261ecSmrg *     Success
37105b261ecSmrg *
37205b261ecSmrg *****************************************************************************/
37305b261ecSmrg
37405b261ecSmrgstatic int
37505b261ecSmrgProcDbeDeallocateBackBufferName(ClientPtr client)
37605b261ecSmrg{
37705b261ecSmrg    REQUEST(xDbeDeallocateBackBufferNameReq);
378f7df2e56Smrg    DbeWindowPrivPtr pDbeWindowPriv;
379f7df2e56Smrg    int rc, i;
380f7df2e56Smrg    void *val;
38105b261ecSmrg
38205b261ecSmrg    REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
38305b261ecSmrg
38405b261ecSmrg    /* Buffer name must be valid */
385f7df2e56Smrg    rc = dixLookupResourceByType((void **) &pDbeWindowPriv, stuff->buffer,
386f7df2e56Smrg                                 dbeWindowPrivResType, client,
387f7df2e56Smrg                                 DixDestroyAccess);
3886747b715Smrg    if (rc != Success)
389f7df2e56Smrg        return rc;
3906747b715Smrg
3916747b715Smrg    rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType,
392f7df2e56Smrg                                 client, DixDestroyAccess);
3936747b715Smrg    if (rc != Success)
394f7df2e56Smrg        return rc;
39505b261ecSmrg
39605b261ecSmrg    /* Make sure that the id is valid for the window.
39705b261ecSmrg     * This is paranoid code since we already looked up the ID by type
39805b261ecSmrg     * above.
39905b261ecSmrg     */
40005b261ecSmrg
401f7df2e56Smrg    for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) {
40205b261ecSmrg        /* Loop through the ID list to find the ID. */
403f7df2e56Smrg        if (pDbeWindowPriv->IDs[i] == stuff->buffer) {
40405b261ecSmrg            break;
40505b261ecSmrg        }
40605b261ecSmrg    }
40705b261ecSmrg
408f7df2e56Smrg    if (i == pDbeWindowPriv->nBufferIDs) {
40905b261ecSmrg        /* We did not find the ID in the ID list. */
41005b261ecSmrg        client->errorValue = stuff->buffer;
4116747b715Smrg        return dbeErrorBase + DbeBadBuffer;
41205b261ecSmrg    }
41305b261ecSmrg
41405b261ecSmrg    FreeResource(stuff->buffer, RT_NONE);
41505b261ecSmrg
4166747b715Smrg    return Success;
41705b261ecSmrg
418f7df2e56Smrg}                               /* ProcDbeDeallocateBackBufferName() */
41905b261ecSmrg
42005b261ecSmrg/******************************************************************************
42105b261ecSmrg *
42205b261ecSmrg * DBE DIX Procedure: ProcDbeSwapBuffers
42305b261ecSmrg *
42405b261ecSmrg * Description:
42505b261ecSmrg *
42605b261ecSmrg *     This function is for processing a DbeSwapBuffers request.
42705b261ecSmrg *     This request swaps the buffers for all windows listed, applying the
42805b261ecSmrg *     appropriate swap action for each window.
42905b261ecSmrg *
43005b261ecSmrg * Return Values:
43105b261ecSmrg *
43205b261ecSmrg *     BadAlloc  - local allocation failed; this return value is not defined
43305b261ecSmrg *                 by the protocol
43405b261ecSmrg *     BadMatch  - a window in request is not double-buffered; a window in
43505b261ecSmrg *                 request is listed more than once
43605b261ecSmrg *     BadValue  - invalid swap action is specified; no swap action is
43705b261ecSmrg *                 specified
43805b261ecSmrg *     BadWindow - a window in request is not valid
43905b261ecSmrg *     Success
44005b261ecSmrg *
44105b261ecSmrg *****************************************************************************/
44205b261ecSmrg
44305b261ecSmrgstatic int
44405b261ecSmrgProcDbeSwapBuffers(ClientPtr client)
44505b261ecSmrg{
44605b261ecSmrg    REQUEST(xDbeSwapBuffersReq);
447f7df2e56Smrg    WindowPtr pWin;
448f7df2e56Smrg    DbeScreenPrivPtr pDbeScreenPriv;
449f7df2e56Smrg    DbeSwapInfoPtr swapInfo;
450f7df2e56Smrg    xDbeSwapInfo *dbeSwapInfo;
451f7df2e56Smrg    int error;
4520b0d8713Smrg    unsigned int i, j;
4530b0d8713Smrg    unsigned int nStuff;
454f7df2e56Smrg    int nStuff_i;       /* DDX API requires int for nStuff */
45505b261ecSmrg
45605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
457f7df2e56Smrg    nStuff = stuff->n;          /* use local variable for performance. */
45805b261ecSmrg
459f7df2e56Smrg    if (nStuff == 0) {
4600b0d8713Smrg        REQUEST_SIZE_MATCH(xDbeSwapBuffersReq);
4616747b715Smrg        return Success;
46205b261ecSmrg    }
46305b261ecSmrg
46405b261ecSmrg    if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
465f7df2e56Smrg        return BadAlloc;
4660b0d8713Smrg    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo));
46705b261ecSmrg
46805b261ecSmrg    /* Get to the swap info appended to the end of the request. */
469f7df2e56Smrg    dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
47005b261ecSmrg
471f7df2e56Smrg    /* Allocate array to record swap information. */
472f7df2e56Smrg    swapInfo = xallocarray(nStuff, sizeof(DbeSwapInfoRec));
473f7df2e56Smrg    if (swapInfo == NULL) {
4746747b715Smrg        return BadAlloc;
47505b261ecSmrg    }
47605b261ecSmrg
477f7df2e56Smrg    for (i = 0; i < nStuff; i++) {
47805b261ecSmrg        /* Check all windows to swap. */
47905b261ecSmrg
48005b261ecSmrg        /* Each window must be a valid window - BadWindow. */
481f7df2e56Smrg        error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client,
482f7df2e56Smrg                                DixWriteAccess);
483f7df2e56Smrg        if (error != Success) {
4846747b715Smrg            free(swapInfo);
485f7df2e56Smrg            return error;
48605b261ecSmrg        }
48705b261ecSmrg
48805b261ecSmrg        /* Each window must be double-buffered - BadMatch. */
489f7df2e56Smrg        if (DBE_WINDOW_PRIV(pWin) == NULL) {
4906747b715Smrg            free(swapInfo);
4916747b715Smrg            return BadMatch;
49205b261ecSmrg        }
49305b261ecSmrg
49405b261ecSmrg        /* Each window must only be specified once - BadMatch. */
495f7df2e56Smrg        for (j = i + 1; j < nStuff; j++) {
496f7df2e56Smrg            if (dbeSwapInfo[i].window == dbeSwapInfo[j].window) {
4976747b715Smrg                free(swapInfo);
4986747b715Smrg                return BadMatch;
499f7df2e56Smrg            }
50005b261ecSmrg        }
50105b261ecSmrg
50205b261ecSmrg        /* Each swap action must be valid - BadValue. */
503f7df2e56Smrg        if ((dbeSwapInfo[i].swapAction != XdbeUndefined) &&
50405b261ecSmrg            (dbeSwapInfo[i].swapAction != XdbeBackground) &&
505f7df2e56Smrg            (dbeSwapInfo[i].swapAction != XdbeUntouched) &&
506f7df2e56Smrg            (dbeSwapInfo[i].swapAction != XdbeCopied)) {
5076747b715Smrg            free(swapInfo);
5086747b715Smrg            return BadValue;
50905b261ecSmrg        }
51005b261ecSmrg
51105b261ecSmrg        /* Everything checks out OK.  Fill in the swap info array. */
512f7df2e56Smrg        swapInfo[i].pWindow = pWin;
513f7df2e56Smrg        swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;
51405b261ecSmrg
515f7df2e56Smrg    }                           /* for (i = 0; i < nStuff; i++) */
51605b261ecSmrg
51705b261ecSmrg    /* Call the DDX routine to perform the swap(s).  The DDX routine should
51805b261ecSmrg     * scan the swap list (swap info), swap any buffers that it knows how to
51905b261ecSmrg     * handle, delete them from the list, and update nStuff to indicate how
52005b261ecSmrg     * many windows it did not handle.
52105b261ecSmrg     *
52205b261ecSmrg     * This scheme allows a range of sophistication in the DDX SwapBuffers()
52305b261ecSmrg     * implementation.  Naive implementations could just swap the first buffer
52405b261ecSmrg     * in the list, move the last buffer to the front, decrement nStuff, and
52505b261ecSmrg     * return.  The next level of sophistication could be to scan the whole
52605b261ecSmrg     * list for windows on the same screen.  Up another level, the DDX routine
52705b261ecSmrg     * could deal with cross-screen synchronization.
52805b261ecSmrg     */
52905b261ecSmrg
530f7df2e56Smrg    nStuff_i = nStuff;
531f7df2e56Smrg    while (nStuff_i > 0) {
53205b261ecSmrg        pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
533f7df2e56Smrg        error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff_i, swapInfo);
534f7df2e56Smrg        if (error != Success) {
5356747b715Smrg            free(swapInfo);
5366747b715Smrg            return error;
53705b261ecSmrg        }
53805b261ecSmrg    }
53905b261ecSmrg
540f7df2e56Smrg    free(swapInfo);
5416747b715Smrg    return Success;
54205b261ecSmrg
543f7df2e56Smrg}                               /* ProcDbeSwapBuffers() */
54405b261ecSmrg
54505b261ecSmrg/******************************************************************************
54605b261ecSmrg *
54705b261ecSmrg * DBE DIX Procedure: ProcDbeGetVisualInfo
54805b261ecSmrg *
54905b261ecSmrg * Description:
55005b261ecSmrg *
55105b261ecSmrg *     This function is for processing a ProcDbeGetVisualInfo request.
55205b261ecSmrg *     This request returns information about which visuals support
55305b261ecSmrg *     double buffering.
55405b261ecSmrg *
55505b261ecSmrg * Return Values:
55605b261ecSmrg *
55705b261ecSmrg *     BadDrawable - value in screen specifiers is not a valid drawable
55805b261ecSmrg *     Success
55905b261ecSmrg *
56005b261ecSmrg *****************************************************************************/
56105b261ecSmrg
56205b261ecSmrgstatic int
56305b261ecSmrgProcDbeGetVisualInfo(ClientPtr client)
56405b261ecSmrg{
56505b261ecSmrg    REQUEST(xDbeGetVisualInfoReq);
566f7df2e56Smrg    DbeScreenPrivPtr pDbeScreenPriv;
567f7df2e56Smrg    xDbeGetVisualInfoReply rep;
568f7df2e56Smrg    Drawable *drawables;
569f7df2e56Smrg    DrawablePtr *pDrawables = NULL;
570f7df2e56Smrg    register int i, j, rc;
571f7df2e56Smrg    register int count;         /* number of visual infos in reply */
572f7df2e56Smrg    register int length;        /* length of reply */
573f7df2e56Smrg    ScreenPtr pScreen;
574f7df2e56Smrg    XdbeScreenVisualInfo *pScrVisInfo;
57505b261ecSmrg
57605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
5776e78d31fSmrg    if (stuff->n > UINT32_MAX / sizeof(CARD32))
5786e78d31fSmrg        return BadLength;
5796e78d31fSmrg    REQUEST_FIXED_SIZE(xDbeGetVisualInfoReq, stuff->n * sizeof(CARD32));
58005b261ecSmrg
58105b261ecSmrg    if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
582f7df2e56Smrg        return BadAlloc;
58305b261ecSmrg    /* Make sure any specified drawables are valid. */
584f7df2e56Smrg    if (stuff->n != 0) {
585f7df2e56Smrg        if (!(pDrawables = xallocarray(stuff->n, sizeof(DrawablePtr)))) {
5866747b715Smrg            return BadAlloc;
58705b261ecSmrg        }
58805b261ecSmrg
589f7df2e56Smrg        drawables = (Drawable *) &stuff[1];
59005b261ecSmrg
591f7df2e56Smrg        for (i = 0; i < stuff->n; i++) {
592f7df2e56Smrg            rc = dixLookupDrawable(pDrawables + i, drawables[i], client, 0,
593f7df2e56Smrg                                   DixGetAttrAccess);
594f7df2e56Smrg            if (rc != Success) {
5956747b715Smrg                free(pDrawables);
59605b261ecSmrg                return rc;
59705b261ecSmrg            }
59805b261ecSmrg        }
59905b261ecSmrg    }
60005b261ecSmrg
60105b261ecSmrg    count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
602f7df2e56Smrg    if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo)))) {
6036747b715Smrg        free(pDrawables);
60405b261ecSmrg
6056747b715Smrg        return BadAlloc;
60605b261ecSmrg    }
60705b261ecSmrg
60805b261ecSmrg    length = 0;
60905b261ecSmrg
610f7df2e56Smrg    for (i = 0; i < count; i++) {
61105b261ecSmrg        pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
612f7df2e56Smrg            pDrawables[i]->pScreen;
61305b261ecSmrg        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
61405b261ecSmrg
615f7df2e56Smrg        rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
6169ace9065Smrg        if (rc != Success)
6179ace9065Smrg            goto freeScrVisInfo;
6189ace9065Smrg
619f7df2e56Smrg        if (!(*pDbeScreenPriv->GetVisualInfo) (pScreen, &pScrVisInfo[i])) {
62005b261ecSmrg            /* We failed to alloc pScrVisInfo[i].visinfo. */
6219ace9065Smrg            rc = BadAlloc;
62205b261ecSmrg
623f7df2e56Smrg            /* Free visinfos that we allocated for previous screen infos. */
6249ace9065Smrg            goto freeScrVisInfo;
62505b261ecSmrg        }
62605b261ecSmrg
62705b261ecSmrg        /* Account for n, number of xDbeVisInfo items in list. */
62805b261ecSmrg        length += sizeof(CARD32);
62905b261ecSmrg
63005b261ecSmrg        /* Account for n xDbeVisInfo items */
63105b261ecSmrg        length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
63205b261ecSmrg    }
63305b261ecSmrg
634f7df2e56Smrg    rep = (xDbeGetVisualInfoReply) {
635f7df2e56Smrg        .type = X_Reply,
636f7df2e56Smrg        .sequenceNumber = client->sequence,
637f7df2e56Smrg        .length = bytes_to_int32(length),
638f7df2e56Smrg        .m = count
639f7df2e56Smrg    };
640f7df2e56Smrg
641f7df2e56Smrg    if (client->swapped) {
642f7df2e56Smrg        swaps(&rep.sequenceNumber);
643f7df2e56Smrg        swapl(&rep.length);
644f7df2e56Smrg        swapl(&rep.m);
64505b261ecSmrg    }
64605b261ecSmrg
64705b261ecSmrg    /* Send off reply. */
648f7df2e56Smrg    WriteToClient(client, sizeof(xDbeGetVisualInfoReply), &rep);
64905b261ecSmrg
650f7df2e56Smrg    for (i = 0; i < count; i++) {
651f7df2e56Smrg        CARD32 data32;
65205b261ecSmrg
65305b261ecSmrg        /* For each screen in the reply, send off the visual info */
65405b261ecSmrg
65505b261ecSmrg        /* Send off number of visuals. */
656f7df2e56Smrg        data32 = (CARD32) pScrVisInfo[i].count;
65705b261ecSmrg
658f7df2e56Smrg        if (client->swapped) {
659f7df2e56Smrg            swapl(&data32);
66005b261ecSmrg        }
66105b261ecSmrg
662f7df2e56Smrg        WriteToClient(client, sizeof(CARD32), &data32);
66305b261ecSmrg
66405b261ecSmrg        /* Now send off visual info items. */
665f7df2e56Smrg        for (j = 0; j < pScrVisInfo[i].count; j++) {
666f7df2e56Smrg            xDbeVisInfo visInfo;
66705b261ecSmrg
66805b261ecSmrg            /* Copy the data in the client data structure to a protocol
66905b261ecSmrg             * data structure.  We will send data to the client from the
67005b261ecSmrg             * protocol data structure.
67105b261ecSmrg             */
67205b261ecSmrg
673f7df2e56Smrg            visInfo.visualID = (CARD32) pScrVisInfo[i].visinfo[j].visual;
674f7df2e56Smrg            visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth;
67505b261ecSmrg            visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;
67605b261ecSmrg
677f7df2e56Smrg            if (client->swapped) {
678f7df2e56Smrg                swapl(&visInfo.visualID);
67905b261ecSmrg
68005b261ecSmrg                /* We do not need to swap depth and perfLevel since they are
68105b261ecSmrg                 * already 1 byte quantities.
68205b261ecSmrg                 */
68305b261ecSmrg            }
68405b261ecSmrg
68505b261ecSmrg            /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
686f7df2e56Smrg            WriteToClient(client, 2 * sizeof(CARD32), &visInfo.visualID);
68705b261ecSmrg        }
68805b261ecSmrg    }
68905b261ecSmrg
6909ace9065Smrg    rc = Success;
6919ace9065Smrg
692f7df2e56Smrg freeScrVisInfo:
69305b261ecSmrg    /* Clean up memory. */
694f7df2e56Smrg    for (i = 0; i < count; i++) {
6956747b715Smrg        free(pScrVisInfo[i].visinfo);
69605b261ecSmrg    }
6976747b715Smrg    free(pScrVisInfo);
69805b261ecSmrg
6996747b715Smrg    free(pDrawables);
70005b261ecSmrg
7019ace9065Smrg    return rc;
70205b261ecSmrg
703f7df2e56Smrg}                               /* ProcDbeGetVisualInfo() */
70405b261ecSmrg
70505b261ecSmrg/******************************************************************************
70605b261ecSmrg *
70705b261ecSmrg * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
70805b261ecSmrg *
70905b261ecSmrg * Description:
71005b261ecSmrg *
71105b261ecSmrg *     This function is for processing a ProcDbeGetbackBufferAttributes
71205b261ecSmrg *     request.  This request returns information about a back buffer.
71305b261ecSmrg *
71405b261ecSmrg * Return Values:
71505b261ecSmrg *
71605b261ecSmrg *     Success
71705b261ecSmrg *
71805b261ecSmrg *****************************************************************************/
71905b261ecSmrg
72005b261ecSmrgstatic int
72105b261ecSmrgProcDbeGetBackBufferAttributes(ClientPtr client)
72205b261ecSmrg{
72305b261ecSmrg    REQUEST(xDbeGetBackBufferAttributesReq);
724f7df2e56Smrg    xDbeGetBackBufferAttributesReply rep = {
725f7df2e56Smrg        .type = X_Reply,
726f7df2e56Smrg        .sequenceNumber = client->sequence,
727f7df2e56Smrg        .length = 0
728f7df2e56Smrg    };
729f7df2e56Smrg    DbeWindowPrivPtr pDbeWindowPriv;
730f7df2e56Smrg    int rc;
73105b261ecSmrg
73205b261ecSmrg    REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
73305b261ecSmrg
734f7df2e56Smrg    rc = dixLookupResourceByType((void **) &pDbeWindowPriv, stuff->buffer,
735f7df2e56Smrg                                 dbeWindowPrivResType, client,
736f7df2e56Smrg                                 DixGetAttrAccess);
737f7df2e56Smrg    if (rc == Success) {
7386747b715Smrg        rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
73905b261ecSmrg    }
740f7df2e56Smrg    else {
7416747b715Smrg        rep.attributes = None;
74205b261ecSmrg    }
743f7df2e56Smrg
744f7df2e56Smrg    if (client->swapped) {
745f7df2e56Smrg        swaps(&rep.sequenceNumber);
746f7df2e56Smrg        swapl(&rep.length);
747f7df2e56Smrg        swapl(&rep.attributes);
74805b261ecSmrg    }
74905b261ecSmrg
750f7df2e56Smrg    WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply), &rep);
7516747b715Smrg    return Success;
75205b261ecSmrg
753f7df2e56Smrg}                               /* ProcDbeGetbackBufferAttributes() */
75405b261ecSmrg
75505b261ecSmrg/******************************************************************************
75605b261ecSmrg *
75705b261ecSmrg * DBE DIX Procedure: ProcDbeDispatch
75805b261ecSmrg *
75905b261ecSmrg * Description:
76005b261ecSmrg *
76105b261ecSmrg *     This function dispatches DBE requests.
76205b261ecSmrg *
76305b261ecSmrg *****************************************************************************/
76405b261ecSmrg
76505b261ecSmrgstatic int
76605b261ecSmrgProcDbeDispatch(ClientPtr client)
76705b261ecSmrg{
76805b261ecSmrg    REQUEST(xReq);
76905b261ecSmrg
770f7df2e56Smrg    switch (stuff->data) {
771f7df2e56Smrg    case X_DbeGetVersion:
772f7df2e56Smrg        return (ProcDbeGetVersion(client));
77305b261ecSmrg
774f7df2e56Smrg    case X_DbeAllocateBackBufferName:
775f7df2e56Smrg        return (ProcDbeAllocateBackBufferName(client));
77605b261ecSmrg
777f7df2e56Smrg    case X_DbeDeallocateBackBufferName:
778f7df2e56Smrg        return (ProcDbeDeallocateBackBufferName(client));
77905b261ecSmrg
780f7df2e56Smrg    case X_DbeSwapBuffers:
781f7df2e56Smrg        return (ProcDbeSwapBuffers(client));
78205b261ecSmrg
783f7df2e56Smrg    case X_DbeBeginIdiom:
784f7df2e56Smrg        return Success;
78505b261ecSmrg
786f7df2e56Smrg    case X_DbeEndIdiom:
787f7df2e56Smrg        return Success;
78805b261ecSmrg
789f7df2e56Smrg    case X_DbeGetVisualInfo:
790f7df2e56Smrg        return (ProcDbeGetVisualInfo(client));
79105b261ecSmrg
792f7df2e56Smrg    case X_DbeGetBackBufferAttributes:
793f7df2e56Smrg        return (ProcDbeGetBackBufferAttributes(client));
79405b261ecSmrg
795f7df2e56Smrg    default:
796f7df2e56Smrg        return BadRequest;
79705b261ecSmrg    }
79805b261ecSmrg
799f7df2e56Smrg}                               /* ProcDbeDispatch() */
80005b261ecSmrg
80105b261ecSmrg/******************************************************************************
80205b261ecSmrg *
80305b261ecSmrg * DBE DIX Procedure: SProcDbeGetVersion
80405b261ecSmrg *
80505b261ecSmrg * Description:
80605b261ecSmrg *
80705b261ecSmrg *     This function is for processing a DbeGetVersion request on a swapped
80805b261ecSmrg *     server.  This request returns the major and minor version numbers of
80905b261ecSmrg *     this extension.
81005b261ecSmrg *
81105b261ecSmrg * Return Values:
81205b261ecSmrg *
81305b261ecSmrg *     Success
81405b261ecSmrg *
81505b261ecSmrg *****************************************************************************/
81605b261ecSmrg
8177e31ba66Smrgstatic int _X_COLD
81805b261ecSmrgSProcDbeGetVersion(ClientPtr client)
81905b261ecSmrg{
82005b261ecSmrg    REQUEST(xDbeGetVersionReq);
82105b261ecSmrg
822f7df2e56Smrg    swaps(&stuff->length);
823f7df2e56Smrg    return (ProcDbeGetVersion(client));
82405b261ecSmrg
825f7df2e56Smrg}                               /* SProcDbeGetVersion() */
82605b261ecSmrg
82705b261ecSmrg/******************************************************************************
82805b261ecSmrg *
82905b261ecSmrg * DBE DIX Procedure: SProcDbeAllocateBackBufferName
83005b261ecSmrg *
83105b261ecSmrg * Description:
83205b261ecSmrg *
83305b261ecSmrg *     This function is for processing a DbeAllocateBackBufferName request on
83405b261ecSmrg *     a swapped server.  This request allocates a drawable ID used to refer
83505b261ecSmrg *     to the back buffer of a window.
83605b261ecSmrg *
83705b261ecSmrg * Return Values:
83805b261ecSmrg *
83905b261ecSmrg *     BadAlloc    - server can not allocate resources
84005b261ecSmrg *     BadIDChoice - id is out of range for client; id is already in use
84105b261ecSmrg *     BadMatch    - window is not an InputOutput window;
84205b261ecSmrg *                   visual of window is not on list returned by
843f7df2e56Smrg *                   DBEGetVisualInfo;
84405b261ecSmrg *     BadValue    - invalid swap action is specified
84505b261ecSmrg *     BadWindow   - window is not a valid window
84605b261ecSmrg *     Success
84705b261ecSmrg *
84805b261ecSmrg *****************************************************************************/
84905b261ecSmrg
8507e31ba66Smrgstatic int _X_COLD
85105b261ecSmrgSProcDbeAllocateBackBufferName(ClientPtr client)
85205b261ecSmrg{
85305b261ecSmrg    REQUEST(xDbeAllocateBackBufferNameReq);
85405b261ecSmrg
855f7df2e56Smrg    swaps(&stuff->length);
85605b261ecSmrg    REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
85705b261ecSmrg
858f7df2e56Smrg    swapl(&stuff->window);
859f7df2e56Smrg    swapl(&stuff->buffer);
86005b261ecSmrg    /* stuff->swapAction is a byte.  We do not need to swap this field. */
86105b261ecSmrg
862f7df2e56Smrg    return (ProcDbeAllocateBackBufferName(client));
86305b261ecSmrg
864f7df2e56Smrg}                               /* SProcDbeAllocateBackBufferName() */
86505b261ecSmrg
86605b261ecSmrg/******************************************************************************
86705b261ecSmrg *
86805b261ecSmrg * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
86905b261ecSmrg *
87005b261ecSmrg * Description:
87105b261ecSmrg *
87205b261ecSmrg *     This function is for processing a DbeDeallocateBackBufferName request
87305b261ecSmrg *     on a swapped server.  This request frees a drawable ID that was
87405b261ecSmrg *     obtained by a DbeAllocateBackBufferName request.
87505b261ecSmrg *
87605b261ecSmrg * Return Values:
87705b261ecSmrg *
87805b261ecSmrg *     BadBuffer - buffer to deallocate is not associated with a window
87905b261ecSmrg *     Success
88005b261ecSmrg *
88105b261ecSmrg *****************************************************************************/
88205b261ecSmrg
8837e31ba66Smrgstatic int _X_COLD
88405b261ecSmrgSProcDbeDeallocateBackBufferName(ClientPtr client)
88505b261ecSmrg{
886f7df2e56Smrg    REQUEST(xDbeDeallocateBackBufferNameReq);
88705b261ecSmrg
888f7df2e56Smrg    swaps(&stuff->length);
88905b261ecSmrg    REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
89005b261ecSmrg
891f7df2e56Smrg    swapl(&stuff->buffer);
89205b261ecSmrg
893f7df2e56Smrg    return (ProcDbeDeallocateBackBufferName(client));
89405b261ecSmrg
895f7df2e56Smrg}                               /* SProcDbeDeallocateBackBufferName() */
89605b261ecSmrg
89705b261ecSmrg/******************************************************************************
89805b261ecSmrg *
89905b261ecSmrg * DBE DIX Procedure: SProcDbeSwapBuffers
90005b261ecSmrg *
90105b261ecSmrg * Description:
90205b261ecSmrg *
90305b261ecSmrg *     This function is for processing a DbeSwapBuffers request on a swapped
90405b261ecSmrg *     server.  This request swaps the buffers for all windows listed,
90505b261ecSmrg *     applying the appropriate swap action for each window.
90605b261ecSmrg *
90705b261ecSmrg * Return Values:
90805b261ecSmrg *
90905b261ecSmrg *     BadMatch  - a window in request is not double-buffered; a window in
91005b261ecSmrg *                 request is listed more than once; all windows in request do
91105b261ecSmrg *                 not have the same root
91205b261ecSmrg *     BadValue  - invalid swap action is specified
91305b261ecSmrg *     BadWindow - a window in request is not valid
91405b261ecSmrg *     Success
91505b261ecSmrg *
91605b261ecSmrg *****************************************************************************/
91705b261ecSmrg
9187e31ba66Smrgstatic int _X_COLD
91905b261ecSmrgSProcDbeSwapBuffers(ClientPtr client)
92005b261ecSmrg{
92105b261ecSmrg    REQUEST(xDbeSwapBuffersReq);
922f7df2e56Smrg    unsigned int i;
923f7df2e56Smrg    xDbeSwapInfo *pSwapInfo;
92405b261ecSmrg
925f7df2e56Smrg    swaps(&stuff->length);
92605b261ecSmrg    REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
92705b261ecSmrg
928f7df2e56Smrg    swapl(&stuff->n);
9290b0d8713Smrg    if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec))
9306e78d31fSmrg        return BadLength;
9310b0d8713Smrg    REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo));
93205b261ecSmrg
933f7df2e56Smrg    if (stuff->n != 0) {
934f7df2e56Smrg        pSwapInfo = (xDbeSwapInfo *) stuff + 1;
93505b261ecSmrg
93605b261ecSmrg        /* The swap info following the fix part of this request is a window(32)
93705b261ecSmrg         * followed by a 1 byte swap action and then 3 pad bytes.  We only need
93805b261ecSmrg         * to swap the window information.
93905b261ecSmrg         */
940f7df2e56Smrg        for (i = 0; i < stuff->n; i++) {
941f7df2e56Smrg            swapl(&pSwapInfo->window);
94205b261ecSmrg        }
94305b261ecSmrg    }
94405b261ecSmrg
945f7df2e56Smrg    return (ProcDbeSwapBuffers(client));
94605b261ecSmrg
947f7df2e56Smrg}                               /* SProcDbeSwapBuffers() */
94805b261ecSmrg
94905b261ecSmrg/******************************************************************************
95005b261ecSmrg *
95105b261ecSmrg * DBE DIX Procedure: SProcDbeGetVisualInfo
95205b261ecSmrg *
95305b261ecSmrg * Description:
95405b261ecSmrg *
95505b261ecSmrg *     This function is for processing a ProcDbeGetVisualInfo request on a
95605b261ecSmrg *     swapped server.  This request returns information about which visuals
95705b261ecSmrg *     support double buffering.
95805b261ecSmrg *
95905b261ecSmrg * Return Values:
96005b261ecSmrg *
96105b261ecSmrg *     BadDrawable - value in screen specifiers is not a valid drawable
96205b261ecSmrg *     Success
96305b261ecSmrg *
96405b261ecSmrg *****************************************************************************/
96505b261ecSmrg
9667e31ba66Smrgstatic int _X_COLD
96705b261ecSmrgSProcDbeGetVisualInfo(ClientPtr client)
96805b261ecSmrg{
96905b261ecSmrg    REQUEST(xDbeGetVisualInfoReq);
97005b261ecSmrg
971f7df2e56Smrg    swaps(&stuff->length);
97205b261ecSmrg    REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
97305b261ecSmrg
974f7df2e56Smrg    swapl(&stuff->n);
97505b261ecSmrg    SwapRestL(stuff);
97605b261ecSmrg
977f7df2e56Smrg    return (ProcDbeGetVisualInfo(client));
97805b261ecSmrg
979f7df2e56Smrg}                               /* SProcDbeGetVisualInfo() */
98005b261ecSmrg
98105b261ecSmrg/******************************************************************************
98205b261ecSmrg *
98305b261ecSmrg * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
98405b261ecSmrg *
98505b261ecSmrg * Description:
98605b261ecSmrg *
98705b261ecSmrg *     This function is for processing a ProcDbeGetbackBufferAttributes
98805b261ecSmrg *     request on a swapped server.  This request returns information about a
98905b261ecSmrg *     back buffer.
99005b261ecSmrg *
99105b261ecSmrg * Return Values:
99205b261ecSmrg *
99305b261ecSmrg *     Success
99405b261ecSmrg *
99505b261ecSmrg *****************************************************************************/
99605b261ecSmrg
9977e31ba66Smrgstatic int _X_COLD
99805b261ecSmrgSProcDbeGetBackBufferAttributes(ClientPtr client)
99905b261ecSmrg{
1000f7df2e56Smrg    REQUEST(xDbeGetBackBufferAttributesReq);
100105b261ecSmrg
1002f7df2e56Smrg    swaps(&stuff->length);
100305b261ecSmrg    REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
100405b261ecSmrg
1005f7df2e56Smrg    swapl(&stuff->buffer);
100605b261ecSmrg
1007f7df2e56Smrg    return (ProcDbeGetBackBufferAttributes(client));
100805b261ecSmrg
1009f7df2e56Smrg}                               /* SProcDbeGetBackBufferAttributes() */
101005b261ecSmrg
101105b261ecSmrg/******************************************************************************
101205b261ecSmrg *
101305b261ecSmrg * DBE DIX Procedure: SProcDbeDispatch
101405b261ecSmrg *
101505b261ecSmrg * Description:
101605b261ecSmrg *
101705b261ecSmrg *     This function dispatches DBE requests on a swapped server.
101805b261ecSmrg *
101905b261ecSmrg *****************************************************************************/
102005b261ecSmrg
10217e31ba66Smrgstatic int _X_COLD
102205b261ecSmrgSProcDbeDispatch(ClientPtr client)
102305b261ecSmrg{
102405b261ecSmrg    REQUEST(xReq);
102505b261ecSmrg
1026f7df2e56Smrg    switch (stuff->data) {
1027f7df2e56Smrg    case X_DbeGetVersion:
1028f7df2e56Smrg        return (SProcDbeGetVersion(client));
102905b261ecSmrg
1030f7df2e56Smrg    case X_DbeAllocateBackBufferName:
1031f7df2e56Smrg        return (SProcDbeAllocateBackBufferName(client));
103205b261ecSmrg
1033f7df2e56Smrg    case X_DbeDeallocateBackBufferName:
1034f7df2e56Smrg        return (SProcDbeDeallocateBackBufferName(client));
103505b261ecSmrg
1036f7df2e56Smrg    case X_DbeSwapBuffers:
1037f7df2e56Smrg        return (SProcDbeSwapBuffers(client));
103805b261ecSmrg
1039f7df2e56Smrg    case X_DbeBeginIdiom:
1040f7df2e56Smrg        return Success;
104105b261ecSmrg
1042f7df2e56Smrg    case X_DbeEndIdiom:
1043f7df2e56Smrg        return Success;
104405b261ecSmrg
1045f7df2e56Smrg    case X_DbeGetVisualInfo:
1046f7df2e56Smrg        return (SProcDbeGetVisualInfo(client));
104705b261ecSmrg
1048f7df2e56Smrg    case X_DbeGetBackBufferAttributes:
1049f7df2e56Smrg        return (SProcDbeGetBackBufferAttributes(client));
105005b261ecSmrg
1051f7df2e56Smrg    default:
1052f7df2e56Smrg        return BadRequest;
105305b261ecSmrg    }
105405b261ecSmrg
1055f7df2e56Smrg}                               /* SProcDbeDispatch() */
105605b261ecSmrg
105705b261ecSmrg/******************************************************************************
105805b261ecSmrg *
105905b261ecSmrg * DBE DIX Procedure: DbeSetupBackgroundPainter
106005b261ecSmrg *
106105b261ecSmrg * Description:
106205b261ecSmrg *
106305b261ecSmrg *     This function sets up pGC to clear pixmaps.
106405b261ecSmrg *
106505b261ecSmrg * Return Values:
106605b261ecSmrg *
106705b261ecSmrg *     TRUE  - setup was successful
106805b261ecSmrg *     FALSE - the window's background state is NONE
1069f7df2e56Smrg *
107005b261ecSmrg *****************************************************************************/
107105b261ecSmrg
107205b261ecSmrgstatic Bool
107305b261ecSmrgDbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
107405b261ecSmrg{
1075f7df2e56Smrg    ChangeGCVal gcvalues[4];
1076f7df2e56Smrg    int ts_x_origin, ts_y_origin;
1077f7df2e56Smrg    PixUnion background;
1078f7df2e56Smrg    int backgroundState;
1079f7df2e56Smrg    Mask gcmask;
108005b261ecSmrg
108105b261ecSmrg    /* First take care of any ParentRelative stuff by altering the
108205b261ecSmrg     * tile/stipple origin to match the coordinates of the upper-left
108305b261ecSmrg     * corner of the first ancestor without a ParentRelative background.
108405b261ecSmrg     * This coordinate is, of course, negative.
108505b261ecSmrg     */
108605b261ecSmrg    ts_x_origin = ts_y_origin = 0;
1087f7df2e56Smrg    while (pWin->backgroundState == ParentRelative) {
108805b261ecSmrg        ts_x_origin -= pWin->origin.x;
108905b261ecSmrg        ts_y_origin -= pWin->origin.y;
109005b261ecSmrg
109105b261ecSmrg        pWin = pWin->parent;
109205b261ecSmrg    }
109305b261ecSmrg    backgroundState = pWin->backgroundState;
1094f7df2e56Smrg    background = pWin->background;
1095f7df2e56Smrg
1096f7df2e56Smrg    switch (backgroundState) {
1097f7df2e56Smrg    case BackgroundPixel:
1098f7df2e56Smrg        gcvalues[0].val = background.pixel;
1099f7df2e56Smrg        gcvalues[1].val = FillSolid;
1100f7df2e56Smrg        gcmask = GCForeground | GCFillStyle;
1101f7df2e56Smrg        break;
1102f7df2e56Smrg
1103f7df2e56Smrg    case BackgroundPixmap:
1104f7df2e56Smrg        gcvalues[0].val = FillTiled;
1105f7df2e56Smrg        gcvalues[1].ptr = background.pixmap;
1106f7df2e56Smrg        gcvalues[2].val = ts_x_origin;
1107f7df2e56Smrg        gcvalues[3].val = ts_y_origin;
1108f7df2e56Smrg        gcmask = GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
1109f7df2e56Smrg        break;
1110f7df2e56Smrg
1111f7df2e56Smrg    default:
1112f7df2e56Smrg        /* pWin->backgroundState == None */
1113f7df2e56Smrg        return FALSE;
111405b261ecSmrg    }
111505b261ecSmrg
11166747b715Smrg    return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0;
1117f7df2e56Smrg}                               /* DbeSetupBackgroundPainter() */
111805b261ecSmrg
111905b261ecSmrg/******************************************************************************
112005b261ecSmrg *
112105b261ecSmrg * DBE DIX Procedure: DbeDrawableDelete
112205b261ecSmrg *
112305b261ecSmrg * Description:
112405b261ecSmrg *
112505b261ecSmrg *     This is the resource delete function for dbeDrawableResType.
112605b261ecSmrg *     It is registered when the drawable resource type is created in
112705b261ecSmrg *     DbeExtensionInit().
112805b261ecSmrg *
112905b261ecSmrg *     To make resource deletion simple, we do not do anything in this function
11305a112b11Smrg *     and leave all resource deletion to DbeWindowPrivDelete(), which will
113105b261ecSmrg *     eventually be called or already has been called.  Deletion functions are
113205b261ecSmrg *     not guaranteed to be called in any particular order.
113305b261ecSmrg *
113405b261ecSmrg *****************************************************************************/
113505b261ecSmrgstatic int
1136f7df2e56SmrgDbeDrawableDelete(void *pDrawable, XID id)
113705b261ecSmrg{
11386747b715Smrg    return Success;
113905b261ecSmrg
1140f7df2e56Smrg}                               /* DbeDrawableDelete() */
114105b261ecSmrg
114205b261ecSmrg/******************************************************************************
114305b261ecSmrg *
114405b261ecSmrg * DBE DIX Procedure: DbeWindowPrivDelete
114505b261ecSmrg *
114605b261ecSmrg * Description:
114705b261ecSmrg *
114805b261ecSmrg *     This is the resource delete function for dbeWindowPrivResType.
114905b261ecSmrg *     It is registered when the drawable resource type is created in
115005b261ecSmrg *     DbeExtensionInit().
115105b261ecSmrg *
115205b261ecSmrg *****************************************************************************/
115305b261ecSmrgstatic int
1154f7df2e56SmrgDbeWindowPrivDelete(void *pDbeWinPriv, XID id)
115505b261ecSmrg{
1156f7df2e56Smrg    DbeScreenPrivPtr pDbeScreenPriv;
1157f7df2e56Smrg    DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr) pDbeWinPriv;
1158f7df2e56Smrg    int i;
115905b261ecSmrg
116005b261ecSmrg    /*
116105b261ecSmrg     **************************************************************************
116205b261ecSmrg     ** Remove the buffer ID from the ID array.
116305b261ecSmrg     **************************************************************************
116405b261ecSmrg     */
116505b261ecSmrg
116605b261ecSmrg    /* Find the ID in the ID array. */
116705b261ecSmrg    i = 0;
1168f7df2e56Smrg    while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id)) {
116905b261ecSmrg        i++;
117005b261ecSmrg    }
117105b261ecSmrg
1172f7df2e56Smrg    if (i == pDbeWindowPriv->nBufferIDs) {
117305b261ecSmrg        /* We did not find the ID in the array.  We should never get here. */
11746747b715Smrg        return BadValue;
117505b261ecSmrg    }
117605b261ecSmrg
117705b261ecSmrg    /* Remove the ID from the array. */
117805b261ecSmrg
1179f7df2e56Smrg    if (i < (pDbeWindowPriv->nBufferIDs - 1)) {
118005b261ecSmrg        /* Compress the buffer ID array, overwriting the ID in the process. */
1181f7df2e56Smrg        memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i + 1],
1182f7df2e56Smrg                (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
118305b261ecSmrg    }
1184f7df2e56Smrg    else {
118505b261ecSmrg        /* We are removing the last ID in the array, in which case, the
11865a112b11Smrg         * assignment below is all that we need to do.
118705b261ecSmrg         */
118805b261ecSmrg    }
118905b261ecSmrg    pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
119005b261ecSmrg
119105b261ecSmrg    pDbeWindowPriv->nBufferIDs--;
119205b261ecSmrg
119305b261ecSmrg    /* If an extended array was allocated, then check to see if the remaining
119405b261ecSmrg     * buffer IDs will fit in the static array.
119505b261ecSmrg     */
119605b261ecSmrg
1197f7df2e56Smrg    if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) &&
1198f7df2e56Smrg        (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS)) {
119905b261ecSmrg        /* Copy the IDs back into the static array. */
120005b261ecSmrg        memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
120105b261ecSmrg               DBE_INIT_MAX_IDS * sizeof(XID));
120205b261ecSmrg
120305b261ecSmrg        /* Free the extended array; use the static array. */
12046747b715Smrg        free(pDbeWindowPriv->IDs);
120505b261ecSmrg        pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
120605b261ecSmrg        pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
120705b261ecSmrg    }
120805b261ecSmrg
120905b261ecSmrg    /*
121005b261ecSmrg     **************************************************************************
121105b261ecSmrg     ** Perform DDX level tasks.
121205b261ecSmrg     **************************************************************************
121305b261ecSmrg     */
121405b261ecSmrg
1215f7df2e56Smrg    pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV((DbeWindowPrivPtr)
1216f7df2e56Smrg                                                      pDbeWindowPriv);
1217f7df2e56Smrg    (*pDbeScreenPriv->WinPrivDelete) ((DbeWindowPrivPtr) pDbeWindowPriv, id);
121805b261ecSmrg
121905b261ecSmrg    /*
122005b261ecSmrg     **************************************************************************
122105b261ecSmrg     ** Perform miscellaneous tasks if this is the last buffer associated
122205b261ecSmrg     ** with the window.
122305b261ecSmrg     **************************************************************************
122405b261ecSmrg     */
122505b261ecSmrg
1226f7df2e56Smrg    if (pDbeWindowPriv->nBufferIDs == 0) {
122705b261ecSmrg        /* Reset the DBE window priv pointer. */
1228f7df2e56Smrg        dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey,
1229f7df2e56Smrg                      NULL);
123005b261ecSmrg
123105b261ecSmrg        /* We are done with the window priv. */
1232f7df2e56Smrg        free(pDbeWindowPriv);
123305b261ecSmrg    }
123405b261ecSmrg
12356747b715Smrg    return Success;
123605b261ecSmrg
1237f7df2e56Smrg}                               /* DbeWindowPrivDelete() */
123805b261ecSmrg
123905b261ecSmrg/******************************************************************************
124005b261ecSmrg *
124105b261ecSmrg * DBE DIX Procedure: DbeResetProc
124205b261ecSmrg *
124305b261ecSmrg * Description:
124405b261ecSmrg *
124505b261ecSmrg *     This routine is called at the end of every server generation.
124605b261ecSmrg *     It deallocates any memory reserved for the extension and performs any
124705b261ecSmrg *     other tasks related to shutting down the extension.
124805b261ecSmrg *
124905b261ecSmrg *****************************************************************************/
125005b261ecSmrgstatic void
1251f7df2e56SmrgDbeResetProc(ExtensionEntry * extEntry)
125205b261ecSmrg{
1253f7df2e56Smrg    int i;
1254f7df2e56Smrg    ScreenPtr pScreen;
1255f7df2e56Smrg    DbeScreenPrivPtr pDbeScreenPriv;
125605b261ecSmrg
1257f7df2e56Smrg    for (i = 0; i < screenInfo.numScreens; i++) {
1258f7df2e56Smrg        pScreen = screenInfo.screens[i];
1259f7df2e56Smrg        pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
126005b261ecSmrg
1261f7df2e56Smrg        if (pDbeScreenPriv) {
1262f7df2e56Smrg            /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */
1263f7df2e56Smrg            pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
1264f7df2e56Smrg            pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
1265f7df2e56Smrg            free(pDbeScreenPriv);
1266f7df2e56Smrg        }
126705b261ecSmrg    }
1268f7df2e56Smrg}                               /* DbeResetProc() */
126905b261ecSmrg
127005b261ecSmrg/******************************************************************************
127105b261ecSmrg *
127205b261ecSmrg * DBE DIX Procedure: DbeDestroyWindow
127305b261ecSmrg *
127405b261ecSmrg * Description:
127505b261ecSmrg *
127605b261ecSmrg *     This is the wrapper for pScreen->DestroyWindow.
127705b261ecSmrg *     This function frees buffer resources for a window before it is
127805b261ecSmrg *     destroyed.
127905b261ecSmrg *
128005b261ecSmrg *****************************************************************************/
128105b261ecSmrg
128205b261ecSmrgstatic Bool
128305b261ecSmrgDbeDestroyWindow(WindowPtr pWin)
128405b261ecSmrg{
1285f7df2e56Smrg    DbeScreenPrivPtr pDbeScreenPriv;
1286f7df2e56Smrg    DbeWindowPrivPtr pDbeWindowPriv;
1287f7df2e56Smrg    ScreenPtr pScreen;
1288f7df2e56Smrg    Bool ret;
128905b261ecSmrg
129005b261ecSmrg    /*
129105b261ecSmrg     **************************************************************************
129205b261ecSmrg     ** 1. Unwrap the member routine.
129305b261ecSmrg     **************************************************************************
129405b261ecSmrg     */
129505b261ecSmrg
1296f7df2e56Smrg    pScreen = pWin->drawable.pScreen;
1297f7df2e56Smrg    pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
129805b261ecSmrg    pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
129905b261ecSmrg
130005b261ecSmrg    /*
130105b261ecSmrg     **************************************************************************
130205b261ecSmrg     ** 2. Do any work necessary before the member routine is called.
130305b261ecSmrg     **
130405b261ecSmrg     **    Call the window priv delete function for all buffer IDs associated
130505b261ecSmrg     **    with this window.
130605b261ecSmrg     **************************************************************************
130705b261ecSmrg     */
130805b261ecSmrg
1309f7df2e56Smrg    if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) {
1310f7df2e56Smrg        while (pDbeWindowPriv) {
131105b261ecSmrg            /* *DbeWinPrivDelete() will free the window private and set it to
131205b261ecSmrg             * NULL if there are no more buffer IDs associated with this
131305b261ecSmrg             * window.
131405b261ecSmrg             */
131505b261ecSmrg            FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
131605b261ecSmrg            pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
131705b261ecSmrg        }
131805b261ecSmrg    }
131905b261ecSmrg
132005b261ecSmrg    /*
132105b261ecSmrg     **************************************************************************
132205b261ecSmrg     ** 3. Call the member routine, saving its result if necessary.
132305b261ecSmrg     **************************************************************************
132405b261ecSmrg     */
132505b261ecSmrg
1326f7df2e56Smrg    ret = (*pScreen->DestroyWindow) (pWin);
132705b261ecSmrg
132805b261ecSmrg    /*
132905b261ecSmrg     **************************************************************************
133005b261ecSmrg     ** 4. Rewrap the member routine, restoring the wrapper value first in case
133105b261ecSmrg     **    the wrapper (or something that it wrapped) change this value.
133205b261ecSmrg     **************************************************************************
133305b261ecSmrg     */
133405b261ecSmrg
133505b261ecSmrg    pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
133605b261ecSmrg    pScreen->DestroyWindow = DbeDestroyWindow;
133705b261ecSmrg
133805b261ecSmrg    /*
133905b261ecSmrg     **************************************************************************
134005b261ecSmrg     ** 5. Do any work necessary after the member routine has been called.
134105b261ecSmrg     **
134205b261ecSmrg     **    In this case we do not need to do anything.
134305b261ecSmrg     **************************************************************************
134405b261ecSmrg     */
134505b261ecSmrg
13466747b715Smrg    return ret;
134705b261ecSmrg
1348f7df2e56Smrg}                               /* DbeDestroyWindow() */
134905b261ecSmrg
135005b261ecSmrg/******************************************************************************
135105b261ecSmrg *
135205b261ecSmrg * DBE DIX Procedure: DbeExtensionInit
135305b261ecSmrg *
135405b261ecSmrg * Description:
135505b261ecSmrg *
135605b261ecSmrg *     Called from InitExtensions in main()
135705b261ecSmrg *
135805b261ecSmrg *****************************************************************************/
135905b261ecSmrg
136005b261ecSmrgvoid
136105b261ecSmrgDbeExtensionInit(void)
136205b261ecSmrg{
1363f7df2e56Smrg    ExtensionEntry *extEntry;
1364f7df2e56Smrg    register int i, j;
1365f7df2e56Smrg    ScreenPtr pScreen = NULL;
1366f7df2e56Smrg    DbeScreenPrivPtr pDbeScreenPriv;
1367f7df2e56Smrg    int nStubbedScreens = 0;
1368f7df2e56Smrg    Bool ddxInitSuccess;
136905b261ecSmrg
137005b261ecSmrg#ifdef PANORAMIX
1371f7df2e56Smrg    if (!noPanoramiXExtension)
1372f7df2e56Smrg        return;
137305b261ecSmrg#endif
137405b261ecSmrg
137505b261ecSmrg    /* Create the resource types. */
137605b261ecSmrg    dbeDrawableResType =
13776747b715Smrg        CreateNewResourceType(DbeDrawableDelete, "dbeDrawable");
13786747b715Smrg    if (!dbeDrawableResType)
1379f7df2e56Smrg        return;
13806747b715Smrg    dbeDrawableResType |= RC_DRAWABLE;
13816747b715Smrg
138205b261ecSmrg    dbeWindowPrivResType =
13836747b715Smrg        CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow");
13846747b715Smrg    if (!dbeWindowPrivResType)
1385f7df2e56Smrg        return;
13866747b715Smrg
13876747b715Smrg    if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0))
1388f7df2e56Smrg        return;
13896747b715Smrg
13906747b715Smrg    if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0))
1391f7df2e56Smrg        return;
139205b261ecSmrg
1393f7df2e56Smrg    for (i = 0; i < screenInfo.numScreens; i++) {
139405b261ecSmrg        /* For each screen, set up DBE screen privates and init DIX and DDX
139505b261ecSmrg         * interface.
139605b261ecSmrg         */
139705b261ecSmrg
1398f7df2e56Smrg        pScreen = screenInfo.screens[i];
139905b261ecSmrg
1400f7df2e56Smrg        if (!(pDbeScreenPriv = malloc(sizeof(DbeScreenPrivRec)))) {
140105b261ecSmrg            /* If we can not alloc a window or screen private,
140205b261ecSmrg             * then free any privates that we already alloc'ed and return
140305b261ecSmrg             */
140405b261ecSmrg
1405f7df2e56Smrg            for (j = 0; j < i; j++) {
1406f7df2e56Smrg                free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates,
1407f7df2e56Smrg                                      dbeScreenPrivKey));
1408f7df2e56Smrg                dixSetPrivate(&screenInfo.screens[j]->devPrivates,
1409f7df2e56Smrg                              dbeScreenPrivKey, NULL);
1410f7df2e56Smrg            }
1411f7df2e56Smrg            return;
1412f7df2e56Smrg        }
141305b261ecSmrg
1414f7df2e56Smrg        dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv);
141505b261ecSmrg
141605b261ecSmrg        {
14174642e01fSmrg            /* We don't have DDX support for DBE anymore */
141805b261ecSmrg
141905b261ecSmrg#ifndef DISABLE_MI_DBE_BY_DEFAULT
142005b261ecSmrg            /* Setup DIX. */
1421f7df2e56Smrg            pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
142205b261ecSmrg
142305b261ecSmrg            /* Setup DDX. */
142405b261ecSmrg            ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
142505b261ecSmrg
142605b261ecSmrg            /* DDX DBE initialization may have the side affect of
142705b261ecSmrg             * reallocating pDbeScreenPriv, so we need to update it.
142805b261ecSmrg             */
142905b261ecSmrg            pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
143005b261ecSmrg
1431f7df2e56Smrg            if (ddxInitSuccess) {
143205b261ecSmrg                /* Wrap DestroyWindow.  The DDX initialization function
143305b261ecSmrg                 * already wrapped PositionWindow for us.
143405b261ecSmrg                 */
143505b261ecSmrg
143605b261ecSmrg                pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
1437f7df2e56Smrg                pScreen->DestroyWindow = DbeDestroyWindow;
143805b261ecSmrg            }
1439f7df2e56Smrg            else {
144005b261ecSmrg                /* DDX initialization failed.  Stub the screen. */
144105b261ecSmrg                DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
144205b261ecSmrg            }
144305b261ecSmrg#else
144405b261ecSmrg            DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
144505b261ecSmrg#endif
144605b261ecSmrg
14474642e01fSmrg        }
144805b261ecSmrg
1449f7df2e56Smrg    }                           /* for (i = 0; i < screenInfo.numScreens; i++) */
145005b261ecSmrg
1451f7df2e56Smrg    if (nStubbedScreens == screenInfo.numScreens) {
1452f7df2e56Smrg        /* All screens stubbed.  Clean up and return. */
145305b261ecSmrg
1454f7df2e56Smrg        for (i = 0; i < screenInfo.numScreens; i++) {
1455f7df2e56Smrg            free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates,
1456f7df2e56Smrg                                  dbeScreenPrivKey));
1457f7df2e56Smrg            dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL);
145805b261ecSmrg        }
145905b261ecSmrg        return;
146005b261ecSmrg    }
146105b261ecSmrg
146205b261ecSmrg    /* Now add the extension. */
1463f7df2e56Smrg    extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
146405b261ecSmrg                            DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
146505b261ecSmrg                            DbeResetProc, StandardMinorOpcode);
146605b261ecSmrg
146705b261ecSmrg    dbeErrorBase = extEntry->errorBase;
1468f7df2e56Smrg    SetResourceTypeErrorValue(dbeWindowPrivResType,
1469f7df2e56Smrg                              dbeErrorBase + DbeBadBuffer);
14706747b715Smrg    SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer);
147105b261ecSmrg
1472f7df2e56Smrg}                               /* DbeExtensionInit() */
1473