]> Pileus Git - ~andy/gtk/blob - gdk/gdkoffscreenwindow.c
gdk: Remove _gdk_drawable_get_source_drawable()
[~andy/gtk] / gdk / gdkoffscreenwindow.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2005.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
25  */
26
27 #include <config.h>
28 #include <math.h>
29 #include "gdk.h"
30 #include "gdkwindow.h"
31 #include "gdkinternals.h"
32 #include "gdkwindowimpl.h"
33 #include "gdkdrawable.h"
34 #include "gdktypes.h"
35 #include "gdkscreen.h"
36 #include "gdkcolor.h"
37
38
39 /* LIMITATIONS:
40  *
41  * Offscreen windows can't be the child of a foreign window,
42  *   nor contain foreign windows
43  * GDK_POINTER_MOTION_HINT_MASK isn't effective
44  */
45
46 typedef struct _GdkOffscreenWindow      GdkOffscreenWindow;
47 typedef struct _GdkOffscreenWindowClass GdkOffscreenWindowClass;
48
49 struct _GdkOffscreenWindow
50 {
51   GdkDrawable parent_instance;
52
53   GdkWindow *wrapper;
54   GdkColormap *colormap;
55   GdkScreen *screen;
56
57   cairo_surface_t *surface;
58   GdkWindow *embedder;
59 };
60
61 struct _GdkOffscreenWindowClass
62 {
63   GdkDrawableClass parent_class;
64 };
65
66 #define GDK_TYPE_OFFSCREEN_WINDOW            (gdk_offscreen_window_get_type())
67 #define GDK_OFFSCREEN_WINDOW(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindow))
68 #define GDK_IS_OFFSCREEN_WINDOW(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_OFFSCREEN_WINDOW))
69 #define GDK_OFFSCREEN_WINDOW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindowClass))
70 #define GDK_IS_OFFSCREEN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_OFFSCREEN_WINDOW))
71 #define GDK_OFFSCREEN_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindowClass))
72
73 static void       gdk_offscreen_window_impl_iface_init    (GdkWindowImplIface         *iface);
74 static void       gdk_offscreen_window_hide               (GdkWindow                  *window);
75
76 G_DEFINE_TYPE_WITH_CODE (GdkOffscreenWindow,
77                          gdk_offscreen_window,
78                          GDK_TYPE_DRAWABLE,
79                          G_IMPLEMENT_INTERFACE (GDK_TYPE_WINDOW_IMPL,
80                                                 gdk_offscreen_window_impl_iface_init));
81
82
83 static void
84 gdk_offscreen_window_finalize (GObject *object)
85 {
86   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (object);
87
88   cairo_surface_destroy (offscreen->surface);
89
90   G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object);
91 }
92
93 static void
94 gdk_offscreen_window_init (GdkOffscreenWindow *window)
95 {
96 }
97
98 static void
99 gdk_offscreen_window_destroy (GdkWindow *window,
100                               gboolean   recursing,
101                               gboolean   foreign_destroy)
102 {
103   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
104   GdkOffscreenWindow *offscreen;
105
106   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
107
108   gdk_offscreen_window_set_embedder (window, NULL);
109   
110   if (!recursing)
111     gdk_offscreen_window_hide (window);
112
113   g_object_unref (offscreen->colormap);
114   offscreen->colormap = NULL;
115 }
116
117 static gboolean
118 is_parent_of (GdkWindow *parent,
119               GdkWindow *child)
120 {
121   GdkWindow *w;
122
123   w = child;
124   while (w != NULL)
125     {
126       if (w == parent)
127         return TRUE;
128
129       w = gdk_window_get_parent (w);
130     }
131
132   return FALSE;
133 }
134
135 static cairo_surface_t *
136 gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable)
137 {
138   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
139
140   return cairo_surface_reference (offscreen->surface);
141 }
142
143 static GdkColormap*
144 gdk_offscreen_window_get_colormap (GdkDrawable *drawable)
145 {
146   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
147
148   return offscreen->colormap;
149 }
150
151 static void
152 gdk_offscreen_window_set_colormap (GdkDrawable *drawable,
153                                    GdkColormap*colormap)
154 {
155   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
156
157   if (colormap && GDK_WINDOW_DESTROYED (offscreen->wrapper))
158     return;
159
160   if (offscreen->colormap == colormap)
161     return;
162
163   if (offscreen->colormap)
164     g_object_unref (offscreen->colormap);
165
166   offscreen->colormap = colormap;
167   if (offscreen->colormap)
168     g_object_ref (offscreen->colormap);
169 }
170
171
172 static gint
173 gdk_offscreen_window_get_depth (GdkDrawable *drawable)
174 {
175   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
176
177   return gdk_drawable_get_depth (offscreen->wrapper);
178 }
179
180 static GdkScreen*
181 gdk_offscreen_window_get_screen (GdkDrawable *drawable)
182 {
183   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
184
185   return offscreen->screen;
186 }
187
188 static GdkVisual*
189 gdk_offscreen_window_get_visual (GdkDrawable    *drawable)
190 {
191   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable);
192
193   return gdk_drawable_get_visual (offscreen->wrapper);
194 }
195
196 void
197 _gdk_offscreen_window_new (GdkWindow     *window,
198                            GdkScreen     *screen,
199                            GdkVisual     *visual,
200                            GdkWindowAttr *attributes,
201                            gint           attributes_mask)
202 {
203   GdkWindowObject *private;
204   GdkOffscreenWindow *offscreen;
205
206   g_return_if_fail (attributes != NULL);
207
208   if (attributes->wclass != GDK_INPUT_OUTPUT)
209     return; /* Can't support input only offscreens */
210
211   private = (GdkWindowObject *)window;
212
213   if (private->parent != NULL && GDK_WINDOW_DESTROYED (private->parent))
214     return;
215
216   private->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL);
217   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
218   offscreen->wrapper = window;
219
220   offscreen->screen = screen;
221
222   if (attributes_mask & GDK_WA_COLORMAP)
223     offscreen->colormap = g_object_ref (attributes->colormap);
224   else
225     {
226       if (gdk_screen_get_system_visual (screen) == visual)
227         {
228           offscreen->colormap = gdk_screen_get_system_colormap (screen);
229           g_object_ref (offscreen->colormap);
230         }
231       else
232         offscreen->colormap = gdk_colormap_new (visual, FALSE);
233     }
234
235   offscreen->surface = gdk_window_create_similar_surface ((GdkWindow *)private->parent,
236                                                           CAIRO_CONTENT_COLOR,
237                                                           private->width,
238                                                           private->height);
239 }
240
241 static gboolean
242 gdk_offscreen_window_reparent (GdkWindow *window,
243                                GdkWindow *new_parent,
244                                gint       x,
245                                gint       y)
246 {
247   GdkWindowObject *private = (GdkWindowObject *)window;
248   GdkWindowObject *new_parent_private = (GdkWindowObject *)new_parent;
249   GdkWindowObject *old_parent;
250   gboolean was_mapped;
251
252   if (new_parent)
253     {
254       /* No input-output children of input-only windows */
255       if (new_parent_private->input_only && !private->input_only)
256         return FALSE;
257
258       /* Don't create loops in hierarchy */
259       if (is_parent_of (window, new_parent))
260         return FALSE;
261     }
262
263   was_mapped = GDK_WINDOW_IS_MAPPED (window);
264
265   gdk_window_hide (window);
266
267   if (private->parent)
268     private->parent->children = g_list_remove (private->parent->children, window);
269
270   old_parent = private->parent;
271   private->parent = new_parent_private;
272   private->x = x;
273   private->y = y;
274
275   if (new_parent_private)
276     private->parent->children = g_list_prepend (private->parent->children, window);
277
278   _gdk_synthesize_crossing_events_for_geometry_change (window);
279   if (old_parent)
280     _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (old_parent));
281
282   return was_mapped;
283 }
284
285 static void
286 from_embedder (GdkWindow *window,
287                double embedder_x, double embedder_y,
288                double *offscreen_x, double *offscreen_y)
289 {
290   GdkWindowObject *private;
291
292   private = (GdkWindowObject *)window;
293
294   g_signal_emit_by_name (private->impl_window,
295                          "from-embedder",
296                          embedder_x, embedder_y,
297                          offscreen_x, offscreen_y,
298                          NULL);
299 }
300
301 static void
302 to_embedder (GdkWindow *window,
303              double offscreen_x, double offscreen_y,
304              double *embedder_x, double *embedder_y)
305 {
306   GdkWindowObject *private;
307
308   private = (GdkWindowObject *)window;
309
310   g_signal_emit_by_name (private->impl_window,
311                          "to-embedder",
312                          offscreen_x, offscreen_y,
313                          embedder_x, embedder_y,
314                          NULL);
315 }
316
317 static gint
318 gdk_offscreen_window_get_root_coords (GdkWindow *window,
319                                       gint       x,
320                                       gint       y,
321                                       gint      *root_x,
322                                       gint      *root_y)
323 {
324   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
325   GdkOffscreenWindow *offscreen;
326   int tmpx, tmpy;
327
328   tmpx = x;
329   tmpy = y;
330
331   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
332   if (offscreen->embedder)
333     {
334       double dx, dy;
335       to_embedder (window,
336                    x, y,
337                    &dx, &dy);
338       tmpx = floor (dx + 0.5);
339       tmpy = floor (dy + 0.5);
340       gdk_window_get_root_coords (offscreen->embedder,
341                                   tmpx, tmpy,
342                                   &tmpx, &tmpy);
343
344     }
345
346   if (root_x)
347     *root_x = tmpx;
348   if (root_y)
349     *root_y = tmpy;
350
351   return TRUE;
352 }
353
354 static gboolean
355 gdk_offscreen_window_get_device_state (GdkWindow       *window,
356                                        GdkDevice       *device,
357                                        gint            *x,
358                                        gint            *y,
359                                        GdkModifierType *mask)
360 {
361   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
362   GdkOffscreenWindow *offscreen;
363   int tmpx, tmpy;
364   double dtmpx, dtmpy;
365   GdkModifierType tmpmask;
366
367   tmpx = 0;
368   tmpy = 0;
369   tmpmask = 0;
370
371   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
372   if (offscreen->embedder != NULL)
373     {
374       gdk_window_get_device_position (offscreen->embedder, device, &tmpx, &tmpy, &tmpmask);
375       from_embedder (window,
376                      tmpx, tmpy,
377                      &dtmpx, &dtmpy);
378       tmpx = floor (dtmpx + 0.5);
379       tmpy = floor (dtmpy + 0.5);
380     }
381
382   if (x)
383     *x = tmpx;
384   if (y)
385     *y = tmpy;
386   if (mask)
387     *mask = tmpmask;
388   return TRUE;
389 }
390
391 /**
392  * gdk_offscreen_window_get_surface:
393  * @window: a #GdkWindow
394  *
395  * Gets the offscreen surface that an offscreen window renders into.
396  * If you need to keep this around over window resizes, you need to
397  * add a reference to it.
398  *
399  * Returns: The offscreen surface, or %NULL if not offscreen
400  */
401 cairo_surface_t *
402 gdk_offscreen_window_get_surface (GdkWindow *window)
403 {
404   GdkWindowObject *private = (GdkWindowObject *)window;
405   GdkOffscreenWindow *offscreen;
406
407   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
408
409   if (!GDK_IS_OFFSCREEN_WINDOW (private->impl))
410     return NULL;
411
412   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
413   return offscreen->surface;
414 }
415
416 static void
417 gdk_offscreen_window_raise (GdkWindow *window)
418 {
419   /* gdk_window_raise already changed the stacking order */
420   _gdk_synthesize_crossing_events_for_geometry_change (window);
421 }
422
423 static void
424 gdk_offscreen_window_lower (GdkWindow *window)
425 {
426   /* gdk_window_lower already changed the stacking order */
427   _gdk_synthesize_crossing_events_for_geometry_change (window);
428 }
429
430 static void
431 gdk_offscreen_window_move_resize_internal (GdkWindow *window,
432                                            gint       x,
433                                            gint       y,
434                                            gint       width,
435                                            gint       height,
436                                            gboolean   send_expose_events)
437 {
438   GdkWindowObject *private = (GdkWindowObject *)window;
439   GdkOffscreenWindow *offscreen;
440   gint dx, dy, dw, dh;
441   cairo_surface_t *old_surface;
442
443   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
444
445   if (width < 1)
446     width = 1;
447   if (height < 1)
448     height = 1;
449
450   if (private->destroyed)
451     return;
452
453   dx = x - private->x;
454   dy = y - private->y;
455   dw = width - private->width;
456   dh = height - private->height;
457
458   private->x = x;
459   private->y = y;
460
461   if (private->width != width ||
462       private->height != height)
463     {
464       cairo_t *cr;
465
466       private->width = width;
467       private->height = height;
468
469       old_surface = offscreen->surface;
470       offscreen->surface = cairo_surface_create_similar (old_surface,
471                                                          cairo_surface_get_content (old_surface),
472                                                          width,
473                                                          height);
474
475       cr = cairo_create (offscreen->surface);
476       cairo_set_source_surface (cr, old_surface, 0, 0);
477       cairo_paint (cr);
478       cairo_destroy (cr);
479
480       cairo_surface_destroy (old_surface);
481     }
482
483   if (GDK_WINDOW_IS_MAPPED (private))
484     {
485       // TODO: Only invalidate new area, i.e. for larger windows
486       gdk_window_invalidate_rect (window, NULL, TRUE);
487       _gdk_synthesize_crossing_events_for_geometry_change (window);
488     }
489 }
490
491 static void
492 gdk_offscreen_window_move_resize (GdkWindow *window,
493                                   gboolean   with_move,
494                                   gint       x,
495                                   gint       y,
496                                   gint       width,
497                                   gint       height)
498 {
499   GdkWindowObject *private = (GdkWindowObject *)window;
500   GdkOffscreenWindow *offscreen;
501
502   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
503
504   if (!with_move)
505     {
506       x = private->x;
507       y = private->y;
508     }
509
510   if (width < 0)
511     width = private->width;
512
513   if (height < 0)
514     height = private->height;
515
516   gdk_offscreen_window_move_resize_internal (window, x, y,
517                                              width, height,
518                                              TRUE);
519 }
520
521 static void
522 gdk_offscreen_window_show (GdkWindow *window,
523                            gboolean already_mapped)
524 {
525   GdkWindowObject *private = (GdkWindowObject *)window;
526   GdkRectangle area = { 0, 0, private->width, private->height };
527
528   gdk_window_clear_area (window, 0, 0,
529                          private->width, private->height);
530   gdk_window_invalidate_rect (window, &area, FALSE);
531 }
532
533
534 static void
535 gdk_offscreen_window_hide (GdkWindow *window)
536 {
537   GdkWindowObject *private;
538   GdkOffscreenWindow *offscreen;
539   GdkDisplay *display;
540
541   g_return_if_fail (window != NULL);
542
543   private = (GdkWindowObject*) window;
544   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
545
546   /* May need to break grabs on children */
547   display = gdk_drawable_get_display (window);
548
549   /* TODO: This needs updating to the new grab world */
550 #if 0
551   if (display->pointer_grab.window != NULL)
552     {
553       if (is_parent_of (window, display->pointer_grab.window))
554         {
555           /* Call this ourselves, even though gdk_display_pointer_ungrab
556              does so too, since we want to pass implicit == TRUE so the
557              broken grab event is generated */
558           _gdk_display_unset_has_pointer_grab (display,
559                                                TRUE,
560                                                FALSE,
561                                                GDK_CURRENT_TIME);
562           gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
563         }
564     }
565 #endif
566 }
567
568 static void
569 gdk_offscreen_window_withdraw (GdkWindow *window)
570 {
571 }
572
573 static GdkEventMask
574 gdk_offscreen_window_get_events (GdkWindow *window)
575 {
576   return 0;
577 }
578
579 static void
580 gdk_offscreen_window_set_events (GdkWindow       *window,
581                                  GdkEventMask     event_mask)
582 {
583 }
584
585 static void
586 gdk_offscreen_window_set_background (GdkWindow      *window,
587                                      cairo_pattern_t *pattern)
588 {
589 }
590
591 static void
592 gdk_offscreen_window_shape_combine_region (GdkWindow       *window,
593                                            const cairo_region_t *shape_region,
594                                            gint             offset_x,
595                                            gint             offset_y)
596 {
597 }
598
599 static void
600 gdk_offscreen_window_input_shape_combine_region (GdkWindow       *window,
601                                                  const cairo_region_t *shape_region,
602                                                  gint             offset_x,
603                                                  gint             offset_y)
604 {
605 }
606
607 static gboolean
608 gdk_offscreen_window_set_static_gravities (GdkWindow *window,
609                                            gboolean   use_static)
610 {
611   return TRUE;
612 }
613
614 static void
615 gdk_offscreen_window_get_geometry (GdkWindow *window,
616                                    gint      *x,
617                                    gint      *y,
618                                    gint      *width,
619                                    gint      *height,
620                                    gint      *depth)
621 {
622   GdkWindowObject *private = (GdkWindowObject *)window;
623
624   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
625
626   if (!GDK_WINDOW_DESTROYED (window))
627     {
628       if (x)
629         *x = private->x;
630       if (y)
631         *y = private->y;
632       if (width)
633         *width = private->width;
634       if (height)
635         *height = private->height;
636       if (depth)
637         *depth = private->depth;
638     }
639 }
640
641 static gboolean
642 gdk_offscreen_window_queue_antiexpose (GdkWindow *window,
643                                        cairo_region_t *area)
644 {
645   return FALSE;
646 }
647
648 static void
649 gdk_offscreen_window_translate (GdkWindow      *window,
650                                 cairo_region_t *area,
651                                 gint            dx,
652                                 gint            dy)
653 {
654   GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (((GdkWindowObject *) window)->impl);
655   cairo_t *cr;
656
657   cr = cairo_create (offscreen->surface);
658
659   area = cairo_region_copy (area);
660
661   gdk_cairo_region (cr, area);
662   cairo_clip (cr);
663   
664   /* NB: This is a self-copy and Cairo doesn't support that yet.
665    * So we do a litle trick.
666    */
667   cairo_push_group (cr);
668
669   cairo_set_source_surface (cr, offscreen->surface, dx, dy);
670   cairo_paint (cr);
671
672   cairo_pop_group_to_source (cr);
673   cairo_paint (cr);
674
675   cairo_destroy (cr);
676
677   _gdk_window_add_damage (window, area);
678 }
679
680 /**
681  * gdk_offscreen_window_set_embedder:
682  * @window: a #GdkWindow
683  * @embedder: the #GdkWindow that @window gets embedded in
684  *
685  * Sets @window to be embedded in @embedder.
686  *
687  * To fully embed an offscreen window, in addition to calling this
688  * function, it is also necessary to handle the #GdkWindow::pick-embedded-child
689  * signal on the @embedder and the #GdkWindow::to-embedder and
690  * #GdkWindow::from-embedder signals on @window.
691  *
692  * Since: 2.18
693  */
694 void
695 gdk_offscreen_window_set_embedder (GdkWindow     *window,
696                                    GdkWindow     *embedder)
697 {
698   GdkWindowObject *private = (GdkWindowObject *)window;
699   GdkOffscreenWindow *offscreen;
700
701   g_return_if_fail (GDK_IS_WINDOW (window));
702
703   if (!GDK_IS_OFFSCREEN_WINDOW (private->impl))
704     return;
705
706   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
707
708   if (embedder)
709     {
710       g_object_ref (embedder);
711       GDK_WINDOW_OBJECT (embedder)->num_offscreen_children++;
712     }
713
714   if (offscreen->embedder)
715     {
716       g_object_unref (offscreen->embedder);
717       GDK_WINDOW_OBJECT (offscreen->embedder)->num_offscreen_children--;
718     }
719
720   offscreen->embedder = embedder;
721 }
722
723 /**
724  * gdk_offscreen_window_get_embedder:
725  * @window: a #GdkWindow
726  *
727  * Gets the window that @window is embedded in.
728  *
729  * Returns: the embedding #GdkWindow, or %NULL if @window is not an
730  *     embedded offscreen window
731  *
732  * Since: 2.18
733  */
734 GdkWindow *
735 gdk_offscreen_window_get_embedder (GdkWindow *window)
736 {
737   GdkWindowObject *private = (GdkWindowObject *)window;
738   GdkOffscreenWindow *offscreen;
739
740   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
741
742   if (!GDK_IS_OFFSCREEN_WINDOW (private->impl))
743     return NULL;
744
745   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
746
747   return offscreen->embedder;
748 }
749
750 static void
751 gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass)
752 {
753   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
754   GObjectClass *object_class = G_OBJECT_CLASS (klass);
755
756   object_class->finalize = gdk_offscreen_window_finalize;
757
758   drawable_class->ref_cairo_surface = gdk_offscreen_window_ref_cairo_surface;
759   drawable_class->set_colormap = gdk_offscreen_window_set_colormap;
760   drawable_class->get_colormap = gdk_offscreen_window_get_colormap;
761   drawable_class->get_depth = gdk_offscreen_window_get_depth;
762   drawable_class->get_screen = gdk_offscreen_window_get_screen;
763   drawable_class->get_visual = gdk_offscreen_window_get_visual;
764 }
765
766 static void
767 gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface)
768 {
769   iface->show = gdk_offscreen_window_show;
770   iface->hide = gdk_offscreen_window_hide;
771   iface->withdraw = gdk_offscreen_window_withdraw;
772   iface->raise = gdk_offscreen_window_raise;
773   iface->lower = gdk_offscreen_window_lower;
774   iface->move_resize = gdk_offscreen_window_move_resize;
775   iface->set_background = gdk_offscreen_window_set_background;
776   iface->get_events = gdk_offscreen_window_get_events;
777   iface->set_events = gdk_offscreen_window_set_events;
778   iface->reparent = gdk_offscreen_window_reparent;
779   iface->get_geometry = gdk_offscreen_window_get_geometry;
780   iface->shape_combine_region = gdk_offscreen_window_shape_combine_region;
781   iface->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
782   iface->set_static_gravities = gdk_offscreen_window_set_static_gravities;
783   iface->queue_antiexpose = gdk_offscreen_window_queue_antiexpose;
784   iface->translate = gdk_offscreen_window_translate;
785   iface->get_root_coords = gdk_offscreen_window_get_root_coords;
786   iface->get_device_state = gdk_offscreen_window_get_device_state;
787   iface->destroy = gdk_offscreen_window_destroy;
788 }