xserver/composite compalloc.c,1.10,1.11 compint.h,1.10,1.11

Keith Packard xserver-commit at pdx.freedesktop.org
Sat Jan 21 20:50:17 PST 2006


Committed by: keithp

Update of /cvs/xserver/xserver/composite
In directory gabe:/tmp/cvs-serv21727/composite

Modified Files:
	compalloc.c compint.h 
Log Message:
2006-01-21  Keith Packard  <keithp at keithp.com>

	* composite/compalloc.c: (compEnsureWindowPrivate),
	(compCheckWindowPrivateNeeded), (compSaveBeforeRedirect),
	(compRestoreAfterRedirect), (compRedirectWindow),
	(compFreeClientWindow), (compRedirectSubwindows),
	(compFreeClientSubwindows):
	* composite/compint.h:
	
	Eliminate one of the two WindowPrivate indices to save
	memory in unredirected windows.

	Clear StructureNotify and SubstructureNotify bits as necessary
	to avoid delivering MapNotify/UnmapNotify events during
	redirect allocation/deallocation.


Index: compalloc.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compalloc.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- compalloc.c	8 Feb 2005 22:39:20 -0000	1.10
+++ compalloc.c	22 Jan 2006 04:50:15 -0000	1.11
@@ -48,6 +48,113 @@
     cw->damage = 0;
 }
 
+static CompWindowPrivatePtr
+compEnsureWindowPrivate (WindowPtr pWin)
+{
+    CompWindowPrivatePtr    cwp = GetCompWindowPrivate(pWin);
+
+    if (!cwp)
+    {
+	cwp = xalloc (sizeof (CompWindowPrivateRec));
+	if (!cwp)
+	    return NULL;
+	cwp->window = NULL;
+	cwp->subwindows = NULL;
+	pWin->devPrivates[CompWindowPrivateIndex].ptr = cwp;
+    }
+    return cwp;
+}
+
+static void
+compCheckWindowPrivateNeeded (WindowPtr pWin)
+{
+    CompWindowPrivatePtr    cwp = GetCompWindowPrivate(pWin);
+
+    if (cwp)
+    {
+	if (cwp->window == NULL &&
+	    cwp->subwindows == NULL)
+	{
+	    pWin->devPrivates[CompWindowPrivateIndex].ptr = NULL;
+	    xfree (cwp);
+	}
+    }
+}
+
+typedef struct {
+    Bool	overrideRedirect;
+    Mask	selfEventMask;
+    Mask	selfOtherEventMasks;
+    Mask	parentEventMask;
+    Mask	parentOtherEventMasks;
+} CompRedirectPreserveRec, *CompRedirectPreservePtr;
+
+static void
+compSaveBeforeRedirect (WindowPtr pWin, CompRedirectPreservePtr pPreserve)
+{
+    WindowPtr	pParent = pWin->parent;
+    
+    /* OverrideRedirect TRUE */
+    pPreserve->overrideRedirect = pWin->overrideRedirect;
+    pWin->overrideRedirect = TRUE;
+
+    /* Disable StructureNotify on self */
+    pPreserve->selfEventMask = pWin->eventMask;
+    pWin->eventMask &= ~StructureNotifyMask;
+    if (pWin->optional) 
+    {
+	pPreserve->selfOtherEventMasks = pWin->optional->otherEventMasks;
+	pWin->optional->otherEventMasks &= ~StructureNotifyMask;
+    }
+    else
+	pPreserve->selfOtherEventMasks = 0;
+
+    /* Disable SubstructureNotify on parent */
+    if (pParent)
+    {
+	pPreserve->parentEventMask = pParent->eventMask;
+	pParent->eventMask &= ~SubstructureNotifyMask;
+	if (pParent->optional)
+	{
+	    pPreserve->parentOtherEventMasks = pParent->optional->otherEventMasks;
+	    pParent->optional->otherEventMasks &= ~SubstructureNotifyMask;
+	}
+	else
+	    pPreserve->parentOtherEventMasks = 0;
+    }
+}
+
+static Bool
+compRestoreAfterRedirect (WindowPtr pWin, CompRedirectPreservePtr pPreserve)
+{
+    WindowPtr	pParent = pWin->parent;
+
+    /* OverrideRedirect */
+    pWin->overrideRedirect = pPreserve->overrideRedirect;
+
+    /* EventMask */
+    pWin->eventMask = pPreserve->selfEventMask;
+    if (pPreserve->selfOtherEventMasks)
+    {
+	if (!MakeWindowOptional (pWin))
+	    return FALSE;
+	pWin->optional->otherEventMasks = pPreserve->selfOtherEventMasks;
+    }
+
+    /* Parent event mask */
+    if (pParent)
+    {
+	pParent->eventMask = pPreserve->parentEventMask;
+	if (pPreserve->parentOtherEventMasks)
+	{
+	    if (!MakeWindowOptional (pParent))
+		return FALSE;
+	    pParent->optional->otherEventMasks = pPreserve->parentOtherEventMasks;
+	}
+    }
+    return TRUE;
+}
+
 /*
  * Redirect one window for one client
  */
@@ -57,6 +164,7 @@
     CompWindowPtr	cw = GetCompWindow (pWin);
     CompClientWindowPtr	ccw;
     Bool		wasMapped = pWin->mapped;
+    CompRedirectPreserveRec preserve;
 
     /*
      * Only one Manual update is allowed
@@ -81,10 +189,16 @@
      */
     if (!cw)
     {
+	CompWindowPrivatePtr	cwp = compEnsureWindowPrivate (pWin);
+	if (!cwp) {
+	    xfree (ccw);
+	    return BadAlloc;
+	}
 	cw = xalloc (sizeof (CompWindowRec));
 	if (!cw)
 	{
 	    xfree (ccw);
+	    compCheckWindowPrivateNeeded (pWin);
 	    return BadAlloc;
 	}
 	cw->damage = DamageCreate (compReportDamage,
@@ -97,10 +211,16 @@
 	{
 	    xfree (ccw);
 	    xfree (cw);
+	    compCheckWindowPrivateNeeded (pWin);
 	    return BadAlloc;
 	}
 	if (wasMapped)
+	{
+	    compSaveBeforeRedirect (pWin, &preserve);
 	    UnmapWindow (pWin, FALSE);
+	    if (!compRestoreAfterRedirect (pWin, &preserve))
+		return BadAlloc;
+	}
 
 	REGION_NULL (pScreen, &cw->borderClip);
 	cw->update = CompositeRedirectAutomatic;
@@ -109,7 +229,7 @@
 	cw->oldy = COMP_ORIGIN_INVALID;
 	cw->damageRegistered = FALSE;
 	cw->damaged = FALSE;
-	pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
+	cwp->window = cw;
     }
     ccw->next = cw->clients;
     cw->clients = ccw;
@@ -132,10 +252,10 @@
     }
     if (wasMapped && !pWin->mapped)
     {
-	Bool	overrideRedirect = pWin->overrideRedirect;
-	pWin->overrideRedirect = TRUE;
+	compSaveBeforeRedirect (pWin, &preserve);
 	MapWindow (pWin, pClient);
-	pWin->overrideRedirect = overrideRedirect;
+	if (!compRestoreAfterRedirect (pWin, &preserve))
+	    return BadAlloc;
     }
     
     return Success;
@@ -148,10 +268,15 @@
 void
 compFreeClientWindow (WindowPtr pWin, XID id)
 {
-    CompWindowPtr	cw = GetCompWindow (pWin);
+    CompWindowPrivatePtr    cwp = GetCompWindowPrivate (pWin);
+    CompWindowPtr	cw;
     CompClientWindowPtr	ccw, *prev;
     Bool		wasMapped = pWin->mapped;
+    CompRedirectPreserveRec preserve;
 
+    if (!cwp)
+	return;
+    cw = cwp->window;
     if (!cw)
 	return;
     for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next)
@@ -168,7 +293,12 @@
     if (!cw->clients)
     {
 	if (wasMapped)
+	{
+	    compSaveBeforeRedirect (pWin, &preserve);
 	    UnmapWindow (pWin, FALSE);
+	    (void) compRestoreAfterRedirect (pWin, &preserve);
+		
+	}
     
 	if (pWin->redirectDraw)
 	    compFreePixmap (pWin);
@@ -178,8 +308,9 @@
 	
 	REGION_UNINIT (pScreen, &cw->borderClip);
     
-	pWin->devPrivates[CompWindowPrivateIndex].ptr = 0;
+	cwp->window = NULL;
 	xfree (cw);
+        compCheckWindowPrivateNeeded (pWin);
     }
     else if (cw->update == CompositeRedirectAutomatic &&
 	     !cw->damageRegistered && pWin->redirectDraw)
@@ -190,10 +321,9 @@
     }
     if (wasMapped && !pWin->mapped)
     {
-	Bool	overrideRedirect = pWin->overrideRedirect;
-	pWin->overrideRedirect = TRUE;
+	compSaveBeforeRedirect (pWin, &preserve);
 	MapWindow (pWin, clients[CLIENT_ID(id)]);
-	pWin->overrideRedirect = overrideRedirect;
+	(void) compRestoreAfterRedirect (pWin, &preserve);
     }
 }
 
@@ -229,6 +359,7 @@
     CompSubwindowsPtr	csw = GetCompSubwindows (pWin);
     CompClientWindowPtr	ccw;
     WindowPtr		pChild;
+    CompWindowPrivatePtr    cwp;
 
     /*
      * Only one Manual update is allowed
@@ -250,17 +381,24 @@
     /*
      * Now make sure there's a per-window structure to hang this from
      */
+    cwp = compEnsureWindowPrivate (pWin);
     if (!csw)
     {
+	if (!cwp) 
+	{
+	    xfree (ccw);
+	    return BadAlloc;
+	}
 	csw = xalloc (sizeof (CompSubwindowsRec));
 	if (!csw)
 	{
+	    compCheckWindowPrivateNeeded (pWin);
 	    xfree (ccw);
 	    return BadAlloc;
 	}
 	csw->update = CompositeRedirectAutomatic;
 	csw->clients = 0;
-	pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = csw;
+	cwp->subwindows = csw;
     }
     /*
      * Redirect all existing windows
@@ -275,7 +413,8 @@
 	    if (!csw->clients)
 	    {
 		xfree (csw);
-		pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
+		cwp->subwindows = NULL;
+		compCheckWindowPrivateNeeded (pWin);
 	    }
 	    xfree (ccw);
 	    return ret;
@@ -307,10 +446,13 @@
 void
 compFreeClientSubwindows (WindowPtr pWin, XID id)
 {
-    CompSubwindowsPtr	csw = GetCompSubwindows (pWin);
+    CompWindowPrivatePtr    cwp = GetCompWindowPrivate (pWin);
+    CompSubwindowsPtr	csw = cwp ? cwp->subwindows : NULL;
     CompClientWindowPtr	ccw, *prev;
     WindowPtr		pChild;
 
+    if (!cwp)
+	return;
     if (!csw)
 	return;
     for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next)
@@ -348,8 +490,9 @@
      */
     if (!csw->clients)
     {
-	pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
 	xfree (csw);
+	cwp->subwindows = NULL;
+	compCheckWindowPrivateNeeded (pWin);
     }
 }
 

Index: compint.h
===================================================================
RCS file: /cvs/xserver/xserver/composite/compint.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- compint.h	8 Feb 2005 22:39:20 -0000	1.10
+++ compint.h	22 Jan 2006 04:50:15 -0000	1.11
@@ -59,7 +59,7 @@
     struct _CompClientWindow	*next;
     XID				id;
     int				update;
-}  CompClientWindowRec, *CompClientWindowPtr;
+} CompClientWindowRec, *CompClientWindowPtr;
 
 typedef struct _CompWindow {
     RegionRec		    borderClip;
@@ -81,6 +81,11 @@
     CompClientWindowPtr	    clients;
 } CompSubwindowsRec, *CompSubwindowsPtr;
 
+typedef struct _CompWindowPrivate {
+    CompWindowPtr	window;
+    CompSubwindowsPtr	subwindows;
+} CompWindowPrivateRec, *CompWindowPrivatePtr;
+
 #ifndef COMP_INCLUDE_RGB24_VISUAL
 #define COMP_INCLUDE_RGB24_VISUAL 0
 #endif
@@ -126,11 +131,11 @@
 
 extern int  CompScreenPrivateIndex;
 extern int  CompWindowPrivateIndex;
-extern int  CompSubwindowsPrivateIndex;
 
 #define GetCompScreen(s) ((CompScreenPtr) ((s)->devPrivates[CompScreenPrivateIndex].ptr))
-#define GetCompWindow(w) ((CompWindowPtr) ((w)->devPrivates[CompWindowPrivateIndex].ptr))
-#define GetCompSubwindows(w) ((CompSubwindowsPtr) ((w)->devPrivates[CompSubwindowsPrivateIndex].ptr))
+#define GetCompWindowPrivate(w)	((CompWindowPrivatePtr) ((w)->devPrivates[CompWindowPrivateIndex].ptr))
+#define GetCompWindow(w) (GetCompWindowPrivate(w) ? GetCompWindowPrivate(w)->window : NULL)
+#define GetCompSubwindows(w) (GetCompWindowPrivate(w) ? GetCompWindowPrivate(w)->subwindows : NULL)
 
 extern RESTYPE		CompositeClientWindowType;
 extern RESTYPE		CompositeClientSubwindowsType;



More information about the xserver-commit mailing list