]> Pileus Git - ~andy/gtk/blobdiff - gdk/gdkoffscreenwindow.c
Remove size_request from GtkSpinButton
[~andy/gtk] / gdk / gdkoffscreenwindow.c
index ebbdcc773789421f48df4c62b3fff4399d8c0d66..f9be9ad6c9f079ef911510da8f4a290991eda94b 100644 (file)
 
 #include "config.h"
 
-#include <math.h>
-
 #include "gdkwindow.h"
 #include "gdkinternals.h"
 #include "gdkwindowimpl.h"
 
+#include <math.h>
 
 /* LIMITATIONS:
  *
@@ -80,7 +79,8 @@ gdk_offscreen_window_finalize (GObject *object)
 {
   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);
 }
@@ -106,6 +106,22 @@ gdk_offscreen_window_destroy (GdkWindow *window,
     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)
@@ -129,7 +145,34 @@ gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable)
 {
   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
@@ -153,11 +196,6 @@ _gdk_offscreen_window_new (GdkWindow     *window,
   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
@@ -332,7 +370,8 @@ gdk_offscreen_window_get_surface (GdkWindow *window)
     return NULL;
 
   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
-  return offscreen->surface;
+
+  return get_surface (offscreen);
 }
 
 static void
@@ -360,7 +399,6 @@ gdk_offscreen_window_move_resize_internal (GdkWindow *window,
   GdkWindowObject *private = (GdkWindowObject *)window;
   GdkOffscreenWindow *offscreen;
   gint dx, dy, dw, dh;
-  cairo_surface_t *old_surface;
 
   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
 
@@ -383,23 +421,26 @@ gdk_offscreen_window_move_resize_internal (GdkWindow *window,
   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))
@@ -572,31 +613,47 @@ gdk_offscreen_window_translate (GdkWindow      *window,
                                 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
@@ -700,4 +757,5 @@ gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface)
   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;
 }