[gtk+/client-side-windows: 245/284] Workaround X11 clipping bug



commit c72e93de16f664e07460723f74f33d306f753bd7
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Feb 4 16:23:15 2009 +0100

    Workaround X11 clipping bug
    
    It turns out that XCopyArea handling of obscured source regions is
    buggy. It clears the destination area even outside the GC clip
    region. We work around this for the pixmap->window case as that
    can happen in gtk+ and is easy to work around.
    
    X Bug report at:
    http://lists.freedesktop.org/archives/xorg/2009-February/043318.html
---
 gdk/x11/gdkdrawable-x11.c |   43 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c
index 2e53041..e6ea4f1 100644
--- a/gdk/x11/gdkdrawable-x11.c
+++ b/gdk/x11/gdkdrawable-x11.c
@@ -634,13 +634,50 @@ gdk_x11_draw_drawable (GdkDrawable *drawable,
 
   if (GDK_IS_DRAWABLE_IMPL_X11 (src))
     src_impl = GDK_DRAWABLE_IMPL_X11 (src);
+  else if (GDK_IS_WINDOW (src))
+    src_impl = GDK_DRAWABLE_IMPL_X11(((GdkWindowObject *)src)->impl);
   else
-    src_impl = NULL;
+    src_impl = GDK_DRAWABLE_IMPL_X11(((GdkPixmapObject *)src)->impl);
+
+  if (GDK_IS_WINDOW_IMPL_X11 (impl) &&
+      GDK_IS_PIXMAP_IMPL_X11 (src_impl))
+    {
+      GdkPixmapImplX11 *src_pixmap = GDK_PIXMAP_IMPL_X11 (src_impl);
+      /* Work around an Xserver bug where non-visible areas from
+       * a pixmap to a window will clear the window background
+       * in destination areas that are supposed to be clipped out.
+       * This is a problem with client side windows as this means
+       * things may draw outside the virtual windows. This could
+       * also happen for window to window copies, but I don't
+       * think we generate any calls like that.
+       *
+       * See: 
+       * http://lists.freedesktop.org/archives/xorg/2009-February/043318.html
+       */
+      if (xsrc < 0)
+	{
+	  width += xsrc;
+	  xdest -= xsrc;
+	  xsrc = 0;
+	}
+      
+      if (ysrc < 0)
+	{
+	  height += ysrc;
+	  ydest -= ysrc;
+	  ysrc = 0;
+	}
+
+      if (xsrc + width > src_pixmap->width)
+	width = src_pixmap->width - xsrc;
+      if (ysrc + height > src_pixmap->height)
+	height = src_pixmap->height - ysrc;
+    }
   
   if (src_depth == 1)
     {
       XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen),
-                 src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src),
+                 src_impl->xid,
 		 impl->xid,
 		 GDK_GC_GET_XGC (gc),
 		 xsrc, ysrc,
@@ -650,7 +687,7 @@ gdk_x11_draw_drawable (GdkDrawable *drawable,
   else if (dest_depth != 0 && src_depth == dest_depth)
     {
       XCopyArea (GDK_SCREEN_XDISPLAY (impl->screen),
-                 src_impl ? src_impl->xid : GDK_DRAWABLE_XID (src),
+                 src_impl->xid,
 		 impl->xid,
 		 GDK_GC_GET_XGC (gc),
 		 xsrc, ysrc,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]