diff options
author | Pierre Ossman <ossman@cendio.se> | 2016-01-11 16:06:26 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2016-01-11 16:06:26 +0100 |
commit | 9986dce0ae20b0821a5e189f58e86a764079048b (patch) | |
tree | 44d8c877b47b2d9e0dd928fb99a83178964b68ec /unix/xserver/hw | |
parent | 35449991b52f1d88cc7ca72d171a184eade04167 (diff) | |
download | tigervnc-9986dce0ae20b0821a5e189f58e86a764079048b.tar.gz tigervnc-9986dce0ae20b0821a5e189f58e86a764079048b.zip |
Better check for on screen visibility
The check for visible drawables didn't account for compositing
which can place a window off-screen. Put all of these checks in
a common place and make sure it detects things properly.
Diffstat (limited to 'unix/xserver/hw')
-rw-r--r-- | unix/xserver/hw/vnc/vncHooks.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/unix/xserver/hw/vnc/vncHooks.c b/unix/xserver/hw/vnc/vncHooks.c index 886c6466..b21f4c67 100644 --- a/unix/xserver/hw/vnc/vncHooks.c +++ b/unix/xserver/hw/vnc/vncHooks.c @@ -372,7 +372,7 @@ void vncGetScreenImage(int scrIdx, int x, int y, int width, int height, ///////////////////////////////////////////////////////////////////////////// // -// Helper functions for adding changes and copies +// Helper functions // static inline void add_changed(ScreenPtr pScreen, RegionPtr reg) @@ -398,6 +398,33 @@ static inline void add_copied(ScreenPtr pScreen, RegionPtr dst, (const struct UpdateRect*)REGION_RECTS(dst), dx, dy); } +static inline Bool is_visible(DrawablePtr drawable) +{ + PixmapPtr scrPixmap; + + scrPixmap = drawable->pScreen->GetScreenPixmap(drawable->pScreen); + + if (drawable->type == DRAWABLE_WINDOW) { + WindowPtr window; + PixmapPtr winPixmap; + + window = (WindowPtr)drawable; + winPixmap = drawable->pScreen->GetWindowPixmap(window); + + if (!window->viewable) + return FALSE; + + if (winPixmap != scrPixmap) + return FALSE; + + return TRUE; + } + + if (drawable != &scrPixmap->drawable) + return FALSE; + + return TRUE; +} ///////////////////////////////////////////////////////////////////////////// // @@ -727,8 +754,7 @@ static void vncHooksComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, RegionRec changed; - if (pDst->pDrawable->type == DRAWABLE_WINDOW && - ((WindowPtr) pDst->pDrawable)->viewable) { + if (is_visible(pDst->pDrawable)) { BoxRec box; RegionRec fbreg; @@ -823,8 +849,7 @@ static void vncHooksGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, RegionPtr changed; - if (pDst->pDrawable->type == DRAWABLE_WINDOW && - ((WindowPtr) pDst->pDrawable)->viewable) { + if (is_visible(pDst->pDrawable)) { BoxRec fbbox; RegionRec fbreg; @@ -950,16 +975,14 @@ static Bool vncHooksRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, (pGC)->ops = &vncHooksGCOps;\ } -// ValidateGC - wrap the "ops" if a viewable window OR the screen pixmap +// ValidateGC - wrap the "ops" if the drawable is on screen static void vncHooksValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) { GC_FUNC_PROLOGUE(pGC, ValidateGC); (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); - if ((pDrawable->type == DRAWABLE_WINDOW && - ((WindowPtr) pDrawable)->viewable) || - (pDrawable == &pGC->pScreen->GetScreenPixmap(pGC->pScreen)->drawable)) { + if (is_visible(pDrawable)) { pGCPriv->wrappedOps = pGC->ops; DBGPRINT((stderr,"vncHooksValidateGC: wrapped GC ops\n")); } else { @@ -1134,10 +1157,7 @@ static RegionPtr vncHooksCopyArea(DrawablePtr pSrc, DrawablePtr pDst, REGION_INTERSECT(pGC->pScreen, &dst, &dst, pGC->pCompositeClip); // The source of the data has to be something that's on screen. - // This means either a window, or the screen pixmap. - if ((pSrc->pScreen == pGC->pScreen) && - ((pSrc->type == DRAWABLE_WINDOW) || - (pSrc == &pGC->pScreen->GetScreenPixmap(pGC->pScreen)->drawable))) { + if (is_visible(pSrc)) { BoxRec box; box.x1 = srcx + pSrc->x; |