dbe.c revision 706f2543
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 670 if (stuff->n > UINT32_MAX / sizeof(DrawablePtr)) 671 return BadAlloc; 672 /* Make sure any specified drawables are valid. */ 673 if (stuff->n != 0) 674 { 675 if (!(pDrawables = (DrawablePtr *)malloc(stuff->n * 676 sizeof(DrawablePtr)))) 677 { 678 return BadAlloc; 679 } 680 681 drawables = (Drawable *)&stuff[1]; 682 683 for (i = 0; i < stuff->n; i++) 684 { 685 rc = dixLookupDrawable(pDrawables+i, drawables[i], client, 0, 686 DixGetAttrAccess); 687 if (rc != Success) { 688 free(pDrawables); 689 return rc; 690 } 691 } 692 } 693 694 count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n; 695 if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo)))) 696 { 697 free(pDrawables); 698 699 return BadAlloc; 700 } 701 702 length = 0; 703 704 for (i = 0; i < count; i++) 705 { 706 pScreen = (stuff->n == 0) ? screenInfo.screens[i] : 707 pDrawables[i]->pScreen; 708 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 709 710 rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 711 if (rc != Success) 712 goto freeScrVisInfo; 713 714 if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i])) 715 { 716 /* We failed to alloc pScrVisInfo[i].visinfo. */ 717 rc = BadAlloc; 718 719 /* Free visinfos that we allocated for previous screen infos.*/ 720 goto freeScrVisInfo; 721 } 722 723 /* Account for n, number of xDbeVisInfo items in list. */ 724 length += sizeof(CARD32); 725 726 /* Account for n xDbeVisInfo items */ 727 length += pScrVisInfo[i].count * sizeof(xDbeVisInfo); 728 } 729 730 rep.type = X_Reply; 731 rep.sequenceNumber = client->sequence; 732 rep.length = bytes_to_int32(length); 733 rep.m = count; 734 735 if (client->swapped) 736 { 737 swaps(&rep.sequenceNumber, n); 738 swapl(&rep.length, n); 739 swapl(&rep.m, n); 740 } 741 742 /* Send off reply. */ 743 WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *)&rep); 744 745 for (i = 0; i < count; i++) 746 { 747 CARD32 data32; 748 749 /* For each screen in the reply, send off the visual info */ 750 751 /* Send off number of visuals. */ 752 data32 = (CARD32)pScrVisInfo[i].count; 753 754 if (client->swapped) 755 { 756 swapl(&data32, n); 757 } 758 759 WriteToClient(client, sizeof(CARD32), (char *)&data32); 760 761 /* Now send off visual info items. */ 762 for (j = 0; j < pScrVisInfo[i].count; j++) 763 { 764 xDbeVisInfo visInfo; 765 766 /* Copy the data in the client data structure to a protocol 767 * data structure. We will send data to the client from the 768 * protocol data structure. 769 */ 770 771 visInfo.visualID = (CARD32)pScrVisInfo[i].visinfo[j].visual; 772 visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth; 773 visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel; 774 775 if (client->swapped) 776 { 777 swapl(&visInfo.visualID, n); 778 779 /* We do not need to swap depth and perfLevel since they are 780 * already 1 byte quantities. 781 */ 782 } 783 784 /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */ 785 WriteToClient(client, 2*sizeof(CARD32), (char *)&visInfo.visualID); 786 } 787 } 788 789 rc = Success; 790 791 freeScrVisInfo: 792 /* Clean up memory. */ 793 for (i = 0; i < count; i++) 794 { 795 free(pScrVisInfo[i].visinfo); 796 } 797 free(pScrVisInfo); 798 799 free(pDrawables); 800 801 return rc; 802 803} /* ProcDbeGetVisualInfo() */ 804 805 806/****************************************************************************** 807 * 808 * DBE DIX Procedure: ProcDbeGetbackBufferAttributes 809 * 810 * Description: 811 * 812 * This function is for processing a ProcDbeGetbackBufferAttributes 813 * request. This request returns information about a back buffer. 814 * 815 * Return Values: 816 * 817 * Success 818 * 819 *****************************************************************************/ 820 821static int 822ProcDbeGetBackBufferAttributes(ClientPtr client) 823{ 824 REQUEST(xDbeGetBackBufferAttributesReq); 825 xDbeGetBackBufferAttributesReply rep; 826 DbeWindowPrivPtr pDbeWindowPriv; 827 int rc, n; 828 829 830 REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); 831 832 rc = dixLookupResourceByType((pointer *)&pDbeWindowPriv, stuff->buffer, 833 dbeWindowPrivResType, client, 834 DixGetAttrAccess); 835 if (rc == Success) 836 { 837 rep.attributes = pDbeWindowPriv->pWindow->drawable.id; 838 } 839 else 840 { 841 rep.attributes = None; 842 } 843 844 rep.type = X_Reply; 845 rep.sequenceNumber = client->sequence; 846 rep.length = 0; 847 848 if (client->swapped) 849 { 850 swaps(&rep.sequenceNumber, n); 851 swapl(&rep.length, n); 852 swapl(&rep.attributes, n); 853 } 854 855 WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply), 856 (char *)&rep); 857 return Success; 858 859} /* ProcDbeGetbackBufferAttributes() */ 860 861 862/****************************************************************************** 863 * 864 * DBE DIX Procedure: ProcDbeDispatch 865 * 866 * Description: 867 * 868 * This function dispatches DBE requests. 869 * 870 *****************************************************************************/ 871 872static int 873ProcDbeDispatch(ClientPtr client) 874{ 875 REQUEST(xReq); 876 877 878 switch (stuff->data) 879 { 880 case X_DbeGetVersion: 881 return(ProcDbeGetVersion(client)); 882 883 case X_DbeAllocateBackBufferName: 884 return(ProcDbeAllocateBackBufferName(client)); 885 886 case X_DbeDeallocateBackBufferName: 887 return(ProcDbeDeallocateBackBufferName(client)); 888 889 case X_DbeSwapBuffers: 890 return(ProcDbeSwapBuffers(client)); 891 892 case X_DbeBeginIdiom: 893 return(ProcDbeBeginIdiom(client)); 894 895 case X_DbeEndIdiom: 896 return Success; 897 898 case X_DbeGetVisualInfo: 899 return(ProcDbeGetVisualInfo(client)); 900 901 case X_DbeGetBackBufferAttributes: 902 return(ProcDbeGetBackBufferAttributes(client)); 903 904 default: 905 return BadRequest; 906 } 907 908} /* ProcDbeDispatch() */ 909 910 911/****************************************************************************** 912 * 913 * DBE DIX Procedure: SProcDbeGetVersion 914 * 915 * Description: 916 * 917 * This function is for processing a DbeGetVersion request on a swapped 918 * server. This request returns the major and minor version numbers of 919 * this extension. 920 * 921 * Return Values: 922 * 923 * Success 924 * 925 *****************************************************************************/ 926 927static int 928SProcDbeGetVersion(ClientPtr client) 929{ 930 REQUEST(xDbeGetVersionReq); 931 register int n; 932 933 934 swaps(&stuff->length, n); 935 return(ProcDbeGetVersion(client)); 936 937} /* SProcDbeGetVersion() */ 938 939 940/****************************************************************************** 941 * 942 * DBE DIX Procedure: SProcDbeAllocateBackBufferName 943 * 944 * Description: 945 * 946 * This function is for processing a DbeAllocateBackBufferName request on 947 * a swapped server. This request allocates a drawable ID used to refer 948 * to the back buffer of a window. 949 * 950 * Return Values: 951 * 952 * BadAlloc - server can not allocate resources 953 * BadIDChoice - id is out of range for client; id is already in use 954 * BadMatch - window is not an InputOutput window; 955 * visual of window is not on list returned by 956 * DBEGetVisualInfo; 957 * BadValue - invalid swap action is specified 958 * BadWindow - window is not a valid window 959 * Success 960 * 961 *****************************************************************************/ 962 963static int 964SProcDbeAllocateBackBufferName(ClientPtr client) 965{ 966 REQUEST(xDbeAllocateBackBufferNameReq); 967 register int n; 968 969 swaps(&stuff->length, n); 970 REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); 971 972 swapl(&stuff->window, n); 973 swapl(&stuff->buffer, n); 974 /* stuff->swapAction is a byte. We do not need to swap this field. */ 975 976 return(ProcDbeAllocateBackBufferName(client)); 977 978} /* SProcDbeAllocateBackBufferName() */ 979 980 981/****************************************************************************** 982 * 983 * DBE DIX Procedure: SProcDbeDeallocateBackBufferName 984 * 985 * Description: 986 * 987 * This function is for processing a DbeDeallocateBackBufferName request 988 * on a swapped server. This request frees a drawable ID that was 989 * obtained by a DbeAllocateBackBufferName request. 990 * 991 * Return Values: 992 * 993 * BadBuffer - buffer to deallocate is not associated with a window 994 * Success 995 * 996 *****************************************************************************/ 997 998static int 999SProcDbeDeallocateBackBufferName(ClientPtr client) 1000{ 1001 REQUEST (xDbeDeallocateBackBufferNameReq); 1002 register int n; 1003 1004 1005 swaps(&stuff->length, n); 1006 REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq); 1007 1008 swapl(&stuff->buffer, n); 1009 1010 return(ProcDbeDeallocateBackBufferName(client)); 1011 1012} /* SProcDbeDeallocateBackBufferName() */ 1013 1014 1015/****************************************************************************** 1016 * 1017 * DBE DIX Procedure: SProcDbeSwapBuffers 1018 * 1019 * Description: 1020 * 1021 * This function is for processing a DbeSwapBuffers request on a swapped 1022 * server. This request swaps the buffers for all windows listed, 1023 * applying the appropriate swap action for each window. 1024 * 1025 * Return Values: 1026 * 1027 * BadMatch - a window in request is not double-buffered; a window in 1028 * request is listed more than once; all windows in request do 1029 * not have the same root 1030 * BadValue - invalid swap action is specified 1031 * BadWindow - a window in request is not valid 1032 * Success 1033 * 1034 *****************************************************************************/ 1035 1036static int 1037SProcDbeSwapBuffers(ClientPtr client) 1038{ 1039 REQUEST(xDbeSwapBuffersReq); 1040 unsigned int i, n; 1041 xDbeSwapInfo *pSwapInfo; 1042 1043 1044 swaps(&stuff->length, n); 1045 REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); 1046 1047 swapl(&stuff->n, n); 1048 if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec)) 1049 return BadAlloc; 1050 REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo)); 1051 1052 if (stuff->n != 0) 1053 { 1054 pSwapInfo = (xDbeSwapInfo *)stuff+1; 1055 1056 /* The swap info following the fix part of this request is a window(32) 1057 * followed by a 1 byte swap action and then 3 pad bytes. We only need 1058 * to swap the window information. 1059 */ 1060 for (i = 0; i < stuff->n; i++) 1061 { 1062 swapl(&pSwapInfo->window, n); 1063 } 1064 } 1065 1066 return(ProcDbeSwapBuffers(client)); 1067 1068} /* SProcDbeSwapBuffers() */ 1069 1070 1071/****************************************************************************** 1072 * 1073 * DBE DIX Procedure: SProcDbeBeginIdiom 1074 * 1075 * Description: 1076 * 1077 * This function is for processing a DbeBeginIdiom request on a swapped 1078 * server. This request informs the server that a complex swap will 1079 * immediately follow this request. 1080 * 1081 * Return Values: 1082 * 1083 * Success 1084 * 1085 *****************************************************************************/ 1086 1087static int 1088SProcDbeBeginIdiom(ClientPtr client) 1089{ 1090 REQUEST(xDbeBeginIdiomReq); 1091 register int n; 1092 1093 swaps(&stuff->length, n); 1094 return(ProcDbeBeginIdiom(client)); 1095 1096} /* SProcDbeBeginIdiom() */ 1097 1098 1099/****************************************************************************** 1100 * 1101 * DBE DIX Procedure: SProcDbeGetVisualInfo 1102 * 1103 * Description: 1104 * 1105 * This function is for processing a ProcDbeGetVisualInfo request on a 1106 * swapped server. This request returns information about which visuals 1107 * support double buffering. 1108 * 1109 * Return Values: 1110 * 1111 * BadDrawable - value in screen specifiers is not a valid drawable 1112 * Success 1113 * 1114 *****************************************************************************/ 1115 1116static int 1117SProcDbeGetVisualInfo(ClientPtr client) 1118{ 1119 REQUEST(xDbeGetVisualInfoReq); 1120 register int n; 1121 1122 1123 swaps(&stuff->length, n); 1124 REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq); 1125 1126 swapl(&stuff->n, n); 1127 SwapRestL(stuff); 1128 1129 return(ProcDbeGetVisualInfo(client)); 1130 1131} /* SProcDbeGetVisualInfo() */ 1132 1133 1134/****************************************************************************** 1135 * 1136 * DBE DIX Procedure: SProcDbeGetbackBufferAttributes 1137 * 1138 * Description: 1139 * 1140 * This function is for processing a ProcDbeGetbackBufferAttributes 1141 * request on a swapped server. This request returns information about a 1142 * back buffer. 1143 * 1144 * Return Values: 1145 * 1146 * Success 1147 * 1148 *****************************************************************************/ 1149 1150static int 1151SProcDbeGetBackBufferAttributes(ClientPtr client) 1152{ 1153 REQUEST (xDbeGetBackBufferAttributesReq); 1154 register int n; 1155 1156 swaps(&stuff->length, n); 1157 REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq); 1158 1159 swapl(&stuff->buffer, n); 1160 1161 return(ProcDbeGetBackBufferAttributes(client)); 1162 1163} /* SProcDbeGetBackBufferAttributes() */ 1164 1165 1166/****************************************************************************** 1167 * 1168 * DBE DIX Procedure: SProcDbeDispatch 1169 * 1170 * Description: 1171 * 1172 * This function dispatches DBE requests on a swapped server. 1173 * 1174 *****************************************************************************/ 1175 1176static int 1177SProcDbeDispatch(ClientPtr client) 1178{ 1179 REQUEST(xReq); 1180 1181 1182 switch (stuff->data) 1183 { 1184 case X_DbeGetVersion: 1185 return(SProcDbeGetVersion(client)); 1186 1187 case X_DbeAllocateBackBufferName: 1188 return(SProcDbeAllocateBackBufferName(client)); 1189 1190 case X_DbeDeallocateBackBufferName: 1191 return(SProcDbeDeallocateBackBufferName(client)); 1192 1193 case X_DbeSwapBuffers: 1194 return(SProcDbeSwapBuffers(client)); 1195 1196 case X_DbeBeginIdiom: 1197 return(SProcDbeBeginIdiom(client)); 1198 1199 case X_DbeEndIdiom: 1200 return Success; 1201 1202 case X_DbeGetVisualInfo: 1203 return(SProcDbeGetVisualInfo(client)); 1204 1205 case X_DbeGetBackBufferAttributes: 1206 return(SProcDbeGetBackBufferAttributes(client)); 1207 1208 default: 1209 return BadRequest; 1210 } 1211 1212} /* SProcDbeDispatch() */ 1213 1214 1215/****************************************************************************** 1216 * 1217 * DBE DIX Procedure: DbeSetupBackgroundPainter 1218 * 1219 * Description: 1220 * 1221 * This function sets up pGC to clear pixmaps. 1222 * 1223 * Return Values: 1224 * 1225 * TRUE - setup was successful 1226 * FALSE - the window's background state is NONE 1227 * 1228 *****************************************************************************/ 1229 1230static Bool 1231DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC) 1232{ 1233 ChangeGCVal gcvalues[4]; 1234 int ts_x_origin, ts_y_origin; 1235 PixUnion background; 1236 int backgroundState; 1237 Mask gcmask; 1238 1239 1240 /* First take care of any ParentRelative stuff by altering the 1241 * tile/stipple origin to match the coordinates of the upper-left 1242 * corner of the first ancestor without a ParentRelative background. 1243 * This coordinate is, of course, negative. 1244 */ 1245 ts_x_origin = ts_y_origin = 0; 1246 while (pWin->backgroundState == ParentRelative) 1247 { 1248 ts_x_origin -= pWin->origin.x; 1249 ts_y_origin -= pWin->origin.y; 1250 1251 pWin = pWin->parent; 1252 } 1253 backgroundState = pWin->backgroundState; 1254 background = pWin->background; 1255 1256 switch (backgroundState) 1257 { 1258 case BackgroundPixel: 1259 gcvalues[0].val = background.pixel; 1260 gcvalues[1].val = FillSolid; 1261 gcmask = GCForeground|GCFillStyle; 1262 break; 1263 1264 case BackgroundPixmap: 1265 gcvalues[0].val = FillTiled; 1266 gcvalues[1].ptr = background.pixmap; 1267 gcvalues[2].val = ts_x_origin; 1268 gcvalues[3].val = ts_y_origin; 1269 gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin; 1270 break; 1271 1272 default: 1273 /* pWin->backgroundState == None */ 1274 return FALSE; 1275 } 1276 1277 return ChangeGC(NullClient, pGC, gcmask, gcvalues) == 0; 1278} /* DbeSetupBackgroundPainter() */ 1279 1280 1281/****************************************************************************** 1282 * 1283 * DBE DIX Procedure: DbeDrawableDelete 1284 * 1285 * Description: 1286 * 1287 * This is the resource delete function for dbeDrawableResType. 1288 * It is registered when the drawable resource type is created in 1289 * DbeExtensionInit(). 1290 * 1291 * To make resource deletion simple, we do not do anything in this function 1292 * and leave all resource deleteion to DbeWindowPrivDelete(), which will 1293 * eventually be called or already has been called. Deletion functions are 1294 * not guaranteed to be called in any particular order. 1295 * 1296 *****************************************************************************/ 1297static int 1298DbeDrawableDelete(pointer pDrawable, XID id) 1299{ 1300 return Success; 1301 1302} /* DbeDrawableDelete() */ 1303 1304 1305/****************************************************************************** 1306 * 1307 * DBE DIX Procedure: DbeWindowPrivDelete 1308 * 1309 * Description: 1310 * 1311 * This is the resource delete function for dbeWindowPrivResType. 1312 * It is registered when the drawable resource type is created in 1313 * DbeExtensionInit(). 1314 * 1315 *****************************************************************************/ 1316static int 1317DbeWindowPrivDelete(pointer pDbeWinPriv, XID id) 1318{ 1319 DbeScreenPrivPtr pDbeScreenPriv; 1320 DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr)pDbeWinPriv; 1321 int i; 1322 1323 1324 /* 1325 ************************************************************************** 1326 ** Remove the buffer ID from the ID array. 1327 ************************************************************************** 1328 */ 1329 1330 /* Find the ID in the ID array. */ 1331 i = 0; 1332 while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id)) 1333 { 1334 i++; 1335 } 1336 1337 if (i == pDbeWindowPriv->nBufferIDs) 1338 { 1339 /* We did not find the ID in the array. We should never get here. */ 1340 return BadValue; 1341 } 1342 1343 /* Remove the ID from the array. */ 1344 1345 if (i < (pDbeWindowPriv->nBufferIDs - 1)) 1346 { 1347 /* Compress the buffer ID array, overwriting the ID in the process. */ 1348 memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i+1], 1349 (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID)); 1350 } 1351 else 1352 { 1353 /* We are removing the last ID in the array, in which case, the 1354 * assignement below is all that we need to do. 1355 */ 1356 } 1357 pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT; 1358 1359 pDbeWindowPriv->nBufferIDs--; 1360 1361 /* If an extended array was allocated, then check to see if the remaining 1362 * buffer IDs will fit in the static array. 1363 */ 1364 1365 if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) && 1366 (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS)) 1367 { 1368 /* Copy the IDs back into the static array. */ 1369 memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs, 1370 DBE_INIT_MAX_IDS * sizeof(XID)); 1371 1372 /* Free the extended array; use the static array. */ 1373 free(pDbeWindowPriv->IDs); 1374 pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs; 1375 pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; 1376 } 1377 1378 1379 /* 1380 ************************************************************************** 1381 ** Perform DDX level tasks. 1382 ************************************************************************** 1383 */ 1384 1385 pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV( 1386 (DbeWindowPrivPtr)pDbeWindowPriv); 1387 (*pDbeScreenPriv->WinPrivDelete)((DbeWindowPrivPtr)pDbeWindowPriv, id); 1388 1389 1390 /* 1391 ************************************************************************** 1392 ** Perform miscellaneous tasks if this is the last buffer associated 1393 ** with the window. 1394 ************************************************************************** 1395 */ 1396 1397 if (pDbeWindowPriv->nBufferIDs == 0) 1398 { 1399 /* Reset the DBE window priv pointer. */ 1400 dixSetPrivate(&pDbeWindowPriv->pWindow->devPrivates, dbeWindowPrivKey, 1401 NULL); 1402 1403 /* We are done with the window priv. */ 1404 dixFreeObjectWithPrivates(pDbeWindowPriv, PRIVATE_DBE_WINDOW); 1405 } 1406 1407 return Success; 1408 1409} /* DbeWindowPrivDelete() */ 1410 1411 1412/****************************************************************************** 1413 * 1414 * DBE DIX Procedure: DbeResetProc 1415 * 1416 * Description: 1417 * 1418 * This routine is called at the end of every server generation. 1419 * It deallocates any memory reserved for the extension and performs any 1420 * other tasks related to shutting down the extension. 1421 * 1422 *****************************************************************************/ 1423static void 1424DbeResetProc(ExtensionEntry *extEntry) 1425{ 1426 int i; 1427 ScreenPtr pScreen; 1428 DbeScreenPrivPtr pDbeScreenPriv; 1429 1430 for (i = 0; i < screenInfo.numScreens; i++) 1431 { 1432 pScreen = screenInfo.screens[i]; 1433 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1434 1435 if (pDbeScreenPriv) 1436 { 1437 /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit().*/ 1438 pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; 1439 1440 if (pDbeScreenPriv->ResetProc) 1441 (*pDbeScreenPriv->ResetProc)(pScreen); 1442 1443 free(pDbeScreenPriv); 1444 } 1445 } 1446} /* DbeResetProc() */ 1447 1448 1449/****************************************************************************** 1450 * 1451 * DBE DIX Procedure: DbeDestroyWindow 1452 * 1453 * Description: 1454 * 1455 * This is the wrapper for pScreen->DestroyWindow. 1456 * This function frees buffer resources for a window before it is 1457 * destroyed. 1458 * 1459 *****************************************************************************/ 1460 1461static Bool 1462DbeDestroyWindow(WindowPtr pWin) 1463{ 1464 DbeScreenPrivPtr pDbeScreenPriv; 1465 DbeWindowPrivPtr pDbeWindowPriv; 1466 ScreenPtr pScreen; 1467 Bool ret; 1468 1469 1470 /* 1471 ************************************************************************** 1472 ** 1. Unwrap the member routine. 1473 ************************************************************************** 1474 */ 1475 1476 pScreen = pWin->drawable.pScreen; 1477 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1478 pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow; 1479 1480 /* 1481 ************************************************************************** 1482 ** 2. Do any work necessary before the member routine is called. 1483 ** 1484 ** Call the window priv delete function for all buffer IDs associated 1485 ** with this window. 1486 ************************************************************************** 1487 */ 1488 1489 if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) 1490 { 1491 while (pDbeWindowPriv) 1492 { 1493 /* *DbeWinPrivDelete() will free the window private and set it to 1494 * NULL if there are no more buffer IDs associated with this 1495 * window. 1496 */ 1497 FreeResource(pDbeWindowPriv->IDs[0], RT_NONE); 1498 pDbeWindowPriv = DBE_WINDOW_PRIV(pWin); 1499 } 1500 } 1501 1502 /* 1503 ************************************************************************** 1504 ** 3. Call the member routine, saving its result if necessary. 1505 ************************************************************************** 1506 */ 1507 1508 ret = (*pScreen->DestroyWindow)(pWin); 1509 1510 /* 1511 ************************************************************************** 1512 ** 4. Rewrap the member routine, restoring the wrapper value first in case 1513 ** the wrapper (or something that it wrapped) change this value. 1514 ************************************************************************** 1515 */ 1516 1517 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; 1518 pScreen->DestroyWindow = DbeDestroyWindow; 1519 1520 /* 1521 ************************************************************************** 1522 ** 5. Do any work necessary after the member routine has been called. 1523 ** 1524 ** In this case we do not need to do anything. 1525 ************************************************************************** 1526 */ 1527 1528 return ret; 1529 1530} /* DbeDestroyWindow() */ 1531 1532 1533/****************************************************************************** 1534 * 1535 * DBE DIX Procedure: DbeExtensionInit 1536 * 1537 * Description: 1538 * 1539 * Called from InitExtensions in main() 1540 * 1541 *****************************************************************************/ 1542 1543void 1544DbeExtensionInit(void) 1545{ 1546 ExtensionEntry *extEntry; 1547 register int i, j; 1548 ScreenPtr pScreen = NULL; 1549 DbeScreenPrivPtr pDbeScreenPriv; 1550 int nStubbedScreens = 0; 1551 Bool ddxInitSuccess; 1552 1553#ifdef PANORAMIX 1554 if(!noPanoramiXExtension) return; 1555#endif 1556 1557 /* Create the resource types. */ 1558 dbeDrawableResType = 1559 CreateNewResourceType(DbeDrawableDelete, "dbeDrawable"); 1560 if (!dbeDrawableResType) 1561 return; 1562 dbeDrawableResType |= RC_DRAWABLE; 1563 1564 dbeWindowPrivResType = 1565 CreateNewResourceType(DbeWindowPrivDelete, "dbeWindow"); 1566 if (!dbeWindowPrivResType) 1567 return; 1568 1569 if (!dixRegisterPrivateKey(&dbeScreenPrivKeyRec, PRIVATE_SCREEN, 0)) 1570 return; 1571 1572 if (!dixRegisterPrivateKey(&dbeWindowPrivKeyRec, PRIVATE_WINDOW, 0)) 1573 return; 1574 1575 for (i = 0; i < screenInfo.numScreens; i++) 1576 { 1577 /* For each screen, set up DBE screen privates and init DIX and DDX 1578 * interface. 1579 */ 1580 1581 pScreen = screenInfo.screens[i]; 1582 1583 if (!(pDbeScreenPriv = malloc (sizeof (DbeScreenPrivRec)))) 1584 { 1585 /* If we can not alloc a window or screen private, 1586 * then free any privates that we already alloc'ed and return 1587 */ 1588 1589 for (j = 0; j < i; j++) 1590 { 1591 free(dixLookupPrivate(&screenInfo.screens[j]->devPrivates, 1592 dbeScreenPrivKey)); 1593 dixSetPrivate(&screenInfo.screens[j]->devPrivates, 1594 dbeScreenPrivKey, NULL); 1595 } 1596 return; 1597 } 1598 1599 dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, pDbeScreenPriv); 1600 1601 { 1602 /* We don't have DDX support for DBE anymore */ 1603 1604#ifndef DISABLE_MI_DBE_BY_DEFAULT 1605 /* Setup DIX. */ 1606 pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter; 1607 1608 /* Setup DDX. */ 1609 ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv); 1610 1611 /* DDX DBE initialization may have the side affect of 1612 * reallocating pDbeScreenPriv, so we need to update it. 1613 */ 1614 pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen); 1615 1616 if (ddxInitSuccess) 1617 { 1618 /* Wrap DestroyWindow. The DDX initialization function 1619 * already wrapped PositionWindow for us. 1620 */ 1621 1622 pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow; 1623 pScreen->DestroyWindow = DbeDestroyWindow; 1624 } 1625 else 1626 { 1627 /* DDX initialization failed. Stub the screen. */ 1628 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); 1629 } 1630#else 1631 DbeStubScreen(pDbeScreenPriv, &nStubbedScreens); 1632#endif 1633 1634 } 1635 1636 } /* for (i = 0; i < screenInfo.numScreens; i++) */ 1637 1638 1639 if (nStubbedScreens == screenInfo.numScreens) 1640 { 1641 /* All screens stubbed. Clean up and return. */ 1642 1643 for (i = 0; i < screenInfo.numScreens; i++) 1644 { 1645 free(dixLookupPrivate(&screenInfo.screens[i]->devPrivates, 1646 dbeScreenPrivKey)); 1647 dixSetPrivate(&pScreen->devPrivates, dbeScreenPrivKey, NULL); 1648 } 1649 return; 1650 } 1651 1652 1653 /* Now add the extension. */ 1654 extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents, 1655 DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch, 1656 DbeResetProc, StandardMinorOpcode); 1657 1658 dbeErrorBase = extEntry->errorBase; 1659 SetResourceTypeErrorValue(dbeWindowPrivResType, dbeErrorBase + DbeBadBuffer); 1660 SetResourceTypeErrorValue(dbeDrawableResType, dbeErrorBase + DbeBadBuffer); 1661 1662} /* DbeExtensionInit() */ 1663 1664