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