]> Pileus Git - ~andy/gtk/blob - gdk/directfb/gdkwindow-directfb.c
Bug 533456 – Memory leak when window is destroyed
[~andy/gtk] / gdk / directfb / gdkwindow-directfb.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 1998-1999 Tor Lillqvist
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.
24  */
25
26 /*
27  * GTK+ DirectFB backend
28  * Copyright (C) 2001-2002  convergence integrated media GmbH
29  * Copyright (C) 2002-2004  convergence GmbH
30  * Written by Denis Oliver Kropp <dok@convergence.de> and
31  *            Sven Neumann <sven@convergence.de>
32  */
33
34 #include "config.h"
35 #include "gdk.h"
36 #include "gdkwindowimpl.h"
37 #include "gdkwindow.h"
38
39 #include "gdkdirectfb.h"
40 #include "gdkprivate-directfb.h"
41 #include "gdkdisplay-directfb.h"
42
43 #include "gdkregion-generic.h"
44
45 #include "gdkinternals.h"
46 #include "gdkalias.h"
47 #include "cairo.h"
48 #include <assert.h>
49
50 #include <direct/debug.h>
51
52 #include <directfb_util.h>
53
54
55
56
57
58 D_DEBUG_DOMAIN( GDKDFB_Crossing,  "GDKDFB/Crossing",  "GDK DirectFB Crossing Events" );
59 D_DEBUG_DOMAIN( GDKDFB_Updates,   "GDKDFB/Updates",   "GDK DirectFB Updates" );
60 D_DEBUG_DOMAIN( GDKDFB_Paintable, "GDKDFB/Paintable", "GDK DirectFB Paintable" );
61 D_DEBUG_DOMAIN( GDKDFB_Window,    "GDKDFB/Window",    "GDK DirectFB Window" );
62
63
64 static GdkRegion * gdk_window_impl_directfb_get_visible_region (GdkDrawable *drawable);
65 static void        gdk_window_impl_directfb_set_colormap       (GdkDrawable *drawable,
66                                                                 GdkColormap *colormap);
67 static void gdk_window_impl_directfb_init       (GdkWindowImplDirectFB      *window);
68 static void gdk_window_impl_directfb_class_init (GdkWindowImplDirectFBClass *klass);
69 static void gdk_window_impl_directfb_finalize   (GObject                    *object);
70
71 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
72
73
74 typedef struct
75 {
76   GdkWindowChildChanged  changed;
77   GdkWindowChildGetPos   get_pos;
78   gpointer               user_data;
79 } GdkWindowChildHandlerData;
80
81
82 /* Code for dirty-region queueing
83  */
84 static GSList *update_windows = NULL;
85 static guint update_idle = 0;
86
87 static void
88 gdk_window_directfb_process_all_updates (void)
89 {
90   GSList *tmp_list;
91   GSList *old_update_windows = update_windows;
92
93   if (update_idle)
94     g_source_remove (update_idle);
95   
96   update_windows = NULL;
97   update_idle = 0;
98
99   D_DEBUG_AT( GDKDFB_Updates, "%s()\n", __FUNCTION__ );
100   
101   g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
102   tmp_list = old_update_windows;
103   while (tmp_list)
104     {
105       GdkWindowObject *private = GDK_WINDOW_OBJECT( tmp_list->data );
106
107       if (private->update_freeze_count)
108         {
109           D_DEBUG_AT( GDKDFB_Updates, "  -> %p frozen [%4d,%4d-%4dx%4d] (%d boxes)\n",
110                       private, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ),
111                       wimpl->flips.num_regions );
112           update_windows = g_slist_prepend (update_windows, private);
113         }
114       else
115         {
116           D_DEBUG_AT( GDKDFB_Updates, "  -> %p update [%4d,%4d-%4dx%4d] (%d boxes)\n",
117                       private, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ),
118                       wimpl->flips.num_regions );
119           gdk_window_process_updates(tmp_list->data,TRUE);
120         }
121
122       g_object_unref (tmp_list->data);
123       tmp_list = tmp_list->next;
124     }
125
126 #ifndef GDK_DIRECTFB_NO_EXPERIMENTS
127   g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
128   tmp_list = old_update_windows;
129   while (tmp_list)
130     {
131       GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( tmp_list->data ) );
132
133       if (top)
134         {
135           GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
136
137           if (wimpl->flips.num_regions)
138             {
139               D_DEBUG_AT( GDKDFB_Updates, "  -> %p flip   [%4d,%4d-%4dx%4d] (%d boxes)\n",
140                           top, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ),
141                           wimpl->flips.num_regions );
142
143               wimpl->drawable.surface->Flip( wimpl->drawable.surface, &wimpl->flips.bounding, DSFLIP_NONE );
144
145               dfb_updates_reset( &wimpl->flips );
146             }
147           else
148             D_DEBUG_AT( GDKDFB_Updates, "  -> %p has no flips!\n", top );
149         }
150       else
151         D_DEBUG_AT( GDKDFB_Updates, "  -> %p has no top level window!\n", tmp_list->data );
152
153       g_object_unref (tmp_list->data);
154       tmp_list = tmp_list->next;
155     }
156 #endif
157
158   g_slist_free (old_update_windows);
159 }
160
161 static gboolean
162 gdk_window_update_idle (gpointer data)
163 {
164   gdk_window_directfb_process_all_updates ();
165   
166   return FALSE;
167 }
168
169 static void
170 gdk_window_schedule_update (GdkWindow *window)
171 {
172   D_DEBUG_AT( GDKDFB_Updates, "%s( %p ) <- freeze count %d\n", __FUNCTION__, window,
173               window ? GDK_WINDOW_OBJECT (window)->update_freeze_count : -1 );
174   
175   if (window && GDK_WINDOW_OBJECT (window)->update_freeze_count)
176     return;
177
178   if (!update_idle)
179     {
180       D_DEBUG_AT( GDKDFB_Updates, "  -> adding idle callback\n" );
181
182       update_idle = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
183                                                gdk_window_update_idle, NULL, NULL);
184     }
185 }
186
187
188 static GdkWindow *gdk_directfb_window_containing_pointer = NULL;
189 static GdkWindow *gdk_directfb_focused_window            = NULL;
190 static gpointer   parent_class                           = NULL;
191 GdkWindow * _gdk_parent_root = NULL;
192
193 static void gdk_window_impl_directfb_paintable_init (GdkPaintableIface *iface);
194
195
196 GType
197 gdk_window_impl_directfb_get_type (void)
198 {
199   static GType object_type = 0;
200
201   if (!object_type)
202     {
203       static const GTypeInfo object_info =
204         {
205           sizeof (GdkWindowImplDirectFBClass),
206           (GBaseInitFunc) NULL,
207           (GBaseFinalizeFunc) NULL,
208           (GClassInitFunc) gdk_window_impl_directfb_class_init,
209           NULL,           /* class_finalize */
210           NULL,           /* class_data */
211           sizeof (GdkWindowImplDirectFB),
212           0,              /* n_preallocs */
213           (GInstanceInitFunc) gdk_window_impl_directfb_init,
214         };
215
216       static const GInterfaceInfo paintable_info =
217         {
218           (GInterfaceInitFunc) gdk_window_impl_directfb_paintable_init,
219           NULL,
220           NULL
221         };
222
223       static const GInterfaceInfo window_impl_info =
224         {
225           (GInterfaceInitFunc) gdk_window_impl_iface_init,
226           NULL,
227           NULL
228         };
229
230       object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_DIRECTFB,
231                                             "GdkWindowImplDirectFB",
232                                             &object_info, 0);
233       g_type_add_interface_static (object_type,
234                                    GDK_TYPE_PAINTABLE,
235                                    &paintable_info);
236
237       g_type_add_interface_static (object_type,
238                                    GDK_TYPE_WINDOW_IMPL,
239                                    &window_impl_info);
240     }
241
242   return object_type;
243 }
244
245 GType
246 _gdk_window_impl_get_type (void)
247 {
248   return gdk_window_impl_directfb_get_type ();
249 }
250
251 static void
252 gdk_window_impl_directfb_init (GdkWindowImplDirectFB *impl)
253 {
254   impl->drawable.width  = 1;
255   impl->drawable.height = 1;
256   //cannot use gdk_cursor_new here since gdk_display_get_default
257   //does not work yet.
258   impl->cursor          = gdk_cursor_new_for_display (GDK_DISPLAY_OBJECT(_gdk_display),GDK_LEFT_PTR);
259   impl->opacity         = 255;
260 }
261
262 static void
263 gdk_window_impl_directfb_class_init (GdkWindowImplDirectFBClass *klass)
264 {
265   GObjectClass     *object_class   = G_OBJECT_CLASS (klass);
266   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
267
268   parent_class = g_type_class_peek_parent (klass);
269
270   object_class->finalize = gdk_window_impl_directfb_finalize;
271
272   drawable_class->set_colormap = gdk_window_impl_directfb_set_colormap;
273
274   /* Visible and clip regions are the same */
275
276   drawable_class->get_clip_region =
277     gdk_window_impl_directfb_get_visible_region;
278
279   drawable_class->get_visible_region =
280     gdk_window_impl_directfb_get_visible_region;
281 }
282
283 static void
284 g_free_2nd (gpointer a,
285             gpointer b,
286             gpointer data)
287 {
288   g_free (b);
289 }
290
291 static void
292 gdk_window_impl_directfb_finalize (GObject *object)
293 {
294   GdkWindowImplDirectFB *impl = GDK_WINDOW_IMPL_DIRECTFB (object);
295
296   D_DEBUG_AT( GDKDFB_Window, "%s( %p ) <- %dx%d\n", __FUNCTION__, impl, impl->drawable.width, impl->drawable.height );
297
298   if (GDK_WINDOW_IS_MAPPED (impl->drawable.wrapper))
299     gdk_window_hide (impl->drawable.wrapper);
300
301   if (impl->cursor)
302     gdk_cursor_unref (impl->cursor);
303
304   if (impl->properties)
305     {
306       g_hash_table_foreach (impl->properties, g_free_2nd, NULL);
307       g_hash_table_destroy (impl->properties);
308     }
309   if (impl->window)
310     {
311       gdk_directfb_window_id_table_remove (impl->dfb_id);
312           /* native window resource must be release before we can finalize !*/
313       impl->window = NULL;
314     }
315
316   if (G_OBJECT_CLASS (parent_class)->finalize)
317     G_OBJECT_CLASS (parent_class)->finalize (object);
318 }
319
320 static GdkRegion*
321 gdk_window_impl_directfb_get_visible_region (GdkDrawable *drawable)
322 {
323   GdkDrawableImplDirectFB *priv = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
324   GdkRectangle             rect = { 0, 0, 0, 0 };
325   DFBRectangle             drect = { 0, 0, 0, 0 };
326
327   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, drawable );
328
329   if (priv->surface)
330   priv->surface->GetVisibleRectangle (priv->surface, &drect);
331   rect.x= drect.x;
332   rect.y= drect.y;
333   rect.width=drect.w;
334   rect.height=drect.h;
335
336   D_DEBUG_AT( GDKDFB_Window, "  -> returning %4d,%4d-%4dx%4d\n", drect.x, drect.y, drect.w, drect.h );
337
338   return gdk_region_rectangle (&rect);
339 }
340
341 static void
342 gdk_window_impl_directfb_set_colormap (GdkDrawable *drawable,
343                                        GdkColormap *colormap)
344 {
345   GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, colormap);
346
347   if (colormap)
348     {
349        GdkDrawableImplDirectFB *priv = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
350
351        if (priv->surface)
352          {
353            IDirectFBPalette *palette = gdk_directfb_colormap_get_palette (colormap);
354
355            if (palette)
356              priv->surface->SetPalette (priv->surface, palette);
357          }
358     }
359 }
360
361
362 static gboolean
363 create_directfb_window (GdkWindowImplDirectFB *impl,
364                         DFBWindowDescription  *desc,
365                         DFBWindowOptions       window_options)
366 {
367   DFBResult        ret;
368   IDirectFBWindow *window;
369
370   D_DEBUG_AT( GDKDFB_Window, "%s( %4dx%4d, caps 0x%08x )\n", __FUNCTION__, desc->width, desc->height, desc->caps );
371
372   ret = _gdk_display->layer->CreateWindow (_gdk_display->layer, desc, &window);
373
374   if (ret != DFB_OK)
375     {
376       DirectFBError ("gdk_window_new: Layer->CreateWindow failed", ret);
377       g_assert (0);
378       return FALSE;
379     }
380
381   if ((desc->flags & DWDESC_CAPS) && (desc->caps & DWCAPS_INPUTONLY))
382   {
383     impl->drawable.surface = NULL;
384   } else 
385     window->GetSurface (window, &impl->drawable.surface);
386
387   if (window_options)
388     {
389       DFBWindowOptions options;
390       window->GetOptions (window, &options);
391       window->SetOptions (window,  options | window_options);
392     }
393
394   impl->window = window;
395
396 #ifndef GDK_DIRECTFB_NO_EXPERIMENTS
397   //direct_log_printf( NULL, "Initializing (window %p, wimpl %p)\n", win, impl );
398
399   dfb_updates_init( &impl->flips, impl->flip_regions, G_N_ELEMENTS(impl->flip_regions) );
400 #endif
401
402   return TRUE;
403 }
404
405 void
406 _gdk_windowing_window_init (void)
407 {
408   GdkWindowObject       *private;
409   GdkWindowImplDirectFB *impl;
410   DFBDisplayLayerConfig  dlc;
411
412   g_assert (_gdk_parent_root == NULL);
413
414   _gdk_display->layer->GetConfiguration( 
415         _gdk_display->layer, &dlc );
416
417   _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
418   private = GDK_WINDOW_OBJECT (_gdk_parent_root);
419   private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
420   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
421
422   private->window_type = GDK_WINDOW_ROOT;
423   private->state       = 0;
424   private->children    = NULL;
425 //  impl->drawable.paint_region   = NULL;
426   impl->gdkWindow      = _gdk_parent_root;
427   impl->window           = NULL;
428   impl->drawable.abs_x   = 0;
429   impl->drawable.abs_y   = 0;
430   impl->drawable.width   = dlc.width;
431   impl->drawable.height  = dlc.height;
432   impl->drawable.wrapper = GDK_DRAWABLE (private);
433   /* custom root window init */
434   {
435     DFBWindowDescription   desc;
436     desc.flags = 0;
437         /*XXX I must do this now its a bug  ALPHA ROOT*/
438
439     desc.flags = DWDESC_CAPS;
440     desc.caps = 0;
441     desc.caps  |= DWCAPS_NODECORATION;
442     desc.caps  |= DWCAPS_ALPHACHANNEL;
443     desc.flags |= ( DWDESC_WIDTH | DWDESC_HEIGHT |
444                       DWDESC_POSX  | DWDESC_POSY );
445     desc.posx   = 0;
446     desc.posy   = 0;
447     desc.width  = dlc.width;
448     desc.height = dlc.height;
449     create_directfb_window (impl,&desc,0);
450         g_assert(impl->window != NULL);
451     g_assert(impl->drawable.surface != NULL );
452   }
453   impl->drawable.surface->GetPixelFormat(impl->drawable.surface,&impl->drawable.format); 
454   private->depth = DFB_BITS_PER_PIXEL(impl->drawable.format);
455   /*
456         Now we can set up the system colormap
457   */
458   gdk_drawable_set_colormap (GDK_DRAWABLE (_gdk_parent_root),gdk_colormap_get_system());
459 }
460
461
462
463 GdkWindow *
464 gdk_directfb_window_new (GdkWindow              *parent,
465                          GdkWindowAttr          *attributes,
466                          gint                    attributes_mask,
467                          DFBWindowCapabilities   window_caps,
468                          DFBWindowOptions        window_options,
469                          DFBSurfaceCapabilities  surface_caps)
470 {
471   GdkWindow             *window;
472   GdkWindowObject       *private;
473   GdkWindowObject       *parent_private;
474   GdkWindowImplDirectFB *impl;
475   GdkWindowImplDirectFB *parent_impl;
476   GdkVisual             *visual;
477   DFBWindowDescription   desc;
478   gint x, y;
479
480   g_return_val_if_fail (attributes != NULL, NULL);
481
482   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, parent );
483
484   if (!parent || attributes->window_type != GDK_WINDOW_CHILD)
485     parent = _gdk_parent_root;
486
487   window = g_object_new (GDK_TYPE_WINDOW, NULL);
488   private = GDK_WINDOW_OBJECT (window);
489   private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
490
491   parent_private = GDK_WINDOW_OBJECT (parent);
492   parent_impl = GDK_WINDOW_IMPL_DIRECTFB (parent_private->impl);
493   private->parent = parent_private;
494
495   x = (attributes_mask & GDK_WA_X) ? attributes->x : 0;
496   y = (attributes_mask & GDK_WA_Y) ? attributes->y : 0;
497
498   gdk_window_set_events (window, attributes->event_mask | GDK_STRUCTURE_MASK);
499
500   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
501   impl->drawable.wrapper = GDK_DRAWABLE (window);
502   impl->gdkWindow      = window;
503
504   private->x = x;
505   private->y = y;
506
507   _gdk_directfb_calc_abs (window);
508
509   impl->drawable.width  = MAX (1, attributes->width);
510   impl->drawable.height = MAX (1, attributes->height);
511
512   private->window_type = attributes->window_type;
513
514   desc.flags = 0;
515
516   if (attributes_mask & GDK_WA_VISUAL)
517     visual = attributes->visual;
518   else
519     visual = gdk_drawable_get_visual (parent);
520
521   switch (attributes->wclass)
522     {
523     case GDK_INPUT_OUTPUT:
524       private->input_only = FALSE;
525
526       desc.flags |= DWDESC_PIXELFORMAT;
527       desc.pixelformat = ((GdkVisualDirectFB *) visual)->format;
528
529       if (DFB_PIXELFORMAT_HAS_ALPHA (desc.pixelformat))
530         {
531           desc.flags |= DWDESC_CAPS;
532           desc.caps = DWCAPS_ALPHACHANNEL;
533         }
534       break;
535
536     case GDK_INPUT_ONLY:
537       private->input_only = TRUE;
538       desc.flags |= DWDESC_CAPS;
539       desc.caps = DWCAPS_INPUTONLY;
540       break;
541
542     default:
543       g_warning ("gdk_window_new: unsupported window class\n");
544       _gdk_window_destroy (window, FALSE);
545       return NULL;
546     }
547
548   switch (private->window_type)
549     {
550     case GDK_WINDOW_TOPLEVEL:
551     case GDK_WINDOW_DIALOG:
552     case GDK_WINDOW_TEMP:
553       desc.flags |= ( DWDESC_WIDTH | DWDESC_HEIGHT |
554                       DWDESC_POSX  | DWDESC_POSY );
555       desc.posx   = x;
556       desc.posy   = y;
557       desc.width  = impl->drawable.width;
558       desc.height = impl->drawable.height;
559 #if 0
560       if (window_caps)
561         {
562           if (! (desc.flags & DWDESC_CAPS))
563             {
564               desc.flags |= DWDESC_CAPS;
565               desc.caps   = DWCAPS_NONE;
566             }
567
568           desc.caps |= window_caps;
569         }
570
571       if (surface_caps)
572         {
573           desc.flags |= DWDESC_SURFACE_CAPS;
574           desc.surface_caps = surface_caps;
575         }
576 #endif
577
578       if (!create_directfb_window (impl, &desc, window_options))
579         {
580                   g_assert(0);
581           _gdk_window_destroy (window, FALSE);
582           return NULL;
583         }
584         if( desc.caps != DWCAPS_INPUTONLY )
585                         impl->window->SetOpacity(impl->window, 0x00 );
586       break;
587
588     case GDK_WINDOW_CHILD:
589            impl->window=NULL;
590       if (!private->input_only && parent_impl->drawable.surface)
591         {
592
593           DFBRectangle rect =
594           { x, y, impl->drawable.width, impl->drawable.height };
595           parent_impl->drawable.surface->GetSubSurface (parent_impl->drawable.surface,
596                                                         &rect,
597                                                         &impl->drawable.surface);
598         }
599       break;
600
601     default:
602       g_warning ("gdk_window_new: unsupported window type: %d",
603                  private->window_type);
604       _gdk_window_destroy (window, FALSE);
605       return NULL;
606     }
607
608   if (impl->drawable.surface)
609     {
610       GdkColormap *colormap;
611
612       impl->drawable.surface->GetPixelFormat (impl->drawable.surface,
613                                               &impl->drawable.format);
614
615           private->depth = DFB_BITS_PER_PIXEL(impl->drawable.format);
616
617       if ((attributes_mask & GDK_WA_COLORMAP) && attributes->colormap)
618         {
619           colormap = attributes->colormap;
620         }
621       else
622         {
623           if (gdk_visual_get_system () == visual)
624             colormap = gdk_colormap_get_system ();
625           else
626             colormap =gdk_drawable_get_colormap (parent);
627         }
628
629       gdk_drawable_set_colormap (GDK_DRAWABLE (window), colormap);
630     }
631   else
632     {
633       impl->drawable.format = ((GdkVisualDirectFB *)visual)->format;
634           private->depth = visual->depth;
635     }
636
637   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
638                                   (attributes->cursor) : NULL));
639
640   if (parent_private)
641     parent_private->children = g_list_prepend (parent_private->children,
642                                                window);
643
644   /* we hold a reference count on ourselves */
645   g_object_ref (window);
646
647   if (impl->window)
648     {
649       impl->window->GetID (impl->window, &impl->dfb_id);
650       gdk_directfb_window_id_table_insert (impl->dfb_id, window);
651       gdk_directfb_event_windows_add (window);
652     }
653
654   if (attributes_mask & GDK_WA_TYPE_HINT)
655     gdk_window_set_type_hint (window, attributes->type_hint);
656
657   return window;
658 }
659
660 GdkWindow *
661 _gdk_window_new (GdkWindow     *parent,
662                  GdkWindowAttr *attributes,
663                  gint           attributes_mask)
664 {
665   g_return_val_if_fail (attributes != NULL, NULL);
666
667   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, parent );
668
669   return gdk_directfb_window_new (parent, attributes, attributes_mask,
670                                   DWCAPS_NONE, DWOP_NONE, DSCAPS_NONE);
671 }
672 void
673 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
674 {
675   /* It's somebody else's window, but in our hierarchy,
676    * so reparent it to the root window, and then send
677    * it a delete event, as if we were a WM
678    */
679         _gdk_windowing_window_destroy (window,TRUE,TRUE);
680 }
681
682
683 void
684 _gdk_windowing_window_destroy (GdkWindow *window,
685                                gboolean   recursing,
686                                gboolean   foreign_destroy)
687 {
688   GdkWindowObject       *private;
689   GdkWindowImplDirectFB *impl;
690
691   g_return_if_fail (GDK_IS_WINDOW (window));
692
693   D_DEBUG_AT( GDKDFB_Window, "%s( %p, %srecursing, %sforeign )\n", __FUNCTION__, window,
694               recursing ? "" : "not ", foreign_destroy ? "" : "no " );
695
696   private = GDK_WINDOW_OBJECT (window);
697   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
698
699   _gdk_selection_window_destroyed (window);
700   gdk_directfb_event_windows_remove (window);
701
702   if (window == _gdk_directfb_pointer_grab_window)
703     gdk_pointer_ungrab (GDK_CURRENT_TIME);
704   if (window == _gdk_directfb_keyboard_grab_window)
705     gdk_keyboard_ungrab (GDK_CURRENT_TIME);
706
707   if (window == gdk_directfb_focused_window)
708     gdk_directfb_change_focus (NULL);
709
710
711   if (impl->drawable.surface) {
712     GdkDrawableImplDirectFB *dimpl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
713     if(dimpl->cairo_surface) {
714       cairo_surface_destroy(dimpl->cairo_surface);
715       dimpl->cairo_surface= NULL;
716     }
717     impl->drawable.surface->Release (impl->drawable.surface);
718     impl->drawable.surface = NULL;
719   }
720
721   if (!recursing && !foreign_destroy && impl->window ) {
722         impl->window->SetOpacity (impl->window,0);
723                 impl->window->Close(impl->window);
724         impl->window->Release(impl->window);
725         impl->window = NULL;
726   }
727 }
728
729 /* This function is called when the window is really gone.
730  */
731 void
732 gdk_window_destroy_notify (GdkWindow *window)
733 {
734   g_return_if_fail (GDK_IS_WINDOW (window));
735
736   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
737
738   if (!GDK_WINDOW_DESTROYED (window))
739     {
740       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
741         g_warning ("GdkWindow %p unexpectedly destroyed", window);
742
743       _gdk_window_destroy (window, TRUE);
744     }
745    g_object_unref (window);
746 }
747
748 /* Focus follows pointer */
749 GdkWindow *
750 gdk_directfb_window_find_toplevel (GdkWindow *window)
751 {
752   while (window && window != _gdk_parent_root)
753     {
754       GdkWindow *parent = (GdkWindow *) (GDK_WINDOW_OBJECT (window))->parent;
755
756       if ((parent == _gdk_parent_root) && GDK_WINDOW_IS_MAPPED (window))
757         return window;
758
759       window = parent;
760     }
761
762   return _gdk_parent_root;
763 }
764
765 GdkWindow *
766 gdk_directfb_window_find_focus (void)
767 {
768   if (_gdk_directfb_keyboard_grab_window)
769     return _gdk_directfb_keyboard_grab_window;
770
771   if (!gdk_directfb_focused_window)
772     gdk_directfb_focused_window = g_object_ref (_gdk_parent_root);
773
774   return gdk_directfb_focused_window;
775 }
776
777 void
778 gdk_directfb_change_focus (GdkWindow *new_focus_window)
779 {
780   GdkEventFocus *event;
781   GdkWindow     *old_win;
782   GdkWindow     *new_win;
783   GdkWindow     *event_win;
784
785   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, new_focus_window );
786
787   /* No focus changes while the pointer is grabbed */
788   if (_gdk_directfb_pointer_grab_window)
789     return;
790
791   old_win = gdk_directfb_focused_window;
792   new_win = gdk_directfb_window_find_toplevel (new_focus_window);
793
794   if (old_win == new_win)
795     return;
796
797   if (old_win)
798     {
799       event_win = gdk_directfb_keyboard_event_window (old_win,
800                                                       GDK_FOCUS_CHANGE);
801       if (event_win)
802         {
803           event = (GdkEventFocus *) gdk_directfb_event_make (event_win,
804                                                              GDK_FOCUS_CHANGE);
805           event->in = FALSE;
806         }
807     }
808
809   event_win = gdk_directfb_keyboard_event_window (new_win,
810                                                   GDK_FOCUS_CHANGE);
811   if (event_win)
812     {
813       event = (GdkEventFocus *) gdk_directfb_event_make (event_win,
814                                                          GDK_FOCUS_CHANGE);
815       event->in = TRUE;
816     }
817
818   if (gdk_directfb_focused_window)
819     g_object_unref (gdk_directfb_focused_window);
820   gdk_directfb_focused_window = g_object_ref (new_win);
821 }
822
823 void
824 gdk_window_set_accept_focus (GdkWindow *window,
825                              gboolean accept_focus)
826 {
827   GdkWindowObject *private;
828   g_return_if_fail (window != NULL);
829   g_return_if_fail (GDK_IS_WINDOW (window));
830                                                                                                                       
831   private = (GdkWindowObject *)window;
832                                                                                                                       
833   accept_focus = accept_focus != FALSE;
834                                                                                                                       
835   if (private->accept_focus != accept_focus)
836     private->accept_focus = accept_focus;
837
838 }
839
840 void
841 gdk_window_set_focus_on_map (GdkWindow *window,
842                              gboolean focus_on_map)
843 {
844   GdkWindowObject *private;
845   g_return_if_fail (window != NULL);
846   g_return_if_fail (GDK_IS_WINDOW (window));
847                                                                                                                       
848   private = (GdkWindowObject *)window;
849                                                                                                                       
850   focus_on_map = focus_on_map != FALSE;
851                                                                                                                       
852   if (private->focus_on_map != focus_on_map)
853     private->focus_on_map = focus_on_map;
854 }
855
856 static gboolean
857 gdk_directfb_window_raise (GdkWindow *window)
858 {
859   GdkWindowObject *parent;
860
861   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
862
863   parent = GDK_WINDOW_OBJECT (window)->parent;
864
865   if (parent->children->data == window)
866     return FALSE;
867
868   parent->children = g_list_remove (parent->children, window);
869   parent->children = g_list_prepend (parent->children, window);
870
871   return TRUE;
872 }
873
874 static void
875 gdk_directfb_window_lower (GdkWindow *window)
876 {
877   GdkWindowObject *parent;
878
879   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
880
881   parent = GDK_WINDOW_OBJECT (window)->parent;
882
883   parent->children = g_list_remove (parent->children, window);
884   parent->children = g_list_append (parent->children, window);
885 }
886
887 static gboolean
888 all_parents_shown (GdkWindowObject *private)
889 {
890   while (GDK_WINDOW_IS_MAPPED (private))
891     {
892       if (private->parent)
893         private = GDK_WINDOW_OBJECT (private)->parent;
894       else
895         return TRUE;
896     }
897
898   return FALSE;
899 }
900
901 static void
902 send_map_events (GdkWindowObject *private)
903 {
904   GList     *list;
905   GdkWindow *event_win;
906
907   if (!GDK_WINDOW_IS_MAPPED (private))
908     return;
909
910   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, private );
911
912   event_win = gdk_directfb_other_event_window ((GdkWindow *) private, GDK_MAP);
913   if (event_win)
914     gdk_directfb_event_make (event_win, GDK_MAP);
915
916   for (list = private->children; list; list = list->next)
917     send_map_events (list->data);
918 }
919
920 static GdkWindow *
921 gdk_directfb_find_common_ancestor (GdkWindow *win1,
922                                    GdkWindow *win2)
923 {
924   GdkWindowObject *a;
925   GdkWindowObject *b;
926
927   for (a = GDK_WINDOW_OBJECT (win1); a; a = a->parent)
928     for (b = GDK_WINDOW_OBJECT (win2); b; b = b->parent)
929       {
930         if (a == b)
931           return GDK_WINDOW (a);
932       }
933
934   return NULL;
935 }
936
937 void
938 gdk_directfb_window_send_crossing_events (GdkWindow       *src,
939                                           GdkWindow       *dest,
940                                           GdkCrossingMode  mode)
941 {
942   GdkWindow       *c;
943   GdkWindow       *win, *last, *next;
944   GdkEvent        *event;
945   gint             x, y, x_int, y_int;
946   GdkModifierType  modifiers;
947   GSList          *path, *list;
948   gboolean         non_linear;
949   GdkWindow       *a;
950   GdkWindow       *b;
951   GdkWindow       *event_win;
952
953   D_DEBUG_AT( GDKDFB_Crossing, "%s( %p -> %p, %d )\n", __FUNCTION__, src, dest, mode );
954
955   /* Do a possible cursor change before checking if we need to
956      generate crossing events so cursor changes due to pointer
957      grabs work correctly. */
958   {
959     static GdkCursorDirectFB *last_cursor = NULL;
960
961     GdkWindowObject       *private = GDK_WINDOW_OBJECT (dest);
962     GdkWindowImplDirectFB *impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
963     GdkCursorDirectFB     *cursor;
964
965     if (_gdk_directfb_pointer_grab_cursor)
966       cursor = (GdkCursorDirectFB*) _gdk_directfb_pointer_grab_cursor;
967     else
968       cursor = (GdkCursorDirectFB*) impl->cursor;
969
970     if (cursor != last_cursor)
971       {
972         win     = gdk_directfb_window_find_toplevel (dest);
973         private = GDK_WINDOW_OBJECT (win);
974         impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
975
976         if (impl->window)
977           impl->window->SetCursorShape (impl->window,
978                                         cursor->shape,
979                                         cursor->hot_x, cursor->hot_y);
980         last_cursor = cursor;
981       }
982   }
983
984   if (dest == gdk_directfb_window_containing_pointer) {
985     D_DEBUG_AT( GDKDFB_Crossing, "  -> already containing the pointer\n" );
986     return;
987   }
988
989   if (gdk_directfb_window_containing_pointer == NULL)
990     gdk_directfb_window_containing_pointer = g_object_ref (_gdk_parent_root);
991
992   if (src)
993     a = src;
994   else
995     a = gdk_directfb_window_containing_pointer;
996
997   b = dest;
998
999   if (a == b) {
1000     D_DEBUG_AT( GDKDFB_Crossing, "  -> src == dest\n" );
1001     return;
1002   }
1003
1004   /* gdk_directfb_window_containing_pointer might have been destroyed.
1005    * The refcount we hold on it should keep it, but it's parents
1006    * might have died.
1007    */
1008   if (GDK_WINDOW_DESTROYED (a)) {
1009     D_DEBUG_AT( GDKDFB_Crossing, "  -> src is destroyed!\n" );
1010     a = _gdk_parent_root;
1011   }
1012
1013   gdk_directfb_mouse_get_info (&x, &y, &modifiers);
1014
1015   c = gdk_directfb_find_common_ancestor (a, b);
1016
1017   D_DEBUG_AT( GDKDFB_Crossing, "  -> common ancestor %p\n", c );
1018
1019   non_linear = (c != a) && (c != b);
1020
1021   D_DEBUG_AT( GDKDFB_Crossing, "  -> non_linear: %s\n", non_linear ? "YES" : "NO" );
1022
1023   event_win = gdk_directfb_pointer_event_window (a, GDK_LEAVE_NOTIFY);
1024   if (event_win)
1025     {
1026       D_DEBUG_AT( GDKDFB_Crossing, "  -> sending LEAVE to src\n" );
1027
1028       event = gdk_directfb_event_make (event_win, GDK_LEAVE_NOTIFY);
1029       event->crossing.subwindow = NULL;
1030
1031       gdk_window_get_origin (a, &x_int, &y_int);
1032
1033       event->crossing.x      = x - x_int;
1034       event->crossing.y      = y - y_int;
1035       event->crossing.x_root = x;
1036       event->crossing.y_root = y;
1037       event->crossing.mode   = mode;
1038
1039       if (non_linear)
1040         event->crossing.detail = GDK_NOTIFY_NONLINEAR;
1041       else if (c == a)
1042         event->crossing.detail = GDK_NOTIFY_INFERIOR;
1043       else
1044         event->crossing.detail = GDK_NOTIFY_ANCESTOR;
1045
1046       event->crossing.focus = FALSE;
1047       event->crossing.state = modifiers;
1048
1049       D_DEBUG_AT( GDKDFB_Crossing, "  => LEAVE (%p/%p) at %4f,%4f (%4f,%4f) mode %d, detail %d\n",
1050                   event_win, a,
1051                   event->crossing.x, event->crossing.y, event->crossing.x_root, event->crossing.y_root,
1052                   event->crossing.mode, event->crossing.detail );
1053     }
1054
1055    /* Traverse up from a to (excluding) c */
1056   if (c != a)
1057     {
1058       last = a;
1059       win = GDK_WINDOW (GDK_WINDOW_OBJECT (a)->parent);
1060       while (win != c)
1061         {
1062           event_win =
1063             gdk_directfb_pointer_event_window (win, GDK_LEAVE_NOTIFY);
1064
1065           if (event_win)
1066             {
1067               event = gdk_directfb_event_make (event_win, GDK_LEAVE_NOTIFY);
1068
1069               event->crossing.subwindow = g_object_ref (last);
1070
1071               gdk_window_get_origin (win, &x_int, &y_int);
1072
1073               event->crossing.x      = x - x_int;
1074               event->crossing.y      = y - y_int;
1075               event->crossing.x_root = x;
1076               event->crossing.y_root = y;
1077               event->crossing.mode   = mode;
1078
1079               if (non_linear)
1080                 event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
1081               else
1082                 event->crossing.detail = GDK_NOTIFY_VIRTUAL;
1083
1084               event->crossing.focus = FALSE;
1085               event->crossing.state = modifiers;
1086
1087               D_DEBUG_AT( GDKDFB_Crossing, "  -> LEAVE (%p/%p) at %4f,%4f (%4f,%4f) mode %d, detail %d\n",
1088                           event_win, win,
1089                           event->crossing.x, event->crossing.y, event->crossing.x_root, event->crossing.y_root,
1090                           event->crossing.mode, event->crossing.detail );
1091             }
1092
1093           last = win;
1094           win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
1095         }
1096     }
1097
1098   /* Traverse down from c to b */
1099   if (c != b)
1100     {
1101       path = NULL;
1102       win = GDK_WINDOW (GDK_WINDOW_OBJECT (b)->parent);
1103       while (win != c)
1104         {
1105           path = g_slist_prepend (path, win);
1106           win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
1107         }
1108
1109       list = path;
1110       while (list)
1111         {
1112           win = GDK_WINDOW (list->data);
1113           list = g_slist_next (list);
1114
1115           if (list)
1116             next = GDK_WINDOW (list->data);
1117           else
1118             next = b;
1119
1120           event_win =
1121             gdk_directfb_pointer_event_window (win, GDK_ENTER_NOTIFY);
1122
1123           if (event_win)
1124             {
1125               event = gdk_directfb_event_make (event_win, GDK_ENTER_NOTIFY);
1126
1127               event->crossing.subwindow = g_object_ref (next);
1128
1129               gdk_window_get_origin (win, &x_int, &y_int);
1130
1131               event->crossing.x      = x - x_int;
1132               event->crossing.y      = y - y_int;
1133               event->crossing.x_root = x;
1134               event->crossing.y_root = y;
1135               event->crossing.mode   = mode;
1136
1137               if (non_linear)
1138                 event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
1139               else
1140                 event->crossing.detail = GDK_NOTIFY_VIRTUAL;
1141
1142               event->crossing.focus = FALSE;
1143               event->crossing.state = modifiers;
1144
1145               D_DEBUG_AT( GDKDFB_Crossing, "  -> ENTER (%p/%p) at %4f,%4f (%4f,%4f) mode %d, detail %d\n",
1146                           event_win, win,
1147                           event->crossing.x, event->crossing.y, event->crossing.x_root, event->crossing.y_root,
1148                           event->crossing.mode, event->crossing.detail );
1149             }
1150         }
1151
1152       g_slist_free (path);
1153     }
1154
1155   event_win = gdk_directfb_pointer_event_window (b, GDK_ENTER_NOTIFY);
1156   if (event_win)
1157     {
1158       event = gdk_directfb_event_make (event_win, GDK_ENTER_NOTIFY);
1159
1160       event->crossing.subwindow = NULL;
1161
1162       gdk_window_get_origin (b, &x_int, &y_int);
1163
1164       event->crossing.x      = x - x_int;
1165       event->crossing.y      = y - y_int;
1166       event->crossing.x_root = x;
1167       event->crossing.y_root = y;
1168       event->crossing.mode   = mode;
1169
1170       if (non_linear)
1171         event->crossing.detail = GDK_NOTIFY_NONLINEAR;
1172       else if (c==a)
1173         event->crossing.detail = GDK_NOTIFY_ANCESTOR;
1174       else
1175         event->crossing.detail = GDK_NOTIFY_INFERIOR;
1176
1177       event->crossing.focus = FALSE;
1178       event->crossing.state = modifiers;
1179
1180       D_DEBUG_AT( GDKDFB_Crossing, "  => ENTER (%p/%p) at %4f,%4f (%4f,%4f) mode %d, detail %d\n",
1181                   event_win, b,
1182                   event->crossing.x, event->crossing.y, event->crossing.x_root, event->crossing.y_root,
1183                   event->crossing.mode, event->crossing.detail );
1184     }
1185
1186   if (mode != GDK_CROSSING_GRAB)
1187     {
1188       //this seems to cause focus to change as the pointer moves yuck
1189       //gdk_directfb_change_focus (b);
1190       if (b != gdk_directfb_window_containing_pointer)
1191         {
1192           g_object_unref (gdk_directfb_window_containing_pointer);
1193           gdk_directfb_window_containing_pointer = g_object_ref (b);
1194         }
1195     }
1196 }
1197
1198 static void
1199 show_window_internal (GdkWindow *window,
1200                       gboolean   raise)
1201 {
1202   GdkWindowObject       *private;
1203   GdkWindowImplDirectFB *impl;
1204   GdkWindow             *mousewin;
1205
1206   D_DEBUG_AT( GDKDFB_Window, "%s( %p, %sraise )\n", __FUNCTION__, window, raise ? "" : "no " );
1207
1208   private = GDK_WINDOW_OBJECT (window);
1209   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
1210
1211   if (!private->destroyed && !GDK_WINDOW_IS_MAPPED (private))
1212     {
1213       private->state &= ~GDK_WINDOW_STATE_WITHDRAWN;
1214
1215       if (raise)
1216         gdk_window_raise (window);
1217
1218       if (all_parents_shown (GDK_WINDOW_OBJECT (private)->parent))
1219         {
1220           send_map_events (private);
1221
1222           mousewin = gdk_window_at_pointer (NULL, NULL);
1223           gdk_directfb_window_send_crossing_events (NULL, mousewin,
1224                                                     GDK_CROSSING_NORMAL);
1225
1226           if (private->input_only)
1227             return;
1228
1229           gdk_window_invalidate_rect (window, NULL, TRUE);
1230         }
1231     }
1232
1233   if (impl->window)
1234     {
1235       if (gdk_directfb_apply_focus_opacity)
1236         impl->window->SetOpacity (impl->window,
1237                                   (impl->opacity >> 1) + (impl->opacity >> 2));
1238       else
1239         impl->window->SetOpacity (impl->window, impl->opacity);
1240           /* if its the first window focus it */
1241     }
1242 }
1243
1244 static void
1245 gdk_directfb_window_show (GdkWindow *window,
1246                           gboolean   raise)
1247 {
1248   g_return_if_fail (GDK_IS_WINDOW (window));
1249
1250   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
1251
1252   show_window_internal (window, raise);
1253 }
1254
1255 static void
1256 gdk_directfb_window_hide (GdkWindow *window)
1257 {
1258   GdkWindowObject       *private;
1259   GdkWindowImplDirectFB *impl;
1260   GdkWindow             *mousewin;
1261   GdkWindow             *event_win;
1262
1263   g_return_if_fail (GDK_IS_WINDOW (window));
1264
1265   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
1266
1267   private = GDK_WINDOW_OBJECT (window);
1268   impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
1269
1270   if (impl->window)
1271     impl->window->SetOpacity (impl->window, 0);
1272
1273   if (!private->destroyed && GDK_WINDOW_IS_MAPPED (private))
1274     {
1275       GdkEvent *event;
1276
1277       private->state |= GDK_WINDOW_STATE_WITHDRAWN;
1278
1279       if (!private->input_only && private->parent)
1280         {
1281           gdk_window_clear_area (GDK_WINDOW (private->parent),
1282                                  private->x,
1283                                  private->y,
1284                                  impl->drawable.width,
1285                                  impl->drawable.height);
1286         }
1287
1288       event_win = gdk_directfb_other_event_window (window, GDK_UNMAP);
1289       if (event_win)
1290         event = gdk_directfb_event_make (event_win, GDK_UNMAP);
1291
1292       mousewin = gdk_window_at_pointer (NULL, NULL);
1293       gdk_directfb_window_send_crossing_events (NULL,
1294                                                 mousewin,
1295                                                 GDK_CROSSING_NORMAL);
1296
1297       if (window == _gdk_directfb_pointer_grab_window)
1298         gdk_pointer_ungrab (GDK_CURRENT_TIME);
1299       if (window == _gdk_directfb_keyboard_grab_window)
1300         gdk_keyboard_ungrab (GDK_CURRENT_TIME);
1301     }
1302 }
1303
1304 static void
1305 gdk_directfb_window_withdraw (GdkWindow *window)
1306 {
1307   g_return_if_fail (GDK_IS_WINDOW (window));
1308
1309   /* for now this should be enough */
1310   gdk_window_hide (window);
1311 }
1312
1313 void
1314 _gdk_directfb_move_resize_child (GdkWindow *window,
1315                                  gint       x,
1316                                  gint       y,
1317                                  gint       width,
1318                                  gint       height)
1319 {
1320   GdkWindowObject       *private;
1321   GdkWindowImplDirectFB *impl;
1322   GdkWindowImplDirectFB *parent_impl;
1323   GList                 *list;
1324
1325   g_return_if_fail (GDK_IS_WINDOW (window));
1326
1327   private = GDK_WINDOW_OBJECT (window);
1328   impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
1329
1330   private->x = x;
1331   private->y = y;
1332
1333   impl->drawable.width  = width;
1334   impl->drawable.height = height;
1335
1336   if (!private->input_only)
1337     {
1338     if (impl->drawable.surface) {
1339       GdkDrawableImplDirectFB *dimpl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
1340       if(dimpl->cairo_surface) {
1341         cairo_surface_destroy(dimpl->cairo_surface);
1342         dimpl->cairo_surface= NULL;
1343       }
1344     impl->drawable.surface->Release (impl->drawable.surface);
1345     impl->drawable.surface = NULL;
1346   }
1347
1348       parent_impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (private->parent)->impl);
1349
1350       if (parent_impl->drawable.surface)
1351         {
1352           DFBRectangle rect = { x, y, width, height };
1353
1354           parent_impl->drawable.surface->GetSubSurface (parent_impl->drawable.surface,
1355                                                         &rect,
1356                                                         &impl->drawable.surface);
1357         }
1358     }
1359
1360   for (list = private->children; list; list = list->next)
1361     {
1362       private = GDK_WINDOW_OBJECT (list->data);
1363           impl  = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
1364       _gdk_directfb_move_resize_child (list->data,
1365                                        private->x, private->y,
1366                                        impl->drawable.width, impl->drawable.height);
1367     }
1368 }
1369
1370 static  void
1371 gdk_directfb_window_move (GdkWindow *window,
1372                           gint       x,
1373                           gint       y)
1374 {
1375   GdkWindowObject       *private;
1376   GdkWindowImplDirectFB *impl;
1377
1378   g_return_if_fail (GDK_IS_WINDOW (window));
1379
1380   private = GDK_WINDOW_OBJECT (window);
1381   impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
1382
1383   if (impl->window)
1384     {
1385       private->x = x;
1386       private->y = y;
1387       impl->window->MoveTo (impl->window, x, y);
1388     }
1389   else
1390     {
1391          gint width=impl->drawable.width;
1392          gint height=impl->drawable.height;
1393       GdkRectangle  old =
1394       { private->x, private->y,width,height };
1395
1396       _gdk_directfb_move_resize_child (window, x, y, width, height);
1397       _gdk_directfb_calc_abs (window);
1398
1399       if (GDK_WINDOW_IS_MAPPED (private))
1400         {
1401           GdkWindow    *mousewin;
1402           GdkRectangle  new = { x, y, width, height };
1403
1404           gdk_rectangle_union (&new, &old, &new);
1405           gdk_window_invalidate_rect (GDK_WINDOW (private->parent), &new,TRUE);
1406
1407           /* The window the pointer is in might have changed */
1408           mousewin = gdk_window_at_pointer (NULL, NULL);
1409           gdk_directfb_window_send_crossing_events (NULL, mousewin,
1410                                                     GDK_CROSSING_NORMAL);
1411         }
1412     }
1413 }
1414
1415 static void
1416 gdk_directfb_window_move_resize (GdkWindow *window,
1417                                  gboolean   with_move,
1418                                  gint       x,
1419                                  gint       y,
1420                                  gint       width,
1421                                  gint       height)
1422 {
1423   GdkWindowObject       *private;
1424   GdkWindowImplDirectFB *impl;
1425
1426   g_return_if_fail (GDK_IS_WINDOW (window));
1427
1428   private = GDK_WINDOW_OBJECT (window);
1429   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
1430
1431   if (width < 1)
1432      width = 1;
1433   if (height < 1)
1434     height = 1;
1435
1436   if (private->destroyed ||
1437       (private->x == x  &&  private->y == y  &&
1438        impl->drawable.width == width  &&  impl->drawable.height == height))
1439     return;
1440
1441   if (private->parent && (private->parent->window_type != GDK_WINDOW_CHILD))
1442     {
1443       GdkWindowChildHandlerData *data;
1444
1445       data = g_object_get_data (G_OBJECT (private->parent),
1446                                 "gdk-window-child-handler");
1447
1448       if (data &&
1449           (*data->changed) (window, x, y, width, height, data->user_data))
1450         return;
1451     }
1452
1453   if (impl->drawable.width == width  &&  impl->drawable.height == height)
1454     {
1455       if (with_move)
1456         gdk_directfb_window_move (window, x, y);
1457     }
1458   else if (impl->window)
1459     {
1460       private->x = x;
1461       private->y = y;
1462       impl->drawable.width = width;
1463       impl->drawable.height = height;
1464
1465       if (with_move)
1466         impl->window->MoveTo (impl->window, x, y);
1467       impl->window->Resize (impl->window, width, height);
1468     }
1469   else
1470     {
1471       GdkRectangle old = { private->x, private->y, impl->drawable.width, impl->drawable.height };
1472       GdkRectangle new = { x, y, width, height };
1473
1474       if (! with_move)
1475         {
1476           new.x = private->x;
1477           new.y = private->y;
1478         }
1479
1480       _gdk_directfb_move_resize_child (window,
1481                                        new.x, new.y, new.width, new.height);
1482       _gdk_directfb_calc_abs (window);
1483
1484       if (GDK_WINDOW_IS_MAPPED (private))
1485         {
1486           GdkWindow *mousewin;
1487
1488           gdk_rectangle_union (&new, &old, &new);
1489           gdk_window_invalidate_rect (GDK_WINDOW (private->parent), &new,TRUE);
1490
1491           /* The window the pointer is in might have changed */
1492           mousewin = gdk_window_at_pointer (NULL, NULL);
1493           gdk_directfb_window_send_crossing_events (NULL, mousewin,
1494                                                     GDK_CROSSING_NORMAL);
1495         }
1496     }
1497 }
1498
1499 static gboolean
1500 gdk_directfb_window_reparent (GdkWindow *window,
1501                               GdkWindow *new_parent,
1502                               gint       x,
1503                               gint       y)
1504 {
1505   GdkWindowObject *window_private;
1506   GdkWindowObject *parent_private;
1507   GdkWindowObject *old_parent_private;
1508   GdkWindowImplDirectFB *impl;
1509   GdkWindowImplDirectFB *parent_impl;
1510   GdkVisual             *visual;
1511
1512   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1513
1514   if (GDK_WINDOW_DESTROYED (window))
1515     return FALSE;
1516
1517   if (!new_parent)
1518     new_parent = _gdk_parent_root;
1519
1520   window_private = (GdkWindowObject *) window;
1521   old_parent_private = (GdkWindowObject *) window_private->parent;
1522   parent_private = (GdkWindowObject *) new_parent;
1523   parent_impl = GDK_WINDOW_IMPL_DIRECTFB (parent_private->impl);
1524   visual = gdk_drawable_get_visual (window);
1525
1526   /* already parented */
1527   if( window_private->parent == (GdkWindowObject *)new_parent )
1528           return FALSE;
1529
1530   window_private->parent = (GdkWindowObject *) new_parent;
1531
1532   if (old_parent_private)
1533     {
1534       old_parent_private->children =
1535         g_list_remove (old_parent_private->children, window);
1536     }
1537
1538     parent_private->children = g_list_prepend (parent_private->children, window);
1539
1540     impl = GDK_WINDOW_IMPL_DIRECTFB (window_private->impl);
1541
1542     if( impl->drawable.surface ) {
1543         impl->drawable.surface->Release (impl->drawable.surface);
1544         impl->drawable.surface = NULL;
1545     }
1546
1547     if( impl->window != NULL ) { 
1548         gdk_directfb_window_id_table_remove (impl->dfb_id);
1549         impl->window->SetOpacity (impl->window,0);
1550                 impl->window->Close(impl->window);
1551         impl->window->Release(impl->window);
1552         impl->window = NULL;
1553     }
1554
1555     //create window were a child of the root now
1556     if( window_private->parent == (GdkWindowObject *)_gdk_parent_root)  {
1557         DFBWindowDescription  desc;
1558         DFBWindowOptions  window_options = DWOP_NONE;
1559         desc.flags = DWDESC_CAPS;
1560         if( window_private->input_only ) {
1561             desc.caps = DWCAPS_INPUTONLY;
1562         } else {
1563             desc.flags |= DWDESC_PIXELFORMAT;
1564             desc.pixelformat = ((GdkVisualDirectFB *) visual)->format;
1565             if (DFB_PIXELFORMAT_HAS_ALPHA (desc.pixelformat)) {
1566                 desc.flags |= DWDESC_CAPS;
1567                 desc.caps = DWCAPS_ALPHACHANNEL;
1568             }
1569        }
1570        if( window_private->window_type ==  GDK_WINDOW_CHILD )
1571            window_private->window_type = GDK_WINDOW_TOPLEVEL;
1572         desc.flags |= ( DWDESC_WIDTH | DWDESC_HEIGHT |
1573                       DWDESC_POSX  | DWDESC_POSY );
1574         desc.posx   = x;
1575         desc.posy   = y;
1576         desc.width  = impl->drawable.width;
1577         desc.height = impl->drawable.height;
1578         if (!create_directfb_window (impl, &desc, window_options))
1579         {
1580                   g_assert(0);
1581           _gdk_window_destroy (window, FALSE);
1582           return FALSE;
1583         }
1584         /* we hold a reference count on ourselves */
1585         g_object_ref (window);
1586         impl->window->GetID (impl->window, &impl->dfb_id);
1587         gdk_directfb_window_id_table_insert (impl->dfb_id, window);
1588         gdk_directfb_event_windows_add (window);
1589    } else {
1590           DFBRectangle rect = { x, y, impl->drawable.width,
1591                                      impl->drawable.height};
1592           impl->window = NULL;
1593           parent_impl->drawable.surface->GetSubSurface (
1594                           parent_impl->drawable.surface,
1595                           &rect,
1596                           &impl->drawable.surface);
1597    }
1598
1599    return TRUE;
1600 }
1601
1602 static void
1603 gdk_directfb_window_clear_area (GdkWindow *window,
1604                                 gint       x,
1605                                 gint       y,
1606                                 gint       width,
1607                                 gint       height,
1608                                 gboolean   send_expose)
1609 {
1610   GdkWindowObject         *private;
1611   GdkDrawableImplDirectFB *impl;
1612   GdkPixmap               *bg_pixmap;
1613   GdkWindowObject         *relative_to;
1614   GdkGC                   *gc = NULL;
1615   gint                     dx = 0;
1616   gint                     dy = 0;
1617
1618   D_DEBUG_AT( GDKDFB_Window, "%s( %p, %4d,%4d-%4dx%4d )\n", __FUNCTION__, window, x, y, width, height );
1619
1620   g_return_if_fail (GDK_IS_WINDOW (window));
1621
1622   if (GDK_WINDOW_DESTROYED (window)) {
1623     D_DEBUG_AT( GDKDFB_Window, "  -> DESTROYED!\n" );
1624     return;
1625   }
1626   
1627   private = GDK_WINDOW_OBJECT (window);
1628
1629   impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
1630
1631   /**
1632         Follow XClearArea definition for zero height width
1633   **/
1634   if( width == 0 )  
1635                 width = impl->width-x;
1636   if( height == 0 )  
1637                 height = impl->height-y;
1638
1639   bg_pixmap = private->bg_pixmap;
1640
1641   for (relative_to = private;
1642        relative_to && bg_pixmap == GDK_PARENT_RELATIVE_BG;
1643        relative_to = relative_to->parent)
1644     {
1645       bg_pixmap = relative_to->bg_pixmap;
1646       dx += relative_to->x;
1647       dy += relative_to->y;
1648     }
1649
1650   if (bg_pixmap == GDK_NO_BG) {
1651     D_DEBUG_AT( GDKDFB_Window, "  -> NO BG\n" );
1652     return;
1653   }
1654
1655   if (bg_pixmap && bg_pixmap != GDK_PARENT_RELATIVE_BG)
1656     {
1657       GdkGCValues  values;
1658
1659       values.fill = GDK_TILED;
1660       values.tile = bg_pixmap;
1661       values.ts_x_origin = - dx;
1662       values.ts_y_origin = - dy;
1663
1664       D_DEBUG_AT( GDKDFB_Window, "  -> PIXMAP\n" );
1665
1666       gc = gdk_gc_new_with_values (GDK_DRAWABLE (impl), &values,
1667                                    GDK_GC_FILL | GDK_GC_TILE |
1668                                    GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
1669     }
1670   else 
1671     {
1672       /* GDK_PARENT_RELATIVE_BG, but no pixmap,
1673          get the color from the parent window. */
1674
1675       GdkGCValues  values;
1676
1677       values.foreground = relative_to->bg_color;
1678
1679       D_DEBUG_AT( GDKDFB_Window, "  -> COLOR\n" );
1680
1681       gc = gdk_gc_new_with_values (GDK_DRAWABLE (impl), &values,
1682                                    GDK_GC_FOREGROUND);
1683     }
1684
1685   gdk_draw_rectangle (GDK_DRAWABLE (impl),
1686                                 gc, TRUE, x, y, width, height);
1687
1688   if (gc)
1689     g_object_unref (gc);
1690 }
1691
1692 static void
1693 gdk_window_directfb_raise (GdkWindow *window)
1694 {
1695   GdkWindowImplDirectFB *impl;
1696
1697   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
1698
1699   g_return_if_fail (GDK_IS_WINDOW (window));
1700
1701   if (GDK_WINDOW_DESTROYED (window))
1702     return;
1703
1704   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
1705
1706   if (impl->window)
1707     {
1708       DFBResult ret;
1709
1710       ret = impl->window->RaiseToTop (impl->window);
1711       if (ret)
1712         DirectFBError ("gdkwindow-directfb.c: RaiseToTop", ret);
1713       else
1714         gdk_directfb_window_raise (window);
1715     }
1716   else
1717     {
1718       if (gdk_directfb_window_raise (window))
1719         gdk_window_invalidate_rect (window, NULL, TRUE);
1720     }
1721 }
1722
1723 static void
1724 gdk_window_directfb_lower (GdkWindow *window)
1725 {
1726   GdkWindowImplDirectFB *impl;
1727
1728   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
1729
1730   g_return_if_fail (GDK_IS_WINDOW (window));
1731
1732   if (GDK_WINDOW_DESTROYED (window))
1733     return;
1734
1735   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
1736
1737   if (impl->window)
1738     {
1739       DFBResult ret;
1740
1741       ret = impl->window->LowerToBottom (impl->window);
1742       if (ret)
1743         DirectFBError ("gdkwindow-directfb.c: LowerToBottom", ret);
1744       else
1745         gdk_directfb_window_lower (window);
1746     }
1747   else
1748     {
1749       gdk_directfb_window_lower (window);
1750       gdk_window_invalidate_rect (window, NULL, TRUE);
1751     }
1752 }
1753
1754 void
1755 gdk_window_set_hints (GdkWindow *window,
1756                       gint       x,
1757                       gint       y,
1758                       gint       min_width,
1759                       gint       min_height,
1760                       gint       max_width,
1761                       gint       max_height,
1762                       gint       flags)
1763 {
1764   g_return_if_fail (GDK_IS_WINDOW (window));
1765
1766   if (GDK_WINDOW_DESTROYED (window))
1767     return;
1768
1769   D_DEBUG_AT( GDKDFB_Window, "%s( %p, %3d,%3d, min %4dx%4d, max %4dx%4d, flags 0x%08x )\n", __FUNCTION__,
1770               window, x,y, min_width, min_height, max_width, max_height, flags );
1771   /* N/A */
1772 }
1773
1774 void
1775 gdk_window_set_geometry_hints (GdkWindow         *window,
1776                                const GdkGeometry *geometry,
1777                                GdkWindowHints     geom_mask)
1778 {
1779   g_return_if_fail (GDK_IS_WINDOW (window));
1780
1781   if (GDK_WINDOW_DESTROYED (window))
1782     return;
1783
1784   /* N/A */
1785 }
1786
1787 void
1788 gdk_window_set_title (GdkWindow   *window,
1789                       const gchar *title)
1790 {
1791   g_return_if_fail (GDK_IS_WINDOW (window));
1792
1793   if (GDK_WINDOW_DESTROYED (window))
1794     return;
1795
1796   D_DEBUG_AT( GDKDFB_Window, "%s( %p, '%s' )\n", __FUNCTION__, window, title );
1797   /* N/A */
1798   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
1799 }
1800
1801 void
1802 gdk_window_set_role (GdkWindow   *window,
1803                      const gchar *role)
1804 {
1805   g_return_if_fail (GDK_IS_WINDOW (window));
1806
1807   if (GDK_WINDOW_DESTROYED (window))
1808     return;
1809
1810   /* N/A */
1811 }
1812
1813 /**
1814  * gdk_window_set_startup_id:
1815  * @window: a toplevel #GdkWindow
1816  * @startup_id: a string with startup-notification identifier
1817  *
1818  * When using GTK+, typically you should use gtk_window_set_startup_id()
1819  * instead of this low-level function.
1820  *
1821  * Since: 2.12
1822  *
1823  **/
1824 void
1825 gdk_window_set_startup_id (GdkWindow   *window,
1826                            const gchar *startup_id)
1827 {
1828 }
1829
1830 void
1831 gdk_window_set_transient_for (GdkWindow *window,
1832                               GdkWindow *parent)
1833 {
1834   GdkWindowObject *private;
1835   GdkWindowObject *root;
1836   gint i;
1837
1838   g_return_if_fail (GDK_IS_WINDOW (window));
1839   g_return_if_fail (GDK_IS_WINDOW (parent));
1840
1841   private = GDK_WINDOW_OBJECT (window);
1842   root    = GDK_WINDOW_OBJECT (_gdk_parent_root);
1843
1844   g_return_if_fail (GDK_WINDOW (private->parent) == _gdk_parent_root);
1845   g_return_if_fail (GDK_WINDOW (GDK_WINDOW_OBJECT (parent)->parent) == _gdk_parent_root);
1846
1847   root->children = g_list_remove (root->children, window);
1848
1849   i = g_list_index (root->children, parent);
1850   if (i < 0)
1851     root->children = g_list_prepend (root->children, window);
1852   else
1853     root->children = g_list_insert (root->children, window, i);
1854 }
1855
1856 static void
1857 gdk_directfb_window_set_background (GdkWindow *window,
1858                                     const GdkColor  *color)
1859 {
1860   GdkWindowObject *private;
1861
1862   g_return_if_fail (GDK_IS_WINDOW (window));
1863
1864   g_return_if_fail (color != NULL);
1865
1866   D_DEBUG_AT( GDKDFB_Window, "%s( %p, %d,%d,%d )\n", __FUNCTION__, window, color->red, color->green, color->blue );
1867
1868   private = GDK_WINDOW_OBJECT (window);
1869   private->bg_color = *color;
1870
1871   if (private->bg_pixmap &&
1872       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1873       private->bg_pixmap != GDK_NO_BG)
1874     g_object_unref (private->bg_pixmap);
1875
1876   private->bg_pixmap = NULL;
1877 }
1878
1879 static void
1880 gdk_directfb_window_set_back_pixmap (GdkWindow *window,
1881                                      GdkPixmap *pixmap,
1882                                      gboolean   parent_relative)
1883 {
1884   GdkWindowObject *private;
1885   GdkPixmap       *old_pixmap;
1886
1887   g_return_if_fail (GDK_IS_WINDOW (window));
1888   g_return_if_fail (pixmap == NULL || !parent_relative);
1889
1890   D_DEBUG_AT( GDKDFB_Window, "%s( %p, %p, %srelative )\n", __FUNCTION__,
1891               window, pixmap, parent_relative ? "" : "not " );
1892
1893   private = GDK_WINDOW_OBJECT (window);
1894   old_pixmap = private->bg_pixmap;
1895
1896   if (private->bg_pixmap &&
1897       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1898       private->bg_pixmap != GDK_NO_BG)
1899     {
1900       g_object_unref (private->bg_pixmap);
1901     }
1902
1903   if (parent_relative)
1904     {
1905       private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1906     }
1907   else
1908     {
1909       if (pixmap)
1910         {
1911           g_object_ref (pixmap);
1912           private->bg_pixmap = pixmap;
1913         }
1914       else
1915         {
1916           private->bg_pixmap = GDK_NO_BG;
1917         }
1918     }
1919 }
1920
1921 static void
1922 gdk_directfb_window_set_cursor (GdkWindow *window,
1923                                 GdkCursor *cursor)
1924 {
1925   GdkWindowImplDirectFB *impl;
1926   GdkCursor             *old_cursor;
1927
1928   g_return_if_fail (GDK_IS_WINDOW (window));
1929
1930   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
1931   old_cursor = impl->cursor;
1932
1933   impl->cursor = (cursor ?
1934                   gdk_cursor_ref (cursor) : gdk_cursor_new (GDK_LEFT_PTR));
1935
1936   if (gdk_window_at_pointer (NULL, NULL) == window)
1937     {
1938       /* This is a bit evil but we want to keep all cursor changes in
1939          one place, so let gdk_directfb_window_send_crossing_events
1940          do the work for us. */
1941
1942       gdk_directfb_window_send_crossing_events (window, window,
1943                                                 GDK_CROSSING_NORMAL);
1944     }
1945   else if (impl->window)
1946     {
1947       GdkCursorDirectFB *dfb_cursor = (GdkCursorDirectFB *) impl->cursor;
1948
1949       /* this branch takes care of setting the cursor for unmapped windows */
1950
1951       impl->window->SetCursorShape (impl->window,
1952                                     dfb_cursor->shape,
1953                                     dfb_cursor->hot_x, dfb_cursor->hot_y);
1954     }
1955
1956   if (old_cursor)
1957     gdk_cursor_unref (old_cursor);
1958 }
1959
1960 static void
1961 gdk_directfb_window_get_geometry (GdkWindow *window,
1962                                   gint      *x,
1963                                   gint      *y,
1964                                   gint      *width,
1965                                   gint      *height,
1966                                   gint      *depth)
1967 {
1968   GdkWindowObject         *private;
1969   GdkDrawableImplDirectFB *impl;
1970
1971   g_return_if_fail (GDK_IS_WINDOW (window));
1972
1973   private = GDK_WINDOW_OBJECT (window);
1974   impl    = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
1975
1976   if (!GDK_WINDOW_DESTROYED (window))
1977     {
1978       if (x)
1979         *x = private->x;
1980
1981       if (y)
1982         *y = private->y;
1983
1984       if (width)
1985         *width = impl->width;
1986
1987       if (height)
1988         *height = impl->height;
1989
1990       if (depth)
1991         *depth = DFB_BITS_PER_PIXEL(impl->format);
1992     }
1993 }
1994
1995 void
1996 _gdk_directfb_calc_abs (GdkWindow *window)
1997 {
1998   GdkWindowObject         *private;
1999   GdkDrawableImplDirectFB *impl;
2000   GList                   *list;
2001
2002   g_return_if_fail (GDK_IS_WINDOW (window));
2003
2004   private = GDK_WINDOW_OBJECT (window);
2005   impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
2006
2007   impl->abs_x = private->x;
2008   impl->abs_y = private->y;
2009
2010   if (private->parent)
2011     {
2012       GdkDrawableImplDirectFB *parent_impl =
2013         GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (private->parent)->impl);
2014
2015       impl->abs_x += parent_impl->abs_x;
2016       impl->abs_y += parent_impl->abs_y;
2017     }
2018
2019   D_DEBUG_AT( GDKDFB_Window, "%s( %p ) -> %4d,%4d\n", __FUNCTION__, window, impl->abs_x, impl->abs_y );
2020
2021   for (list = private->children; list; list = list->next)
2022     {
2023       _gdk_directfb_calc_abs (list->data);
2024     }
2025 }
2026
2027 static gboolean
2028 gdk_directfb_window_get_origin (GdkWindow *window,
2029                                 gint      *x,
2030                                 gint      *y)
2031 {
2032   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2033
2034   if (!GDK_WINDOW_DESTROYED (window))
2035     {
2036       GdkDrawableImplDirectFB *impl;
2037
2038       impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
2039
2040       if (x)
2041         *x = impl->abs_x;
2042       if (y)
2043         *y = impl->abs_y;
2044
2045       return TRUE;
2046     }
2047
2048   return FALSE;
2049 }
2050
2051 gboolean
2052 gdk_window_get_deskrelative_origin (GdkWindow *window,
2053                                     gint      *x,
2054                                     gint      *y)
2055 {
2056   return gdk_window_get_origin (window, x, y);
2057 }
2058
2059 void
2060 gdk_window_get_root_origin (GdkWindow *window,
2061                             gint      *x,
2062                             gint      *y)
2063 {
2064   GdkWindowObject *rover;
2065
2066   g_return_if_fail (GDK_IS_WINDOW (window));
2067
2068   rover = (GdkWindowObject*) window;
2069   if (x)
2070     *x = 0;
2071   if (y)
2072     *y = 0;
2073
2074   if (GDK_WINDOW_DESTROYED (window))
2075     return;
2076
2077   while (rover->parent && ((GdkWindowObject*) rover->parent)->parent)
2078     rover = (GdkWindowObject *) rover->parent;
2079   if (rover->destroyed)
2080     return;
2081
2082   if (x)
2083     *x = rover->x;
2084   if (y)
2085     *y = rover->y;
2086 }
2087
2088 GdkWindow *
2089 _gdk_windowing_window_get_pointer (GdkDisplay      *display,
2090                                    GdkWindow       *window,
2091                                    gint            *x,
2092                                    gint            *y,
2093                                    GdkModifierType *mask)
2094 {
2095   GdkWindow               *retval = NULL;
2096   gint                     rx, ry, wx, wy;
2097   GdkDrawableImplDirectFB *impl;
2098
2099   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
2100
2101   if (!window)
2102     window = _gdk_parent_root;
2103
2104   gdk_directfb_mouse_get_info (&rx, &ry, mask);
2105
2106   wx = rx;
2107   wy = ry;
2108   retval = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
2109
2110   impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
2111
2112   if (x)
2113     *x = rx - impl->abs_x;
2114   if (y)
2115     *y = ry - impl->abs_y;
2116
2117   return retval;
2118 }
2119
2120 GdkWindow *
2121 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2122                                   gint       *win_x,
2123                                   gint       *win_y)
2124 {
2125   GdkWindow *retval;
2126   gint       wx, wy;
2127
2128   if (!win_x || !win_y)
2129   gdk_directfb_mouse_get_info (&wx, &wy, NULL);
2130
2131   if (win_x)
2132     wx = *win_x;
2133
2134   if (win_y)
2135     wy = *win_y;
2136
2137   retval = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
2138
2139   if (win_x)
2140     *win_x = wx;
2141
2142   if (win_y)
2143     *win_y = wy;
2144
2145   return retval;
2146 }
2147
2148 void
2149 _gdk_windowing_get_pointer (GdkDisplay       *display,
2150                             GdkScreen       **screen,
2151                             gint             *x,
2152                             gint             *y,
2153                             GdkModifierType  *mask)
2154 {
2155 (void)screen;
2156 if(screen) {
2157         *screen = gdk_display_get_default_screen  (display);
2158 }
2159 _gdk_windowing_window_get_pointer (display,
2160                                    _gdk_windowing_window_at_pointer(display,NULL,NULL),x,y,mask);
2161
2162 }
2163
2164 static GdkEventMask
2165 gdk_directfb_window_get_events (GdkWindow *window)
2166 {
2167   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2168
2169   if (GDK_WINDOW_DESTROYED (window))
2170     return 0;
2171   else
2172     return GDK_WINDOW_OBJECT (window)->event_mask;
2173 }
2174
2175 static void
2176 gdk_directfb_window_set_events (GdkWindow    *window,
2177                                 GdkEventMask  event_mask)
2178 {
2179   g_return_if_fail (GDK_IS_WINDOW (window));
2180
2181   if (event_mask & GDK_BUTTON_MOTION_MASK)
2182     event_mask |= (GDK_BUTTON1_MOTION_MASK |
2183                    GDK_BUTTON2_MOTION_MASK |
2184                    GDK_BUTTON3_MOTION_MASK);
2185
2186   GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
2187 }
2188
2189 static void
2190 gdk_directfb_window_shape_combine_mask (GdkWindow *window,
2191                                         GdkBitmap *mask,
2192                                         gint       x,
2193                                         gint       y)
2194 {
2195 }
2196
2197 void
2198 gdk_window_input_shape_combine_mask (GdkWindow *window,
2199                                      GdkBitmap *mask,
2200                                      gint       x,
2201                                      gint       y)
2202 {
2203 }
2204
2205 static void
2206 gdk_directfb_window_shape_combine_region (GdkWindow       *window,
2207                                           const GdkRegion *shape_region,
2208                                           gint             offset_x,
2209                                           gint             offset_y)
2210 {
2211 }
2212
2213 void
2214 gdk_window_input_shape_combine_region (GdkWindow       *window,
2215                                        const GdkRegion *shape_region,
2216                                        gint             offset_x,
2217                                        gint             offset_y)
2218 {
2219 }
2220
2221 void
2222 gdk_window_set_override_redirect (GdkWindow *window,
2223                                   gboolean   override_redirect)
2224 {
2225   g_return_if_fail (GDK_IS_WINDOW (window));
2226
2227   if (GDK_WINDOW_DESTROYED (window))
2228     return;
2229
2230   /* N/A */
2231 }
2232
2233 void
2234 gdk_window_set_icon_list (GdkWindow *window,
2235                           GList     *pixbufs)
2236 {
2237   g_return_if_fail (GDK_IS_WINDOW (window));
2238
2239   if (GDK_WINDOW_DESTROYED (window))
2240     return;
2241
2242   /* N/A */
2243 }
2244
2245 void
2246 gdk_window_set_icon (GdkWindow *window,
2247                      GdkWindow *icon_window,
2248                      GdkPixmap *pixmap,
2249                      GdkBitmap *mask)
2250 {
2251   g_return_if_fail (GDK_IS_WINDOW (window));
2252
2253   if (GDK_WINDOW_DESTROYED (window))
2254     return;
2255
2256   /* N/A */
2257 }
2258
2259 void
2260 gdk_window_set_icon_name (GdkWindow   *window,
2261                           const gchar *name)
2262 {
2263   g_return_if_fail (GDK_IS_WINDOW (window));
2264
2265   if (GDK_WINDOW_DESTROYED (window))
2266     return;
2267
2268   /* N/A */
2269 }
2270
2271 void
2272 gdk_window_iconify (GdkWindow *window)
2273 {
2274   g_return_if_fail (GDK_IS_WINDOW (window));
2275
2276   if (GDK_WINDOW_DESTROYED (window))
2277     return;
2278
2279   gdk_window_hide (window);
2280 }
2281
2282 void
2283 gdk_window_deiconify (GdkWindow *window)
2284 {
2285   g_return_if_fail (GDK_IS_WINDOW (window));
2286
2287   if (GDK_WINDOW_DESTROYED (window))
2288     return;
2289
2290   gdk_window_show (window);
2291 }
2292
2293 void
2294 gdk_window_stick (GdkWindow *window)
2295 {
2296   g_return_if_fail (GDK_IS_WINDOW (window));
2297
2298   if (GDK_WINDOW_DESTROYED (window))
2299     return;
2300
2301   /* N/A */
2302 }
2303
2304 void
2305 gdk_window_unstick (GdkWindow *window)
2306 {
2307   g_return_if_fail (GDK_IS_WINDOW (window));
2308
2309   if (GDK_WINDOW_DESTROYED (window))
2310     return;
2311
2312   /* N/A */
2313 }
2314
2315 void
2316 gdk_directfb_window_set_opacity (GdkWindow *window,
2317                                  guchar     opacity)
2318 {
2319   GdkWindowImplDirectFB *impl;
2320
2321   g_return_if_fail (GDK_IS_WINDOW (window));
2322
2323   if (GDK_WINDOW_DESTROYED (window))
2324     return;
2325
2326   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
2327
2328   impl->opacity = opacity;
2329
2330   if (impl->window && GDK_WINDOW_IS_MAPPED (window))
2331     {
2332       if (gdk_directfb_apply_focus_opacity &&
2333           window == gdk_directfb_focused_window)
2334         impl->window->SetOpacity (impl->window,
2335                                   (impl->opacity >> 1) + (impl->opacity >> 2));
2336       else
2337         impl->window->SetOpacity (impl->window, impl->opacity);
2338     }
2339 }
2340
2341 void
2342 gdk_window_focus (GdkWindow *window,
2343                   guint32    timestamp)
2344 {
2345   GdkWindow *toplevel;
2346
2347   g_return_if_fail (GDK_IS_WINDOW (window));
2348
2349   if (GDK_WINDOW_DESTROYED (window))
2350     return;
2351
2352   toplevel = gdk_directfb_window_find_toplevel (window);
2353   if (toplevel != _gdk_parent_root)
2354     {
2355       GdkWindowImplDirectFB *impl;
2356
2357       impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (toplevel)->impl);
2358
2359       impl->window->RequestFocus (impl->window);
2360     }
2361 }
2362
2363 void
2364 gdk_window_maximize (GdkWindow *window)
2365 {
2366   g_return_if_fail (GDK_IS_WINDOW (window));
2367
2368   if (GDK_WINDOW_DESTROYED (window))
2369     return;
2370
2371   /* N/A */
2372 }
2373
2374 void
2375 gdk_window_unmaximize (GdkWindow *window)
2376 {
2377   g_return_if_fail (GDK_IS_WINDOW (window));
2378
2379   if (GDK_WINDOW_DESTROYED (window))
2380     return;
2381
2382   /* N/A */
2383 }
2384
2385 void
2386 gdk_window_set_type_hint (GdkWindow        *window,
2387                           GdkWindowTypeHint hint)
2388 {
2389   g_return_if_fail (GDK_IS_WINDOW (window));
2390
2391   if (GDK_WINDOW_DESTROYED (window))
2392     return;
2393
2394   GDK_NOTE (MISC, g_print ("gdk_window_set_type_hint: 0x%x: %d\n",
2395                GDK_WINDOW_DFB_ID (window), hint));
2396
2397   ((GdkWindowImplDirectFB *)((GdkWindowObject *)window)->impl)->type_hint = hint;
2398
2399
2400   /* N/A */
2401 }
2402
2403 GdkWindowTypeHint
2404 gdk_window_get_type_hint (GdkWindow *window)
2405 {
2406   g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2407   
2408   if (GDK_WINDOW_DESTROYED (window))
2409     return GDK_WINDOW_TYPE_HINT_NORMAL;
2410
2411   return GDK_WINDOW_IMPL_DIRECTFB (((GdkWindowObject *) window)->impl)->type_hint;
2412 }
2413
2414 void
2415 gdk_window_set_modal_hint (GdkWindow *window,
2416                            gboolean   modal)
2417 {
2418   GdkWindowImplDirectFB *impl;
2419
2420   g_return_if_fail (GDK_IS_WINDOW (window));
2421
2422   if (GDK_WINDOW_DESTROYED (window))
2423     return;
2424
2425   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
2426
2427   if (impl->window)
2428     {
2429       impl->window->SetStackingClass (impl->window,
2430                                       modal ? DWSC_UPPER : DWSC_MIDDLE);
2431     }
2432 }
2433
2434 void
2435 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2436                                   gboolean   skips_taskbar)
2437 {
2438   g_return_if_fail (GDK_IS_WINDOW (window));
2439 }
2440
2441 void
2442 gdk_window_set_skip_pager_hint (GdkWindow *window,
2443                                 gboolean   skips_pager)
2444 {
2445   g_return_if_fail (GDK_IS_WINDOW (window));
2446 }
2447
2448
2449 void
2450 gdk_window_set_group (GdkWindow *window,
2451                       GdkWindow *leader)
2452 {
2453   g_return_if_fail (GDK_IS_WINDOW (window));
2454   g_return_if_fail (GDK_IS_WINDOW (leader));
2455  g_warning(" DirectFb set_group groups not supported \n");
2456
2457   if (GDK_WINDOW_DESTROYED (window))
2458     return;
2459
2460   /* N/A */
2461 }
2462
2463 GdkWindow * gdk_window_get_group (GdkWindow *window)
2464 {
2465  g_warning(" DirectFb get_group groups not supported \n");
2466  return window; 
2467 }
2468
2469 void
2470 gdk_fb_window_set_child_handler (GdkWindow             *window,
2471                                  GdkWindowChildChanged  changed,
2472                                  GdkWindowChildGetPos   get_pos,
2473                                  gpointer               user_data)
2474 {
2475   GdkWindowChildHandlerData *data;
2476
2477   g_return_if_fail (GDK_IS_WINDOW (window));
2478
2479   data = g_new (GdkWindowChildHandlerData, 1);
2480   data->changed   = changed;
2481   data->get_pos   = get_pos;
2482   data->user_data = user_data;
2483
2484   g_object_set_data_full (G_OBJECT (window), "gdk-window-child-handler",
2485                           data, (GDestroyNotify) g_free);
2486 }
2487
2488 void
2489 gdk_window_set_decorations (GdkWindow       *window,
2490                             GdkWMDecoration  decorations)
2491 {
2492   GdkWMDecoration *dec;
2493
2494   g_return_if_fail (GDK_IS_WINDOW (window));
2495
2496   dec = g_new (GdkWMDecoration, 1);
2497   *dec = decorations;
2498
2499   g_object_set_data_full (G_OBJECT (window), "gdk-window-decorations",
2500                           dec, (GDestroyNotify) g_free);
2501 }
2502
2503 gboolean
2504 gdk_window_get_decorations (GdkWindow       *window,
2505                             GdkWMDecoration *decorations)
2506 {
2507   GdkWMDecoration *dec;
2508
2509   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2510
2511   dec = g_object_get_data (G_OBJECT (window), "gdk-window-decorations");
2512   if (dec)
2513     {
2514       *decorations = *dec;
2515       return TRUE;
2516     }
2517   return FALSE;
2518 }
2519
2520 void
2521 gdk_window_set_functions (GdkWindow     *window,
2522                           GdkWMFunction  functions)
2523 {
2524   g_return_if_fail (GDK_IS_WINDOW (window));
2525
2526   if (GDK_WINDOW_DESTROYED (window))
2527     return;
2528
2529   /* N/A */
2530   g_message("unimplemented %s", __FUNCTION__);
2531 }
2532
2533 static void
2534 gdk_directfb_window_set_child_shapes (GdkWindow *window)
2535 {
2536 }
2537
2538 static void
2539 gdk_directfb_window_merge_child_shapes (GdkWindow *window)
2540 {
2541 }
2542
2543 void
2544 gdk_window_set_child_input_shapes (GdkWindow *window)
2545 {
2546 }
2547
2548 void
2549 gdk_window_merge_child_input_shapes (GdkWindow *window)
2550 {
2551 }
2552
2553 static gboolean
2554 gdk_directfb_window_set_static_gravities (GdkWindow *window,
2555                                           gboolean   use_static)
2556 {
2557   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2558
2559   if (GDK_WINDOW_DESTROYED (window))
2560     return FALSE;
2561
2562   /* N/A */
2563   g_message("unimplemented %s", __FUNCTION__);
2564
2565   return FALSE;
2566 }
2567
2568 void
2569 gdk_window_begin_resize_drag (GdkWindow     *window,
2570                               GdkWindowEdge  edge,
2571                               gint           button,
2572                               gint           root_x,
2573                               gint           root_y,
2574                               guint32        timestamp)
2575 {
2576   g_return_if_fail (GDK_IS_WINDOW (window));
2577
2578   if (GDK_WINDOW_DESTROYED (window))
2579     return;
2580
2581   g_message("unimplemented %s", __FUNCTION__);
2582 }
2583
2584 void
2585 gdk_window_begin_move_drag (GdkWindow *window,
2586                             gint       button,
2587                             gint       root_x,
2588                             gint       root_y,
2589                             guint32    timestamp)
2590 {
2591   g_return_if_fail (GDK_IS_WINDOW (window));
2592
2593   if (GDK_WINDOW_DESTROYED (window))
2594     return;
2595
2596   g_message("unimplemented %s", __FUNCTION__);
2597 }
2598
2599 /**
2600  * gdk_window_get_frame_extents:
2601  * @window: a #GdkWindow
2602  * @rect: rectangle to fill with bounding box of the window frame
2603  *
2604  * Obtains the bounding box of the window, including window manager
2605  * titlebar/borders if any. The frame position is given in root window
2606  * coordinates. To get the position of the window itself (rather than
2607  * the frame) in root window coordinates, use gdk_window_get_origin().
2608  *
2609  **/
2610 void
2611 gdk_window_get_frame_extents (GdkWindow    *window,
2612                               GdkRectangle *rect)
2613 {
2614   GdkWindowObject         *private;
2615   GdkDrawableImplDirectFB *impl;
2616
2617   g_return_if_fail (GDK_IS_WINDOW (window));
2618   g_return_if_fail (rect != NULL);
2619
2620   if (GDK_WINDOW_DESTROYED (window))
2621     return;
2622
2623   private = GDK_WINDOW_OBJECT (window);
2624
2625   while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2626     private = (GdkWindowObject*) private->parent;
2627   if (GDK_WINDOW_DESTROYED (window))
2628     return;
2629
2630   impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
2631
2632   rect->x      = impl->abs_x;
2633   rect->y      = impl->abs_y;
2634   rect->width  = impl->width;
2635   rect->height = impl->height;
2636 }
2637
2638 /*
2639  * Given a directfb window and a subsurface of that window
2640  * create a gdkwindow child wrapper
2641  */
2642 GdkWindow *gdk_directfb_create_child_window(GdkWindow *parent,
2643                                             IDirectFBSurface *subsurface)
2644 {
2645   GdkWindow             *window;
2646   GdkWindowObject       *private;
2647   GdkWindowObject       *parent_private;
2648   GdkWindowImplDirectFB *impl;
2649   GdkWindowImplDirectFB *parent_impl;
2650   gint x,y,w,h;
2651
2652   g_return_val_if_fail (parent != NULL, NULL);
2653
2654   window = g_object_new (GDK_TYPE_WINDOW, NULL);
2655   private = GDK_WINDOW_OBJECT (window);
2656   parent_private = GDK_WINDOW_OBJECT (parent);
2657   parent_impl = GDK_WINDOW_IMPL_DIRECTFB (parent_private->impl);
2658   private->parent = parent_private;
2659
2660   subsurface->GetPosition(subsurface,&x,&y);
2661   subsurface->GetSize(subsurface,&w,&h);
2662
2663   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
2664   impl->drawable.wrapper = GDK_DRAWABLE (window);
2665
2666   private->x = x;
2667   private->y = y;
2668
2669   _gdk_directfb_calc_abs (window);
2670
2671   impl->drawable.width  = w;
2672   impl->drawable.height = h;
2673   private->window_type = GDK_WINDOW_CHILD;
2674   impl->drawable.surface = subsurface;
2675   impl->drawable.format = parent_impl->drawable.format;
2676   private->depth = parent_private->depth;
2677   gdk_drawable_set_colormap (GDK_DRAWABLE (window),
2678         gdk_drawable_get_colormap (parent));
2679   gdk_window_set_cursor (window, NULL);
2680   parent_private->children = g_list_prepend (parent_private->children,window);
2681   /*we hold a reference count on ourselves */
2682   g_object_ref (window);
2683
2684   return window;
2685
2686 }
2687
2688 /*
2689  * The wrapping is not perfect since directfb does not give full access
2690  * to the current state of a window event mask etc need to fix dfb
2691  */
2692 GdkWindow *
2693 gdk_window_foreign_new_for_display (GdkDisplay* display,GdkNativeWindow anid)
2694 {
2695     GdkWindow *window = NULL;
2696     GdkWindow              *parent =NULL;
2697     GdkWindowObject       *private =NULL;
2698     GdkWindowObject       *parent_private =NULL;
2699     GdkWindowImplDirectFB *parent_impl =NULL;
2700     GdkWindowImplDirectFB *impl =NULL;
2701     DFBWindowOptions options;
2702     DFBResult        ret;
2703     GdkDisplayDFB * gdkdisplay =  _gdk_display;
2704     IDirectFBWindow *dfbwindow;
2705
2706     window = gdk_window_lookup (anid);
2707
2708     if (window) {
2709         g_object_ref (window);
2710         return window;
2711     }
2712     if( display != NULL )
2713             gdkdisplay = GDK_DISPLAY_DFB(display);
2714
2715     ret = gdkdisplay->layer->GetWindow (gdkdisplay->layer,
2716                     (DFBWindowID)anid,&dfbwindow);
2717
2718     if (ret != DFB_OK) {
2719         DirectFBError ("gdk_window_new: Layer->GetWindow failed", ret);
2720         return NULL;
2721     }
2722
2723     parent = _gdk_parent_root;
2724
2725     if(parent) {
2726         parent_private = GDK_WINDOW_OBJECT (parent);
2727         parent_impl = GDK_WINDOW_IMPL_DIRECTFB (parent_private->impl);
2728     }
2729
2730     window = g_object_new (GDK_TYPE_WINDOW, NULL);
2731     /* we hold a reference count on ourselves */
2732     g_object_ref (window);
2733     private = GDK_WINDOW_OBJECT (window);
2734     private->parent = parent_private;
2735     private->window_type = GDK_WINDOW_TOPLEVEL;
2736     impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
2737
2738     impl->drawable.wrapper = GDK_DRAWABLE (window);
2739     impl->window = dfbwindow;
2740     dfbwindow->GetOptions(dfbwindow,&options);
2741     dfbwindow->GetPosition(dfbwindow,&private->x,&private->y);
2742     dfbwindow->GetSize(dfbwindow,&impl->drawable.width,&impl->drawable.height);
2743
2744
2745     private->input_only = FALSE;
2746
2747     if( dfbwindow->GetSurface (dfbwindow, &impl->drawable.surface) == DFB_UNSUPPORTED ){
2748         private->input_only = TRUE;
2749         impl->drawable.surface = NULL;
2750     }
2751     /*
2752      * Position ourselevs
2753      */
2754     _gdk_directfb_calc_abs (window);
2755
2756     /* We default to all events least surprise to the user 
2757      * minus the poll for motion events 
2758      */
2759     gdk_window_set_events (window, (GDK_ALL_EVENTS_MASK ^ GDK_POINTER_MOTION_HINT_MASK));
2760
2761     if (impl->drawable.surface)
2762     {
2763       impl->drawable.surface->GetPixelFormat (impl->drawable.surface,
2764                                               &impl->drawable.format);
2765
2766           private->depth = DFB_BITS_PER_PIXEL(impl->drawable.format);
2767       if( parent )
2768         gdk_drawable_set_colormap (GDK_DRAWABLE (window), gdk_drawable_get_colormap (parent));
2769       else
2770         gdk_drawable_set_colormap (GDK_DRAWABLE (window), gdk_colormap_get_system());
2771     }
2772
2773     //can  be null for the soft cursor window itself when
2774     //running a gtk directfb wm
2775     if( gdk_display_get_default() != NULL ) {
2776         gdk_window_set_cursor (window,NULL);
2777     }
2778
2779     if (parent_private)
2780         parent_private->children = g_list_prepend (parent_private->children,
2781                                                window);
2782     impl->dfb_id = (DFBWindowID)anid; 
2783     gdk_directfb_window_id_table_insert (impl->dfb_id, window);
2784     gdk_directfb_event_windows_add (window);
2785
2786     return window;
2787 }
2788
2789 GdkWindow *
2790 gdk_window_lookup_for_display (GdkDisplay *display,GdkNativeWindow anid)
2791 {
2792   return gdk_directfb_window_id_table_lookup ((DFBWindowID) anid);
2793 }
2794
2795 GdkWindow *
2796 gdk_window_lookup (GdkNativeWindow anid)
2797 {
2798   return gdk_directfb_window_id_table_lookup ((DFBWindowID) anid);
2799 }
2800
2801 IDirectFBWindow *gdk_directfb_window_lookup(GdkWindow *window )
2802 {
2803   GdkWindowObject       *private;
2804   GdkWindowImplDirectFB *impl;
2805   g_return_val_if_fail (GDK_IS_WINDOW (window),NULL);
2806   private = GDK_WINDOW_OBJECT (window);
2807   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
2808   return impl->window;
2809 }
2810
2811 IDirectFBSurface *gdk_directfb_surface_lookup(GdkWindow *window)
2812 {
2813   GdkWindowObject       *private;
2814   GdkWindowImplDirectFB *impl;
2815   g_return_val_if_fail (GDK_IS_WINDOW (window),NULL);
2816   private = GDK_WINDOW_OBJECT (window);
2817   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
2818   return impl->drawable.surface;
2819 }
2820
2821 void
2822 gdk_window_fullscreen (GdkWindow *window)
2823 {
2824   g_return_if_fail (GDK_IS_WINDOW (window));
2825   g_warning ("gdk_window_fullscreen() not implemented.\n");
2826 }
2827
2828 void
2829 gdk_window_unfullscreen (GdkWindow *window)
2830 {
2831   g_return_if_fail (GDK_IS_WINDOW (window));
2832   /* g_warning ("gdk_window_unfullscreen() not implemented.\n");*/
2833 }
2834
2835 void
2836 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
2837 {
2838   g_return_if_fail (GDK_IS_WINDOW (window));
2839   static gboolean first_call = TRUE;
2840   if (first_call) {
2841   g_warning ("gdk_window_set_keep_above() not implemented.\n");
2842         first_call=FALSE;
2843   }
2844         
2845 }
2846
2847 void
2848 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
2849 {
2850   g_return_if_fail (GDK_IS_WINDOW (window));
2851   static gboolean first_call = TRUE;
2852   if (first_call) {
2853   g_warning ("gdk_window_set_keep_below() not implemented.\n");
2854   first_call=FALSE;
2855   }
2856   
2857 }
2858
2859 void
2860 gdk_window_enable_synchronized_configure (GdkWindow *window)
2861 {
2862 }
2863
2864 void
2865 gdk_window_configure_finished (GdkWindow *window)
2866 {
2867 }
2868
2869 void
2870 gdk_display_warp_pointer (GdkDisplay *display,
2871                           GdkScreen  *screen,
2872                           gint        x,
2873                           gint        y)
2874 {
2875   g_warning ("gdk_display_warp_pointer() not implemented.\n");
2876 }
2877
2878 void
2879 gdk_window_set_urgency_hint (GdkWindow *window,
2880                              gboolean   urgent)
2881 {
2882   g_return_if_fail (GDK_IS_WINDOW (window));
2883   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2884
2885   if (GDK_WINDOW_DESTROYED (window))
2886     return;
2887
2888   g_warning ("gdk_window_set_urgency_hint() not implemented.\n");
2889
2890 }
2891
2892 static void
2893 gdk_window_impl_directfb_invalidate_maybe_recurse (GdkPaintable    *paintable,
2894                                                    const GdkRegion *region,
2895                                                    gboolean       (*child_func) (GdkWindow *, gpointer),
2896                                                    gpointer         user_data)
2897 {
2898   GdkWindow *window;
2899   GdkWindowObject *private;
2900   GdkWindowImplDirectFB *wimpl;
2901   GdkDrawableImplDirectFB *impl;
2902
2903   wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable);
2904   impl = (GdkDrawableImplDirectFB *)wimpl;
2905   window = wimpl->gdkWindow;
2906   private = (GdkWindowObject *)window;
2907
2908   GdkRegion visible_region;
2909   GList *tmp_list;
2910
2911   g_return_if_fail (window != NULL);
2912   g_return_if_fail (GDK_IS_WINDOW (window));
2913
2914   if (GDK_WINDOW_DESTROYED (window))
2915     return;
2916   
2917   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
2918     return;
2919
2920   temp_region_init_rectangle_vals( &visible_region, 0, 0, impl->width, impl->height );
2921   gdk_region_intersect (&visible_region, region);
2922
2923   tmp_list = private->children;
2924   while (tmp_list)
2925     {
2926       GdkWindowObject         *child = tmp_list->data;
2927       GdkDrawableImplDirectFB *cimpl = (GdkDrawableImplDirectFB *) child->impl;
2928       
2929       if (!child->input_only)
2930         {
2931           GdkRegion child_region;
2932           
2933           temp_region_init_rectangle_vals( &child_region, child->x, child->y, cimpl->width, cimpl->height );
2934           
2935           /* remove child area from the invalid area of the parent */
2936           if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped)
2937             gdk_region_subtract (&visible_region, &child_region);
2938           
2939           if (child_func && (*child_func) ((GdkWindow *)child, user_data))
2940             {
2941               gdk_region_intersect (&child_region, region);
2942               gdk_region_offset (&child_region, - child->x, - child->y);
2943               
2944               gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
2945                                                    &child_region, child_func, user_data);
2946             }
2947
2948           temp_region_deinit( &child_region );
2949         }
2950
2951       tmp_list = tmp_list->next;
2952     }
2953   
2954   if (!gdk_region_empty (&visible_region))
2955     {
2956       
2957       if (private->update_area)
2958         {
2959           gdk_region_union (private->update_area, &visible_region);
2960         }
2961       else
2962         {
2963           update_windows = g_slist_prepend (update_windows, window);
2964           private->update_area = gdk_region_copy (&visible_region);
2965           gdk_window_schedule_update (window);
2966         }
2967     }
2968
2969   temp_region_deinit( &visible_region );
2970 }
2971
2972
2973 static void
2974 gdk_window_impl_directfb_process_updates (GdkPaintable *paintable,
2975                                           gboolean      update_children)
2976 {
2977   GdkWindowImplDirectFB *wimpl;
2978   GdkDrawableImplDirectFB *impl;
2979   GdkWindow               *window;
2980   GdkWindowObject         *private;
2981   GdkRegion               *update_area;
2982
2983   wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable);
2984   impl = (GdkDrawableImplDirectFB *)wimpl;
2985   window = wimpl->gdkWindow;
2986   private = (GdkWindowObject *)window;
2987
2988   D_DEBUG_AT( GDKDFB_Paintable, "%s( %p, %schildren )\n", __FUNCTION__,
2989               paintable, update_children ? "update " : "no " );
2990
2991   /* If an update got queued during update processing, we can get a
2992    * window in the update queue that has an empty update_area.
2993    * just ignore it.
2994    */
2995   if (!private->update_area)
2996     return;
2997
2998   update_area = private->update_area;
2999   private->update_area = NULL;
3000       
3001   D_DEBUG_AT( GDKDFB_Paintable, "  -> update area %4d,%4d-%4dx%4d\n",
3002               GDKDFB_RECTANGLE_VALS_FROM_BOX( &update_area->extents ) );
3003
3004   if (_gdk_event_func && gdk_window_is_viewable (window))
3005     {
3006       GdkRegion *expose_region = update_area;
3007       GdkRegion  window_region;
3008           
3009       temp_region_init_rectangle_vals( &window_region, 0, 0, impl->width, impl->height );
3010       gdk_region_intersect( expose_region, &window_region );
3011       temp_region_deinit (&window_region);
3012           
3013       if (!gdk_region_empty (expose_region) && (private->event_mask & GDK_EXPOSURE_MASK))
3014         {
3015           GdkEvent event;
3016               
3017           event.expose.type = GDK_EXPOSE;
3018           event.expose.window = g_object_ref (window);
3019           event.expose.send_event = FALSE;
3020           event.expose.count = 0;
3021           event.expose.region = expose_region;
3022           gdk_region_get_clipbox (expose_region, &event.expose.area);
3023           (*_gdk_event_func) (&event, _gdk_event_data);
3024               
3025           g_object_unref (window);
3026         }
3027
3028       if (expose_region != update_area)
3029         gdk_region_destroy (expose_region);
3030     }
3031
3032   gdk_region_destroy (update_area);
3033 }
3034
3035
3036 static void
3037 gdk_window_impl_directfb_begin_paint_region (GdkPaintable    *paintable,
3038                                              const GdkRegion *region)
3039 {
3040   GdkDrawableImplDirectFB *impl;
3041   GdkWindowImplDirectFB   *wimpl;
3042   gint                     i;
3043
3044
3045   g_assert (region != NULL );
3046   wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable);
3047   impl = (GdkDrawableImplDirectFB *)wimpl;
3048
3049   if (!region)
3050     return;
3051
3052   D_DEBUG_AT( GDKDFB_Window, "%s( %p ) <- %4d,%4d-%4d,%4d (%ld boxes)\n", __FUNCTION__,
3053               paintable, GDKDFB_RECTANGLE_VALS_FROM_BOX(&region->extents), region->numRects );
3054
3055   /* When it's buffered... */
3056   if (impl->buffered)
3057     {
3058       /* ...we're already painting on it! */
3059       g_assert( impl->paint_depth > 0 );
3060     
3061       D_DEBUG_AT( GDKDFB_Window, "  -> painted  %4d,%4d-%4dx%4d (%ld boxes)\n",
3062                   DFB_RECTANGLE_VALS_FROM_REGION( &impl->paint_region.extents ), impl->paint_region.numRects );
3063
3064       /* Add the new region to the paint region... */
3065       gdk_region_union (&impl->paint_region, region);
3066     }
3067   else
3068     {
3069       /* ...otherwise it's the first time! */
3070       g_assert( impl->paint_depth == 0 );
3071
3072       /* Generate the clip region for painting around child windows. */
3073       gdk_directfb_clip_region( GDK_DRAWABLE(paintable), NULL, NULL, &impl->clip_region );
3074
3075       /* Initialize the paint region with the new one... */
3076       temp_region_init_copy( &impl->paint_region, region );
3077
3078       impl->buffered = TRUE;
3079     }
3080
3081   D_DEBUG_AT( GDKDFB_Window, "  -> painting %4d,%4d-%4dx%4d (%ld boxes)\n",
3082               DFB_RECTANGLE_VALS_FROM_REGION( &impl->paint_region.extents ), impl->paint_region.numRects );
3083
3084   /* ...but clip the initial/compound result against the clip region. */
3085   gdk_region_intersect (&impl->paint_region, &impl->clip_region);
3086
3087   D_DEBUG_AT( GDKDFB_Window, "  -> clipped  %4d,%4d-%4dx%4d (%ld boxes)\n",
3088               DFB_RECTANGLE_VALS_FROM_REGION( &impl->paint_region.extents ), impl->paint_region.numRects );
3089
3090   impl->paint_depth++;
3091
3092   D_DEBUG_AT( GDKDFB_Window, "  -> depth is now %d\n", impl->paint_depth );
3093
3094   for (i = 0; i < region->numRects; i++)
3095     {
3096       GdkRegionBox *box = &region->rects[i];
3097
3098       D_DEBUG_AT( GDKDFB_Window, "  -> [%2d] %4d,%4d-%4dx%4d\n", i, GDKDFB_RECTANGLE_VALS_FROM_BOX( box ) );
3099
3100       gdk_window_clear_area (GDK_WINDOW(wimpl->gdkWindow),
3101                              box->x1,
3102                              box->y1,
3103                              box->x2 - box->x1,
3104                              box->y2 - box->y1);
3105     }
3106 }
3107
3108 static void
3109 gdk_window_impl_directfb_end_paint (GdkPaintable *paintable)
3110 {
3111   GdkDrawableImplDirectFB *impl;
3112
3113   impl = GDK_DRAWABLE_IMPL_DIRECTFB (paintable);
3114
3115   D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, paintable );
3116
3117   g_return_if_fail (impl->paint_depth > 0);
3118
3119   g_assert( impl->buffered );
3120
3121   impl->paint_depth--;
3122
3123 #ifdef GDK_DIRECTFB_NO_EXPERIMENTS
3124   if (impl->paint_depth == 0)
3125     {
3126       impl->buffered = FALSE;
3127
3128       if (impl->paint_region.numRects)
3129         {
3130           DFBRegion reg = { impl->paint_region.extents.x1,
3131                             impl->paint_region.extents.y1,
3132                             impl->paint_region.extents.x2-1,
3133                             impl->paint_region.extents.y2-1 };
3134
3135           D_DEBUG_AT( GDKDFB_Window, "  -> flip %4d,%4d-%4dx%4d (%ld boxes)\n",
3136                       DFB_RECTANGLE_VALS_FROM_REGION( &reg ), impl->paint_region.numRects );
3137
3138           impl->surface->Flip( impl->surface, &reg, 0 );
3139
3140           temp_region_reset( &impl->paint_region );
3141         }
3142     }
3143 #else
3144   if (impl->paint_depth == 0)
3145     {
3146       impl->buffered = FALSE;
3147   
3148       temp_region_deinit( &impl->clip_region );
3149   
3150       if (impl->paint_region.numRects)
3151         {
3152           GdkWindow *window = GDK_WINDOW( impl->wrapper );
3153   
3154           if (GDK_IS_WINDOW(window))
3155             {
3156               GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( window ) );
3157   
3158               if (top)
3159                 {
3160                   DFBRegion              reg;
3161                   GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
3162   
3163                   reg.x1 = impl->abs_x - top->x + impl->paint_region.extents.x1;
3164                   reg.y1 = impl->abs_y - top->y + impl->paint_region.extents.y1;
3165                   reg.x2 = impl->abs_x - top->x + impl->paint_region.extents.x2 - 1;
3166                   reg.y2 = impl->abs_y - top->y + impl->paint_region.extents.y2 - 1;
3167   
3168                   D_DEBUG_AT( GDKDFB_Window, "  -> queue flip %4d,%4d-%4dx%4d (%ld boxes)\n",
3169                               DFB_RECTANGLE_VALS_FROM_REGION( &reg ), impl->paint_region.numRects );
3170   
3171                   dfb_updates_add( &wimpl->flips, &reg );
3172                 }
3173             }
3174   
3175           temp_region_reset( &impl->paint_region );
3176         }
3177     }
3178 #endif
3179   else
3180     D_DEBUG_AT( GDKDFB_Window, "  -> depth is still %d\n", impl->paint_depth );
3181 }
3182
3183
3184 static void
3185 gdk_window_impl_directfb_paintable_init (GdkPaintableIface *iface)
3186 {
3187   iface->begin_paint_region = gdk_window_impl_directfb_begin_paint_region;
3188   iface->end_paint = gdk_window_impl_directfb_end_paint;
3189
3190   iface->invalidate_maybe_recurse = gdk_window_impl_directfb_invalidate_maybe_recurse;
3191   iface->process_updates = gdk_window_impl_directfb_process_updates;
3192 }
3193
3194 void
3195 gdk_window_beep (GdkWindow *window)
3196 {
3197   gdk_display_beep (gdk_display_get_default());
3198 }
3199
3200 void
3201 gdk_window_set_opacity (GdkWindow *window,
3202                         gdouble    opacity)
3203 {
3204   GdkDisplay *display;
3205   guint8 cardinal;
3206
3207   g_return_if_fail (GDK_IS_WINDOW (window));
3208
3209   if (GDK_WINDOW_DESTROYED (window))
3210     return;
3211
3212   display = gdk_drawable_get_display (window);
3213
3214   if (opacity < 0)
3215     opacity = 0;
3216   else if (opacity > 1)
3217     opacity = 1;
3218   cardinal = opacity * 0xff;
3219   gdk_directfb_window_set_opacity(window,cardinal);
3220 }
3221
3222 void
3223 _gdk_windowing_window_set_composited (GdkWindow *window,
3224                                       gboolean   composited)
3225 {
3226 }
3227
3228 static void
3229 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3230 {
3231   iface->show = gdk_directfb_window_show;
3232   iface->hide = gdk_directfb_window_hide;
3233   iface->withdraw = gdk_directfb_window_withdraw;
3234   iface->raise = gdk_window_directfb_raise;
3235   iface->lower = gdk_window_directfb_lower;
3236   iface->move_resize = gdk_directfb_window_move_resize;
3237   iface->move_region = _gdk_directfb_window_move_region;
3238   iface->scroll = _gdk_directfb_window_scroll;
3239   iface->clear_area = gdk_directfb_window_clear_area;
3240   iface->set_background = gdk_directfb_window_set_background;
3241   iface->set_back_pixmap = gdk_directfb_window_set_back_pixmap;
3242   iface->get_events = gdk_directfb_window_get_events;
3243   iface->set_events = gdk_directfb_window_set_events;
3244   iface->reparent = gdk_directfb_window_reparent;
3245   iface->set_cursor = gdk_directfb_window_set_cursor;
3246   iface->get_geometry = gdk_directfb_window_get_geometry;
3247   iface->get_origin = gdk_directfb_window_get_origin;
3248   iface->get_offsets = _gdk_directfb_window_get_offsets;
3249   iface->shape_combine_mask = gdk_directfb_window_shape_combine_mask;
3250   iface->shape_combine_region = gdk_directfb_window_shape_combine_region;
3251   iface->set_child_shapes = gdk_directfb_window_set_child_shapes;
3252   iface->merge_child_shapes = gdk_directfb_window_merge_child_shapes;
3253   iface->set_static_gravities = gdk_directfb_window_set_static_gravities;
3254 }
3255
3256 #define __GDK_WINDOW_X11_C__
3257 #include "gdkaliasdef.c"
3258