]> Pileus Git - ~andy/gtk/blobdiff - gdk/win32/gdkwindow-win32.c
List the three theme gtkrc files separately, zip doesn't do anything if
[~andy/gtk] / gdk / win32 / gdkwindow-win32.c
index 1d6e7deeb408112743a1d2d559ab3ba91df1d2b0..5fe64b7e9f728fb73089e79486f537297a1ad564 100644 (file)
@@ -1,6 +1,7 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- * Copyright (C) 1998-1999 Tor Lillqvist
+ * Copyright (C) 1998-2004 Tor Lillqvist
+ * Copyright (C) 2001-2004 Hans Breuer
  *
  * 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 <stdlib.h>
 
 #include "gdk.h" /* gdk_rectangle_intersect */
 #include "gdkevents.h"
 #include "gdkpixmap.h"
 #include "gdkwindow.h"
-#include "gdkinternals.h"
+#include "gdkdisplay.h"
 #include "gdkprivate-win32.h"
 #include "gdkinput-win32.h"
 
-static gboolean gdk_window_gravity_works (void);
-static void     gdk_window_set_static_win_gravity (GdkWindow *window, 
-                                                  gboolean   on);
+#if defined __MINGW32__ || (WINVER < 0x0500)
+typedef struct { 
+  DWORD        bV5Size; 
+  LONG         bV5Width; 
+  LONG         bV5Height; 
+  WORD         bV5Planes; 
+  WORD         bV5BitCount; 
+  DWORD        bV5Compression; 
+  DWORD        bV5SizeImage; 
+  LONG         bV5XPelsPerMeter; 
+  LONG         bV5YPelsPerMeter; 
+  DWORD        bV5ClrUsed; 
+  DWORD        bV5ClrImportant; 
+  DWORD        bV5RedMask; 
+  DWORD        bV5GreenMask; 
+  DWORD        bV5BlueMask; 
+  DWORD        bV5AlphaMask; 
+  DWORD        bV5CSType; 
+  CIEXYZTRIPLE bV5Endpoints; 
+  DWORD        bV5GammaRed; 
+  DWORD        bV5GammaGreen; 
+  DWORD        bV5GammaBlue; 
+  DWORD        bV5Intent; 
+  DWORD        bV5ProfileData; 
+  DWORD        bV5ProfileSize; 
+  DWORD        bV5Reserved; 
+} BITMAPV5HEADER;
+
+#endif
+
+#if 0
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <stdio.h>
+#endif
 
 static GdkColormap* gdk_window_impl_win32_get_colormap (GdkDrawable *drawable);
 static void         gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
@@ -45,7 +78,7 @@ static void         gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
 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 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);
@@ -53,7 +86,7 @@ static void gdk_window_impl_win32_finalize   (GObject                 *object);
 static gpointer parent_class = NULL;
 
 GType
-gdk_window_impl_win32_get_type (void)
+_gdk_window_impl_win32_get_type (void)
 {
   static GType object_type = 0;
 
@@ -83,7 +116,7 @@ gdk_window_impl_win32_get_type (void)
 GType
 _gdk_window_impl_get_type (void)
 {
-  return gdk_window_impl_win32_get_type ();
+  return _gdk_window_impl_win32_get_type ();
 }
 
 static void
@@ -92,13 +125,11 @@ gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
   impl->width = 1;
   impl->height = 1;
 
-  impl->event_mask = 0;
   impl->hcursor = NULL;
+  impl->hicon_big = NULL;
+  impl->hicon_small = NULL;
   impl->hint_flags = 0;
   impl->extension_events_selected = FALSE;
-  impl->input_locale = GetKeyboardLayout (0);
-  TranslateCharsetInfo ((DWORD FAR *) GetACP (), &impl->charset_info,
-                       TCI_SRCCODEPAGE);
 }
 
 static void
@@ -141,30 +172,59 @@ gdk_window_impl_win32_finalize (GObject *object)
 
   if (window_impl->hcursor != NULL)
     {
-      if (!DestroyCursor (window_impl->hcursor))
-        WIN32_GDI_FAILED("DestroyCursor");
+      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));
+      window_impl->hicon_small = NULL;
+    }
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+void
+_gdk_win32_adjust_client_rect (GdkWindow *window,
+                              RECT      *rect)
+{
+  LONG style, exstyle;
+
+  style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
+  exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
+  API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
+}
+
+void
+_gdk_win32_get_adjusted_client_rect (GdkWindow *window,
+                                    RECT      *rect)
+{
+  GetClientRect (GDK_WINDOW_HWND (window), rect);
+  _gdk_win32_adjust_client_rect (window, rect);
+}
+
 static GdkColormap*
 gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
 {
   GdkDrawableImplWin32 *drawable_impl;
-  GdkWindowImplWin32 *window_impl;
   
   g_return_val_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable), NULL);
 
   drawable_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
-  window_impl = GDK_WINDOW_IMPL_WIN32 (drawable);
 
   if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only && 
       drawable_impl->colormap == NULL)
     {
-      drawable_impl->colormap = gdk_colormap_get_system ();
-      gdk_colormap_ref (drawable_impl->colormap);
+      drawable_impl->colormap = 
+        gdk_screen_get_system_colormap (gdk_drawable_get_screen (drawable));
+      g_object_ref (drawable_impl->colormap);
     }
   
   return drawable_impl->colormap;
@@ -178,15 +238,18 @@ gdk_window_impl_win32_set_colormap (GdkDrawable *drawable,
   GdkDrawableImplWin32 *draw_impl;
   
   g_return_if_fail (GDK_IS_WINDOW_IMPL_WIN32 (drawable));
-  g_return_if_fail (gdk_colormap_get_visual (cmap) != gdk_drawable_get_visual (drawable));
 
   impl = GDK_WINDOW_IMPL_WIN32 (drawable);
   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (drawable);
 
-  GDK_DRAWABLE_GET_CLASS (draw_impl)->set_colormap (drawable, cmap);
+  /* chain up */
+  GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
   
-  /* XXX */
-  g_print("gdk_window_impl_win32_set_colormap: XXX\n");
+  if (cmap)
+    {
+      /* XXX */
+      g_print("gdk_window_impl_win32_set_colormap: XXX\n");
+    }
 }
 
 static void
@@ -207,6 +270,7 @@ gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
 {
   GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (drawable);
   GdkRectangle result_rect;
+  HDC hdc;
 
   result_rect.x = 0;
   result_rect.y = 0;
@@ -215,66 +279,82 @@ gdk_window_impl_win32_get_visible_region (GdkDrawable *drawable)
 
   gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
 
+  /* take this win32 specific part into account (smaller when obscured) */
+  hdc = GetDC (GDK_DRAWABLE_IMPL_WIN32_HANDLE (impl));
+  if (hdc)
+    {
+      RECT r;
+      if (SIMPLEREGION == GetClipBox (hdc, &r))
+        {
+          GdkRectangle gr;
+
+          gr.x = r.left;
+          gr.y = r.top;
+          gr.width = r.right - r.left;
+          gr.height = r.bottom - r.top;
+
+          gdk_rectangle_intersect (&result_rect, &gr, &result_rect);
+        }
+      ReleaseDC (GDK_DRAWABLE_IMPL_WIN32_HANDLE (drawable), hdc);
+    }
+
   return gdk_region_rectangle (&result_rect);
 }
 
+void
+_gdk_root_window_size_init (void)
+{
+  GdkWindowImplWin32 *impl;
+  GdkRectangle rect;
+  int i;
+
+  impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) _gdk_parent_root)->impl);
+  rect = _gdk_monitors[0];
+  for (i = 1; i < _gdk_num_monitors; i++)
+    gdk_rectangle_union (&rect, _gdk_monitors+i, &rect);
+
+  impl->width = rect.width;
+  impl->height = rect.height;
+}
+
 void
 _gdk_windowing_window_init (void)
 {
   GdkWindowObject *private;
-  GdkWindowImplWin32 *impl;
   GdkDrawableImplWin32 *draw_impl;
-  RECT rect;
-  guint width;
-  guint height;
 
-  g_assert (gdk_parent_root == NULL);
+  g_assert (_gdk_parent_root == NULL);
   
-  SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
-  width  = rect.right - rect.left;
-  height = rect.bottom - rect.top;
-
-  gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
-  private = (GdkWindowObject *)gdk_parent_root;
-  impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
+  _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
+  private = (GdkWindowObject *)_gdk_parent_root;
   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
   
-  draw_impl->handle = gdk_root_window;
+  draw_impl->handle = _gdk_root_window;
   draw_impl->wrapper = GDK_DRAWABLE (private);
+  draw_impl->colormap = gdk_colormap_get_system ();
+  g_object_ref (draw_impl->colormap);
   
   private->window_type = GDK_WINDOW_ROOT;
   private->depth = gdk_visual_get_system ()->depth;
-  impl->width = width;
-  impl->height = height;
 
-  gdk_win32_handle_table_insert (&gdk_root_window, gdk_parent_root);
+  _gdk_root_window_size_init ();
+  _gdk_window_init_position (GDK_WINDOW (private));
+
+  gdk_win32_handle_table_insert (&_gdk_root_window, _gdk_parent_root);
+
+  GDK_NOTE (MISC, g_print ("_gdk_parent_root=%p\n", GDK_WINDOW_HWND (_gdk_parent_root)));
 }
 
-/* The Win API function AdjustWindowRect may return negative values
- * resulting in obscured title bars. This helper function is coreccting it.
- */
-BOOL
-SafeAdjustWindowRectEx (RECT* lpRect,
-                       DWORD dwStyle, 
-                       BOOL  bMenu, 
-                       DWORD dwExStyle)
+static const gchar *
+get_default_title (void)
 {
-  if (!AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle))
-    {
-      WIN32_API_FAILED ("AdjustWindowRectEx");
-      return FALSE;
-    }
-  if (lpRect->left < 0)
-    {
-      lpRect->right -= lpRect->left;
-      lpRect->left = 0;
-    }
-  if (lpRect->top < 0)
-    {
-      lpRect->bottom -= lpRect->top;
-      lpRect->top = 0;
-    }
-  return TRUE;
+  const char *title;
+  title = g_get_application_name ();
+  if (!title)
+    title = g_get_prgname ();
+
+  return title;
 }
 
 /* RegisterGdkClass
@@ -284,7 +364,7 @@ SafeAdjustWindowRectEx (RECT* lpRect,
  *   is ever needed (e.g Dialog specific), every such window should
  *   get its own class
  */
-ATOM
+static ATOM
 RegisterGdkClass (GdkWindowType wtype)
 {
   static ATOM klassTOPLEVEL = 0;
@@ -295,34 +375,31 @@ RegisterGdkClass (GdkWindowType wtype)
   static WNDCLASSEX wcl; 
   ATOM klass = 0;
 
-  wcl.cbSize = sizeof(WNDCLASSEX);     
+  wcl.cbSize = sizeof (WNDCLASSEX);
   wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
                   * on WM_SIZE and WM_MOVE. Flicker, Performance!
                   */
-  wcl.lpfnWndProc = gdk_window_procedure;
+  wcl.lpfnWndProc = _gdk_win32_window_procedure;
   wcl.cbClsExtra = 0;
   wcl.cbWndExtra = 0;
-  wcl.hInstance = gdk_app_hmodule;
+  wcl.hInstance = _gdk_app_hmodule;
   wcl.hIcon = 0;
   /* initialize once! */
   if (0 == hAppIcon)
     {
-      gchar sLoc [_MAX_PATH+1];
+      gchar sLoc [MAX_PATH+1];
 
-      if (0 != GetModuleFileName (gdk_app_hmodule, sLoc, _MAX_PATH))
+      if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH))
        {
-         hAppIcon = ExtractIcon (gdk_app_hmodule, sLoc, 0);
+         hAppIcon = ExtractIcon (_gdk_app_hmodule, sLoc, 0);
          if (0 == hAppIcon)
            {
-             char *gdklibname = g_strdup_printf ("gdk-%s.dll", GDK_VERSION);
-
-             hAppIcon = ExtractIcon (gdk_app_hmodule, gdklibname, 0);
-             g_free (gdklibname);
+             if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
+               hAppIcon = ExtractIcon (_gdk_dll_hinstance, sLoc, 0);
            }
-         
-         if (0 == hAppIcon) 
-           hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
        }
+      if (0 == hAppIcon) 
+       hAppIcon = LoadIcon (NULL, IDI_APPLICATION);
     }
 
   wcl.lpszMenuName = NULL;
@@ -337,22 +414,22 @@ RegisterGdkClass (GdkWindowType wtype)
 #define ONCE_PER_CLASS() \
   wcl.hIcon = CopyIcon (hAppIcon); \
   wcl.hIconSm = CopyIcon (hAppIcon); \
-  wcl.hbrBackground = NULL; /* CreateSolidBrush (RGB (0,0,0)); */ \
+  wcl.hbrBackground = NULL; \
   wcl.hCursor = LoadCursor (NULL, IDC_ARROW); 
   
   switch (wtype)
-  {
-  case GDK_WINDOW_TOPLEVEL:
-    if (0 == klassTOPLEVEL)
-      {
-       wcl.lpszClassName = "gdkWindowToplevel";
-       
-       ONCE_PER_CLASS();
-       klassTOPLEVEL = RegisterClassEx (&wcl);
-      }
-    klass = klassTOPLEVEL;
-    break;
-
+    {
+    case GDK_WINDOW_TOPLEVEL:
+      if (0 == klassTOPLEVEL)
+       {
+         wcl.lpszClassName = "gdkWindowToplevel";
+         
+         ONCE_PER_CLASS();
+         klassTOPLEVEL = RegisterClassEx (&wcl);
+       }
+      klass = klassTOPLEVEL;
+      break;
+      
     case GDK_WINDOW_CHILD:
       if (0 == klassCHILD)
        {
@@ -364,34 +441,34 @@ RegisterGdkClass (GdkWindowType wtype)
        }
       klass = klassCHILD;
       break;
-
-  case GDK_WINDOW_DIALOG:
-    if (0 == klassDIALOG)
-      {
-       wcl.lpszClassName = "gdkWindowDialog";
-        wcl.style |= CS_SAVEBITS;
-       ONCE_PER_CLASS();
-       klassDIALOG = RegisterClassEx (&wcl);
-      }
-    klass = klassDIALOG;
-    break;
-
-  case GDK_WINDOW_TEMP:
-    if (0 == klassTEMP)
-      {
-       wcl.lpszClassName = "gdkWindowTemp";
-        wcl.style |= CS_SAVEBITS;
-       ONCE_PER_CLASS();
-       klassTEMP = RegisterClassEx (&wcl);
-      }
-    klass = klassTEMP;
-    break;
-
-  default:
-    g_assert_not_reached ();
-    break;
-  }
-
+      
+    case GDK_WINDOW_DIALOG:
+      if (0 == klassDIALOG)
+       {
+         wcl.lpszClassName = "gdkWindowDialog";
+         wcl.style |= CS_SAVEBITS;
+         ONCE_PER_CLASS();
+         klassDIALOG = RegisterClassEx (&wcl);
+       }
+      klass = klassDIALOG;
+      break;
+      
+    case GDK_WINDOW_TEMP:
+      if (0 == klassTEMP)
+       {
+         wcl.lpszClassName = "gdkWindowTemp";
+         wcl.style |= CS_SAVEBITS;
+         ONCE_PER_CLASS();
+         klassTEMP = RegisterClassEx (&wcl);
+       }
+      klass = klassTEMP;
+      break;
+      
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+  
   if (klass == 0)
     {
       WIN32_API_FAILED ("RegisterClassEx");
@@ -400,34 +477,36 @@ RegisterGdkClass (GdkWindowType wtype)
   return klass;
 }
 
-GdkWindow*
-gdk_window_new (GdkWindow     *parent,
-               GdkWindowAttr *attributes,
-               gint           attributes_mask)
+static GdkWindow*
+gdk_window_new_internal (GdkWindow     *parent,
+                        GdkWindowAttr *attributes,
+                        gint           attributes_mask,
+                        gboolean       from_set_skip_taskbar_hint)
 {
+  HANDLE hparent;
+  ATOM klass = 0;
+  DWORD dwStyle = 0, dwExStyle;
+  RECT rect;
   GdkWindow *window;
   GdkWindowObject *private;
-  GdkWindowObject *parent_private;
   GdkWindowImplWin32 *impl;
   GdkDrawableImplWin32 *draw_impl;
-
+  GdkScreen *screen;
   GdkVisual *visual;
-
-  HANDLE hparent;
-  ATOM klass = 0;
-  DWORD dwStyle, dwExStyle;
-  RECT rect;
-  Visual *xvisual;
-
-  int width, height;
-  int x, y;
-  char *title;
+  const gchar *title;
   char *mbtitle;
+  gint window_width, window_height;
+  gint offset_x = 0, offset_y = 0;
 
   g_return_val_if_fail (attributes != NULL, NULL);
 
   if (!parent)
-    parent = gdk_parent_root;
+    {
+      screen = gdk_screen_get_default ();
+      parent = gdk_screen_get_root_window (screen);
+    }
+  else
+    screen = gdk_drawable_get_screen (parent);
 
   g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
   
@@ -439,7 +518,6 @@ gdk_window_new (GdkWindow     *parent,
                        (attributes->window_type == GDK_WINDOW_TEMP ? "TEMP" :
                         "???"))))));
 
-  parent_private = (GdkWindowObject*) parent;
   if (GDK_WINDOW_DESTROYED (parent))
     return NULL;
   
@@ -451,50 +529,50 @@ gdk_window_new (GdkWindow     *parent,
   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
   draw_impl->wrapper = GDK_DRAWABLE (window);
 
+  /* 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_parent_root;
+  
   private->parent = (GdkWindowObject *)parent;
 
+  private->accept_focus = TRUE;
+  private->focus_on_map = TRUE;
+
   if (attributes_mask & GDK_WA_X)
-    x = attributes->x;
+    private->x = attributes->x;
   else
-    x = CW_USEDEFAULT;
+    private->x = 0;
   
   if (attributes_mask & GDK_WA_Y)
-    y = attributes->y;
+    private->y = attributes->y;
   else if (attributes_mask & GDK_WA_X)
-    y = 100;                   /* ??? We must put it somewhere... */
+    private->y = 100;          /* ??? We must put it somewhere... */
   else
-    y = 0;                     /* x is CW_USEDEFAULT, y doesn't matter then */
+    private->y = 0;
   
-  private->x = x;
-  private->y = y;
-  impl->width = (attributes->width > 1) ? (attributes->width) : (1);
-  impl->height = (attributes->height > 1) ? (attributes->height) : (1);
-  impl->extension_events_selected = FALSE;
-  private->window_type = attributes->window_type;
-
-  _gdk_window_init_position (GDK_WINDOW (private));
-  if (impl->position_info.big)
-    private->guffaw_gravity = TRUE;
-
   if (attributes_mask & GDK_WA_VISUAL)
     visual = attributes->visual;
   else
     visual = gdk_visual_get_system ();
-  xvisual = ((GdkVisualPrivate*) visual)->xvisual;
-
-  if (attributes_mask & GDK_WA_TITLE)
-    title = attributes->title;
-  else
-    title = g_get_prgname ();
-  if (!title || !*title)
-    title = "GDK client window";
 
-  impl->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
-      
-  if (parent_private && parent_private->guffaw_gravity)
+  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)
     {
-      /* XXX ??? */
+      /* Backwards compatiblity - we've always ignored
+       * attributes->window_type for input-only windows
+       * before
+       */
+      if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_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)
     {
@@ -506,23 +584,12 @@ gdk_window_new (GdkWindow     *parent,
       if (attributes_mask & GDK_WA_COLORMAP)
        {
          draw_impl->colormap = attributes->colormap;
-          gdk_colormap_ref (attributes->colormap);
+          g_object_ref (attributes->colormap);
         }
       else
        {
-         if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
-            {
-              draw_impl->colormap = gdk_colormap_get_system ();
-              gdk_colormap_ref (draw_impl->colormap);
-             GDK_NOTE (MISC, g_print ("...using system colormap %p\n",
-                                      draw_impl->colormap));
-            }
-         else
-            {
-              draw_impl->colormap = gdk_colormap_new (visual, FALSE);
-             GDK_NOTE (MISC, g_print ("...using new colormap %p\n",
-                                      draw_impl->colormap));
-            }
+         draw_impl->colormap = gdk_screen_get_system_colormap (screen);
+         g_object_ref (draw_impl->colormap);
        }
     }
   else
@@ -530,19 +597,18 @@ gdk_window_new (GdkWindow     *parent,
       dwExStyle = WS_EX_TRANSPARENT;
       private->depth = 0;
       private->input_only = TRUE;
-      draw_impl->colormap = gdk_colormap_get_system ();
-      gdk_colormap_ref (draw_impl->colormap);
-      GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, system colormap\n"));
+      draw_impl->colormap = gdk_screen_get_system_colormap (screen);
+      g_object_ref (draw_impl->colormap);
+      GDK_NOTE (MISC, g_print ("...GDK_INPUT_ONLY, system colormap"));
     }
 
-  if (parent_private)
-    parent_private->children = g_list_prepend (parent_private->children, window);
-
   switch (private->window_type)
     {
     case GDK_WINDOW_TOPLEVEL:
       dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
-      hparent = gdk_root_window;
+      hparent = _gdk_root_window;
+      offset_x = _gdk_offset_x;
+      offset_y = _gdk_offset_y;
       break;
 
     case GDK_WINDOW_CHILD:
@@ -554,86 +620,90 @@ gdk_window_new (GdkWindow     *parent,
 #if 0
       dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
 #endif
-      hparent = gdk_root_window;
+      hparent = _gdk_root_window;
+      offset_x = _gdk_offset_x;
+      offset_y = _gdk_offset_y;
       break;
 
     case GDK_WINDOW_TEMP:
       dwStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
       /* a temp window is not necessarily a top level window */
-      dwStyle |= (gdk_parent_root == parent ? WS_POPUP : WS_CHILDWINDOW);
+      dwStyle |= (_gdk_parent_root == parent ? WS_POPUP : WS_CHILDWINDOW);
       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 ();
     }
 
-  klass = RegisterGdkClass (private->window_type);
+  _gdk_window_init_position (GDK_WINDOW (private));
 
   if (private->window_type != GDK_WINDOW_CHILD)
     {
-      if (x == CW_USEDEFAULT)
-       {
-         rect.left = 100;
-         rect.top = 100;
-       }
-      else
-       {
-         rect.left = x;
-         rect.top = y;
-       }
+      rect.left = rect.top = 0;
+      rect.right = impl->position_info.width;
+      rect.bottom = impl->position_info.height;
 
-      rect.right = rect.left + impl->width;
-      rect.bottom = rect.top + impl->height;
-
-      SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
+      AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
 
-      if (x != CW_USEDEFAULT)
-       {
-         x = rect.left;
-         y = rect.top;
-       }
-      width = rect.right - rect.left;
-      height = rect.bottom - rect.top;
+      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;
     }
+
+  if (impl->position_info.big)
+    private->guffaw_gravity = TRUE;
+
+  if (attributes_mask & GDK_WA_TITLE)
+    title = attributes->title;
   else
+    title = get_default_title ();
+  if (!title || !*title)
+    title = "GDK client window";
+
+  private->event_mask = GDK_STRUCTURE_MASK | attributes->event_mask;
+      
+  if (private->parent && private->parent->guffaw_gravity)
     {
-      width = impl->width;
-      height = impl->height;
+      /* XXX ??? */
     }
 
+  if (private->parent)
+    private->parent->children = g_list_prepend (private->parent->children, window);
+
+  klass = RegisterGdkClass (private->window_type);
+
   mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
   
-#ifdef WITHOUT_WM_CREATE
-  draw_impl->handle = CreateWindowEx (dwExStyle,
-                                     MAKEINTRESOURCE(klass),
-                                     mbtitle,
-                                     dwStyle,
-                                     x, y, 
-                                     width, height,
-                                     hparent,
-                                     NULL,
-                                     gdk_app_hmodule,
-                                     NULL);
-#else
   {
   HWND hwndNew =
     CreateWindowEx (dwExStyle,
                    MAKEINTRESOURCE(klass),
                    mbtitle,
                    dwStyle,
-                   x, y, 
-                   width, height,
+                   ((attributes_mask & GDK_WA_X) ?
+                    impl->position_info.x - offset_x: CW_USEDEFAULT),
+                   impl->position_info.y - offset_y, 
+                   window_width, window_height,
                    hparent,
                    NULL,
-                   gdk_app_hmodule,
+                   _gdk_app_hmodule,
                    window);
   if (GDK_WINDOW_HWND (window) != hwndNew)
     {
-      g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%#x, %#x) HWND mismatch.",
-               (guint) GDK_WINDOW_HWND (window),
-               (guint) hwndNew);
+      g_warning("gdk_window_new: gdk_event_translate::WM_CREATE (%p, %p) HWND mismatch.",
+               GDK_WINDOW_HWND (window),
+               hwndNew);
 
       /* HB: IHMO due to a race condition the handle was increased by
        * one, which causes much trouble. Because I can't find the 
@@ -646,38 +716,34 @@ gdk_window_new (GdkWindow     *parent,
       gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
 # else
       /* the old behaviour, but with warning */
-      GDK_WINDOW_HWND (window) = hwndNew;
+      draw_impl->handle = hwndNew;
 # endif
 
     }
   }
-  gdk_drawable_ref (window);
+  g_object_ref (window);
   gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
-#endif
 
-  GDK_NOTE (MISC,
-           g_print ("... \"%s\" %dx%d@+%d+%d %#x = %#x\n"
-                    "... locale %#x codepage %d\n",
-                    mbtitle,
-                    width, height, (x == CW_USEDEFAULT ? -9999 : x), y, 
-                    (guint) hparent,
-                    (guint) GDK_WINDOW_HWND (window),
-                    (guint) impl->input_locale,
-                    (guint) impl->charset_info.ciACP));
+  GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@+%d+%d %p = %p\n",
+                          mbtitle,
+                          window_width, window_height,
+                          ((attributes_mask & GDK_WA_X) ?
+                           impl->position_info.x - offset_x: CW_USEDEFAULT),
+                          impl->position_info.y - offset_y, 
+                          hparent,
+                          GDK_WINDOW_HWND (window)));
 
   g_free (mbtitle);
 
   if (draw_impl->handle == NULL)
     {
       WIN32_API_FAILED ("CreateWindowEx");
-      g_object_unref ((GObject *) window);
+      g_object_unref (window);
       return NULL;
     }
 
-#ifdef WITHOUT_WM_CREATE
-  gdk_drawable_ref (window);
-  gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
-#endif
+  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) :
@@ -686,12 +752,20 @@ gdk_window_new (GdkWindow     *parent,
   return window;
 }
 
+GdkWindow*
+gdk_window_new (GdkWindow     *parent,
+               GdkWindowAttr *attributes,
+               gint           attributes_mask)
+{
+  return gdk_window_new_internal (parent, attributes, attributes_mask, FALSE);
+}
+
 GdkWindow *
-gdk_window_foreign_new (GdkNativeWindow anid)
+gdk_window_foreign_new_for_display (GdkDisplay      *display,
+                                    GdkNativeWindow  anid)
 {
   GdkWindow *window;
   GdkWindowObject *private;
-  GdkWindowObject *parent_private;
   GdkWindowImplWin32 *impl;
   GdkDrawableImplWin32 *draw_impl;
 
@@ -699,6 +773,8 @@ gdk_window_foreign_new (GdkNativeWindow anid)
   RECT rect;
   POINT point;
 
+  g_return_val_if_fail (display == gdk_display_get_default (), NULL);
+
   window = g_object_new (GDK_TYPE_WINDOW, NULL);
   private = (GdkWindowObject *)window;
   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
@@ -707,18 +783,17 @@ gdk_window_foreign_new (GdkNativeWindow anid)
   parent = GetParent ((HWND)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_parent_root;
   
-  parent_private = (GdkWindowObject *)private->parent;
-  
-  if (parent_private)
-    parent_private->children = g_list_prepend (parent_private->children, window);
+  private->parent->children = g_list_prepend (private->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 != gdk_root_window)
+  if (parent != _gdk_root_window)
     ScreenToClient (parent, &point);
   private->x = point.x;
   private->y = point.y;
@@ -726,18 +801,33 @@ gdk_window_foreign_new (GdkNativeWindow anid)
   impl->height = rect.bottom - rect.top;
   private->window_type = GDK_WINDOW_FOREIGN;
   private->destroyed = FALSE;
+  private->event_mask = GDK_ALL_EVENTS_MASK; /* XXX */
   if (IsWindowVisible ((HWND) anid))
     private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
   else
     private->state |= GDK_WINDOW_STATE_WITHDRAWN;
+  if (GetWindowLong ((HWND)anid, GWL_EXSTYLE) & WS_EX_TOPMOST)
+    private->state |= GDK_WINDOW_STATE_ABOVE;
+  else
+    private->state &= (~GDK_WINDOW_STATE_ABOVE);
+  private->state &= (~GDK_WINDOW_STATE_BELOW);
+
   private->depth = gdk_visual_get_system ()->depth;
 
-  gdk_drawable_ref (window);
+  _gdk_window_init_position (GDK_WINDOW (private));
+
+  g_object_ref (window);
   gdk_win32_handle_table_insert (&GDK_WINDOW_HWND (window), window);
 
   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,
@@ -747,36 +837,37 @@ _gdk_windowing_window_destroy (GdkWindow *window,
 
   g_return_if_fail (GDK_IS_WINDOW (window));
   
-  GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy %#x\n",
-                          (guint) GDK_WINDOW_HWND (window)));
+  GDK_NOTE (MISC, g_print ("_gdk_windowing_window_destroy: %p\n",
+                          GDK_WINDOW_HWND (window)));
 
   if (private->extension_events != 0)
-    gdk_input_window_destroy (window);
+    _gdk_input_window_destroy (window);
 
-  if (private->window_type == GDK_WINDOW_FOREIGN)
-    {
-      if (!foreign_destroy && (private->parent != NULL))
-       {
-         /* It's somebody else's window, but in our hierarchy,
-          * so reparent it to the root window, and then call
-          * DestroyWindow() on it.
-          */
-         gdk_window_hide (window);
-         gdk_window_reparent (window, NULL, 0, 0);
-         
-         /* Is this too drastic? Many (most?) applications
-          * quit if any window receives WM_QUIT I think.
-          * OTOH, I don't think foreign windows are much
-          * used, so the question is maybe academic.
-          */
-         PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
-       }
-    }
-  else if (!recursing && !foreign_destroy)
+
+  if (!recursing && !foreign_destroy)
     {
       private->destroyed = TRUE;
       DestroyWindow (GDK_WINDOW_HWND (window));
     }
+  gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
+}
+
+void
+_gdk_windowing_window_destroy_foreign (GdkWindow *window)
+{
+  /* It's somebody else's window, but in our hierarchy,
+   * so reparent it to the root window, and then call
+   * DestroyWindow() on it.
+   */
+  gdk_window_hide (window);
+  gdk_window_reparent (window, NULL, 0, 0);
+  
+  /* Is this too drastic? Many (most?) applications
+   * quit if any window receives WM_QUIT I think.
+   * OTOH, I don't think foreign windows are much
+   * used, so the question is maybe academic.
+   */
+  PostMessage (GDK_WINDOW_HWND (window), WM_QUIT, 0, 0);
 }
 
 /* This function is called when the window really gone.
@@ -788,107 +879,271 @@ gdk_window_destroy_notify (GdkWindow *window)
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   GDK_NOTE (EVENTS,
-           g_print ("gdk_window_destroy_notify: %#x  %s\n",
-                    (guint) GDK_WINDOW_HWND (window),
-                    (GDK_WINDOW_DESTROYED (window) ? "(destroyed)" : "")));
+           g_print ("gdk_window_destroy_notify: %p%s\n",
+                    GDK_WINDOW_HWND (window),
+                    (GDK_WINDOW_DESTROYED (window) ? " (destroyed)" : "")));
 
   if (!GDK_WINDOW_DESTROYED (window))
     {
       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
-       g_warning ("window %#x unexpectedly destroyed",
-                  (guint) GDK_WINDOW_HWND (window));
+       g_warning ("window %p unexpectedly destroyed",
+                  GDK_WINDOW_HWND (window));
 
       _gdk_window_destroy (window, TRUE);
     }
   
   gdk_win32_handle_table_remove (GDK_WINDOW_HWND (window));
-  gdk_drawable_unref (window);
+  g_object_unref (window);
 }
 
-void
-gdk_window_show (GdkWindow *window)
+static void
+get_outer_rect (GdkWindow *window,
+               gint       width,
+               gint       height,
+               RECT      *rect)
 {
-  GdkWindowObject *private;
-  
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  private = (GdkWindowObject*) window;
-  if (!private->destroyed)
+  LONG style, exstyle;
+      
+  style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
+  exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
+      
+  rect->left = rect->top = 0;
+  rect->right = width;
+  rect->bottom = height;
+      
+  API_CALL (AdjustWindowRectEx, (rect, style, FALSE, exstyle));
+}
+
+static void
+adjust_for_gravity_hints (GdkWindowImplWin32 *impl,
+                         RECT               *outer_rect,
+                         gint               *x,
+                         gint               *y)
+{
+  if (impl->hint_flags & GDK_HINT_WIN_GRAVITY)
     {
-      GDK_NOTE (MISC, g_print ("gdk_window_show: %#x\n",
-                              (guint) GDK_WINDOW_HWND (window)));
+      gint orig_x = *x, orig_y = *y;
 
-      private->state &= (~GDK_WINDOW_STATE_WITHDRAWN);
-      if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP)
+      switch (impl->hints.win_gravity)
        {
-         ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
-         SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST, 0, 0, 0, 0,
-                       SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-#if 0
-         /* Don't put on toolbar */
-         ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
-#endif
+       case GDK_GRAVITY_NORTH:
+       case GDK_GRAVITY_CENTER:
+       case GDK_GRAVITY_SOUTH:
+         *x -= (outer_rect->right - outer_rect->left) / 2;
+         *x += impl->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;
+         break;
+
+       case GDK_GRAVITY_STATIC:
+         *x += outer_rect->left;
+         break;
+
+       default:
+         break;
        }
-      else
+
+      switch (impl->hints.win_gravity)
        {
-          if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
-           {
-             SetWindowPos(GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0,
-                          SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE);
-           }
-          else
-            {
-             GdkWindow *parent = GDK_WINDOW (private->parent);
-
-             /* Todo: GDK_WINDOW_STATE_STICKY */
-             if (private->state & GDK_WINDOW_STATE_ICONIFIED)
-               ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMINIMIZED);
-             else if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
-               ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
-             else
-               {
-                 ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
-                 ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
-               }
-              if (parent == gdk_parent_root)
-                SetForegroundWindow (GDK_WINDOW_HWND (window));
-             BringWindowToTop (GDK_WINDOW_HWND (window));
-#if 0
-             ShowOwnedPopups (GDK_WINDOW_HWND (window), TRUE);
-#endif
-           }
+       case GDK_GRAVITY_WEST:
+       case GDK_GRAVITY_CENTER:
+       case GDK_GRAVITY_EAST:
+         *y -= (outer_rect->bottom - outer_rect->top) / 2;
+         *y += impl->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;
+         break;
+
+       case GDK_GRAVITY_STATIC:
+         *y += outer_rect->top;
+         break;
+
+       default:
+         break;
        }
+      GDK_NOTE (MISC,
+               (orig_x != *x || orig_y != *y) ?
+               g_print ("adjust_for_gravity_hints: x: %d->%d, y: %d->%d\n",
+                        orig_x, *x, orig_y, *y)
+                 : (void) 0);
     }
 }
 
-void
-gdk_window_hide (GdkWindow *window)
+static void
+show_window_internal (GdkWindow *window,
+                      gboolean   raise,
+                     gboolean   deiconify)
 {
   GdkWindowObject *private;
-  
-  g_return_if_fail (window != NULL);
+  HWND old_active_window;
+  gboolean focus_on_map = TRUE;
 
-  private = (GdkWindowObject*) window;
-  if (!private->destroyed)
-    {
-      GDK_NOTE (MISC, g_print ("gdk_window_hide: %#x\n",
-                              (guint) GDK_WINDOW_HWND (window)));
+  private = (GdkWindowObject *) window;
 
-      private->state |= GDK_WINDOW_STATE_WITHDRAWN;
-      if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
-       ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
+  if (private->destroyed)
+    return;
 
-      if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
-       {
-         SetWindowPos(GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
-                      SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
-       }
-      else
-       {
-         ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
-       }
+  GDK_NOTE (MISC, g_print ("show_window_internal: %p: %s%s%s\n",
+                          GDK_WINDOW_HWND (window),
+                          _gdk_win32_window_state_to_string (private->state),
+                          (raise ? " raise" : ""),
+                          (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))
+    {  
+      ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
+      return;
     }
-}
+  
+  /* If asked to just show an iconified window, do nothing. */
+  if (!deiconify && (private->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))
+    return;
+  
+  /* If asked to show (but not raise) a window that is already
+   * visible, do nothing.
+   */
+  if (!deiconify && !raise && 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;
+    }
+
+  /* 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)
+    {
+      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)
+       flags |= SWP_NOACTIVATE;
+
+      SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0, flags);
+      return;
+    }
+
+  old_active_window = GetActiveWindow ();
+
+  if (private->state & (GDK_WINDOW_STATE_BELOW | GDK_WINDOW_STATE_ABOVE))
+    {
+      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;
+
+      if (!SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, exstyle))
+        WIN32_API_FAILED ("SetWindowLong");
+    }
+
+  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);
+  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)
+        SetForegroundWindow (GDK_WINDOW_HWND (window));
+      else
+        BringWindowToTop (GDK_WINDOW_HWND (window));
+    }
+  else if (old_active_window != GDK_WINDOW_HWND (window))
+    SetActiveWindow (old_active_window);
+}
+
+void
+gdk_window_show_unraised (GdkWindow *window)
+{
+  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)
+{
+  GdkWindowObject *private;
+  
+  g_return_if_fail (window != NULL);
+
+  private = (GdkWindowObject*) window;
+  if (private->destroyed)
+    return;
+
+  GDK_NOTE (MISC, g_print ("gdk_window_hide: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          _gdk_win32_window_state_to_string (private->state)));
+  
+  if (GDK_WINDOW_IS_MAPPED (window))
+    gdk_synthesize_window_state (window,
+                                0,
+                                GDK_WINDOW_STATE_WITHDRAWN);
+  
+  _gdk_window_clear_update_area (window);
+  
+  if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
+    ShowOwnedPopups (GDK_WINDOW_HWND (window), FALSE);
+  
+  if (GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE) & WS_EX_TRANSPARENT)
+    {
+      SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
+                   SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
+    }
+  else
+    {
+      ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
+    }
+}
 
 void
 gdk_window_withdraw (GdkWindow *window)
@@ -898,13 +1153,14 @@ gdk_window_withdraw (GdkWindow *window)
   g_return_if_fail (window != NULL);
   
   private = (GdkWindowObject*) window;
-  if (!private->destroyed)
-    {
-      GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %#x\n",
-                              (guint) GDK_WINDOW_HWND (window)));
+  if (private->destroyed)
+    return;
 
-      gdk_window_hide (window);        /* ??? */
-    }
+  GDK_NOTE (MISC, g_print ("gdk_window_withdraw: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          _gdk_win32_window_state_to_string (private->state)));
+  
+  gdk_window_hide (window);    /* ??? */
 }
 
 void
@@ -918,9 +1174,31 @@ gdk_window_move (GdkWindow *window,
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (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_window_move_resize (window, x, y, impl->width, impl->height);
+
+  if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
+    return;
+
+  if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
+    _gdk_window_move_resize_child (window, x, y, impl->width, impl->height);
+  else
+    {
+      RECT outer_rect;
+
+      get_outer_rect (window, impl->width, impl->height, &outer_rect);
+      
+      adjust_for_gravity_hints (impl, &outer_rect, &x, &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));
+    }
 }
 
 void
@@ -930,64 +1208,39 @@ gdk_window_resize (GdkWindow *window,
 {
   GdkWindowObject *private = (GdkWindowObject*) window;
   GdkWindowImplWin32 *impl;
-  int x, y;
 
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
   if (width < 1)
     width = 1;
   if (height < 1)
     height = 1;
 
+  GDK_NOTE (MISC, g_print ("gdk_window_resize: %p: %dx%d\n",
+                          GDK_WINDOW_HWND (window), width, height));
+
   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
   
-  if (!private->destroyed)
-    {
-      GDK_NOTE (MISC, g_print ("gdk_window_resize: %#x %dx%d\n",
-                              (guint) GDK_WINDOW_HWND (window),
-                              width, height));
-      
-      if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD)
-       {
-         POINT pt;
-         RECT rect;
-         DWORD dwStyle;
-         DWORD dwExStyle;
-
-         pt.x = 0;
-         pt.y = 0; 
-         ClientToScreen (GDK_WINDOW_HWND (window), &pt);
-         rect.left = pt.x;
-         rect.top = pt.y;
-         rect.right = pt.x + width;
-         rect.bottom = pt.y + height;
-
-         dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-         dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-         if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
-           WIN32_API_FAILED ("AdjustWindowRectEx");
-
-         x = rect.left;
-         y = rect.top;
-         width = rect.right - rect.left;
-         height = rect.bottom - rect.top;
-       }
-      else
-       {
-         x = private->x;
-         y = private->y;
-         impl->width = width;
-         impl->height = height;
-       }
+  if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
+    return;
 
+  if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
+    _gdk_window_move_resize_child (window, private->x, private->y, width, height);
+  else
+    {
+      RECT outer_rect;
+      get_outer_rect (window, width, height, &outer_rect);
+
+      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;
-
-      GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%dx%d@+%d+%d)\n",
-                              (guint) GDK_WINDOW_HWND (window),
-                              width, height, x, y));
-      if (!MoveWindow (GDK_WINDOW_HWND (window), x, y, width, height, TRUE))
-       WIN32_API_FAILED ("MoveWindow");
     }
 }
 
@@ -1004,6 +1257,9 @@ gdk_window_move_resize (GdkWindow *window,
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
   if (width < 1)
     width = 1;
   if (height < 1)
@@ -1011,40 +1267,28 @@ gdk_window_move_resize (GdkWindow *window,
   
   impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
 
-  if (!private->destroyed)
+  if (private->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));
+  
+  if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
+    _gdk_window_move_resize_child (window, x, y, width, height);
+  else
     {
-      RECT rect;
-      DWORD dwStyle;
-      DWORD dwExStyle;
+      RECT outer_rect;
 
-      GDK_NOTE (MISC, g_print ("gdk_window_move_resize: %#x %dx%d@+%d+%d\n",
-                              (guint) GDK_WINDOW_HWND (window),
-                              width, height, x, y));
-      
-      if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
-       _gdk_window_move_resize_child (window, x, y, width, height);
-      else
-       {
-         rect.left = x;
-         rect.top = y;
-         rect.right = x + width;
-         rect.bottom = y + height;
-
-         dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-         dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-         if (!AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle))
-           WIN32_API_FAILED ("AdjustWindowRectEx");
-
-         GDK_NOTE (MISC, g_print ("...MoveWindow(%#x,%ldx%ld@+%ld+%ld)\n",
-                                  (guint) GDK_WINDOW_HWND (window),
-                                  rect.right - rect.left, rect.bottom - rect.top,
-                                  rect.left, rect.top));
-         if (!MoveWindow (GDK_WINDOW_HWND (window),
-                          rect.left, rect.top,
-                          rect.right - rect.left, rect.bottom - rect.top,
-                          TRUE))
-           WIN32_API_FAILED ("MoveWindow");
-       }
+      get_outer_rect (window, width, height, &outer_rect);
+
+      adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
+
+      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));
     }
 }
 
@@ -1060,9 +1304,18 @@ gdk_window_reparent (GdkWindow *window,
   GdkWindowImplWin32 *impl;
 
   g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
+  g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
+    {
+      return;
+    }
 
   if (!new_parent)
-    new_parent = gdk_parent_root;
+    new_parent = _gdk_parent_root;
 
   window_private = (GdkWindowObject*) window;
   old_parent_private = (GdkWindowObject *) window_private->parent;
@@ -1071,17 +1324,22 @@ gdk_window_reparent (GdkWindow *window,
 
   if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
     {
-      GDK_NOTE (MISC, g_print ("gdk_window_reparent: %#x %#x\n",
-                              (guint) GDK_WINDOW_HWND (window),
-                              (guint) GDK_WINDOW_HWND (new_parent)));
-      if (!SetParent (GDK_WINDOW_HWND (window),
-                     GDK_WINDOW_HWND (new_parent)))
-       WIN32_API_FAILED ("SetParent");
+      GDK_NOTE (MISC, g_print ("gdk_window_reparent: %p: %p\n",
+                              GDK_WINDOW_HWND (window),
+                              GDK_WINDOW_HWND (new_parent)));
 
-      if (!MoveWindow (GDK_WINDOW_HWND (window),
-                      x, y, impl->width, impl->height, TRUE))
-       WIN32_API_FAILED ("MoveWindow");
+      API_CALL (SetParent, (GDK_WINDOW_HWND (window),
+                           GDK_WINDOW_HWND (new_parent)));
+
+      API_CALL (MoveWindow, (GDK_WINDOW_HWND (window),
+                            x, y, impl->width, impl->height, TRUE));
     }
+
+  /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
+   * the root window
+   */
+  if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
+    new_parent = _gdk_parent_root;
   
   window_private->parent = (GdkWindowObject *)new_parent;
 
@@ -1089,12 +1347,15 @@ gdk_window_reparent (GdkWindow *window,
     old_parent_private->children =
       g_list_remove (old_parent_private->children, window);
 
+#if 0
   if ((old_parent_private &&
        (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
       (!old_parent_private && parent_private->guffaw_gravity))
     gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
-  
+#endif
+
   parent_private->children = g_list_prepend (parent_private->children, window);
+  _gdk_window_init_position (GDK_WINDOW (window_private));
 }
 
 void
@@ -1119,14 +1380,14 @@ _gdk_windowing_window_clear_area (GdkWindow *window,
        width = impl->width - x;
       if (height == 0)
        height = impl->height - y;
-      GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area: "
-                              "%#x %dx%d@+%d+%d\n",
-                              (guint) GDK_WINDOW_HWND (window),
+      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);
       SendMessage (GDK_WINDOW_HWND (window), WM_ERASEBKGND, (WPARAM) hdc, 0);
-      ReleaseDC (GDK_WINDOW_HWND (window), hdc);
+      GDI_CALL (ReleaseDC, (GDK_WINDOW_HWND (window), hdc));
     }
 }
 
@@ -1144,17 +1405,16 @@ _gdk_windowing_window_clear_area_e (GdkWindow *window,
     {
       RECT rect;
 
-      GDK_NOTE (MISC, g_print ("_gdk_windowing_window_clear_area_e: "
-                              "%#x %dx%d@+%d+%d\n",
-                              (guint) GDK_WINDOW_HWND (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));
 
       rect.left = x;
       rect.right = x + width + 1;
       rect.top = y;
       rect.bottom = y + height + 1;
-      if (!InvalidateRect (GDK_WINDOW_HWND (window), &rect, TRUE))
-       WIN32_GDI_FAILED ("InvalidateRect");
+      GDI_CALL (InvalidateRect, (GDK_WINDOW_HWND (window), &rect, TRUE));
       UpdateWindow (GDK_WINDOW_HWND (window));
     }
 }
@@ -1167,11 +1427,10 @@ gdk_window_raise (GdkWindow *window)
   
   if (!GDK_WINDOW_DESTROYED (window))
     {
-      GDK_NOTE (MISC, g_print ("gdk_window_raise: %#x\n",
-                              (guint) GDK_WINDOW_HWND (window)));
+      GDK_NOTE (MISC, g_print ("gdk_window_raise: %p\n",
+                              GDK_WINDOW_HWND (window)));
 
-      if (!BringWindowToTop (GDK_WINDOW_HWND (window)))
-       WIN32_API_FAILED ("BringWindowToTop");
+      API_CALL (BringWindowToTop, (GDK_WINDOW_HWND (window)));
     }
 }
 
@@ -1183,12 +1442,11 @@ gdk_window_lower (GdkWindow *window)
   
   if (!GDK_WINDOW_DESTROYED (window))
     {
-      GDK_NOTE (MISC, g_print ("gdk_window_lower: %#x\n",
-                              (guint) GDK_WINDOW_HWND (window)));
+      GDK_NOTE (MISC, g_print ("gdk_window_lower: %p\n",
+                              GDK_WINDOW_HWND (window)));
 
-      if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
-                        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE))
-       WIN32_API_FAILED ("SetWindowPos");
+      API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
+                              SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE));
     }
 }
 
@@ -1202,13 +1460,10 @@ gdk_window_set_hints (GdkWindow *window,
                      gint       max_height,
                      gint       flags)
 {
+  /* Note that this function is obsolete */
+
   GdkWindowImplWin32 *impl;
-  WINDOWPLACEMENT size_hints;
-  RECT rect;
-  DWORD dwStyle;
-  DWORD dwExStyle;
-  int diff;
-  
+
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
@@ -1217,104 +1472,28 @@ gdk_window_set_hints (GdkWindow *window,
   
   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
 
-  GDK_NOTE (MISC, g_print ("gdk_window_set_hints: %#x %dx%d..%dx%d @+%d+%d\n",
-                          (guint) GDK_WINDOW_HWND (window),
+  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));
 
-  impl->hint_flags = flags;
-  size_hints.length = sizeof (size_hints);
-
   if (flags)
     {
-      if (flags & GDK_HINT_POS)
-       {
-         if (!GetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
-           WIN32_API_FAILED ("GetWindowPlacement");
-         else
-           {
-             GDK_NOTE (MISC, g_print ("...rcNormalPosition:"
-                                      " (%ld,%ld)--(%ld,%ld)\n",
-                                      size_hints.rcNormalPosition.left,
-                                      size_hints.rcNormalPosition.top,
-                                      size_hints.rcNormalPosition.right,
-                                      size_hints.rcNormalPosition.bottom));
-             /* What are the corresponding window coordinates for client
-              * area coordinates x, y
-              */
-             rect.left = x;
-             rect.top = y;
-             rect.right = rect.left + 200;     /* dummy */
-             rect.bottom = rect.top + 200;
-             dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-             dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-             AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
-             size_hints.flags = 0;
-             size_hints.showCmd = SW_SHOWNA;
-             
-             /* Set the normal position hint to that location, with unchanged
-              * width and height.
-              */
-             diff = size_hints.rcNormalPosition.left - rect.left;
-             size_hints.rcNormalPosition.left = rect.left;
-             size_hints.rcNormalPosition.right -= diff;
-             diff = size_hints.rcNormalPosition.top - rect.top;
-             size_hints.rcNormalPosition.top = rect.top;
-             size_hints.rcNormalPosition.bottom -= diff;
-             GDK_NOTE (MISC, g_print ("...setting: (%ld,%ld)--(%ld,%ld)\n",
-                                      size_hints.rcNormalPosition.left,
-                                      size_hints.rcNormalPosition.top,
-                                      size_hints.rcNormalPosition.right,
-                                      size_hints.rcNormalPosition.bottom));
-             if (!SetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
-               WIN32_API_FAILED ("SetWindowPlacement");
-             impl->hint_x = rect.left;
-             impl->hint_y = rect.top;
-           }
-       }
+      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)
-       {
-         rect.left = 0;
-         rect.top = 0;
-         rect.right = min_width;
-         rect.bottom = min_height;
-         dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-         dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-         SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
-         impl->hint_min_width = rect.right - rect.left;
-         impl->hint_min_height = rect.bottom - rect.top;
-
-         /* Also chek if he current size of the window is in bounds. */
-         GetClientRect (GDK_WINDOW_HWND (window), &rect);
-         if (rect.right < min_width && rect.bottom < min_height)
-           gdk_window_resize (window, min_width, min_height);
-         else if (rect.right < min_width)
-           gdk_window_resize (window, min_width, rect.bottom);
-         else if (rect.bottom < min_height)
-           gdk_window_resize (window, rect.right, min_height);
-       }
+        geom_mask |= GDK_HINT_MIN_SIZE;
 
       if (flags & GDK_HINT_MAX_SIZE)
-       {
-         rect.left = 0;
-         rect.top = 0;
-         rect.right = max_width;
-         rect.bottom = max_height;
-         dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-         dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-         AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
-         impl->hint_max_width = rect.right - rect.left;
-         impl->hint_max_height = rect.bottom - rect.top;
-         /* Again, check if the window is too large currently. */
-         GetClientRect (GDK_WINDOW_HWND (window), &rect);
-         if (rect.right > max_width && rect.bottom > max_height)
-           gdk_window_resize (window, max_width, max_height);
-         else if (rect.right > max_width)
-           gdk_window_resize (window, max_width, rect.bottom);
-         else if (rect.bottom > max_height)
-           gdk_window_resize (window, rect.right, max_height);
-       }
+        geom_mask |= GDK_HINT_MAX_SIZE;
+
+      gdk_window_set_geometry_hints (window, &geom, geom_mask);
     }
 }
 
@@ -1324,90 +1503,107 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
                               GdkWindowHints  geom_mask)
 {
   GdkWindowImplWin32 *impl;
+#if 0
   WINDOWPLACEMENT size_hints;
   RECT rect;
-  DWORD dwStyle;
-  DWORD dwExStyle;
-  
+  gint new_width = 0, new_height = 0;
+#endif
+
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  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);
-  size_hints.length = sizeof (size_hints);
 
   impl->hint_flags = geom_mask;
+  impl->hints = *geometry;
 
   if (geom_mask & GDK_HINT_POS)
     ; /* even the X11 mplementation doesn't care */
 
   if (geom_mask & GDK_HINT_MIN_SIZE)
     {
-      rect.left = 0;
-      rect.top = 0;
-      rect.right = geometry->min_width;
-      rect.bottom = geometry->min_height;
-      dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-      dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-      AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
-      impl->hint_min_width = rect.right - rect.left;
-      impl->hint_min_height = rect.bottom - rect.top;
+      GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
+                              geometry->min_width, geometry->min_height));
 
-      /* Also check if he current size of the window is in bounds */
+#if 0
+      /* Check if the current size of the window is in bounds */
       GetClientRect (GDK_WINDOW_HWND (window), &rect);
-      if (rect.right < geometry->min_width
-         && rect.bottom < geometry->min_height)
-       gdk_window_resize (window, geometry->min_width, geometry->min_height);
+
+      if (rect.right < geometry->min_width &&
+         rect.bottom < geometry->min_height)
+       {
+         new_width = geometry->min_width;
+         new_height = geometry->min_height;
+       }
       else if (rect.right < geometry->min_width)
-       gdk_window_resize (window, geometry->min_width, rect.bottom);
+       {
+         new_width = geometry->min_width;
+         new_height = rect.bottom;
+       }
       else if (rect.bottom < geometry->min_height)
-       gdk_window_resize (window, rect.right, geometry->min_height);
+       {
+         new_width = rect.right;
+         new_height = geometry->min_height;
+       }
+#endif
     }
   
   if (geom_mask & GDK_HINT_MAX_SIZE)
     {
-      rect.left = 0;
-      rect.top = 0;
-      rect.right = geometry->max_width;
-      rect.bottom = geometry->max_height;
-      dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-      dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-      /* HB: dont' know why AdjustWindowRectEx is called here, ... */
-      SafeAdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
-      impl->hint_max_width = rect.right - rect.left;
-      impl->hint_max_height = rect.bottom - rect.top;
-      /* ... but negative sizes are always wrong */
-      if (impl->hint_max_width < 0) impl->hint_max_width = G_MAXSHORT;
-      if (impl->hint_max_height < 0) impl->hint_max_height = G_MAXSHORT;
-
-      /* Again, check if the window is too large currently. */
+      GDK_NOTE (MISC, g_print ("... MAX_SIZE: %dx%d\n",
+                              geometry->max_width, geometry->max_height));
+
+#if 0
+      /* Check if the current size of the window is in bounds */
       GetClientRect (GDK_WINDOW_HWND (window), &rect);
-      if (rect.right > geometry->max_width
-         && rect.bottom > geometry->max_height)
-       gdk_window_resize (window, geometry->max_width, geometry->max_height);
+
+      if (rect.right > geometry->max_width &&
+         rect.bottom > geometry->max_height)
+       {
+         new_width = geometry->max_width;
+         new_height = geometry->max_height;
+       }
       else if (rect.right > geometry->max_width)
-       gdk_window_resize (window, geometry->max_width, rect.bottom);
+       {
+         new_width = geometry->max_width;
+         new_height = rect.bottom;
+       }
       else if (rect.bottom > geometry->max_height)
-       gdk_window_resize (window, rect.right, geometry->max_height);
+       {
+         new_width = rect.right;
+         new_height = geometry->max_height;
+       }
+#endif
     }
-  
-  /* I don't know what to do when called with zero base_width and height. */
-  if (geom_mask & GDK_HINT_BASE_SIZE
-      && geometry->base_width > 0
-      && geometry->base_height > 0)
+
+#if 0
+  /* Apply new size constraints */
+  if (new_width != 0 && new_height != 0)
+    gdk_window_resize (window, new_width, new_height);
+#endif
+
+  if (geom_mask & GDK_HINT_BASE_SIZE)
     {
-      if (!GetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
-       WIN32_API_FAILED ("GetWindowPlacement");
-      else
+      GDK_NOTE (MISC, g_print ("... BASE_SIZE: %dx%d\n",
+                              geometry->base_width, geometry->base_height));
+
+#if 0
+      size_hints.length = sizeof (size_hints);
+
+      if (API_CALL (GetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints)))
        {
-         GDK_NOTE (MISC, g_print ("gdk_window_set_geometry_hints:"
-                                  " rcNormalPosition: (%ld,%ld)--(%ld,%ld)\n",
-                                  size_hints.rcNormalPosition.left,
-                                  size_hints.rcNormalPosition.top,
-                                  size_hints.rcNormalPosition.right,
-                                  size_hints.rcNormalPosition.bottom));
+         GDK_NOTE (MISC,
+                   g_print ("... rcNormalPosition: (%ld,%ld)--(%ld,%ld)\n",
+                            size_hints.rcNormalPosition.left,
+                            size_hints.rcNormalPosition.top,
+                            size_hints.rcNormalPosition.right,
+                            size_hints.rcNormalPosition.bottom));
          size_hints.rcNormalPosition.right =
            size_hints.rcNormalPosition.left + geometry->base_width;
          size_hints.rcNormalPosition.bottom =
@@ -1417,19 +1613,26 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
                                   size_hints.rcNormalPosition.top,
                                   size_hints.rcNormalPosition.right,
                                   size_hints.rcNormalPosition.bottom));
-         if (!SetWindowPlacement (GDK_WINDOW_HWND (window), &size_hints))
-           WIN32_API_FAILED ("SetWindowPlacement");
+         API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints));
        }
+#endif
     }
   
   if (geom_mask & GDK_HINT_RESIZE_INC)
     {
-      /* XXX */
+      GDK_NOTE (MISC, g_print ("... RESIZE_INC: (%d,%d)\n",
+                              geometry->width_inc, geometry->height_inc));
     }
   
   if (geom_mask & GDK_HINT_ASPECT)
     {
-      /* XXX */
+      GDK_NOTE (MISC, g_print ("... ASPECT: %g--%g\n",
+                              geometry->min_aspect, geometry->max_aspect));
+    }
+
+  if (geom_mask & GDK_HINT_WIN_GRAVITY)
+    {
+      GDK_NOTE (MISC, g_print ("... GRAVITY: %d\n", geometry->win_gravity));
     }
 }
 
@@ -1447,8 +1650,8 @@ gdk_window_set_title (GdkWindow   *window,
   if (!title[0])
     title = ".";
   
-  GDK_NOTE (MISC, g_print ("gdk_window_set_title: %#x %s\n",
-                          (guint) GDK_WINDOW_HWND (window), title));
+  GDK_NOTE (MISC, g_print ("gdk_window_set_title: %p: %s\n",
+                          GDK_WINDOW_HWND (window), title));
   
   if (!GDK_WINDOW_DESTROYED (window))
     {
@@ -1456,9 +1659,7 @@ gdk_window_set_title (GdkWindow   *window,
        * to the system codepage.
        */
       mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
-      if (!SetWindowText (GDK_WINDOW_HWND (window), mbtitle))
-       WIN32_API_FAILED ("SetWindowText");
-
+      API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), mbtitle));
       g_free (mbtitle);
     }
 }
@@ -1470,8 +1671,8 @@ gdk_window_set_role (GdkWindow   *window,
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
-  GDK_NOTE (MISC, g_print ("gdk_window_set_role: %#x %s\n",
-                          (guint) GDK_WINDOW_HWND (window),
+  GDK_NOTE (MISC, g_print ("gdk_window_set_role: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
                           (role ? role : "NULL")));
   /* XXX */
 }
@@ -1481,53 +1682,49 @@ gdk_window_set_transient_for (GdkWindow *window,
                              GdkWindow *parent)
 {
   HWND window_id, parent_id;
-  LONG style;
 
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
-  GDK_NOTE (MISC, g_print ("gdk_window_set_transient_for: %#x %#x\n",
-                          (guint) GDK_WINDOW_HWND (window),
-                          (guint) GDK_WINDOW_HWND (parent)));
+  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;
 
+  if (((GdkWindowObject *) 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 ((style = GetWindowLong (window_id, GWL_STYLE)) == 0)
-    WIN32_API_FAILED ("GetWindowLong");
-
-  style |= WS_POPUP;
-#if 0 /* not sure if we want to do this */
-  style &= ~(WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
-#endif
-
-  if (!SetWindowLong (window_id, GWL_STYLE, style))
+  /* This changes the *owner* of the window, despite the misleading
+   * name. (Owner and parent are unrelated concepts.) At least that's
+   * what people who seem to know what they talk about say on
+   * USENET. Search on Google.
+   */
+  SetLastError (0);
+  if (SetWindowLong (window_id, GWL_HWNDPARENT, (long) parent_id) == 0 &&
+      GetLastError () != 0)
     WIN32_API_FAILED ("SetWindowLong");
-#if 0 /* not sure if we want to do this, clipping to parent size! */
-  if (!SetParent (window_id, parent_id))
-       WIN32_API_FAILED ("SetParent");
-#endif
-
-  if (!RedrawWindow (window_id, NULL, NULL, 
-                     RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW))
-    WIN32_API_FAILED ("RedrawWindow");
 }
 
 void
-gdk_window_set_background (GdkWindow *window,
-                          GdkColor  *color)
+gdk_window_set_background (GdkWindow      *window,
+                          const GdkColor *color)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
   
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
-  GDK_NOTE (MISC, g_print ("gdk_window_set_background: %#x %s\n",
-                          (guint) GDK_WINDOW_HWND (window), 
-                          gdk_win32_color_to_string (color)));
+  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;
 
@@ -1535,7 +1732,7 @@ gdk_window_set_background (GdkWindow *window,
       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
       private->bg_pixmap != GDK_NO_BG)
     {
-      gdk_drawable_unref (private->bg_pixmap);
+      g_object_unref (private->bg_pixmap);
       private->bg_pixmap = NULL;
     }
 }
@@ -1550,21 +1747,23 @@ gdk_window_set_back_pixmap (GdkWindow *window,
   g_return_if_fail (window != NULL);
   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 (private->bg_pixmap &&
       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
       private->bg_pixmap != GDK_NO_BG)
-    gdk_drawable_unref (private->bg_pixmap);
+    g_object_unref (private->bg_pixmap);
 
   if (parent_relative)
     {
       private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
+      GDK_NOTE (MISC, g_print (G_STRLOC ": setting background pixmap to parent_relative\n"));
     }
   else
     {
       if (pixmap)
        {
-         gdk_drawable_ref (pixmap);
+         g_object_ref (pixmap);
          private->bg_pixmap = pixmap;
        }
       else
@@ -1580,9 +1779,9 @@ gdk_window_set_cursor (GdkWindow *window,
 {
   GdkWindowImplWin32 *impl;
   GdkCursorPrivate *cursor_private;
+  GdkWindowObject *parent_window;
   HCURSOR hcursor;
   HCURSOR hprevcursor;
-  POINT pt;
   
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -1590,43 +1789,76 @@ gdk_window_set_cursor (GdkWindow *window,
   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
   cursor_private = (GdkCursorPrivate*) cursor;
   
-  if (!GDK_WINDOW_DESTROYED (window))
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  if (!cursor)
+    hcursor = NULL;
+  else
+    hcursor = cursor_private->hcursor;
+  
+  GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %p: %p\n",
+                          GDK_WINDOW_HWND (window),
+                          hcursor));
+
+  /* First get the old cursor, if any (we wait to free the old one
+   * since it may be the current cursor set in the Win32 API right
+   * now).
+   */
+  hprevcursor = impl->hcursor;
+
+  if (hcursor == NULL)
+    impl->hcursor = NULL;
+  else
     {
-      if (!cursor)
-       hcursor = NULL;
-      else
-       hcursor = cursor_private->hcursor;
-
-      GDK_NOTE (MISC, g_print ("gdk_window_set_cursor: %#x %#x\n",
-                              (guint) GDK_WINDOW_HWND (window),
-                              (guint) hcursor));
-      hprevcursor = impl->hcursor;
-      if (hcursor == NULL)
-       impl->hcursor = NULL;
-      else
+      /* We must copy the cursor as it is OK to destroy the GdkCursor
+       * while still in use for some window. See for instance
+       * gimp_change_win_cursor() which calls gdk_window_set_cursor
+       * (win, cursor), and immediately afterwards gdk_cursor_destroy
+       * (cursor).
+       */
+      if ((impl->hcursor = CopyCursor (hcursor)) == NULL)
+       WIN32_API_FAILED ("CopyCursor");
+      GDK_NOTE (MISC, g_print ("...CopyCursor (%p) = %p\n",
+                              hcursor, impl->hcursor));
+    }
+
+  /* If the pointer is over our window, set new cursor if given */
+  if (gdk_window_get_pointer(window, NULL, NULL, NULL) == window)
+    if (impl->hcursor != NULL)
+      SetCursor (impl->hcursor);
+
+  /* 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.
+   */
+  if (hprevcursor != NULL)
+    {
+      if (GetCursor() == hprevcursor)
        {
-         /* We must copy the cursor as it is OK to destroy the GdkCursor
-          * while still in use for some window. See for instance
-          * gimp_change_win_cursor() which calls
-          * gdk_window_set_cursor (win, cursor), and immediately
-          * afterwards gdk_cursor_destroy (cursor).
-          */
-         impl->hcursor = CopyCursor (hcursor);
-         GDK_NOTE (MISC, g_print ("...CopyCursor (%#x) = %#x\n",
-                                  (guint) hcursor, (guint) impl->hcursor));
-
-         if (hprevcursor != NULL && GetCursor () == hprevcursor)
-           SetCursor (impl->hcursor);
-
-         if (hprevcursor != NULL)
+         /* Look for a suitable cursor to use instead */
+         hcursor = NULL;
+          parent_window = GDK_WINDOW_OBJECT (window)->parent;
+          while (hcursor == NULL)
            {
-             GDK_NOTE (MISC, g_print ("...DestroyCursor (%#x)\n",
-                                      (guint) hprevcursor));
-         
-             if (!DestroyCursor (hprevcursor))
-               WIN32_API_FAILED ("DestroyCursor");
+             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));
     }
 }
 
@@ -1641,14 +1873,41 @@ gdk_window_get_geometry (GdkWindow *window,
   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
   
   if (!window)
-    window = gdk_parent_root;
+    window = _gdk_parent_root;
   
   if (!GDK_WINDOW_DESTROYED (window))
     {
       RECT rect;
 
-      if (!GetClientRect (GDK_WINDOW_HWND (window), &rect))
-       WIN32_API_FAILED ("GetClientRect");
+      API_CALL (GetClientRect, (GDK_WINDOW_HWND (window), &rect));
+
+      if (window != _gdk_parent_root)
+       {
+         POINT pt;
+         GdkWindow *parent = gdk_window_get_parent (window);
+
+         pt.x = rect.left;
+         pt.y = rect.top;
+         ClientToScreen (GDK_WINDOW_HWND (window), &pt);
+         ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
+         rect.left = pt.x;
+         rect.top = pt.y;
+
+         pt.x = rect.right;
+         pt.y = rect.bottom;
+         ClientToScreen (GDK_WINDOW_HWND (window), &pt);
+         ScreenToClient (GDK_WINDOW_HWND (parent), &pt);
+         rect.right = pt.x;
+         rect.bottom = pt.y;
+
+         if (parent == _gdk_parent_root)
+           {
+             rect.left += _gdk_offset_x;
+             rect.top += _gdk_offset_y;
+             rect.right += _gdk_offset_x;
+             rect.bottom += _gdk_offset_y;
+           }
+       }
 
       if (x)
        *x = rect.left;
@@ -1660,6 +1919,12 @@ gdk_window_get_geometry (GdkWindow *window,
        *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_WINDOW_HWND (window),
+                              rect.right - rect.left, rect.bottom - rect.top,
+                              gdk_drawable_get_visual (window)->depth,
+                              rect.left, rect.top));
     }
 }
 
@@ -1689,12 +1954,12 @@ gdk_window_get_origin (GdkWindow *window,
     return_val = 0;
   
   if (x)
-    *x = tx;
+    *x = tx + _gdk_offset_x;
   if (y)
-    *y = ty;
+    *y = ty + _gdk_offset_y;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %#x: +%d+%d\n",
-                          (guint) GDK_WINDOW_HWND (window),
+  GDK_NOTE (MISC, g_print ("gdk_window_get_origin: %p: +%d+%d\n",
+                          GDK_WINDOW_HWND (window),
                           tx, ty));
   return return_val;
 }
@@ -1712,38 +1977,20 @@ gdk_window_get_root_origin (GdkWindow *window,
                            gint      *x,
                            gint      *y)
 {
-  GdkWindowObject *rover;
-  POINT pt;
+  GdkRectangle rect;
 
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  rover = (GdkWindowObject*) window;
-  if (x)
-    *x = 0;
-  if (y)
-    *y = 0;
-
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
-      
-  while (rover->parent && ((GdkWindowObject*) rover->parent)->parent)
-    rover = (GdkWindowObject *) rover->parent;
-  if (rover->destroyed)
-    return;
+  gdk_window_get_frame_extents (window, &rect);
 
-  pt.x = 0;
-  pt.y = 0;
-  ClientToScreen (GDK_WINDOW_HWND (rover), &pt);
   if (x)
-    *x = pt.x;
+    *x = rect.x;
+
   if (y)
-    *y = pt.y;
+    *y = rect.y;
 
-  GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %#x: (%#x) +%ld+%ld\n",
-                          (guint) GDK_WINDOW_HWND (window),
-                          (guint) GDK_WINDOW_HWND (rover),
-                          pt.x, pt.y));
+  GDK_NOTE (MISC, g_print ("gdk_window_get_root_origin: %p: +%d+%d\n",
+                          GDK_WINDOW_HWND (window), rect.x, rect.y));
 }
 
 void
@@ -1767,10 +2014,14 @@ gdk_window_get_frame_extents (GdkWindow    *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  /* 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;
 
   hwnd = GDK_WINDOW_HWND (window);
+
   /* find the frame window */
   while (HWND_DESKTOP != GetParent (hwnd))
     {
@@ -1778,80 +2029,108 @@ gdk_window_get_frame_extents (GdkWindow    *window,
       g_return_if_fail (NULL != hwnd);
     }
 
-  if (!GetWindowRect (hwnd, &r))
-    WIN32_API_FAILED ("GetWindowRect");
+  API_CALL (GetWindowRect, (hwnd, &r));
 
-  rect->x = r.left;
-  rect->y = r.right;
+  rect->x = r.left + _gdk_offset_x;
+  rect->y = r.top + _gdk_offset_y;
   rect->width = r.right - r.left;
   rect->height = r.bottom - r.top;
+
+  GDK_NOTE (MISC, g_print ("gdk_window_get_frame_extents: %p: %ldx%ld@+%ld+%ld\n",
+                          GDK_WINDOW_HWND (window),
+                          r.right - r.left, r.bottom - r.top,
+                          r.left, r.top));
 }
 
 GdkWindow*
-_gdk_windowing_window_get_pointer (GdkWindow       *window,
+_gdk_windowing_window_get_pointer (GdkDisplay      *display,
+                                  GdkWindow       *window,
                                   gint            *x,
                                   gint            *y,
                                   GdkModifierType *mask)
 {
   GdkWindow *return_val;
-  POINT pointc, point;
+  POINT screen_point, point;
   HWND hwnd, hwndc;
+  BYTE kbd[256];
 
   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
   
-  if (!window)
-    window = gdk_parent_root;
-
   return_val = NULL;
-  GetCursorPos (&pointc);
-  point = pointc;
+  GetCursorPos (&screen_point);
+  point = screen_point;
   ScreenToClient (GDK_WINDOW_HWND (window), &point);
 
-  if (x)
-    *x = point.x;
-  if (y)
-    *y = point.y;
-
-  hwnd = WindowFromPoint (point);
-  point = pointc;
-  ScreenToClient (hwnd, &point);
-  
-  do {
-    hwndc = ChildWindowFromPoint (hwnd, point);
-    ClientToScreen (hwnd, &point);
-    ScreenToClient (hwndc, &point);
-  } while (hwndc != hwnd && (hwnd = hwndc, 1));        /* Ouch! */
+  *x = point.x;
+  *y = point.y;
 
-  return_val = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
+  if (window == _gdk_parent_root)
+    {
+      *x += _gdk_offset_x;
+      *y += _gdk_offset_y;
+    }
 
-  if (mask)
+  hwnd = WindowFromPoint (screen_point);
+  if (hwnd != NULL)
     {
-      BYTE kbd[256];
-
-      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;
+      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;
 }
 
+void
+_gdk_windowing_get_pointer (GdkDisplay       *display,
+                           GdkScreen       **screen,
+                           gint             *x,
+                           gint             *y,
+                           GdkModifierType  *mask)
+{
+  GdkScreen *default_screen = gdk_display_get_default_screen (display);
+  GdkWindow *root_window = gdk_screen_get_root_window (default_screen);
+  
+  *screen = default_screen;
+  _gdk_windowing_window_get_pointer (display, root_window, x, y, mask);
+}
+
 GdkWindow*
-_gdk_windowing_window_at_pointer (gint *win_x,
-                                 gint *win_y)
+_gdk_windowing_window_at_pointer (GdkDisplay *display,
+                                 gint       *win_x,
+                                 gint       *win_y)
 {
   GdkWindow *window;
   POINT point, pointc;
@@ -1864,11 +2143,9 @@ _gdk_windowing_window_at_pointer (gint *win_x,
 
   if (hwnd == NULL)
     {
-      window = gdk_parent_root;
-      if (win_x)
-       *win_x = pointc.x;
-      if (win_y)
-       *win_y = pointc.y;
+      window = _gdk_parent_root;
+      *win_x = pointc.x + _gdk_offset_x;
+      *win_y = pointc.y + _gdk_offset_y;
       return window;
     }
       
@@ -1885,15 +2162,13 @@ _gdk_windowing_window_at_pointer (gint *win_x,
   if (window && (win_x || win_y))
     {
       GetClientRect (hwnd, &rect);
-      if (win_x)
-       *win_x = point.x - rect.left;
-      if (win_y)
-       *win_y = point.y - rect.top;
+      *win_x = point.x - rect.left;
+      *win_y = point.y - rect.top;
     }
 
-  GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%ld+%ld %#x%s\n",
-                          point.x, point.y,
-                          (guint) hwnd,
+  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;
@@ -1908,7 +2183,7 @@ gdk_window_get_events (GdkWindow *window)
   if (GDK_WINDOW_DESTROYED (window))
     return 0;
 
-  return GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask;
+  return GDK_WINDOW_OBJECT (window)->event_mask;
 }
 
 void          
@@ -1921,7 +2196,11 @@ gdk_window_set_events (GdkWindow   *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask = event_mask;
+  /* 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;
 }
 
 void
@@ -1934,39 +2213,33 @@ gdk_window_shape_combine_mask (GdkWindow *window,
 
   if (!mask)
     {
-      GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x none\n",
-                              (guint) GDK_WINDOW_HWND (window)));
+      GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: none\n",
+                              GDK_WINDOW_HWND (window)));
       SetWindowRgn (GDK_WINDOW_HWND (window), NULL, TRUE);
     }
   else
     {
       HRGN hrgn;
-      DWORD dwStyle;
-      DWORD dwExStyle;
       RECT rect;
 
       /* Convert mask bitmap to region */
-      hrgn = BitmapToRegion (GDK_WINDOW_HWND (mask));
+      hrgn = _gdk_win32_bitmap_to_hrgn (mask);
 
-      GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %#x %#x\n",
-                              (guint) GDK_WINDOW_HWND (window),
-                              (guint) GDK_WINDOW_HWND (mask)));
+      GDK_NOTE (MISC, g_print ("gdk_window_shape_combine_mask: %p: %p\n",
+                              GDK_WINDOW_HWND (window),
+                              GDK_WINDOW_HWND (mask)));
 
-      /* SetWindowRgn wants window (not client) coordinates */ 
-      dwStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-      dwExStyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-      GetClientRect (GDK_WINDOW_HWND (window), &rect);
-      AdjustWindowRectEx (&rect, dwStyle, FALSE, dwExStyle);
-      OffsetRgn (hrgn, -rect.left, -rect.top);
+      _gdk_win32_get_adjusted_client_rect (window, &rect);
 
+      OffsetRgn (hrgn, -rect.left, -rect.top);
       OffsetRgn (hrgn, x, y);
 
       /* If this is a top-level window, add the title bar to the region */
       if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TOPLEVEL)
        {
-         CombineRgn (hrgn, hrgn,
-                     CreateRectRgn (0, 0, rect.right - rect.left, -rect.top),
-                     RGN_OR);
+         HRGN tmp = CreateRectRgn (0, 0, rect.right - rect.left, -rect.top);
+         CombineRgn (hrgn, hrgn, tmp, RGN_OR);
+         DeleteObject (tmp);
        }
       
       SetWindowRgn (GDK_WINDOW_HWND (window), hrgn, TRUE);
@@ -1983,6 +2256,306 @@ gdk_window_set_override_redirect (GdkWindow *window,
   g_warning ("gdk_window_set_override_redirect not implemented");
 }
 
+void
+gdk_window_set_accept_focus (GdkWindow *window,
+                            gboolean accept_focus)
+{
+  GdkWindowObject *private;
+  g_return_if_fail (window != NULL);
+  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;
+}
+
+void
+gdk_window_set_focus_on_map (GdkWindow *window,
+                            gboolean focus_on_map)
+{
+  GdkWindowObject *private;
+  g_return_if_fail (window != NULL);
+  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;
+}
+
+static HICON
+pixbuf_to_hicon_alpha_winxp (GdkWindow *window,
+                            GdkPixbuf *pixbuf)
+{
+  /* Based on code from
+   * http://www.dotnet247.com/247reference/msgs/13/66301.aspx
+   */
+  HDC hdc;
+  BITMAPV5HEADER bi;
+  HBITMAP hBitmap, hMonoBitmap;
+  guchar *indata, *inrow;
+  guchar *outdata, *outrow;
+  HICON hAlphaIcon = NULL;
+  ICONINFO ii;
+  gint width, height, i, j, rowstride;
+
+  if (pixbuf == NULL)
+    return NULL;
+
+  width = gdk_pixbuf_get_width (pixbuf); /* width of icon */
+  height = gdk_pixbuf_get_height (pixbuf); /* height of icon */
+
+  ZeroMemory (&bi, sizeof (BITMAPV5HEADER));
+  bi.bV5Size = sizeof (BITMAPV5HEADER);
+  bi.bV5Width = width;
+  bi.bV5Height = height;
+  bi.bV5Planes = 1;
+  bi.bV5BitCount = 32;
+  bi.bV5Compression = BI_BITFIELDS;
+  /* The following mask specification specifies a supported 32 BPP
+   * alpha format for Windows XP (BGRA format).
+   */
+  bi.bV5RedMask   = 0x00FF0000;
+  bi.bV5GreenMask = 0x0000FF00;
+  bi.bV5BlueMask  = 0x000000FF;
+  bi.bV5AlphaMask = 0xFF000000;
+
+  /* Create the DIB section with an alpha channel. */
+  hdc = GetDC (NULL);
+  hBitmap = CreateDIBSection (hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS,
+                             (void **)&outdata, NULL, (DWORD)0);
+  ReleaseDC (NULL, hdc);
+
+  /* Draw something on the DIB section */
+  indata = gdk_pixbuf_get_pixels (pixbuf);
+  rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+  for (j=0; j<height; j++)
+    {
+      outrow = outdata + 4*j*width;
+      inrow  = indata  + (height-j-1)*rowstride;
+      for (i=0; i<width; i++)
+       {
+         outrow[4*i+0] = inrow[4*i+2];
+         outrow[4*i+1] = inrow[4*i+1];
+         outrow[4*i+2] = inrow[4*i+0];
+         outrow[4*i+3] = inrow[4*i+3];
+       }
+    }
+
+  /* Create an empty mask bitmap */
+  hMonoBitmap = CreateBitmap (width, height, 1, 1, NULL);
+
+  ii.fIcon = TRUE;
+  ii.xHotspot = 0;
+  ii.yHotspot = 0;
+  ii.hbmMask = hMonoBitmap;
+  ii.hbmColor = hBitmap;
+
+  /* Create the alpha cursor with the alpha DIB section */
+  hAlphaIcon = CreateIconIndirect (&ii);
+
+  GDI_CALL (DeleteObject, (hBitmap));
+  GDI_CALL (DeleteObject, (hMonoBitmap));
+
+  return hAlphaIcon;
+}
+
+static HICON
+pixbuf_to_hicon_normal (GdkWindow *window,
+                       GdkPixbuf *pixbuf)
+{
+  GdkPixmap *pixmap;
+  GdkBitmap *mask;
+  HBITMAP hbmmask = NULL;
+  ICONINFO ii;
+  HICON hIcon;
+  gint w = 0, h = 0;
+
+  if (pixbuf == NULL)
+    return NULL;
+
+  /* create a normal icon with a bitmap mask */
+  w = gdk_pixbuf_get_width (pixbuf);
+  h = gdk_pixbuf_get_height (pixbuf);
+  gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, 
+                                                 gdk_drawable_get_colormap (window),
+                                                 &pixmap,
+                                                 &mask,
+                                                 128);
+
+  /* we need the inverted mask for the XOR op */
+  {
+    HDC hdc1 = CreateCompatibleDC (NULL);
+    HBITMAP hbmold1;
+
+    hbmmask = CreateCompatibleBitmap (hdc1, w, h);
+    hbmold1 = SelectObject (hdc1, hbmmask);
+    if (mask)
+      {
+       HDC hdc2 = CreateCompatibleDC (NULL);
+       HBITMAP hbmold2 = SelectObject (hdc2, GDK_PIXMAP_HBITMAP (mask));
+       GDI_CALL (BitBlt, (hdc1, 0,0,w,h, hdc2, 0,0, NOTSRCCOPY));
+       GDI_CALL (SelectObject, (hdc2, hbmold2));
+       GDI_CALL (DeleteDC, (hdc2));
+      }
+    else
+      {
+       RECT rect;
+       GetClipBox (hdc1, &rect);
+       GDI_CALL (FillRect, (hdc1, &rect, GetStockObject (BLACK_BRUSH)));
+      }
+    GDI_CALL (SelectObject, (hdc1, hbmold1));
+    GDI_CALL (DeleteDC, (hdc1));
+  }
+
+  ii.fIcon = TRUE;
+  ii.xHotspot = ii.yHotspot = 0; /* ignored for icons */
+  ii.hbmMask = hbmmask;
+  ii.hbmColor = GDK_PIXMAP_HBITMAP (pixmap);
+  hIcon = CreateIconIndirect (&ii);
+  if (!hIcon)
+    WIN32_API_FAILED ("CreateIconIndirect");
+  GDI_CALL (DeleteObject, (hbmmask));
+
+#if 0 /* to debug pixmap and mask setting */
+  {
+    static int num = 0;
+    GdkPixbuf* pixbuf = NULL;
+    char name[256];
+
+    pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0, w, h);
+    if (pixbuf)
+      {
+       num = (num + 1) % 999; /* restrict maximim number */
+       sprintf (name, "c:\\temp\\ico%03dpixm.png", num); 
+       gdk_pixbuf_save (pixbuf, name, "png", NULL, NULL);
+       gdk_pixbuf_unref (pixbuf);
+      }
+  }
+#endif
+
+  if (pixmap)
+    g_object_unref (G_OBJECT (pixmap));
+  if (mask)
+    g_object_unref (G_OBJECT (mask));
+
+  return hIcon;
+}
+
+static HICON
+pixbuf_to_hicon (GdkWindow *window,
+                GdkPixbuf *pixbuf)
+{
+  static gboolean is_win_xp=FALSE, is_win_xp_checked=FALSE;
+
+  if (!is_win_xp_checked)
+    {
+      OSVERSIONINFO version;
+
+      is_win_xp_checked = TRUE;
+      memset (&version, 0, sizeof (version));
+      version.dwOSVersionInfoSize = sizeof (version);
+      is_win_xp = GetVersionEx (&version)
+       && version.dwPlatformId == VER_PLATFORM_WIN32_NT
+       && (version.dwMajorVersion > 5
+           || (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1));
+    }
+
+  if (pixbuf == NULL)
+    return NULL;
+
+  if (is_win_xp && gdk_pixbuf_get_has_alpha (pixbuf))
+    return pixbuf_to_hicon_alpha_winxp (window, pixbuf);
+  else
+    return pixbuf_to_hicon_normal (window, pixbuf);
+}
+
+void          
+gdk_window_set_icon_list (GdkWindow *window,
+                         GList     *pixbufs)
+{
+  GdkPixbuf *pixbuf, *big_pixbuf, *small_pixbuf;
+  gint big_diff, small_diff;
+  gint big_w, big_h, small_w, small_h;
+  gint w, h;
+  gint dw, dh, diff;
+  HICON small_hicon, big_hicon;
+  GdkWindowImplWin32 *impl;
+  gint i, big_i, small_i;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+
+  /* ideal sizes for small and large icons */
+  big_w = GetSystemMetrics (SM_CXICON);
+  big_h = GetSystemMetrics (SM_CYICON);
+  small_w = GetSystemMetrics (SM_CXSMICON);
+  small_h = GetSystemMetrics (SM_CYSMICON);
+
+  /* find closest sized icons in the list */
+  big_pixbuf = NULL;
+  small_pixbuf = NULL;
+  big_diff = 0;
+  small_diff = 0;
+  i = 0;
+  while (pixbufs)
+    {
+      pixbuf = (GdkPixbuf*) pixbufs->data;
+      w = gdk_pixbuf_get_width (pixbuf);
+      h = gdk_pixbuf_get_height (pixbuf);
+
+      dw = ABS (w - big_w);
+      dh = ABS (h - big_h);
+      diff = dw*dw + dh*dh;
+      if (big_pixbuf == NULL || diff < big_diff)
+       {
+         big_pixbuf = pixbuf;
+         big_diff = diff;
+         big_i = i;
+       }
+
+      dw = ABS(w - small_w);
+      dh = ABS(h - small_h);
+      diff = dw*dw + dh*dh;
+      if (small_pixbuf == NULL || diff < small_diff)
+       {
+         small_pixbuf = pixbuf;
+         small_diff = diff;
+         small_i = i;
+       }
+
+      pixbufs = g_list_next (pixbufs);
+      i++;
+    }
+
+  /* Create the icons */
+  big_hicon = pixbuf_to_hicon (window, big_pixbuf);
+  small_hicon = pixbuf_to_hicon (window, small_pixbuf);
+
+  /* Set the icons */
+  SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG,
+              (LPARAM)big_hicon);
+  SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_SMALL,
+              (LPARAM)small_hicon);
+
+  /* Store the icons, destroying any previous icons */
+  if (impl->hicon_big)
+    GDI_CALL (DestroyIcon, (impl->hicon_big));
+  impl->hicon_big = big_hicon;
+  if (impl->hicon_small)
+    GDI_CALL (DestroyIcon, (impl->hicon_small));
+  impl->hicon_small = small_hicon;
+}
+
 void          
 gdk_window_set_icon (GdkWindow *window, 
                     GdkWindow *icon_window,
@@ -1992,13 +2565,7 @@ gdk_window_set_icon (GdkWindow *window,
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
-  
-  /* Nothing to do, really. As we share window classes between windows
-   * we can't have window-specific icons, sorry. Don't print any warning
-   * either.
-   */
+  /* do nothing, use gdk_window_set_icon_list instead */
 }
 
 void
@@ -2011,8 +2578,21 @@ gdk_window_set_icon_name (GdkWindow   *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
   
-  if (!SetWindowText (GDK_WINDOW_HWND (window), name))
-    WIN32_API_FAILED ("SetWindowText");
+  API_CALL (SetWindowText, (GDK_WINDOW_HWND (window), name));
+}
+
+GdkWindow *
+gdk_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);
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return NULL;
+  
+  g_warning ("gdk_window_get_group not yet implemented");
+
+  return NULL;
 }
 
 void          
@@ -2034,80 +2614,123 @@ void
 gdk_window_set_decorations (GdkWindow      *window,
                            GdkWMDecoration decorations)
 {
-  LONG style, exstyle;
+  LONG style, bits;
+  const LONG settable_bits = WS_BORDER|WS_THICKFRAME|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
 
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
-  style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-  exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
+  GDK_NOTE (MISC, g_print ("gdk_window_set_decorations: %p: %s%s%s%s%s%s%s\n",
+                          GDK_WINDOW_HWND (window),
+                          (decorations & GDK_DECOR_ALL ? "ALL " : ""),
+                          (decorations & GDK_DECOR_BORDER ? "BORDER " : ""),
+                          (decorations & GDK_DECOR_RESIZEH ? "RESIZEH " : ""),
+                          (decorations & GDK_DECOR_TITLE ? "TITLE " : ""),
+                          (decorations & GDK_DECOR_MENU ? "MENU " : ""),
+                          (decorations & GDK_DECOR_MINIMIZE ? "MINIMIZE " : ""),
+                          (decorations & GDK_DECOR_MAXIMIZE ? "MAXIMIZE " : "")));
 
-  style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
-           |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE);
+  style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
 
-  exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
+  bits = 0;
 
-  if (decorations & GDK_DECOR_ALL)
-    style |= (WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
   if (decorations & GDK_DECOR_BORDER)
-    style |= (WS_BORDER);
+    bits |= WS_BORDER;
   if (decorations & GDK_DECOR_RESIZEH)
-    style |= (WS_THICKFRAME);
+    bits |= WS_THICKFRAME;
   if (decorations & GDK_DECOR_TITLE)
-    style |= (WS_CAPTION);
+    bits |= WS_CAPTION;
   if (decorations & GDK_DECOR_MENU)
-    style |= (WS_SYSMENU);
+    bits |= WS_SYSMENU;
   if (decorations & GDK_DECOR_MINIMIZE)
-    style |= (WS_MINIMIZEBOX);
+    bits |= WS_MINIMIZEBOX;
   if (decorations & GDK_DECOR_MAXIMIZE)
-    style |= (WS_MAXIMIZEBOX);
+    bits |= WS_MAXIMIZEBOX;
+
+  if (decorations & GDK_DECOR_ALL)
+    style |= settable_bits, style &= ~bits;
+  else
+    style &= ~settable_bits, style |= bits;
   
   SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
+  SetWindowPos (GDK_WINDOW_HWND (window), NULL, 0, 0, 0, 0,
+               SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
+               SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
+}
+
+gboolean
+gdk_window_get_decorations(GdkWindow       *window,
+                          GdkWMDecoration *decorations)
+{
+  LONG style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
+
+  *decorations = 0;
+
+  if (style & WS_BORDER)
+    *decorations |= GDK_DECOR_BORDER;
+  if (style & WS_THICKFRAME)
+    *decorations |= GDK_DECOR_RESIZEH;
+  if (style & WS_CAPTION)
+    *decorations |= GDK_DECOR_TITLE;
+  if (style & WS_SYSMENU)
+    *decorations |= GDK_DECOR_MENU;
+  if (style & WS_MINIMIZEBOX)
+    *decorations |= GDK_DECOR_MINIMIZE;
+  if (style & WS_MAXIMIZEBOX)
+    *decorations |= GDK_DECOR_MAXIMIZE;
+
+  return *decorations != 0;
 }
 
 void
 gdk_window_set_functions (GdkWindow    *window,
                          GdkWMFunction functions)
 {
-  LONG style, exstyle;
+  LONG style, bits;
+  const LONG settable_bits = (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU);
 
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
-  style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
-  exstyle = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
+  GDK_NOTE (MISC, g_print ("gdk_window_set_functions: %p: %s%s%s%s%s%s\n",
+                          GDK_WINDOW_HWND (window),
+                          (functions & GDK_FUNC_ALL ? "ALL " : ""),
+                          (functions & GDK_FUNC_RESIZE ? "RESIZE " : ""),
+                          (functions & GDK_FUNC_MOVE ? "MOVE " : ""),
+                          (functions & GDK_FUNC_MINIMIZE ? "MINIMIZE " : ""),
+                          (functions & GDK_FUNC_MAXIMIZE ? "MAXIMIZE " : ""),
+                          (functions & GDK_FUNC_CLOSE ? "CLOSE " : "")));
 
-  style &= (WS_OVERLAPPED|WS_POPUP|WS_CHILD|WS_MINIMIZE|WS_VISIBLE|WS_DISABLED
-           |WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZE|WS_CAPTION|WS_BORDER
-           |WS_SYSMENU);
+  style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
 
-  exstyle &= (WS_EX_TOPMOST|WS_EX_TRANSPARENT);
+  bits = 0;
 
-  if (functions & GDK_FUNC_ALL)
-    style |= (WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
   if (functions & GDK_FUNC_RESIZE)
-    style |= (WS_THICKFRAME);
+    bits |= WS_THICKFRAME;
   if (functions & GDK_FUNC_MOVE)
-    style |= (WS_THICKFRAME);
+    bits |= (WS_THICKFRAME|WS_SYSMENU);
   if (functions & GDK_FUNC_MINIMIZE)
-    style |= (WS_MINIMIZEBOX);
+    bits |= WS_MINIMIZEBOX;
   if (functions & GDK_FUNC_MAXIMIZE)
-    style |= (WS_MAXIMIZEBOX);
+    bits |= WS_MAXIMIZEBOX;
+  if (functions & GDK_FUNC_CLOSE)
+    bits |= WS_SYSMENU;
+  
+  if (functions & GDK_FUNC_ALL)
+    style |= settable_bits, style &= ~bits;
+  else
+    style &= ~settable_bits, style |= bits;
   
   SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, style);
+  SetWindowPos (GDK_WINDOW_HWND (window), NULL, 0, 0, 0, 0,
+               SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
+               SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
 }
 
-/* 
- * propagate the shapes from all child windows of a GDK window to the parent 
- * window. Shamelessly ripped from Enlightenment's code
- * 
- * - Raster
- */
-
 static void
-QueryTree (HWND hwnd,
+QueryTree (HWND   hwnd,
           HWND **children,
-          gint *nchildren)
+          gint  *nchildren)
 {
   guint i, n;
   HWND child;
@@ -2169,6 +2792,7 @@ gdk_propagate_shapes (HANDLE   win,
             }
          }
        SetWindowRgn (win, region, TRUE);
+       g_free (list);
      }
    else
      DeleteObject (region);
@@ -2198,92 +2822,11 @@ gdk_window_merge_child_shapes (GdkWindow *window)
   gdk_propagate_shapes (GDK_WINDOW_HWND (window), TRUE);
 }
 
-/* Support for windows that can be guffaw-scrolled
- * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
- */
-
-static gboolean
-gdk_window_gravity_works (void)
-{
-  enum { UNKNOWN, NO, YES };
-  static gint gravity_works = UNKNOWN;
-  
-  if (gravity_works == UNKNOWN)
-    {
-      GdkWindowAttr attr;
-      GdkWindow *parent;
-      GdkWindow *child;
-      gint y;
-      
-      attr.window_type = GDK_WINDOW_TEMP;
-      attr.wclass = GDK_INPUT_OUTPUT;
-      attr.x = 0;
-      attr.y = 0;
-      attr.width = 100;
-      attr.height = 100;
-      attr.event_mask = 0;
-      
-      parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
-      
-      attr.window_type = GDK_WINDOW_CHILD;
-      child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
-      
-      gdk_window_set_static_win_gravity (child, TRUE);
-      
-      gdk_window_resize (parent, 100, 110);
-      gdk_window_move (parent, 0, -10);
-      gdk_window_move_resize (parent, 0, 0, 100, 100);
-      
-      gdk_window_resize (parent, 100, 110);
-      gdk_window_move (parent, 0, -10);
-      gdk_window_move_resize (parent, 0, 0, 100, 100);
-      
-      gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
-      
-      gdk_window_destroy (parent);
-      gdk_window_destroy (child);
-      
-      gravity_works = ((y == -20) ? YES : NO);
-    }
-  
-  return (gravity_works == YES);
-}
-
-static void
-gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
-{
-  g_return_if_fail (window != NULL);
-
-  GDK_NOTE (MISC, g_print ("gdk_window_set_static_bit_gravity: Not implemented\n"));
-}
-
-static void
-gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
-{
-  g_return_if_fail (window != NULL);
-
-  GDK_NOTE (MISC,
-           g_print ("gdk_window_set_static_win_gravity: Not implemented\n"));
-}
-
-/*************************************************************
- * gdk_window_set_static_gravities:
- *     Set the bit gravity of the given window to static,
- *     and flag it so all children get static subwindow
- *     gravity.
- *   arguments:
- *     window: window for which to set static gravity
- *     use_static: Whether to turn static gravity on or off.
- *   results:
- *     Does the XServer support static gravity?
- *************************************************************/
-
 gboolean 
 gdk_window_set_static_gravities (GdkWindow *window,
                                 gboolean   use_static)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
-  GList *tmp_list;
   
   g_return_val_if_fail (window != NULL, FALSE);
   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
@@ -2291,46 +2834,73 @@ gdk_window_set_static_gravities (GdkWindow *window,
   if (!use_static == !private->guffaw_gravity)
     return TRUE;
   
-  if (use_static && !gdk_window_gravity_works ())
+  if (use_static)
     return FALSE;
   
   private->guffaw_gravity = use_static;
   
-  if (!GDK_WINDOW_DESTROYED (window))
-    {
-      gdk_window_set_static_bit_gravity (window, use_static);
-      
-      tmp_list = private->children;
-      while (tmp_list)
-       {
-         gdk_window_set_static_win_gravity (window, use_static);
-         
-         tmp_list = tmp_list->next;
-       }
-    }
-  
   return TRUE;
 }
 
+void
+gdk_window_begin_resize_drag (GdkWindow     *window,
+                              GdkWindowEdge  edge,
+                              gint           button,
+                              gint           root_x,
+                              gint           root_y,
+                              guint32        timestamp)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  /* XXX: isn't all this default on win32 ... */  
+}
+
+void
+gdk_window_begin_move_drag (GdkWindow *window,
+                            gint       button,
+                            gint       root_x,
+                            gint       root_y,
+                            guint32    timestamp)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  /* XXX: isn't all this default on win32 ... */  
+}
+
+
 /*
  * Setting window states
  */
 void
 gdk_window_iconify (GdkWindow *window)
 {
+  HWND old_active_window;
+
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  GDK_NOTE (MISC, g_print ("gdk_window_iconify: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+
   if (GDK_WINDOW_IS_MAPPED (window))
     {
+      old_active_window = GetActiveWindow ();
       ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
+      if (old_active_window != GDK_WINDOW_HWND (window))
+       SetActiveWindow (old_active_window);
     }
   else
     {
-      /* Flip our client side flag, the real work happens on map. */
       gdk_synthesize_window_state (window,
                                    0,
                                    GDK_WINDOW_STATE_ICONIFIED);
@@ -2346,13 +2916,16 @@ gdk_window_deiconify (GdkWindow *window)
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  GDK_NOTE (MISC, g_print ("gdk_window_deiconify: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+
   if (GDK_WINDOW_IS_MAPPED (window))
     {  
-      gdk_window_show (window);
+      show_window_internal (window, FALSE, TRUE);
     }
   else
     {
-      /* Flip our client side flag, the real work happens on map. */
       gdk_synthesize_window_state (window,
                                    GDK_WINDOW_STATE_ICONIFIED,
                                    0);
@@ -2367,20 +2940,7 @@ gdk_window_stick (GdkWindow *window)
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  if (GDK_WINDOW_IS_MAPPED (window))
-    {
-      /* "stick" means stick to all desktops _and_ do not scroll with the
-       * viewport. i.e. glue to the monitor glass in all cases.
-       */
-      g_warning ("gdk_window_stick (0x%X) ???", GDK_WINDOW_HWND (window));
-    }
-  else
-    {
-      /* Flip our client side flag, the real work happens on map. */
-      gdk_synthesize_window_state (window,
-                                   0,
-                                   GDK_WINDOW_STATE_STICKY);
-    }
+  /* FIXME: Do something? */
 }
 
 void
@@ -2391,18 +2951,7 @@ gdk_window_unstick (GdkWindow *window)
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  if (GDK_WINDOW_IS_MAPPED (window))
-    {
-      g_warning ("gdk_window_unstick (0x%X) ???", GDK_WINDOW_HWND (window));
-    }
-  else
-    {
-      /* Flip our client side flag, the real work happens on map. */
-      gdk_synthesize_window_state (window,
-                                   GDK_WINDOW_STATE_STICKY,
-                                   0);
-
-    }
+  /* FIXME: Do something? */
 }
 
 void
@@ -2413,6 +2962,10 @@ gdk_window_maximize (GdkWindow *window)
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  GDK_NOTE (MISC, g_print ("gdk_window_maximize: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+
   if (GDK_WINDOW_IS_MAPPED (window))
     ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
   else
@@ -2429,6 +2982,10 @@ gdk_window_unmaximize (GdkWindow *window)
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  GDK_NOTE (MISC, g_print ("gdk_window_unmaximize: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+
   if (GDK_WINDOW_IS_MAPPED (window))
     ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
   else
@@ -2437,6 +2994,119 @@ gdk_window_unmaximize (GdkWindow *window)
                                 0);
 }
 
+typedef struct _FullscreenInfo FullscreenInfo;
+
+struct _FullscreenInfo
+{
+  RECT  r;
+  guint hint_flags;
+  LONG  style;
+};
+
+void
+gdk_window_fullscreen (GdkWindow *window)
+{
+  gint width, height;
+  FullscreenInfo *fi;
+  GdkWindowObject *private = (GdkWindowObject *) window;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  fi = g_new (FullscreenInfo, 1);
+
+  if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
+    g_free (fi);
+  else
+    {
+      GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (private->impl);
+
+      width = GetSystemMetrics (SM_CXSCREEN);
+      height = GetSystemMetrics (SM_CYSCREEN);
+      /* remember for restoring */
+      fi->hint_flags = impl->hint_flags;
+      impl->hint_flags &= ~GDK_HINT_MAX_SIZE;
+      g_object_set_data (G_OBJECT (window), "fullscreen-info", fi);
+      fi->style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE);
+
+      SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, 
+                     (fi->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP);
+      if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOP /*not MOST, taskswitch!*/,
+                         0, 0, width, height,
+                         SWP_NOCOPYBITS | SWP_SHOWWINDOW))
+        WIN32_API_FAILED ("SetWindowPos");
+
+      gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
+    }
+}
+
+void
+gdk_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);
+
+      impl->hint_flags = fi->hint_flags;
+      SetWindowLong (GDK_WINDOW_HWND (window), GWL_STYLE, fi->style);
+      if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_NOTOPMOST,
+                         fi->r.left, fi->r.top, fi->r.right - fi->r.left, fi->r.bottom - fi->r.top,
+                         SWP_NOCOPYBITS | SWP_SHOWWINDOW))
+         WIN32_API_FAILED ("SetWindowPos");
+
+      g_object_set_data (G_OBJECT (window), "fullscreen-info", NULL);
+      g_free (fi);
+
+      gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
+    }
+}
+
+void
+gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  if (GDK_WINDOW_IS_MAPPED (window))
+    {
+      if (!SetWindowPos(GDK_WINDOW_HWND (window), setting ? HWND_TOPMOST : HWND_NOTOPMOST,
+                        0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE))
+         WIN32_API_FAILED ("SetWindowPos");
+    }
+  else
+    gdk_synthesize_window_state (window,
+                                setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
+                                setting ? GDK_WINDOW_STATE_ABOVE : 0);
+}
+
+void
+gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  if (GDK_WINDOW_IS_MAPPED (window))
+    {
+      if (!SetWindowPos(GDK_WINDOW_HWND (window), setting ? HWND_BOTTOM : HWND_NOTOPMOST,
+                        0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE))
+         WIN32_API_FAILED ("SetWindowPos");
+    }
+  else
+    gdk_synthesize_window_state (window,
+                                setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
+                                setting ? GDK_WINDOW_STATE_BELOW : 0);
+}
+
 void
 gdk_window_focus (GdkWindow *window,
                   guint32    timestamp)
@@ -2446,7 +3116,15 @@ gdk_window_focus (GdkWindow *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
   
-  ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
+  GDK_NOTE (MISC, g_print ("gdk_window_focus: %p: %s\n",
+                          GDK_WINDOW_HWND (window),
+                          _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
+
+  if (((GdkWindowObject *) 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
@@ -2466,47 +3144,105 @@ gdk_window_set_modal_hint (GdkWindow *window,
   private->modal_hint = modal;
 
   if (GDK_WINDOW_IS_MAPPED (window))
-    if (!SetWindowPos (GDK_WINDOW_HWND (window), HWND_TOPMOST,
-                           0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE))
-      WIN32_API_FAILED ("SetWindowPos");
+    API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), 
+                            modal ? HWND_TOPMOST : HWND_NOTOPMOST,
+                            0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE));
+}
+
+void
+gdk_window_set_skip_taskbar_hint (GdkWindow *window,
+                                 gboolean   skips_taskbar)
+{
+  static GdkWindow *owner = NULL;
+  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_WINDOW_HWND (window),
+                          skips_taskbar ? "TRUE" : "FALSE"));
+
+  if (skips_taskbar)
+    {
+      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);
+       }
+
+      SetWindowLong (GDK_WINDOW_HWND (window), GWL_HWNDPARENT,
+                    (long) 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 |
+                   SWP_NOREPOSITION | SWP_NOSIZE | SWP_NOZORDER);
+#endif
+    }
+  else
+    {
+      SetWindowLong (GDK_WINDOW_HWND (window), GWL_HWNDPARENT, 0);
+    }
+}
+
+void
+gdk_window_set_skip_pager_hint (GdkWindow *window,
+                               gboolean   skips_pager)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
 }
 
 void
 gdk_window_set_type_hint (GdkWindow        *window,
                          GdkWindowTypeHint hint)
 {
-  GdkAtom atom;
-  
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (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));
   switch (hint)
     {
     case GDK_WINDOW_TYPE_HINT_DIALOG:
-      atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DIALOG", FALSE);
       break;
     case GDK_WINDOW_TYPE_HINT_MENU:
-      atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_MENU", FALSE);
+      gdk_window_set_decorations (window,
+                                 GDK_DECOR_ALL |
+                                 GDK_DECOR_RESIZEH |
+                                 GDK_DECOR_MINIMIZE |
+                                 GDK_DECOR_MAXIMIZE);
       break;
     case GDK_WINDOW_TYPE_HINT_TOOLBAR:
-      atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_TOOLBAR", FALSE);
+      gdk_window_set_skip_taskbar_hint (window, TRUE);
+      break;
+    case GDK_WINDOW_TYPE_HINT_UTILITY:
+      break;
+    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+      gdk_window_set_decorations (window,
+                                 GDK_DECOR_ALL |
+                                 GDK_DECOR_RESIZEH |
+                                 GDK_DECOR_MENU |
+                                 GDK_DECOR_MINIMIZE |
+                                 GDK_DECOR_MAXIMIZE);
+      break;
+    case GDK_WINDOW_TYPE_HINT_DOCK:
+      break;
+    case GDK_WINDOW_TYPE_HINT_DESKTOP:
       break;
     default:
       g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
       /* Fall thru */
     case GDK_WINDOW_TYPE_HINT_NORMAL:
-      atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_NORMAL", FALSE);
       break;
     }
-  /*
-   * XXX ???
-   */
-  GDK_NOTE (MISC,
-            g_print ("gdk_window_set_type_hint (0x%0X)\n",
-                     GDK_WINDOW_HWND (window)));
 }
 
 void
@@ -2515,8 +3251,6 @@ gdk_window_shape_combine_region (GdkWindow *window,
                                  gint       offset_x,
                                  gint       offset_y)
 {
-  gint xoffset, yoffset;
-  
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -2525,33 +3259,20 @@ gdk_window_shape_combine_region (GdkWindow *window,
   /* XXX: even on X implemented conditional ... */  
 }
 
-void
-gdk_window_begin_resize_drag (GdkWindow     *window,
-                              GdkWindowEdge  edge,
-                              gint           button,
-                              gint           root_x,
-                              gint           root_y,
-                              guint32        timestamp)
+GdkWindow *
+gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
+  g_return_val_if_fail (display == gdk_display_get_default(), NULL);
 
-  /* XXX: isn't all this default on win32 ... */  
+  return gdk_window_lookup (anid);
 }
 
 void
-gdk_window_begin_move_drag (GdkWindow *window,
-                            gint       button,
-                            gint       root_x,
-                            gint       root_y,
-                            guint32    timestamp)
+gdk_window_enable_synchronized_configure (GdkWindow *window)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
+}
 
-  /* XXX: isn't all this default on win32 ... */  
+void
+gdk_window_configure_finished (GdkWindow *window)
+{
 }