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