xserver: Branch 'master'

Keith Packard keithp at kemper.freedesktop.org
Tue Jul 3 14:29:33 PDT 2007


 composite/compalloc.c  |   14 +++++++++-----
 composite/compwindow.c |   33 +++++++++++++++++----------------
 configure.ac           |    2 +-
 dix/window.c           |   14 +++++++++++---
 include/windowstr.h    |   29 ++++++++++++++++++++++++++++-
 mi/mivaltree.c         |   31 +++++++++++++++++++++----------
 6 files changed, 87 insertions(+), 36 deletions(-)

New commits:
diff-tree 866f092ca0160a366add01b48ad03438926c4d16 (from 2a75c774975b50dd4e71b7dbea7bd65ca2984a43)
Author: Keith Packard <keithp at neko.keithp.com>
Date:   Tue Jul 3 14:29:11 2007 -0700

    Make Composite manual redirect windows not clip their parent.
    
    This patch changes the semantics of manual redirect windows so that they no
    longer affect the clip list of their parent. Doing this means the parent can
    draw to the area covered by the child without using IncludeInferiors. More
    importantly, this also means that the parent receives expose events when
    that region is damaged by other actions.

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 5ea015b..1a7e4a0 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -204,7 +204,7 @@ compFreeClientWindow (WindowPtr pWin, XI
 	    EnableMapUnmapEvents (pWin);
 	}
     
-	if (pWin->redirectDraw)
+	if (pWin->redirectDraw != RedirectDrawNone)
 	    compFreePixmap (pWin);
 
 	if (cw->damage)
@@ -216,7 +216,7 @@ compFreeClientWindow (WindowPtr pWin, XI
 	xfree (cw);
     }
     else if (cw->update == CompositeRedirectAutomatic &&
-	     !cw->damageRegistered && pWin->redirectDraw)
+	     !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
     {
 	DamageRegister (&pWin->drawable, cw->damage);
 	cw->damageRegistered = TRUE;
@@ -506,7 +506,11 @@ compAllocPixmap (WindowPtr pWin)
 
     if (!pPixmap)
 	return FALSE;
-    pWin->redirectDraw = TRUE;
+    if (cw->update == CompositeRedirectAutomatic)
+	pWin->redirectDraw = RedirectDrawAutomatic;
+    else
+	pWin->redirectDraw = RedirectDrawManual;
+
     compSetPixmap (pWin, pPixmap);
     cw->oldx = COMP_ORIGIN_INVALID;
     cw->oldy = COMP_ORIGIN_INVALID;
@@ -541,7 +545,7 @@ compFreePixmap (WindowPtr pWin)
     REGION_COPY (pScreen, &pWin->borderClip, &cw->borderClip);
     pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
     pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
-    pWin->redirectDraw = FALSE;
+    pWin->redirectDraw = RedirectDrawNone;
     compSetPixmap (pWin, pParentPixmap);
     (*pScreen->DestroyPixmap) (pRedirectPixmap);
 }
@@ -562,7 +566,7 @@ compReallocPixmap (WindowPtr pWin, int d
     int		    pix_x, pix_y;
     int		    pix_w, pix_h;
 
-    assert (cw && pWin->redirectDraw);
+    assert (cw && pWin->redirectDraw != RedirectDrawNone);
     cw->oldx = pOld->screen_x;
     cw->oldy = pOld->screen_y;
     pix_x = draw_x - bw;
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 9114fff..6633163 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -57,10 +57,10 @@ compCheckWindow (WindowPtr pWin, pointer
     
     if (!pWin->parent)
     {
-	assert (!pWin->redirectDraw);
+	assert (pWin->redirectDraw == RedirectDrawNone);
 	assert (pWinPixmap == pScreenPixmap);
     }
-    else if (pWin->redirectDraw)
+    else if (pWin->redirectDraw != RedirectDrawNone)
     {
 	assert (pWinPixmap != pParentPixmap);
 	assert (pWinPixmap != pScreenPixmap);
@@ -111,7 +111,7 @@ compSetPixmapVisitWindow (WindowPtr pWin
     CompPixmapVisitPtr	pVisit = (CompPixmapVisitPtr) data;
     ScreenPtr		pScreen = pWindow->drawable.pScreen;
 
-    if (pWindow != pVisit->pWindow && pWindow->redirectDraw)
+    if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone)
 	return WT_DONTWALKCHILDREN;
     (*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap);
     /*
@@ -155,7 +155,7 @@ compCheckRedirect (WindowPtr pWin)
 	}
     }	
     
-    if (should != pWin->redirectDraw)
+    if (should != (pWin->redirectDraw != RedirectDrawNone))
     {
 	if (should)
 	    return compAllocPixmap (pWin);
@@ -179,10 +179,11 @@ compPositionWindow (WindowPtr pWin, int 
     compCheckRedirect (pWin);
      */
 #ifdef COMPOSITE_DEBUG
-    if (pWin->redirectDraw != (pWin->viewable && (GetCompWindow(pWin) != NULL)))
+    if ((pWin->redirectDraw != RedirectDrawNone) !=
+	(pWin->viewable && (GetCompWindow(pWin) != NULL)))
 	abort ();
 #endif
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	PixmapPtr   pPixmap = (*pScreen->GetWindowPixmap) (pWin);
 	int	    bw = wBorderWidth (pWin);
@@ -329,7 +330,7 @@ compMoveWindow (WindowPtr pWin, int x, i
     CompScreenPtr	cs = GetCompScreen (pScreen);
 
     compCheckTree (pScreen);
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	WindowPtr		pParent;
 	int			draw_x, draw_y;
@@ -353,7 +354,7 @@ compMoveWindow (WindowPtr pWin, int x, i
     cs->MoveWindow = pScreen->MoveWindow;
     pScreen->MoveWindow = compMoveWindow;
 
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	CompWindowPtr	cw = GetCompWindow (pWin);
 	if (cw->pOldPixmap)
@@ -374,7 +375,7 @@ compResizeWindow (WindowPtr pWin, int x,
     CompScreenPtr	cs = GetCompScreen (pScreen);
 
     compCheckTree (pScreen);
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	WindowPtr		pParent;
 	int			draw_x, draw_y;
@@ -395,7 +396,7 @@ compResizeWindow (WindowPtr pWin, int x,
     (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
     cs->ResizeWindow = pScreen->ResizeWindow;
     pScreen->ResizeWindow = compResizeWindow;
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	CompWindowPtr	cw = GetCompWindow (pWin);
 	if (cw->pOldPixmap)
@@ -414,7 +415,7 @@ compChangeBorderWidth (WindowPtr pWin, u
     CompScreenPtr	cs = GetCompScreen (pScreen);
 
     compCheckTree (pScreen);
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	WindowPtr		pParent;
 	int			draw_x, draw_y;
@@ -436,7 +437,7 @@ compChangeBorderWidth (WindowPtr pWin, u
     (*pScreen->ChangeBorderWidth) (pWin, bw);
     cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
     pScreen->ChangeBorderWidth = compChangeBorderWidth;
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	CompWindowPtr	cw = GetCompWindow (pWin);
 	if (cw->pOldPixmap)
@@ -480,7 +481,7 @@ compReparentWindow (WindowPtr pWin, Wind
     /*
      * Reset pixmap pointers as appropriate
      */
-    if (pWin->parent && !pWin->redirectDraw)
+    if (pWin->parent && pWin->redirectDraw != RedirectDrawNone)
 	compSetPixmap (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
     /*
      * Call down to next function
@@ -499,7 +500,7 @@ compCopyWindow (WindowPtr pWin, DDXPoint
     CompScreenPtr   cs = GetCompScreen (pScreen);
     int		    dx = 0, dy = 0;
 
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	PixmapPtr	pPixmap = (*pScreen->GetWindowPixmap) (pWin);
 	CompWindowPtr	cw = GetCompWindow (pWin);
@@ -624,7 +625,7 @@ compDestroyWindow (WindowPtr pWin)
     while ((csw = GetCompSubwindows (pWin)))
 	FreeResource (csw->clients->id, RT_NONE);
     
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
 	compFreePixmap (pWin);
     ret = (*pScreen->DestroyWindow) (pWin);
     cs->DestroyWindow = pScreen->DestroyWindow;
@@ -768,7 +769,7 @@ compWindowUpdate (WindowPtr pWin)
 
     for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
 	compWindowUpdate (pChild);
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	CompWindowPtr	cw = GetCompWindow(pWin);
 
diff --git a/configure.ac b/configure.ac
index 06473ef..5ee9ad7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -649,7 +649,7 @@ fi
 AM_CONDITIONAL(COMPOSITE, [test "x$COMPOSITE" = xyes])
 if test "x$COMPOSITE" = xyes; then
 	AC_DEFINE(COMPOSITE, 1, [Support Composite Extension])
-	REQUIRED_MODULES="$REQUIRED_MODULES [compositeproto >= 0.3]"
+	REQUIRED_MODULES="$REQUIRED_MODULES [compositeproto >= 0.4]"
 	COMPOSITE_LIB='$(top_builddir)/composite/libcomposite.la'
 	COMPOSITE_INC='-I$(top_srcdir)/composite'
 fi
diff --git a/dix/window.c b/dix/window.c
index 96002eb..be4ea2c 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -298,7 +298,7 @@ SetWindowToDefaults(WindowPtr pWin)
     pWin->dontPropagate = 0;
     pWin->forcedBS = FALSE;
 #ifdef COMPOSITE
-    pWin->redirectDraw = 0;
+    pWin->redirectDraw = RedirectDrawNone;
 #endif
 }
 
@@ -1687,10 +1687,14 @@ _X_EXPORT void
 SetWinSize (WindowPtr pWin)
 {
 #ifdef COMPOSITE
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	BoxRec	box;
 
+	/*
+	 * Redirected clients get clip list equal to their
+	 * own geometry, not clipped to their parent
+	 */
 	box.x1 = pWin->drawable.x;
 	box.y1 = pWin->drawable.y;
 	box.x2 = pWin->drawable.x + pWin->drawable.width;
@@ -1730,10 +1734,14 @@ SetBorderSize (WindowPtr pWin)
     if (HasBorder (pWin)) {
 	bw = wBorderWidth (pWin);
 #ifdef COMPOSITE
-	if (pWin->redirectDraw)
+	if (pWin->redirectDraw != RedirectDrawNone)
 	{
 	    BoxRec	box;
 
+	    /*
+	     * Redirected clients get clip list equal to their
+	     * own geometry, not clipped to their parent
+	     */
 	    box.x1 = pWin->drawable.x - bw;
 	    box.y1 = pWin->drawable.y - bw;
 	    box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
diff --git a/include/windowstr.h b/include/windowstr.h
index 9fd6d76..6d874ae 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -94,6 +94,33 @@ typedef struct _WindowOpt {
 #define BackgroundPixel	    2L
 #define BackgroundPixmap    3L
 
+/*
+ * The redirectDraw field can have one of three values:
+ *
+ *  RedirectDrawNone
+ *	A normal window; painted into the same pixmap as the parent
+ *	and clipping parent and siblings to its geometry. These
+ *	windows get a clip list equal to the intersection of their
+ *	geometry with the parent geometry, minus the geometry
+ *	of overlapping None and Clipped siblings.
+ *  RedirectDrawAutomatic
+ *	A redirected window which clips parent and sibling drawing.
+ *	Contents for these windows are manage inside the server.
+ *	These windows get an internal clip list equal to their
+ *	geometry.
+ *  RedirectDrawManual
+ *	A redirected window which does not clip parent and sibling
+ *	drawing; the window must be represented within the parent
+ *	geometry by the client performing the redirection management.
+ *	Contents for these windows are managed outside the server.
+ *	These windows get an internal clip list equal to their
+ *	geometry.
+ */
+
+#define RedirectDrawNone	0
+#define RedirectDrawAutomatic	1
+#define RedirectDrawManual	2
+
 typedef struct _Window {
     DrawableRec		drawable;
     WindowPtr		parent;		/* ancestor chain */
@@ -130,7 +157,7 @@ typedef struct _Window {
     unsigned		dontPropagate:3;/* index into DontPropagateMasks */
     unsigned		forcedBS:1;	/* system-supplied backingStore */
 #ifdef COMPOSITE
-    unsigned		redirectDraw:1;	/* rendering is redirected from here */
+    unsigned		redirectDraw:2;	/* rendering is redirected from here */
 #endif
     DevUnion		*devPrivates;
 } WindowRec;
diff --git a/mi/mivaltree.c b/mi/mivaltree.c
index 92ea0a8..c999267 100644
--- a/mi/mivaltree.c
+++ b/mi/mivaltree.c
@@ -179,6 +179,17 @@ miRegisterRedirectBorderClipProc (SetRed
     miGetRedirectBorderClipProc = getBorderClip;
 }
 
+/*
+ * Manual redirected windows are treated as transparent; they do not obscure
+ * siblings or parent windows
+ */
+
+#ifdef COMPOSITE
+#define TreatAsTransparent(w)	((w)->redirectDraw == RedirectDrawManual)
+#else
+#define TreatAsTransparent(w)	FALSE
+#endif
+
 #define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
 				    HasBorder(w) && \
 				    (w)->backgroundState == ParentRelative)
@@ -241,7 +252,7 @@ miComputeClips (
     /*
      * In redirected drawing case, reset universe to borderSize
      */
-    if (pParent->redirectDraw)
+    if (pParent->redirectDraw != RedirectDrawNone)
     {
 	if (miSetRedirectBorderClipProc)
 	    (*miSetRedirectBorderClipProc) (pParent, universe);
@@ -432,7 +443,7 @@ miComputeClips (
 	{
 	    for (; pChild; pChild = pChild->nextSib)
 	    {
-		if (pChild->viewable)
+		if (pChild->viewable && !TreatAsTransparent(pChild))
 		    REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
 	    }
 	}
@@ -440,7 +451,7 @@ miComputeClips (
 	{
 	    for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
 	    {
-		if (pChild->viewable)
+		if (pChild->viewable && !TreatAsTransparent(pChild))
 		    REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
 	    }
 	}
@@ -472,7 +483,7 @@ miComputeClips (
 		 * from the current universe, thus denying its space to any
 		 * other sibling.
 		 */
-		if (overlap)
+		if (overlap && !TreatAsTransparent (pChild))
 		    REGION_SUBTRACT( pScreen, universe, universe,
 					  &pChild->borderSize);
 	    }
@@ -644,7 +655,7 @@ miValidateTree (pParent, pChild, kind)
 	
 	for (pWin = pParent->firstChild; pWin != pChild; pWin = pWin->nextSib)
 	{
-	    if (pWin->viewable)
+	    if (pWin->viewable && !TreatAsTransparent (pWin))
 		REGION_SUBTRACT (pScreen, &totalClip, &totalClip, &pWin->borderSize);
 	}
 	for (pWin = pChild; pWin; pWin = pWin->nextSib)
@@ -666,7 +677,7 @@ miValidateTree (pParent, pChild, kind)
 		{
 		    RegionPtr	pBorderClip = &pWin->borderClip;
 #ifdef COMPOSITE
-		    if (pWin->redirectDraw && miGetRedirectBorderClipProc)
+		    if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc)
 			pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
 #endif
 		    REGION_APPEND( pScreen, &totalClip, pBorderClip );
@@ -685,7 +696,7 @@ miValidateTree (pParent, pChild, kind)
 		{
 		    RegionPtr	pBorderClip = &pWin->borderClip;
 #ifdef COMPOSITE
-		    if (pWin->redirectDraw && miGetRedirectBorderClipProc)
+		    if (pWin->redirectDraw != RedirectDrawNone && miGetRedirectBorderClipProc)
 			pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
 #endif
 		    REGION_APPEND( pScreen, &totalClip, pBorderClip );
@@ -724,7 +735,7 @@ miValidateTree (pParent, pChild, kind)
 	    if (forward)
 	    {
 		for (pWin = pChild; pWin; pWin = pWin->nextSib)
-		    if (pWin->valdata && pWin->viewable)
+		    if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin))
 			REGION_APPEND( pScreen, &childUnion,
 						   &pWin->borderSize);
 	    }
@@ -733,7 +744,7 @@ miValidateTree (pParent, pChild, kind)
 		pWin = pParent->lastChild;
 		while (1)
 		{
-		    if (pWin->valdata && pWin->viewable)
+		    if (pWin->valdata && pWin->viewable && !TreatAsTransparent (pWin))
 			REGION_APPEND( pScreen, &childUnion,
 						   &pWin->borderSize);
 		    if (pWin == pChild)
@@ -757,7 +768,7 @@ miValidateTree (pParent, pChild, kind)
 					&totalClip,
  					&pWin->borderSize);
 		miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
-		if (overlap)
+		if (overlap && !TreatAsTransparent (pWin))
 		{
 		    REGION_SUBTRACT( pScreen, &totalClip,
 				       	   &totalClip,


More information about the xorg-commit mailing list