dbe.c revision 48a68b89
1/****************************************************************************** 2 * 3 * Copyright (c) 1994, 1995 Hewlett-Packard Company 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 22 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Except as contained in this notice, the name of the Hewlett-Packard 25 * Company shall not be used in advertising or otherwise to promote the 26 * sale, use or other dealings in this Software without prior written 27 * authorization from the Hewlett-Packard Company. 28 * 29 * DIX DBE code 30 * 31 *****************************************************************************/ 32 33 34/* INCLUDES */ 35 36#ifdef HAVE_DIX_CONFIG_H 37#include <dix-config.h> 38#endif 39 40#include <string.h> 41#if HAVE_STDINT_H 42#include <stdint.h> 43#elif !defined(UINT32_MAX) 44#define UINT32_MAX 0xffffffffU 45#endif 46 47#include <X11/X.h> 48#include <X11/Xproto.h> 49#include "scrnintstr.h" 50#include "extnsionst.h" 51#include "gcstruct.h" 52#include "dixstruct.h" 53#define NEED_DBE_PROTOCOL 54#include "dbestruct.h" 55#include "midbe.h" 56#include "xace.h" 57 58/* GLOBALS */ 59 60/* These are globals for use by DDX */ 61DevPrivateKeyRec dbeScreenPrivKeyRec; 62DevPrivateKeyRec dbeWindowPrivKeyRec; 63 64/* These are globals for use by DDX */ 65RESTYPE dbeDrawableResType; 66RESTYPE dbeWindowPrivResType; 67 68/* Used to generate DBE's BadBuffer error. */ 69static int dbeErrorBase; 70 71/****************************************************************************** 72 * 73 * DBE DIX Procedure: DbeStubScreen 74 * 75 * Description: 76 * 77 * This is function stubs the function pointers in the given DBE screen 78 * private and increments the number of stubbed screens. 79 * 80 *****************************************************************************/ 81 82static void 83DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens) 84{ 85 /* Stub DIX. */ 86 pDbeScreenPriv->SetupBackgroundPainter = NULL; 87 88 /* Do not unwrap PositionWindow nor DestroyWindow. If the DDX 89 * initialization function failed, we assume that it did not wrap 90 * PositionWindow. Also, DestroyWindow is only wrapped if the DDX 91 * initialization function succeeded. 92 */ 93 94 /* Stub DDX. */ 95 pDbeScreenPriv->GetVisualInfo = NULL; 96 pDbeScreenPriv->AllocBackBufferName = NULL; 97 pDbeScreenPriv->SwapBuffers = NULL; 98 pDbeScreenPriv->BeginIdiom = NULL; 99 pDbeScreenPriv->EndIdiom = NULL; 100 pDbeScreenPriv->WinPrivDelete = NULL; 101 pDbeScreenPriv->ResetProc = NULL; 102 103 (*nStubbedScreens)++; 104 105} /* DbeStubScreen() */ 106 107 108 109/****************************************************************************** 110 * 111 * DBE DIX Procedure: ProcDbeGetVersion 112 * 113 * Description: 114 * 115 * This function is for processing a DbeGetVersion request. 116 * This request returns the major and minor version numbers of this 117 * extension. 118 * 119 * Return Values: 120 * 121 * Success 122 * 123 *****************************************************************************/ 124 125static int 126ProcDbeGetVersion(ClientPtr client) 127{ 128 /* REQUEST(xDbeGetVersionReq); */ 129 xDbeGetVersionReply rep; 130 register int n; 131 132 133 REQUEST_SIZE_MATCH(xDbeGetVersionReq); 134 135 rep.type = X_Reply; 136 rep.length = 0; 137 rep.sequenceNumber = client->sequence; 138 rep.majorVersion = DBE_MAJOR_VERSION; 139 rep.minorVersion = DBE_MINOR_VERSION; 140 141 if (client->swapped) 142 { 143 swaps(&rep.sequenceNumber, n); 144 } 145 146 WriteToClient(client, sizeof(xDbeGetVersionReply), (char *)&rep); 147 148 return Success; 149 150} /* ProcDbeGetVersion() */ 151 152 153/****************************************************************************** 154 * 155 * DBE DIX Procedure: ProcDbeAllocateBackBufferName 156 * 157 * Description: 158 * 159 * This function is for processing a DbeAllocateBackBufferName request. 160 * This request allocates a drawable ID used to refer to the back buffer 161 * of a window. 162 * 163 * Return Values: 164 * 165 * BadAlloc - server can not allocate resources 166 * BadIDChoice - id is out of range for client; id is already in use 167 * BadMatch - window is not an InputOutput window; 168 * visual of window is not on list returned by 169 * DBEGetVisualInfo; 170 * BadValue - invalid swap action is specified 171 * BadWindow - window is not a valid window 172 * Success 173 * 174 *****************************************************************************/ 175 176static int 177ProcDbeAllocateBackBufferName(ClientPtr client) 178{ 179 REQUEST(xDbeAllocateBackBufferNameReq); 180 WindowPtr pWin; 181 DbeScreenPrivPtr pDbeScreenPriv; 182 DbeWindowPrivPtr pDbeWindowPriv; 183 XdbeScreenVisualInfo scrVisInfo; 184 register int i; 185 Bool visualMatched = FALSE; 186 xDbeSwapAction swapAction; 187 VisualID visual; 188 int status; 189 int add_index; 190 191 192 REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); 193 194 /* The window must be valid. */ 195 status = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 196 if (status != Success) 197 return status; 198 199 /* The window must be InputOutput. */ 200 if (pWin->drawable.class != InputOutput) 201 { 202 return BadMatch; 203 } 204 205 /* The swap action must be valid. */ 206 swapAction = stuff->swapAction; /* use local var for performance. */ 207 if ((swapAction != XdbeUndefined ) && 208 (swapAction != XdbeBackground) && 209 (swapAction != XdbeUntouched ) && 210 (swapAction != XdbeCopied )) 211 { 212 return BadValue; 213 } 214 215 /* The id must be in range and not already in use. */ 216 LEGAL_NEW_RESOURCE(stuff->buffer, client); 217 218 /* The visual of the window must be in the list returned by 219 * GetVisualInfo. 220 */ 221 pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin); 222 if (!pDbeScreenPriv->GetVisualInfo) 223 return BadMatch; /* screen doesn't support double buffering */ 224 225 if (!(*pDbeScreenPriv->GetVisualInfo)(pWin->drawable.pScreen, &scrVisInfo)) 226 { 227 /* GetVisualInfo() failed to allocate visual info data. */ 228 return BadAlloc; 229 } 230 231 /* See if the window's visual is on the list. */ 232 visual = wVisual(pWin); 233 for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++) 234 { 235 if (scrVisInfo.visinfo[i].visual == visual) 236 { 237 visualMatched = TRUE; 238 } 239 } 240 241 /* Free what was allocated by the GetVisualInfo() call above. */ 242 free(scrVisInfo.visinfo); 243 244 if (!visualMatched) 245 { 246 return BadMatch; 247 } 248 249 if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL) 250 { 251 /* There is no buffer associated with the window. 252 * Allocate a window priv. 253 */ 254 255 pDbeWindowPriv = dixAllocateObjectWithPrivates(DbeWindowPrivRec, PRIVATE_DBE_WINDOW); 256 if (!pDbeWindowPriv) 257 return BadAlloc; 258 259 /* Fill out window priv information. */ 260 pDbeWindowPriv->pWindow = pWin; 261 pDbeWindowPriv->width = pWin->drawable.width; 262 pDbeWindowPriv->height = pWin->drawable.height; 263 pDbeWindowPriv->x = pWin->drawable.x; 264 pDbeWindowPriv->y = pWin->drawable.y; 265 pDbeWindowPriv->nBufferIDs = 0; 266 267 /* Set the buffer ID array pointer to the initial (static) array). */ 268 pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; 269 270 /* Initialize the buffer ID list. */ 271 pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; 272 pDbeWindowPriv->IDs[0] = stuff->buffer; 273 274 add_index = 0; 275 for (i = 0; i < DBE_INIT_MAX_IDS; i++) 276 { 277 pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT; 278 } 279 280 /* Actually connect the window priv to the window. */ 281 dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv); 282 283 } /* if -- There is no buffer associated with the window. */ 284 285 else 286 { 287 /* A buffer is already associated with the window. 288 * Add the new buffer ID to the array, reallocating the array memory 289 * if necessary. 290 */ 291 292 /* Determine if there is a free element in the ID array. */ 293 for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++) 294 { 295 if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT) 296 { 297 /* There is still room in the ID array. */ 298 break; 299 } 300 } 301 302 if (i == pDbeWindowPriv->maxAvailableIDs) 303 { 304 /* No more room in the ID array -- reallocate another array. */ 305 XID *pIDs; 306 307 /* Setup an array pointer for the realloc operation below. */ 308 if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) 309 { 310 /* We will malloc a new array. */ 311 pIDs = NULL; 312 } 313 else 314 { 315 /* We will realloc a new array. */ 316 pIDs = pDbeWindowPriv->IDs; 317 } 318 319 /* malloc/realloc a new array and initialize all elements to 0. */ 320 pDbeWindowPriv->IDs = (XID *)realloc(pIDs, 321 (pDbeWindowPriv->maxAvailableIDs+DBE_INCR_MAX_IDS)*sizeof(XID)); 322 if (!pDbeWindowPriv->IDs) 323 { 324 return BadAlloc; 325 } 326 memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0, 327 (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS - 328 pDbeWindowPriv->nBufferIDs) * sizeof(XID)); 329 330 if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) 331 { 332 /* We just went from using the initial (static) array to a 333 * newly allocated array. Copy the IDs from the initial array 334 * to the new array. 335 */ 336 memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs, 337 DBE_INIT_MAX_IDS * sizeof(XID)); 338 } 339 340 pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS; 341 } 342 343 add_index = i; 344 345 } /* else -- A buffer is already associated with the window. */ 346 347 348 /* Call the DDX routine to allocate the back buffer. */ 349 status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer, 350 stuff->swapAction); 351 352 if (status == Success) 353 { 354 pDbeWindowPriv->IDs[add_index] = stuff->buffer; 355 if (!AddResource(stuff->buffer, dbeWindowPrivResType, 356 (pointer)pDbeWindowPriv)) 357 { 358 pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT; 359 360 if (pDbeWindowPriv->nBufferIDs == 0) { 361 status = BadAlloc; 362 goto out_free; 363 } 364 } 365 } else { 366 /* The DDX buffer allocation routine failed for the first buffer of 367 * this window. 368 */ 369 if (pDbeWindowPriv->nBufferIDs == 0) { 370 goto out_free; 371 } 372 } 373 374 /* Increment the number of buffers (XIDs) associated with this window. */ 375 pDbeWindowPriv->nBufferIDs++; 376 377 /* Set swap action on all calls. */ 378 pDbeWindowPriv->swapAction = stuff->swapAction; 379 380 return status; 381 382out_free: 383 dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL); 384 free(pDbeWindowPriv); 385 return status; 386 387} /* ProcDbeAllocateBackBufferName() */ 388 389 390/****************************************************************************** 391 * 392 * DBE DIX Procedure: ProcDbeDeallocateBackBufferName 393 * 394 * Description: 395 * 396 * This function is for processing a DbeDeallocateBackBufferName request. 397 * This request frees a drawable ID that was obtained by a 398 * DbeAllocateBackBufferName request. 399 * 400 * Return Values: 401 * 402 * BadBuffer - buffer to deallocate is not associated with a window 403 * Success 404 * 405 *****************************************************************************/ 406 407static int 408ProcDbeDeallocateBackBufferName(ClientPtr client) 409{ 410 REQUEST(xDbeDeallocateBackBufferNameReq); 411 DbeWindowPrivPtr pDbeWindowPriv; 412 int rc, i; 413 pointer val; 414 415 416 REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); 417 418 /* Buffer name must be valid */ 419 rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer, 420 dbeWindowPrivResType, client, 421 DixDestroyAccess); 422 if (rc != Success) 423 return rc; 424 425 rc = dixLookupResourceByType(&val, stuff->buffer, dbeDrawableResType, 426 client, DixDestroyAccess); 427 if (rc != Success) 428 return rc; 429 430 /* Make sure that the id is valid for the window. 431 * This is paranoid code since we already looked up the ID by type 432 * above. 433 */ 434 435 for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) 436 { 437 /* Loop through the ID list to find the ID. */ 438 if (pDbeWindowPriv->IDs[i] == stuff->buffer) 439 { 440 break; 441 } 442 } 443 444 if (i == pDbeWindowPriv->nBufferIDs) 445 { 446 /* We did not find the ID in the ID list. */ 447 client->errorValue = stuff->buffer; 448 return dbeErrorBase + DbeBadBuffer; 449 } 450 451 FreeResource(stuff->buffer, RT_NONE); 452 453 return Success; 454 455} /* ProcDbeDeallocateBackBufferName() */ 456 457 458/****************************************************************************** 459 * 460 * DBE DIX Procedure: ProcDbeSwapBuffers 461 * 462 * Description: 463 * 464 * This function is for processing a DbeSwapBuffers request. 465 * This request swaps the buffers for all windows listed, applying the 466 * appropriate swap action for each window. 467 * 468 * Return Values: 469 * 470 * BadAlloc - local allocation failed; this return value is not defined 471 * by the protocol 472 * BadMatch - a window in request is not double-buffered; a window in 473 * request is listed more than once 474 * BadValue - invalid swap action is specified; no swap action is 475 * specified 476 * BadWindow - a window in request is not valid 477 * Success 478 * 479 *****************************************************************************/ 480 481static int 482ProcDbeSwapBuffers(ClientPtr client) 483{ 484 REQUEST(xDbeSwapBuffersReq); 485 WindowPtr pWin; 486 DbeScreenPrivPtr pDbeScreenPriv; 487 DbeSwapInfoPtr swapInfo; 488 xDbeSwapInfo *dbeSwapInfo; 489 int error; 490 unsigned int i, j; 491 unsigned int nStuff; 492 493 494 REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); 495 nStuff = stuff->n; /* use local variable for performance. */ 496 497 if (nStuff == 0) 498 { 499 REQUEST_SIZE_MATCH(xDbeSwapBuffersReq); 500 return Success; 501 } 502 503 if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec)) 504 return BadAlloc; 505 REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo)); 506 507 /* Get to the swap info appended to the end of the request. */ 508 dbeSwapInfo = (xDbeSwapInfo *)&stuff[1]; 509 510 /* Allocate array to record swap information. */ 511 swapInfo = (DbeSwapInfoPtr)malloc(nStuff * sizeof(DbeSwapInfoRec)); 512 if (swapInfo == NULL) 513 { 514 return BadAlloc; 515 } 516 517 518 for (i = 0; i < nStuff; i++) 519 { 520 /* Check all windows to swap. */ 521 522 /* Each window must be a valid window - BadWindow. */ 523 error = dixLookupWindow(&pWin, dbeSwapInfo[i].window, client, 524 DixWriteAccess); 525 if (error != Success) { 526 free(swapInfo); 527 return error; 528 } 529 530 /* Each window must be double-buffered - BadMatch. */ 531 if (DBE_WINDOW_PRIV(pWin) == NULL) 532 { 533 free(swapInfo); 534 return BadMatch; 535 } 536 537 /* Each window must only be specified once - BadMatch. */ 538 for (j = i + 1; j < nStuff; j++) 539 { 540 if (dbeSwapInfo[i].window == dbeSwapInfo[j].window) 541 { 542 free(swapInfo); 543 return BadMatch; 544 } 545 } 546 547 /* Each swap action must be valid - BadValue. */ 548 if ((dbeSwapInfo[i].swapAction != XdbeUndefined ) && 549 (dbeSwapInfo[i].swapAction != XdbeBackground) && 550 (dbeSwapInfo[i].swapAction != XdbeUntouched ) && 551 (dbeSwapInfo[i].swapAction != XdbeCopied )) 552 { 553 free(swapInfo); 554 return BadValue; 555 } 556 557 /* Everything checks out OK. Fill in the swap info array. */ 558 swapInfo[i].pWindow = pWin; 559 swapInfo[i].swapAction = dbeSwapInfo[i].swapAction; 560 561 } /* for (i = 0; i < nStuff; i++) */ 562 563 564 /* Call the DDX routine to perform the swap(s). The DDX routine should 565 * scan the swap list (swap info), swap any buffers that it knows how to 566 * handle, delete them from the list, and update nStuff to indicate how 567 * many windows it did not handle. 568 * 569 * This scheme allows a range of sophistication in the DDX SwapBuffers() 570 * implementation. Naive implementations could just swap the first buffer 571 * in the list, move the last buffer to the front, decrement nStuff, and 572 * return. The next level of sophistication could be to scan the whole 573 * list for windows on the same screen. Up another level, the DDX routine 574 * could deal with cross-screen synchronization. 575 */ 576 577 while (nStuff > 0) 578 { 579 pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow); 580 error = (*pDbeScreenPriv->SwapBuffers)(client, &nStuff, swapInfo); 581 if (error != Success) 582 { 583 free(swapInfo); 584 return error; 585 } 586 } 587 588 free(swapInfo); 589 return Success; 590 591} /* ProcDbeSwapBuffers() */ 592 593 594/****************************************************************************** 595 * 596 * DBE DIX Procedure: ProcDbeBeginIdiom 597 * 598 * Description: 599 * 600 * This function is for processing a DbeBeginIdiom request. 601 * This request informs the server that a complex swap will immediately 602 * follow this request. 603 * 604 * Return Values: 605 * 606 * Success 607 * 608 *****************************************************************************/ 609 610static int 611ProcDbeBeginIdiom(ClientPtr client) 612{ 613 /* REQUEST(xDbeBeginIdiomReq); */ 614 DbeScreenPrivPtr pDbeScreenPriv; 615 register int i; 616 617 618 REQUEST_SIZE_MATCH(xDbeBeginIdiomReq); 619 620 for (i = 0; i < screenInfo.numScreens; i++) 621 { 622 pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]); 623 624 /* Call the DDX begin idiom procedure if there is one. */ 625 if (pDbeScreenPriv->BeginIdiom) 626 { 627 (*pDbeScreenPriv->BeginIdiom)(client); 628 } 629 } 630 631 return Success; 632 633} /* ProcDbeBeginIdiom() */ 634 635 636/****************************************************************************** 637 * 638 * DBE DIX Procedure: ProcDbeGetVisualInfo 639 * 640 * Description: 641 * 642 * This function is for processing a ProcDbeGetVisualInfo request. 643 * This request returns information about which visuals support 644 * double buffering. 645 * 646 * Return Values: 647 * 648 * BadDrawable - value in screen specifiers is not a valid drawable 649 * Success 650 * 651 *****************************************************************************/ 652 653static int 654ProcDbeGetVisualInfo(ClientPtr client) 655{ 656 REQUEST(xDbeGetVisualInfoReq); 657 DbeScreenPrivPtr pDbeScreenPriv; 658 xDbeGetVisualInfoReply rep; 659 Drawable *drawables; 660 DrawablePtr *pDrawables = NULL; 661 register int i, j, n, rc; 662 register int count; /* number of visual infos in reply */ 663 register int length; /* length of reply */ 664 ScreenPtr pScreen; 665 XdbeScreenVisualInfo *pScrVisInfo; 666 667 668 REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); 669 if (stuff->n > UINT32_MAX / sizeof(CARD32)) 670 return BadLength; 671 REQUEST_FIXED_SIZE(xDbeGetVisualInfoReq, stuff->n * sizeof(CARD32)); 672 673 if (stuff->n > UINT32_MAX / sizeof(DrawablePtr)) 674 return BadAlloc; 675 /* Make sure any specified drawables are valid. */ 676 if (stuff->n != 0) 677 { 678 if (!(pDrawables = (DrawablePtr *)malloc(stuff->n * 679 sizeof(DrawablePtr)))) 680 { 681 return BadAlloc; 682 } 683 684 drawables = (Drawable *)&stuff[1]; 685 686 for (i = 0; i < stuff->n; i++) 687 { 688 rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0, 689 DixGetAttrAccess); 690 if (rc != Success) { 691 free(pDrawables); 692 return rc; 693 } 694 } 695 } 696 697 count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n; 698 if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo)))) 699 { 700 free(pDrawables); 701 702 return BadAlloc; 703 } 704 705 length = 0; 706 707 for (i = 0; i < count; i++) 708 { 709 pScreen = (stuff->n == 0) ? screenInfo.screens[i] : 710 pDrawables[i]->pScreen; 711 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 712 713 rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 714 if (rc != Success) 715 goto freeScrVisInfo; 716 717 if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i])) 718 { 719 /* We failed to alloc pScrVisInfo[i].visinfo. */ 720 rc = BadAlloc; 721 722 /* Free visinfos that we allocated for previous screen infos.*/ 723 goto freeScrVisInfo; 724 } 725 726 /* Account for n, number of xDbeVisInfo items in list. */ 727 length += sizeof(CARD32); 728 729 /* Account for n xDbeVisInfo items */ 730 length += pScrVisInfo[i].count * sizeof(xDbeVisInfo); 731 } 732 733 rep.type = X_Reply; 734 rep.sequenceNumber = client->sequence; 735 rep.length = bytes_to_int32(length); 736 rep.m = count; 737 738 if (client->swapped) 739 { 740 swaps(&rep.sequenceNumber, n); 741 swapl(&rep.length, n); 742 swapl(&rep.m, n); 743 } 744 745 /* Send off reply. */ 746 WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep); 747 748 for (i = 0; i < count; i++) 749 { 750 CARD32 data32; 751 752 /* For each screen in the reply, send off the visual info */ 753 754 /* Send off number of visuals. */ 755 data32 = (CARD32)pScrVisInfo[i].count; 756 757 if (client->swapped) 758 { 759 swapl(&data32, n); 760 } 761 762 WriteToClient(client, sizeof(CARD32), (char *)&data32); 763 764 /* Now send off visual info items. */ 765 for (j = 0; j < pScrVisInfo[i].count; j++) 766 { 767 xDbeVisInfo visInfo; 768 769 /* Copy the data in the client data structure to a protocol 770 * data structure. We will send data to the client from the 771 * protocol data structure. 772 */ 773 774 visInfo.visualID = (CARD32)pScrVisInfo[i].visinfo[j].visual; 775 visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth; 776 visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel; 777 778 if (client->swapped) 779 { 780 swapl(&visInfo.visualID, n); 781 782 /* We do not need to swap depth and perfLevel since they are 783 * already 1 byte quantities. 784 */ 785 } 786 787 /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */ 788 WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID); 789 } 790 } 791 792 rc = Success; 793 794 freeScrVisInfo: 795 /* Clean up memory. */ 796 for (i = 0; i < count; i++) 797 { 798 free(pScrVisInfo[i].visinfo); 799 } 800 free(pScrVisInfo); 801 802 free(pDrawables); 803 804 return rc; 805 806} /* ProcDbeGetVisualInfo() */ 807 808 809/****************************************************************************** 810 * 811 * DBE DIX Procedure: ProcDbeGetbackBufferAttributes 812 * 813 * Description: 814 * 815 * This function is for processing a ProcDbeGetbackBufferAttributes 816 * request. This request returns information about a back buffer. 817 * 818 * Return Values: 819 * 820 * Success 821 * 822 *****************************************************************************/ 823 824static int 825ProcDbeGetBackBufferAttributes(ClientPtr client) 826{ 827 REQUEST(xDbeGetBackBufferAttributesReq); 828 xDbeGetBackBufferAttributesReply rep; 829 DbeWindowPrivPtr pDbeWindowPriv; 830 int rc, n; 831 832 833 REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); 834 835 rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer, 836 dbeWindowPrivResType, client, 837 DixGetAttrAccess); 838 if (rc == Success) 839 { 840 rep.attributes = pDbeWindowPriv->pWindow->drawable.id; 841 } 842 else 843 { 844 rep.attributes = None; 845 } 846 847 rep.type = X_Reply; 848 rep.sequenceNumber = client->sequence; 849 rep.length = 0; 850 851 if (client->swapped) 852 { 853 swaps(&rep.sequenceNumber, n); 854 swapl(&rep.length, n); 855 swapl(&rep.attributes, n); 856 } 857 858 WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply), 859 (char *)&rep); 860 return Success; 861 862} /* ProcDbeGetbackBufferAttributes() */ 863 864 865/****************************************************************************** 866 * 867 * DBE DIX Procedure: ProcDbeDispatch 868 * 869 * Description: 870 * 871 * This function dispatches DBE requests. 872 * 873 *****************************************************************************/ 874 875static int 876ProcDbeDispatch(ClientPtr client) 877{ 878 REQUEST(xReq); 879 880 881 switch (stuff->data) 882 { 883 case X_DbeGetVersion: 884 return(ProcDbeGetVersion(client)); 885 886 case X_DbeAllocateBackBufferName: 887 return(ProcDbeAllocateBackBufferName(client)); 888 889 case X_DbeDeallocateBackBufferName: 890 return(ProcDbeDeallocateBackBufferName(client)); 891 892 case X_DbeSwapBuffers: 893 return(ProcDbeSwapBuffers(client)); 894 895 case X_DbeBeginIdiom: 896 return(ProcDbeBeginIdiom(client)); 897 898 case X_DbeEndIdiom: 899 return Success; 900 901 case X_DbeGetVisualInfo: 902 return(ProcDbeGetVisualInfo(client)); 903 904 case X_DbeGetBackBufferAttributes: 905 return(ProcDbeGetBackBufferAttributes(client)); 906 907 default: 908 return BadRequest; 909 } 910 911} /* ProcDbeDispatch() */ 912 913 914/****************************************************************************** 915 * 916 * DBE DIX Procedure: SProcDbeGetVersion 917 * 918 * Description: 919 * 920 * This function is for processing a DbeGetVersion request on a swapped 921 * server. This request returns the major and minor version numbers of 922 * this extension. 923 * 924 * Return Values: 925 * 926 * Success 927 * 928 *****************************************************************************/ 929 930static int 931SProcDbeGetVersion(ClientPtr client) 932{ 933 REQUEST(xDbeGetVersionReq); 934 register int n; 935 936 937 swaps(&stuff->length, n); 938 return(ProcDbeGetVersion(client)); 939 940} /* SProcDbeGetVersion() */ 941 942 943/****************************************************************************** 944 * 945 * DBE DIX Procedure: SProcDbeAllocateBackBufferName 946 * 947 * Description: 948 * 949 * This function is for processing a DbeAllocateBackBufferName request on 950 * a swapped server. This request allocates a drawable ID used to refer 951 * to the back buffer of a window. 952 * 953 * Return Values: 954 * 955 * BadAlloc - server can not allocate resources 956 * BadIDChoice - id is out of range for client; id is already in use 957 * BadMatch - window is not an InputOutput window; 958 * visual of window is not on list returned by 959 * DBEGetVisualInfo; 960 * BadValue - invalid swap action is specified 961 * BadWindow - window is not a valid window 962 * Success 963 * 964 *****************************************************************************/ 965 966static int 967SProcDbeAllocateBackBufferName(ClientPtr client) 968{ 969 REQUEST(xDbeAllocateBackBufferNameReq); 970 register int n; 971 972 swaps(&stuff->length, n); 973 REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); 974 975 swapl(&stuff->window, n); 976 swapl(&stuff->buffer, n); 977 /* stuff->swapAction is a byte. We do not need to swap this field. */ 978 979 return(ProcDbeAllocateBackBufferName(client)); 980 981} /* SProcDbeAllocateBackBufferName() */ 982 983 984/****************************************************************************** 985 * 986 * DBE DIX Procedure: SProcDbeDeallocateBackBufferName 987 * 988 * Description: 989 * 990 * This function is for processing a DbeDeallocateBackBufferName request 991 * on a swapped server. This request frees a drawable ID that was 992 * obtained by a DbeAllocateBackBufferName request. 993 * 994 * Return Values: 995 * 996 * BadBuffer - buffer to deallocate is not associated with a window 997 * Success 998 * 999 *****************************************************************************/ 1000 1001static int 1002SProcDbeDeallocateBackBufferName(ClientPtr client) 1003{ 1004 REQUEST (xDbeDeallocateBackBufferNameReq); 1005 register int n; 1006 1007 1008 swaps(&stuff->length, n); 1009 REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); 1010 1011 swapl(&stuff->buffer, n); 1012 1013 return(ProcDbeDeallocateBackBufferName(client)); 1014 1015} /* SProcDbeDeallocateBackBufferName() */ 1016 1017 1018/****************************************************************************** 1019 * 1020 * DBE DIX Procedure: SProcDbeSwapBuffers 1021 * 1022 * Description: 1023 * 1024 * This function is for processing a DbeSwapBuffers request on a swapped 1025 * server. This request swaps the buffers for all windows listed, 1026 * applying the appropriate swap action for each window. 1027 * 1028 * Return Values: 1029 * 1030 * BadMatch - a window in request is not double-buffered; a window in 1031 * request is listed more than once; all windows in request do 1032 * not have the same root 1033 * BadValue - invalid swap action is specified 1034 * BadWindow - a window in request is not valid 1035 * Success 1036 * 1037 *****************************************************************************/ 1038 1039static int 1040SProcDbeSwapBuffers(ClientPtr client) 1041{ 1042 REQUEST(xDbeSwapBuffersReq); 1043 unsigned int i, n; 1044 xDbeSwapInfo *pSwapInfo; 1045 1046 1047 swaps(&stuff->length, n); 1048 REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); 1049 1050 swapl(&stuff->n, n); 1051 if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec)) 1052 return BadLength; 1053 REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo)); 1054 1055 if (stuff->n != 0) 1056 { 1057 pSwapInfo = (xDbeSwapInfo *)stuff+1; 1058 1059 /* The swap info following the fix part of this request is a window(32) 1060 * followed by a 1 byte swap action and then 3 pad bytes. We only need 1061 * to swap the window information. 1062 */ 1063 for (i = 0; i < stuff->n; i++) 1064 { 1065 swapl(&pSwapInfo->window, n); 1066 } 1067 } 1068 1069 return(ProcDbeSwapBuffers(client)); 1070 1071} /* SProcDbeSwapBuffers() */ 1072 1073 1074/****************************************************************************** 1075 * 1076 * DBE DIX Procedure: SProcDbeBeginIdiom 1077 * 1078 * Description: 1079 * 1080 * This function is for processing a DbeBeginIdiom request on a swapped 1081 * server. This request informs the server that a complex swap will 1082 * immediately follow this request. 1083 * 1084 * Return Values: 1085 * 1086 * Success 1087 * 1088 *****************************************************************************/ 1089 1090static int 1091SProcDbeBeginIdiom(ClientPtr client) 1092{ 1093 REQUEST(xDbeBeginIdiomReq); 1094 register int n; 1095 1096 swaps(&stuff->length, n); 1097 return(ProcDbeBeginIdiom(client)); 1098 1099} /* SProcDbeBeginIdiom() */ 1100 1101 1102/****************************************************************************** 1103 * 1104 * DBE DIX Procedure: SProcDbeGetVisualInfo 1105 * 1106 * Description: 1107 * 1108 * This function is for processing a ProcDbeGetVisualInfo request on a 1109 * swapped server. This request returns information about which visuals 1110 * support double buffering. 1111 * 1112 * Return Values: 1113 * 1114 * BadDrawable - value in screen specifiers is not a valid drawable 1115 * Success 1116 * 1117 *****************************************************************************/ 1118 1119static int 1120SProcDbeGetVisualInfo(ClientPtr client) 1121{ 1122 REQUEST(xDbeGetVisualInfoReq); 1123 register int n; 1124 1125 1126 swaps(&stuff->length, n); 1127 REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); 1128 1129 swapl(&stuff->n, n); 1130 SwapRestL(stuff); 1131 1132 return(ProcDbeGetVisualInfo(client)); 1133 1134} /* SProcDbeGetVisualInfo() */ 1135 1136 1137/****************************************************************************** 1138 * 1139 * DBE DIX Procedure: SProcDbeGetbackBufferAttributes 1140 * 1141 * Description: 1142 * 1143 * This function is for processing a ProcDbeGetbackBufferAttributes 1144 * request on a swapped server. This request returns information about a 1145 * back buffer. 1146 * 1147 * Return Values: 1148 * 1149 * Success 1150 * 1151 *****************************************************************************/ 1152 1153static int 1154SProcDbeGetBackBufferAttributes(ClientPtr client) 1155{ 1156 REQUEST (xDbeGetBackBufferAttributesReq); 1157 register int n; 1158 1159 swaps(&stuff->length, n); 1160 REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); 1161 1162 swapl(&stuff->buffer, n); 1163 1164 return(ProcDbeGetBackBufferAttributes(client)); 1165 1166} /* SProcDbeGetBackBufferAttributes() */ 1167 1168 1169/****************************************************************************** 1170 * 1171 * DBE DIX Procedure: SProcDbeDispatch 1172 * 1173 * Description: 1174 * 1175 * This function dispatches DBE requests on a swapped server. 1176 * 1177 *****************************************************************************/ 1178 1179static int 1180SProcDbeDispatch(ClientPtr client) 1181{ 1182 REQUEST(xReq); 1183 1184 1185 switch (stuff->data) 1186 { 1187 case X_DbeGetVersion: 1188 return(SProcDbeGetVersion(client)); 1189 1190 case X_DbeAllocateBackBufferName: 1191 return(SProcDbeAllocateBackBufferName(client)); 1192 1193 case X_DbeDeallocateBackBufferName: 1194 return(SProcDbeDeallocateBackBufferName(client)); 1195 1196 case X_DbeSwapBuffers: 1197 return(SProcDbeSwapBuffers(client)); 1198 1199 case X_DbeBeginIdiom: 1200 return(SProcDbeBeginIdiom(client)); 1201 1202 case X_DbeEndIdiom: 1203 return Success; 1204 1205 case X_DbeGetVisualInfo: 1206 return(SProcDbeGetVisualInfo(client)); 1207 1208 case X_DbeGetBackBufferAttributes: 1209 return(SProcDbeGetBackBufferAttributes(client)); 1210 1211 default: 1212 return BadRequest; 1213 } 1214 1215} /* SProcDbeDispatch() */ 1216 1217 1218/****************************************************************************** 1219 * 1220 * DBE DIX Procedure: DbeSetupBackgroundPainter 1221 * 1222 * Description: 1223 * 1224 * This function sets up pGC to clear pixmaps. 1225 * 1226 * Return Values: 1227 * 1228 * TRUE - setup was successful 1229 * FALSE - the window's background state is NONE 1230 * 1231 *****************************************************************************/ 1232 1233static Bool 1234DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC) 1235{ 1236 ChangeGCVal gcvalues[4]; 1237 int ts_x_origin, ts_y_origin; 1238 PixUnion background; 1239 int backgroundState; 1240 Mask gcmask; 1241 1242 1243 /* First take care of any ParentRelative stuff by altering the 1244 * tile/stipple origin to match the coordinates of the upper-left 1245 * corner of the first ancestor without a ParentRelative background. 1246 * This coordinate is, of course, negative. 1247 */ 1248 ts_x_origin = ts_y_origin = 0; 1249 while (pWin->backgroundState == ParentRelative) 1250 { 1251 ts_x_origin -= pWin->origin.x; 1252 ts_y_origin -= pWin->origin.y; 1253 1254 pWin = pWin->parent; 1255 } 1256 backgroundState = pWin->backgroundState; 1257 background = pWin->background; 1258 1259 switch (backgroundState) 1260 { 1261 case BackgroundPixel: 1262 gcvalues[0].val = background.pixel; 1263 gcvalues[1].val = FillSolid; 1264 gcmask = GCForeground|GCFillStyle; 1265 break; 1266 1267 case BackgroundPixmap: 1268 gcvalues[0].val = FillTiled; 1269 gcvalues[1].ptr = background.pixmap; 1270 gcvalues[2].val = ts_x_origin; 1271 gcvalues[3].val = ts_y_origin; 1272 gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin; 1273 break; 1274 1275 default: 1276 /* pWin->backgroundState == None */ 1277 return FALSE; 1278 } 1279 1280 return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0; 1281} /* DbeSetupBackgroundPainter() */ 1282 1283 1284/****************************************************************************** 1285 * 1286 * DBE DIX Procedure: DbeDrawableDelete 1287 * 1288 * Description: 1289 * 1290 * This is the resource delete function for dbeDrawableResType. 1291 * It is registered when the drawable resource type is created in 1292 * DbeExtensionInit(). 1293 * 1294 * To make resource deletion simple, we do not do anything in this function 1295 * and leave all resource deleteion to DbeWindowPrivDelete(), which will 1296 * eventually be called or already has been called. Deletion functions are 1297 * not guaranteed to be called in any particular order. 1298 * 1299 *****************************************************************************/ 1300static int 1301DbeDrawableDelete(pointer pDrawable, XID id) 1302{ 1303 return Success; 1304 1305} /* DbeDrawableDelete() */ 1306 1307 1308/****************************************************************************** 1309 * 1310 * DBE DIX Procedure: DbeWindowPrivDelete 1311 * 1312 * Description: 1313 * 1314 * This is the resource delete function for dbeWindowPrivResType. 1315 * It is registered when the drawable resource type is created in 1316 * DbeExtensionInit(). 1317 * 1318 *****************************************************************************/ 1319static int 1320DbeWindowPrivDelete(pointer pDbeWinPriv, XID id) 1321{ 1322 DbeScreenPrivPtr pDbeScreenPriv; 1323 DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv; 1324 int i; 1325 1326 1327 /* 1328 ************************************************************************** 1329 ** Remove the buffer ID from the ID array. 1330 ************************************************************************** 1331 */ 1332 1333 /* Find the ID in the ID array. */ 1334 i = 0; 1335 while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id)) 1336 { 1337 i++; 1338 } 1339 1340 if (i == pDbeWindowPriv->nBufferIDs) 1341 { 1342 /* We did not find the ID in the array. We should never get here. */ 1343 return BadValue; 1344 } 1345 1346 /* Remove the ID from the array. */ 1347 1348 if (i < (pDbeWindowPriv->nBufferIDs - 1)) 1349 { 1350 /* Compress the buffer ID array, overwriting the ID in the process. */ 1351 memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1], 1352 (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID)); 1353 } 1354 else 1355 { 1356 /* We are removing the last ID in the array, in which case, the 1357 * assignement below is all that we need to do. 1358 */ 1359 } 1360 pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT; 1361 1362 pDbeWindowPriv->nBufferIDs--; 1363 1364 /* If an extended array was allocated, then check to see if the remaining 1365 * buffer IDs will fit in the static array. 1366 */ 1367 1368 if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) && 1369 (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS)) 1370 { 1371 /* Copy the IDs back into the static array. */ 1372 memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs, 1373 DBE_INIT_MAX_IDS * sizeof(XID)); 1374 1375 /* Free the extended array; use the static array. */ 1376 free(pDbeWindowPriv->IDs); 1377 pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; 1378 pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; 1379 } 1380 1381 1382 /* 1383 ************************************************************************** 1384 ** Perform DDX level tasks. 1385 ************************************************************************** 1386 */ 1387 1388 pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV( 1389 (DbeWindowPrivPtr)pDbeWindowPriv); 1390 (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id); 1391 1392 1393 /* 1394 ************************************************************************** 1395 ** Perform miscellaneous tasks if this is the last buffer associated 1396 ** with the window. 1397 ************************************************************************** 1398 */ 1399 1400 if (pDbeWindowPriv->nBufferIDs == 0) 1401 { 1402 /* Reset the DBE window priv pointer. */ 1403 dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey, 1404 NULL); 1405 1406 /* We are done with the window priv. */ 1407 dixFreeObjectWithPrivates(pDbeWindowPriv, PRIVATE_DBE_WINDOW); 1408 } 1409 1410 return Success; 1411 1412} /* DbeWindowPrivDelete() */ 1413 1414 1415/****************************************************************************** 1416 * 1417 * DBE DIX Procedure: DbeResetProc 1418 * 1419 * Description: 1420 * 1421 * This routine is called at the end of every server generation. 1422 * It deallocates any memory reserved for the extension and performs any 1423 * other tasks related to shutting down the extension. 1424 * 1425 *****************************************************************************/ 1426static void 1427DbeResetProc(ExtensionEntry *extEntry) 1428{ 1429 int i; 1430 ScreenPtr pScreen; 1431 DbeScreenPrivPtr pDbeScreenPriv; 1432 1433 for (i = 0; i < screenInfo.numScreens; i++) 1434 { 1435 pScreen = screenInfo.screens[i]; 1436 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1437 1438 if (pDbeScreenPriv) 1439 { 1440 /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/ 1441 pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; 1442 1443 if (pDbeScreenPriv->ResetProc) 1444 (*pDbeScreenPriv->ResetProc)(pScreen); 1445 1446 free(pDbeScreenPriv); 1447 } 1448 } 1449} /* DbeResetProc() */ 1450 1451 1452/****************************************************************************** 1453 * 1454 * DBE DIX Procedure: DbeDestroyWindow 1455 * 1456 * Description: 1457 * 1458 * This is the wrapper for pScreen->DestroyWindow. 1459 * This function frees buffer resources for a window before it is 1460 * destroyed. 1461 * 1462 *****************************************************************************/ 1463 1464static Bool 1465DbeDestroyWindow(WindowPtr pWin) 1466{ 1467 DbeScreenPrivPtr pDbeScreenPriv; 1468 DbeWindowPrivPtr pDbeWindowPriv; 1469 ScreenPtr pScreen; 1470 Bool ret; 1471 1472 1473 /* 1474 ************************************************************************** 1475 ** 1. Unwrap the member routine. 1476 ************************************************************************** 1477 */ 1478 1479 pScreen = pWin->drawable.pScreen; 1480 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1481 pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; 1482 1483 /* 1484 ************************************************************************** 1485 ** 2. Do any work necessary before the member routine is called. 1486 ** 1487 ** Call the window priv delete function for all buffer IDs associated 1488 ** with this window. 1489 ************************************************************************** 1490 */ 1491 1492 if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) 1493 { 1494 while (pDbeWindowPriv) 1495 { 1496 /* *DbeWinPrivDelete() will free the window private and set it to 1497 * NULL if there are no more buffer IDs associated with this 1498 * window. 1499 */ 1500 FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); 1501 pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 1502 } 1503 } 1504 1505 /* 1506 ************************************************************************** 1507 ** 3. Call the member routine, saving its result if necessary. 1508 ************************************************************************** 1509 */ 1510 1511 ret = (*pScreen->DestroyWindow)(pWin); 1512 1513 /* 1514 ************************************************************************** 1515 ** 4. Rewrap the member routine, restoring the wrapper value first in case 1516 ** the wrapper (or something that it wrapped) change this value. 1517 ************************************************************************** 1518 */ 1519 1520 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; 1521 pScreen->DestroyWindow = DbeDestroyWindow; 1522 1523 /* 1524 ************************************************************************** 1525 ** 5. Do any work necessary after the member routine has been called. 1526 ** 1527 ** In this case we do not need to do anything. 1528 ************************************************************************** 1529 */ 1530 1531 return ret; 1532 1533} /* DbeDestroyWindow() */ 1534 1535 1536/****************************************************************************** 1537 * 1538 * DBE DIX Procedure: DbeExtensionInit 1539 * 1540 * Description: 1541 * 1542 * Called from InitExtensions in main() 1543 * 1544 *****************************************************************************/ 1545 1546void 1547DbeExtensionInit(void) 1548{ 1549 ExtensionEntry *extEntry; 1550 register int i, j; 1551 ScreenPtr pScreen = NULL; 1552 DbeScreenPrivPtr pDbeScreenPriv; 1553 int nStubbedScreens = 0; 1554 Bool ddxInitSuccess; 1555 1556#ifdef PANORAMIX 1557 if(!noPanoramiXExtension) return; 1558#endif 1559 1560 /* Create the resource types. */ 1561 dbeDrawableResType = 1562 CreateNewResourceType(DbeDrawableDelete, "dbeDrawable"); 1563 if (!dbeDrawableResType) 1564 return; 1565 dbeDrawableResType |= RC_DRAWABLE; 1566 1567 dbeWindowPrivResType = 1568 CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow"); 1569 if (!dbeWindowPrivResType) 1570 return; 1571 1572 if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0)) 1573 return; 1574 1575 if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0)) 1576 return; 1577 1578 for (i = 0; i < screenInfo.numScreens; i++) 1579 { 1580 /* For each screen, set up DBE screen privates and init DIX and DDX 1581 * interface. 1582 */ 1583 1584 pScreen = screenInfo.screens[i]; 1585 1586 if (!(pDbeScreenPriv = malloc (sizeof (DbeScreenPrivRec)))) 1587 { 1588 /* If we can not alloc a window or screen private, 1589 * then free any privates that we already alloc'ed and return 1590 */ 1591 1592 for (j = 0; j < i; j++) 1593 { 1594 free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates, 1595 dbeScreenPrivKey)); 1596 dixSetPrivate(&screenInfo.screens[j]->devPrivates, 1597 dbeScreenPrivKey, NULL); 1598 } 1599 return; 1600 } 1601 1602 dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv); 1603 1604 { 1605 /* We don't have DDX support for DBE anymore */ 1606 1607#ifndef DISABLE_MI_DBE_BY_DEFAULT 1608 /* Setup DIX. */ 1609 pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter; 1610 1611 /* Setup DDX. */ 1612 ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv); 1613 1614 /* DDX DBE initialization may have the side affect of 1615 * reallocating pDbeScreenPriv, so we need to update it. 1616 */ 1617 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1618 1619 if (ddxInitSuccess) 1620 { 1621 /* Wrap DestroyWindow. The DDX initialization function 1622 * already wrapped PositionWindow for us. 1623 */ 1624 1625 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; 1626 pScreen->DestroyWindow = DbeDestroyWindow; 1627 } 1628 else 1629 { 1630 /* DDX initialization failed. Stub the screen. */ 1631 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); 1632 } 1633#else 1634 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); 1635#endif 1636 1637 } 1638 1639 } /* for (i = 0; i < screenInfo.numScreens; i++) */ 1640 1641 1642 if (nStubbedScreens == screenInfo.numScreens) 1643 { 1644 /* All screens stubbed. Clean up and return. */ 1645 1646 for (i = 0; i < screenInfo.numScreens; i++) 1647 { 1648 free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates, 1649 dbeScreenPrivKey)); 1650 dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL); 1651 } 1652 return; 1653 } 1654 1655 1656 /* Now add the extension. */ 1657 extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents, 1658 DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch, 1659 DbeResetProc, StandardMinorOpcode); 1660 1661 dbeErrorBase = extEntry->errorBase; 1662 SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer); 1663 SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer); 1664 1665} /* DbeExtensionInit() */ 1666 1667