]> Pileus Git - ~andy/gtk/blobdiff - gdk/gdkoffscreenwindow.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gdk / gdkoffscreenwindow.c
index efdfcd93f38e35771cf2d73ee72adb7d4bc2cb04..aed09e0e83097d92756c9a580811a2ae8d408421 100644 (file)
@@ -12,9 +12,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
  */
 
-#include <config.h>
-#include <math.h>
-#include "gdk.h"
+#include "config.h"
+
 #include "gdkwindow.h"
 #include "gdkinternals.h"
 #include "gdkwindowimpl.h"
-#include "gdkpixmap.h"
-#include "gdkdrawable.h"
-#include "gdktypes.h"
-#include "gdkscreen.h"
-#include "gdkgc.h"
-#include "gdkcolor.h"
-#include "gdkcursor.h"
-#include "gdkalias.h"
+
+#include <math.h>
 
 /* LIMITATIONS:
  *
@@ -51,19 +42,17 @@ typedef struct _GdkOffscreenWindowClass GdkOffscreenWindowClass;
 
 struct _GdkOffscreenWindow
 {
-  GdkDrawable parent_instance;
+  GdkWindowImpl parent_instance;
 
   GdkWindow *wrapper;
-  GdkCursor *cursor;
-  GdkColormap *colormap;
-  GdkScreen *screen;
 
-  GdkPixmap *pixmap;
+  cairo_surface_t *surface;
+  GdkWindow *embedder;
 };
 
 struct _GdkOffscreenWindowClass
 {
-  GdkDrawableClass parent_class;
+  GdkWindowImplClass parent_class;
 };
 
 #define GDK_TYPE_OFFSCREEN_WINDOW            (gdk_offscreen_window_get_type())
@@ -73,14 +62,9 @@ struct _GdkOffscreenWindowClass
 #define GDK_IS_OFFSCREEN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_OFFSCREEN_WINDOW))
 #define GDK_OFFSCREEN_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindowClass))
 
-static void       gdk_offscreen_window_impl_iface_init    (GdkWindowImplIface         *iface);
 static void       gdk_offscreen_window_hide               (GdkWindow                  *window);
 
-G_DEFINE_TYPE_WITH_CODE (GdkOffscreenWindow,
-                         gdk_offscreen_window,
-                         GDK_TYPE_DRAWABLE,
-                        G_IMPLEMENT_INTERFACE (GDK_TYPE_WINDOW_IMPL,
-                                               gdk_offscreen_window_impl_iface_init));
+G_DEFINE_TYPE (GdkOffscreenWindow, gdk_offscreen_window, GDK_TYPE_WINDOW_IMPL)
 
 
 static void
@@ -88,13 +72,9 @@ gdk_offscreen_window_finalize (GObject *object)
 {
   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (object);
 
-  if (offscreen->cursor)
-    gdk_cursor_unref (offscreen->cursor);
-
-  offscreen->cursor = NULL;
+  if (offscreen->surface)
+    cairo_surface_destroy (offscreen->surface);
 
-  gdk_pixmap_unref (offscreen->pixmap);
-  
   G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object);
 }
 
@@ -105,24 +85,34 @@ gdk_offscreen_window_init (GdkOffscreenWindow *window)
 
 static void
 gdk_offscreen_window_destroy (GdkWindow *window,
-                             gboolean   recursing,
-                             gboolean   foreign_destroy)
+                              gboolean   recursing,
+                              gboolean   foreign_destroy)
 {
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
-  GdkOffscreenWindow *offscreen;
-
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
+  gdk_offscreen_window_set_embedder (window, NULL);
 
   if (!recursing)
     gdk_offscreen_window_hide (window);
+}
+
+static cairo_surface_t *
+get_surface (GdkOffscreenWindow *offscreen)
+{
+  if (! offscreen->surface)
+    {
+      GdkWindow *window = offscreen->wrapper;
+
+      g_signal_emit_by_name (window, "create-surface",
+                             window->width,
+                             window->height,
+                             &offscreen->surface);
+    }
 
-  g_object_unref (offscreen->colormap);
-  offscreen->colormap = NULL;
+  return offscreen->surface;
 }
 
 static gboolean
 is_parent_of (GdkWindow *parent,
-              GdkWindow *child)
+             GdkWindow *child)
 {
   GdkWindow *w;
 
@@ -138,723 +128,343 @@ is_parent_of (GdkWindow *parent,
   return FALSE;
 }
 
-static GdkGC *
-gdk_offscreen_window_create_gc (GdkDrawable     *drawable,
-                               GdkGCValues     *values,
-                               GdkGCValuesMask  values_mask)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
-  return gdk_gc_new_with_values (offscreen->pixmap, values, values_mask);
-}
-
-static GdkImage*
-gdk_offscreen_window_copy_to_image (GdkDrawable    *drawable,
-                                   GdkImage       *image,
-                                   gint            src_x,
-                                   gint            src_y,
-                                   gint            dest_x,
-                                   gint            dest_y,
-                                   gint            width,
-                                   gint            height)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
-  return gdk_drawable_copy_to_image (offscreen->pixmap,
-                                     image,
-                                     src_x,
-                                     src_y,
-                                     dest_x, dest_y,
-                                     width, height);
-}
-
 static cairo_surface_t *
-gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  
-  return _gdk_drawable_ref_cairo_surface (offscreen->pixmap);
-}
-
-static GdkColormap*
-gdk_offscreen_window_get_colormap (GdkDrawable *drawable)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
-  return offscreen->colormap;
-}
-
-static void
-gdk_offscreen_window_set_colormap (GdkDrawable *drawable,
-                                  GdkColormap*colormap)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
-  if (colormap && GDK_WINDOW_DESTROYED (offscreen->wrapper))
-    return;
-
-  if (offscreen->colormap == colormap)
-    return;
-
-  if (offscreen->colormap)
-    g_object_unref (offscreen->colormap);
-
-  offscreen->colormap = colormap;
-  if (offscreen->colormap)
-    g_object_ref (offscreen->colormap);
-}
-
-
-static gint
-gdk_offscreen_window_get_depth (GdkDrawable *drawable)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-
-  return gdk_drawable_get_depth (offscreen->wrapper);
-}
-
-static GdkDrawable *
-gdk_offscreen_window_get_source_drawable (GdkDrawable  *drawable)
+gdk_offscreen_window_ref_cairo_surface (GdkWindow *window)
 {
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
+  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
 
-  return _gdk_drawable_get_source_drawable (offscreen->pixmap);
+  return cairo_surface_reference (get_surface (offscreen));
 }
 
-static GdkDrawable *
-gdk_offscreen_window_get_composite_drawable (GdkDrawable *drawable,
-                                            gint         x,
-                                            gint         y,
-                                            gint         width,
-                                            gint         height,
-                                            gint        *composite_x_offset,
-                                            gint        *composite_y_offset)
+cairo_surface_t *
+_gdk_offscreen_window_create_surface (GdkWindow *offscreen,
+                                      gint       width,
+                                      gint       height)
 {
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
+  cairo_surface_t *similar;
+  cairo_surface_t *surface;
 
-  return g_object_ref (offscreen->pixmap);
-}
+  g_return_val_if_fail (GDK_IS_OFFSCREEN_WINDOW (offscreen->impl), NULL);
 
-static GdkScreen*
-gdk_offscreen_window_get_screen (GdkDrawable *drawable)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
+  similar = _gdk_window_ref_cairo_surface (offscreen->parent);
 
-  return offscreen->screen;
-}
+  surface = cairo_surface_create_similar (similar, CAIRO_CONTENT_COLOR_ALPHA, width, height);
 
-static GdkVisual*
-gdk_offscreen_window_get_visual (GdkDrawable    *drawable)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
+  cairo_surface_destroy (similar);
 
-  return gdk_drawable_get_visual (offscreen->wrapper);
+  return surface;
 }
 
-static void
-add_damage (GdkOffscreenWindow *offscreen,
-           int x, int y,
-           int w, int h)
-{
-  GdkRectangle rect;
-  GdkRegion *damage;
-  
-  rect.x = x;
-  rect.y = y;
-  rect.width = w;
-  rect.height = h;
-
-  damage = gdk_region_rectangle (&rect);
-  _gdk_window_add_damage (offscreen->wrapper, damage);
-  gdk_region_destroy (damage);
-}
-
-static GdkDrawable *
-get_real_drawable (GdkOffscreenWindow *offscreen)
+void
+_gdk_offscreen_window_new (GdkWindow     *window,
+                          GdkWindowAttr *attributes,
+                          gint           attributes_mask)
 {
-  GdkPixmapObject *pixmap;
-  pixmap = (GdkPixmapObject *) offscreen->pixmap;
-  return GDK_DRAWABLE (pixmap->impl);
-}
+  GdkOffscreenWindow *offscreen;
 
-static void
-gdk_offscreen_window_draw_drawable (GdkDrawable *drawable,
-                                   GdkGC       *gc,
-                                   GdkPixmap   *src,
-                                   GdkDrawable *original_src,
-                                   gint         xsrc,
-                                   gint         ysrc,
-                                   gint         xdest,
-                                   gint         ydest,
-                                   gint         width,
-                                   gint         height)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  
-  gdk_draw_drawable (real_drawable, gc,
-                    src, xsrc, ysrc,
-                    xdest, ydest,
-                    width, height);
-
-  add_damage (offscreen, xdest, ydest, width, height);
-}
+  g_return_if_fail (attributes != NULL);
 
-static void
-gdk_offscreen_window_draw_rectangle (GdkDrawable  *drawable,
-                                    GdkGC        *gc,
-                                    gboolean      filled,
-                                    gint          x,
-                                    gint          y,
-                                    gint          width,
-                                    gint          height)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
+  if (attributes->wclass != GDK_INPUT_OUTPUT)
+    return; /* Can't support input only offscreens */
 
-  gdk_draw_rectangle (real_drawable,
-                     gc, filled, x, y, width, height);
+  if (window->parent != NULL && GDK_WINDOW_DESTROYED (window->parent))
+    return;
 
-  add_damage (offscreen, x, y, width, height);
-  
+  window->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL);
+  offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
+  offscreen->wrapper = window;
 }
 
-static void
-gdk_offscreen_window_draw_arc (GdkDrawable  *drawable,
-                              GdkGC           *gc,
-                              gboolean filled,
-                              gint             x,
-                              gint             y,
-                              gint             width,
-                              gint             height,
-                              gint             angle1,
-                              gint             angle2)
+static gboolean
+gdk_offscreen_window_reparent (GdkWindow *window,
+                              GdkWindow *new_parent,
+                              gint       x,
+                              gint       y)
 {
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_arc (real_drawable,
-               gc,
-               filled,
-               x,
-               y,
-               width,
-               height,
-               angle1,
-               angle2);
-  add_damage (offscreen, x, y, width, height);
-}
+  GdkWindow *old_parent;
+  gboolean was_mapped;
 
-static void
-gdk_offscreen_window_draw_polygon (GdkDrawable  *drawable,
-                                  GdkGC               *gc,
-                                  gboolean     filled,
-                                  GdkPoint     *points,
-                                  gint         npoints)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  
-  gdk_draw_polygon (real_drawable,
-                   gc,
-                   filled,
-                   points,
-                   npoints);
-
-  if (npoints > 0)
+  if (new_parent)
     {
-      int min_x, min_y, max_x, max_y, i;
-      
-      min_x = max_x = points[0].x;
-      min_y = max_y = points[0].y;
-      
-       for (i = 1; i < npoints; i++)
-         {
-           min_x = MIN (min_x, points[i].x);
-           max_x = MAX (max_x, points[i].x);
-           min_y = MIN (min_y, points[i].y);
-           max_y = MAX (max_y, points[i].y);
-         }
-       
-       add_damage (offscreen, min_x, min_y,
-                   max_x - min_x,
-                   max_y - min_y);
-    }
-}
-
-static void
-gdk_offscreen_window_draw_text (GdkDrawable  *drawable,
-                               GdkFont      *font,
-                               GdkGC          *gc,
-                               gint            x,
-                               gint            y,
-                               const gchar  *text,
-                               gint            text_length)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper);
-
-  gdk_draw_text (real_drawable,
-                font,
-                gc,
-                x,
-                y,
-                text,
-                text_length);
-
-  /* Hard to compute the minimal size, not that often used anyway. */
-  add_damage (offscreen, 0, 0, private->width, private->height);
-}
-
-static void
-gdk_offscreen_window_draw_text_wc (GdkDrawable  *drawable,
-                                  GdkFont       *font,
-                                  GdkGC                 *gc,
-                                  gint           x,
-                                  gint           y,
-                                  const GdkWChar *text,
-                                  gint           text_length)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper);
-
-  gdk_draw_text_wc (real_drawable,
-                   font,
-                   gc,
-                   x,
-                   y,
-                   text,
-                   text_length);
-
-  /* Hard to compute the minimal size, not that often used anyway. */
-  add_damage (offscreen, 0, 0, private->width, private->height);
-}
+      /* No input-output children of input-only windows */
+      if (new_parent->input_only && !window->input_only)
+       return FALSE;
 
-static void
-gdk_offscreen_window_draw_points (GdkDrawable  *drawable,
-                                 GdkGC        *gc,
-                                 GdkPoint     *points,
-                                 gint          npoints)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
+      /* Don't create loops in hierarchy */
+      if (is_parent_of (window, new_parent))
+       return FALSE;
+    }
 
-  gdk_draw_points (real_drawable,
-                  gc,
-                  points,
-                  npoints);
+  was_mapped = GDK_WINDOW_IS_MAPPED (window);
 
+  gdk_window_hide (window);
 
-  if (npoints > 0)
-    {
-      int min_x, min_y, max_x, max_y, i;
-      
-      min_x = max_x = points[0].x;
-      min_y = max_y = points[0].y;
-      
-       for (i = 1; i < npoints; i++)
-         {
-           min_x = MIN (min_x, points[i].x);
-           max_x = MAX (max_x, points[i].x);
-           min_y = MIN (min_y, points[i].y);
-           max_y = MAX (max_y, points[i].y);
-         }
-       
-       add_damage (offscreen, min_x, min_y,
-                   max_x - min_x,
-                   max_y - min_y);
-    }
-}
+  if (window->parent)
+    window->parent->children = g_list_remove (window->parent->children, window);
 
-static void
-gdk_offscreen_window_draw_segments (GdkDrawable  *drawable,
-                                   GdkGC        *gc,
-                                   GdkSegment   *segs,
-                                   gint          nsegs)
-{
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
+  old_parent = window->parent;
+  window->parent = new_parent;
+  window->x = x;
+  window->y = y;
 
-  gdk_draw_segments (real_drawable,
-                    gc,
-                    segs,
-                    nsegs);
+  if (new_parent)
+    window->parent->children = g_list_prepend (window->parent->children, window);
 
-  if (nsegs > 0)
-    {
-      int min_x, min_y, max_x, max_y, i;
-      
-      min_x = max_x = segs[0].x1;
-      min_y = max_y = segs[0].y1;
-      
-       for (i = 1; i < nsegs; i++)
-         {
-           min_x = MIN (min_x, segs[i].x1);
-           max_x = MAX (max_x, segs[i].x1);
-           min_x = MIN (min_x, segs[i].x2);
-           max_x = MAX (max_x, segs[i].x2);
-           min_y = MIN (min_y, segs[i].y1);
-           max_y = MAX (max_y, segs[i].y1);
-           min_y = MIN (min_y, segs[i].y2);
-           max_y = MAX (max_y, segs[i].y2);
-         }
-       
-       add_damage (offscreen, min_x, min_y,
-                   max_x - min_x,
-                   max_y - min_y);
-    }
+  _gdk_synthesize_crossing_events_for_geometry_change (window);
+  if (old_parent)
+    _gdk_synthesize_crossing_events_for_geometry_change (old_parent);
 
+  return was_mapped;
 }
 
 static void
-gdk_offscreen_window_draw_lines (GdkDrawable  *drawable,
-                                GdkGC        *gc,
-                                GdkPoint     *points,
-                                gint          npoints)
+gdk_offscreen_window_set_device_cursor (GdkWindow     *window,
+                                       GdkDevice     *device,
+                                       GdkCursor     *cursor)
 {
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper);
-
-  gdk_draw_lines (real_drawable,
-                 gc,
-                 points,
-                 npoints);
-
-  /* Hard to compute the minimal size, as we don't know the line
-     width, and since joins are hard to calculate.
-     Its not that often used anyway, damage it all */
-  add_damage (offscreen, 0, 0, private->width, private->height);
 }
 
 static void
-gdk_offscreen_window_draw_image (GdkDrawable *drawable,
-                                GdkGC        *gc,
-                                GdkImage    *image,
-                                gint          xsrc,
-                                gint          ysrc,
-                                gint          xdest,
-                                gint          ydest,
-                                gint          width,
-                                gint          height)
+from_embedder (GdkWindow *window,
+              double embedder_x, double embedder_y,
+              double *offscreen_x, double *offscreen_y)
 {
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-
-  gdk_draw_image (real_drawable,
-                 gc,
-                 image,
-                 xsrc,
-                 ysrc,
-                 xdest,
-                 ydest,
-                 width,
-                 height);
-
-  add_damage (offscreen, xdest, ydest, width, height);
+  g_signal_emit_by_name (window->impl_window,
+                        "from-embedder",
+                        embedder_x, embedder_y,
+                        offscreen_x, offscreen_y,
+                        NULL);
 }
 
-
 static void
-gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable,
-                                 GdkGC       *gc,
-                                 GdkPixbuf   *pixbuf,
-                                 gint         src_x,
-                                 gint         src_y,
-                                 gint         dest_x,
-                                 gint         dest_y,
-                                 gint         width,
-                                 gint         height,
-                                 GdkRgbDither dither,
-                                 gint         x_dither,
-                                 gint         y_dither)
+to_embedder (GdkWindow *window,
+            double offscreen_x, double offscreen_y,
+            double *embedder_x, double *embedder_y)
 {
-  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
-  GdkDrawable *real_drawable = get_real_drawable (offscreen);
-  
-  gdk_draw_pixbuf (real_drawable,
-                  gc,
-                  pixbuf,
-                  src_x,
-                  src_y,
-                  dest_x,
-                  dest_y,
-                  width,
-                  height,
-                  dither,
-                  x_dither,
-                  y_dither);
-
-  add_damage (offscreen, dest_x, dest_y, width, height);
-
+  g_signal_emit_by_name (window->impl_window,
+                        "to-embedder",
+                        offscreen_x, offscreen_y,
+                        embedder_x, embedder_y,
+                        NULL);
 }
 
-void 
-_gdk_offscreen_window_new (GdkWindow     *window,
-                          GdkScreen     *screen,
-                          GdkVisual     *visual,
-                          GdkWindowAttr *attributes,
-                          gint           attributes_mask)
+static gint
+gdk_offscreen_window_get_root_coords (GdkWindow *window,
+                                     gint       x,
+                                     gint       y,
+                                     gint      *root_x,
+                                     gint      *root_y)
 {
-  GdkWindowObject *parent_private;
-  GdkWindowObject *private;
   GdkOffscreenWindow *offscreen;
+  int tmpx, tmpy;
 
-  g_return_if_fail (attributes != NULL);
-
-  if (attributes->wclass != GDK_INPUT_OUTPUT)
-    return; /* Can't support input only offscreens */
-  
-  private = (GdkWindowObject *)window;
-
-  if (private->parent != NULL && GDK_WINDOW_DESTROYED (private->parent))
-    return;
-
-  parent_private = (GdkWindowObject*) private->parent;
-  private->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL);
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
-  offscreen->wrapper = window;
-
-  offscreen->screen = screen;
+  tmpx = x;
+  tmpy = y;
 
-  if (attributes_mask & GDK_WA_COLORMAP)
-    offscreen->colormap = g_object_ref (attributes->colormap);
-  else
+  offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
+  if (offscreen->embedder)
     {
-      if (gdk_screen_get_system_visual (screen) == visual)
-       {
-         offscreen->colormap = gdk_screen_get_system_colormap (screen);
-         g_object_ref (offscreen->colormap);
-       }
-      else
-       offscreen->colormap = gdk_colormap_new (visual, FALSE);
+      double dx, dy;
+      to_embedder (window,
+                  x, y,
+                  &dx, &dy);
+      tmpx = floor (dx + 0.5);
+      tmpy = floor (dy + 0.5);
+      gdk_window_get_root_coords (offscreen->embedder,
+                                 tmpx, tmpy,
+                                 &tmpx, &tmpy);
+
     }
 
-  offscreen->pixmap = gdk_pixmap_new ((GdkDrawable *)private->parent,
-                                     private->width,
-                                     private->height,
-                                     private->depth);
+  if (root_x)
+    *root_x = tmpx;
+  if (root_y)
+    *root_y = tmpy;
+
+  return TRUE;
 }
 
 static gboolean
-gdk_offscreen_window_reparent (GdkWindow *window,
-                              GdkWindow *new_parent,
-                              gint       x,
-                              gint       y)
+gdk_offscreen_window_get_device_state (GdkWindow       *window,
+                                       GdkDevice       *device,
+                                       gint            *x,
+                                       gint            *y,
+                                       GdkModifierType *mask)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkWindowObject *new_parent_private = (GdkWindowObject *)new_parent;
-  GdkWindowObject *old_parent;
   GdkOffscreenWindow *offscreen;
-  gboolean was_mapped;
+  int tmpx, tmpy;
+  double dtmpx, dtmpy;
+  GdkModifierType tmpmask;
 
-  if (new_parent)
+  tmpx = 0;
+  tmpy = 0;
+  tmpmask = 0;
+
+  offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
+  if (offscreen->embedder != NULL)
     {
-      /* No input-output children of input-only windows */
-      if (new_parent_private->input_only && !private->input_only)
-       return FALSE;
-      
-      /* Don't create loops in hierarchy */
-      if (is_parent_of (window, new_parent))
-       return FALSE;
+      gdk_window_get_device_position (offscreen->embedder, device, &tmpx, &tmpy, &tmpmask);
+      from_embedder (window,
+                    tmpx, tmpy,
+                    &dtmpx, &dtmpy);
+      tmpx = floor (dtmpx + 0.5);
+      tmpy = floor (dtmpy + 0.5);
     }
 
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
-
-  was_mapped = GDK_WINDOW_IS_MAPPED (window);
-
-  gdk_window_hide (window);
-
-  if (private->parent)
-    private->parent->children = g_list_remove (private->parent->children, window);
-
-  old_parent = private->parent;
-  private->parent = new_parent_private;
-  private->x = x;
-  private->y = y;
-
-  if (new_parent_private)
-    private->parent->children = g_list_prepend (private->parent->children, window);
-
-  _gdk_syntesize_crossing_events_for_geometry_change (window);
-  if (old_parent)
-    _gdk_syntesize_crossing_events_for_geometry_change (GDK_WINDOW (old_parent));
-  
-  return was_mapped;
-}
-
-static gint
-gdk_offscreen_window_get_origin (GdkWindow *window,
-                                gint      *x,
-                                gint      *y)
-{
   if (x)
-    *x = 0;
+    *x = tmpx;
   if (y)
-    *y = 0;
-
+    *y = tmpy;
+  if (mask)
+    *mask = tmpmask;
   return TRUE;
 }
 
 /**
- * gdk_window_get_offscreen_pixmap:
+ * gdk_offscreen_window_get_surface:
  * @window: a #GdkWindow
  *
- * Gets the offscreen pixmap that an offscreen window renders into. If
- * you need to keep this around over window resizes, you need to add a
- * reference to it.
+ * Gets the offscreen surface that an offscreen window renders into.
+ * If you need to keep this around over window resizes, you need to
+ * add a reference to it.
  *
- * Returns: The offscreen pixmap, or NULL if not offscreen
- **/
-GdkPixmap *
-gdk_window_get_offscreen_pixmap (GdkWindow *window)
+ * Returns: (transfer none): The offscreen surface, or %NULL if not offscreen
+ */
+cairo_surface_t *
+gdk_offscreen_window_get_surface (GdkWindow *window)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
   GdkOffscreenWindow *offscreen;
-  
+
   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
 
-  if (!GDK_IS_OFFSCREEN_WINDOW (private->impl))
+  if (!GDK_IS_OFFSCREEN_WINDOW (window->impl))
     return NULL;
-  
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
-  return offscreen->pixmap;
+
+  offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
+
+  return get_surface (offscreen);
 }
 
 static void
 gdk_offscreen_window_raise (GdkWindow *window)
 {
   /* gdk_window_raise already changed the stacking order */
-  _gdk_syntesize_crossing_events_for_geometry_change (window);
+  _gdk_synthesize_crossing_events_for_geometry_change (window);
 }
 
 static void
 gdk_offscreen_window_lower (GdkWindow *window)
 {
   /* gdk_window_lower already changed the stacking order */
-  _gdk_syntesize_crossing_events_for_geometry_change (window);
+  _gdk_synthesize_crossing_events_for_geometry_change (window);
 }
 
 static void
 gdk_offscreen_window_move_resize_internal (GdkWindow *window,
-                                          gint       x,
-                                          gint       y,
-                                          gint       width,
-                                          gint       height,
-                                          gboolean   send_expose_events)
+                                           gint       x,
+                                           gint       y,
+                                           gint       width,
+                                           gint       height,
+                                           gboolean   send_expose_events)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
   GdkOffscreenWindow *offscreen;
-  gint dx, dy, dw, dh;
-  GdkGC *gc;
-  GdkPixmap *old_pixmap;
 
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
+  offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
 
   if (width < 1)
     width = 1;
   if (height < 1)
     height = 1;
 
-  if (private->destroyed)
+  if (window->destroyed)
     return;
 
-  dx = x - private->x;
-  dy = y - private->y;
-  dw = width - private->width;
-  dh = height - private->height;
-
-  private->x = x;
-  private->y = y;
+  window->x = x;
+  window->y = y;
 
-  if (private->width != width ||
-      private->height != height)
+  if (window->width != width ||
+      window->height != height)
     {
-      private->width = width;
-      private->height = height;
-      
-      old_pixmap = offscreen->pixmap;
-      offscreen->pixmap = gdk_pixmap_new (GDK_DRAWABLE (old_pixmap),
-                                         width,
-                                         height,
-                                         private->depth);
-
-      gc = _gdk_drawable_get_scratch_gc (offscreen->pixmap, FALSE);
-      gdk_draw_drawable (offscreen->pixmap,
-                        gc,
-                        old_pixmap,
-                        0,0, 0, 0,
-                        -1, -1);
-      g_object_unref (old_pixmap);
+      window->width = width;
+      window->height = height;
+
+      if (offscreen->surface)
+        {
+          cairo_surface_t *old_surface;
+          cairo_t *cr;
+
+          old_surface = offscreen->surface;
+          offscreen->surface = NULL;
+
+          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))
+
+  if (GDK_WINDOW_IS_MAPPED (window))
     {
-      // TODO: Only invalidate new area, i.e. for larger windows
+      /* TODO: Only invalidate new area, i.e. for larger windows */
       gdk_window_invalidate_rect (window, NULL, TRUE);
-      _gdk_syntesize_crossing_events_for_geometry_change (window);
+      _gdk_synthesize_crossing_events_for_geometry_change (window);
     }
 }
 
 static void
 gdk_offscreen_window_move_resize (GdkWindow *window,
                                   gboolean   with_move,
-                                 gint       x,
+                                  gint       x,
                                   gint       y,
-                                 gint       width,
+                                  gint       width,
                                   gint       height)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkOffscreenWindow *offscreen;
-
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
-
   if (!with_move)
     {
-      x = private->x;
-      y = private->y;
+      x = window->x;
+      y = window->y;
     }
 
   if (width < 0)
-    width = private->width;
+    width = window->width;
 
   if (height < 0)
-    height = private->height;
+    height = window->height;
 
-  gdk_offscreen_window_move_resize_internal (window, x, y,
-                                            width, height,
-                                            TRUE);
+  gdk_offscreen_window_move_resize_internal (window,
+                                             x, y, width, height,
+                                             TRUE);
 }
 
 static void
-gdk_offscreen_window_show (GdkWindow *window)
+gdk_offscreen_window_show (GdkWindow *window,
+                          gboolean already_mapped)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkRectangle area = { 0, 0, window->width, window->height };
 
-  gdk_window_clear_area_e (window, 0, 0,
-                          private->width, private->height);
+  gdk_window_invalidate_rect (window, &area, FALSE);
 }
 
 
 static void
 gdk_offscreen_window_hide (GdkWindow *window)
 {
-  GdkWindowObject *private;
+  /* TODO: This needs updating to the new grab world */
+#if 0
   GdkOffscreenWindow *offscreen;
   GdkDisplay *display;
 
   g_return_if_fail (window != NULL);
 
-  private = (GdkWindowObject*) window;
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
+  offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
 
   /* May need to break grabs on children */
-  display = gdk_drawable_get_display (window);
+  display = gdk_window_get_display (window);
 
-  /* TODO: This needs updating to the new grab world */
-#if 0
   if (display->pointer_grab.window != NULL)
     {
       if (is_parent_of (window, display->pointer_grab.window))
@@ -891,61 +501,21 @@ gdk_offscreen_window_set_events (GdkWindow       *window,
 
 static void
 gdk_offscreen_window_set_background (GdkWindow      *window,
-                                    const GdkColor *color)
-{
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkColormap *colormap = gdk_drawable_get_colormap (window);
-
-  private->bg_color = *color;
-  gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color);
-
-  if (private->bg_pixmap &&
-      private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
-      private->bg_pixmap != GDK_NO_BG)
-    g_object_unref (private->bg_pixmap);
-
-  private->bg_pixmap = NULL;
-}
-
-static void
-gdk_offscreen_window_set_back_pixmap (GdkWindow *window,
-                                     GdkPixmap *pixmap)
+                                    cairo_pattern_t *pattern)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
-
-  if (pixmap &&
-      private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
-      private->bg_pixmap != GDK_NO_BG &&
-      !gdk_drawable_get_colormap (pixmap))
-    {
-      g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
-      return;
-    }
-
-  if (private->bg_pixmap &&
-      private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
-      private->bg_pixmap != GDK_NO_BG)
-    g_object_unref (private->bg_pixmap);
-
-  private->bg_pixmap = pixmap;
-
-  if (pixmap &&
-      private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
-      private->bg_pixmap != GDK_NO_BG)
-    g_object_ref (pixmap);
 }
 
 static void
 gdk_offscreen_window_shape_combine_region (GdkWindow       *window,
-                                           const GdkRegion *shape_region,
-                                           gint             offset_x,
-                                           gint             offset_y)
+                                          const cairo_region_t *shape_region,
+                                          gint             offset_x,
+                                          gint             offset_y)
 {
 }
 
 static void
 gdk_offscreen_window_input_shape_combine_region (GdkWindow       *window,
-                                                const GdkRegion *shape_region,
+                                                const cairo_region_t *shape_region,
                                                 gint             offset_x,
                                                 gint             offset_y)
 {
@@ -959,128 +529,275 @@ gdk_offscreen_window_set_static_gravities (GdkWindow *window,
 }
 
 static void
-gdk_offscreen_window_set_cursor (GdkWindow *window,
-                                GdkCursor *cursor)
+gdk_offscreen_window_get_geometry (GdkWindow *window,
+                                  gint      *x,
+                                  gint      *y,
+                                  gint      *width,
+                                  gint      *height)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkOffscreenWindow *offscreen;
+  if (!GDK_WINDOW_DESTROYED (window))
+    {
+      if (x)
+       *x = window->x;
+      if (y)
+       *y = window->y;
+      if (width)
+       *width = window->width;
+      if (height)
+       *height = window->height;
+    }
+}
 
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
+static gboolean
+gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
+                                      cairo_region_t *area)
+{
+  return FALSE;
+}
+
+static void
+gdk_offscreen_window_translate (GdkWindow      *window,
+                                cairo_region_t *area,
+                                gint            dx,
+                                gint            dy)
+{
+  GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
 
-  if (offscreen->cursor)
+  if (offscreen->surface)
     {
-      gdk_cursor_unref (offscreen->cursor);
-      offscreen->cursor = NULL;
+      cairo_t *cr;
+
+      cr = cairo_create (offscreen->surface);
+
+      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_pop_group_to_source (cr);
+      cairo_paint (cr);
+
+      cairo_destroy (cr);
     }
 
-  if (cursor)
-    offscreen->cursor = gdk_cursor_ref (cursor);
+  _gdk_window_add_damage (window, area);
+}
 
-  /* TODO: The cursor is never actually used... */
+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;
 }
 
-static void
-gdk_offscreen_window_get_geometry (GdkWindow *window,
-                                  gint      *x,
-                                  gint      *y,
-                                  gint      *width,
-                                  gint      *height,
-                                  gint      *depth)
+/**
+ * gdk_offscreen_window_set_embedder:
+ * @window: a #GdkWindow
+ * @embedder: the #GdkWindow that @window gets embedded in
+ *
+ * Sets @window to be embedded in @embedder.
+ *
+ * To fully embed an offscreen window, in addition to calling this
+ * function, it is also necessary to handle the #GdkWindow::pick-embedded-child
+ * signal on the @embedder and the #GdkWindow::to-embedder and
+ * #GdkWindow::from-embedder signals on @window.
+ *
+ * Since: 2.18
+ */
+void
+gdk_offscreen_window_set_embedder (GdkWindow     *window,
+                                  GdkWindow     *embedder)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
   GdkOffscreenWindow *offscreen;
 
-  offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
+  g_return_if_fail (GDK_IS_WINDOW (window));
 
-  g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
+  if (!GDK_IS_OFFSCREEN_WINDOW (window->impl))
+    return;
 
-  if (!GDK_WINDOW_DESTROYED (window))
+  offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
+
+  if (embedder)
     {
-      if (x)
-       *x = private->x;
-      if (y)
-       *y = private->y;
-      if (width)
-       *width = private->width;
-      if (height)
-       *height = private->height;
-      if (depth)
-       *depth = private->depth;
+      g_object_ref (embedder);
+      embedder->num_offscreen_children++;
     }
+
+  if (offscreen->embedder)
+    {
+      g_object_unref (offscreen->embedder);
+      offscreen->embedder->num_offscreen_children--;
+    }
+
+  offscreen->embedder = embedder;
 }
 
-static gboolean
-gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
-                                      GdkRegion *area)
+/**
+ * gdk_offscreen_window_get_embedder:
+ * @window: a #GdkWindow
+ *
+ * Gets the window that @window is embedded in.
+ *
+ * Returns: (transfer none): the embedding #GdkWindow, or %NULL
+ *     if @window is not an mbedded offscreen window
+ *
+ * Since: 2.18
+ */
+GdkWindow *
+gdk_offscreen_window_get_embedder (GdkWindow *window)
 {
-  return FALSE;
+  GdkOffscreenWindow *offscreen;
+
+  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+
+  if (!GDK_IS_OFFSCREEN_WINDOW (window->impl))
+    return NULL;
+
+  offscreen = GDK_OFFSCREEN_WINDOW (window->impl);
+
+  return offscreen->embedder;
 }
 
 static void
-gdk_offscreen_window_queue_translation (GdkWindow *window,
-                                       GdkRegion *area,
-                                       gint       dx,
-                                       gint       dy)
+gdk_offscreen_window_do_nothing (GdkWindow *window)
 {
 }
 
+static void
+gdk_offscreen_window_set_boolean (GdkWindow *window,
+                                  gboolean   setting)
+{
+}
 
 static void
-gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
+gdk_offscreen_window_set_string (GdkWindow *window,
+                                const gchar *setting)
 {
-  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+}
 
-  object_class->finalize = gdk_offscreen_window_finalize;
+static void
+gdk_offscreen_window_set_list (GdkWindow *window,
+                               GList *list)
+{
+}
 
-  drawable_class->create_gc = gdk_offscreen_window_create_gc;
-  drawable_class->_copy_to_image = gdk_offscreen_window_copy_to_image;
-  drawable_class->ref_cairo_surface = gdk_offscreen_window_ref_cairo_surface;
-  drawable_class->set_colormap = gdk_offscreen_window_set_colormap;
-  drawable_class->get_colormap = gdk_offscreen_window_get_colormap;
-  drawable_class->get_depth = gdk_offscreen_window_get_depth;
-  drawable_class->get_screen = gdk_offscreen_window_get_screen;
-  drawable_class->get_visual = gdk_offscreen_window_get_visual;
-  drawable_class->get_source_drawable = gdk_offscreen_window_get_source_drawable;
-  drawable_class->get_composite_drawable = gdk_offscreen_window_get_composite_drawable;
-
-  drawable_class->draw_rectangle = gdk_offscreen_window_draw_rectangle;
-  drawable_class->draw_arc = gdk_offscreen_window_draw_arc;
-  drawable_class->draw_polygon = gdk_offscreen_window_draw_polygon;
-  drawable_class->draw_text = gdk_offscreen_window_draw_text;
-  drawable_class->draw_text_wc = gdk_offscreen_window_draw_text_wc;
-  drawable_class->draw_drawable = gdk_offscreen_window_draw_drawable;
-  drawable_class->draw_points = gdk_offscreen_window_draw_points;
-  drawable_class->draw_segments = gdk_offscreen_window_draw_segments;
-  drawable_class->draw_lines = gdk_offscreen_window_draw_lines;
-  drawable_class->draw_image = gdk_offscreen_window_draw_image;
-  drawable_class->draw_pixbuf = gdk_offscreen_window_draw_pixbuf;
+static void
+gdk_offscreen_window_set_wmfunctions (GdkWindow            *window,
+                                     GdkWMFunction  functions)
+{
+}
+
+static void
+gdk_offscreen_window_set_transient_for (GdkWindow *window,
+                                       GdkWindow *another)
+{
 }
 
 static void
-gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface)
+gdk_offscreen_window_process_updates_recurse (GdkWindow *window,
+                                              cairo_region_t *region)
 {
-  iface->show = gdk_offscreen_window_show;
-  iface->hide = gdk_offscreen_window_hide;
-  iface->withdraw = gdk_offscreen_window_withdraw;
-  iface->raise = gdk_offscreen_window_raise;
-  iface->lower = gdk_offscreen_window_lower;
-  iface->move_resize = gdk_offscreen_window_move_resize;
-  iface->set_background = gdk_offscreen_window_set_background;
-  iface->set_back_pixmap = gdk_offscreen_window_set_back_pixmap;
-  iface->get_events = gdk_offscreen_window_get_events;
-  iface->set_events = gdk_offscreen_window_set_events;
-  iface->reparent = gdk_offscreen_window_reparent;
-  iface->set_cursor = gdk_offscreen_window_set_cursor;
-  iface->get_geometry = gdk_offscreen_window_get_geometry;
-  iface->shape_combine_region = gdk_offscreen_window_shape_combine_region;
-  iface->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
-  iface->set_static_gravities = gdk_offscreen_window_set_static_gravities;
-  iface->queue_antiexpose = gdk_offscreen_window_queue_antiexpose;
-  iface->queue_translation = gdk_offscreen_window_queue_translation;
-  iface->get_origin = gdk_offscreen_window_get_origin;
-  iface->destroy = gdk_offscreen_window_destroy;
+  _gdk_window_process_updates_recurse (window, region);
 }
 
-#define __GDK_OFFSCREEN_WINDOW_C__
-#include "gdkaliasdef.c"
+static void
+gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
+{
+  GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gdk_offscreen_window_finalize;
+
+  impl_class->ref_cairo_surface = gdk_offscreen_window_ref_cairo_surface;
+  impl_class->show = gdk_offscreen_window_show;
+  impl_class->hide = gdk_offscreen_window_hide;
+  impl_class->withdraw = gdk_offscreen_window_withdraw;
+  impl_class->set_events = gdk_offscreen_window_set_events;
+  impl_class->get_events = gdk_offscreen_window_get_events;
+  impl_class->raise = gdk_offscreen_window_raise;
+  impl_class->lower = gdk_offscreen_window_lower;
+  impl_class->restack_under = NULL;
+  impl_class->restack_toplevel = NULL;
+  impl_class->move_resize = gdk_offscreen_window_move_resize;
+  impl_class->set_background = gdk_offscreen_window_set_background;
+  impl_class->reparent = gdk_offscreen_window_reparent;
+  impl_class->set_device_cursor = gdk_offscreen_window_set_device_cursor;
+  impl_class->get_geometry = gdk_offscreen_window_get_geometry;
+  impl_class->get_root_coords = gdk_offscreen_window_get_root_coords;
+  impl_class->get_device_state = gdk_offscreen_window_get_device_state;
+  impl_class->shape_combine_region = gdk_offscreen_window_shape_combine_region;
+  impl_class->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
+  impl_class->set_static_gravities = gdk_offscreen_window_set_static_gravities;
+  impl_class->queue_antiexpose = gdk_offscreen_window_queue_antiexpose;
+  impl_class->translate = gdk_offscreen_window_translate;
+  impl_class->destroy = gdk_offscreen_window_destroy;
+  impl_class->destroy_foreign = NULL;
+  impl_class->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface;
+  impl_class->get_shape = NULL;
+  impl_class->get_input_shape = NULL;
+  impl_class->beep = NULL;
+
+  impl_class->focus = NULL;
+  impl_class->set_type_hint = NULL;
+  impl_class->get_type_hint = NULL;
+  impl_class->set_modal_hint = NULL;
+  impl_class->set_skip_taskbar_hint = gdk_offscreen_window_set_boolean;
+  impl_class->set_skip_pager_hint = gdk_offscreen_window_set_boolean;
+  impl_class->set_urgency_hint = gdk_offscreen_window_set_boolean;
+  impl_class->set_geometry_hints = NULL;
+  impl_class->set_title = gdk_offscreen_window_set_string;
+  impl_class->set_role = gdk_offscreen_window_set_string;
+  impl_class->set_startup_id = gdk_offscreen_window_set_string;
+  impl_class->set_transient_for = gdk_offscreen_window_set_transient_for;
+  impl_class->get_root_origin = NULL;
+  impl_class->get_frame_extents = NULL;
+  impl_class->set_override_redirect = NULL;
+  impl_class->set_accept_focus = NULL;
+  impl_class->set_focus_on_map = gdk_offscreen_window_set_boolean;
+  impl_class->set_icon_list = gdk_offscreen_window_set_list;
+  impl_class->set_icon_name = gdk_offscreen_window_set_string;
+  impl_class->iconify = gdk_offscreen_window_do_nothing;
+  impl_class->deiconify = gdk_offscreen_window_do_nothing;
+  impl_class->stick = gdk_offscreen_window_do_nothing;
+  impl_class->unstick = gdk_offscreen_window_do_nothing;
+  impl_class->maximize = gdk_offscreen_window_do_nothing;
+  impl_class->unmaximize = gdk_offscreen_window_do_nothing;
+  impl_class->fullscreen = gdk_offscreen_window_do_nothing;
+  impl_class->unfullscreen = gdk_offscreen_window_do_nothing;
+  impl_class->set_keep_above = gdk_offscreen_window_set_boolean;
+  impl_class->set_keep_below = gdk_offscreen_window_set_boolean;
+  impl_class->get_group = NULL;
+  impl_class->set_group = NULL;
+  impl_class->set_decorations = NULL;
+  impl_class->get_decorations = NULL;
+  impl_class->set_functions = gdk_offscreen_window_set_wmfunctions;
+  impl_class->begin_resize_drag = NULL;
+  impl_class->begin_move_drag = NULL;
+  impl_class->enable_synchronized_configure = gdk_offscreen_window_do_nothing;
+  impl_class->configure_finished = NULL;
+  impl_class->set_opacity = NULL;
+  impl_class->set_composited = NULL;
+  impl_class->destroy_notify = NULL;
+  impl_class->register_dnd = gdk_offscreen_window_do_nothing;
+  impl_class->drag_begin = NULL;
+  impl_class->process_updates_recurse = gdk_offscreen_window_process_updates_recurse;
+  impl_class->sync_rendering = NULL;
+  impl_class->simulate_key = NULL;
+  impl_class->simulate_button = NULL;
+  impl_class->get_property = NULL;
+  impl_class->change_property = NULL;
+  impl_class->delete_property = NULL;
+}