]> Pileus Git - ~andy/gtk/blobdiff - gdk/x11/gdkwindow-x11.c
moved and renamed the gdk_settings_names and gdk_settings_map.
[~andy/gtk] / gdk / x11 / gdkwindow-x11.c
index d25c0980fbcc82b8b15cdb640bb163a9269e2b8f..59ffd53122b53632f15f26e2f9f21f4c83bf4cfe 100644 (file)
@@ -31,6 +31,7 @@
 #include <X11/Xatom.h>
 #include <netinet/in.h>
 #include <unistd.h>
+
 #include "gdk.h"
 
 #include "gdkwindow.h"
@@ -42,6 +43,7 @@
 #include "gdkinternals.h"
 #include "MwmUtil.h"
 #include "gdkwindow-x11.h"
+#include "gdkalias.h"
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -81,7 +83,6 @@ const int _gdk_nenvent_masks = sizeof (_gdk_event_mask_table) / sizeof (int);
 /* Forward declarations */
 static void     gdk_window_set_static_win_gravity (GdkWindow  *window,
                                                   gboolean    on);
-static gboolean gdk_window_have_shape_ext         (GdkDisplay *display);
 static gboolean gdk_window_icon_name_set          (GdkWindow  *window);
 static void     gdk_window_add_colormap_windows   (GdkWindow  *window);
 static void     set_wm_name                       (GdkDisplay  *display,
@@ -105,6 +106,14 @@ static gpointer parent_class = NULL;
   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
    GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
 
+/* Return whether time1 is considered later than time2 as far as xserver
+ * time is concerned.  Accounts for wraparound.
+ */
+#define XSERVER_TIME_IS_LATER(time1, time2)                        \
+  ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) ||  \
+    (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
+  )
+
 GType
 gdk_window_impl_x11_get_type (void)
 {
@@ -126,7 +135,7 @@ gdk_window_impl_x11_get_type (void)
       };
       
       object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
-                                            "GdkWindowImplX11",
+                                            g_intern_static_string ("GdkWindowImplX11"),
                                             &object_info, 0);
     }
   
@@ -214,6 +223,9 @@ gdk_window_impl_x11_finalize (GObject *object)
   if (window_impl->toplevel)
     g_free (window_impl->toplevel);
 
+  if (window_impl->cursor)
+    gdk_cursor_unref (window_impl->cursor);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -226,6 +238,13 @@ tmp_unset_bg (GdkWindow *window)
   obj = (GdkWindowObject *) window;
   impl = GDK_WINDOW_IMPL_X11 (obj->impl);
 
+  /* For windows without EXPOSURE_MASK, we can't do this
+   * unsetting because such windows depend on the drawing
+   * that the X server is going to do
+   */
+  if (!(obj->event_mask & GDK_EXPOSURE_MASK))
+    return;
+    
   impl->position_info.no_bg = TRUE;
 
   if (obj->bg_pixmap != GDK_NO_BG)
@@ -242,6 +261,9 @@ tmp_reset_bg (GdkWindow *window)
   obj = (GdkWindowObject *) window;
   impl = GDK_WINDOW_IMPL_X11 (obj->impl);
 
+  if (!(obj->event_mask & GDK_EXPOSURE_MASK))
+    return;
+    
   impl->position_info.no_bg = FALSE;
 
   if (obj->bg_pixmap == GDK_NO_BG)
@@ -284,13 +306,8 @@ _gdk_x11_window_tmp_unset_bg (GdkWindow *window,
       return;
     }
 
-  /* Don't unset the background of windows that don't select for expose
-   * events. Such windows don't get drawn, so we need the X server
-   * drawing them to prevent them from containing garbage
-   */
   if (private->window_type != GDK_WINDOW_ROOT &&
-      private->window_type != GDK_WINDOW_FOREIGN &&
-      (private->event_mask & GDK_EXPOSURE_MASK))
+      private->window_type != GDK_WINDOW_FOREIGN)
     {
       tmp_unset_bg (window);
     }
@@ -322,8 +339,7 @@ _gdk_x11_window_tmp_reset_bg (GdkWindow *window,
     }
 
   if (private->window_type != GDK_WINDOW_ROOT &&
-      private->window_type != GDK_WINDOW_FOREIGN &&
-      (private->event_mask & GDK_EXPOSURE_MASK))
+      private->window_type != GDK_WINDOW_FOREIGN)
     {
       tmp_reset_bg (window);
     }
@@ -341,12 +357,10 @@ static GdkColormap*
 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
 {
   GdkDrawableImplX11 *drawable_impl;
-  GdkWindowImplX11 *window_impl;
   
   g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
 
   drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
-  window_impl = GDK_WINDOW_IMPL_X11 (drawable);
 
   if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only && 
       drawable_impl->colormap == NULL)
@@ -371,12 +385,10 @@ static void
 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
                                   GdkColormap *cmap)
 {
-  GdkWindowImplX11 *impl;
   GdkDrawableImplX11 *draw_impl;
   
   g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
 
-  impl = GDK_WINDOW_IMPL_X11 (drawable);
   draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
   if (cmap && GDK_WINDOW_DESTROYED (draw_impl->wrapper))
@@ -470,13 +482,19 @@ static void
 set_wm_protocols (GdkWindow *window)
 {
   GdkDisplay *display = gdk_drawable_get_display (window);
-  Atom protocols[3];
+  Atom protocols[4];
+  int n = 0;
   
-  protocols[0] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
-  protocols[1] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
-  protocols[2] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
+  protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
+  protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
+  protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
 
-  XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, 3);
+#ifdef HAVE_XSYNC
+  if (GDK_DISPLAY_X11 (display)->use_sync)
+    protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST");
+#endif
+  
+  XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
 }
 
 static const gchar *
@@ -525,7 +543,45 @@ create_focus_window (Display *xdisplay,
 }
 
 static void
-setup_toplevel_window (GdkWindow *window, GdkWindow *parent)
+ensure_sync_counter (GdkWindow *window)
+{
+#ifdef HAVE_XSYNC
+  if (!GDK_WINDOW_DESTROYED (window))
+    {
+      GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+      GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+      GdkWindowObject *private = (GdkWindowObject *)window;
+      GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
+
+      if (toplevel && impl->use_synchronized_configure &&
+         toplevel->update_counter == None &&
+         GDK_DISPLAY_X11 (display)->use_sync)
+       {
+         Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+         XSyncValue value;
+         Atom atom;
+
+         XSyncIntToValue (&value, 0);
+         
+         toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
+         
+         atom = gdk_x11_get_xatom_by_name_for_display (display,
+                                                       "_NET_WM_SYNC_REQUEST_COUNTER");
+         
+         XChangeProperty (xdisplay, GDK_WINDOW_XID (window),
+                          atom, XA_CARDINAL,
+                          32, PropModeReplace,
+                          (guchar *)&toplevel->update_counter, 1);
+         
+         XSyncIntToValue (&toplevel->current_counter_value, 0);
+       }
+    }
+#endif
+}
+
+static void
+setup_toplevel_window (GdkWindow *window, 
+                      GdkWindow *parent)
 {
   GdkWindowObject *obj = (GdkWindowObject *)window;
   GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
@@ -582,6 +638,8 @@ setup_toplevel_window (GdkWindow *window, GdkWindow *parent)
     gdk_x11_window_set_user_time (window, 0);
   else if (GDK_DISPLAY_X11 (screen_x11->display)->user_time != 0)
     gdk_x11_window_set_user_time (window, GDK_DISPLAY_X11 (screen_x11->display)->user_time);
+
+  ensure_sync_counter (window);
 }
 
 /**
@@ -782,6 +840,7 @@ gdk_window_new (GdkWindow     *parent,
        }
       
       private->bg_color.pixel = BlackPixel (xdisplay, screen_x11->screen_num);
+      private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
       xattributes.background_pixel = private->bg_color.pixel;
 
       private->bg_pixmap = NULL;
@@ -897,13 +956,16 @@ x_event_mask_to_gdk_event_mask (long mask)
  * @anid: a native window handle.
  * 
  * Wraps a native window in a #GdkWindow.
- * This may fail if the window has been destroyed.
+ * This may fail if the window has been destroyed. If the window
+ * was already known to GDK, a new reference to the existing 
+ * #GdkWindow is returned.
  *
  * For example in the X backend, a native window handle is an Xlib
  * <type>XID</type>.
  * 
- * Return value: the newly-created #GdkWindow wrapper for the 
- *    native window or %NULL if the window has been destroyed.
+ * Return value: a #GdkWindow wrapper for the native window or 
+ *   %NULL if the window has been destroyed. The wrapper will be
+ *   newly created, if one doesn't exist already.
  *
  * Since: 2.2
  **/
@@ -925,7 +987,10 @@ gdk_window_foreign_new_for_display (GdkDisplay     *display,
   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
 
   display_x11 = GDK_DISPLAY_X11 (display);
-  
+
+  if ((window = gdk_xid_table_lookup_for_display (display, anid)) != NULL)
+    return g_object_ref (window);
+
   gdk_error_trap_push ();
   result = XGetWindowAttributes (display_x11->xdisplay, anid, &attrs);
   if (gdk_error_trap_pop () || !result)
@@ -1020,7 +1085,8 @@ gdk_window_lookup (GdkNativeWindow anid)
 }
 
 static void
-gdk_toplevel_x11_free_contents (GdkToplevelX11 *toplevel)
+gdk_toplevel_x11_free_contents (GdkDisplay *display,
+                               GdkToplevelX11 *toplevel)
 {
   if (toplevel->icon_window)
     {
@@ -1042,6 +1108,16 @@ gdk_toplevel_x11_free_contents (GdkToplevelX11 *toplevel)
       g_object_unref (toplevel->group_leader);
       toplevel->group_leader = NULL;
     }
+#ifdef HAVE_XSYNC
+  if (toplevel->update_counter != None)
+    {
+      XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display), 
+                          toplevel->update_counter);
+      toplevel->update_counter = None;
+
+      XSyncIntToValue (&toplevel->current_counter_value, 0);
+    }
+#endif
 }
 
 void
@@ -1051,7 +1127,6 @@ _gdk_windowing_window_destroy (GdkWindow *window,
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
   GdkToplevelX11 *toplevel;
-  GdkDrawableImplX11 *draw_impl;
   
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -1062,12 +1137,9 @@ _gdk_windowing_window_destroy (GdkWindow *window,
 
   toplevel = _gdk_x11_window_get_toplevel (window);
   if (toplevel)
-    gdk_toplevel_x11_free_contents (toplevel);
+    gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
 
-  draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
-    
-  if (draw_impl->xft_draw)
-    XftDrawDestroy (draw_impl->xft_draw);
+  _gdk_x11_drawable_finish (private->impl);
 
   if (!recursing && !foreign_destroy)
     {
@@ -1122,7 +1194,7 @@ gdk_window_destroy_notify (GdkWindow *window)
 {
   GdkWindowImplX11 *window_impl;
 
-  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
   
   window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
 
@@ -1153,6 +1225,7 @@ update_wm_hints (GdkWindow *window,
   XWMHints wm_hints;
 
   if (!force &&
+      !toplevel->is_leader &&
       private->state & GDK_WINDOW_STATE_WITHDRAWN)
     return;
 
@@ -1192,6 +1265,9 @@ update_wm_hints (GdkWindow *window,
     }
   else
     wm_hints.window_group = GDK_DISPLAY_X11 (display)->leader_window;
+
+  if (toplevel->urgency_hint)
+    wm_hints.flags |= XUrgencyHint;
   
   XSetWMHints (GDK_WINDOW_XDISPLAY (window),
               GDK_WINDOW_XID (window),
@@ -1322,6 +1398,9 @@ show_window_internal (GdkWindow *window,
                       gboolean   raise)
 {
   GdkWindowObject *private;
+  GdkDisplay *display;
+  GdkDisplayX11 *display_x11;
+  GdkToplevelX11 *toplevel;
   
   g_return_if_fail (GDK_IS_WINDOW (window));
   
@@ -1346,6 +1425,18 @@ show_window_internal (GdkWindow *window,
       
       g_assert (GDK_WINDOW_IS_MAPPED (window));
 
+      if (WINDOW_IS_TOPLEVEL (window))
+       {
+         display = gdk_drawable_get_display (window);
+         display_x11 = GDK_DISPLAY_X11 (display);
+         toplevel = _gdk_x11_window_get_toplevel (window);
+
+          if (toplevel->user_time != 0 &&
+             display_x11->user_time != 0 &&
+             XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time))
+           gdk_x11_window_set_user_time (window, display_x11->user_time);
+       }
+
       if (impl->position_info.mapped)
        {
          gboolean unset_bg = !private->input_only &&
@@ -1475,7 +1566,7 @@ gdk_window_hide (GdkWindow *window)
 {
   GdkWindowObject *private;
   
-  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
 
   private = (GdkWindowObject*) window;
 
@@ -1536,7 +1627,7 @@ gdk_window_withdraw (GdkWindow *window)
 {
   GdkWindowObject *private;
   
-  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
   
   private = (GdkWindowObject*) window;
   if (!private->destroyed)
@@ -1580,7 +1671,6 @@ gdk_window_move (GdkWindow *window,
   GdkWindowObject *private = (GdkWindowObject *)window;
   GdkWindowImplX11 *impl;
 
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   impl = GDK_WINDOW_IMPL_X11 (private->impl);
@@ -1629,7 +1719,6 @@ gdk_window_resize (GdkWindow *window,
 {
   GdkWindowObject *private;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (width < 1)
@@ -1645,6 +1734,7 @@ gdk_window_resize (GdkWindow *window,
        {
          _gdk_window_move_resize_child (window, private->x, private->y,
                                         width, height);
+         _gdk_x11_drawable_update_size (private->impl);
        }
       else
        {
@@ -1658,6 +1748,7 @@ gdk_window_resize (GdkWindow *window,
            {
              impl->width = width;
              impl->height = height;
+             _gdk_x11_drawable_update_size (private->impl);
            }
          else
            {
@@ -1665,6 +1756,8 @@ gdk_window_resize (GdkWindow *window,
                private->resize_count += 1;
            }
        }
+
+      _gdk_x11_drawable_update_size (private->impl);
     }
 }
 
@@ -1690,7 +1783,6 @@ gdk_window_move_resize (GdkWindow *window,
 {
   GdkWindowObject *private;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (width < 1)
@@ -1705,6 +1797,7 @@ gdk_window_move_resize (GdkWindow *window,
       if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
        {
          _gdk_window_move_resize_child (window, x, y, width, height);
+         _gdk_x11_drawable_update_size (private->impl);
        }
       else
        {
@@ -1719,6 +1812,8 @@ gdk_window_move_resize (GdkWindow *window,
              private->y = y;
              impl->width = width;
              impl->height = height;
+
+             _gdk_x11_drawable_update_size (private->impl);
            }
          else
            {
@@ -1746,14 +1841,12 @@ gdk_window_reparent (GdkWindow *window,
                     gint       x,
                     gint       y)
 {
-  GdkDisplay *display;
   GdkWindowObject *window_private;
   GdkWindowObject *parent_private;
   GdkWindowObject *old_parent_private;
   GdkWindowImplX11 *impl;
   gboolean was_toplevel;
   
-  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);
@@ -1767,8 +1860,6 @@ gdk_window_reparent (GdkWindow *window,
   if (!new_parent)
     new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
 
-  display = GDK_WINDOW_DISPLAY (window);
-  
   window_private = (GdkWindowObject*) window;
   old_parent_private = (GdkWindowObject*)window_private->parent;
   parent_private = (GdkWindowObject*) new_parent;
@@ -1825,7 +1916,8 @@ gdk_window_reparent (GdkWindow *window,
                  _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
                }
                
-             gdk_toplevel_x11_free_contents (impl->toplevel);
+             gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), 
+                                             impl->toplevel);
              g_free (impl->toplevel);
              impl->toplevel = NULL;
            }
@@ -1851,7 +1943,6 @@ _gdk_windowing_window_clear_area (GdkWindow *window,
                                  gint       width,
                                  gint       height)
 {
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (!GDK_WINDOW_DESTROYED (window))
@@ -1866,7 +1957,6 @@ _gdk_windowing_window_clear_area_e (GdkWindow *window,
                                    gint       width,
                                    gint       height)
 {
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (!GDK_WINDOW_DESTROYED (window))
@@ -1891,7 +1981,6 @@ _gdk_windowing_window_clear_area_e (GdkWindow *window,
 void
 gdk_window_raise (GdkWindow *window)
 {
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (!GDK_WINDOW_DESTROYED (window))
@@ -1917,21 +2006,92 @@ gdk_window_raise (GdkWindow *window)
 void
 gdk_window_lower (GdkWindow *window)
 {
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (!GDK_WINDOW_DESTROYED (window))
     XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
 }
 
+/**
+ * gdk_x11_window_move_to_current_desktop:
+ * @window: a #GdkWindow
+ * 
+ * Moves the window to the correct workspace when running under a 
+ * window manager that supports multiple workspaces, as described
+ * in the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended 
+ * Window Manager Hints</ulink>.  Will not do anything if the
+ * window is already on all workspaces.
+ * 
+ * Since: 2.8
+ */
+void
+gdk_x11_window_move_to_current_desktop (GdkWindow *window)
+{
+  GdkToplevelX11 *toplevel;
+  toplevel = _gdk_x11_window_get_toplevel (window);
+
+  if (toplevel->on_all_desktops)
+    return;
+
+  if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
+                                          gdk_atom_intern_static_string ("_NET_WM_DESKTOP")))
+    {
+      XEvent xev;
+      Atom type;
+      gint format;
+      gulong nitems;
+      gulong bytes_after;
+      guchar *data;
+      gulong *current_desktop;
+      GdkDisplay *display;
+      
+      display = gdk_drawable_get_display (window);
+
+      /* Get current desktop, then set it; this is a race, but not
+       * one that matters much in practice.
+       */
+      XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), 
+                          GDK_WINDOW_XROOTWIN (window),
+                         gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
+                          0, G_MAXLONG,
+                          False, XA_CARDINAL, &type, &format, &nitems,
+                          &bytes_after, &data);
+
+      if (type == XA_CARDINAL)
+        {
+         current_desktop = (gulong *)data;
+         
+          xev.xclient.type = ClientMessage;
+          xev.xclient.serial = 0;
+          xev.xclient.send_event = True;
+          xev.xclient.window = GDK_WINDOW_XWINDOW (window);
+         xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
+          xev.xclient.format = 32;
+
+          xev.xclient.data.l[0] = *current_desktop;
+          xev.xclient.data.l[1] = 0;
+          xev.xclient.data.l[2] = 0;
+          xev.xclient.data.l[3] = 0;
+          xev.xclient.data.l[4] = 0;
+      
+          XSendEvent (GDK_DISPLAY_XDISPLAY (display), 
+                      GDK_WINDOW_XROOTWIN (window), 
+                      False,
+                      SubstructureRedirectMask | SubstructureNotifyMask,
+                      &xev);
+
+          XFree (current_desktop);
+        }
+    }
+}
+
 /**
  * gdk_window_focus:
  * @window: a #GdkWindow
  * @timestamp: timestamp of the event triggering the window focus
  *
- * Sets keyboard focus to @window. If @window is not onscreen this
- * will not work. In most cases, gtk_window_present() should be used on
- * a #GtkWindow, rather than calling this function.
+ * Sets keyboard focus to @window. In most cases, gtk_window_present() 
+ * should be used on a #GtkWindow, rather than calling this function.
  * 
  **/
 void
@@ -1948,7 +2108,7 @@ gdk_window_focus (GdkWindow *window,
   display = GDK_WINDOW_DISPLAY (window);
 
   if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
-                                          gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
+                                          gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
     {
       XEvent xev;
 
@@ -1959,9 +2119,9 @@ gdk_window_focus (GdkWindow *window,
       xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
                                                                        "_NET_ACTIVE_WINDOW");
       xev.xclient.format = 32;
-      xev.xclient.data.l[0] = 0;
-      xev.xclient.data.l[1] = 0;
-      xev.xclient.data.l[2] = 0;
+      xev.xclient.data.l[0] = 1; /* requestor type; we're an app */
+      xev.xclient.data.l[1] = timestamp;
+      xev.xclient.data.l[2] = None; /* currently active window */
       xev.xclient.data.l[3] = 0;
       xev.xclient.data.l[4] = 0;
       
@@ -2013,7 +2173,6 @@ gdk_window_set_hints (GdkWindow *window,
 {
   XSizeHints size_hints;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (GDK_WINDOW_DESTROYED (window))
@@ -2069,7 +2228,6 @@ gdk_window_set_type_hint (GdkWindow        *window,
   GdkDisplay *display;
   Atom atom;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (GDK_WINDOW_DESTROYED (window))
@@ -2114,6 +2272,69 @@ gdk_window_set_type_hint (GdkWindow        *window,
                   (guchar *)&atom, 1);
 }
 
+/**
+ * gdk_window_get_type_hint:
+ * @window: A toplevel #GdkWindow
+ *
+ * This function returns the type hint set for a window.
+ *
+ * Return value: The type hint set for @window
+ *
+ * Since: 2.10
+ **/
+GdkWindowTypeHint
+gdk_window_get_type_hint (GdkWindow *window)
+{
+  GdkDisplay *display;
+  GdkWindowTypeHint type;
+  Atom type_return;
+  gint format_return;
+  gulong nitems_return;
+  gulong bytes_after_return;
+  guchar *data = NULL;
+
+  g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return GDK_WINDOW_TYPE_HINT_NORMAL;
+
+  type = GDK_WINDOW_TYPE_HINT_NORMAL;
+
+  display = gdk_drawable_get_display (window);
+
+  if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+                          gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
+                          0, G_MAXLONG, False, XA_ATOM, &type_return,
+                          &format_return, &nitems_return, &bytes_after_return,
+                          &data) == Success)
+    {
+      if ((type_return == XA_ATOM) && (format_return == 32) &&
+          (data) && (nitems_return == 1))
+        {
+          Atom atom = (Atom) *data;
+
+          if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG"))
+            type = GDK_WINDOW_TYPE_HINT_DIALOG;
+          else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU"))
+            type = GDK_WINDOW_TYPE_HINT_MENU;
+          else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR"))
+            type = GDK_WINDOW_TYPE_HINT_TOOLBAR;
+          else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY"))
+            type = GDK_WINDOW_TYPE_HINT_UTILITY;
+          else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH"))
+            type = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN;
+          else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK"))
+            type = GDK_WINDOW_TYPE_HINT_DOCK;
+          else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
+            type = GDK_WINDOW_TYPE_HINT_DESKTOP;
+        }
+
+      if (type_return != None && data != NULL)
+        XFree (data);
+    }
+
+  return type;
+}
 
 static void
 gdk_wmspec_change_state (gboolean   add,
@@ -2148,7 +2369,7 @@ gdk_wmspec_change_state (gboolean   add,
 /**
  * gdk_window_set_modal_hint:
  * @window: A toplevel #GdkWindow
- * @modal: TRUE if the window is modal, FALSE otherwise.
+ * @modal: %TRUE if the window is modal, %FALSE otherwise.
  *
  * The application can use this hint to tell the window manager
  * that a certain window has modal behaviour. The window manager
@@ -2156,7 +2377,7 @@ gdk_wmspec_change_state (gboolean   add,
  * way.
  *
  * You should only use this on windows for which you have
- * previously called #gdk_window_set_transient_for()
+ * previously called gdk_window_set_transient_for()
  **/
 void
 gdk_window_set_modal_hint (GdkWindow *window,
@@ -2164,7 +2385,6 @@ gdk_window_set_modal_hint (GdkWindow *window,
 {
   GdkWindowObject *private;
 
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (GDK_WINDOW_DESTROYED (window))
@@ -2176,8 +2396,8 @@ gdk_window_set_modal_hint (GdkWindow *window,
 
   if (GDK_WINDOW_IS_MAPPED (window))
     gdk_wmspec_change_state (modal, window,
-                            gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE), 
-                            0);
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_MODAL"), 
+                            NULL);
 }
 
 /**
@@ -2188,9 +2408,9 @@ gdk_window_set_modal_hint (GdkWindow *window,
  * Toggles whether a window should appear in a task list or window
  * list. If a window's semantic type as specified with
  * gdk_window_set_type_hint() already fully describes the window, this
- * function should NOT be called in addition, instead you should allow
- * the window to be treated according to standard policy for its
- * semantic type.
+ * function should <emphasis>not</emphasis> be called in addition, 
+ * instead you should allow the window to be treated according to 
+ * standard policy for its semantic type.
  *
  * Since: 2.2
  **/
@@ -2200,7 +2420,6 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
 {
   GdkToplevelX11 *toplevel;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
   
@@ -2212,8 +2431,8 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
 
   if (GDK_WINDOW_IS_MAPPED (window))
     gdk_wmspec_change_state (skips_taskbar, window,
-                            gdk_atom_intern ("_NET_WM_STATE_SKIP_TASKBAR", FALSE), 
-                            0);
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_TASKBAR"), 
+                            NULL);
 }
 
 /**
@@ -2225,9 +2444,10 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
  * switcher, or other desktop utility program that displays a small
  * thumbnail representation of the windows on the desktop). If a
  * window's semantic type as specified with gdk_window_set_type_hint()
- * already fully describes the window, this function should NOT be
- * called in addition, instead you should allow the window to be
- * treated according to standard policy for its semantic type.
+ * already fully describes the window, this function should 
+ * <emphasis>not</emphasis> be called in addition, instead you should 
+ * allow the window to be treated according to standard policy for 
+ * its semantic type.
  *
  * Since: 2.2
  **/
@@ -2237,7 +2457,6 @@ gdk_window_set_skip_pager_hint (GdkWindow *window,
 {
   GdkToplevelX11 *toplevel;
     
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
   
@@ -2249,8 +2468,36 @@ gdk_window_set_skip_pager_hint (GdkWindow *window,
   
   if (GDK_WINDOW_IS_MAPPED (window))
     gdk_wmspec_change_state (skips_pager, window,
-                            gdk_atom_intern ("_NET_WM_STATE_SKIP_PAGER", FALSE), 
-                            0);
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_PAGER"), 
+                            NULL);
+}
+
+/**
+ * gdk_window_set_urgency_hint:
+ * @window: a toplevel #GdkWindow
+ * @urgent: %TRUE if the window is urgent
+ * 
+ * Toggles whether a window needs the user's
+ * urgent attention.
+ *
+ * Since: 2.8
+ **/
+void
+gdk_window_set_urgency_hint (GdkWindow *window,
+                            gboolean   urgent)
+{
+  GdkToplevelX11 *toplevel;
+    
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
+  
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  toplevel = _gdk_x11_window_get_toplevel (window);
+  toplevel->urgency_hint = urgent;
+  
+  update_wm_hints (window, FALSE);
 }
 
 /**
@@ -2272,7 +2519,7 @@ gdk_window_set_skip_pager_hint (GdkWindow *window,
  * gdk_window_move_resize().
  * 
  * Note that on X11, this effect has no effect on windows
- * of type GDK_WINDOW_TEMP or windows where override_redirect
+ * of type %GDK_WINDOW_TEMP or windows where override redirect
  * has been turned on via gdk_window_set_override_redirect()
  * since these windows are not resizable by the user.
  * 
@@ -2289,7 +2536,6 @@ gdk_window_set_geometry_hints (GdkWindow      *window,
 {
   XSizeHints size_hints;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (GDK_WINDOW_DESTROYED (window))
@@ -2471,7 +2717,7 @@ set_text_property (GdkDisplay  *display,
                   Atom         property,
                   const gchar *utf8_str)
 {
-  guchar *prop_text = NULL;
+  gchar *prop_text = NULL;
   Atom prop_type;
   gint prop_length;
   gint prop_format;
@@ -2491,7 +2737,7 @@ set_text_property (GdkDisplay  *display,
       
       gdk_utf8_to_compound_text_for_display (display,
                                             utf8_str, &gdk_type, &prop_format,
-                                            &prop_text, &prop_length);
+                                            (guchar **)&prop_text, &prop_length);
       prop_type = gdk_x11_atom_to_xatom_for_display (display, gdk_type);
       is_compound_text = TRUE;
     }
@@ -2502,11 +2748,11 @@ set_text_property (GdkDisplay  *display,
                       xwindow,
                       property,
                       prop_type, prop_format,
-                      PropModeReplace, prop_text,
+                      PropModeReplace, (guchar *)prop_text,
                       prop_length);
 
       if (is_compound_text)
-       gdk_free_compound_text (prop_text);
+       gdk_free_compound_text ((guchar *)prop_text);
       else
        g_free (prop_text);
     }
@@ -2522,7 +2768,7 @@ set_wm_name (GdkDisplay  *display,
   XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
                   gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"),
                   gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
-                  PropModeReplace, name, strlen (name));
+                  PropModeReplace, (guchar *)name, strlen (name));
   
   set_text_property (display, xwindow,
                     gdk_x11_get_xatom_by_name_for_display (display, "WM_NAME"),
@@ -2548,7 +2794,6 @@ gdk_window_set_title (GdkWindow   *window,
   Display *xdisplay;
   Window xwindow;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (title != NULL);
 
@@ -2566,7 +2811,7 @@ gdk_window_set_title (GdkWindow   *window,
       XChangeProperty (xdisplay, xwindow,
                       gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
                       gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
-                      PropModeReplace, title, strlen (title));
+                      PropModeReplace, (guchar *)title, strlen (title));
       
       set_text_property (display, xwindow,
                         gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
@@ -2599,7 +2844,6 @@ gdk_window_set_role (GdkWindow   *window,
 {
   GdkDisplay *display;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   display = gdk_drawable_get_display (window);
@@ -2609,7 +2853,7 @@ gdk_window_set_role (GdkWindow   *window,
       if (role)
        XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
                         gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
-                        XA_STRING, 8, PropModeReplace, role, strlen (role));
+                        XA_STRING, 8, PropModeReplace, (guchar *)role, strlen (role));
       else
        XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
                         gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
@@ -2634,15 +2878,8 @@ void
 gdk_window_set_transient_for (GdkWindow *window, 
                              GdkWindow *parent)
 {
-  GdkWindowObject *private;
-  GdkWindowObject *parent_private;
-  
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
-  private = (GdkWindowObject*) window;
-  parent_private = (GdkWindowObject*) parent;
-  
   if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
     XSetTransientForHint (GDK_WINDOW_XDISPLAY (window), 
                          GDK_WINDOW_XID (window),
@@ -2670,8 +2907,8 @@ gdk_window_set_background (GdkWindow      *window,
                           const GdkColor *color)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkColormap *colormap = gdk_drawable_get_colormap (window);
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (!GDK_WINDOW_DESTROYED (window))
@@ -2679,6 +2916,7 @@ gdk_window_set_background (GdkWindow      *window,
                          GDK_WINDOW_XID (window), color->pixel);
 
   private->bg_color = *color;
+  gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color);
 
   if (private->bg_pixmap &&
       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
@@ -2720,10 +2958,15 @@ gdk_window_set_back_pixmap (GdkWindow *window,
   GdkWindowObject *private = (GdkWindowObject *)window;
   Pixmap xpixmap;
   
-  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 (pixmap && !gdk_drawable_get_colormap (pixmap))
+    {
+      g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
+      return;
+    }
   
   if (private->bg_pixmap &&
       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
@@ -2772,23 +3015,54 @@ void
 gdk_window_set_cursor (GdkWindow *window,
                       GdkCursor *cursor)
 {
+  GdkWindowObject *private;
+  GdkWindowImplX11 *impl;
   GdkCursorPrivate *cursor_private;
   Cursor xcursor;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
-  
+    
+  private = (GdkWindowObject *)window;
+  impl = GDK_WINDOW_IMPL_X11 (private->impl);
   cursor_private = (GdkCursorPrivate*) cursor;
-  
+
+  if (impl->cursor)
+    {
+      gdk_cursor_unref (impl->cursor);
+      impl->cursor = NULL;
+    }
+
   if (!cursor)
     xcursor = None;
   else
-    xcursor = cursor_private->xcursor;
+    {
+      _gdk_x11_cursor_update_theme (cursor);
+      xcursor = cursor_private->xcursor;
+    }
   
   if (!GDK_WINDOW_DESTROYED (window))
-    XDefineCursor (GDK_WINDOW_XDISPLAY (window),
-                  GDK_WINDOW_XID (window),
-                  xcursor);
+    {
+      XDefineCursor (GDK_WINDOW_XDISPLAY (window),
+                    GDK_WINDOW_XID (window),
+                    xcursor);
+      
+      if (cursor)
+       impl->cursor = gdk_cursor_ref (cursor);
+    }
+}
+
+GdkCursor *
+_gdk_x11_window_get_cursor (GdkWindow *window)
+{
+  GdkWindowObject *private;
+  GdkWindowImplX11 *impl;
+  
+  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+    
+  private = (GdkWindowObject *)window;
+  impl = GDK_WINDOW_IMPL_X11 (private->impl);
+
+  return impl->cursor;
 }
 
 /**
@@ -2814,6 +3088,14 @@ gdk_window_set_cursor (GdkWindow *window,
  * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
  * position from the most recent configure event.
  * 
+ * <note>
+ * If @window is not a toplevel, it is <emphasis>much</emphasis> better 
+ * to call gdk_window_get_position() and gdk_drawable_get_size() instead, 
+ * because it avoids the roundtrip to the X server and because 
+ * gdk_drawable_get_size() supports the full 32-bit coordinate space,
+ * whereas gdk_window_get_geometry() is restricted to the 16-bit
+ * coordinates of X11.
+ *</note>
  **/
 void
 gdk_window_get_geometry (GdkWindow *window,
@@ -2882,7 +3164,7 @@ gdk_window_get_origin (GdkWindow *window,
   gint tx = 0;
   gint ty = 0;
   
-  g_return_val_if_fail (window != NULL, 0);
+  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
   
   if (!GDK_WINDOW_DESTROYED (window))
     {
@@ -2933,7 +3215,6 @@ gdk_window_get_deskrelative_origin (GdkWindow *window,
   gulong number_return, bytes_after_return;
   guchar *data_return;
   
-  g_return_val_if_fail (window != NULL, FALSE);
   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
   
   if (!GDK_WINDOW_DESTROYED (window))
@@ -3026,12 +3307,23 @@ void
 gdk_window_get_frame_extents (GdkWindow    *window,
                               GdkRectangle *rect)
 {
+  GdkDisplay *display;
   GdkWindowObject *private;
   Window xwindow;
   Window xparent;
   Window root;
   Window *children;
-  unsigned int nchildren;
+  guchar *data;
+  Window *vroots;
+  Atom type_return;
+  guint nchildren;
+  guint nvroots;
+  gulong nitems_return;
+  gulong bytes_after_return;
+  gint format_return;
+  gint i;
+  guint ww, wh, wb, wd;
+  gint wx, wy;
   
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (rect != NULL);
@@ -3059,35 +3351,67 @@ gdk_window_get_frame_extents (GdkWindow    *window,
 
   gdk_error_trap_push();
   
+  /* use NETWM_VIRTUAL_ROOTS if available */
+  display = gdk_drawable_get_display (window);
+  root = GDK_WINDOW_XROOTWIN (window);
+
+  nvroots = 0;
+  vroots = NULL;
+
+  if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), root,
+                         gdk_x11_get_xatom_by_name_for_display (display, 
+                                                                "_NET_VIRTUAL_ROOTS"),
+                         0, G_MAXLONG, False, XA_WINDOW, &type_return,
+                         &format_return, &nitems_return, &bytes_after_return,
+                         &data)
+      == Success)
+    {
+      if ((type_return == XA_WINDOW) && (format_return == 32) && (data))
+       {
+         nvroots = nitems_return;
+         vroots = (Window *)data;
+       }
+    }
+
   xparent = GDK_WINDOW_XID (window);
+
   do
     {
       xwindow = xparent;
-      if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
+
+      if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xwindow,
                       &root, &xparent,
                       &children, &nchildren))
        goto fail;
       
       if (children)
        XFree (children);
+
+      /* check virtual roots */
+      for (i = 0; i < nvroots; i++)
+       {
+         if (xparent == vroots[i])
+           {
+             root = xparent;
+             break;
+           }
+       }
     }
   while (xparent != root);
   
-  if (xparent == root)
+  if (XGetGeometry (GDK_DISPLAY_XDISPLAY (display), xwindow, 
+                   &root, &wx, &wy, &ww, &wh, &wb, &wd))
     {
-      unsigned int ww, wh, wb, wd;
-      int wx, wy;
-      
-      if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
-       {
-          rect->x = wx;
-          rect->y = wy;
-          rect->width = ww;
-          rect->height = wh;
-       }
+      rect->x = wx;
+      rect->y = wy;
+      rect->width = ww;
+      rect->height = wh;
     }
 
  fail:
+  if (vroots)
+    XFree (vroots);
+
   gdk_error_trap_pop ();
 }
 
@@ -3163,6 +3487,42 @@ _gdk_windowing_window_get_pointer (GdkDisplay      *display,
   return return_val;
 }
 
+/**
+ * gdk_display_warp_pointer:
+ * @display: a #GdkDisplay
+ * @screen: the screen of @display to warp the pointer to
+ * @x: the x coordinate of the destination
+ * @y: the y coordinate of the destination
+ * 
+ * Warps the pointer of @display to the point @x,@y on 
+ * the screen @screen, unless the pointer is confined
+ * to a window by a grab, in which case it will be moved
+ * as far as allowed by the grab. Warping the pointer 
+ * creates events as if the user had moved the mouse 
+ * instantaneously to the destination.
+ * 
+ * Note that the pointer should normally be under the
+ * control of the user. This function was added to cover
+ * some rare use cases like keyboard navigation support
+ * for the color picker in the #GtkColorSelectionDialog.
+ *
+ * Since: 2.8
+ */ 
+void
+gdk_display_warp_pointer (GdkDisplay *display,
+                         GdkScreen  *screen,
+                         gint        x,
+                         gint        y)
+{
+  Display *xdisplay;
+  Window dest;
+
+  xdisplay = GDK_DISPLAY_XDISPLAY (display);
+  dest = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
+
+  XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);  
+}
+
 GdkWindow*
 _gdk_windowing_window_at_pointer (GdkDisplay *display,
                                   gint       *win_x,
@@ -3228,7 +3588,6 @@ gdk_window_get_events (GdkWindow *window)
   XWindowAttributes attrs;
   GdkEventMask event_mask;
   
-  g_return_val_if_fail (window != NULL, 0);
   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -3264,7 +3623,6 @@ gdk_window_set_events (GdkWindow       *window,
   long xevent_mask;
   int i;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   if (!GDK_WINDOW_DESTROYED (window))
@@ -3291,7 +3649,6 @@ gdk_window_add_colormap_windows (GdkWindow *window)
   Window *new_windows;
   int i, count;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -3328,19 +3685,6 @@ gdk_window_add_colormap_windows (GdkWindow *window)
     XFree (old_windows);
 }
 
-static gboolean
-gdk_window_have_shape_ext (GdkDisplay *display)
-{
-#ifdef HAVE_SHAPE_EXT
-  int ignore;
-
-  return XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display),
-                              &ignore, &ignore);
-#else
-  return 0;
-#endif  
-}
-
 #define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
 
 /*
@@ -3348,39 +3692,17 @@ gdk_window_have_shape_ext (GdkDisplay *display)
  * If not available, shaped windows will look
  * ugly, but programs still work.    Stefan Wille
  */
-/**
- * gdk_window_shape_combine_mask:
- * @window: a #GdkWindow
- * @mask: shape mask
- * @x: X position of shape mask with respect to @window
- * @y: Y position of shape mask with respect to @window
- *
- * Applies a shape mask to @window. Pixels in @window corresponding to
- * set bits in the @mask will be visible; pixels in @window
- * corresponding to unset bits in the @mask will be transparent. This
- * gives a non-rectangular window.
- *
- * If @mask is %NULL, the shape mask will be unset, and the @x/@y
- * parameters are not used.
- *
- * On the X11 platform, this uses an X server extension which is
- * widely available on most common platforms, but not available on
- * very old X servers, and occasionally the implementation will be
- * buggy. On servers without the shape extension, this function
- * will do nothing.
- *
- * This function works on both toplevel and child windows.
- * 
- **/
-void
-gdk_window_shape_combine_mask (GdkWindow *window,
-                              GdkBitmap *mask,
-                              gint x, gint y)
+static void
+do_shape_combine_mask (GdkWindow *window,
+                      GdkBitmap *mask,
+                      gint       x, 
+                      gint       y,
+                      gint       shape)
 {
+  GdkWindowObject *private = (GdkWindowObject *)window;
   Pixmap pixmap;
   gint xoffset, yoffset;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
 #ifdef HAVE_SHAPE_EXT
@@ -3395,22 +3717,28 @@ gdk_window_shape_combine_mask (GdkWindow *window,
       return;
     }
   
-  if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+  if (shape == ShapeBounding
+      ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
+      : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
     {
       if (mask)
        {
          pixmap = GDK_PIXMAP_XID (mask);
+         
+         private->shaped = (shape == ShapeBounding);
        }
       else
        {
          x = 0;
          y = 0;
          pixmap = None;
+
+         private->shaped = FALSE;
        }
       
       XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
                         GDK_WINDOW_XID (window),
-                        ShapeBounding,
+                        shape,
                         x, y,
                         pixmap,
                         ShapeSet);
@@ -3419,20 +3747,20 @@ gdk_window_shape_combine_mask (GdkWindow *window,
 }
 
 /**
- * gdk_window_shape_combine_region:
+ * gdk_window_shape_combine_mask:
  * @window: a #GdkWindow
- * @shape_region: region of window to be non-transparent
- * @offset_x: X position of @shape_region in @window coordinates
- * @offset_y: Y position of @shape_region in @window coordinates
+ * @mask: shape mask
+ * @x: X position of shape mask with respect to @window
+ * @y: Y position of shape mask with respect to @window
  *
- * Makes pixels in @window outside @shape_region be transparent,
- * so that the window may be nonrectangular. See also
- * gdk_window_shape_combine_mask() to use a bitmap as the mask.
+ * Applies a shape mask to @window. Pixels in @window corresponding to
+ * set bits in the @mask will be visible; pixels in @window
+ * corresponding to unset bits in the @mask will be transparent. This
+ * gives a non-rectangular window.
+ *
+ * If @mask is %NULL, the shape mask will be unset, and the @x/@y
+ * parameters are not used.
  *
- * If @shape_region is %NULL, the shape will be unset, so the whole
- * window will be opaque again. @offset_x and @offset_y are ignored
- * if @shape_region is %NULL.
- * 
  * On the X11 platform, this uses an X server extension which is
  * widely available on most common platforms, but not available on
  * very old X servers, and occasionally the implementation will be
@@ -3443,11 +3771,57 @@ gdk_window_shape_combine_mask (GdkWindow *window,
  * 
  **/
 void
-gdk_window_shape_combine_region (GdkWindow *window,
-                                 GdkRegion *shape_region,
-                                 gint       offset_x,
-                                 gint       offset_y)
+gdk_window_shape_combine_mask (GdkWindow *window,
+                              GdkBitmap *mask,
+                              gint       x, 
+                              gint       y)
 {
+  do_shape_combine_mask (window, mask, x, y, ShapeBounding);
+}
+
+/**
+ * gdk_window_input_shape_combine_mask:
+ * @window: a #GdkWindow
+ * @mask: shape mask
+ * @x: X position of shape mask with respect to @window
+ * @y: Y position of shape mask with respect to @window
+ * 
+ * Like gdk_window_shape_combine_mask(), but the shape applies
+ * only to event handling. Mouse events which happen while
+ * the pointer position corresponds to an unset bit in the 
+ * mask will be passed on the window below @window.
+ *
+ * An input shape is typically used with RGBA windows.
+ * The alpha channel of the window defines which pixels are 
+ * invisible and allows for nicely antialiased borders,
+ * and the input shape controls where the window is
+ * "clickable".
+ *
+ * On the X11 platform, this requires version 1.1 of the
+ * shape extension.
+ *
+ * Since: 2.10
+ */
+void 
+gdk_window_input_shape_combine_mask (GdkWindow *window,
+                                    GdkBitmap *mask,
+                                    gint       x,
+                                    gint       y)
+{
+#ifdef ShapeInput
+  do_shape_combine_mask (window, mask, x, y, ShapeInput);
+#endif
+}
+
+
+static void
+do_shape_combine_region (GdkWindow *window,
+                        GdkRegion *shape_region,
+                        gint       offset_x,
+                        gint       offset_y,
+                        gint       shape)
+{
+  GdkWindowObject *private = (GdkWindowObject *)window;
   gint xoffset, yoffset;
   
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -3471,18 +3845,22 @@ gdk_window_shape_combine_region (GdkWindow *window,
       return;
     }
   
-  if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+  if (shape == ShapeBounding
+      ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
+      : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
     {
       gint n_rects = 0;
       XRectangle *xrects = NULL;
 
+      private->shaped = shape == ShapeBounding;
+
       _gdk_region_get_xrectangles (shape_region,
                                    0, 0,
                                    &xrects, &n_rects);
       
       XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
                                GDK_WINDOW_XID (window),
-                               ShapeBounding,
+                               shape,
                                offset_x, offset_y,
                                xrects, n_rects,
                                ShapeSet,
@@ -3493,6 +3871,73 @@ gdk_window_shape_combine_region (GdkWindow *window,
 #endif /* HAVE_SHAPE_EXT */
 }
 
+/**
+ * gdk_window_shape_combine_region:
+ * @window: a #GdkWindow
+ * @shape_region: region of window to be non-transparent
+ * @offset_x: X position of @shape_region in @window coordinates
+ * @offset_y: Y position of @shape_region in @window coordinates
+ *
+ * Makes pixels in @window outside @shape_region be transparent,
+ * so that the window may be nonrectangular. See also
+ * gdk_window_shape_combine_mask() to use a bitmap as the mask.
+ *
+ * If @shape_region is %NULL, the shape will be unset, so the whole
+ * window will be opaque again. @offset_x and @offset_y are ignored
+ * if @shape_region is %NULL.
+ * 
+ * On the X11 platform, this uses an X server extension which is
+ * widely available on most common platforms, but not available on
+ * very old X servers, and occasionally the implementation will be
+ * buggy. On servers without the shape extension, this function
+ * will do nothing.
+ *
+ * This function works on both toplevel and child windows.
+ * 
+ **/
+void
+gdk_window_shape_combine_region (GdkWindow *window,
+                                 GdkRegion *shape_region,
+                                 gint       offset_x,
+                                 gint       offset_y)
+{ 
+  do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeBounding);
+}
+
+/**
+ * gdk_window_input_shape_combine_region:
+ * @window: a #GdkWindow
+ * @shape_region: region of window to be non-transparent
+ * @offset_x: X position of @shape_region in @window coordinates
+ * @offset_y: Y position of @shape_region in @window coordinates
+ * 
+ * Like gdk_window_shape_combine_region(), but the shape applies
+ * only to event handling. Mouse events which happen while
+ * the pointer position corresponds to an unset bit in the 
+ * mask will be passed on the window below @window.
+ *
+ * An input shape is typically used with RGBA windows.
+ * The alpha channel of the window defines which pixels are 
+ * invisible and allows for nicely antialiased borders,
+ * and the input shape controls where the window is
+ * "clickable".
+ *
+ * On the X11 platform, this requires version 1.1 of the
+ * shape extension.
+ *
+ * Since: 2.10
+ */
+void 
+gdk_window_input_shape_combine_region (GdkWindow *window,
+                                      GdkRegion *shape_region,
+                                      gint       offset_x,
+                                      gint       offset_y)
+{
+#ifdef ShapeInput
+  do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeInput);
+#endif
+}
+
 
 /**
  * gdk_window_set_override_redirect:
@@ -3515,7 +3960,6 @@ gdk_window_set_override_redirect (GdkWindow *window,
 {
   XSetWindowAttributes attr;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (!GDK_WINDOW_DESTROYED (window))
@@ -3551,7 +3995,7 @@ 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;  
@@ -3588,7 +4032,7 @@ 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;  
@@ -3630,9 +4074,9 @@ gdk_x11_window_set_user_time (GdkWindow *window,
 {
   GdkDisplay *display;
   GdkDisplayX11 *display_x11;
+  GdkToplevelX11 *toplevel;
   glong timestamp_long = (glong)timestamp;
 
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -3640,6 +4084,7 @@ gdk_x11_window_set_user_time (GdkWindow *window,
 
   display = gdk_drawable_get_display (window);
   display_x11 = GDK_DISPLAY_X11 (display);
+  toplevel = _gdk_x11_window_get_toplevel (window);
 
   XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
                    gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
@@ -3648,8 +4093,16 @@ gdk_x11_window_set_user_time (GdkWindow *window,
 
   if (timestamp_long != GDK_CURRENT_TIME)
     display_x11->user_time = timestamp_long;
+
+  toplevel->user_time = timestamp_long;
 }
 
+#define GDK_SELECTION_MAX_SIZE(display)                                 \
+  MIN(262144,                                                           \
+      XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0     \
+       ? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100         \
+       : XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
+
 /**
  * gdk_window_set_icon_list:
  * @window: The #GdkWindow toplevel window to set the icon of.
@@ -3678,6 +4131,7 @@ gdk_window_set_icon_list (GdkWindow *window,
   gint x, y;
   gint n_channels;
   GdkDisplay *display;
+  gint n;
   
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -3688,7 +4142,7 @@ gdk_window_set_icon_list (GdkWindow *window,
   
   l = pixbufs;
   size = 0;
-  
+  n = 0;
   while (l)
     {
       pixbuf = l->data;
@@ -3697,8 +4151,16 @@ gdk_window_set_icon_list (GdkWindow *window,
       width = gdk_pixbuf_get_width (pixbuf);
       height = gdk_pixbuf_get_height (pixbuf);
       
+      /* silently ignore overlarge icons */
+      if (size + 2 + width * height > GDK_SELECTION_MAX_SIZE(display))
+       {
+         g_warning ("gdk_window_set_icon_list: icons too large");
+         break;
+       }
+     
+      n++;
       size += 2 + width * height;
-
+      
       l = g_list_next (l);
     }
 
@@ -3706,7 +4168,7 @@ gdk_window_set_icon_list (GdkWindow *window,
 
   l = pixbufs;
   p = data;
-  while (l)
+  while (l && n > 0)
     {
       pixbuf = l->data;
       
@@ -3739,6 +4201,7 @@ gdk_window_set_icon_list (GdkWindow *window,
        }
 
       l = g_list_next (l);
+      n--;
     }
 
   if (size > 0)
@@ -3782,7 +4245,6 @@ gdk_window_set_icon (GdkWindow *window,
 {
   GdkToplevelX11 *toplevel;
 
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
   
@@ -3843,7 +4305,6 @@ gdk_window_set_icon_name (GdkWindow   *window,
 {
   GdkDisplay *display;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -3858,7 +4319,7 @@ gdk_window_set_icon_name (GdkWindow   *window,
                   GDK_WINDOW_XID (window),
                   gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
                   gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
-                  PropModeReplace, name, strlen (name));
+                  PropModeReplace, (guchar *)name, strlen (name));
   
   set_text_property (display, GDK_WINDOW_XID (window),
                     gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
@@ -3879,16 +4340,11 @@ gdk_window_set_icon_name (GdkWindow   *window,
 void
 gdk_window_iconify (GdkWindow *window)
 {
-  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;
-
   if (GDK_WINDOW_IS_MAPPED (window))
     {  
       XIconifyWindow (GDK_WINDOW_XDISPLAY (window),
@@ -3918,16 +4374,11 @@ gdk_window_iconify (GdkWindow *window)
 void
 gdk_window_deiconify (GdkWindow *window)
 {
-  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;
-
   if (GDK_WINDOW_IS_MAPPED (window))
     {  
       gdk_window_show (window);
@@ -3974,8 +4425,8 @@ gdk_window_stick (GdkWindow *window)
 
       /* Request stick during viewport scroll */
       gdk_wmspec_change_state (TRUE, window,
-                              gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
-                              0);
+                              gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
+                              NULL);
 
       /* Request desktop 0xFFFFFFFF */
       xev.xclient.type = ClientMessage;
@@ -4029,13 +4480,14 @@ gdk_window_unstick (GdkWindow *window)
       gint format;
       gulong nitems;
       gulong bytes_after;
+      guchar *data;
       gulong *current_desktop;
       GdkDisplay *display = gdk_drawable_get_display (window);
       
       /* Request unstick from viewport */
       gdk_wmspec_change_state (FALSE, window,
-                              gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
-                              0);
+                              gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
+                              NULL);
 
       /* Get current desktop, then set it; this is a race, but not
        * one that matters much in practice.
@@ -4044,10 +4496,12 @@ gdk_window_unstick (GdkWindow *window)
                          gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
                           0, G_MAXLONG,
                           False, XA_CARDINAL, &type, &format, &nitems,
-                          &bytes_after, (guchar **)&current_desktop);
+                          &bytes_after, &data);
 
       if (type == XA_CARDINAL)
         {
+         current_desktop = (gulong *)data;
+         
           xev.xclient.type = ClientMessage;
           xev.xclient.serial = 0;
           xev.xclient.send_event = True;
@@ -4105,8 +4559,8 @@ gdk_window_maximize (GdkWindow *window)
 
   if (GDK_WINDOW_IS_MAPPED (window))
     gdk_wmspec_change_state (TRUE, window,
-                            gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
-                            gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
   else
     gdk_synthesize_window_state (window,
                                 0,
@@ -4140,8 +4594,8 @@ gdk_window_unmaximize (GdkWindow *window)
 
   if (GDK_WINDOW_IS_MAPPED (window))
     gdk_wmspec_change_state (FALSE, window,
-                            gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
-                            gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
   else
     gdk_synthesize_window_state (window,
                                 GDK_WINDOW_STATE_MAXIMIZED,
@@ -4178,7 +4632,7 @@ gdk_window_fullscreen (GdkWindow *window)
 
   if (GDK_WINDOW_IS_MAPPED (window))
     gdk_wmspec_change_state (TRUE, window,
-                            gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE),
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
                              GDK_NONE);
 
   else
@@ -4214,7 +4668,7 @@ gdk_window_unfullscreen (GdkWindow *window)
 
   if (GDK_WINDOW_IS_MAPPED (window))
     gdk_wmspec_change_state (FALSE, window,
-                            gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE),
+                            gdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
                              GDK_NONE);
 
   else
@@ -4249,10 +4703,15 @@ gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
     return;
 
   if (GDK_WINDOW_IS_MAPPED (window))
-    gdk_wmspec_change_state (setting, window,
-                            gdk_atom_intern ("_NET_WM_STATE_ABOVE", setting),
-                            setting ? gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE)
-                               : GDK_NONE);
+    {
+      if (setting)
+       gdk_wmspec_change_state (FALSE, window,
+                                gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
+                                GDK_NONE);
+      gdk_wmspec_change_state (setting, window,
+                              gdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
+                              GDK_NONE);
+    }
   else
     gdk_synthesize_window_state (window,
                                 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
@@ -4285,10 +4744,15 @@ gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
     return;
 
   if (GDK_WINDOW_IS_MAPPED (window))
-    gdk_wmspec_change_state (setting, window,
-                            gdk_atom_intern ("_NET_WM_STATE_BELOW", setting),
-                            setting ? gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE)
-                                : GDK_NONE);
+    {
+      if (setting)
+       gdk_wmspec_change_state (FALSE, window,
+                                gdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
+                                GDK_NONE);
+      gdk_wmspec_change_state (setting, window,
+                              gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
+                              GDK_NONE);
+    }
   else
     gdk_synthesize_window_state (window,
                                 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
@@ -4310,7 +4774,6 @@ gdk_window_get_group (GdkWindow *window)
 {
   GdkToplevelX11 *toplevel;
   
-  g_return_val_if_fail (window != NULL, NULL);
   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
   g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
 
@@ -4344,7 +4807,6 @@ gdk_window_set_group (GdkWindow *window,
 {
   GdkToplevelX11 *toplevel;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
   g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
@@ -4362,6 +4824,7 @@ gdk_window_set_group (GdkWindow *window,
       if (toplevel->group_leader)
        g_object_unref (toplevel->group_leader);
       toplevel->group_leader = g_object_ref (leader);
+      (_gdk_x11_window_get_toplevel (leader))->is_leader = TRUE;      
     }
 
   update_wm_hints (window, FALSE);
@@ -4372,7 +4835,7 @@ gdk_window_get_mwm_hints (GdkWindow *window)
 {
   GdkDisplay *display;
   Atom hints_atom = None;
-  MotifWmHints *hints;
+  guchar *data;
   Atom type;
   gint format;
   gulong nitems;
@@ -4388,12 +4851,12 @@ gdk_window_get_mwm_hints (GdkWindow *window)
   XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
                      hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
                      False, AnyPropertyType, &type, &format, &nitems,
-                     &bytes_after, (guchar **)&hints);
+                     &bytes_after, &data);
 
   if (type == None)
     return NULL;
   
-  return hints;
+  return (MotifWmHints *)data;
 }
 
 static void
@@ -4402,6 +4865,7 @@ gdk_window_set_mwm_hints (GdkWindow *window,
 {
   GdkDisplay *display;
   Atom hints_atom = None;
+  guchar *data;
   MotifWmHints *hints;
   Atom type;
   gint format;
@@ -4418,12 +4882,14 @@ gdk_window_set_mwm_hints (GdkWindow *window,
   XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
                      hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
                      False, AnyPropertyType, &type, &format, &nitems,
-                     &bytes_after, (guchar **)&hints);
+                     &bytes_after, &data);
   
   if (type == None)
     hints = new_hints;
   else
     {
+      hints = (MotifWmHints *)data;
+       
       if (new_hints->flags & MWM_HINTS_FUNCTIONS)
        {
          hints->flags |= MWM_HINTS_FUNCTIONS;
@@ -4471,7 +4937,6 @@ gdk_window_set_decorations (GdkWindow      *window,
 {
   MotifWmHints hints;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   hints.flags = MWM_HINTS_DECORATIONS;
@@ -4538,7 +5003,6 @@ gdk_window_set_functions (GdkWindow    *window,
 {
   MotifWmHints hints;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
   hints.flags = MWM_HINTS_FUNCTIONS;
@@ -4736,7 +5200,8 @@ gdk_add_rectangles (Display           *disp,
 static void
 gdk_propagate_shapes (Display *disp,
                      Window   win,
-                     gboolean merge)
+                     gboolean merge,
+                     int      shape)
 {
   Window              rt, par, *list = NULL;
   gint                i, j, num = 0, num_rects = 0;
@@ -4841,7 +5306,7 @@ gdk_propagate_shapes (Display *disp,
       /* set the rects as the shape mask */
       if (rects)
        {
-         XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
+         XShapeCombineRectangles (disp, win, shape, 0, 0, rects, num_rects,
                                   ShapeSet, YXSorted);
          g_free (rects);
        }
@@ -4875,14 +5340,14 @@ gdk_propagate_shapes (Display *disp,
 void
 gdk_window_set_child_shapes (GdkWindow *window)
 {
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
+  
 #ifdef HAVE_SHAPE_EXT
   if (!GDK_WINDOW_DESTROYED (window) &&
-      gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+      gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
     gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
-                         GDK_WINDOW_XID (window), FALSE);
+                         GDK_WINDOW_XID (window), FALSE, ShapeBounding);
 #endif   
 }
 
@@ -4898,22 +5363,77 @@ gdk_window_set_child_shapes (GdkWindow *window)
  * This function is distinct from gdk_window_set_child_shapes()
  * because it includes @window's shape mask in the set of shapes to
  * be merged.
- * 
  **/
 void
 gdk_window_merge_child_shapes (GdkWindow *window)
 {
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
   
 #ifdef HAVE_SHAPE_EXT
   if (!GDK_WINDOW_DESTROYED (window) &&
-      gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+      gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
+    gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
+                         GDK_WINDOW_XID (window), TRUE, ShapeBounding);
+#endif   
+}
+
+/**
+ * gdk_window_set_child_input_shapes:
+ * @window: a #GdkWindow
+ * 
+ * Sets the input shape mask of @window to the union of input shape masks
+ * for all children of @window, ignoring the input shape mask of @window
+ * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
+ * the input shape mask of @window in the masks to be merged.
+ *
+ * Since: 2.10
+ **/
+void 
+gdk_window_set_child_input_shapes (GdkWindow *window)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+#ifdef HAVE_SHAPE_EXT
+#ifdef ShapeInput
+  if (!GDK_WINDOW_DESTROYED (window) &&
+      gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
+    gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
+                         GDK_WINDOW_XID (window), FALSE, ShapeInput);
+#endif
+#endif   
+}
+
+/**
+ * gdk_window_merge_child_input_shapes:
+ * @window: a #GdkWindow
+ * 
+ * Merges the input shape masks for any child windows into the
+ * input shape mask for @window. i.e. the union of all input masks
+ * for @window and its children will become the new input mask
+ * for @window. See gdk_window_input_shape_combine_mask().
+ *
+ * This function is distinct from gdk_window_set_child_input_shapes()
+ * because it includes @window's input shape mask in the set of 
+ * shapes to be merged.
+ *
+ * Since: 2.10
+ **/
+void 
+gdk_window_merge_child_input_shapes (GdkWindow *window)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+#ifdef HAVE_SHAPE_EXT
+#ifdef ShapeInput
+  if (!GDK_WINDOW_DESTROYED (window) &&
+      gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
     gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
-                         GDK_WINDOW_XID (window), TRUE);
+                         GDK_WINDOW_XID (window), TRUE, ShapeInput);
+#endif
 #endif   
 }
 
+
 static void
 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
 {
@@ -4921,7 +5441,7 @@ gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
   GdkWindowObject *private;
   guint xattributes_mask = 0;
   
-  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
 
   private = GDK_WINDOW_OBJECT (window);
   if (private->input_only)
@@ -4940,7 +5460,7 @@ gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
 {
   XSetWindowAttributes xattributes;
   
-  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
   
   xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
   
@@ -4968,7 +5488,6 @@ gdk_window_set_static_gravities (GdkWindow *window,
   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);
 
   if (!use_static == !private->guffaw_gravity)
@@ -5226,6 +5745,7 @@ finish_drag (MoveResizeData *mv_resize)
 {
   gdk_window_destroy (mv_resize->moveresize_emulation_window);
   mv_resize->moveresize_emulation_window = NULL;
+  g_object_unref (mv_resize->moveresize_window);
   mv_resize->moveresize_window = NULL;
 
   if (mv_resize->moveresize_pending_event)
@@ -5405,8 +5925,7 @@ create_moveresize_window (MoveResizeData *mv_resize,
       /* If this fails, some other client has grabbed the window
        * already.
        */
-      gdk_window_destroy (mv_resize->moveresize_emulation_window);
-      mv_resize->moveresize_emulation_window = NULL;
+      finish_drag (mv_resize);
     }
 
   mv_resize->moveresize_process_time = 0;
@@ -5548,9 +6067,8 @@ emulate_move_drag (GdkWindow     *window,
  * Begins a window resize operation (for a toplevel window).
  * You might use this function to implement a "window resize grip," for
  * example; in fact #GtkStatusbar uses it. The function works best
- * with window managers that support the Extended Window Manager Hints spec
- * (see http://www.freedesktop.org), but has a fallback implementation
- * for other window managers.
+ * with window managers that support the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended Window Manager Hints</ulink>, but has a 
+ * fallback implementation for other window managers.
  * 
  **/
 void
@@ -5567,7 +6085,7 @@ gdk_window_begin_resize_drag (GdkWindow     *window,
     return;
 
   if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
-                                          gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
+                                          gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
     wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
   else
     emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
@@ -5584,8 +6102,8 @@ gdk_window_begin_resize_drag (GdkWindow     *window,
  * Begins a window move operation (for a toplevel window).  You might
  * use this function to implement a "window move grip," for
  * example. The function works best with window managers that support
- * the Extended Window Manager Hints spec (see
- * http://www.freedesktop.org), but has a fallback implementation for
+ * the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended 
+ * Window Manager Hints</ulink>, but has a fallback implementation for
  * other window managers.
  * 
  **/
@@ -5602,9 +6120,92 @@ gdk_window_begin_move_drag (GdkWindow *window,
     return;
 
   if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
-                                          gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
+                                          gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
     wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, root_x, root_y,
                       timestamp);
   else
     emulate_move_drag (window, button, root_x, root_y, timestamp);
 }
+
+/**
+ * gdk_window_enable_synchronized_configure:
+ * @window: a toplevel #GdkWindow
+ * 
+ * Indicates that the application will cooperate with the window
+ * system in synchronizing the window repaint with the window
+ * manager during resizing operations. After an application calls
+ * this function, it must call gdk_window_configure_finished() every
+ * time it has finished all processing associated with a set of
+ * Configure events. Toplevel GTK+ windows automatically use this
+ * protocol.
+ * 
+ * On X, calling this function makes @window participate in the
+ * _NET_WM_SYNC_REQUEST window manager protocol.
+ * 
+ * Since: 2.6
+ **/
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+  GdkWindowObject *private = (GdkWindowObject *)window;
+  GdkWindowImplX11 *impl;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  impl = GDK_WINDOW_IMPL_X11 (private->impl);
+         
+  if (!impl->use_synchronized_configure)
+    {
+      impl->use_synchronized_configure = TRUE;
+      ensure_sync_counter (window);
+    }
+}
+
+/**
+ * gdk_window_configure_finished:
+ * @window: a toplevel #GdkWindow
+ * 
+ * Signal to the window system that the application has finished
+ * handling Configure events it has received. Window Managers can
+ * use this to better synchronize the frame repaint with the
+ * application. GTK+ applications will automatically call this
+ * function when appropriate.
+ *
+ * This function can only be called if gdk_window_enable_synchronized_configure()
+ * was called previously.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_window_configure_finished (GdkWindow *window)
+{
+  GdkWindowImplX11 *impl;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
+  if (!impl->use_synchronized_configure)
+    return;
+  
+#ifdef HAVE_XSYNC
+  if (!GDK_WINDOW_DESTROYED (window))
+    {
+      GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+      GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+
+      if (toplevel && toplevel->update_counter != None &&
+         GDK_DISPLAY_X11 (display)->use_sync &&
+         !XSyncValueIsZero (toplevel->current_counter_value))
+       {
+         XSyncSetCounter (GDK_WINDOW_XDISPLAY (window), 
+                          toplevel->update_counter,
+                          toplevel->current_counter_value);
+         
+         XSyncIntToValue (&toplevel->current_counter_value, 0);
+       }
+    }
+#endif
+}
+
+#define __GDK_WINDOW_X11_C__
+#include "gdkaliasdef.c"