summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-09-22 16:10:45 +0200
committerBenjamin Otte <otte@redhat.com>2010-09-26 15:11:45 +0200
commit0795f1e0c9e678b13d6a6fb6dd9641480b5559c3 (patch)
tree5dd9a821514651b91b39cb31852535d9457fa9d0 /gtk
parente66129015de47d21006ff03f82964a77fdf7ca3d (diff)
downloadgtk+-0795f1e0c9e678b13d6a6fb6dd9641480b5559c3.tar.gz
API: Add gtk_cairo_transform_to_window()
The function reverses the transform that GTK does before emitting a draw event. So we can use it in "old" widgets to revert the coordinate system properly.
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtk.symbols1
-rw-r--r--gtk/gtkwidget.c103
-rw-r--r--gtk/gtkwidget.h3
3 files changed, 81 insertions, 26 deletions
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 6730ce993b..b9cb161639 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -4237,6 +4237,7 @@ gtk_widget_get_tooltip_markup
gtk_widget_get_tooltip_text
gtk_widget_get_tooltip_window
gtk_widget_get_toplevel
+gtk_cairo_transform_to_window
gtk_widget_get_type G_GNUC_CONST
gtk_widget_get_visible
gtk_widget_get_visual
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 15f52143af..2b614a0295 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -5246,6 +5246,77 @@ gtk_widget_event (GtkWidget *widget,
return gtk_widget_event_internal (widget, event);
}
+/* Returns TRUE if a translation should be done */
+static gboolean
+gtk_widget_get_translation_to_window (GtkWidget *widget,
+ GdkWindow *window,
+ int *x,
+ int *y)
+{
+ GdkWindow *w, *widget_window;
+
+ if (!gtk_widget_get_has_window (widget))
+ {
+ *x = -widget->priv->allocation.x;
+ *y = -widget->priv->allocation.y;
+ }
+ else
+ {
+ *x = 0;
+ *y = 0;
+ }
+
+ widget_window = gtk_widget_get_window (widget);
+
+ for (w = window; w && w != widget_window; w = gdk_window_get_parent (w))
+ {
+ int wx, wy;
+ gdk_window_get_position (w, &wx, &wy);
+ *x += wx;
+ *y += wy;
+ }
+
+ if (w == NULL)
+ {
+ *x = 0;
+ *y = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * gtk_cairo_transform_to_window:
+ * @cr: the cairo context to transform
+ * @widget: the widget the context is currently centered for
+ * @window: the window to transform the context to
+ *
+ * Transforms the given cairo context @cr that from @widget-relative
+ * coordinates to @window-relative coordinates.
+ * If the @widget's window is not an ancestor of @window, no
+ * modification will be applied.
+ *
+ * This is the inverse to the transformation GTK applies when
+ * preparing an expose event to be emitted with the GtkWidget::draw
+ * signal. It is intended to help porting multiwindow widgets from
+ * GTK 2 to the rendering architecture of GTK 3.
+ **/
+void
+gtk_cairo_transform_to_window (cairo_t *cr,
+ GtkWidget *widget,
+ GdkWindow *window)
+{
+ int x, y;
+
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (gtk_widget_get_translation_to_window (widget, window, &x, &y))
+ cairo_translate (cr, x, y);
+}
/**
* gtk_widget_send_expose:
@@ -5270,10 +5341,10 @@ gint
gtk_widget_send_expose (GtkWidget *widget,
GdkEvent *event)
{
- GdkWindow *window, *w;
gboolean result = FALSE;
cairo_t *cr;
int x, y;
+ gboolean do_clip;
g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE);
g_return_val_if_fail (gtk_widget_get_realized (widget), TRUE);
@@ -5286,32 +5357,12 @@ gtk_widget_send_expose (GtkWidget *widget,
gdk_cairo_region (cr, event->expose.region);
cairo_clip (cr);
- if (!gtk_widget_get_has_window (widget))
- {
- x = widget->priv->allocation.x;
- y = widget->priv->allocation.y;
- }
- else
- {
- x = 0;
- y = 0;
- }
-
- /* translate cairo context properly */
- window = gtk_widget_get_window (widget);
-
- for (w = event->expose.window; w && w != window; w = gdk_window_get_parent (w))
- {
- int wx, wy;
- gdk_window_get_position (w, &wx, &wy);
- x -= wx;
- y -= wy;
- }
-
- if (w)
- cairo_translate (cr, x, y);
+ do_clip = gtk_widget_get_translation_to_window (widget,
+ event->expose.window,
+ &x, &y);
+ cairo_translate (cr, -x, -y);
- _gtk_widget_draw_internal (widget, cr, w != NULL);
+ _gtk_widget_draw_internal (widget, cr, do_clip);
/* unset here, so if someone keeps a reference to cr we
* don't leak the window. */
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 3376466923..03fa0f4d9d 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -979,6 +979,9 @@ gboolean gtk_widget_get_has_tooltip (GtkWidget *widget);
gboolean gtk_cairo_should_draw_window (cairo_t *cr,
GdkWindow *window);
+void gtk_cairo_transform_to_window (cairo_t *cr,
+ GtkWidget *widget,
+ GdkWindow *window);
GType gtk_requisition_get_type (void) G_GNUC_CONST;
GtkRequisition *gtk_requisition_new (void) G_GNUC_MALLOC;