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