[xserver-commit] xserver/composite compalloc.c,1.2,1.3 compext.c,1.1,1.2 compinit.c,1.3,1.4 compint.h,1.2,1.3 compwindow.c,1.3,1.4

Keith Packard xserver-commit@pdx.freedesktop.org
Fri, 07 Nov 2003 15:29:31 -0800


Committed by: keithp

Update of /cvs/xserver/xserver/composite
In directory pdx:/tmp/cvs-serv8754/composite

Modified Files:
	compalloc.c compext.c compinit.c compint.h compwindow.c 
Log Message:
	* composite/compalloc.c: (compReportDamage), (compRedirectWindow),
	(compFreeClientWindow), (compFreeClientSubwindows),
	(compRedirectOneSubwindow), (compUnredirectOneSubwindow),
	(compAllocPixmap), (compFreePixmap), (compReallocPixmap):
	* composite/compext.c: (CompositeExtensionInit):
	* composite/compinit.c: (compScreenInit):
	* composite/compint.h:
	* composite/compwindow.c: (compCheckRedirect),
	(compReparentWindow), (compCopyWindow), (compDestroyWindow),
	(compSetRedirectBorderClip), (compGetRedirectBorderClip),
	(compWindowUpdateAutomatic), (compWindowUpdate):
	* fb/fb.h:
	* fb/fbpixmap.c: (fbCreatePixmapBpp):
	* fb/fbwindow.c: (fbCopyWindow):
	* hw/kdrive/fbdev/fbdev.c: (fbdevInitialize), (fbdevScreenInit):
	* hw/kdrive/linux/keyboard.c: (readKernelMapping):
	* hw/kdrive/linux/linux.c: (LinuxInit), (LinuxSpecialKey),
	(LinuxFini):
	* hw/kdrive/linux/mouse.c: (MouseWaitForReadable), (MouseReadByte),
	(ps2SkipInit), (MouseRead):
	* hw/kdrive/smi/smi.c: (smiScreenInit):
	* include/pixmapstr.h:
	* mi/mi.h:
	* mi/midispcur.c:
	* mi/mivaltree.c: (miRegisterRedirectBorderClipProc),
	(miComputeClips):
	* miext/damage/damage.c: (DamageDamageRegion):
	* miext/damage/damage.h:
	* render/mipict.c: (miValidatePicture):
	Ok, Composite extension is semi-working; when no-one asks
	for redirection, the server seems to act as before.  With
	RedirectSubwindows (root, automatic), the server looks just
	like a regular X server.  Now to go rewrite the (currently lame)
	compositing manager to get some real action on the screen.
	
	Some of the fixes here are to make valgrind quiet with
	various ioctls used by kdrive/linux.

	Also fixed a bug where fbdev initialization was out of order
	in fbdev.c and smi.c


Index: compalloc.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compalloc.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- compalloc.c	7 Nov 2003 04:26:08 -0000	1.2
+++ compalloc.c	7 Nov 2003 23:29:29 -0000	1.3
@@ -27,14 +27,16 @@
 #endif
 #include "compint.h"
 
-static void
+void
 compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
 {
     WindowPtr	    pWin = (WindowPtr) closure;
     ScreenPtr	    pScreen = pWin->drawable.pScreen;
     CompScreenPtr   cs = GetCompScreen (pScreen);
+    CompWindowPtr   cw = GetCompWindow (pWin);
 
     cs->damaged = TRUE;
+    cw->damaged = TRUE;
 }
 
 static void
@@ -54,6 +56,7 @@
 {
     CompWindowPtr	cw = GetCompWindow (pWin);
     CompClientWindowPtr	ccw;
+    Bool		wasMapped = pWin->mapped;
 
     /*
      * Only one Manual update is allowed
@@ -86,7 +89,7 @@
 	}
 	cw->damage = DamageCreate (compReportDamage,
 				   compDestroyDamage,
-				   DamageReportRawRegion,
+				   DamageReportNonEmpty,
 				   FALSE,
 				   pWin);
 	if (!cw->damage)
@@ -95,8 +98,16 @@
 	    xfree (cw);
 	    return BadAlloc;
 	}
+	if (wasMapped)
+	    UnmapWindow (pWin, FALSE);
+
+	REGION_INIT (pScreen, &cw->borderClip, NullBox, 0);
 	cw->update = CompositeRedirectAutomatic;
 	cw->clients = 0;
+	cw->oldx = COMP_ORIGIN_INVALID;
+	cw->oldy = COMP_ORIGIN_INVALID;
+	cw->damageRegistered = FALSE;
+	cw->damaged = FALSE;
 	pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
     }
     ccw->next = cw->clients;
@@ -104,13 +115,27 @@
     if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
 	return BadAlloc;
     if (ccw->update == CompositeRedirectManual)
+    {
+	if (cw->damageRegistered)
+	{
+	    DamageUnregister (&pWin->drawable, cw->damage);
+	    cw->damageRegistered = FALSE;
+	}
 	cw->update = CompositeRedirectManual;
+    }
 
     if (!compCheckRedirect (pWin))
     {
 	FreeResource (ccw->id, RT_NONE);
 	return BadAlloc;
     }
+    if (wasMapped && !pWin->mapped)
+    {
+	Bool	overrideRedirect = pWin->overrideRedirect;
+	pWin->overrideRedirect = TRUE;
+	MapWindow (pWin, pClient);
+	pWin->overrideRedirect = overrideRedirect;
+    }
     
     return Success;
 }
@@ -124,6 +149,7 @@
 {
     CompWindowPtr	cw = GetCompWindow (pWin);
     CompClientWindowPtr	ccw, *prev;
+    Bool		wasMapped = pWin->mapped;
 
     if (!cw)
 	return;
@@ -140,15 +166,33 @@
     }
     if (!cw->clients)
     {
-	pWin->devPrivates[CompWindowPrivateIndex].ptr = 0;
-	
-	(void) compCheckRedirect (pWin);
-	
+	if (wasMapped)
+	    UnmapWindow (pWin, FALSE);
+    
+	if (pWin->redirectDraw)
+	    compFreePixmap (pWin);
+
 	if (cw->damage)
 	    DamageDestroy (cw->damage);
+	
 	REGION_UNINIT (pScreen, &cw->borderClip);
+    
+	pWin->devPrivates[CompWindowPrivateIndex].ptr = 0;
 	xfree (cw);
     }
+    else if (cw->update == CompositeRedirectAutomatic &&
+	     !cw->damageRegistered && pWin->redirectDraw)
+    {
+	DamageRegister (&pWin->drawable, cw->damage);
+	cw->damageRegistered = TRUE;
+    }
+    if (wasMapped && !pWin->mapped)
+    {
+	Bool	overrideRedirect = pWin->overrideRedirect;
+	pWin->overrideRedirect = TRUE;
+	MapWindow (pWin, clients[CLIENT_ID(id)]);
+	pWin->overrideRedirect = overrideRedirect;
+    }
 }
 
 /*
@@ -273,7 +317,7 @@
 	    /*
 	     * Unredirect all existing subwindows
 	     */
-	    for (pChild = pWin->lastChild; pWin; pWin = pWin->prevSib)
+	    for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
 		(void) compUnredirectWindow (pClient, pChild, ccw->update);
 
 	    xfree (ccw);
@@ -312,6 +356,50 @@
     return BadValue;
 }
 
+/*
+ * Add redirection information for one subwindow (during reparent)
+ */
+
+int
+compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
+{
+    CompSubwindowsPtr	csw = GetCompSubwindows (pParent);
+    CompClientWindowPtr	ccw;
+
+    if (!csw)
+	return Success;
+    for (ccw = csw->clients; ccw; ccw = ccw->next)
+    {
+	int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)],
+				      pWin, ccw->update);
+	if (ret != Success)
+	    return ret;
+    }
+    return Success;
+}
+
+/*
+ * Remove redirection information for one subwindow (during reparent)
+ */
+
+int
+compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
+{
+    CompSubwindowsPtr	csw = GetCompSubwindows (pParent);
+    CompClientWindowPtr	ccw;
+
+    if (!csw)
+	return Success;
+    for (ccw = csw->clients; ccw; ccw = ccw->next)
+    {
+	int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)],
+					pWin, ccw->update);
+	if (ret != Success)
+	    return ret;
+    }
+    return Success;
+}
+
 Bool
 compAllocPixmap (WindowPtr pWin)
 {
@@ -328,12 +416,18 @@
     pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth);
     if (!pPixmap)
 	return FALSE;
-    pPixmap->drawable.x = -x;
-    pPixmap->drawable.y = -y;
+    pPixmap->screen_x = x;
+    pPixmap->screen_y = y;
     pWin->redirectDraw = TRUE;
     compSetPixmap (pWin, pPixmap);
-    REGION_INIT (pScreen, &cw->borderClip, NullBox, 0);
-    DamageRegister (&pWin->drawable, cw->damage);
+    cw->oldx = COMP_ORIGIN_INVALID;
+    cw->oldy = COMP_ORIGIN_INVALID;
+    cw->damageRegistered = FALSE;
+    if (cw->update == CompositeRedirectAutomatic)
+    {
+	DamageRegister (&pWin->drawable, cw->damage);
+	cw->damageRegistered = TRUE;
+    }
     return TRUE;
 }
 
@@ -342,7 +436,13 @@
 {
     ScreenPtr	    pScreen = pWin->drawable.pScreen;
     PixmapPtr	    pRedirectPixmap, pParentPixmap;
+    CompWindowPtr   cw = GetCompWindow (pWin);
 
+    if (cw && cw->damageRegistered)
+    {
+	DamageUnregister (&pWin->drawable, cw->damage);
+	cw->damageRegistered = FALSE;
+    }
     pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
     pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
     pWin->redirectDraw = FALSE;
@@ -350,13 +450,18 @@
     (*pScreen->DestroyPixmap) (pRedirectPixmap);
 }
 
+/*
+ * Make sure the pixmap is the right size and offset.  Allocate a new
+ * pixmap to change size, adjust origin to change offset
+ */
 Bool
 compReallocPixmap (WindowPtr pWin)
 {
-    ScreenPtr	pScreen = pWin->drawable.pScreen;
-    PixmapPtr	pPixmap = (*pScreen->GetWindowPixmap) (pWin);
-    int		bw = (int) pWin->borderWidth;
-    int		x, y, w, h;
+    ScreenPtr	    pScreen = pWin->drawable.pScreen;
+    PixmapPtr	    pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+    CompWindowPtr   cw = GetCompWindow (pWin);
+    int		    bw = (int) pWin->borderWidth;
+    int		    x, y, w, h;
 
     x = pWin->drawable.x - bw;
     y = pWin->drawable.y - bw;
@@ -365,15 +470,37 @@
     if (w != pPixmap->drawable.width ||
 	h != pPixmap->drawable.height)
     {
+	GCPtr	    pGC;
+	PixmapPtr   pNew;
+	
+	pPixmap->refcnt++;
 	compFreePixmap (pWin);
 	if (!compAllocPixmap (pWin))
 	    return FALSE;
+	cw->oldx = pPixmap->screen_x;
+	cw->oldy = pPixmap->screen_y;
+	pNew = (*pScreen->GetWindowPixmap) (pWin);
+	pGC = GetScratchGC (pNew->drawable.depth, pScreen);
+	if (pGC)
+	{
+	    ValidateGC(&pNew->drawable, pGC);
+	    (void) (*pGC->ops->CopyArea) (&pPixmap->drawable,
+					  &pNew->drawable,
+					  pGC,
+					  0, 0,
+					  pNew->drawable.width,
+					  pNew->drawable.height,
+					  0, 0);
+	    FreeScratchGC (pGC);
+	}
+	(*pScreen->DestroyPixmap) (pPixmap);
     }
-    else if (x != -pPixmap->drawable.x ||
-	     y != -pPixmap->drawable.y)
+    else
     {
-	pPixmap->drawable.x = -x;
-	pPixmap->drawable.y = -y;
+	cw->oldx = pPixmap->screen_x;
+	cw->oldy = pPixmap->screen_y;
+	pPixmap->screen_x = x;
+	pPixmap->screen_y = y;
     }
     return TRUE;
 }

Index: compext.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compext.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- compext.c	7 Nov 2003 04:27:30 -0000	1.1
+++ compext.c	7 Nov 2003 23:29:29 -0000	1.2
@@ -357,5 +357,6 @@
     for (s = 0; s < screenInfo.numScreens; s++)
 	if (!compScreenInit (screenInfo.screens[s]))
 	    return;
-    miRegisterRedirectBorderClipProc (compRedirectBorderClip);
+    miRegisterRedirectBorderClipProc (compSetRedirectBorderClip,
+				      compGetRedirectBorderClip);
 }

Index: compinit.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compinit.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- compinit.c	7 Nov 2003 04:26:08 -0000	1.3
+++ compinit.c	7 Nov 2003 23:29:29 -0000	1.4
@@ -112,6 +112,8 @@
     if (!cs)
 	return FALSE;
 
+    cs->damaged = FALSE;
+
     cs->PositionWindow = pScreen->PositionWindow;
     pScreen->PositionWindow = compPositionWindow;
 

Index: compint.h
===================================================================
RCS file: /cvs/xserver/xserver/composite/compint.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- compint.h	7 Nov 2003 04:26:08 -0000	1.2
+++ compint.h	7 Nov 2003 23:29:29 -0000	1.3
@@ -56,10 +56,16 @@
 typedef struct _CompWindow {
     RegionRec		    borderClip;
     DamagePtr		    damage;	/* for automatic update mode */
+    Bool		    damageRegistered;
+    Bool		    damaged;
     int			    update;
     CompClientWindowPtr	    clients;
+    int			    oldx;
+    int			    oldy;
 } CompWindowRec, *CompWindowPtr;
 
+#define COMP_ORIGIN_INVALID	    0x80000000
+
 typedef struct _CompSubwindows {
     int			    update;
     CompClientWindowPtr	    clients;
@@ -99,6 +105,9 @@
  * compalloc.c
  */
 
+void
+compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure);
+
 Bool
 compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
 
@@ -117,6 +126,12 @@
 int
 compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
 
+int
+compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
+
+int
+compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
+
 Bool
 compAllocPixmap (WindowPtr pWin);
 
@@ -172,7 +187,10 @@
 compDestroyWindow (WindowPtr pWin);
 
 void
-compRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
+compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
+
+RegionPtr
+compGetRedirectBorderClip (WindowPtr pWin);
 
 void
 compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);

Index: compwindow.c
===================================================================
RCS file: /cvs/xserver/xserver/composite/compwindow.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- compwindow.c	7 Nov 2003 04:26:08 -0000	1.3
+++ compwindow.c	7 Nov 2003 23:29:29 -0000	1.4
@@ -81,16 +81,11 @@
     compCheckTree (pWin->drawable.pScreen);
 }
 
-static Bool
-compShouldBeRedirected (WindowPtr pWin)
-{
-    return pWin->viewable && GetCompWindow (pWin);
-}
-
 Bool
 compCheckRedirect (WindowPtr pWin)
 {
-    Bool	should = compShouldBeRedirected (pWin);
+    CompWindowPtr   cw = GetCompWindow (pWin);
+    Bool	    should = pWin->viewable && (cw != NULL);
     
     if (should != pWin->redirectDraw)
     {
@@ -158,10 +153,12 @@
 void
 compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
 {
-    ScreenPtr	    pScreen = pWin->drawable.pScreen;
-    CompScreenPtr   cs = GetCompScreen (pScreen);
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
+    CompScreenPtr	cs = GetCompScreen (pScreen);
 
     pScreen->ReparentWindow = cs->ReparentWindow;
+    compUnredirectOneSubwindow (pPriorParent, pWin);
+    compRedirectOneSubwindow (pWin->parent, pWin);
     compCheckRedirect (pWin);
     if (pWin->parent && !pWin->redirectDraw)
 	compSetPixmap (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
@@ -177,13 +174,38 @@
 {
     ScreenPtr	    pScreen = pWin->drawable.pScreen;
     CompScreenPtr   cs = GetCompScreen (pScreen);
+    int		    dx = 0, dy = 0;
 
     pScreen->CopyWindow = cs->CopyWindow;
     if (pWin->redirectDraw)
     {
-	;
+	PixmapPtr	pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+	CompWindowPtr	cw = GetCompWindow (pWin);
+	
+	assert (cw->oldx != COMP_ORIGIN_INVALID);
+	assert (cw->oldy != COMP_ORIGIN_INVALID);
+	dx = pPixmap->screen_x - cw->oldx;
+	dy = pPixmap->screen_y - cw->oldy;
+	ptOldOrg.x += dx;
+	ptOldOrg.y += dy;
+    }
+    if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y)
+    {
+	if (dx || dy)
+	    REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
+	(*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+	if (dx || dy)
+	    REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
+    }
+    else
+    {
+	ptOldOrg.x -= dx;
+	ptOldOrg.y -= dy;
+	REGION_TRANSLATE (prgnSrc, prgnSrc,
+			  pWin->drawable.x - ptOldOrg.x,
+			  pWin->drawable.y - ptOldOrg.y);
+	DamageDamageRegion (&pWin->drawable, prgnSrc);
     }
-    (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
     cs->CopyWindow = pScreen->CopyWindow;
     pScreen->CopyWindow = compCopyWindow;
     compCheckTree (pWin->drawable.pScreen);
@@ -218,11 +240,21 @@
 Bool
 compDestroyWindow (WindowPtr pWin)
 {
-    ScreenPtr	    pScreen = pWin->drawable.pScreen;
-    CompScreenPtr   cs = GetCompScreen (pScreen);
-    Bool	    ret;
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
+    CompScreenPtr	cs = GetCompScreen (pScreen);
+    CompWindowPtr	cw = GetCompWindow (pWin);
+    CompSubwindowsPtr	csw = GetCompSubwindows (pWin);
+    CompClientWindowPtr ccw;
+    Bool		ret;
 
     pScreen->DestroyWindow = cs->DestroyWindow;
+    if (cw)
+	while ((ccw = cw->clients))
+	    FreeResource (ccw->id, RT_NONE);
+    if (csw)
+	while ((ccw = csw->clients))
+	    FreeResource (ccw->id, RT_NONE);
+    
     if (pWin->redirectDraw)
 	compFreePixmap (pWin);
     ret = (*pScreen->DestroyWindow) (pWin);
@@ -233,11 +265,25 @@
 }
 
 void
-compRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion)
+compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion)
 {
-    CompWindowPtr   cs = GetCompWindow (pWin);
+    CompWindowPtr   cw = GetCompWindow (pWin);
+    RegionRec	    more;
 
-    REGION_COPY (pScreen, &cs->borderClip, pRegion);
+    REGION_INIT(pScreen, &more, NullBox, 0);
+    REGION_SUBTRACT(pScreen, &more, pRegion, &cw->borderClip);
+    DamageDamageRegion (&pWin->drawable, &more);
+    REGION_UNINIT (pScreen, &more);
+
+    REGION_COPY (pScreen, &cw->borderClip, pRegion);
+}
+
+RegionPtr
+compGetRedirectBorderClip (WindowPtr pWin)
+{
+    CompWindowPtr   cw = GetCompWindow (pWin);
+
+    return &cw->borderClip;
 }
 
 static VisualPtr
@@ -265,24 +311,32 @@
 static void
 compWindowUpdateAutomatic (WindowPtr pWin)
 {
+    CompWindowPtr   cw = GetCompWindow (pWin);
     ScreenPtr	    pScreen = pWin->drawable.pScreen;
+    WindowPtr	    pParent = pWin->parent;
     PixmapPtr	    pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
+    PixmapPtr	    pDstPixmap = (*pScreen->GetWindowPixmap) (pParent);
     PictFormatPtr   pSrcFormat = compWindowFormat (pWin);
     PictFormatPtr   pDstFormat = compWindowFormat (pWin->parent);
     int		    error;
-    XID		    vlist[1] = { IncludeInferiors };
-    PicturePtr	    pSrcPicture = CreatePicture (0, &pWin->drawable,
+    RegionPtr	    pRegion = DamageRegion (cw->damage);
+    PicturePtr	    pSrcPicture = CreatePicture (0, &pSrcPixmap->drawable,
 						 pSrcFormat, 
-						 CPSubwindowMode,
-						 vlist,
+						 0, 0,
 						 serverClient,
 						 &error);
-    PicturePtr	    pDstPicture = CreatePicture (0, &pWin->parent->drawable,
+    PicturePtr	    pDstPicture = CreatePicture (0, &pDstPixmap->drawable,
 						 pDstFormat,
-						 CPSubwindowMode,
-						 vlist,
+						 0, 0,
 						 serverClient,
 						 &error);
+
+    REGION_INTERSECT (pScreen, pRegion, pRegion, &cw->borderClip);
+    
+    SetPictureClipRegion (pDstPicture,
+			  -pDstPixmap->screen_x,
+			  -pDstPixmap->screen_y,
+			  pRegion);
     
     CompositePicture (PictOpSrc,
 		      pSrcPicture,
@@ -291,12 +345,13 @@
 		      0,
 		      0,
 		      0, 0,
-		      -pSrcPixmap->drawable.x,
-		      -pSrcPixmap->drawable.y,
+		      pSrcPixmap->screen_x - pDstPixmap->screen_x,
+		      pSrcPixmap->screen_y - pDstPixmap->screen_x,
 		      pSrcPixmap->drawable.width,
 		      pSrcPixmap->drawable.height);
     FreePicture (pSrcPicture, 0);
     FreePicture (pDstPicture, 0);
+    DamageEmpty (cw->damage);
 }
 
 void
@@ -308,11 +363,12 @@
 	compWindowUpdate (pChild);
     if (pWin->redirectDraw)
     {
-	CompWindowPtr	cs = GetCompWindow(pWin);
+	CompWindowPtr	cw = GetCompWindow(pWin);
 
-	if (cs->update == CompositeRedirectAutomatic)
+	if (cw->damaged)
 	{
 	    compWindowUpdateAutomatic (pWin);
+	    cw->damaged = FALSE;
 	}
     }
 }