aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/composite
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/composite')
-rw-r--r--xorg-server/composite/compalloc.c38
-rw-r--r--xorg-server/composite/compinit.c62
-rw-r--r--xorg-server/composite/compint.h5
-rw-r--r--xorg-server/composite/compwindow.c34
4 files changed, 101 insertions, 38 deletions
diff --git a/xorg-server/composite/compalloc.c b/xorg-server/composite/compalloc.c
index c69a9c05c..8853f7058 100644
--- a/xorg-server/composite/compalloc.c
+++ b/xorg-server/composite/compalloc.c
@@ -48,6 +48,30 @@
#include "compint.h"
static void
+compScreenUpdate (ScreenPtr pScreen)
+{
+ compCheckTree (pScreen);
+ compPaintChildrenToWindow (pScreen->root);
+}
+
+static void
+compBlockHandler (int i,
+ pointer blockData,
+ pointer pTimeout,
+ pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ CompScreenPtr cs = GetCompScreen (pScreen);
+
+ pScreen->BlockHandler = cs->BlockHandler;
+ compScreenUpdate (pScreen);
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+
+ /* Next damage will restore the block handler */
+ cs->BlockHandler = NULL;
+}
+
+static void
compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
{
WindowPtr pWin = (WindowPtr) closure;
@@ -55,8 +79,20 @@ compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
CompScreenPtr cs = GetCompScreen (pScreen);
CompWindowPtr cw = GetCompWindow (pWin);
- cs->damaged = TRUE;
+ if (!cs->BlockHandler) {
+ cs->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = compBlockHandler;
+ }
cw->damaged = TRUE;
+
+ /* Mark the ancestors */
+ pWin = pWin->parent;
+ while (pWin) {
+ if (pWin->damagedDescendants)
+ break;
+ pWin->damagedDescendants = TRUE;
+ pWin = pWin->parent;
+ }
}
static void
diff --git a/xorg-server/composite/compinit.c b/xorg-server/composite/compinit.c
index 98b8d0565..291b759be 100644
--- a/xorg-server/composite/compinit.c
+++ b/xorg-server/composite/compinit.c
@@ -61,7 +61,6 @@ compCloseScreen (int index, ScreenPtr pScreen)
free(cs->alternateVisuals);
pScreen->CloseScreen = cs->CloseScreen;
- pScreen->BlockHandler = cs->BlockHandler;
pScreen->InstallColormap = cs->InstallColormap;
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
pScreen->ReparentWindow = cs->ReparentWindow;
@@ -78,6 +77,9 @@ compCloseScreen (int index, ScreenPtr pScreen)
pScreen->CopyWindow = cs->CopyWindow;
pScreen->PositionWindow = cs->PositionWindow;
+ pScreen->GetImage = cs->GetImage;
+ pScreen->SourceValidate = cs->SourceValidate;
+
free(cs);
dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL);
ret = (*pScreen->CloseScreen) (index, pScreen);
@@ -131,32 +133,40 @@ compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
}
static void
-compScreenUpdate (ScreenPtr pScreen)
+compGetImage (DrawablePtr pDrawable,
+ int sx, int sy,
+ int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine)
{
- CompScreenPtr cs = GetCompScreen (pScreen);
+ ScreenPtr pScreen = pDrawable->pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
- compCheckTree (pScreen);
- if (cs->damaged)
- {
- compWindowUpdate (pScreen->root);
- cs->damaged = FALSE;
- }
+ pScreen->GetImage = cs->GetImage;
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ compPaintChildrenToWindow ((WindowPtr) pDrawable);
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine);
+ cs->GetImage = pScreen->GetImage;
+ pScreen->GetImage = compGetImage;
}
-static void
-compBlockHandler (int i,
- pointer blockData,
- pointer pTimeout,
- pointer pReadmask)
+static void compSourceValidate(DrawablePtr pDrawable,
+ int x, int y,
+ int width, int height,
+ unsigned int subWindowMode)
{
- ScreenPtr pScreen = screenInfo.screens[i];
- CompScreenPtr cs = GetCompScreen (pScreen);
+ ScreenPtr pScreen = pDrawable->pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
- pScreen->BlockHandler = cs->BlockHandler;
- compScreenUpdate (pScreen);
- (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
- cs->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = compBlockHandler;
+ pScreen->SourceValidate = cs->SourceValidate;
+ if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors)
+ compPaintChildrenToWindow ((WindowPtr) pDrawable);
+ if (pScreen->SourceValidate)
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height,
+ subWindowMode);
+ cs->SourceValidate = pScreen->SourceValidate;
+ pScreen->SourceValidate = compSourceValidate;
}
/*
@@ -331,7 +341,6 @@ compScreenInit (ScreenPtr pScreen)
if (!cs)
return FALSE;
- cs->damaged = FALSE;
cs->overlayWid = FakeClientID(0);
cs->pOverlayWin = NULL;
cs->pOverlayClients = NULL;
@@ -387,12 +396,17 @@ compScreenInit (ScreenPtr pScreen)
cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
- cs->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = compBlockHandler;
+ cs->BlockHandler = NULL;
cs->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = compCloseScreen;
+ cs->GetImage = pScreen->GetImage;
+ pScreen->GetImage = compGetImage;
+
+ cs->SourceValidate = pScreen->SourceValidate;
+ pScreen->SourceValidate = compSourceValidate;
+
dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs);
RegisterRealChildHeadProc(CompositeRealChildHead);
diff --git a/xorg-server/composite/compint.h b/xorg-server/composite/compint.h
index a85d62faa..55cd6459e 100644
--- a/xorg-server/composite/compint.h
+++ b/xorg-server/composite/compint.h
@@ -152,7 +152,6 @@ typedef struct _CompScreen {
ScreenBlockHandlerProcPtr BlockHandler;
CloseScreenProcPtr CloseScreen;
- Bool damaged;
int numAlternateVisuals;
VisualID *alternateVisuals;
@@ -160,6 +159,8 @@ typedef struct _CompScreen {
Window overlayWid;
CompOverlayClientPtr pOverlayClients;
+ GetImageProcPtr GetImage;
+ SourceValidateProcPtr SourceValidate;
} CompScreenRec, *CompScreenPtr;
extern DevPrivateKeyRec CompScreenPrivateKeyRec;
@@ -314,7 +315,7 @@ void
compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
void
-compWindowUpdate (WindowPtr pWin);
+compPaintChildrenToWindow (WindowPtr pWin);
WindowPtr
CompositeRealChildHead (WindowPtr pWin);
diff --git a/xorg-server/composite/compwindow.c b/xorg-server/composite/compwindow.c
index 11df8b39d..ef1f7f154 100644
--- a/xorg-server/composite/compwindow.c
+++ b/xorg-server/composite/compwindow.c
@@ -653,9 +653,10 @@ compWindowFormat (WindowPtr pWin)
}
static void
-compWindowUpdateAutomatic (WindowPtr pWin, ScreenPtr pScreen)
+compWindowUpdateAutomatic (WindowPtr pWin)
{
CompWindowPtr cw = GetCompWindow (pWin);
+ ScreenPtr pScreen = pWin->drawable.pScreen;
WindowPtr pParent = pWin->parent;
PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
PictFormatPtr pSrcFormat = compWindowFormat (pWin);
@@ -678,7 +679,8 @@ compWindowUpdateAutomatic (WindowPtr pWin, ScreenPtr pScreen)
/*
* First move the region from window to screen coordinates
*/
- RegionTranslate(pRegion, pWin->drawable.x, pWin->drawable.y);
+ RegionTranslate(pRegion,
+ pWin->drawable.x, pWin->drawable.y);
/*
* Clip against the "real" border clip
@@ -688,7 +690,8 @@ compWindowUpdateAutomatic (WindowPtr pWin, ScreenPtr pScreen)
/*
* Now translate from screen to dest coordinates
*/
- RegionTranslate(pRegion, -pParent->drawable.x, -pParent->drawable.y);
+ RegionTranslate(pRegion,
+ -pParent->drawable.x, -pParent->drawable.y);
/*
* Clip the picture
@@ -717,26 +720,35 @@ compWindowUpdateAutomatic (WindowPtr pWin, ScreenPtr pScreen)
DamageEmpty (cw->damage);
}
-static int
-compWindowUpdateVisit(WindowPtr pWin, void *data)
+static void
+compPaintWindowToParent (WindowPtr pWin)
{
+ compPaintChildrenToWindow (pWin);
+
if (pWin->redirectDraw != RedirectDrawNone)
{
- CompWindowPtr cw = GetCompWindow(pWin);
+ CompWindowPtr cw = GetCompWindow(pWin);
+
if (cw->damaged)
{
- compWindowUpdateAutomatic(pWin, data);
+ compWindowUpdateAutomatic (pWin);
cw->damaged = FALSE;
}
}
-
- return WT_WALKCHILDREN;
}
void
-compWindowUpdate (WindowPtr pWin)
+compPaintChildrenToWindow (WindowPtr pWin)
{
- TraverseTree(pWin, compWindowUpdateVisit, pWin->drawable.pScreen);
+ WindowPtr pChild;
+
+ if (!pWin->damagedDescendants)
+ return;
+
+ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+ compPaintWindowToParent (pChild);
+
+ pWin->damagedDescendants = FALSE;
}
WindowPtr