aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/composite/compalloc.c
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2016-05-31 12:09:23 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2016-05-31 12:09:23 +0200
commit4a9c1b9465f189a1477b1ecce7cdfacfd266cd65 (patch)
tree4688606f66a7e3a79944bd23299dddda06c2a219 /nx-X11/programs/Xserver/composite/compalloc.c
parentaba2a534f630f5b65a53e0ea7cdba17b77263f87 (diff)
parentcad9f4ef87ddf4e2865783ce7ea7e772d7b196b7 (diff)
downloadnx-libs-4a9c1b9465f189a1477b1ecce7cdfacfd266cd65.tar.gz
nx-libs-4a9c1b9465f189a1477b1ecce7cdfacfd266cd65.tar.bz2
nx-libs-4a9c1b9465f189a1477b1ecce7cdfacfd266cd65.zip
Merge branch 'Ionic-feature/composite-update' into 3.6.x
Diffstat (limited to 'nx-X11/programs/Xserver/composite/compalloc.c')
-rw-r--r--nx-X11/programs/Xserver/composite/compalloc.c295
1 files changed, 226 insertions, 69 deletions
diff --git a/nx-X11/programs/Xserver/composite/compalloc.c b/nx-X11/programs/Xserver/composite/compalloc.c
index f66a90989..9279a5248 100644
--- a/nx-X11/programs/Xserver/composite/compalloc.c
+++ b/nx-X11/programs/Xserver/composite/compalloc.c
@@ -28,36 +28,110 @@
#include "compint.h"
-void
-compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
+static void
+compScreenUpdate(ScreenPtr pScreen)
{
- WindowPtr pWin = (WindowPtr) closure;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- CompScreenPtr cs = GetCompScreen (pScreen);
- CompWindowPtr cw = GetCompWindow (pWin);
+ compCheckTree(pScreen);
+ compPaintChildrenToWindow(pScreen, WindowTable[pScreen->myNum]);
+}
+
+static void
+compBlockHandler(int i, void *blockData, void *pTimeout, void *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;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompWindowPtr cw = GetCompWindow(pWin);
+
+ if (!cs->BlockHandler) {
+ cs->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = compBlockHandler;
+ }
cs->damaged = TRUE;
cw->damaged = TRUE;
+
+ /* Mark the ancestors */
+ /* We can't do this, Dave. No damagedDescendants support. */
+ /*
+ pWin = pWin->parent;
+ while (pWin) {
+ if (pWin->damagedDescendants)
+ break;
+ pWin->damagedDescendants = TRUE;
+ pWin = pWin->parent;
+ }
+ */
}
static void
-compDestroyDamage (DamagePtr pDamage, void *closure)
+compDestroyDamage(DamagePtr pDamage, void *closure)
{
- WindowPtr pWin = (WindowPtr) closure;
- CompWindowPtr cw = GetCompWindow (pWin);
+ WindowPtr pWin = (WindowPtr) closure;
+ CompWindowPtr cw = GetCompWindow(pWin);
cw->damage = 0;
}
+static Bool
+compMarkWindows(WindowPtr pWin, WindowPtr *ppLayerWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pLayerWin = pWin;
+
+ if (!pWin->viewable)
+ return FALSE;
+
+ (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
+ (*pScreen->MarkWindow) (pLayerWin->parent);
+
+ *ppLayerWin = pLayerWin;
+
+ return TRUE;
+}
+
+static void
+compHandleMarkedWindows(WindowPtr pWin, WindowPtr pLayerWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ (*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
+ (*pScreen->HandleExposures) (pLayerWin->parent);
+ if (pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
+}
+
/*
* Redirect one window for one client
*/
int
-compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
+compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update)
{
- CompWindowPtr cw = GetCompWindow (pWin);
- CompClientWindowPtr ccw;
- Bool wasMapped = pWin->mapped;
+ CompWindowPtr cw = GetCompWindow(pWin);
+ CompClientWindowPtr ccw;
+ CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
+ WindowPtr pLayerWin;
+ Bool anyMarked = FALSE;
+
+ if (pWin == cs->pOverlayWin) {
+ return Success;
+ }
+
+ if (!pWin->parent)
+ return BadMatch;
/*
* Only one Manual update is allowed
@@ -100,8 +174,8 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
xfree (cw);
return BadAlloc;
}
- if (wasMapped)
- UnmapWindow (pWin, FALSE);
+
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
RegionNull(&cw->borderClip);
cw->update = CompositeRedirectAutomatic;
@@ -110,7 +184,8 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
cw->oldy = COMP_ORIGIN_INVALID;
cw->damageRegistered = FALSE;
cw->damaged = FALSE;
- pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
+ cw->pOldPixmap = NullPixmap;
+ FAKE_DIX_SET_WINDOW_PRIVATE(pWin, cw);
}
ccw->next = cw->clients;
cw->clients = ccw;
@@ -118,30 +193,59 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
return BadAlloc;
if (ccw->update == CompositeRedirectManual)
{
- if (cw->damageRegistered)
- {
+ if (!anyMarked)
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+
+ if (cw->damageRegistered) {
DamageUnregister (&pWin->drawable, cw->damage);
cw->damageRegistered = FALSE;
}
cw->update = CompositeRedirectManual;
}
+ else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) {
+ if (!anyMarked)
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+ }
if (!compCheckRedirect (pWin))
{
FreeResource (ccw->id, RT_NONE);
return BadAlloc;
}
- if (wasMapped && !pWin->mapped)
- {
- Bool overrideRedirect = pWin->overrideRedirect;
- pWin->overrideRedirect = TRUE;
- MapWindow (pWin, pClient);
- pWin->overrideRedirect = overrideRedirect;
- }
+
+ if (anyMarked)
+ compHandleMarkedWindows(pWin, pLayerWin);
return Success;
}
+void
+compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pParent = pWin->parent;
+
+ if (pParent->drawable.depth == pWin->drawable.depth) {
+ GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen);
+ int bw = (int) pWin->borderWidth;
+ int x = bw;
+ int y = bw;
+ int w = pWin->drawable.width;
+ int h = pWin->drawable.height;
+
+ if (pGC) {
+ ChangeGCVal val;
+
+ val.val = IncludeInferiors;
+ dixChangeGC(NullClient, pGC, GCSubwindowMode, NULL, &val);
+ ValidateGC(&pWin->drawable, pGC);
+ (*pGC->ops->CopyArea) (&pPixmap->drawable,
+ &pWin->drawable, pGC, x, y, w, h, 0, 0);
+ FreeScratchGC(pGC);
+ }
+ }
+}
+
/*
* Free one of the per-client per-window resources, clearing
* redirect and the per-window pointer as appropriate
@@ -149,9 +253,12 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
void
compFreeClientWindow (WindowPtr pWin, XID id)
{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
CompWindowPtr cw = GetCompWindow (pWin);
CompClientWindowPtr ccw, *prev;
- Bool wasMapped = pWin->mapped;
+ Bool anyMarked = FALSE;
+ WindowPtr pLayerWin;
+ PixmapPtr pPixmap = NULL;
if (!cw)
return;
@@ -168,33 +275,38 @@ compFreeClientWindow (WindowPtr pWin, XID id)
}
if (!cw->clients)
{
- if (wasMapped)
- UnmapWindow (pWin, FALSE);
-
- if (pWin->redirectDraw)
- compFreePixmap (pWin);
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+
+ if (pWin->redirectDraw != RedirectDrawNone) {
+ pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ compSetParentPixmap(pWin);
+ }
if (cw->damage)
DamageDestroy (cw->damage);
RegionUninit(&cw->borderClip);
- pWin->devPrivates[CompWindowPrivateIndex].ptr = 0;
+ FAKE_DIX_SET_WINDOW_PRIVATE(pWin, NULL);
xfree (cw);
}
else if (cw->update == CompositeRedirectAutomatic &&
- !cw->damageRegistered && pWin->redirectDraw)
+ !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
{
+ anyMarked = compMarkWindows(pWin, &pLayerWin);
+
DamageRegister (&pWin->drawable, cw->damage);
cw->damageRegistered = TRUE;
+ pWin->redirectDraw = RedirectDrawAutomatic;
DamageDamageRegion (&pWin->drawable, &pWin->borderSize);
}
- if (wasMapped && !pWin->mapped)
- {
- Bool overrideRedirect = pWin->overrideRedirect;
- pWin->overrideRedirect = TRUE;
- MapWindow (pWin, clients[CLIENT_ID(id)]);
- pWin->overrideRedirect = overrideRedirect;
+
+ if (anyMarked)
+ compHandleMarkedWindows(pWin, pLayerWin);
+
+ if (pPixmap) {
+ compRestoreWindow(pWin, pPixmap);
+ (*pScreen->DestroyPixmap) (pPixmap);
}
}
@@ -261,7 +373,7 @@ compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
}
csw->update = CompositeRedirectAutomatic;
csw->clients = 0;
- pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = csw;
+ FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, csw);
}
/*
* Redirect all existing windows
@@ -276,7 +388,7 @@ compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
if (!csw->clients)
{
xfree (csw);
- pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
+ FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, NULL);
}
xfree (ccw);
return ret;
@@ -349,7 +461,7 @@ compFreeClientSubwindows (WindowPtr pWin, XID id)
*/
if (!csw->clients)
{
- pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
+ FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, NULL);
xfree (csw);
}
}
@@ -425,9 +537,10 @@ compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
ScreenPtr pScreen = pWin->drawable.pScreen;
WindowPtr pParent = pWin->parent;
PixmapPtr pPixmap;
- GCPtr pGC;
- pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth);
+ /* usage_hint unsupported by our old server infrastructure. */
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth /*,
+ CREATE_PIXMAP_USAGE_BACKING_PIXMAP */);
if (!pPixmap)
return 0;
@@ -435,25 +548,60 @@ compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
pPixmap->screen_x = x;
pPixmap->screen_y = y;
- pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+ if (pParent->drawable.depth == pWin->drawable.depth) {
+ GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
- /*
- * Copy bits from the parent into the new pixmap so that it will
- * have "reasonable" contents in case for background None areas.
- */
- if (pGC)
- {
- XID val = IncludeInferiors;
-
- ValidateGC(&pPixmap->drawable, pGC);
- dixChangeGC (serverClient, pGC, GCSubwindowMode, &val, NULL);
- (*pGC->ops->CopyArea) (&pParent->drawable,
- &pPixmap->drawable,
- pGC,
- x - pParent->drawable.x,
- y - pParent->drawable.y,
- w, h, 0, 0);
- FreeScratchGC (pGC);
+ /*
+ * Copy bits from the parent into the new pixmap so that it will
+ * have "reasonable" contents in case for background None areas.
+ */
+ if (pGC)
+ {
+ ChangeGCVal val;
+
+ val.val = IncludeInferiors;
+ dixChangeGC(NullClient, pGC, GCSubwindowMode, NULL, &val);
+ ValidateGC(&pPixmap->drawable, pGC);
+ (*pGC->ops->CopyArea) (&pParent->drawable,
+ &pPixmap->drawable,
+ pGC,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y,
+ w, h, 0, 0);
+ FreeScratchGC (pGC);
+ }
+ }
+ else {
+ PictFormatPtr pSrcFormat = compWindowFormat (pParent);
+ PictFormatPtr pDstFormat = compWindowFormat (pWin);
+ XID inferiors = IncludeInferiors;
+ int error;
+
+ PicturePtr pSrcPicture = CreatePicture(None,
+ &pParent->drawable,
+ pSrcFormat,
+ CPSubwindowMode,
+ &inferiors,
+ serverClient, &error);
+
+ PicturePtr pDstPicture = CreatePicture(None,
+ &pPixmap->drawable,
+ pDstFormat,
+ 0, 0,
+ serverClient, &error);
+
+ if (pSrcPicture && pDstPicture) {
+ CompositePicture(PictOpSrc,
+ pSrcPicture,
+ NULL,
+ pDstPicture,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y, 0, 0, 0, 0, w, h);
+ }
+ if (pSrcPicture)
+ FreePicture(pSrcPicture, 0);
+ if (pDstPicture)
+ FreePicture(pDstPicture, 0);
}
return pPixmap;
}
@@ -471,7 +619,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;
@@ -481,14 +633,21 @@ compAllocPixmap (WindowPtr pWin)
DamageRegister (&pWin->drawable, cw->damage);
cw->damageRegistered = TRUE;
}
+
+ /* Make sure our borderClip is up to date */
+ RegionUninit(&cw->borderClip);
+ RegionCopy(&cw->borderClip, &pWin->borderClip);
+ cw->borderClipX = pWin->drawable.x;
+ cw->borderClipY = pWin->drawable.y;
+
return TRUE;
}
void
-compFreePixmap (WindowPtr pWin)
+compSetParentPixmap (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
- PixmapPtr pRedirectPixmap, pParentPixmap;
+ PixmapPtr pParentPixmap;
CompWindowPtr cw = GetCompWindow (pWin);
if (cw->damageRegistered)
@@ -504,11 +663,9 @@ compFreePixmap (WindowPtr pWin)
* parent exposed area; regions beyond the parent cause crashes
*/
RegionCopy(&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);
}
/*
@@ -527,7 +684,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;