1/* 2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Copyright © 2003 Keith Packard 24 * 25 * Permission to use, copy, modify, distribute, and sell this software and its 26 * documentation for any purpose is hereby granted without fee, provided that 27 * the above copyright notice appear in all copies and that both that 28 * copyright notice and this permission notice appear in supporting 29 * documentation, and that the name of Keith Packard not be used in 30 * advertising or publicity pertaining to distribution of the software without 31 * specific, written prior permission. Keith Packard makes no 32 * representations about the suitability of this software for any purpose. It 33 * is provided "as is" without express or implied warranty. 34 * 35 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 36 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 37 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 38 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 39 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 40 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 41 * PERFORMANCE OF THIS SOFTWARE. 42 */ 43 44#ifdef HAVE_DIX_CONFIG_H 45#include <dix-config.h> 46#endif 47 48#include "compint.h" 49#include "xace.h" 50#include "protocol-versions.h" 51#include "extinit.h" 52 53static CARD8 CompositeReqCode; 54static DevPrivateKeyRec CompositeClientPrivateKeyRec; 55 56#define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec) 57RESTYPE CompositeClientWindowType; 58RESTYPE CompositeClientSubwindowsType; 59RESTYPE CompositeClientOverlayType; 60 61typedef struct _CompositeClient { 62 int major_version; 63 int minor_version; 64} CompositeClientRec, *CompositeClientPtr; 65 66#define GetCompositeClient(pClient) ((CompositeClientPtr) \ 67 dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey)) 68 69static int 70FreeCompositeClientWindow(void *value, XID ccwid) 71{ 72 WindowPtr pWin = value; 73 74 compFreeClientWindow(pWin, ccwid); 75 return Success; 76} 77 78static int 79FreeCompositeClientSubwindows(void *value, XID ccwid) 80{ 81 WindowPtr pWin = value; 82 83 compFreeClientSubwindows(pWin, ccwid); 84 return Success; 85} 86 87static int 88FreeCompositeClientOverlay(void *value, XID ccwid) 89{ 90 CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; 91 92 compFreeOverlayClient(pOc); 93 return Success; 94} 95 96static int 97ProcCompositeQueryVersion(ClientPtr client) 98{ 99 CompositeClientPtr pCompositeClient = GetCompositeClient(client); 100 xCompositeQueryVersionReply rep = { 101 .type = X_Reply, 102 .sequenceNumber = client->sequence, 103 .length = 0 104 }; 105 106 REQUEST(xCompositeQueryVersionReq); 107 108 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); 109 if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) { 110 rep.majorVersion = stuff->majorVersion; 111 rep.minorVersion = stuff->minorVersion; 112 } 113 else { 114 rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION; 115 rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION; 116 } 117 pCompositeClient->major_version = rep.majorVersion; 118 pCompositeClient->minor_version = rep.minorVersion; 119 if (client->swapped) { 120 swaps(&rep.sequenceNumber); 121 swapl(&rep.length); 122 swapl(&rep.majorVersion); 123 swapl(&rep.minorVersion); 124 } 125 WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep); 126 return Success; 127} 128 129#define VERIFY_WINDOW(pWindow, wid, client, mode) \ 130 do { \ 131 int err; \ 132 err = dixLookupResourceByType((void **) &pWindow, wid, \ 133 RT_WINDOW, client, mode); \ 134 if (err != Success) { \ 135 client->errorValue = wid; \ 136 return err; \ 137 } \ 138 } while (0) 139 140static int 141ProcCompositeRedirectWindow(ClientPtr client) 142{ 143 WindowPtr pWin; 144 145 REQUEST(xCompositeRedirectWindowReq); 146 147 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); 148 VERIFY_WINDOW(pWin, stuff->window, client, 149 DixSetAttrAccess | DixManageAccess | DixBlendAccess); 150 151 return compRedirectWindow(client, pWin, stuff->update); 152} 153 154static int 155ProcCompositeRedirectSubwindows(ClientPtr client) 156{ 157 WindowPtr pWin; 158 159 REQUEST(xCompositeRedirectSubwindowsReq); 160 161 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); 162 VERIFY_WINDOW(pWin, stuff->window, client, 163 DixSetAttrAccess | DixManageAccess | DixBlendAccess); 164 165 return compRedirectSubwindows(client, pWin, stuff->update); 166} 167 168static int 169ProcCompositeUnredirectWindow(ClientPtr client) 170{ 171 WindowPtr pWin; 172 173 REQUEST(xCompositeUnredirectWindowReq); 174 175 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); 176 VERIFY_WINDOW(pWin, stuff->window, client, 177 DixSetAttrAccess | DixManageAccess | DixBlendAccess); 178 179 return compUnredirectWindow(client, pWin, stuff->update); 180} 181 182static int 183ProcCompositeUnredirectSubwindows(ClientPtr client) 184{ 185 WindowPtr pWin; 186 187 REQUEST(xCompositeUnredirectSubwindowsReq); 188 189 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); 190 VERIFY_WINDOW(pWin, stuff->window, client, 191 DixSetAttrAccess | DixManageAccess | DixBlendAccess); 192 193 return compUnredirectSubwindows(client, pWin, stuff->update); 194} 195 196static int 197ProcCompositeCreateRegionFromBorderClip(ClientPtr client) 198{ 199 WindowPtr pWin; 200 CompWindowPtr cw; 201 RegionPtr pBorderClip, pRegion; 202 203 REQUEST(xCompositeCreateRegionFromBorderClipReq); 204 205 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); 206 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); 207 LEGAL_NEW_RESOURCE(stuff->region, client); 208 209 cw = GetCompWindow(pWin); 210 if (cw) 211 pBorderClip = &cw->borderClip; 212 else 213 pBorderClip = &pWin->borderClip; 214 pRegion = XFixesRegionCopy(pBorderClip); 215 if (!pRegion) 216 return BadAlloc; 217 RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y); 218 219 if (!AddResource(stuff->region, RegionResType, (void *) pRegion)) 220 return BadAlloc; 221 222 return Success; 223} 224 225static int 226ProcCompositeNameWindowPixmap(ClientPtr client) 227{ 228 WindowPtr pWin; 229 CompWindowPtr cw; 230 PixmapPtr pPixmap; 231 ScreenPtr pScreen; 232 int rc; 233 234 REQUEST(xCompositeNameWindowPixmapReq); 235 236 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); 237 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); 238 239 pScreen = pWin->drawable.pScreen; 240 241 if (!pWin->viewable) 242 return BadMatch; 243 244 LEGAL_NEW_RESOURCE(stuff->pixmap, client); 245 246 cw = GetCompWindow(pWin); 247 if (!cw) 248 return BadMatch; 249 250 pPixmap = (*pScreen->GetWindowPixmap) (pWin); 251 if (!pPixmap) 252 return BadMatch; 253 254 /* security creation/labeling check */ 255 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, 256 pPixmap, RT_WINDOW, pWin, DixCreateAccess); 257 if (rc != Success) 258 return rc; 259 260 ++pPixmap->refcnt; 261 262 if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pPixmap)) 263 return BadAlloc; 264 265 if (pScreen->NameWindowPixmap) { 266 rc = pScreen->NameWindowPixmap(pWin, pPixmap, stuff->pixmap); 267 if (rc != Success) { 268 FreeResource(stuff->pixmap, RT_NONE); 269 return rc; 270 } 271 } 272 273 return Success; 274} 275 276static int 277ProcCompositeGetOverlayWindow(ClientPtr client) 278{ 279 REQUEST(xCompositeGetOverlayWindowReq); 280 xCompositeGetOverlayWindowReply rep; 281 WindowPtr pWin; 282 ScreenPtr pScreen; 283 CompScreenPtr cs; 284 CompOverlayClientPtr pOc; 285 int rc; 286 287 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); 288 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); 289 pScreen = pWin->drawable.pScreen; 290 291 /* 292 * Create an OverlayClient structure to mark this client's 293 * interest in the overlay window 294 */ 295 pOc = compCreateOverlayClient(pScreen, client); 296 if (pOc == NULL) 297 return BadAlloc; 298 299 /* 300 * Make sure the overlay window exists 301 */ 302 cs = GetCompScreen(pScreen); 303 if (cs->pOverlayWin == NULL) 304 if (!compCreateOverlayWindow(pScreen)) { 305 FreeResource(pOc->resource, RT_NONE); 306 return BadAlloc; 307 } 308 309 rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id, 310 RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess); 311 if (rc != Success) { 312 FreeResource(pOc->resource, RT_NONE); 313 return rc; 314 } 315 316 rep = (xCompositeGetOverlayWindowReply) { 317 .type = X_Reply, 318 .sequenceNumber = client->sequence, 319 .length = 0, 320 .overlayWin = cs->pOverlayWin->drawable.id 321 }; 322 323 if (client->swapped) { 324 swaps(&rep.sequenceNumber); 325 swapl(&rep.length); 326 swapl(&rep.overlayWin); 327 } 328 WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep); 329 330 return Success; 331} 332 333static int 334ProcCompositeReleaseOverlayWindow(ClientPtr client) 335{ 336 REQUEST(xCompositeReleaseOverlayWindowReq); 337 WindowPtr pWin; 338 CompOverlayClientPtr pOc; 339 340 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); 341 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); 342 343 /* 344 * Has client queried a reference to the overlay window 345 * on this screen? If not, generate an error. 346 */ 347 pOc = compFindOverlayClient(pWin->drawable.pScreen, client); 348 if (pOc == NULL) 349 return BadMatch; 350 351 /* The delete function will free the client structure */ 352 FreeResource(pOc->resource, RT_NONE); 353 354 return Success; 355} 356 357static int (*ProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = { 358ProcCompositeQueryVersion, 359 ProcCompositeRedirectWindow, 360 ProcCompositeRedirectSubwindows, 361 ProcCompositeUnredirectWindow, 362 ProcCompositeUnredirectSubwindows, 363 ProcCompositeCreateRegionFromBorderClip, 364 ProcCompositeNameWindowPixmap, 365 ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,}; 366 367static int 368ProcCompositeDispatch(ClientPtr client) 369{ 370 REQUEST(xReq); 371 372 if (stuff->data < CompositeNumberRequests) 373 return (*ProcCompositeVector[stuff->data]) (client); 374 else 375 return BadRequest; 376} 377 378static int _X_COLD 379SProcCompositeQueryVersion(ClientPtr client) 380{ 381 REQUEST(xCompositeQueryVersionReq); 382 383 swaps(&stuff->length); 384 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); 385 swapl(&stuff->majorVersion); 386 swapl(&stuff->minorVersion); 387 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 388} 389 390static int _X_COLD 391SProcCompositeRedirectWindow(ClientPtr client) 392{ 393 REQUEST(xCompositeRedirectWindowReq); 394 395 swaps(&stuff->length); 396 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); 397 swapl(&stuff->window); 398 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 399} 400 401static int _X_COLD 402SProcCompositeRedirectSubwindows(ClientPtr client) 403{ 404 REQUEST(xCompositeRedirectSubwindowsReq); 405 406 swaps(&stuff->length); 407 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); 408 swapl(&stuff->window); 409 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 410} 411 412static int _X_COLD 413SProcCompositeUnredirectWindow(ClientPtr client) 414{ 415 REQUEST(xCompositeUnredirectWindowReq); 416 417 swaps(&stuff->length); 418 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); 419 swapl(&stuff->window); 420 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 421} 422 423static int _X_COLD 424SProcCompositeUnredirectSubwindows(ClientPtr client) 425{ 426 REQUEST(xCompositeUnredirectSubwindowsReq); 427 428 swaps(&stuff->length); 429 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); 430 swapl(&stuff->window); 431 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 432} 433 434static int _X_COLD 435SProcCompositeCreateRegionFromBorderClip(ClientPtr client) 436{ 437 REQUEST(xCompositeCreateRegionFromBorderClipReq); 438 439 swaps(&stuff->length); 440 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); 441 swapl(&stuff->region); 442 swapl(&stuff->window); 443 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 444} 445 446static int _X_COLD 447SProcCompositeNameWindowPixmap(ClientPtr client) 448{ 449 REQUEST(xCompositeNameWindowPixmapReq); 450 451 swaps(&stuff->length); 452 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); 453 swapl(&stuff->window); 454 swapl(&stuff->pixmap); 455 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 456} 457 458static int _X_COLD 459SProcCompositeGetOverlayWindow(ClientPtr client) 460{ 461 REQUEST(xCompositeGetOverlayWindowReq); 462 463 swaps(&stuff->length); 464 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); 465 swapl(&stuff->window); 466 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 467} 468 469static int _X_COLD 470SProcCompositeReleaseOverlayWindow(ClientPtr client) 471{ 472 REQUEST(xCompositeReleaseOverlayWindowReq); 473 474 swaps(&stuff->length); 475 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); 476 swapl(&stuff->window); 477 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 478} 479 480static int 481(*SProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = { 482 SProcCompositeQueryVersion, 483 SProcCompositeRedirectWindow, 484 SProcCompositeRedirectSubwindows, 485 SProcCompositeUnredirectWindow, 486 SProcCompositeUnredirectSubwindows, 487 SProcCompositeCreateRegionFromBorderClip, 488 SProcCompositeNameWindowPixmap, 489 SProcCompositeGetOverlayWindow, 490 SProcCompositeReleaseOverlayWindow, 491}; 492 493static int _X_COLD 494SProcCompositeDispatch(ClientPtr client) 495{ 496 REQUEST(xReq); 497 498 if (stuff->data < CompositeNumberRequests) 499 return (*SProcCompositeVector[stuff->data]) (client); 500 else 501 return BadRequest; 502} 503 504/** @see GetDefaultBytes */ 505static SizeType coreGetWindowBytes; 506 507static void 508GetCompositeWindowBytes(void *value, XID id, ResourceSizePtr size) 509{ 510 WindowPtr window = value; 511 512 /* call down */ 513 coreGetWindowBytes(value, id, size); 514 515 /* account for redirection */ 516 if (window->redirectDraw != RedirectDrawNone) 517 { 518 SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); 519 ResourceSizeRec pixmapSize = { 0, 0 }; 520 ScreenPtr screen = window->drawable.pScreen; 521 PixmapPtr pixmap = screen->GetWindowPixmap(window); 522 pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); 523 size->pixmapRefSize += pixmapSize.pixmapRefSize; 524 } 525} 526 527void 528CompositeExtensionInit(void) 529{ 530 ExtensionEntry *extEntry; 531 int s; 532 533 /* Assume initialization is going to fail */ 534 noCompositeExtension = TRUE; 535 536 for (s = 0; s < screenInfo.numScreens; s++) { 537 ScreenPtr pScreen = screenInfo.screens[s]; 538 VisualPtr vis; 539 540 /* Composite on 8bpp pseudocolor root windows appears to fail, so 541 * just disable it on anything pseudocolor for safety. 542 */ 543 for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++); 544 if ((vis->class | DynamicClass) == PseudoColor) 545 return; 546 547 /* Ensure that Render is initialized, which is required for automatic 548 * compositing. 549 */ 550 if (GetPictureScreenIfSet(pScreen) == NULL) 551 return; 552 } 553 554 CompositeClientWindowType = CreateNewResourceType 555 (FreeCompositeClientWindow, "CompositeClientWindow"); 556 if (!CompositeClientWindowType) 557 return; 558 559 coreGetWindowBytes = GetResourceTypeSizeFunc(RT_WINDOW); 560 SetResourceTypeSizeFunc(RT_WINDOW, GetCompositeWindowBytes); 561 562 CompositeClientSubwindowsType = CreateNewResourceType 563 (FreeCompositeClientSubwindows, "CompositeClientSubwindows"); 564 if (!CompositeClientSubwindowsType) 565 return; 566 567 CompositeClientOverlayType = CreateNewResourceType 568 (FreeCompositeClientOverlay, "CompositeClientOverlay"); 569 if (!CompositeClientOverlayType) 570 return; 571 572 if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT, 573 sizeof(CompositeClientRec))) 574 return; 575 576 for (s = 0; s < screenInfo.numScreens; s++) 577 if (!compScreenInit(screenInfo.screens[s])) 578 return; 579 580 extEntry = AddExtension(COMPOSITE_NAME, 0, 0, 581 ProcCompositeDispatch, SProcCompositeDispatch, 582 NULL, StandardMinorOpcode); 583 if (!extEntry) 584 return; 585 CompositeReqCode = (CARD8) extEntry->base; 586 587 /* Initialization succeeded */ 588 noCompositeExtension = FALSE; 589} 590 591#ifdef PANORAMIX 592#include "panoramiXsrv.h" 593 594int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr); 595 596static int 597PanoramiXCompositeRedirectWindow(ClientPtr client) 598{ 599 PanoramiXRes *win; 600 int rc = 0, j; 601 602 REQUEST(xCompositeRedirectWindowReq); 603 604 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); 605 606 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, 607 client, DixUnknownAccess))) { 608 client->errorValue = stuff->window; 609 return rc; 610 } 611 612 FOR_NSCREENS_FORWARD(j) { 613 stuff->window = win->info[j].id; 614 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); 615 if (rc != Success) 616 break; 617 } 618 619 return rc; 620} 621 622static int 623PanoramiXCompositeRedirectSubwindows(ClientPtr client) 624{ 625 PanoramiXRes *win; 626 int rc = 0, j; 627 628 REQUEST(xCompositeRedirectSubwindowsReq); 629 630 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); 631 632 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, 633 client, DixUnknownAccess))) { 634 client->errorValue = stuff->window; 635 return rc; 636 } 637 638 FOR_NSCREENS_FORWARD(j) { 639 stuff->window = win->info[j].id; 640 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); 641 if (rc != Success) 642 break; 643 } 644 645 return rc; 646} 647 648static int 649PanoramiXCompositeUnredirectWindow(ClientPtr client) 650{ 651 PanoramiXRes *win; 652 int rc = 0, j; 653 654 REQUEST(xCompositeUnredirectWindowReq); 655 656 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); 657 658 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, 659 client, DixUnknownAccess))) { 660 client->errorValue = stuff->window; 661 return rc; 662 } 663 664 FOR_NSCREENS_FORWARD(j) { 665 stuff->window = win->info[j].id; 666 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); 667 if (rc != Success) 668 break; 669 } 670 671 return rc; 672} 673 674static int 675PanoramiXCompositeUnredirectSubwindows(ClientPtr client) 676{ 677 PanoramiXRes *win; 678 int rc = 0, j; 679 680 REQUEST(xCompositeUnredirectSubwindowsReq); 681 682 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); 683 684 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, 685 client, DixUnknownAccess))) { 686 client->errorValue = stuff->window; 687 return rc; 688 } 689 690 FOR_NSCREENS_FORWARD(j) { 691 stuff->window = win->info[j].id; 692 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); 693 if (rc != Success) 694 break; 695 } 696 697 return rc; 698} 699 700static int 701PanoramiXCompositeNameWindowPixmap(ClientPtr client) 702{ 703 WindowPtr pWin; 704 CompWindowPtr cw; 705 PixmapPtr pPixmap; 706 int rc; 707 PanoramiXRes *win, *newPix; 708 int i; 709 710 REQUEST(xCompositeNameWindowPixmapReq); 711 712 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); 713 714 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, 715 client, DixUnknownAccess))) { 716 client->errorValue = stuff->window; 717 return rc; 718 } 719 720 LEGAL_NEW_RESOURCE(stuff->pixmap, client); 721 722 if (!(newPix = malloc(sizeof(PanoramiXRes)))) 723 return BadAlloc; 724 725 newPix->type = XRT_PIXMAP; 726 newPix->u.pix.shared = FALSE; 727 panoramix_setup_ids(newPix, client, stuff->pixmap); 728 729 FOR_NSCREENS(i) { 730 rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, 731 RT_WINDOW, client, DixGetAttrAccess); 732 if (rc != Success) { 733 client->errorValue = stuff->window; 734 free(newPix); 735 return rc; 736 } 737 738 if (!pWin->viewable) { 739 free(newPix); 740 return BadMatch; 741 } 742 743 cw = GetCompWindow(pWin); 744 if (!cw) { 745 free(newPix); 746 return BadMatch; 747 } 748 749 pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); 750 if (!pPixmap) { 751 free(newPix); 752 return BadMatch; 753 } 754 755 if (!AddResource(newPix->info[i].id, RT_PIXMAP, (void *) pPixmap)) 756 return BadAlloc; 757 758 ++pPixmap->refcnt; 759 } 760 761 if (!AddResource(stuff->pixmap, XRT_PIXMAP, (void *) newPix)) 762 return BadAlloc; 763 764 return Success; 765} 766 767static int 768PanoramiXCompositeGetOverlayWindow(ClientPtr client) 769{ 770 REQUEST(xCompositeGetOverlayWindowReq); 771 xCompositeGetOverlayWindowReply rep; 772 WindowPtr pWin; 773 ScreenPtr pScreen; 774 CompScreenPtr cs; 775 CompOverlayClientPtr pOc; 776 int rc; 777 PanoramiXRes *win, *overlayWin = NULL; 778 int i; 779 780 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); 781 782 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, 783 client, DixUnknownAccess))) { 784 client->errorValue = stuff->window; 785 return rc; 786 } 787 788 cs = GetCompScreen(screenInfo.screens[0]); 789 if (!cs->pOverlayWin) { 790 if (!(overlayWin = malloc(sizeof(PanoramiXRes)))) 791 return BadAlloc; 792 793 overlayWin->type = XRT_WINDOW; 794 overlayWin->u.win.root = FALSE; 795 } 796 797 FOR_NSCREENS_BACKWARD(i) { 798 rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, 799 RT_WINDOW, client, DixGetAttrAccess); 800 if (rc != Success) { 801 client->errorValue = stuff->window; 802 free(overlayWin); 803 return rc; 804 } 805 pScreen = pWin->drawable.pScreen; 806 807 /* 808 * Create an OverlayClient structure to mark this client's 809 * interest in the overlay window 810 */ 811 pOc = compCreateOverlayClient(pScreen, client); 812 if (pOc == NULL) { 813 free(overlayWin); 814 return BadAlloc; 815 } 816 817 /* 818 * Make sure the overlay window exists 819 */ 820 cs = GetCompScreen(pScreen); 821 if (cs->pOverlayWin == NULL) 822 if (!compCreateOverlayWindow(pScreen)) { 823 FreeResource(pOc->resource, RT_NONE); 824 free(overlayWin); 825 return BadAlloc; 826 } 827 828 rc = XaceHook(XACE_RESOURCE_ACCESS, client, 829 cs->pOverlayWin->drawable.id, 830 RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, 831 DixGetAttrAccess); 832 if (rc != Success) { 833 FreeResource(pOc->resource, RT_NONE); 834 free(overlayWin); 835 return rc; 836 } 837 } 838 839 if (overlayWin) { 840 FOR_NSCREENS(i) { 841 cs = GetCompScreen(screenInfo.screens[i]); 842 overlayWin->info[i].id = cs->pOverlayWin->drawable.id; 843 } 844 845 AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin); 846 } 847 848 cs = GetCompScreen(screenInfo.screens[0]); 849 850 rep = (xCompositeGetOverlayWindowReply) { 851 .type = X_Reply, 852 .sequenceNumber = client->sequence, 853 .length = 0, 854 .overlayWin = cs->pOverlayWin->drawable.id 855 }; 856 857 if (client->swapped) { 858 swaps(&rep.sequenceNumber); 859 swapl(&rep.length); 860 swapl(&rep.overlayWin); 861 } 862 WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep); 863 864 return Success; 865} 866 867static int 868PanoramiXCompositeReleaseOverlayWindow(ClientPtr client) 869{ 870 REQUEST(xCompositeReleaseOverlayWindowReq); 871 WindowPtr pWin; 872 CompOverlayClientPtr pOc; 873 PanoramiXRes *win; 874 int i, rc; 875 876 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); 877 878 if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, 879 client, DixUnknownAccess))) { 880 client->errorValue = stuff->window; 881 return rc; 882 } 883 884 FOR_NSCREENS_BACKWARD(i) { 885 if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, 886 XRT_WINDOW, client, 887 DixUnknownAccess))) { 888 client->errorValue = stuff->window; 889 return rc; 890 } 891 892 /* 893 * Has client queried a reference to the overlay window 894 * on this screen? If not, generate an error. 895 */ 896 pOc = compFindOverlayClient(pWin->drawable.pScreen, client); 897 if (pOc == NULL) 898 return BadMatch; 899 900 /* The delete function will free the client structure */ 901 FreeResource(pOc->resource, RT_NONE); 902 } 903 904 return Success; 905} 906 907void 908PanoramiXCompositeInit(void) 909{ 910 int i; 911 912 for (i = 0; i < CompositeNumberRequests; i++) 913 PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i]; 914 /* 915 * Stuff in Xinerama aware request processing hooks 916 */ 917 ProcCompositeVector[X_CompositeRedirectWindow] = 918 PanoramiXCompositeRedirectWindow; 919 ProcCompositeVector[X_CompositeRedirectSubwindows] = 920 PanoramiXCompositeRedirectSubwindows; 921 ProcCompositeVector[X_CompositeUnredirectWindow] = 922 PanoramiXCompositeUnredirectWindow; 923 ProcCompositeVector[X_CompositeUnredirectSubwindows] = 924 PanoramiXCompositeUnredirectSubwindows; 925 ProcCompositeVector[X_CompositeNameWindowPixmap] = 926 PanoramiXCompositeNameWindowPixmap; 927 ProcCompositeVector[X_CompositeGetOverlayWindow] = 928 PanoramiXCompositeGetOverlayWindow; 929 ProcCompositeVector[X_CompositeReleaseOverlayWindow] = 930 PanoramiXCompositeReleaseOverlayWindow; 931} 932 933void 934PanoramiXCompositeReset(void) 935{ 936 int i; 937 938 for (i = 0; i < CompositeNumberRequests; i++) 939 ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i]; 940} 941 942#endif 943