[gtk+/rendering-cleanup-next: 13/153] API: Add gtk_cairo_should_draw_window()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/rendering-cleanup-next: 13/153] API: Add gtk_cairo_should_draw_window()
- Date: Sat, 11 Sep 2010 04:52:31 +0000 (UTC)
commit a6dee229797360b3d94f48a4ec53c223faa4066d
Author: Benjamin Otte <otte redhat com>
Date: Thu Sep 2 23:26:13 2010 +0200
API: Add gtk_cairo_should_draw_window()
See the function documentation for its purpose and the next commit(s)
for examples on how to use it.
gtk/gtk.symbols | 1 +
gtk/gtkwidget.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 79 insertions(+), 1 deletions(-)
---
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index f88c1e1..7f72bd6 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -4176,6 +4176,7 @@ gtk_vseparator_new
#if IN_HEADER(__GTK_WIDGET_H__)
#if IN_FILE(__GTK_WIDGET_C__)
+gtk_cairo_should_draw_window
gtk_requisition_copy
gtk_requisition_free
gtk_requisition_get_type G_GNUC_CONST
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 6aef0a4..9340c41 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4680,10 +4680,59 @@ gtk_widget_real_mnemonic_activate (GtkWidget *widget,
return TRUE;
}
+static const cairo_user_data_key_t window_key;
+
+static GdkWindow *
+gtk_cairo_get_window (cairo_t *cr)
+{
+ g_return_val_if_fail (cr != NULL, NULL);
+
+ return cairo_get_user_data (cr, &window_key);
+}
+
+/**
+ * gtk_cairo_should_draw_window:
+ * @cr: a cairo context
+ * @window: the window to check
+ *
+ * This function is supposed to be called in GtkWidget::draw
+ * implementations for widgets that support multiple windows.
+ * @cr must be untransformed from invoking of the draw function.
+ * This function will return %TRUE if the contents of the given
+ * @window are supposed to be drawn and %FALSE otherwise. Note
+ * that when the drawing was not initiated by the windowing
+ * system this function will return %TRUE for all windows, so
+ * you need to draw the bottommost window first. Also, do not
+ * use "else if" statements to check which window should be drawn.
+ *
+ * Returns: %TRUE if @window should be drawn
+ **/
+gboolean
+gtk_cairo_should_draw_window (cairo_t *cr,
+ GdkWindow *window)
+{
+ GdkWindow *cairo_window;
+
+ g_return_val_if_fail (cr != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+ cairo_window = gtk_cairo_get_window (cr);
+
+ return cairo_window == NULL ||
+ cairo_window == window;
+}
+
+static void
+gtk_cairo_set_window (cairo_t *cr,
+ GdkWindow *window)
+{
+ cairo_set_user_data (cr, &window_key, window, NULL);
+}
static gboolean
gtk_widget_real_expose_event (GtkWidget *widget,
GdkEventExpose *expose)
{
+ GdkWindow *window;
gboolean result = FALSE;
cairo_t *cr;
@@ -4691,9 +4740,34 @@ gtk_widget_real_expose_event (GtkWidget *widget,
return FALSE;
cr = gdk_cairo_create (expose->window);
+ gtk_cairo_set_window (cr, expose->window);
+
gdk_cairo_region (cr, expose->region);
cairo_clip (cr);
+ /* translate cairo context properly */
+ window = gtk_widget_get_window (widget);
+ if (window != expose->window)
+ {
+ int x, y;
+
+ if (gdk_window_get_parent (expose->window) == window)
+ {
+ gdk_window_get_position (expose->window, &x, &y);
+ }
+ else
+ {
+ int ex, ey;
+ gdk_window_get_origin (expose->window, &ex, &ey);
+ gdk_window_get_origin (window, &x, &y);
+ x = ex - x;
+ y = ey - y;
+ }
+
+ cairo_translate (cr, -x, -y);
+ }
+
+
if (!gtk_widget_get_has_window (widget))
{
cairo_translate (cr,
@@ -4706,7 +4780,10 @@ gtk_widget_real_expose_event (GtkWidget *widget,
widget->priv->allocation.width,
widget->priv->allocation.height,
&result);
-
+
+ /* unset here, so if someone keeps a reference to cr we
+ * don't leak the window. */
+ gtk_cairo_set_window (cr, NULL);
cairo_destroy (cr);
return result;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]