[gtk+/client-side-windows] Add support for client side graphics exposures in gdk_draw_drawable



commit 0b586a5ad7b991cc4c7027a2e36aeccd7f99b545
Author: Alexander Larsson <alexl redhat com>
Date:   Wed May 27 17:08:09 2009 +0200

    Add support for client side graphics exposures in gdk_draw_drawable
---
 gdk/gdkdraw.c                   |   12 ++++---
 gdk/gdkdrawable.h               |    1 +
 gdk/gdkpixmap.c                 |    2 +
 gdk/gdkwindow.c                 |   68 +++++++++++++++++++++++++++++++++++---
 gdk/quartz/gdkdrawable-quartz.c |    1 +
 gdk/win32/gdkdrawable-win32.c   |    2 +
 gdk/x11/gdkdrawable-x11.c       |    2 +
 7 files changed, 77 insertions(+), 11 deletions(-)

diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c
index 8c5d422..321b883 100644
--- a/gdk/gdkdraw.c
+++ b/gdk/gdkdraw.c
@@ -663,16 +663,18 @@ gdk_draw_drawable (GdkDrawable *drawable,
     composite_impl = GDK_WINDOW_OBJECT (src)->impl;
   else
     composite_impl = composite;
-  
+
   /* TODO: For non-native windows this may copy stuff from other overlapping
-     windows. We should clip that and clear that area in the destination instead. */
-  
-  GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, composite_impl,
+     windows. We should clip that and (for windows with bg != None) clear that
+     area in the destination instead. */
+
+  GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc,
+						    composite_impl, src,
                                                     xsrc - composite_x_offset,
                                                     ysrc - composite_y_offset,
                                                     xdest, ydest,
                                                     width, height);
-  
+
   g_object_unref (composite);
 }
 
diff --git a/gdk/gdkdrawable.h b/gdk/gdkdrawable.h
index 50904fc..1d8d694 100644
--- a/gdk/gdkdrawable.h
+++ b/gdk/gdkdrawable.h
@@ -100,6 +100,7 @@ struct _GdkDrawableClass
   void (*draw_drawable)  (GdkDrawable  *drawable,
 			  GdkGC	       *gc,
 			  GdkDrawable  *src,
+			  GdkDrawable  *original_src,
 			  gint		xsrc,
 			  gint		ysrc,
 			  gint		xdest,
diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c
index de735b9..e4d8869 100644
--- a/gdk/gdkpixmap.c
+++ b/gdk/gdkpixmap.c
@@ -72,6 +72,7 @@ static void   gdk_pixmap_draw_text_wc   (GdkDrawable     *drawable,
 static void   gdk_pixmap_draw_drawable  (GdkDrawable     *drawable,
 					 GdkGC           *gc,
 					 GdkPixmap       *src,
+					 GdkPixmap       *original_src,
 					 gint             xsrc,
 					 gint             ysrc,
 					 gint             xdest,
@@ -374,6 +375,7 @@ static void
 gdk_pixmap_draw_drawable (GdkDrawable *drawable,
 			  GdkGC       *gc,
 			  GdkPixmap   *src,
+			  GdkPixmap   *original_src,
 			  gint         xsrc,
 			  gint         ysrc,
 			  gint         xdest,
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 1f2388b..a2b5d6d 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -126,6 +126,7 @@ static void   gdk_window_draw_text_wc   (GdkDrawable     *drawable,
 static void   gdk_window_draw_drawable  (GdkDrawable     *drawable,
                                          GdkGC           *gc,
                                          GdkPixmap       *src,
+					 GdkDrawable     *original_src,
                                          gint             xsrc,
                                          gint             ysrc,
                                          gint             xdest,
@@ -3426,6 +3427,7 @@ static void
 gdk_window_draw_drawable (GdkDrawable *drawable,
 			  GdkGC       *gc,
 			  GdkPixmap   *src,
+			  GdkDrawable *original_src,
 			  gint         xsrc,
 			  gint         ysrc,
 			  gint         xdest,
@@ -3435,7 +3437,7 @@ gdk_window_draw_drawable (GdkDrawable *drawable,
 {
   GdkWindowObject *private = (GdkWindowObject *)drawable;
   OFFSET_GC (gc);
-  
+
   if (GDK_WINDOW_DESTROYED (drawable))
     return;
 
@@ -3445,9 +3447,8 @@ gdk_window_draw_drawable (GdkDrawable *drawable,
       GdkWindowPaint *paint = private->paint_stack->data;
       SETUP_PAINT_GC_CLIP (gc);
       gdk_draw_drawable (pixmap_impl (paint->pixmap), gc,
-                         src, xsrc, ysrc,
+			 src, xsrc, ysrc,
 			 xdest - x_offset, ydest - y_offset, width, height);
-
       RESTORE_PAINT_GC_CLIP (gc);
     }
   else
@@ -3458,6 +3459,59 @@ gdk_window_draw_drawable (GdkDrawable *drawable,
 			 xdest - x_offset, ydest - y_offset,
 			 width, height);
       RESTORE_DIRECT_GC_CLIP(gc);
+
+      /* We might have drawn from an obscured part of a client
+	 side window, if so we need to send graphics exposures */
+      if (_gdk_gc_get_exposures (gc) &&
+	  GDK_IS_WINDOW (original_src))
+	{
+	  GdkRegion *exposure_region;
+	  GdkRegion *clip;
+	  GdkRectangle r;
+
+	  r.x = xdest;
+	  r.y = ydest;
+	  r.width = width;
+	  r.height = height;
+	  exposure_region = gdk_region_rectangle (&r);
+
+	  if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
+	    clip = private->clip_region_with_children;
+	  else
+	    clip = private->clip_region;
+	  gdk_region_intersect (exposure_region, clip);
+
+	  clip = _gdk_gc_get_clip_region (gc);
+	  if (clip)
+	    {
+	      gdk_region_offset (exposure_region,
+				 old_clip_x,
+				 old_clip_y);
+	      gdk_region_intersect (exposure_region, clip);
+	      gdk_region_offset (exposure_region,
+				 -old_clip_x,
+				 -old_clip_y);
+	    }
+
+	  /* Note: We don't clip by the clip mask if set, so this
+	     may invalidate to much */
+
+	  /* Remove the area that is correctly copied from the src.
+	   * Note that xsrc/ysrc has been corrected for abs_x/y offsets already,
+	   * which need to be undone */
+	  clip = gdk_drawable_get_visible_region (original_src);
+	  gdk_region_offset (clip,
+			     xdest - (xsrc - GDK_WINDOW_OBJECT (original_src)->abs_x),
+			     ydest - (ysrc - GDK_WINDOW_OBJECT (original_src)->abs_y));
+	  gdk_region_subtract (exposure_region, clip);
+	  gdk_region_destroy (clip);
+
+	  gdk_window_invalidate_region (GDK_WINDOW (private),
+					exposure_region,
+					_gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS);
+
+	  gdk_region_destroy (exposure_region);
+	}
     }
 
   RESTORE_GC (gc);
@@ -5012,8 +5066,10 @@ gdk_window_invalidate_maybe_recurse (GdkWindow       *window,
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
-  
-  if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
+
+  if (private->input_only ||
+      !GDK_WINDOW_IS_MAPPED (window) ||
+      gdk_region_empty (region))
     return;
 
   visible_region = gdk_drawable_get_visible_region (window);
@@ -5086,7 +5142,7 @@ gdk_window_invalidate_maybe_recurse (GdkWindow       *window,
 	  gdk_window_schedule_update ((GdkWindow *)impl_window);
 	}
     }
-  
+
   gdk_region_destroy (visible_region);
 }
 
diff --git a/gdk/quartz/gdkdrawable-quartz.c b/gdk/quartz/gdkdrawable-quartz.c
index 72b678c..673da06 100644
--- a/gdk/quartz/gdkdrawable-quartz.c
+++ b/gdk/quartz/gdkdrawable-quartz.c
@@ -326,6 +326,7 @@ static void
 gdk_quartz_draw_drawable (GdkDrawable *drawable,
 			  GdkGC       *gc,
 			  GdkPixmap   *src,
+			  GdkDrawable *original_src,
 			  gint         xsrc,
 			  gint         ysrc,
 			  gint         xdest,
diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c
index 4ccf0b3..18997ad 100644
--- a/gdk/win32/gdkdrawable-win32.c
+++ b/gdk/win32/gdkdrawable-win32.c
@@ -87,6 +87,7 @@ static void gdk_win32_draw_text_wc   (GdkDrawable    *drawable,
 static void gdk_win32_draw_drawable  (GdkDrawable    *drawable,
 				      GdkGC          *gc,
 				      GdkPixmap      *src,
+				      GdkDrawable    *original_src,
 				      gint            xsrc,
 				      gint            ysrc,
 				      gint            xdest,
@@ -1143,6 +1144,7 @@ static void
 gdk_win32_draw_drawable (GdkDrawable *drawable,
 			 GdkGC       *gc,
 			 GdkPixmap   *src,
+			 GdkDrawable *original_src,
 			 gint         xsrc,
 			 gint         ysrc,
 			 gint         xdest,
diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c
index e6ea4f1..90d5c9e 100644
--- a/gdk/x11/gdkdrawable-x11.c
+++ b/gdk/x11/gdkdrawable-x11.c
@@ -88,6 +88,7 @@ static void gdk_x11_draw_text_wc   (GdkDrawable    *drawable,
 static void gdk_x11_draw_drawable  (GdkDrawable    *drawable,
 				    GdkGC          *gc,
 				    GdkPixmap      *src,
+				    GdkDrawable    *original_src,
 				    gint            xsrc,
 				    gint            ysrc,
 				    gint            xdest,
@@ -618,6 +619,7 @@ static void
 gdk_x11_draw_drawable (GdkDrawable *drawable,
 		       GdkGC       *gc,
 		       GdkPixmap   *src,
+		       GdkDrawable *original_src,
 		       gint         xsrc,
 		       gint         ysrc,
 		       gint         xdest,



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