Rework composite overlay window code to fix several resource management bugs.
The composite overlay window code had several misunderstandings of the workings of the X server, in particular error handling paths would often double-free objects. Clean all of this up by using resource destruction as the sole mechanism for freeing resource-based objects.
This commit is contained in:
parent
6c1accce87
commit
efa65a0317
|
@ -7,4 +7,5 @@ libcomposite_la_SOURCES = \
|
||||||
compext.c \
|
compext.c \
|
||||||
compint.h \
|
compint.h \
|
||||||
compinit.c \
|
compinit.c \
|
||||||
|
compoverlay.c \
|
||||||
compwindow.c
|
compwindow.c
|
||||||
|
|
|
@ -54,10 +54,7 @@ static CARD8 CompositeReqCode;
|
||||||
static DevPrivateKey CompositeClientPrivateKey = &CompositeClientPrivateKey;
|
static DevPrivateKey CompositeClientPrivateKey = &CompositeClientPrivateKey;
|
||||||
RESTYPE CompositeClientWindowType;
|
RESTYPE CompositeClientWindowType;
|
||||||
RESTYPE CompositeClientSubwindowsType;
|
RESTYPE CompositeClientSubwindowsType;
|
||||||
static RESTYPE CompositeClientOverlayType;
|
RESTYPE CompositeClientOverlayType;
|
||||||
|
|
||||||
static void deleteCompOverlayClient (CompOverlayClientPtr pOcToDel,
|
|
||||||
ScreenPtr pScreen);
|
|
||||||
|
|
||||||
typedef struct _CompositeClient {
|
typedef struct _CompositeClient {
|
||||||
int major_version;
|
int major_version;
|
||||||
|
@ -107,19 +104,8 @@ static int
|
||||||
FreeCompositeClientOverlay (pointer value, XID ccwid)
|
FreeCompositeClientOverlay (pointer value, XID ccwid)
|
||||||
{
|
{
|
||||||
CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
compFreeOverlayClient (pOc);
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,137 +290,6 @@ ProcCompositeNameWindowPixmap (ClientPtr client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
static int
|
||||||
ProcCompositeGetOverlayWindow (ClientPtr client)
|
ProcCompositeGetOverlayWindow (ClientPtr client)
|
||||||
{
|
{
|
||||||
|
@ -456,28 +311,31 @@ ProcCompositeGetOverlayWindow (ClientPtr client)
|
||||||
}
|
}
|
||||||
pScreen = pWin->drawable.pScreen;
|
pScreen = pWin->drawable.pScreen;
|
||||||
|
|
||||||
cs = GetCompScreen(pScreen);
|
/*
|
||||||
if (cs->pOverlayWin == NULL) {
|
* Create an OverlayClient structure to mark this client's
|
||||||
cs->pOverlayWin = createOverlayWindow(pScreen);
|
* interest in the overlay window
|
||||||
if (cs->pOverlayWin == NULL) {
|
*/
|
||||||
|
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;
|
return BadAlloc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
|
rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
|
||||||
RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
|
RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
|
{
|
||||||
|
FreeResource (pOc->resource, RT_NONE);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
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.type = X_Reply;
|
||||||
|
@ -504,7 +362,6 @@ ProcCompositeReleaseOverlayWindow (ClientPtr client)
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
ScreenPtr pScreen;
|
ScreenPtr pScreen;
|
||||||
CompOverlayClientPtr pOc;
|
CompOverlayClientPtr pOc;
|
||||||
CompScreenPtr cs;
|
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
|
REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
|
||||||
pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
|
pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
|
||||||
|
@ -519,18 +376,12 @@ ProcCompositeReleaseOverlayWindow (ClientPtr client)
|
||||||
* Has client queried a reference to the overlay window
|
* Has client queried a reference to the overlay window
|
||||||
* on this screen? If not, generate an error.
|
* on this screen? If not, generate an error.
|
||||||
*/
|
*/
|
||||||
pOc = findCompOverlayClient(client, pWin->drawable.pScreen);
|
pOc = compFindOverlayClient (pWin->drawable.pScreen, client);
|
||||||
if (pOc == NULL) {
|
if (pOc == NULL)
|
||||||
return BadMatch;
|
return BadMatch;
|
||||||
}
|
|
||||||
|
|
||||||
/* The delete function will free the client structure */
|
/* The delete function will free the client structure */
|
||||||
FreeResource (pOc->resource, 0);
|
FreeResource (pOc->resource, RT_NONE);
|
||||||
|
|
||||||
cs = GetCompScreen(pScreen);
|
|
||||||
if (cs->pOverlayClients == NULL) {
|
|
||||||
UnmapWindow(cs->pOverlayWin, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return client->noClientException;
|
return client->noClientException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,14 +76,6 @@ compCloseScreen (int index, ScreenPtr pScreen)
|
||||||
pScreen->CopyWindow = cs->CopyWindow;
|
pScreen->CopyWindow = cs->CopyWindow;
|
||||||
pScreen->PositionWindow = cs->PositionWindow;
|
pScreen->PositionWindow = cs->PositionWindow;
|
||||||
|
|
||||||
deleteCompOverlayClientsForScreen(pScreen);
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Note: no need to call DeleteWindow; the server has
|
|
||||||
** already destroyed it.
|
|
||||||
*/
|
|
||||||
cs->pOverlayWin = NULL;
|
|
||||||
|
|
||||||
xfree (cs);
|
xfree (cs);
|
||||||
dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL);
|
dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL);
|
||||||
ret = (*pScreen->CloseScreen) (index, pScreen);
|
ret = (*pScreen->CloseScreen) (index, pScreen);
|
||||||
|
@ -122,11 +114,11 @@ compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||||
if (ret && (mask & CWBackingStore)) {
|
if (ret && (mask & CWBackingStore)) {
|
||||||
if (pWin->backingStore != NotUseful) {
|
if (pWin->backingStore != NotUseful) {
|
||||||
compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
|
compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
|
||||||
pWin->backStorage = TRUE;
|
pWin->backStorage = (pointer) (intptr_t) 1;
|
||||||
} else {
|
} else {
|
||||||
compUnredirectWindow(serverClient, pWin,
|
compUnredirectWindow(serverClient, pWin,
|
||||||
CompositeRedirectAutomatic);
|
CompositeRedirectAutomatic);
|
||||||
pWin->backStorage = FALSE;
|
pWin->backStorage = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,6 +372,7 @@ compScreenInit (ScreenPtr pScreen)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
cs->damaged = FALSE;
|
cs->damaged = FALSE;
|
||||||
|
cs->overlayWid = FakeClientID(0);
|
||||||
cs->pOverlayWin = NULL;
|
cs->pOverlayWin = NULL;
|
||||||
cs->pOverlayClients = NULL;
|
cs->pOverlayClients = NULL;
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,7 @@ typedef struct _CompScreen {
|
||||||
VisualID *alternateVisuals;
|
VisualID *alternateVisuals;
|
||||||
|
|
||||||
WindowPtr pOverlayWin;
|
WindowPtr pOverlayWin;
|
||||||
|
Window overlayWid;
|
||||||
CompOverlayClientPtr pOverlayClients;
|
CompOverlayClientPtr pOverlayClients;
|
||||||
|
|
||||||
} CompScreenRec, *CompScreenPtr;
|
} CompScreenRec, *CompScreenPtr;
|
||||||
|
@ -172,6 +173,7 @@ extern DevPrivateKey CompSubwindowsPrivateKey;
|
||||||
|
|
||||||
extern RESTYPE CompositeClientWindowType;
|
extern RESTYPE CompositeClientWindowType;
|
||||||
extern RESTYPE CompositeClientSubwindowsType;
|
extern RESTYPE CompositeClientSubwindowsType;
|
||||||
|
extern RESTYPE CompositeClientOverlayType;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* compalloc.c
|
* compalloc.c
|
||||||
|
@ -229,6 +231,25 @@ CompositeRegisterAlternateVisuals (ScreenPtr pScreen,
|
||||||
Bool
|
Bool
|
||||||
compScreenInit (ScreenPtr pScreen);
|
compScreenInit (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compoverlay.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
compFreeOverlayClient (CompOverlayClientPtr pOcToDel);
|
||||||
|
|
||||||
|
CompOverlayClientPtr
|
||||||
|
compFindOverlayClient (ScreenPtr pScreen, ClientPtr pClient);
|
||||||
|
|
||||||
|
CompOverlayClientPtr
|
||||||
|
compCreateOverlayClient (ScreenPtr pScreen, ClientPtr pClient);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
compCreateOverlayWindow (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
void
|
||||||
|
compDestroyOverlayWindow (ScreenPtr pScreen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* compwindow.c
|
* compwindow.c
|
||||||
*/
|
*/
|
||||||
|
@ -292,9 +313,6 @@ compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||||
void
|
void
|
||||||
compWindowUpdate (WindowPtr pWin);
|
compWindowUpdate (WindowPtr pWin);
|
||||||
|
|
||||||
void
|
|
||||||
deleteCompOverlayClientsForScreen (ScreenPtr pScreen);
|
|
||||||
|
|
||||||
WindowPtr
|
WindowPtr
|
||||||
CompositeRealChildHead (WindowPtr pWin);
|
CompositeRealChildHead (WindowPtr pWin);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* 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"
|
||||||
|
#include "xace.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete the given overlay client list element from its screen list.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
compFreeOverlayClient (CompOverlayClientPtr pOcToDel)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pOcToDel->pScreen;
|
||||||
|
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||||
|
CompOverlayClientPtr *pPrev, pOc;
|
||||||
|
|
||||||
|
for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext)
|
||||||
|
{
|
||||||
|
if (pOc == pOcToDel) {
|
||||||
|
*pPrev = pOc->pNext;
|
||||||
|
xfree (pOc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy overlay window when there are no more clients using it */
|
||||||
|
if (cs->pOverlayClients == NULL)
|
||||||
|
compDestroyOverlayWindow (pScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the client's first overlay client rec from the given screen
|
||||||
|
*/
|
||||||
|
CompOverlayClientPtr
|
||||||
|
compFindOverlayClient (ScreenPtr pScreen, ClientPtr pClient)
|
||||||
|
{
|
||||||
|
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||||
|
CompOverlayClientPtr pOc;
|
||||||
|
|
||||||
|
for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext)
|
||||||
|
if (pOc->pClient == pClient)
|
||||||
|
return pOc;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create an overlay client object for the given client
|
||||||
|
*/
|
||||||
|
CompOverlayClientPtr
|
||||||
|
compCreateOverlayClient (ScreenPtr pScreen, ClientPtr pClient)
|
||||||
|
{
|
||||||
|
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||||
|
CompOverlayClientPtr pOc;
|
||||||
|
|
||||||
|
pOc = (CompOverlayClientPtr) xalloc(sizeof(CompOverlayClientRec));
|
||||||
|
if (pOc == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
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))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return pOc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the overlay window and map it
|
||||||
|
*/
|
||||||
|
Bool
|
||||||
|
compCreateOverlayWindow (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||||
|
WindowPtr pRoot = WindowTable[pScreen->myNum];
|
||||||
|
WindowPtr pWin;
|
||||||
|
XID overrideRedirect = TRUE;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
pWin = cs->pOverlayWin =
|
||||||
|
CreateWindow (cs->overlayWid, pRoot,
|
||||||
|
0, 0, pScreen->width, pScreen->height, 0,
|
||||||
|
InputOutput, CWOverrideRedirect, &overrideRedirect,
|
||||||
|
pRoot->drawable.depth,
|
||||||
|
serverClient, pScreen->rootVisual, &result);
|
||||||
|
if (pWin == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
MapWindow(pWin, serverClient);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroy the overlay window
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
compDestroyOverlayWindow (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||||
|
|
||||||
|
cs->pOverlayWin = NullWindow;
|
||||||
|
FreeResource (cs->overlayWid, RT_NONE);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue