]> Pileus Git - ~andy/gtk/blobdiff - gdk/win32/gdkwindow-win32.c
win32: Ignore client requested window move/size during SIZEMOVE
[~andy/gtk] / gdk / win32 / gdkwindow-win32.c
index 9d029619ab37496013cac71b600505af74cf21d5..b08d74b570beb8b254d21ce7731ac7a98acc6f2c 100644 (file)
@@ -1,7 +1,8 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  * Copyright (C) 1998-2004 Tor Lillqvist
- * Copyright (C) 2001-2004 Hans Breuer
+ * Copyright (C) 2001-2011 Hans Breuer
+ * Copyright (C) 2007-2009 Cody Russell
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-#include <config.h>
+#include "config.h"
 #include <stdlib.h>
 
 #include "gdk.h"
+#include "gdkwindowimpl.h"
 #include "gdkprivate-win32.h"
-#include "gdkinput-win32.h"
+#include "gdkdeviceprivate.h"
+#include "gdkdevicemanager-win32.h"
+#include "gdkenumtypes.h"
+#include "gdkwin32.h"
+#include "gdkdisplayprivate.h"
+#include "gdkvisualprivate.h"
+#include "gdkwin32window.h"
 
-#if 0
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <stdio.h>
-#endif
+#include <cairo-win32.h>
 
-static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
-static void         gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
-                                                       GdkColormap *cmap);
-static void         gdk_window_impl_win32_get_size     (GdkDrawable *drawable,
-                                                       gint *width,
-                                                       gint *height);
-static GdkRegion*   gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable);
 static void gdk_window_impl_win32_init       (GdkWindowImplWin32      *window);
 static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
 static void gdk_window_impl_win32_finalize   (GObject                 *object);
 
 static gpointer parent_class = NULL;
+static GSList *modal_window_stack = NULL;
 
-static void     update_style_bits         (GdkWindow *window);
-static gboolean _gdk_window_get_functions (GdkWindow     *window,
-                                           GdkWMFunction *functions);
+static const cairo_user_data_key_t gdk_win32_cairo_key;
+
+static void     update_style_bits         (GdkWindow         *window);
+static gboolean _gdk_window_get_functions (GdkWindow         *window,
+                                           GdkWMFunction     *functions);
 
 #define WINDOW_IS_TOPLEVEL(window)                \
   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
-   GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
+   GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
+   GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
+
+GdkScreen *
+GDK_WINDOW_SCREEN (GObject *win)
+{
+  return _gdk_screen;
+}
+
+struct _GdkWin32Window {
+  GdkWindow parent;
+};
+
+struct _GdkWin32WindowClass {
+  GdkWindowClass parent_class;
+};
+
+G_DEFINE_TYPE (GdkWin32Window, gdk_win32_window, GDK_TYPE_WINDOW)
+
+static void
+gdk_win32_window_class_init (GdkWin32WindowClass *window_class)
+{
+}
+
+static void
+gdk_win32_window_init (GdkWin32Window *window)
+{
+}
+
+
+G_DEFINE_TYPE (GdkWindowImplWin32, gdk_window_impl_win32, GDK_TYPE_WINDOW_IMPL)
 
 GType
 _gdk_window_impl_win32_get_type (void)
@@ -66,7 +97,7 @@ _gdk_window_impl_win32_get_type (void)
 
   if (!object_type)
     {
-      static const GTypeInfo object_info =
+      const GTypeInfo object_info =
       {
         sizeof (GdkWindowImplWin32Class),
         (GBaseInitFunc) NULL,
@@ -78,8 +109,8 @@ _gdk_window_impl_win32_get_type (void)
         0,              /* n_preallocs */
         (GInstanceInitFunc) gdk_window_impl_win32_init,
       };
-      
-      object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_WIN32,
+
+      object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL,
                                             "GdkWindowImplWin32",
                                             &object_info, 0);
     }
@@ -87,17 +118,9 @@ _gdk_window_impl_win32_get_type (void)
   return object_type;
 }
 
-GType
-_gdk_window_impl_get_type (void)
-{
-  return _gdk_window_impl_win32_get_type ();
-}
-
 static void
 gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
 {
-  impl->width = 1;
-  impl->height = 1;
   impl->toplevel_window_type = -1;
   impl->hcursor = NULL;
   impl->hicon_big = NULL;
@@ -105,58 +128,44 @@ gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
   impl->hint_flags = 0;
   impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
   impl->extension_events_selected = FALSE;
-}
-
-static void
-gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
-  
-  parent_class = g_type_class_peek_parent (klass);
-
-  object_class->finalize = gdk_window_impl_win32_finalize;
-
-  drawable_class->set_colormap = gdk_window_impl_win32_set_colormap;
-  drawable_class->get_colormap = gdk_window_impl_win32_get_colormap;
-  drawable_class->get_size = gdk_window_impl_win32_get_size;
-
-  /* Visible and clip regions are the same */
-  drawable_class->get_clip_region = gdk_window_impl_win32_get_visible_region;
-  drawable_class->get_visible_region = gdk_window_impl_win32_get_visible_region;
+  impl->transient_owner = NULL;
+  impl->transient_children = NULL;
+  impl->num_transients = 0;
+  impl->changing_state = FALSE;
 }
 
 static void
 gdk_window_impl_win32_finalize (GObject *object)
 {
-  GdkWindowObject *wrapper;
-  GdkDrawableImplWin32 *draw_impl;
+  GdkWindow *wrapper;
   GdkWindowImplWin32 *window_impl;
   
   g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (object));
 
-  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (object);
   window_impl = GDK_WINDOW_IMPL_WIN32 (object);
   
-  wrapper = (GdkWindowObject*) draw_impl->wrapper;
+  wrapper = window_impl->wrapper;
 
   if (!GDK_WINDOW_DESTROYED (wrapper))
     {
-      gdk_win32_handle_table_remove (draw_impl->handle);
+      gdk_win32_handle_table_remove (window_impl->handle);
     }
 
   if (window_impl->hcursor != NULL)
     {
       if (GetCursor () == window_impl->hcursor)
        SetCursor (NULL);
+
       GDI_CALL (DestroyCursor, (window_impl->hcursor));
       window_impl->hcursor = NULL;
     }
+
   if (window_impl->hicon_big != NULL)
     {
       GDI_CALL (DestroyIcon, (window_impl->hicon_big));
       window_impl->hicon_big = NULL;
     }
+
   if (window_impl->hicon_small != NULL)
     {
       GDI_CALL (DestroyIcon, (window_impl->hicon_small));
@@ -177,117 +186,53 @@ _gdk_win32_adjust_client_rect (GdkWindow *window,
   API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
 }
 
-static GdkColormap*
-gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
-{
-  GdkDrawableImplWin32 *drawable_impl;
-  
-  g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
-
-  drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
-
-  if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only && 
-      drawable_impl->colormap == NULL)
-    {
-      drawable_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
-      g_object_ref (drawable_impl->colormap);
-    }
-  
-  return drawable_impl->colormap;
-}
-
-static void
-gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
-                                   GdkColormap *cmap)
-{
-  GdkWindowImplWin32 *impl;
-  GdkDrawableImplWin32 *draw_impl;
-  
-  g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
-
-  impl = GDK_WINDOW_IMPL_WIN32 (drawable);
-  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
-
-  /* chain up */
-  GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
-  
-  if (cmap)
-    {
-      /* XXX */
-      g_print ("gdk_window_impl_win32_set_colormap: XXX\n");
-    }
-}
-
-static void
-gdk_window_impl_win32_get_size (GdkDrawable *drawable,
-                               gint        *width,
-                               gint        *height)
-{
-  g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
-
-  if (width)
-    *width = GDK_WINDOW_IMPL_WIN32 (drawable)->width;
-  if (height)
-    *height = GDK_WINDOW_IMPL_WIN32 (drawable)->height;
-}
-
-static GdkRegion*
-gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
-{
-  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable);
-  GdkRectangle result_rect;
-
-  result_rect.x = 0;
-  result_rect.y = 0;
-  result_rect.width = impl->width;
-  result_rect.height = impl->height;
-
-  gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
-
-  return gdk_region_rectangle (&result_rect);
-}
-
 void
 _gdk_root_window_size_init (void)
 {
-  GdkWindowImplWin32 *impl;
+  GdkWindow *window;
   GdkRectangle rect;
   int i;
 
-  impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) _gdk_root)->impl);
-  rect = _gdk_monitors[0];
+  window = GDK_WINDOW (_gdk_root);
+  rect = _gdk_monitors[0].rect;
   for (i = 1; i < _gdk_num_monitors; i++)
-    gdk_rectangle_union (&rect, _gdk_monitors+i, &rect);
+    gdk_rectangle_union (&rect, &_gdk_monitors[i].rect, &rect);
 
-  impl->width = rect.width;
-  impl->height = rect.height;
+  window->width = rect.width;
+  window->height = rect.height;
 }
 
 void
-_gdk_windowing_window_init (void)
+_gdk_windowing_window_init (GdkScreen *screen)
 {
-  GdkWindowObject *private;
-  GdkDrawableImplWin32 *draw_impl;
+  GdkWindow *window;
+  GdkWindowImplWin32 *impl_win32;
 
   g_assert (_gdk_root == NULL);
   
-  _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
-  private = (GdkWindowObject *)_gdk_root;
-  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
-  
-  draw_impl->handle = GetDesktopWindow ();
-  draw_impl->wrapper = GDK_DRAWABLE (private);
-  draw_impl->colormap = gdk_screen_get_default_colormap (_gdk_screen);
-  g_object_ref (draw_impl->colormap);
-  
-  private->window_type = GDK_WINDOW_ROOT;
-  private->depth = gdk_visual_get_system ()->depth;
+  _gdk_root = _gdk_display_create_window (_gdk_display);
+
+  window = (GdkWindow *)_gdk_root;
+  window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
+  impl_win32 = GDK_WINDOW_IMPL_WIN32 (window->impl);
+  impl_win32->wrapper = window;
+
+  window->impl_window = window;
+  window->visual = gdk_screen_get_system_visual (screen);
+
+  window->window_type = GDK_WINDOW_ROOT;
+  window->depth = gdk_visual_get_system ()->depth;
 
   _gdk_root_window_size_init ();
-  _gdk_window_init_position (GDK_WINDOW (private));
 
-  gdk_win32_handle_table_insert ((HANDLE *) &draw_impl->handle, _gdk_root);
+  window->x = 0;
+  window->y = 0;
+  window->abs_x = 0;
+  window->abs_y = 0;
+  /* width and height already initialised in _gdk_root_window_size_init() */
+  window->viewable = TRUE;
+
+  gdk_win32_handle_table_insert ((HANDLE *) &impl_win32->handle, _gdk_root);
 
   GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
 }
@@ -314,7 +259,6 @@ static ATOM
 RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
 {
   static ATOM klassTOPLEVEL   = 0;
-  static ATOM klassDIALOG     = 0;
   static ATOM klassCHILD      = 0;
   static ATOM klassTEMP       = 0;
   static ATOM klassTEMPSHADOW = 0;
@@ -333,6 +277,7 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
   wcl.hInstance = _gdk_app_hmodule;
   wcl.hIcon = 0;
   wcl.hIconSm = 0;
+
   /* initialize once! */
   if (0 == hAppIcon && 0 == hAppIconSm)
     {
@@ -341,12 +286,16 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
       if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
         {
           ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
+
           if (0 == hAppIcon && 0 == hAppIconSm)
             {
               if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
-                ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
+               {
+                 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
+               }
             }
         }
+
       if (0 == hAppIcon && 0 == hAppIconSm)
         {
           hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
@@ -357,6 +306,7 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
                                   GetSystemMetrics (SM_CYSMICON), 0);
         }
     }
+
   if (0 == hAppIcon)
     hAppIcon = hAppIconSm;
   else if (0 == hAppIconSm)
@@ -401,17 +351,6 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
       klass = klassCHILD;
       break;
       
-    case GDK_WINDOW_DIALOG:
-      if (0 == klassDIALOG)
-       {
-         wcl.lpszClassName = L"gdkWindowDialog";
-         wcl.style |= CS_SAVEBITS;
-         ONCE_PER_CLASS ();
-         klassDIALOG = RegisterClassExW (&wcl);
-       }
-      klass = klassDIALOG;
-      break;
-      
     case GDK_WINDOW_TEMP:
       if ((wtype_hint == GDK_WINDOW_TYPE_HINT_MENU) ||
           (wtype_hint == GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU) ||
@@ -420,12 +359,16 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
         {
           if (klassTEMPSHADOW == 0)
             {
-              wcl.lpszClassName = "gdkWindowTempShadow";
+              wcl.lpszClassName = L"gdkWindowTempShadow";
               wcl.style |= CS_SAVEBITS;
-              if (_winver >= 0x0501) /* Windows XP (5.1) or above */
-                wcl.style |= 0x00020000; /* CS_DROPSHADOW */
+              if (LOBYTE (g_win32_get_windows_version()) > 0x05 ||
+                 LOWORD (g_win32_get_windows_version()) == 0x0105)
+               {
+                 /* Windows XP (5.1) or above */
+                 wcl.style |= 0x00020000; /* CS_DROPSHADOW */
+               }
               ONCE_PER_CLASS ();
-              klassTEMPSHADOW = RegisterClassEx (&wcl);
+              klassTEMPSHADOW = RegisterClassExW (&wcl);
             }
 
           klass = klassTEMPSHADOW;
@@ -434,10 +377,10 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
         {
           if (klassTEMP == 0)
             {
-              wcl.lpszClassName = "gdkWindowTemp";
+              wcl.lpszClassName = L"gdkWindowTemp";
               wcl.style |= CS_SAVEBITS;
               ONCE_PER_CLASS ();
-              klassTEMP = RegisterClassEx (&wcl);
+              klassTEMP = RegisterClassExW (&wcl);
             }
 
           klass = klassTEMP;
@@ -457,118 +400,92 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint)
   return klass;
 }
 
-static GdkWindow*
-gdk_window_new_internal (GdkWindow     *parent,
-                        GdkWindowAttr *attributes,
-                        gint           attributes_mask,
-                        gboolean       from_set_skip_taskbar_hint)
+/*
+ * Create native windows.
+ *
+ * With the default Gdk the created windows are mostly toplevel windows.
+ *
+ * Placement of the window is derived from the passed in window,
+ * except for toplevel window where OS/Window Manager placement
+ * is used.
+ *
+ * The visual parameter, is based on GDK_WA_VISUAL if set already.
+ * From attributes the only things used is: colormap, title, 
+ * wmclass and type_hint. [1]. We are checking redundant information
+ * and complain if that changes, which would break this implementation
+ * again.
+ *
+ * [1] http://mail.gnome.org/archives/gtk-devel-list/2010-August/msg00214.html
+ */
+void
+_gdk_win32_display_create_window_impl (GdkDisplay    *display,
+                                      GdkWindow     *window,
+                                      GdkWindow     *real_parent,
+                                      GdkScreen     *screen,
+                                      GdkEventMask   event_mask,
+                                      GdkWindowAttr *attributes,
+                                      gint           attributes_mask)
 {
   HWND hwndNew;
   HANDLE hparent;
   ATOM klass = 0;
   DWORD dwStyle = 0, dwExStyle;
   RECT rect;
-  GdkWindow *window;
-  GdkWindow *orig_parent;
-  GdkWindowObject *private;
   GdkWindowImplWin32 *impl;
-  GdkDrawableImplWin32 *draw_impl;
-  GdkVisual *visual;
   const gchar *title;
   wchar_t *wtitle;
   gint window_width, window_height;
   gint offset_x = 0, offset_y = 0;
-
-  g_return_val_if_fail (attributes != NULL, NULL);
-
-  if (!parent)
-    parent = _gdk_root;
-
-  g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
-  
-  orig_parent = parent;
+  gint x, y;
+  /* check consistency of redundant information */
+  guint remaining_mask = attributes_mask;
 
   GDK_NOTE (MISC,
-           g_print ("gdk_window_new: %s\n",
-                    (attributes->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
-                     (attributes->window_type == GDK_WINDOW_CHILD ? "CHILD" :
-                      (attributes->window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
-                       (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
-                        "???"))))));
-
-  if (GDK_WINDOW_DESTROYED (parent))
-    return NULL;
-  
-  hparent = GDK_WINDOW_HWND (parent);
+           g_print ("_gdk_window_impl_new: %s %s\n",
+                    (window->window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
+                     (window->window_type == GDK_WINDOW_CHILD ? "CHILD" :
+                      (window->window_type == GDK_WINDOW_TEMP ? "TEMP" :
+                       "???"))),
+                    (attributes->wclass == GDK_INPUT_OUTPUT ? "" : "input-only"))
+                          );
+
+  /* to ensure to not miss important information some additional check against
+   * attributes which may silently work on X11 */
+  if ((attributes_mask & GDK_WA_X) != 0)
+    {
+      g_assert (attributes->x == window->x);
+      remaining_mask &= ~GDK_WA_X;
+    }
+  if ((attributes_mask & GDK_WA_Y) != 0)
+    {
+      g_assert (attributes->y == window->y);
+      remaining_mask &= ~GDK_WA_Y;
+    }
+  if ((attributes_mask & GDK_WA_NOREDIR) != 0)
+    remaining_mask &= ~GDK_WA_NOREDIR;
 
-  window = g_object_new (GDK_TYPE_WINDOW, NULL);
-  private = (GdkWindowObject *)window;
-  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
-  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
-  draw_impl->wrapper = GDK_DRAWABLE (window);
+  if ((remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_TITLE|GDK_WA_TYPE_HINT)) != 0)
+    g_warning ("_gdk_window_impl_new: uexpected attribute 0x%X",
+               remaining_mask & ~(GDK_WA_WMCLASS|GDK_WA_VISUAL|GDK_WA_CURSOR|GDK_WA_TITLE|GDK_WA_TYPE_HINT));
 
-  /* Windows with a foreign parent are treated as if they are children
-   * of the root window, except for actual creation.
-   */
-  if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
-    parent = _gdk_root;
-  
-  private->parent = (GdkWindowObject *)parent;
+  hparent = GDK_WINDOW_HWND (real_parent);
 
-  private->accept_focus = TRUE;
-  private->focus_on_map = TRUE;
+  impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
+  impl->wrapper = GDK_WINDOW (window);
+  window->impl = GDK_WINDOW_IMPL (impl);
 
-  if (attributes_mask & GDK_WA_X)
-    private->x = attributes->x;
-  else
-    private->x = 0;
-  
-  if (attributes_mask & GDK_WA_Y)
-    private->y = attributes->y;
-  else if (attributes_mask & GDK_WA_X)
-    private->y = 100;          /* ??? We must put it somewhere... */
-  else
-    private->y = 0;
-  
   if (attributes_mask & GDK_WA_VISUAL)
-    visual = attributes->visual;
-  else
-    visual = gdk_visual_get_system ();
+    g_assert (gdk_screen_get_system_visual (screen) == attributes->visual);
 
-  impl->width = (attributes->width > 1) ? (attributes->width) : (1);
-  impl->height = (attributes->height > 1) ? (attributes->height) : (1);
   impl->extension_events_selected = FALSE;
-  if (attributes->wclass == GDK_INPUT_ONLY)
-    {
-      /* Backwards compatiblity - we've always ignored
-       * attributes->window_type for input-only windows
-       * before
-       */
-      if (parent == _gdk_root)
-       private->window_type = GDK_WINDOW_TEMP;
-      else
-       private->window_type = GDK_WINDOW_CHILD;
-    }
-  else
-    private->window_type = attributes->window_type;
 
-  if (attributes->wclass == GDK_INPUT_OUTPUT)
+  /* wclass is not any longer set always, but if is ... */
+  if ((attributes_mask & GDK_WA_WMCLASS) == GDK_WA_WMCLASS)
+    g_assert ((attributes->wclass == GDK_INPUT_OUTPUT) == !window->input_only);
+
+  if (!window->input_only)
     {
       dwExStyle = 0;
-
-      private->input_only = FALSE;
-      private->depth = visual->depth;
-      
-      if (attributes_mask & GDK_WA_COLORMAP)
-       {
-         draw_impl->colormap = attributes->colormap;
-          g_object_ref (attributes->colormap);
-        }
-      else
-       {
-         draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
-         g_object_ref (draw_impl->colormap);
-       }
     }
   else
     {
@@ -577,31 +494,25 @@ gdk_window_new_internal (GdkWindow     *parent,
        * to work well enough for the actual use cases in gtk.
        */
       dwExStyle = WS_EX_TRANSPARENT;
-      private->depth = 0;
-      private->input_only = TRUE;
-      draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
-      g_object_ref (draw_impl->colormap);
-      GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY, system colormap"));
+      GDK_NOTE (MISC, g_print ("... GDK_INPUT_ONLY\n"));
     }
 
-  switch (private->window_type)
+  switch (window->window_type)
     {
     case GDK_WINDOW_TOPLEVEL:
-    case GDK_WINDOW_DIALOG:
-      if (parent != _gdk_root)
+      if (GDK_WINDOW_TYPE (window->parent) != GDK_WINDOW_ROOT)
        {
-         g_warning (G_STRLOC ": Toplevel windows must be created as children\n"
-                    "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
+         /* The common code warns for this case. */
          hparent = GetDesktopWindow ();
        }
       /* Children of foreign windows aren't toplevel windows */
-      if (GDK_WINDOW_TYPE (orig_parent) == GDK_WINDOW_FOREIGN)
+      if (GDK_WINDOW_TYPE (real_parent) == GDK_WINDOW_FOREIGN)
        {
          dwStyle = WS_CHILDWINDOW | WS_CLIPCHILDREN;
        }
       else
        {
-         if (private->window_type == GDK_WINDOW_TOPLEVEL)
+         if (window->window_type == GDK_WINDOW_TOPLEVEL)
            dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
          else
            dwStyle = WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION | WS_THICKFRAME | WS_CLIPCHILDREN;
@@ -617,38 +528,40 @@ gdk_window_new_internal (GdkWindow     *parent,
 
     case GDK_WINDOW_TEMP:
       /* A temp window is not necessarily a top level window */
-      dwStyle = (_gdk_root == parent ? WS_POPUP : WS_CHILDWINDOW);
+      dwStyle = (_gdk_root == real_parent ? WS_POPUP : WS_CHILDWINDOW);
       dwStyle |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
       dwExStyle |= WS_EX_TOOLWINDOW;
       offset_x = _gdk_offset_x;
       offset_y = _gdk_offset_y;
       break;
 
-    case GDK_WINDOW_ROOT:
-      g_error ("cannot make windows of type GDK_WINDOW_ROOT");
-      break;
-
     default:
       g_assert_not_reached ();
     }
 
-  _gdk_window_init_position (GDK_WINDOW (private));
-
-  if (private->window_type != GDK_WINDOW_CHILD)
+  if (window->window_type != GDK_WINDOW_CHILD)
     {
-      rect.left = rect.top = 0;
-      rect.right = impl->position_info.width;
-      rect.bottom = impl->position_info.height;
+      rect.left = window->x;
+      rect.top = window->y;
+      rect.right = window->width;
+      rect.bottom = window->height;
 
       AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
 
+      /* non child windows are placed by the OS/window manager */
+      x = y = CW_USEDEFAULT;
+
       window_width = rect.right - rect.left;
       window_height = rect.bottom - rect.top;
     }
   else
     {
-      window_width = impl->position_info.width;
-      window_height = impl->position_info.height;
+      /* adjust position relative to real_parent */
+      window_width = window->width;
+      window_height = window->height;
+      /* use given position for initial placement, native coordinates */
+      x = window->x + window->parent->abs_x - offset_x;
+      y = window->y + window->parent->abs_y - offset_y;
     }
 
   if (attributes_mask & GDK_WA_TITLE)
@@ -658,17 +571,15 @@ gdk_window_new_internal (GdkWindow     *parent,
   if (!title || !*title)
     title = "";
 
-  private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
+  impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
       
   if (attributes_mask & GDK_WA_TYPE_HINT)
-    impl->type_hint = attributes->type_hint;
-  else
-    impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
+    gdk_window_set_type_hint (window, attributes->type_hint);
 
-  if (private->parent)
-    private->parent->children = g_list_prepend (private->parent->children, window);
+  if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
+    dwExStyle |= WS_EX_TOOLWINDOW;
 
-  klass = RegisterGdkClass (private->window_type, impl->type_hint);
+  klass = RegisterGdkClass (window->window_type, impl->type_hint);
 
   wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
   
@@ -676,9 +587,8 @@ gdk_window_new_internal (GdkWindow     *parent,
                             MAKEINTRESOURCEW (klass),
                             wtitle,
                             dwStyle,
-                            ((attributes_mask & GDK_WA_X) ?
-                             impl->position_info.x - offset_x : CW_USEDEFAULT),
-                            impl->position_info.y - offset_y, 
+                            x,
+                            y,
                             window_width, window_height,
                             hparent,
                             NULL,
@@ -701,7 +611,7 @@ gdk_window_new_internal (GdkWindow     *parent,
       gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
 # else
       /* the old behaviour, but with warning */
-      draw_impl->handle = hwndNew;
+      impl->handle = hwndNew;
 # endif
 
     }
@@ -712,47 +622,36 @@ gdk_window_new_internal (GdkWindow     *parent,
   GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
                           title,
                           window_width, window_height,
-                          ((attributes_mask & GDK_WA_X) ?
-                           impl->position_info.x - offset_x: CW_USEDEFAULT),
-                          impl->position_info.y - offset_y, 
+                          window->x - offset_x,
+                          window->y - offset_y, 
                           hparent,
                           GDK_WINDOW_HWND (window)));
 
+  /* Add window handle to title */
+  GDK_NOTE (MISC_OR_EVENTS, gdk_window_set_title (window, title));
+
   g_free (wtitle);
 
-  if (draw_impl->handle == NULL)
+  if (impl->handle == NULL)
     {
       WIN32_API_FAILED ("CreateWindowExW");
       g_object_unref (window);
-      return NULL;
+      return;
     }
 
-  if (!from_set_skip_taskbar_hint && private->window_type == GDK_WINDOW_TEMP)
-    gdk_window_set_skip_taskbar_hint (window, TRUE);
-
-  gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
-                                 (attributes->cursor) :
-                                 NULL));
+//  if (!from_set_skip_taskbar_hint && window->window_type == GDK_WINDOW_TEMP)
+//    gdk_window_set_skip_taskbar_hint (window, TRUE);
 
-  return window;
-}
-
-GdkWindow*
-gdk_window_new (GdkWindow     *parent,
-               GdkWindowAttr *attributes,
-               gint           attributes_mask)
-{
-  return gdk_window_new_internal (parent, attributes, attributes_mask, FALSE);
+  if (attributes_mask & GDK_WA_CURSOR)
+    gdk_window_set_cursor (window, attributes->cursor);
 }
 
 GdkWindow *
-gdk_window_foreign_new_for_display (GdkDisplay      *display,
-                                    GdkNativeWindow  anid)
+gdk_win32_window_foreign_new_for_display (GdkDisplay      *display,
+                                          HWND             anid)
 {
   GdkWindow *window;
-  GdkWindowObject *private;
   GdkWindowImplWin32 *impl;
-  GdkDrawableImplWin32 *draw_impl;
 
   HANDLE parent;
   RECT rect;
@@ -760,92 +659,117 @@ gdk_window_foreign_new_for_display (GdkDisplay      *display,
 
   g_return_val_if_fail (display == _gdk_display, NULL);
 
-  window = g_object_new (GDK_TYPE_WINDOW, NULL);
-  private = (GdkWindowObject *)window;
-  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
-  draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
-  draw_impl->wrapper = GDK_DRAWABLE (window);
-  parent = GetParent ((HWND)anid);
+  if ((window = gdk_win32_window_lookup_for_display (display, anid)) != NULL)
+    return g_object_ref (window);
+
+  window = _gdk_display_create_window (display);
+  window->visual = gdk_screen_get_system_visual (_gdk_screen);
+  window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WIN32, NULL);
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+  impl->wrapper = window;
+  parent = GetParent (anid);
   
-  private->parent = gdk_win32_handle_table_lookup ((GdkNativeWindow) parent);
-  if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
-    private->parent = (GdkWindowObject *)_gdk_root;
+  window->parent = gdk_win32_handle_table_lookup (parent);
+  if (!window->parent || GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_FOREIGN)
+    window->parent = _gdk_root;
   
-  private->parent->children = g_list_prepend (private->parent->children, window);
+  window->parent->children = g_list_prepend (window->parent->children, window);
 
-  draw_impl->handle = (HWND) anid;
   GetClientRect ((HWND) anid, &rect);
   point.x = rect.left;
   point.y = rect.right;
   ClientToScreen ((HWND) anid, &point);
   if (parent != GetDesktopWindow ())
     ScreenToClient (parent, &point);
-  private->x = point.x;
-  private->y = point.y;
-  impl->width = rect.right - rect.left;
-  impl->height = rect.bottom - rect.top;
-  private->window_type = GDK_WINDOW_FOREIGN;
-  private->destroyed = FALSE;
-  private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
+  window->x = point.x;
+  window->y = point.y;
+  window->width = rect.right - rect.left;
+  window->height = rect.bottom - rect.top;
+  window->window_type = GDK_WINDOW_FOREIGN;
+  window->destroyed = FALSE;
+  window->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
   if (IsWindowVisible ((HWND) anid))
-    private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
+    window->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
   else
-    private->state |= GDK_WINDOW_STATE_WITHDRAWN;
+    window->state |= GDK_WINDOW_STATE_WITHDRAWN;
   if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
-    private->state |= GDK_WINDOW_STATE_ABOVE;
+    window->state |= GDK_WINDOW_STATE_ABOVE;
   else
-    private->state &= (~GDK_WINDOW_STATE_ABOVE);
-  private->state &= (~GDK_WINDOW_STATE_BELOW);
+    window->state &= (~GDK_WINDOW_STATE_ABOVE);
+  window->state &= (~GDK_WINDOW_STATE_BELOW);
+  window->viewable = TRUE;
 
-  private->depth = gdk_visual_get_system ()->depth;
-
-  _gdk_window_init_position (GDK_WINDOW (private));
+  window->depth = gdk_visual_get_system ()->depth;
 
   g_object_ref (window);
   gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
 
-  GDK_NOTE (MISC, g_print ("gdk_window_foreign_new_for_display: %p: %s@%+d%+d\n",
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_foreign_new_for_display: %p: %s@%+d%+d\n",
                           (HWND) anid,
-                          _gdk_win32_drawable_description (window),
-                          private->x, private->y));
+                          _gdk_win32_window_description (window),
+                          window->x, window->y));
 
   return window;
 }
 
-GdkWindow*
-gdk_window_lookup (GdkNativeWindow hwnd)
-{
-  return (GdkWindow*) gdk_win32_handle_table_lookup (hwnd); 
-}
-
-void
-_gdk_windowing_window_destroy (GdkWindow *window,
-                              gboolean   recursing,
-                              gboolean   foreign_destroy)
+static void
+gdk_win32_window_destroy (GdkWindow *window,
+                         gboolean   recursing,
+                         gboolean   foreign_destroy)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+  GSList *tmp;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
   
-  GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n",
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_destroy: %p\n",
                           GDK_WINDOW_HWND (window)));
 
-  if (private->extension_events != 0)
-    _gdk_input_window_destroy (window);
+  /* Remove ourself from the modal stack */
+  _gdk_remove_modal_window (window);
 
+  /* Remove all our transient children */
+  tmp = window_impl->transient_children;
+  while (tmp != NULL)
+    {
+      GdkWindow *child = tmp->data;
+      GdkWindowImplWin32 *child_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW (child)->impl);
 
-  if (!recursing && !foreign_destroy)
+      child_impl->transient_owner = NULL;
+      tmp = g_slist_next (tmp);
+    }
+  g_slist_free (window_impl->transient_children);
+  window_impl->transient_children = NULL;
+
+  /* Remove ourself from our transient owner */
+  if (window_impl->transient_owner != NULL)
     {
-      _gdk_win32_drawable_finish (private->impl);
+      gdk_window_set_transient_for (window, NULL);
+    }
 
-      private->destroyed = TRUE;
+  if (!recursing && !foreign_destroy)
+    {
+      window->destroyed = TRUE;
       DestroyWindow (GDK_WINDOW_HWND (window));
     }
+
   gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
 }
 
-void
-_gdk_windowing_window_destroy_foreign (GdkWindow *window)
+static cairo_surface_t *
+gdk_win32_window_resize_cairo_surface (GdkWindow       *window,
+                                       cairo_surface_t *surface,
+                                       gint             width,
+                                       gint             height)
+{
+  /* XXX: Make Cairo surface use DC clip */
+  cairo_surface_destroy (surface);
+
+  return NULL;
+}
+
+static void
+gdk_win32_window_destroy_foreign (GdkWindow *window)
 {
   /* It's somebody else's window, but in our hierarchy, so reparent it
    * to the desktop, and then try to destroy it.
@@ -858,8 +782,8 @@ _gdk_windowing_window_destroy_foreign (GdkWindow *window)
 
 /* This function is called when the window really gone.
  */
-void
-gdk_window_destroy_notify (GdkWindow *window)
+static void
+gdk_win32_window_destroy_notify (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -895,11 +819,15 @@ get_outer_rect (GdkWindow *window,
 }
 
 static void
-adjust_for_gravity_hints (GdkWindowImplWin32 *impl,
-                         RECT               *outer_rect,
-                         gint               *x,
-                         gint               *y)
+adjust_for_gravity_hints (GdkWindow *window,
+                         RECT      *outer_rect,
+                         gint          *x,
+                         gint          *y)
 {
+  GdkWindowImplWin32 *impl;
+
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
   if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
     {
       gint orig_x = *x, orig_y = *y;
@@ -910,14 +838,14 @@ adjust_for_gravity_hints (GdkWindowImplWin32 *impl,
        case GDK_GRAVITY_CENTER:
        case GDK_GRAVITY_SOUTH:
          *x -= (outer_rect->right - outer_rect->left) / 2;
-         *x += impl->width / 2;
+         *x += window->width / 2;
          break;
              
        case GDK_GRAVITY_SOUTH_EAST:
        case GDK_GRAVITY_EAST:
        case GDK_GRAVITY_NORTH_EAST:
          *x -= outer_rect->right - outer_rect->left;
-         *x += impl->width;
+         *x += window->width;
          break;
 
        case GDK_GRAVITY_STATIC:
@@ -934,14 +862,14 @@ adjust_for_gravity_hints (GdkWindowImplWin32 *impl,
        case GDK_GRAVITY_CENTER:
        case GDK_GRAVITY_EAST:
          *y -= (outer_rect->bottom - outer_rect->top) / 2;
-         *y += impl->height / 2;
+         *y += window->height / 2;
          break;
 
        case GDK_GRAVITY_SOUTH_WEST:
        case GDK_GRAVITY_SOUTH:
        case GDK_GRAVITY_SOUTH_EAST:
          *y -= outer_rect->bottom - outer_rect->top;
-         *y += impl->height;
+         *y += window->height;
          break;
 
        case GDK_GRAVITY_STATIC:
@@ -961,155 +889,124 @@ adjust_for_gravity_hints (GdkWindowImplWin32 *impl,
 
 static void
 show_window_internal (GdkWindow *window,
-                      gboolean   raise,
+                      gboolean   already_mapped,
                      gboolean   deiconify)
 {
-  GdkWindowObject *private;
   HWND old_active_window;
-  gboolean focus_on_map = TRUE;
-
-  private = (GdkWindowObject *) window;
+  gboolean focus_on_map = FALSE;
+  DWORD exstyle;
+  HWND top;
 
-  if (private->destroyed)
+  if (window->destroyed)
     return;
 
-  GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
+  GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s\n",
                           GDK_WINDOW_HWND (window),
-                          _gdk_win32_window_state_to_string (private->state),
-                          (raise ? " raise" : ""),
+                          _gdk_win32_window_state_to_string (window->state),
                           (deiconify ? " deiconify" : "")));
   
   /* If asked to show (not deiconify) an withdrawn and iconified
    * window, do that.
    */
   if (!deiconify &&
-      !GDK_WINDOW_IS_MAPPED (window) &&
-      (private->state & GDK_WINDOW_STATE_ICONIFIED))
+      !already_mapped &&
+      (window->state & GDK_WINDOW_STATE_ICONIFIED))
     {  
-      ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
+      ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMINNOACTIVE);
       return;
     }
   
   /* If asked to just show an iconified window, do nothing. */
-  if (!deiconify && (private->state & GDK_WINDOW_STATE_ICONIFIED))
+  if (!deiconify && (window->state & GDK_WINDOW_STATE_ICONIFIED))
     return;
   
   /* If asked to deiconify an already noniconified window, do
    * nothing. (Especially, don't cause the window to rise and
    * activate. There are different calls for that.)
    */
-  if (deiconify && !(private->state & GDK_WINDOW_STATE_ICONIFIED))
+  if (deiconify && !(window->state & GDK_WINDOW_STATE_ICONIFIED))
     return;
   
   /* If asked to show (but not raise) a window that is already
    * visible, do nothing.
    */
-  if (!deiconify && !raise && IsWindowVisible (GDK_WINDOW_HWND (window)))
+  if (!deiconify && !already_mapped && IsWindowVisible (GDK_WINDOW_HWND (window)))
     return;
 
   /* Other cases */
   
-  if (!GDK_WINDOW_IS_MAPPED (window))
-    {
-      gdk_synthesize_window_state (window,
-                                  GDK_WINDOW_STATE_WITHDRAWN,
-                                  0);
-      focus_on_map = private->focus_on_map;
-    }
+  if (!already_mapped)
+    focus_on_map = window->focus_on_map;
+
+  exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
+
+  if (window->state & GDK_WINDOW_STATE_BELOW)
+    exstyle &= (~WS_EX_TOPMOST);
+
+  if (window->state & GDK_WINDOW_STATE_ABOVE)
+    exstyle |= WS_EX_TOPMOST;
+
+  if (exstyle & WS_EX_TOPMOST)
+    top = HWND_TOPMOST;
+  else
+    top = HWND_TOP;
 
   /* Use SetWindowPos to show transparent windows so automatic redraws
    * in other windows can be suppressed.
    */
-  if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
+  if (exstyle & WS_EX_TRANSPARENT)
     {
-      UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE;
-      if (!raise)
-       flags |= SWP_NOZORDER;
-      if (!raise || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
+      UINT flags = SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER;
+
+      if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
        flags |= SWP_NOACTIVATE;
 
-      SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags);
+      SetWindowPos (GDK_WINDOW_HWND (window), top, 0, 0, 0, 0, flags);
+
       return;
     }
 
-  old_active_window = GetActiveWindow ();
-
-  if (private->state & (GDK_WINDOW_STATE_BELOW | GDK_WINDOW_STATE_ABOVE))
+  if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
     {
-      DWORD exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-
-      if (private->state & GDK_WINDOW_STATE_BELOW)
-        exstyle &= (~WS_EX_TOPMOST);
-      if (private->state & GDK_WINDOW_STATE_ABOVE)
-        exstyle |= WS_EX_TOPMOST;
-
-      API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window), GWL_EXSTYLE, exstyle));
+      gdk_window_fullscreen (window);
+    }
+  else if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
+    {
+      ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
+    }
+  else if (window->state & GDK_WINDOW_STATE_ICONIFIED)
+    {
+      if (focus_on_map)
+       ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
+      else
+       ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
     }
-
-  if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
-    gdk_window_fullscreen (window);
-  else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
-    ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
-  else if (private->state & GDK_WINDOW_STATE_ICONIFIED)
-    ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
   else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
-    ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
+    {
+      ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
+    }
   else
-    ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
-
-  if (raise)
     {
-      if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
-        SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
-                     0, 0, 0, 0,
-                     SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-      else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL ||
-              GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
-       {
-          if (focus_on_map && private->accept_focus)
-            SetForegroundWindow (GDK_WINDOW_HWND (window));
-         else
-            SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP,
-                         0, 0, 0, 0,
-                         SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-       }
-      else
-        BringWindowToTop (GDK_WINDOW_HWND (window));
+      ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
     }
-  else if (old_active_window != GDK_WINDOW_HWND (window))
-    SetActiveWindow (old_active_window);
 }
 
-void
-gdk_window_show_unraised (GdkWindow *window)
+static void
+gdk_win32_window_show (GdkWindow *window, 
+                      gboolean already_mapped)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
   show_window_internal (window, FALSE, FALSE);
 }
 
-void
-gdk_window_show (GdkWindow *window)
-{
-  g_return_if_fail (GDK_IS_WINDOW (window));
-
-  show_window_internal (window, TRUE, FALSE);
-}
-
-void
-gdk_window_hide (GdkWindow *window)
+static void
+gdk_win32_window_hide (GdkWindow *window)
 {
-  GdkWindowObject *private;
-  
-  g_return_if_fail (GDK_IS_WINDOW (window));
-
-  private = (GdkWindowObject*) window;
-  if (private->destroyed)
+  if (window->destroyed)
     return;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_hide: %p: %s\n",
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_hide: %p: %s\n",
                           GDK_WINDOW_HWND (window),
-                          _gdk_win32_window_state_to_string (private->state)));
+                          _gdk_win32_window_state_to_string (window->state)));
   
   if (GDK_WINDOW_IS_MAPPED (window))
     gdk_synthesize_window_state (window,
@@ -1133,30 +1030,23 @@ gdk_window_hide (GdkWindow *window)
     }
 }
 
-void
-gdk_window_withdraw (GdkWindow *window)
+static void
+gdk_win32_window_withdraw (GdkWindow *window)
 {
-  GdkWindowObject *private;
-  
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  private = (GdkWindowObject*) window;
-  if (private->destroyed)
+  if (window->destroyed)
     return;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %p: %s\n",
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_withdraw: %p: %s\n",
                           GDK_WINDOW_HWND (window),
-                          _gdk_win32_window_state_to_string (private->state)));
-  
+                          _gdk_win32_window_state_to_string (window->state)));
+
   gdk_window_hide (window);    /* ??? */
 }
 
-void
-gdk_window_move (GdkWindow *window,
-                gint       x,
-                gint       y)
+static void
+gdk_win32_window_move (GdkWindow *window,
+                      gint x, gint y)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
   GdkWindowImplWin32 *impl;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -1164,45 +1054,45 @@ gdk_window_move (GdkWindow *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_move: %p: %+d%+d\n",
-                          GDK_WINDOW_HWND (window), x, y));
-      
-  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_move: %p: %+d%+d\n",
+                           GDK_WINDOW_HWND (window), x, y));
 
-  if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+  if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
     return;
 
-  /* Don't check GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD.
+  /* Don't check GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD.
    * Foreign windows (another app's windows) might be children of our
    * windows! Especially in the case of gtkplug/socket.
-   */ 
+   */
   if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
-    _gdk_window_move_resize_child (window, x, y, impl->width, impl->height);
+    {
+      _gdk_window_move_resize_child (window, x, y, window->width, window->height);
+    }
   else
     {
       RECT outer_rect;
 
-      get_outer_rect (window, impl->width, impl->height, &outer_rect);
-      
-      adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
+      get_outer_rect (window, window->width, window->height, &outer_rect);
+
+      adjust_for_gravity_hints (window, &outer_rect, &x, &y);
 
       GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,0,0,"
-                              "NOACTIVATE|NOSIZE|NOZORDER)\n",
-                              GDK_WINDOW_HWND (window),
-                              x - _gdk_offset_x, y - _gdk_offset_y));
+                               "NOACTIVATE|NOSIZE|NOZORDER)\n",
+                               GDK_WINDOW_HWND (window),
+                               x - _gdk_offset_x, y - _gdk_offset_y));
 
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
-                              x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
-                              SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
+                               x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
+                               SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
     }
 }
 
-void
-gdk_window_resize (GdkWindow *window,
-                  gint       width,
-                  gint       height)
+static void
+gdk_win32_window_resize (GdkWindow *window,
+                        gint width, gint height)
 {
-  GdkWindowObject *private = (GdkWindowObject*) window;
   GdkWindowImplWin32 *impl;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -1215,16 +1105,18 @@ gdk_window_resize (GdkWindow *window,
   if (height < 1)
     height = 1;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_resize: %p: %dx%d\n",
-                          GDK_WINDOW_HWND (window), width, height));
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_resize: %p: %dx%d\n",
+                           GDK_WINDOW_HWND (window), width, height));
 
-  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
-  
-  if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+  if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
     return;
 
   if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
-    _gdk_window_move_resize_child (window, private->x, private->y, width, height);
+    {
+      _gdk_window_move_resize_child (window, window->x, window->y, width, height);
+    }
   else
     {
       RECT outer_rect;
@@ -1232,28 +1124,27 @@ gdk_window_resize (GdkWindow *window,
       get_outer_rect (window, width, height, &outer_rect);
 
       GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,0,0,%ld,%ld,"
-                              "NOACTIVATE|NOMOVE|NOZORDER)\n",
-                              GDK_WINDOW_HWND (window),
-                              outer_rect.right - outer_rect.left,
-                              outer_rect.bottom - outer_rect.top));
+                               "NOACTIVATE|NOMOVE|NOZORDER)\n",
+                               GDK_WINDOW_HWND (window),
+                               outer_rect.right - outer_rect.left,
+                               outer_rect.bottom - outer_rect.top));
 
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
-                              0, 0,
-                              outer_rect.right - outer_rect.left,
-                              outer_rect.bottom - outer_rect.top,
-                              SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
-      private->resize_count += 1;
+                               0, 0,
+                               outer_rect.right - outer_rect.left,
+                               outer_rect.bottom - outer_rect.top,
+                               SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER));
+      window->resize_count += 1;
     }
 }
 
-void
-gdk_window_move_resize (GdkWindow *window,
-                       gint       x,
-                       gint       y,
-                       gint       width,
-                       gint       height)
+static void
+gdk_win32_window_move_resize_internal (GdkWindow *window,
+                                      gint       x,
+                                      gint       y,
+                                      gint       width,
+                                      gint       height)
 {
-  GdkWindowObject *private = (GdkWindowObject*) window;
   GdkWindowImplWin32 *impl;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -1265,73 +1156,93 @@ gdk_window_move_resize (GdkWindow *window,
     width = 1;
   if (height < 1)
     height = 1;
-  
-  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
 
-  if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+  if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
     return;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %p: %dx%d@%+d%+d\n",
-                          GDK_WINDOW_HWND (window),
-                          width, height, x, y));
-  
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_move_resize: %p: %dx%d@%+d%+d\n",
+                           GDK_WINDOW_HWND (window),
+                           width, height, x, y));
+
   if (GetAncestor (GDK_WINDOW_HWND (window), GA_PARENT) != GetDesktopWindow ())
-    _gdk_window_move_resize_child (window, x, y, width, height);
+    {
+      _gdk_window_move_resize_child (window, x, y, width, height);
+    }
   else
     {
       RECT outer_rect;
 
       get_outer_rect (window, width, height, &outer_rect);
 
-      adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
+      adjust_for_gravity_hints (window, &outer_rect, &x, &y);
 
       GDK_NOTE (MISC, g_print ("... SetWindowPos(%p,NULL,%d,%d,%ld,%ld,"
-                              "NOACTIVATE|NOZORDER)\n",
-                              GDK_WINDOW_HWND (window),
-                              x - _gdk_offset_x, y - _gdk_offset_y,
-                              outer_rect.right - outer_rect.left,
-                              outer_rect.bottom - outer_rect.top));
-                              
+                               "NOACTIVATE|NOZORDER)\n",
+                               GDK_WINDOW_HWND (window),
+                               x - _gdk_offset_x, y - _gdk_offset_y,
+                               outer_rect.right - outer_rect.left,
+                               outer_rect.bottom - outer_rect.top));
+
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
-                              x - _gdk_offset_x, y - _gdk_offset_y,
-                              outer_rect.right - outer_rect.left,
-                              outer_rect.bottom - outer_rect.top,
-                              SWP_NOACTIVATE | SWP_NOZORDER));
+                               x - _gdk_offset_x, y - _gdk_offset_y,
+                               outer_rect.right - outer_rect.left,
+                               outer_rect.bottom - outer_rect.top,
+                               SWP_NOACTIVATE | SWP_NOZORDER));
     }
 }
 
-void
-gdk_window_reparent (GdkWindow *window,
-                    GdkWindow *new_parent,
-                    gint       x,
-                    gint       y)
-{
-  GdkWindowObject *window_private;
-  GdkWindowObject *parent_private;
-  GdkWindowObject *old_parent_private;
-  GdkWindowImplWin32 *impl;
-  gboolean was_toplevel;
-  LONG style;
-
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
-  g_return_if_fail (window != _gdk_root);
+static void
+gdk_win32_window_move_resize (GdkWindow *window,
+                             gboolean   with_move,
+                             gint       x,
+                             gint       y,
+                             gint       width,
+                             gint       height)
+{
+  /* We ignore changes to the window being moved or resized by the 
+     user, as we don't want to fight the user */
+  if (GDK_WINDOW_HWND (window) == _modal_move_resize_window)
+    return;
 
-  if (GDK_WINDOW_DESTROYED (window) ||
-      (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
+  if (with_move && (width < 0 && height < 0))
     {
-      return;
+      gdk_win32_window_move (window, x, y);
+    }
+  else
+    {
+      if (with_move)
+       {
+         gdk_win32_window_move_resize_internal (window, x, y, width, height);
+       }
+      else
+       {
+         gdk_win32_window_resize (window, width, height);
+       }
     }
+}
+
+static gboolean
+gdk_win32_window_reparent (GdkWindow *window,
+                          GdkWindow *new_parent,
+                          gint       x,
+                          gint       y)
+{
+  GdkWindow *parent;
+  GdkWindow *old_parent;
+  GdkWindowImplWin32 *impl;
+  gboolean was_toplevel;
+  LONG style;
 
   if (!new_parent)
     new_parent = _gdk_root;
 
-  window_private = (GdkWindowObject*) window;
-  old_parent_private = (GdkWindowObject *) window_private->parent;
-  parent_private = (GdkWindowObject*) new_parent;
-  impl = GDK_WINDOW_IMPL_WIN32 (window_private->impl);
+  old_parent = window->parent;
+  parent = new_parent;
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
-  GDK_NOTE (MISC, g_print ("gdk_window_reparent: %p: %p\n",
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_reparent: %p: %p\n",
                           GDK_WINDOW_HWND (window),
                           GDK_WINDOW_HWND (new_parent)));
 
@@ -1359,7 +1270,7 @@ gdk_window_reparent (GdkWindow *window,
                        GDK_WINDOW_HWND (new_parent)));
   
   API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
-                        x, y, impl->width, impl->height, TRUE));
+                        x, y, window->width, window->height, TRUE));
 
   /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
    * the root window
@@ -1367,7 +1278,7 @@ gdk_window_reparent (GdkWindow *window,
   if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
     new_parent = _gdk_root;
   
-  window_private->parent = (GdkWindowObject *)new_parent;
+  window->parent = new_parent;
 
   /* Switch the window type as appropriate */
 
@@ -1382,7 +1293,6 @@ gdk_window_reparent (GdkWindow *window,
 
     case GDK_WINDOW_TOPLEVEL:
     case GDK_WINDOW_CHILD:
-    case GDK_WINDOW_DIALOG:
     case GDK_WINDOW_TEMP:
       if (WINDOW_IS_TOPLEVEL (window))
        {
@@ -1394,88 +1304,28 @@ gdk_window_reparent (GdkWindow *window,
        }
     }
 
-  if (old_parent_private)
-    old_parent_private->children =
-      g_list_remove (old_parent_private->children, window);
-
-  parent_private->children = g_list_prepend (parent_private->children, window);
-  _gdk_window_init_position (GDK_WINDOW (window_private));
-}
-
-void
-_gdk_windowing_window_clear_area (GdkWindow *window,
-                                 gint       x,
-                                 gint       y,
-                                 gint       width,
-                                 gint       height)
-{
-  GdkWindowImplWin32 *impl;
-
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
-
-  if (!GDK_WINDOW_DESTROYED (window))
-    {
-      HDC hdc;
-
-      if (width == 0)
-       width = impl->width - x;
-      if (height == 0)
-       height = impl->height - y;
-      GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: %p: "
-                              "%dx%d@%+d%+d\n",
-                              GDK_WINDOW_HWND (window),
-                              width, height, x, y));
-      hdc = GetDC (GDK_WINDOW_HWND (window));
-      IntersectClipRect (hdc, x, y, x + width + 1, y + height + 1);
-      SendMessageW (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
-      GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc));
-    }
-}
-
-void
-_gdk_windowing_window_clear_area_e (GdkWindow *window,
-                                   gint       x,
-                                   gint       y,
-                                   gint       width,
-                                   gint       height)
-{
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  if (!GDK_WINDOW_DESTROYED (window))
-    {
-      RECT rect;
+  if (old_parent)
+    old_parent->children =
+      g_list_remove (old_parent->children, window);
 
-      GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: %p: "
-                              "%dx%d@%+d%+d\n",
-                              GDK_WINDOW_HWND (window),
-                              width, height, x, y));
+  parent->children = g_list_prepend (parent->children, window);
 
-      rect.left = x;
-      rect.right = x + width + 1;
-      rect.top = y;
-      rect.bottom = y + height + 1;
-      GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE));
-      UpdateWindow (GDK_WINDOW_HWND (window));
-    }
+  return FALSE;
 }
 
-void
-gdk_window_raise (GdkWindow *window)
+static void
+gdk_win32_window_raise (GdkWindow *window)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
   if (!GDK_WINDOW_DESTROYED (window))
     {
-      GDK_NOTE (MISC, g_print ("gdk_window_raise: %p\n",
+      GDK_NOTE (MISC, g_print ("gdk_win32_window_raise: %p\n",
                               GDK_WINDOW_HWND (window)));
 
       if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
         API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOPMOST,
                                 0, 0, 0, 0,
                                 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
-      else if (((GdkWindowObject *)window)->accept_focus)
+      else if (window->accept_focus)
         API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
       else
         API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
@@ -1484,14 +1334,12 @@ gdk_window_raise (GdkWindow *window)
     }
 }
 
-void
-gdk_window_lower (GdkWindow *window)
+static void
+gdk_win32_window_lower (GdkWindow *window)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
   if (!GDK_WINDOW_DESTROYED (window))
     {
-      GDK_NOTE (MISC, g_print ("gdk_window_lower: %p\n"
+      GDK_NOTE (MISC, g_print ("gdk_win32_window_lower: %p\n"
                               "... SetWindowPos(%p,HWND_BOTTOM,0,0,0,0,"
                               "NOACTIVATE|NOMOVE|NOSIZE)\n",
                               GDK_WINDOW_HWND (window),
@@ -1503,54 +1351,8 @@ gdk_window_lower (GdkWindow *window)
     }
 }
 
-void
-gdk_window_set_hints (GdkWindow *window,
-                     gint       x,
-                     gint       y,
-                     gint       min_width,
-                     gint       min_height,
-                     gint       max_width,
-                     gint       max_height,
-                     gint       flags)
-{
-  /* Note that this function is obsolete */
-
-  GdkWindowImplWin32 *impl;
-
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
-  
-  impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
-
-  GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %p: %dx%d..%dx%d @%+d%+d\n",
-                          GDK_WINDOW_HWND (window),
-                          min_width, min_height, max_width, max_height,
-                          x, y));
-
-  if (flags)
-    {
-      GdkGeometry geom;
-      gint geom_mask = 0;
-
-      geom.min_width  = min_width;
-      geom.min_height = min_height;
-      geom.max_width  = max_width;
-      geom.max_height = max_height;
-
-      if (flags & GDK_HINT_MIN_SIZE)
-        geom_mask |= GDK_HINT_MIN_SIZE;
-
-      if (flags & GDK_HINT_MAX_SIZE)
-        geom_mask |= GDK_HINT_MAX_SIZE;
-
-      gdk_window_set_geometry_hints (window, &geom, geom_mask);
-    }
-}
-
-void
-gdk_window_set_urgency_hint (GdkWindow *window,
+static void
+gdk_win32_window_set_urgency_hint (GdkWindow *window,
                             gboolean   urgent)
 {
   FLASHWINFO flashwinfo;
@@ -1590,14 +1392,15 @@ get_effective_window_decorations (GdkWindow       *window,
 {
   GdkWindowImplWin32 *impl;
 
-  impl = (GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl;
+  impl = (GdkWindowImplWin32 *)window->impl;
 
   if (gdk_window_get_decorations (window, decoration))
     return TRUE;
     
-  if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL &&
-      ((GdkWindowObject *) window)->window_type != GDK_WINDOW_DIALOG)
-    return FALSE;
+  if (window->window_type != GDK_WINDOW_TOPLEVEL) 
+    {
+      return FALSE;
+    }
 
   if ((impl->hint_flags & GDK_HINT_MIN_SIZE) &&
       (impl->hint_flags & GDK_HINT_MAX_SIZE) &&
@@ -1605,12 +1408,17 @@ get_effective_window_decorations (GdkWindow       *window,
       impl->hints.min_height == impl->hints.max_height)
     {
       *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE;
+
       if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
          impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
          impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
-       *decoration |= GDK_DECOR_MINIMIZE;
+       {
+         *decoration |= GDK_DECOR_MINIMIZE;
+       }
       else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
-       *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
+       {
+         *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE;
+       }
 
       return TRUE;
     }
@@ -1620,7 +1428,10 @@ get_effective_window_decorations (GdkWindow       *window,
       if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
          impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU ||
          impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR)
-       *decoration |= GDK_DECOR_MINIMIZE;
+       {
+         *decoration |= GDK_DECOR_MINIMIZE;
+       }
+
       return TRUE;
     }
   else
@@ -1636,16 +1447,15 @@ get_effective_window_decorations (GdkWindow       *window,
          return TRUE;
 
        case GDK_WINDOW_TYPE_HINT_TOOLBAR:
+       case GDK_WINDOW_TYPE_HINT_UTILITY:
          gdk_window_set_skip_taskbar_hint (window, TRUE);
-         *decoration = GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE;
+         gdk_window_set_skip_pager_hint (window, TRUE);
+         *decoration = (GDK_DECOR_ALL | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
          return TRUE;
 
-       case GDK_WINDOW_TYPE_HINT_UTILITY:
-         return FALSE;
-
        case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
-         *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU
-                  | GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
+         *decoration = (GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MENU |
+                        GDK_DECOR_MINIMIZE | GDK_DECOR_MAXIMIZE);
          return TRUE;
          
        case GDK_WINDOW_TYPE_HINT_DOCK:
@@ -1665,10 +1475,10 @@ get_effective_window_decorations (GdkWindow       *window,
   return FALSE;
 }
 
-void 
-gdk_window_set_geometry_hints (GdkWindow      *window,
-                              GdkGeometry    *geometry,
-                              GdkWindowHints  geom_mask)
+static void
+gdk_win32_window_set_geometry_hints (GdkWindow         *window,
+                              const GdkGeometry *geometry,
+                              GdkWindowHints     geom_mask)
 {
   GdkWindowImplWin32 *impl;
 
@@ -1680,7 +1490,7 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
   GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints: %p\n",
                           GDK_WINDOW_HWND (window)));
 
-  impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
   impl->hint_flags = geom_mask;
   impl->hints = *geometry;
@@ -1726,8 +1536,8 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
   update_style_bits (window);
 }
 
-void
-gdk_window_set_title (GdkWindow   *window,
+static void
+gdk_win32_window_set_title (GdkWindow   *window,
                      const gchar *title)
 {
   wchar_t *wtitle;
@@ -1745,13 +1555,17 @@ gdk_window_set_title (GdkWindow   *window,
   GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
                           GDK_WINDOW_HWND (window), title));
   
+  GDK_NOTE (MISC_OR_EVENTS, title = g_strdup_printf ("%p %s", GDK_WINDOW_HWND (window), title));
+
   wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
   API_CALL (SetWindowTextW, (GDK_WINDOW_HWND (window), wtitle));
   g_free (wtitle);
+
+  GDK_NOTE (MISC_OR_EVENTS, g_free ((char *) title));
 }
 
-void          
-gdk_window_set_role (GdkWindow   *window,
+static void
+gdk_win32_window_set_role (GdkWindow   *window,
                     const gchar *role)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -1762,29 +1576,68 @@ gdk_window_set_role (GdkWindow   *window,
   /* XXX */
 }
 
-void          
-gdk_window_set_transient_for (GdkWindow *window, 
+static void
+gdk_win32_window_set_transient_for (GdkWindow *window, 
                              GdkWindow *parent)
 {
   HWND window_id, parent_id;
+  GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+  GdkWindowImplWin32 *parent_impl = NULL;
+  GSList *item;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n",
-                          GDK_WINDOW_HWND (window),
-                          GDK_WINDOW_HWND (parent)));
 
-  if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent))
-    return;
+  window_id = GDK_WINDOW_HWND (window);
+  parent_id = parent != NULL ? GDK_WINDOW_HWND (parent) : NULL;
+
+  GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %p: %p\n", window_id, parent_id));
+
+  if (GDK_WINDOW_DESTROYED (window) || (parent && GDK_WINDOW_DESTROYED (parent)))
+    {
+      if (GDK_WINDOW_DESTROYED (window))
+       GDK_NOTE (MISC, g_print ("... destroyed!\n"));
+      else
+       GDK_NOTE (MISC, g_print ("... owner destroyed!\n"));
+
+      return;
+    }
 
-  if (((GdkWindowObject *) window)->window_type == GDK_WINDOW_CHILD)
+  if (window->window_type == GDK_WINDOW_CHILD)
     {
       GDK_NOTE (MISC, g_print ("... a child window!\n"));
       return;
     }
-  
-  window_id = GDK_WINDOW_HWND (window);
-  parent_id = GDK_WINDOW_HWND (parent);
+
+  if (parent == NULL)
+    {
+      GdkWindowImplWin32 *trans_impl = GDK_WINDOW_IMPL_WIN32 (window_impl->transient_owner->impl);
+      if (trans_impl->transient_children != NULL)
+        {
+          item = g_slist_find (trans_impl->transient_children, window);
+          item->data = NULL;
+          trans_impl->transient_children = g_slist_delete_link (trans_impl->transient_children, item);
+          trans_impl->num_transients--;
+
+          if (!trans_impl->num_transients)
+            {
+              trans_impl->transient_children = NULL;
+            }
+        }
+      g_object_unref (G_OBJECT (window_impl->transient_owner));
+      g_object_unref (G_OBJECT (window));
+
+      window_impl->transient_owner = NULL;
+    }
+  else
+    {
+      parent_impl = GDK_WINDOW_IMPL_WIN32 (parent->impl);
+
+      parent_impl->transient_children = g_slist_append (parent_impl->transient_children, window);
+      g_object_ref (G_OBJECT (window));
+      parent_impl->num_transients++;
+      window_impl->transient_owner = parent;
+      g_object_ref (G_OBJECT (parent));
+    }
 
   /* This changes the *owner* of the window, despite the misleading
    * name. (Owner and parent are unrelated concepts.) At least that's
@@ -1792,89 +1645,77 @@ gdk_window_set_transient_for (GdkWindow *window,
    * USENET. Search on Google.
    */
   SetLastError (0);
-  if (SetWindowLong (window_id, GWL_HWNDPARENT, (long) parent_id) == 0 &&
+  if (SetWindowLongPtr (window_id, GWLP_HWNDPARENT, (LONG_PTR) parent_id) == 0 &&
       GetLastError () != 0)
-    WIN32_API_FAILED ("SetWindowLong");
+    WIN32_API_FAILED ("SetWindowLongPtr");
 }
 
 void
-gdk_window_set_background (GdkWindow      *window,
-                          const GdkColor *color)
+_gdk_push_modal_window (GdkWindow *window)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  GDK_NOTE (MISC, g_print ("gdk_window_set_background: %p: %s\n",
-                          GDK_WINDOW_HWND (window), 
-                          _gdk_win32_color_to_string (color)));
-
-  private->bg_color = *color;
-
-  if (private->bg_pixmap &&
-      private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
-      private->bg_pixmap != GDK_NO_BG)
-    {
-      g_object_unref (private->bg_pixmap);
-      private->bg_pixmap = NULL;
-    }
+  modal_window_stack = g_slist_prepend (modal_window_stack,
+                                        window);
 }
 
 void
-gdk_window_set_back_pixmap (GdkWindow *window,
-                           GdkPixmap *pixmap,
-                           gint       parent_relative)
+_gdk_remove_modal_window (GdkWindow *window)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
+  GSList *tmp;
 
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  g_return_if_fail (pixmap == NULL || !parent_relative);
-  g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
-  
-  if (pixmap && !gdk_drawable_get_colormap (pixmap))
+  g_return_if_fail (window != NULL);
+
+  /* It's possible to be NULL here if someone sets the modal hint of the window
+   * to FALSE before a modal window stack has ever been created. */
+  if (modal_window_stack == NULL)
+    return;
+
+  /* Find the requested window in the stack and remove it.  Yeah, I realize this
+   * means we're not a 'real stack', strictly speaking.  Sue me. :) */
+  tmp = g_slist_find (modal_window_stack, window);
+  if (tmp != NULL)
     {
-      g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
-      return;
+      modal_window_stack = g_slist_delete_link (modal_window_stack, tmp);
     }
-  
-  if (private->bg_pixmap &&
-      private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
-      private->bg_pixmap != GDK_NO_BG)
-    g_object_unref (private->bg_pixmap);
+}
 
-  if (parent_relative)
+GdkWindow *
+_gdk_modal_current (void)
+{
+  if (modal_window_stack != NULL)
     {
-      private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
-      GDK_NOTE (MISC, g_print (G_STRLOC ": setting background pixmap to parent_relative\n"));
+      GSList *tmp = modal_window_stack;
+
+      while (tmp != NULL && !GDK_WINDOW_IS_MAPPED (GDK_WINDOW (tmp->data)))
+       {
+         tmp = g_slist_next (tmp);
+       }
+
+      return tmp != NULL ? tmp->data : NULL;
     }
   else
     {
-      if (pixmap)
-       {
-         g_object_ref (pixmap);
-         private->bg_pixmap = pixmap;
-       }
-      else
-       {
-         private->bg_pixmap = GDK_NO_BG;
-       }
+      return NULL;
     }
 }
 
-void
-gdk_window_set_cursor (GdkWindow *window,
-                      GdkCursor *cursor)
+static void
+gdk_win32_window_set_background (GdkWindow       *window,
+                                cairo_pattern_t *pattern)
+{
+}
+
+static void
+gdk_win32_window_set_device_cursor (GdkWindow *window,
+                                    GdkDevice *device,
+                                    GdkCursor *cursor)
 {
   GdkWindowImplWin32 *impl;
-  GdkCursorPrivate *cursor_private;
-  GdkWindowObject *parent_window;
+  GdkWin32Cursor *cursor_private;
   HCURSOR hcursor;
   HCURSOR hprevcursor;
   
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
-  cursor_private = (GdkCursorPrivate*) cursor;
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+  cursor_private = (GdkWin32Cursor*) cursor;
   
   if (GDK_WINDOW_DESTROYED (window))
     return;
@@ -1884,7 +1725,7 @@ gdk_window_set_cursor (GdkWindow *window,
   else
     hcursor = cursor_private->hcursor;
   
-  GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %p: %p\n",
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_set_cursor: %p: %p\n",
                           GDK_WINDOW_HWND (window),
                           hcursor));
 
@@ -1894,6 +1735,8 @@ gdk_window_set_cursor (GdkWindow *window,
    */
   hprevcursor = impl->hcursor;
 
+  GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
+
   if (hcursor == NULL)
     impl->hcursor = NULL;
   else
@@ -1910,75 +1753,21 @@ gdk_window_set_cursor (GdkWindow *window,
                               hcursor, impl->hcursor));
     }
 
-  if (impl->hcursor != NULL)
-    {
-      /* If the pointer is over our window, set new cursor */
-      GdkWindow *curr_window = gdk_window_get_pointer (window, NULL, NULL, NULL);
-      if (curr_window == window)
-        SetCursor (impl->hcursor);
-      else
-       {
-         /* Climb up the tree and find whether our window is the
-          * first ancestor that has cursor defined, and if so, set
-          * new cursor.
-          */
-         GdkWindowObject *curr_window_obj = GDK_WINDOW_OBJECT (curr_window);
-         while (curr_window_obj &&
-                !GDK_WINDOW_IMPL_WIN32 (curr_window_obj->impl)->hcursor)
-           {
-             curr_window_obj = curr_window_obj->parent;
-             if (curr_window_obj == GDK_WINDOW_OBJECT (window))
-               {
-                 SetCursor (impl->hcursor);
-                 break;
-               }
-           }
-       }
-    }
-
-  /* Destroy the previous cursor: Need to make sure it's no longer in
-   * use before we destroy it, in case we're not over our window but
-   * the cursor is still set to our old one.
-   */
+  /* Destroy the previous cursor */
   if (hprevcursor != NULL)
     {
-      if (GetCursor () == hprevcursor)
-       {
-         /* Look for a suitable cursor to use instead */
-         hcursor = NULL;
-          parent_window = GDK_WINDOW_OBJECT (window)->parent;
-          while (hcursor == NULL)
-           {
-             if (parent_window)
-               {
-                 impl = GDK_WINDOW_IMPL_WIN32 (parent_window->impl);
-                 hcursor = impl->hcursor;
-                 parent_window = parent_window->parent;
-               }
-             else
-               {
-                 hcursor = LoadCursor (NULL, IDC_ARROW);
-               }
-           }
-          SetCursor (hcursor);
-        }
-
       GDK_NOTE (MISC, g_print ("... DestroyCursor (%p)\n", hprevcursor));
-      
       API_CALL (DestroyCursor, (hprevcursor));
     }
 }
 
-void
-gdk_window_get_geometry (GdkWindow *window,
-                        gint      *x,
-                        gint      *y,
-                        gint      *width,
-                        gint      *height,
-                        gint      *depth)
-{
-  g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
-  
+static void
+gdk_win32_window_get_geometry (GdkWindow *window,
+                              gint      *x,
+                              gint      *y,
+                              gint      *width,
+                              gint      *height)
+{
   if (!window)
     window = _gdk_root;
   
@@ -2024,63 +1813,61 @@ gdk_window_get_geometry (GdkWindow *window,
        *width = rect.right - rect.left;
       if (height)
        *height = rect.bottom - rect.top;
-      if (depth)
-       *depth = gdk_drawable_get_visual (window)->depth;
 
-      GDK_NOTE (MISC, g_print ("gdk_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
+      GDK_NOTE (MISC, g_print ("gdk_win32_window_get_geometry: %p: %ldx%ldx%d@%+ld%+ld\n",
                               GDK_WINDOW_HWND (window),
                               rect.right - rect.left, rect.bottom - rect.top,
-                              gdk_drawable_get_visual (window)->depth,
+                              gdk_window_get_visual (window)->depth,
                               rect.left, rect.top));
     }
 }
 
-gint
-gdk_window_get_origin (GdkWindow *window,
-                      gint      *x,
-                      gint      *y)
+static gint
+gdk_win32_window_get_root_coords (GdkWindow *window,
+                                 gint       x,
+                                 gint       y,
+                                 gint      *root_x,
+                                 gint      *root_y)
 {
-  gint return_val;
-  gint tx = 0;
-  gint ty = 0;
-
-  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
-
-  if (!GDK_WINDOW_DESTROYED (window))
-    {
-      POINT pt;
+  gint tx;
+  gint ty;
+  POINT pt;
 
-      pt.x = 0;
-      pt.y = 0;
-      ClientToScreen (GDK_WINDOW_HWND (window), &pt);
-      tx = pt.x;
-      ty = pt.y;
-      return_val = 1;
-    }
-  else
-    return_val = 0;
+  pt.x = x;
+  pt.y = y;
+  ClientToScreen (GDK_WINDOW_HWND (window), &pt);
+  tx = pt.x;
+  ty = pt.y;
   
-  if (x)
-    *x = tx + _gdk_offset_x;
-  if (y)
-    *y = ty + _gdk_offset_y;
+  if (root_x)
+    *root_x = tx + _gdk_offset_x;
+  if (root_y)
+    *root_y = ty + _gdk_offset_y;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %p: %+d%+d\n",
+  GDK_NOTE (MISC, g_print ("gdk_win32_window_get_root_coords: %p: %+d%+d %+d%+d\n",
                           GDK_WINDOW_HWND (window),
-                          tx, ty));
-  return return_val;
+                          x, y,
+                          tx + _gdk_offset_x, ty + _gdk_offset_y));
+  return 1;
 }
 
-gboolean
-gdk_window_get_deskrelative_origin (GdkWindow *window,
-                                   gint      *x,
-                                   gint      *y)
+static void
+gdk_win32_window_restack_under (GdkWindow *window,
+                               GList *native_siblings)
 {
-  return gdk_window_get_origin (window, x, y);
+       // ### TODO
 }
 
-void
-gdk_window_get_root_origin (GdkWindow *window,
+static void
+gdk_win32_window_restack_toplevel (GdkWindow *window,
+                                  GdkWindow *sibling,
+                                  gboolean   above)
+{
+       // ### TODO
+}
+
+static void
+gdk_win32_window_get_root_origin (GdkWindow *window,
                            gint      *x,
                            gint      *y)
 {
@@ -2100,19 +1887,16 @@ gdk_window_get_root_origin (GdkWindow *window,
                           GDK_WINDOW_HWND (window), rect.x, rect.y));
 }
 
-void
-gdk_window_get_frame_extents (GdkWindow    *window,
+static void
+gdk_win32_window_get_frame_extents (GdkWindow    *window,
                               GdkRectangle *rect)
 {
-  GdkWindowObject *private;
   HWND hwnd;
   RECT r;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (rect != NULL);
 
-  private = GDK_WINDOW_OBJECT (window);
-
   rect->x = 0;
   rect->y = 0;
   rect->width = 1;
@@ -2124,8 +1908,8 @@ gdk_window_get_frame_extents (GdkWindow    *window,
   /* FIXME: window is documented to be a toplevel GdkWindow, so is it really
    * necessary to walk its parent chain?
    */
-  while (private->parent && ((GdkWindowObject*) private->parent)->parent)
-    private = (GdkWindowObject*) private->parent;
+  while (window->parent && window->parent->parent)
+    window = window->parent;
 
   hwnd = GDK_WINDOW_HWND (window);
   API_CALL (GetWindowRect, (hwnd, &r));
@@ -2141,174 +1925,97 @@ gdk_window_get_frame_extents (GdkWindow    *window,
                           r.left, r.top));
 }
 
-GdkWindow*
-_gdk_windowing_window_get_pointer (GdkDisplay      *display,
-                                  GdkWindow       *window,
-                                  gint            *x,
-                                  gint            *y,
-                                  GdkModifierType *mask)
-{
-  GdkWindow *return_val;
-  POINT screen_point, point;
-  HWND hwnd, hwndc;
-  BYTE kbd[256];
-
-  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
-  
-  return_val = NULL;
-  GetCursorPos (&screen_point);
-  point = screen_point;
-  ScreenToClient (GDK_WINDOW_HWND (window), &point);
-
-  *x = point.x;
-  *y = point.y;
+static gboolean
+gdk_window_win32_get_device_state (GdkWindow       *window,
+                                   GdkDevice       *device,
+                                   gint            *x,
+                                   gint            *y,
+                                   GdkModifierType *mask)
+{
+  GdkWindow *child;
 
-  if (window == _gdk_root)
-    {
-      *x += _gdk_offset_x;
-      *y += _gdk_offset_y;
-    }
+  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
 
-  hwnd = WindowFromPoint (screen_point);
-  if (hwnd != NULL)
-    {
-      gboolean done = FALSE;
-      
-      while (!done)
-       {
-         point = screen_point;
-         ScreenToClient (hwnd, &point);
-         hwndc = ChildWindowFromPoint (hwnd, point);
-         if (hwndc == NULL)
-           done = TRUE;
-         else if (hwndc == hwnd)
-           done = TRUE;
-         else
-           hwnd = hwndc;
-       }
-      
-      return_val = gdk_window_lookup ((GdkNativeWindow) hwnd);
-    }
-  else
-    return_val = NULL;
-      
-  GetKeyboardState (kbd);
-  *mask = 0;
-  if (kbd[VK_SHIFT] & 0x80)
-    *mask |= GDK_SHIFT_MASK;
-  if (kbd[VK_CAPITAL] & 0x80)
-    *mask |= GDK_LOCK_MASK;
-  if (kbd[VK_CONTROL] & 0x80)
-    *mask |= GDK_CONTROL_MASK;
-  if (kbd[VK_MENU] & 0x80)
-    *mask |= GDK_MOD1_MASK;
-  if (kbd[VK_LBUTTON] & 0x80)
-    *mask |= GDK_BUTTON1_MASK;
-  if (kbd[VK_MBUTTON] & 0x80)
-    *mask |= GDK_BUTTON2_MASK;
-  if (kbd[VK_RBUTTON] & 0x80)
-    *mask |= GDK_BUTTON3_MASK;
-  
-  return return_val;
+  GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
+                                              NULL, &child,
+                                              NULL, NULL,
+                                              x, y, mask);
+  return (child != NULL);
 }
 
 void
-_gdk_windowing_get_pointer (GdkDisplay       *display,
-                           GdkScreen       **screen,
-                           gint             *x,
-                           gint             *y,
-                           GdkModifierType  *mask)
+_gdk_windowing_get_device_state (GdkDisplay       *display,
+                                 GdkDevice        *device,
+                                 GdkScreen       **screen,
+                                 gint             *x,
+                                 gint             *y,
+                                 GdkModifierType  *mask)
 {
   g_return_if_fail (display == _gdk_display);
-  
-  *screen = _gdk_screen;
-  _gdk_windowing_window_get_pointer (_gdk_display, _gdk_root, x, y, mask);
+
+  if (screen)
+    *screen = _gdk_screen;
+
+  GDK_DEVICE_GET_CLASS (device)->query_state (device,
+                                              gdk_screen_get_root_window (_gdk_screen),
+                                              NULL, NULL,
+                                              x, y,
+                                              NULL, NULL,
+                                              mask);
 }
 
 void
-gdk_display_warp_pointer (GdkDisplay *display,
-                         GdkScreen  *screen,
-                         gint        x,
-                         gint        y)
+gdk_display_warp_device (GdkDisplay *display,
+                         GdkDevice  *device,
+                         GdkScreen  *screen,
+                         gint        x,
+                         gint        y)
 {
   g_return_if_fail (display == _gdk_display);
   g_return_if_fail (screen == _gdk_screen);
+  g_return_if_fail (GDK_IS_DEVICE (device));
+  g_return_if_fail (display == gdk_device_get_display (device));
 
-  SetCursorPos (x - _gdk_offset_x, y - _gdk_offset_y);
+  GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
 }
 
 GdkWindow*
-_gdk_windowing_window_at_pointer (GdkDisplay *display,
-                                 gint       *win_x,
-                                 gint       *win_y)
+_gdk_windowing_window_at_device_position (GdkDisplay      *display,
+                                          GdkDevice       *device,
+                                          gint            *win_x,
+                                          gint            *win_y,
+                                          GdkModifierType *mask,
+                                          gboolean         get_toplevel)
 {
-  GdkWindow *window;
-  POINT point, pointc;
-  HWND hwnd, hwndc;
-  RECT rect;
-
-  GetCursorPos (&pointc);
-  point = pointc;
-  hwnd = WindowFromPoint (point);
-
-  if (hwnd == NULL)
-    {
-      window = _gdk_root;
-      *win_x = pointc.x + _gdk_offset_x;
-      *win_y = pointc.y + _gdk_offset_y;
-      return window;
-    }
-      
-  ScreenToClient (hwnd, &point);
-
-  do {
-    hwndc = ChildWindowFromPoint (hwnd, point);
-    ClientToScreen (hwnd, &point);
-    ScreenToClient (hwndc, &point);
-  } while (hwndc != hwnd && (hwnd = hwndc, 1));
-
-  window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
-
-  if (window && (win_x || win_y))
-    {
-      GetClientRect (hwnd, &rect);
-      *win_x = point.x - rect.left;
-      *win_y = point.y - rect.top;
-    }
-
-  GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: %+d%+d %p%s\n",
-                          *win_x, *win_y,
-                          hwnd,
-                          (window == NULL ? " NULL" : "")));
-
-  return window;
+  return GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y, mask, get_toplevel);
 }
 
-GdkEventMask  
-gdk_window_get_events (GdkWindow *window)
+static GdkEventMask  
+gdk_win32_window_get_events (GdkWindow *window)
 {
-  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+  GdkWindowImplWin32 *impl;
 
   if (GDK_WINDOW_DESTROYED (window))
     return 0;
 
-  return GDK_WINDOW_OBJECT (window)->event_mask;
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+  return impl->native_event_mask;
 }
 
-void          
-gdk_window_set_events (GdkWindow   *window,
-                      GdkEventMask event_mask)
+static void          
+gdk_win32_window_set_events (GdkWindow   *window,
+                            GdkEventMask event_mask)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
+  GdkWindowImplWin32 *impl;
 
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
   /* gdk_window_new() always sets the GDK_STRUCTURE_MASK, so better
    * set it here, too. Not that I know or remember why it is
    * necessary, will have to test some day.
    */
-  GDK_WINDOW_OBJECT (window)->event_mask = GDK_STRUCTURE_MASK | event_mask;
+  impl->native_event_mask = GDK_STRUCTURE_MASK | event_mask;
 }
 
 static void
@@ -2335,63 +2042,8 @@ do_shape_combine_region (GdkWindow *window,
   SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
 }
 
-void
-gdk_window_shape_combine_mask (GdkWindow *window,
-                              GdkBitmap *mask,
-                              gint x, gint y)
-{
-  GdkWindowObject *private = (GdkWindowObject *)window;
-
-  g_return_if_fail (GDK_IS_WINDOW (window));
-
-  if (!mask)
-    {
-      GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
-                              GDK_WINDOW_HWND (window)));
-      SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
-
-      private->shaped = FALSE;
-    }
-  else
-    {
-      HRGN hrgn;
-
-      GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
-                              GDK_WINDOW_HWND (window),
-                              GDK_WINDOW_HWND (mask)));
-
-      /* Convert mask bitmap to region */
-      hrgn = _gdk_win32_bitmap_to_hrgn (mask);
-
-      do_shape_combine_region (window, hrgn, x, y);
-
-      private->shaped = TRUE;
-    }
-}
-
-void 
-gdk_window_input_shape_combine_mask (GdkWindow *window,
-                                    GdkBitmap *mask,
-                                    gint       x,
-                                    gint       y)
-{
-  g_return_if_fail (GDK_IS_WINDOW (window));
-
-  /* Not yet implemented
-   *
-   * I don't think there is anything in the Win32 API to directly
-   * support this. And anyway, as we don't currently support RGBA
-   * windows, it doesn't really matter.
-   *
-   * When we do support RGBA, input shape functionality could probably
-   * be implemented by saving the input shape region in the per-window
-   * private data, and then simply checking before generating an input
-   * event whether the event's coordinates are inside the region.
-   */
-}
-
-void
-gdk_window_set_override_redirect (GdkWindow *window,
+static void
+gdk_win32_window_set_override_redirect (GdkWindow *window,
                                  gboolean   override_redirect)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -2399,40 +2051,32 @@ gdk_window_set_override_redirect (GdkWindow *window,
   g_warning ("gdk_window_set_override_redirect not implemented");
 }
 
-void
-gdk_window_set_accept_focus (GdkWindow *window,
+static void
+gdk_win32_window_set_accept_focus (GdkWindow *window,
                             gboolean accept_focus)
 {
-  GdkWindowObject *private;
-
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  private = (GdkWindowObject *)window;  
-  
   accept_focus = accept_focus != FALSE;
 
-  if (private->accept_focus != accept_focus)
-    private->accept_focus = accept_focus;
+  if (window->accept_focus != accept_focus)
+    window->accept_focus = accept_focus;
 }
 
-void
-gdk_window_set_focus_on_map (GdkWindow *window,
+static void
+gdk_win32_window_set_focus_on_map (GdkWindow *window,
                             gboolean focus_on_map)
 {
-  GdkWindowObject *private;
-
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  private = (GdkWindowObject *)window;  
-  
   focus_on_map = focus_on_map != FALSE;
 
-  if (private->focus_on_map != focus_on_map)
-    private->focus_on_map = focus_on_map;
+  if (window->focus_on_map != focus_on_map)
+    window->focus_on_map = focus_on_map;
 }
 
-void          
-gdk_window_set_icon_list (GdkWindow *window,
+static void
+gdk_win32_window_set_icon_list (GdkWindow *window,
                          GList     *pixbufs)
 {
   GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
@@ -2449,7 +2093,7 @@ gdk_window_set_icon_list (GdkWindow *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
   /* ideal sizes for small and large icons */
   big_w = GetSystemMetrics (SM_CXICON);
@@ -2512,19 +2156,8 @@ gdk_window_set_icon_list (GdkWindow *window,
   impl->hicon_small = small_hicon;
 }
 
-void          
-gdk_window_set_icon (GdkWindow *window, 
-                    GdkWindow *icon_window,
-                    GdkPixmap *pixmap,
-                    GdkBitmap *mask)
-{
-  g_return_if_fail (GDK_IS_WINDOW (window));
-
-  /* do nothing, use gdk_window_set_icon_list instead */
-}
-
-void
-gdk_window_set_icon_name (GdkWindow   *window, 
+static void
+gdk_win32_window_set_icon_name (GdkWindow   *window, 
                          const gchar *name)
 {
   /* In case I manage to confuse this again (or somebody else does):
@@ -2552,8 +2185,8 @@ gdk_window_set_icon_name (GdkWindow   *window,
 #endif
 }
 
-GdkWindow *
-gdk_window_get_group (GdkWindow *window)
+static GdkWindow *
+gdk_win32_window_get_group (GdkWindow *window)
 {
   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
   g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
@@ -2566,8 +2199,8 @@ gdk_window_get_group (GdkWindow *window)
   return NULL;
 }
 
-void          
-gdk_window_set_group (GdkWindow *window, 
+static void
+gdk_win32_window_set_group (GdkWindow *window, 
                      GdkWindow *leader)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -2581,14 +2214,15 @@ gdk_window_set_group (GdkWindow *window,
 }
 
 static void
-update_single_bit (LONG *style,
-                   BOOL  all,
-                  int   gdk_bit,
-                  int   style_bit)
-{
-  /* all controls the interpretation of gdk_bit -- if all is true, gdk_bit
-     indicates whether style_bit is off; if all is false, gdk bit indicate whether
-     style_bit is on */
+update_single_bit (LONG    *style,
+                   gboolean all,
+                  int      gdk_bit,
+                  int      style_bit)
+{
+  /* all controls the interpretation of gdk_bit -- if all is TRUE,
+   * gdk_bit indicates whether style_bit is off; if all is FALSE, gdk
+   * bit indicate whether style_bit is on
+   */
   if ((!all && gdk_bit) || (all && !gdk_bit))
     *style |= style_bit;
   else
@@ -2598,45 +2232,67 @@ update_single_bit (LONG *style,
 static void
 update_style_bits (GdkWindow *window)
 {
+  GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)window->impl;
   GdkWMDecoration decorations;
-  GdkWMFunction functions;
-  LONG style, exstyle;
-  BOOL all;
+  LONG old_style, new_style, old_exstyle, new_exstyle;
+  gboolean all;
   RECT rect, before, after;
 
-  style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-  exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
+  old_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
+  old_exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
 
   GetClientRect (GDK_WINDOW_HWND (window), &before);
   after = before;
-  AdjustWindowRectEx (&before, style, FALSE, exstyle);
+  AdjustWindowRectEx (&before, old_style, FALSE, old_exstyle);
+
+  new_style = old_style;
+  new_exstyle = old_exstyle;
+
+  if (window->window_type == GDK_WINDOW_TEMP ||
+      impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY)
+    new_exstyle |= WS_EX_TOOLWINDOW;
+  else
+    new_exstyle &= ~WS_EX_TOOLWINDOW;
 
   if (get_effective_window_decorations (window, &decorations))
     {
       all = (decorations & GDK_DECOR_ALL);
-      update_single_bit (&style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
-      update_single_bit (&style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
-      update_single_bit (&style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
-      update_single_bit (&style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
-      update_single_bit (&style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
-      update_single_bit (&style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
+      update_single_bit (&new_style, all, decorations & GDK_DECOR_BORDER, WS_BORDER);
+      update_single_bit (&new_style, all, decorations & GDK_DECOR_RESIZEH, WS_THICKFRAME);
+      update_single_bit (&new_style, all, decorations & GDK_DECOR_TITLE, WS_CAPTION);
+      update_single_bit (&new_style, all, decorations & GDK_DECOR_MENU, WS_SYSMENU);
+      update_single_bit (&new_style, all, decorations & GDK_DECOR_MINIMIZE, WS_MINIMIZEBOX);
+      update_single_bit (&new_style, all, decorations & GDK_DECOR_MAXIMIZE, WS_MAXIMIZEBOX);
     }
 
-  /* XXX this is actually incorrect.  The menu entries should be added or removed
-     from the system menu without affecting the window style. */
-  if (_gdk_window_get_functions (window, &functions))
+  if (old_style == new_style && old_exstyle == new_exstyle )
     {
-      all = (functions & GDK_DECOR_ALL);
-      update_single_bit (&style, all, functions & GDK_FUNC_RESIZE, WS_THICKFRAME);
-      update_single_bit (&style, all, functions & GDK_FUNC_MOVE, WS_THICKFRAME | WS_SYSMENU);
-      update_single_bit (&style, all, functions & GDK_FUNC_MINIMIZE, WS_MINIMIZE);
-      update_single_bit (&style, all, functions & GDK_FUNC_MOVE, WS_MAXIMIZE);
-      update_single_bit (&style, all, functions & GDK_FUNC_CLOSE, WS_SYSMENU);
+      GDK_NOTE (MISC, g_print ("update_style_bits: %p: no change\n",
+                              GDK_WINDOW_HWND (window)));
+      return;
     }
-    
-  SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
 
-  AdjustWindowRectEx (&after, style, FALSE, exstyle);
+  if (old_style != new_style)
+    {
+      GDK_NOTE (MISC, g_print ("update_style_bits: %p: STYLE: %s => %s\n",
+                              GDK_WINDOW_HWND (window),
+                              _gdk_win32_window_style_to_string (old_style),
+                              _gdk_win32_window_style_to_string (new_style)));
+      
+      SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, new_style);
+    }
+
+  if (old_exstyle != new_exstyle)
+    {
+      GDK_NOTE (MISC, g_print ("update_style_bits: %p: EXSTYLE: %s => %s\n",
+                              GDK_WINDOW_HWND (window),
+                              _gdk_win32_window_exstyle_to_string (old_exstyle),
+                              _gdk_win32_window_exstyle_to_string (new_exstyle)));
+      
+      SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, new_exstyle);
+    }
+
+  AdjustWindowRectEx (&after, new_style, FALSE, new_exstyle);
 
   GetWindowRect (GDK_WINDOW_HWND (window), &rect);
   rect.left += after.left - before.left;
@@ -2649,6 +2305,42 @@ update_style_bits (GdkWindow *window)
                rect.right - rect.left, rect.bottom - rect.top,
                SWP_FRAMECHANGED | SWP_NOACTIVATE | 
                SWP_NOREPOSITION | SWP_NOZORDER);
+
+}
+
+static void
+update_single_system_menu_entry (HMENU    hmenu,
+                                gboolean all,
+                                int      gdk_bit,
+                                int      menu_entry)
+{
+  /* all controls the interpretation of gdk_bit -- if all is TRUE,
+   * gdk_bit indicates whether menu entry is disabled; if all is
+   * FALSE, gdk bit indicate whether menu entry is enabled
+   */
+  if ((!all && gdk_bit) || (all && !gdk_bit))
+    EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_ENABLED);
+  else
+    EnableMenuItem (hmenu, menu_entry, MF_BYCOMMAND | MF_GRAYED);
+}
+
+static void
+update_system_menu (GdkWindow *window)
+{
+  GdkWMFunction functions;
+  BOOL all;
+
+  if (_gdk_window_get_functions (window, &functions))
+    {
+      HMENU hmenu = GetSystemMenu (GDK_WINDOW_HWND (window), FALSE);
+
+      all = (functions & GDK_FUNC_ALL);
+      update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_RESIZE, SC_SIZE);
+      update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MOVE, SC_MOVE);
+      update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MINIMIZE, SC_MINIMIZE);
+      update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_MAXIMIZE, SC_MAXIMIZE);
+      update_single_system_menu_entry (hmenu, all, functions & GDK_FUNC_CLOSE, SC_CLOSE);
+    }
 }
 
 static GQuark
@@ -2662,8 +2354,8 @@ get_decorations_quark ()
   return quark;
 }
 
-void
-gdk_window_set_decorations (GdkWindow      *window,
+static void
+gdk_win32_window_set_decorations (GdkWindow      *window,
                            GdkWMDecoration decorations)
 {
   GdkWMDecoration* decorations_copy;
@@ -2687,8 +2379,8 @@ gdk_window_set_decorations (GdkWindow      *window,
   update_style_bits (window);
 }
 
-gboolean
-gdk_window_get_decorations (GdkWindow       *window,
+static gboolean
+gdk_win32_window_get_decorations (GdkWindow       *window,
                            GdkWMDecoration *decorations)
 {
   GdkWMDecoration* decorations_set;
@@ -2713,8 +2405,8 @@ get_functions_quark ()
   return quark;
 }
 
-void
-gdk_window_set_functions (GdkWindow    *window,
+static void
+gdk_win32_window_set_functions (GdkWindow    *window,
                          GdkWMFunction functions)
 {
   GdkWMFunction* functions_copy;
@@ -2734,7 +2426,7 @@ gdk_window_set_functions (GdkWindow    *window,
   *functions_copy = functions;
   g_object_set_qdata_full (G_OBJECT (window), get_functions_quark (), functions_copy, g_free);
 
-  update_style_bits (window);
+  update_system_menu (window);
 }
 
 gboolean
@@ -2750,121 +2442,8 @@ _gdk_window_get_functions (GdkWindow     *window,
   return (functions_set != NULL);
 }
 
-static void
-QueryTree (HWND   hwnd,
-          HWND **children,
-          gint  *nchildren)
-{
-  guint i, n;
-  HWND child;
-
-  n = 0;
-  do {
-    if (n == 0)
-      child = GetWindow (hwnd, GW_CHILD);
-    else
-      child = GetWindow (child, GW_HWNDNEXT);
-    if (child != NULL)
-      n++;
-  } while (child != NULL);
-
-  if (n > 0)
-    {
-      *children = g_new (HWND, n);
-      for (i = 0; i < n; i++)
-       {
-         if (i == 0)
-           child = GetWindow (hwnd, GW_CHILD);
-         else
-           child = GetWindow (child, GW_HWNDNEXT);
-         *children[i] = child;
-       }
-    }
-}
-
-static void
-gdk_propagate_shapes (HANDLE   win,
-                     gboolean merge)
-{
-   RECT emptyRect;
-   HRGN region, childRegion;
-   HWND *list = NULL;
-   gint i, num;
-
-   SetRectEmpty (&emptyRect);
-   region = CreateRectRgnIndirect (&emptyRect);
-   if (merge)
-     GetWindowRgn (win, region);
-   
-   QueryTree (win, &list, &num);
-   if (list != NULL)
-     {
-       WINDOWPLACEMENT placement;
-
-       placement.length = sizeof (WINDOWPLACEMENT);
-       /* go through all child windows and combine regions */
-       for (i = 0; i < num; i++)
-        {
-          GetWindowPlacement (list[i], &placement);
-          if (placement.showCmd == SW_SHOWNORMAL)
-            {
-              childRegion = CreateRectRgnIndirect (&emptyRect);
-              GetWindowRgn (list[i], childRegion);
-              CombineRgn (region, region, childRegion, RGN_OR);
-              DeleteObject (childRegion);
-            }
-         }
-       SetWindowRgn (win, region, TRUE);
-       g_free (list);
-     }
-   else
-     DeleteObject (region);
-}
-
-void
-gdk_window_set_child_shapes (GdkWindow *window)
-{
-  g_return_if_fail (GDK_IS_WINDOW (window));
-   
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
-
-  gdk_propagate_shapes (GDK_WINDOW_HWND (window), FALSE);
-}
-
-void
-gdk_window_merge_child_shapes (GdkWindow *window)
-{
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
-
-  gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
-}
-
-void 
-gdk_window_set_child_input_shapes (GdkWindow *window)
-{
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  /* Not yet implemented. See comment in
-   * gdk_window_input_shape_combine_mask().
-   */
-}
-
-void 
-gdk_window_merge_child_input_shapes (GdkWindow *window)
-{
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  /* Not yet implemented. See comment in
-   * gdk_window_input_shape_combine_mask().
-   */
-}
-
-gboolean 
-gdk_window_set_static_gravities (GdkWindow *window,
+static gboolean 
+gdk_win32_window_set_static_gravities (GdkWindow *window,
                                 gboolean   use_static)
 {
   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
@@ -2872,9 +2451,10 @@ gdk_window_set_static_gravities (GdkWindow *window,
   return !use_static;
 }
 
-void
-gdk_window_begin_resize_drag (GdkWindow     *window,
+static void
+gdk_win32_window_begin_resize_drag (GdkWindow     *window,
                               GdkWindowEdge  edge,
+                              GdkDevice     *device,
                               gint           button,
                               gint           root_x,
                               gint           root_y,
@@ -2941,8 +2521,9 @@ gdk_window_begin_resize_drag (GdkWindow     *window,
                  MAKELPARAM (root_x - _gdk_offset_x, root_y - _gdk_offset_y));
 }
 
-void
-gdk_window_begin_move_drag (GdkWindow *window,
+static void
+gdk_win32_window_begin_move_drag (GdkWindow *window,
+                            GdkDevice *device,
                             gint       button,
                             gint       root_x,
                             gint       root_y,
@@ -2975,8 +2556,8 @@ gdk_window_begin_move_drag (GdkWindow *window,
 /*
  * Setting window states
  */
-void
-gdk_window_iconify (GdkWindow *window)
+static void
+gdk_win32_window_iconify (GdkWindow *window)
 {
   HWND old_active_window;
 
@@ -2987,7 +2568,7 @@ gdk_window_iconify (GdkWindow *window)
 
   GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
                           GDK_WINDOW_HWND (window),
-                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+                          _gdk_win32_window_state_to_string (window->state)));
 
   if (GDK_WINDOW_IS_MAPPED (window))
     {
@@ -3004,8 +2585,8 @@ gdk_window_iconify (GdkWindow *window)
     }
 }
 
-void
-gdk_window_deiconify (GdkWindow *window)
+static void
+gdk_win32_window_deiconify (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3014,11 +2595,11 @@ gdk_window_deiconify (GdkWindow *window)
 
   GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
                           GDK_WINDOW_HWND (window),
-                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+                          _gdk_win32_window_state_to_string (window->state)));
 
   if (GDK_WINDOW_IS_MAPPED (window))
     {  
-      show_window_internal (window, FALSE, TRUE);
+      show_window_internal (window, GDK_WINDOW_IS_MAPPED (window), TRUE);
     }
   else
     {
@@ -3028,8 +2609,8 @@ gdk_window_deiconify (GdkWindow *window)
     }
 }
 
-void
-gdk_window_stick (GdkWindow *window)
+static void
+gdk_win32_window_stick (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3039,8 +2620,8 @@ gdk_window_stick (GdkWindow *window)
   /* FIXME: Do something? */
 }
 
-void
-gdk_window_unstick (GdkWindow *window)
+static void
+gdk_win32_window_unstick (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3050,8 +2631,8 @@ gdk_window_unstick (GdkWindow *window)
   /* FIXME: Do something? */
 }
 
-void
-gdk_window_maximize (GdkWindow *window)
+static void
+gdk_win32_window_maximize (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3060,7 +2641,7 @@ gdk_window_maximize (GdkWindow *window)
 
   GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
                           GDK_WINDOW_HWND (window),
-                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+                          _gdk_win32_window_state_to_string (window->state)));
 
   if (GDK_WINDOW_IS_MAPPED (window))
     ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
@@ -3070,8 +2651,8 @@ gdk_window_maximize (GdkWindow *window)
                                 GDK_WINDOW_STATE_MAXIMIZED);
 }
 
-void
-gdk_window_unmaximize (GdkWindow *window)
+static void
+gdk_win32_window_unmaximize (GdkWindow *window)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3080,7 +2661,7 @@ gdk_window_unmaximize (GdkWindow *window)
 
   GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
                           GDK_WINDOW_HWND (window),
-                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+                          _gdk_win32_window_state_to_string (window->state)));
 
   if (GDK_WINDOW_IS_MAPPED (window))
     ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
@@ -3099,12 +2680,13 @@ struct _FullscreenInfo
   LONG  style;
 };
 
-void
-gdk_window_fullscreen (GdkWindow *window)
+static void
+gdk_win32_window_fullscreen (GdkWindow *window)
 {
-  gint width, height;
+  gint x, y, width, height;
   FullscreenInfo *fi;
-  GdkWindowObject *private = (GdkWindowObject *) window;
+  HMONITOR monitor;
+  MONITORINFO mi;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3114,11 +2696,24 @@ gdk_window_fullscreen (GdkWindow *window)
     g_free (fi);
   else
     {
-      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
+      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+      monitor = MonitorFromWindow (GDK_WINDOW_HWND (window), MONITOR_DEFAULTTONEAREST);
+      mi.cbSize = sizeof (mi);
+      if (monitor && GetMonitorInfo (monitor, &mi))
+       {
+         x = mi.rcMonitor.left;
+         y = mi.rcMonitor.top;
+         width = mi.rcMonitor.right - x;
+         height = mi.rcMonitor.bottom - y;
+       }
+      else
+       {
+         x = y = 0;
+         width = GetSystemMetrics (SM_CXSCREEN);
+         height = GetSystemMetrics (SM_CYSCREEN);
+       }
 
-      width = GetSystemMetrics (SM_CXSCREEN);
-      height = GetSystemMetrics (SM_CYSCREEN);
       /* remember for restoring */
       fi->hint_flags = impl->hint_flags;
       impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
@@ -3129,25 +2724,24 @@ gdk_window_fullscreen (GdkWindow *window)
                      (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
 
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_TOP,
-                              0, 0, width, height,
+                              x, y, width, height,
                               SWP_NOCOPYBITS | SWP_SHOWWINDOW));
 
       gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
     }
 }
 
-void
-gdk_window_unfullscreen (GdkWindow *window)
+static void
+gdk_win32_window_unfullscreen (GdkWindow *window)
 {
   FullscreenInfo *fi;
-  GdkWindowObject *private = (GdkWindowObject *) window;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   fi = g_object_get_data (G_OBJECT (window), "fullscreen-info");
   if (fi)
     {
-      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
+      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
       impl->hint_flags = fi->hint_flags;
       SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
@@ -3163,14 +2757,19 @@ gdk_window_unfullscreen (GdkWindow *window)
     }
 }
 
-void
-gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
+static void
+gdk_win32_window_set_keep_above (GdkWindow *window,
+                          gboolean   setting)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  GDK_NOTE (MISC, g_print ("gdk_window_set_keep_above: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          setting ? "YES" : "NO"));
+
   if (GDK_WINDOW_IS_MAPPED (window))
     {
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
@@ -3184,14 +2783,19 @@ gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
                                 setting ? GDK_WINDOW_STATE_ABOVE : 0);
 }
 
-void
-gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
+static void
+gdk_win32_window_set_keep_below (GdkWindow *window,
+                          gboolean   setting)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  GDK_NOTE (MISC, g_print ("gdk_window_set_keep_below: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          setting ? "YES" : "NO"));
+
   if (GDK_WINDOW_IS_MAPPED (window))
     {
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window),
@@ -3205,9 +2809,9 @@ gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
                                 setting ? GDK_WINDOW_STATE_BELOW : 0);
 }
 
-void
-gdk_window_focus (GdkWindow *window,
-                  guint32    timestamp)
+static void
+gdk_win32_window_focus (GdkWindow *window,
+                       guint32    timestamp)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3216,67 +2820,90 @@ gdk_window_focus (GdkWindow *window,
   
   GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
                           GDK_WINDOW_HWND (window),
-                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+                          _gdk_win32_window_state_to_string (window->state)));
 
-  if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_MAXIMIZED)
+  if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
     ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
   else
     ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
   SetFocus (GDK_WINDOW_HWND (window));
 }
 
-void
-gdk_window_set_modal_hint (GdkWindow *window,
+static void
+gdk_win32_window_set_modal_hint (GdkWindow *window,
                           gboolean   modal)
 {
-  GdkWindowObject *private;
-
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  private = (GdkWindowObject*) window;
+  GDK_NOTE (MISC, g_print ("gdk_window_set_modal_hint: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          modal ? "YES" : "NO"));
+
+  if (modal == window->modal_hint)
+    return;
 
-  private->modal_hint = modal;
+  window->modal_hint = modal;
 
+#if 0
+  /* Not sure about this one.. -- Cody */
   if (GDK_WINDOW_IS_MAPPED (window))
     API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), 
                             modal ? HWND_TOPMOST : HWND_NOTOPMOST,
                             0, 0, 0, 0,
                             SWP_NOMOVE | SWP_NOSIZE));
+#else
+
+  if (modal)
+    {
+      _gdk_push_modal_window (window);
+      gdk_window_raise (window);
+    }
+  else
+    {
+      _gdk_remove_modal_window (window);
+    }
+
+#endif
 }
 
-void
-gdk_window_set_skip_taskbar_hint (GdkWindow *window,
+static void
+gdk_win32_window_set_skip_taskbar_hint (GdkWindow *window,
                                  gboolean   skips_taskbar)
 {
   static GdkWindow *owner = NULL;
-  GdkWindowAttr wa;
+  //GdkWindowAttr wa;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s\n",
+  GDK_NOTE (MISC, g_print ("gdk_window_set_skip_taskbar_hint: %p: %s, doing nothing\n",
                           GDK_WINDOW_HWND (window),
-                          skips_taskbar ? "TRUE" : "FALSE"));
+                          skips_taskbar ? "YES" : "NO"));
+
+  // ### TODO: Need to figure out what to do here.
+  return;
 
   if (skips_taskbar)
     {
+#if 0
       if (owner == NULL)
-       {
-         wa.window_type = GDK_WINDOW_TEMP;
-         wa.wclass = GDK_INPUT_OUTPUT;
-         wa.width = wa.height = 1;
-         wa.event_mask = 0;
-         owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
-       }
+               {
+                 wa.window_type = GDK_WINDOW_TEMP;
+                 wa.wclass = GDK_INPUT_OUTPUT;
+                 wa.width = wa.height = 1;
+                 wa.event_mask = 0;
+                 owner = gdk_window_new_internal (NULL, &wa, 0, TRUE);
+               }
+#endif
 
-      SetWindowLong (GDK_WINDOW_HWND (window), GWL_HWNDPARENT,
-                    (long) GDK_WINDOW_HWND (owner));
+      SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, (LONG_PTR) GDK_WINDOW_HWND (owner));
 
 #if 0 /* Should we also turn off the minimize and maximize buttons? */
       SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE,
                     GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE) & ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU));
+     
       SetWindowPos (GDK_WINDOW_HWND (window), NULL,
                    0, 0, 0, 0,
                    SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
@@ -3285,19 +2912,23 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
     }
   else
     {
-      SetWindowLong (GDK_WINDOW_HWND (window), GWL_HWNDPARENT, 0);
+      SetWindowLongPtr (GDK_WINDOW_HWND (window), GWLP_HWNDPARENT, 0);
     }
 }
 
-void
-gdk_window_set_skip_pager_hint (GdkWindow *window,
+static void
+gdk_win32_window_set_skip_pager_hint (GdkWindow *window,
                                gboolean   skips_pager)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
+
+  GDK_NOTE (MISC, g_print ("gdk_window_set_skip_pager_hint: %p: %s, doing nothing\n",
+                          GDK_WINDOW_HWND (window),
+                          skips_pager ? "YES" : "NO"));
 }
 
-void
-gdk_window_set_type_hint (GdkWindow        *window,
+static void
+gdk_win32_window_set_type_hint (GdkWindow        *window,
                          GdkWindowTypeHint hint)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -3305,97 +2936,461 @@ gdk_window_set_type_hint (GdkWindow        *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_set_type_hint: %p: %d\n",
-                          GDK_WINDOW_HWND (window), hint));
+  GDK_NOTE (MISC,
+           G_STMT_START{
+             static GEnumClass *class = NULL;
+             if (!class)
+               class = g_type_class_ref (GDK_TYPE_WINDOW_TYPE_HINT);
+             g_print ("gdk_window_set_type_hint: %p: %s\n",
+                      GDK_WINDOW_HWND (window),
+                      g_enum_get_value (class, hint)->value_name);
+           }G_STMT_END);
 
-  ((GdkWindowImplWin32 *)((GdkWindowObject *)window)->impl)->type_hint = hint;
+  ((GdkWindowImplWin32 *)window->impl)->type_hint = hint;
 
   update_style_bits (window);
 }
 
-GdkWindowTypeHint
-gdk_window_get_type_hint (GdkWindow *window)
+static GdkWindowTypeHint
+gdk_win32_window_get_type_hint (GdkWindow *window)
 {
   g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
   
   if (GDK_WINDOW_DESTROYED (window))
     return GDK_WINDOW_TYPE_HINT_NORMAL;
 
-  return GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->type_hint;
+  return GDK_WINDOW_IMPL_WIN32 (window->impl)->type_hint;
 }
 
-void
-gdk_window_shape_combine_region (GdkWindow *window,
-                                 GdkRegion *shape_region,
-                                 gint       offset_x,
-                                 gint       offset_y)
+static HRGN
+cairo_region_to_hrgn (const cairo_region_t *region,
+                     gint                  x_origin,
+                     gint                  y_origin)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
+  HRGN hrgn;
+  RGNDATA *rgndata;
+  RECT *rect;
+  cairo_rectangle_int_t r;
+  const int nrects = cairo_region_num_rectangles (region);
+  guint nbytes =
+    sizeof (RGNDATAHEADER) + (sizeof (RECT) * nrects);
+  int i;
 
-  g_return_if_fail (GDK_IS_WINDOW (window));
+  rgndata = g_malloc (nbytes);
+  rgndata->rdh.dwSize = sizeof (RGNDATAHEADER);
+  rgndata->rdh.iType = RDH_RECTANGLES;
+  rgndata->rdh.nCount = rgndata->rdh.nRgnSize = 0;
+  SetRect (&rgndata->rdh.rcBound,
+          G_MAXLONG, G_MAXLONG, G_MINLONG, G_MINLONG);
+
+  for (i = 0; i < nrects; i++)
+    {
+      rect = ((RECT *) rgndata->Buffer) + rgndata->rdh.nCount++;
+      
+      cairo_region_get_rectangle (region, i, &r);
+      rect->left = r.x + x_origin;
+      rect->right = rect->left + r.width;
+      rect->top = r.y + y_origin;
+      rect->bottom = rect->top + r.height;
+
+      if (rect->left < rgndata->rdh.rcBound.left)
+       rgndata->rdh.rcBound.left = rect->left;
+      if (rect->right > rgndata->rdh.rcBound.right)
+       rgndata->rdh.rcBound.right = rect->right;
+      if (rect->top < rgndata->rdh.rcBound.top)
+       rgndata->rdh.rcBound.top = rect->top;
+      if (rect->bottom > rgndata->rdh.rcBound.bottom)
+       rgndata->rdh.rcBound.bottom = rect->bottom;
+    }
+  if ((hrgn = ExtCreateRegion (NULL, nbytes, rgndata)) == NULL)
+    WIN32_API_FAILED ("ExtCreateRegion");
+
+  g_free (rgndata);
+
+  return (hrgn);
+}
 
+static void
+gdk_win32_window_shape_combine_region (GdkWindow       *window,
+                                      const cairo_region_t *shape_region,
+                                      gint             offset_x,
+                                      gint             offset_y)
+{
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
   if (!shape_region)
     {
-      GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: none\n",
+      GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: none\n",
                               GDK_WINDOW_HWND (window)));
       SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
-
-      private->shaped = FALSE;
     }
   else
     {
       HRGN hrgn;
 
-      hrgn = _gdk_win32_gdkregion_to_hrgn (shape_region, 0, 0);
+      hrgn = cairo_region_to_hrgn (shape_region, 0, 0);
       
-      GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_region: %p: %p\n",
+      GDK_NOTE (MISC, g_print ("gdk_win32_window_shape_combine_region: %p: %p\n",
                               GDK_WINDOW_HWND (window),
                               hrgn));
 
       do_shape_combine_region (window, hrgn, offset_x, offset_y);
-
-      private->shaped = TRUE;
     }
 }
 
-void 
-gdk_window_input_shape_combine_region (GdkWindow *window,
-                                      GdkRegion *shape_region,
-                                      gint       offset_x,
-                                      gint       offset_y)
+GdkWindow *
+gdk_win32_window_lookup_for_display (GdkDisplay *display,
+                                     HWND        anid)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_val_if_fail (display == _gdk_display, NULL);
 
-  /* Not yet implemented. See comment in
-   * gdk_window_input_shape_combine_mask().
-   */
+  return (GdkWindow*) gdk_win32_handle_table_lookup (anid);
 }
 
-GdkWindow *
-gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
+static void
+gdk_win32_window_enable_synchronized_configure (GdkWindow *window)
 {
-  g_return_val_if_fail (display == _gdk_display, NULL);
+  /* nothing - no window manager to cooperate with */
+}
 
-  return gdk_window_lookup (anid);
+static void
+gdk_win32_window_configure_finished (GdkWindow *window)
+{
+  /* nothing - no window manager to cooperate with */
 }
 
-void
-gdk_window_enable_synchronized_configure (GdkWindow *window)
+static void
+gdk_win32_window_set_opacity (GdkWindow *window,
+                       gdouble    opacity)
 {
+  LONG exstyle;
+  typedef BOOL (*PFN_SetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
+  PFN_SetLayeredWindowAttributes setLayeredWindowAttributes = NULL;
+
   g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  if (opacity < 0)
+    opacity = 0;
+  else if (opacity > 1)
+    opacity = 1;
+
+  exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
+
+  if (!(exstyle & WS_EX_LAYERED))
+    API_CALL (SetWindowLong, (GDK_WINDOW_HWND (window),
+                             GWL_EXSTYLE,
+                             exstyle | WS_EX_LAYERED));
+
+  setLayeredWindowAttributes = 
+    (PFN_SetLayeredWindowAttributes)GetProcAddress (GetModuleHandle ("user32.dll"), "SetLayeredWindowAttributes");
+
+  if (setLayeredWindowAttributes)
+    {
+      API_CALL (setLayeredWindowAttributes, (GDK_WINDOW_HWND (window),
+                                            0,
+                                            opacity * 0xff,
+                                            LWA_ALPHA));
+    }
 }
 
-void
-gdk_window_configure_finished (GdkWindow *window)
+static cairo_region_t *
+gdk_win32_window_get_shape (GdkWindow *window)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
+  HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
+  int  type = GetWindowRgn (GDK_WINDOW_HWND (window), hrgn);
+
+  if (type == SIMPLEREGION || type == COMPLEXREGION)
+    {
+      cairo_region_t *region = _gdk_win32_hrgn_to_region (hrgn);
+
+      DeleteObject (hrgn);
+      return region;
+    }
+
+  return NULL;
 }
 
-void
-gdk_window_beep (GdkWindow *window)
+static gboolean
+_gdk_win32_window_queue_antiexpose (GdkWindow *window,
+                                   cairo_region_t *area)
+{
+  HRGN hrgn = cairo_region_to_hrgn (area, 0, 0);
+
+  GDK_NOTE (EVENTS, g_print ("_gdk_windowing_window_queue_antiexpose: ValidateRgn %p %s\n",
+                            GDK_WINDOW_HWND (window),
+                            _gdk_win32_cairo_region_to_string (area)));
+
+  ValidateRgn (GDK_WINDOW_HWND (window), hrgn);
+
+  DeleteObject (hrgn);
+
+  return FALSE;
+}
+
+/* Gets called from gdwindow.c(do_move_region_bits_on_impl)
+ * and got tested with testgtk::big_window. Given the previous,
+ * untested implementation this one looks much too simple ;)
+ */
+static void
+_gdk_win32_window_translate (GdkWindow *window,
+                             cairo_region_t *area, /* In impl window coords */
+                             gint       dx,
+                             gint       dy)
+{
+  GdkRectangle extents;
+  RECT rect;
+
+  cairo_region_get_extents (area, &extents);
+  rect.left = extents.x - dx;
+  rect.top = extents.y - dy;
+  rect.right = rect.left + extents.width;
+  rect.bottom = rect.top + extents.height;
+
+  API_CALL (ScrollWindowEx, (GDK_WINDOW_HWND (window), 
+                            dx, dy, &rect, 
+                            NULL, NULL, NULL, 
+                            SW_INVALIDATE));
+
+}
+
+static void
+gdk_win32_input_shape_combine_region (GdkWindow *window,
+                                     const cairo_region_t *shape_region,
+                                     gint offset_x,
+                                     gint offset_y)
+{
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+  /* CHECK: are these really supposed to be the same? */
+  gdk_win32_window_shape_combine_region (window, shape_region, offset_x, offset_y);
+}
+
+static void
+gdk_win32_window_process_updates_recurse (GdkWindow *window,
+                                              cairo_region_t *region)
+{
+  _gdk_window_process_updates_recurse (window, region);
+}
+
+gboolean
+gdk_win32_window_is_win32 (GdkWindow *window)
+{
+  return GDK_WINDOW_IS_WIN32 (window);
+}
+
+/**
+ * _gdk_win32_acquire_dc
+ * @impl: a Win32 #GdkWindowImplWin32 implementation
+ * 
+ * Gets a DC with the given drawable selected into it.
+ *
+ * Return value: The DC, on success. Otherwise
+ *  %NULL. If this function succeeded
+ *  _gdk_win32_impl_release_dc()  must be called
+ *  release the DC when you are done using it.
+ **/
+static HDC 
+_gdk_win32_impl_acquire_dc (GdkWindowImplWin32 *impl)
+{
+  if (GDK_IS_WINDOW_IMPL_WIN32 (impl) &&
+      GDK_WINDOW_DESTROYED (impl->wrapper))
+    return NULL;
+
+  if (!impl->hdc)
+    {
+      impl->hdc = GetDC (impl->handle);
+      if (!impl->hdc)
+       WIN32_GDI_FAILED ("GetDC");
+    }
+
+  if (impl->hdc)
+    {
+      impl->hdc_count++;
+      return impl->hdc;
+    }
+  else
+    {
+      return NULL;
+    }
+}
+
+/**
+ * _gdk_win32_impl_release_dc
+ * @impl: a Win32 #GdkWindowImplWin32 implementation
+ * 
+ * Releases the reference count for the DC
+ * from _gdk_win32_impl_acquire_dc()
+ **/
+static void
+_gdk_win32_impl_release_dc (GdkWindowImplWin32 *impl)
+{
+  g_return_if_fail (impl->hdc_count > 0);
+
+  impl->hdc_count--;
+  if (impl->hdc_count == 0)
+    {
+      if (impl->saved_dc_bitmap)
+       {
+         GDI_CALL (SelectObject, (impl->hdc, impl->saved_dc_bitmap));
+         impl->saved_dc_bitmap = NULL;
+       }
+      
+      if (impl->hdc)
+       {
+         GDI_CALL (ReleaseDC, (impl->handle, impl->hdc));
+         impl->hdc = NULL;
+       }
+    }
+}
+
+static void
+gdk_win32_cairo_surface_destroy (void *data)
 {
-  gdk_display_beep (_gdk_display);
+  GdkWindowImplWin32 *impl = data;
+
+  _gdk_win32_impl_release_dc (impl);
+  impl->cairo_surface = NULL;
+}
+
+static cairo_surface_t *
+gdk_win32_ref_cairo_surface (GdkWindow *window)
+{
+  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
+
+  if (GDK_IS_WINDOW_IMPL_WIN32 (impl) &&
+      GDK_WINDOW_DESTROYED (impl->wrapper))
+    return NULL;
+
+  if (!impl->cairo_surface)
+    {
+      HDC hdc = _gdk_win32_impl_acquire_dc (impl);
+      if (!hdc)
+       return NULL;
+
+      impl->cairo_surface = cairo_win32_surface_create (hdc);
+
+      cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
+                                  impl, gdk_win32_cairo_surface_destroy);
+    }
+  else
+    cairo_surface_reference (impl->cairo_surface);
+
+  return impl->cairo_surface;
+}
+
+static void
+gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize = gdk_window_impl_win32_finalize;
+  
+  impl_class->ref_cairo_surface = gdk_win32_ref_cairo_surface;
+
+  impl_class->show = gdk_win32_window_show;
+  impl_class->hide = gdk_win32_window_hide;
+  impl_class->withdraw = gdk_win32_window_withdraw;
+  impl_class->set_events = gdk_win32_window_set_events;
+  impl_class->get_events = gdk_win32_window_get_events;
+  impl_class->raise = gdk_win32_window_raise;
+  impl_class->lower = gdk_win32_window_lower;
+  impl_class->restack_under = gdk_win32_window_restack_under;
+  impl_class->restack_toplevel = gdk_win32_window_restack_toplevel;
+  impl_class->move_resize = gdk_win32_window_move_resize;
+  impl_class->set_background = gdk_win32_window_set_background;
+  impl_class->reparent = gdk_win32_window_reparent;
+  impl_class->set_device_cursor = gdk_win32_window_set_device_cursor;
+  impl_class->get_geometry = gdk_win32_window_get_geometry;
+  impl_class->get_device_state = gdk_window_win32_get_device_state;
+  impl_class->get_root_coords = gdk_win32_window_get_root_coords;
+
+  impl_class->shape_combine_region = gdk_win32_window_shape_combine_region;
+  impl_class->input_shape_combine_region = gdk_win32_input_shape_combine_region;
+  impl_class->set_static_gravities = gdk_win32_window_set_static_gravities;
+  impl_class->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
+  impl_class->translate = _gdk_win32_window_translate;
+  impl_class->destroy = gdk_win32_window_destroy;
+  impl_class->destroy_foreign = gdk_win32_window_destroy_foreign;
+  impl_class->resize_cairo_surface = gdk_win32_window_resize_cairo_surface;
+  impl_class->get_shape = gdk_win32_window_get_shape;
+  //FIXME?: impl_class->get_input_shape = gdk_win32_window_get_input_shape;
+
+  //impl_class->beep = gdk_x11_window_beep;
+
+  impl_class->focus = gdk_win32_window_focus;
+  impl_class->set_type_hint = gdk_win32_window_set_type_hint;
+  impl_class->get_type_hint = gdk_win32_window_get_type_hint;
+  impl_class->set_modal_hint = gdk_win32_window_set_modal_hint;
+  impl_class->set_skip_taskbar_hint = gdk_win32_window_set_skip_taskbar_hint;
+  impl_class->set_skip_pager_hint = gdk_win32_window_set_skip_pager_hint;
+  impl_class->set_urgency_hint = gdk_win32_window_set_urgency_hint;
+  impl_class->set_geometry_hints = gdk_win32_window_set_geometry_hints;
+  impl_class->set_title = gdk_win32_window_set_title;
+  impl_class->set_role = gdk_win32_window_set_role;
+  //impl_class->set_startup_id = gdk_x11_window_set_startup_id;
+  impl_class->set_transient_for = gdk_win32_window_set_transient_for;
+  impl_class->get_root_origin = gdk_win32_window_get_root_origin;
+  impl_class->get_frame_extents = gdk_win32_window_get_frame_extents;
+  impl_class->set_override_redirect = gdk_win32_window_set_override_redirect;
+  impl_class->set_accept_focus = gdk_win32_window_set_accept_focus;
+  impl_class->set_focus_on_map = gdk_win32_window_set_focus_on_map;
+  impl_class->set_icon_list = gdk_win32_window_set_icon_list;
+  impl_class->set_icon_name = gdk_win32_window_set_icon_name;
+  impl_class->iconify = gdk_win32_window_iconify;
+  impl_class->deiconify = gdk_win32_window_deiconify;
+  impl_class->stick = gdk_win32_window_stick;
+  impl_class->unstick = gdk_win32_window_unstick;
+  impl_class->maximize = gdk_win32_window_maximize;
+  impl_class->unmaximize = gdk_win32_window_unmaximize;
+  impl_class->fullscreen = gdk_win32_window_fullscreen;
+  impl_class->unfullscreen = gdk_win32_window_unfullscreen;
+  impl_class->set_keep_above = gdk_win32_window_set_keep_above;
+  impl_class->set_keep_below = gdk_win32_window_set_keep_below;
+  impl_class->get_group = gdk_win32_window_get_group;
+  impl_class->set_group = gdk_win32_window_set_group;
+  impl_class->set_decorations = gdk_win32_window_set_decorations;
+  impl_class->get_decorations = gdk_win32_window_get_decorations;
+  impl_class->set_functions = gdk_win32_window_set_functions;
+
+  impl_class->begin_resize_drag = gdk_win32_window_begin_resize_drag;
+  impl_class->begin_move_drag = gdk_win32_window_begin_move_drag;
+  impl_class->enable_synchronized_configure = gdk_win32_window_enable_synchronized_configure;
+  impl_class->configure_finished = gdk_win32_window_configure_finished;
+  impl_class->set_opacity = gdk_win32_window_set_opacity;
+  //impl_class->set_composited = gdk_win32_window_set_composited;
+  impl_class->destroy_notify = gdk_win32_window_destroy_notify;
+  impl_class->get_drag_protocol = _gdk_win32_window_get_drag_protocol;
+  impl_class->register_dnd = _gdk_win32_window_register_dnd;
+  impl_class->drag_begin = _gdk_win32_window_drag_begin;
+  impl_class->process_updates_recurse = gdk_win32_window_process_updates_recurse;
+  //? impl_class->sync_rendering = _gdk_win32_window_sync_rendering;
+  impl_class->simulate_key = _gdk_win32_window_simulate_key;
+  impl_class->simulate_button = _gdk_win32_window_simulate_button;
+  impl_class->get_property = _gdk_win32_window_get_property;
+  impl_class->change_property = _gdk_win32_window_change_property;
+  impl_class->delete_property = _gdk_win32_window_delete_property;
+}
+
+HGDIOBJ
+gdk_win32_window_get_handle (GdkWindow *window)
+{
+  /* Try to ensure the window has a native window */
+  if (!_gdk_window_has_impl (window))
+    gdk_window_ensure_native (window);
+
+  if (!GDK_WINDOW_IS_WIN32 (window))
+    {
+      g_warning (G_STRLOC " window is not a native Win32 window");
+      return NULL;
+    }
+
+  return GDK_WINDOW_HWND (window);
 }