#include "config.h"
-#include <math.h>
-
#include "gdkwindow.h"
#include "gdkinternals.h"
#include "gdkwindowimpl.h"
+#include <math.h>
/* LIMITATIONS:
*
{
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (object);
- cairo_surface_destroy (offscreen->surface);
+ if (offscreen->surface)
+ cairo_surface_destroy (offscreen->surface);
G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object);
}
gdk_offscreen_window_hide (window);
}
+static cairo_surface_t *
+get_surface (GdkOffscreenWindow *offscreen)
+{
+ if (! offscreen->surface)
+ {
+ GdkWindowObject *private = (GdkWindowObject *) offscreen->wrapper;
+
+ g_signal_emit_by_name (private, "create-surface",
+ private->width,
+ private->height,
+ &offscreen->surface);
+ }
+
+ return offscreen->surface;
+}
+
static gboolean
is_parent_of (GdkWindow *parent,
GdkWindow *child)
{
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
- return cairo_surface_reference (offscreen->surface);
+ 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;
+ cairo_content_t content = CAIRO_CONTENT_COLOR;
+
+ g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (private->impl), NULL);
+
+ similar = _gdk_drawable_ref_cairo_surface ((GdkWindow *)private->parent);
+
+ if (gdk_window_get_visual (offscreen) ==
+ gdk_screen_get_rgba_visual (gdk_window_get_screen (offscreen)))
+ {
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+ }
+
+ surface = cairo_surface_create_similar (similar, content, width, height);
+
+ cairo_surface_destroy (similar);
+
+ return surface;
}
void
private->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL);
offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
offscreen->wrapper = window;
-
- offscreen->surface = gdk_window_create_similar_surface ((GdkWindow *)private->parent,
- CAIRO_CONTENT_COLOR,
- private->width,
- private->height);
}
static gboolean
return NULL;
offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
- return offscreen->surface;
+
+ return get_surface (offscreen);
}
static void
GdkWindowObject *private = (GdkWindowObject *)window;
GdkOffscreenWindow *offscreen;
gint dx, dy, dw, dh;
- cairo_surface_t *old_surface;
offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
if (private->width != width ||
private->height != height)
{
- cairo_t *cr;
-
private->width = width;
private->height = height;
- old_surface = offscreen->surface;
- offscreen->surface = cairo_surface_create_similar (old_surface,
- cairo_surface_get_content (old_surface),
- width,
- height);
+ if (offscreen->surface)
+ {
+ cairo_surface_t *old_surface;
+ cairo_t *cr;
- cr = cairo_create (offscreen->surface);
- cairo_set_source_surface (cr, old_surface, 0, 0);
- cairo_paint (cr);
- cairo_destroy (cr);
+ old_surface = offscreen->surface;
+ offscreen->surface = NULL;
- cairo_surface_destroy (old_surface);
+ offscreen->surface = get_surface (offscreen);
+
+ cr = cairo_create (offscreen->surface);
+ cairo_set_source_surface (cr, old_surface, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (old_surface);
+ }
}
if (GDK_WINDOW_IS_MAPPED (private))
gint dy)
{
GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (((GdkWindowObject *) window)->impl);
- cairo_t *cr;
- cr = cairo_create (offscreen->surface);
+ if (offscreen->surface)
+ {
+ cairo_t *cr;
- area = cairo_region_copy (area);
+ cr = cairo_create (offscreen->surface);
- gdk_cairo_region (cr, area);
- cairo_clip (cr);
-
- /* NB: This is a self-copy and Cairo doesn't support that yet.
- * So we do a litle trick.
- */
- cairo_push_group (cr);
+ area = cairo_region_copy (area);
+
+ gdk_cairo_region (cr, area);
+ cairo_clip (cr);
+
+ /* NB: This is a self-copy and Cairo doesn't support that yet.
+ * So we do a litle trick.
+ */
+ cairo_push_group (cr);
- cairo_set_source_surface (cr, offscreen->surface, dx, dy);
- cairo_paint (cr);
+ cairo_set_source_surface (cr, offscreen->surface, dx, dy);
+ cairo_paint (cr);
- cairo_pop_group_to_source (cr);
- cairo_paint (cr);
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
- cairo_destroy (cr);
+ cairo_destroy (cr);
+ }
_gdk_window_add_damage (window, area);
}
+static cairo_surface_t *
+gdk_offscreen_window_resize_cairo_surface (GdkWindow *window,
+ cairo_surface_t *surface,
+ gint width,
+ gint height)
+{
+ /* No-op. The surface gets resized in
+ * gdk_offscreen_window_move_resize_internal().
+ */
+ return surface;
+}
+
/**
* gdk_offscreen_window_set_embedder:
* @window: a #GdkWindow
iface->get_root_coords = gdk_offscreen_window_get_root_coords;
iface->get_device_state = gdk_offscreen_window_get_device_state;
iface->destroy = gdk_offscreen_window_destroy;
+ iface->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface;
}