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