]> Pileus Git - ~andy/gtk/blob - gdk/broadway/gdkwindow-broadway.c
[broadway] Remove unneeded _gdk_window_impl_get_type call
[~andy/gtk] / gdk / broadway / gdkwindow-broadway.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3  * Josh MacDonald, Ryan Lortie
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include "config.h"
29
30 #include "gdkwindow-broadway.h"
31 #include "gdkscreen-broadway.h"
32
33 #include "gdkwindow.h"
34 #include "gdkwindowimpl.h"
35 #include "gdkdisplay-broadway.h"
36 #include "gdkprivate-broadway.h"
37 #include "gdkinternals.h"
38 #include "gdkdeviceprivate.h"
39 #include "gdkeventsource.h"
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <netinet/in.h>
45 #include <unistd.h>
46
47 /* Forward declarations */
48 static void     gdk_window_broadway_set_background     (GdkWindow      *window,
49                                                    cairo_pattern_t *pattern);
50
51 static void        gdk_window_impl_broadway_finalize   (GObject            *object);
52
53 static const cairo_user_data_key_t gdk_broadway_cairo_key;
54
55 #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
56   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
57    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
58
59 #define WINDOW_IS_TOPLEVEL(window)                   \
60   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
61    GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
62    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
63
64 G_DEFINE_TYPE (GdkWindowImplBroadway,
65                gdk_window_impl_broadway,
66                GDK_TYPE_WINDOW_IMPL)
67
68 static void
69 diff_surfaces (cairo_surface_t *surface,
70                cairo_surface_t *old_surface)
71 {
72   guint8 *data, *old_data;
73   guint32 *line, *old_line;
74   int w, h, stride, old_stride;
75   int x, y;
76
77   data = cairo_image_surface_get_data (surface);
78   old_data = cairo_image_surface_get_data (old_surface);
79
80   w = cairo_image_surface_get_width (surface);
81   h = cairo_image_surface_get_height (surface);
82
83   stride = cairo_image_surface_get_stride (surface);
84   old_stride = cairo_image_surface_get_stride (old_surface);
85
86   for (y = 0; y < h; y++)
87     {
88       line = (guint32 *)data;
89       old_line = (guint32 *)old_data;
90
91       for (x = 0; x < w; x++)
92         {
93           if ((*line & 0xffffff) == (*old_line & 0xffffff))
94             *old_line = 0;
95           else
96             *old_line = *line | 0xff000000;
97           line ++;
98           old_line ++;
99         }
100
101       data += stride;
102       old_data += old_stride;
103     }
104 }
105
106 static guint dirty_flush_id = 0;
107
108 static void
109 window_data_send (BroadwayOutput *output, GdkWindowImplBroadway *impl)
110 {
111   cairo_t *cr;
112
113   if (impl->surface == NULL)
114     return;
115
116   if (impl->last_synced)
117     {
118       diff_surfaces (impl->surface,
119                      impl->last_surface);
120       broadway_output_put_rgba (output, impl->id, 0, 0,
121                                 cairo_image_surface_get_width (impl->last_surface),
122                                 cairo_image_surface_get_height (impl->last_surface),
123                                 cairo_image_surface_get_stride (impl->last_surface),
124                                 cairo_image_surface_get_data (impl->last_surface));
125     }
126   else
127     {
128       impl->last_synced = TRUE;
129       broadway_output_put_rgb (output, impl->id, 0, 0,
130                                cairo_image_surface_get_width (impl->surface),
131                                cairo_image_surface_get_height (impl->surface),
132                                cairo_image_surface_get_stride (impl->surface),
133                                cairo_image_surface_get_data (impl->surface));
134     }
135
136   cr = cairo_create (impl->last_surface);
137   cairo_set_source_surface (cr, impl->surface, 0, 0);
138   cairo_paint (cr);
139   cairo_destroy (cr);
140 }
141
142 static gboolean
143 dirty_flush_idle (gpointer data)
144 {
145   GList *l;
146   GdkDisplayBroadway *display;
147   BroadwayOutput *output;
148
149   dirty_flush_id = 0;
150
151   display = GDK_DISPLAY_BROADWAY (gdk_display_get_default ());
152   output = display->output;
153   if (output == NULL)
154     return FALSE;
155
156   for (l = display->toplevels; l != NULL; l = l->next)
157     {
158       GdkWindowImplBroadway *impl = l->data;
159
160       if (impl->dirty)
161         {
162           impl->dirty = FALSE;
163           window_data_send (display->output, impl);
164         }
165     }
166
167   if (!broadway_output_flush (display->output))
168     {
169       broadway_output_free (display->output);
170       display->output = NULL;
171     }
172
173   return FALSE;
174 }
175
176 static void
177 queue_dirty_flush (GdkDisplayBroadway *display)
178 {
179   if (dirty_flush_id == 0 && display->output != NULL)
180     dirty_flush_id = gdk_threads_add_idle (dirty_flush_idle, NULL);
181 }
182
183 void
184 _gdk_broadway_resync_windows (void)
185 {
186   GdkDisplayBroadway *display;
187   GList *l;
188
189   dirty_flush_id = 0;
190
191   display = GDK_DISPLAY_BROADWAY (gdk_display_get_default ());
192
193   for (l = display->toplevels; l != NULL; l = l->next)
194     {
195       GdkWindowImplBroadway *impl = l->data;
196       GdkWindow *window;
197
198       window = impl->wrapper;
199
200       if (impl->id == 0)
201         continue; /* Skip root */
202
203       impl->dirty = FALSE;
204       impl->last_synced = FALSE;
205       broadway_output_new_surface (display->output,
206                                    impl->id,
207                                    window->x,
208                                    window->y,
209                                    window->width,
210                                    window->height);
211       if (GDK_WINDOW_IS_MAPPED (window))
212         {
213           broadway_output_show_surface (display->output, impl->id);
214           window_data_send (display->output, impl);
215         }
216     }
217
218   broadway_output_flush (display->output);
219 }
220
221 static void
222 gdk_window_impl_broadway_init (GdkWindowImplBroadway *impl)
223 {
224   impl->toplevel_window_type = -1;
225   impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
226                                                (GDestroyNotify) gdk_cursor_unref);
227 }
228
229 static void
230 gdk_window_impl_broadway_finalize (GObject *object)
231 {
232   GdkWindow *wrapper;
233   GdkWindowImplBroadway *impl;
234   GdkDisplayBroadway *display_broadway;
235
236   g_return_if_fail (GDK_IS_WINDOW_IMPL_BROADWAY (object));
237
238   impl = GDK_WINDOW_IMPL_BROADWAY (object);
239
240   wrapper = impl->wrapper;
241
242   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (impl->wrapper));
243
244   if (display_broadway->mouse_in_toplevel == GDK_WINDOW (wrapper))
245     {
246       /* TODO: Send leave + enter event, update cursors, etc */
247       display_broadway->mouse_in_toplevel = NULL;
248     }
249
250   g_hash_table_remove (display_broadway->id_ht, GINT_TO_POINTER(impl->id));
251
252   if (impl->cursor)
253     gdk_cursor_unref (impl->cursor);
254
255   g_hash_table_destroy (impl->device_cursor);
256
257   display_broadway->toplevels = g_list_remove (display_broadway->toplevels, impl);
258
259   G_OBJECT_CLASS (gdk_window_impl_broadway_parent_class)->finalize (object);
260 }
261
262 void
263 _gdk_windowing_window_init (GdkScreen * screen)
264 {
265   GdkWindow *window;
266   GdkWindowImplBroadway *impl;
267   GdkScreenBroadway *screen_broadway;
268
269   screen_broadway = GDK_SCREEN_BROADWAY (screen);
270
271   g_assert (screen_broadway->root_window == NULL);
272
273   screen_broadway->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
274
275   window = screen_broadway->root_window;
276   window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_BROADWAY, NULL);
277   window->impl_window = window;
278   window->visual = gdk_screen_get_system_visual (screen);
279
280   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
281
282   impl->screen = screen;
283   impl->wrapper = window;
284
285   window->window_type = GDK_WINDOW_ROOT;
286   window->depth = 24;
287
288   window->x = 0;
289   window->y = 0;
290   window->abs_x = 0;
291   window->abs_y = 0;
292   window->width = gdk_screen_get_width (screen);
293   window->height = gdk_screen_get_height (screen);
294   window->viewable = TRUE;
295
296   _gdk_window_update_size (screen_broadway->root_window);
297 }
298
299 void
300 _gdk_window_impl_new (GdkWindow     *window,
301                       GdkWindow     *real_parent,
302                       GdkScreen     *screen,
303                       GdkEventMask   event_mask,
304                       GdkWindowAttr *attributes,
305                       gint           attributes_mask)
306 {
307   GdkWindowImplBroadway *impl;
308   GdkScreenBroadway *screen_broadway;
309   GdkDisplayBroadway *display_broadway;
310   static int current_id = 1; /* 0 is the root window */
311
312   screen_broadway = GDK_SCREEN_BROADWAY (screen);
313   display_broadway = GDK_DISPLAY_BROADWAY (GDK_SCREEN_DISPLAY (screen));
314
315   impl = g_object_new (GDK_TYPE_WINDOW_IMPL_BROADWAY, NULL);
316   window->impl = (GdkWindowImpl *)impl;
317   impl->id = current_id++;
318   g_hash_table_insert (display_broadway->id_ht, GINT_TO_POINTER(impl->id), window);
319   impl->wrapper = window;
320
321   impl->screen = screen;
322
323   g_assert (window->window_type == GDK_WINDOW_TOPLEVEL ||
324             window->window_type == GDK_WINDOW_TEMP);
325   g_assert (GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_ROOT);
326
327   display_broadway->toplevels = g_list_prepend (display_broadway->toplevels, impl);
328
329   /* Instead of window manager placement we have this mini hack
330      so that the main/first window is not covered in the demos. */
331   if (impl->id > 1 && window->window_type == GDK_WINDOW_TOPLEVEL)
332     {
333       window->x = 100;
334       window->y = 20;
335     }
336
337   if (display_broadway->output)
338     broadway_output_new_surface (display_broadway->output,
339                                  impl->id,
340                                  window->x,
341                                  window->y,
342                                  window->width,
343                                  window->height);
344 }
345
346
347 GdkWindow *
348 gdk_window_foreign_new_for_display (GdkDisplay     *display,
349                                     GdkNativeWindow anid)
350 {
351   return NULL;
352 }
353
354 GdkWindow *
355 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
356 {
357   return NULL;
358 }
359
360 GdkWindow *
361 gdk_window_lookup (GdkNativeWindow anid)
362 {
363   return NULL;
364 }
365
366 static void
367 resize_surface (GdkWindow *window)
368 {
369   GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
370   cairo_surface_t *old, *last_old;
371
372   if (impl->surface)
373     {
374       old = impl->surface;
375       last_old = impl->last_surface;
376
377       impl->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
378                                                   gdk_window_get_width (impl->wrapper),
379                                                   gdk_window_get_height (impl->wrapper));
380       impl->last_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
381                                                        gdk_window_get_width (impl->wrapper),
382                                                        gdk_window_get_height (impl->wrapper));
383
384       { cairo_t *cr;
385       cr = cairo_create (impl->surface);
386       cairo_set_source_rgb (cr, 0.0, 1.0, 0.0);
387       cairo_rectangle (cr, 0, 0, 1000, 1000);
388       cairo_fill (cr);
389       cairo_destroy (cr);
390       }
391
392       cairo_surface_destroy (old);
393       cairo_surface_destroy (last_old);
394     }
395
396   if (impl->ref_surface)
397     {
398       cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
399                                    NULL, NULL);
400       impl->ref_surface = NULL;
401     }
402 }
403
404 static void
405 ref_surface_destroyed (void *data)
406 {
407   GdkWindowImplBroadway *impl = data;
408
409   impl->ref_surface = NULL;
410 }
411
412 static cairo_surface_t *
413 gdk_window_broadway_ref_cairo_surface (GdkWindow *window)
414 {
415   GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
416   cairo_t *cr;
417   int w, h;
418
419   if (GDK_IS_WINDOW_IMPL_BROADWAY (window) &&
420       GDK_WINDOW_DESTROYED (impl->wrapper))
421     return NULL;
422
423   w = gdk_window_get_width (impl->wrapper);
424   h = gdk_window_get_height (impl->wrapper);
425
426   /* Create actual backing store if missing */
427   if (!impl->surface)
428     {
429       impl->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
430       impl->last_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
431
432       cr = cairo_create (impl->surface);
433       cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
434       cairo_rectangle (cr, 0, 0, w, h);
435       cairo_fill (cr);
436       cairo_destroy (cr);
437
438       cr = cairo_create (impl->last_surface);
439       cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
440       cairo_rectangle (cr, 0, 0, w, h);
441       cairo_fill (cr);
442       cairo_destroy (cr);
443     }
444
445   /* Create a destroyable surface referencing the real one */
446   if (!impl->ref_surface)
447     {
448       impl->ref_surface =
449         cairo_surface_create_for_rectangle (impl->surface,
450                                             0, 0,
451                                             w, h);
452       if (impl->ref_surface)
453         cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
454                                      impl, ref_surface_destroyed);
455     }
456   else
457     cairo_surface_reference (impl->ref_surface);
458
459   return impl->ref_surface;
460 }
461
462 static void
463 _gdk_broadway_window_destroy (GdkWindow *window,
464                               gboolean   recursing,
465                               gboolean   foreign_destroy)
466 {
467   GdkWindowImplBroadway *impl;
468   GdkDisplayBroadway *display_broadway;
469
470   g_return_if_fail (GDK_IS_WINDOW (window));
471
472   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
473
474   _gdk_selection_window_destroyed (window);
475
476   if (impl->ref_surface)
477     {
478       cairo_surface_finish (impl->ref_surface);
479       cairo_surface_set_user_data (impl->ref_surface, &gdk_broadway_cairo_key,
480                                    NULL, NULL);
481     }
482
483   if (impl->surface)
484     {
485       cairo_surface_destroy (impl->surface);
486       impl->surface = NULL;
487       cairo_surface_destroy (impl->last_surface);
488       impl->last_surface = NULL;
489     }
490
491   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
492   if (display_broadway->output)
493     broadway_output_destroy_surface (display_broadway->output,
494                                      impl->id);
495 }
496
497 static cairo_surface_t *
498 gdk_window_broadway_resize_cairo_surface (GdkWindow       *window,
499                                           cairo_surface_t *surface,
500                                           gint             width,
501                                           gint             height)
502 {
503   /* Image surfaces cannot be resized */
504   cairo_surface_destroy (surface);
505
506   return NULL;
507 }
508
509 void
510 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
511 {
512 }
513
514 /* This function is called when the XWindow is really gone.
515  */
516 void
517 gdk_window_destroy_notify (GdkWindow *window)
518 {
519   GdkWindowImplBroadway *window_impl;
520
521   window_impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
522
523   if (!GDK_WINDOW_DESTROYED (window))
524     {
525       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
526         g_warning ("GdkWindow %p unexpectedly destroyed", window);
527
528       _gdk_window_destroy (window, TRUE);
529     }
530
531   g_object_unref (window);
532 }
533
534 static void
535 gdk_window_broadway_show (GdkWindow *window, gboolean already_mapped)
536 {
537   GdkWindowImplBroadway *impl;
538   GdkDisplayBroadway *display_broadway;
539
540   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
541
542   if (window->event_mask & GDK_STRUCTURE_MASK)
543     _gdk_make_event (GDK_WINDOW (window), GDK_MAP, NULL, FALSE);
544
545   if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
546     _gdk_make_event (GDK_WINDOW (window), GDK_MAP, NULL, FALSE);
547
548   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
549   if (display_broadway->output)
550     {
551       broadway_output_show_surface (display_broadway->output, impl->id);
552       queue_dirty_flush (display_broadway);
553     }
554 }
555
556 static void
557 gdk_window_broadway_hide (GdkWindow *window)
558 {
559   GdkWindowImplBroadway *impl;
560   GdkDisplayBroadway *display_broadway;
561
562   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
563
564   if (window->event_mask & GDK_STRUCTURE_MASK)
565     _gdk_make_event (GDK_WINDOW (window), GDK_UNMAP, NULL, FALSE);
566
567   if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
568     _gdk_make_event (GDK_WINDOW (window), GDK_UNMAP, NULL, FALSE);
569
570   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
571   if (display_broadway->output)
572     {
573       broadway_output_hide_surface (display_broadway->output, impl->id);
574       queue_dirty_flush (display_broadway);
575     }
576
577   if (display_broadway->mouse_in_toplevel == window)
578     {
579       /* TODO: Send leave + enter event, update cursors, etc */
580       display_broadway->mouse_in_toplevel = NULL;
581     }
582
583   _gdk_window_clear_update_area (window);
584 }
585
586 static void
587 gdk_window_broadway_withdraw (GdkWindow *window)
588 {
589   gdk_window_broadway_hide (window);
590 }
591
592 static void
593 gdk_window_broadway_move_resize (GdkWindow *window,
594                                  gboolean   with_move,
595                                  gint       x,
596                                  gint       y,
597                                  gint       width,
598                                  gint       height)
599 {
600   GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
601   GdkDisplayBroadway *display_broadway;
602   gboolean changed;
603
604   changed = FALSE;
605
606   display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
607   if (with_move)
608     {
609       changed = TRUE;
610       window->x = x;
611       window->y = y;
612       if (display_broadway->output != NULL)
613         {
614           broadway_output_move_surface (display_broadway->output,
615                                         impl->id, x, y);
616           queue_dirty_flush (display_broadway);
617         }
618     }
619
620
621   if (width > 0 || height > 0)
622     {
623       if (width < 1)
624         width = 1;
625
626       if (height < 1)
627         height = 1;
628
629       if (width != window->width ||
630           height != window->height)
631         {
632           changed = TRUE;
633
634           /* Resize clears the content */
635           impl->dirty = TRUE;
636           impl->last_synced = FALSE;
637
638           broadway_output_resize_surface (display_broadway->output,
639                                           impl->id, width, height);
640           queue_dirty_flush (display_broadway);
641
642           window->width = width;
643           window->height = height;
644           resize_surface (window);
645           gdk_window_invalidate_rect (window, NULL, TRUE);
646         }
647     }
648
649   if (changed)
650     {
651       GdkEvent *event;
652       GList *node;
653
654       event = gdk_event_new (GDK_CONFIGURE);
655       event->configure.window = g_object_ref (window);
656       event->configure.x = window->x;
657       event->configure.y = window->y;
658       event->configure.width = window->width;
659       event->configure.height = window->height;
660
661       gdk_event_set_device (event, GDK_DISPLAY_OBJECT (display_broadway)->core_pointer);
662
663       node = _gdk_event_queue_append (GDK_DISPLAY_OBJECT (display_broadway), event);
664       _gdk_windowing_got_event (GDK_DISPLAY_OBJECT (display_broadway), node, event, 0);
665     }
666 }
667
668 static gboolean
669 gdk_window_broadway_reparent (GdkWindow *window,
670                          GdkWindow *new_parent,
671                          gint       x,
672                          gint       y)
673 {
674   return FALSE;
675 }
676
677 static void
678 gdk_window_broadway_raise (GdkWindow *window)
679 {
680 }
681
682 static void
683 gdk_window_broadway_restack_under (GdkWindow *window,
684                               GList *native_siblings /* in requested order, first is bottom-most */)
685 {
686 }
687
688 static void
689 gdk_window_broadway_restack_toplevel (GdkWindow *window,
690                                  GdkWindow *sibling,
691                                  gboolean   above)
692 {
693 }
694
695 static void
696 gdk_window_broadway_lower (GdkWindow *window)
697 {
698 }
699
700
701 void
702 gdk_window_focus (GdkWindow *window,
703                   guint32    timestamp)
704 {
705 }
706
707 void
708 gdk_window_set_type_hint (GdkWindow        *window,
709                           GdkWindowTypeHint hint)
710 {
711 }
712
713 GdkWindowTypeHint
714 gdk_window_get_type_hint (GdkWindow *window)
715 {
716   return GDK_WINDOW_TYPE_HINT_NORMAL;
717 }
718
719 void
720 gdk_window_set_modal_hint (GdkWindow *window,
721                            gboolean   modal)
722 {
723 }
724
725 void
726 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
727                                   gboolean   skips_taskbar)
728 {
729 }
730
731 void
732 gdk_window_set_skip_pager_hint (GdkWindow *window,
733                                 gboolean   skips_pager)
734 {
735 }
736
737 void
738 gdk_window_set_urgency_hint (GdkWindow *window,
739                              gboolean   urgent)
740 {
741 }
742
743 void
744 gdk_window_set_geometry_hints (GdkWindow         *window,
745                                const GdkGeometry *geometry,
746                                GdkWindowHints     geom_mask)
747 {
748 }
749
750 void
751 gdk_window_set_title (GdkWindow   *window,
752                       const gchar *title)
753 {
754 }
755
756 void
757 gdk_window_set_role (GdkWindow   *window,
758                      const gchar *role)
759 {
760 }
761
762 void
763 gdk_window_set_startup_id (GdkWindow   *window,
764                            const gchar *startup_id)
765 {
766 }
767
768 void
769 gdk_window_set_transient_for (GdkWindow *window,
770                               GdkWindow *parent)
771 {
772 }
773
774 static void
775 gdk_window_broadway_set_background (GdkWindow      *window,
776                                cairo_pattern_t *pattern)
777 {
778   return;
779 }
780
781 static void
782 gdk_window_broadway_set_device_cursor (GdkWindow *window,
783                                   GdkDevice *device,
784                                   GdkCursor *cursor)
785 {
786   GdkWindowImplBroadway *impl;
787
788   g_return_if_fail (GDK_IS_WINDOW (window));
789   g_return_if_fail (GDK_IS_DEVICE (device));
790
791   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
792
793   if (!cursor)
794     g_hash_table_remove (impl->device_cursor, device);
795   else
796     {
797       _gdk_broadway_cursor_update_theme (cursor);
798       g_hash_table_replace (impl->device_cursor,
799                             device, gdk_cursor_ref (cursor));
800     }
801
802   if (!GDK_WINDOW_DESTROYED (window))
803     GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
804 }
805
806 GdkCursor *
807 _gdk_broadway_window_get_cursor (GdkWindow *window)
808 {
809   GdkWindowImplBroadway *impl;
810
811   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
812
813   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
814
815   return impl->cursor;
816 }
817
818 static void
819 gdk_window_broadway_get_geometry (GdkWindow *window,
820                              gint      *x,
821                              gint      *y,
822                              gint      *width,
823                              gint      *height,
824                              gint      *depth)
825 {
826 }
827
828 static gint
829 gdk_window_broadway_get_root_coords (GdkWindow *window,
830                                 gint       x,
831                                 gint       y,
832                                 gint      *root_x,
833                                 gint      *root_y)
834 {
835   if (root_x)
836     *root_x = x;
837   if (root_y)
838     *root_y = y;
839
840   return 1;
841 }
842
843 void
844 gdk_window_get_root_origin (GdkWindow *window,
845                             gint      *x,
846                             gint      *y)
847 {
848   if (x)
849     *x = 0;
850
851   if (y)
852     *y = 0;
853 }
854
855 void
856 gdk_window_get_frame_extents (GdkWindow    *window,
857                               GdkRectangle *rect)
858 {
859   g_return_if_fail (rect != NULL);
860
861   rect->x = window->x;
862   rect->y = window->y;
863   rect->width = window->width;
864   rect->height = window->height;
865 }
866
867 void
868 _gdk_windowing_get_device_state (GdkDisplay       *display,
869                                  GdkDevice        *device,
870                                  GdkScreen       **screen,
871                                  gint             *x,
872                                  gint             *y,
873                                  GdkModifierType  *mask)
874 {
875   if (display->closed)
876     return;
877
878   *screen = gdk_display_get_default_screen (display);
879   *x = 0;
880   *y = 0;
881   *mask = 0;
882 }
883
884 static gboolean
885 gdk_window_broadway_get_device_state (GdkWindow       *window,
886                                       GdkDevice       *device,
887                                       gint            *x,
888                                       gint            *y,
889                                       GdkModifierType *mask)
890 {
891   *x = 0;
892   *y = 0;
893   *mask = 0;
894   return FALSE;
895 }
896
897 void
898 gdk_display_warp_pointer (GdkDisplay *display,
899                           GdkScreen  *screen,
900                           gint        x,
901                           gint        y)
902 {
903   GdkDevice *device;
904
905   g_return_if_fail (GDK_IS_DISPLAY (display));
906   g_return_if_fail (GDK_IS_SCREEN (screen));
907
908   device = display->core_pointer;
909   GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
910 }
911
912 void
913 gdk_display_warp_device (GdkDisplay *display,
914                          GdkDevice  *device,
915                          GdkScreen  *screen,
916                          gint        x,
917                          gint        y)
918 {
919   g_return_if_fail (GDK_IS_DISPLAY (display));
920   g_return_if_fail (GDK_IS_DEVICE (device));
921   g_return_if_fail (GDK_IS_SCREEN (screen));
922   g_return_if_fail (display == gdk_device_get_display (device));
923
924   GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
925 }
926
927 GdkWindow*
928 _gdk_windowing_window_at_device_position (GdkDisplay      *display,
929                                           GdkDevice       *device,
930                                           gint            *win_x,
931                                           gint            *win_y,
932                                           GdkModifierType *mask,
933                                           gboolean         get_toplevel)
934 {
935   GdkWindow *window;
936   GdkDisplayBroadway *display_broadway;
937   GdkScreen *screen;
938
939   display_broadway = GDK_DISPLAY_BROADWAY (display);
940   screen = gdk_display_get_screen (display, 0);
941   window = _gdk_window_find_child_at (gdk_screen_get_root_window (screen),
942                                       display_broadway->last_x,
943                                       display_broadway->last_y);
944
945   if (window != NULL)
946     {
947       *win_x = display_broadway->last_x - window->x;
948       *win_y = display_broadway->last_y - window->y;
949       if (mask)
950         *mask = 0;
951     }
952
953   return window;
954 }
955
956 static GdkEventMask
957 gdk_window_broadway_get_events (GdkWindow *window)
958 {
959   if (GDK_WINDOW_DESTROYED (window))
960     return 0;
961
962   return 0;
963 }
964 static void
965 gdk_window_broadway_set_events (GdkWindow    *window,
966                            GdkEventMask  event_mask)
967 {
968   if (!GDK_WINDOW_DESTROYED (window))
969     {
970     }
971 }
972
973 static void
974 gdk_window_broadway_shape_combine_region (GdkWindow       *window,
975                                      const cairo_region_t *shape_region,
976                                      gint             offset_x,
977                                      gint             offset_y)
978 {
979 }
980
981 static void
982 gdk_window_broadway_input_shape_combine_region (GdkWindow       *window,
983                                            const cairo_region_t *shape_region,
984                                            gint             offset_x,
985                                            gint             offset_y)
986 {
987 }
988
989
990 void
991 gdk_window_set_override_redirect (GdkWindow *window,
992                                   gboolean override_redirect)
993 {
994 }
995
996 void
997 gdk_window_set_accept_focus (GdkWindow *window,
998                              gboolean accept_focus)
999 {
1000   accept_focus = accept_focus != FALSE;
1001
1002   if (window->accept_focus != accept_focus)
1003     {
1004       window->accept_focus = accept_focus;
1005     }
1006 }
1007
1008 void
1009 gdk_window_set_focus_on_map (GdkWindow *window,
1010                              gboolean focus_on_map)
1011 {
1012   focus_on_map = focus_on_map != FALSE;
1013
1014   if (window->focus_on_map != focus_on_map)
1015     {
1016       window->focus_on_map = focus_on_map;
1017     }
1018 }
1019
1020
1021 void
1022 gdk_window_set_icon_list (GdkWindow *window,
1023                           GList     *pixbufs)
1024 {
1025 }
1026
1027 void
1028 gdk_window_set_icon_name (GdkWindow   *window, 
1029                           const gchar *name)
1030 {
1031   GdkDisplay *display;
1032
1033   if (GDK_WINDOW_DESTROYED (window) ||
1034       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1035     return;
1036
1037   display = gdk_window_get_display (window);
1038
1039   g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
1040                       GUINT_TO_POINTER (name != NULL));
1041 }
1042
1043 void
1044 gdk_window_iconify (GdkWindow *window)
1045 {
1046   if (GDK_WINDOW_DESTROYED (window) ||
1047       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1048     return;
1049 }
1050
1051 void
1052 gdk_window_deiconify (GdkWindow *window)
1053 {
1054   if (GDK_WINDOW_DESTROYED (window) ||
1055       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1056     return;
1057 }
1058
1059 void
1060 gdk_window_stick (GdkWindow *window)
1061 {
1062   if (GDK_WINDOW_DESTROYED (window) ||
1063       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1064     return;
1065
1066 }
1067
1068 void
1069 gdk_window_unstick (GdkWindow *window)
1070 {
1071   if (GDK_WINDOW_DESTROYED (window) ||
1072       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1073     return;
1074
1075 }
1076
1077 void
1078 gdk_window_maximize (GdkWindow *window)
1079 {
1080   if (GDK_WINDOW_DESTROYED (window) ||
1081       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1082     return;
1083
1084 }
1085
1086 void
1087 gdk_window_unmaximize (GdkWindow *window)
1088 {
1089   if (GDK_WINDOW_DESTROYED (window) ||
1090       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1091     return;
1092
1093 }
1094
1095 void
1096 gdk_window_fullscreen (GdkWindow *window)
1097 {
1098   if (GDK_WINDOW_DESTROYED (window) ||
1099       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1100     return;
1101
1102 }
1103
1104 void
1105 gdk_window_unfullscreen (GdkWindow *window)
1106 {
1107   if (GDK_WINDOW_DESTROYED (window) ||
1108       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1109     return;
1110
1111 }
1112
1113 void
1114 gdk_window_set_keep_above (GdkWindow *window,
1115                            gboolean   setting)
1116 {
1117   g_return_if_fail (GDK_IS_WINDOW (window));
1118
1119   if (GDK_WINDOW_DESTROYED (window) ||
1120       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1121     return;
1122
1123 }
1124
1125 void
1126 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
1127 {
1128   g_return_if_fail (GDK_IS_WINDOW (window));
1129
1130   if (GDK_WINDOW_DESTROYED (window) ||
1131       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1132     return;
1133
1134 }
1135
1136 GdkWindow *
1137 gdk_window_get_group (GdkWindow *window)
1138 {
1139   if (GDK_WINDOW_DESTROYED (window) ||
1140       !WINDOW_IS_TOPLEVEL (window))
1141     return NULL;
1142
1143   return window;
1144 }
1145
1146 void
1147 gdk_window_set_group (GdkWindow *window,
1148                       GdkWindow *leader)
1149 {
1150 }
1151
1152 void
1153 gdk_window_set_decorations (GdkWindow      *window,
1154                             GdkWMDecoration decorations)
1155 {
1156   if (GDK_WINDOW_DESTROYED (window) ||
1157       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1158     return;
1159
1160 }
1161
1162 gboolean
1163 gdk_window_get_decorations(GdkWindow       *window,
1164                            GdkWMDecoration *decorations)
1165 {
1166   gboolean result = FALSE;
1167
1168   if (GDK_WINDOW_DESTROYED (window) ||
1169       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1170     return FALSE;
1171
1172   return result;
1173 }
1174
1175 void
1176 gdk_window_set_functions (GdkWindow    *window,
1177                           GdkWMFunction functions)
1178 {
1179   g_return_if_fail (GDK_IS_WINDOW (window));
1180
1181   if (GDK_WINDOW_DESTROYED (window) ||
1182       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1183     return;
1184 }
1185
1186 cairo_region_t *
1187 _gdk_windowing_window_get_shape (GdkWindow *window)
1188 {
1189   return NULL;
1190 }
1191
1192 cairo_region_t *
1193 _gdk_windowing_window_get_input_shape (GdkWindow *window)
1194 {
1195   return NULL;
1196 }
1197
1198
1199 static gboolean
1200 gdk_window_broadway_set_static_gravities (GdkWindow *window,
1201                                      gboolean   use_static)
1202 {
1203   return TRUE;
1204 }
1205
1206 void
1207 gdk_window_begin_resize_drag (GdkWindow     *window,
1208                               GdkWindowEdge  edge,
1209                               gint           button,
1210                               gint           root_x,
1211                               gint           root_y,
1212                               guint32        timestamp)
1213 {
1214   if (GDK_WINDOW_DESTROYED (window) ||
1215       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1216     return;
1217
1218 }
1219
1220 void
1221 gdk_window_begin_move_drag (GdkWindow *window,
1222                             gint       button,
1223                             gint       root_x,
1224                             gint       root_y,
1225                             guint32    timestamp)
1226 {
1227   if (GDK_WINDOW_DESTROYED (window) ||
1228       !WINDOW_IS_TOPLEVEL (window))
1229     return;
1230
1231 }
1232
1233 void
1234 gdk_window_enable_synchronized_configure (GdkWindow *window)
1235 {
1236   if (!GDK_IS_WINDOW_IMPL_BROADWAY (window->impl))
1237     return;
1238 }
1239
1240 void
1241 gdk_window_configure_finished (GdkWindow *window)
1242 {
1243   if (!WINDOW_IS_TOPLEVEL (window))
1244     return;
1245 }
1246
1247 void
1248 _gdk_windowing_window_beep (GdkWindow *window)
1249 {
1250   GdkDisplay *display;
1251
1252   g_return_if_fail (GDK_IS_WINDOW (window));
1253
1254   display = GDK_WINDOW_DISPLAY (window);
1255
1256   gdk_display_beep (display);
1257 }
1258
1259 void
1260 gdk_window_set_opacity (GdkWindow *window,
1261                         gdouble    opacity)
1262 {
1263   GdkDisplay *display;
1264
1265   g_return_if_fail (GDK_IS_WINDOW (window));
1266
1267   if (GDK_WINDOW_DESTROYED (window) ||
1268       !WINDOW_IS_TOPLEVEL (window))
1269     return;
1270
1271   display = gdk_window_get_display (window);
1272
1273   if (opacity < 0)
1274     opacity = 0;
1275   else if (opacity > 1)
1276     opacity = 1;
1277
1278 }
1279
1280 void
1281 _gdk_windowing_window_set_composited (GdkWindow *window,
1282                                       gboolean   composited)
1283 {
1284 }
1285
1286 void
1287 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
1288                                                cairo_region_t *region)
1289 {
1290   GdkWindowImplBroadway *impl;
1291
1292   _gdk_window_process_updates_recurse (window, region);
1293
1294   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
1295   impl->dirty = TRUE;
1296   queue_dirty_flush (GDK_DISPLAY_BROADWAY (gdk_window_get_display (window)));
1297 }
1298
1299 void
1300 _gdk_windowing_before_process_all_updates (void)
1301 {
1302 }
1303
1304 void
1305 _gdk_windowing_after_process_all_updates (void)
1306 {
1307 }
1308
1309 gboolean
1310 _gdk_broadway_window_queue_antiexpose (GdkWindow *window,
1311                                   cairo_region_t *area)
1312 {
1313   return TRUE;
1314 }
1315
1316 static void
1317 copy_region (cairo_surface_t *surface,
1318              cairo_region_t *area,
1319              gint            dx,
1320              gint            dy)
1321 {
1322   cairo_t *cr;
1323
1324   cr = cairo_create (surface);
1325
1326   gdk_cairo_region (cr, area);
1327   cairo_clip (cr);
1328
1329   /* NB: This is a self-copy and Cairo doesn't support that yet.
1330    * So we do a litle trick.
1331    */
1332   cairo_push_group (cr);
1333
1334   cairo_set_source_surface (cr, surface, dx, dy);
1335   cairo_paint (cr);
1336
1337   cairo_pop_group_to_source (cr);
1338   cairo_paint (cr);
1339
1340   cairo_destroy (cr);
1341 }
1342
1343 void
1344 _gdk_broadway_window_translate (GdkWindow      *window,
1345                                 cairo_region_t *area,
1346                                 gint            dx,
1347                                 gint            dy)
1348 {
1349   GdkWindowImplBroadway *impl;
1350   GdkDisplayBroadway *display_broadway;
1351   int n_rects, i;
1352   BroadwayRect *rects;
1353   cairo_rectangle_int_t rect;
1354
1355   impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
1356
1357   if (impl->surface)
1358     {
1359       copy_region (impl->surface, area, dx, dy);
1360       if (GDK_WINDOW_IMPL_BROADWAY (impl)->last_synced)
1361         {
1362           copy_region (impl->last_surface, area, dx, dy);
1363           n_rects = cairo_region_num_rectangles (area);
1364           rects = g_new (BroadwayRect, n_rects);
1365           for (i = 0; i < n_rects; i++)
1366             {
1367               cairo_region_get_rectangle (area, i, &rect);
1368               rects[i].x = rect.x;
1369               rects[i].y = rect.y;
1370               rects[i].width = rect.width;
1371               rects[i].height = rect.height;
1372             }
1373           display_broadway = GDK_DISPLAY_BROADWAY (gdk_window_get_display (window));
1374           broadway_output_copy_rectangles (display_broadway->output,
1375                                            GDK_WINDOW_IMPL_BROADWAY (impl)->id,
1376                                            rects, n_rects, dx, dy);
1377           queue_dirty_flush (display_broadway);
1378           g_free (rects);
1379         }
1380     }
1381 }
1382
1383 static void
1384 gdk_window_impl_broadway_class_init (GdkWindowImplBroadwayClass *klass)
1385 {
1386   GObjectClass *object_class = G_OBJECT_CLASS (klass);
1387   GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
1388
1389   object_class->finalize = gdk_window_impl_broadway_finalize;
1390
1391   impl_class->ref_cairo_surface = gdk_window_broadway_ref_cairo_surface;
1392   impl_class->show = gdk_window_broadway_show;
1393   impl_class->hide = gdk_window_broadway_hide;
1394   impl_class->withdraw = gdk_window_broadway_withdraw;
1395   impl_class->set_events = gdk_window_broadway_set_events;
1396   impl_class->get_events = gdk_window_broadway_get_events;
1397   impl_class->raise = gdk_window_broadway_raise;
1398   impl_class->lower = gdk_window_broadway_lower;
1399   impl_class->restack_under = gdk_window_broadway_restack_under;
1400   impl_class->restack_toplevel = gdk_window_broadway_restack_toplevel;
1401   impl_class->move_resize = gdk_window_broadway_move_resize;
1402   impl_class->set_background = gdk_window_broadway_set_background;
1403   impl_class->reparent = gdk_window_broadway_reparent;
1404   impl_class->set_device_cursor = gdk_window_broadway_set_device_cursor;
1405   impl_class->get_geometry = gdk_window_broadway_get_geometry;
1406   impl_class->get_root_coords = gdk_window_broadway_get_root_coords;
1407   impl_class->get_device_state = gdk_window_broadway_get_device_state;
1408   impl_class->shape_combine_region = gdk_window_broadway_shape_combine_region;
1409   impl_class->input_shape_combine_region = gdk_window_broadway_input_shape_combine_region;
1410   impl_class->set_static_gravities = gdk_window_broadway_set_static_gravities;
1411   impl_class->queue_antiexpose = _gdk_broadway_window_queue_antiexpose;
1412   impl_class->translate = _gdk_broadway_window_translate;
1413   impl_class->destroy = _gdk_broadway_window_destroy;
1414   impl_class->resize_cairo_surface = gdk_window_broadway_resize_cairo_surface;
1415 }