1706f2543Smrg/****************************************************************************** 2706f2543Smrg * 3706f2543Smrg * Copyright (c) 1994, 1995 Hewlett-Packard Company 4706f2543Smrg * 5706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 6706f2543Smrg * a copy of this software and associated documentation files (the 7706f2543Smrg * "Software"), to deal in the Software without restriction, including 8706f2543Smrg * without limitation the rights to use, copy, modify, merge, publish, 9706f2543Smrg * distribute, sublicense, and/or sell copies of the Software, and to 10706f2543Smrg * permit persons to whom the Software is furnished to do so, subject to 11706f2543Smrg * the following conditions: 12706f2543Smrg * 13706f2543Smrg * The above copyright notice and this permission notice shall be included 14706f2543Smrg * in all copies or substantial portions of the Software. 15706f2543Smrg * 16706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17706f2543Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19706f2543Smrg * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, 20706f2543Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21706f2543Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 22706f2543Smrg * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23706f2543Smrg * 24706f2543Smrg * Except as contained in this notice, the name of the Hewlett-Packard 25706f2543Smrg * Company shall not be used in advertising or otherwise to promote the 26706f2543Smrg * sale, use or other dealings in this Software without prior written 27706f2543Smrg * authorization from the Hewlett-Packard Company. 28706f2543Smrg * 29706f2543Smrg * DIX DBE code 30706f2543Smrg * 31706f2543Smrg *****************************************************************************/ 32706f2543Smrg 33706f2543Smrg 34706f2543Smrg/* INCLUDES */ 35706f2543Smrg 36706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 37706f2543Smrg#include <dix-config.h> 38706f2543Smrg#endif 39706f2543Smrg 40706f2543Smrg#include <string.h> 41706f2543Smrg#if HAVE_STDINT_H 42706f2543Smrg#include <stdint.h> 43706f2543Smrg#elif !defined(UINT32_MAX) 44706f2543Smrg#define UINT32_MAX 0xffffffffU 45706f2543Smrg#endif 46706f2543Smrg 47706f2543Smrg#include <X11/X.h> 48706f2543Smrg#include <X11/Xproto.h> 49706f2543Smrg#include "scrnintstr.h" 50706f2543Smrg#include "extnsionst.h" 51706f2543Smrg#include "gcstruct.h" 52706f2543Smrg#include "dixstruct.h" 53706f2543Smrg#define NEED_DBE_PROTOCOL 54706f2543Smrg#include "dbestruct.h" 55706f2543Smrg#include "midbe.h" 56706f2543Smrg#include "xace.h" 57706f2543Smrg 58706f2543Smrg/* GLOBALS */ 59706f2543Smrg 60706f2543Smrg/* These are globals for use by DDX */ 61706f2543SmrgDevPrivateKeyRec dbeScreenPrivKeyRec; 62706f2543SmrgDevPrivateKeyRec dbeWindowPrivKeyRec; 63706f2543Smrg 64706f2543Smrg/* These are globals for use by DDX */ 65706f2543SmrgRESTYPE dbeDrawableResType; 66706f2543SmrgRESTYPE dbeWindowPrivResType; 67706f2543Smrg 68706f2543Smrg/* Used to generate DBE's BadBuffer error. */ 69706f2543Smrgstatic int dbeErrorBase; 70706f2543Smrg 71706f2543Smrg/****************************************************************************** 72706f2543Smrg * 73706f2543Smrg * DBE DIX Procedure: DbeStubScreen 74706f2543Smrg * 75706f2543Smrg * Description: 76706f2543Smrg * 77706f2543Smrg * This is function stubs the function pointers in the given DBE screen 78706f2543Smrg * private and increments the number of stubbed screens. 79706f2543Smrg * 80706f2543Smrg *****************************************************************************/ 81706f2543Smrg 82706f2543Smrgstatic void 83706f2543SmrgDbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens) 84706f2543Smrg{ 85706f2543Smrg /* Stub DIX. */ 86706f2543Smrg pDbeScreenPriv->SetupBackgroundPainter = NULL; 87706f2543Smrg 88706f2543Smrg /* Do not unwrap PositionWindow nor DestroyWindow. If the DDX 89706f2543Smrg * initialization function failed, we assume that it did not wrap 90706f2543Smrg * PositionWindow. Also, DestroyWindow is only wrapped if the DDX 91706f2543Smrg * initialization function succeeded. 92706f2543Smrg */ 93706f2543Smrg 94706f2543Smrg /* Stub DDX. */ 95706f2543Smrg pDbeScreenPriv->GetVisualInfo = NULL; 96706f2543Smrg pDbeScreenPriv->AllocBackBufferName = NULL; 97706f2543Smrg pDbeScreenPriv->SwapBuffers = NULL; 98706f2543Smrg pDbeScreenPriv->BeginIdiom = NULL; 99706f2543Smrg pDbeScreenPriv->EndIdiom = NULL; 100706f2543Smrg pDbeScreenPriv->WinPrivDelete = NULL; 101706f2543Smrg pDbeScreenPriv->ResetProc = NULL; 102706f2543Smrg 103706f2543Smrg (*nStubbedScreens)++; 104706f2543Smrg 105706f2543Smrg} /* DbeStubScreen() */ 106706f2543Smrg 107706f2543Smrg 108706f2543Smrg 109706f2543Smrg/****************************************************************************** 110706f2543Smrg * 111706f2543Smrg * DBE DIX Procedure: ProcDbeGetVersion 112706f2543Smrg * 113706f2543Smrg * Description: 114706f2543Smrg * 115706f2543Smrg * This function is for processing a DbeGetVersion request. 116706f2543Smrg * This request returns the major and minor version numbers of this 117706f2543Smrg * extension. 118706f2543Smrg * 119706f2543Smrg * Return Values: 120706f2543Smrg * 121706f2543Smrg * Success 122706f2543Smrg * 123706f2543Smrg *****************************************************************************/ 124706f2543Smrg 125706f2543Smrgstatic int 126706f2543SmrgProcDbeGetVersion(ClientPtr client) 127706f2543Smrg{ 128706f2543Smrg /* REQUEST(xDbeGetVersionReq); */ 129706f2543Smrg xDbeGetVersionReply rep; 130706f2543Smrg register int n; 131706f2543Smrg 132706f2543Smrg 133706f2543Smrg REQUEST_SIZE_MATCH(xDbeGetVersionReq); 134706f2543Smrg 135706f2543Smrg rep.type = X_Reply; 136706f2543Smrg rep.length = 0; 137706f2543Smrg rep.sequenceNumber = client->sequence; 138706f2543Smrg rep.majorVersion = DBE_MAJOR_VERSION; 139706f2543Smrg rep.minorVersion = DBE_MINOR_VERSION; 140706f2543Smrg 141706f2543Smrg if (client->swapped) 142706f2543Smrg { 143706f2543Smrg swaps(&rep.sequenceNumber, n); 144706f2543Smrg } 145706f2543Smrg 146706f2543Smrg WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep); 147706f2543Smrg 148706f2543Smrg return Success; 149706f2543Smrg 150706f2543Smrg} /* ProcDbeGetVersion() */ 151706f2543Smrg 152706f2543Smrg 153706f2543Smrg/****************************************************************************** 154706f2543Smrg * 155706f2543Smrg * DBE DIX Procedure: ProcDbeAllocateBackBufferName 156706f2543Smrg * 157706f2543Smrg * Description: 158706f2543Smrg * 159706f2543Smrg * This function is for processing a DbeAllocateBackBufferName request. 160706f2543Smrg * This request allocates a drawable ID used to refer to the back buffer 161706f2543Smrg * of a window. 162706f2543Smrg * 163706f2543Smrg * Return Values: 164706f2543Smrg * 165706f2543Smrg * BadAlloc - server can not allocate resources 166706f2543Smrg * BadIDChoice - id is out of range for client; id is already in use 167706f2543Smrg * BadMatch - window is not an InputOutput window; 168706f2543Smrg * visual of window is not on list returned by 169706f2543Smrg * DBEGetVisualInfo; 170706f2543Smrg * BadValue - invalid swap action is specified 171706f2543Smrg * BadWindow - window is not a valid window 172706f2543Smrg * Success 173706f2543Smrg * 174706f2543Smrg *****************************************************************************/ 175706f2543Smrg 176706f2543Smrgstatic int 177706f2543SmrgProcDbeAllocateBackBufferName(ClientPtr client) 178706f2543Smrg{ 179706f2543Smrg REQUEST(xDbeAllocateBackBufferNameReq); 180706f2543Smrg WindowPtr pWin; 181706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 182706f2543Smrg DbeWindowPrivPtr pDbeWindowPriv; 183706f2543Smrg XdbeScreenVisualInfo scrVisInfo; 184706f2543Smrg register int i; 185706f2543Smrg Bool visualMatched = FALSE; 186706f2543Smrg xDbeSwapAction swapAction; 187706f2543Smrg VisualID visual; 188706f2543Smrg int status; 189706f2543Smrg int add_index; 190706f2543Smrg 191706f2543Smrg 192706f2543Smrg REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); 193706f2543Smrg 194706f2543Smrg /* The window must be valid. */ 195706f2543Smrg status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 196706f2543Smrg if (status != Success) 197706f2543Smrg return status; 198706f2543Smrg 199706f2543Smrg /* The window must be InputOutput. */ 200706f2543Smrg if (pWin->drawable.class != InputOutput) 201706f2543Smrg { 202706f2543Smrg return BadMatch; 203706f2543Smrg } 204706f2543Smrg 205706f2543Smrg /* The swap action must be valid. */ 206706f2543Smrg swapAction = stuff->swapAction; /* use local var for performance. */ 207706f2543Smrg if ((swapAction != XdbeUndefined ) && 208706f2543Smrg (swapAction != XdbeBackground) && 209706f2543Smrg (swapAction != XdbeUntouched ) && 210706f2543Smrg (swapAction != XdbeCopied )) 211706f2543Smrg { 212706f2543Smrg return BadValue; 213706f2543Smrg } 214706f2543Smrg 215706f2543Smrg /* The id must be in range and not already in use. */ 216706f2543Smrg LEGAL_NEW_RESOURCE(stuff->buffer, client); 217706f2543Smrg 218706f2543Smrg /* The visual of the window must be in the list returned by 219706f2543Smrg * GetVisualInfo. 220706f2543Smrg */ 221706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); 222706f2543Smrg if (!pDbeScreenPriv->GetVisualInfo) 223706f2543Smrg return BadMatch; /* screen doesn't support double buffering */ 224706f2543Smrg 225706f2543Smrg if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo)) 226706f2543Smrg { 227706f2543Smrg /* GetVisualInfo() failed to allocate visual info data. */ 228706f2543Smrg return BadAlloc; 229706f2543Smrg } 230706f2543Smrg 231706f2543Smrg /* See if the window's visual is on the list. */ 232706f2543Smrg visual = wVisual(pWin); 233706f2543Smrg for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++) 234706f2543Smrg { 235706f2543Smrg if (scrVisInfo.visinfo[i].visual == visual) 236706f2543Smrg { 237706f2543Smrg visualMatched = TRUE; 238706f2543Smrg } 239706f2543Smrg } 240706f2543Smrg 241706f2543Smrg /* Free what was allocated by the GetVisualInfo() call above. */ 242706f2543Smrg free(scrVisInfo.visinfo); 243706f2543Smrg 244706f2543Smrg if (!visualMatched) 245706f2543Smrg { 246706f2543Smrg return BadMatch; 247706f2543Smrg } 248706f2543Smrg 249706f2543Smrg if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL) 250706f2543Smrg { 251706f2543Smrg /* There is no buffer associated with the window. 252706f2543Smrg * Allocate a window priv. 253706f2543Smrg */ 254706f2543Smrg 255706f2543Smrg pDbeWindowPriv = dixAllocateObjectWithPrivates(DbeWindowPrivRec, PRIVATE_DBE_WINDOW); 256706f2543Smrg if (!pDbeWindowPriv) 257706f2543Smrg return BadAlloc; 258706f2543Smrg 259706f2543Smrg /* Fill out window priv information. */ 260706f2543Smrg pDbeWindowPriv->pWindow = pWin; 261706f2543Smrg pDbeWindowPriv->width = pWin->drawable.width; 262706f2543Smrg pDbeWindowPriv->height = pWin->drawable.height; 263706f2543Smrg pDbeWindowPriv->x = pWin->drawable.x; 264706f2543Smrg pDbeWindowPriv->y = pWin->drawable.y; 265706f2543Smrg pDbeWindowPriv->nBufferIDs = 0; 266706f2543Smrg 267706f2543Smrg /* Set the buffer ID array pointer to the initial (static) array). */ 268706f2543Smrg pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; 269706f2543Smrg 270706f2543Smrg /* Initialize the buffer ID list. */ 271706f2543Smrg pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; 272706f2543Smrg pDbeWindowPriv->IDs[0] = stuff->buffer; 273706f2543Smrg 274706f2543Smrg add_index = 0; 275706f2543Smrg for (i = 0; i < DBE_INIT_MAX_IDS; i++) 276706f2543Smrg { 277706f2543Smrg pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT; 278706f2543Smrg } 279706f2543Smrg 280706f2543Smrg /* Actually connect the window priv to the window. */ 281706f2543Smrg dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv); 282706f2543Smrg 283706f2543Smrg } /* if -- There is no buffer associated with the window. */ 284706f2543Smrg 285706f2543Smrg else 286706f2543Smrg { 287706f2543Smrg /* A buffer is already associated with the window. 288706f2543Smrg * Add the new buffer ID to the array, reallocating the array memory 289706f2543Smrg * if necessary. 290706f2543Smrg */ 291706f2543Smrg 292706f2543Smrg /* Determine if there is a free element in the ID array. */ 293706f2543Smrg for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++) 294706f2543Smrg { 295706f2543Smrg if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT) 296706f2543Smrg { 297706f2543Smrg /* There is still room in the ID array. */ 298706f2543Smrg break; 299706f2543Smrg } 300706f2543Smrg } 301706f2543Smrg 302706f2543Smrg if (i == pDbeWindowPriv->maxAvailableIDs) 303706f2543Smrg { 304706f2543Smrg /* No more room in the ID array -- reallocate another array. */ 305706f2543Smrg XID *pIDs; 306706f2543Smrg 307706f2543Smrg /* Setup an array pointer for the realloc operation below. */ 308706f2543Smrg if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) 309706f2543Smrg { 310706f2543Smrg /* We will malloc a new array. */ 311706f2543Smrg pIDs = NULL; 312706f2543Smrg } 313706f2543Smrg else 314706f2543Smrg { 315706f2543Smrg /* We will realloc a new array. */ 316706f2543Smrg pIDs = pDbeWindowPriv->IDs; 317706f2543Smrg } 318706f2543Smrg 319706f2543Smrg /* malloc/realloc a new array and initialize all elements to 0. */ 320706f2543Smrg pDbeWindowPriv->IDs = (XID *)realloc(pIDs, 321706f2543Smrg (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID)); 322706f2543Smrg if (!pDbeWindowPriv->IDs) 323706f2543Smrg { 324706f2543Smrg return BadAlloc; 325706f2543Smrg } 326706f2543Smrg memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0, 327706f2543Smrg (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS - 328706f2543Smrg pDbeWindowPriv->nBufferIDs) * sizeof(XID)); 329706f2543Smrg 330706f2543Smrg if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) 331706f2543Smrg { 332706f2543Smrg /* We just went from using the initial (static) array to a 333706f2543Smrg * newly allocated array. Copy the IDs from the initial array 334706f2543Smrg * to the new array. 335706f2543Smrg */ 336706f2543Smrg memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs, 337706f2543Smrg DBE_INIT_MAX_IDS * sizeof(XID)); 338706f2543Smrg } 339706f2543Smrg 340706f2543Smrg pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS; 341706f2543Smrg } 342706f2543Smrg 343706f2543Smrg add_index = i; 344706f2543Smrg 345706f2543Smrg } /* else -- A buffer is already associated with the window. */ 346706f2543Smrg 347706f2543Smrg 348706f2543Smrg /* Call the DDX routine to allocate the back buffer. */ 349706f2543Smrg status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer, 350706f2543Smrg stuff->swapAction); 351706f2543Smrg 352706f2543Smrg if (status == Success) 353706f2543Smrg { 354706f2543Smrg pDbeWindowPriv->IDs[add_index] = stuff->buffer; 355706f2543Smrg if (!AddResource(stuff->buffer, dbeWindowPrivResType, 356706f2543Smrg (pointer)pDbeWindowPriv)) 357706f2543Smrg { 358706f2543Smrg pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT; 359706f2543Smrg 360706f2543Smrg if (pDbeWindowPriv->nBufferIDs == 0) { 361706f2543Smrg status = BadAlloc; 362706f2543Smrg goto out_free; 363706f2543Smrg } 364706f2543Smrg } 365706f2543Smrg } else { 366706f2543Smrg /* The DDX buffer allocation routine failed for the first buffer of 367706f2543Smrg * this window. 368706f2543Smrg */ 369706f2543Smrg if (pDbeWindowPriv->nBufferIDs == 0) { 370706f2543Smrg goto out_free; 371706f2543Smrg } 372706f2543Smrg } 373706f2543Smrg 374706f2543Smrg /* Increment the number of buffers (XIDs) associated with this window. */ 375706f2543Smrg pDbeWindowPriv->nBufferIDs++; 376706f2543Smrg 377706f2543Smrg /* Set swap action on all calls. */ 378706f2543Smrg pDbeWindowPriv->swapAction = stuff->swapAction; 379706f2543Smrg 380706f2543Smrg return status; 381706f2543Smrg 382706f2543Smrgout_free: 383706f2543Smrg dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL); 384706f2543Smrg free(pDbeWindowPriv); 385706f2543Smrg return status; 386706f2543Smrg 387706f2543Smrg} /* ProcDbeAllocateBackBufferName() */ 388706f2543Smrg 389706f2543Smrg 390706f2543Smrg/****************************************************************************** 391706f2543Smrg * 392706f2543Smrg * DBE DIX Procedure: ProcDbeDeallocateBackBufferName 393706f2543Smrg * 394706f2543Smrg * Description: 395706f2543Smrg * 396706f2543Smrg * This function is for processing a DbeDeallocateBackBufferName request. 397706f2543Smrg * This request frees a drawable ID that was obtained by a 398706f2543Smrg * DbeAllocateBackBufferName request. 399706f2543Smrg * 400706f2543Smrg * Return Values: 401706f2543Smrg * 402706f2543Smrg * BadBuffer - buffer to deallocate is not associated with a window 403706f2543Smrg * Success 404706f2543Smrg * 405706f2543Smrg *****************************************************************************/ 406706f2543Smrg 407706f2543Smrgstatic int 408706f2543SmrgProcDbeDeallocateBackBufferName(ClientPtr client) 409706f2543Smrg{ 410706f2543Smrg REQUEST(xDbeDeallocateBackBufferNameReq); 411706f2543Smrg DbeWindowPrivPtr pDbeWindowPriv; 412706f2543Smrg int rc, i; 413706f2543Smrg pointer val; 414706f2543Smrg 415706f2543Smrg 416706f2543Smrg REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); 417706f2543Smrg 418706f2543Smrg /* Buffer name must be valid */ 419706f2543Smrg rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer, 420706f2543Smrg dbeWindowPrivResType, client, 421706f2543Smrg DixDestroyAccess); 422706f2543Smrg if (rc != Success) 423706f2543Smrg return rc; 424706f2543Smrg 425706f2543Smrg rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType, 426706f2543Smrg client, DixDestroyAccess); 427706f2543Smrg if (rc != Success) 428706f2543Smrg return rc; 429706f2543Smrg 430706f2543Smrg /* Make sure that the id is valid for the window. 431706f2543Smrg * This is paranoid code since we already looked up the ID by type 432706f2543Smrg * above. 433706f2543Smrg */ 434706f2543Smrg 435706f2543Smrg for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) 436706f2543Smrg { 437706f2543Smrg /* Loop through the ID list to find the ID. */ 438706f2543Smrg if (pDbeWindowPriv->IDs[i] == stuff->buffer) 439706f2543Smrg { 440706f2543Smrg break; 441706f2543Smrg } 442706f2543Smrg } 443706f2543Smrg 444706f2543Smrg if (i == pDbeWindowPriv->nBufferIDs) 445706f2543Smrg { 446706f2543Smrg /* We did not find the ID in the ID list. */ 447706f2543Smrg client->errorValue = stuff->buffer; 448706f2543Smrg return dbeErrorBase + DbeBadBuffer; 449706f2543Smrg } 450706f2543Smrg 451706f2543Smrg FreeResource(stuff->buffer, RT_NONE); 452706f2543Smrg 453706f2543Smrg return Success; 454706f2543Smrg 455706f2543Smrg} /* ProcDbeDeallocateBackBufferName() */ 456706f2543Smrg 457706f2543Smrg 458706f2543Smrg/****************************************************************************** 459706f2543Smrg * 460706f2543Smrg * DBE DIX Procedure: ProcDbeSwapBuffers 461706f2543Smrg * 462706f2543Smrg * Description: 463706f2543Smrg * 464706f2543Smrg * This function is for processing a DbeSwapBuffers request. 465706f2543Smrg * This request swaps the buffers for all windows listed, applying the 466706f2543Smrg * appropriate swap action for each window. 467706f2543Smrg * 468706f2543Smrg * Return Values: 469706f2543Smrg * 470706f2543Smrg * BadAlloc - local allocation failed; this return value is not defined 471706f2543Smrg * by the protocol 472706f2543Smrg * BadMatch - a window in request is not double-buffered; a window in 473706f2543Smrg * request is listed more than once 474706f2543Smrg * BadValue - invalid swap action is specified; no swap action is 475706f2543Smrg * specified 476706f2543Smrg * BadWindow - a window in request is not valid 477706f2543Smrg * Success 478706f2543Smrg * 479706f2543Smrg *****************************************************************************/ 480706f2543Smrg 481706f2543Smrgstatic int 482706f2543SmrgProcDbeSwapBuffers(ClientPtr client) 483706f2543Smrg{ 484706f2543Smrg REQUEST(xDbeSwapBuffersReq); 485706f2543Smrg WindowPtr pWin; 486706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 487706f2543Smrg DbeSwapInfoPtr swapInfo; 488706f2543Smrg xDbeSwapInfo *dbeSwapInfo; 489706f2543Smrg int error; 490706f2543Smrg unsigned int i, j; 491706f2543Smrg unsigned int nStuff; 492706f2543Smrg 493706f2543Smrg 494706f2543Smrg REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); 495706f2543Smrg nStuff = stuff->n; /* use local variable for performance. */ 496706f2543Smrg 497706f2543Smrg if (nStuff == 0) 498706f2543Smrg { 499706f2543Smrg REQUEST_SIZE_MATCH(xDbeSwapBuffersReq); 500706f2543Smrg return Success; 501706f2543Smrg } 502706f2543Smrg 503706f2543Smrg if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec)) 504706f2543Smrg return BadAlloc; 505706f2543Smrg REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo)); 506706f2543Smrg 507706f2543Smrg /* Get to the swap info appended to the end of the request. */ 508706f2543Smrg dbeSwapInfo = (xDbeSwapInfo *)&stuff[1]; 509706f2543Smrg 510706f2543Smrg /* Allocate array to record swap information. */ 511706f2543Smrg swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec)); 512706f2543Smrg if (swapInfo == NULL) 513706f2543Smrg { 514706f2543Smrg return BadAlloc; 515706f2543Smrg } 516706f2543Smrg 517706f2543Smrg 518706f2543Smrg for (i = 0; i < nStuff; i++) 519706f2543Smrg { 520706f2543Smrg /* Check all windows to swap. */ 521706f2543Smrg 522706f2543Smrg /* Each window must be a valid window - BadWindow. */ 523706f2543Smrg error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client, 524706f2543Smrg DixWriteAccess); 525706f2543Smrg if (error != Success) { 526706f2543Smrg free(swapInfo); 527706f2543Smrg return error; 528706f2543Smrg } 529706f2543Smrg 530706f2543Smrg /* Each window must be double-buffered - BadMatch. */ 531706f2543Smrg if (DBE_WINDOW_PRIV(pWin) == NULL) 532706f2543Smrg { 533706f2543Smrg free(swapInfo); 534706f2543Smrg return BadMatch; 535706f2543Smrg } 536706f2543Smrg 537706f2543Smrg /* Each window must only be specified once - BadMatch. */ 538706f2543Smrg for (j = i + 1; j < nStuff; j++) 539706f2543Smrg { 540706f2543Smrg if (dbeSwapInfo[i].window == dbeSwapInfo[j].window) 541706f2543Smrg { 542706f2543Smrg free(swapInfo); 543706f2543Smrg return BadMatch; 544706f2543Smrg } 545706f2543Smrg } 546706f2543Smrg 547706f2543Smrg /* Each swap action must be valid - BadValue. */ 548706f2543Smrg if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) && 549706f2543Smrg (dbeSwapInfo[i].swapAction != XdbeBackground) && 550706f2543Smrg (dbeSwapInfo[i].swapAction != XdbeUntouched ) && 551706f2543Smrg (dbeSwapInfo[i].swapAction != XdbeCopied )) 552706f2543Smrg { 553706f2543Smrg free(swapInfo); 554706f2543Smrg return BadValue; 555706f2543Smrg } 556706f2543Smrg 557706f2543Smrg /* Everything checks out OK. Fill in the swap info array. */ 558706f2543Smrg swapInfo[i].pWindow = pWin; 559706f2543Smrg swapInfo[i].swapAction = dbeSwapInfo[i].swapAction; 560706f2543Smrg 561706f2543Smrg } /* for (i = 0; i < nStuff; i++) */ 562706f2543Smrg 563706f2543Smrg 564706f2543Smrg /* Call the DDX routine to perform the swap(s). The DDX routine should 565706f2543Smrg * scan the swap list (swap info), swap any buffers that it knows how to 566706f2543Smrg * handle, delete them from the list, and update nStuff to indicate how 567706f2543Smrg * many windows it did not handle. 568706f2543Smrg * 569706f2543Smrg * This scheme allows a range of sophistication in the DDX SwapBuffers() 570706f2543Smrg * implementation. Naive implementations could just swap the first buffer 571706f2543Smrg * in the list, move the last buffer to the front, decrement nStuff, and 572706f2543Smrg * return. The next level of sophistication could be to scan the whole 573706f2543Smrg * list for windows on the same screen. Up another level, the DDX routine 574706f2543Smrg * could deal with cross-screen synchronization. 575706f2543Smrg */ 576706f2543Smrg 577706f2543Smrg while (nStuff > 0) 578706f2543Smrg { 579706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow); 580706f2543Smrg error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo); 581706f2543Smrg if (error != Success) 582706f2543Smrg { 583706f2543Smrg free(swapInfo); 584706f2543Smrg return error; 585706f2543Smrg } 586706f2543Smrg } 587706f2543Smrg 588706f2543Smrg free(swapInfo); 589706f2543Smrg return Success; 590706f2543Smrg 591706f2543Smrg} /* ProcDbeSwapBuffers() */ 592706f2543Smrg 593706f2543Smrg 594706f2543Smrg/****************************************************************************** 595706f2543Smrg * 596706f2543Smrg * DBE DIX Procedure: ProcDbeBeginIdiom 597706f2543Smrg * 598706f2543Smrg * Description: 599706f2543Smrg * 600706f2543Smrg * This function is for processing a DbeBeginIdiom request. 601706f2543Smrg * This request informs the server that a complex swap will immediately 602706f2543Smrg * follow this request. 603706f2543Smrg * 604706f2543Smrg * Return Values: 605706f2543Smrg * 606706f2543Smrg * Success 607706f2543Smrg * 608706f2543Smrg *****************************************************************************/ 609706f2543Smrg 610706f2543Smrgstatic int 611706f2543SmrgProcDbeBeginIdiom(ClientPtr client) 612706f2543Smrg{ 613706f2543Smrg /* REQUEST(xDbeBeginIdiomReq); */ 614706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 615706f2543Smrg register int i; 616706f2543Smrg 617706f2543Smrg 618706f2543Smrg REQUEST_SIZE_MATCH(xDbeBeginIdiomReq); 619706f2543Smrg 620706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) 621706f2543Smrg { 622706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]); 623706f2543Smrg 624706f2543Smrg /* Call the DDX begin idiom procedure if there is one. */ 625706f2543Smrg if (pDbeScreenPriv->BeginIdiom) 626706f2543Smrg { 627706f2543Smrg (*pDbeScreenPriv->BeginIdiom)(client); 628706f2543Smrg } 629706f2543Smrg } 630706f2543Smrg 631706f2543Smrg return Success; 632706f2543Smrg 633706f2543Smrg} /* ProcDbeBeginIdiom() */ 634706f2543Smrg 635706f2543Smrg 636706f2543Smrg/****************************************************************************** 637706f2543Smrg * 638706f2543Smrg * DBE DIX Procedure: ProcDbeGetVisualInfo 639706f2543Smrg * 640706f2543Smrg * Description: 641706f2543Smrg * 642706f2543Smrg * This function is for processing a ProcDbeGetVisualInfo request. 643706f2543Smrg * This request returns information about which visuals support 644706f2543Smrg * double buffering. 645706f2543Smrg * 646706f2543Smrg * Return Values: 647706f2543Smrg * 648706f2543Smrg * BadDrawable - value in screen specifiers is not a valid drawable 649706f2543Smrg * Success 650706f2543Smrg * 651706f2543Smrg *****************************************************************************/ 652706f2543Smrg 653706f2543Smrgstatic int 654706f2543SmrgProcDbeGetVisualInfo(ClientPtr client) 655706f2543Smrg{ 656706f2543Smrg REQUEST(xDbeGetVisualInfoReq); 657706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 658706f2543Smrg xDbeGetVisualInfoReply rep; 659706f2543Smrg Drawable *drawables; 660706f2543Smrg DrawablePtr *pDrawables = NULL; 661706f2543Smrg register int i, j, n, rc; 662706f2543Smrg register int count; /* number of visual infos in reply */ 663706f2543Smrg register int length; /* length of reply */ 664706f2543Smrg ScreenPtr pScreen; 665706f2543Smrg XdbeScreenVisualInfo *pScrVisInfo; 666706f2543Smrg 667706f2543Smrg 668706f2543Smrg REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); 66948a68b89Smrg if (stuff->n > UINT32_MAX / sizeof(CARD32)) 67048a68b89Smrg return BadLength; 67148a68b89Smrg REQUEST_FIXED_SIZE(xDbeGetVisualInfoReq, stuff->n * sizeof(CARD32)); 672706f2543Smrg 673706f2543Smrg if (stuff->n > UINT32_MAX / sizeof(DrawablePtr)) 674706f2543Smrg return BadAlloc; 675706f2543Smrg /* Make sure any specified drawables are valid. */ 676706f2543Smrg if (stuff->n != 0) 677706f2543Smrg { 678706f2543Smrg if (!(pDrawables = (DrawablePtr *)malloc(stuff->n * 679706f2543Smrg sizeof(DrawablePtr)))) 680706f2543Smrg { 681706f2543Smrg return BadAlloc; 682706f2543Smrg } 683706f2543Smrg 684706f2543Smrg drawables = (Drawable *)&stuff[1]; 685706f2543Smrg 686706f2543Smrg for (i = 0; i < stuff->n; i++) 687706f2543Smrg { 688706f2543Smrg rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0, 689706f2543Smrg DixGetAttrAccess); 690706f2543Smrg if (rc != Success) { 691706f2543Smrg free(pDrawables); 692706f2543Smrg return rc; 693706f2543Smrg } 694706f2543Smrg } 695706f2543Smrg } 696706f2543Smrg 697706f2543Smrg count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n; 698706f2543Smrg if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo)))) 699706f2543Smrg { 700706f2543Smrg free(pDrawables); 701706f2543Smrg 702706f2543Smrg return BadAlloc; 703706f2543Smrg } 704706f2543Smrg 705706f2543Smrg length = 0; 706706f2543Smrg 707706f2543Smrg for (i = 0; i < count; i++) 708706f2543Smrg { 709706f2543Smrg pScreen = (stuff->n == 0) ? screenInfo.screens[i] : 710706f2543Smrg pDrawables[i]->pScreen; 711706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 712706f2543Smrg 713706f2543Smrg rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 714706f2543Smrg if (rc != Success) 715706f2543Smrg goto freeScrVisInfo; 716706f2543Smrg 717706f2543Smrg if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i])) 718706f2543Smrg { 719706f2543Smrg /* We failed to alloc pScrVisInfo[i].visinfo. */ 720706f2543Smrg rc = BadAlloc; 721706f2543Smrg 722706f2543Smrg /* Free visinfos that we allocated for previous screen infos.*/ 723706f2543Smrg goto freeScrVisInfo; 724706f2543Smrg } 725706f2543Smrg 726706f2543Smrg /* Account for n, number of xDbeVisInfo items in list. */ 727706f2543Smrg length += sizeof(CARD32); 728706f2543Smrg 729706f2543Smrg /* Account for n xDbeVisInfo items */ 730706f2543Smrg length += pScrVisInfo[i].count * sizeof(xDbeVisInfo); 731706f2543Smrg } 732706f2543Smrg 733706f2543Smrg rep.type = X_Reply; 734706f2543Smrg rep.sequenceNumber = client->sequence; 735706f2543Smrg rep.length = bytes_to_int32(length); 736706f2543Smrg rep.m = count; 737706f2543Smrg 738706f2543Smrg if (client->swapped) 739706f2543Smrg { 740706f2543Smrg swaps(&rep.sequenceNumber, n); 741706f2543Smrg swapl(&rep.length, n); 742706f2543Smrg swapl(&rep.m, n); 743706f2543Smrg } 744706f2543Smrg 745706f2543Smrg /* Send off reply. */ 746706f2543Smrg WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep); 747706f2543Smrg 748706f2543Smrg for (i = 0; i < count; i++) 749706f2543Smrg { 750706f2543Smrg CARD32 data32; 751706f2543Smrg 752706f2543Smrg /* For each screen in the reply, send off the visual info */ 753706f2543Smrg 754706f2543Smrg /* Send off number of visuals. */ 755706f2543Smrg data32 = (CARD32)pScrVisInfo[i].count; 756706f2543Smrg 757706f2543Smrg if (client->swapped) 758706f2543Smrg { 759706f2543Smrg swapl(&data32, n); 760706f2543Smrg } 761706f2543Smrg 762706f2543Smrg WriteToClient(client, sizeof(CARD32), (char *)&data32); 763706f2543Smrg 764706f2543Smrg /* Now send off visual info items. */ 765706f2543Smrg for (j = 0; j < pScrVisInfo[i].count; j++) 766706f2543Smrg { 767706f2543Smrg xDbeVisInfo visInfo; 768706f2543Smrg 769706f2543Smrg /* Copy the data in the client data structure to a protocol 770706f2543Smrg * data structure. We will send data to the client from the 771706f2543Smrg * protocol data structure. 772706f2543Smrg */ 773706f2543Smrg 774706f2543Smrg visInfo.visualID = (CARD32)pScrVisInfo[i].visinfo[j].visual; 775706f2543Smrg visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth; 776706f2543Smrg visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel; 777706f2543Smrg 778706f2543Smrg if (client->swapped) 779706f2543Smrg { 780706f2543Smrg swapl(&visInfo.visualID, n); 781706f2543Smrg 782706f2543Smrg /* We do not need to swap depth and perfLevel since they are 783706f2543Smrg * already 1 byte quantities. 784706f2543Smrg */ 785706f2543Smrg } 786706f2543Smrg 787706f2543Smrg /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */ 788706f2543Smrg WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID); 789706f2543Smrg } 790706f2543Smrg } 791706f2543Smrg 792706f2543Smrg rc = Success; 793706f2543Smrg 794706f2543Smrg freeScrVisInfo: 795706f2543Smrg /* Clean up memory. */ 796706f2543Smrg for (i = 0; i < count; i++) 797706f2543Smrg { 798706f2543Smrg free(pScrVisInfo[i].visinfo); 799706f2543Smrg } 800706f2543Smrg free(pScrVisInfo); 801706f2543Smrg 802706f2543Smrg free(pDrawables); 803706f2543Smrg 804706f2543Smrg return rc; 805706f2543Smrg 806706f2543Smrg} /* ProcDbeGetVisualInfo() */ 807706f2543Smrg 808706f2543Smrg 809706f2543Smrg/****************************************************************************** 810706f2543Smrg * 811706f2543Smrg * DBE DIX Procedure: ProcDbeGetbackBufferAttributes 812706f2543Smrg * 813706f2543Smrg * Description: 814706f2543Smrg * 815706f2543Smrg * This function is for processing a ProcDbeGetbackBufferAttributes 816706f2543Smrg * request. This request returns information about a back buffer. 817706f2543Smrg * 818706f2543Smrg * Return Values: 819706f2543Smrg * 820706f2543Smrg * Success 821706f2543Smrg * 822706f2543Smrg *****************************************************************************/ 823706f2543Smrg 824706f2543Smrgstatic int 825706f2543SmrgProcDbeGetBackBufferAttributes(ClientPtr client) 826706f2543Smrg{ 827706f2543Smrg REQUEST(xDbeGetBackBufferAttributesReq); 828706f2543Smrg xDbeGetBackBufferAttributesReply rep; 829706f2543Smrg DbeWindowPrivPtr pDbeWindowPriv; 830706f2543Smrg int rc, n; 831706f2543Smrg 832706f2543Smrg 833706f2543Smrg REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); 834706f2543Smrg 835706f2543Smrg rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer, 836706f2543Smrg dbeWindowPrivResType, client, 837706f2543Smrg DixGetAttrAccess); 838706f2543Smrg if (rc == Success) 839706f2543Smrg { 840706f2543Smrg rep.attributes = pDbeWindowPriv->pWindow->drawable.id; 841706f2543Smrg } 842706f2543Smrg else 843706f2543Smrg { 844706f2543Smrg rep.attributes = None; 845706f2543Smrg } 846706f2543Smrg 847706f2543Smrg rep.type = X_Reply; 848706f2543Smrg rep.sequenceNumber = client->sequence; 849706f2543Smrg rep.length = 0; 850706f2543Smrg 851706f2543Smrg if (client->swapped) 852706f2543Smrg { 853706f2543Smrg swaps(&rep.sequenceNumber, n); 854706f2543Smrg swapl(&rep.length, n); 855706f2543Smrg swapl(&rep.attributes, n); 856706f2543Smrg } 857706f2543Smrg 858706f2543Smrg WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply), 859706f2543Smrg (char *)&rep); 860706f2543Smrg return Success; 861706f2543Smrg 862706f2543Smrg} /* ProcDbeGetbackBufferAttributes() */ 863706f2543Smrg 864706f2543Smrg 865706f2543Smrg/****************************************************************************** 866706f2543Smrg * 867706f2543Smrg * DBE DIX Procedure: ProcDbeDispatch 868706f2543Smrg * 869706f2543Smrg * Description: 870706f2543Smrg * 871706f2543Smrg * This function dispatches DBE requests. 872706f2543Smrg * 873706f2543Smrg *****************************************************************************/ 874706f2543Smrg 875706f2543Smrgstatic int 876706f2543SmrgProcDbeDispatch(ClientPtr client) 877706f2543Smrg{ 878706f2543Smrg REQUEST(xReq); 879706f2543Smrg 880706f2543Smrg 881706f2543Smrg switch (stuff->data) 882706f2543Smrg { 883706f2543Smrg case X_DbeGetVersion: 884706f2543Smrg return(ProcDbeGetVersion(client)); 885706f2543Smrg 886706f2543Smrg case X_DbeAllocateBackBufferName: 887706f2543Smrg return(ProcDbeAllocateBackBufferName(client)); 888706f2543Smrg 889706f2543Smrg case X_DbeDeallocateBackBufferName: 890706f2543Smrg return(ProcDbeDeallocateBackBufferName(client)); 891706f2543Smrg 892706f2543Smrg case X_DbeSwapBuffers: 893706f2543Smrg return(ProcDbeSwapBuffers(client)); 894706f2543Smrg 895706f2543Smrg case X_DbeBeginIdiom: 896706f2543Smrg return(ProcDbeBeginIdiom(client)); 897706f2543Smrg 898706f2543Smrg case X_DbeEndIdiom: 899706f2543Smrg return Success; 900706f2543Smrg 901706f2543Smrg case X_DbeGetVisualInfo: 902706f2543Smrg return(ProcDbeGetVisualInfo(client)); 903706f2543Smrg 904706f2543Smrg case X_DbeGetBackBufferAttributes: 905706f2543Smrg return(ProcDbeGetBackBufferAttributes(client)); 906706f2543Smrg 907706f2543Smrg default: 908706f2543Smrg return BadRequest; 909706f2543Smrg } 910706f2543Smrg 911706f2543Smrg} /* ProcDbeDispatch() */ 912706f2543Smrg 913706f2543Smrg 914706f2543Smrg/****************************************************************************** 915706f2543Smrg * 916706f2543Smrg * DBE DIX Procedure: SProcDbeGetVersion 917706f2543Smrg * 918706f2543Smrg * Description: 919706f2543Smrg * 920706f2543Smrg * This function is for processing a DbeGetVersion request on a swapped 921706f2543Smrg * server. This request returns the major and minor version numbers of 922706f2543Smrg * this extension. 923706f2543Smrg * 924706f2543Smrg * Return Values: 925706f2543Smrg * 926706f2543Smrg * Success 927706f2543Smrg * 928706f2543Smrg *****************************************************************************/ 929706f2543Smrg 930706f2543Smrgstatic int 931706f2543SmrgSProcDbeGetVersion(ClientPtr client) 932706f2543Smrg{ 933706f2543Smrg REQUEST(xDbeGetVersionReq); 934706f2543Smrg register int n; 935706f2543Smrg 936706f2543Smrg 937706f2543Smrg swaps(&stuff->length, n); 938706f2543Smrg return(ProcDbeGetVersion(client)); 939706f2543Smrg 940706f2543Smrg} /* SProcDbeGetVersion() */ 941706f2543Smrg 942706f2543Smrg 943706f2543Smrg/****************************************************************************** 944706f2543Smrg * 945706f2543Smrg * DBE DIX Procedure: SProcDbeAllocateBackBufferName 946706f2543Smrg * 947706f2543Smrg * Description: 948706f2543Smrg * 949706f2543Smrg * This function is for processing a DbeAllocateBackBufferName request on 950706f2543Smrg * a swapped server. This request allocates a drawable ID used to refer 951706f2543Smrg * to the back buffer of a window. 952706f2543Smrg * 953706f2543Smrg * Return Values: 954706f2543Smrg * 955706f2543Smrg * BadAlloc - server can not allocate resources 956706f2543Smrg * BadIDChoice - id is out of range for client; id is already in use 957706f2543Smrg * BadMatch - window is not an InputOutput window; 958706f2543Smrg * visual of window is not on list returned by 959706f2543Smrg * DBEGetVisualInfo; 960706f2543Smrg * BadValue - invalid swap action is specified 961706f2543Smrg * BadWindow - window is not a valid window 962706f2543Smrg * Success 963706f2543Smrg * 964706f2543Smrg *****************************************************************************/ 965706f2543Smrg 966706f2543Smrgstatic int 967706f2543SmrgSProcDbeAllocateBackBufferName(ClientPtr client) 968706f2543Smrg{ 969706f2543Smrg REQUEST(xDbeAllocateBackBufferNameReq); 970706f2543Smrg register int n; 971706f2543Smrg 972706f2543Smrg swaps(&stuff->length, n); 973706f2543Smrg REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); 974706f2543Smrg 975706f2543Smrg swapl(&stuff->window, n); 976706f2543Smrg swapl(&stuff->buffer, n); 977706f2543Smrg /* stuff->swapAction is a byte. We do not need to swap this field. */ 978706f2543Smrg 979706f2543Smrg return(ProcDbeAllocateBackBufferName(client)); 980706f2543Smrg 981706f2543Smrg} /* SProcDbeAllocateBackBufferName() */ 982706f2543Smrg 983706f2543Smrg 984706f2543Smrg/****************************************************************************** 985706f2543Smrg * 986706f2543Smrg * DBE DIX Procedure: SProcDbeDeallocateBackBufferName 987706f2543Smrg * 988706f2543Smrg * Description: 989706f2543Smrg * 990706f2543Smrg * This function is for processing a DbeDeallocateBackBufferName request 991706f2543Smrg * on a swapped server. This request frees a drawable ID that was 992706f2543Smrg * obtained by a DbeAllocateBackBufferName request. 993706f2543Smrg * 994706f2543Smrg * Return Values: 995706f2543Smrg * 996706f2543Smrg * BadBuffer - buffer to deallocate is not associated with a window 997706f2543Smrg * Success 998706f2543Smrg * 999706f2543Smrg *****************************************************************************/ 1000706f2543Smrg 1001706f2543Smrgstatic int 1002706f2543SmrgSProcDbeDeallocateBackBufferName(ClientPtr client) 1003706f2543Smrg{ 1004706f2543Smrg REQUEST (xDbeDeallocateBackBufferNameReq); 1005706f2543Smrg register int n; 1006706f2543Smrg 1007706f2543Smrg 1008706f2543Smrg swaps(&stuff->length, n); 1009706f2543Smrg REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); 1010706f2543Smrg 1011706f2543Smrg swapl(&stuff->buffer, n); 1012706f2543Smrg 1013706f2543Smrg return(ProcDbeDeallocateBackBufferName(client)); 1014706f2543Smrg 1015706f2543Smrg} /* SProcDbeDeallocateBackBufferName() */ 1016706f2543Smrg 1017706f2543Smrg 1018706f2543Smrg/****************************************************************************** 1019706f2543Smrg * 1020706f2543Smrg * DBE DIX Procedure: SProcDbeSwapBuffers 1021706f2543Smrg * 1022706f2543Smrg * Description: 1023706f2543Smrg * 1024706f2543Smrg * This function is for processing a DbeSwapBuffers request on a swapped 1025706f2543Smrg * server. This request swaps the buffers for all windows listed, 1026706f2543Smrg * applying the appropriate swap action for each window. 1027706f2543Smrg * 1028706f2543Smrg * Return Values: 1029706f2543Smrg * 1030706f2543Smrg * BadMatch - a window in request is not double-buffered; a window in 1031706f2543Smrg * request is listed more than once; all windows in request do 1032706f2543Smrg * not have the same root 1033706f2543Smrg * BadValue - invalid swap action is specified 1034706f2543Smrg * BadWindow - a window in request is not valid 1035706f2543Smrg * Success 1036706f2543Smrg * 1037706f2543Smrg *****************************************************************************/ 1038706f2543Smrg 1039706f2543Smrgstatic int 1040706f2543SmrgSProcDbeSwapBuffers(ClientPtr client) 1041706f2543Smrg{ 1042706f2543Smrg REQUEST(xDbeSwapBuffersReq); 1043706f2543Smrg unsigned int i, n; 1044706f2543Smrg xDbeSwapInfo *pSwapInfo; 1045706f2543Smrg 1046706f2543Smrg 1047706f2543Smrg swaps(&stuff->length, n); 1048706f2543Smrg REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); 1049706f2543Smrg 1050706f2543Smrg swapl(&stuff->n, n); 1051706f2543Smrg if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec)) 105248a68b89Smrg return BadLength; 1053706f2543Smrg REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo)); 1054706f2543Smrg 1055706f2543Smrg if (stuff->n != 0) 1056706f2543Smrg { 1057706f2543Smrg pSwapInfo = (xDbeSwapInfo *)stuff+1; 1058706f2543Smrg 1059706f2543Smrg /* The swap info following the fix part of this request is a window(32) 1060706f2543Smrg * followed by a 1 byte swap action and then 3 pad bytes. We only need 1061706f2543Smrg * to swap the window information. 1062706f2543Smrg */ 1063706f2543Smrg for (i = 0; i < stuff->n; i++) 1064706f2543Smrg { 1065706f2543Smrg swapl(&pSwapInfo->window, n); 1066706f2543Smrg } 1067706f2543Smrg } 1068706f2543Smrg 1069706f2543Smrg return(ProcDbeSwapBuffers(client)); 1070706f2543Smrg 1071706f2543Smrg} /* SProcDbeSwapBuffers() */ 1072706f2543Smrg 1073706f2543Smrg 1074706f2543Smrg/****************************************************************************** 1075706f2543Smrg * 1076706f2543Smrg * DBE DIX Procedure: SProcDbeBeginIdiom 1077706f2543Smrg * 1078706f2543Smrg * Description: 1079706f2543Smrg * 1080706f2543Smrg * This function is for processing a DbeBeginIdiom request on a swapped 1081706f2543Smrg * server. This request informs the server that a complex swap will 1082706f2543Smrg * immediately follow this request. 1083706f2543Smrg * 1084706f2543Smrg * Return Values: 1085706f2543Smrg * 1086706f2543Smrg * Success 1087706f2543Smrg * 1088706f2543Smrg *****************************************************************************/ 1089706f2543Smrg 1090706f2543Smrgstatic int 1091706f2543SmrgSProcDbeBeginIdiom(ClientPtr client) 1092706f2543Smrg{ 1093706f2543Smrg REQUEST(xDbeBeginIdiomReq); 1094706f2543Smrg register int n; 1095706f2543Smrg 1096706f2543Smrg swaps(&stuff->length, n); 1097706f2543Smrg return(ProcDbeBeginIdiom(client)); 1098706f2543Smrg 1099706f2543Smrg} /* SProcDbeBeginIdiom() */ 1100706f2543Smrg 1101706f2543Smrg 1102706f2543Smrg/****************************************************************************** 1103706f2543Smrg * 1104706f2543Smrg * DBE DIX Procedure: SProcDbeGetVisualInfo 1105706f2543Smrg * 1106706f2543Smrg * Description: 1107706f2543Smrg * 1108706f2543Smrg * This function is for processing a ProcDbeGetVisualInfo request on a 1109706f2543Smrg * swapped server. This request returns information about which visuals 1110706f2543Smrg * support double buffering. 1111706f2543Smrg * 1112706f2543Smrg * Return Values: 1113706f2543Smrg * 1114706f2543Smrg * BadDrawable - value in screen specifiers is not a valid drawable 1115706f2543Smrg * Success 1116706f2543Smrg * 1117706f2543Smrg *****************************************************************************/ 1118706f2543Smrg 1119706f2543Smrgstatic int 1120706f2543SmrgSProcDbeGetVisualInfo(ClientPtr client) 1121706f2543Smrg{ 1122706f2543Smrg REQUEST(xDbeGetVisualInfoReq); 1123706f2543Smrg register int n; 1124706f2543Smrg 1125706f2543Smrg 1126706f2543Smrg swaps(&stuff->length, n); 1127706f2543Smrg REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); 1128706f2543Smrg 1129706f2543Smrg swapl(&stuff->n, n); 1130706f2543Smrg SwapRestL(stuff); 1131706f2543Smrg 1132706f2543Smrg return(ProcDbeGetVisualInfo(client)); 1133706f2543Smrg 1134706f2543Smrg} /* SProcDbeGetVisualInfo() */ 1135706f2543Smrg 1136706f2543Smrg 1137706f2543Smrg/****************************************************************************** 1138706f2543Smrg * 1139706f2543Smrg * DBE DIX Procedure: SProcDbeGetbackBufferAttributes 1140706f2543Smrg * 1141706f2543Smrg * Description: 1142706f2543Smrg * 1143706f2543Smrg * This function is for processing a ProcDbeGetbackBufferAttributes 1144706f2543Smrg * request on a swapped server. This request returns information about a 1145706f2543Smrg * back buffer. 1146706f2543Smrg * 1147706f2543Smrg * Return Values: 1148706f2543Smrg * 1149706f2543Smrg * Success 1150706f2543Smrg * 1151706f2543Smrg *****************************************************************************/ 1152706f2543Smrg 1153706f2543Smrgstatic int 1154706f2543SmrgSProcDbeGetBackBufferAttributes(ClientPtr client) 1155706f2543Smrg{ 1156706f2543Smrg REQUEST (xDbeGetBackBufferAttributesReq); 1157706f2543Smrg register int n; 1158706f2543Smrg 1159706f2543Smrg swaps(&stuff->length, n); 1160706f2543Smrg REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); 1161706f2543Smrg 1162706f2543Smrg swapl(&stuff->buffer, n); 1163706f2543Smrg 1164706f2543Smrg return(ProcDbeGetBackBufferAttributes(client)); 1165706f2543Smrg 1166706f2543Smrg} /* SProcDbeGetBackBufferAttributes() */ 1167706f2543Smrg 1168706f2543Smrg 1169706f2543Smrg/****************************************************************************** 1170706f2543Smrg * 1171706f2543Smrg * DBE DIX Procedure: SProcDbeDispatch 1172706f2543Smrg * 1173706f2543Smrg * Description: 1174706f2543Smrg * 1175706f2543Smrg * This function dispatches DBE requests on a swapped server. 1176706f2543Smrg * 1177706f2543Smrg *****************************************************************************/ 1178706f2543Smrg 1179706f2543Smrgstatic int 1180706f2543SmrgSProcDbeDispatch(ClientPtr client) 1181706f2543Smrg{ 1182706f2543Smrg REQUEST(xReq); 1183706f2543Smrg 1184706f2543Smrg 1185706f2543Smrg switch (stuff->data) 1186706f2543Smrg { 1187706f2543Smrg case X_DbeGetVersion: 1188706f2543Smrg return(SProcDbeGetVersion(client)); 1189706f2543Smrg 1190706f2543Smrg case X_DbeAllocateBackBufferName: 1191706f2543Smrg return(SProcDbeAllocateBackBufferName(client)); 1192706f2543Smrg 1193706f2543Smrg case X_DbeDeallocateBackBufferName: 1194706f2543Smrg return(SProcDbeDeallocateBackBufferName(client)); 1195706f2543Smrg 1196706f2543Smrg case X_DbeSwapBuffers: 1197706f2543Smrg return(SProcDbeSwapBuffers(client)); 1198706f2543Smrg 1199706f2543Smrg case X_DbeBeginIdiom: 1200706f2543Smrg return(SProcDbeBeginIdiom(client)); 1201706f2543Smrg 1202706f2543Smrg case X_DbeEndIdiom: 1203706f2543Smrg return Success; 1204706f2543Smrg 1205706f2543Smrg case X_DbeGetVisualInfo: 1206706f2543Smrg return(SProcDbeGetVisualInfo(client)); 1207706f2543Smrg 1208706f2543Smrg case X_DbeGetBackBufferAttributes: 1209706f2543Smrg return(SProcDbeGetBackBufferAttributes(client)); 1210706f2543Smrg 1211706f2543Smrg default: 1212706f2543Smrg return BadRequest; 1213706f2543Smrg } 1214706f2543Smrg 1215706f2543Smrg} /* SProcDbeDispatch() */ 1216706f2543Smrg 1217706f2543Smrg 1218706f2543Smrg/****************************************************************************** 1219706f2543Smrg * 1220706f2543Smrg * DBE DIX Procedure: DbeSetupBackgroundPainter 1221706f2543Smrg * 1222706f2543Smrg * Description: 1223706f2543Smrg * 1224706f2543Smrg * This function sets up pGC to clear pixmaps. 1225706f2543Smrg * 1226706f2543Smrg * Return Values: 1227706f2543Smrg * 1228706f2543Smrg * TRUE - setup was successful 1229706f2543Smrg * FALSE - the window's background state is NONE 1230706f2543Smrg * 1231706f2543Smrg *****************************************************************************/ 1232706f2543Smrg 1233706f2543Smrgstatic Bool 1234706f2543SmrgDbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC) 1235706f2543Smrg{ 1236706f2543Smrg ChangeGCVal gcvalues[4]; 1237706f2543Smrg int ts_x_origin, ts_y_origin; 1238706f2543Smrg PixUnion background; 1239706f2543Smrg int backgroundState; 1240706f2543Smrg Mask gcmask; 1241706f2543Smrg 1242706f2543Smrg 1243706f2543Smrg /* First take care of any ParentRelative stuff by altering the 1244706f2543Smrg * tile/stipple origin to match the coordinates of the upper-left 1245706f2543Smrg * corner of the first ancestor without a ParentRelative background. 1246706f2543Smrg * This coordinate is, of course, negative. 1247706f2543Smrg */ 1248706f2543Smrg ts_x_origin = ts_y_origin = 0; 1249706f2543Smrg while (pWin->backgroundState == ParentRelative) 1250706f2543Smrg { 1251706f2543Smrg ts_x_origin -= pWin->origin.x; 1252706f2543Smrg ts_y_origin -= pWin->origin.y; 1253706f2543Smrg 1254706f2543Smrg pWin = pWin->parent; 1255706f2543Smrg } 1256706f2543Smrg backgroundState = pWin->backgroundState; 1257706f2543Smrg background = pWin->background; 1258706f2543Smrg 1259706f2543Smrg switch (backgroundState) 1260706f2543Smrg { 1261706f2543Smrg case BackgroundPixel: 1262706f2543Smrg gcvalues[0].val = background.pixel; 1263706f2543Smrg gcvalues[1].val = FillSolid; 1264706f2543Smrg gcmask = GCForeground|GCFillStyle; 1265706f2543Smrg break; 1266706f2543Smrg 1267706f2543Smrg case BackgroundPixmap: 1268706f2543Smrg gcvalues[0].val = FillTiled; 1269706f2543Smrg gcvalues[1].ptr = background.pixmap; 1270706f2543Smrg gcvalues[2].val = ts_x_origin; 1271706f2543Smrg gcvalues[3].val = ts_y_origin; 1272706f2543Smrg gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin; 1273706f2543Smrg break; 1274706f2543Smrg 1275706f2543Smrg default: 1276706f2543Smrg /* pWin->backgroundState == None */ 1277706f2543Smrg return FALSE; 1278706f2543Smrg } 1279706f2543Smrg 1280706f2543Smrg return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0; 1281706f2543Smrg} /* DbeSetupBackgroundPainter() */ 1282706f2543Smrg 1283706f2543Smrg 1284706f2543Smrg/****************************************************************************** 1285706f2543Smrg * 1286706f2543Smrg * DBE DIX Procedure: DbeDrawableDelete 1287706f2543Smrg * 1288706f2543Smrg * Description: 1289706f2543Smrg * 1290706f2543Smrg * This is the resource delete function for dbeDrawableResType. 1291706f2543Smrg * It is registered when the drawable resource type is created in 1292706f2543Smrg * DbeExtensionInit(). 1293706f2543Smrg * 1294706f2543Smrg * To make resource deletion simple, we do not do anything in this function 1295706f2543Smrg * and leave all resource deleteion to DbeWindowPrivDelete(), which will 1296706f2543Smrg * eventually be called or already has been called. Deletion functions are 1297706f2543Smrg * not guaranteed to be called in any particular order. 1298706f2543Smrg * 1299706f2543Smrg *****************************************************************************/ 1300706f2543Smrgstatic int 1301706f2543SmrgDbeDrawableDelete(pointer pDrawable, XID id) 1302706f2543Smrg{ 1303706f2543Smrg return Success; 1304706f2543Smrg 1305706f2543Smrg} /* DbeDrawableDelete() */ 1306706f2543Smrg 1307706f2543Smrg 1308706f2543Smrg/****************************************************************************** 1309706f2543Smrg * 1310706f2543Smrg * DBE DIX Procedure: DbeWindowPrivDelete 1311706f2543Smrg * 1312706f2543Smrg * Description: 1313706f2543Smrg * 1314706f2543Smrg * This is the resource delete function for dbeWindowPrivResType. 1315706f2543Smrg * It is registered when the drawable resource type is created in 1316706f2543Smrg * DbeExtensionInit(). 1317706f2543Smrg * 1318706f2543Smrg *****************************************************************************/ 1319706f2543Smrgstatic int 1320706f2543SmrgDbeWindowPrivDelete(pointer pDbeWinPriv, XID id) 1321706f2543Smrg{ 1322706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 1323706f2543Smrg DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv; 1324706f2543Smrg int i; 1325706f2543Smrg 1326706f2543Smrg 1327706f2543Smrg /* 1328706f2543Smrg ************************************************************************** 1329706f2543Smrg ** Remove the buffer ID from the ID array. 1330706f2543Smrg ************************************************************************** 1331706f2543Smrg */ 1332706f2543Smrg 1333706f2543Smrg /* Find the ID in the ID array. */ 1334706f2543Smrg i = 0; 1335706f2543Smrg while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id)) 1336706f2543Smrg { 1337706f2543Smrg i++; 1338706f2543Smrg } 1339706f2543Smrg 1340706f2543Smrg if (i == pDbeWindowPriv->nBufferIDs) 1341706f2543Smrg { 1342706f2543Smrg /* We did not find the ID in the array. We should never get here. */ 1343706f2543Smrg return BadValue; 1344706f2543Smrg } 1345706f2543Smrg 1346706f2543Smrg /* Remove the ID from the array. */ 1347706f2543Smrg 1348706f2543Smrg if (i < (pDbeWindowPriv->nBufferIDs - 1)) 1349706f2543Smrg { 1350706f2543Smrg /* Compress the buffer ID array, overwriting the ID in the process. */ 1351706f2543Smrg memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1], 1352706f2543Smrg (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID)); 1353706f2543Smrg } 1354706f2543Smrg else 1355706f2543Smrg { 1356706f2543Smrg /* We are removing the last ID in the array, in which case, the 1357706f2543Smrg * assignement below is all that we need to do. 1358706f2543Smrg */ 1359706f2543Smrg } 1360706f2543Smrg pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT; 1361706f2543Smrg 1362706f2543Smrg pDbeWindowPriv->nBufferIDs--; 1363706f2543Smrg 1364706f2543Smrg /* If an extended array was allocated, then check to see if the remaining 1365706f2543Smrg * buffer IDs will fit in the static array. 1366706f2543Smrg */ 1367706f2543Smrg 1368706f2543Smrg if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) && 1369706f2543Smrg (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS)) 1370706f2543Smrg { 1371706f2543Smrg /* Copy the IDs back into the static array. */ 1372706f2543Smrg memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs, 1373706f2543Smrg DBE_INIT_MAX_IDS * sizeof(XID)); 1374706f2543Smrg 1375706f2543Smrg /* Free the extended array; use the static array. */ 1376706f2543Smrg free(pDbeWindowPriv->IDs); 1377706f2543Smrg pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; 1378706f2543Smrg pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; 1379706f2543Smrg } 1380706f2543Smrg 1381706f2543Smrg 1382706f2543Smrg /* 1383706f2543Smrg ************************************************************************** 1384706f2543Smrg ** Perform DDX level tasks. 1385706f2543Smrg ************************************************************************** 1386706f2543Smrg */ 1387706f2543Smrg 1388706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV( 1389706f2543Smrg (DbeWindowPrivPtr)pDbeWindowPriv); 1390706f2543Smrg (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id); 1391706f2543Smrg 1392706f2543Smrg 1393706f2543Smrg /* 1394706f2543Smrg ************************************************************************** 1395706f2543Smrg ** Perform miscellaneous tasks if this is the last buffer associated 1396706f2543Smrg ** with the window. 1397706f2543Smrg ************************************************************************** 1398706f2543Smrg */ 1399706f2543Smrg 1400706f2543Smrg if (pDbeWindowPriv->nBufferIDs == 0) 1401706f2543Smrg { 1402706f2543Smrg /* Reset the DBE window priv pointer. */ 1403706f2543Smrg dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey, 1404706f2543Smrg NULL); 1405706f2543Smrg 1406706f2543Smrg /* We are done with the window priv. */ 1407706f2543Smrg dixFreeObjectWithPrivates(pDbeWindowPriv, PRIVATE_DBE_WINDOW); 1408706f2543Smrg } 1409706f2543Smrg 1410706f2543Smrg return Success; 1411706f2543Smrg 1412706f2543Smrg} /* DbeWindowPrivDelete() */ 1413706f2543Smrg 1414706f2543Smrg 1415706f2543Smrg/****************************************************************************** 1416706f2543Smrg * 1417706f2543Smrg * DBE DIX Procedure: DbeResetProc 1418706f2543Smrg * 1419706f2543Smrg * Description: 1420706f2543Smrg * 1421706f2543Smrg * This routine is called at the end of every server generation. 1422706f2543Smrg * It deallocates any memory reserved for the extension and performs any 1423706f2543Smrg * other tasks related to shutting down the extension. 1424706f2543Smrg * 1425706f2543Smrg *****************************************************************************/ 1426706f2543Smrgstatic void 1427706f2543SmrgDbeResetProc(ExtensionEntry *extEntry) 1428706f2543Smrg{ 1429706f2543Smrg int i; 1430706f2543Smrg ScreenPtr pScreen; 1431706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 1432706f2543Smrg 1433706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) 1434706f2543Smrg { 1435706f2543Smrg pScreen = screenInfo.screens[i]; 1436706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1437706f2543Smrg 1438706f2543Smrg if (pDbeScreenPriv) 1439706f2543Smrg { 1440706f2543Smrg /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/ 1441706f2543Smrg pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; 1442706f2543Smrg 1443706f2543Smrg if (pDbeScreenPriv->ResetProc) 1444706f2543Smrg (*pDbeScreenPriv->ResetProc)(pScreen); 1445706f2543Smrg 1446706f2543Smrg free(pDbeScreenPriv); 1447706f2543Smrg } 1448706f2543Smrg } 1449706f2543Smrg} /* DbeResetProc() */ 1450706f2543Smrg 1451706f2543Smrg 1452706f2543Smrg/****************************************************************************** 1453706f2543Smrg * 1454706f2543Smrg * DBE DIX Procedure: DbeDestroyWindow 1455706f2543Smrg * 1456706f2543Smrg * Description: 1457706f2543Smrg * 1458706f2543Smrg * This is the wrapper for pScreen->DestroyWindow. 1459706f2543Smrg * This function frees buffer resources for a window before it is 1460706f2543Smrg * destroyed. 1461706f2543Smrg * 1462706f2543Smrg *****************************************************************************/ 1463706f2543Smrg 1464706f2543Smrgstatic Bool 1465706f2543SmrgDbeDestroyWindow(WindowPtr pWin) 1466706f2543Smrg{ 1467706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 1468706f2543Smrg DbeWindowPrivPtr pDbeWindowPriv; 1469706f2543Smrg ScreenPtr pScreen; 1470706f2543Smrg Bool ret; 1471706f2543Smrg 1472706f2543Smrg 1473706f2543Smrg /* 1474706f2543Smrg ************************************************************************** 1475706f2543Smrg ** 1. Unwrap the member routine. 1476706f2543Smrg ************************************************************************** 1477706f2543Smrg */ 1478706f2543Smrg 1479706f2543Smrg pScreen = pWin->drawable.pScreen; 1480706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1481706f2543Smrg pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; 1482706f2543Smrg 1483706f2543Smrg /* 1484706f2543Smrg ************************************************************************** 1485706f2543Smrg ** 2. Do any work necessary before the member routine is called. 1486706f2543Smrg ** 1487706f2543Smrg ** Call the window priv delete function for all buffer IDs associated 1488706f2543Smrg ** with this window. 1489706f2543Smrg ************************************************************************** 1490706f2543Smrg */ 1491706f2543Smrg 1492706f2543Smrg if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) 1493706f2543Smrg { 1494706f2543Smrg while (pDbeWindowPriv) 1495706f2543Smrg { 1496706f2543Smrg /* *DbeWinPrivDelete() will free the window private and set it to 1497706f2543Smrg * NULL if there are no more buffer IDs associated with this 1498706f2543Smrg * window. 1499706f2543Smrg */ 1500706f2543Smrg FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); 1501706f2543Smrg pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 1502706f2543Smrg } 1503706f2543Smrg } 1504706f2543Smrg 1505706f2543Smrg /* 1506706f2543Smrg ************************************************************************** 1507706f2543Smrg ** 3. Call the member routine, saving its result if necessary. 1508706f2543Smrg ************************************************************************** 1509706f2543Smrg */ 1510706f2543Smrg 1511706f2543Smrg ret = (*pScreen->DestroyWindow)(pWin); 1512706f2543Smrg 1513706f2543Smrg /* 1514706f2543Smrg ************************************************************************** 1515706f2543Smrg ** 4. Rewrap the member routine, restoring the wrapper value first in case 1516706f2543Smrg ** the wrapper (or something that it wrapped) change this value. 1517706f2543Smrg ************************************************************************** 1518706f2543Smrg */ 1519706f2543Smrg 1520706f2543Smrg pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; 1521706f2543Smrg pScreen->DestroyWindow = DbeDestroyWindow; 1522706f2543Smrg 1523706f2543Smrg /* 1524706f2543Smrg ************************************************************************** 1525706f2543Smrg ** 5. Do any work necessary after the member routine has been called. 1526706f2543Smrg ** 1527706f2543Smrg ** In this case we do not need to do anything. 1528706f2543Smrg ************************************************************************** 1529706f2543Smrg */ 1530706f2543Smrg 1531706f2543Smrg return ret; 1532706f2543Smrg 1533706f2543Smrg} /* DbeDestroyWindow() */ 1534706f2543Smrg 1535706f2543Smrg 1536706f2543Smrg/****************************************************************************** 1537706f2543Smrg * 1538706f2543Smrg * DBE DIX Procedure: DbeExtensionInit 1539706f2543Smrg * 1540706f2543Smrg * Description: 1541706f2543Smrg * 1542706f2543Smrg * Called from InitExtensions in main() 1543706f2543Smrg * 1544706f2543Smrg *****************************************************************************/ 1545706f2543Smrg 1546706f2543Smrgvoid 1547706f2543SmrgDbeExtensionInit(void) 1548706f2543Smrg{ 1549706f2543Smrg ExtensionEntry *extEntry; 1550706f2543Smrg register int i, j; 1551706f2543Smrg ScreenPtr pScreen = NULL; 1552706f2543Smrg DbeScreenPrivPtr pDbeScreenPriv; 1553706f2543Smrg int nStubbedScreens = 0; 1554706f2543Smrg Bool ddxInitSuccess; 1555706f2543Smrg 1556706f2543Smrg#ifdef PANORAMIX 1557706f2543Smrg if(!noPanoramiXExtension) return; 1558706f2543Smrg#endif 1559706f2543Smrg 1560706f2543Smrg /* Create the resource types. */ 1561706f2543Smrg dbeDrawableResType = 1562706f2543Smrg CreateNewResourceType(DbeDrawableDelete, "dbeDrawable"); 1563706f2543Smrg if (!dbeDrawableResType) 1564706f2543Smrg return; 1565706f2543Smrg dbeDrawableResType |= RC_DRAWABLE; 1566706f2543Smrg 1567706f2543Smrg dbeWindowPrivResType = 1568706f2543Smrg CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow"); 1569706f2543Smrg if (!dbeWindowPrivResType) 1570706f2543Smrg return; 1571706f2543Smrg 1572706f2543Smrg if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0)) 1573706f2543Smrg return; 1574706f2543Smrg 1575706f2543Smrg if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0)) 1576706f2543Smrg return; 1577706f2543Smrg 1578706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) 1579706f2543Smrg { 1580706f2543Smrg /* For each screen, set up DBE screen privates and init DIX and DDX 1581706f2543Smrg * interface. 1582706f2543Smrg */ 1583706f2543Smrg 1584706f2543Smrg pScreen = screenInfo.screens[i]; 1585706f2543Smrg 1586706f2543Smrg if (!(pDbeScreenPriv = malloc (sizeof (DbeScreenPrivRec)))) 1587706f2543Smrg { 1588706f2543Smrg /* If we can not alloc a window or screen private, 1589706f2543Smrg * then free any privates that we already alloc'ed and return 1590706f2543Smrg */ 1591706f2543Smrg 1592706f2543Smrg for (j = 0; j < i; j++) 1593706f2543Smrg { 1594706f2543Smrg free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates, 1595706f2543Smrg dbeScreenPrivKey)); 1596706f2543Smrg dixSetPrivate(&screenInfo.screens[j]->devPrivates, 1597706f2543Smrg dbeScreenPrivKey, NULL); 1598706f2543Smrg } 1599706f2543Smrg return; 1600706f2543Smrg } 1601706f2543Smrg 1602706f2543Smrg dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv); 1603706f2543Smrg 1604706f2543Smrg { 1605706f2543Smrg /* We don't have DDX support for DBE anymore */ 1606706f2543Smrg 1607706f2543Smrg#ifndef DISABLE_MI_DBE_BY_DEFAULT 1608706f2543Smrg /* Setup DIX. */ 1609706f2543Smrg pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter; 1610706f2543Smrg 1611706f2543Smrg /* Setup DDX. */ 1612706f2543Smrg ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv); 1613706f2543Smrg 1614706f2543Smrg /* DDX DBE initialization may have the side affect of 1615706f2543Smrg * reallocating pDbeScreenPriv, so we need to update it. 1616706f2543Smrg */ 1617706f2543Smrg pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1618706f2543Smrg 1619706f2543Smrg if (ddxInitSuccess) 1620706f2543Smrg { 1621706f2543Smrg /* Wrap DestroyWindow. The DDX initialization function 1622706f2543Smrg * already wrapped PositionWindow for us. 1623706f2543Smrg */ 1624706f2543Smrg 1625706f2543Smrg pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; 1626706f2543Smrg pScreen->DestroyWindow = DbeDestroyWindow; 1627706f2543Smrg } 1628706f2543Smrg else 1629706f2543Smrg { 1630706f2543Smrg /* DDX initialization failed. Stub the screen. */ 1631706f2543Smrg DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); 1632706f2543Smrg } 1633706f2543Smrg#else 1634706f2543Smrg DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); 1635706f2543Smrg#endif 1636706f2543Smrg 1637706f2543Smrg } 1638706f2543Smrg 1639706f2543Smrg } /* for (i = 0; i < screenInfo.numScreens; i++) */ 1640706f2543Smrg 1641706f2543Smrg 1642706f2543Smrg if (nStubbedScreens == screenInfo.numScreens) 1643706f2543Smrg { 1644706f2543Smrg /* All screens stubbed. Clean up and return. */ 1645706f2543Smrg 1646706f2543Smrg for (i = 0; i < screenInfo.numScreens; i++) 1647706f2543Smrg { 1648706f2543Smrg free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates, 1649706f2543Smrg dbeScreenPrivKey)); 1650706f2543Smrg dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL); 1651706f2543Smrg } 1652706f2543Smrg return; 1653706f2543Smrg } 1654706f2543Smrg 1655706f2543Smrg 1656706f2543Smrg /* Now add the extension. */ 1657706f2543Smrg extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents, 1658706f2543Smrg DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch, 1659706f2543Smrg DbeResetProc, StandardMinorOpcode); 1660706f2543Smrg 1661706f2543Smrg dbeErrorBase = extEntry->errorBase; 1662706f2543Smrg SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer); 1663706f2543Smrg SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer); 1664706f2543Smrg 1665706f2543Smrg} /* DbeExtensionInit() */ 1666706f2543Smrg 1667