]> 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 1493216c1c3a3f38b127f1c30fce242aab07b0e0..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-2002 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
@@ -25,6 +26,7 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <config.h>
 #include <stdlib.h>
 
 #include "gdk.h" /* gdk_rectangle_intersect */
 #include "gdkprivate-win32.h"
 #include "gdkinput-win32.h"
 
+#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,
                                                        GdkColormap *cmap);
@@ -89,7 +126,8 @@ gdk_window_impl_win32_init (GdkWindowImplWin32 *impl)
   impl->height = 1;
 
   impl->hcursor = NULL;
-  impl->hicon = NULL;
+  impl->hicon_big = NULL;
+  impl->hicon_small = NULL;
   impl->hint_flags = 0;
   impl->extension_events_selected = FALSE;
 }
@@ -139,15 +177,39 @@ gdk_window_impl_win32_finalize (GObject *object)
       GDI_CALL (DestroyCursor, (window_impl->hcursor));
       window_impl->hcursor = NULL;
     }
-  if (window_impl->hicon != NULL)
+  if (window_impl->hicon_big != NULL)
     {
-      GDI_CALL (DestroyIcon, (window_impl->hicon));
-      window_impl->hicon = 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)
 {
@@ -160,7 +222,8 @@ gdk_window_impl_win32_get_colormap (GdkDrawable *drawable)
   if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only && 
       drawable_impl->colormap == NULL)
     {
-      drawable_impl->colormap = gdk_colormap_get_system ();
+      drawable_impl->colormap = 
+        gdk_screen_get_system_colormap (gdk_drawable_get_screen (drawable));
       g_object_ref (drawable_impl->colormap);
     }
   
@@ -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,28 +279,54 @@ 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);
   
-  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);
   draw_impl = GDK_DRAWABLE_IMPL_WIN32 (private->impl);
   
   draw_impl->handle = _gdk_root_window;
@@ -247,9 +337,8 @@ _gdk_windowing_window_init (void)
   private->window_type = GDK_WINDOW_ROOT;
   private->depth = gdk_visual_get_system ()->depth;
 
-  impl->width = width;
-  impl->height = height;
-
+  _gdk_root_window_size_init ();
   _gdk_window_init_position (GDK_WINDOW (private));
 
   gdk_win32_handle_table_insert (&_gdk_root_window, _gdk_parent_root);
@@ -388,10 +477,11 @@ 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;
@@ -406,6 +496,7 @@ gdk_window_new (GdkWindow     *parent,
   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);
 
@@ -446,6 +537,9 @@ gdk_window_new (GdkWindow     *parent,
   
   private->parent = (GdkWindowObject *)parent;
 
+  private->accept_focus = TRUE;
+  private->focus_on_map = TRUE;
+
   if (attributes_mask & GDK_WA_X)
     private->x = attributes->x;
   else
@@ -466,7 +560,19 @@ gdk_window_new (GdkWindow     *parent,
   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;
+  if (attributes->wclass == GDK_INPUT_ONLY)
+    {
+      /* 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)
     {
@@ -491,7 +597,7 @@ gdk_window_new (GdkWindow     *parent,
       dwExStyle = WS_EX_TRANSPARENT;
       private->depth = 0;
       private->input_only = TRUE;
-      draw_impl->colormap = gdk_colormap_get_system ();
+      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"));
     }
@@ -501,6 +607,8 @@ gdk_window_new (GdkWindow     *parent,
     case GDK_WINDOW_TOPLEVEL:
       dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
       hparent = _gdk_root_window;
+      offset_x = _gdk_offset_x;
+      offset_y = _gdk_offset_y;
       break;
 
     case GDK_WINDOW_CHILD:
@@ -513,6 +621,8 @@ gdk_window_new (GdkWindow     *parent,
       dwExStyle |= WS_EX_TOPMOST; /* //HB: want this? */
 #endif
       hparent = _gdk_root_window;
+      offset_x = _gdk_offset_x;
+      offset_y = _gdk_offset_y;
       break;
 
     case GDK_WINDOW_TEMP:
@@ -520,6 +630,8 @@ gdk_window_new (GdkWindow     *parent,
       /* a temp window is not necessarily a top level window */
       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:
@@ -573,21 +685,6 @@ gdk_window_new (GdkWindow     *parent,
 
   mbtitle = g_locale_from_utf8 (title, -1, NULL, NULL, NULL);
   
-#ifdef WITHOUT_WM_CREATE
-  draw_impl->handle =
-    CreateWindowEx (dwExStyle,
-                   MAKEINTRESOURCE(klass),
-                   mbtitle,
-                   dwStyle,
-                   ((attributes_mask & GDK_WA_X) ?
-                    impl->position_info.x : CW_USEDEFAULT),
-                   impl->position_info.y, 
-                   window_width, window_height,
-                   hparent,
-                   NULL,
-                   _gdk_app_hmodule,
-                   NULL);
-#else
   {
   HWND hwndNew =
     CreateWindowEx (dwExStyle,
@@ -595,8 +692,8 @@ gdk_window_new (GdkWindow     *parent,
                    mbtitle,
                    dwStyle,
                    ((attributes_mask & GDK_WA_X) ?
-                    impl->position_info.x : CW_USEDEFAULT),
-                   impl->position_info.y, 
+                    impl->position_info.x - offset_x: CW_USEDEFAULT),
+                   impl->position_info.y - offset_y
                    window_width, window_height,
                    hparent,
                    NULL,
@@ -626,14 +723,13 @@ gdk_window_new (GdkWindow     *parent,
   }
   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 %p = %p\n",
                           mbtitle,
                           window_width, window_height,
                           ((attributes_mask & GDK_WA_X) ?
-                           impl->position_info.x : CW_USEDEFAULT),
-                          impl->position_info.y, 
+                           impl->position_info.x - offset_x: CW_USEDEFAULT),
+                          impl->position_info.y - offset_y
                           hparent,
                           GDK_WINDOW_HWND (window)));
 
@@ -646,10 +742,8 @@ gdk_window_new (GdkWindow     *parent,
       return NULL;
     }
 
-#ifdef WITHOUT_WM_CREATE
-  g_object_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) :
@@ -658,6 +752,14 @@ 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_for_display (GdkDisplay      *display,
                                     GdkNativeWindow  anid)
@@ -704,6 +806,12 @@ gdk_window_foreign_new_for_display (GdkDisplay      *display,
     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_window_init_position (GDK_WINDOW (private));
@@ -735,30 +843,31 @@ _gdk_windowing_window_destroy (GdkWindow *window,
   if (private->extension_events != 0)
     _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.
@@ -877,7 +986,8 @@ show_window_internal (GdkWindow *window,
 {
   GdkWindowObject *private;
   HWND old_active_window;
-  
+  gboolean focus_on_map = TRUE;
+
   private = (GdkWindowObject *) window;
 
   if (private->destroyed)
@@ -920,39 +1030,65 @@ show_window_internal (GdkWindow *window,
   /* Other cases */
   
   if (!GDK_WINDOW_IS_MAPPED (window))
-    gdk_synthesize_window_state (window,
-                                GDK_WINDOW_STATE_WITHDRAWN,
-                                0);
+    {
+      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)
     {
-      /* Don't really know if this makes sense, can't remember whether
-       * this case is handled like this because it is necessary, or
-       * if this is just old crap.
-       */
-      SetWindowPos(GDK_WINDOW_HWND (window), HWND_TOP, 0, 0, 0, 0,
-                  SWP_SHOWWINDOW | SWP_NOREDRAW | SWP_NOMOVE | SWP_NOSIZE);
+      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)
+  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
-      BringWindowToTop (GDK_WINDOW_HWND (window));
+    {
+      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);
 }
@@ -1000,8 +1136,8 @@ gdk_window_hide (GdkWindow *window)
   
   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);
+      SetWindowPos (GDK_WINDOW_HWND (window), HWND_BOTTOM, 0, 0, 0, 0,
+                   SWP_HIDEWINDOW | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
     }
   else
     {
@@ -1060,7 +1196,7 @@ gdk_window_move (GdkWindow *window,
       adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
 
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
-                              xy, 0, 0,
+                              x - _gdk_offset_x, y - _gdk_offset_y, 0, 0,
                               SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER));
     }
 }
@@ -1149,7 +1285,7 @@ gdk_window_move_resize (GdkWindow *window,
       adjust_for_gravity_hints (impl, &outer_rect, &x, &y);
 
       API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), NULL,
-                              xy,
+                              x - _gdk_offset_x, y - _gdk_offset_y,
                               outer_rect.right - outer_rect.left,
                               outer_rect.bottom - outer_rect.top,
                               SWP_NOACTIVATE | SWP_NOZORDER));
@@ -1172,6 +1308,12 @@ gdk_window_reparent (GdkWindow *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;
 
@@ -1321,12 +1463,7 @@ gdk_window_set_hints (GdkWindow *window,
   /* 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));
   
@@ -1340,9 +1477,6 @@ gdk_window_set_hints (GdkWindow *window,
                           min_width, min_height, max_width, max_height,
                           x, y));
 
-  impl->hint_flags = flags;
-  size_hints.length = sizeof (size_hints);
-
   if (flags)
     {
       GdkGeometry geom;
@@ -1353,50 +1487,6 @@ gdk_window_set_hints (GdkWindow *window,
       geom.max_width  = max_width;
       geom.max_height = max_height;
 
-      if (flags & GDK_HINT_POS)
-       {
-         if (API_CALL (GetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints)))
-           {
-             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
-              */
-
-             /* FIXME: Is the hint client area pos or border? */
-             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));
-             API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window),
-                                            &size_hints));
-           }
-       }
-
       if (flags & GDK_HINT_MIN_SIZE)
         geom_mask |= GDK_HINT_MIN_SIZE;
 
@@ -1413,10 +1503,12 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
                               GdkWindowHints  geom_mask)
 {
   GdkWindowImplWin32 *impl;
+#if 0
   WINDOWPLACEMENT size_hints;
   RECT rect;
   gint new_width = 0, new_height = 0;
-  
+#endif
+
   g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
@@ -1427,7 +1519,6 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
                           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;
@@ -1440,6 +1531,7 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
       GDK_NOTE (MISC, g_print ("... MIN_SIZE: %dx%d\n",
                               geometry->min_width, geometry->min_height));
 
+#if 0
       /* Check if the current size of the window is in bounds */
       GetClientRect (GDK_WINDOW_HWND (window), &rect);
 
@@ -1459,6 +1551,7 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
          new_width = rect.right;
          new_height = geometry->min_height;
        }
+#endif
     }
   
   if (geom_mask & GDK_HINT_MAX_SIZE)
@@ -1466,6 +1559,7 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
       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);
 
@@ -1485,20 +1579,23 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
          new_width = rect.right;
          new_height = geometry->max_height;
        }
+#endif
     }
 
+#if 0
   /* Apply new size constraints */
   if (new_width != 0 && new_height != 0)
     gdk_window_resize (window, new_width, new_height);
-  
-  /* 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)
+#endif
+
+  if (geom_mask & GDK_HINT_BASE_SIZE)
     {
       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,
@@ -1518,6 +1615,7 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
                                   size_hints.rcNormalPosition.bottom));
          API_CALL (SetWindowPlacement, (GDK_WINDOW_HWND (window), &size_hints));
        }
+#endif
     }
   
   if (geom_mask & GDK_HINT_RESIZE_INC)
@@ -1616,8 +1714,8 @@ gdk_window_set_transient_for (GdkWindow *window,
 }
 
 void
-gdk_window_set_background (GdkWindow *window,
-                          GdkColor  *color)
+gdk_window_set_background (GdkWindow      *window,
+                          const GdkColor *color)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
   
@@ -1801,6 +1899,14 @@ gdk_window_get_geometry (GdkWindow *window,
          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)
@@ -1848,9 +1954,9 @@ 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: %p: +%d+%d\n",
                           GDK_WINDOW_HWND (window),
@@ -1925,8 +2031,8 @@ gdk_window_get_frame_extents (GdkWindow    *window,
 
   API_CALL (GetWindowRect, (hwnd, &r));
 
-  rect->x = r.left;
-  rect->y = r.top;
+  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;
 
@@ -1958,6 +2064,12 @@ _gdk_windowing_window_get_pointer (GdkDisplay      *display,
   *x = point.x;
   *y = point.y;
 
+  if (window == _gdk_parent_root)
+    {
+      *x += _gdk_offset_x;
+      *y += _gdk_offset_y;
+    }
+
   hwnd = WindowFromPoint (screen_point);
   if (hwnd != NULL)
     {
@@ -2032,8 +2144,8 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
   if (hwnd == NULL)
     {
       window = _gdk_parent_root;
-      *win_x = pointc.x;
-      *win_y = pointc.y;
+      *win_x = pointc.x + _gdk_offset_x;
+      *win_y = pointc.y + _gdk_offset_y;
       return window;
     }
       
@@ -2054,8 +2166,8 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
       *win_y = point.y - rect.top;
     }
 
-  GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: +%ld+%ld %p%s\n",
-                          point.x, point.y,
+  GDK_NOTE (MISC, g_print ("_gdk_windowing_window_at_pointer: +%d+%d %p%s\n",
+                          *win_x, *win_y,
                           hwnd,
                           (window == NULL ? " NULL" : "")));
 
@@ -2108,8 +2220,6 @@ gdk_window_shape_combine_mask (GdkWindow *window,
   else
     {
       HRGN hrgn;
-      DWORD dwStyle;
-      DWORD dwExStyle;
       RECT rect;
 
       /* Convert mask bitmap to region */
@@ -2119,13 +2229,9 @@ gdk_window_shape_combine_mask (GdkWindow *window,
                               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 */
@@ -2150,34 +2256,238 @@ gdk_window_set_override_redirect (GdkWindow *window,
   g_warning ("gdk_window_set_override_redirect not implemented");
 }
 
-void          
-gdk_window_set_icon_list (GdkWindow *window,
-                         GList     *pixbufs)
+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));
 
-  if (GDK_WINDOW_DESTROYED (window))
-    return;
+  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;
 
-  /* We could convert it to a hIcon and DrawIcon () it when getting
-   * a WM_PAINT with IsIconic, but is it worth it ? Same probably
-   * goes for gdk_window_set_icon (). Patches accepted :-)  --hb
-   * Or do we only need to deliver the Icon on WM_GETICON ?
+  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;
 }
 
-void          
-gdk_window_set_icon (GdkWindow *window, 
-                    GdkWindow *icon_window,
-                    GdkPixmap *pixmap,
-                    GdkBitmap *mask)
+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 (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -2185,32 +2495,77 @@ gdk_window_set_icon (GdkWindow *window,
 
   impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
 
-  if (pixmap && mask)
-    {
-      gdk_drawable_get_size (GDK_DRAWABLE(pixmap), &w, &h);
+  /* 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;
+       }
 
-      ii.fIcon = TRUE;
-      ii.xHotspot = ii.yHotspot = 0; /* ignored for icons */
-      ii.hbmMask = GDK_PIXMAP_HBITMAP (mask);
-      ii.hbmColor = GDK_PIXMAP_HBITMAP (pixmap); 
-      hIcon = CreateIconIndirect (&ii);
-      hIcon = (HICON)SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG, (LPARAM)hIcon);
-      if (impl->hicon)
-        GDI_CALL (DestroyIcon, (impl->hicon));
-      impl->hicon = hIcon;
-    }
-  else
-    {
-      /* reseting to default icon */
-      if (impl->hicon)
-        {
-          hIcon = (HICON)SendMessage (GDK_WINDOW_HWND (window), WM_SETICON, ICON_BIG, 0);
-          GDI_CALL (DestroyIcon, (impl->hicon));
-          impl->hicon = NULL;
-        }
+      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++;
     }
 
-  GDK_NOTE (MISC, g_print ("gdk_window_set_icon : %p %dx%d\n", hIcon, w, h));
+  /* 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,
+                    GdkPixmap *pixmap,
+                    GdkBitmap *mask)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  /* do nothing, use gdk_window_set_icon_list instead */
 }
 
 void
@@ -2226,6 +2581,20 @@ gdk_window_set_icon_name (GdkWindow   *window,
   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          
 gdk_window_set_group (GdkWindow *window, 
                      GdkWindow *leader)
@@ -2473,6 +2842,38 @@ gdk_window_set_static_gravities (GdkWindow *window,
   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
  */
@@ -2611,9 +3012,6 @@ gdk_window_fullscreen (GdkWindow *window)
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  width = GetSystemMetrics (SM_CXSCREEN);
-  height = GetSystemMetrics (SM_CYSCREEN);
   fi = g_new (FullscreenInfo, 1);
 
   if (!GetWindowRect (GDK_WINDOW_HWND (window), &(fi->r)))
@@ -2622,6 +3020,9 @@ gdk_window_fullscreen (GdkWindow *window)
     {
       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;
@@ -2666,6 +3067,46 @@ gdk_window_unfullscreen (GdkWindow *window)
     }
 }
 
+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)
@@ -2679,7 +3120,10 @@ gdk_window_focus (GdkWindow *window,
                           GDK_WINDOW_HWND (window),
                           _gdk_win32_window_state_to_string (((GdkWindowObject *) window)->state)));
 
-  ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
+  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));
 }
 
@@ -2709,7 +3153,8 @@ void
 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
                                  gboolean   skips_taskbar)
 {
-  LONG extended_style;
+  static GdkWindow *owner = NULL;
+  GdkWindowAttr wa;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -2717,14 +3162,32 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
                           GDK_WINDOW_HWND (window),
                           skips_taskbar ? "TRUE" : "FALSE"));
 
-  extended_style = GetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE);
-
   if (skips_taskbar)
-    extended_style |= WS_EX_TOOLWINDOW;
-  else
-    extended_style &= ~WS_EX_TOOLWINDOW;
+    {
+      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));
 
-  SetWindowLong (GDK_WINDOW_HWND (window), GWL_EXSTYLE, extended_style);
+#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
@@ -2763,6 +3226,12 @@ gdk_window_set_type_hint (GdkWindow        *window,
     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;
@@ -2790,41 +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 ... */  
 }
 
-GdkWindow *
-gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
+void
+gdk_window_configure_finished (GdkWindow *window)
 {
-  g_return_val_if_fail (display == gdk_display_get_default(), NULL);
-
-  return gdk_window_lookup (anid);
 }