From c38dead3ea7e177728d90cd815cf4eead0c9f534 Mon Sep 17 00:00:00 2001 From: marha Date: Sat, 15 May 2010 16:28:11 +0000 Subject: xserver git update 15/5/2010 --- xorg-server/dbe/dbe.c | 3364 +++++++++++++++++++++++------------------------ xorg-server/dbe/midbe.c | 1618 +++++++++++------------ 2 files changed, 2488 insertions(+), 2494 deletions(-) (limited to 'xorg-server/dbe') 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 -#endif - -#include -#if HAVE_STDINT_H -#include -#elif !defined(UINT32_MAX) -#define UINT32_MAX 0xffffffffU -#endif - -#include -#include -#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 +#endif + +#include +#if HAVE_STDINT_H +#include +#elif !defined(UINT32_MAX) +#define UINT32_MAX 0xffffffffU +#endif + +#include +#include +#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 -#endif - -#include -#include -#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 - -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 +#endif + +#include +#include +#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 + +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() */ -- cgit v1.2.3