944 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			944 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
 | |
|  *
 | |
|  * Permission is hereby granted, free of charge, to any person obtaining a
 | |
|  * copy of this software and associated documentation files (the "Software"),
 | |
|  * to deal in the Software without restriction, including without limitation
 | |
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | |
|  * and/or sell copies of the Software, and to permit persons to whom the
 | |
|  * Software is furnished to do so, subject to the following conditions:
 | |
|  *
 | |
|  * The above copyright notice and this permission notice (including the next
 | |
|  * paragraph) shall be included in all copies or substantial portions of the
 | |
|  * Software.
 | |
|  *
 | |
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | |
|  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | |
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | |
|  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | |
|  * DEALINGS IN THE SOFTWARE.
 | |
|  *
 | |
|  * Copyright © 2003 Keith Packard
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute, and sell this software and its
 | |
|  * documentation for any purpose is hereby granted without fee, provided that
 | |
|  * the above copyright notice appear in all copies and that both that
 | |
|  * copyright notice and this permission notice appear in supporting
 | |
|  * documentation, and that the name of Keith Packard not be used in
 | |
|  * advertising or publicity pertaining to distribution of the software without
 | |
|  * specific, written prior permission.  Keith Packard makes no
 | |
|  * representations about the suitability of this software for any purpose.  It
 | |
|  * is provided "as is" without express or implied warranty.
 | |
|  *
 | |
|  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | |
|  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | |
|  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | |
|  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | |
|  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | |
|  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | |
|  * PERFORMANCE OF THIS SOFTWARE.
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #include "compint.h"
 | |
| #include "xace.h"
 | |
| #include "protocol-versions.h"
 | |
| #include "extinit.h"
 | |
| 
 | |
| static CARD8 CompositeReqCode;
 | |
| static DevPrivateKeyRec CompositeClientPrivateKeyRec;
 | |
| 
 | |
| #define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec)
 | |
| RESTYPE CompositeClientWindowType;
 | |
| RESTYPE CompositeClientSubwindowsType;
 | |
| RESTYPE CompositeClientOverlayType;
 | |
| 
 | |
| typedef struct _CompositeClient {
 | |
|     int major_version;
 | |
|     int minor_version;
 | |
| } CompositeClientRec, *CompositeClientPtr;
 | |
| 
 | |
| #define GetCompositeClient(pClient) ((CompositeClientPtr) \
 | |
|     dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
 | |
| 
 | |
| static void
 | |
| CompositeClientCallback(CallbackListPtr *list, pointer closure, pointer data)
 | |
| {
 | |
|     NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
 | |
|     ClientPtr pClient = clientinfo->client;
 | |
|     CompositeClientPtr pCompositeClient = GetCompositeClient(pClient);
 | |
| 
 | |
|     pCompositeClient->major_version = 0;
 | |
|     pCompositeClient->minor_version = 0;
 | |
| }
 | |
| 
 | |
| static int
 | |
| FreeCompositeClientWindow(pointer value, XID ccwid)
 | |
| {
 | |
|     WindowPtr pWin = value;
 | |
| 
 | |
|     compFreeClientWindow(pWin, ccwid);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| FreeCompositeClientSubwindows(pointer value, XID ccwid)
 | |
| {
 | |
|     WindowPtr pWin = value;
 | |
| 
 | |
|     compFreeClientSubwindows(pWin, ccwid);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| FreeCompositeClientOverlay(pointer value, XID ccwid)
 | |
| {
 | |
|     CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
 | |
| 
 | |
|     compFreeOverlayClient(pOc);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeQueryVersion(ClientPtr client)
 | |
| {
 | |
|     CompositeClientPtr pCompositeClient = GetCompositeClient(client);
 | |
|     xCompositeQueryVersionReply rep = {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0
 | |
|     };
 | |
| 
 | |
|     REQUEST(xCompositeQueryVersionReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
 | |
|     if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
 | |
|         rep.majorVersion = stuff->majorVersion;
 | |
|         rep.minorVersion = stuff->minorVersion;
 | |
|     }
 | |
|     else {
 | |
|         rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
 | |
|         rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
 | |
|     }
 | |
|     pCompositeClient->major_version = rep.majorVersion;
 | |
|     pCompositeClient->minor_version = rep.minorVersion;
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.majorVersion);
 | |
|         swapl(&rep.minorVersion);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| #define VERIFY_WINDOW(pWindow, wid, client, mode)			\
 | |
|     do {								\
 | |
| 	int err;							\
 | |
| 	err = dixLookupResourceByType((pointer *) &pWindow, wid,	\
 | |
| 				      RT_WINDOW, client, mode);		\
 | |
| 	if (err != Success) {						\
 | |
| 	    client->errorValue = wid;					\
 | |
| 	    return err;							\
 | |
| 	}								\
 | |
|     } while (0)
 | |
| 
 | |
| static int
 | |
| ProcCompositeRedirectWindow(ClientPtr client)
 | |
| {
 | |
|     WindowPtr pWin;
 | |
| 
 | |
|     REQUEST(xCompositeRedirectWindowReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
 | |
|     VERIFY_WINDOW(pWin, stuff->window, client,
 | |
|                   DixSetAttrAccess | DixManageAccess | DixBlendAccess);
 | |
| 
 | |
|     return compRedirectWindow(client, pWin, stuff->update);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeRedirectSubwindows(ClientPtr client)
 | |
| {
 | |
|     WindowPtr pWin;
 | |
| 
 | |
|     REQUEST(xCompositeRedirectSubwindowsReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
 | |
|     VERIFY_WINDOW(pWin, stuff->window, client,
 | |
|                   DixSetAttrAccess | DixManageAccess | DixBlendAccess);
 | |
| 
 | |
|     return compRedirectSubwindows(client, pWin, stuff->update);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeUnredirectWindow(ClientPtr client)
 | |
| {
 | |
|     WindowPtr pWin;
 | |
| 
 | |
|     REQUEST(xCompositeUnredirectWindowReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
 | |
|     VERIFY_WINDOW(pWin, stuff->window, client,
 | |
|                   DixSetAttrAccess | DixManageAccess | DixBlendAccess);
 | |
| 
 | |
|     return compUnredirectWindow(client, pWin, stuff->update);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeUnredirectSubwindows(ClientPtr client)
 | |
| {
 | |
|     WindowPtr pWin;
 | |
| 
 | |
|     REQUEST(xCompositeUnredirectSubwindowsReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
 | |
|     VERIFY_WINDOW(pWin, stuff->window, client,
 | |
|                   DixSetAttrAccess | DixManageAccess | DixBlendAccess);
 | |
| 
 | |
|     return compUnredirectSubwindows(client, pWin, stuff->update);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeCreateRegionFromBorderClip(ClientPtr client)
 | |
| {
 | |
|     WindowPtr pWin;
 | |
|     CompWindowPtr cw;
 | |
|     RegionPtr pBorderClip, pRegion;
 | |
| 
 | |
|     REQUEST(xCompositeCreateRegionFromBorderClipReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
 | |
|     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
 | |
|     LEGAL_NEW_RESOURCE(stuff->region, client);
 | |
| 
 | |
|     cw = GetCompWindow(pWin);
 | |
|     if (cw)
 | |
|         pBorderClip = &cw->borderClip;
 | |
|     else
 | |
|         pBorderClip = &pWin->borderClip;
 | |
|     pRegion = XFixesRegionCopy(pBorderClip);
 | |
|     if (!pRegion)
 | |
|         return BadAlloc;
 | |
|     RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
 | |
| 
 | |
|     if (!AddResource(stuff->region, RegionResType, (pointer) pRegion))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeNameWindowPixmap(ClientPtr client)
 | |
| {
 | |
|     WindowPtr pWin;
 | |
|     CompWindowPtr cw;
 | |
|     PixmapPtr pPixmap;
 | |
|     int rc;
 | |
| 
 | |
|     REQUEST(xCompositeNameWindowPixmapReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
 | |
|     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
 | |
| 
 | |
|     if (!pWin->viewable)
 | |
|         return BadMatch;
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->pixmap, client);
 | |
| 
 | |
|     cw = GetCompWindow(pWin);
 | |
|     if (!cw)
 | |
|         return BadMatch;
 | |
| 
 | |
|     pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
 | |
|     if (!pPixmap)
 | |
|         return BadMatch;
 | |
| 
 | |
|     /* security creation/labeling check */
 | |
|     rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
 | |
|                   pPixmap, RT_WINDOW, pWin, DixCreateAccess);
 | |
|     if (rc != Success)
 | |
|         return rc;
 | |
| 
 | |
|     ++pPixmap->refcnt;
 | |
| 
 | |
|     if (!AddResource(stuff->pixmap, RT_PIXMAP, (pointer) pPixmap))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeGetOverlayWindow(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeGetOverlayWindowReq);
 | |
|     xCompositeGetOverlayWindowReply rep;
 | |
|     WindowPtr pWin;
 | |
|     ScreenPtr pScreen;
 | |
|     CompScreenPtr cs;
 | |
|     CompOverlayClientPtr pOc;
 | |
|     int rc;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
 | |
|     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
 | |
|     pScreen = pWin->drawable.pScreen;
 | |
| 
 | |
|     /* 
 | |
|      * Create an OverlayClient structure to mark this client's
 | |
|      * interest in the overlay window
 | |
|      */
 | |
|     pOc = compCreateOverlayClient(pScreen, client);
 | |
|     if (pOc == NULL)
 | |
|         return BadAlloc;
 | |
| 
 | |
|     /*
 | |
|      * Make sure the overlay window exists
 | |
|      */
 | |
|     cs = GetCompScreen(pScreen);
 | |
|     if (cs->pOverlayWin == NULL)
 | |
|         if (!compCreateOverlayWindow(pScreen)) {
 | |
|             FreeResource(pOc->resource, RT_NONE);
 | |
|             return BadAlloc;
 | |
|         }
 | |
| 
 | |
|     rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
 | |
|                   RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
 | |
|     if (rc != Success) {
 | |
|         FreeResource(pOc->resource, RT_NONE);
 | |
|         return rc;
 | |
|     }
 | |
| 
 | |
|     rep = (xCompositeGetOverlayWindowReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .overlayWin = cs->pOverlayWin->drawable.id
 | |
|     };
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.overlayWin);
 | |
|     }
 | |
|     WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeReleaseOverlayWindow(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeReleaseOverlayWindowReq);
 | |
|     WindowPtr pWin;
 | |
|     ScreenPtr pScreen;
 | |
|     CompOverlayClientPtr pOc;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
 | |
|     VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
 | |
|     pScreen = pWin->drawable.pScreen;
 | |
| 
 | |
|     /* 
 | |
|      * Has client queried a reference to the overlay window
 | |
|      * on this screen? If not, generate an error.
 | |
|      */
 | |
|     pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
 | |
|     if (pOc == NULL)
 | |
|         return BadMatch;
 | |
| 
 | |
|     /* The delete function will free the client structure */
 | |
|     FreeResource(pOc->resource, RT_NONE);
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int (*ProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
 | |
| ProcCompositeQueryVersion,
 | |
|         ProcCompositeRedirectWindow,
 | |
|         ProcCompositeRedirectSubwindows,
 | |
|         ProcCompositeUnredirectWindow,
 | |
|         ProcCompositeUnredirectSubwindows,
 | |
|         ProcCompositeCreateRegionFromBorderClip,
 | |
|         ProcCompositeNameWindowPixmap,
 | |
|         ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,};
 | |
| 
 | |
| static int
 | |
| ProcCompositeDispatch(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xReq);
 | |
| 
 | |
|     if (stuff->data < CompositeNumberRequests)
 | |
|         return (*ProcCompositeVector[stuff->data]) (client);
 | |
|     else
 | |
|         return BadRequest;
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeQueryVersion(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeQueryVersionReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
 | |
|     swapl(&stuff->majorVersion);
 | |
|     swapl(&stuff->minorVersion);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeRedirectWindow(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeRedirectWindowReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
 | |
|     swapl(&stuff->window);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeRedirectSubwindows(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeRedirectSubwindowsReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
 | |
|     swapl(&stuff->window);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeUnredirectWindow(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeUnredirectWindowReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
 | |
|     swapl(&stuff->window);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeUnredirectSubwindows(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeUnredirectSubwindowsReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
 | |
|     swapl(&stuff->window);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeCreateRegionFromBorderClip(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeCreateRegionFromBorderClipReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
 | |
|     swapl(&stuff->region);
 | |
|     swapl(&stuff->window);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeNameWindowPixmap(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeNameWindowPixmapReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
 | |
|     swapl(&stuff->window);
 | |
|     swapl(&stuff->pixmap);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeGetOverlayWindow(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeGetOverlayWindowReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
 | |
|     swapl(&stuff->window);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeReleaseOverlayWindow(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeReleaseOverlayWindowReq);
 | |
| 
 | |
|     swaps(&stuff->length);
 | |
|     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
 | |
|     swapl(&stuff->window);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int (*SProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
 | |
| SProcCompositeQueryVersion,
 | |
|         SProcCompositeRedirectWindow,
 | |
|         SProcCompositeRedirectSubwindows,
 | |
|         SProcCompositeUnredirectWindow,
 | |
|         SProcCompositeUnredirectSubwindows,
 | |
|         SProcCompositeCreateRegionFromBorderClip,
 | |
|         SProcCompositeNameWindowPixmap,
 | |
|         SProcCompositeGetOverlayWindow, SProcCompositeReleaseOverlayWindow,};
 | |
| 
 | |
| static int
 | |
| SProcCompositeDispatch(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xReq);
 | |
| 
 | |
|     if (stuff->data < CompositeNumberRequests)
 | |
|         return (*SProcCompositeVector[stuff->data]) (client);
 | |
|     else
 | |
|         return BadRequest;
 | |
| }
 | |
| 
 | |
| /** @see GetDefaultBytes */
 | |
| static void
 | |
| GetCompositeClientWindowBytes(pointer value, XID id, ResourceSizePtr size)
 | |
| {
 | |
|     WindowPtr window = value;
 | |
| 
 | |
|     /* Currently only pixmap bytes are reported to clients. */
 | |
|     size->resourceSize = 0;
 | |
| 
 | |
|     /* Calculate pixmap reference sizes. */
 | |
|     size->pixmapRefSize = 0;
 | |
|     if (window->redirectDraw != RedirectDrawNone)
 | |
|     {
 | |
|         SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP);
 | |
|         ResourceSizeRec pixmapSize = { 0, 0 };
 | |
|         ScreenPtr screen = window->drawable.pScreen;
 | |
|         PixmapPtr pixmap = screen->GetWindowPixmap(window);
 | |
|         pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize);
 | |
|         size->pixmapRefSize += pixmapSize.pixmapRefSize;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| CompositeExtensionInit(void)
 | |
| {
 | |
|     ExtensionEntry *extEntry;
 | |
|     int s;
 | |
| 
 | |
|     /* Assume initialization is going to fail */
 | |
|     noCompositeExtension = TRUE;
 | |
| 
 | |
|     for (s = 0; s < screenInfo.numScreens; s++) {
 | |
|         ScreenPtr pScreen = screenInfo.screens[s];
 | |
|         VisualPtr vis;
 | |
| 
 | |
|         /* Composite on 8bpp pseudocolor root windows appears to fail, so
 | |
|          * just disable it on anything pseudocolor for safety.
 | |
|          */
 | |
|         for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++);
 | |
|         if ((vis->class | DynamicClass) == PseudoColor)
 | |
|             return;
 | |
| 
 | |
|         /* Ensure that Render is initialized, which is required for automatic
 | |
|          * compositing.
 | |
|          */
 | |
|         if (GetPictureScreenIfSet(pScreen) == NULL)
 | |
|             return;
 | |
|     }
 | |
| 
 | |
|     CompositeClientWindowType = CreateNewResourceType
 | |
|         (FreeCompositeClientWindow, "CompositeClientWindow");
 | |
|     if (!CompositeClientWindowType)
 | |
|         return;
 | |
| 
 | |
|     SetResourceTypeSizeFunc(CompositeClientWindowType,
 | |
|                             GetCompositeClientWindowBytes);
 | |
| 
 | |
|     CompositeClientSubwindowsType = CreateNewResourceType
 | |
|         (FreeCompositeClientSubwindows, "CompositeClientSubwindows");
 | |
|     if (!CompositeClientSubwindowsType)
 | |
|         return;
 | |
| 
 | |
|     CompositeClientOverlayType = CreateNewResourceType
 | |
|         (FreeCompositeClientOverlay, "CompositeClientOverlay");
 | |
|     if (!CompositeClientOverlayType)
 | |
|         return;
 | |
| 
 | |
|     if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT,
 | |
|                                sizeof(CompositeClientRec)))
 | |
|         return;
 | |
| 
 | |
|     if (!AddCallback(&ClientStateCallback, CompositeClientCallback, 0))
 | |
|         return;
 | |
| 
 | |
|     for (s = 0; s < screenInfo.numScreens; s++)
 | |
|         if (!compScreenInit(screenInfo.screens[s]))
 | |
|             return;
 | |
| 
 | |
|     extEntry = AddExtension(COMPOSITE_NAME, 0, 0,
 | |
|                             ProcCompositeDispatch, SProcCompositeDispatch,
 | |
|                             NULL, StandardMinorOpcode);
 | |
|     if (!extEntry)
 | |
|         return;
 | |
|     CompositeReqCode = (CARD8) extEntry->base;
 | |
| 
 | |
|     miRegisterRedirectBorderClipProc(compSetRedirectBorderClip,
 | |
|                                      compGetRedirectBorderClip);
 | |
| 
 | |
|     /* Initialization succeeded */
 | |
|     noCompositeExtension = FALSE;
 | |
| }
 | |
| 
 | |
| #ifdef PANORAMIX
 | |
| #include "panoramiXsrv.h"
 | |
| 
 | |
| int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr);
 | |
| 
 | |
| static int
 | |
| PanoramiXCompositeRedirectWindow(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *win;
 | |
|     int rc = 0, j;
 | |
| 
 | |
|     REQUEST(xCompositeRedirectWindowReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
 | |
| 
 | |
|     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
 | |
|                                       client, DixUnknownAccess))) {
 | |
|         client->errorValue = stuff->window;
 | |
|         return rc;
 | |
|     }
 | |
| 
 | |
|     FOR_NSCREENS_FORWARD(j) {
 | |
|         stuff->window = win->info[j].id;
 | |
|         rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
 | |
|         if (rc != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXCompositeRedirectSubwindows(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *win;
 | |
|     int rc = 0, j;
 | |
| 
 | |
|     REQUEST(xCompositeRedirectSubwindowsReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
 | |
| 
 | |
|     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
 | |
|                                       client, DixUnknownAccess))) {
 | |
|         client->errorValue = stuff->window;
 | |
|         return rc;
 | |
|     }
 | |
| 
 | |
|     FOR_NSCREENS_FORWARD(j) {
 | |
|         stuff->window = win->info[j].id;
 | |
|         rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
 | |
|         if (rc != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXCompositeUnredirectWindow(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *win;
 | |
|     int rc = 0, j;
 | |
| 
 | |
|     REQUEST(xCompositeUnredirectWindowReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
 | |
| 
 | |
|     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
 | |
|                                       client, DixUnknownAccess))) {
 | |
|         client->errorValue = stuff->window;
 | |
|         return rc;
 | |
|     }
 | |
| 
 | |
|     FOR_NSCREENS_FORWARD(j) {
 | |
|         stuff->window = win->info[j].id;
 | |
|         rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
 | |
|         if (rc != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXCompositeUnredirectSubwindows(ClientPtr client)
 | |
| {
 | |
|     PanoramiXRes *win;
 | |
|     int rc = 0, j;
 | |
| 
 | |
|     REQUEST(xCompositeUnredirectSubwindowsReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
 | |
| 
 | |
|     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
 | |
|                                       client, DixUnknownAccess))) {
 | |
|         client->errorValue = stuff->window;
 | |
|         return rc;
 | |
|     }
 | |
| 
 | |
|     FOR_NSCREENS_FORWARD(j) {
 | |
|         stuff->window = win->info[j].id;
 | |
|         rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
 | |
|         if (rc != Success)
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     return rc;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXCompositeNameWindowPixmap(ClientPtr client)
 | |
| {
 | |
|     WindowPtr pWin;
 | |
|     CompWindowPtr cw;
 | |
|     PixmapPtr pPixmap;
 | |
|     int rc;
 | |
|     PanoramiXRes *win, *newPix;
 | |
|     int i;
 | |
| 
 | |
|     REQUEST(xCompositeNameWindowPixmapReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
 | |
| 
 | |
|     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
 | |
|                                       client, DixUnknownAccess))) {
 | |
|         client->errorValue = stuff->window;
 | |
|         return rc;
 | |
|     }
 | |
| 
 | |
|     LEGAL_NEW_RESOURCE(stuff->pixmap, client);
 | |
| 
 | |
|     if (!(newPix = malloc(sizeof(PanoramiXRes))))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     newPix->type = XRT_PIXMAP;
 | |
|     newPix->u.pix.shared = FALSE;
 | |
|     panoramix_setup_ids(newPix, client, stuff->pixmap);
 | |
| 
 | |
|     FOR_NSCREENS(i) {
 | |
|         rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
 | |
|                                      RT_WINDOW, client, DixGetAttrAccess);
 | |
|         if (rc != Success) {
 | |
|             client->errorValue = stuff->window;
 | |
|             free(newPix);
 | |
|             return rc;
 | |
|         }
 | |
| 
 | |
|         if (!pWin->viewable) {
 | |
|             free(newPix);
 | |
|             return BadMatch;
 | |
|         }
 | |
| 
 | |
|         cw = GetCompWindow(pWin);
 | |
|         if (!cw) {
 | |
|             free(newPix);
 | |
|             return BadMatch;
 | |
|         }
 | |
| 
 | |
|         pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
 | |
|         if (!pPixmap) {
 | |
|             free(newPix);
 | |
|             return BadMatch;
 | |
|         }
 | |
| 
 | |
|         if (!AddResource(newPix->info[i].id, RT_PIXMAP, (pointer) pPixmap))
 | |
|             return BadAlloc;
 | |
| 
 | |
|         ++pPixmap->refcnt;
 | |
|     }
 | |
| 
 | |
|     if (!AddResource(stuff->pixmap, XRT_PIXMAP, (pointer) newPix))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXCompositeGetOverlayWindow(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeGetOverlayWindowReq);
 | |
|     xCompositeGetOverlayWindowReply rep;
 | |
|     WindowPtr pWin;
 | |
|     ScreenPtr pScreen;
 | |
|     CompScreenPtr cs;
 | |
|     CompOverlayClientPtr pOc;
 | |
|     int rc;
 | |
|     PanoramiXRes *win, *overlayWin = NULL;
 | |
|     int i;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
 | |
| 
 | |
|     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
 | |
|                                       client, DixUnknownAccess))) {
 | |
|         client->errorValue = stuff->window;
 | |
|         return rc;
 | |
|     }
 | |
| 
 | |
|     cs = GetCompScreen(screenInfo.screens[0]);
 | |
|     if (!cs->pOverlayWin) {
 | |
|         if (!(overlayWin = malloc(sizeof(PanoramiXRes))))
 | |
|             return BadAlloc;
 | |
| 
 | |
|         overlayWin->type = XRT_WINDOW;
 | |
|         overlayWin->u.win.root = FALSE;
 | |
|     }
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(i) {
 | |
|         rc = dixLookupResourceByType((pointer *) &pWin, win->info[i].id,
 | |
|                                      RT_WINDOW, client, DixGetAttrAccess);
 | |
|         if (rc != Success) {
 | |
|             client->errorValue = stuff->window;
 | |
|             return rc;
 | |
|         }
 | |
|         pScreen = pWin->drawable.pScreen;
 | |
| 
 | |
|         /*
 | |
|          * Create an OverlayClient structure to mark this client's
 | |
|          * interest in the overlay window
 | |
|          */
 | |
|         pOc = compCreateOverlayClient(pScreen, client);
 | |
|         if (pOc == NULL)
 | |
|             return BadAlloc;
 | |
| 
 | |
|         /*
 | |
|          * Make sure the overlay window exists
 | |
|          */
 | |
|         cs = GetCompScreen(pScreen);
 | |
|         if (cs->pOverlayWin == NULL)
 | |
|             if (!compCreateOverlayWindow(pScreen)) {
 | |
|                 FreeResource(pOc->resource, RT_NONE);
 | |
|                 return BadAlloc;
 | |
|             }
 | |
| 
 | |
|         rc = XaceHook(XACE_RESOURCE_ACCESS, client,
 | |
|                       cs->pOverlayWin->drawable.id,
 | |
|                       RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL,
 | |
|                       DixGetAttrAccess);
 | |
|         if (rc != Success) {
 | |
|             FreeResource(pOc->resource, RT_NONE);
 | |
|             return rc;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (overlayWin) {
 | |
|         FOR_NSCREENS(i) {
 | |
|             cs = GetCompScreen(screenInfo.screens[i]);
 | |
|             overlayWin->info[i].id = cs->pOverlayWin->drawable.id;
 | |
|         }
 | |
| 
 | |
|         AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin);
 | |
|     }
 | |
| 
 | |
|     cs = GetCompScreen(screenInfo.screens[0]);
 | |
| 
 | |
|     rep = (xCompositeGetOverlayWindowReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .overlayWin = cs->pOverlayWin->drawable.id
 | |
|     };
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.overlayWin);
 | |
|     }
 | |
|     WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeReleaseOverlayWindowReq);
 | |
|     WindowPtr pWin;
 | |
|     ScreenPtr pScreen;
 | |
|     CompOverlayClientPtr pOc;
 | |
|     PanoramiXRes *win;
 | |
|     int i, rc;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
 | |
| 
 | |
|     if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
 | |
|                                       client, DixUnknownAccess))) {
 | |
|         client->errorValue = stuff->window;
 | |
|         return rc;
 | |
|     }
 | |
| 
 | |
|     FOR_NSCREENS_BACKWARD(i) {
 | |
|         if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
 | |
|                                           XRT_WINDOW, client,
 | |
|                                           DixUnknownAccess))) {
 | |
|             client->errorValue = stuff->window;
 | |
|             return rc;
 | |
|         }
 | |
|         pScreen = pWin->drawable.pScreen;
 | |
| 
 | |
|         /*
 | |
|          * Has client queried a reference to the overlay window
 | |
|          * on this screen? If not, generate an error.
 | |
|          */
 | |
|         pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
 | |
|         if (pOc == NULL)
 | |
|             return BadMatch;
 | |
| 
 | |
|         /* The delete function will free the client structure */
 | |
|         FreeResource(pOc->resource, RT_NONE);
 | |
|     }
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| void
 | |
| PanoramiXCompositeInit(void)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for (i = 0; i < CompositeNumberRequests; i++)
 | |
|         PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i];
 | |
|     /*
 | |
|      * Stuff in Xinerama aware request processing hooks
 | |
|      */
 | |
|     ProcCompositeVector[X_CompositeRedirectWindow] =
 | |
|         PanoramiXCompositeRedirectWindow;
 | |
|     ProcCompositeVector[X_CompositeRedirectSubwindows] =
 | |
|         PanoramiXCompositeRedirectSubwindows;
 | |
|     ProcCompositeVector[X_CompositeUnredirectWindow] =
 | |
|         PanoramiXCompositeUnredirectWindow;
 | |
|     ProcCompositeVector[X_CompositeUnredirectSubwindows] =
 | |
|         PanoramiXCompositeUnredirectSubwindows;
 | |
|     ProcCompositeVector[X_CompositeNameWindowPixmap] =
 | |
|         PanoramiXCompositeNameWindowPixmap;
 | |
|     ProcCompositeVector[X_CompositeGetOverlayWindow] =
 | |
|         PanoramiXCompositeGetOverlayWindow;
 | |
|     ProcCompositeVector[X_CompositeReleaseOverlayWindow] =
 | |
|         PanoramiXCompositeReleaseOverlayWindow;
 | |
| }
 | |
| 
 | |
| void
 | |
| PanoramiXCompositeReset(void)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for (i = 0; i < CompositeNumberRequests; i++)
 | |
|         ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i];
 | |
| }
 | |
| 
 | |
| #endif
 |