diff options
-rw-r--r-- | composite/compalloc.c | 14 | ||||
-rw-r--r-- | composite/compwindow.c | 33 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | dix/window.c | 14 | ||||
-rw-r--r-- | include/windowstr.h | 29 | ||||
-rw-r--r-- | mi/mivaltree.c | 31 |
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, |