739 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			739 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * $Id$
 | |
|  *
 | |
|  *
 | |
|  * Copyright © 2006 Sun Microsystems
 | |
|  *
 | |
|  * 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 Sun Microsystems not be used in
 | |
|  * advertising or publicity pertaining to distribution of the software without
 | |
|  * specific, written prior permission.  Sun Microsystems makes no
 | |
|  * representations about the suitability of this software for any purpose.  It
 | |
|  * is provided "as is" without express or implied warranty.
 | |
|  *
 | |
|  * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | |
|  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | |
|  * EVENT SHALL SUN MICROSYSTEMS 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.
 | |
|  *
 | |
|  * 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"
 | |
| 
 | |
| static CARD8	CompositeReqCode;
 | |
| static int	CompositeClientPrivateIndex;
 | |
| RESTYPE		CompositeClientWindowType;
 | |
| RESTYPE		CompositeClientSubwindowsType;
 | |
| static RESTYPE	CompositeClientOverlayType;
 | |
| 
 | |
| static void deleteCompOverlayClient (CompOverlayClientPtr pOcToDel, 
 | |
| 				     ScreenPtr pScreen);
 | |
| 
 | |
| typedef struct _CompositeClient {
 | |
|     int	    major_version;
 | |
|     int	    minor_version;
 | |
| } CompositeClientRec, *CompositeClientPtr;
 | |
| 
 | |
| #define GetCompositeClient(pClient)    ((CompositeClientPtr) (pClient)->devPrivates[CompositeClientPrivateIndex].ptr)
 | |
| 
 | |
| 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 void
 | |
| CompositeResetProc (ExtensionEntry *extEntry)
 | |
| {
 | |
| }
 | |
|     
 | |
| 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;
 | |
|     ScreenPtr pScreen = pOc->pScreen;
 | |
|     CompScreenPtr cs;
 | |
| 
 | |
|     deleteCompOverlayClient(pOc, pScreen);
 | |
| 
 | |
|     /* Unmap overlay window when there are no more clients using it */
 | |
|     cs = GetCompScreen(pScreen);
 | |
|     if (cs->pOverlayClients == NULL) {
 | |
| 	if (cs->pOverlayWin != NULL) {
 | |
| 	    UnmapWindow(cs->pOverlayWin, FALSE);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeQueryVersion (ClientPtr client)
 | |
| {
 | |
|     CompositeClientPtr pCompositeClient = GetCompositeClient (client);
 | |
|     xCompositeQueryVersionReply rep;
 | |
|     register int n;
 | |
|     REQUEST(xCompositeQueryVersionReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
 | |
|     rep.type = X_Reply;
 | |
|     rep.length = 0;
 | |
|     rep.sequenceNumber = client->sequence;
 | |
|     if (stuff->majorVersion < COMPOSITE_MAJOR) {
 | |
| 	rep.majorVersion = stuff->majorVersion;
 | |
| 	rep.minorVersion = stuff->minorVersion;
 | |
|     } else {
 | |
| 	rep.majorVersion = COMPOSITE_MAJOR;
 | |
| 	if (stuff->majorVersion == COMPOSITE_MAJOR && 
 | |
| 	    stuff->minorVersion < COMPOSITE_MINOR)
 | |
| 	    rep.minorVersion = stuff->minorVersion;
 | |
| 	else
 | |
| 	    rep.minorVersion = COMPOSITE_MINOR;
 | |
|     }
 | |
|     pCompositeClient->major_version = rep.majorVersion;
 | |
|     pCompositeClient->minor_version = rep.minorVersion;
 | |
|     if (client->swapped) {
 | |
|     	swaps(&rep.sequenceNumber, n);
 | |
|     	swapl(&rep.length, n);
 | |
| 	swapl(&rep.majorVersion, n);
 | |
| 	swapl(&rep.minorVersion, n);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep);
 | |
|     return(client->noClientException);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeRedirectWindow (ClientPtr client)
 | |
| {
 | |
|     WindowPtr	pWin;
 | |
|     REQUEST(xCompositeRedirectWindowReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
 | |
|     pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
 | |
|     if (!pWin)
 | |
|     {
 | |
| 	client->errorValue = stuff->window;
 | |
| 	return BadWindow;
 | |
|     }
 | |
|     return compRedirectWindow (client, pWin, stuff->update);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeRedirectSubwindows (ClientPtr client)
 | |
| {
 | |
|     WindowPtr	pWin;
 | |
|     REQUEST(xCompositeRedirectSubwindowsReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
 | |
|     pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
 | |
|     if (!pWin)
 | |
|     {
 | |
| 	client->errorValue = stuff->window;
 | |
| 	return BadWindow;
 | |
|     }
 | |
|     return compRedirectSubwindows (client, pWin, stuff->update);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeUnredirectWindow (ClientPtr client)
 | |
| {
 | |
|     WindowPtr	pWin;
 | |
|     REQUEST(xCompositeUnredirectWindowReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
 | |
|     pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
 | |
|     if (!pWin)
 | |
|     {
 | |
| 	client->errorValue = stuff->window;
 | |
| 	return BadWindow;
 | |
|     }
 | |
|     return compUnredirectWindow (client, pWin, stuff->update);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeUnredirectSubwindows (ClientPtr client)
 | |
| {
 | |
|     WindowPtr	pWin;
 | |
|     REQUEST(xCompositeUnredirectSubwindowsReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
 | |
|     pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
 | |
|     if (!pWin)
 | |
|     {
 | |
| 	client->errorValue = stuff->window;
 | |
| 	return BadWindow;
 | |
|     }
 | |
|     return compUnredirectSubwindows (client, pWin, stuff->update);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeCreateRegionFromBorderClip (ClientPtr client)
 | |
| {
 | |
|     WindowPtr	    pWin;
 | |
|     CompWindowPtr   cw;
 | |
|     RegionPtr	    pBorderClip, pRegion;
 | |
|     REQUEST(xCompositeCreateRegionFromBorderClipReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
 | |
|     pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
 | |
|     if (!pWin)
 | |
|     {
 | |
| 	client->errorValue = stuff->window;
 | |
| 	return BadWindow;
 | |
|     }
 | |
|     
 | |
|     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;
 | |
|     REGION_TRANSLATE (pScreen, pRegion, -pWin->drawable.x, -pWin->drawable.y);
 | |
|     
 | |
|     if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
 | |
| 	return BadAlloc;
 | |
| 
 | |
|     return(client->noClientException);
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeNameWindowPixmap (ClientPtr client)
 | |
| {
 | |
|     WindowPtr	    pWin;
 | |
|     CompWindowPtr   cw;
 | |
|     PixmapPtr	    pPixmap;
 | |
|     REQUEST(xCompositeNameWindowPixmapReq);
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
 | |
|     pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
 | |
|     if (!pWin)
 | |
|     {
 | |
| 	client->errorValue = stuff->window;
 | |
| 	return BadWindow;
 | |
|     }
 | |
| 
 | |
|     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;
 | |
| 
 | |
|     ++pPixmap->refcnt;
 | |
|     
 | |
|     if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap))
 | |
| 	return BadAlloc;
 | |
| 
 | |
|     return(client->noClientException);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * Routines for manipulating the per-screen overlay clients list.
 | |
|  * This list indicates which clients have called GetOverlayWindow
 | |
|  * for this screen.
 | |
|  */
 | |
| 
 | |
| /* Return the screen's overlay client list element for the given client */
 | |
| static CompOverlayClientPtr
 | |
| findCompOverlayClient (ClientPtr pClient, ScreenPtr pScreen) 
 | |
| {
 | |
|     CompScreenPtr    cs = GetCompScreen(pScreen);
 | |
|     CompOverlayClientPtr pOc;
 | |
| 
 | |
|     for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext) {
 | |
| 	if (pOc->pClient == pClient) {
 | |
| 	    return pOc;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     return NULL;           
 | |
| }
 | |
| 
 | |
| static int
 | |
| createCompOverlayClient (ClientPtr pClient, ScreenPtr pScreen)
 | |
| {
 | |
|     CompScreenPtr    cs = GetCompScreen(pScreen);
 | |
|     CompOverlayClientPtr pOc;
 | |
| 
 | |
|     pOc = (CompOverlayClientPtr) xalloc(sizeof(CompOverlayClientRec));
 | |
|     if (pOc == NULL) {
 | |
| 	return BadAlloc;
 | |
|     }
 | |
|     pOc->pClient = pClient;
 | |
|     pOc->pScreen = pScreen;
 | |
|     pOc->resource = FakeClientID(pClient->index);
 | |
|     pOc->pNext = cs->pOverlayClients;
 | |
|     cs->pOverlayClients = pOc;
 | |
| 
 | |
|     /* 
 | |
|      * Create a resource for this element so it can be deleted
 | |
|      * when the client goes away.
 | |
|      */
 | |
|     if (!AddResource (pOc->resource, CompositeClientOverlayType, 
 | |
| 		      (pointer) pOc)) {
 | |
| 	xfree(pOc);
 | |
| 	return BadAlloc;
 | |
|     }
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * Delete the given overlay client list element from its screen list.
 | |
|  */
 | |
| static void
 | |
| deleteCompOverlayClient (CompOverlayClientPtr pOcToDel, ScreenPtr pScreen)
 | |
| {
 | |
|     CompScreenPtr    cs = GetCompScreen(pScreen);
 | |
|     CompOverlayClientPtr pOc, pNext;
 | |
|     CompOverlayClientPtr pOcLast = NULL;
 | |
| 
 | |
|     pOc = cs->pOverlayClients;
 | |
|     while (pOc != NULL) {
 | |
| 	pNext = pOc->pNext;
 | |
| 	if (pOc == pOcToDel) {
 | |
| 	    xfree(pOc);
 | |
| 	    if (pOcLast == NULL) {
 | |
| 		cs->pOverlayClients = pNext;
 | |
| 	    } else {
 | |
| 		pOcLast->pNext = pNext;
 | |
| 	    }
 | |
| 	    break;
 | |
| 	}
 | |
| 	pOcLast = pOc;
 | |
| 	pOc = pNext;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * Delete all the hide-counts list elements for this screen.
 | |
|  */
 | |
| void
 | |
| deleteCompOverlayClientsForScreen (ScreenPtr pScreen)
 | |
| {
 | |
|     CompScreenPtr    cs = GetCompScreen(pScreen);
 | |
|     CompOverlayClientPtr pOc, pTmp;
 | |
| 
 | |
|     pOc = cs->pOverlayClients;
 | |
|     while (pOc != NULL) {
 | |
| 	pTmp = pOc->pNext;
 | |
| 	FreeResource(pOc->resource, 0);
 | |
| 	pOc = pTmp;
 | |
|     }
 | |
|     cs->pOverlayClients = NULL;
 | |
| }
 | |
| 
 | |
| /* 
 | |
| ** If necessary, create the overlay window. And map it 
 | |
| ** Note: I found it excessively difficult to destroy this window
 | |
| ** during compCloseScreen; DeleteWindow can't be called because
 | |
| ** the input devices are already shut down. So we are going to 
 | |
| ** just allocate an overlay window once per screen per X server
 | |
| ** invocation.
 | |
| */
 | |
| 
 | |
| static WindowPtr
 | |
| createOverlayWindow (ScreenPtr pScreen)
 | |
| {
 | |
|     int wid = FakeClientID(0);
 | |
|     WindowPtr pWin;
 | |
|     XID overrideRedirect = TRUE;
 | |
|     int result;
 | |
| 
 | |
|     pWin = CreateWindow (
 | |
| 	        wid, WindowTable[pScreen->myNum],
 | |
|     	        0, 0, pScreen->width, pScreen->height, 0, 
 | |
| 	        InputOutput, CWOverrideRedirect, &overrideRedirect,
 | |
| 	        WindowTable[pScreen->myNum]->drawable.depth, 
 | |
| 	        serverClient, pScreen->rootVisual, &result);
 | |
|     if (pWin == NULL) {
 | |
| 	return NULL;
 | |
|     }
 | |
| 
 | |
|     if (!AddResource(wid, RT_WINDOW, (pointer)pWin)) {
 | |
| 	DeleteWindow(pWin, None);
 | |
| 	return NULL;
 | |
|     }
 | |
| 
 | |
|     return pWin;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeGetOverlayWindow (ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeGetOverlayWindowReq); 
 | |
|     xCompositeGetOverlayWindowReply rep;
 | |
|     WindowPtr pWin;
 | |
|     ScreenPtr pScreen;
 | |
|     CompScreenPtr cs;
 | |
|     CompOverlayClientPtr pOc;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
 | |
|     pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
 | |
|     if (!pWin)
 | |
|     {
 | |
| 	client->errorValue = stuff->window;
 | |
| 	return BadWindow;
 | |
|     }
 | |
|     pScreen = pWin->drawable.pScreen;
 | |
| 
 | |
|     cs = GetCompScreen(pScreen);
 | |
|     if (cs->pOverlayWin == NULL) {
 | |
| 	cs->pOverlayWin = createOverlayWindow(pScreen);
 | |
| 	if (cs->pOverlayWin == NULL) {
 | |
| 	    return BadAlloc;
 | |
| 	}
 | |
|     }
 | |
|     MapWindow(cs->pOverlayWin, serverClient);
 | |
| 
 | |
|     /* Record that client is using this overlay window */
 | |
|     pOc = findCompOverlayClient(client, pScreen);
 | |
|     if (pOc == NULL) {
 | |
| 	int ret = createCompOverlayClient(client, pScreen);
 | |
| 	if (ret != Success) {
 | |
| 	    return ret;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     rep.type = X_Reply;
 | |
|     rep.sequenceNumber = client->sequence;
 | |
|     rep.length = 0;
 | |
|     rep.overlayWin = cs->pOverlayWin->drawable.id;
 | |
| 
 | |
|     if (client->swapped)
 | |
|     {
 | |
| 	int n;
 | |
| 	swaps(&rep.sequenceNumber, n);
 | |
|     	swapl(&rep.length, n);
 | |
| 	swapl(&rep.overlayWin, n);
 | |
|     }
 | |
|     (void) WriteToClient(client, sz_xCompositeGetOverlayWindowReply, (char *)&rep);
 | |
| 
 | |
|     return client->noClientException;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcCompositeReleaseOverlayWindow (ClientPtr client)
 | |
| {
 | |
|     REQUEST(xCompositeReleaseOverlayWindowReq); 
 | |
|     WindowPtr pWin;
 | |
|     ScreenPtr pScreen;
 | |
|     CompOverlayClientPtr pOc;
 | |
|     CompScreenPtr cs;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
 | |
|     pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
 | |
|     if (!pWin)
 | |
|     {
 | |
| 	client->errorValue = stuff->window;
 | |
| 	return BadWindow;
 | |
|     }
 | |
|     pScreen = pWin->drawable.pScreen;
 | |
| 
 | |
|     /* 
 | |
|      * Has client queried a reference to the overlay window
 | |
|      * on this screen? If not, generate an error.
 | |
|      */
 | |
|     pOc = findCompOverlayClient(client, pWin->drawable.pScreen);
 | |
|     if (pOc == NULL) {
 | |
| 	return BadMatch;
 | |
|     }
 | |
| 
 | |
|     /* The delete function will free the client structure */
 | |
|     FreeResource (pOc->resource, 0);
 | |
| 
 | |
|     cs = GetCompScreen(pScreen);
 | |
|     if (cs->pOverlayClients == NULL) {
 | |
| 	UnmapWindow(cs->pOverlayWin, FALSE);
 | |
|     }
 | |
| 
 | |
|     return client->noClientException;
 | |
| }
 | |
| 
 | |
| 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)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeQueryVersionReq);
 | |
| 
 | |
|     swaps(&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
 | |
|     swapl(&stuff->majorVersion, n);
 | |
|     swapl(&stuff->minorVersion, n);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeRedirectWindow (ClientPtr client)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeRedirectWindowReq);
 | |
| 
 | |
|     swaps(&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
 | |
|     swapl (&stuff->window, n);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeRedirectSubwindows (ClientPtr client)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeRedirectSubwindowsReq);
 | |
| 
 | |
|     swaps(&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
 | |
|     swapl (&stuff->window, n);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeUnredirectWindow (ClientPtr client)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeUnredirectWindowReq);
 | |
| 
 | |
|     swaps(&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
 | |
|     swapl (&stuff->window, n);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeUnredirectSubwindows (ClientPtr client)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeUnredirectSubwindowsReq);
 | |
| 
 | |
|     swaps(&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
 | |
|     swapl (&stuff->window, n);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeCreateRegionFromBorderClip (ClientPtr client)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeCreateRegionFromBorderClipReq);
 | |
| 
 | |
|     swaps(&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
 | |
|     swapl (&stuff->region, n);
 | |
|     swapl (&stuff->window, n);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeNameWindowPixmap (ClientPtr client)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeNameWindowPixmapReq);
 | |
| 
 | |
|     swaps(&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
 | |
|     swapl (&stuff->window, n);
 | |
|     swapl (&stuff->pixmap, n);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeGetOverlayWindow (ClientPtr client)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeGetOverlayWindowReq);
 | |
| 
 | |
|     swaps (&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
 | |
|     swapl(&stuff->window, n);
 | |
|     return (*ProcCompositeVector[stuff->compositeReqType]) (client);
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcCompositeReleaseOverlayWindow (ClientPtr client)
 | |
| {
 | |
|     int n;
 | |
|     REQUEST(xCompositeReleaseOverlayWindowReq);
 | |
| 
 | |
|     swaps (&stuff->length, n);
 | |
|     REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
 | |
|     swapl(&stuff->window, n);
 | |
|     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;
 | |
| }
 | |
| 
 | |
| void
 | |
| CompositeExtensionInit (void)
 | |
| {
 | |
|     ExtensionEntry  *extEntry;
 | |
|     int		    s;
 | |
| 
 | |
|     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;
 | |
|     }
 | |
| #ifdef PANORAMIX
 | |
|     /* Xinerama's rewriting of window drawing before Composite gets to it
 | |
|      * breaks Composite.
 | |
|      */
 | |
|     if (!noPanoramiXExtension)
 | |
| 	return;
 | |
| #endif
 | |
| 
 | |
|     CompositeClientWindowType = CreateNewResourceType (FreeCompositeClientWindow);
 | |
|     if (!CompositeClientWindowType)
 | |
| 	return;
 | |
| 
 | |
|     CompositeClientSubwindowsType = CreateNewResourceType (FreeCompositeClientSubwindows);
 | |
|     if (!CompositeClientSubwindowsType)
 | |
| 	return;
 | |
| 
 | |
|     CompositeClientOverlayType = CreateNewResourceType (FreeCompositeClientOverlay);
 | |
|     if (!CompositeClientOverlayType)
 | |
| 	return;
 | |
| 
 | |
|     CompositeClientPrivateIndex = AllocateClientPrivateIndex ();
 | |
|     if (!AllocateClientPrivate (CompositeClientPrivateIndex, 
 | |
| 				sizeof (CompositeClientRec)))
 | |
| 	return;
 | |
|     if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0))
 | |
| 	return;
 | |
| 
 | |
|     extEntry = AddExtension (COMPOSITE_NAME, 0, 0,
 | |
| 			     ProcCompositeDispatch, SProcCompositeDispatch,
 | |
| 			     CompositeResetProc, StandardMinorOpcode);
 | |
|     if (!extEntry)
 | |
| 	return;
 | |
|     CompositeReqCode = (CARD8) extEntry->base;
 | |
| 
 | |
|     for (s = 0; s < screenInfo.numScreens; s++)
 | |
| 	if (!compScreenInit (screenInfo.screens[s]))
 | |
| 	    return;
 | |
|     miRegisterRedirectBorderClipProc (compSetRedirectBorderClip,
 | |
| 				      compGetRedirectBorderClip);
 | |
| }
 |