diff options
author | Michael Natterer <mitch@gimp.org> | 2010-10-14 13:25:23 +0200 |
---|---|---|
committer | Michael Natterer <mitch@gimp.org> | 2010-10-14 13:25:23 +0200 |
commit | 9d9742f1e56a331f71c6a46b11ccc765621d46c7 (patch) | |
tree | 2a8736e41f6ea1f8ab254bcda86a41c711cd3240 /gdk | |
parent | 10c76c1c956c9dee46a6d9e28b9456967d508889 (diff) | |
download | gtk+-9d9742f1e56a331f71c6a46b11ccc765621d46c7.tar.gz |
Bug 631599 - Allow to use arbitrary surfaces for offscreen windows
Add signal GdkWindow::create-surface which allows to use any
surface type as storage for offscreen windows.
Test the new signal in tests/gdkoffscreenbox.c
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdkinternals.h | 3 | ||||
-rw-r--r-- | gdk/gdkmarshalers.list | 1 | ||||
-rw-r--r-- | gdk/gdkoffscreenwindow.c | 38 | ||||
-rw-r--r-- | gdk/gdkwindow.c | 50 | ||||
-rw-r--r-- | gdk/gdkwindow.h | 4 |
5 files changed, 86 insertions, 10 deletions
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index e2f45d5cf5..e1b458e803 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -550,6 +550,9 @@ GType gdk_offscreen_window_get_type (void); void _gdk_offscreen_window_new (GdkWindow *window, GdkWindowAttr *attributes, gint attributes_mask); +cairo_surface_t * _gdk_offscreen_window_create_surface (GdkWindow *window, + gint width, + gint height); /************************************ diff --git a/gdk/gdkmarshalers.list b/gdk/gdkmarshalers.list index ea36baeb88..cb42499721 100644 --- a/gdk/gdkmarshalers.list +++ b/gdk/gdkmarshalers.list @@ -3,4 +3,5 @@ VOID:BOOLEAN VOID:POINTER,POINTER,POINTER OBJECT:VOID OBJECT:DOUBLE,DOUBLE +BOXED:INT,INT VOID:DOUBLE,DOUBLE,POINTER,POINTER diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c index 0cea577379..55d1fad827 100644 --- a/gdk/gdkoffscreenwindow.c +++ b/gdk/gdkoffscreenwindow.c @@ -113,17 +113,11 @@ get_surface (GdkOffscreenWindow *offscreen) if (! offscreen->surface) { GdkWindowObject *private = (GdkWindowObject *) offscreen->wrapper; - cairo_surface_t *similar; - similar = _gdk_drawable_ref_cairo_surface ((GdkWindow *)private->parent); - - offscreen->surface = cairo_surface_create_similar (similar, - /* FIXME: use visual */ - CAIRO_CONTENT_COLOR, - private->width, - private->height); - - cairo_surface_destroy (similar); + g_signal_emit_by_name (private, "create-surface", + private->width, + private->height, + &offscreen->surface); } return offscreen->surface; @@ -155,6 +149,30 @@ gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable) return cairo_surface_reference (get_surface (offscreen)); } +cairo_surface_t * +_gdk_offscreen_window_create_surface (GdkWindow *offscreen, + gint width, + gint height) +{ + GdkWindowObject *private = (GdkWindowObject *) offscreen; + cairo_surface_t *similar; + cairo_surface_t *surface; + + g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (private->impl), NULL); + + similar = _gdk_drawable_ref_cairo_surface ((GdkWindow *)private->parent); + + surface = cairo_surface_create_similar (similar, + /* FIXME: use visual */ + CAIRO_CONTENT_COLOR, + width, + height); + + cairo_surface_destroy (similar); + + return surface; +} + void _gdk_offscreen_window_new (GdkWindow *window, GdkWindowAttr *attributes, diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 6801900f8a..8be5dcc213 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -27,6 +27,8 @@ #include "config.h" +#include <cairo-gobject.h> + #include "gdkwindow.h" #ifdef GDK_WINDOWING_X11 @@ -185,6 +187,7 @@ enum { PICK_EMBEDDED_CHILD, /* only called if children are embedded */ TO_EMBEDDER, FROM_EMBEDDER, + CREATE_SURFACE, LAST_SIGNAL }; @@ -353,6 +356,18 @@ accumulate_get_window (GSignalInvocationHint *ihint, return g_value_get_object (handler_return) == NULL; } +static gboolean +create_surface_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + g_value_copy (handler_return, return_accu); + + /* Stop on the first non-NULL return value */ + return g_value_get_boxed (handler_return) == NULL; +} + static GQuark quark_pointer_window = 0; static void @@ -373,6 +388,8 @@ gdk_window_class_init (GdkWindowObjectClass *klass) drawable_class->get_clip_region = gdk_window_get_clip_region; drawable_class->get_visible_region = gdk_window_get_visible_region; + klass->create_surface = _gdk_offscreen_window_create_surface; + quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window"); @@ -476,6 +493,39 @@ gdk_window_class_init (GdkWindowObjectClass *klass) G_TYPE_DOUBLE, G_TYPE_POINTER, G_TYPE_POINTER); + + /** + * GdkWindow::create-surface: + * @window: the offscreen window on which the signal is emitted + * @width: the width of the offscreen surface to create + * @height: the height of the offscreen surface to create + * + * The ::create-surface signal is emitted when an offscreen window + * needs its surface (re)created, which happens either when the the + * window is first drawn to, or when the window is being + * resized. The first signal handler that returns a non-%NULL + * surface will stop any further signal emission, and its surface + * will be used. + * + * Note that it is not possible to access the window's previous + * surface from within any callback of this signal. Calling + * gdk_offscreen_window_get_surface() will lead to a crash. + * + * Returns: the newly created #cairo_surface_t for the offscreen window + * + * Since: 3.0 + */ + signals[CREATE_SURFACE] = + g_signal_new (g_intern_static_string ("create-surface"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkWindowObjectClass, create_surface), + create_surface_accumulator, NULL, + _gdk_marshal_BOXED__INT_INT, + CAIRO_GOBJECT_TYPE_SURFACE, + 2, + G_TYPE_INT, + G_TYPE_INT); } static void diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index 5f2c6cbbc3..05a998930e 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -489,6 +489,10 @@ typedef struct _GdkWindowObjectClass GdkWindowObjectClass; struct _GdkWindowObjectClass { GdkDrawableClass parent_class; + + cairo_surface_t * (* create_surface) (GdkWindow *window, + gint width, + gint height); }; /* Windows |