diff options
Diffstat (limited to 'nx-X11/programs/Xserver/composite/compalloc.c')
-rw-r--r-- | nx-X11/programs/Xserver/composite/compalloc.c | 295 |
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; |