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