summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2009-06-26 17:07:24 +0200
committerAlexander Larsson <alexl@redhat.com>2009-06-26 17:07:24 +0200
commitc84c0e92f8c80ef0d75a05f1bea94c21a6020674 (patch)
tree3f74f052bddc1b0f4fa3cf3bf166b74317133cc9
parent0e548579de34dbbf8b74742d58a9a57ed69d658e (diff)
downloadgdk-pixbuf-c84c0e92f8c80ef0d75a05f1bea94c21a6020674.tar.gz
Better implementation of native clear_area
Last commit was bad, as it didn't clip against client side children. This implements such clipping first and then only clears the rectangles that need to be cleared.
-rw-r--r--gdk/gdkwindow.c28
-rw-r--r--gdk/gdkwindowimpl.h7
-rw-r--r--gdk/x11/gdkwindow-x11.c28
3 files changed, 38 insertions, 25 deletions
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 665e01f78..201f84af7 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -4039,9 +4039,24 @@ gdk_window_clear_region_internal (GdkWindow *window,
if (private->redirect)
gdk_window_clear_backing_region_redirect (window, region);
- gdk_window_clear_backing_region_direct (window, region);
- if (send_expose)
- gdk_window_invalidate_region (window, region, FALSE);
+ if (GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_region &&
+ gdk_window_has_impl (private))
+ {
+ GdkRegion *copy;
+ copy = gdk_region_copy (region);
+ gdk_region_intersect (copy, private->clip_region_with_children);
+
+ GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_region
+ (window, copy, send_expose);
+
+ gdk_region_destroy (copy);
+ }
+ else
+ {
+ gdk_window_clear_backing_region_direct (window, region);
+ if (send_expose)
+ gdk_window_invalidate_region (window, region, FALSE);
+ }
}
}
@@ -4062,13 +4077,6 @@ gdk_window_clear_area_internal (GdkWindow *window,
if (GDK_WINDOW_DESTROYED (window))
return;
- if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
- {
- GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_area
- (window, x, y, width, height, send_expose);
- return;
- }
-
/* This is what XClearArea does, and e.g. GtkCList uses it,
so we need to duplicate that */
if (width == 0)
diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h
index d12a872c5..ad1ae6b5e 100644
--- a/gdk/gdkwindowimpl.h
+++ b/gdk/gdkwindowimpl.h
@@ -71,11 +71,8 @@ struct _GdkWindowImplIface
GdkWindow *new_parent,
gint x,
gint y);
- void (* clear_area) (GdkWindow *window,
- gint x,
- gint y,
- gint width,
- gint height,
+ void (* clear_region) (GdkWindow *window,
+ GdkRegion *region,
gboolean send_expose);
void (* set_cursor) (GdkWindow *window,
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index cd5a3778f..1c7c669e7 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -1661,16 +1661,24 @@ gdk_window_x11_reparent (GdkWindow *window,
}
static void
-gdk_window_x11_clear_area (GdkWindow *window,
- gint x,
- gint y,
- gint width,
- gint height,
- gboolean send_expose)
+gdk_window_x11_clear_region (GdkWindow *window,
+ GdkRegion *region,
+ gboolean send_expose)
{
- XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
- x, y, width, height,
- send_expose);
+ GdkRectangle *rectangles;
+ int n_rectangles, i;
+
+ gdk_region_get_rectangles (region,
+ &rectangles,
+ &n_rectangles);
+
+ for (i = 0; i < n_rectangles; i++)
+ XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
+ rectangles[i].x, rectangles[i].y,
+ rectangles[i].width, rectangles[i].height,
+ send_expose);
+
+ g_free (rectangles);
}
static void
@@ -5569,7 +5577,7 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
iface->set_background = gdk_window_x11_set_background;
iface->set_back_pixmap = gdk_window_x11_set_back_pixmap;
iface->reparent = gdk_window_x11_reparent;
- iface->clear_area = gdk_window_x11_clear_area;
+ iface->clear_region = gdk_window_x11_clear_region;
iface->set_cursor = gdk_window_x11_set_cursor;
iface->get_geometry = gdk_window_x11_get_geometry;
iface->get_root_coords = gdk_window_x11_get_root_coords;