compext.c revision 706f2543
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 52static CARD8 CompositeReqCode; 53static DevPrivateKeyRec CompositeClientPrivateKeyRec; 54#define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec) 55RESTYPE CompositeClientWindowType; 56RESTYPE CompositeClientSubwindowsType; 57RESTYPE CompositeClientOverlayType; 58 59typedef struct _CompositeClient { 60 int major_version; 61 int minor_version; 62} CompositeClientRec, *CompositeClientPtr; 63 64#define GetCompositeClient(pClient) ((CompositeClientPtr) \ 65 dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey)) 66 67static void 68CompositeClientCallback (CallbackListPtr *list, 69 pointer closure, 70 pointer data) 71{ 72 NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; 73 ClientPtr pClient = clientinfo->client; 74 CompositeClientPtr pCompositeClient = GetCompositeClient (pClient); 75 76 pCompositeClient->major_version = 0; 77 pCompositeClient->minor_version = 0; 78} 79 80static int 81FreeCompositeClientWindow (pointer value, XID ccwid) 82{ 83 WindowPtr pWin = value; 84 85 compFreeClientWindow (pWin, ccwid); 86 return Success; 87} 88 89static int 90FreeCompositeClientSubwindows (pointer value, XID ccwid) 91{ 92 WindowPtr pWin = value; 93 94 compFreeClientSubwindows (pWin, ccwid); 95 return Success; 96} 97 98static int 99FreeCompositeClientOverlay (pointer value, XID ccwid) 100{ 101 CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; 102 103 compFreeOverlayClient (pOc); 104 return Success; 105} 106 107static int 108ProcCompositeQueryVersion (ClientPtr client) 109{ 110 CompositeClientPtr pCompositeClient = GetCompositeClient (client); 111 xCompositeQueryVersionReply rep; 112 register int n; 113 REQUEST(xCompositeQueryVersionReq); 114 115 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); 116 rep.type = X_Reply; 117 rep.length = 0; 118 rep.sequenceNumber = client->sequence; 119 if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) { 120 rep.majorVersion = stuff->majorVersion; 121 rep.minorVersion = stuff->minorVersion; 122 } else { 123 rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION; 124 rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION; 125 } 126 pCompositeClient->major_version = rep.majorVersion; 127 pCompositeClient->minor_version = rep.minorVersion; 128 if (client->swapped) { 129 swaps(&rep.sequenceNumber, n); 130 swapl(&rep.length, n); 131 swapl(&rep.majorVersion, n); 132 swapl(&rep.minorVersion, n); 133 } 134 WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep); 135 return Success; 136} 137 138#define VERIFY_WINDOW(pWindow, wid, client, mode) \ 139 do { \ 140 int err; \ 141 err = dixLookupResourceByType((pointer *) &pWindow, wid, \ 142 RT_WINDOW, client, mode); \ 143 if (err != Success) { \ 144 client->errorValue = wid; \ 145 return err; \ 146 } \ 147 } while (0) 148 149static int 150ProcCompositeRedirectWindow (ClientPtr client) 151{ 152 WindowPtr pWin; 153 REQUEST(xCompositeRedirectWindowReq); 154 155 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); 156 VERIFY_WINDOW(pWin, stuff->window, client, 157 DixSetAttrAccess|DixManageAccess|DixBlendAccess); 158 159 return compRedirectWindow (client, pWin, stuff->update); 160} 161 162static int 163ProcCompositeRedirectSubwindows (ClientPtr client) 164{ 165 WindowPtr pWin; 166 REQUEST(xCompositeRedirectSubwindowsReq); 167 168 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); 169 VERIFY_WINDOW(pWin, stuff->window, client, 170 DixSetAttrAccess|DixManageAccess|DixBlendAccess); 171 172 return compRedirectSubwindows (client, pWin, stuff->update); 173} 174 175static int 176ProcCompositeUnredirectWindow (ClientPtr client) 177{ 178 WindowPtr pWin; 179 REQUEST(xCompositeUnredirectWindowReq); 180 181 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); 182 VERIFY_WINDOW(pWin, stuff->window, client, 183 DixSetAttrAccess|DixManageAccess|DixBlendAccess); 184 185 return compUnredirectWindow (client, pWin, stuff->update); 186} 187 188static int 189ProcCompositeUnredirectSubwindows (ClientPtr client) 190{ 191 WindowPtr pWin; 192 REQUEST(xCompositeUnredirectSubwindowsReq); 193 194 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); 195 VERIFY_WINDOW(pWin, stuff->window, client, 196 DixSetAttrAccess|DixManageAccess|DixBlendAccess); 197 198 return compUnredirectSubwindows (client, pWin, stuff->update); 199} 200 201static int 202ProcCompositeCreateRegionFromBorderClip (ClientPtr client) 203{ 204 WindowPtr pWin; 205 CompWindowPtr cw; 206 RegionPtr pBorderClip, pRegion; 207 REQUEST(xCompositeCreateRegionFromBorderClipReq); 208 209 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); 210 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); 211 LEGAL_NEW_RESOURCE (stuff->region, client); 212 213 cw = GetCompWindow (pWin); 214 if (cw) 215 pBorderClip = &cw->borderClip; 216 else 217 pBorderClip = &pWin->borderClip; 218 pRegion = XFixesRegionCopy (pBorderClip); 219 if (!pRegion) 220 return BadAlloc; 221 RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y); 222 223 if (!AddResource (stuff->region, RegionResType, (pointer) pRegion)) 224 return BadAlloc; 225 226 return Success; 227} 228 229static int 230ProcCompositeNameWindowPixmap (ClientPtr client) 231{ 232 WindowPtr pWin; 233 CompWindowPtr cw; 234 PixmapPtr pPixmap; 235 int rc; 236 REQUEST(xCompositeNameWindowPixmapReq); 237 238 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); 239 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); 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 = (*pWin->drawable.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, (pointer) pPixmap)) 263 return BadAlloc; 264 265 return Success; 266} 267 268 269static int 270ProcCompositeGetOverlayWindow (ClientPtr client) 271{ 272 REQUEST(xCompositeGetOverlayWindowReq); 273 xCompositeGetOverlayWindowReply rep; 274 WindowPtr pWin; 275 ScreenPtr pScreen; 276 CompScreenPtr cs; 277 CompOverlayClientPtr pOc; 278 int rc; 279 280 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); 281 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); 282 pScreen = pWin->drawable.pScreen; 283 284 /* 285 * Create an OverlayClient structure to mark this client's 286 * interest in the overlay window 287 */ 288 pOc = compCreateOverlayClient(pScreen, client); 289 if (pOc == NULL) 290 return BadAlloc; 291 292 /* 293 * Make sure the overlay window exists 294 */ 295 cs = GetCompScreen(pScreen); 296 if (cs->pOverlayWin == NULL) 297 if (!compCreateOverlayWindow(pScreen)) 298 { 299 FreeResource (pOc->resource, RT_NONE); 300 return BadAlloc; 301 } 302 303 rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id, 304 RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess); 305 if (rc != Success) 306 { 307 FreeResource (pOc->resource, RT_NONE); 308 return rc; 309 } 310 311 rep.type = X_Reply; 312 rep.sequenceNumber = client->sequence; 313 rep.length = 0; 314 rep.overlayWin = cs->pOverlayWin->drawable.id; 315 316 if (client->swapped) 317 { 318 int n; 319 swaps(&rep.sequenceNumber, n); 320 swapl(&rep.length, n); 321 swapl(&rep.overlayWin, n); 322 } 323 (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep); 324 325 return Success; 326} 327 328static int 329ProcCompositeReleaseOverlayWindow (ClientPtr client) 330{ 331 REQUEST(xCompositeReleaseOverlayWindowReq); 332 WindowPtr pWin; 333 ScreenPtr pScreen; 334 CompOverlayClientPtr pOc; 335 336 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); 337 VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); 338 pScreen = pWin->drawable.pScreen; 339 340 /* 341 * Has client queried a reference to the overlay window 342 * on this screen? If not, generate an error. 343 */ 344 pOc = compFindOverlayClient (pWin->drawable.pScreen, client); 345 if (pOc == NULL) 346 return BadMatch; 347 348 /* The delete function will free the client structure */ 349 FreeResource (pOc->resource, RT_NONE); 350 351 return Success; 352} 353 354static int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { 355 ProcCompositeQueryVersion, 356 ProcCompositeRedirectWindow, 357 ProcCompositeRedirectSubwindows, 358 ProcCompositeUnredirectWindow, 359 ProcCompositeUnredirectSubwindows, 360 ProcCompositeCreateRegionFromBorderClip, 361 ProcCompositeNameWindowPixmap, 362 ProcCompositeGetOverlayWindow, 363 ProcCompositeReleaseOverlayWindow, 364}; 365 366static int 367ProcCompositeDispatch (ClientPtr client) 368{ 369 REQUEST(xReq); 370 371 if (stuff->data < CompositeNumberRequests) 372 return (*ProcCompositeVector[stuff->data]) (client); 373 else 374 return BadRequest; 375} 376 377static int 378SProcCompositeQueryVersion (ClientPtr client) 379{ 380 int n; 381 REQUEST(xCompositeQueryVersionReq); 382 383 swaps(&stuff->length, n); 384 REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); 385 swapl(&stuff->majorVersion, n); 386 swapl(&stuff->minorVersion, n); 387 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 388} 389 390static int 391SProcCompositeRedirectWindow (ClientPtr client) 392{ 393 int n; 394 REQUEST(xCompositeRedirectWindowReq); 395 396 swaps(&stuff->length, n); 397 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); 398 swapl (&stuff->window, n); 399 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 400} 401 402static int 403SProcCompositeRedirectSubwindows (ClientPtr client) 404{ 405 int n; 406 REQUEST(xCompositeRedirectSubwindowsReq); 407 408 swaps(&stuff->length, n); 409 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); 410 swapl (&stuff->window, n); 411 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 412} 413 414static int 415SProcCompositeUnredirectWindow (ClientPtr client) 416{ 417 int n; 418 REQUEST(xCompositeUnredirectWindowReq); 419 420 swaps(&stuff->length, n); 421 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); 422 swapl (&stuff->window, n); 423 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 424} 425 426static int 427SProcCompositeUnredirectSubwindows (ClientPtr client) 428{ 429 int n; 430 REQUEST(xCompositeUnredirectSubwindowsReq); 431 432 swaps(&stuff->length, n); 433 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); 434 swapl (&stuff->window, n); 435 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 436} 437 438static int 439SProcCompositeCreateRegionFromBorderClip (ClientPtr client) 440{ 441 int n; 442 REQUEST(xCompositeCreateRegionFromBorderClipReq); 443 444 swaps(&stuff->length, n); 445 REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); 446 swapl (&stuff->region, n); 447 swapl (&stuff->window, n); 448 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 449} 450 451static int 452SProcCompositeNameWindowPixmap (ClientPtr client) 453{ 454 int n; 455 REQUEST(xCompositeNameWindowPixmapReq); 456 457 swaps(&stuff->length, n); 458 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); 459 swapl (&stuff->window, n); 460 swapl (&stuff->pixmap, n); 461 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 462} 463 464static int 465SProcCompositeGetOverlayWindow (ClientPtr client) 466{ 467 int n; 468 REQUEST(xCompositeGetOverlayWindowReq); 469 470 swaps (&stuff->length, n); 471 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); 472 swapl(&stuff->window, n); 473 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 474} 475 476static int 477SProcCompositeReleaseOverlayWindow (ClientPtr client) 478{ 479 int n; 480 REQUEST(xCompositeReleaseOverlayWindowReq); 481 482 swaps (&stuff->length, n); 483 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); 484 swapl(&stuff->window, n); 485 return (*ProcCompositeVector[stuff->compositeReqType]) (client); 486} 487 488static int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = { 489 SProcCompositeQueryVersion, 490 SProcCompositeRedirectWindow, 491 SProcCompositeRedirectSubwindows, 492 SProcCompositeUnredirectWindow, 493 SProcCompositeUnredirectSubwindows, 494 SProcCompositeCreateRegionFromBorderClip, 495 SProcCompositeNameWindowPixmap, 496 SProcCompositeGetOverlayWindow, 497 SProcCompositeReleaseOverlayWindow, 498}; 499 500static int 501SProcCompositeDispatch (ClientPtr client) 502{ 503 REQUEST(xReq); 504 505 if (stuff->data < CompositeNumberRequests) 506 return (*SProcCompositeVector[stuff->data]) (client); 507 else 508 return BadRequest; 509} 510 511void 512CompositeExtensionInit (void) 513{ 514 ExtensionEntry *extEntry; 515 int s; 516 517 /* Assume initialization is going to fail */ 518 noCompositeExtension = TRUE; 519 520 for (s = 0; s < screenInfo.numScreens; s++) { 521 ScreenPtr pScreen = screenInfo.screens[s]; 522 VisualPtr vis; 523 524 /* Composite on 8bpp pseudocolor root windows appears to fail, so 525 * just disable it on anything pseudocolor for safety. 526 */ 527 for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++) 528 ; 529 if ((vis->class | DynamicClass) == PseudoColor) 530 return; 531 532 /* Ensure that Render is initialized, which is required for automatic 533 * compositing. 534 */ 535 if (GetPictureScreenIfSet(pScreen) == NULL) 536 return; 537 } 538 539 CompositeClientWindowType = CreateNewResourceType 540 (FreeCompositeClientWindow, "CompositeClientWindow"); 541 if (!CompositeClientWindowType) 542 return; 543 544 CompositeClientSubwindowsType = CreateNewResourceType 545 (FreeCompositeClientSubwindows, "CompositeClientSubwindows"); 546 if (!CompositeClientSubwindowsType) 547 return; 548 549 CompositeClientOverlayType = CreateNewResourceType 550 (FreeCompositeClientOverlay, "CompositeClientOverlay"); 551 if (!CompositeClientOverlayType) 552 return; 553 554 if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT, 555 sizeof(CompositeClientRec))) 556 return; 557 558 if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0)) 559 return; 560 561 for (s = 0; s < screenInfo.numScreens; s++) 562 if (!compScreenInit (screenInfo.screens[s])) 563 return; 564 565 extEntry = AddExtension (COMPOSITE_NAME, 0, 0, 566 ProcCompositeDispatch, SProcCompositeDispatch, 567 NULL, StandardMinorOpcode); 568 if (!extEntry) 569 return; 570 CompositeReqCode = (CARD8) extEntry->base; 571 572 miRegisterRedirectBorderClipProc (compSetRedirectBorderClip, 573 compGetRedirectBorderClip); 574 575 /* Initialization succeeded */ 576 noCompositeExtension = FALSE; 577} 578 579#ifdef PANORAMIX 580#include "panoramiXsrv.h" 581 582int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr); 583 584static int 585PanoramiXCompositeRedirectWindow (ClientPtr client) 586{ 587 PanoramiXRes *win; 588 int rc = 0, j; 589 REQUEST(xCompositeRedirectWindowReq); 590 591 REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); 592 593 if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, 594 client, DixUnknownAccess))) { 595 client->errorValue = stuff->window; 596 return rc; 597 } 598 599 FOR_NSCREENS_FORWARD(j) { 600 stuff->window = win->info[j].id; 601 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); 602 if (rc != Success) break; 603 } 604 605 return rc; 606} 607 608static int 609PanoramiXCompositeRedirectSubwindows (ClientPtr client) 610{ 611 PanoramiXRes *win; 612 int rc = 0, j; 613 REQUEST(xCompositeRedirectSubwindowsReq); 614 615 REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); 616 617 if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, 618 client, DixUnknownAccess))) { 619 client->errorValue = stuff->window; 620 return rc; 621 } 622 623 FOR_NSCREENS_FORWARD(j) { 624 stuff->window = win->info[j].id; 625 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); 626 if (rc != Success) break; 627 } 628 629 return rc; 630} 631 632static int 633PanoramiXCompositeUnredirectWindow (ClientPtr client) 634{ 635 PanoramiXRes *win; 636 int rc = 0, j; 637 REQUEST(xCompositeUnredirectWindowReq); 638 639 REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); 640 641 if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, 642 client, DixUnknownAccess))) { 643 client->errorValue = stuff->window; 644 return rc; 645 } 646 647 FOR_NSCREENS_FORWARD(j) { 648 stuff->window = win->info[j].id; 649 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); 650 if (rc != Success) break; 651 } 652 653 return rc; 654} 655 656static int 657PanoramiXCompositeUnredirectSubwindows (ClientPtr client) 658{ 659 PanoramiXRes *win; 660 int rc = 0, j; 661 REQUEST(xCompositeUnredirectSubwindowsReq); 662 663 REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); 664 665 if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, 666 client, DixUnknownAccess))) { 667 client->errorValue = stuff->window; 668 return rc; 669 } 670 671 FOR_NSCREENS_FORWARD(j) { 672 stuff->window = win->info[j].id; 673 rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); 674 if (rc != Success) break; 675 } 676 677 return rc; 678} 679 680static int 681PanoramiXCompositeNameWindowPixmap (ClientPtr client) 682{ 683 WindowPtr pWin; 684 CompWindowPtr cw; 685 PixmapPtr pPixmap; 686 int rc; 687 PanoramiXRes *win, *newPix; 688 int i; 689 REQUEST(xCompositeNameWindowPixmapReq); 690 691 REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); 692 693 if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, 694 client, DixUnknownAccess))) { 695 client->errorValue = stuff->window; 696 return rc; 697 } 698 699 LEGAL_NEW_RESOURCE (stuff->pixmap, client); 700 701 if(!(newPix = malloc(sizeof(PanoramiXRes)))) 702 return BadAlloc; 703 704 newPix->type = XRT_PIXMAP; 705 newPix->u.pix.shared = FALSE; 706 newPix->info[0].id = stuff->pixmap; 707 708 for (i = 1; i < PanoramiXNumScreens; i++) 709 newPix->info[i].id = FakeClientID (client->index); 710 711 FOR_NSCREENS(i) { 712 rc = dixLookupResourceByType ((void **) &pWin, win->info[i].id, 713 RT_WINDOW, client, DixGetAttrAccess); 714 if (rc != Success) 715 { 716 client->errorValue = stuff->window; 717 free (newPix); 718 return rc; 719 } 720 721 if (!pWin->viewable) 722 { 723 free (newPix); 724 return BadMatch; 725 } 726 727 cw = GetCompWindow (pWin); 728 if (!cw) 729 { 730 free (newPix); 731 return BadMatch; 732 } 733 734 pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); 735 if (!pPixmap) 736 { 737 free (newPix); 738 return BadMatch; 739 } 740 741 if (!AddResource (newPix->info[i].id, RT_PIXMAP, 742 (pointer) pPixmap)) 743 return BadAlloc; 744 745 ++pPixmap->refcnt; 746 } 747 748 if (!AddResource (stuff->pixmap, XRT_PIXMAP, (pointer) newPix)) 749 return BadAlloc; 750 751 return Success; 752} 753 754 755static int 756PanoramiXCompositeGetOverlayWindow (ClientPtr client) 757{ 758 REQUEST(xCompositeGetOverlayWindowReq); 759 xCompositeGetOverlayWindowReply rep; 760 WindowPtr pWin; 761 ScreenPtr pScreen; 762 CompScreenPtr cs; 763 CompOverlayClientPtr pOc; 764 int rc; 765 PanoramiXRes *win, *overlayWin = NULL; 766 int i; 767 768 REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); 769 770 if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, 771 client, DixUnknownAccess))) { 772 client->errorValue = stuff->window; 773 return rc; 774 } 775 776 cs = GetCompScreen(screenInfo.screens[0]); 777 if (!cs->pOverlayWin) 778 { 779 if(!(overlayWin = malloc(sizeof(PanoramiXRes)))) 780 return BadAlloc; 781 782 overlayWin->type = XRT_WINDOW; 783 overlayWin->u.win.root = FALSE; 784 } 785 786 FOR_NSCREENS_BACKWARD(i) { 787 rc = dixLookupResourceByType((pointer *)&pWin, win->info[i].id, 788 RT_WINDOW, client, DixGetAttrAccess); 789 if (rc != Success) 790 { 791 client->errorValue = stuff->window; 792 return rc; 793 } 794 pScreen = pWin->drawable.pScreen; 795 796 /* 797 * Create an OverlayClient structure to mark this client's 798 * interest in the overlay window 799 */ 800 pOc = compCreateOverlayClient(pScreen, client); 801 if (pOc == NULL) 802 return BadAlloc; 803 804 /* 805 * Make sure the overlay window exists 806 */ 807 cs = GetCompScreen(pScreen); 808 if (cs->pOverlayWin == NULL) 809 if (!compCreateOverlayWindow(pScreen)) 810 { 811 FreeResource (pOc->resource, RT_NONE); 812 return BadAlloc; 813 } 814 815 rc = XaceHook(XACE_RESOURCE_ACCESS, client, 816 cs->pOverlayWin->drawable.id, 817 RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, 818 DixGetAttrAccess); 819 if (rc != Success) 820 { 821 FreeResource (pOc->resource, RT_NONE); 822 return rc; 823 } 824 } 825 826 if (overlayWin) 827 { 828 FOR_NSCREENS(i) { 829 cs = GetCompScreen(screenInfo.screens[i]); 830 overlayWin->info[i].id = cs->pOverlayWin->drawable.id; 831 } 832 833 AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin); 834 } 835 836 cs = GetCompScreen(screenInfo.screens[0]); 837 838 rep.type = X_Reply; 839 rep.sequenceNumber = client->sequence; 840 rep.length = 0; 841 rep.overlayWin = cs->pOverlayWin->drawable.id; 842 843 if (client->swapped) 844 { 845 int n; 846 swaps(&rep.sequenceNumber, n); 847 swapl(&rep.length, n); 848 swapl(&rep.overlayWin, n); 849 } 850 (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep); 851 852 return Success; 853} 854 855static int 856PanoramiXCompositeReleaseOverlayWindow (ClientPtr client) 857{ 858 REQUEST(xCompositeReleaseOverlayWindowReq); 859 WindowPtr pWin; 860 ScreenPtr pScreen; 861 CompOverlayClientPtr pOc; 862 PanoramiXRes *win; 863 int i, rc; 864 865 REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); 866 867 if ((rc = dixLookupResourceByType((void **)&win, stuff->window, XRT_WINDOW, 868 client, DixUnknownAccess))) { 869 client->errorValue = stuff->window; 870 return rc; 871 } 872 873 FOR_NSCREENS_BACKWARD(i) { 874 if ((rc = dixLookupResourceByType((void **)&pWin, win->info[i].id, 875 XRT_WINDOW, client, 876 DixUnknownAccess))) { 877 client->errorValue = stuff->window; 878 return rc; 879 } 880 pScreen = pWin->drawable.pScreen; 881 882 /* 883 * Has client queried a reference to the overlay window 884 * on this screen? If not, generate an error. 885 */ 886 pOc = compFindOverlayClient (pWin->drawable.pScreen, client); 887 if (pOc == NULL) 888 return BadMatch; 889 890 /* The delete function will free the client structure */ 891 FreeResource (pOc->resource, RT_NONE); 892 } 893 894 return Success; 895} 896 897void 898PanoramiXCompositeInit (void) 899{ 900 int i; 901 902 for (i = 0; i < CompositeNumberRequests; i++) 903 PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i]; 904 /* 905 * Stuff in Xinerama aware request processing hooks 906 */ 907 ProcCompositeVector[X_CompositeRedirectWindow] = 908 PanoramiXCompositeRedirectWindow; 909 ProcCompositeVector[X_CompositeRedirectSubwindows] = 910 PanoramiXCompositeRedirectSubwindows; 911 ProcCompositeVector[X_CompositeUnredirectWindow] = 912 PanoramiXCompositeUnredirectWindow; 913 ProcCompositeVector[X_CompositeUnredirectSubwindows] = 914 PanoramiXCompositeUnredirectSubwindows; 915 ProcCompositeVector[X_CompositeNameWindowPixmap] = 916 PanoramiXCompositeNameWindowPixmap; 917 ProcCompositeVector[X_CompositeGetOverlayWindow] = 918 PanoramiXCompositeGetOverlayWindow; 919 ProcCompositeVector[X_CompositeReleaseOverlayWindow] = 920 PanoramiXCompositeReleaseOverlayWindow; 921} 922 923void 924PanoramiXCompositeReset (void) 925{ 926 int i; 927 928 for (i = 0; i < CompositeNumberRequests; i++) 929 ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i]; 930} 931 932#endif 933