From 9037aab61a904b2c489d317dbbd9b8c6c5e4fad9 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 8 Jul 2009 05:47:59 +0000 Subject: [PATCH] Some csw drawing fixes --- csw-fixes.patch | 183 ++++++++++++++++++++++++++++++++++++++++++++++++ gtk2.spec | 8 ++- 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 csw-fixes.patch diff --git a/csw-fixes.patch b/csw-fixes.patch new file mode 100644 index 0000000..bb280e3 --- /dev/null +++ b/csw-fixes.patch @@ -0,0 +1,183 @@ +diff --git a/gdk/gdkdraw.c b/gdk/gdkdraw.c +index 869d535..44652bc 100644 +--- a/gdk/gdkdraw.c ++++ b/gdk/gdkdraw.c +@@ -752,9 +752,6 @@ gdk_draw_image (GdkDrawable *drawable, + * On older X servers, rendering pixbufs with an alpha channel involves round + * trips to the X server, and may be somewhat slow. + * +- * The clip mask of @gc is ignored, but clip rectangles and clip regions work +- * fine. +- * + * If GDK is built with the Sun mediaLib library, the gdk_draw_pixbuf + * function is accelerated using mediaLib, which provides hardware + * acceleration on Intel, AMD, and Sparc chipsets. If desired, mediaLib +diff --git a/gdk/gdkgc.c b/gdk/gdkgc.c +index b4c6f81..699cebf 100644 +--- a/gdk/gdkgc.c ++++ b/gdk/gdkgc.c +@@ -646,24 +646,49 @@ _gdk_gc_add_drawable_clip (GdkGC *gc, + GdkPixmap *new_mask; + GdkGC *tmp_gc; + GdkColor black = {0, 0, 0, 0}; ++ GdkRectangle r; ++ GdkOverlapType overlap; + +- priv->old_clip_mask = g_object_ref (priv->clip_mask); +- gdk_drawable_get_size (priv->old_clip_mask, &w, &h); +- +- new_mask = gdk_pixmap_new (priv->old_clip_mask, w, h, -1); +- tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE); +- +- gdk_gc_set_foreground (tmp_gc, &black); +- gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1); +- _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */ +- gdk_draw_drawable (new_mask, +- tmp_gc, +- priv->old_clip_mask, +- 0, 0, +- 0, 0, +- -1, -1); +- gdk_gc_set_clip_region (tmp_gc, NULL); +- gdk_gc_set_clip_mask (gc, new_mask); ++ gdk_drawable_get_size (priv->clip_mask, &w, &h); ++ ++ r.x = 0; ++ r.y = 0; ++ r.width = w; ++ r.height = h; ++ ++ /* Its quite common to expose areas that are completely in or outside ++ * the region, so we try to avoid allocating bitmaps that are just fully ++ * set or completely unset. ++ */ ++ overlap = gdk_region_rect_in (region, &r); ++ if (overlap == GDK_OVERLAP_RECTANGLE_PART) ++ { ++ /* The region and the mask intersect, create a new clip mask that ++ includes both areas */ ++ priv->old_clip_mask = g_object_ref (priv->clip_mask); ++ new_mask = gdk_pixmap_new (priv->old_clip_mask, w, h, -1); ++ tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE); ++ ++ gdk_gc_set_foreground (tmp_gc, &black); ++ gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1); ++ _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */ ++ gdk_draw_drawable (new_mask, ++ tmp_gc, ++ priv->old_clip_mask, ++ 0, 0, ++ 0, 0, ++ -1, -1); ++ gdk_gc_set_clip_region (tmp_gc, NULL); ++ gdk_gc_set_clip_mask (gc, new_mask); ++ } ++ else if (overlap == GDK_OVERLAP_RECTANGLE_OUT) ++ { ++ GdkRegion *empty = gdk_region_new (); ++ ++ priv->old_clip_mask = g_object_ref (priv->clip_mask); ++ _gdk_windowing_gc_set_clip_region (gc, empty, FALSE); ++ gdk_region_destroy (empty); ++ } + } + else + { +@@ -775,6 +800,24 @@ _gdk_gc_get_clip_region (GdkGC *gc) + } + + /** ++ * _gdk_gc_get_clip_mask: ++ * @gc: a #GdkGC ++ * ++ * Gets the current clip mask for @gc, if any. ++ * ++ * Return value: the clip mask for the GC, or %NULL. ++ * (if a clip region is set, the return will be %NULL) ++ * This value is owned by the GC and must not be freed. ++ **/ ++GdkBitmap * ++_gdk_gc_get_clip_mask (GdkGC *gc) ++{ ++ g_return_val_if_fail (GDK_IS_GC (gc), NULL); ++ ++ return GDK_GC_GET_PRIVATE (gc)->clip_mask; ++} ++ ++/** + * _gdk_gc_get_fill: + * @gc: a #GdkGC + * +diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h +index 946c3f9..c984386 100644 +--- a/gdk/gdkinternals.h ++++ b/gdk/gdkinternals.h +@@ -399,6 +399,7 @@ void _gdk_gc_init (GdkGC *gc, + GdkGCValuesMask values_mask); + + GdkRegion *_gdk_gc_get_clip_region (GdkGC *gc); ++GdkBitmap *_gdk_gc_get_clip_mask (GdkGC *gc); + gboolean _gdk_gc_get_exposures (GdkGC *gc); + GdkFill _gdk_gc_get_fill (GdkGC *gc); + GdkPixmap *_gdk_gc_get_tile (GdkGC *gc); +diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c +index 6e72cab..d9b1e5b 100644 +--- a/gdk/gdkwindow.c ++++ b/gdk/gdkwindow.c +@@ -639,7 +639,12 @@ remove_child_area (GdkWindowObject *private, + child_region = gdk_region_rectangle (&r); + + if (child->shape) +- gdk_region_intersect (child_region, child->shape); ++ { ++ /* Adjust shape region to parent window coords */ ++ gdk_region_offset (child->shape, child->x, child->y); ++ gdk_region_intersect (child_region, child->shape); ++ gdk_region_offset (child->shape, -child->x, -child->y); ++ } + else if (private->window_type == GDK_WINDOW_FOREIGN) + { + shape = _gdk_windowing_window_get_shape ((GdkWindow *)child); +@@ -4660,7 +4665,12 @@ _gdk_window_process_updates_recurse (GdkWindow *window, + + child_region = gdk_region_rectangle (&r); + if (child->shape) +- gdk_region_intersect (child_region, child->shape); ++ { ++ /* Adjust shape region to parent window coords */ ++ gdk_region_offset (child->shape, child->x, child->y); ++ gdk_region_intersect (child_region, child->shape); ++ gdk_region_offset (child->shape, -child->x, -child->y); ++ } + + if (child->impl == private->impl) + { +diff --git a/gdk/x11/gdkdrawable-x11.c b/gdk/x11/gdkdrawable-x11.c +index 537a47e..b2cac29 100644 +--- a/gdk/x11/gdkdrawable-x11.c ++++ b/gdk/x11/gdkdrawable-x11.c +@@ -388,9 +388,22 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable, + else + { + XRenderPictureAttributes pa; +- pa.clip_mask = None; ++ GdkBitmap *mask; ++ gulong pa_mask; ++ ++ pa_mask = CPClipMask; ++ if (gc && (mask = _gdk_gc_get_clip_mask (gc))) ++ { ++ pa.clip_mask = GDK_PIXMAP_XID (mask); ++ pa.clip_x_origin = gc->clip_x_origin; ++ pa.clip_y_origin = gc->clip_y_origin; ++ pa_mask |= CPClipXOrigin | CPClipYOrigin; ++ } ++ else ++ pa.clip_mask = None; ++ + XRenderChangePicture (xdisplay, picture, +- CPClipMask, &pa); ++ pa_mask, &pa); + } + } + diff --git a/gtk2.spec b/gtk2.spec index fc2175e..d08dc0a 100644 --- a/gtk2.spec +++ b/gtk2.spec @@ -17,7 +17,7 @@ Summary: The GIMP ToolKit (GTK+), a library for creating GUIs for X Name: gtk2 Version: %{base_version} -Release: 1%{?dist} +Release: 2%{?dist} License: LGPLv2+ Group: System Environment/Libraries Source: http://download.gnome.org/sources/gtk+/2.17/gtk+-%{version}.tar.bz2 @@ -28,6 +28,8 @@ Source2: update-gtk-immodules Patch0: gtk+-2.13.5-lib64.patch # http://bugzilla.redhat.com/show_bug.cgi?id=478400 Patch1: default_printer.patch +# from upstream +Patch2: csw-fixes.patch BuildRequires: atk-devel >= %{atk_version} BuildRequires: pango-devel >= %{pango_version} @@ -138,6 +140,7 @@ This package contains developer documentation for the GTK+ widget toolkit. %patch0 -p1 -b .lib64 %patch1 -p0 -b .default-printer +%patch2 -p1 -b .csw-fixes # make sure that gtkmarshalers.{c, h} get regenerated during the build # - caused by print_authentication.patch @@ -370,6 +373,9 @@ fi %changelog +* Wed Jul 8 2009 Matthias Clasen - 2.17.3-2 +- Some fixes for drawing issues, e.g. with statusicons + * Tue Jul 7 2009 Matthias Clasen - 2.17.3-1 - Update to 2.17.3