summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--composite/compalloc.c14
-rw-r--r--composite/compwindow.c33
-rw-r--r--configure.ac2
-rw-r--r--dix/window.c14
-rw-r--r--include/windowstr.h29
-rw-r--r--mi/mivaltree.c31
6 files changed, 87 insertions, 36 deletions
diff --git a/composite/compalloc.c b/composite/compalloc.c
index 5ea015b76..1a7e4a0da 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -204,7 +204,7 @@ compFreeClientWindow (WindowPtr pWin, XID id)
EnableMapUnmapEvents (pWin);
}
- if (pWin->redirectDraw)
+ if (pWin->redirectDraw != RedirectDrawNone)
compFreePixmap (pWin);
if (cw->damage)
@@ -216,7 +216,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;
@@ -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 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 9114fff26..6633163b5 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -57,10 +57,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);
@@ -111,7 +111,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);
/*
@@ -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 x, int y)
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, 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;
@@ -353,7 +354,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)
@@ -374,7 +375,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;
@@ -395,7 +396,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)
@@ -414,7 +415,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;
@@ -436,7 +437,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)
@@ -480,7 +481,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
@@ -499,7 +500,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);
@@ -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 06473ef05..5ee9ad75d 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 96002eb1f..be4ea2c97 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 9fd6d768c..6d874ae9e 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 92ea0a8a9..c999267e5 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,