diff -puraN gtk+-2.12.9/gdk/directfb/Makefile.am gtk+-2.12.9-dok2/gdk/directfb/Makefile.am
--- gtk+-2.12.9/gdk/directfb/Makefile.am	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/Makefile.am	2008-05-21 20:20:24.000000000 +0200
@@ -3,6 +3,7 @@
 libgdkincludedir = $(includedir)/gtk-2.0/gdk
 
 INCLUDES = 		\
+	-DDIRECTFB_ENABLE_DEPRECATED	\
 	-DG_LOG_DOMAIN=\"Gdk-DirectFB\"	\
 	-DGDK_COMPILATION \
 	-I$(top_srcdir)			\
diff -puraN gtk+-2.12.9/gdk/directfb/Makefile.in gtk+-2.12.9-dok2/gdk/directfb/Makefile.in
--- gtk+-2.12.9/gdk/directfb/Makefile.in	2008-03-12 05:18:11.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/Makefile.in	2008-05-21 20:20:24.000000000 +0200
@@ -332,6 +332,7 @@ target_alias = @target_alias@
 libgdkincludedir = $(includedir)/gtk-2.0/gdk
 
 INCLUDES = \
+	-DDIRECTFB_ENABLE_DEPRECATED	\
 	-DG_LOG_DOMAIN=\"Gdk-DirectFB\"	\
 	-DGDK_COMPILATION \
 	-I$(top_srcdir)			\
diff -puraN gtk+-2.12.9/gdk/directfb/gdkdirectfb-debug.h gtk+-2.12.9-dok2/gdk/directfb/gdkdirectfb-debug.h
--- gtk+-2.12.9/gdk/directfb/gdkdirectfb-debug.h	1970-01-01 01:00:00.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkdirectfb-debug.h	2008-05-21 20:20:24.000000000 +0200
@@ -0,0 +1,48 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.
+ */
+
+/*
+ * GTK+ DirectFB backend
+ * Copyright (C) 2001-2002  convergence integrated media GmbH
+ * Copyright (C) 2002       convergence GmbH
+ * Written by Denis Oliver Kropp <dok@convergence.de> and
+ *            Sven Neumann <sven@convergence.de>
+ */
+
+#ifndef __GDK_DIRECTFB_DEBUG_H__
+#define __GDK_DIRECTFB_DEBUG_H__
+
+#ifdef __DIRECT__DEBUG_H__
+#error This file MUST be included BEFORE <direct/debug.h>!
+#endif
+
+/* Global debug switch. */
+#if GDK_DIRECTFB_DEBUG
+#ifndef DIRECT_ENABLE_DEBUG
+#define DIRECT_ENABLE_DEBUG
+#endif
+#endif
+
+
+#endif /* __GDK_DIRECTFB_DEBUG_H__ */
diff -puraN gtk+-2.12.9/gdk/directfb/gdkdirectfb.h gtk+-2.12.9-dok2/gdk/directfb/gdkdirectfb.h
--- gtk+-2.12.9/gdk/directfb/gdkdirectfb.h	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkdirectfb.h	2008-05-21 20:20:24.000000000 +0200
@@ -33,19 +33,17 @@
 #ifndef __GDK_DIRECTFB_H__
 #define __GDK_DIRECTFB_H__
 
-#include <cairo.h>
-#include <directfb.h>
+/* This define disables some experimental code
+ */
+//#define GDK_DIRECTFB_NO_EXPERIMENTS
+
 #include "gdk/gdkprivate.h"
+#include "gdkdirectfb-debug.h"
 
-/* macro for a safe call to DirectFB functions */
-#define DFBCHECK(x...) \
-     {                                                                \
-          int err = x;                                                    \
-          if (err != DFB_OK) {                                        \
-               fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
-               DirectFBErrorFatal( #x, err );                         \
-          }                                                           \
-     }
+#include <cairo.h>
+#include <directfb.h>
+#include <directfb_util.h>
+#include <directfb_version.h>
 
 
 extern GdkWindow * _gdk_parent_root;
diff -puraN gtk+-2.12.9/gdk/directfb/gdkdisplay-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkdisplay-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkdisplay-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkdisplay-directfb.c	2008-05-21 20:24:32.000000000 +0200
@@ -26,6 +26,8 @@
 
 #include <config.h>
 
+#include <direct/mem.h>
+
 #include <glib.h>
 #include "gdk.h"
 #include "gdkdirectfb.h"
@@ -36,9 +38,12 @@
 #include "gdkalias.h"
 
 
+D_DEBUG_DOMAIN( GDKDFB_GrabKeyboard, "GDKDFB/Grab/Kbd", "GDK DirectFB Keyboard Grabbing" );
+D_DEBUG_DOMAIN( GDKDFB_GrabPointer,  "GDKDFB/Grab/Ptr", "GDK DirectFB Pointer Grabbing" );
+
 
 extern void _gdk_visual_init (void);
-extern void _gdk_events_init (void);
+extern void _gdk_events_init (GdkDisplay *display);
 extern void _gdk_input_init (void);
 extern void _gdk_dnd_init (void);
 extern void _gdk_windowing_window_init (void);
@@ -62,22 +67,68 @@ const GOptionEntry _gdk_windowing_args[]
   { NULL}
 };
 
+#include <stdlib.h>
+
+/*static gpointer
+_wrapped_direct_malloc (gsize n_bytes)
+{
+  printf("%s %zu\n", __FUNCTION__, n_bytes);
+  return direct_malloc (__FILE__, __LINE__, __FUNCTION__, n_bytes);
+//  return malloc (n_bytes);
+}
+
+static gpointer
+_wrapped_direct_realloc (gpointer mem,
+                                  gsize    n_bytes)
+{
+  printf("%s %p %zu\n", __FUNCTION__, mem, n_bytes);
+  return direct_realloc (__FILE__, __LINE__, __FUNCTION__, "<wrapped>", mem, n_bytes);
+//  return realloc (mem, n_bytes);
+}
+
+static void
+_wrapped_direct_free (gpointer mem)
+{
+  printf("%s %p\n", __FUNCTION__, mem);
+  direct_free (__FILE__, __LINE__, __FUNCTION__, "<wrapped>", mem);
+//  free (mem);
+}
+*/
+/*static GMemVTable wrapped_direct_mem_vtable = {
+  malloc:   _wrapped_direct_malloc,
+  realloc:  _wrapped_direct_realloc,
+  free:     _wrapped_direct_free
+};
+*/
+/*__attribute__((constructor))
+static void _gdk_directfb_hook_g_onto_direct_mem()
+{
+//  direct_initialize();
+  g_mem_set_vtable( &wrapped_direct_mem_vtable );
+}
+*/
 /**
   Main entry point for gdk in 2.6 args are parsed
 **/
 GdkDisplay * gdk_display_open (const gchar *display_name)
 {
-
-  if (_gdk_display) {
-    return GDK_DISPLAY_OBJECT(_gdk_display); /* single display only */
-  }
-  DFBResult  ret;
+  DFBResult               ret;
   IDirectFB              *directfb;
   IDirectFBDisplayLayer  *layer;
   IDirectFBInputDevice   *keyboard;
 
-  int argc=0;
-  char **argv=NULL;
+  /* Give at least something to distinguish a bit, allowing the user to create a specific
+   * directfbrc for gtk+, e.g. in "~/.directfbrc.gtk+" or "/usr/local/etc/directfbrc.gtk+".
+   */
+  char  *args[] = { "gtk+", NULL };
+  char **argv   = args;
+  int    argc   = 1;
+
+  /* single display only */
+  if (_gdk_display)
+    return GDK_DISPLAY_OBJECT(_gdk_display);
+
+//  g_mem_set_vtable( &wrapped_direct_mem_vtable );
 
 #if 0  /* arg hack arg support broken*/
   if(directfb_args ) {
@@ -90,42 +141,45 @@ GdkDisplay * gdk_display_open (const gch
 
   ret = DirectFBInit (&argc,&argv);
   if (ret != DFB_OK)
-{
+    {
       DirectFBError ("gdk_display_open: DirectFBInit", ret);
       return NULL;
     }
 
-    ret = DirectFBCreate (&directfb);
+  ret = DirectFBCreate (&directfb);
 
   if (ret != DFB_OK)
     {
       DirectFBError ("gdk_display_open: DirectFBCreate", ret);
       return NULL;
     }
-  _gdk_display = g_object_new(GDK_TYPE_DISPLAY_DFB,NULL);
-  _gdk_display->directfb=directfb;
+
+  _gdk_display = g_object_new (GDK_TYPE_DISPLAY_DFB,NULL);
+
+  _gdk_display->directfb = directfb;
 
   ret = directfb->GetDisplayLayer (directfb, DLID_PRIMARY, &layer);
   if (ret != DFB_OK)
     {
       DirectFBError ("gdk_display_open: GetDisplayLayer", ret);
       directfb->Release (directfb);
-	  directfb = NULL;
+      directfb = NULL;
       return NULL;
     }
 
 
   ret=directfb->GetInputDevice (directfb, DIDID_KEYBOARD, &keyboard);
 
-  if (ret != DFB_OK){
+  if (ret != DFB_OK)
+    {
       DirectFBError ("gdk_display_open: GetDisplayLayer", ret);
-   	return NULL;
-  }
+      return NULL;
+    }
 
   _gdk_display->layer=layer;
   _gdk_display->keyboard=keyboard;
 
-    _gdk_directfb_keyboard_init ();
+  _gdk_directfb_keyboard_init ();
 
   _gdk_screen = g_object_new (GDK_TYPE_SCREEN, NULL);
 
@@ -139,7 +193,8 @@ GdkDisplay * gdk_display_open (const gch
   _gdk_input_init ();
   _gdk_dnd_init ();
 
-  _gdk_events_init ();
+  _gdk_events_init (GDK_DISPLAY_OBJECT(_gdk_display));
+
   layer->EnableCursor (layer, 1);
 
   g_signal_emit_by_name (gdk_display_manager_get (),
@@ -195,6 +250,9 @@ IDirectFBSurface * gdk_display_dfb_creat
 }
 
 
+/*************************************************************************************************
+ * Displays and Screens
+ */
 
 void
 _gdk_windowing_set_default_display (GdkDisplay *display)
@@ -228,64 +286,68 @@ gdk_display_get_default_screen (GdkDispl
 }
 
 gboolean
-gdk_display_supports_selection_notification (GdkDisplay *display)
+gdk_display_supports_shapes (GdkDisplay *display)
 {
-	return FALSE;
+       return FALSE;
 }
 
-gboolean gdk_display_request_selection_notification  (GdkDisplay *display,
-                                                      GdkAtom     selection)
-
+gboolean
+gdk_display_supports_input_shapes (GdkDisplay *display)
 {
-
-	g_warning("gdk_display_request_selection_notification Unimplemented function \n");
-	return FALSE;
+       return FALSE;
 }
 
-gboolean
-gdk_display_supports_clipboard_persistence (GdkDisplay *display)
+
+GdkWindow *gdk_display_get_default_group (GdkDisplay *display)
 {
-	g_warning("gdk_display_supports_clipboard_persistence Unimplemented function \n");
-	return FALSE;
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+  return  _gdk_parent_root;
 }
 
-void
-gdk_display_store_clipboard (GdkDisplay *display,
-                             GdkWindow  *clipboard_window,
-                             guint32     time_,
-                             GdkAtom    *targets,
-                             gint        n_targets)
-{
 
-	g_warning("gdk_display_store_clipboard Unimplemented function \n");
+/*************************************************************************************************
+ * Selection and Clipboard
+ */
 
+gboolean
+gdk_display_supports_selection_notification (GdkDisplay *display)
+{
+  D_UNIMPLEMENTED();
+
+  return FALSE;
 }
 
+gboolean gdk_display_request_selection_notification  (GdkDisplay *display,
+                                                      GdkAtom     selection)
 
-gboolean
-gdk_display_supports_shapes (GdkDisplay *display)
 {
-       return FALSE;
-}
+  D_UNIMPLEMENTED();
 
+  return FALSE;
+}
 
 gboolean
-gdk_display_supports_input_shapes (GdkDisplay *display)
+gdk_display_supports_clipboard_persistence (GdkDisplay *display)
 {
-       return FALSE;
-}
+  D_UNIMPLEMENTED();
 
+  return FALSE;
+}
 
-GdkWindow *gdk_display_get_default_group (GdkDisplay *display)
+void
+gdk_display_store_clipboard (GdkDisplay    *display,
+                             GdkWindow     *clipboard_window,
+                             guint32        time_,
+                             GdkAtom       *targets,
+                             gint           n_targets)
 {
-  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
-  return  _gdk_parent_root;
+  D_UNIMPLEMENTED();
 }
 
 
-
-
-static gboolean _gdk_directfb_pointer_implicit_grab = FALSE;
+/*************************************************************************************************
+ * Pointer
+ */
 
 GdkGrabStatus
 gdk_directfb_pointer_grab (GdkWindow    *window,
@@ -297,12 +359,22 @@ gdk_directfb_pointer_grab (GdkWindow    
                            gboolean      implicit_grab)
 {
   GdkWindow             *toplevel;
-  GdkWindowImplDirectFB *impl;
+  GdkWindowImplDirectFB *impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
+
+  D_DEBUG_AT( GDKDFB_GrabPointer, "%s( %p [" GDKDFB_WIMPL_FORM "], owner %d, mask 0x%x, time %u, %splicit )\n",
+              __FUNCTION__, window, GDKDFB_WIMPL_V(impl), owner_events, event_mask, time, implicit_grab ? "im" : "ex" );
+
   if (_gdk_directfb_pointer_grab_window)
     {
+      GdkWindowObject       *grab_priv = GDK_WINDOW_OBJECT(_gdk_directfb_pointer_grab_window);
+      GdkWindowImplDirectFB *grab_impl = GDK_WINDOW_IMPL_DIRECTFB (grab_priv->impl);
+
       if (implicit_grab && !_gdk_directfb_pointer_implicit_grab)
         return GDK_GRAB_ALREADY_GRABBED;
 
+      D_DEBUG_AT( GDKDFB_GrabPointer, "  -> Breaking %splicit grab of " GDKDFB_WIMPL_FORM "!\n",
+                  _gdk_directfb_pointer_implicit_grab ? "im" : "ex", GDKDFB_WIMPL_V(grab_impl) );
+
       gdk_pointer_ungrab (time);
     }
 
@@ -311,6 +383,8 @@ gdk_directfb_pointer_grab (GdkWindow    
 
   if (impl->window)
     {
+      D_DEBUG_AT( GDKDFB_GrabPointer, "  -> Grabbing at top level [" GDKDFB_WIMPL_FORM "].\n", GDKDFB_WIMPL_V(impl) );
+
       if (impl->window->GrabPointer (impl->window) == DFB_LOCKED)
         return GDK_GRAB_ALREADY_GRABBED;
     }
@@ -331,16 +405,13 @@ gdk_directfb_pointer_grab (GdkWindow    
                                              gdk_cursor_ref (cursor) : NULL);
 
 
-  gdk_directfb_window_send_crossing_events (NULL,
+/* FIXME  gdk_directfb_window_send_crossing_events (NULL,
                                             window,
-                                            GDK_CROSSING_GRAB);
+                                            GDK_CROSSING_GRAB);*/
 
   return GDK_GRAB_SUCCESS;
 }
 
-
-
-
 void
 gdk_directfb_pointer_ungrab (guint32  time,
                              gboolean implicit_grab)
@@ -350,18 +421,34 @@ gdk_directfb_pointer_ungrab (guint32  ti
   GdkWindow             *old_grab_window;
   GdkWindowImplDirectFB *impl;
 
+  D_DEBUG_AT( GDKDFB_GrabPointer, "%s( %u, %splicit )\n", __FUNCTION__, time, implicit_grab ? "im" : "ex" );
+
   if (implicit_grab && !_gdk_directfb_pointer_implicit_grab)
     return;
 
   if (!_gdk_directfb_pointer_grab_window)
     return;
 
-  toplevel =
-    gdk_directfb_window_find_toplevel (_gdk_directfb_pointer_grab_window);
+#if D_DEBUG_ENABLED
+  if (_gdk_directfb_pointer_grab_window)
+    {
+      GdkWindowObject       *grab_priv = GDK_WINDOW_OBJECT(_gdk_directfb_pointer_grab_window);
+      GdkWindowImplDirectFB *grab_impl = GDK_WINDOW_IMPL_DIRECTFB (grab_priv->impl);
+
+      D_DEBUG_AT( GDKDFB_GrabPointer, "  -> Finish %splicit grab of " GDKDFB_WIMPL_FORM "!\n",
+                  _gdk_directfb_pointer_implicit_grab ? "im" : "ex", GDKDFB_WIMPL_V(grab_impl) );
+    }
+#endif
+
+  toplevel = gdk_directfb_window_find_toplevel (_gdk_directfb_pointer_grab_window);
   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (toplevel)->impl);
 
   if (impl->window)
-    impl->window->UngrabPointer (impl->window);
+    {
+      D_DEBUG_AT( GDKDFB_GrabPointer, "  -> Ungrabbing at top level [" GDKDFB_WIMPL_FORM "].\n", GDKDFB_WIMPL_V(impl) );
+
+      impl->window->UngrabPointer (impl->window);
+    }
 
   if (_gdk_directfb_pointer_grab_confine)
     {
@@ -381,53 +468,60 @@ gdk_directfb_pointer_ungrab (guint32  ti
   _gdk_directfb_pointer_implicit_grab = FALSE;
 
   mousewin = gdk_window_at_pointer (NULL, NULL);
-  gdk_directfb_window_send_crossing_events (old_grab_window,
+/* FIXME  gdk_directfb_window_send_crossing_events (old_grab_window,
                                             mousewin,
-                                            GDK_CROSSING_UNGRAB);
+                                            GDK_CROSSING_UNGRAB);*/
   g_object_unref (old_grab_window);
 }
 
+gint
+gdk_display_pointer_is_grabbed (GdkDisplay *display)
+{
+  return _gdk_directfb_pointer_grab_window != NULL;
+}
 
+void
+gdk_display_pointer_ungrab (GdkDisplay *display,guint32 time)
+{
+  gdk_directfb_pointer_ungrab (time, _gdk_directfb_pointer_implicit_grab);
+}
 
 
-/*
- *--------------------------------------------------------------
- * gdk_keyboard_grab
- *
- *   Grabs the keyboard to a specific window
- *
- * Arguments:
- *   "window" is the window which will receive the grab
- *   "owner_events" specifies whether events will be reported as is,
- *     or relative to "window"
- *   "time" specifies the time
- *
- * Results:
- *
- * Side effects:
- *   requires a corresponding call to gdk_keyboard_ungrab
- *
- *--------------------------------------------------------------
+/*************************************************************************************************
+ * Keyboard
  */
 
 GdkGrabStatus
-gdk_display_keyboard_grab (GdkDisplay *display,GdkWindow *window,
-                   gint       owner_events,
-                   guint32    time)
+gdk_directfb_keyboard_grab (GdkDisplay *display,
+                            GdkWindow  *window,
+                            gint        owner_events,
+                            guint32     time)
 {
   GdkWindow             *toplevel;
   GdkWindowImplDirectFB *impl;
 
   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
 
+  D_DEBUG_AT( GDKDFB_GrabKeyboard, "%s( %p [" GDKDFB_WIMPL_FORM "], owner %d, time %u )\n", __FUNCTION__, window,
+              GDKDFB_WIMPL_V(GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl)), owner_events, time );
+
   if (_gdk_directfb_keyboard_grab_window)
-    gdk_keyboard_ungrab (time);
+    {
+      GdkWindowObject       *grab_priv = GDK_WINDOW_OBJECT(_gdk_directfb_keyboard_grab_window);
+      GdkWindowImplDirectFB *grab_impl = GDK_WINDOW_IMPL_DIRECTFB (grab_priv->impl);
+
+      D_DEBUG_AT( GDKDFB_GrabKeyboard, "  -> Breaking grab of " GDKDFB_WIMPL_FORM "!\n", GDKDFB_WIMPL_V(grab_impl) );
+
+      gdk_keyboard_ungrab (time);
+    }
 
   toplevel = gdk_directfb_window_find_toplevel (window);
   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (toplevel)->impl);
 
   if (impl->window)
     {
+      D_DEBUG_AT( GDKDFB_GrabKeyboard, "  -> Grabbing at top level [" GDKDFB_WIMPL_FORM "].\n", GDKDFB_WIMPL_V(impl) );
+
       if (impl->window->GrabKeyboard (impl->window) == DFB_LOCKED)
         return GDK_GRAB_ALREADY_GRABBED;
     }
@@ -438,37 +532,82 @@ gdk_display_keyboard_grab (GdkDisplay *d
 }
 
 void
-gdk_display_keyboard_ungrab (GdkDisplay *display,guint32 time)
+gdk_directfb_keyboard_ungrab (GdkDisplay *display,
+                              guint32     time)
 {
   GdkWindow             *toplevel;
   GdkWindowImplDirectFB *impl;
 
+  D_DEBUG_AT( GDKDFB_GrabKeyboard, "%s( %u )\n", __FUNCTION__, time );
+
   if (!_gdk_directfb_keyboard_grab_window)
     return;
 
-  toplevel =
-    gdk_directfb_window_find_toplevel (_gdk_directfb_keyboard_grab_window);
+#if D_DEBUG_ENABLED
+  if (_gdk_directfb_keyboard_grab_window)
+    {
+      GdkWindowObject       *grab_priv = GDK_WINDOW_OBJECT(_gdk_directfb_keyboard_grab_window);
+      GdkWindowImplDirectFB *grab_impl = GDK_WINDOW_IMPL_DIRECTFB (grab_priv->impl);
+
+      D_DEBUG_AT( GDKDFB_GrabKeyboard, "  -> Finish grab of " GDKDFB_WIMPL_FORM "!\n", GDKDFB_WIMPL_V(grab_impl) );
+    }
+#endif
+
+  toplevel = gdk_directfb_window_find_toplevel (_gdk_directfb_keyboard_grab_window);
   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (toplevel)->impl);
 
   if (impl->window)
-    impl->window->UngrabKeyboard (impl->window);
+    {
+      D_DEBUG_AT( GDKDFB_GrabKeyboard, "  -> Ungrabbing at top level [" GDKDFB_WIMPL_FORM "].\n", GDKDFB_WIMPL_V(impl) );
+
+      impl->window->UngrabKeyboard (impl->window);
+    }
 
   g_object_unref (_gdk_directfb_keyboard_grab_window);
   _gdk_directfb_keyboard_grab_window = NULL;
 }
 
-gint
-gdk_display_pointer_is_grabbed (GdkDisplay *display)
+/*
+ *--------------------------------------------------------------
+ * gdk_keyboard_grab
+ *
+ *   Grabs the keyboard to a specific window
+ *
+ * Arguments:
+ *   "window" is the window which will receive the grab
+ *   "owner_events" specifies whether events will be reported as is,
+ *     or relative to "window"
+ *   "time" specifies the time
+ *
+ * Results:
+ *
+ * Side effects:
+ *   requires a corresponding call to gdk_keyboard_ungrab
+ *
+ *--------------------------------------------------------------
+ */
+
+GdkGrabStatus
+gdk_display_keyboard_grab (GdkDisplay *display,
+                           GdkWindow  *window,
+                           gint        owner_events,
+                           guint32     time)
 {
-  return _gdk_directfb_pointer_grab_window != NULL;
+  return gdk_directfb_keyboard_grab (display, window, owner_events, time);
 }
 
 void
-gdk_display_pointer_ungrab (GdkDisplay *display,guint32 time)
+gdk_display_keyboard_ungrab (GdkDisplay *display,
+                             guint32     time)
 {
-  gdk_directfb_pointer_ungrab (time, _gdk_directfb_pointer_implicit_grab);
+  return gdk_directfb_keyboard_ungrab (display, time);
 }
 
+
+/*************************************************************************************************
+ * Misc Stuff
+ */
+
 void
 gdk_display_beep (GdkDisplay *display)
 {
@@ -485,6 +624,9 @@ gdk_display_flush (GdkDisplay *display)
 }
 
 
+/*************************************************************************************************
+ * Notifications
+ */
 
 void
 gdk_notify_startup_complete (void)
@@ -512,6 +654,10 @@ gdk_notify_startup_complete_with_id (con
 }
 
 
+/*************************************************************************************************
+ * Compositing
+ */
+
 gboolean
 gdk_display_supports_composite (GdkDisplay *display)
 {
diff -puraN gtk+-2.12.9/gdk/directfb/gdkdisplay-directfb.h gtk+-2.12.9-dok2/gdk/directfb/gdkdisplay-directfb.h
--- gtk+-2.12.9/gdk/directfb/gdkdisplay-directfb.h	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkdisplay-directfb.h	2008-05-21 20:20:24.000000000 +0200
@@ -42,7 +42,12 @@ struct _GdkDisplayDFB
   IDirectFBDisplayLayer  *layer;
   IDirectFBEventBuffer   *buffer;
   IDirectFBInputDevice   *keyboard;
-  GdkKeymap *keymap;
+  GdkKeymap              *keymap;
+
+  int                     event_fd;
+  GSource                *event_source;
+
+  GList                  *client_filters; /* list of filters for client messages */
 };
 
 struct _GdkDisplayDFBClass
diff -puraN gtk+-2.12.9/gdk/directfb/gdkdrawable-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkdrawable-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkdrawable-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkdrawable-directfb.c	2008-05-21 20:21:10.000000000 +0200
@@ -39,6 +39,8 @@
 #include "gdkdirectfb.h"
 #include "gdkprivate-directfb.h"
 
+#include "../../gdk-pixbuf/gdk-pixbuf-private.h"
+
 #include "gdkinternals.h"
 
 
@@ -47,15 +49,75 @@
 
 #include "cairo-directfb.h"
 
-#define WARN_UNIMPLEMENTED(func)\
-{\
-  static gboolean first_call = TRUE;\
-  if (first_call)\
-    {\
-                        g_message ("unimplemented " func);\
-      first_call = FALSE;\
-    }\
-}
+
+#include <direct/debug.h>
+#include <direct/messages.h>
+
+/*
+ * There can be multiple domains in one file and one domain (same same) in multiple files.
+ */
+D_DEBUG_DOMAIN( GDKDFB_Drawable, "GDKDFB/Drawable", "GDK DirectFB Drawable" );
+D_DEBUG_DOMAIN( GDKDFB_DrawClip, "GDKDFB/DrawClip", "GDK DirectFB Drawable Clip Region" );
+
+
+/* From DirectFB's <gfx/generix/duffs_device.h> */
+#define DUFF_1() \
+               case 1:\
+                    SET_PIXEL( D[0], S[0] );
+
+#define DUFF_2() \
+               case 3:\
+                    SET_PIXEL( D[2], S[2] );\
+               case 2:\
+                    SET_PIXEL( D[1], S[1] );\
+               DUFF_1()
+
+#define DUFF_3() \
+               case 7:\
+                    SET_PIXEL( D[6], S[6] );\
+               case 6:\
+                    SET_PIXEL( D[5], S[5] );\
+               case 5:\
+                    SET_PIXEL( D[4], S[4] );\
+               case 4:\
+                    SET_PIXEL( D[3], S[3] );\
+               DUFF_2()
+
+#define DUFF_4() \
+               case 15:\
+                    SET_PIXEL( D[14], S[14] );\
+               case 14:\
+                    SET_PIXEL( D[13], S[13] );\
+               case 13:\
+                    SET_PIXEL( D[12], S[12] );\
+               case 12:\
+                    SET_PIXEL( D[11], S[11] );\
+               case 11:\
+                    SET_PIXEL( D[10], S[10] );\
+               case 10:\
+                    SET_PIXEL( D[9], S[9] );\
+               case 9:\
+                    SET_PIXEL( D[8], S[8] );\
+               case 8:\
+                    SET_PIXEL( D[7], S[7] );\
+               DUFF_3()
+
+#define SET_PIXEL_DUFFS_DEVICE_N( D, S, w, n ) \
+do {\
+     while (w) {\
+          register int l = w & ((1 << n) - 1);\
+          switch (l) {\
+               default:\
+                    l = (1 << n);\
+                    SET_PIXEL( D[(1 << n)-1], S[(1 << n)-1] );\
+               DUFF_##n()\
+          }\
+          D += l;\
+          S += l;\
+          w -= l;\
+     }\
+} while(0)
+
 
 static GdkScreen * gdk_directfb_get_screen (GdkDrawable    *drawable);
 static void gdk_drawable_impl_directfb_class_init (GdkDrawableImplDirectFBClass *klass);
@@ -71,6 +133,19 @@ static gboolean  accelerated_alpha_blend
 static gpointer  parent_class               = NULL;
 static const cairo_user_data_key_t gdk_directfb_cairo_key;
 
+static void (*real_draw_pixbuf) (GdkDrawable *drawable,
+                                 GdkGC       *gc,
+                                 GdkPixbuf   *pixbuf,
+                                 gint         src_x,
+                                 gint         src_y,
+                                 gint         dest_x,
+                                 gint         dest_y,
+                                 gint         width,
+                                 gint         height,
+                                 GdkRgbDither dither,
+                                 gint         x_dither,
+                                 gint         y_dither);
+
 
 /**********************************************************
  * DirectFB specific implementations of generic functions *
@@ -85,6 +160,8 @@ gdk_directfb_set_colormap (GdkDrawable *
 
   impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
 
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p ) <- old %p\n", __FUNCTION__, drawable, colormap, impl->colormap );
+
   if (impl->colormap == colormap)
     return;
 
@@ -145,18 +222,20 @@ gdk_directfb_get_visual (GdkDrawable *dr
 /* Calculates the real clipping region for a drawable, taking into account
  * other windows and the gc clip region.
  */
-static GdkRegion *
+void
 gdk_directfb_clip_region (GdkDrawable  *drawable,
                           GdkGC        *gc,
-                          GdkRectangle *draw_rect)
+                          GdkRectangle *draw_rect,
+                          GdkRegion    *ret_clip)
 {
   GdkDrawableImplDirectFB *private;
-  GdkRegion               *clip_region;
-  GdkRegion               *tmpreg;
   GdkRectangle             rect;
 
-  g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
-  g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable), NULL);
+  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
+  g_return_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable));
+  g_return_if_fail (ret_clip != NULL);
+
+  D_DEBUG_AT( GDKDFB_DrawClip, "%s( %p, %p, %p )\n", __FUNCTION__, drawable, gc, draw_rect );
 
   private = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
 
@@ -169,43 +248,62 @@ gdk_directfb_clip_region (GdkDrawable  *
 
       draw_rect = &rect;
     }
+  D_DEBUG_AT( GDKDFB_DrawClip, "  -> draw rectangle   == %4d,%4d - %4dx%4d =\n",
+              draw_rect->x, draw_rect->y, draw_rect->width, draw_rect->height );
 
-  clip_region = gdk_region_rectangle (draw_rect);
+  temp_region_init_rectangle( ret_clip, draw_rect );
 
-  if (private->buffered && private->paint_region)
-    gdk_region_intersect (clip_region, private->paint_region);
+  if (private->buffered) {
+       D_DEBUG_AT( GDKDFB_DrawClip, "  -> buffered region   > %4d,%4d - %4dx%4d <  (%ld boxes)\n",
+                   GDKDFB_RECTANGLE_VALS_FROM_BOX( &private->paint_region.extents ),
+                   private->paint_region.numRects );
+
+    gdk_region_intersect (ret_clip, &private->paint_region);
+  }
 
   if (gc)
     {
       GdkGCDirectFB *gc_private = GDK_GC_DIRECTFB (gc);
-      GdkRegion     *region     = gc_private->clip_region;
+      GdkRegion     *region     = &gc_private->clip_region;
 
-      if (region)
+      if (region->numRects)
         {
+          D_DEBUG_AT( GDKDFB_DrawClip, "  -> clipping region   > %4d,%4d - %4dx%4d <  (%ld boxes)\n",
+                      GDKDFB_RECTANGLE_VALS_FROM_BOX( &region->extents ), region->numRects );
+
           if (gc->clip_x_origin || gc->clip_y_origin)
             {
-              tmpreg = gdk_region_copy (region);
-
-              gdk_region_offset (tmpreg, gc->clip_x_origin, gc->clip_y_origin);
-              gdk_region_intersect (clip_region, tmpreg);
-              gdk_region_destroy (tmpreg);
+              gdk_region_offset (ret_clip, -gc->clip_x_origin, -gc->clip_y_origin);
+              gdk_region_intersect (ret_clip, region);
+              gdk_region_offset (ret_clip, gc->clip_x_origin, gc->clip_y_origin);
             }
           else
             {
-              gdk_region_intersect (clip_region, region);
+              gdk_region_intersect (ret_clip, region);
             }
         }
 
       if (gc_private->values_mask & GDK_GC_SUBWINDOW &&
           gc_private->values.subwindow_mode == GDK_INCLUDE_INFERIORS)
-        return clip_region;
+        return;
     }
 
+  if (private->buffered) {
+       D_DEBUG_AT( GDKDFB_DrawClip, "  => returning clip   >> %4d,%4d - %4dx%4d << (%ld boxes)\n",
+                   GDKDFB_RECTANGLE_VALS_FROM_BOX( &ret_clip->extents ), ret_clip->numRects );
+    return;
+  }
+
   if (GDK_IS_WINDOW (private->wrapper) &&
       GDK_WINDOW_IS_MAPPED (private->wrapper) &&
       !GDK_WINDOW_OBJECT (private->wrapper)->input_only)
     {
-      GList *cur;
+      GList     *cur;
+      GdkRegion  temp;
+
+      temp.numRects = 1;
+      temp.rects = &temp.extents;
+      temp.size = 1;
 
       for (cur = GDK_WINDOW_OBJECT (private->wrapper)->children;
            cur;
@@ -221,18 +319,20 @@ gdk_directfb_clip_region (GdkDrawable  *
 
           cur_impl = GDK_DRAWABLE_IMPL_DIRECTFB (cur_private->impl);
 
-          rect.x      = cur_private->x;
-          rect.y      = cur_private->y;
-          rect.width  = cur_impl->width;
-          rect.height = cur_impl->height;
+          temp.extents.x1 = cur_private->x;
+          temp.extents.y1 = cur_private->y;
+          temp.extents.x2 = cur_private->x + cur_impl->width;
+          temp.extents.y2 = cur_private->y + cur_impl->height;
+
+          D_DEBUG_AT( GDKDFB_DrawClip, "  -> clipping child    [ %4d,%4d - %4dx%4d ]  (%ld boxes)\n",
+                      GDKDFB_RECTANGLE_VALS_FROM_BOX( &temp.extents ), temp.numRects );
 
-          tmpreg = gdk_region_rectangle (&rect);
-          gdk_region_subtract (clip_region, tmpreg);
-          gdk_region_destroy (tmpreg);
+          gdk_region_subtract (ret_clip, &temp);
         }
     }
 
-  return clip_region;
+  D_DEBUG_AT( GDKDFB_DrawClip, "  => returning clip   >> %4d,%4d - %4dx%4d << (%ld boxes)\n",
+              GDKDFB_RECTANGLE_VALS_FROM_BOX( &ret_clip->extents ), ret_clip->numRects );
 }
 
 /* Drawing
@@ -318,29 +418,31 @@ gdk_directfb_setup_for_drawing (GdkDrawa
   return TRUE;
 }
 
-void
-_gdk_directfb_draw_rectangle (GdkDrawable *drawable,
-                              GdkGC       *gc,
-                              gint         filled,
-                              gint         x,
-                              gint         y,
-                              gint         width,
-                              gint         height)
+static void
+gdk_directfb_draw_rectangle (GdkDrawable *drawable,
+                             GdkGC       *gc,
+                             gint         filled,
+                             gint         x,
+                             gint         y,
+                             gint         width,
+                             gint         height)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   GdkGCDirectFB           *gc_private = NULL;
   IDirectFBSurface        *surface    = NULL;
   gint  i;
 
   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
 
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %s, %4d,%4d - %4dx%4d )\n", __FUNCTION__,
+              drawable, gc, filled ? " filled" : "outline", x, y, width, height );
+
   impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
 
   if (!impl->surface)
     return;
 
-
   if (gc)
     gc_private = GDK_GC_DIRECTFB (gc);
 
@@ -392,7 +494,7 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
     {
       GdkRectangle  rect = { x, y, width, height };
 
-      clip = gdk_directfb_clip_region (drawable, gc, &rect);
+      gdk_directfb_clip_region (drawable, gc, &rect, &clip);
 
       if (gc_private && gc_private->values_mask & GDK_GC_FILL)
         {
@@ -412,6 +514,8 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
                    gc_private->values.tile)
             {
               surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (gc_private->values.tile)->impl)->surface;
+
+              impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
             }
         }
 
@@ -422,33 +526,35 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
           if (gc_private->values_mask & GDK_GC_TS_Y_ORIGIN)
             y = gc_private->values.ts_y_origin;
 
-          for (i = 0; i < clip->numRects; i++)
+          for (i = 0; i < clip.numRects; i++)
             {
-              DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1,
-                                clip->rects[i].x2, clip->rects[i].y2 };
+              DFBRegion reg = { clip.rects[i].x1,     clip.rects[i].y1,
+                                clip.rects[i].x2, clip.rects[i].y2 };
 
               impl->surface->SetClip (impl->surface, &reg);
               impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
             }
-
-          impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
-          impl->surface->SetClip (impl->surface, NULL);
         }
       else  /* normal rectangle filling */
         {
-          for (i = 0; i < clip->numRects; i++)
+          DFBRectangle rects[clip.numRects];
+
+          impl->surface->SetClip (impl->surface, NULL);
+
+          for (i = 0; i < clip.numRects; i++)
             {
-              DFBRegion *region = (DFBRegion *) &clip->rects[i];
+              GdkRegionBox *box = &clip.rects[i];
 
-              impl->surface->FillRectangle (impl->surface,
-                                            region->x1,
-                                            region->y1,
-                                            region->x2 - region->x1,
-                                            region->y2 - region->y1);
+              rects[i].x = box->x1;
+              rects[i].y = box->y1;
+              rects[i].w = box->x2 - box->x1;
+              rects[i].h = box->y2 - box->y1;
             }
+
+          impl->surface->FillRectangles(impl->surface, rects, clip.numRects);
         }
 
-      gdk_region_destroy (clip);
+      temp_region_deinit( &clip );
     }
   else
     {
@@ -461,7 +567,6 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
           X draws the rectangle one pixel taller and wider.  */
       impl->surface->DrawRectangle (impl->surface,
                                     x, y, width , height);
-      impl->surface->SetClip (impl->surface, NULL);
     }
 }
 
@@ -476,7 +581,7 @@ gdk_directfb_draw_arc (GdkDrawable *draw
                        gint         angle1,
                        gint         angle2)
 {
-  WARN_UNIMPLEMENTED (G_STRLOC);
+  D_UNIMPLEMENTED();
 }
 
 static void
@@ -488,18 +593,20 @@ gdk_directfb_draw_polygon (GdkDrawable *
 {
   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
 
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %s, %p, %d )\n", __FUNCTION__,
+              drawable, gc, filled ? " filled" : "outline", points, npoints );
+
   if (npoints < 3)
     return;
 
   if (filled)
     {
-                if (npoints == 3 ||
-                                (npoints == 4 && 
+      if (npoints == 3 || (npoints == 4 && 
                                  points[0].x == points[npoints-1].x &&
                                  points[0].y == points[npoints-1].y))
           {
             GdkDrawableImplDirectFB *impl;
-            GdkRegion               *clip;
+            GdkRegion                clip;
             gint                     i;
 
             impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
@@ -507,12 +614,12 @@ gdk_directfb_draw_polygon (GdkDrawable *
             if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
               return;
 
-            clip = gdk_directfb_clip_region (drawable, gc, NULL);
+            gdk_directfb_clip_region (drawable, gc, NULL, &clip);
 
-            for (i = 0; i < clip->numRects; i++)
+            for (i = 0; i < clip.numRects; i++)
               {
-                                DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1, 
-                    clip->rects[i].x2 , clip->rects[i].y2  };
+                                DFBRegion reg = { clip.rects[i].x1,     clip.rects[i].y1, 
+                    clip.rects[i].x2 , clip.rects[i].y2  };
 
                 impl->surface->SetClip (impl->surface, &reg);
                 impl->surface->FillTriangle (impl->surface,
@@ -521,8 +628,8 @@ gdk_directfb_draw_polygon (GdkDrawable *
                                              points[2].x, points[2].y);
 
               }
-            impl->surface->SetClip (impl->surface, NULL);
-            gdk_region_destroy (clip);
+
+            temp_region_deinit( &clip );
 
             return;
           }
@@ -560,7 +667,7 @@ gdk_directfb_draw_text (GdkDrawable *dra
                         const gchar *text,
                         gint         text_length)
 {
-  WARN_UNIMPLEMENTED (G_STRLOC);
+  D_UNIMPLEMENTED();
 }
 
 static void
@@ -572,7 +679,7 @@ gdk_directfb_draw_text_wc (GdkDrawable  
                            const GdkWChar *text,
                            gint            text_length)
 {
-  WARN_UNIMPLEMENTED (G_STRLOC);
+  D_UNIMPLEMENTED();
 }
 
 static void
@@ -588,7 +695,7 @@ gdk_directfb_draw_drawable (GdkDrawable 
 {
   GdkDrawableImplDirectFB *impl;
   GdkDrawableImplDirectFB *src_impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   GdkRectangle             dest_rect = { xdest,
                                          ydest,
                 xdest + width ,
@@ -597,6 +704,9 @@ gdk_directfb_draw_drawable (GdkDrawable 
   DFBRectangle rect = { xsrc, ysrc, width, height };
   gint i;
 
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %p, %4d,%4d -> %4d,%4d - %dx%d )\n", __FUNCTION__,
+              drawable, gc, src, xsrc, ysrc, xdest, ydest, width, height );
+
   impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
 
   if (!impl->surface)
@@ -611,19 +721,21 @@ gdk_directfb_draw_drawable (GdkDrawable 
   else
     return;
 
-  clip = gdk_directfb_clip_region (drawable, gc, &dest_rect);
+  gdk_directfb_clip_region (drawable, gc, &dest_rect, &clip);
+
+  impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
 
-  for (i = 0; i < clip->numRects; i++)
+  for (i = 0; i < clip.numRects; i++)
     {
-      DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1,
-                        clip->rects[i].x2 , clip->rects[i].y2 };
+      DFBRegion reg = { clip.rects[i].x1,     clip.rects[i].y1,
+                        clip.rects[i].x2 , clip.rects[i].y2 };
 
       impl->surface->SetClip (impl->surface, &reg);
       impl->surface->Blit (impl->surface, src_impl->surface, &rect,
                            xdest, ydest);
     }
-  impl->surface->SetClip (impl->surface, NULL);
-  gdk_region_destroy (clip);
+
+  temp_region_deinit( &clip );
 }
 
 static void
@@ -633,10 +745,12 @@ gdk_directfb_draw_points (GdkDrawable *d
                           gint         npoints)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
 
   DFBRegion region = { points->x, points->y, points->x, points->y };
 
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %p, %d )\n", __FUNCTION__, drawable, gc, points, npoints );
+
   if (npoints < 1)
     return;
 
@@ -645,11 +759,11 @@ gdk_directfb_draw_points (GdkDrawable *d
   if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
     return;
 
-  clip = gdk_directfb_clip_region (drawable, gc, NULL);
+  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
 
   while (npoints > 0)
     {
-      if (gdk_region_point_in (clip, points->x, points->y))
+      if (gdk_region_point_in (&clip, points->x, points->y))
         {
           impl->surface->FillRectangle (impl->surface,
                                         points->x, points->y, 1, 1);
@@ -669,7 +783,7 @@ gdk_directfb_draw_points (GdkDrawable *d
       points++;
     }
 
-  gdk_region_destroy (clip);
+  temp_region_deinit( &clip );
 }
 
 static void
@@ -679,10 +793,12 @@ gdk_directfb_draw_segments (GdkDrawable 
                             gint         nsegs)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   gint                     i;
 
-  DFBRegion region = { segs->x1, segs->y1, segs->x2, segs->y2 };
+//  DFBRegion region = { segs->x1, segs->y1, segs->x2, segs->y2 };
+
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %p, %d )\n", __FUNCTION__, drawable, gc, segs, nsegs );
 
   if (nsegs < 1)
     return;
@@ -692,24 +808,22 @@ gdk_directfb_draw_segments (GdkDrawable 
   if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
     return;
 
-  clip = gdk_directfb_clip_region (drawable, gc, NULL);
+  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
 
-  for (i = 0; i < clip->numRects; i++)
+  for (i = 0; i < clip.numRects; i++)
     {
-      DFBRegion reg = { clip->rects[i].x1,   clip->rects[i].y1,
-                        clip->rects[i].x2, clip->rects[i].y2 };
+      DFBRegion reg = { clip.rects[i].x1,   clip.rects[i].y1,
+                        clip.rects[i].x2, clip.rects[i].y2 };
 
       impl->surface->SetClip (impl->surface, &reg);
 
       impl->surface->DrawLines (impl->surface, (DFBRegion *)segs, nsegs);
     }
 
-  impl->surface->SetClip (impl->surface, NULL);
-
-  gdk_region_destroy (clip);
+  temp_region_deinit( &clip );
 
   /* everything below can be omitted if the drawing is buffered */
-  if (impl->buffered)
+/*  if (impl->buffered)
     return;
 
   if (region.x1 > region.x2)
@@ -747,7 +861,7 @@ gdk_directfb_draw_segments (GdkDrawable 
         region.y2 = segs->y1;
       if (segs->y2 > region.y2)
         region.y2 = segs->y2;
-    }
+    }*/
 }
 
 static void
@@ -757,13 +871,15 @@ gdk_directfb_draw_lines (GdkDrawable *dr
                          gint         npoints)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   gint                     i;
 
   DFBRegion lines[npoints > 1 ? npoints - 1 : 1];
 
   DFBRegion region = { points->x, points->y, points->x, points->y };
 
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %p, %d )\n", __FUNCTION__, drawable, gc, points, npoints );
+
   if (npoints < 2)
     return;
 
@@ -801,20 +917,18 @@ gdk_directfb_draw_lines (GdkDrawable *dr
   lines[i].x2 = points->x;
   lines[i].y2 = points->y;
 
-  clip = gdk_directfb_clip_region (drawable, gc, NULL);
+  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
 
-  for (i = 0; i < clip->numRects; i++)
+  for (i = 0; i < clip.numRects; i++)
     {
-      DFBRegion reg = { clip->rects[i].x1,   clip->rects[i].y1,
-                        clip->rects[i].x2, clip->rects[i].y2 };
+      DFBRegion reg = { clip.rects[i].x1,   clip.rects[i].y1,
+                        clip.rects[i].x2, clip.rects[i].y2 };
 
       impl->surface->SetClip (impl->surface, &reg);
       impl->surface->DrawLines (impl->surface, lines, npoints - 1);
     }
 
-  impl->surface->SetClip (impl->surface, NULL);
-
-  gdk_region_destroy (clip);
+  temp_region_deinit( &clip );
 }
 
 static void
@@ -830,7 +944,7 @@ gdk_directfb_draw_image (GdkDrawable *dr
 {
   GdkDrawableImplDirectFB *impl;
   GdkImageDirectFB        *image_private;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   GdkRectangle             dest_rect = { xdest, ydest, width, height };
 
   gint pitch = 0;
@@ -839,38 +953,474 @@ gdk_directfb_draw_image (GdkDrawable *dr
   g_return_if_fail (GDK_IS_DRAWABLE (drawable));
   g_return_if_fail (image != NULL);
 
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %p, %4d,%4d -> %4d,%4d - %dx%d )\n", __FUNCTION__,
+              drawable, gc, image, xsrc, ysrc, xdest, ydest, width, height );
+
   impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
   image_private = image->windowing_data;
 
   if (!impl->surface)
     return;
 
-  clip = gdk_directfb_clip_region (drawable, gc, &dest_rect);
+  gdk_directfb_clip_region (drawable, gc, &dest_rect, &clip);
 
-  if (!gdk_region_empty (clip))
+  if (!gdk_region_empty (&clip))
     {
       DFBRectangle  src_rect = { xsrc, ysrc, width, height };
 
       image_private->surface->Unlock (image_private->surface);
 
-      for (i = 0; i < clip->numRects; i++)
+      impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
+
+      for (i = 0; i < clip.numRects; i++)
         {
-          DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1,
-                            clip->rects[i].x2 , clip->rects[i].y2  };
+          DFBRegion reg = { clip.rects[i].x1,     clip.rects[i].y1,
+                            clip.rects[i].x2 , clip.rects[i].y2  };
 
           impl->surface->SetClip (impl->surface, &reg);
           impl->surface->Blit (impl->surface,
                                image_private->surface, &src_rect,
                                xdest, ydest);
         }
-      impl->surface->SetClip (impl->surface, NULL);
 
       image_private->surface->Lock (image_private->surface, DSLF_WRITE,
                                     &image->mem, &pitch);
       image->bpl = pitch;
     }
 
+  temp_region_deinit( &clip );
+}
+
+static void
+composite (guchar *src_buf,
+           gint    src_rowstride,
+           guchar *dest_buf,
+           gint    dest_rowstride,
+           gint    width,
+           gint    height)
+{
+  guchar *src = src_buf;
+  guchar *dest = dest_buf;
+
+  while (height--)
+    {
+      gint twidth = width;
+      guchar *p = src;
+      guchar *q = dest;
+
+      while (twidth--)
+        {
+          guchar a = p[3];
+          guint t;
+
+          t = a * p[0] + (255 - a) * q[0] + 0x80;
+          q[0] = (t + (t >> 8)) >> 8;
+          t = a * p[1] + (255 - a) * q[1] + 0x80;
+          q[1] = (t + (t >> 8)) >> 8;
+          t = a * p[2] + (255 - a) * q[2] + 0x80;
+          q[2] = (t + (t >> 8)) >> 8;
+
+          p += 4;
+          q += 3;
+        }
+      
+      src += src_rowstride;
+      dest += dest_rowstride;
+    }
+}
+
+static void
+composite_0888 (guchar      *src_buf,
+                gint         src_rowstride,
+                guchar      *dest_buf,
+                gint         dest_rowstride,
+                GdkByteOrder dest_byte_order,
+                gint         width,
+                gint         height)
+{
+  guchar *src = src_buf;
+  guchar *dest = dest_buf;
+
+  while (height--)
+    {
+      gint twidth = width;
+      guchar *p = src;
+      guchar *q = dest;
+
+      if (dest_byte_order == GDK_LSB_FIRST)
+        {
+          while (twidth--)
+            {
+              guint t;
+              
+              t = p[3] * p[2] + (255 - p[3]) * q[0] + 0x80;
+              q[0] = (t + (t >> 8)) >> 8;
+              t = p[3] * p[1] + (255 - p[3]) * q[1] + 0x80;
+              q[1] = (t + (t >> 8)) >> 8;
+              t = p[3] * p[0] + (255 - p[3]) * q[2] + 0x80;
+              q[2] = (t + (t >> 8)) >> 8;
+              p += 4;
+              q += 4;
+            }
+        }
+      else
+        {
+          while (twidth--)
+            {
+              guint t;
+              
+              t = p[3] * p[0] + (255 - p[3]) * q[1] + 0x80;
+              q[1] = (t + (t >> 8)) >> 8;
+              t = p[3] * p[1] + (255 - p[3]) * q[2] + 0x80;
+              q[2] = (t + (t >> 8)) >> 8;
+              t = p[3] * p[2] + (255 - p[3]) * q[3] + 0x80;
+              q[3] = (t + (t >> 8)) >> 8;
+              p += 4;
+              q += 4;
+            }
+        }
+      
+      src += src_rowstride;
+      dest += dest_rowstride;
+    }
+}
+
+/* change the last value to adjust the size of the device (1-4) */
+#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
+     SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 2 )
+
+/* From DirectFB's gfx/generic/generic.c" */
+#define SET_PIXEL( D, S )                    \
+     switch (S >> 26) {                      \
+          case 0:                            \
+               break;                        \
+          case 0x3f:                         \
+               D = ((S <<  8) & 0xF800) |    \
+                   ((S >>  5) & 0x07E0) |    \
+                   ((S >> 19) & 0x001F);     \
+               break;                        \
+          default:                           \
+               D = (((( (((S<<8) & 0xf800) | ((S>>19) & 0x001f))                                    \
+                        - (D & 0xf81f)) * ((S>>26)+1) + ((D & 0xf81f)<<6)) & 0x003e07c0)            \
+                      +                                                                             \
+                    ((( ((S>>5) & 0x07e0)                                                           \
+                        - (D & 0x07e0)) * ((S>>26)+1) + ((D & 0x07e0)<<6)) & 0x0001f800)) >> 6;     \
+     }
+
+static void
+composite_565 (guchar      *src_buf,
+               gint         src_rowstride,
+               guchar      *dest_buf,
+               gint         dest_rowstride,
+               GdkByteOrder dest_byte_order,
+               gint         width,
+               gint         height)
+{
+     while (height--) {
+          int  w = width;
+          u16 *D = (u16*) dest_buf;
+          u32 *S = (u32*) src_buf;
+#if 1
+          if ((unsigned long)D & 2) {
+               SET_PIXEL( D[0], S[0] );
+               w--;
+               D++;
+               S++;
+          }
+
+          int  i;
+          int  w2  = w / 2;
+          u32 *D32 = (u32*) D;
+
+          for (i=0; i<w2; i++) {
+               register u32 S0 = S[(i << 1) + 0];
+               register u32 S1 = S[(i << 1) + 1];
+
+               if ((S0 >> 26) == 0x3f && (S1 >> 26) == 0x3f) {
+                    D32[i] = ((S0 <<  8) & 0x0000F800) |
+                             ((S0 >>  5) & 0x000007E0) |
+                             ((S0 >> 19) & 0x0000001F) |
+                             ((S1 << 24) & 0xF8000000) |
+                             ((S1 << 11) & 0x07E00000) |
+                             ((S1 >>  3) & 0x001F0000);
+               }
+               else {
+                    SET_PIXEL( D[(i << 1) + 0], S0 );
+                    SET_PIXEL( D[(i << 1) + 1], S1 );
+               }
+          }
+
+          if (w & 1)
+               SET_PIXEL( D[w-1], S[w-1] );
+#else
+          SET_PIXEL_DUFFS_DEVICE( D, S, w );
+#endif
+
+          dest_buf += dest_rowstride;
+          src_buf += src_rowstride;
+     }
+}
+
+#undef SET_PIXEL
+#undef SET_PIXEL_DUFFS_DEVICE
+
+static void
+gdk_directfb_draw_pixbuf (GdkDrawable  *drawable,
+                          GdkGC        *gc,
+                          GdkPixbuf    *pixbuf,
+                          gint          src_x,
+                          gint          src_y,
+                          gint          dest_x,
+                          gint          dest_y,
+                          gint          width,
+                          gint          height,
+                          GdkRgbDither  dither,
+                          gint          x_dither,
+                          gint          y_dither)
+{
+  GdkPixbuf *composited = NULL;
+#if 0
+  GdkRegion *clip;
+  GdkRegion *drect;
+  GdkRectangle tmp_rect;
+#endif
+  GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
+
+  g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+  g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB);
+  g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4);
+  g_return_if_fail (pixbuf->bits_per_sample == 8);
+
+  g_return_if_fail (drawable != NULL);
+
+  if (width == -1) 
+    width = pixbuf->width;
+  if (height == -1)
+    height = pixbuf->height;
+
+  g_return_if_fail (width >= 0 && height >= 0);
+  g_return_if_fail (src_x >= 0 && src_x + width <= pixbuf->width);
+  g_return_if_fail (src_y >= 0 && src_y + height <= pixbuf->height);
+
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p, %p, %p, %4d,%4d -> %4d,%4d - %dx%d )\n", __FUNCTION__,
+              drawable, gc, pixbuf, src_x, src_y, dest_x, dest_y, width, height );
+
+  /* Clip to the drawable; this is required for get_from_drawable() so
+   * can't be done implicitly
+   */
+  
+  if (dest_x < 0)
+    {
+      src_x -= dest_x;
+      width += dest_x;
+      dest_x = 0;
+    }
+
+  if (dest_y < 0)
+    {
+      src_y -= dest_y;
+      height += dest_y;
+      dest_y = 0;
+    }
+
+  if ((dest_x + width) > impl->width)
+    width = impl->width - dest_x;
+
+  if ((dest_y + height) > impl->height)
+    height = impl->height - dest_y;
+
+  if (width <= 0 || height <= 0)
+    return;
+
+#if 0
+  /* Clip to the clip region; this avoids getting more
+   * image data from the server than we need to.
+   */
+  
+  tmp_rect.x = dest_x;
+  tmp_rect.y = dest_y;
+  tmp_rect.width = width;
+  tmp_rect.height = height;
+
+  drect = gdk_region_rectangle (&tmp_rect);
+  clip = gdk_drawable_get_clip_region (drawable);
+
+  gdk_region_intersect (drect, clip);
+
+  gdk_region_get_clipbox (drect, &tmp_rect);
+  
+  gdk_region_destroy (drect);
   gdk_region_destroy (clip);
+
+  if (tmp_rect.width == 0 ||
+      tmp_rect.height == 0)
+    return;
+#endif
+
+  if (pixbuf->has_alpha && impl->format == DSPF_RGB16) {
+       void *data;
+       int   pitch;
+
+       if (impl->surface->Lock( impl->surface, DSLF_READ | DSLF_WRITE, &data, &pitch ) == DFB_OK) {
+            composite_565( pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
+                           pixbuf->rowstride,
+                           data + dest_y * pitch + dest_x * 2,
+                           pitch,
+                         #if G_BYTE_ORDER == G_BIG_ENDIAN
+                           GDK_MSB_FIRST,
+                         #else
+                           GDK_LSB_FIRST,
+                         #endif
+                           width, height );
+
+            impl->surface->Unlock( impl->surface );
+
+            return;
+       }
+  }
+
+  /* Actually draw */
+  if (!gc)
+    gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
+
+  if (pixbuf->has_alpha)
+    {
+      GdkVisual *visual = gdk_drawable_get_visual (drawable);
+      void (*composite_func) (guchar       *src_buf,
+                              gint          src_rowstride,
+                              guchar       *dest_buf,
+                              gint          dest_rowstride,
+                              GdkByteOrder  dest_byte_order,
+                              gint          width,
+                              gint          height) = NULL;
+
+      /* First we see if we have a visual-specific composition function that can composite
+       * the pixbuf data directly onto the image
+       */
+      if (visual)
+        {
+          gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_drawable_get_display (drawable),
+                                                                   visual->depth);
+          
+          if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) &&
+              visual->depth == 16 &&
+              visual->red_mask   == 0xf800 &&
+              visual->green_mask == 0x07e0 &&
+              visual->blue_mask  == 0x001f)
+            composite_func = composite_565;
+          else if (visual->depth == 24 && bits_per_pixel == 32 &&
+                   visual->red_mask   == 0xff0000 &&
+                   visual->green_mask == 0x00ff00 &&
+                   visual->blue_mask  == 0x0000ff)
+            composite_func = composite_0888;
+        }
+
+      /* We can't use our composite func if we are required to dither
+       */
+      if (composite_func && !(dither == GDK_RGB_DITHER_MAX && visual->depth != 24))
+        {
+#if 0
+          gint x0, y0;
+          for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
+            {
+              gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
+              for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
+                {
+                  gint xs0, ys0;
+                  
+                  gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
+                  
+                  GdkImage *image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable),
+                                                            width1, height1,
+                                                            gdk_drawable_get_depth (drawable), &xs0, &ys0);
+                  
+                  gdk_drawable_copy_to_image (drawable, image,
+                                              dest_x + x0, dest_y + y0,
+                                              xs0, ys0,
+                                              width1, height1);
+                  (*composite_func) (pixbuf->pixels + (src_y + y0) * pixbuf->rowstride + (src_x + x0) * 4,
+                                     pixbuf->rowstride,
+                                     (guchar*)image->mem + ys0 * image->bpl + xs0 * image->bpp,
+                                     image->bpl,
+                                     visual->byte_order,
+                                     width1, height1);
+                  gdk_draw_image (drawable, gc, image,
+                                  xs0, ys0,
+                                  dest_x + x0, dest_y + y0,
+                                  width1, height1);
+                }
+            }
+#else
+          void *data;
+          int   pitch;
+
+          if (impl->surface->Lock( impl->surface, DSLF_READ | DSLF_WRITE, &data, &pitch ) == DFB_OK) {
+               (*composite_func) (pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
+                                  pixbuf->rowstride,
+                                  data + dest_y * pitch + DFB_BYTES_PER_LINE( impl->format, dest_x ),
+                                  pitch,
+                                  visual->byte_order,
+                                  width, height);
+
+               impl->surface->Unlock( impl->surface );
+          }
+#endif          
+          goto out;
+        }
+      else
+        {
+          /* No special composition func, convert dest to 24 bit RGB data, composite against
+           * that, and convert back.
+           */
+          composited = gdk_pixbuf_get_from_drawable (NULL,
+                                                     drawable,
+                                                     NULL,
+                                                     dest_x, dest_y,
+                                                     0, 0,
+                                                     width, height);
+          
+          if (composited)
+            composite (pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
+                       pixbuf->rowstride,
+                       composited->pixels,
+                       composited->rowstride,
+                       width, height);
+        }
+    }
+
+  if (composited)
+    {
+      src_x = 0;
+      src_y = 0;
+      pixbuf = composited;
+    }
+  
+  if (pixbuf->n_channels == 4)
+    {
+      guchar *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4;
+
+      gdk_draw_rgb_32_image_dithalign (drawable, gc,
+                                       dest_x, dest_y,
+                                       width, height,
+                                       dither,
+                                       buf, pixbuf->rowstride,
+                                       x_dither, y_dither);
+    }
+  else                                /* n_channels == 3 */
+    {
+      guchar *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 3;
+
+      gdk_draw_rgb_image_dithalign (drawable, gc,
+                                    dest_x, dest_y,
+                                    width, height,
+                                    dither,
+                                    buf, pixbuf->rowstride,
+                                    x_dither, y_dither);
+    }
+
+ out:
+  if (composited)
+    g_object_unref (composited);
 }
 
 static inline void
@@ -922,6 +1472,21 @@ convert_rgb_pixbuf_to_image (guchar  *sr
 /*
  * Object stuff
  */
+static inline const char *
+drawable_impl_type_name( GObject *object )
+{
+     if (GDK_IS_PIXMAP (object))
+          return "PIXMAP";
+
+     if (GDK_IS_WINDOW (object))
+          return "WINDOW";
+
+     if (GDK_IS_DRAWABLE_IMPL_DIRECTFB (object))
+          return "DRAWABLE";
+
+     return "unknown";
+}
+
 
 static void
 gdk_drawable_impl_directfb_finalize (GObject *object)
@@ -929,6 +1494,11 @@ gdk_drawable_impl_directfb_finalize (GOb
   GdkDrawableImplDirectFB *impl;
   impl = GDK_DRAWABLE_IMPL_DIRECTFB (object);
 
+  D_DEBUG_AT( GDKDFB_Drawable, "%s( %p ) <- %dx%d (%s at %4d,%4d)\n", __FUNCTION__,
+              object, impl->width, impl->height,
+              drawable_impl_type_name( object ),
+              impl->abs_x, impl->abs_y );
+
   gdk_directfb_set_colormap (GDK_DRAWABLE (object), NULL);
   if( impl->cairo_surface ) {
 	cairo_surface_finish(impl->cairo_surface);
@@ -949,7 +1519,7 @@ gdk_drawable_impl_directfb_class_init (G
   object_class->finalize = gdk_drawable_impl_directfb_finalize;
 
   drawable_class->create_gc      = _gdk_directfb_gc_new;
-  drawable_class->draw_rectangle = _gdk_directfb_draw_rectangle;
+  drawable_class->draw_rectangle = gdk_directfb_draw_rectangle;
   drawable_class->draw_arc       = gdk_directfb_draw_arc;
   drawable_class->draw_polygon   = gdk_directfb_draw_polygon;
   drawable_class->draw_text      = gdk_directfb_draw_text;
@@ -976,6 +1546,10 @@ gdk_drawable_impl_directfb_class_init (G
   drawable_class->_copy_to_image = _gdk_directfb_copy_to_image;
         drawable_class->get_screen = gdk_directfb_get_screen;
 
+
+  real_draw_pixbuf = drawable_class->draw_pixbuf;
+  drawable_class->draw_pixbuf = gdk_directfb_draw_pixbuf;
+
   /* check for hardware-accelerated alpha-blending */
   {
     DFBGraphicsDeviceDescription desc;
@@ -1030,27 +1604,39 @@ gdk_directfb_cairo_surface_destroy (void
 static cairo_surface_t *
 gdk_directfb_ref_cairo_surface (GdkDrawable *drawable)
 {
-    g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
-    g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable), NULL);
+  GdkDrawableImplDirectFB *impl;
+  IDirectFB               *dfb;
+  
+  g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
+  g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable), NULL);
 
-    GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
-    IDirectFB *dfb = GDK_DISPLAY_DFB(gdk_drawable_get_display(drawable))->directfb;
-    if (!impl->cairo_surface) {
-//      IDirectFBSurface *surface;
-     // if (impl->surface->GetSubSurface (impl->surface, NULL, &surface) == DFB_OK) {
-        //impl->cairo_surface = cairo_directfb_surface_create (dfb, surface);
-        g_assert( impl->surface != NULL);
-        impl->cairo_surface = cairo_directfb_surface_create (dfb,impl->surface);
-        g_assert( impl->cairo_surface != NULL);
+  impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
+  dfb = GDK_DISPLAY_DFB(gdk_drawable_get_display(drawable))->directfb;
+  
+  if (!impl->cairo_surface) {
+    IDirectFBSurface *surface;
+    g_assert (impl->surface != NULL);
+#if defined(CAIRO_VERSION_CODE) && CAIRO_VERSION_CODE >= CAIRO_VERSION_ENCODE(1,5,5)
+    impl->surface->GetSubSurface (impl->surface, NULL, &surface);
+#else
+    surface = impl->surface;
+#endif
+    if (surface) {
+      impl->cairo_surface = cairo_directfb_surface_create (dfb, surface);
+      if (impl->cairo_surface) {
         cairo_surface_set_user_data (impl->cairo_surface, 
                                      &gdk_directfb_cairo_key, drawable, 
                                      gdk_directfb_cairo_surface_destroy);
-       // surface->Release (surface);
-      //}
-    } else {
-        cairo_surface_reference (impl->cairo_surface);
+      }
+#if defined(CAIRO_VERSION_CODE) && CAIRO_VERSION_CODE >= CAIRO_VERSION_ENCODE(1,5,5)
+      surface->Release (surface);
+#endif
     }
-  g_assert( impl->cairo_surface != NULL);
+  } else {
+    cairo_surface_reference (impl->cairo_surface);
+  }
+  
+  g_assert (impl->cairo_surface != NULL);
   return impl->cairo_surface;
 }
 
diff -puraN gtk+-2.12.9/gdk/directfb/gdkevents-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkevents-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkevents-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkevents-directfb.c	2008-05-21 20:29:35.000000000 +0200
@@ -26,13 +26,15 @@
  * GTK+ DirectFB backend
  * Copyright (C) 2001-2002  convergence integrated media GmbH
  * Copyright (C) 2002-2004  convergence GmbH
- * Written by Denis Oliver Kropp <dok@convergence.de> and
+ * Written by Denis Oliver Kropp <dok@directfb.org> and
  *            Sven Neumann <sven@convergence.de>
  */
 
 #include "config.h"
+
 #include "gdk.h"
 #include "gdkdirectfb.h"
+#include "gdkdirectfb-debug.h"
 #include "gdkprivate-directfb.h"
 
 #include "gdkinternals.h"
@@ -41,6 +43,7 @@
 
 #include "gdkinput-directfb.h"
 #include <string.h>
+#include <unistd.h>
 
 #ifndef __GDK_X_H__
 #define __GDK_X_H__
@@ -53,171 +56,264 @@ gboolean gdk_net_wm_supports (GdkAtom pr
 #define DirectFB _gdk_display->directfb
 
 
+D_DEBUG_DOMAIN( GDKDFB_Events,     "GDKDFB/Events",     "GDK DirectFB Events" );
+D_DEBUG_DOMAIN( GDKDFB_EventCheck, "GDKDFB/EventCheck", "GDK DirectFB Event Checking" );
+D_DEBUG_DOMAIN( GDKDFB_EventTrans, "GDKDFB/EventTrans", "GDK DirectFB Event Translation" );
 
+D_DEBUG_DOMAIN( GDKDFB_Crossing,  "GDKDFB/Crossing",  "GDK DirectFB Crossing" );
+D_DEBUG_DOMAIN( GDKDFB_CrossX,    "GDKDFB/CrossX",    "GDK DirectFB Crossing (actual)" );
 
-#include "gdkaliasdef.c"
-
-/*********************************************
- * Functions for maintaining the event queue *
- *********************************************/
-
-static GdkEvent * gdk_event_translate  (DFBWindowEvent  *dfbevent,
-                                        GdkWindow       *window);
 
-/*
- * Private variable declarations
- */
-static GList *client_filters;  /* Filters for client messages */
+typedef struct _GdkDisplaySource GdkDisplaySource;
 
-static void
-dfb_events_process_window_event (DFBWindowEvent *event)
+struct _GdkDisplaySource
 {
-  GdkWindow *window = gdk_directfb_window_id_table_lookup (event->window_id);
+  GSource     source;
+  
+  GdkDisplay *display;
+  GPollFD     event_poll_fd;
+};
 
-  if (! window)
-     return;
+typedef struct {
+  const DFBWindowEvent    *event;
+  GdkWindow               *window;
+  GdkWindowObject         *private;
+  GdkWindowImplDirectFB   *impl;
+
+  GdkEventType             type;
+  GdkEventMask             mask;
+  gint                     win_x;
+  gint                     win_y;
+  guint                    button;
+} GdkEventFactory;
 
-  gdk_event_translate (event, window);
-}
+/* 
+ * Private function declarations
+ */
 
-static gboolean
-gdk_event_send_client_message_by_window (GdkEvent *event,
-                                        GdkWindow *window)
-{
-  GdkEvent *new_event;
+static gboolean gdk_event_translate (GdkDisplay     *display,
+                                     GdkEvent       *event,
+                                     DFBWindowEvent *dfbevent);
+
+static gboolean gdk_event_prepare  (GSource     *source,
+				    gint        *timeout);
+static gboolean gdk_event_check    (GSource     *source);
+static gboolean gdk_event_dispatch (GSource     *source,
+				    GSourceFunc  callback,
+				    gpointer     user_data);
 
-  g_return_val_if_fail(event != NULL, FALSE);
-  g_return_val_if_fail(GDK_IS_WINDOW(window), FALSE);
+static GSource *gdk_display_source_new (GdkDisplay       *display);
+static gboolean gdk_check_dfb_pending  (GdkDisplaySource *display_source);
 
-  new_event = gdk_directfb_event_make (window, GDK_CLIENT_EVENT);
-  new_event->client.message_type = event->client.message_type;
-  new_event->client.data_format = event->client.data_format;
-  memcpy(&new_event->client.data,
-        &event->client.data,
-        sizeof(event->client.data));
+static gboolean gdk_event_send_client_message_by_window (GdkEvent  *event,
+                                                         GdkWindow *window);
 
-  return TRUE;
-}
+/*
+ * Private variable declarations
+ */
+static GList *display_sources;
 
+static GSourceFuncs event_funcs = {
+  gdk_event_prepare,
+  gdk_event_check,
+  gdk_event_dispatch,
+  NULL
+};
 
-static void
-dfb_events_dispatch (void)
+static GSource *
+gdk_display_source_new (GdkDisplay *display)
 {
-  GdkDisplay *display = gdk_display_get_default ();
-  GdkEvent   *event;
+  GSource          *source         = g_source_new (&event_funcs, sizeof (GdkDisplaySource));
+  GdkDisplaySource *display_source = (GdkDisplaySource *)source;
 
-  while ((event = _gdk_event_unqueue (display)) != NULL)
-    {
-      if (_gdk_event_func)
-        (*_gdk_event_func) (event, _gdk_event_data);
+  D_DEBUG_AT( GDKDFB_Events, "%s( %p )\n", __FUNCTION__, display );
+  
+  display_source->display = display;
 
-      gdk_event_free (event);
-    }
+  return source;
 }
 
 static gboolean
-dfb_events_io_func (GIOChannel   *channel,
-                    GIOCondition  condition,
-                    gpointer      data)
+gdk_check_dfb_pending (GdkDisplaySource *display_source)
 {
-  gsize      i;
-  gsize      read;
-  GIOStatus  result;
-  DFBEvent   buf[23];
-  DFBEvent  *event;
-
-  result = g_io_channel_read_chars (channel,
-                                    (gchar *) buf, sizeof (buf), &read, NULL);
-
-  if (result == G_IO_STATUS_ERROR)
-    {
-      g_warning ("%s: GIOError occured", __FUNCTION__);
-      return TRUE;
-    }
+  D_DEBUG_AT( GDKDFB_EventCheck, "%s( %p )\n", __FUNCTION__, display_source );
 
-  read /= sizeof (DFBEvent);
+  g_return_val_if_fail( display_source != NULL, FALSE );
 
-  for (i = 0, event = buf; i < read; i++, event++)
-    {
-      switch (event->clazz)
-        {
-        case DFEC_WINDOW:
-          /* TODO workaround to prevent two DWET_ENTER in a row from being delivered */
-          if (event->window.type == DWET_ENTER ) {
-            if ( i>0 && buf[i-1].window.type != DWET_ENTER )
-              dfb_events_process_window_event (&event->window);
-          }
-          else
-            dfb_events_process_window_event (&event->window);
-          break;
-        default:
-          break;
-        }
-    }
+  D_DEBUG_AT( GDKDFB_EventCheck, "  -> 0x%02x\n", display_source->event_poll_fd.revents );
 
-  EventBuffer->Reset (EventBuffer);
+  return (display_source->event_poll_fd.revents & G_IO_IN) != 0;
+}
 
-  dfb_events_dispatch ();
 
-  return TRUE;
-}
+/*********************************************
+ * Functions for maintaining the event queue *
+ *********************************************/
 
 void
-_gdk_events_init (void)
+_gdk_events_init (GdkDisplay *display)
 {
-  GIOChannel *channel;
-  GSource    *source;
-  DFBResult   ret;
-  gint        fd;
+  DFBResult         ret;
+  int               fd;
+  GSource          *source;
+  GdkDisplaySource *display_source;
+  GdkDisplayDFB    *display_dfb = GDK_DISPLAY_DFB (display);
+
+  D_DEBUG_AT( GDKDFB_Events, "%s( %p )\n", __FUNCTION__, display );
+
+  /*
+   * The setup of system event handling and local event dispatch is now in line
+   * with the X11 backend to ensure maximum compatibility in a very critical area.
+   *
+   * (2008-01-31 - dok)
+   */
 
+  /* Create an event buffer for this display. */
   ret = DirectFB->CreateEventBuffer (DirectFB, &EventBuffer);
   if (ret)
     {
-      DirectFBError ("_gdk_events_init: "
-                     "IDirectFB::CreateEventBuffer() failed", ret);
+      D_DERROR( ret, "%s(): IDirectFB::CreateEventBuffer() for display %p failed!\n",
+                __FUNCTION__, display );
       return;
     }
 
+  /*
+   * Turn buffer into file descriptor mode which writes a copy of each event to the
+   * file descriptor being our "connection number".
+   */
   ret = EventBuffer->CreateFileDescriptor (EventBuffer, &fd);
   if (ret)
     {
-      DirectFBError ("_gdk_events_init: "
-                     "IDirectFBEventBuffer::CreateFileDescriptor() failed",
-                     ret);
+      D_DERROR( ret, "%s(): IDirectFBEventBuffer::CreateFileDescriptor() for display %p failed!\n",
+                __FUNCTION__, display );
       return;
     }
 
-  channel = g_io_channel_unix_new (fd);
+  source = gdk_display_source_new (display);
 
-  g_io_channel_set_encoding (channel, NULL, NULL);
-  g_io_channel_set_buffered (channel, FALSE);
+  display_dfb->event_fd     = fd;
+  display_dfb->event_source = source;
 
-  source = g_io_create_watch (channel, G_IO_IN);
+  display_source = (GdkDisplaySource*) source;
 
-  g_source_set_priority (source, G_PRIORITY_DEFAULT);
-  g_source_set_can_recurse (source, TRUE);
-  g_source_set_callback (source, (GSourceFunc) dfb_events_io_func, NULL, NULL);
+  display_source->event_poll_fd.fd     = fd;
+  display_source->event_poll_fd.events = G_IO_IN;
 
+  g_source_set_priority (source, GDK_PRIORITY_EVENTS);
+  g_source_add_poll (source, &display_source->event_poll_fd);
+  g_source_set_can_recurse (source, TRUE);
   g_source_attach (source, NULL);
-  g_source_unref (source);
+
+  display_sources = g_list_prepend (display_sources, display_source);
+
+  _gdk_directfb_pointer_window = gdk_window_ref (_gdk_parent_root);
+}
+
+void
+_gdk_events_uninit (GdkDisplay *display)
+{
+  GdkDisplayDFB *display_dfb = GDK_DISPLAY_DFB (display);
+
+  if (display_dfb->event_source)
+    {
+      display_sources = g_list_remove (display_sources,
+                                       display_dfb->event_source);
+      g_source_destroy (display_dfb->event_source);
+      g_source_unref (display_dfb->event_source);
+      display_dfb->event_source = NULL;
+    }
 }
 
+/**
+ * gdk_events_pending:
+ * 
+ * Checks if any events are ready to be processed for any display.
+ * 
+ * Return value:  %TRUE if any events are pending.
+ **/
 gboolean
 gdk_events_pending (void)
 {
-  GdkDisplay *display = gdk_display_get_default ();
+  GList *tmp_list;
+
+  D_DEBUG_AT( GDKDFB_Events, "%s()\n", __FUNCTION__ );
+
+  /*
+   * According to GDK X11's implementation we check the local queue AND the system queue.
+   *
+   * (2008-01-31 - dok)
+   */
+
+  /* Check local queues. */
+  for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next)
+    {
+      GdkDisplaySource *tmp_source = tmp_list->data;
+      GdkDisplay       *display    = tmp_source->display;
+      GList            *tmp_first  = _gdk_event_queue_find_first (display);
+      GdkEvent         *tmp_event  = (GdkEvent*) tmp_first->data;
+
+      if (tmp_event)
+        {
+          D_DEBUG_AT( GDKDFB_Events, "  -> GDK [%d]\n", tmp_event->type );
+          return TRUE;
+        }
+    }
+
+  /* Check DirectFB queues that might contain events not being added to the local queue yet. */
+  for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next)
+    {
+      GdkDisplaySource *tmp_source = tmp_list->data;
+
+      if (gdk_check_dfb_pending (tmp_source))
+        {
+          D_DEBUG_AT( GDKDFB_Events, "  -> DFB []\n" );
+          return TRUE;
+        }
+    }
 
-  return _gdk_event_queue_find_first (display) ? TRUE : FALSE;
+  return FALSE;
 }
 
+/**
+ * gdk_event_get_graphics_expose:
+ * @window: the #GdkWindow to wait for the events for.
+ * 
+ * Waits for a GraphicsExpose or NoExpose event from the X server.
+ * This is used in the #GtkText and #GtkCList widgets in GTK+ to make sure any
+ * GraphicsExpose events are handled before the widget is scrolled.
+ *
+ * Return value:  a #GdkEventExpose if a GraphicsExpose was received, or %NULL if a
+ * NoExpose event was received.
+ **/
 GdkEvent *
 gdk_event_get_graphics_expose (GdkWindow *window)
 {
   GdkDisplay *display;
   GList      *list;
 
+  D_DEBUG_AT( GDKDFB_Events, "%s( %p )\n", __FUNCTION__, window );
+
   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
 
+  /*
+   * GDK X11 calls XIfEvent here which is specified to wait until the
+   * user supplied filter function returns true, which it does for
+   * GraphicsExpose and NoExpose in that case.
+   * 
+   * But neither does DirectFB send any Expose event at any time, nor
+   * do I understand why this function should block the main loop.
+   *
+   * GDK X11 does no checks on the local queues afterwards, but we have
+   * to do it, because GDK DirectFB synthesizes Expose events in some
+   * cases where the X Server would have sent one, e.g. showing a window.
+   *
+   * FIXME: To ensure correct order of events we need to add a queue for
+   * synthesized (expose) events or use the DirectFB event buffer with a
+   * user event (or universal event) to IDirectFBEventBuffer::PostEvent().
+   *
+   * (2008-01-31 - dok)
+   */
+
   display = gdk_drawable_get_display (GDK_DRAWABLE (window));
 
   for (list = _gdk_event_queue_find_first (display); list; list = list->next)
@@ -243,26 +339,175 @@ gdk_event_get_graphics_expose (GdkWindow
 void
 _gdk_events_queue (GdkDisplay *display)
 {
+  int               ret;
+  GList            *node;
+  GdkEvent         *event;
+  DFBEvent          dfbevent;
+  GdkDisplayDFB    *display_dfb    = GDK_DISPLAY_DFB (display);
+  GdkDisplaySource *display_source = (GdkDisplaySource*) display_dfb->event_source;
+
+  /*
+   * GDK X11 does not process all events here, just until one got into the local queue.
+   */
+
+  while (!_gdk_event_queue_find_first (display) && gdk_check_dfb_pending (display_source))
+    {
+      /* Read ONE event from the DirectFB queue. */
+      ret = read (display_dfb->event_fd, &dfbevent, sizeof(dfbevent));
+      if (ret <= 0)
+        {
+          D_PERROR ("%s: Failed to read from event file descriptor!\n", __FUNCTION__);
+          return;
+        }
+
+      /* Only window events are handled and no others should arrive. */
+      if (dfbevent.clazz != DFEC_WINDOW)
+        {
+          g_warning ("%s: Got event of class %d other than DFEC_WINDOW!\n",
+                     __FUNCTION__, dfbevent.clazz);
+          continue;
+        }
+
+      event = gdk_event_new (GDK_NOTHING);
+
+      event->any.window     = NULL;
+      event->any.send_event = FALSE;  /* We don't use PostEvent() so far. */
+
+      ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
+
+      node = _gdk_event_queue_append (display, event);
+
+      if (gdk_event_translate (display, event, &dfbevent.window))
+        {
+          ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
+        }
+      else
+        {
+          _gdk_event_queue_remove_link (display, node);
+          g_list_free_1 (node);
+          gdk_event_free (event);
+        }
+    }
+}
+
+/**********************************************************************************************************************/
+
+static gboolean  
+gdk_event_prepare (GSource  *source,
+		   gint     *timeout)
+{
+  gboolean          retval;
+  GdkDisplaySource *display_source = (GdkDisplaySource*)source;
+  GdkDisplay       *display        = display_source->display;
+  
+  GDK_THREADS_ENTER ();
+
+  *timeout = -1;
+  retval = _gdk_event_queue_find_first (display) != NULL || gdk_check_dfb_pending (display_source);
+  
+  GDK_THREADS_LEAVE ();
+
+  return retval;
+}
+
+static gboolean  
+gdk_event_check (GSource *source) 
+{
+  gboolean          retval;
+  GdkDisplaySource *display_source = (GdkDisplaySource*)source;
+  GdkDisplay       *display        = display_source->display;
+
+  GDK_THREADS_ENTER ();
+
+  if (display_source->event_poll_fd.revents & G_IO_IN)
+    retval = _gdk_event_queue_find_first (display) != NULL || gdk_check_dfb_pending (display_source);
+  else
+    retval = FALSE;
+
+  GDK_THREADS_LEAVE ();
+
+  return retval;
+}
+
+static gboolean  
+gdk_event_dispatch (GSource    *source,
+		    GSourceFunc callback,
+		    gpointer    user_data)
+{
+  GdkDisplay *display = ((GdkDisplaySource*)source)->display;
+  GdkEvent   *event;
+ 
+  GDK_THREADS_ENTER ();
+
+  _gdk_events_queue (display);
+  event = _gdk_event_unqueue (display);
+
+  if (event)
+    {
+      if (_gdk_event_func)
+        (*_gdk_event_func) (event, _gdk_event_data);
+      
+      gdk_event_free (event);
+    }
+  
+  GDK_THREADS_LEAVE ();
+
+  return TRUE;
 }
 
+/**********************************************************************************************************************/
+
+/*
+ *--------------------------------------------------------------
+ * gdk_flush
+ *
+ *   Flushes the Xlib output buffer and then waits
+ *   until all requests have been received and processed
+ *   by the X server. The only real use for this function
+ *   is in dealing with XShm.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
 void
 gdk_flush (void)
 {
-gdk_display_flush ( GDK_DISPLAY_OBJECT(_gdk_display));
+  GSList *tmp_list = _gdk_displays;
+  
+  while (tmp_list)
+    {
+      IDirectFB *dfb = GDK_DISPLAY_DFB (tmp_list->data)->directfb;
+
+      g_assert (dfb != NULL);
+
+      dfb->WaitIdle (dfb);
+
+      tmp_list = tmp_list->next;
+    }
 }
 
 /* Sends a ClientMessage to all toplevel client windows */
 gboolean
-gdk_event_send_client_message_for_display (GdkDisplay *display,
-                                           GdkEvent   *event,
-                                           guint32     xid)
+gdk_event_send_client_message_for_display (GdkDisplay      *display,
+                                           GdkEvent        *event,
+                                           GdkNativeWindow  winid)
 {
-  GdkWindow *win = NULL;
-  gboolean ret = TRUE;
+  GdkWindow *win;
+  gboolean   ret = FALSE;
+
+  /*
+   * The event should go through the system event queue using IDirectFBEventBuffer::PostEvent().
+   */
 
   g_return_val_if_fail(event != NULL, FALSE);
 
-  win = gdk_window_lookup_for_display (display, (GdkNativeWindow) xid);
+  win = gdk_window_lookup_for_display (display, winid);
 
   g_return_val_if_fail(win != NULL, FALSE);
 
@@ -279,14 +524,12 @@ gdk_event_send_client_message_for_displa
     }
   else
     {
-      ret &= gdk_event_send_client_message_by_window (event, win);
+      ret = gdk_event_send_client_message_by_window (event, win);
     }
 
   return ret;
 }
 
-/*****/
-
 guint32
 gdk_directfb_get_time (void)
 {
@@ -365,422 +608,1261 @@ gdk_directfb_child_at (GdkWindow *window
   return window;
 }
 
-static GdkEvent *
-gdk_event_translate (DFBWindowEvent *dfbevent,
-                     GdkWindow      *window)
+/**********************************************************************************************************************/
+
+static gboolean
+gdk_event_send_client_message_by_window (GdkEvent  *event,
+                                         GdkWindow *window)
 {
-  GdkWindowObject *private;
-  GdkDisplay      *display;
-  GdkEvent        *event    = NULL;
+  GdkEvent *new_event;
 
-  g_return_val_if_fail (dfbevent != NULL, NULL);
-  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+  g_return_val_if_fail(event != NULL, FALSE);
+  g_return_val_if_fail(GDK_IS_WINDOW(window), FALSE);
 
-  private = GDK_WINDOW_OBJECT (window);
+  /* FIXME: Use the system queue to post events so they come in the correct order. */
+  D_ONCE("bad function");
 
-  g_object_ref (G_OBJECT (window));
-  display = gdk_drawable_get_display (GDK_DRAWABLE (window));
+  new_event = gdk_directfb_event_make (window, GDK_CLIENT_EVENT);
+  new_event->client.message_type = event->client.message_type;
+  new_event->client.data_format = event->client.data_format;
+  memcpy(&new_event->client.data,
+        &event->client.data,
+        sizeof(event->client.data));
 
-  switch (dfbevent->type)
+  return TRUE;
+}
+
+static gint
+gdk_event_apply_filters (DFBWindowEvent *dfbevent,
+			 GdkEvent       *event,
+			 GList          *filters)
+{
+  GList *tmp_list;
+  GdkFilterReturn result;
+  
+  tmp_list = filters;
+  
+  while (tmp_list)
     {
-    case DWET_BUTTONDOWN:
-    case DWET_BUTTONUP:
-      {
-        static gboolean  click_grab = FALSE;
-        GdkWindow       *child;
-        gint             wx, wy;
-        guint            mask;
-        guint            button;
+      GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data;
+      
+      tmp_list = tmp_list->next;
+      result = filter->function (dfbevent, event, filter->data);
+      if (result !=  GDK_FILTER_CONTINUE)
+        return result;
+    }
+  
+  return GDK_FILTER_CONTINUE;
+}
 
-        _gdk_directfb_mouse_x = wx = dfbevent->cx;
-        _gdk_directfb_mouse_y = wy = dfbevent->cy;
+/**********************************************************************************************************************/
 
-        switch (dfbevent->button)
-          {
-          case DIBI_LEFT:
-            button = 1;
-            mask   = GDK_BUTTON1_MASK;
-            break;
-          case DIBI_MIDDLE:
-            button = 2;
-            mask   = GDK_BUTTON2_MASK;
-            break;
-          case DIBI_RIGHT:
-            button = 3;
-            mask   = GDK_BUTTON3_MASK;
-            break;
-          default:
-            button = dfbevent->button + 1;
-            mask   = 0;
-            break;
-          }
+/* Update mouse window */
+void
+_gdk_directfb_events_update_mouse_window (GdkWindow *window)
+{
+  if (window == _gdk_directfb_pointer_window)
+    return;
 
-        child = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
+  if (window)
+    g_object_ref (window);
+  if (_gdk_directfb_pointer_window)
+    g_object_unref (_gdk_directfb_pointer_window);
 
-        if (_gdk_directfb_pointer_grab_window &&
-            (_gdk_directfb_pointer_grab_events & (dfbevent->type ==
-                                                  DWET_BUTTONDOWN ?
-                                                  GDK_BUTTON_PRESS_MASK :
-                                                  GDK_BUTTON_RELEASE_MASK)) &&
-            (_gdk_directfb_pointer_grab_owner_events == FALSE ||
-             child == _gdk_parent_root) )
-          {
-            GdkDrawableImplDirectFB *impl;
+  _gdk_directfb_pointer_window = window;
+}
 
-            child = _gdk_directfb_pointer_grab_window;
-            impl  = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (child)->impl);
+/* Update current cursor */
+void
+_gdk_directfb_events_update_cursor (GdkWindow *window)
+{
+  static GdkCursorDirectFB *last_cursor = NULL;
 
-            dfbevent->x = dfbevent->cx - impl->abs_x;
-            dfbevent->y = dfbevent->cy - impl->abs_y;
-          }
-        else if (!_gdk_directfb_pointer_grab_window ||
-                 (_gdk_directfb_pointer_grab_owner_events == TRUE))
-          {
-            dfbevent->x = wx;
-            dfbevent->y = wy;
-          }
-        else
-          {
-            child = NULL;
-          }
+  GdkWindowObject       *private = GDK_WINDOW_OBJECT (window);
+  GdkWindowImplDirectFB *impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
+  GdkCursorDirectFB     *cursor;
 
-        if (dfbevent->type == DWET_BUTTONDOWN)
-          _gdk_directfb_modifiers |= mask;
-        else
-          _gdk_directfb_modifiers &= ~mask;
+  if (_gdk_directfb_pointer_grab_cursor)
+    cursor = (GdkCursorDirectFB*) _gdk_directfb_pointer_grab_cursor;
+  else
+    cursor = (GdkCursorDirectFB*) impl->cursor;
 
-        if (child)
-          {
-            event =
-              gdk_directfb_event_make (child,
-                                       dfbevent->type == DWET_BUTTONDOWN ?
-                                       GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
-
-            event->button.x_root = _gdk_directfb_mouse_x;
-            event->button.y_root = _gdk_directfb_mouse_y;
-
-            event->button.x = dfbevent->x;
-            event->button.y = dfbevent->y;
-
-            event->button.state  = _gdk_directfb_modifiers;
-            event->button.button = button;
-            event->button.device = display->core_pointer;
-
-            GDK_NOTE (EVENTS,
-                      g_message ("button: %d at %d,%d %s with state 0x%08x",
-                                 event->button.button,
-                                 (int)event->button.x, (int)event->button.y,
-                                 dfbevent->type == DWET_BUTTONDOWN ?
-                                 "pressed" : "released",
-                                 _gdk_directfb_modifiers));
+  if (cursor != last_cursor)
+    {
+      window  = gdk_directfb_window_find_toplevel (window);
+      private = GDK_WINDOW_OBJECT (window);
+      impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
+
+      if (impl->window)
+        impl->window->SetCursorShape (impl->window,
+                                      cursor->shape,
+                                      cursor->hot_x, cursor->hot_y);
+      last_cursor = cursor;
+    }
+}
 
-            if (dfbevent->type == DWET_BUTTONDOWN)
-              _gdk_event_button_generate (display, event);
-          }
+/**********************************************************************************************************************/
 
-        /* Handle implicit button grabs: */
-        if (dfbevent->type == DWET_BUTTONDOWN  &&  !click_grab  &&  child)
-          {
-            if (gdk_directfb_pointer_grab (child, FALSE,
-                                           gdk_window_get_events (child),
-                                           NULL, NULL,
-                                           GDK_CURRENT_TIME,
-                                           TRUE) == GDK_GRAB_SUCCESS)
-              click_grab = TRUE;
-          }
-        else if (dfbevent->type == DWET_BUTTONUP &&
-                 !(_gdk_directfb_modifiers & (GDK_BUTTON1_MASK |
-                                              GDK_BUTTON2_MASK |
-                                              GDK_BUTTON3_MASK)) && click_grab)
-          {
-            gdk_directfb_pointer_ungrab (GDK_CURRENT_TIME, TRUE);
-            click_grab = FALSE;
-          }
-      }
-      break;
+/* Return an event mask from a DFBWindowEvent */
+static GdkEventMask
+get_event_mask_from_dfb_event (const DFBWindowEvent *dfbevent)
+{
+  GdkEventMask mask;
 
-    case DWET_MOTION:
-      {
-        GdkWindow *event_win=NULL;
-        GdkWindow *child;
+  switch (dfbevent->type)
+    {
+    case DWET_BUTTONDOWN:
+      return GDK_BUTTON_PRESS_MASK;
 
-        _gdk_directfb_mouse_x = dfbevent->cx;
-        _gdk_directfb_mouse_y = dfbevent->cy;
+    case DWET_BUTTONUP:
+      return GDK_BUTTON_RELEASE_MASK;
 
-	//child = gdk_directfb_child_at (window, &dfbevent->x, &dfbevent->y);
-    /* Go all the way to root to catch popup menus */
-    int wx=_gdk_directfb_mouse_x;
-    int wy=_gdk_directfb_mouse_y;
-	child = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
-
-    /* first let's see if any cossing event has to be send */
-    gdk_directfb_window_send_crossing_events (NULL, child, GDK_CROSSING_NORMAL);
-
-    /* then dispatch the motion event to the window the cursor it's inside */
-	event_win = gdk_directfb_pointer_event_window (child, GDK_MOTION_NOTIFY);
-
-
-	if (event_win)
-	  {
-
-	    if (event_win == _gdk_directfb_pointer_grab_window) {
-		GdkDrawableImplDirectFB *impl;
-
-		child = _gdk_directfb_pointer_grab_window;
-		impl = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (child)->impl);
-
-		dfbevent->x = _gdk_directfb_mouse_x - impl->abs_x;
-		dfbevent->y = _gdk_directfb_mouse_y - impl->abs_y;
-	      }
-
-	    event = gdk_directfb_event_make (child, GDK_MOTION_NOTIFY);
-
-	    event->motion.x_root = _gdk_directfb_mouse_x;
-	    event->motion.y_root = _gdk_directfb_mouse_y;
-
-	    //event->motion.x = dfbevent->x;
-	    //event->motion.y = dfbevent->y;
-	    event->motion.x = wx;
-	    event->motion.y = wy;
-
-	    event->motion.state   = _gdk_directfb_modifiers;
-	    event->motion.is_hint = FALSE;
-	    event->motion.device  = display->core_pointer;
-
-	    if (GDK_WINDOW_OBJECT (event_win)->event_mask &
-		GDK_POINTER_MOTION_HINT_MASK)
-	      {
-		while (EventBuffer->PeekEvent (EventBuffer,
-					       DFB_EVENT (dfbevent)) == DFB_OK
-		       && dfbevent->type == DWET_MOTION)
-		  {
-		    EventBuffer->GetEvent (EventBuffer, DFB_EVENT (dfbevent));
-		    event->motion.is_hint = TRUE;
-		  }
-	      }
-	  }
-          /* make sure crossing events go to the event window found */
-/*        GdkWindow *ev_win = ( event_win == NULL ) ? gdk_window_at_pointer (NULL,NULL) :event_win;
-	     gdk_directfb_window_send_crossing_events (NULL,ev_win,GDK_CROSSING_NORMAL);
-*/
-      }
-      break;
+    case DWET_MOTION:
+      mask = GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK;
 
-    case DWET_GOTFOCUS:
-      gdk_directfb_change_focus (window);
+      if (dfbevent->buttons & DIBM_LEFT)
+        {
+          mask |= GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
+                  GDK_BUTTON_MOTION_MASK  | GDK_BUTTON1_MOTION_MASK      | 
+                  GDK_BUTTON1_MASK;
+        }
+      if (dfbevent->buttons & DIBM_RIGHT)
+        {
+          mask |= GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
+                  GDK_BUTTON_MOTION_MASK  | GDK_BUTTON3_MOTION_MASK      | 
+                  GDK_BUTTON3_MASK;
+        }
+      if (dfbevent->buttons & DIBM_MIDDLE)
+        {
+          mask |= GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
+                  GDK_BUTTON_MOTION_MASK  | GDK_BUTTON2_MOTION_MASK      | 
+                  GDK_BUTTON2_MASK;
+        }
+      return mask;
 
-      break;
+    case DWET_WHEEL:
+      /* Since applications that want button press events can get
+       * scroll events on X11 (since scroll wheel events are really
+       * button press events there), we need to use GDK_BUTTON_PRESS_MASK too.
+       */
+      return GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK;
 
-    case DWET_LOSTFOCUS:
-      gdk_directfb_change_focus (_gdk_parent_root);
+    case DWET_KEYDOWN:
+      return GDK_KEY_PRESS_MASK;
 
-      break;
+    case DWET_KEYUP:
+      return GDK_KEY_RELEASE_MASK;
 
+    case DWET_CLOSE:
+    case DWET_DESTROYED:
+    case DWET_SIZE:
     case DWET_POSITION:
-      {
-        GdkWindow *event_win;
+    case DWET_POSITION_SIZE:
+      return GDK_STRUCTURE_MASK;
 
-        private->x = dfbevent->x;
-        private->y = dfbevent->y;
+    case DWET_ENTER:
+      return GDK_ENTER_NOTIFY_MASK;
 
-        event_win = gdk_directfb_other_event_window (window, GDK_CONFIGURE);
+    case DWET_LEAVE:
+      return GDK_LEAVE_NOTIFY_MASK;
 
-        if (event_win)
-          {
-            event = gdk_directfb_event_make (event_win, GDK_CONFIGURE);
-            event->configure.x = dfbevent->x;
-            event->configure.y = dfbevent->y;
-            event->configure.width =
-              GDK_DRAWABLE_IMPL_DIRECTFB (private->impl)->width;
-            event->configure.height =
-              GDK_DRAWABLE_IMPL_DIRECTFB (private->impl)->height;
-          }
+    case DWET_GOTFOCUS:
+    case DWET_LOSTFOCUS:
+      return GDK_FOCUS_CHANGE_MASK;
 
-        _gdk_directfb_calc_abs (window);
-      }
-      break;
+    default:
+      D_WARN( "DFBWindowEventType 0x%08x unknown", dfbevent->type );
+    }
 
-    case DWET_POSITION_SIZE:
-      private->x = dfbevent->x;
-      private->y = dfbevent->y;
-      /* fallthru */
+  return GDK_ALL_EVENTS_MASK;
+}
+			 
+gboolean
+gdk_directfb_window_is_ancestor (GdkWindow *ancestor,
+                                 GdkWindow *window)
+{
+  if (ancestor == NULL || window == NULL)
+    return FALSE;
 
-    case DWET_SIZE:
-      {
-        GdkDrawableImplDirectFB *impl;
-        GdkWindow               *event_win;
-        GList                   *list;
+  return (gdk_window_get_parent (window) == ancestor ||
+          gdk_directfb_window_is_ancestor (ancestor, 
+                                           gdk_window_get_parent (window)));
+}
 
-        impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
+static void
+fixup_event (GdkEvent *event)
+{
+  if (event->any.window)
+    g_object_ref (event->any.window);
+  if (((event->any.type == GDK_ENTER_NOTIFY) ||
+       (event->any.type == GDK_LEAVE_NOTIFY)) &&
+      (event->crossing.subwindow != NULL))
+    g_object_ref (event->crossing.subwindow);
+  event->any.send_event = FALSE;
+}
 
-        event_win = gdk_directfb_other_event_window (window, GDK_CONFIGURE);
+static void
+append_event (GdkEvent *event)
+{
+  fixup_event (event);
+  _gdk_event_queue_append (GDK_DISPLAY_OBJECT(_gdk_display), event);
+}
 
-        if (event_win)
-          {
-            event = gdk_directfb_event_make (event_win, GDK_CONFIGURE);
-            event->configure.x      = private->x;
-            event->configure.y      = private->y;
-            event->configure.width  = dfbevent->w;
-            event->configure.height = dfbevent->h;
-          }
+/* FIXME: Refactor and share with scroll event. */
+static GdkEvent *
+create_crossing_event (GdkWindow            *window, 
+		       const DFBWindowEvent *dfbevent, 
+		       GdkEventType          event_type,
+		       GdkCrossingMode       mode, 
+		       GdkNotifyType         detail)
+{
+  GdkEvent *event;
+  GdkWindowImplDirectFB *impl;
 
-        impl->width  = dfbevent->w;
-        impl->height = dfbevent->h;
+  impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
 
-        for (list = private->children; list; list = list->next)
-          {
-            GdkWindowObject         *win;
-            GdkDrawableImplDirectFB *impl;
+  D_DEBUG_AT( GDKDFB_CrossX, "-> %s [" GDKDFB_WIMPL_FORM "]\n",
+              event_type == GDK_ENTER_NOTIFY ? "ENTER" :
+              event_type == GDK_LEAVE_NOTIFY ? "LEAVE" : "<unknown crossing>",
+              GDKDFB_WIMPL_V(impl) );
 
-            win  = GDK_WINDOW_OBJECT (list->data);
-            impl = GDK_DRAWABLE_IMPL_DIRECTFB (win->impl);
+  event = gdk_event_new (event_type);
 
-            _gdk_directfb_move_resize_child (GDK_WINDOW (win),
-                                             win->x, win->y,
-                                             impl->width, impl->height);
-          }
+  event->crossing.window = window;
+  event->crossing.subwindow = NULL; /* FIXME */
+  event->crossing.time = (guint32)(dfbevent->timestamp.tv_sec * 1000 + dfbevent->timestamp.tv_usec / 1000);
 
-        _gdk_directfb_calc_abs (window);
+  event->crossing.x = dfbevent->cx - impl->drawable.abs_x;
+  event->crossing.y = dfbevent->cy - impl->drawable.abs_y;
+
+  event->crossing.x_root = dfbevent->cx;
+  event->crossing.y_root = dfbevent->cy;
+
+  event->crossing.mode = mode;
+  event->crossing.detail = detail;
+  event->crossing.state = _gdk_directfb_modifiers;
+
+  /* FIXME: focus and button state */
+
+  if (event_type == GDK_ENTER_NOTIFY)
+    {
+      GDK_NOTE (EVENTS,
+                g_message ("enter notify:\t\twindow: %p  detail: %d subwin: %p",
+                           event->crossing.window,
+                           event->crossing.detail,
+                           event->crossing.subwindow));
+    }
+  else
+    GDK_NOTE (EVENTS,
+              g_message ("leave notify:\t\twindow: %p  detail: %d subwin: %p",
+                         event->crossing.window,
+                         event->crossing.detail,
+                         event->crossing.subwindow));
+
+  return event;
+}
+
+static void
+synthesize_enter_event (GdkWindow            *window,
+			const DFBWindowEvent *dfbevent,
+			GdkCrossingMode       mode,
+			GdkNotifyType         detail)
+{
+  GdkEvent *event;
+
+  if (_gdk_directfb_pointer_grab_window != NULL && 
+      !_gdk_directfb_pointer_grab_owner_events && 
+      !(_gdk_directfb_pointer_grab_events & GDK_ENTER_NOTIFY_MASK))
+    return;
+
+  if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_ENTER_NOTIFY_MASK))
+    return;
+
+  event = create_crossing_event (window, dfbevent, GDK_ENTER_NOTIFY, mode, detail);
+
+  append_event (event);
+}
+  
+static void
+synthesize_enter_events (GdkWindow            *from,
+			 GdkWindow            *to,
+			 const DFBWindowEvent *dfbevent,
+			 GdkCrossingMode       mode,
+			 GdkNotifyType         detail)
+{
+  GdkWindow *prev = gdk_window_get_parent (to);
+
+  if (prev != from)
+    synthesize_enter_events (from, prev, dfbevent, mode, detail);
+
+  synthesize_enter_event (to, dfbevent, mode, detail);
+}
+
+static void
+synthesize_leave_event (GdkWindow            *window,
+			const DFBWindowEvent *dfbevent,
+			GdkCrossingMode       mode,
+			GdkNotifyType         detail)
+{
+  GdkEvent *event;
+
+  if (_gdk_directfb_pointer_grab_window != NULL && 
+      !_gdk_directfb_pointer_grab_owner_events && 
+      !(_gdk_directfb_pointer_grab_events & GDK_LEAVE_NOTIFY_MASK))
+    return;
+
+  if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
+    return;
+
+  event = create_crossing_event (window, dfbevent, GDK_LEAVE_NOTIFY, mode, detail);
+
+  append_event (event);
+}
+			 
+static void
+synthesize_leave_events (GdkWindow            *from,
+			 GdkWindow            *to,
+			 const DFBWindowEvent *dfbevent,
+			 GdkCrossingMode       mode,
+			 GdkNotifyType	       detail)
+{
+  GdkWindow *next = gdk_window_get_parent (from);
+  
+  synthesize_leave_event (from, dfbevent, mode, detail);
+
+  if (next != to)
+    synthesize_leave_events (next, to, dfbevent, mode, detail);
+}
+
+static void
+synthesize_crossing_events (GdkEventFactory *factory,
+                            GdkWindow       *window,
+			    GdkCrossingMode  mode,
+			    gint             x,
+			    gint             y)
+{
+  GdkWindow *intermediate, *tem, *common_ancestor;
+
+  if (window == _gdk_directfb_pointer_window)
+    return;
+
+  if (gdk_directfb_window_is_ancestor (_gdk_directfb_pointer_window, window))
+    {
+      /* Pointer has moved to an inferior window. */
+      synthesize_leave_event (_gdk_directfb_pointer_window, factory->event, mode, GDK_NOTIFY_INFERIOR);
+
+      /* If there are intermediate windows, generate ENTER_NOTIFY
+       * events for them
+       */
+      intermediate = gdk_window_get_parent (window);
+
+      if (intermediate != _gdk_directfb_pointer_window)
+	{
+	  synthesize_enter_events (_gdk_directfb_pointer_window, intermediate, factory->event, mode, GDK_NOTIFY_VIRTUAL);
+	}
+
+      synthesize_enter_event (window, factory->event, mode, GDK_NOTIFY_ANCESTOR);
+    }
+  else if (gdk_directfb_window_is_ancestor (window, _gdk_directfb_pointer_window))
+    {
+      /* Pointer has moved to an ancestor window. */
+      synthesize_leave_event (_gdk_directfb_pointer_window, factory->event, mode, GDK_NOTIFY_ANCESTOR);
+      
+      /* If there are intermediate windows, generate LEAVE_NOTIFY
+       * events for them
+       */
+      intermediate = gdk_window_get_parent (_gdk_directfb_pointer_window);
+      if (intermediate != window)
+	{
+	  synthesize_leave_events (intermediate, window, factory->event, mode, GDK_NOTIFY_VIRTUAL);
+	}
+
+      synthesize_enter_event (window, factory->event, mode, GDK_NOTIFY_INFERIOR);
+    }
+  else if (_gdk_directfb_pointer_window)
+    {
+      /* Find least common ancestor of _gdk_directfb_pointer_window and window */
+      tem = _gdk_directfb_pointer_window;
+      do {
+	common_ancestor = gdk_window_get_parent (tem);
+	tem = common_ancestor;
+      } while (common_ancestor &&
+	       !gdk_directfb_window_is_ancestor (common_ancestor, window));
+      if (common_ancestor)
+	{
+	  synthesize_leave_event (_gdk_directfb_pointer_window, factory->event, mode, GDK_NOTIFY_NONLINEAR);
+	  intermediate = gdk_window_get_parent (_gdk_directfb_pointer_window);
+	  if (intermediate != common_ancestor)
+	    {
+	      synthesize_leave_events (intermediate, common_ancestor,
+				       factory->event, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
+	    }
+	  intermediate = gdk_window_get_parent (window);
+	  if (intermediate != common_ancestor)
+	    {
+	      synthesize_enter_events (common_ancestor, intermediate,
+				       factory->event, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
+	    }
+	  synthesize_enter_event (window, factory->event, mode, GDK_NOTIFY_NONLINEAR);
+	}
+    }
+  else
+    {
+      /* This means we have no _gdk_directfb_pointer_window, which probably
+       * means that there is a bug somewhere, we should always have
+       * the root in we don't have another window. Does this ever
+       * happen?
+       */
+      g_warning ("Trying to create crossing event when _gdk_directfb_pointer_window is NULL");
+    }
+
+  _gdk_directfb_events_update_mouse_window (window);
+
+  /* FIXME: This does't work when someone calls gdk_window_set_cursor
+   * during a grab. The right behavior is that the cursor doesn't
+   * change when a grab is in effect, but in that case it does.
+   */
+  if (window && !_gdk_directfb_pointer_grab_window)
+    _gdk_directfb_events_update_cursor (window);
+}
+
+/* Synthesizes crossing events if necessary, based on the passed in
+ * DFBEvent. Uses DWET_ENTER and DWET_LEAVE for toplevels and
+ * the mouse moved/dragged events for child windows, to see if the
+ * mouse window has changed.
+ */
+static void
+factory_synthesize_crossing (GdkEventFactory *factory)
+{
+  GdkWindow *mouse_window;
+  gint x;
+  gint y;
+
+  switch (factory->event->type)
+    {
+    case DWET_MOTION:
+      /* We only handle moving the pointer to another GDK window.
+       * Leaving to a non-GDK toplevel window (or window title bar or
+       * the desktop) is covered by NSMouseExited events.
+       */
+      x = factory->event->cx; 
+      y = factory->event->cy;
+      mouse_window = gdk_directfb_child_at (_gdk_parent_root, &x, &y);
+      if (mouse_window != _gdk_parent_root)
+        synthesize_crossing_events (factory, mouse_window, GDK_CROSSING_NORMAL, x, y);
 
-        gdk_window_clear (window);
-        gdk_window_invalidate_rect (window, NULL, TRUE);
-      }
       break;
 
-    case DWET_KEYDOWN:
-    case DWET_KEYUP:
+    case DWET_ENTER:
       {
+	GdkWindow *event_toplevel;
+        GdkWindowImplDirectFB *impl;
+
+        /* This is the only case where we actually use the window from
+         * the event since we need to know which toplevel we entered
+         * so it can be tracked properly.
+         */
+        event_toplevel = factory->window;
+        impl = factory->impl;
 
-        GdkEventType type = (dfbevent->type == DWET_KEYUP ?
-                             GDK_KEY_RELEASE : GDK_KEY_PRESS);
-        GdkWindow *event_win =
-          gdk_directfb_keyboard_event_window (gdk_directfb_window_find_focus (),
-                                              type);
-        if (event_win)
+        x = factory->win_x; 
+        y = factory->win_y;
+
+        mouse_window = gdk_directfb_child_at (event_toplevel, &x, &y);
+
+        /* Treat unknown windows (like the title bar buttons or
+         * desktop) as the root window.
+         */
+        if (!mouse_window)
           {
-            event = gdk_directfb_event_make (event_win, type);
-            gdk_directfb_translate_key_event (dfbevent, &event->key);
+            x = factory->event->cx; 
+            y = factory->event->cy;
+            mouse_window = _gdk_parent_root;
           }
+
+        synthesize_crossing_events (factory, mouse_window, GDK_CROSSING_NORMAL, x, y);
       }
       break;
 
     case DWET_LEAVE:
+      {
+	GdkWindow *event_toplevel;
+        GdkWindowImplDirectFB *impl;
+
+        /* We only use NSMouseExited when leaving to the root
+         * window. The other cases are handled above by checking the
+         * motion/button events, or getting a NSMouseEntered for
+         * another GDK window. The reason we don't use NSMouseExited
+         * for other windows is that quartz first delivers the entered
+         * event and then the exited which is the opposite from what
+         * we need.
+         */
+        event_toplevel = factory->window;
+        impl = factory->impl;
+
+        x = factory->event->cx; 
+        y = factory->event->cy;
+
+        /* If there is a window other than the root window at this
+         * position, it means we didn't exit to the root window and we
+         * ignore the event. (Note that we can get NULL here when swithing
+         * spaces for example.)
+         *
+         * FIXME: This is not enough, it doesn't catch the case where
+         * we leave a GDK window to a non-GDK window that has GDK
+         * windows below it.
+         */
+        mouse_window = gdk_directfb_child_at (event_toplevel, &x, &y);
+
+        if (!mouse_window ||
+            gdk_directfb_window_find_toplevel (mouse_window) ==
+            gdk_directfb_window_find_toplevel (_gdk_directfb_pointer_window))
+          {
+            mouse_window = _gdk_parent_root;
+          }
+
+        if (mouse_window == _gdk_parent_root)
+          synthesize_crossing_events (factory, _gdk_parent_root, GDK_CROSSING_NORMAL, x, y);
+      }
+      break;
+
+    default:
+      break;
+    }
+}
+
+/**********************************************************************************************************************/
+
+/* Checks if the passed in window is interested in the event mask, and
+ * if so, it's returned. If not, the event can be propagated through
+ * its ancestors until one with the right event mask is found, up to
+ * the nearest toplevel.
+ */
+static GdkWindow *
+find_window_interested_in_event_mask (GdkWindow    *window, 
+				      GdkEventMask  event_mask,
+				      gboolean      propagate)
+{
+  GdkWindowObject *private;
+
+  private = GDK_WINDOW_OBJECT (window);
+  while (private)
+    {
+      if (private->event_mask & event_mask)
+	return (GdkWindow *)private;
+
+      if (!propagate)
+	return NULL;
+
+      /* Don't traverse beyond toplevels. */
+      if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD)
+	break;
+
+      private = private->parent;
+    }
+
+  return NULL;
+}
+
+/*
+ * Main part of adaption, may synthesize some events, will determine actual window to which the event should be sent.
+ */
+static gboolean
+factory_process (GdkEventFactory  *factory,
+                 GdkWindow       **ret_event_window,
+                 GdkWindow       **ret_filter_window)
+{
+  int                      wx, wy;
+  const DFBWindowEvent    *dfbevent;
+  GdkWindow               *event_window;
+  GdkWindow               *filter_window;
+  guint                    mask;
+  guint                    button;
+
+  g_return_val_if_fail (factory != NULL, FALSE);
+  g_return_val_if_fail (factory->event != NULL, FALSE);
+  g_return_val_if_fail (GDK_IS_WINDOW(factory->window), FALSE);
+
+  /* Initialize with root window coords. */
+  dfbevent = factory->event;
+  wx       = dfbevent->cx;
+  wy       = dfbevent->cy;
+
+  /* Start with original window. */
+  event_window = factory->window;
+
+  /* We always run the filters for the window where the event
+   * is delivered, not the window that it relates to
+   */
+  filter_window = factory->window;
+
+  /* Generate event mask from type, buttons etc. */
+  factory->mask = get_event_mask_from_dfb_event (dfbevent);
+
+  D_DEBUG_AT( GDKDFB_EventTrans, "  -> event mask    0x%08x\n", factory->mask );
+
+  /* Check event types. */
+  switch (dfbevent->type)
+    {
+    case DWET_BUTTONDOWN:
+    case DWET_BUTTONUP:
+    case DWET_MOTION:
+    case DWET_WHEEL:
       _gdk_directfb_mouse_x = dfbevent->cx;
       _gdk_directfb_mouse_y = dfbevent->cy;
 
-      gdk_directfb_window_send_crossing_events (NULL, _gdk_parent_root,
-                                                GDK_CROSSING_NORMAL);
+      switch (dfbevent->button)
+        {
+        case DIBI_LEFT:
+          button = 1;
+          mask   = GDK_BUTTON1_MASK;
+          break;
+        case DIBI_MIDDLE:
+          button = 2;
+          mask   = GDK_BUTTON2_MASK;
+          break;
+        case DIBI_RIGHT:
+          button = 3;
+          mask   = GDK_BUTTON3_MASK;
+          break;
+        default:
+          button = dfbevent->button + 1;
+          mask   = 0;
+          break;
+        }
 
-      if (gdk_directfb_apply_focus_opacity)
+      factory->button = button;
+
+      if (dfbevent->type == DWET_BUTTONDOWN)
+        _gdk_directfb_modifiers |= mask;
+      else
+        _gdk_directfb_modifiers &= ~mask;
+
+      factory->type = (dfbevent->type == DWET_BUTTONDOWN ? GDK_BUTTON_PRESS   :
+                       dfbevent->type == DWET_BUTTONUP   ? GDK_BUTTON_RELEASE :
+                       dfbevent->type == DWET_MOTION     ? GDK_MOTION_NOTIFY  : GDK_SCROLL);
+
+
+
+      GdkWindow *mouse_window;
+
+      /* From the docs for XGrabPointer:
+       *
+       * If owner_events is True and if a generated pointer event
+       * would normally be reported to this client, it is reported
+       * as usual. Otherwise, the event is reported with respect to
+       * the grab_window and is reported only if selected by
+       * event_mask. For either value of owner_events, unreported
+       * events are discarded.
+       *
+       * This means we first try the owner, then the grab window,
+       * then give up.
+       */
+      if (_gdk_directfb_pointer_grab_window)
         {
-          if (GDK_WINDOW_IS_MAPPED (window))
-            GDK_WINDOW_IMPL_DIRECTFB (private->impl)->window->SetOpacity
-              (GDK_WINDOW_IMPL_DIRECTFB (private->impl)->window,
-               (GDK_WINDOW_IMPL_DIRECTFB (private->impl)->opacity >> 1) +
-               (GDK_WINDOW_IMPL_DIRECTFB (private->impl)->opacity >> 2));
+          if (_gdk_directfb_pointer_grab_owner_events)
+            {
+              mouse_window = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
+              event_window = find_window_interested_in_event_mask (mouse_window, factory->mask, TRUE);
+
+              /* We have to translate the coordinates if the actual
+               * window is different from the mouse window.
+               */
+              if (mouse_window && event_window && mouse_window != event_window)
+                {
+                  GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB( GDK_WINDOW_OBJECT(event_window)->impl );
+
+                  wx = dfbevent->cx - impl->abs_x;
+                  wy = dfbevent->cy - impl->abs_y;
+                }
+
+              if (event_window)
+                {
+                  D_DEBUG_AT( GDKDFB_EventTrans, "  -> owner       %4d,%4d (%4d,%4d) [%4d,%4d]\n",
+                              wx, wy, dfbevent->x, dfbevent->y, dfbevent->cx, dfbevent->cy );
+
+                  break;
+                }
+            }
+
+          /* Finally check the grab window. */
+          if (_gdk_directfb_pointer_grab_events & factory->mask)
+            {
+              GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB(
+                                                GDK_WINDOW_OBJECT(_gdk_directfb_pointer_grab_window)->impl );
+
+              wx = dfbevent->cx - impl->abs_x;
+              wy = dfbevent->cy - impl->abs_y;
+
+              event_window = _gdk_directfb_pointer_grab_window;
+
+              D_DEBUG_AT( GDKDFB_EventTrans, "  -> grab        %4d,%4d (%4d,%4d) [%4d,%4d]\n",
+                          wx, wy, dfbevent->x, dfbevent->y, dfbevent->cx, dfbevent->cy );
+            }
+          else
+            event_window = NULL;
+        }
+      else 
+        {
+          /* The non-grabbed case. */
+          mouse_window = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
+          event_window = find_window_interested_in_event_mask (mouse_window, factory->mask, TRUE);
+  
+          /* We have to translate the coordinates if the actual
+           * window is different from the mouse window.
+           */
+          if (mouse_window && event_window && mouse_window != event_window)
+            {
+              GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB( GDK_WINDOW_OBJECT(event_window)->impl );
+  
+              wx = dfbevent->cx - impl->abs_x;
+              wy = dfbevent->cy - impl->abs_y;
+            }
+
+          D_DEBUG_AT( GDKDFB_EventTrans, "  -> normal      %4d,%4d (%4d,%4d) [%4d,%4d]\n",
+                      wx, wy, dfbevent->x, dfbevent->y, dfbevent->cx, dfbevent->cy );
         }
       break;
 
-    case DWET_ENTER:
-      {
-        GdkWindow *child;
+    case DWET_GOTFOCUS:
+    case DWET_LOSTFOCUS:
+      factory->type = GDK_FOCUS_CHANGE;
+      event_window = gdk_directfb_other_event_window (event_window, factory->type);
+      break;
 
-        _gdk_directfb_mouse_x = dfbevent->cx;
-        _gdk_directfb_mouse_y = dfbevent->cy;
+    case DWET_POSITION:
+    case DWET_POSITION_SIZE:
+    case DWET_SIZE:
+      factory->type = GDK_CONFIGURE;
+      event_window = gdk_directfb_other_event_window (event_window, factory->type);
+      break;
 
-        child = gdk_directfb_child_at (window, &dfbevent->x, &dfbevent->y);
+    case DWET_KEYDOWN:
+    case DWET_KEYUP:
+      factory->type = (dfbevent->type == DWET_KEYUP ? GDK_KEY_RELEASE : GDK_KEY_PRESS);
+      event_window = gdk_directfb_keyboard_event_window (gdk_directfb_window_find_focus (), factory->type);
+      break;
 
-        /* this makes sure pointer is set correctly when it previously left
-         * a window being not standard shaped
-         */
-        gdk_window_set_cursor (window, NULL);
-        gdk_directfb_window_send_crossing_events (NULL, child,
-                                                  GDK_CROSSING_NORMAL);
+    case DWET_LEAVE:
+      factory->type = GDK_LEAVE_NOTIFY;
+      event_window = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
 
-        if (gdk_directfb_apply_focus_opacity)
-          {
-            GDK_WINDOW_IMPL_DIRECTFB (private->impl)->window->SetOpacity
-              (GDK_WINDOW_IMPL_DIRECTFB (private->impl)->window,
-               GDK_WINDOW_IMPL_DIRECTFB (private->impl)->opacity);
-          }
-      }
+      if (event_window == _gdk_parent_root)
+        event_window = NULL;
       break;
 
-    case DWET_CLOSE:
-      {
- 
-        GdkWindow *event_win;
+    case DWET_ENTER:
+      factory->type = GDK_ENTER_NOTIFY;
+      event_window = gdk_directfb_child_at (_gdk_parent_root, &wx, &wy);
 
-        event_win = gdk_directfb_other_event_window (window, GDK_DELETE);
+      /* this makes sure pointer is set correctly when it previously left
+       * a window being not standard shaped
+       */
+      if (event_window)
+        gdk_window_set_cursor (event_window, NULL); /* FIXME */
+      break;
 
-        if (event_win)
-          event = gdk_directfb_event_make (event_win, GDK_DELETE);
-      }
+    case DWET_CLOSE:
+      factory->type = GDK_DELETE;
+      event_window = gdk_directfb_other_event_window (event_window, factory->type);
       break;
 
     case DWET_DESTROYED:
-      {
-        GdkWindow *event_win;
+      factory->type = GDK_DESTROY;
+      event_window = gdk_directfb_other_event_window (event_window, factory->type);
+      break;
+
+    default:
+      D_WARN( "DFBWindowEventType 0x%08x unknown", dfbevent->type );
+    }
 
-        event_win = gdk_directfb_other_event_window (window, GDK_DESTROY);
+  /* Return information. */
+  factory->win_x = wx;
+  factory->win_y = wy;
 
-        if (event_win)
-          event = gdk_directfb_event_make (event_win, GDK_DESTROY);
+  if (ret_event_window)
+    *ret_event_window = event_window;
 
-	gdk_window_destroy_notify (window);
-      }
+  if (ret_filter_window)
+    *ret_filter_window = filter_window;
+
+  return true;
+}
+
+static inline bool
+factory_init (GdkEventFactory      *factory, 
+              GdkDisplay           *display,
+              const DFBWindowEvent *dfbevent)
+{
+  GdkWindow       *window;
+  GdkWindowObject *private;
+
+  g_return_val_if_fail (factory != NULL, FALSE);
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+  g_return_val_if_fail (dfbevent != NULL, FALSE);
+
+  memset (factory, 0, sizeof(GdkEventFactory));
+
+  window = gdk_window_lookup_for_display (display, dfbevent->window_id);
+  if (!window)
+    {
+      g_warning ("%s: Could not find window for id %u!\n", __FUNCTION__, dfbevent->window_id );
+      return false;
+    }
+
+  g_return_val_if_fail (GDK_IS_WINDOW(window), FALSE);
+
+  private = GDK_WINDOW_OBJECT (window);
+
+  factory->event   = dfbevent;
+  factory->window  = window;
+  factory->private = private;
+  factory->impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
+  factory->win_x   = dfbevent->x;
+  factory->win_y   = dfbevent->y;
+
+  return true;
+}
+
+static inline bool
+factory_build (GdkEventFactory *factory,
+               GdkEvent        *event,
+               GdkWindow       *window)
+{
+  const DFBWindowEvent *dfbevent;
+  guint32               the_time;
+
+  g_return_val_if_fail (factory != NULL, FALSE);
+  g_return_val_if_fail (factory->event != NULL, FALSE);
+  g_return_val_if_fail (factory->window != NULL, FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (window)
+    D_ASSUME( GDK_IS_WINDOW (window) );
+
+  dfbevent = factory->event;
+  the_time = (guint32)(dfbevent->timestamp.tv_sec * 1000 + dfbevent->timestamp.tv_usec / 1000);
+
+  event->any.type       = factory->type;
+  event->any.window     = window;
+  event->any.send_event = FALSE;  /* We don't use PostEvent() so far. */
+
+  switch (factory->type)
+    {
+    case GDK_MOTION_NOTIFY:
+      event->motion.time = the_time;
+      event->motion.axes = NULL;
+      break;
+    case GDK_BUTTON_PRESS:
+    case GDK_2BUTTON_PRESS:
+    case GDK_3BUTTON_PRESS:
+    case GDK_BUTTON_RELEASE:
+      event->button.time = the_time;
+      event->button.axes = NULL;
+      break;
+    case GDK_KEY_PRESS:
+    case GDK_KEY_RELEASE:
+      event->key.time = the_time;
+      break;
+    case GDK_ENTER_NOTIFY:
+    case GDK_LEAVE_NOTIFY:
+      event->crossing.time = the_time;
+      break;
+    case GDK_PROPERTY_NOTIFY:
+      event->property.time = the_time;
+      break;
+    case GDK_SELECTION_CLEAR:
+    case GDK_SELECTION_REQUEST:
+    case GDK_SELECTION_NOTIFY:
+      event->selection.time = the_time;
       break;
+    case GDK_PROXIMITY_IN:
+    case GDK_PROXIMITY_OUT:
+      event->proximity.time = the_time;
+      break;
+    case GDK_DRAG_ENTER:
+    case GDK_DRAG_LEAVE:
+    case GDK_DRAG_MOTION:
+    case GDK_DRAG_STATUS:
+    case GDK_DROP_START:
+    case GDK_DROP_FINISHED:
+      event->dnd.time = the_time;
+      break;
+    case GDK_SCROLL:
+      event->scroll.time = the_time;
+      break;
+    case GDK_FOCUS_CHANGE:
+    case GDK_CONFIGURE:
+    case GDK_MAP:
+    case GDK_UNMAP:
+    case GDK_CLIENT_EVENT:
+    case GDK_VISIBILITY_NOTIFY:
+    case GDK_NO_EXPOSE:
+    case GDK_DELETE:
+    case GDK_DESTROY:
+    case GDK_EXPOSE:
+    default:
+      break;
+    }
 
-    case DWET_WHEEL:
-      {
-        GdkWindow *event_win;
+  return true;
+}
 
-        _gdk_directfb_mouse_x = dfbevent->cx;
-        _gdk_directfb_mouse_y = dfbevent->cy;
+/**********************************************************************************************************************/
 
-        if (_gdk_directfb_pointer_grab_window)
-          {
-            GdkDrawableImplDirectFB *impl;
+static gboolean
+gdk_event_translate (GdkDisplay     *display,
+                     GdkEvent       *event,
+                     DFBWindowEvent *dfbevent)
+{
+  GdkEventFactory        factory;
+  GdkWindow             *event_window  = NULL;
+  GdkWindowObject       *event_private = NULL;
+  GdkWindowImplDirectFB *event_impl    = NULL;
+  GdkWindow             *filter_window = NULL;
+  gboolean               return_val    = FALSE;
+
+  /* Hmm, no g_goto_if_fail? */
+#define return goto done
+  g_return_if_fail (GDK_IS_DISPLAY_DFB(display));
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (dfbevent != NULL);
+#undef return
+
+  D_DEBUG_AT( GDKDFB_EventTrans, "%s( %p, %p, %p )\n", __FUNCTION__, display, event, dfbevent );
 
-            event_win = _gdk_directfb_pointer_grab_window;
-            impl =
-              GDK_DRAWABLE_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (event_win)->impl);
+  D_DEBUG_AT( GDKDFB_EventTrans, "  -> type       %s\n", dfb_window_event_type_name (dfbevent->type) );
 
-            dfbevent->x = dfbevent->cx - impl->abs_x;
-            dfbevent->y = dfbevent->cy - impl->abs_y;
-          }
-        else
+  /* init this, since the done: block uses it */
+  event->any.window = NULL;
+
+  /* Apply global filters */
+  if (_gdk_default_filters)
+    {
+      GdkFilterReturn result = gdk_event_apply_filters (dfbevent, event,
+                                                        _gdk_default_filters);
+      if (result != GDK_FILTER_CONTINUE)
+        {
+          return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+          goto done;
+        }
+    }  
+
+  /* Determine the original window of the event, type, mask etc. */
+  if (!factory_init (&factory, display, dfbevent))
+    goto done;
+
+  if (factory.impl)
+    D_DEBUG_AT( GDKDFB_EventTrans, "  -> window     [" GDKDFB_WIMPL_FORM "]\n", GDKDFB_WIMPL_V(factory.impl) );
+
+  /* Take care of DWET_ENTER/LEAVE events and mouse movement
+   * events and emit the right GDK crossing events.
+   */
+  factory_synthesize_crossing (&factory);
+
+  /* Main part of adaption, may synthesize some events, will determine actual window
+   * to which the event should be sent and return the window that filters it.
+   */
+  if (!factory_process (&factory, &event_window, &filter_window))
+    goto done;
+
+  /* We always run the filters for the window where the event
+   * is delivered, not the window that it relates to
+   */
+  if (filter_window && !GDK_IS_WINDOW (filter_window))
+    filter_window = NULL;
+
+  /* Check window receiving the event. */
+  if (event_window)
+    {
+      if (GDK_IS_WINDOW (event_window))
+        {
+          g_object_ref (G_OBJECT (event_window));
+
+          event_private = GDK_WINDOW_OBJECT (event_window);
+          event_impl    = GDK_WINDOW_IMPL_DIRECTFB(event_private->impl);
+
+          D_DEBUG_AT( GDKDFB_EventTrans, "  -> event win  [" GDKDFB_WIMPL_FORM "]\n",
+                      GDKDFB_WIMPL_V(event_impl) );
+        }
+      else
+        event_window = NULL;
+    }
+
+  if (event_private && GDK_WINDOW_DESTROYED (event_window))
+    {
+      if (dfbevent->type != DWET_DESTROYED)
+        goto done;
+    }
+  else if (filter_window)
+    {
+      /* Apply per-window filters */
+      GdkWindowObject *filter_private = (GdkWindowObject *) filter_window;
+
+      if (filter_private->filters)
+        {
+          GdkFilterReturn result;
+
+          g_object_ref (filter_window);
+
+          result = gdk_event_apply_filters (dfbevent, event,
+                                            filter_private->filters);
+
+          g_object_unref (filter_window);
+
+          if (result != GDK_FILTER_CONTINUE)
+            {
+              return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+              goto done;
+            }
+        }
+    }
+
+  /* Fill out GDK Event structure. */
+  if (!factory_build (&factory, event, event_window))
+    goto done;
+
+  switch (dfbevent->type)
+    {
+    case DWET_BUTTONDOWN:
+    case DWET_BUTTONUP:
+      if (dfbevent->type == DWET_BUTTONDOWN)
+        {
+          GdkEventMask event_mask;
+  
+          GDK_NOTE (EVENTS, 
+                    g_message ("button press:\t\twindow: %p  x,y: %d %d  button: %d",
+                               event_window,
+                               factory.win_x, factory.win_y,
+                               event->button.button));
+
+          /* Emulate implicit grab, when the window has both PRESS and RELEASE
+           * in its mask, like X.
+           */
+          event_mask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+          if (!_gdk_directfb_pointer_grab_window && event_window &&
+              (GDK_WINDOW_OBJECT (event_window)->event_mask & event_mask) == event_mask)
+            {
+              gdk_directfb_pointer_grab (event_window, FALSE,
+                                         gdk_window_get_events (event_window),
+                                         NULL, NULL,
+                                         GDK_CURRENT_TIME,
+                                         TRUE);
+            }
+        }
+      else
+        {
+          GDK_NOTE (EVENTS, 
+                    g_message ("button release:\t\twindow: %p  x,y: %d %d  button: %d",
+                               event_window,
+                               factory.win_x, factory.win_y,
+                               event->button.button));
+
+          if (!(_gdk_directfb_modifiers & (GDK_BUTTON1_MASK |
+                                           GDK_BUTTON2_MASK |
+                                           GDK_BUTTON3_MASK)))
+            gdk_directfb_pointer_ungrab (GDK_CURRENT_TIME, TRUE);
+        }
+
+
+      if (event_window)
+        {
+          event->button.x_root = _gdk_directfb_mouse_x;
+          event->button.y_root = _gdk_directfb_mouse_y;
+
+          event->button.x      = factory.win_x;
+          event->button.y      = factory.win_y;
+
+          event->button.state  = _gdk_directfb_modifiers;
+          event->button.button = factory.button;
+          event->button.device = display->core_pointer;
+
+          D_DEBUG_AT( GDKDFB_EventTrans, "  => BUTTON   %c%d %4.0f,%4.0f (0x%08x)\n",
+                      (dfbevent->type == DWET_BUTTONDOWN) ? '+' : '-',
+                      event->button.button, event->button.x, event->button.y, event->button.state );
+
+          if (dfbevent->type == DWET_BUTTONDOWN)
+            _gdk_event_button_generate (display, event);
+
+          return_val = TRUE;
+        }
+      break;
+
+    case DWET_MOTION:
+      GDK_NOTE (EVENTS,
+                g_message ("motion notify:\t\twindow: %p  x,y: %d %d  hint: %s", 
+                           event_window,
+                           factory.win_x, factory.win_y,
+                           (event->motion.is_hint) ? "true" : "false"));
+
+      if (event_window)
+        {
+          event->motion.x_root  = _gdk_directfb_mouse_x;
+          event->motion.y_root  = _gdk_directfb_mouse_y;
+
+          event->motion.x       = factory.win_x;
+          event->motion.y       = factory.win_y;
+
+          event->motion.state   = _gdk_directfb_modifiers;
+          event->motion.is_hint = FALSE;
+          event->motion.device  = display->core_pointer;
+
+          D_DEBUG_AT( GDKDFB_EventTrans, "  => MOTION      %4.0f,%4.0f (0x%08x)\n",
+                      event->motion.x, event->motion.y, event->motion.state );
+
+          return_val = TRUE;
+        }
+      break;
+
+    case DWET_GOTFOCUS:
+      gdk_directfb_change_focus (event_window);
+      break;
+
+    case DWET_LOSTFOCUS:
+      gdk_directfb_change_focus (_gdk_parent_root);
+      break;
+
+    case DWET_POSITION:
+      factory.private->x = dfbevent->x;
+      factory.private->y = dfbevent->y;
+
+      if (event_window)
+        {
+          event->configure.x      = dfbevent->x;
+          event->configure.y      = dfbevent->y;
+          event->configure.width  = factory.impl->drawable.width;
+          event->configure.height = factory.impl->drawable.height;
+
+          return_val = TRUE;
+        }
+
+      _gdk_directfb_calc_abs (factory.window);
+      break;
+
+    case DWET_POSITION_SIZE:
+      factory.private->x = dfbevent->x;
+      factory.private->y = dfbevent->y;
+      /* fallthru */
+
+    case DWET_SIZE:
+      {
+        GList *list;
+
+        if (event_window)
           {
-            event_win = gdk_directfb_child_at (window,
-                                               &dfbevent->x, &dfbevent->y);
+            event->configure.x      = factory.private->x;
+            event->configure.y      = factory.private->y;
+            event->configure.width  = dfbevent->w;
+            event->configure.height = dfbevent->h;
+
+            return_val = TRUE;
           }
 
-        if (event_win)
+        factory.impl->drawable.width  = dfbevent->w;
+        factory.impl->drawable.height = dfbevent->h;
+
+        for (list = factory.private->children; list; list = list->next)
           {
-            event = gdk_directfb_event_make (event_win, GDK_SCROLL);
+            GdkWindowObject         *win;
+            GdkDrawableImplDirectFB *impl;
 
-            event->scroll.direction = (dfbevent->step < 0 ?
-                                       GDK_SCROLL_DOWN : GDK_SCROLL_UP);
+            win  = GDK_WINDOW_OBJECT (list->data);
+            impl = GDK_DRAWABLE_IMPL_DIRECTFB (win->impl);
 
-            event->scroll.x_root = _gdk_directfb_mouse_x;
-            event->scroll.y_root = _gdk_directfb_mouse_y;
-            event->scroll.x      = dfbevent->x;
-            event->scroll.y      = dfbevent->y;
-            event->scroll.state  = _gdk_directfb_modifiers;
-            event->scroll.device = display->core_pointer;
+            /* FIXME: Get rid off that recursive bloat. */
+            _gdk_directfb_move_resize_child (GDK_WINDOW (win),
+                                             win->x, win->y,
+                                             impl->width, impl->height);
           }
+
+        /* FIXME: Get rid off that recursive bloat. */
+        if (dfbevent->type != DWET_SIZE)
+          _gdk_directfb_calc_abs (factory.window);
+
+        gdk_window_clear (factory.window);
+        gdk_window_invalidate_rect (factory.window, NULL, TRUE);
       }
       break;
 
+    case DWET_KEYDOWN:
+    case DWET_KEYUP:
+      if (event_window)
+        {
+          gdk_directfb_translate_key_event (dfbevent, &event->key);
+
+          return_val = TRUE;
+        }
+      break;
+
+    case DWET_LEAVE:
+      if (gdk_directfb_apply_focus_opacity && GDK_WINDOW_IS_MAPPED (factory.window))
+        factory.impl->window->SetOpacity (factory.impl->window,
+                                         factory.impl->opacity / 2 +
+                                         factory.impl->opacity / 4);
+      break;
+
+    case DWET_ENTER:
+      if (gdk_directfb_apply_focus_opacity && GDK_WINDOW_IS_MAPPED (factory.window))
+        factory.impl->window->SetOpacity (factory.impl->window, factory.impl->opacity);
+      break;
+
+    case DWET_CLOSE:
+      return_val = TRUE;
+      break;
+
+    case DWET_DESTROYED:
+      gdk_window_destroy_notify (factory.window);
+      return_val = TRUE;
+      break;
+
+    case DWET_WHEEL:
+      if (event_window)
+        {
+          event->scroll.direction = (dfbevent->step < 0 ?
+                                     GDK_SCROLL_DOWN : GDK_SCROLL_UP);
+
+          event->scroll.x_root    = _gdk_directfb_mouse_x;
+          event->scroll.y_root    = _gdk_directfb_mouse_y;
+          event->scroll.x         = factory.win_x;
+          event->scroll.y         = factory.win_y;
+          event->scroll.state     = _gdk_directfb_modifiers;
+          event->scroll.device    = display->core_pointer;
+
+          return_val = TRUE;
+        }
+      break;
+
     default:
       g_message ("unhandled DirectFB windowing event 0x%08x", dfbevent->type);
     }
 
-  g_object_unref (G_OBJECT (window));
 
-  return event;
+done:
+  if (return_val)
+    {
+      if (event->any.window)
+	g_object_ref (event->any.window);
+
+      if (((event->any.type == GDK_ENTER_NOTIFY) ||
+           (event->any.type == GDK_LEAVE_NOTIFY)) &&
+          (event->crossing.subwindow != NULL))
+	g_object_ref (event->crossing.subwindow);
+    }
+  else
+    {
+      /* Mark this event as having no resources to be freed */
+      event->any.window = NULL;
+      event->any.type = GDK_NOTHING;
+    }
+  
+  if (event_window)
+    g_object_unref (event_window);
+  
+  return return_val;
 }
 
+/**********************************************************************************************************************/
+
 gboolean
 gdk_screen_get_setting (GdkScreen   *screen,
                         const gchar *name,
@@ -789,22 +1871,51 @@ gdk_screen_get_setting (GdkScreen   *scr
   return FALSE;
 }
 
+/**
+ * gdk_display_add_client_message_filter:
+ * @display: a #GdkDisplay for which this message filter applies
+ * @message_type: the type of ClientMessage events to receive.
+ *   This will be checked against the @message_type field 
+ *   of the XClientMessage event struct.
+ * @func: the function to call to process the event.
+ * @data: user data to pass to @func.
+ *
+ * Adds a filter to be called when X ClientMessage events are received.
+ * See gdk_window_add_filter() if you are interested in filtering other
+ * types of events.
+ *
+ * Since: 2.2
+ **/ 
 void
 gdk_display_add_client_message_filter (GdkDisplay   *display,
                                        GdkAtom       message_type,
                                        GdkFilterFunc func,
                                        gpointer      data)
 {
-  /* XXX: display should be used */
-  GdkClientFilter *filter = g_new (GdkClientFilter, 1);
+  GdkClientFilter *filter;
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  filter = g_new (GdkClientFilter, 1);
 
   filter->type = message_type;
   filter->function = func;
   filter->data = data;
-  client_filters = g_list_append (client_filters, filter);
-}
 
+  GDK_DISPLAY_DFB(display)->client_filters = 
+    g_list_append (GDK_DISPLAY_DFB (display)->client_filters,
+                   filter);
+}
 
+/**
+ * gdk_add_client_message_filter:
+ * @message_type: the type of ClientMessage events to receive. This will be
+ *     checked against the <structfield>message_type</structfield> field of the
+ *     XClientMessage event struct.
+ * @func: the function to call to process the event.
+ * @data: user data to pass to @func. 
+ * 
+ * Adds a filter to the default display to be called when X ClientMessage events
+ * are received. See gdk_display_add_client_message_filter().
+ **/
 void
 gdk_add_client_message_filter (GdkAtom       message_type,
                                GdkFilterFunc func,
diff -puraN gtk+-2.12.9/gdk/directfb/gdkgc-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkgc-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkgc-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkgc-directfb.c	2008-05-21 20:20:24.000000000 +0200
@@ -113,8 +113,8 @@ gdk_gc_directfb_finalize (GObject *objec
   GdkGC         *gc      = GDK_GC (object);
   GdkGCDirectFB *private = GDK_GC_DIRECTFB (gc);
 
-  if (private->clip_region)
-    gdk_region_destroy (private->clip_region);
+  if (private->clip_region.numRects)
+    temp_region_deinit (&private->clip_region);
   if (private->values.clip_mask)
     g_object_unref (private->values.clip_mask);
   if (private->values.stipple)
@@ -262,11 +262,7 @@ gdk_directfb_gc_set_values (GdkGC       
       if (oldpm)
         g_object_unref (oldpm);
 
-      if (private->clip_region)
-        {
-          gdk_region_destroy (private->clip_region);
-          private->clip_region = NULL;
-        }
+      temp_region_reset (&private->clip_region);
     }
 
   if (values_mask & GDK_GC_SUBWINDOW)
@@ -363,17 +359,13 @@ _gdk_windowing_gc_set_clip_region (GdkGC
 
   data = GDK_GC_DIRECTFB (gc);
 
-  if (region == data->clip_region)
+  if (region == &data->clip_region)
     return;
 
-  if (data->clip_region)
-    {
-      gdk_region_destroy (data->clip_region);
-      data->clip_region = NULL;
-    }
-
   if (region)
-    data->clip_region = gdk_region_copy (region);
+       temp_region_init_copy (&data->clip_region, region);
+  else
+       temp_region_reset (&data->clip_region);
 
   gc->clip_x_origin = 0;
   gc->clip_y_origin = 0;
@@ -394,8 +386,7 @@ _gdk_windowing_gc_copy (GdkGC *dst_gc,
 
   dst_private = GDK_GC_DIRECTFB (dst_gc);
 
-  if (dst_private->clip_region)
-    gdk_region_destroy(dst_private->clip_region);
+  temp_region_reset(&dst_private->clip_region);
 
   if (dst_private->values_mask & GDK_GC_FONT)
     gdk_font_unref (dst_private->values.font);
@@ -415,8 +406,6 @@ _gdk_windowing_gc_copy (GdkGC *dst_gc,
     g_object_ref (dst_private->values.stipple);
   if (dst_private->values_mask & GDK_GC_CLIP_MASK)
     g_object_ref (dst_private->values.clip_mask);
-  if (dst_private->clip_region)
-    dst_private->clip_region = gdk_region_copy (dst_private->clip_region);
 }
 
 /**
diff -puraN gtk+-2.12.9/gdk/directfb/gdkglobals-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkglobals-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkglobals-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkglobals-directfb.c	2008-05-21 20:20:24.000000000 +0200
@@ -48,6 +48,10 @@ DFBColor              gdk_directfb_bg_co
 DFBColor              gdk_directfb_bg_color_key               = { 0, 0, 0, 0 };
 gboolean              gdk_directfb_monochrome_fonts           = FALSE;
 
+GdkWindow          * _gdk_parent_root                         = NULL;
+GdkWindow          * _gdk_directfb_pointer_window             = NULL;
+
+gboolean             _gdk_directfb_pointer_implicit_grab      = FALSE;
 GdkWindow          * _gdk_directfb_pointer_grab_window        = NULL;
 GdkWindow          * _gdk_directfb_keyboard_grab_window       = NULL;
 GdkWindow          * _gdk_directfb_pointer_grab_confine       = NULL;
diff -puraN gtk+-2.12.9/gdk/directfb/gdkimage-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkimage-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkimage-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkimage-directfb.c	2008-05-21 20:20:24.000000000 +0200
@@ -225,7 +225,13 @@ _gdk_image_new_for_depth (GdkScreen    *
 
   private->surface = surface;
 
-  surface->Lock( surface, DSLF_WRITE, &image->mem, &pitch );
+  ret = surface->Lock( surface, DSLF_WRITE, &image->mem, &pitch );
+  if (ret)
+    {
+      DirectFBError( "IDirectFBSurface::Lock() for writing failed!\n", ret );
+      gdk_image_unref( image );
+      return NULL;
+    }
 
   image->type           = type;
   image->visual         = visual;
@@ -272,7 +278,7 @@ _gdk_directfb_copy_to_image (GdkDrawable
     {
       DFBResult ret;
 
-      ret = layer->SetCooperativeLevel (layer, DLSCL_EXCLUSIVE);
+      ret = layer->SetCooperativeLevel (layer, DLSCL_ADMINISTRATIVE);
       if (ret)
         {
           DirectFBError ("_gdk_directfb_copy_to_image - SetCooperativeLevel",
@@ -294,7 +300,7 @@ _gdk_directfb_copy_to_image (GdkDrawable
 
   if (!image)
     image =  gdk_image_new (GDK_IMAGE_NORMAL,
-                            gdk_visual_get_system (), width, height);
+                            gdk_drawable_get_visual (drawable), width, height);
 
   private = image->windowing_data;
 
@@ -303,7 +309,7 @@ _gdk_directfb_copy_to_image (GdkDrawable
   private->surface->Blit( private->surface,
                           impl->surface, &rect, dest_x, dest_y );
 
-  private->surface->Lock( private->surface, DSLF_WRITE, &image->mem, &pitch );
+  private->surface->Lock( private->surface, DSLF_READ | DSLF_WRITE, &image->mem, &pitch );
   image->bpl = pitch;
 
   if (impl->wrapper == _gdk_parent_root)
@@ -403,8 +409,8 @@ gdk_directfb_image_destroy (GdkImage *im
   if (!private)
     return;
 
-  GDK_NOTE (MISC, g_print ("gdk_directfb_image_destroy: %#x\n",
-                           (guint) private->surface));
+  GDK_NOTE (MISC, g_print ("gdk_directfb_image_destroy: %#lx\n",
+                           (gulong) private->surface));
 
   private->surface->Unlock( private->surface );
   private->surface->Release( private->surface );
diff -puraN gtk+-2.12.9/gdk/directfb/gdkinput-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkinput-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkinput-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkinput-directfb.c	2008-05-21 20:26:44.000000000 +0200
@@ -228,7 +228,7 @@ gboolean
 gdk_device_set_mode (GdkDevice    *device,
                      GdkInputMode  mode)
 {
-  g_message ("unimplemented %s", G_STRLOC);
+  D_UNIMPLEMENTED();
 
   return FALSE;
 }
@@ -303,7 +303,7 @@ gdk_input_set_extension_events (GdkWindo
                                 gint              mask,
                                 GdkExtensionMode  mode)
 {
-  g_message ("unimplemented %s", G_STRLOC);
+  D_UNIMPLEMENTED();
 }
 
 GList *
diff -puraN gtk+-2.12.9/gdk/directfb/gdkkeys-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkkeys-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkkeys-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkkeys-directfb.c	2008-05-21 20:20:24.000000000 +0200
@@ -1937,7 +1937,7 @@ gdk_keymap_translate_keyboard_state (Gdk
 			if (level)
 				*level = i;
 
-			if (i && directfb_keymap[index + 2 * *effective_group] != *keyval)
+			if (i && directfb_keymap[index + (effective_group ? 2 * *effective_group : 0)] != *keyval)
                 if(consumed_modifiers)
 				    *consumed_modifiers |= GDK_SHIFT_MASK;
 
diff -puraN gtk+-2.12.9/gdk/directfb/gdkmain-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkmain-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkmain-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkmain-directfb.c	2008-05-21 20:20:24.000000000 +0200
@@ -108,44 +108,60 @@ gdk_get_display (void)
   return g_strdup (gdk_display_get_name (gdk_display_get_default ()));
 }
 
-
 /* utils */
-static const guint type_masks[] =
+static const guint event_type_masks[] =
 {
-  GDK_STRUCTURE_MASK,        /* GDK_DELETE            =  0, */
-  GDK_STRUCTURE_MASK,        /* GDK_DESTROY           =  1, */
-  GDK_EXPOSURE_MASK,         /* GDK_EXPOSE            =  2, */
-  GDK_POINTER_MOTION_MASK,   /* GDK_MOTION_NOTIFY     =  3, */
-  GDK_BUTTON_PRESS_MASK,     /* GDK_BUTTON_PRESS      =  4, */
-  GDK_BUTTON_PRESS_MASK,     /* GDK_2BUTTON_PRESS     =  5, */
-  GDK_BUTTON_PRESS_MASK,     /* GDK_3BUTTON_PRESS     =  6, */
-  GDK_BUTTON_RELEASE_MASK,   /* GDK_BUTTON_RELEASE    =  7, */
-  GDK_KEY_PRESS_MASK,        /* GDK_KEY_PRESS         =  8, */
-  GDK_KEY_RELEASE_MASK,      /* GDK_KEY_RELEASE       =  9, */
-  GDK_ENTER_NOTIFY_MASK,     /* GDK_ENTER_NOTIFY      = 10, */
-  GDK_LEAVE_NOTIFY_MASK,     /* GDK_LEAVE_NOTIFY      = 11, */
-  GDK_FOCUS_CHANGE_MASK,     /* GDK_FOCUS_CHANGE      = 12, */
-  GDK_STRUCTURE_MASK,        /* GDK_CONFIGURE         = 13, */
-  GDK_VISIBILITY_NOTIFY_MASK,/* GDK_MAP               = 14, */
-  GDK_VISIBILITY_NOTIFY_MASK,/* GDK_UNMAP             = 15, */
-  GDK_PROPERTY_CHANGE_MASK,  /* GDK_PROPERTY_NOTIFY   = 16, */
-  GDK_PROPERTY_CHANGE_MASK,  /* GDK_SELECTION_CLEAR   = 17, */
-  GDK_PROPERTY_CHANGE_MASK,  /* GDK_SELECTION_REQUEST = 18, */
-  GDK_PROPERTY_CHANGE_MASK,  /* GDK_SELECTION_NOTIFY  = 19, */
-  GDK_PROXIMITY_IN_MASK,     /* GDK_PROXIMITY_IN      = 20, */
-  GDK_PROXIMITY_OUT_MASK,    /* GDK_PROXIMITY_OUT     = 21, */
-  GDK_ALL_EVENTS_MASK,       /* GDK_DRAG_ENTER        = 22, */
-  GDK_ALL_EVENTS_MASK,       /* GDK_DRAG_LEAVE        = 23, */
-  GDK_ALL_EVENTS_MASK,       /* GDK_DRAG_MOTION       = 24, */
-  GDK_ALL_EVENTS_MASK,       /* GDK_DRAG_STATUS       = 25, */
-  GDK_ALL_EVENTS_MASK,       /* GDK_DROP_START        = 26, */
-  GDK_ALL_EVENTS_MASK,       /* GDK_DROP_FINISHED     = 27, */
-  GDK_ALL_EVENTS_MASK,       /* GDK_CLIENT_EVENT      = 28, */
-  GDK_VISIBILITY_NOTIFY_MASK,/* GDK_VISIBILITY_NOTIFY = 29, */
-  GDK_EXPOSURE_MASK,         /* GDK_NO_EXPOSE         = 30, */
-  GDK_SCROLL_MASK            /* GDK_SCROLL            = 31  */
+  GDK_STRUCTURE_MASK,                       /* GDK_DELETE            =  0, */
+  GDK_STRUCTURE_MASK,                       /* GDK_DESTROY           =  1, */
+  GDK_EXPOSURE_MASK,                        /* GDK_EXPOSE            =  2, */
+  GDK_POINTER_MOTION_MASK,                  /* GDK_MOTION_NOTIFY     =  3, */
+  GDK_BUTTON_PRESS_MASK,                    /* GDK_BUTTON_PRESS      =  4, */
+  GDK_BUTTON_PRESS_MASK,                    /* GDK_2BUTTON_PRESS     =  5, */
+  GDK_BUTTON_PRESS_MASK,                    /* GDK_3BUTTON_PRESS     =  6, */
+  GDK_BUTTON_RELEASE_MASK,                  /* GDK_BUTTON_RELEASE    =  7, */
+  GDK_KEY_PRESS_MASK,                       /* GDK_KEY_PRESS         =  8, */
+  GDK_KEY_RELEASE_MASK,                     /* GDK_KEY_RELEASE       =  9, */
+  GDK_ENTER_NOTIFY_MASK,                    /* GDK_ENTER_NOTIFY      = 10, */
+  GDK_LEAVE_NOTIFY_MASK,                    /* GDK_LEAVE_NOTIFY      = 11, */
+  GDK_FOCUS_CHANGE_MASK,                    /* GDK_FOCUS_CHANGE      = 12, */
+  GDK_STRUCTURE_MASK,                       /* GDK_CONFIGURE         = 13, */
+  GDK_VISIBILITY_NOTIFY_MASK,               /* GDK_MAP               = 14, */
+  GDK_VISIBILITY_NOTIFY_MASK,               /* GDK_UNMAP             = 15, */
+  GDK_PROPERTY_CHANGE_MASK,                 /* GDK_PROPERTY_NOTIFY   = 16, */
+  GDK_PROPERTY_CHANGE_MASK,                 /* GDK_SELECTION_CLEAR   = 17, */
+  GDK_PROPERTY_CHANGE_MASK,                 /* GDK_SELECTION_REQUEST = 18, */
+  GDK_PROPERTY_CHANGE_MASK,                 /* GDK_SELECTION_NOTIFY  = 19, */
+  GDK_PROXIMITY_IN_MASK,                    /* GDK_PROXIMITY_IN      = 20, */
+  GDK_PROXIMITY_OUT_MASK,                   /* GDK_PROXIMITY_OUT     = 21, */
+  GDK_ALL_EVENTS_MASK,                      /* GDK_DRAG_ENTER        = 22, */
+  GDK_ALL_EVENTS_MASK,                      /* GDK_DRAG_LEAVE        = 23, */
+  GDK_ALL_EVENTS_MASK,                      /* GDK_DRAG_MOTION       = 24, */
+  GDK_ALL_EVENTS_MASK,                      /* GDK_DRAG_STATUS       = 25, */
+  GDK_ALL_EVENTS_MASK,                      /* GDK_DROP_START        = 26, */
+  GDK_ALL_EVENTS_MASK,                      /* GDK_DROP_FINISHED     = 27, */
+  GDK_ALL_EVENTS_MASK,                      /* GDK_CLIENT_EVENT      = 28, */
+  GDK_VISIBILITY_NOTIFY_MASK,               /* GDK_VISIBILITY_NOTIFY = 29, */
+  GDK_EXPOSURE_MASK,                        /* GDK_NO_EXPOSE         = 30, */
+  GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,  /* GDK_SCROLL            = 31, */
+  GDK_WINDOW_STATE,                         /* GDK_WINDOW_STATE      = 32, */
+  GDK_SETTING,                              /* GDK_SETTING,          = 33, */
+  GDK_OWNER_CHANGE,                         /* GDK_OWNER_CHANGE      = 34, */
+  GDK_GRAB_BROKEN,                          /* GDK_GRAB_BROKEN       = 35, */
 };
 
+GdkEventMask
+gdk_directfb_event_type_mask (GdkEventType type)
+{
+  unsigned int index = type;
+
+  if (index < G_N_ELEMENTS(event_type_masks))
+    return event_type_masks[index];
+
+  g_warning ("%s: event type (%u) outside of known range!\n", __FUNCTION__, index);
+
+  return GDK_ALL_EVENTS_MASK;
+}
+
 GdkWindow *
 gdk_directfb_other_event_window (GdkWindow    *window,
                                  GdkEventType  type)
@@ -164,7 +180,7 @@ gdk_directfb_other_event_window (GdkWind
 
       evmask = GDK_WINDOW_OBJECT (w)->event_mask;
 
-      if (evmask & type_masks[type])
+      if (evmask & gdk_directfb_event_type_mask(type))
         return w;
 
       w = gdk_window_get_parent (w);
@@ -200,7 +216,7 @@ gdk_directfb_pointer_event_window (GdkWi
             evmask |= GDK_POINTER_MOTION_MASK;
         }
 
-      if (evmask & type_masks[type]) {
+      if (evmask & gdk_directfb_event_type_mask(type)) {
 
         if( _gdk_directfb_pointer_grab_owner_events ) {
         return _gdk_directfb_pointer_grab_window;
@@ -244,7 +260,7 @@ gdk_directfb_pointer_event_window (GdkWi
             evmask |= GDK_POINTER_MOTION_MASK;
         }
 
-      if (evmask & type_masks[type])
+      if (evmask & gdk_directfb_event_type_mask(type))
         return w;
 
       w = gdk_window_get_parent (w);
@@ -277,7 +293,7 @@ gdk_directfb_keyboard_event_window (GdkW
 
       evmask = GDK_WINDOW_OBJECT (w)->event_mask;
 
-      if (evmask & type_masks[type])
+      if (evmask & gdk_directfb_event_type_mask(type))
         return w;
 
       w = gdk_window_get_parent (w);
@@ -299,6 +315,7 @@ gdk_directfb_event_make (GdkWindow    *w
   switch (type)
     {
     case GDK_MOTION_NOTIFY:
+      D_ONCE("bad function");
       event->motion.time = the_time;
       event->motion.axes = NULL;
       break;
@@ -306,15 +323,18 @@ gdk_directfb_event_make (GdkWindow    *w
     case GDK_2BUTTON_PRESS:
     case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
+      D_ONCE("bad function");
       event->button.time = the_time;
       event->button.axes = NULL;
       break;
     case GDK_KEY_PRESS:
     case GDK_KEY_RELEASE:
+      D_ONCE("bad function");
       event->key.time = the_time;
       break;
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
+      D_ONCE("bad function");
       event->crossing.time = the_time;
       break;
     case GDK_PROPERTY_NOTIFY:
@@ -338,6 +358,7 @@ gdk_directfb_event_make (GdkWindow    *w
       event->dnd.time = the_time;
       break;
     case GDK_SCROLL:
+      D_ONCE("bad function");
       event->scroll.time = the_time;
       break;
     case GDK_FOCUS_CHANGE:
@@ -351,6 +372,7 @@ gdk_directfb_event_make (GdkWindow    *w
     case GDK_DESTROY:
     case GDK_EXPOSE:
     default:
+//      D_ONCE("bad function");
       break;
     }
 
@@ -435,7 +457,7 @@ gdk_keyboard_grab (GdkWindow *window,
                    gint       owner_events,
                    guint32    time) 
 {
-	return gdk_display_keyboard_grab(gdk_display_get_default(),
+	return gdk_directfb_keyboard_grab(gdk_display_get_default(),
 			window,
 			owner_events,
 			time);
diff -puraN gtk+-2.12.9/gdk/directfb/gdkpixmap-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkpixmap-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkpixmap-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkpixmap-directfb.c	2008-05-21 20:20:24.000000000 +0200
@@ -109,8 +109,6 @@ gdk_pixmap_impl_directfb_class_init (Gdk
 static void
 gdk_pixmap_impl_directfb_finalize (GObject *object)
 {
-  GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (object);
-
   if (G_OBJECT_CLASS (parent_class)->finalize)
     G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -219,16 +217,17 @@ gdk_bitmap_create_from_data (GdkDrawable
 
   if (pixmap)
     {
-      guchar *dst;
-      gint    pitch;
+      void *ptr;
+      gint  pitch;
 
       IDirectFBSurface *surface;
 
       surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (pixmap)->impl)->surface;
 
-      if (surface->Lock( surface, DSLF_WRITE, (void**)(&dst), &pitch ) == DFB_OK)
+      if (surface->Lock( surface, DSLF_WRITE, &ptr, &pitch ) == DFB_OK)
         {
-          gint i, j;
+          gint    i, j;
+          guchar *dst = ptr;
 
           for (i = 0; i < height; i++)
             {
@@ -274,8 +273,8 @@ gdk_pixmap_create_from_data (GdkDrawable
   if (pixmap)
     {
       IDirectFBSurface *surface;
-      gchar            *dst;
-      gint              pitch;
+      void             *ptr;
+      int               pitch;
       gint              src_pitch;
 
       depth = gdk_drawable_get_depth (pixmap);
@@ -284,9 +283,10 @@ gdk_pixmap_create_from_data (GdkDrawable
       surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (pixmap)->impl)->surface;
 
       if (surface->Lock( surface,
-                         DSLF_WRITE, (void**)(&dst), &pitch ) == DFB_OK)
+                         DSLF_WRITE, &ptr, &pitch ) == DFB_OK)
         {
-          gint i;
+          gint   i;
+          gchar *dst = ptr;
 
           for (i = 0; i < height; i++)
             {
diff -puraN gtk+-2.12.9/gdk/directfb/gdkprivate-directfb.h gtk+-2.12.9-dok2/gdk/directfb/gdkprivate-directfb.h
--- gtk+-2.12.9/gdk/directfb/gdkprivate-directfb.h	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkprivate-directfb.h	2008-05-21 20:20:24.000000000 +0200
@@ -38,8 +38,13 @@
 #include "gdkinternals.h"
 #include "gdkcursor.h"
 #include "gdkdisplay-directfb.h"
+#include "gdkregion-generic.h"
 #include <cairo.h>
 
+#include <string.h>
+
+#include <directfb_util.h>
+#include <directfb_version.h>
 
 
 #define GDK_TYPE_DRAWABLE_IMPL_DIRECTFB       (gdk_drawable_impl_directfb_get_type ())
@@ -68,19 +73,20 @@ struct _GdkDrawableImplDirectFB
 
   gboolean                buffered;
 
-  GdkRegion              *paint_region;
+  GdkRegion               paint_region;
   gint                    paint_depth;
   gint                    width;
   gint                    height;
   gint                    abs_x;
   gint                    abs_y;
 
+  GdkRegion               clip_region;
+
   GdkColormap            *colormap;
 
   IDirectFBSurface       *surface;
   DFBSurfacePixelFormat   format;
-  cairo_surface_t *  cairo_surface;
-
+  cairo_surface_t        *cairo_surface;
 };
 
 typedef struct
@@ -90,17 +96,6 @@ typedef struct
 
 GType      gdk_drawable_impl_directfb_get_type (void);
 
-void       _gdk_directfb_draw_rectangle (GdkDrawable *drawable,
-                                         GdkGC       *gc,
-                                         gint         filled,
-                                         gint         x,
-                                         gint         y,
-                                         gint         width,
-                                         gint         height);
-
-void       _gdk_directfb_update         (GdkDrawableImplDirectFB *impl,
-                                         DFBRegion               *region);
-
 GdkEvent *  gdk_directfb_event_make     (GdkWindow               *window,
                                          GdkEventType             type);
 
@@ -139,7 +134,8 @@ typedef struct
 struct _GdkWindowImplDirectFB
 {
   GdkDrawableImplDirectFB drawable;
-  GdkWindow             *gdkWindow;
+
+  GdkWindow              *gdkWindow;
 
   IDirectFBWindow        *window;
 
@@ -151,6 +147,9 @@ struct _GdkWindowImplDirectFB
   guint8                  opacity;
 
   GdkWindowTypeHint       type_hint;
+
+  DFBUpdates              flips;
+  DFBRegion               flip_regions[4];
 };
 
 typedef struct
@@ -158,11 +157,20 @@ typedef struct
   GdkDrawableImplDirectFBClass parent_class;
 } GdkWindowImplDirectFBClass;
 
-GType gdk_window_impl_directfb_get_type        (void);
 
-void  gdk_directfb_window_send_crossing_events (GdkWindow       *src,
-                                                GdkWindow       *dest,
-                                                GdkCrossingMode  mode);
+#define GDKDFB_WIMPL_FORM   "%4d,%4d-%4dx%4d %d"
+#define GDKDFB_WIMPL_V(w)   ((GdkWindowObject*)((w)->gdkWindow))->x,    \
+                            ((GdkWindowObject*)((w)->gdkWindow))->y,    \
+                            (w)->drawable.width, (w)->drawable.height,  \
+                            (w)->dfb_id
+
+#define GDKDFB_REGION_FORM  "%4d,%4d-%4dx%4d (%ld boxes)"
+#define GDKDFB_REGION_V(r)  GDKDFB_RECTANGLE_VALS_FROM_BOX(&((r)->extents)), (r)->numRects
+
+#define DFB_REGION_FORM     "%4d,%4d-%4dx%4d"
+#define DFB_REGION_V(r)     DFB_RECTANGLE_VALS_FROM_REGION(r)
+
+GType gdk_window_impl_directfb_get_type        (void);
 
 void  _gdk_directfb_calc_abs                   (GdkWindow       *window);
 
@@ -174,6 +182,9 @@ void        gdk_directfb_window_id_table
 void        gdk_directfb_window_id_table_remove (DFBWindowID  dfb_id);
 GdkWindow * gdk_directfb_window_id_table_lookup (DFBWindowID  dfb_id);
 
+void        _gdk_directfb_events_update_mouse_window (GdkWindow *window);
+
+void        _gdk_directfb_events_update_cursor       (GdkWindow *window);
 
 typedef struct
 {
@@ -204,7 +215,7 @@ typedef struct
 {
   GdkGC             parent_instance;
 
-  GdkRegion        *clip_region;
+  GdkRegion         clip_region;
 
   GdkGCValuesMask   values_mask;
   GdkGCValues       values;
@@ -235,6 +246,14 @@ void       gdk_directfb_event_windows_ad
 void       gdk_directfb_event_windows_remove (GdkWindow *window);
 #endif
 
+GdkGrabStatus gdk_directfb_keyboard_grab  (GdkDisplay          *display,
+                                           GdkWindow           *window,
+                                           gint                 owner_events,
+                                           guint32              time);
+
+void          gdk_directfb_keyboard_ungrab(GdkDisplay          *display,
+                                           guint32              time);
+
 GdkGrabStatus gdk_directfb_pointer_grab   (GdkWindow           *window,
                                            gint                 owner_events,
                                            GdkEventMask         event_mask,
@@ -247,10 +266,13 @@ void          gdk_directfb_pointer_ungra
 
 guint32       gdk_directfb_get_time       (void);
 
+GdkEventMask  gdk_directfb_event_type_mask     (GdkEventType  type);
+
 GdkWindow * gdk_directfb_pointer_event_window  (GdkWindow    *window,
                                                 GdkEventType  type);
 GdkWindow * gdk_directfb_keyboard_event_window (GdkWindow    *window,
                                                 GdkEventType  type);
+
 GdkWindow * gdk_directfb_other_event_window    (GdkWindow    *window,
                                                 GdkEventType  type);
 void       _gdk_selection_window_destroyed    (GdkWindow       *window);
@@ -279,7 +301,11 @@ void        gdk_directfb_mouse_get_info 
 
 extern GdkDisplayDFB *_gdk_display;
 
+extern GdkWindow           * _gdk_parent_root;
+extern GdkWindow           * _gdk_directfb_pointer_window;
+
 /* Pointer grab info */
+extern gboolean              _gdk_directfb_pointer_implicit_grab;
 extern GdkWindow           * _gdk_directfb_pointer_grab_window;
 extern gboolean              _gdk_directfb_pointer_grab_owner_events;
 extern GdkWindow           * _gdk_directfb_pointer_grab_confine;
@@ -291,7 +317,7 @@ extern GdkWindow           * _gdk_direct
 extern GdkEventMask          _gdk_directfb_keyboard_grab_events;
 extern gboolean              _gdk_directfb_keyboard_grab_owner_events;
 
-extern GdkScreen  *  _gdk_screen;
+extern GdkScreen           * _gdk_screen;
 
 extern GdkAtom               _gdk_selection_property;
 
@@ -317,5 +343,91 @@ void gdk_fb_window_set_child_handler (Gd
                                       GdkWindowChildGetPos   get_pos,
                                       gpointer               user_data);
 
+void gdk_directfb_clip_region (GdkDrawable  *drawable,
+                               GdkGC        *gc,
+                               GdkRectangle *draw_rect,
+                               GdkRegion    *ret_clip);
+
+
+/* Utilities for avoiding mallocs */
+
+static inline void
+temp_region_init_copy( GdkRegion       *region, 
+                       const GdkRegion *source)
+{
+  if (region != source) /*  don't want to copy to itself */
+    {  
+      if (region->size < source->numRects)
+        {
+          if (region->rects && region->rects != &region->extents)
+            g_free( region->rects );
+
+          region->rects = g_new (GdkRegionBox, source->numRects);
+          region->size  = source->numRects;
+        }
+
+      region->numRects = source->numRects;
+      region->extents  = source->extents;
+
+      memcpy( region->rects, source->rects, source->numRects * sizeof (GdkRegionBox) );
+    }
+}
+
+static inline void
+temp_region_init_rectangle( GdkRegion          *region,
+                            const GdkRectangle *rect )
+{
+     region->numRects = 1;
+     region->rects = &region->extents;
+     region->extents.x1 = rect->x;
+     region->extents.y1 = rect->y;
+     region->extents.x2 = rect->x + rect->width;
+     region->extents.y2 = rect->y + rect->height;
+     region->size = 1;
+}
+
+static inline void
+temp_region_init_rectangle_vals( GdkRegion *region,
+                                 int        x,
+                                 int        y,
+                                 int        w,
+                                 int        h )
+{
+     region->numRects = 1;
+     region->rects = &region->extents;
+     region->extents.x1 = x;
+     region->extents.y1 = y;
+     region->extents.x2 = x + w;
+     region->extents.y2 = y + h;
+     region->size = 1;
+}
+
+static inline void
+temp_region_reset( GdkRegion *region )
+{
+     if (region->size > 32 && region->rects && region->rects != &region->extents) {
+          g_free( region->rects );
+
+          region->size  = 1;
+          region->rects = &region->extents;
+     }
+
+     region->numRects = 0;
+}
+
+static inline void
+temp_region_deinit( GdkRegion *region )
+{
+     if (region->rects && region->rects != &region->extents) {
+          g_free( region->rects );
+          region->rects = NULL;
+     }
+
+     region->numRects = 0;
+}
+
+
+#define GDKDFB_RECTANGLE_VALS_FROM_BOX(s)   (s)->x1, (s)->y1, (s)->x2-(s)->x1, (s)->y2-(s)->y1
+
 
 #endif /* __GDK_PRIVATE_DIRECTFB_H__ */
diff -puraN gtk+-2.12.9/gdk/directfb/gdkvisual-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkvisual-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkvisual-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkvisual-directfb.c	2008-05-21 20:20:24.000000000 +0200
@@ -55,18 +55,18 @@ static GdkVisualDirectFB * gdk_directfb_
 static DFBSurfacePixelFormat formats[] =
 {
   DSPF_ARGB,
-  DSPF_LUT8,
   DSPF_RGB32,
   DSPF_RGB24,
   DSPF_RGB16,
   DSPF_ARGB1555,
-  DSPF_RGB332
+  DSPF_LUT8,
+  DSPF_RGB332,
 };
 
-GdkVisual         * system_visual = NULL;
-static GdkVisualDirectFB * visuals[G_N_ELEMENTS (formats) + 1] = { NULL };
-static gint                available_depths[G_N_ELEMENTS (formats) + 1] = {0};
-static GdkVisualType       available_types[G_N_ELEMENTS (formats) + 1]  = {0};
+static GdkVisualDirectFB *system_visual;
+static GdkVisualDirectFB *visuals[G_N_ELEMENTS (formats) + 1] = { NULL };
+static gint               available_depths[G_N_ELEMENTS (formats) + 1] = {0};
+static GdkVisualType      available_types[G_N_ELEMENTS (formats) + 1]  = {0};
 
 
 static void
@@ -112,7 +112,6 @@ gdk_visual_get_type (void)
 void
 _gdk_visual_init ()
 {
-  DFBResult              ret;
   DFBDisplayLayerConfig  dlc;
   DFBSurfaceDescription  desc;
   IDirectFBSurface      *dest;
@@ -143,63 +142,67 @@ _gdk_visual_init ()
       IDirectFBSurface    *src;
       DFBAccelerationMask  acc;
 
-      desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
+      desc.flags       = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT;
       desc.width       = 8;
       desc.height      = 8;
       desc.pixelformat = formats[i];
-      //call direct so fail silently  is ok
-      if (_gdk_display->directfb->CreateSurface (_gdk_display->directfb,
-	 &desc, &src) != DFB_OK) 
+
+      /* call direct so fail silently is ok */
+      if (_gdk_display->directfb->CreateSurface (_gdk_display->directfb, &desc, &src) != DFB_OK) 
         continue;
 
-      visuals[i] = gdk_directfb_visual_create (formats[i]);
+      visuals[c] = gdk_directfb_visual_create (formats[i]);
 
       dest->GetAccelerationMask (dest, src, &acc);
 
-      if (acc & DFXL_BLIT || formats[i] == dlc.pixelformat)
-        {
-            system_visual = GDK_VISUAL (visuals[c]);
-          c++;
-        }
+      if (formats[i] == dlc.pixelformat || (acc & DFXL_BLIT && !system_visual))
+        system_visual = visuals[c];
+
+      c++;
 
       src->Release (src);
     }
 
   dest->Release (dest);
 
-  //fallback to ARGB must be supported
   if (!system_visual)
     {
-       g_assert (visuals[DSPF_ARGB] != NULL);
-       system_visual = GDK_VISUAL(visuals[DSPF_ARGB]);
+      g_assert( GDK_IS_VISUAL(visuals[0]) );
+
+      system_visual = visuals[0];
     }
 
   g_assert (system_visual != NULL);
+  extern const char *dfb_pixelformat_name( DFBSurfacePixelFormat format );
+  D_INFO( "GDK/DirectFB: System visual %s\n", dfb_pixelformat_name( system_visual->format ) );
 }
 
 gint
 gdk_visual_get_best_depth (void)
 {
-  return system_visual->depth;
+  return system_visual->visual.depth;
 }
 
 GdkVisualType
 gdk_visual_get_best_type (void)
 {
-  return system_visual->type;
+  return system_visual->visual.type;
 }
 
 GdkVisual*
 gdk_screen_get_system_visual (GdkScreen *screen)
 {
   g_assert( system_visual);
-  return system_visual;
+
+  return GDK_VISUAL (system_visual);
 }
 
 GdkVisual*
 gdk_visual_get_best (void)
 {
-  return system_visual;
+  g_assert( system_visual);
+
+  return GDK_VISUAL (system_visual);
 }
 
 GdkVisual*
@@ -254,7 +257,9 @@ gdk_visual_get_best_with_both (gint     
       }
     }
 
-  return system_visual;
+  g_assert( system_visual);
+
+  return GDK_VISUAL (system_visual);
 }
 
 void
@@ -398,7 +403,10 @@ gdk_directfb_visual_create (DFBSurfacePi
       break;
 
     case DSPF_RGB332:
-      visual->type         = GDK_VISUAL_STATIC_COLOR;
+      visual->type         = GDK_VISUAL_TRUE_COLOR;
+      visual->red_mask     = 0x000000E0;
+      visual->green_mask   = 0x0000001C;
+      visual->blue_mask    = 0x00000003;
       visual->bits_per_rgb = 3;
       break;
 
diff -puraN gtk+-2.12.9/gdk/directfb/gdkwindow-directfb.c gtk+-2.12.9-dok2/gdk/directfb/gdkwindow-directfb.c
--- gtk+-2.12.9/gdk/directfb/gdkwindow-directfb.c	2008-03-12 05:17:24.000000000 +0100
+++ gtk+-2.12.9-dok2/gdk/directfb/gdkwindow-directfb.c	2008-05-21 20:23:19.000000000 +0200
@@ -46,6 +46,19 @@
 #include "cairo.h"
 #include <assert.h>
 
+#include <direct/debug.h>
+
+#include <directfb_util.h>
+
+
+
+
+
+D_DEBUG_DOMAIN( GDKDFB_Updates,   "GDKDFB/Updates",   "GDK DirectFB Updates" );
+D_DEBUG_DOMAIN( GDKDFB_Paintable, "GDKDFB/Paintable", "GDK DirectFB Paintable" );
+D_DEBUG_DOMAIN( GDKDFB_Window,    "GDKDFB/Window",    "GDK DirectFB Window" );
+
+
 static GdkRegion * gdk_window_impl_directfb_get_visible_region (GdkDrawable *drawable);
 static void        gdk_window_impl_directfb_set_colormap       (GdkDrawable *drawable,
                                                                 GdkColormap *colormap);
@@ -69,8 +82,8 @@ static guint update_idle = 0;
 static void
 gdk_window_directfb_process_all_updates (void)
 {
+  GSList *tmp_list;
   GSList *old_update_windows = update_windows;
-  GSList *tmp_list = update_windows;
 
   if (update_idle)
     g_source_remove (update_idle);
@@ -78,23 +91,72 @@ gdk_window_directfb_process_all_updates 
   update_windows = NULL;
   update_idle = 0;
 
-  g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
+  D_DEBUG_AT( GDKDFB_Updates, "%s()\n", __FUNCTION__ );
   
+  g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
+  tmp_list = old_update_windows;
   while (tmp_list)
     {
-      GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
+      GdkWindowObject       *private = GDK_WINDOW_OBJECT( tmp_list->data );
+      GdkWindowImplDirectFB *wimpl   = GDK_WINDOW_IMPL_DIRECTFB( private->impl );
       
       if (private->update_freeze_count)
-	update_windows = g_slist_prepend (update_windows, private);
+        {
+          D_DEBUG_AT( GDKDFB_Updates, "  -> %p fRoZeN [%4d,%4d-%4dx%4d] (%d boxes)\n",
+                      private, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ),
+                      wimpl->flips.num_regions );
+          update_windows = g_slist_prepend (update_windows, private);
+        }
       else
-	gdk_window_process_updates(tmp_list->data,TRUE);
+        {
+          D_DEBUG_AT( GDKDFB_Updates, "  -> %p update [%4d,%4d-%4dx%4d] (%d boxes)\n",
+                      private, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ),
+                      wimpl->flips.num_regions );
+          gdk_window_process_updates(tmp_list->data,TRUE);
+        }
       
       g_object_unref (tmp_list->data);
       tmp_list = tmp_list->next;
     }
 
-  g_slist_free (old_update_windows);
+#ifndef GDK_DIRECTFB_NO_EXPERIMENTS
+  g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
+  tmp_list = old_update_windows;
+  while (tmp_list)
+    {
+      GdkWindow *win = tmp_list->data;
+
+      if (!GDK_WINDOW_DESTROYED(win))
+        {
+          GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( win ) );
+
+          if (top)
+            {
+              GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
+
+              if (wimpl->flips.num_regions)
+                {
+                  D_DEBUG_AT( GDKDFB_Updates, "  -> %p flip   [%4d,%4d-%4dx%4d] (%d boxes)\n",
+                              top, DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ),
+                              wimpl->flips.num_regions );
+
+                  wimpl->drawable.surface->Flip( wimpl->drawable.surface, &wimpl->flips.bounding, DSFLIP_NONE );
+
+                  dfb_updates_reset( &wimpl->flips );
+                }
+              else
+                D_DEBUG_AT( GDKDFB_Updates, "  -> %p has no flips!\n", top );
+            }
+          else
+            D_DEBUG_AT( GDKDFB_Updates, "  -> %p has no top level window!\n", tmp_list->data );
+        }
+
+      g_object_unref (tmp_list->data);
+      tmp_list = tmp_list->next;
+    }
+#endif
 
+  g_slist_free (old_update_windows);
 }
 
 static gboolean
@@ -108,6 +170,9 @@ gdk_window_update_idle (gpointer data)
 static void
 gdk_window_schedule_update (GdkWindow *window)
 {
+  D_DEBUG_AT( GDKDFB_Updates, "%s( %p ) <- freeze count %d\n", __FUNCTION__, window,
+              window ? GDK_WINDOW_OBJECT (window)->update_freeze_count : -1 );
+  
   if (window && GDK_WINDOW_OBJECT (window)->update_freeze_count)
     return;
 
@@ -115,14 +180,15 @@ gdk_window_schedule_update (GdkWindow *w
     {
       update_idle = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
 				     gdk_window_update_idle, NULL, NULL);
+      D_DEBUG_AT( GDKDFB_Updates, "  -> adding idle callback\n" );
+
     }
 }
 
 
-static GdkWindow *gdk_directfb_window_containing_pointer = NULL;
-static GdkWindow *gdk_directfb_focused_window            = NULL;
-static gpointer   parent_class                           = NULL;
-GdkWindow * _gdk_parent_root = NULL;
+static GdkWindow *gdk_directfb_focused_window  = NULL;
+static gpointer   parent_class                 = NULL;
+
 static void
 gdk_window_impl_directfb_paintable_init (GdkPaintableIface *iface);
 
@@ -220,6 +286,8 @@ gdk_window_impl_directfb_finalize (GObje
 {
   GdkWindowImplDirectFB *impl = GDK_WINDOW_IMPL_DIRECTFB (object);
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p ) <- %dx%d\n", __FUNCTION__, impl, impl->drawable.width, impl->drawable.height );
+
   if (GDK_WINDOW_IS_MAPPED (impl->drawable.wrapper))
     gdk_window_hide (impl->drawable.wrapper);
 
@@ -249,12 +317,17 @@ gdk_window_impl_directfb_get_visible_reg
   GdkRectangle             rect = { 0, 0, 0, 0 };
   DFBRectangle             drect = { 0, 0, 0, 0 };
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, drawable );
+
   if (priv->surface)
   priv->surface->GetVisibleRectangle (priv->surface, &drect);
   rect.x= drect.x;
   rect.y= drect.y;
   rect.width=drect.w;
   rect.height=drect.h;
+
+  D_DEBUG_AT( GDKDFB_Window, "  -> returning %4d,%4d-%4dx%4d\n", drect.x, drect.y, drect.w, drect.h );
+
   return gdk_region_rectangle (&rect);
 }
 
@@ -287,6 +360,8 @@ create_directfb_window (GdkWindowImplDir
   DFBResult        ret;
   IDirectFBWindow *window;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %4dx%4d, caps 0x%08x )\n", __FUNCTION__, desc->width, desc->height, desc->caps );
+
   ret = _gdk_display->layer->CreateWindow (_gdk_display->layer, desc, &window);
 
   if (ret != DFB_OK)
@@ -311,6 +386,12 @@ create_directfb_window (GdkWindowImplDir
 
   impl->window = window;
 
+#ifndef GDK_DIRECTFB_NO_EXPERIMENTS
+  //direct_log_printf( NULL, "Initializing (window %p, wimpl %p)\n", win, impl );
+
+  dfb_updates_init( &impl->flips, impl->flip_regions, G_N_ELEMENTS(impl->flip_regions) );
+#endif
+
   return TRUE;
 }
 
@@ -333,7 +414,7 @@ _gdk_windowing_window_init (void)
   private->window_type = GDK_WINDOW_ROOT;
   private->state       = 0;
   private->children    = NULL;
-  impl->drawable.paint_region   = NULL;
+//  impl->drawable.paint_region   = NULL;
   impl->gdkWindow      = _gdk_parent_root;
   impl->window           = NULL;
   impl->drawable.abs_x   = 0;
@@ -390,6 +471,8 @@ gdk_directfb_window_new (GdkWindow      
 
   g_return_val_if_fail (attributes != NULL, NULL);
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, parent );
+
   if (!parent || attributes->window_type != GDK_WINDOW_CHILD)
     parent = _gdk_parent_root;
 
@@ -572,6 +655,8 @@ gdk_window_new (GdkWindow     *parent,
 {
   g_return_val_if_fail (attributes != NULL, NULL);
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, parent );
+
   return gdk_directfb_window_new (parent, attributes, attributes_mask,
                                   DWCAPS_NONE, DWOP_NONE, DSCAPS_NONE);
 }
@@ -596,6 +681,9 @@ _gdk_windowing_window_destroy (GdkWindow
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p, %srecursing, %sforeign )\n", __FUNCTION__, window,
+              recursing ? "" : "not ", foreign_destroy ? "" : "no " );
+
   private = GDK_WINDOW_OBJECT (window);
   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
 
@@ -637,6 +725,8 @@ gdk_window_destroy_notify (GdkWindow *wi
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
+
   if (!GDK_WINDOW_DESTROYED (window))
     {
       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
@@ -684,6 +774,7 @@ gdk_directfb_change_focus (GdkWindow *ne
   GdkWindow     *new_win;
   GdkWindow     *event_win;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, new_focus_window );
 
   /* No focus changes while the pointer is grabbed */
   if (_gdk_directfb_pointer_grab_window)
@@ -759,6 +850,8 @@ gdk_directfb_window_raise (GdkWindow *wi
 {
   GdkWindowObject *parent;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
+
   parent = GDK_WINDOW_OBJECT (window)->parent;
 
   if (parent->children->data == window)
@@ -775,6 +868,8 @@ gdk_directfb_window_lower (GdkWindow *wi
 {
   GdkWindowObject *parent;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
+
   parent = GDK_WINDOW_OBJECT (window)->parent;
 
   parent->children = g_list_remove (parent->children, window);
@@ -804,6 +899,8 @@ send_map_events (GdkWindowObject *privat
   if (!GDK_WINDOW_IS_MAPPED (private))
     return;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, private );
+
   event_win = gdk_directfb_other_event_window ((GdkWindow *) private, GDK_MAP);
   if (event_win)
     gdk_directfb_event_make (event_win, GDK_MAP);
@@ -812,257 +909,14 @@ send_map_events (GdkWindowObject *privat
     send_map_events (list->data);
 }
 
-static GdkWindow *
-gdk_directfb_find_common_ancestor (GdkWindow *win1,
-                                   GdkWindow *win2)
-{
-  GdkWindowObject *a;
-  GdkWindowObject *b;
-
-  for (a = GDK_WINDOW_OBJECT (win1); a; a = a->parent)
-    for (b = GDK_WINDOW_OBJECT (win2); b; b = b->parent)
-      {
-        if (a == b)
-          return GDK_WINDOW (a);
-      }
-
-  return NULL;
-}
-
-void
-gdk_directfb_window_send_crossing_events (GdkWindow       *src,
-                                          GdkWindow       *dest,
-                                          GdkCrossingMode  mode)
-{
-  GdkWindow       *c;
-  GdkWindow       *win, *last, *next;
-  GdkEvent        *event;
-  gint             x, y, x_int, y_int;
-  GdkModifierType  modifiers;
-  GSList          *path, *list;
-  gboolean         non_linear;
-  GdkWindow       *a;
-  GdkWindow       *b;
-  GdkWindow       *event_win;
-
-  /* Do a possible cursor change before checking if we need to
-     generate crossing events so cursor changes due to pointer
-     grabs work correctly. */
-  {
-    static GdkCursorDirectFB *last_cursor = NULL;
-
-    GdkWindowObject       *private = GDK_WINDOW_OBJECT (dest);
-    GdkWindowImplDirectFB *impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
-    GdkCursorDirectFB     *cursor;
-
-    if (_gdk_directfb_pointer_grab_cursor)
-      cursor = (GdkCursorDirectFB*) _gdk_directfb_pointer_grab_cursor;
-    else
-      cursor = (GdkCursorDirectFB*) impl->cursor;
-
-    if (cursor != last_cursor)
-      {
-        win     = gdk_directfb_window_find_toplevel (dest);
-        private = GDK_WINDOW_OBJECT (win);
-        impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
-
-        if (impl->window)
-          impl->window->SetCursorShape (impl->window,
-                                        cursor->shape,
-                                        cursor->hot_x, cursor->hot_y);
-        last_cursor = cursor;
-      }
-  }
-
-  if (dest == gdk_directfb_window_containing_pointer)
-    return;
-
-  if (gdk_directfb_window_containing_pointer == NULL)
-    gdk_directfb_window_containing_pointer = g_object_ref (_gdk_parent_root);
-
-  if (src)
-    a = src;
-  else
-    a = gdk_directfb_window_containing_pointer;
-
-  b = dest;
-
-  if (a == b)
-    return;
-
-  /* gdk_directfb_window_containing_pointer might have been destroyed.
-   * The refcount we hold on it should keep it, but it's parents
-   * might have died.
-   */
-  if (GDK_WINDOW_DESTROYED (a))
-    a = _gdk_parent_root;
-
-  gdk_directfb_mouse_get_info (&x, &y, &modifiers);
-
-  c = gdk_directfb_find_common_ancestor (a, b);
-
-  non_linear = (c != a) && (c != b);
-
-  event_win = gdk_directfb_pointer_event_window (a, GDK_LEAVE_NOTIFY);
-  if (event_win)
-    {
-      event = gdk_directfb_event_make (event_win, GDK_LEAVE_NOTIFY);
-      event->crossing.subwindow = NULL;
-
-      gdk_window_get_origin (a, &x_int, &y_int);
-
-      event->crossing.x      = x - x_int;
-      event->crossing.y      = y - y_int;
-      event->crossing.x_root = x;
-      event->crossing.y_root = y;
-      event->crossing.mode   = mode;
-
-      if (non_linear)
-        event->crossing.detail = GDK_NOTIFY_NONLINEAR;
-      else if (c == a)
-        event->crossing.detail = GDK_NOTIFY_INFERIOR;
-      else
-        event->crossing.detail = GDK_NOTIFY_ANCESTOR;
-
-      event->crossing.focus = FALSE;
-      event->crossing.state = modifiers;
-    }
-
-   /* Traverse up from a to (excluding) c */
-  if (c != a)
-    {
-      last = a;
-      win = GDK_WINDOW (GDK_WINDOW_OBJECT (a)->parent);
-      while (win != c)
-        {
-          event_win =
-            gdk_directfb_pointer_event_window (win, GDK_LEAVE_NOTIFY);
-
-          if (event_win)
-            {
-              event = gdk_directfb_event_make (event_win, GDK_LEAVE_NOTIFY);
-
-              event->crossing.subwindow = g_object_ref (last);
-
-              gdk_window_get_origin (win, &x_int, &y_int);
-
-              event->crossing.x      = x - x_int;
-              event->crossing.y      = y - y_int;
-              event->crossing.x_root = x;
-              event->crossing.y_root = y;
-              event->crossing.mode   = mode;
-
-              if (non_linear)
-                event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
-              else
-                event->crossing.detail = GDK_NOTIFY_VIRTUAL;
-
-              event->crossing.focus = FALSE;
-              event->crossing.state = modifiers;
-            }
-
-          last = win;
-          win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
-        }
-    }
-
-  /* Traverse down from c to b */
-  if (c != b)
-    {
-      path = NULL;
-      win = GDK_WINDOW (GDK_WINDOW_OBJECT (b)->parent);
-      while (win != c)
-        {
-          path = g_slist_prepend (path, win);
-          win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent);
-        }
-
-      list = path;
-      while (list)
-        {
-          win = GDK_WINDOW (list->data);
-          list = g_slist_next (list);
-
-          if (list)
-            next = GDK_WINDOW (list->data);
-          else
-            next = b;
-
-          event_win =
-            gdk_directfb_pointer_event_window (win, GDK_ENTER_NOTIFY);
-
-          if (event_win)
-            {
-              event = gdk_directfb_event_make (event_win, GDK_ENTER_NOTIFY);
-
-              event->crossing.subwindow = g_object_ref (next);
-
-              gdk_window_get_origin (win, &x_int, &y_int);
-
-              event->crossing.x      = x - x_int;
-              event->crossing.y      = y - y_int;
-              event->crossing.x_root = x;
-              event->crossing.y_root = y;
-              event->crossing.mode   = mode;
-
-              if (non_linear)
-                event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
-              else
-                event->crossing.detail = GDK_NOTIFY_VIRTUAL;
-
-              event->crossing.focus = FALSE;
-              event->crossing.state = modifiers;
-            }
-        }
-
-      g_slist_free (path);
-    }
-
-  event_win = gdk_directfb_pointer_event_window (b, GDK_ENTER_NOTIFY);
-  if (event_win)
-    {
-      event = gdk_directfb_event_make (event_win, GDK_ENTER_NOTIFY);
-
-      event->crossing.subwindow = NULL;
-
-      gdk_window_get_origin (b, &x_int, &y_int);
-
-      event->crossing.x      = x - x_int;
-      event->crossing.y      = y - y_int;
-      event->crossing.x_root = x;
-      event->crossing.y_root = y;
-      event->crossing.mode   = mode;
-
-      if (non_linear)
-        event->crossing.detail = GDK_NOTIFY_NONLINEAR;
-      else if (c==a)
-        event->crossing.detail = GDK_NOTIFY_ANCESTOR;
-      else
-        event->crossing.detail = GDK_NOTIFY_INFERIOR;
-
-      event->crossing.focus = FALSE;
-      event->crossing.state = modifiers;
-    }
-
-  if (mode != GDK_CROSSING_GRAB)
-    {
-      //this seems to cause focus to change as the pointer moves yuck
-      //gdk_directfb_change_focus (b);
-      if (b != gdk_directfb_window_containing_pointer)
-        {
-          g_object_unref (gdk_directfb_window_containing_pointer);
-          gdk_directfb_window_containing_pointer = g_object_ref (b);
-        }
-    }
-}
-
 static void
 show_window_internal (GdkWindow *window,
                       gboolean   raise)
 {
   GdkWindowObject       *private;
   GdkWindowImplDirectFB *impl;
-  GdkWindow             *mousewin;
+
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p, %sraise )\n", __FUNCTION__, window, raise ? "" : "no " );
 
   private = GDK_WINDOW_OBJECT (window);
   impl = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
@@ -1078,10 +932,6 @@ show_window_internal (GdkWindow *window,
         {
           send_map_events (private);
 
-          mousewin = gdk_window_at_pointer (NULL, NULL);
-          gdk_directfb_window_send_crossing_events (NULL, mousewin,
-                                                    GDK_CROSSING_NORMAL);
-
           if (private->input_only)
             return;
 
@@ -1105,6 +955,8 @@ gdk_window_show_unraised (GdkWindow *win
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
+
   show_window_internal (window, FALSE);
 }
 
@@ -1113,6 +965,8 @@ gdk_window_show (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
+
   show_window_internal (window, TRUE);
 }
 
@@ -1121,11 +975,12 @@ gdk_window_hide (GdkWindow *window)
 {
   GdkWindowObject       *private;
   GdkWindowImplDirectFB *impl;
-  GdkWindow             *mousewin;
   GdkWindow             *event_win;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
+
   private = GDK_WINDOW_OBJECT (window);
   impl    = GDK_WINDOW_IMPL_DIRECTFB (private->impl);
 
@@ -1151,11 +1006,6 @@ gdk_window_hide (GdkWindow *window)
       if (event_win)
         event = gdk_directfb_event_make (event_win, GDK_UNMAP);
 
-      mousewin = gdk_window_at_pointer (NULL, NULL);
-      gdk_directfb_window_send_crossing_events (NULL,
-                                                mousewin,
-                                                GDK_CROSSING_NORMAL);
-
       if (window == _gdk_directfb_pointer_grab_window)
         gdk_pointer_ungrab (GDK_CURRENT_TIME);
       if (window == _gdk_directfb_keyboard_grab_window)
@@ -1203,16 +1053,10 @@ gdk_window_move (GdkWindow *window,
 
       if (GDK_WINDOW_IS_MAPPED (private))
         {
-          GdkWindow    *mousewin;
           GdkRectangle  new = { x, y, width, height };
 
           gdk_rectangle_union (&new, &old, &new);
           gdk_window_invalidate_rect (GDK_WINDOW (private->parent), &new,TRUE);
-
-          /* The window the pointer is in might have changed */
-          mousewin = gdk_window_at_pointer (NULL, NULL);
-          gdk_directfb_window_send_crossing_events (NULL, mousewin,
-                                                    GDK_CROSSING_NORMAL);
         }
     }
 }
@@ -1360,16 +1204,10 @@ gdk_window_move_resize (GdkWindow *windo
 
       if (GDK_WINDOW_IS_MAPPED (private))
         {
-          GdkWindow    *mousewin;
           GdkRectangle  new = { x, y, width, height };
 
           gdk_rectangle_union (&new, &old, &new);
           gdk_window_invalidate_rect (GDK_WINDOW (private->parent), &new,TRUE);
-
-          /* The window the pointer is in might have changed */
-          mousewin = gdk_window_at_pointer (NULL, NULL);
-          gdk_directfb_window_send_crossing_events (NULL, mousewin,
-                                                    GDK_CROSSING_NORMAL);
         }
     }
 }
@@ -1490,11 +1328,15 @@ _gdk_windowing_window_clear_area (GdkWin
   gint                     dx = 0;
   gint                     dy = 0;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p, %4d,%4d-%4dx%4d )\n", __FUNCTION__, window, x, y, width, height );
+
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  if (GDK_WINDOW_DESTROYED (window))
+  if (GDK_WINDOW_DESTROYED (window)) {
+    D_DEBUG_AT( GDKDFB_Window, "  -> DESTROYED!\n" );
     return;
-
+  }
+   
   private = GDK_WINDOW_OBJECT (window);
 
   impl = GDK_DRAWABLE_IMPL_DIRECTFB (private->impl);
@@ -1518,8 +1360,10 @@ _gdk_windowing_window_clear_area (GdkWin
       dy += relative_to->y;
     }
 
-  if (bg_pixmap == GDK_NO_BG)
+  if (bg_pixmap == GDK_NO_BG) {
+    D_DEBUG_AT( GDKDFB_Window, "  -> NO BG\n" );
     return;
+  }
 
   if (bg_pixmap && bg_pixmap != GDK_PARENT_RELATIVE_BG)
     {
@@ -1530,6 +1374,8 @@ _gdk_windowing_window_clear_area (GdkWin
       values.ts_x_origin = - dx;
       values.ts_y_origin = - dy;
 
+      D_DEBUG_AT( GDKDFB_Window, "  -> PIXMAP\n" );
+
       gc = gdk_gc_new_with_values (GDK_DRAWABLE (impl), &values,
                                    GDK_GC_FILL | GDK_GC_TILE |
                                    GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
@@ -1543,6 +1389,8 @@ _gdk_windowing_window_clear_area (GdkWin
 
       values.foreground = relative_to->bg_color;
 
+      D_DEBUG_AT( GDKDFB_Window, "  -> COLOR\n" );
+
       gc = gdk_gc_new_with_values (GDK_DRAWABLE (impl), &values,
                                    GDK_GC_FOREGROUND);
     }
@@ -1565,6 +1413,8 @@ _gdk_windowing_window_clear_area_e (GdkW
   GdkWindowObject       *private;
   GdkWindowImplDirectFB *impl;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p, %4d,%4d-%4dx%4d )\n", __FUNCTION__, window, x, y, width, height );
+
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   private = GDK_WINDOW_OBJECT (window);
@@ -1585,8 +1435,10 @@ _gdk_windowing_window_clear_area_e (GdkW
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  if (GDK_WINDOW_DESTROYED (window))
+  if (GDK_WINDOW_DESTROYED (window)) {
+    D_DEBUG_AT( GDKDFB_Window, "  -> DESTROYED!\n" );
     return;
+  }
 
   _gdk_windowing_window_clear_area (window, x, y, width, height);
 
@@ -1598,6 +1450,8 @@ gdk_window_raise (GdkWindow *window)
 {
   GdkWindowImplDirectFB *impl;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
+
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -1627,6 +1481,8 @@ gdk_window_lower (GdkWindow *window)
 {
   GdkWindowImplDirectFB *impl;
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p )\n", __FUNCTION__, window );
+
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -1759,6 +1615,8 @@ gdk_window_set_background (GdkWindow *wi
 
   g_return_if_fail (color != NULL);
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p, %d,%d,%d )\n", __FUNCTION__, window, color->red, color->green, color->blue );
+
   private = GDK_WINDOW_OBJECT (window);
   private->bg_color = *color;
 
@@ -1781,6 +1639,9 @@ gdk_window_set_back_pixmap (GdkWindow *w
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (pixmap == NULL || !parent_relative);
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p, %p, %srelative )\n", __FUNCTION__,
+              window, pixmap, parent_relative ? "" : "not " );
+
   private = GDK_WINDOW_OBJECT (window);
   old_pixmap = private->bg_pixmap;
 
@@ -1797,10 +1658,15 @@ gdk_window_set_back_pixmap (GdkWindow *w
     }
   else
     {
-      if (pixmap && pixmap != GDK_NO_BG && pixmap != GDK_PARENT_RELATIVE_BG)
-        g_object_ref (pixmap);
-
-      private->bg_pixmap = pixmap;
+      if (pixmap)
+        {
+          g_object_ref (pixmap);
+          private->bg_pixmap = pixmap;
+        }
+      else
+        {
+          private->bg_pixmap = GDK_NO_BG;
+        }
     }
 }
 
@@ -1821,12 +1687,7 @@ gdk_window_set_cursor (GdkWindow *window
 
   if (gdk_window_at_pointer (NULL, NULL) == window)
     {
-      /* This is a bit evil but we want to keep all cursor changes in
-         one place, so let gdk_directfb_window_send_crossing_events
-         do the work for us. */
-
-      gdk_directfb_window_send_crossing_events (window, window,
-                                                GDK_CROSSING_NORMAL);
+      _gdk_directfb_events_update_cursor (window);
     }
   else if (impl->window)
     {
@@ -1902,6 +1763,8 @@ _gdk_directfb_calc_abs (GdkWindow *windo
       impl->abs_y += parent_impl->abs_y;
     }
 
+  D_DEBUG_AT( GDKDFB_Window, "%s( %p ) -> %4d,%4d\n", __FUNCTION__, window, impl->abs_x, impl->abs_y );
+
   for (list = private->children; list; list = list->next)
     {
       _gdk_directfb_calc_abs (list->data);
@@ -2410,8 +2273,7 @@ gdk_window_set_functions (GdkWindow     
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  /* N/A */
-  g_message("unimplemented %s", G_STRLOC);
+  D_UNIMPLEMENTED();
 }
 
 void
@@ -2443,8 +2305,7 @@ gdk_window_set_static_gravities (GdkWind
   if (GDK_WINDOW_DESTROYED (window))
     return FALSE;
 
-  /* N/A */
-  g_message("unimplemented %s", G_STRLOC);
+  D_UNIMPLEMENTED();
 
   return FALSE;
 }
@@ -2462,7 +2323,7 @@ gdk_window_begin_resize_drag (GdkWindow 
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  g_message("unimplemented %s", G_STRLOC);
+  D_UNIMPLEMENTED();
 }
 
 void
@@ -2477,7 +2338,7 @@ gdk_window_begin_move_drag (GdkWindow *w
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  g_message("unimplemented %s", G_STRLOC);
+  D_UNIMPLEMENTED();
 }
 
 /**
@@ -2708,48 +2569,44 @@ void
 gdk_window_fullscreen (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
-  g_warning ("gdk_window_fullscreen() not implemented.\n");
+
+  D_UNIMPLEMENTED();
 }
 
 void
 gdk_window_unfullscreen (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
-  /* g_warning ("gdk_window_unfullscreen() not implemented.\n");*/
+
+  D_UNIMPLEMENTED();
 }
 
 void
 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
-  static gboolean first_call = TRUE;
-  if (first_call) {
-  g_warning ("gdk_window_set_keep_above() not implemented.\n");
-	first_call=FALSE;
-  }
-	
+
+  D_UNIMPLEMENTED();
 }
 
 void
 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
-  static gboolean first_call = TRUE;
-  if (first_call) {
-  g_warning ("gdk_window_set_keep_below() not implemented.\n");
-  first_call=FALSE;
-  }
-  
+
+  D_UNIMPLEMENTED();
 }
 
 void
 gdk_window_enable_synchronized_configure (GdkWindow *window)
 {
+  D_UNIMPLEMENTED();
 }
 
 void
 gdk_window_configure_finished (GdkWindow *window)
 {
+  D_UNIMPLEMENTED();
 }
 
 void
@@ -2758,7 +2615,7 @@ gdk_display_warp_pointer (GdkDisplay *di
                           gint        x,
                           gint        y)
 {
-  g_warning ("gdk_display_warp_pointer() not implemented.\n");
+  D_UNIMPLEMENTED();
 }
 
 void
@@ -2777,9 +2634,9 @@ gdk_window_set_urgency_hint (GdkWindow *
 
 static void
 gdk_window_impl_directfb_invalidate_maybe_recurse (GdkPaintable *paintable,
-                         GdkRegion    *region,
-                         gboolean    (*child_func) (GdkWindow *, gpointer),
-                         gpointer      user_data)
+                                                   GdkRegion    *region,
+                                                   gboolean    (*child_func) (GdkWindow *, gpointer),
+                                                   gpointer      user_data)
 {
   GdkWindow *window;
   GdkWindowObject *private;
@@ -2791,7 +2648,7 @@ gdk_window_impl_directfb_invalidate_mayb
   window = wimpl->gdkWindow;
   private = (GdkWindowObject *)window;
 
-  GdkRegion *visible_region;
+  GdkRegion visible_region;
   GList *tmp_list;
 
   g_return_if_fail (window != NULL);
@@ -2803,173 +2660,187 @@ gdk_window_impl_directfb_invalidate_mayb
   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
     return;
 
-  visible_region = gdk_drawable_get_visible_region (window);
-  gdk_region_intersect (visible_region, region);
+  D_DEBUG_AT( GDKDFB_Updates, "%s( %p ) <- [" GDKDFB_WIMPL_FORM "]\n", __FUNCTION__,
+              paintable, GDKDFB_WIMPL_V(wimpl) );
+
+  temp_region_init_rectangle_vals( &visible_region, 0, 0, impl->width, impl->height );
+  gdk_region_intersect (&visible_region, region);
 
   tmp_list = private->children;
   while (tmp_list)
     {
-      GdkWindowObject *child = tmp_list->data;
+      GdkWindowObject         *child = tmp_list->data;
+      GdkDrawableImplDirectFB *cimpl = (GdkDrawableImplDirectFB *) child->impl;
       
       if (!child->input_only)
-	{
-	  GdkRegion *child_region;
-	  GdkRectangle child_rect;
-	  
-	  gdk_window_get_position ((GdkWindow *)child,
-				   &child_rect.x, &child_rect.y);
-	  gdk_drawable_get_size ((GdkDrawable *)child,
-				 &child_rect.width, &child_rect.height);
-
-	  child_region = gdk_region_rectangle (&child_rect);
-	  
-	  /* remove child area from the invalid area of the parent */
-	  if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped)
-	    gdk_region_subtract (visible_region, child_region);
-	  
-	  if (child_func && (*child_func) ((GdkWindow *)child, user_data))
-	    {
-	      gdk_region_offset (region, - child_rect.x, - child_rect.y);
-	      gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
-	      gdk_region_intersect (child_region, region);
-	      
-	      gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
-						   child_region, child_func, user_data);
-	      
-	      gdk_region_offset (region, child_rect.x, child_rect.y);
-	    }
+        {
+          GdkRegion child_region;
+          
+          temp_region_init_rectangle_vals( &child_region, child->x, child->y, cimpl->width, cimpl->height );
+          
+          /* remove child area from the invalid area of the parent */
+          if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped)
+            gdk_region_subtract (&visible_region, &child_region);
+          
+          if (child_func && (*child_func) ((GdkWindow *)child, user_data))
+            {
+              gdk_region_intersect (&child_region, region);
+              gdk_region_offset (&child_region, - child->x, - child->y);
+              
+              gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
+                                                   &child_region, child_func, user_data);
+            }
 
-	  gdk_region_destroy (child_region);
-	}
+          temp_region_deinit( &child_region );
+        }
 
       tmp_list = tmp_list->next;
     }
   
-  if (!gdk_region_empty (visible_region))
+  if (!gdk_region_empty (&visible_region))
     {
       
       if (private->update_area)
-	{
-	  gdk_region_union (private->update_area, visible_region);
-	}
+        {
+          gdk_region_union (private->update_area, &visible_region);
+        }
       else
-	{
-	  update_windows = g_slist_prepend (update_windows, window);
-	  private->update_area = gdk_region_copy (visible_region);
-	  gdk_window_schedule_update (window);
-	}
+        {
+          update_windows = g_slist_prepend (update_windows, window);
+          private->update_area = gdk_region_copy (&visible_region);
+          gdk_window_schedule_update (window);
+        }
     }
-    gdk_region_destroy (visible_region);
+
+  temp_region_deinit( &visible_region );
 }
 
 
 static void
 gdk_window_impl_directfb_process_updates (GdkPaintable *paintable,
-                    gboolean      update_children)
+                                          gboolean      update_children)
 {
-  GdkWindow *window;
-  GdkWindowObject *private;
   GdkWindowImplDirectFB *wimpl;
   GdkDrawableImplDirectFB *impl;
+  GdkWindow               *window;
+  GdkWindowObject         *private;
+  GdkRegion               *update_area;
 
   wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable);
   impl = (GdkDrawableImplDirectFB *)wimpl;
   window = wimpl->gdkWindow;
   private = (GdkWindowObject *)window;
-  gboolean save_region = FALSE;
+
+  D_DEBUG_AT( GDKDFB_Updates, "%s( %p, %schildren ) <- [" GDKDFB_WIMPL_FORM "]\n", __FUNCTION__,
+              paintable, update_children ? "update " : "no ", GDKDFB_WIMPL_V(wimpl) );
 
   /* If an update got queued during update processing, we can get a
    * window in the update queue that has an empty update_area.
    * just ignore it.
    */
-  if (private->update_area)
-    {
-      GdkRegion *update_area = private->update_area;
-      private->update_area = NULL;
+  if (!private->update_area)
+    return;
+
+  update_area = private->update_area;
+  private->update_area = NULL;
       
-      if (_gdk_event_func && gdk_window_is_viewable (window))
-	{
-	  GdkRectangle window_rect;
-	  GdkRegion *expose_region;
-	  GdkRegion *window_region;
-          gint width, height;
-	  save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
+  D_DEBUG_AT( GDKDFB_Updates, "  -> update area    " GDKDFB_REGION_FORM "\n", GDKDFB_REGION_V(update_area) );
 
-	  if (save_region)
-	    expose_region = gdk_region_copy (update_area);
-	  else
-	    expose_region = update_area;
-	  
-          gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
-
-	  window_rect.x = 0;
-	  window_rect.y = 0;
-	  window_rect.width = width;
-	  window_rect.height = height;
-
-	  window_region = gdk_region_rectangle (&window_rect);
-	  gdk_region_intersect (expose_region,
-				window_region);
-	  gdk_region_destroy (window_region);
-	  
-	  if (!gdk_region_empty (expose_region) &&
-	      (private->event_mask & GDK_EXPOSURE_MASK))
-	    {
-	      GdkEvent event;
-	      
-	      event.expose.type = GDK_EXPOSE;
-	      event.expose.window = g_object_ref (window);
-	      event.expose.send_event = FALSE;
-	      event.expose.count = 0;
-	      event.expose.region = expose_region;
-	      gdk_region_get_clipbox (expose_region, &event.expose.area);
-	      (*_gdk_event_func) (&event, _gdk_event_data);
-	      
-	      g_object_unref (window);
-	    }
+  if (_gdk_event_func && gdk_window_is_viewable (window))
+    {
+      GdkRegion *expose_region = update_area;
+      GdkRegion  window_region;
+          
+      temp_region_init_rectangle_vals( &window_region, 0, 0, impl->width, impl->height );
+      gdk_region_intersect( expose_region, &window_region );
+      temp_region_deinit (&window_region);
+          
+      D_DEBUG_AT( GDKDFB_Updates, "  -> expose region  " GDKDFB_REGION_FORM "\n", GDKDFB_REGION_V(expose_region) );
 
-	  if (expose_region != update_area)
-	    gdk_region_destroy (expose_region);
-	}
-      if (!save_region)
-	gdk_region_destroy (update_area);
+      if (!gdk_region_empty (expose_region) && (private->event_mask & GDK_EXPOSURE_MASK))
+        {
+          GdkEvent event;
+              
+          event.expose.type = GDK_EXPOSE;
+          event.expose.window = g_object_ref (window);
+          event.expose.send_event = FALSE;
+          event.expose.count = 0;
+          event.expose.region = expose_region;
+          gdk_region_get_clipbox (expose_region, &event.expose.area);
+          (*_gdk_event_func) (&event, _gdk_event_data);
+              
+          g_object_unref (window);
+        }
+
+      if (expose_region != update_area)
+        gdk_region_destroy (expose_region);
     }
+
+  gdk_region_destroy (update_area);
 }
 
 
 static void
 gdk_window_impl_directfb_begin_paint_region (GdkPaintable *paintable,
-					   GdkRegion    *region)
+                                             GdkRegion    *region)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkWindowImplDirectFB *wimpl;
+  GdkWindowImplDirectFB   *wimpl;
   gint                     i;
 
-
-  g_assert (region != NULL );
   wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable);
-  impl = (GdkDrawableImplDirectFB *)wimpl;
-  impl->buffered = TRUE;
-  impl->paint_depth++;
+  impl  = (GdkDrawableImplDirectFB *)wimpl;
 
-  if (!region)
-    return;
+  g_return_if_fail (region != NULL);
 
-  if (impl->paint_region)
-    gdk_region_union (impl->paint_region, region);
+  D_DEBUG_AT( GDKDFB_Paintable, "%s( %p ) <- [" GDKDFB_WIMPL_FORM "] (%d)\n", __FUNCTION__, paintable,
+              GDKDFB_WIMPL_V(wimpl), impl->paint_depth );
+
+  /* When it's buffered... */
+  if (impl->buffered)
+    {
+      /* ...we're already painting on it! */
+      g_assert( impl->paint_depth > 0 );
+    
+      D_DEBUG_AT( GDKDFB_Updates, "  -> already        " GDKDFB_REGION_FORM "\n", GDKDFB_REGION_V(&impl->paint_region) );
+
+      /* Add the new region to the paint region... */
+      gdk_region_union (&impl->paint_region, region);
+    }
   else
-    impl->paint_region = gdk_region_copy (region);
+    {
+      /* ...otherwise it's the first time! */
+      g_assert( impl->paint_depth == 0 );
+
+      /* Generate the clip region for painting around child windows. */
+      gdk_directfb_clip_region( GDK_DRAWABLE(paintable), NULL, NULL, &impl->clip_region );
+
+      /* Initialize the paint region with the new one... */
+      temp_region_init_copy( &impl->paint_region, region );
+
+      impl->buffered = TRUE;
+    }
+
+  D_DEBUG_AT( GDKDFB_Updates, "  -> painting       " GDKDFB_REGION_FORM "\n", GDKDFB_REGION_V(&impl->paint_region) );
+
+  /* ...but clip the initial/compound result against the clip region. */
+  gdk_region_intersect (&impl->paint_region, &impl->clip_region);
+
+  D_DEBUG_AT( GDKDFB_Updates, "  -> clipped        " GDKDFB_REGION_FORM "\n", GDKDFB_REGION_V(&impl->paint_region) );
+
+  impl->paint_depth++;
 
   for (i = 0; i < region->numRects; i++)
     {
       GdkRegionBox *box = &region->rects[i];
 
+      D_DEBUG_AT( GDKDFB_Paintable, "  -> [%2d] %4d,%4d-%4dx%4d\n", i, GDKDFB_RECTANGLE_VALS_FROM_BOX( box ) );
+
       _gdk_windowing_window_clear_area (GDK_WINDOW(wimpl->gdkWindow),
                                         box->x1,
                                         box->y1,
                                         box->x2 - box->x1,
                                         box->y2 - box->y1);
-                                        
     }
 }
 
@@ -2977,29 +2848,76 @@ static void
 gdk_window_impl_directfb_end_paint (GdkPaintable *paintable)
 {
   GdkDrawableImplDirectFB *impl;
+  GdkWindowImplDirectFB   *wimpl;
+
+  wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable);
+  impl  = (GdkDrawableImplDirectFB *)wimpl;
 
-  impl = GDK_DRAWABLE_IMPL_DIRECTFB (paintable);
+  D_DEBUG_AT( GDKDFB_Paintable, "%s( %p ) <- [" GDKDFB_WIMPL_FORM "] (%d)\n", __FUNCTION__,
+              paintable, GDKDFB_WIMPL_V(wimpl), impl->paint_depth );
 
   g_return_if_fail (impl->paint_depth > 0);
 
+  g_assert( impl->buffered );
+
   impl->paint_depth--;
 
+#ifdef GDK_DIRECTFB_NO_EXPERIMENTS
   if (impl->paint_depth == 0)
     {
       impl->buffered = FALSE;
 
-      if (impl->paint_region)
+      if (impl->paint_region.numRects)
         {
-          DFBRegion reg = { impl->paint_region->extents.x1,
-                            impl->paint_region->extents.y1,
-                            impl->paint_region->extents.x2 ,
-                            impl->paint_region->extents.y2 };
-
-          impl->surface->Flip(impl->surface, &reg,0);
-          gdk_region_destroy (impl->paint_region);
-          impl->paint_region = NULL;
+          DFBRegion reg = { impl->paint_region.extents.x1,
+                            impl->paint_region.extents.y1,
+                            impl->paint_region.extents.x2-1,
+                            impl->paint_region.extents.y2-1 };
+
+          D_DEBUG_AT( GDKDFB_Paintable, "  -> flip           " DFB_REGION_FORM "\n", DFB_REGION_V(&reg) );
+
+          impl->surface->Flip( impl->surface, &reg, 0 );
+
+          temp_region_reset( &impl->paint_region );
         }
     }
+#else
+  if (impl->paint_depth == 0)
+    {
+      impl->buffered = FALSE;
+  
+      temp_region_deinit( &impl->clip_region );
+  
+      if (impl->paint_region.numRects)
+        {
+          GdkWindow *window = GDK_WINDOW( impl->wrapper );
+  
+          if (GDK_IS_WINDOW(window))
+            {
+              GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( window ) );
+  
+              if (top)
+                {
+                  DFBRegion              reg;
+                  GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
+  
+                  reg.x1 = impl->abs_x - top->x + impl->paint_region.extents.x1;
+                  reg.y1 = impl->abs_y - top->y + impl->paint_region.extents.y1;
+                  reg.x2 = impl->abs_x - top->x + impl->paint_region.extents.x2 - 1;
+                  reg.y2 = impl->abs_y - top->y + impl->paint_region.extents.y2 - 1;
+  
+                  D_DEBUG_AT( GDKDFB_Paintable, "  -> queue flip     " DFB_REGION_FORM "\n", DFB_REGION_V(&reg) );
+  
+                  dfb_updates_add( &wimpl->flips, &reg );
+                }
+            }
+  
+          temp_region_reset( &impl->paint_region );
+        }
+    }
+#endif
+  else
+    D_DEBUG_AT( GDKDFB_Paintable, "  -> depth is still %d\n", impl->paint_depth );
 }
 
 
