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