diff options
Diffstat (limited to 'xorg-server/dbe')
-rw-r--r-- | xorg-server/dbe/dbe.c | 3364 | ||||
-rw-r--r-- | xorg-server/dbe/midbe.c | 1618 |
2 files changed, 2488 insertions, 2494 deletions
diff --git a/xorg-server/dbe/dbe.c b/xorg-server/dbe/dbe.c index 825d2e08f..a6c1c4f56 100644 --- a/xorg-server/dbe/dbe.c +++ b/xorg-server/dbe/dbe.c @@ -1,1685 +1,1679 @@ -/****************************************************************************** - * - * Copyright (c) 1994, 1995 Hewlett-Packard Company - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of the Hewlett-Packard - * Company shall not be used in advertising or otherwise to promote the - * sale, use or other dealings in this Software without prior written - * authorization from the Hewlett-Packard Company. - * - * DIX DBE code - * - *****************************************************************************/ - - -/* INCLUDES */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <string.h> -#if HAVE_STDINT_H -#include <stdint.h> -#elif !defined(UINT32_MAX) -#define UINT32_MAX 0xffffffffU -#endif - -#include <X11/X.h> -#include <X11/Xproto.h> -#include "scrnintstr.h" -#include "extnsionst.h" -#include "gcstruct.h" -#include "dixstruct.h" -#define NEED_DBE_PROTOCOL -#include "dbestruct.h" -#include "midbe.h" -#include "xace.h" - -/* GLOBALS */ - -/* These are static globals copied to DBE's screen private for use by DDX */ -static int dbeScreenPrivKeyIndex; -static DevPrivateKey dbeScreenPrivKey = &dbeScreenPrivKeyIndex; -static int dbeWindowPrivKeyIndex; -static DevPrivateKey dbeWindowPrivKey = &dbeWindowPrivKeyIndex; - -/* These are static globals copied to DBE's screen private for use by DDX */ -static RESTYPE dbeDrawableResType; -static RESTYPE dbeWindowPrivResType; - -/* Used to generate DBE's BadBuffer error. */ -static int dbeErrorBase; - -/****************************************************************************** - * - * DBE DIX Procedure: DbeStubScreen - * - * Description: - * - * This is function stubs the function pointers in the given DBE screen - * private and increments the number of stubbed screens. - * - *****************************************************************************/ - -static void -DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens) -{ - /* Stub DIX. */ - pDbeScreenPriv->SetupBackgroundPainter = NULL; - - /* Do not unwrap PositionWindow nor DestroyWindow. If the DDX - * initialization function failed, we assume that it did not wrap - * PositionWindow. Also, DestroyWindow is only wrapped if the DDX - * initialization function succeeded. - */ - - /* Stub DDX. */ - pDbeScreenPriv->GetVisualInfo = NULL; - pDbeScreenPriv->AllocBackBufferName = NULL; - pDbeScreenPriv->SwapBuffers = NULL; - pDbeScreenPriv->BeginIdiom = NULL; - pDbeScreenPriv->EndIdiom = NULL; - pDbeScreenPriv->WinPrivDelete = NULL; - pDbeScreenPriv->ResetProc = NULL; - - (*nStubbedScreens)++; - -} /* DbeStubScreen() */ - - - -/****************************************************************************** - * - * DBE DIX Procedure: ProcDbeGetVersion - * - * Description: - * - * This function is for processing a DbeGetVersion request. - * This request returns the major and minor version numbers of this - * extension. - * - * Return Values: - * - * Success - * - *****************************************************************************/ - -static int -ProcDbeGetVersion(ClientPtr client) -{ - /* REQUEST(xDbeGetVersionReq); */ - xDbeGetVersionReply rep; - register int n; - - - REQUEST_SIZE_MATCH(xDbeGetVersionReq); - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = DBE_MAJOR_VERSION; - rep.minorVersion = DBE_MINOR_VERSION; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - } - - WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep); - - return(client->noClientException); - -} /* ProcDbeGetVersion() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: ProcDbeAllocateBackBufferName - * - * Description: - * - * This function is for processing a DbeAllocateBackBufferName request. - * This request allocates a drawable ID used to refer to the back buffer - * of a window. - * - * Return Values: - * - * BadAlloc - server can not allocate resources - * BadIDChoice - id is out of range for client; id is already in use - * BadMatch - window is not an InputOutput window; - * visual of window is not on list returned by - * DBEGetVisualInfo; - * BadValue - invalid swap action is specified - * BadWindow - window is not a valid window - * Success - * - *****************************************************************************/ - -static int -ProcDbeAllocateBackBufferName(ClientPtr client) -{ - REQUEST(xDbeAllocateBackBufferNameReq); - WindowPtr pWin; - DbeScreenPrivPtr pDbeScreenPriv; - DbeWindowPrivPtr pDbeWindowPriv; - XdbeScreenVisualInfo scrVisInfo; - register int i; - Bool visualMatched = FALSE; - xDbeSwapAction swapAction; - VisualID visual; - int status; - int add_index; - - - REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); - - /* The window must be valid. */ - status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); - if (status != Success) - return status; - - /* The window must be InputOutput. */ - if (pWin->drawable.class != InputOutput) - { - return(BadMatch); - } - - /* The swap action must be valid. */ - swapAction = stuff->swapAction; /* use local var for performance. */ - if ((swapAction != XdbeUndefined ) && - (swapAction != XdbeBackground) && - (swapAction != XdbeUntouched ) && - (swapAction != XdbeCopied )) - { - return(BadValue); - } - - /* The id must be in range and not already in use. */ - LEGAL_NEW_RESOURCE(stuff->buffer, client); - - /* The visual of the window must be in the list returned by - * GetVisualInfo. - */ - pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); - if (!pDbeScreenPriv->GetVisualInfo) - return(BadMatch); /* screen doesn't support double buffering */ - - if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo)) - { - /* GetVisualInfo() failed to allocate visual info data. */ - return(BadAlloc); - } - - /* See if the window's visual is on the list. */ - visual = wVisual(pWin); - for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++) - { - if (scrVisInfo.visinfo[i].visual == visual) - { - visualMatched = TRUE; - } - } - - /* Free what was allocated by the GetVisualInfo() call above. */ - xfree(scrVisInfo.visinfo); - - if (!visualMatched) - { - return(BadMatch); - } - - if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL) - { - /* There is no buffer associated with the window. - * Allocate a window priv. - */ - - pDbeWindowPriv = xcalloc(1, sizeof(DbeWindowPrivRec)); - if (!pDbeWindowPriv) - return(BadAlloc); - - /* Fill out window priv information. */ - pDbeWindowPriv->pWindow = pWin; - pDbeWindowPriv->width = pWin->drawable.width; - pDbeWindowPriv->height = pWin->drawable.height; - pDbeWindowPriv->x = pWin->drawable.x; - pDbeWindowPriv->y = pWin->drawable.y; - pDbeWindowPriv->nBufferIDs = 0; - - /* Set the buffer ID array pointer to the initial (static) array). */ - pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; - - /* Initialize the buffer ID list. */ - pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; - pDbeWindowPriv->IDs[0] = stuff->buffer; - - add_index = 0; - for (i = 0; i < DBE_INIT_MAX_IDS; i++) - { - pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT; - } - - /* Actually connect the window priv to the window. */ - dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv); - - } /* if -- There is no buffer associated with the window. */ - - else - { - /* A buffer is already associated with the window. - * Add the new buffer ID to the array, reallocating the array memory - * if necessary. - */ - - /* Determine if there is a free element in the ID array. */ - for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++) - { - if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT) - { - /* There is still room in the ID array. */ - break; - } - } - - if (i == pDbeWindowPriv->maxAvailableIDs) - { - /* No more room in the ID array -- reallocate another array. */ - XID *pIDs; - - /* Setup an array pointer for the realloc operation below. */ - if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) - { - /* We will malloc a new array. */ - pIDs = NULL; - } - else - { - /* We will realloc a new array. */ - pIDs = pDbeWindowPriv->IDs; - } - - /* malloc/realloc a new array and initialize all elements to 0. */ - pDbeWindowPriv->IDs = (XID *)xrealloc(pIDs, - (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID)); - if (!pDbeWindowPriv->IDs) - { - return(BadAlloc); - } - memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0, - (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS - - pDbeWindowPriv->nBufferIDs) * sizeof(XID)); - - if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) - { - /* We just went from using the initial (static) array to a - * newly allocated array. Copy the IDs from the initial array - * to the new array. - */ - memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs, - DBE_INIT_MAX_IDS * sizeof(XID)); - } - - pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS; - } - - add_index = i; - - } /* else -- A buffer is already associated with the window. */ - - - /* Call the DDX routine to allocate the back buffer. */ - status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer, - stuff->swapAction); - - if (status == Success) - { - pDbeWindowPriv->IDs[add_index] = stuff->buffer; - if (!AddResource(stuff->buffer, dbeWindowPrivResType, - (pointer)pDbeWindowPriv)) - { - pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT; - - if (pDbeWindowPriv->nBufferIDs == 0) { - status = BadAlloc; - goto out_free; - } - } - } else { - /* The DDX buffer allocation routine failed for the first buffer of - * this window. - */ - if (pDbeWindowPriv->nBufferIDs == 0) { - goto out_free; - } - } - - /* Increment the number of buffers (XIDs) associated with this window. */ - pDbeWindowPriv->nBufferIDs++; - - /* Set swap action on all calls. */ - pDbeWindowPriv->swapAction = stuff->swapAction; - - return(status); - -out_free: - dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL); - xfree(pDbeWindowPriv); - return (status); - -} /* ProcDbeAllocateBackBufferName() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: ProcDbeDeallocateBackBufferName - * - * Description: - * - * This function is for processing a DbeDeallocateBackBufferName request. - * This request frees a drawable ID that was obtained by a - * DbeAllocateBackBufferName request. - * - * Return Values: - * - * BadBuffer - buffer to deallocate is not associated with a window - * Success - * - *****************************************************************************/ - -static int -ProcDbeDeallocateBackBufferName(ClientPtr client) -{ - REQUEST(xDbeDeallocateBackBufferNameReq); - DbeWindowPrivPtr pDbeWindowPriv; - int rc, i; - pointer val; - - - REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); - - /* Buffer name must be valid */ - rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer, - dbeWindowPrivResType, client, - DixDestroyAccess); - if (rc != Success) - return (rc == BadValue) ? dbeErrorBase + DbeBadBuffer : rc; - - rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType, - client, DixDestroyAccess); - if (rc != Success) - return (rc == BadValue) ? dbeErrorBase + DbeBadBuffer : rc; - - /* Make sure that the id is valid for the window. - * This is paranoid code since we already looked up the ID by type - * above. - */ - - for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) - { - /* Loop through the ID list to find the ID. */ - if (pDbeWindowPriv->IDs[i] == stuff->buffer) - { - break; - } - } - - if (i == pDbeWindowPriv->nBufferIDs) - { - /* We did not find the ID in the ID list. */ - client->errorValue = stuff->buffer; - return(dbeErrorBase + DbeBadBuffer); - } - - FreeResource(stuff->buffer, RT_NONE); - - return(Success); - -} /* ProcDbeDeallocateBackBufferName() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: ProcDbeSwapBuffers - * - * Description: - * - * This function is for processing a DbeSwapBuffers request. - * This request swaps the buffers for all windows listed, applying the - * appropriate swap action for each window. - * - * Return Values: - * - * BadAlloc - local allocation failed; this return value is not defined - * by the protocol - * BadMatch - a window in request is not double-buffered; a window in - * request is listed more than once - * BadValue - invalid swap action is specified; no swap action is - * specified - * BadWindow - a window in request is not valid - * Success - * - *****************************************************************************/ - -static int -ProcDbeSwapBuffers(ClientPtr client) -{ - REQUEST(xDbeSwapBuffersReq); - WindowPtr pWin; - DbeScreenPrivPtr pDbeScreenPriv; - DbeSwapInfoPtr swapInfo; - xDbeSwapInfo *dbeSwapInfo; - int error; - register int i, j; - int nStuff; - - - REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); - nStuff = stuff->n; /* use local variable for performance. */ - - if (nStuff == 0) - { - return(Success); - } - - if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec)) - return BadAlloc; - - /* Get to the swap info appended to the end of the request. */ - dbeSwapInfo = (xDbeSwapInfo *)&stuff[1]; - - /* Allocate array to record swap information. */ - swapInfo = (DbeSwapInfoPtr)Xalloc(nStuff * sizeof(DbeSwapInfoRec)); - if (swapInfo == NULL) - { - return(BadAlloc); - } - - - for (i = 0; i < nStuff; i++) - { - /* Check all windows to swap. */ - - /* Each window must be a valid window - BadWindow. */ - error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client, - DixWriteAccess); - if (error != Success) { - Xfree(swapInfo); - return error; - } - - /* Each window must be double-buffered - BadMatch. */ - if (DBE_WINDOW_PRIV(pWin) == NULL) - { - Xfree(swapInfo); - return(BadMatch); - } - - /* Each window must only be specified once - BadMatch. */ - for (j = i + 1; j < nStuff; j++) - { - if (dbeSwapInfo[i].window == dbeSwapInfo[j].window) - { - Xfree(swapInfo); - return(BadMatch); - } - } - - /* Each swap action must be valid - BadValue. */ - if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) && - (dbeSwapInfo[i].swapAction != XdbeBackground) && - (dbeSwapInfo[i].swapAction != XdbeUntouched ) && - (dbeSwapInfo[i].swapAction != XdbeCopied )) - { - Xfree(swapInfo); - return(BadValue); - } - - /* Everything checks out OK. Fill in the swap info array. */ - swapInfo[i].pWindow = pWin; - swapInfo[i].swapAction = dbeSwapInfo[i].swapAction; - - } /* for (i = 0; i < nStuff; i++) */ - - - /* Call the DDX routine to perform the swap(s). The DDX routine should - * scan the swap list (swap info), swap any buffers that it knows how to - * handle, delete them from the list, and update nStuff to indicate how - * many windows it did not handle. - * - * This scheme allows a range of sophistication in the DDX SwapBuffers() - * implementation. Naive implementations could just swap the first buffer - * in the list, move the last buffer to the front, decrement nStuff, and - * return. The next level of sophistication could be to scan the whole - * list for windows on the same screen. Up another level, the DDX routine - * could deal with cross-screen synchronization. - */ - - while (nStuff > 0) - { - pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow); - error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo); - if (error != Success) - { - Xfree(swapInfo); - return(error); - } - } - - Xfree(swapInfo); - return(Success); - -} /* ProcDbeSwapBuffers() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: ProcDbeBeginIdiom - * - * Description: - * - * This function is for processing a DbeBeginIdiom request. - * This request informs the server that a complex swap will immediately - * follow this request. - * - * Return Values: - * - * Success - * - *****************************************************************************/ - -static int -ProcDbeBeginIdiom(ClientPtr client) -{ - /* REQUEST(xDbeBeginIdiomReq); */ - DbeScreenPrivPtr pDbeScreenPriv; - register int i; - - - REQUEST_SIZE_MATCH(xDbeBeginIdiomReq); - - for (i = 0; i < screenInfo.numScreens; i++) - { - pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]); - - /* Call the DDX begin idiom procedure if there is one. */ - if (pDbeScreenPriv->BeginIdiom) - { - (*pDbeScreenPriv->BeginIdiom)(client); - } - } - - return(Success); - -} /* ProcDbeBeginIdiom() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: ProcDbeGetVisualInfo - * - * Description: - * - * This function is for processing a ProcDbeGetVisualInfo request. - * This request returns information about which visuals support - * double buffering. - * - * Return Values: - * - * BadDrawable - value in screen specifiers is not a valid drawable - * Success - * - *****************************************************************************/ - -static int -ProcDbeGetVisualInfo(ClientPtr client) -{ - REQUEST(xDbeGetVisualInfoReq); - DbeScreenPrivPtr pDbeScreenPriv; - xDbeGetVisualInfoReply rep; - Drawable *drawables; - DrawablePtr *pDrawables = NULL; - register int i, j, n, rc; - register int count; /* number of visual infos in reply */ - register int length; /* length of reply */ - ScreenPtr pScreen; - XdbeScreenVisualInfo *pScrVisInfo; - - - REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); - - if (stuff->n > UINT32_MAX / sizeof(DrawablePtr)) - return BadAlloc; - /* Make sure any specified drawables are valid. */ - if (stuff->n != 0) - { - if (!(pDrawables = (DrawablePtr *)Xalloc(stuff->n * - sizeof(DrawablePtr)))) - { - return(BadAlloc); - } - - drawables = (Drawable *)&stuff[1]; - - for (i = 0; i < stuff->n; i++) - { - rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0, - DixGetAttrAccess); - if (rc != Success) { - Xfree(pDrawables); - return rc; - } - } - } - - count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n; - if (!(pScrVisInfo = (XdbeScreenVisualInfo *)xalloc(count * - sizeof(XdbeScreenVisualInfo)))) - { - if (pDrawables) - { - Xfree(pDrawables); - } - - return(BadAlloc); - } - - length = 0; - - for (i = 0; i < count; i++) - { - pScreen = (stuff->n == 0) ? screenInfo.screens[i] : - pDrawables[i]->pScreen; - pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); - - rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); - if ((rc != Success) || - !(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i])) - { - /* We failed to alloc pScrVisInfo[i].visinfo. */ - - /* Free visinfos that we allocated for previous screen infos.*/ - for (j = 0; j < i; j++) - { - xfree(pScrVisInfo[j].visinfo); - } - - /* Free pDrawables if we needed to allocate it above. */ - if (pDrawables) - { - Xfree(pDrawables); - } - - return (rc == Success) ? BadAlloc : rc; - } - - /* Account for n, number of xDbeVisInfo items in list. */ - length += sizeof(CARD32); - - /* Account for n xDbeVisInfo items */ - length += pScrVisInfo[i].count * sizeof(xDbeVisInfo); - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = bytes_to_int32(length); - rep.m = count; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.m, n); - } - - /* Send off reply. */ - WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep); - - for (i = 0; i < count; i++) - { - CARD32 data32; - - /* For each screen in the reply, send off the visual info */ - - /* Send off number of visuals. */ - data32 = (CARD32)pScrVisInfo[i].count; - - if (client->swapped) - { - swapl(&data32, n); - } - - WriteToClient(client, sizeof(CARD32), (char *)&data32); - - /* Now send off visual info items. */ - for (j = 0; j < pScrVisInfo[i].count; j++) - { - xDbeVisInfo visInfo; - - /* Copy the data in the client data structure to a protocol - * data structure. We will send data to the client from the - * protocol data structure. - */ - - visInfo.visualID = (CARD32)pScrVisInfo[i].visinfo[j].visual; - visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth; - visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel; - - if (client->swapped) - { - swapl(&visInfo.visualID, n); - - /* We do not need to swap depth and perfLevel since they are - * already 1 byte quantities. - */ - } - - /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */ - WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID); - } - } - - /* Clean up memory. */ - for (i = 0; i < count; i++) - { - xfree(pScrVisInfo[i].visinfo); - } - xfree(pScrVisInfo); - - if (pDrawables) - { - Xfree(pDrawables); - } - - return(client->noClientException); - -} /* ProcDbeGetVisualInfo() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: ProcDbeGetbackBufferAttributes - * - * Description: - * - * This function is for processing a ProcDbeGetbackBufferAttributes - * request. This request returns information about a back buffer. - * - * Return Values: - * - * Success - * - *****************************************************************************/ - -static int -ProcDbeGetBackBufferAttributes(ClientPtr client) -{ - REQUEST(xDbeGetBackBufferAttributesReq); - xDbeGetBackBufferAttributesReply rep; - DbeWindowPrivPtr pDbeWindowPriv; - int rc, n; - - - REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); - - rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer, - dbeWindowPrivResType, client, - DixGetAttrAccess); - if (rc == Success) - { - rep.attributes = pDbeWindowPriv->pWindow->drawable.id; - } - else - { - rep.attributes = None; - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.attributes, n); - } - - WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply), - (char *)&rep); - return(client->noClientException); - -} /* ProcDbeGetbackBufferAttributes() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: ProcDbeDispatch - * - * Description: - * - * This function dispatches DBE requests. - * - *****************************************************************************/ - -static int -ProcDbeDispatch(ClientPtr client) -{ - REQUEST(xReq); - - - switch (stuff->data) - { - case X_DbeGetVersion: - return(ProcDbeGetVersion(client)); - - case X_DbeAllocateBackBufferName: - return(ProcDbeAllocateBackBufferName(client)); - - case X_DbeDeallocateBackBufferName: - return(ProcDbeDeallocateBackBufferName(client)); - - case X_DbeSwapBuffers: - return(ProcDbeSwapBuffers(client)); - - case X_DbeBeginIdiom: - return(ProcDbeBeginIdiom(client)); - - case X_DbeEndIdiom: - return(Success); - - case X_DbeGetVisualInfo: - return(ProcDbeGetVisualInfo(client)); - - case X_DbeGetBackBufferAttributes: - return(ProcDbeGetBackBufferAttributes(client)); - - default: - return(BadRequest); - } - -} /* ProcDbeDispatch() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: SProcDbeGetVersion - * - * Description: - * - * This function is for processing a DbeGetVersion request on a swapped - * server. This request returns the major and minor version numbers of - * this extension. - * - * Return Values: - * - * Success - * - *****************************************************************************/ - -static int -SProcDbeGetVersion(ClientPtr client) -{ - REQUEST(xDbeGetVersionReq); - register int n; - - - swaps(&stuff->length, n); - return(ProcDbeGetVersion(client)); - -} /* SProcDbeGetVersion() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: SProcDbeAllocateBackBufferName - * - * Description: - * - * This function is for processing a DbeAllocateBackBufferName request on - * a swapped server. This request allocates a drawable ID used to refer - * to the back buffer of a window. - * - * Return Values: - * - * BadAlloc - server can not allocate resources - * BadIDChoice - id is out of range for client; id is already in use - * BadMatch - window is not an InputOutput window; - * visual of window is not on list returned by - * DBEGetVisualInfo; - * BadValue - invalid swap action is specified - * BadWindow - window is not a valid window - * Success - * - *****************************************************************************/ - -static int -SProcDbeAllocateBackBufferName(ClientPtr client) -{ - REQUEST(xDbeAllocateBackBufferNameReq); - register int n; - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); - - swapl(&stuff->window, n); - swapl(&stuff->buffer, n); - /* stuff->swapAction is a byte. We do not need to swap this field. */ - - return(ProcDbeAllocateBackBufferName(client)); - -} /* SProcDbeAllocateBackBufferName() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: SProcDbeDeallocateBackBufferName - * - * Description: - * - * This function is for processing a DbeDeallocateBackBufferName request - * on a swapped server. This request frees a drawable ID that was - * obtained by a DbeAllocateBackBufferName request. - * - * Return Values: - * - * BadBuffer - buffer to deallocate is not associated with a window - * Success - * - *****************************************************************************/ - -static int -SProcDbeDeallocateBackBufferName(ClientPtr client) -{ - REQUEST (xDbeDeallocateBackBufferNameReq); - register int n; - - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); - - swapl(&stuff->buffer, n); - - return(ProcDbeDeallocateBackBufferName(client)); - -} /* SProcDbeDeallocateBackBufferName() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: SProcDbeSwapBuffers - * - * Description: - * - * This function is for processing a DbeSwapBuffers request on a swapped - * server. This request swaps the buffers for all windows listed, - * applying the appropriate swap action for each window. - * - * Return Values: - * - * BadMatch - a window in request is not double-buffered; a window in - * request is listed more than once; all windows in request do - * not have the same root - * BadValue - invalid swap action is specified - * BadWindow - a window in request is not valid - * Success - * - *****************************************************************************/ - -static int -SProcDbeSwapBuffers(ClientPtr client) -{ - REQUEST(xDbeSwapBuffersReq); - register int i, n; - xDbeSwapInfo *pSwapInfo; - - - swaps(&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); - - swapl(&stuff->n, n); - - if (stuff->n != 0) - { - pSwapInfo = (xDbeSwapInfo *)stuff+1; - - /* The swap info following the fix part of this request is a window(32) - * followed by a 1 byte swap action and then 3 pad bytes. We only need - * to swap the window information. - */ - for (i = 0; i < stuff->n; i++) - { - swapl(&pSwapInfo->window, n); - } - } - - return(ProcDbeSwapBuffers(client)); - -} /* SProcDbeSwapBuffers() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: SProcDbeBeginIdiom - * - * Description: - * - * This function is for processing a DbeBeginIdiom request on a swapped - * server. This request informs the server that a complex swap will - * immediately follow this request. - * - * Return Values: - * - * Success - * - *****************************************************************************/ - -static int -SProcDbeBeginIdiom(ClientPtr client) -{ - REQUEST(xDbeBeginIdiomReq); - register int n; - - swaps(&stuff->length, n); - return(ProcDbeBeginIdiom(client)); - -} /* SProcDbeBeginIdiom() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: SProcDbeGetVisualInfo - * - * Description: - * - * This function is for processing a ProcDbeGetVisualInfo request on a - * swapped server. This request returns information about which visuals - * support double buffering. - * - * Return Values: - * - * BadDrawable - value in screen specifiers is not a valid drawable - * Success - * - *****************************************************************************/ - -static int -SProcDbeGetVisualInfo(ClientPtr client) -{ - REQUEST(xDbeGetVisualInfoReq); - register int n; - - - swaps(&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); - - swapl(&stuff->n, n); - SwapRestL(stuff); - - return(ProcDbeGetVisualInfo(client)); - -} /* SProcDbeGetVisualInfo() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: SProcDbeGetbackBufferAttributes - * - * Description: - * - * This function is for processing a ProcDbeGetbackBufferAttributes - * request on a swapped server. This request returns information about a - * back buffer. - * - * Return Values: - * - * Success - * - *****************************************************************************/ - -static int -SProcDbeGetBackBufferAttributes(ClientPtr client) -{ - REQUEST (xDbeGetBackBufferAttributesReq); - register int n; - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); - - swapl(&stuff->buffer, n); - - return(ProcDbeGetBackBufferAttributes(client)); - -} /* SProcDbeGetBackBufferAttributes() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: SProcDbeDispatch - * - * Description: - * - * This function dispatches DBE requests on a swapped server. - * - *****************************************************************************/ - -static int -SProcDbeDispatch(ClientPtr client) -{ - REQUEST(xReq); - - - switch (stuff->data) - { - case X_DbeGetVersion: - return(SProcDbeGetVersion(client)); - - case X_DbeAllocateBackBufferName: - return(SProcDbeAllocateBackBufferName(client)); - - case X_DbeDeallocateBackBufferName: - return(SProcDbeDeallocateBackBufferName(client)); - - case X_DbeSwapBuffers: - return(SProcDbeSwapBuffers(client)); - - case X_DbeBeginIdiom: - return(SProcDbeBeginIdiom(client)); - - case X_DbeEndIdiom: - return(Success); - - case X_DbeGetVisualInfo: - return(SProcDbeGetVisualInfo(client)); - - case X_DbeGetBackBufferAttributes: - return(SProcDbeGetBackBufferAttributes(client)); - - default: - return (BadRequest); - } - -} /* SProcDbeDispatch() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: DbeSetupBackgroundPainter - * - * Description: - * - * This function sets up pGC to clear pixmaps. - * - * Return Values: - * - * TRUE - setup was successful - * FALSE - the window's background state is NONE - * - *****************************************************************************/ - -static Bool -DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC) -{ - pointer gcvalues[4]; - int ts_x_origin, ts_y_origin; - PixUnion background; - int backgroundState; - Mask gcmask; - - - /* First take care of any ParentRelative stuff by altering the - * tile/stipple origin to match the coordinates of the upper-left - * corner of the first ancestor without a ParentRelative background. - * This coordinate is, of course, negative. - */ - ts_x_origin = ts_y_origin = 0; - while (pWin->backgroundState == ParentRelative) - { - ts_x_origin -= pWin->origin.x; - ts_y_origin -= pWin->origin.y; - - pWin = pWin->parent; - } - backgroundState = pWin->backgroundState; - background = pWin->background; - - switch (backgroundState) - { - case BackgroundPixel: - gcvalues[0] = (pointer)background.pixel; - gcvalues[1] = (pointer)FillSolid; - gcmask = GCForeground|GCFillStyle; - break; - - case BackgroundPixmap: - gcvalues[0] = (pointer)FillTiled; - gcvalues[1] = (pointer)background.pixmap; - gcvalues[2] = (pointer)(long)ts_x_origin; - gcvalues[3] = (pointer)(long)ts_y_origin; - gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin; - break; - - default: - /* pWin->backgroundState == None */ - return(FALSE); - } - - if (DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE) != 0) - { - return(FALSE); - } - - return(TRUE); - -} /* DbeSetupBackgroundPainter() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: DbeDrawableDelete - * - * Description: - * - * This is the resource delete function for dbeDrawableResType. - * It is registered when the drawable resource type is created in - * DbeExtensionInit(). - * - * To make resource deletion simple, we do not do anything in this function - * and leave all resource deleteion to DbeWindowPrivDelete(), which will - * eventually be called or already has been called. Deletion functions are - * not guaranteed to be called in any particular order. - * - *****************************************************************************/ -static int -DbeDrawableDelete(pointer pDrawable, XID id) -{ - return(Success); - -} /* DbeDrawableDelete() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: DbeWindowPrivDelete - * - * Description: - * - * This is the resource delete function for dbeWindowPrivResType. - * It is registered when the drawable resource type is created in - * DbeExtensionInit(). - * - *****************************************************************************/ -static int -DbeWindowPrivDelete(pointer pDbeWinPriv, XID id) -{ - DbeScreenPrivPtr pDbeScreenPriv; - DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv; - int i; - - - /* - ************************************************************************** - ** Remove the buffer ID from the ID array. - ************************************************************************** - */ - - /* Find the ID in the ID array. */ - i = 0; - while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id)) - { - i++; - } - - if (i == pDbeWindowPriv->nBufferIDs) - { - /* We did not find the ID in the array. We should never get here. */ - return(BadValue); - } - - /* Remove the ID from the array. */ - - if (i < (pDbeWindowPriv->nBufferIDs - 1)) - { - /* Compress the buffer ID array, overwriting the ID in the process. */ - memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1], - (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID)); - } - else - { - /* We are removing the last ID in the array, in which case, the - * assignement below is all that we need to do. - */ - } - pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT; - - pDbeWindowPriv->nBufferIDs--; - - /* If an extended array was allocated, then check to see if the remaining - * buffer IDs will fit in the static array. - */ - - if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) && - (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS)) - { - /* Copy the IDs back into the static array. */ - memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs, - DBE_INIT_MAX_IDS * sizeof(XID)); - - /* Free the extended array; use the static array. */ - xfree(pDbeWindowPriv->IDs); - pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; - pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; - } - - - /* - ************************************************************************** - ** Perform DDX level tasks. - ************************************************************************** - */ - - pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV( - (DbeWindowPrivPtr)pDbeWindowPriv); - (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id); - - - /* - ************************************************************************** - ** Perform miscellaneous tasks if this is the last buffer associated - ** with the window. - ************************************************************************** - */ - - if (pDbeWindowPriv->nBufferIDs == 0) - { - /* Reset the DBE window priv pointer. */ - dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey, - NULL); - - /* We are done with the window priv. */ - dixFreePrivates(pDbeWindowPriv->devPrivates); - xfree(pDbeWindowPriv); - } - - return(Success); - -} /* DbeWindowPrivDelete() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: DbeResetProc - * - * Description: - * - * This routine is called at the end of every server generation. - * It deallocates any memory reserved for the extension and performs any - * other tasks related to shutting down the extension. - * - *****************************************************************************/ -static void -DbeResetProc(ExtensionEntry *extEntry) -{ - int i; - ScreenPtr pScreen; - DbeScreenPrivPtr pDbeScreenPriv; - - for (i = 0; i < screenInfo.numScreens; i++) - { - pScreen = screenInfo.screens[i]; - pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); - - if (pDbeScreenPriv) - { - /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/ - pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; - - if (pDbeScreenPriv->ResetProc) - (*pDbeScreenPriv->ResetProc)(pScreen); - - dixFreePrivates(pDbeScreenPriv->devPrivates); - xfree(pDbeScreenPriv); - } - } -} /* DbeResetProc() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: DbeDestroyWindow - * - * Description: - * - * This is the wrapper for pScreen->DestroyWindow. - * This function frees buffer resources for a window before it is - * destroyed. - * - *****************************************************************************/ - -static Bool -DbeDestroyWindow(WindowPtr pWin) -{ - DbeScreenPrivPtr pDbeScreenPriv; - DbeWindowPrivPtr pDbeWindowPriv; - ScreenPtr pScreen; - Bool ret; - - - /* - ************************************************************************** - ** 1. Unwrap the member routine. - ************************************************************************** - */ - - pScreen = pWin->drawable.pScreen; - pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); - pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; - - /* - ************************************************************************** - ** 2. Do any work necessary before the member routine is called. - ** - ** Call the window priv delete function for all buffer IDs associated - ** with this window. - ************************************************************************** - */ - - if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) - { - while (pDbeWindowPriv) - { - /* *DbeWinPrivDelete() will free the window private and set it to - * NULL if there are no more buffer IDs associated with this - * window. - */ - FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); - pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); - } - } - - /* - ************************************************************************** - ** 3. Call the member routine, saving its result if necessary. - ************************************************************************** - */ - - ret = (*pScreen->DestroyWindow)(pWin); - - /* - ************************************************************************** - ** 4. Rewrap the member routine, restoring the wrapper value first in case - ** the wrapper (or something that it wrapped) change this value. - ************************************************************************** - */ - - pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; - pScreen->DestroyWindow = DbeDestroyWindow; - - /* - ************************************************************************** - ** 5. Do any work necessary after the member routine has been called. - ** - ** In this case we do not need to do anything. - ************************************************************************** - */ - - return(ret); - -} /* DbeDestroyWindow() */ - - -/****************************************************************************** - * - * DBE DIX Procedure: DbeExtensionInit - * - * Description: - * - * Called from InitExtensions in main() - * - *****************************************************************************/ - -void -DbeExtensionInit(void) -{ - ExtensionEntry *extEntry; - register int i, j; - ScreenPtr pScreen = NULL; - DbeScreenPrivPtr pDbeScreenPriv; - int nStubbedScreens = 0; - Bool ddxInitSuccess; - -#ifdef PANORAMIX - if(!noPanoramiXExtension) return; -#endif - - /* Create the resource types. */ - dbeDrawableResType = - CreateNewResourceType(DbeDrawableDelete, "dbeDrawable"); - if (!dbeDrawableResType) - return; - dbeDrawableResType |= RC_DRAWABLE; - - dbeWindowPrivResType = - CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow"); - if (!dbeWindowPrivResType) - return; - - if (!dixRegisterPrivateOffset(dbeDrawableResType, - offsetof(PixmapRec, devPrivates))) - return; - - for (i = 0; i < screenInfo.numScreens; i++) - { - /* For each screen, set up DBE screen privates and init DIX and DDX - * interface. - */ - - pScreen = screenInfo.screens[i]; - - if (!(pDbeScreenPriv = - (DbeScreenPrivPtr)Xcalloc(sizeof(DbeScreenPrivRec)))) - { - /* If we can not alloc a window or screen private, - * then free any privates that we already alloc'ed and return - */ - - for (j = 0; j < i; j++) - { - xfree(dixLookupPrivate(&screenInfo.screens[j]->devPrivates, - dbeScreenPrivKey)); - dixSetPrivate(&screenInfo.screens[j]->devPrivates, - dbeScreenPrivKey, NULL); - } - return; - } - - dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv); - - /* Copy the resource types */ - pDbeScreenPriv->dbeDrawableResType = dbeDrawableResType; - pDbeScreenPriv->dbeWindowPrivResType = dbeWindowPrivResType; - - /* Copy the private indices */ - pDbeScreenPriv->dbeScreenPrivKey = dbeScreenPrivKey; - pDbeScreenPriv->dbeWindowPrivKey = dbeWindowPrivKey; - - { - /* We don't have DDX support for DBE anymore */ - -#ifndef DISABLE_MI_DBE_BY_DEFAULT - /* Setup DIX. */ - pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter; - - /* Setup DDX. */ - ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv); - - /* DDX DBE initialization may have the side affect of - * reallocating pDbeScreenPriv, so we need to update it. - */ - pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); - - if (ddxInitSuccess) - { - /* Wrap DestroyWindow. The DDX initialization function - * already wrapped PositionWindow for us. - */ - - pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; - pScreen->DestroyWindow = DbeDestroyWindow; - } - else - { - /* DDX initialization failed. Stub the screen. */ - DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); - } -#else - DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); -#endif - - } - - } /* for (i = 0; i < screenInfo.numScreens; i++) */ - - - if (nStubbedScreens == screenInfo.numScreens) - { - /* All screens stubbed. Clean up and return. */ - - for (i = 0; i < screenInfo.numScreens; i++) - { - xfree(dixLookupPrivate(&screenInfo.screens[i]->devPrivates, - dbeScreenPrivKey)); - dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL); - } - return; - } - - - /* Now add the extension. */ - extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents, - DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch, - DbeResetProc, StandardMinorOpcode); - - dbeErrorBase = extEntry->errorBase; - -} /* DbeExtensionInit() */ - +/******************************************************************************
+ *
+ * Copyright (c) 1994, 1995 Hewlett-Packard Company
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Hewlett-Packard
+ * Company shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the Hewlett-Packard Company.
+ *
+ * DIX DBE code
+ *
+ *****************************************************************************/
+
+
+/* INCLUDES */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#define NEED_DBE_PROTOCOL
+#include "dbestruct.h"
+#include "midbe.h"
+#include "xace.h"
+
+/* GLOBALS */
+
+/* These are static globals copied to DBE's screen private for use by DDX */
+static int dbeScreenPrivKeyIndex;
+static DevPrivateKey dbeScreenPrivKey = &dbeScreenPrivKeyIndex;
+static int dbeWindowPrivKeyIndex;
+static DevPrivateKey dbeWindowPrivKey = &dbeWindowPrivKeyIndex;
+
+/* These are static globals copied to DBE's screen private for use by DDX */
+static RESTYPE dbeDrawableResType;
+static RESTYPE dbeWindowPrivResType;
+
+/* Used to generate DBE's BadBuffer error. */
+static int dbeErrorBase;
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeStubScreen
+ *
+ * Description:
+ *
+ * This is function stubs the function pointers in the given DBE screen
+ * private and increments the number of stubbed screens.
+ *
+ *****************************************************************************/
+
+static void
+DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
+{
+ /* Stub DIX. */
+ pDbeScreenPriv->SetupBackgroundPainter = NULL;
+
+ /* Do not unwrap PositionWindow nor DestroyWindow. If the DDX
+ * initialization function failed, we assume that it did not wrap
+ * PositionWindow. Also, DestroyWindow is only wrapped if the DDX
+ * initialization function succeeded.
+ */
+
+ /* Stub DDX. */
+ pDbeScreenPriv->GetVisualInfo = NULL;
+ pDbeScreenPriv->AllocBackBufferName = NULL;
+ pDbeScreenPriv->SwapBuffers = NULL;
+ pDbeScreenPriv->BeginIdiom = NULL;
+ pDbeScreenPriv->EndIdiom = NULL;
+ pDbeScreenPriv->WinPrivDelete = NULL;
+ pDbeScreenPriv->ResetProc = NULL;
+
+ (*nStubbedScreens)++;
+
+} /* DbeStubScreen() */
+
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeGetVersion
+ *
+ * Description:
+ *
+ * This function is for processing a DbeGetVersion request.
+ * This request returns the major and minor version numbers of this
+ * extension.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeGetVersion(ClientPtr client)
+{
+ /* REQUEST(xDbeGetVersionReq); */
+ xDbeGetVersionReply rep;
+ register int n;
+
+
+ REQUEST_SIZE_MATCH(xDbeGetVersionReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = DBE_MAJOR_VERSION;
+ rep.minorVersion = DBE_MINOR_VERSION;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ }
+
+ WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep);
+
+ return Success;
+
+} /* ProcDbeGetVersion() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeAllocateBackBufferName
+ *
+ * Description:
+ *
+ * This function is for processing a DbeAllocateBackBufferName request.
+ * This request allocates a drawable ID used to refer to the back buffer
+ * of a window.
+ *
+ * Return Values:
+ *
+ * BadAlloc - server can not allocate resources
+ * BadIDChoice - id is out of range for client; id is already in use
+ * BadMatch - window is not an InputOutput window;
+ * visual of window is not on list returned by
+ * DBEGetVisualInfo;
+ * BadValue - invalid swap action is specified
+ * BadWindow - window is not a valid window
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeAllocateBackBufferName(ClientPtr client)
+{
+ REQUEST(xDbeAllocateBackBufferNameReq);
+ WindowPtr pWin;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ XdbeScreenVisualInfo scrVisInfo;
+ register int i;
+ Bool visualMatched = FALSE;
+ xDbeSwapAction swapAction;
+ VisualID visual;
+ int status;
+ int add_index;
+
+
+ REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
+
+ /* The window must be valid. */
+ status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
+ if (status != Success)
+ return status;
+
+ /* The window must be InputOutput. */
+ if (pWin->drawable.class != InputOutput)
+ {
+ return(BadMatch);
+ }
+
+ /* The swap action must be valid. */
+ swapAction = stuff->swapAction; /* use local var for performance. */
+ if ((swapAction != XdbeUndefined ) &&
+ (swapAction != XdbeBackground) &&
+ (swapAction != XdbeUntouched ) &&
+ (swapAction != XdbeCopied ))
+ {
+ return(BadValue);
+ }
+
+ /* The id must be in range and not already in use. */
+ LEGAL_NEW_RESOURCE(stuff->buffer, client);
+
+ /* The visual of the window must be in the list returned by
+ * GetVisualInfo.
+ */
+ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
+ if (!pDbeScreenPriv->GetVisualInfo)
+ return(BadMatch); /* screen doesn't support double buffering */
+
+ if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo))
+ {
+ /* GetVisualInfo() failed to allocate visual info data. */
+ return(BadAlloc);
+ }
+
+ /* See if the window's visual is on the list. */
+ visual = wVisual(pWin);
+ for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++)
+ {
+ if (scrVisInfo.visinfo[i].visual == visual)
+ {
+ visualMatched = TRUE;
+ }
+ }
+
+ /* Free what was allocated by the GetVisualInfo() call above. */
+ free(scrVisInfo.visinfo);
+
+ if (!visualMatched)
+ {
+ return(BadMatch);
+ }
+
+ if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL)
+ {
+ /* There is no buffer associated with the window.
+ * Allocate a window priv.
+ */
+
+ pDbeWindowPriv = calloc(1, sizeof(DbeWindowPrivRec));
+ if (!pDbeWindowPriv)
+ return(BadAlloc);
+
+ /* Fill out window priv information. */
+ pDbeWindowPriv->pWindow = pWin;
+ pDbeWindowPriv->width = pWin->drawable.width;
+ pDbeWindowPriv->height = pWin->drawable.height;
+ pDbeWindowPriv->x = pWin->drawable.x;
+ pDbeWindowPriv->y = pWin->drawable.y;
+ pDbeWindowPriv->nBufferIDs = 0;
+
+ /* Set the buffer ID array pointer to the initial (static) array). */
+ pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
+
+ /* Initialize the buffer ID list. */
+ pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
+ pDbeWindowPriv->IDs[0] = stuff->buffer;
+
+ add_index = 0;
+ for (i = 0; i < DBE_INIT_MAX_IDS; i++)
+ {
+ pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
+ }
+
+ /* Actually connect the window priv to the window. */
+ dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv);
+
+ } /* if -- There is no buffer associated with the window. */
+
+ else
+ {
+ /* A buffer is already associated with the window.
+ * Add the new buffer ID to the array, reallocating the array memory
+ * if necessary.
+ */
+
+ /* Determine if there is a free element in the ID array. */
+ for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++)
+ {
+ if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT)
+ {
+ /* There is still room in the ID array. */
+ break;
+ }
+ }
+
+ if (i == pDbeWindowPriv->maxAvailableIDs)
+ {
+ /* No more room in the ID array -- reallocate another array. */
+ XID *pIDs;
+
+ /* Setup an array pointer for the realloc operation below. */
+ if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
+ {
+ /* We will malloc a new array. */
+ pIDs = NULL;
+ }
+ else
+ {
+ /* We will realloc a new array. */
+ pIDs = pDbeWindowPriv->IDs;
+ }
+
+ /* malloc/realloc a new array and initialize all elements to 0. */
+ pDbeWindowPriv->IDs = (XID *)realloc(pIDs,
+ (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID));
+ if (!pDbeWindowPriv->IDs)
+ {
+ return(BadAlloc);
+ }
+ memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
+ (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
+ pDbeWindowPriv->nBufferIDs) * sizeof(XID));
+
+ if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS)
+ {
+ /* We just went from using the initial (static) array to a
+ * newly allocated array. Copy the IDs from the initial array
+ * to the new array.
+ */
+ memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
+ DBE_INIT_MAX_IDS * sizeof(XID));
+ }
+
+ pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
+ }
+
+ add_index = i;
+
+ } /* else -- A buffer is already associated with the window. */
+
+
+ /* Call the DDX routine to allocate the back buffer. */
+ status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer,
+ stuff->swapAction);
+
+ if (status == Success)
+ {
+ pDbeWindowPriv->IDs[add_index] = stuff->buffer;
+ if (!AddResource(stuff->buffer, dbeWindowPrivResType,
+ (pointer)pDbeWindowPriv))
+ {
+ pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT;
+
+ if (pDbeWindowPriv->nBufferIDs == 0) {
+ status = BadAlloc;
+ goto out_free;
+ }
+ }
+ } else {
+ /* The DDX buffer allocation routine failed for the first buffer of
+ * this window.
+ */
+ if (pDbeWindowPriv->nBufferIDs == 0) {
+ goto out_free;
+ }
+ }
+
+ /* Increment the number of buffers (XIDs) associated with this window. */
+ pDbeWindowPriv->nBufferIDs++;
+
+ /* Set swap action on all calls. */
+ pDbeWindowPriv->swapAction = stuff->swapAction;
+
+ return(status);
+
+out_free:
+ dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL);
+ free(pDbeWindowPriv);
+ return (status);
+
+} /* ProcDbeAllocateBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
+ *
+ * Description:
+ *
+ * This function is for processing a DbeDeallocateBackBufferName request.
+ * This request frees a drawable ID that was obtained by a
+ * DbeAllocateBackBufferName request.
+ *
+ * Return Values:
+ *
+ * BadBuffer - buffer to deallocate is not associated with a window
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeDeallocateBackBufferName(ClientPtr client)
+{
+ REQUEST(xDbeDeallocateBackBufferNameReq);
+ DbeWindowPrivPtr pDbeWindowPriv;
+ int rc, i;
+ pointer val;
+
+
+ REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
+
+ /* Buffer name must be valid */
+ rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
+ dbeWindowPrivResType, client,
+ DixDestroyAccess);
+ if (rc != Success)
+ return (rc == BadValue) ? dbeErrorBase + DbeBadBuffer : rc;
+
+ rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType,
+ client, DixDestroyAccess);
+ if (rc != Success)
+ return (rc == BadValue) ? dbeErrorBase + DbeBadBuffer : rc;
+
+ /* Make sure that the id is valid for the window.
+ * This is paranoid code since we already looked up the ID by type
+ * above.
+ */
+
+ for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
+ {
+ /* Loop through the ID list to find the ID. */
+ if (pDbeWindowPriv->IDs[i] == stuff->buffer)
+ {
+ break;
+ }
+ }
+
+ if (i == pDbeWindowPriv->nBufferIDs)
+ {
+ /* We did not find the ID in the ID list. */
+ client->errorValue = stuff->buffer;
+ return(dbeErrorBase + DbeBadBuffer);
+ }
+
+ FreeResource(stuff->buffer, RT_NONE);
+
+ return(Success);
+
+} /* ProcDbeDeallocateBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeSwapBuffers
+ *
+ * Description:
+ *
+ * This function is for processing a DbeSwapBuffers request.
+ * This request swaps the buffers for all windows listed, applying the
+ * appropriate swap action for each window.
+ *
+ * Return Values:
+ *
+ * BadAlloc - local allocation failed; this return value is not defined
+ * by the protocol
+ * BadMatch - a window in request is not double-buffered; a window in
+ * request is listed more than once
+ * BadValue - invalid swap action is specified; no swap action is
+ * specified
+ * BadWindow - a window in request is not valid
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeSwapBuffers(ClientPtr client)
+{
+ REQUEST(xDbeSwapBuffersReq);
+ WindowPtr pWin;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeSwapInfoPtr swapInfo;
+ xDbeSwapInfo *dbeSwapInfo;
+ int error;
+ register int i, j;
+ int nStuff;
+
+
+ REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
+ nStuff = stuff->n; /* use local variable for performance. */
+
+ if (nStuff == 0)
+ {
+ return(Success);
+ }
+
+ if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
+ return BadAlloc;
+
+ /* Get to the swap info appended to the end of the request. */
+ dbeSwapInfo = (xDbeSwapInfo *)&stuff[1];
+
+ /* Allocate array to record swap information. */
+ swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec));
+ if (swapInfo == NULL)
+ {
+ return(BadAlloc);
+ }
+
+
+ for (i = 0; i < nStuff; i++)
+ {
+ /* Check all windows to swap. */
+
+ /* Each window must be a valid window - BadWindow. */
+ error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client,
+ DixWriteAccess);
+ if (error != Success) {
+ free(swapInfo);
+ return error;
+ }
+
+ /* Each window must be double-buffered - BadMatch. */
+ if (DBE_WINDOW_PRIV(pWin) == NULL)
+ {
+ free(swapInfo);
+ return(BadMatch);
+ }
+
+ /* Each window must only be specified once - BadMatch. */
+ for (j = i + 1; j < nStuff; j++)
+ {
+ if (dbeSwapInfo[i].window == dbeSwapInfo[j].window)
+ {
+ free(swapInfo);
+ return(BadMatch);
+ }
+ }
+
+ /* Each swap action must be valid - BadValue. */
+ if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) &&
+ (dbeSwapInfo[i].swapAction != XdbeBackground) &&
+ (dbeSwapInfo[i].swapAction != XdbeUntouched ) &&
+ (dbeSwapInfo[i].swapAction != XdbeCopied ))
+ {
+ free(swapInfo);
+ return(BadValue);
+ }
+
+ /* Everything checks out OK. Fill in the swap info array. */
+ swapInfo[i].pWindow = pWin;
+ swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;
+
+ } /* for (i = 0; i < nStuff; i++) */
+
+
+ /* Call the DDX routine to perform the swap(s). The DDX routine should
+ * scan the swap list (swap info), swap any buffers that it knows how to
+ * handle, delete them from the list, and update nStuff to indicate how
+ * many windows it did not handle.
+ *
+ * This scheme allows a range of sophistication in the DDX SwapBuffers()
+ * implementation. Naive implementations could just swap the first buffer
+ * in the list, move the last buffer to the front, decrement nStuff, and
+ * return. The next level of sophistication could be to scan the whole
+ * list for windows on the same screen. Up another level, the DDX routine
+ * could deal with cross-screen synchronization.
+ */
+
+ while (nStuff > 0)
+ {
+ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
+ error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo);
+ if (error != Success)
+ {
+ free(swapInfo);
+ return(error);
+ }
+ }
+
+ free(swapInfo);
+ return(Success);
+
+} /* ProcDbeSwapBuffers() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeBeginIdiom
+ *
+ * Description:
+ *
+ * This function is for processing a DbeBeginIdiom request.
+ * This request informs the server that a complex swap will immediately
+ * follow this request.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeBeginIdiom(ClientPtr client)
+{
+ /* REQUEST(xDbeBeginIdiomReq); */
+ DbeScreenPrivPtr pDbeScreenPriv;
+ register int i;
+
+
+ REQUEST_SIZE_MATCH(xDbeBeginIdiomReq);
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]);
+
+ /* Call the DDX begin idiom procedure if there is one. */
+ if (pDbeScreenPriv->BeginIdiom)
+ {
+ (*pDbeScreenPriv->BeginIdiom)(client);
+ }
+ }
+
+ return(Success);
+
+} /* ProcDbeBeginIdiom() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeGetVisualInfo
+ *
+ * Description:
+ *
+ * This function is for processing a ProcDbeGetVisualInfo request.
+ * This request returns information about which visuals support
+ * double buffering.
+ *
+ * Return Values:
+ *
+ * BadDrawable - value in screen specifiers is not a valid drawable
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeGetVisualInfo(ClientPtr client)
+{
+ REQUEST(xDbeGetVisualInfoReq);
+ DbeScreenPrivPtr pDbeScreenPriv;
+ xDbeGetVisualInfoReply rep;
+ Drawable *drawables;
+ DrawablePtr *pDrawables = NULL;
+ register int i, j, n, rc;
+ register int count; /* number of visual infos in reply */
+ register int length; /* length of reply */
+ ScreenPtr pScreen;
+ XdbeScreenVisualInfo *pScrVisInfo;
+
+
+ REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
+
+ if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
+ return BadAlloc;
+ /* Make sure any specified drawables are valid. */
+ if (stuff->n != 0)
+ {
+ if (!(pDrawables = (DrawablePtr *)malloc(stuff->n *
+ sizeof(DrawablePtr))))
+ {
+ return(BadAlloc);
+ }
+
+ drawables = (Drawable *)&stuff[1];
+
+ for (i = 0; i < stuff->n; i++)
+ {
+ rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0,
+ DixGetAttrAccess);
+ if (rc != Success) {
+ free(pDrawables);
+ return rc;
+ }
+ }
+ }
+
+ count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
+ if (!(pScrVisInfo = (XdbeScreenVisualInfo *)malloc(count *
+ sizeof(XdbeScreenVisualInfo))))
+ {
+ if (pDrawables)
+ {
+ free(pDrawables);
+ }
+
+ return(BadAlloc);
+ }
+
+ length = 0;
+
+ for (i = 0; i < count; i++)
+ {
+ pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
+ pDrawables[i]->pScreen;
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
+ if ((rc != Success) ||
+ !(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
+ {
+ /* We failed to alloc pScrVisInfo[i].visinfo. */
+
+ /* Free visinfos that we allocated for previous screen infos.*/
+ for (j = 0; j < i; j++)
+ {
+ free(pScrVisInfo[j].visinfo);
+ }
+
+ /* Free pDrawables if we needed to allocate it above. */
+ if (pDrawables)
+ {
+ free(pDrawables);
+ }
+
+ return (rc == Success) ? BadAlloc : rc;
+ }
+
+ /* Account for n, number of xDbeVisInfo items in list. */
+ length += sizeof(CARD32);
+
+ /* Account for n xDbeVisInfo items */
+ length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = bytes_to_int32(length);
+ rep.m = count;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.m, n);
+ }
+
+ /* Send off reply. */
+ WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep);
+
+ for (i = 0; i < count; i++)
+ {
+ CARD32 data32;
+
+ /* For each screen in the reply, send off the visual info */
+
+ /* Send off number of visuals. */
+ data32 = (CARD32)pScrVisInfo[i].count;
+
+ if (client->swapped)
+ {
+ swapl(&data32, n);
+ }
+
+ WriteToClient(client, sizeof(CARD32), (char *)&data32);
+
+ /* Now send off visual info items. */
+ for (j = 0; j < pScrVisInfo[i].count; j++)
+ {
+ xDbeVisInfo visInfo;
+
+ /* Copy the data in the client data structure to a protocol
+ * data structure. We will send data to the client from the
+ * protocol data structure.
+ */
+
+ visInfo.visualID = (CARD32)pScrVisInfo[i].visinfo[j].visual;
+ visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth;
+ visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;
+
+ if (client->swapped)
+ {
+ swapl(&visInfo.visualID, n);
+
+ /* We do not need to swap depth and perfLevel since they are
+ * already 1 byte quantities.
+ */
+ }
+
+ /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
+ WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID);
+ }
+ }
+
+ /* Clean up memory. */
+ for (i = 0; i < count; i++)
+ {
+ free(pScrVisInfo[i].visinfo);
+ }
+ free(pScrVisInfo);
+
+ if (pDrawables)
+ {
+ free(pDrawables);
+ }
+
+ return Success;
+
+} /* ProcDbeGetVisualInfo() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
+ *
+ * Description:
+ *
+ * This function is for processing a ProcDbeGetbackBufferAttributes
+ * request. This request returns information about a back buffer.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeGetBackBufferAttributes(ClientPtr client)
+{
+ REQUEST(xDbeGetBackBufferAttributesReq);
+ xDbeGetBackBufferAttributesReply rep;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ int rc, n;
+
+
+ REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
+
+ rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer,
+ dbeWindowPrivResType, client,
+ DixGetAttrAccess);
+ if (rc == Success)
+ {
+ rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
+ }
+ else
+ {
+ rep.attributes = None;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.attributes, n);
+ }
+
+ WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
+ (char *)&rep);
+ return Success;
+
+} /* ProcDbeGetbackBufferAttributes() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: ProcDbeDispatch
+ *
+ * Description:
+ *
+ * This function dispatches DBE requests.
+ *
+ *****************************************************************************/
+
+static int
+ProcDbeDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+
+ switch (stuff->data)
+ {
+ case X_DbeGetVersion:
+ return(ProcDbeGetVersion(client));
+
+ case X_DbeAllocateBackBufferName:
+ return(ProcDbeAllocateBackBufferName(client));
+
+ case X_DbeDeallocateBackBufferName:
+ return(ProcDbeDeallocateBackBufferName(client));
+
+ case X_DbeSwapBuffers:
+ return(ProcDbeSwapBuffers(client));
+
+ case X_DbeBeginIdiom:
+ return(ProcDbeBeginIdiom(client));
+
+ case X_DbeEndIdiom:
+ return(Success);
+
+ case X_DbeGetVisualInfo:
+ return(ProcDbeGetVisualInfo(client));
+
+ case X_DbeGetBackBufferAttributes:
+ return(ProcDbeGetBackBufferAttributes(client));
+
+ default:
+ return(BadRequest);
+ }
+
+} /* ProcDbeDispatch() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeGetVersion
+ *
+ * Description:
+ *
+ * This function is for processing a DbeGetVersion request on a swapped
+ * server. This request returns the major and minor version numbers of
+ * this extension.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeGetVersion(ClientPtr client)
+{
+ REQUEST(xDbeGetVersionReq);
+ register int n;
+
+
+ swaps(&stuff->length, n);
+ return(ProcDbeGetVersion(client));
+
+} /* SProcDbeGetVersion() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeAllocateBackBufferName
+ *
+ * Description:
+ *
+ * This function is for processing a DbeAllocateBackBufferName request on
+ * a swapped server. This request allocates a drawable ID used to refer
+ * to the back buffer of a window.
+ *
+ * Return Values:
+ *
+ * BadAlloc - server can not allocate resources
+ * BadIDChoice - id is out of range for client; id is already in use
+ * BadMatch - window is not an InputOutput window;
+ * visual of window is not on list returned by
+ * DBEGetVisualInfo;
+ * BadValue - invalid swap action is specified
+ * BadWindow - window is not a valid window
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeAllocateBackBufferName(ClientPtr client)
+{
+ REQUEST(xDbeAllocateBackBufferNameReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
+
+ swapl(&stuff->window, n);
+ swapl(&stuff->buffer, n);
+ /* stuff->swapAction is a byte. We do not need to swap this field. */
+
+ return(ProcDbeAllocateBackBufferName(client));
+
+} /* SProcDbeAllocateBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
+ *
+ * Description:
+ *
+ * This function is for processing a DbeDeallocateBackBufferName request
+ * on a swapped server. This request frees a drawable ID that was
+ * obtained by a DbeAllocateBackBufferName request.
+ *
+ * Return Values:
+ *
+ * BadBuffer - buffer to deallocate is not associated with a window
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeDeallocateBackBufferName(ClientPtr client)
+{
+ REQUEST (xDbeDeallocateBackBufferNameReq);
+ register int n;
+
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
+
+ swapl(&stuff->buffer, n);
+
+ return(ProcDbeDeallocateBackBufferName(client));
+
+} /* SProcDbeDeallocateBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeSwapBuffers
+ *
+ * Description:
+ *
+ * This function is for processing a DbeSwapBuffers request on a swapped
+ * server. This request swaps the buffers for all windows listed,
+ * applying the appropriate swap action for each window.
+ *
+ * Return Values:
+ *
+ * BadMatch - a window in request is not double-buffered; a window in
+ * request is listed more than once; all windows in request do
+ * not have the same root
+ * BadValue - invalid swap action is specified
+ * BadWindow - a window in request is not valid
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeSwapBuffers(ClientPtr client)
+{
+ REQUEST(xDbeSwapBuffersReq);
+ register int i, n;
+ xDbeSwapInfo *pSwapInfo;
+
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
+
+ swapl(&stuff->n, n);
+
+ if (stuff->n != 0)
+ {
+ pSwapInfo = (xDbeSwapInfo *)stuff+1;
+
+ /* The swap info following the fix part of this request is a window(32)
+ * followed by a 1 byte swap action and then 3 pad bytes. We only need
+ * to swap the window information.
+ */
+ for (i = 0; i < stuff->n; i++)
+ {
+ swapl(&pSwapInfo->window, n);
+ }
+ }
+
+ return(ProcDbeSwapBuffers(client));
+
+} /* SProcDbeSwapBuffers() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeBeginIdiom
+ *
+ * Description:
+ *
+ * This function is for processing a DbeBeginIdiom request on a swapped
+ * server. This request informs the server that a complex swap will
+ * immediately follow this request.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeBeginIdiom(ClientPtr client)
+{
+ REQUEST(xDbeBeginIdiomReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ return(ProcDbeBeginIdiom(client));
+
+} /* SProcDbeBeginIdiom() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeGetVisualInfo
+ *
+ * Description:
+ *
+ * This function is for processing a ProcDbeGetVisualInfo request on a
+ * swapped server. This request returns information about which visuals
+ * support double buffering.
+ *
+ * Return Values:
+ *
+ * BadDrawable - value in screen specifiers is not a valid drawable
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeGetVisualInfo(ClientPtr client)
+{
+ REQUEST(xDbeGetVisualInfoReq);
+ register int n;
+
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
+
+ swapl(&stuff->n, n);
+ SwapRestL(stuff);
+
+ return(ProcDbeGetVisualInfo(client));
+
+} /* SProcDbeGetVisualInfo() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
+ *
+ * Description:
+ *
+ * This function is for processing a ProcDbeGetbackBufferAttributes
+ * request on a swapped server. This request returns information about a
+ * back buffer.
+ *
+ * Return Values:
+ *
+ * Success
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeGetBackBufferAttributes(ClientPtr client)
+{
+ REQUEST (xDbeGetBackBufferAttributesReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
+
+ swapl(&stuff->buffer, n);
+
+ return(ProcDbeGetBackBufferAttributes(client));
+
+} /* SProcDbeGetBackBufferAttributes() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: SProcDbeDispatch
+ *
+ * Description:
+ *
+ * This function dispatches DBE requests on a swapped server.
+ *
+ *****************************************************************************/
+
+static int
+SProcDbeDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+
+ switch (stuff->data)
+ {
+ case X_DbeGetVersion:
+ return(SProcDbeGetVersion(client));
+
+ case X_DbeAllocateBackBufferName:
+ return(SProcDbeAllocateBackBufferName(client));
+
+ case X_DbeDeallocateBackBufferName:
+ return(SProcDbeDeallocateBackBufferName(client));
+
+ case X_DbeSwapBuffers:
+ return(SProcDbeSwapBuffers(client));
+
+ case X_DbeBeginIdiom:
+ return(SProcDbeBeginIdiom(client));
+
+ case X_DbeEndIdiom:
+ return(Success);
+
+ case X_DbeGetVisualInfo:
+ return(SProcDbeGetVisualInfo(client));
+
+ case X_DbeGetBackBufferAttributes:
+ return(SProcDbeGetBackBufferAttributes(client));
+
+ default:
+ return (BadRequest);
+ }
+
+} /* SProcDbeDispatch() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeSetupBackgroundPainter
+ *
+ * Description:
+ *
+ * This function sets up pGC to clear pixmaps.
+ *
+ * Return Values:
+ *
+ * TRUE - setup was successful
+ * FALSE - the window's background state is NONE
+ *
+ *****************************************************************************/
+
+static Bool
+DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
+{
+ ChangeGCVal gcvalues[4];
+ int ts_x_origin, ts_y_origin;
+ PixUnion background;
+ int backgroundState;
+ Mask gcmask;
+
+
+ /* First take care of any ParentRelative stuff by altering the
+ * tile/stipple origin to match the coordinates of the upper-left
+ * corner of the first ancestor without a ParentRelative background.
+ * This coordinate is, of course, negative.
+ */
+ ts_x_origin = ts_y_origin = 0;
+ while (pWin->backgroundState == ParentRelative)
+ {
+ ts_x_origin -= pWin->origin.x;
+ ts_y_origin -= pWin->origin.y;
+
+ pWin = pWin->parent;
+ }
+ backgroundState = pWin->backgroundState;
+ background = pWin->background;
+
+ switch (backgroundState)
+ {
+ case BackgroundPixel:
+ gcvalues[0].val = background.pixel;
+ gcvalues[1].val = FillSolid;
+ gcmask = GCForeground|GCFillStyle;
+ break;
+
+ case BackgroundPixmap:
+ gcvalues[0].val = FillTiled;
+ gcvalues[1].ptr = background.pixmap;
+ gcvalues[2].val = ts_x_origin;
+ gcvalues[3].val = ts_y_origin;
+ gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
+ break;
+
+ default:
+ /* pWin->backgroundState == None */
+ return(FALSE);
+ }
+
+ return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0;
+} /* DbeSetupBackgroundPainter() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeDrawableDelete
+ *
+ * Description:
+ *
+ * This is the resource delete function for dbeDrawableResType.
+ * It is registered when the drawable resource type is created in
+ * DbeExtensionInit().
+ *
+ * To make resource deletion simple, we do not do anything in this function
+ * and leave all resource deleteion to DbeWindowPrivDelete(), which will
+ * eventually be called or already has been called. Deletion functions are
+ * not guaranteed to be called in any particular order.
+ *
+ *****************************************************************************/
+static int
+DbeDrawableDelete(pointer pDrawable, XID id)
+{
+ return(Success);
+
+} /* DbeDrawableDelete() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeWindowPrivDelete
+ *
+ * Description:
+ *
+ * This is the resource delete function for dbeWindowPrivResType.
+ * It is registered when the drawable resource type is created in
+ * DbeExtensionInit().
+ *
+ *****************************************************************************/
+static int
+DbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv;
+ int i;
+
+
+ /*
+ **************************************************************************
+ ** Remove the buffer ID from the ID array.
+ **************************************************************************
+ */
+
+ /* Find the ID in the ID array. */
+ i = 0;
+ while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id))
+ {
+ i++;
+ }
+
+ if (i == pDbeWindowPriv->nBufferIDs)
+ {
+ /* We did not find the ID in the array. We should never get here. */
+ return(BadValue);
+ }
+
+ /* Remove the ID from the array. */
+
+ if (i < (pDbeWindowPriv->nBufferIDs - 1))
+ {
+ /* Compress the buffer ID array, overwriting the ID in the process. */
+ memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1],
+ (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
+ }
+ else
+ {
+ /* We are removing the last ID in the array, in which case, the
+ * assignement below is all that we need to do.
+ */
+ }
+ pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
+
+ pDbeWindowPriv->nBufferIDs--;
+
+ /* If an extended array was allocated, then check to see if the remaining
+ * buffer IDs will fit in the static array.
+ */
+
+ if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) &&
+ (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS))
+ {
+ /* Copy the IDs back into the static array. */
+ memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
+ DBE_INIT_MAX_IDS * sizeof(XID));
+
+ /* Free the extended array; use the static array. */
+ free(pDbeWindowPriv->IDs);
+ pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
+ pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
+ }
+
+
+ /*
+ **************************************************************************
+ ** Perform DDX level tasks.
+ **************************************************************************
+ */
+
+ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV(
+ (DbeWindowPrivPtr)pDbeWindowPriv);
+ (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id);
+
+
+ /*
+ **************************************************************************
+ ** Perform miscellaneous tasks if this is the last buffer associated
+ ** with the window.
+ **************************************************************************
+ */
+
+ if (pDbeWindowPriv->nBufferIDs == 0)
+ {
+ /* Reset the DBE window priv pointer. */
+ dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey,
+ NULL);
+
+ /* We are done with the window priv. */
+ dixFreePrivates(pDbeWindowPriv->devPrivates);
+ free(pDbeWindowPriv);
+ }
+
+ return(Success);
+
+} /* DbeWindowPrivDelete() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeResetProc
+ *
+ * Description:
+ *
+ * This routine is called at the end of every server generation.
+ * It deallocates any memory reserved for the extension and performs any
+ * other tasks related to shutting down the extension.
+ *
+ *****************************************************************************/
+static void
+DbeResetProc(ExtensionEntry *extEntry)
+{
+ int i;
+ ScreenPtr pScreen;
+ DbeScreenPrivPtr pDbeScreenPriv;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ if (pDbeScreenPriv)
+ {
+ /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/
+ pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
+
+ if (pDbeScreenPriv->ResetProc)
+ (*pDbeScreenPriv->ResetProc)(pScreen);
+
+ dixFreePrivates(pDbeScreenPriv->devPrivates);
+ free(pDbeScreenPriv);
+ }
+ }
+} /* DbeResetProc() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeDestroyWindow
+ *
+ * Description:
+ *
+ * This is the wrapper for pScreen->DestroyWindow.
+ * This function frees buffer resources for a window before it is
+ * destroyed.
+ *
+ *****************************************************************************/
+
+static Bool
+DbeDestroyWindow(WindowPtr pWin)
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ ScreenPtr pScreen;
+ Bool ret;
+
+
+ /*
+ **************************************************************************
+ ** 1. Unwrap the member routine.
+ **************************************************************************
+ */
+
+ pScreen = pWin->drawable.pScreen;
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+ pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
+
+ /*
+ **************************************************************************
+ ** 2. Do any work necessary before the member routine is called.
+ **
+ ** Call the window priv delete function for all buffer IDs associated
+ ** with this window.
+ **************************************************************************
+ */
+
+ if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
+ {
+ while (pDbeWindowPriv)
+ {
+ /* *DbeWinPrivDelete() will free the window private and set it to
+ * NULL if there are no more buffer IDs associated with this
+ * window.
+ */
+ FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
+ pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
+ }
+ }
+
+ /*
+ **************************************************************************
+ ** 3. Call the member routine, saving its result if necessary.
+ **************************************************************************
+ */
+
+ ret = (*pScreen->DestroyWindow)(pWin);
+
+ /*
+ **************************************************************************
+ ** 4. Rewrap the member routine, restoring the wrapper value first in case
+ ** the wrapper (or something that it wrapped) change this value.
+ **************************************************************************
+ */
+
+ pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DbeDestroyWindow;
+
+ /*
+ **************************************************************************
+ ** 5. Do any work necessary after the member routine has been called.
+ **
+ ** In this case we do not need to do anything.
+ **************************************************************************
+ */
+
+ return(ret);
+
+} /* DbeDestroyWindow() */
+
+
+/******************************************************************************
+ *
+ * DBE DIX Procedure: DbeExtensionInit
+ *
+ * Description:
+ *
+ * Called from InitExtensions in main()
+ *
+ *****************************************************************************/
+
+void
+DbeExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ register int i, j;
+ ScreenPtr pScreen = NULL;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ int nStubbedScreens = 0;
+ Bool ddxInitSuccess;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) return;
+#endif
+
+ /* Create the resource types. */
+ dbeDrawableResType =
+ CreateNewResourceType(DbeDrawableDelete, "dbeDrawable");
+ if (!dbeDrawableResType)
+ return;
+ dbeDrawableResType |= RC_DRAWABLE;
+
+ dbeWindowPrivResType =
+ CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow");
+ if (!dbeWindowPrivResType)
+ return;
+
+ if (!dixRegisterPrivateOffset(dbeDrawableResType,
+ offsetof(PixmapRec, devPrivates)))
+ return;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ /* For each screen, set up DBE screen privates and init DIX and DDX
+ * interface.
+ */
+
+ pScreen = screenInfo.screens[i];
+
+ if (!(pDbeScreenPriv =
+ (DbeScreenPrivPtr)calloc(1, sizeof(DbeScreenPrivRec))))
+ {
+ /* If we can not alloc a window or screen private,
+ * then free any privates that we already alloc'ed and return
+ */
+
+ for (j = 0; j < i; j++)
+ {
+ free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates,
+ dbeScreenPrivKey));
+ dixSetPrivate(&screenInfo.screens[j]->devPrivates,
+ dbeScreenPrivKey, NULL);
+ }
+ return;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv);
+
+ /* Copy the resource types */
+ pDbeScreenPriv->dbeDrawableResType = dbeDrawableResType;
+ pDbeScreenPriv->dbeWindowPrivResType = dbeWindowPrivResType;
+
+ /* Copy the private indices */
+ pDbeScreenPriv->dbeScreenPrivKey = dbeScreenPrivKey;
+ pDbeScreenPriv->dbeWindowPrivKey = dbeWindowPrivKey;
+
+ {
+ /* We don't have DDX support for DBE anymore */
+
+#ifndef DISABLE_MI_DBE_BY_DEFAULT
+ /* Setup DIX. */
+ pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
+
+ /* Setup DDX. */
+ ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
+
+ /* DDX DBE initialization may have the side affect of
+ * reallocating pDbeScreenPriv, so we need to update it.
+ */
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ if (ddxInitSuccess)
+ {
+ /* Wrap DestroyWindow. The DDX initialization function
+ * already wrapped PositionWindow for us.
+ */
+
+ pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DbeDestroyWindow;
+ }
+ else
+ {
+ /* DDX initialization failed. Stub the screen. */
+ DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
+ }
+#else
+ DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
+#endif
+
+ }
+
+ } /* for (i = 0; i < screenInfo.numScreens; i++) */
+
+
+ if (nStubbedScreens == screenInfo.numScreens)
+ {
+ /* All screens stubbed. Clean up and return. */
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates,
+ dbeScreenPrivKey));
+ dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL);
+ }
+ return;
+ }
+
+
+ /* Now add the extension. */
+ extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
+ DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
+ DbeResetProc, StandardMinorOpcode);
+
+ dbeErrorBase = extEntry->errorBase;
+
+} /* DbeExtensionInit() */
+
diff --git a/xorg-server/dbe/midbe.c b/xorg-server/dbe/midbe.c index 4426c9d85..cba386c0b 100644 --- a/xorg-server/dbe/midbe.c +++ b/xorg-server/dbe/midbe.c @@ -1,809 +1,809 @@ -/****************************************************************************** - * - * Copyright (c) 1994, 1995 Hewlett-Packard Company - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of the Hewlett-Packard - * Company shall not be used in advertising or otherwise to promote the - * sale, use or other dealings in this Software without prior written - * authorization from the Hewlett-Packard Company. - * - * Machine-independent DBE code - * - *****************************************************************************/ - - -/* INCLUDES */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "os.h" -#include "windowstr.h" -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "dixstruct.h" -#include "resource.h" -#include "opaque.h" -#include "dbestruct.h" -#include "midbestr.h" -#include "regionstr.h" -#include "gcstruct.h" -#include "inputstr.h" -#include "midbe.h" -#include "xace.h" - -#include <stdio.h> - -static int miDbeWindowPrivPrivKeyIndex; -static DevPrivateKey miDbeWindowPrivPrivKey = &miDbeWindowPrivPrivKeyIndex; -static RESTYPE dbeDrawableResType; -static RESTYPE dbeWindowPrivResType; -static int dbeScreenPrivKeyIndex; -static DevPrivateKey dbeScreenPrivKey = &dbeScreenPrivKeyIndex; -static int dbeWindowPrivKeyIndex; -static DevPrivateKey dbeWindowPrivKey = &dbeWindowPrivKeyIndex; - - -/****************************************************************************** - * - * DBE MI Procedure: miDbeGetVisualInfo - * - * Description: - * - * This is the MI function for the DbeGetVisualInfo request. This function - * is called through pDbeScreenPriv->GetVisualInfo. This function is also - * called for the DbeAllocateBackBufferName request at the extension level; - * it is called by ProcDbeAllocateBackBufferName() in dbe.c. - * - * If memory allocation fails or we can not get the visual info, this - * function returns FALSE. Otherwise, it returns TRUE for success. - * - *****************************************************************************/ - -static Bool -miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo *pScrVisInfo) -{ - register int i, j, k; - register int count; - DepthPtr pDepth; - XdbeVisualInfo *visInfo; - - - /* Determine number of visuals for this screen. */ - for (i = 0, count = 0; i < pScreen->numDepths; i++) - { - count += pScreen->allowedDepths[i].numVids; - } - - /* Allocate an array of XdbeVisualInfo items. */ - if (!(visInfo = (XdbeVisualInfo *)xalloc(count * sizeof(XdbeVisualInfo)))) - { - return(FALSE); /* memory alloc failure */ - } - - for (i = 0, k = 0; i < pScreen->numDepths; i++) - { - /* For each depth of this screen, get visual information. */ - - pDepth = &pScreen->allowedDepths[i]; - - for (j = 0; j < pDepth->numVids; j++) - { - /* For each visual for this depth of this screen, get visual ID - * and visual depth. Since this is MI code, we will always return - * the same performance level for all visuals (0). A higher - * performance level value indicates higher performance. - */ - visInfo[k].visual = pDepth->vids[j]; - visInfo[k].depth = pDepth->depth; - visInfo[k].perflevel = 0; - k++; - } - } - - /* Record the number of visuals and point visual_depth to - * the array of visual info. - */ - pScrVisInfo->count = count; - pScrVisInfo->visinfo = visInfo; - - return(TRUE); /* success */ - -} /* miDbeGetVisualInfo() */ - - -/****************************************************************************** - * - * DBE MI Procedure: miAllocBackBufferName - * - * Description: - * - * This is the MI function for the DbeAllocateBackBufferName request. - * - *****************************************************************************/ - -static int -miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction) -{ - ScreenPtr pScreen; - DbeWindowPrivPtr pDbeWindowPriv; - MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; - DbeScreenPrivPtr pDbeScreenPriv; - GCPtr pGC; - xRectangle clearRect; - int rc; - - - pScreen = pWin->drawable.pScreen; - pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); - - if (pDbeWindowPriv->nBufferIDs == 0) - { - /* There is no buffer associated with the window. - * We have to create the window priv priv. Remember, the window - * priv was created at the DIX level, so all we need to do is - * create the priv priv and attach it to the priv. - */ - - pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); - - /* Setup the window priv priv. */ - pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); - pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv; - - /* Get a front pixmap. */ - if (!(pDbeWindowPrivPriv->pFrontBuffer = - (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width, - pDbeWindowPriv->height, - pWin->drawable.depth, 0))) - { - return(BadAlloc); - } - - /* Get a back pixmap. */ - if (!(pDbeWindowPrivPriv->pBackBuffer = - (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width, - pDbeWindowPriv->height, - pWin->drawable.depth, 0))) - { - (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); - return(BadAlloc); - } - - /* Security creation/labeling check. */ - rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId, - dbeDrawableResType, pDbeWindowPrivPriv->pBackBuffer, - RT_WINDOW, pWin, DixCreateAccess); - - /* Make the back pixmap a DBE drawable resource. */ - if (rc != Success || !AddResource(bufId, dbeDrawableResType, - pDbeWindowPrivPriv->pBackBuffer)) - { - /* free the buffer and the drawable resource */ - FreeResource(bufId, RT_NONE); - return (rc == Success) ? BadAlloc : rc; - } - - - /* Attach the priv priv to the priv. */ - dixSetPrivate(&pDbeWindowPriv->devPrivates, miDbeWindowPrivPrivKey, - pDbeWindowPrivPriv); - - - /* Clear the back buffer. */ - pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); - if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) - { - ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC); - clearRect.x = clearRect.y = 0; - clearRect.width = pDbeWindowPrivPriv->pBackBuffer->drawable.width; - clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height; - (*pGC->ops->PolyFillRect)( - (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC, 1, - &clearRect); - } - FreeScratchGC(pGC); - - } /* if no buffer associated with the window */ - - else - { - /* A buffer is already associated with the window. - * Place the new buffer ID information at the head of the ID list. - */ - - /* Associate the new ID with an existing pixmap. */ - pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); - if (!AddResource(bufId, dbeDrawableResType, - (pointer)pDbeWindowPrivPriv->pBackBuffer)) - { - return(BadAlloc); - } - - } - - return(Success); - -} /* miDbeAllocBackBufferName() */ - - -/****************************************************************************** - * - * DBE MI Procedure: miDbeAliasBuffers - * - * Description: - * - * This function associates all XIDs of a buffer with the back pixmap - * stored in the window priv. - * - *****************************************************************************/ - -static void -miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv) -{ - int i; - MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv = - MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); - - for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) - { - ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType, - (pointer)pDbeWindowPrivPriv->pBackBuffer); - } - -} /* miDbeAliasBuffers() */ - - -/****************************************************************************** - * - * DBE MI Procedure: miDbeSwapBuffers - * - * Description: - * - * This is the MI function for the DbeSwapBuffers request. - * - *****************************************************************************/ - -static int -miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo) -{ - DbeScreenPrivPtr pDbeScreenPriv; - GCPtr pGC; - WindowPtr pWin; - MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; - PixmapPtr pTmpBuffer; - xRectangle clearRect; - - - pWin = swapInfo[0].pWindow; - pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); - pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin); - pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); - - /* - ********************************************************************** - ** Setup before swap. - ********************************************************************** - */ - - switch(swapInfo[0].swapAction) - { - case XdbeUndefined: - break; - - case XdbeBackground: - break; - - case XdbeUntouched: - ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, pGC); - (*pGC->ops->CopyArea)((DrawablePtr)pWin, - (DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, - pGC, 0, 0, pWin->drawable.width, - pWin->drawable.height, 0, 0); - break; - - case XdbeCopied: - break; - - } - - /* - ********************************************************************** - ** Swap. - ********************************************************************** - */ - - ValidateGC((DrawablePtr)pWin, pGC); - (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, - (DrawablePtr)pWin, pGC, 0, 0, - pWin->drawable.width, pWin->drawable.height, - 0, 0); - - /* - ********************************************************************** - ** Tasks after swap. - ********************************************************************** - */ - - switch(swapInfo[0].swapAction) - { - case XdbeUndefined: - break; - - case XdbeBackground: - if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) - { - ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC); - clearRect.x = 0; - clearRect.y = 0; - clearRect.width = - pDbeWindowPrivPriv->pBackBuffer->drawable.width; - clearRect.height = - pDbeWindowPrivPriv->pBackBuffer->drawable.height; - (*pGC->ops->PolyFillRect)( - (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, - pGC, 1, &clearRect); - } - break; - - case XdbeUntouched: - /* Swap pixmap pointers. */ - pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer; - pDbeWindowPrivPriv->pBackBuffer = - pDbeWindowPrivPriv->pFrontBuffer; - pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer; - - miDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv); - - break; - - case XdbeCopied: - break; - - } - - /* Remove the swapped window from the swap information array and decrement - * pNumWindows to indicate to the DIX level how many windows were actually - * swapped. - */ - - if (*pNumWindows > 1) - { - /* We were told to swap more than one window, but we only swapped the - * first one. Remove the first window in the list by moving the last - * window to the beginning. - */ - swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow; - swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction; - - /* Clear the last window information just to be safe. */ - swapInfo[*pNumWindows - 1].pWindow = (WindowPtr)NULL; - swapInfo[*pNumWindows - 1].swapAction = 0; - } - else - { - /* Clear the window information just to be safe. */ - swapInfo[0].pWindow = (WindowPtr)NULL; - swapInfo[0].swapAction = 0; - } - - (*pNumWindows)--; - - FreeScratchGC(pGC); - - return(Success); - -} /* miSwapBuffers() */ - - -/****************************************************************************** - * - * DBE MI Procedure: miDbeWinPrivDelete - * - * Description: - * - * This is the MI function for deleting the dbeWindowPrivResType resource. - * This function is invoked indirectly by calling FreeResource() to free - * the resources associated with a DBE buffer ID. There are 5 ways that - * miDbeWinPrivDelete() can be called by FreeResource(). They are: - * - * - A DBE window is destroyed, in which case the DbeDestroyWindow() - * wrapper is invoked. The wrapper calls FreeResource() for all DBE - * buffer IDs. - * - * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources - * after a buffer allocation failure. - * - * - The PositionWindow wrapper, miDbePositionWindow(), calls - * FreeResource() when it fails to create buffers of the new size. - * FreeResource() is called for all DBE buffer IDs. - * - * - FreeClientResources() calls FreeResource() when a client dies or the - * the server resets. - * - * When FreeResource() is called for a DBE buffer ID, the delete function - * for the only other type of DBE resource, dbeDrawableResType, is also - * invoked. This delete function (DbeDrawableDelete) is a NOOP to make - * resource deletion easier. It is not guaranteed which delete function is - * called first. Hence, we will let miDbeWinPrivDelete() free all DBE - * resources. - * - * This function deletes/frees the following stuff associated with - * the window private: - * - * - the ID node in the ID list representing the passed in ID. - * - * In addition, pDbeWindowPriv->nBufferIDs is decremented. - * - * If this function is called for the last/only buffer ID for a window, - * these are additionally deleted/freed: - * - * - the front and back pixmaps - * - the window priv itself - * - *****************************************************************************/ - -static void -miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId) -{ - MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; - - - if (pDbeWindowPriv->nBufferIDs != 0) - { - /* We still have at least one more buffer ID associated with this - * window. - */ - return; - } - - - /* We have no more buffer IDs associated with this window. We need to - * free some stuff. - */ - - pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); - - /* Destroy the front and back pixmaps. */ - if (pDbeWindowPrivPriv->pFrontBuffer) - { - (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)( - pDbeWindowPrivPriv->pFrontBuffer); - } - if (pDbeWindowPrivPriv->pBackBuffer) - { - (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)( - pDbeWindowPrivPriv->pBackBuffer); - } - -} /* miDbeWinPrivDelete() */ - - -/****************************************************************************** - * - * DBE MI Procedure: miDbePositionWindow - * - * Description: - * - * This function was cloned from miMbxPositionWindow() in mimultibuf.c. - * This function resizes the buffer when the window is resized. - * - *****************************************************************************/ - -static Bool -miDbePositionWindow(WindowPtr pWin, int x, int y) -{ - ScreenPtr pScreen; - DbeScreenPrivPtr pDbeScreenPriv; - DbeWindowPrivPtr pDbeWindowPriv; - int width, height; - int dx, dy, dw, dh; - int sourcex, sourcey; - int destx, desty; - int savewidth, saveheight; - PixmapPtr pFrontBuffer; - PixmapPtr pBackBuffer; - Bool clear; - GCPtr pGC; - xRectangle clearRect; - Bool ret; - - - /* - ************************************************************************** - ** 1. Unwrap the member routine. - ************************************************************************** - */ - - pScreen = pWin->drawable.pScreen; - pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); - pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; - - /* - ************************************************************************** - ** 2. Do any work necessary before the member routine is called. - ** - ** In this case we do not need to do anything. - ************************************************************************** - */ - - /* - ************************************************************************** - ** 3. Call the member routine, saving its result if necessary. - ************************************************************************** - */ - - ret = (*pScreen->PositionWindow)(pWin, x, y); - - /* - ************************************************************************** - ** 4. Rewrap the member routine, restoring the wrapper value first in case - ** the wrapper (or something that it wrapped) change this value. - ************************************************************************** - */ - - pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; - pScreen->PositionWindow = miDbePositionWindow; - - /* - ************************************************************************** - ** 5. Do any work necessary after the member routine has been called. - ************************************************************************** - */ - - if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) - { - return(ret); - } - - if (pDbeWindowPriv->width == pWin->drawable.width && - pDbeWindowPriv->height == pWin->drawable.height) - { - return(ret); - } - - width = pWin->drawable.width; - height = pWin->drawable.height; - - dx = pWin->drawable.x - pDbeWindowPriv->x; - dy = pWin->drawable.y - pDbeWindowPriv->y; - dw = width - pDbeWindowPriv->width; - dh = height - pDbeWindowPriv->height; - - GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty); - - clear = ((pDbeWindowPriv->width < (unsigned short)width ) || - (pDbeWindowPriv->height < (unsigned short)height) || - (pWin->bitGravity == ForgetGravity)); - - sourcex = 0; - sourcey = 0; - savewidth = pDbeWindowPriv->width; - saveheight = pDbeWindowPriv->height; - - /* Clip rectangle to source and destination. */ - if (destx < 0) - { - savewidth += destx; - sourcex -= destx; - destx = 0; - } - - if (destx + savewidth > width) - { - savewidth = width - destx; - } - - if (desty < 0) - { - saveheight += desty; - sourcey -= desty; - desty = 0; - } - - if (desty + saveheight > height) - { - saveheight = height - desty; - } - - pDbeWindowPriv->width = width; - pDbeWindowPriv->height = height; - pDbeWindowPriv->x = pWin->drawable.x; - pDbeWindowPriv->y = pWin->drawable.y; - - pGC = GetScratchGC (pWin->drawable.depth, pScreen); - - if (clear) - { - if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC)) - { - clearRect.x = 0; - clearRect.y = 0; - clearRect.width = width; - clearRect.height = height; - } - else - { - clear = FALSE; - } - } - - /* Create DBE buffer pixmaps equal to size of resized window. */ - pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height, - pWin->drawable.depth, 0); - - pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height, - pWin->drawable.depth, 0); - - if (!pFrontBuffer || !pBackBuffer) - { - /* We failed at creating 1 or 2 of the pixmaps. */ - - if (pFrontBuffer) - { - (*pScreen->DestroyPixmap)(pFrontBuffer); - } - - if (pBackBuffer) - { - (*pScreen->DestroyPixmap)(pBackBuffer); - } - - /* Destroy all buffers for this window. */ - while (pDbeWindowPriv) - { - /* DbeWindowPrivDelete() will free the window private if there no - * more buffer IDs associated with this window. - */ - FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); - pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); - } - - FreeScratchGC(pGC); - return(FALSE); - } - - else - { - /* Clear out the new DBE buffer pixmaps. */ - - MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv; - - - pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv); - ValidateGC((DrawablePtr)pFrontBuffer, pGC); - - /* I suppose this could avoid quite a bit of work if - * it computed the minimal area required. - */ - if (clear) - { - (*pGC->ops->PolyFillRect)((DrawablePtr)pFrontBuffer, pGC, 1, - &clearRect); - (*pGC->ops->PolyFillRect)((DrawablePtr)pBackBuffer , pGC, 1, - &clearRect); - } - - /* Copy the contents of the old DBE pixmaps to the new pixmaps. */ - if (pWin->bitGravity != ForgetGravity) - { - (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, - (DrawablePtr)pFrontBuffer, pGC, sourcex, - sourcey, savewidth, saveheight, destx, desty); - (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, - (DrawablePtr)pBackBuffer, pGC, sourcex, - sourcey, savewidth, saveheight, destx, desty); - } - - /* Destroy the old pixmaps, and point the DBE window priv to the new - * pixmaps. - */ - - (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer); - (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer); - - pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer; - pDbeWindowPrivPriv->pBackBuffer = pBackBuffer; - - /* Make sure all XID are associated with the new back pixmap. */ - miDbeAliasBuffers(pDbeWindowPriv); - - FreeScratchGC(pGC); - } - - return(ret); - -} /* miDbePositionWindow() */ - - -/****************************************************************************** - * - * DBE MI Procedure: miDbeResetProc - * - * Description: - * - * This function is called from DbeResetProc(), which is called at the end - * of every server generation. This function peforms any MI-specific - * shutdown tasks. - * - *****************************************************************************/ - -static void -miDbeResetProc(ScreenPtr pScreen) -{ - DbeScreenPrivPtr pDbeScreenPriv; - - - pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); - - /* Unwrap wrappers */ - pScreen->PositionWindow = pDbeScreenPriv->PositionWindow; - -} /* miDbeResetProc() */ - - -/****************************************************************************** - * - * DBE MI Procedure: miDbeInit - * - * Description: - * - * This is the MI initialization function called by DbeExtensionInit(). - * - *****************************************************************************/ - -Bool -miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv) -{ - /* Copy resource types created by DIX */ - dbeDrawableResType = pDbeScreenPriv->dbeDrawableResType; - dbeWindowPrivResType = pDbeScreenPriv->dbeWindowPrivResType; - - /* Copy private indices created by DIX */ - dbeScreenPrivKey = pDbeScreenPriv->dbeScreenPrivKey; - dbeWindowPrivKey = pDbeScreenPriv->dbeWindowPrivKey; - - if (!dixRequestPrivate(miDbeWindowPrivPrivKey, - sizeof(MiDbeWindowPrivPrivRec))) - return(FALSE); - - /* Wrap functions. */ - pDbeScreenPriv->PositionWindow = pScreen->PositionWindow; - pScreen->PositionWindow = miDbePositionWindow; - - /* Initialize the per-screen DBE function pointers. */ - pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo; - pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName; - pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers; - pDbeScreenPriv->BeginIdiom = 0; - pDbeScreenPriv->EndIdiom = 0; - pDbeScreenPriv->ResetProc = miDbeResetProc; - pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete; - - return(TRUE); - -} /* miDbeInit() */ +/******************************************************************************
+ *
+ * Copyright (c) 1994, 1995 Hewlett-Packard Company
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Hewlett-Packard
+ * Company shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization from the Hewlett-Packard Company.
+ *
+ * Machine-independent DBE code
+ *
+ *****************************************************************************/
+
+
+/* INCLUDES */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include "dbestruct.h"
+#include "midbestr.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "inputstr.h"
+#include "midbe.h"
+#include "xace.h"
+
+#include <stdio.h>
+
+static int miDbeWindowPrivPrivKeyIndex;
+static DevPrivateKey miDbeWindowPrivPrivKey = &miDbeWindowPrivPrivKeyIndex;
+static RESTYPE dbeDrawableResType;
+static RESTYPE dbeWindowPrivResType;
+static int dbeScreenPrivKeyIndex;
+static DevPrivateKey dbeScreenPrivKey = &dbeScreenPrivKeyIndex;
+static int dbeWindowPrivKeyIndex;
+static DevPrivateKey dbeWindowPrivKey = &dbeWindowPrivKeyIndex;
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeGetVisualInfo
+ *
+ * Description:
+ *
+ * This is the MI function for the DbeGetVisualInfo request. This function
+ * is called through pDbeScreenPriv->GetVisualInfo. This function is also
+ * called for the DbeAllocateBackBufferName request at the extension level;
+ * it is called by ProcDbeAllocateBackBufferName() in dbe.c.
+ *
+ * If memory allocation fails or we can not get the visual info, this
+ * function returns FALSE. Otherwise, it returns TRUE for success.
+ *
+ *****************************************************************************/
+
+static Bool
+miDbeGetVisualInfo(ScreenPtr pScreen, XdbeScreenVisualInfo *pScrVisInfo)
+{
+ register int i, j, k;
+ register int count;
+ DepthPtr pDepth;
+ XdbeVisualInfo *visInfo;
+
+
+ /* Determine number of visuals for this screen. */
+ for (i = 0, count = 0; i < pScreen->numDepths; i++)
+ {
+ count += pScreen->allowedDepths[i].numVids;
+ }
+
+ /* Allocate an array of XdbeVisualInfo items. */
+ if (!(visInfo = (XdbeVisualInfo *)malloc(count * sizeof(XdbeVisualInfo))))
+ {
+ return(FALSE); /* memory alloc failure */
+ }
+
+ for (i = 0, k = 0; i < pScreen->numDepths; i++)
+ {
+ /* For each depth of this screen, get visual information. */
+
+ pDepth = &pScreen->allowedDepths[i];
+
+ for (j = 0; j < pDepth->numVids; j++)
+ {
+ /* For each visual for this depth of this screen, get visual ID
+ * and visual depth. Since this is MI code, we will always return
+ * the same performance level for all visuals (0). A higher
+ * performance level value indicates higher performance.
+ */
+ visInfo[k].visual = pDepth->vids[j];
+ visInfo[k].depth = pDepth->depth;
+ visInfo[k].perflevel = 0;
+ k++;
+ }
+ }
+
+ /* Record the number of visuals and point visual_depth to
+ * the array of visual info.
+ */
+ pScrVisInfo->count = count;
+ pScrVisInfo->visinfo = visInfo;
+
+ return(TRUE); /* success */
+
+} /* miDbeGetVisualInfo() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miAllocBackBufferName
+ *
+ * Description:
+ *
+ * This is the MI function for the DbeAllocateBackBufferName request.
+ *
+ *****************************************************************************/
+
+static int
+miDbeAllocBackBufferName(WindowPtr pWin, XID bufId, int swapAction)
+{
+ ScreenPtr pScreen;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ GCPtr pGC;
+ xRectangle clearRect;
+ int rc;
+
+
+ pScreen = pWin->drawable.pScreen;
+ pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
+
+ if (pDbeWindowPriv->nBufferIDs == 0)
+ {
+ /* There is no buffer associated with the window.
+ * We have to create the window priv priv. Remember, the window
+ * priv was created at the DIX level, so all we need to do is
+ * create the priv priv and attach it to the priv.
+ */
+
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ /* Setup the window priv priv. */
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+ pDbeWindowPrivPriv->pDbeWindowPriv = pDbeWindowPriv;
+
+ /* Get a front pixmap. */
+ if (!(pDbeWindowPrivPriv->pFrontBuffer =
+ (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
+ pDbeWindowPriv->height,
+ pWin->drawable.depth, 0)))
+ {
+ return(BadAlloc);
+ }
+
+ /* Get a back pixmap. */
+ if (!(pDbeWindowPrivPriv->pBackBuffer =
+ (*pScreen->CreatePixmap)(pScreen, pDbeWindowPriv->width,
+ pDbeWindowPriv->height,
+ pWin->drawable.depth, 0)))
+ {
+ (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
+ return(BadAlloc);
+ }
+
+ /* Security creation/labeling check. */
+ rc = XaceHook(XACE_RESOURCE_ACCESS, serverClient, bufId,
+ dbeDrawableResType, pDbeWindowPrivPriv->pBackBuffer,
+ RT_WINDOW, pWin, DixCreateAccess);
+
+ /* Make the back pixmap a DBE drawable resource. */
+ if (rc != Success || !AddResource(bufId, dbeDrawableResType,
+ pDbeWindowPrivPriv->pBackBuffer))
+ {
+ /* free the buffer and the drawable resource */
+ FreeResource(bufId, RT_NONE);
+ return (rc == Success) ? BadAlloc : rc;
+ }
+
+
+ /* Attach the priv priv to the priv. */
+ dixSetPrivate(&pDbeWindowPriv->devPrivates, miDbeWindowPrivPrivKey,
+ pDbeWindowPrivPriv);
+
+
+ /* Clear the back buffer. */
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
+ {
+ ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
+ clearRect.x = clearRect.y = 0;
+ clearRect.width = pDbeWindowPrivPriv->pBackBuffer->drawable.width;
+ clearRect.height = pDbeWindowPrivPriv->pBackBuffer->drawable.height;
+ (*pGC->ops->PolyFillRect)(
+ (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC, 1,
+ &clearRect);
+ }
+ FreeScratchGC(pGC);
+
+ } /* if no buffer associated with the window */
+
+ else
+ {
+ /* A buffer is already associated with the window.
+ * Place the new buffer ID information at the head of the ID list.
+ */
+
+ /* Associate the new ID with an existing pixmap. */
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+ if (!AddResource(bufId, dbeDrawableResType,
+ (pointer)pDbeWindowPrivPriv->pBackBuffer))
+ {
+ return(BadAlloc);
+ }
+
+ }
+
+ return(Success);
+
+} /* miDbeAllocBackBufferName() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeAliasBuffers
+ *
+ * Description:
+ *
+ * This function associates all XIDs of a buffer with the back pixmap
+ * stored in the window priv.
+ *
+ *****************************************************************************/
+
+static void
+miDbeAliasBuffers(DbeWindowPrivPtr pDbeWindowPriv)
+{
+ int i;
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv =
+ MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+
+ for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++)
+ {
+ ChangeResourceValue(pDbeWindowPriv->IDs[i], dbeDrawableResType,
+ (pointer)pDbeWindowPrivPriv->pBackBuffer);
+ }
+
+} /* miDbeAliasBuffers() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeSwapBuffers
+ *
+ * Description:
+ *
+ * This is the MI function for the DbeSwapBuffers request.
+ *
+ *****************************************************************************/
+
+static int
+miDbeSwapBuffers(ClientPtr client, int *pNumWindows, DbeSwapInfoPtr swapInfo)
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+ GCPtr pGC;
+ WindowPtr pWin;
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
+ PixmapPtr pTmpBuffer;
+ xRectangle clearRect;
+
+
+ pWin = swapInfo[0].pWindow;
+ pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV_FROM_WINDOW(pWin);
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+
+ /*
+ **********************************************************************
+ ** Setup before swap.
+ **********************************************************************
+ */
+
+ switch(swapInfo[0].swapAction)
+ {
+ case XdbeUndefined:
+ break;
+
+ case XdbeBackground:
+ break;
+
+ case XdbeUntouched:
+ ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer, pGC);
+ (*pGC->ops->CopyArea)((DrawablePtr)pWin,
+ (DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
+ pGC, 0, 0, pWin->drawable.width,
+ pWin->drawable.height, 0, 0);
+ break;
+
+ case XdbeCopied:
+ break;
+
+ }
+
+ /*
+ **********************************************************************
+ ** Swap.
+ **********************************************************************
+ */
+
+ ValidateGC((DrawablePtr)pWin, pGC);
+ (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
+ (DrawablePtr)pWin, pGC, 0, 0,
+ pWin->drawable.width, pWin->drawable.height,
+ 0, 0);
+
+ /*
+ **********************************************************************
+ ** Tasks after swap.
+ **********************************************************************
+ */
+
+ switch(swapInfo[0].swapAction)
+ {
+ case XdbeUndefined:
+ break;
+
+ case XdbeBackground:
+ if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
+ {
+ ValidateGC((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer, pGC);
+ clearRect.x = 0;
+ clearRect.y = 0;
+ clearRect.width =
+ pDbeWindowPrivPriv->pBackBuffer->drawable.width;
+ clearRect.height =
+ pDbeWindowPrivPriv->pBackBuffer->drawable.height;
+ (*pGC->ops->PolyFillRect)(
+ (DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
+ pGC, 1, &clearRect);
+ }
+ break;
+
+ case XdbeUntouched:
+ /* Swap pixmap pointers. */
+ pTmpBuffer = pDbeWindowPrivPriv->pBackBuffer;
+ pDbeWindowPrivPriv->pBackBuffer =
+ pDbeWindowPrivPriv->pFrontBuffer;
+ pDbeWindowPrivPriv->pFrontBuffer = pTmpBuffer;
+
+ miDbeAliasBuffers(pDbeWindowPrivPriv->pDbeWindowPriv);
+
+ break;
+
+ case XdbeCopied:
+ break;
+
+ }
+
+ /* Remove the swapped window from the swap information array and decrement
+ * pNumWindows to indicate to the DIX level how many windows were actually
+ * swapped.
+ */
+
+ if (*pNumWindows > 1)
+ {
+ /* We were told to swap more than one window, but we only swapped the
+ * first one. Remove the first window in the list by moving the last
+ * window to the beginning.
+ */
+ swapInfo[0].pWindow = swapInfo[*pNumWindows - 1].pWindow;
+ swapInfo[0].swapAction = swapInfo[*pNumWindows - 1].swapAction;
+
+ /* Clear the last window information just to be safe. */
+ swapInfo[*pNumWindows - 1].pWindow = (WindowPtr)NULL;
+ swapInfo[*pNumWindows - 1].swapAction = 0;
+ }
+ else
+ {
+ /* Clear the window information just to be safe. */
+ swapInfo[0].pWindow = (WindowPtr)NULL;
+ swapInfo[0].swapAction = 0;
+ }
+
+ (*pNumWindows)--;
+
+ FreeScratchGC(pGC);
+
+ return(Success);
+
+} /* miSwapBuffers() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeWinPrivDelete
+ *
+ * Description:
+ *
+ * This is the MI function for deleting the dbeWindowPrivResType resource.
+ * This function is invoked indirectly by calling FreeResource() to free
+ * the resources associated with a DBE buffer ID. There are 5 ways that
+ * miDbeWinPrivDelete() can be called by FreeResource(). They are:
+ *
+ * - A DBE window is destroyed, in which case the DbeDestroyWindow()
+ * wrapper is invoked. The wrapper calls FreeResource() for all DBE
+ * buffer IDs.
+ *
+ * - miDbeAllocBackBufferName() calls FreeResource() to clean up resources
+ * after a buffer allocation failure.
+ *
+ * - The PositionWindow wrapper, miDbePositionWindow(), calls
+ * FreeResource() when it fails to create buffers of the new size.
+ * FreeResource() is called for all DBE buffer IDs.
+ *
+ * - FreeClientResources() calls FreeResource() when a client dies or the
+ * the server resets.
+ *
+ * When FreeResource() is called for a DBE buffer ID, the delete function
+ * for the only other type of DBE resource, dbeDrawableResType, is also
+ * invoked. This delete function (DbeDrawableDelete) is a NOOP to make
+ * resource deletion easier. It is not guaranteed which delete function is
+ * called first. Hence, we will let miDbeWinPrivDelete() free all DBE
+ * resources.
+ *
+ * This function deletes/frees the following stuff associated with
+ * the window private:
+ *
+ * - the ID node in the ID list representing the passed in ID.
+ *
+ * In addition, pDbeWindowPriv->nBufferIDs is decremented.
+ *
+ * If this function is called for the last/only buffer ID for a window,
+ * these are additionally deleted/freed:
+ *
+ * - the front and back pixmaps
+ * - the window priv itself
+ *
+ *****************************************************************************/
+
+static void
+miDbeWinPrivDelete(DbeWindowPrivPtr pDbeWindowPriv, XID bufId)
+{
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
+
+
+ if (pDbeWindowPriv->nBufferIDs != 0)
+ {
+ /* We still have at least one more buffer ID associated with this
+ * window.
+ */
+ return;
+ }
+
+
+ /* We have no more buffer IDs associated with this window. We need to
+ * free some stuff.
+ */
+
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+
+ /* Destroy the front and back pixmaps. */
+ if (pDbeWindowPrivPriv->pFrontBuffer)
+ {
+ (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
+ pDbeWindowPrivPriv->pFrontBuffer);
+ }
+ if (pDbeWindowPrivPriv->pBackBuffer)
+ {
+ (*pDbeWindowPriv->pWindow->drawable.pScreen->DestroyPixmap)(
+ pDbeWindowPrivPriv->pBackBuffer);
+ }
+
+} /* miDbeWinPrivDelete() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbePositionWindow
+ *
+ * Description:
+ *
+ * This function was cloned from miMbxPositionWindow() in mimultibuf.c.
+ * This function resizes the buffer when the window is resized.
+ *
+ *****************************************************************************/
+
+static Bool
+miDbePositionWindow(WindowPtr pWin, int x, int y)
+{
+ ScreenPtr pScreen;
+ DbeScreenPrivPtr pDbeScreenPriv;
+ DbeWindowPrivPtr pDbeWindowPriv;
+ int width, height;
+ int dx, dy, dw, dh;
+ int sourcex, sourcey;
+ int destx, desty;
+ int savewidth, saveheight;
+ PixmapPtr pFrontBuffer;
+ PixmapPtr pBackBuffer;
+ Bool clear;
+ GCPtr pGC;
+ xRectangle clearRect;
+ Bool ret;
+
+
+ /*
+ **************************************************************************
+ ** 1. Unwrap the member routine.
+ **************************************************************************
+ */
+
+ pScreen = pWin->drawable.pScreen;
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+ pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
+
+ /*
+ **************************************************************************
+ ** 2. Do any work necessary before the member routine is called.
+ **
+ ** In this case we do not need to do anything.
+ **************************************************************************
+ */
+
+ /*
+ **************************************************************************
+ ** 3. Call the member routine, saving its result if necessary.
+ **************************************************************************
+ */
+
+ ret = (*pScreen->PositionWindow)(pWin, x, y);
+
+ /*
+ **************************************************************************
+ ** 4. Rewrap the member routine, restoring the wrapper value first in case
+ ** the wrapper (or something that it wrapped) change this value.
+ **************************************************************************
+ */
+
+ pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = miDbePositionWindow;
+
+ /*
+ **************************************************************************
+ ** 5. Do any work necessary after the member routine has been called.
+ **************************************************************************
+ */
+
+ if (!(pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)))
+ {
+ return(ret);
+ }
+
+ if (pDbeWindowPriv->width == pWin->drawable.width &&
+ pDbeWindowPriv->height == pWin->drawable.height)
+ {
+ return(ret);
+ }
+
+ width = pWin->drawable.width;
+ height = pWin->drawable.height;
+
+ dx = pWin->drawable.x - pDbeWindowPriv->x;
+ dy = pWin->drawable.y - pDbeWindowPriv->y;
+ dw = width - pDbeWindowPriv->width;
+ dh = height - pDbeWindowPriv->height;
+
+ GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty);
+
+ clear = ((pDbeWindowPriv->width < (unsigned short)width ) ||
+ (pDbeWindowPriv->height < (unsigned short)height) ||
+ (pWin->bitGravity == ForgetGravity));
+
+ sourcex = 0;
+ sourcey = 0;
+ savewidth = pDbeWindowPriv->width;
+ saveheight = pDbeWindowPriv->height;
+
+ /* Clip rectangle to source and destination. */
+ if (destx < 0)
+ {
+ savewidth += destx;
+ sourcex -= destx;
+ destx = 0;
+ }
+
+ if (destx + savewidth > width)
+ {
+ savewidth = width - destx;
+ }
+
+ if (desty < 0)
+ {
+ saveheight += desty;
+ sourcey -= desty;
+ desty = 0;
+ }
+
+ if (desty + saveheight > height)
+ {
+ saveheight = height - desty;
+ }
+
+ pDbeWindowPriv->width = width;
+ pDbeWindowPriv->height = height;
+ pDbeWindowPriv->x = pWin->drawable.x;
+ pDbeWindowPriv->y = pWin->drawable.y;
+
+ pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+
+ if (clear)
+ {
+ if ((*pDbeScreenPriv->SetupBackgroundPainter)(pWin, pGC))
+ {
+ clearRect.x = 0;
+ clearRect.y = 0;
+ clearRect.width = width;
+ clearRect.height = height;
+ }
+ else
+ {
+ clear = FALSE;
+ }
+ }
+
+ /* Create DBE buffer pixmaps equal to size of resized window. */
+ pFrontBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
+ pWin->drawable.depth, 0);
+
+ pBackBuffer = (*pScreen->CreatePixmap)(pScreen, width, height,
+ pWin->drawable.depth, 0);
+
+ if (!pFrontBuffer || !pBackBuffer)
+ {
+ /* We failed at creating 1 or 2 of the pixmaps. */
+
+ if (pFrontBuffer)
+ {
+ (*pScreen->DestroyPixmap)(pFrontBuffer);
+ }
+
+ if (pBackBuffer)
+ {
+ (*pScreen->DestroyPixmap)(pBackBuffer);
+ }
+
+ /* Destroy all buffers for this window. */
+ while (pDbeWindowPriv)
+ {
+ /* DbeWindowPrivDelete() will free the window private if there no
+ * more buffer IDs associated with this window.
+ */
+ FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
+ pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
+ }
+
+ FreeScratchGC(pGC);
+ return(FALSE);
+ }
+
+ else
+ {
+ /* Clear out the new DBE buffer pixmaps. */
+
+ MiDbeWindowPrivPrivPtr pDbeWindowPrivPriv;
+
+
+ pDbeWindowPrivPriv = MI_DBE_WINDOW_PRIV_PRIV(pDbeWindowPriv);
+ ValidateGC((DrawablePtr)pFrontBuffer, pGC);
+
+ /* I suppose this could avoid quite a bit of work if
+ * it computed the minimal area required.
+ */
+ if (clear)
+ {
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pFrontBuffer, pGC, 1,
+ &clearRect);
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pBackBuffer , pGC, 1,
+ &clearRect);
+ }
+
+ /* Copy the contents of the old DBE pixmaps to the new pixmaps. */
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pFrontBuffer,
+ (DrawablePtr)pFrontBuffer, pGC, sourcex,
+ sourcey, savewidth, saveheight, destx, desty);
+ (*pGC->ops->CopyArea)((DrawablePtr)pDbeWindowPrivPriv->pBackBuffer,
+ (DrawablePtr)pBackBuffer, pGC, sourcex,
+ sourcey, savewidth, saveheight, destx, desty);
+ }
+
+ /* Destroy the old pixmaps, and point the DBE window priv to the new
+ * pixmaps.
+ */
+
+ (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pFrontBuffer);
+ (*pScreen->DestroyPixmap)(pDbeWindowPrivPriv->pBackBuffer);
+
+ pDbeWindowPrivPriv->pFrontBuffer = pFrontBuffer;
+ pDbeWindowPrivPriv->pBackBuffer = pBackBuffer;
+
+ /* Make sure all XID are associated with the new back pixmap. */
+ miDbeAliasBuffers(pDbeWindowPriv);
+
+ FreeScratchGC(pGC);
+ }
+
+ return(ret);
+
+} /* miDbePositionWindow() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeResetProc
+ *
+ * Description:
+ *
+ * This function is called from DbeResetProc(), which is called at the end
+ * of every server generation. This function peforms any MI-specific
+ * shutdown tasks.
+ *
+ *****************************************************************************/
+
+static void
+miDbeResetProc(ScreenPtr pScreen)
+{
+ DbeScreenPrivPtr pDbeScreenPriv;
+
+
+ pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
+
+ /* Unwrap wrappers */
+ pScreen->PositionWindow = pDbeScreenPriv->PositionWindow;
+
+} /* miDbeResetProc() */
+
+
+/******************************************************************************
+ *
+ * DBE MI Procedure: miDbeInit
+ *
+ * Description:
+ *
+ * This is the MI initialization function called by DbeExtensionInit().
+ *
+ *****************************************************************************/
+
+Bool
+miDbeInit(ScreenPtr pScreen, DbeScreenPrivPtr pDbeScreenPriv)
+{
+ /* Copy resource types created by DIX */
+ dbeDrawableResType = pDbeScreenPriv->dbeDrawableResType;
+ dbeWindowPrivResType = pDbeScreenPriv->dbeWindowPrivResType;
+
+ /* Copy private indices created by DIX */
+ dbeScreenPrivKey = pDbeScreenPriv->dbeScreenPrivKey;
+ dbeWindowPrivKey = pDbeScreenPriv->dbeWindowPrivKey;
+
+ if (!dixRequestPrivate(miDbeWindowPrivPrivKey,
+ sizeof(MiDbeWindowPrivPrivRec)))
+ return(FALSE);
+
+ /* Wrap functions. */
+ pDbeScreenPriv->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = miDbePositionWindow;
+
+ /* Initialize the per-screen DBE function pointers. */
+ pDbeScreenPriv->GetVisualInfo = miDbeGetVisualInfo;
+ pDbeScreenPriv->AllocBackBufferName = miDbeAllocBackBufferName;
+ pDbeScreenPriv->SwapBuffers = miDbeSwapBuffers;
+ pDbeScreenPriv->BeginIdiom = 0;
+ pDbeScreenPriv->EndIdiom = 0;
+ pDbeScreenPriv->ResetProc = miDbeResetProc;
+ pDbeScreenPriv->WinPrivDelete = miDbeWinPrivDelete;
+
+ return(TRUE);
+
+} /* miDbeInit() */
|