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