Inline patch for unclipped manual redirect changes in Composite

Keith Packard keithp at keithp.com
Tue Mar 20 12:15:48 PDT 2007


Our fine mail archiving software throws away attachments, so here's an
inline version of the patch. Again, this patch changes the semantics of
manual-redirect Composite windows so that they do not clip sibling or
parent drawing. This allows parents to draw composited windows without
using IncludeInferiors mode, as well as having Expose events delivered
to the parent in regions covered by manual redirect composited children.

# On branch server-1.3-branch
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   composite/compalloc.c
#	modified:   composite/compwindow.c
#	modified:   dix/window.c
#	modified:   include/windowstr.h
#	modified:   mi/mivaltree.c
#
diff --git a/composite/compalloc.c b/composite/compalloc.c
index 5bbf0a2..75dea02 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -206,7 +206,7 @@ compFreeClientWindow (WindowPtr pWin, XID id)
 	    EnableMapUnmapEvents (pWin);
 	}
     
-	if (pWin->redirectDraw)
+	if (pWin->redirectDraw != RedirectDrawNone)
 	    compFreePixmap (pWin);
 
 	if (cw->damage)
@@ -218,7 +218,7 @@ compFreeClientWindow (WindowPtr pWin, XID id)
 	xfree (cw);
     }
     else if (cw->update == CompositeRedirectAutomatic &&
-	     !cw->damageRegistered && pWin->redirectDraw)
+	     !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
     {
 	DamageRegister (&pWin->drawable, cw->damage);
 	cw->damageRegistered = TRUE;
@@ -508,7 +508,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;
@@ -543,7 +547,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);
 }
@@ -564,7 +568,7 @@ compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
     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 2c86cdd..b98c43c 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -59,10 +59,10 @@ compCheckWindow (WindowPtr pWin, pointer data)
     
     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);
@@ -113,7 +113,7 @@ compSetPixmapVisitWindow (WindowPtr pWindow, pointer data)
     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);
     /*
@@ -157,7 +157,7 @@ compCheckRedirect (WindowPtr pWin)
 	}
     }	
     
-    if (should != pWin->redirectDraw)
+    if (should != (pWin->redirectDraw != RedirectDrawNone))
     {
 	if (should)
 	    return compAllocPixmap (pWin);
@@ -181,10 +181,11 @@ compPositionWindow (WindowPtr pWin, int x, int y)
     compCheckRedirect (pWin);
      */
 #ifdef COMPOSITE_DEBUG
-    if (pWin->redirectDraw != (pWin->viewable && (GetCompWindow(pWin) != NULL)))
+    if ((pWin->redirectDraw != CompRedirectNone) !=
+	(pWin->viewable && (GetCompWindow(pWin) != NULL)))
 	abort ();
 #endif
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != CompRedirectNone)
     {
 	PixmapPtr   pPixmap = (*pScreen->GetWindowPixmap) (pWin);
 	int	    bw = wBorderWidth (pWin);
@@ -331,7 +332,7 @@ compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
     CompScreenPtr	cs = GetCompScreen (pScreen);
 
     compCheckTree (pScreen);
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	WindowPtr		pParent;
 	int			draw_x, draw_y;
@@ -355,7 +356,7 @@ compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
     cs->MoveWindow = pScreen->MoveWindow;
     pScreen->MoveWindow = compMoveWindow;
 
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	CompWindowPtr	cw = GetCompWindow (pWin);
 	if (cw->pOldPixmap)
@@ -376,7 +377,7 @@ compResizeWindow (WindowPtr pWin, int x, int y,
     CompScreenPtr	cs = GetCompScreen (pScreen);
 
     compCheckTree (pScreen);
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	WindowPtr		pParent;
 	int			draw_x, draw_y;
@@ -397,7 +398,7 @@ compResizeWindow (WindowPtr pWin, int x, int y,
     (*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)
@@ -416,7 +417,7 @@ compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
     CompScreenPtr	cs = GetCompScreen (pScreen);
 
     compCheckTree (pScreen);
-    if (pWin->redirectDraw)
+    if (pWin->redirectDraw != RedirectDrawNone)
     {
 	WindowPtr		pParent;
 	int			draw_x, draw_y;
@@ -438,7 +439,7 @@ compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
     (*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)
@@ -482,7 +483,7 @@ compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
     /*
      * 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
@@ -501,7 +502,7 @@ compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
     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);
@@ -626,7 +627,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;
@@ -770,7 +771,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/dix/window.c b/dix/window.c
index 3dfeda3..6ee6cd9 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -303,7 +303,7 @@ SetWindowToDefaults(register WindowPtr pWin)
     pWin->dstBuffer = DBE_FRONT_BUFFER;
 #endif
 #ifdef COMPOSITE
-    pWin->redirectDraw = 0;
+    pWin->redirectDraw = RedirectDrawNone;
 #endif
 }
 
@@ -1681,10 +1681,14 @@ _X_EXPORT void
 SetWinSize (register 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;
@@ -1723,10 +1727,14 @@ SetBorderSize (register 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 a37dc6b..16fe12e 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 */
@@ -136,7 +163,7 @@ typedef struct _Window {
     unsigned		srcBuffer:1;	/* source buffer for rendering */
 #endif
 #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 0e5ed61..8801498 100644
--- a/mi/mivaltree.c
+++ b/mi/mivaltree.c
@@ -179,6 +179,17 @@ miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
     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,

-- 
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.x.org/archives/xorg/attachments/20070320/5f4943bc/attachment.pgp>


More information about the xorg mailing list