From f98dfec79dadb70fa7bba84e7335f92b3a73dc02 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 1 Sep 2007 21:14:22 -0700 Subject: [PATCH] [COMPOSITE] Composite used for pixmap population on redirect. (Bug #7447) compNewPixmap copies bits from the parent window to the redirected child pixmap to populate the pixmap with reasonable data. It cannot always use CopyArea as that only works across matching depths. Use Composite when the depths do not match. --- composite/compalloc.c | 73 +++++++++++++++++++++++++++++++----------- composite/compint.h | 3 ++ composite/compwindow.c | 2 +- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/composite/compalloc.c b/composite/compalloc.c index f555411bf..006e80840 100644 --- a/composite/compalloc.c +++ b/composite/compalloc.c @@ -461,7 +461,6 @@ 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); @@ -471,25 +470,63 @@ 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); - - /* - * Copy bits from the parent into the new pixmap so that it will - * have "reasonable" contents in case for background None areas. - */ - if (pGC) + if (pParent->drawable.depth == pWin->drawable.depth) { - XID val = IncludeInferiors; + GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen); - 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) + { + 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); + } + } + 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; } diff --git a/composite/compint.h b/composite/compint.h index 38b1777a2..f69595ccc 100644 --- a/composite/compint.h +++ b/composite/compint.h @@ -237,6 +237,9 @@ compCheckTree (ScreenPtr pScreen); #define compCheckTree(s) #endif +PictFormatPtr +compWindowFormat (WindowPtr pWin); + void compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap); diff --git a/composite/compwindow.c b/composite/compwindow.c index a4c4e6f32..bfd29460b 100644 --- a/composite/compwindow.c +++ b/composite/compwindow.c @@ -685,7 +685,7 @@ compGetWindowVisual (WindowPtr pWin) return 0; } -static PictFormatPtr +PictFormatPtr compWindowFormat (WindowPtr pWin) { ScreenPtr pScreen = pWin->drawable.pScreen;