]> Pileus Git - ~andy/gtk/blobdiff - gdk/quartz/gdkwindow-quartz.c
quartz: Null check title before setting it
[~andy/gtk] / gdk / quartz / gdkwindow-quartz.c
index 93b68c29ca38cf8eb652bf936c9b33cf905f8a9d..5550fa88a323cefdd76a93000e57dfe012d3c224 100644 (file)
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
-#include <Carbon/Carbon.h>
 
-#include "gdk.h"
+#include <gdk/gdk.h>
+#include <gdk/gdkdeviceprivate.h>
+#include <gdk/gdkdisplayprivate.h>
+
 #include "gdkwindowimpl.h"
 #include "gdkprivate-quartz.h"
-#include "gdkscreen-quartz.h"
-#include "gdkinputprivate.h"
+#include "gdkquartzscreen.h"
+#include "gdkquartzcursor.h"
+
+#include <Carbon/Carbon.h>
+
+#include <sys/time.h>
+#include <cairo-quartz.h>
 
 static gpointer parent_class;
+static gpointer root_window_parent_class;
 
 static GSList   *update_nswindows;
 static gboolean  in_process_all_updates = FALSE;
 
 static GSList *main_window_stack;
 
+void _gdk_quartz_window_flush (GdkWindowImplQuartz *window_impl);
+
 #define FULLSCREEN_DATA "fullscreen-data"
 
 typedef struct
@@ -55,39 +63,62 @@ static FullscreenSavedGeometry *get_fullscreen_geometry (GdkWindow *window);
    GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
 
-static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
+/*
+ * GdkQuartzWindow
+ */
+
+struct _GdkQuartzWindow
+{
+  GdkWindow parent;
+};
+
+struct _GdkQuartzWindowClass
+{
+  GdkWindowClass parent_class;
+};
+
+G_DEFINE_TYPE (GdkQuartzWindow, gdk_quartz_window, GDK_TYPE_WINDOW);
+
+static void
+gdk_quartz_window_class_init (GdkQuartzWindowClass *quartz_window_class)
+{
+}
+
+static void
+gdk_quartz_window_init (GdkQuartzWindow *quartz_window)
+{
+}
+
+
+/*
+ * GdkQuartzWindowImpl
+ */
 
 NSView *
 gdk_quartz_window_get_nsview (GdkWindow *window)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
-
   if (GDK_WINDOW_DESTROYED (window))
     return NULL;
 
-  return ((GdkWindowImplQuartz *)private->impl)->view;
+  return ((GdkWindowImplQuartz *)window->impl)->view;
 }
 
 NSWindow *
 gdk_quartz_window_get_nswindow (GdkWindow *window)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
-
   if (GDK_WINDOW_DESTROYED (window))
     return NULL;
 
-  return ((GdkWindowImplQuartz *)private->impl)->toplevel;
+  return ((GdkWindowImplQuartz *)window->impl)->toplevel;
 }
 
 static CGContextRef
-gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
-                                   gboolean     antialias)
+gdk_window_impl_quartz_get_context (GdkWindowImplQuartz *window_impl,
+                                   gboolean             antialias)
 {
-  GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
-  GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
   CGContextRef cg_context;
 
-  if (GDK_WINDOW_DESTROYED (drawable_impl->wrapper))
+  if (GDK_WINDOW_DESTROYED (window_impl->wrapper))
     return NULL;
 
   /* Lock focus when not called as part of a drawRect call. This
@@ -111,28 +142,28 @@ gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
     {
       CGRect rect;
       CGRect *cg_rects;
-      GdkRectangle *rects;
       gint n_rects, i;
 
-      gdk_region_get_rectangles (window_impl->paint_clip_region,
-                                 &rects, &n_rects);
+      n_rects = cairo_region_num_rectangles (window_impl->paint_clip_region);
 
       if (n_rects == 1)
-        cg_rects = &rect;
+       cg_rects = &rect;
       else
-        cg_rects = g_new (CGRect, n_rects);
+       cg_rects = g_new (CGRect, n_rects);
 
       for (i = 0; i < n_rects; i++)
-        {
-          cg_rects[i].origin.x = rects[i].x;
-          cg_rects[i].origin.y = rects[i].y;
-          cg_rects[i].size.width = rects[i].width;
-          cg_rects[i].size.height = rects[i].height;
-        }
+       {
+          cairo_rectangle_int_t cairo_rect;
+          cairo_region_get_rectangle (window_impl->paint_clip_region,
+                                      i, &cairo_rect);
+         cg_rects[i].origin.x = cairo_rect.x;
+         cg_rects[i].origin.y = cairo_rect.y;
+         cg_rects[i].size.width = cairo_rect.width;
+         cg_rects[i].size.height = cairo_rect.height;
+       }
 
       CGContextClipToRects (cg_context, cg_rects, n_rects);
 
-      g_free (rects);
       if (cg_rects != &rect)
         g_free (cg_rects);
     }
@@ -141,43 +172,64 @@ gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
 }
 
 static void
-check_grab_unmap (GdkWindow *window)
+gdk_window_impl_quartz_release_context (GdkWindowImplQuartz *window_impl,
+                                        CGContextRef         cg_context)
 {
-  GdkDisplay *display = gdk_drawable_get_display (window);
+  CGContextRestoreGState (cg_context);
+  CGContextSetAllowsAntialiasing (cg_context, TRUE);
 
-  _gdk_display_end_pointer_grab (display, 0, window, TRUE);
-
-  if (display->keyboard_grab.window)
+  /* See comment in gdk_quartz_window_get_context(). */
+  if (window_impl->in_paint_rect_count == 0)
     {
-      GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
-      GdkWindowObject *tmp = GDK_WINDOW_OBJECT (display->keyboard_grab.window);
+      _gdk_quartz_window_flush (window_impl);
+      [window_impl->view unlockFocus];
+    }
+}
 
-      while (tmp && tmp != private)
-       tmp = tmp->parent;
+static void
+check_grab_unmap (GdkWindow *window)
+{
+  GList *list, *l;
+  GdkDisplay *display = gdk_window_get_display (window);
+  GdkDeviceManager *device_manager;
 
-      if (tmp)
-       _gdk_display_unset_has_keyboard_grab (display, TRUE);
+  device_manager = gdk_display_get_device_manager (display);
+  list = gdk_device_manager_list_devices (device_manager,
+                                          GDK_DEVICE_TYPE_FLOATING);
+  for (l = list; l; l = l->next)
+    {
+      _gdk_display_end_device_grab (display, l->data, 0, window, TRUE);
     }
+
+  g_list_free (list);
 }
 
 static void
 check_grab_destroy (GdkWindow *window)
 {
-  GdkDisplay *display = gdk_drawable_get_display (window);
-  GdkPointerGrabInfo *grab;
+  GList *list, *l;
+  GdkDisplay *display = gdk_window_get_display (window);
+  GdkDeviceManager *device_manager;
 
   /* Make sure there is no lasting grab in this native window */
-  grab = _gdk_display_get_last_pointer_grab (display);
-  if (grab && grab->native_window == window)
+  device_manager = gdk_display_get_device_manager (display);
+  list = gdk_device_manager_list_devices (device_manager,
+                                          GDK_DEVICE_TYPE_MASTER);
+
+  for (l = list; l; l = l->next)
     {
-      /* Serials are always 0 in quartz, but for clarity: */
-      grab->serial_end = grab->serial_start;
-      grab->implicit_ungrab = TRUE;
+      GdkDeviceGrabInfo *grab;
+
+      grab = _gdk_display_get_last_device_grab (display, l->data);
+      if (grab && grab->native_window == window)
+        {
+          /* Serials are always 0 in quartz, but for clarity: */
+          grab->serial_end = grab->serial_start;
+          grab->implicit_ungrab = TRUE;
+        }
     }
 
-  if (window == display->keyboard_grab.native_window &&
-      display->keyboard_grab.window != NULL)
-    _gdk_display_unset_has_keyboard_grab (display, TRUE);
+  g_list_free (list);
 }
 
 static void
@@ -185,10 +237,10 @@ gdk_window_impl_quartz_finalize (GObject *object)
 {
   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (object);
 
-  check_grab_destroy (GDK_DRAWABLE_IMPL_QUARTZ (object)->wrapper);
+  check_grab_destroy (GDK_WINDOW_IMPL_QUARTZ (object)->wrapper);
 
   if (impl->paint_clip_region)
-    gdk_region_destroy (impl->paint_clip_region);
+    cairo_region_destroy (impl->paint_clip_region);
 
   if (impl->transient_for)
     g_object_unref (impl->transient_for);
@@ -196,17 +248,114 @@ gdk_window_impl_quartz_finalize (GObject *object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+/* Help preventing "beam sync penalty" where CG makes all graphics code
+ * block until the next vsync if we try to flush (including call display on
+ * a view) too often. We do this by limiting the manual flushing done
+ * outside of expose calls to less than some frequency when measured over
+ * the last 4 flushes. This is a bit arbitray, but seems to make it possible
+ * for some quick manual flushes (such as gtkruler or gimp's marching ants)
+ * without hitting the max flush frequency.
+ *
+ * If drawable NULL, no flushing is done, only registering that a flush was
+ * done externally.
+ */
+void
+_gdk_quartz_window_flush (GdkWindowImplQuartz *window_impl)
+{
+  static struct timeval prev_tv;
+  static gint intervals[4];
+  static gint index;
+  struct timeval tv;
+  gint ms;
+
+  gettimeofday (&tv, NULL);
+  ms = (tv.tv_sec - prev_tv.tv_sec) * 1000 + (tv.tv_usec - prev_tv.tv_usec) / 1000;
+  intervals[index++ % 4] = ms;
+
+  if (window_impl)
+    {
+      ms = intervals[0] + intervals[1] + intervals[2] + intervals[3];
+
+      /* ~25Hz on average. */
+      if (ms > 4*40)
+        {
+          if (window_impl)
+            [window_impl->toplevel flushWindow];
+
+          prev_tv = tv;
+        }
+    }
+  else
+    prev_tv = tv;
+}
+
+static cairo_user_data_key_t gdk_quartz_cairo_key;
+
+typedef struct {
+  GdkWindowImplQuartz  *window_impl;
+  CGContextRef  cg_context;
+} GdkQuartzCairoSurfaceData;
+
 static void
-gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
+gdk_quartz_cairo_surface_destroy (void *data)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass);
+  GdkQuartzCairoSurfaceData *surface_data = data;
 
-  parent_class = g_type_class_peek_parent (klass);
+  surface_data->window_impl->cairo_surface = NULL;
 
-  object_class->finalize = gdk_window_impl_quartz_finalize;
+  gdk_quartz_window_release_context (surface_data->window_impl,
+                                     surface_data->cg_context);
 
-  drawable_quartz_class->get_context = gdk_window_impl_quartz_get_context;
+  g_free (surface_data);
+}
+
+static cairo_surface_t *
+gdk_quartz_create_cairo_surface (GdkWindowImplQuartz *impl,
+                                int                  width,
+                                int                  height)
+{
+  CGContextRef cg_context;
+  GdkQuartzCairoSurfaceData *surface_data;
+  cairo_surface_t *surface;
+
+  cg_context = gdk_quartz_window_get_context (impl, TRUE);
+
+  if (!cg_context)
+    return NULL;
+
+  surface_data = g_new (GdkQuartzCairoSurfaceData, 1);
+  surface_data->window_impl = impl;
+  surface_data->cg_context = cg_context;
+
+  surface = cairo_quartz_surface_create_for_cg_context (cg_context,
+                                                        width, height);
+
+  cairo_surface_set_user_data (surface, &gdk_quartz_cairo_key,
+                               surface_data,
+                               gdk_quartz_cairo_surface_destroy);
+
+  return surface;
+}
+
+static cairo_surface_t *
+gdk_quartz_ref_cairo_surface (GdkWindow *window)
+{
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return NULL;
+
+  if (!impl->cairo_surface)
+    {
+      impl->cairo_surface = 
+          gdk_quartz_create_cairo_surface (impl,
+                                           gdk_window_get_width (impl->wrapper),
+                                           gdk_window_get_height (impl->wrapper));
+    }
+  else
+    cairo_surface_reference (impl->cairo_surface);
+
+  return impl->cairo_surface;
 }
 
 static void
@@ -218,121 +367,54 @@ gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
 static void
 gdk_window_impl_quartz_begin_paint_region (GdkPaintable    *paintable,
                                            GdkWindow       *window,
-                                          const GdkRegion *region)
+                                          const cairo_region_t *region)
 {
   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
-  GdkWindowObject *private = (GdkWindowObject*)window;
-  int n_rects;
-  GdkRectangle *rects = NULL;
-  GdkPixmap *bg_pixmap;
-  GdkRegion *clipped_and_offset_region;
-  gboolean free_clipped_and_offset_region = TRUE;
+  cairo_region_t *clipped_and_offset_region;
+  cairo_t *cr;
 
-  bg_pixmap = private->bg_pixmap;
+  clipped_and_offset_region = cairo_region_copy (region);
 
-  clipped_and_offset_region = gdk_region_copy (region);
-
-  gdk_region_intersect (clipped_and_offset_region,
-                        private->clip_region_with_children);
-  gdk_region_offset (clipped_and_offset_region,
-                     private->abs_x, private->abs_y);
+  cairo_region_intersect (clipped_and_offset_region,
+                        window->clip_region_with_children);
+  cairo_region_translate (clipped_and_offset_region,
+                     window->abs_x, window->abs_y);
 
   if (impl->begin_paint_count == 0)
-    {
-      impl->paint_clip_region = clipped_and_offset_region;
-      free_clipped_and_offset_region = FALSE;
-    }
+    impl->paint_clip_region = cairo_region_reference (clipped_and_offset_region);
   else
-    gdk_region_union (impl->paint_clip_region, clipped_and_offset_region);
+    cairo_region_union (impl->paint_clip_region, clipped_and_offset_region);
 
   impl->begin_paint_count++;
 
-  if (bg_pixmap == GDK_NO_BG)
+  if (cairo_region_is_empty (clipped_and_offset_region))
     goto done;
 
-  gdk_region_get_rectangles (clipped_and_offset_region, &rects, &n_rects);
+  cr = gdk_cairo_create (window);
 
-  if (bg_pixmap == NULL)
-    {
-      CGContextRef cg_context;
-      CGFloat r, g, b, a;
-      gint i;
+  cairo_translate (cr, -window->abs_x, -window->abs_y);
 
-      cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
-      _gdk_quartz_colormap_get_rgba_from_pixel (gdk_drawable_get_colormap (window),
-                                                private->bg_color.pixel,
-                                                &r, &g, &b, &a);
-      CGContextSetRGBFillColor (cg_context, r, g, b, a);
-      for (i = 0; i < n_rects; i++)
-        {
-          CGContextFillRect (cg_context,
-                             CGRectMake (rects[i].x, rects[i].y,
-                                         rects[i].width, rects[i].height));
-        }
+  gdk_cairo_region (cr, clipped_and_offset_region);
+  cairo_clip (cr);
 
-      gdk_quartz_drawable_release_context (GDK_DRAWABLE (impl), cg_context);
+  while (window->background == NULL && window->parent)
+    {
+      cairo_translate (cr, -window->x, window->y);
+      window = window->parent;
     }
+  
+  if (window->background)
+    cairo_set_source (cr, window->background);
   else
-    {
-      int x, y;
-      int x_offset, y_offset;
-      int width, height;
-      GdkGC *gc;
+    cairo_set_source_rgba (cr, 0, 0, 0, 0);
 
-      x_offset = y_offset = 0;
+  /* Can use cairo_paint() here, we clipped above */
+  cairo_paint (cr);
 
-      while (window && bg_pixmap == GDK_PARENT_RELATIVE_BG)
-        {
-          /* If this window should have the same background as the parent,
-           * fetch the parent. (And if the same goes for the parent, fetch
-           * the grandparent, etc.)
-           */
-          x_offset += ((GdkWindowObject *) window)->x;
-          y_offset += ((GdkWindowObject *) window)->y;
-          window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
-          bg_pixmap = ((GdkWindowObject *) window)->bg_pixmap;
-        }
-
-      if (bg_pixmap == NULL || bg_pixmap == GDK_NO_BG || bg_pixmap == GDK_PARENT_RELATIVE_BG)
-        {
-          /* Parent relative background but the parent doesn't have a
-           * pixmap.
-           */ 
-          goto done;
-        }
-
-      /* Note: There should be a CG API to draw tiled images, we might
-       * want to look into that for this. 
-       */
-      gc = gdk_gc_new (GDK_DRAWABLE (impl));
-
-      gdk_drawable_get_size (GDK_DRAWABLE (bg_pixmap), &width, &height);
-
-      x = -x_offset;
-      while (x < (rects[0].x + rects[0].width))
-        {
-          if (x + width >= rects[0].x)
-           {
-              y = -y_offset;
-              while (y < (rects[0].y + rects[0].height))
-                {
-                  if (y + height >= rects[0].y)
-                    gdk_draw_drawable (GDK_DRAWABLE (impl), gc, bg_pixmap, 0, 0, x, y, width, height);
-                 
-                  y += height;
-                }
-            }
-          x += width;
-        }
+  cairo_destroy (cr);
 
-      g_object_unref (gc);
-    }
-
- done:
-  if (free_clipped_and_offset_region)
-    gdk_region_destroy (clipped_and_offset_region);
-  g_free (rects);
+done:
+  cairo_region_destroy (clipped_and_offset_region);
 }
 
 static void
@@ -344,38 +426,39 @@ gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
 
   if (impl->begin_paint_count == 0)
     {
-      gdk_region_destroy (impl->paint_clip_region);
+      cairo_region_destroy (impl->paint_clip_region);
       impl->paint_clip_region = NULL;
     }
 }
 
-void
-_gdk_quartz_window_set_needs_display_in_rect (GdkWindow    *window,
-                                              GdkRectangle *rect)
+static void
+gdk_quartz_window_set_needs_display_in_region (GdkWindow    *window,
+                                               cairo_region_t    *region)
 {
-  GdkWindowObject *private;
   GdkWindowImplQuartz *impl;
+  int i, n_rects;
 
-  private = GDK_WINDOW_OBJECT (window);
-  impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (!impl->needs_display_region)
-    impl->needs_display_region = gdk_region_new ();
-
-  gdk_region_union_with_rect (impl->needs_display_region, rect);
+    impl->needs_display_region = cairo_region_create ();
 
-  [impl->view setNeedsDisplayInRect:NSMakeRect (rect->x, rect->y,
-                                                rect->width, rect->height)];
+  cairo_region_union (impl->needs_display_region, region);
 
+  n_rects = cairo_region_num_rectangles (region);
+  for (i = 0; i < n_rects; i++)
+    {
+      cairo_rectangle_int_t rect;
+      cairo_region_get_rectangle (region, i, &rect);
+      [impl->view setNeedsDisplayInRect:NSMakeRect (rect.x, rect.y,
+                                                    rect.width, rect.height)];
+    }
 }
 
 void
-_gdk_windowing_window_process_updates_recurse (GdkWindow *window,
-                                               GdkRegion *region)
+_gdk_quartz_window_process_updates_recurse (GdkWindow *window,
+                                            cairo_region_t *region)
 {
-  int i, n_rects;
-  GdkRectangle *rects;
-
   /* Make sure to only flush each toplevel at most once if we're called
    * from process_all_updates.
    */
@@ -383,15 +466,13 @@ _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
     {
       GdkWindow *toplevel;
 
-      toplevel = gdk_window_get_toplevel (window);
-      if (toplevel)
+      toplevel = gdk_window_get_effective_toplevel (window);
+      if (toplevel && WINDOW_IS_TOPLEVEL (toplevel))
         {
-          GdkWindowObject *toplevel_private;
           GdkWindowImplQuartz *toplevel_impl;
           NSWindow *nswindow;
 
-          toplevel_private = (GdkWindowObject *)toplevel;
-          toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl;
+          toplevel_impl = (GdkWindowImplQuartz *)toplevel->impl;
           nswindow = toplevel_impl->toplevel;
 
           /* In theory, we could skip the flush disabling, since we only
@@ -406,12 +487,10 @@ _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
         }
     }
 
-  gdk_region_get_rectangles (region, &rects, &n_rects);
-
-  for (i = 0; i < n_rects; i++)
-    _gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]);
-
-  g_free (rects);
+  if (WINDOW_IS_TOPLEVEL (window))
+    gdk_quartz_window_set_needs_display_in_region (window, region);
+  else
+    _gdk_window_process_updates_recurse (window, region);
 
   /* NOTE: I'm not sure if we should displayIfNeeded here. It slows down a
    * lot (since it triggers the beam syncing) and things seem to work
@@ -420,7 +499,7 @@ _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
 }
 
 void
-_gdk_windowing_before_process_all_updates (void)
+_gdk_quartz_display_before_process_all_updates (GdkDisplay *display)
 {
   in_process_all_updates = TRUE;
 
@@ -428,7 +507,7 @@ _gdk_windowing_before_process_all_updates (void)
 }
 
 void
-_gdk_windowing_after_process_all_updates (void)
+_gdk_quartz_display_after_process_all_updates (GdkDisplay *display)
 {
   GSList *old_update_nswindows = update_nswindows;
   GSList *tmp_list = update_nswindows;
@@ -441,7 +520,7 @@ _gdk_windowing_after_process_all_updates (void)
 
       [[nswindow contentView] displayIfNeeded];
 
-      _gdk_quartz_drawable_flush (NULL);
+      _gdk_quartz_window_flush (NULL);
 
       [nswindow enableFlushWindow];
       [nswindow flushWindow];
@@ -464,60 +543,6 @@ gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
   iface->end_paint = gdk_window_impl_quartz_end_paint;
 }
 
-GType
-_gdk_window_impl_quartz_get_type (void)
-{
-  static GType object_type = 0;
-
-  if (!object_type)
-    {
-      const GTypeInfo object_info =
-       {
-         sizeof (GdkWindowImplQuartzClass),
-         (GBaseInitFunc) NULL,
-         (GBaseFinalizeFunc) NULL,
-         (GClassInitFunc) gdk_window_impl_quartz_class_init,
-         NULL,           /* class_finalize */
-         NULL,           /* class_data */
-         sizeof (GdkWindowImplQuartz),
-         0,              /* n_preallocs */
-         (GInstanceInitFunc) gdk_window_impl_quartz_init,
-       };
-
-      const GInterfaceInfo paintable_info = 
-       {
-         (GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
-         NULL,
-         NULL
-       };
-
-      const GInterfaceInfo window_impl_info = 
-       {
-         (GInterfaceInitFunc) gdk_window_impl_iface_init,
-         NULL,
-         NULL
-       };
-
-      object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
-                                            "GdkWindowImplQuartz",
-                                            &object_info, 0);
-      g_type_add_interface_static (object_type,
-                                  GDK_TYPE_PAINTABLE,
-                                  &paintable_info);
-      g_type_add_interface_static (object_type,
-                                  GDK_TYPE_WINDOW_IMPL,
-                                  &window_impl_info);
-    }
-
-  return object_type;
-}
-
-GType
-_gdk_window_impl_get_type (void)
-{
-  return _gdk_window_impl_quartz_get_type ();
-}
-
 static const gchar *
 get_default_title (void)
 {
@@ -538,15 +563,12 @@ get_ancestor_coordinates_from_child (GdkWindow *child_window,
                                     gint      *ancestor_x, 
                                     gint      *ancestor_y)
 {
-  GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window);
-  GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window);
-
-  while (child_private != ancestor_private)
+  while (child_window != ancestor_window)
     {
-      child_x += child_private->x;
-      child_y += child_private->y;
+      child_x += child_window->x;
+      child_y += child_window->y;
 
-      child_private = child_private->parent;
+      child_window = child_window->parent;
     }
 
   *ancestor_x = child_x;
@@ -556,7 +578,6 @@ get_ancestor_coordinates_from_child (GdkWindow *child_window,
 void
 _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number)
 {
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
   gint x, y;
   gint gx, gy;
   GdkWindow *toplevel;
@@ -587,10 +608,10 @@ _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number)
   x += tx;
   y += ty;
 
-  _gdk_quartz_window_gdk_xy_to_xy (x, y + private->height,
+  _gdk_quartz_window_gdk_xy_to_xy (x, y + window->height,
                                    &gx, &gy);
 
-  rect = NSMakeRect (gx, gy, private->width, private->height);
+  rect = NSMakeRect (gx, gy, window->width, window->height);
 
   if (debug_window[number] && NSEqualRects (rect, old_rect[number]))
     return;
@@ -660,7 +681,7 @@ _gdk_quartz_window_gdk_xy_to_xy (gint  gdk_x,
                                  gint *ns_x,
                                  gint *ns_y)
 {
-  GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen);
+  GdkQuartzScreen *screen_quartz = GDK_QUARTZ_SCREEN (_gdk_screen);
 
   if (ns_y)
     *ns_y = screen_quartz->height - gdk_y + screen_quartz->min_y;
@@ -675,7 +696,7 @@ _gdk_quartz_window_xy_to_gdk_xy (gint  ns_x,
                                  gint *gdk_x,
                                  gint *gdk_y)
 {
-  GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen);
+  GdkQuartzScreen *screen_quartz = GDK_QUARTZ_SCREEN (_gdk_screen);
 
   if (gdk_y)
     *gdk_y = screen_quartz->height - ns_y + screen_quartz->min_y;
@@ -698,27 +719,28 @@ find_child_window_helper (GdkWindow *window,
                          gint       x,
                          gint       y,
                          gint       x_offset,
-                         gint       y_offset)
+                         gint       y_offset,
+                          gboolean   get_toplevel)
 {
   GdkWindowImplQuartz *impl;
   GList *l;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (window == _gdk_root)
     update_toplevel_order ();
 
   for (l = impl->sorted_children; l; l = l->next)
     {
-      GdkWindowObject *child_private = l->data;
-      GdkWindowImplQuartz *child_impl = GDK_WINDOW_IMPL_QUARTZ (child_private->impl);
+      GdkWindow *child = l->data;
+      GdkWindowImplQuartz *child_impl = GDK_WINDOW_IMPL_QUARTZ (child->impl);
       int temp_x, temp_y;
 
-      if (!GDK_WINDOW_IS_MAPPED (child_private))
+      if (!GDK_WINDOW_IS_MAPPED (child))
        continue;
 
-      temp_x = x_offset + child_private->x;
-      temp_y = y_offset + child_private->y;
+      temp_x = x_offset + child->x;
+      temp_y = y_offset + child->y;
 
       /* Special-case the root window. We have to include the title
        * bar in the checks, otherwise the window below the title bar
@@ -742,7 +764,7 @@ find_child_window_helper (GdkWindow *window,
 
           if (titlebar_height > 0 &&
               x >= temp_x && y >= temp_y - titlebar_height &&
-              x < temp_x + child_private->width && y < temp_y)
+              x < temp_x + child->width && y < temp_y)
             {
               /* The root means "unknown" i.e. a window not managed by
                * GDK.
@@ -751,13 +773,15 @@ find_child_window_helper (GdkWindow *window,
             }
         }
 
-      if (x >= temp_x && y >= temp_y &&
-         x < temp_x + child_private->width && y < temp_y + child_private->height)
+      if ((!get_toplevel || (get_toplevel && window == _gdk_root)) &&
+          x >= temp_x && y >= temp_y &&
+         x < temp_x + child->width && y < temp_y + child->height)
        {
          /* Look for child windows. */
          return find_child_window_helper (l->data,
                                           x, y,
-                                          temp_x, temp_y);
+                                          temp_x, temp_y,
+                                           get_toplevel);
        }
     }
   
@@ -771,12 +795,11 @@ find_child_window_helper (GdkWindow *window,
 GdkWindow *
 _gdk_quartz_window_find_child (GdkWindow *window,
                               gint       x,
-                              gint       y)
+                              gint       y,
+                               gboolean   get_toplevel)
 {
-  GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
-
-  if (x >= 0 && y >= 0 && x < private->width && y < private->height)
-    return find_child_window_helper (window, x, y, 0, 0);
+  if (x >= 0 && y >= 0 && x < window->width && y < window->height)
+    return find_child_window_helper (window, x, y, 0, 0, get_toplevel);
 
   return NULL;
 }
@@ -787,7 +810,7 @@ _gdk_quartz_window_did_become_main (GdkWindow *window)
 {
   main_window_stack = g_slist_remove (main_window_stack, window);
 
-  if (GDK_WINDOW_OBJECT (window)->window_type != GDK_WINDOW_TEMP)
+  if (window->window_type != GDK_WINDOW_TEMP)
     main_window_stack = g_slist_prepend (main_window_stack, window);
 
   clear_toplevel_order ();
@@ -813,10 +836,9 @@ _gdk_quartz_window_did_resign_main (GdkWindow *window)
   if (new_window &&
       new_window != window &&
       GDK_WINDOW_IS_MAPPED (new_window) &&
-      GDK_WINDOW_OBJECT (new_window)->window_type != GDK_WINDOW_TEMP)
+      WINDOW_IS_TOPLEVEL (new_window))
     {
-      GdkWindowObject *private = (GdkWindowObject *) new_window;
-      GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+      GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (new_window->impl);
 
       [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
     }
@@ -853,75 +875,38 @@ get_nsscreen_for_point (gint x, gint y)
 }
 
 void
-_gdk_window_impl_new (GdkWindow     *window,
-                     GdkWindow     *real_parent,
-                     GdkScreen     *screen,
-                     GdkVisual     *visual,
-                     GdkEventMask   event_mask,
-                     GdkWindowAttr *attributes,
-                     gint           attributes_mask)
-{
-  GdkWindowObject *private;
+_gdk_quartz_display_create_window_impl (GdkDisplay    *display,
+                                        GdkWindow     *window,
+                                        GdkWindow     *real_parent,
+                                        GdkScreen     *screen,
+                                        GdkEventMask   event_mask,
+                                        GdkWindowAttr *attributes,
+                                        gint           attributes_mask)
+{
   GdkWindowImplQuartz *impl;
-  GdkDrawableImplQuartz *draw_impl;
   GdkWindowImplQuartz *parent_impl;
 
   GDK_QUARTZ_ALLOC_POOL;
 
-  private = (GdkWindowObject *)window;
+  impl = g_object_new (GDK_TYPE_WINDOW_IMPL_QUARTZ, NULL);
+  window->impl = GDK_WINDOW_IMPL (impl);
+  impl->wrapper = window;
 
-  impl = g_object_new (_gdk_window_impl_get_type (), NULL);
-  private->impl = (GdkDrawable *)impl;
-  draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (impl);
-  draw_impl->wrapper = GDK_DRAWABLE (window);
+  parent_impl = GDK_WINDOW_IMPL_QUARTZ (window->parent->impl);
 
-  parent_impl = GDK_WINDOW_IMPL_QUARTZ (private->parent->impl);
-
-  switch (private->window_type)
+  switch (window->window_type)
     {
     case GDK_WINDOW_TOPLEVEL:
-    case GDK_WINDOW_DIALOG:
     case GDK_WINDOW_TEMP:
-      if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
+      if (GDK_WINDOW_TYPE (window->parent) != GDK_WINDOW_ROOT)
        {
          /* The common code warns for this case */
-          parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
-       }
-    }
-
-  if (!private->input_only)
-    {
-      if (attributes_mask & GDK_WA_COLORMAP)
-       {
-         draw_impl->colormap = attributes->colormap;
-         g_object_ref (attributes->colormap);
-       }
-      else
-       {
-         if (visual == gdk_screen_get_system_visual (_gdk_screen))
-           {
-             draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
-             g_object_ref (draw_impl->colormap);
-           }
-         else if (visual == gdk_screen_get_rgba_visual (_gdk_screen))
-           {
-             draw_impl->colormap = gdk_screen_get_rgba_colormap (_gdk_screen);
-             g_object_ref (draw_impl->colormap);
-           }
-         else
-           {
-             draw_impl->colormap = gdk_colormap_new (visual, FALSE);
-           }
+          parent_impl = GDK_WINDOW_IMPL_QUARTZ (_gdk_root->impl);
        }
     }
-  else
-    {
-      draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
-      g_object_ref (draw_impl->colormap);
-    }
 
   /* Maintain the z-ordered list of children. */
-  if (private->parent != (GdkWindowObject *)_gdk_root)
+  if (window->parent != _gdk_root)
     parent_impl->sorted_children = g_list_prepend (parent_impl->sorted_children, window);
   else
     clear_toplevel_order ();
@@ -930,10 +915,11 @@ _gdk_window_impl_new (GdkWindow     *window,
                                  (attributes->cursor) :
                                  NULL));
 
-  switch (attributes->window_type) 
+  impl->view = NULL;
+
+  switch (attributes->window_type)
     {
     case GDK_WINDOW_TOPLEVEL:
-    case GDK_WINDOW_DIALOG:
     case GDK_WINDOW_TEMP:
       {
         NSScreen *screen;
@@ -948,16 +934,16 @@ _gdk_window_impl_new (GdkWindow     *window,
          * to find the screen the window will be on and correct the
          * content_rect coordinates to be relative to that screen.
          */
-        _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y, &nx, &ny);
+        _gdk_quartz_window_gdk_xy_to_xy (window->x, window->y, &nx, &ny);
 
         screen = get_nsscreen_for_point (nx, ny);
         screen_rect = [screen frame];
         nx -= screen_rect.origin.x;
         ny -= screen_rect.origin.y;
 
-        content_rect = NSMakeRect (nx, ny - private->height,
-                                   private->width,
-                                   private->height);
+        content_rect = NSMakeRect (nx, ny - window->height,
+                                   window->width,
+                                   window->height);
 
         if (attributes->window_type == GDK_WINDOW_TEMP ||
             attributes->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
@@ -972,11 +958,11 @@ _gdk_window_impl_new (GdkWindow     *window,
                           NSResizableWindowMask);
           }
 
-       impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect 
-                                                           styleMask:style_mask
-                                                             backing:NSBackingStoreBuffered
-                                                               defer:NO
-                                                                screen:screen];
+       impl->toplevel = [[GdkQuartzNSWindow alloc] initWithContentRect:content_rect 
+                                                             styleMask:style_mask
+                                                               backing:NSBackingStoreBuffered
+                                                                 defer:NO
+                                                                  screen:screen];
 
        if (attributes_mask & GDK_WA_TITLE)
          title = attributes->title;
@@ -985,7 +971,7 @@ _gdk_window_impl_new (GdkWindow     *window,
 
        gdk_window_set_title (window, title);
   
-       if (draw_impl->colormap == gdk_screen_get_rgba_colormap (_gdk_screen))
+       if (gdk_window_get_visual (window) == gdk_screen_get_rgba_visual (_gdk_screen))
          {
            [impl->toplevel setOpaque:NO];
            [impl->toplevel setBackgroundColor:[NSColor clearColor]];
@@ -1003,14 +989,14 @@ _gdk_window_impl_new (GdkWindow     *window,
 
     case GDK_WINDOW_CHILD:
       {
-       GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (private->parent)->impl);
+       GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (window->parent->impl);
 
-       if (!private->input_only)
+       if (!window->input_only)
          {
-           NSRect frame_rect = NSMakeRect (private->x + private->parent->abs_x,
-                                            private->y + private->parent->abs_y,
-                                            private->width,
-                                            private->height);
+           NSRect frame_rect = NSMakeRect (window->x + window->parent->abs_x,
+                                            window->y + window->parent->abs_y,
+                                            window->width,
+                                            window->height);
        
            impl->view = [[GdkQuartzView alloc] initWithFrame:frame_rect];
            
@@ -1039,8 +1025,7 @@ _gdk_quartz_window_update_position (GdkWindow *window)
 {
   NSRect frame_rect;
   NSRect content_rect;
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   GDK_QUARTZ_ALLOC_POOL;
 
@@ -1049,89 +1034,54 @@ _gdk_quartz_window_update_position (GdkWindow *window)
 
   _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x,
                                    content_rect.origin.y + content_rect.size.height,
-                                   &private->x, &private->y);
+                                   &window->x, &window->y);
 
 
   GDK_QUARTZ_RELEASE_POOL;
 }
 
 void
-_gdk_windowing_update_window_sizes (GdkScreen *screen)
-{
-  GList *windows, *list;
-  GdkWindowObject *private = (GdkWindowObject *)_gdk_root;
-
-  /* The size of the root window is so that it can contain all
-   * monitors attached to this machine.  The monitors are laid out
-   * within this root window.  We calculate the size of the root window
-   * and the positions of the different monitors in gdkscreen-quartz.c.
-   *
-   * This data is updated when the monitor configuration is changed.
-   */
-  private->x = 0;
-  private->y = 0;
-  private->abs_x = 0;
-  private->abs_y = 0;
-  private->width = gdk_screen_get_width (screen);
-  private->height = gdk_screen_get_height (screen);
-
-  windows = gdk_screen_get_toplevel_windows (screen);
-
-  for (list = windows; list; list = list->next)
-    _gdk_quartz_window_update_position (list->data);
-
-  g_list_free (windows);
-}
-
-void
-_gdk_windowing_window_init (void)
+_gdk_quartz_window_init_windowing (GdkDisplay *display,
+                                   GdkScreen  *screen)
 {
-  GdkWindowObject *private;
   GdkWindowImplQuartz *impl;
-  GdkDrawableImplQuartz *drawable_impl;
 
   g_assert (_gdk_root == NULL);
 
-  _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
+  _gdk_root = _gdk_display_create_window (display);
 
-  private = (GdkWindowObject *)_gdk_root;
-  private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
-  private->impl_window = private;
+  _gdk_root->impl = g_object_new (_gdk_root_window_impl_quartz_get_type (), NULL);
+  _gdk_root->impl_window = _gdk_root;
+  _gdk_root->visual = gdk_screen_get_system_visual (screen);
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (_gdk_root->impl);
 
-  _gdk_windowing_update_window_sizes (_gdk_screen);
+  _gdk_quartz_screen_update_window_sizes (screen);
 
-  private->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */
-  private->window_type = GDK_WINDOW_ROOT;
-  private->depth = 24;
-  private->viewable = TRUE;
+  _gdk_root->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */
+  _gdk_root->window_type = GDK_WINDOW_ROOT;
+  _gdk_root->depth = 24;
+  _gdk_root->viewable = TRUE;
 
-  drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl);
-  
-  drawable_impl->wrapper = GDK_DRAWABLE (private);
-  drawable_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
-  g_object_ref (drawable_impl->colormap);
+  impl->wrapper = _gdk_root;
 }
 
 static void
-_gdk_quartz_window_destroy (GdkWindow *window,
-                            gboolean   recursing,
-                            gboolean   foreign_destroy)
+gdk_quartz_window_destroy (GdkWindow *window,
+                           gboolean   recursing,
+                           gboolean   foreign_destroy)
 {
-  GdkWindowObject *private;
   GdkWindowImplQuartz *impl;
-  GdkWindowObject *parent;
+  GdkWindow *parent;
 
-  private = GDK_WINDOW_OBJECT (window);
-  impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   main_window_stack = g_slist_remove (main_window_stack, window);
 
   g_list_free (impl->sorted_children);
   impl->sorted_children = NULL;
 
-  parent = private->parent;
+  parent = window->parent;
   if (parent)
     {
       GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
@@ -1139,7 +1089,13 @@ _gdk_quartz_window_destroy (GdkWindow *window,
       parent_impl->sorted_children = g_list_remove (parent_impl->sorted_children, window);
     }
 
-  _gdk_quartz_drawable_finish (GDK_DRAWABLE (impl));
+  if (impl->cairo_surface)
+    {
+      cairo_surface_finish (impl->cairo_surface);
+      cairo_surface_set_user_data (impl->cairo_surface, &gdk_quartz_cairo_key,
+                                  NULL, NULL);
+      impl->cairo_surface = NULL;
+    }
 
   if (!recursing && !foreign_destroy)
     {
@@ -1154,8 +1110,20 @@ _gdk_quartz_window_destroy (GdkWindow *window,
     }
 }
 
-void
-_gdk_windowing_window_destroy_foreign (GdkWindow *window)
+static cairo_surface_t *
+gdk_window_quartz_resize_cairo_surface (GdkWindow       *window,
+                                        cairo_surface_t *surface,
+                                        gint             width,
+                                        gint             height)
+{
+  /* Quartz surfaces cannot be resized */
+  cairo_surface_destroy (surface);
+
+  return NULL;
+}
+
+static void
+gdk_quartz_window_destroy_foreign (GdkWindow *window)
 {
   /* Foreign windows aren't supported in OSX. */
 }
@@ -1166,25 +1134,24 @@ _gdk_windowing_window_destroy_foreign (GdkWindow *window)
 static void
 gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   gboolean focus_on_map;
 
   GDK_QUARTZ_ALLOC_POOL;
 
   if (!GDK_WINDOW_IS_MAPPED (window))
-    focus_on_map = private->focus_on_map;
+    focus_on_map = window->focus_on_map;
   else
     focus_on_map = TRUE;
 
-  if (impl->toplevel)
+  if (WINDOW_IS_TOPLEVEL (window) && impl->toplevel)
     {
       gboolean make_key;
 
-      make_key = (private->accept_focus && focus_on_map &&
-                  private->window_type != GDK_WINDOW_TEMP);
+      make_key = (window->accept_focus && focus_on_map &&
+                  window->window_type != GDK_WINDOW_TEMP);
 
-      [(GdkQuartzWindow*)impl->toplevel showAndMakeKey:make_key];
+      [(GdkQuartzNSWindow*)impl->toplevel showAndMakeKey:make_key];
       clear_toplevel_order ();
 
       _gdk_quartz_events_send_map_event (window);
@@ -1198,10 +1165,10 @@ gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped)
 
   gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0);
 
-  if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
+  if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
     gdk_window_maximize (window);
 
-  if (private->state & GDK_WINDOW_STATE_ICONIFIED)
+  if (window->state & GDK_WINDOW_STATE_ICONIFIED)
     gdk_window_iconify (window);
 
   if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
@@ -1220,7 +1187,7 @@ _gdk_quartz_window_detach_from_parent (GdkWindow *window)
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   
   g_return_if_fail (impl->toplevel != NULL);
 
@@ -1228,7 +1195,7 @@ _gdk_quartz_window_detach_from_parent (GdkWindow *window)
     {
       GdkWindowImplQuartz *parent_impl;
 
-      parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
+      parent_impl = GDK_WINDOW_IMPL_QUARTZ (impl->transient_for->impl);
       [parent_impl->toplevel removeChildWindow:impl->toplevel];
       clear_toplevel_order ();
     }
@@ -1242,7 +1209,7 @@ _gdk_quartz_window_attach_to_parent (GdkWindow *window)
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   
   g_return_if_fail (impl->toplevel != NULL);
 
@@ -1250,7 +1217,7 @@ _gdk_quartz_window_attach_to_parent (GdkWindow *window)
     {
       GdkWindowImplQuartz *parent_impl;
 
-      parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
+      parent_impl = GDK_WINDOW_IMPL_QUARTZ (impl->transient_for->impl);
       [parent_impl->toplevel addChildWindow:impl->toplevel ordered:NSWindowAbove];
       clear_toplevel_order ();
     }
@@ -1259,7 +1226,6 @@ _gdk_quartz_window_attach_to_parent (GdkWindow *window)
 void
 gdk_window_quartz_hide (GdkWindow *window)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
   GdkWindowImplQuartz *impl;
 
   /* Make sure we're not stuck in fullscreen mode. */
@@ -1270,9 +1236,9 @@ gdk_window_quartz_hide (GdkWindow *window)
 
   _gdk_window_clear_update_area (window);
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
-  if (impl->toplevel
+  if (WINDOW_IS_TOPLEVEL (window)
     {
      /* Update main window. */
       main_window_stack = g_slist_remove (main_window_stack, window);
@@ -1282,7 +1248,7 @@ gdk_window_quartz_hide (GdkWindow *window)
       if (impl->transient_for)
         _gdk_quartz_window_detach_from_parent (window);
 
-      [(GdkQuartzWindow*)impl->toplevel hide];
+      [(GdkQuartzNSWindow*)impl->toplevel hide];
     }
   else if (impl->view)
     {
@@ -1303,24 +1269,23 @@ move_resize_window_internal (GdkWindow *window,
                             gint       width,
                             gint       height)
 {
-  GdkWindowObject *private = (GdkWindowObject *)window;
   GdkWindowImplQuartz *impl;
   GdkRectangle old_visible;
   GdkRectangle new_visible;
   GdkRectangle scroll_rect;
-  GdkRegion *old_region;
-  GdkRegion *expose_region;
+  cairo_region_t *old_region;
+  cairo_region_t *expose_region;
   NSSize delta;
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
-  if ((x == -1 || (x == private->x)) &&
-      (y == -1 || (y == private->y)) &&
-      (width == -1 || (width == private->width)) &&
-      (height == -1 || (height == private->height)))
+  if ((x == -1 || (x == window->x)) &&
+      (y == -1 || (y == window->y)) &&
+      (width == -1 || (width == window->width)) &&
+      (height == -1 || (height == window->height)))
     {
       return;
     }
@@ -1330,18 +1295,17 @@ move_resize_window_internal (GdkWindow *window,
       /* The previously visible area of this window in a coordinate
        * system rooted at the origin of this window.
        */
-      old_visible.x = -private->x;
-      old_visible.y = -private->y;
+      old_visible.x = -window->x;
+      old_visible.y = -window->y;
 
-      gdk_drawable_get_size (GDK_DRAWABLE (private->parent),
-                             &old_visible.width,
-                             &old_visible.height);
+      old_visible.width = window->width;
+      old_visible.height = window->height;
     }
 
   if (x != -1)
     {
-      delta.width = x - private->x;
-      private->x = x;
+      delta.width = x - window->x;
+      window->x = x;
     }
   else
     {
@@ -1350,8 +1314,8 @@ move_resize_window_internal (GdkWindow *window,
 
   if (y != -1)
     {
-      delta.height = y - private->y;
-      private->y = y;
+      delta.height = y - window->y;
+      window->y = y;
     }
   else
     {
@@ -1359,10 +1323,10 @@ move_resize_window_internal (GdkWindow *window,
     }
 
   if (width != -1)
-    private->width = width;
+    window->width = width;
 
   if (height != -1)
-    private->height = height;
+    window->height = height;
 
   GDK_QUARTZ_ALLOC_POOL;
 
@@ -1372,33 +1336,33 @@ move_resize_window_internal (GdkWindow *window,
       NSRect frame_rect;
       gint gx, gy;
 
-      _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y + private->height,
+      _gdk_quartz_window_gdk_xy_to_xy (window->x, window->y + window->height,
                                        &gx, &gy);
 
-      content_rect = NSMakeRect (gx, gy, private->width, private->height);
+      content_rect = NSMakeRect (gx, gy, window->width, window->height);
 
       frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
       [impl->toplevel setFrame:frame_rect display:YES];
     }
   else 
     {
-      if (!private->input_only)
+      if (!window->input_only)
         {
           NSRect nsrect;
 
-          nsrect = NSMakeRect (private->x, private->y, private->width, private->height);
+          nsrect = NSMakeRect (window->x, window->y, window->width, window->height);
 
           /* The newly visible area of this window in a coordinate
            * system rooted at the origin of this window.
            */
-          new_visible.x = -private->x;
-          new_visible.y = -private->y;
+          new_visible.x = -window->x;
+          new_visible.y = -window->y;
           new_visible.width = old_visible.width;   /* parent has not changed size */
           new_visible.height = old_visible.height; /* parent has not changed size */
 
-          expose_region = gdk_region_rectangle (&new_visible);
-          old_region = gdk_region_rectangle (&old_visible);
-          gdk_region_subtract (expose_region, old_region);
+          expose_region = cairo_region_create_rectangle (&new_visible);
+          old_region = cairo_region_create_rectangle (&old_visible);
+          cairo_region_subtract (expose_region, old_region);
 
           /* Determine what (if any) part of the previously visible
            * part of the window can be copied without a redraw
@@ -1408,12 +1372,8 @@ move_resize_window_internal (GdkWindow *window,
           scroll_rect.y -= delta.height;
           gdk_rectangle_intersect (&scroll_rect, &old_visible, &scroll_rect);
 
-          if (!gdk_region_empty (expose_region))
+          if (!cairo_region_is_empty (expose_region))
             {
-              GdkRectangle* rects;
-              gint n_rects;
-              gint n;
-
               if (scroll_rect.width != 0 && scroll_rect.height != 0)
                 {
                   [impl->view scrollRect:NSMakeRect (scroll_rect.x,
@@ -1425,12 +1385,7 @@ move_resize_window_internal (GdkWindow *window,
 
               [impl->view setFrame:nsrect];
 
-              gdk_region_get_rectangles (expose_region, &rects, &n_rects);
-
-              for (n = 0; n < n_rects; ++n)
-                _gdk_quartz_window_set_needs_display_in_rect (window, &rects[n]);
-
-              g_free (rects);
+              gdk_quartz_window_set_needs_display_in_region (window, expose_region);
             }
           else
             {
@@ -1438,8 +1393,8 @@ move_resize_window_internal (GdkWindow *window,
               [impl->view setNeedsDisplay:YES];
             }
 
-          gdk_region_destroy (expose_region);
-          gdk_region_destroy (old_region);
+          cairo_region_destroy (expose_region);
+          cairo_region_destroy (old_region);
         }
     }
 
@@ -1453,7 +1408,7 @@ window_quartz_move (GdkWindow *window,
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  if (((GdkWindowObject *)window)->state & GDK_WINDOW_STATE_FULLSCREEN)
+  if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
     return;
 
   move_resize_window_internal (window, x, y, -1, -1);
@@ -1466,7 +1421,7 @@ window_quartz_resize (GdkWindow *window,
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  if (((GdkWindowObject *)window)->state & GDK_WINDOW_STATE_FULLSCREEN)
+  if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
     return;
 
   if (width < 1)
@@ -1520,7 +1475,7 @@ gdk_window_quartz_reparent (GdkWindow *window,
                             gint       x,
                             gint       y)
 {
-  GdkWindowObject *private, *old_parent_private, *new_parent_private;
+  GdkWindow *old_parent;
   GdkWindowImplQuartz *impl, *old_parent_impl, *new_parent_impl;
   NSView *view, *new_parent_view;
 
@@ -1531,16 +1486,14 @@ gdk_window_quartz_reparent (GdkWindow *window,
       return FALSE;
     }
 
-  private = GDK_WINDOW_OBJECT (window);
-  impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   view = impl->view;
 
-  new_parent_private = GDK_WINDOW_OBJECT (new_parent);
-  new_parent_impl = GDK_WINDOW_IMPL_QUARTZ (new_parent_private->impl);
+  new_parent_impl = GDK_WINDOW_IMPL_QUARTZ (new_parent->impl);
   new_parent_view = new_parent_impl->view;
 
-  old_parent_private = GDK_WINDOW_OBJECT (private->parent);
-  old_parent_impl = GDK_WINDOW_IMPL_QUARTZ (old_parent_private->impl);
+  old_parent = window->parent;
+  old_parent_impl = GDK_WINDOW_IMPL_QUARTZ (old_parent->impl);
 
   [view retain];
 
@@ -1549,9 +1502,9 @@ gdk_window_quartz_reparent (GdkWindow *window,
 
   [view release];
 
-  private->parent = new_parent_private;
+  window->parent = new_parent;
 
-  if (old_parent_private)
+  if (old_parent)
     {
       old_parent_impl->sorted_children = g_list_remove (old_parent_impl->sorted_children, window);
     }
@@ -1568,14 +1521,12 @@ gdk_window_quartz_reparent (GdkWindow *window,
 static void
 update_toplevel_order (void)
 {
-  GdkWindowObject *root;
   GdkWindowImplQuartz *root_impl;
   NSEnumerator *enumerator;
   id nswindow;
   GList *toplevels = NULL;
 
-  root = GDK_WINDOW_OBJECT (_gdk_root);
-  root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
+  root_impl = GDK_WINDOW_IMPL_QUARTZ (_gdk_root->impl);
 
   if (root_impl->sorted_children)
     return;
@@ -1602,11 +1553,9 @@ update_toplevel_order (void)
 static void
 clear_toplevel_order (void)
 {
-  GdkWindowObject *root;
   GdkWindowImplQuartz *root_impl;
 
-  root = GDK_WINDOW_OBJECT (_gdk_root);
-  root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
+  root_impl = GDK_WINDOW_IMPL_QUARTZ (_gdk_root->impl);
 
   g_list_free (root_impl->sorted_children);
   root_impl->sorted_children = NULL;
@@ -1622,14 +1571,14 @@ gdk_window_quartz_raise (GdkWindow *window)
     {
       GdkWindowImplQuartz *impl;
 
-      impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+      impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
       [impl->toplevel orderFront:impl->toplevel];
 
       clear_toplevel_order ();
     }
   else
     {
-      GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
+      GdkWindow *parent = window->parent;
 
       if (parent)
         {
@@ -1653,14 +1602,14 @@ gdk_window_quartz_lower (GdkWindow *window)
     {
       GdkWindowImplQuartz *impl;
 
-      impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+      impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
       [impl->toplevel orderBack:impl->toplevel];
 
       clear_toplevel_order ();
     }
   else
     {
-      GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
+      GdkWindow *parent = window->parent;
 
       if (parent)
         {
@@ -1679,12 +1628,23 @@ gdk_window_quartz_restack_toplevel (GdkWindow *window,
                                    GdkWindow *sibling,
                                    gboolean   above)
 {
-  /* FIXME: Implement this */
+  GdkWindowImplQuartz *impl;
+  gint sibling_num;
+
+  impl = GDK_WINDOW_IMPL_QUARTZ (sibling->impl);
+  sibling_num = [impl->toplevel windowNumber];
+
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+  if (above)
+    [impl->toplevel orderWindow:NSWindowAbove relativeTo:sibling_num];
+  else
+    [impl->toplevel orderWindow:NSWindowBelow relativeTo:sibling_num];
 }
 
 static void
-gdk_window_quartz_set_background (GdkWindow      *window,
-                                  const GdkColor *color)
+gdk_window_quartz_set_background (GdkWindow       *window,
+                                  cairo_pattern_t *pattern)
 {
   /* FIXME: We could theoretically set the background color for toplevels
    * here. (Currently we draw the background before emitting expose events)
@@ -1692,30 +1652,16 @@ gdk_window_quartz_set_background (GdkWindow      *window,
 }
 
 static void
-gdk_window_quartz_set_back_pixmap (GdkWindow *window,
-                                   GdkPixmap *pixmap)
-{
-  /* FIXME: Could theoretically set some background image here. (Currently
-   * the back pixmap is drawn before emitting expose events.
-   */
-}
-
-static void
-gdk_window_quartz_set_cursor (GdkWindow *window,
-                              GdkCursor *cursor)
+gdk_window_quartz_set_device_cursor (GdkWindow *window,
+                                     GdkDevice *device,
+                                     GdkCursor *cursor)
 {
-  GdkCursorPrivate *cursor_private;
   NSCursor *nscursor;
 
-  cursor_private = (GdkCursorPrivate *)cursor;
-
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  if (!cursor)
-    nscursor = [NSCursor arrowCursor];
-  else 
-    nscursor = cursor_private->nscursor;
+  nscursor = _gdk_quartz_cursor_get_ns_cursor (cursor);
 
   [nscursor set];
 }
@@ -1725,18 +1671,15 @@ gdk_window_quartz_get_geometry (GdkWindow *window,
                                 gint      *x,
                                 gint      *y,
                                 gint      *width,
-                                gint      *height,
-                                gint      *depth)
+                                gint      *height)
 {
   GdkWindowImplQuartz *impl;
-  GdkWindowObject *private;
   NSRect ns_rect;
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
-  private = GDK_WINDOW_OBJECT (window);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   if (window == _gdk_root)
     {
       if (x) 
@@ -1745,9 +1688,9 @@ gdk_window_quartz_get_geometry (GdkWindow *window,
         *y = 0;
 
       if (width) 
-        *width = private->width;
+        *width = window->width;
       if (height)
-        *height = private->height;
+        *height = window->height;
     }
   else if (WINDOW_IS_TOPLEVEL (window))
     {
@@ -1793,9 +1736,6 @@ gdk_window_quartz_get_geometry (GdkWindow *window,
       if (height)
         *height = ns_rect.size.height;
     }
-    
-  if (depth)
-      *depth = gdk_drawable_get_depth (window);
 }
 
 static gint
@@ -1805,7 +1745,6 @@ gdk_window_quartz_get_root_coords (GdkWindow *window,
                                    gint      *root_x,
                                    gint      *root_y)
 {
-  GdkWindowObject *private;
   int tmp_x = 0, tmp_y = 0;
   GdkWindow *toplevel;
   NSRect content_rect;
@@ -1831,10 +1770,8 @@ gdk_window_quartz_get_root_coords (GdkWindow *window,
       return 1;
     }
   
-  private = GDK_WINDOW_OBJECT (window);
-
   toplevel = gdk_window_get_toplevel (window);
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
 
   content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
 
@@ -1845,15 +1782,15 @@ gdk_window_quartz_get_root_coords (GdkWindow *window,
   tmp_x += x;
   tmp_y += y;
 
-  while (private != GDK_WINDOW_OBJECT (toplevel))
+  while (window != toplevel)
     {
-      if (_gdk_window_has_impl ((GdkWindow *)private))
+      if (_gdk_window_has_impl ((GdkWindow *)window))
         {
-          tmp_x += private->x;
-          tmp_y += private->y;
+          tmp_x += window->x;
+          tmp_y += window->y;
         }
 
-      private = private->parent;
+      window = window->parent;
     }
 
   if (root_x)
@@ -1864,18 +1801,10 @@ gdk_window_quartz_get_root_coords (GdkWindow *window,
   return TRUE;
 }
 
-static gboolean
-gdk_window_quartz_get_deskrelative_origin (GdkWindow *window,
-                                           gint      *x,
-                                           gint      *y)
-{
-  return gdk_window_get_origin (window, x, y);
-}
-
-void
-gdk_window_get_root_origin (GdkWindow *window,
-                           gint      *x,
-                           gint      *y)
+static void
+gdk_quartz_window_get_root_origin (GdkWindow *window,
+                                   gint      *x,
+                                   gint      *y)
 {
   GdkRectangle rect;
 
@@ -1893,15 +1822,15 @@ gdk_window_get_root_origin (GdkWindow *window,
 
 /* Returns coordinates relative to the passed in window. */
 static GdkWindow *
-gdk_window_quartz_get_pointer_helper (GdkWindow       *window,
-                                      gint            *x,
-                                      gint            *y,
-                                      GdkModifierType *mask)
+gdk_window_quartz_get_device_state_helper (GdkWindow       *window,
+                                           GdkDevice       *device,
+                                           gint            *x,
+                                           gint            *y,
+                                           GdkModifierType *mask)
 {
-  GdkWindowObject *toplevel;
-  GdkWindowObject *private;
   NSPoint point;
   gint x_tmp, y_tmp;
+  GdkWindow *toplevel;
   GdkWindow *found_window;
 
   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
@@ -1914,9 +1843,10 @@ gdk_window_quartz_get_pointer_helper (GdkWindow       *window,
       return NULL;
     }
   
-  toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (window));
+  toplevel = gdk_window_get_toplevel (window);
 
-  *mask = _gdk_quartz_events_get_current_event_mask ();
+  *mask = _gdk_quartz_events_get_current_keyboard_modifiers () |
+      _gdk_quartz_events_get_current_mouse_modifiers ();
 
   /* Get the y coordinate, needs to be flipped. */
   if (window == _gdk_root)
@@ -1930,18 +1860,18 @@ gdk_window_quartz_get_pointer_helper (GdkWindow       *window,
       NSWindow *nswindow;
 
       impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
-      private = GDK_WINDOW_OBJECT (toplevel);
       nswindow = impl->toplevel;
 
       point = [nswindow mouseLocationOutsideOfEventStream];
 
       x_tmp = point.x;
-      y_tmp = private->height - point.y;
+      y_tmp = toplevel->height - point.y;
 
       window = (GdkWindow *)toplevel;
     }
 
-  found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp);
+  found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
+                                                FALSE);
 
   /* We never return the root window. */
   if (found_window == _gdk_root)
@@ -1954,35 +1884,30 @@ gdk_window_quartz_get_pointer_helper (GdkWindow       *window,
 }
 
 static gboolean
-gdk_window_quartz_get_pointer (GdkWindow       *window,
-                               gint            *x,
-                               gint            *y,
-                               GdkModifierType *mask)
+gdk_window_quartz_get_device_state (GdkWindow       *window,
+                                    GdkDevice       *device,
+                                    gint            *x,
+                                    gint            *y,
+                                    GdkModifierType *mask)
 {
-  return gdk_window_quartz_get_pointer_helper (window, x, y, mask) != NULL;
+  return gdk_window_quartz_get_device_state_helper (window,
+                                                    device,
+                                                    x, y, mask) != NULL;
 }
 
 /* Returns coordinates relative to the root. */
 void
-_gdk_windowing_get_pointer (GdkDisplay       *display,
-                            GdkScreen       **screen,
-                            gint             *x,
-                            gint             *y,
-                            GdkModifierType  *mask)
+_gdk_windowing_get_device_state (GdkDisplay       *display,
+                                 GdkDevice        *device,
+                                 GdkScreen       **screen,
+                                 gint             *x,
+                                 gint             *y,
+                                 GdkModifierType  *mask)
 {
   g_return_if_fail (display == _gdk_display);
   
   *screen = _gdk_screen;
-  gdk_window_quartz_get_pointer_helper (_gdk_root, x, y, mask);
-}
-
-void
-gdk_display_warp_pointer (GdkDisplay *display,
-                         GdkScreen  *screen,
-                         gint        x,
-                         gint        y)
-{
-  CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
+  gdk_window_quartz_get_device_state_helper (_gdk_root, device, x, y, mask);
 }
 
 /* Returns coordinates relative to the found window. */
@@ -1997,23 +1922,21 @@ _gdk_windowing_window_at_pointer (GdkDisplay      *display,
   gint x, y;
   GdkModifierType tmp_mask = 0;
 
-  found_window = gdk_window_quartz_get_pointer_helper (_gdk_root,
-                                                       &x, &y,
-                                                       &tmp_mask);
+  found_window = gdk_window_quartz_get_device_state_helper (_gdk_root,
+                                                            display->core_pointer,
+                                                            &x, &y,
+                                                            &tmp_mask);
   if (found_window)
     {
-      GdkWindowObject *private;
-
       /* The coordinates returned above are relative the root, we want
        * coordinates relative the window here. 
        */
-      private = GDK_WINDOW_OBJECT (found_window);
-      while (private != GDK_WINDOW_OBJECT (_gdk_root))
+      while (found_window != _gdk_root)
        {
-         x -= private->x;
-         y -= private->y;
+         x -= found_window->x;
+         y -= found_window->y;
          
-         private = private->parent;
+         found_window = found_window->parent;
        }
 
       *win_x = x;
@@ -2031,34 +1954,47 @@ _gdk_windowing_window_at_pointer (GdkDisplay      *display,
 
   if (get_toplevel)
     {
-      GdkWindowObject *w = (GdkWindowObject *)found_window;
       /* Requested toplevel, find it. */
       /* TODO: This can be implemented more efficient by never
         recursing into children in the first place */
-      if (w)
+      if (found_window)
        {
          /* Convert to toplevel */
-         while (w->parent != NULL &&
-                w->parent->window_type != GDK_WINDOW_ROOT)
+         while (found_window->parent != NULL &&
+                found_window->parent->window_type != GDK_WINDOW_ROOT)
            {
-             *win_x += w->x;
-             *win_y += w->y;
-             w = w->parent;
+             *win_x += found_window->x;
+             *win_y += found_window->y;
+             found_window = found_window->parent;
            }
-         found_window = (GdkWindow *)w;
        }
     }
 
   return found_window;
 }
 
+GdkWindow*
+_gdk_windowing_window_at_device_position (GdkDisplay      *display,
+                                          GdkDevice       *device,
+                                          gint            *win_x,
+                                          gint            *win_y,
+                                          GdkModifierType *mask,
+                                          gboolean         get_toplevel)
+{
+  return GDK_DEVICE_GET_CLASS (device)->window_at_position (device,
+                                                            win_x, win_y,
+                                                            mask,
+                                                            get_toplevel);
+}
+
+
 static GdkEventMask  
 gdk_window_quartz_get_events (GdkWindow *window)
 {
   if (GDK_WINDOW_DESTROYED (window))
     return 0;
   else
-    return GDK_WINDOW_OBJECT (window)->event_mask;
+    return window->event_mask;
 }
 
 static void
@@ -2068,9 +2004,9 @@ gdk_window_quartz_set_events (GdkWindow       *window,
   /* The mask is set in the common code. */
 }
 
-void
-gdk_window_set_urgency_hint (GdkWindow *window,
-                            gboolean   urgent)
+static void
+gdk_quartz_window_set_urgency_hint (GdkWindow *window,
+                                    gboolean   urgent)
 {
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
@@ -2079,10 +2015,10 @@ gdk_window_set_urgency_hint (GdkWindow *window,
   /* FIXME: Implement */
 }
 
-void 
-gdk_window_set_geometry_hints (GdkWindow         *window,
-                              const GdkGeometry *geometry,
-                              GdkWindowHints     geom_mask)
+static void
+gdk_quartz_window_set_geometry_hints (GdkWindow         *window,
+                                      const GdkGeometry *geometry,
+                                      GdkWindowHints     geom_mask)
 {
   GdkWindowImplQuartz *impl;
 
@@ -2092,7 +2028,7 @@ gdk_window_set_geometry_hints (GdkWindow         *window,
       !WINDOW_IS_TOPLEVEL (window))
     return;
   
-  impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   if (!impl->toplevel)
     return;
 
@@ -2157,9 +2093,9 @@ gdk_window_set_geometry_hints (GdkWindow         *window,
     }
 }
 
-void
-gdk_window_set_title (GdkWindow   *window,
-                     const gchar *title)
+static void
+gdk_quartz_window_set_title (GdkWindow   *window,
+                             const gchar *title)
 {
   GdkWindowImplQuartz *impl;
 
@@ -2169,7 +2105,7 @@ gdk_window_set_title (GdkWindow   *window,
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (impl->toplevel)
     {
@@ -2179,9 +2115,9 @@ gdk_window_set_title (GdkWindow   *window,
     }
 }
 
-void          
-gdk_window_set_role (GdkWindow   *window,
-                    const gchar *role)
+static void
+gdk_quartz_window_set_role (GdkWindow   *window,
+                            const gchar *role)
 {
   if (GDK_WINDOW_DESTROYED (window) ||
       WINDOW_IS_TOPLEVEL (window))
@@ -2190,9 +2126,16 @@ gdk_window_set_role (GdkWindow   *window,
   /* FIXME: Implement */
 }
 
-void
-gdk_window_set_transient_for (GdkWindow *window, 
-                             GdkWindow *parent)
+static void
+gdk_quartz_window_set_startup_id (GdkWindow   *window,
+                                  const gchar *startup_id)
+{
+  /* FIXME: Implement? */
+}
+
+static void
+gdk_quartz_window_set_transient_for (GdkWindow *window,
+                                     GdkWindow *parent)
 {
   GdkWindowImplQuartz *window_impl;
   GdkWindowImplQuartz *parent_impl;
@@ -2201,7 +2144,7 @@ gdk_window_set_transient_for (GdkWindow *window,
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  window_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  window_impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   if (!window_impl->toplevel)
     return;
 
@@ -2215,7 +2158,7 @@ gdk_window_set_transient_for (GdkWindow *window,
       window_impl->transient_for = NULL;
     }
 
-  parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl);
+  parent_impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
   if (parent_impl->toplevel)
     {
       /* We save the parent because it needs to be unset/reset when
@@ -2235,7 +2178,7 @@ gdk_window_set_transient_for (GdkWindow *window,
            * be shown unconditionally here. If it is not shown, the
            * window will be added in show() instead.
            */
-          if (!(GDK_WINDOW_OBJECT (window)->state & GDK_WINDOW_STATE_WITHDRAWN))
+          if (!(window->state & GDK_WINDOW_STATE_WITHDRAWN))
             _gdk_quartz_window_attach_to_parent (window);
         }
     }
@@ -2245,7 +2188,7 @@ gdk_window_set_transient_for (GdkWindow *window,
 
 static void
 gdk_window_quartz_shape_combine_region (GdkWindow       *window,
-                                        const GdkRegion *shape,
+                                        const cairo_region_t *shape,
                                         gint             x,
                                         gint             y)
 {
@@ -2254,29 +2197,25 @@ gdk_window_quartz_shape_combine_region (GdkWindow       *window,
 
 static void
 gdk_window_quartz_input_shape_combine_region (GdkWindow       *window,
-                                              const GdkRegion *shape_region,
+                                              const cairo_region_t *shape_region,
                                               gint             offset_x,
                                               gint             offset_y)
 {
   /* FIXME: Implement */
 }
 
-void
-gdk_window_set_override_redirect (GdkWindow *window,
-                                 gboolean override_redirect)
+static void
+gdk_quartz_window_set_override_redirect (GdkWindow *window,
+                                         gboolean override_redirect)
 {
   /* FIXME: Implement */
 }
 
-void
-gdk_window_set_accept_focus (GdkWindow *window,
-                            gboolean accept_focus)
+static void
+gdk_quartz_window_set_accept_focus (GdkWindow *window,
+                                    gboolean accept_focus)
 {
-  GdkWindowObject *private;
-
-  private = (GdkWindowObject *)window;  
-
-  private->accept_focus = accept_focus != FALSE;
+  window->accept_focus = accept_focus != FALSE;
 }
 
 static gboolean 
@@ -2291,48 +2230,83 @@ gdk_window_quartz_set_static_gravities (GdkWindow *window,
   return FALSE;
 }
 
-void
-gdk_window_set_focus_on_map (GdkWindow *window,
-                            gboolean focus_on_map)
+static gboolean
+gdk_quartz_window_queue_antiexpose (GdkWindow *window,
+                                    cairo_region_t *area)
+{
+  return FALSE;
+}
+
+static void
+gdk_quartz_window_translate (GdkWindow      *window,
+                             cairo_region_t *area,
+                             gint            dx,
+                             gint            dy)
 {
-  GdkWindowObject *private;
+  cairo_region_t *invalidate, *scrolled;
+  GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *)window->impl;
+  GdkRectangle extents;
 
-  private = (GdkWindowObject *)window;  
-  
-  private->focus_on_map = focus_on_map != FALSE;
+  cairo_region_get_extents (area, &extents);
+
+  [impl->view scrollRect:NSMakeRect (extents.x - dx, extents.y - dy,
+                                     extents.width, extents.height)
+              by:NSMakeSize (dx, dy)];
+
+  if (impl->needs_display_region)
+    {
+      cairo_region_t *intersection;
+
+      /* Invalidate already invalidated area that was moved at new
+       * location.
+       */
+      intersection = cairo_region_copy (impl->needs_display_region);
+      cairo_region_intersect (intersection, area);
+      cairo_region_translate (intersection, dx, dy);
+
+      gdk_quartz_window_set_needs_display_in_region (window, intersection);
+      cairo_region_destroy (intersection);
+    }
+
+  /* Calculate newly exposed area that needs invalidation */
+  scrolled = cairo_region_copy (area);
+  cairo_region_translate (scrolled, dx, dy);
+
+  invalidate = cairo_region_copy (area);
+  cairo_region_subtract (invalidate, scrolled);
+  cairo_region_destroy (scrolled);
+
+  gdk_quartz_window_set_needs_display_in_region (window, invalidate);
+  cairo_region_destroy (invalidate);
 }
 
-void          
-gdk_window_set_icon (GdkWindow *window, 
-                    GdkWindow *icon_window,
-                    GdkPixmap *pixmap,
-                    GdkBitmap *mask)
+static void
+gdk_quartz_window_set_focus_on_map (GdkWindow *window,
+                                    gboolean focus_on_map)
 {
-  /* FIXME: Implement */
+  window->focus_on_map = focus_on_map != FALSE;
 }
 
-void          
-gdk_window_set_icon_name (GdkWindow   *window, 
-                         const gchar *name)
+static void
+gdk_quartz_window_set_icon_name (GdkWindow   *window,
+                                 const gchar *name)
 {
   /* FIXME: Implement */
 }
 
-void
-gdk_window_focus (GdkWindow *window,
-                  guint32    timestamp)
+static void
+gdk_quartz_window_focus (GdkWindow *window,
+                         guint32    timestamp)
 {
-  GdkWindowObject *private;
   GdkWindowImplQuartz *impl;
        
-  private = (GdkWindowObject*) window;
-  impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  if (private->accept_focus && private->window_type != GDK_WINDOW_TEMP)
+  if (window->accept_focus && window->window_type != GDK_WINDOW_TEMP)
     {
       GDK_QUARTZ_ALLOC_POOL;
       [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
@@ -2341,28 +2315,31 @@ gdk_window_focus (GdkWindow *window,
     }
 }
 
-static
-gint window_type_hint_to_level (GdkWindowTypeHint hint)
+static gint
+window_type_hint_to_level (GdkWindowTypeHint hint)
 {
+  /*  the order in this switch statement corresponds to the actual
+   *  stacking order: the first group is top, the last group is bottom
+   */
   switch (hint)
     {
-    case GDK_WINDOW_TYPE_HINT_DOCK:
-    case GDK_WINDOW_TYPE_HINT_UTILITY:
-      return NSFloatingWindowLevel;
+    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
+    case GDK_WINDOW_TYPE_HINT_COMBO:
+    case GDK_WINDOW_TYPE_HINT_DND:
+    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+      return NSPopUpMenuWindowLevel;
+
+    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+      return NSStatusWindowLevel;
 
     case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
     case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
       return NSTornOffMenuWindowLevel;
 
-    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
-    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
-      return NSStatusWindowLevel;
-
-    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
-    case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
-    case GDK_WINDOW_TYPE_HINT_COMBO:
-    case GDK_WINDOW_TYPE_HINT_DND:
-      return NSPopUpMenuWindowLevel;
+    case GDK_WINDOW_TYPE_HINT_DOCK:
+    case GDK_WINDOW_TYPE_HINT_UTILITY:
+      return NSFloatingWindowLevel;
 
     case GDK_WINDOW_TYPE_HINT_NORMAL:  /* Normal toplevel window */
     case GDK_WINDOW_TYPE_HINT_DIALOG:  /* Dialog window */
@@ -2377,7 +2354,7 @@ gint window_type_hint_to_level (GdkWindowTypeHint hint)
   return NSNormalWindowLevel;
 }
 
-static gboolean 
+static gboolean
 window_type_hint_to_shadow (GdkWindowTypeHint hint)
 {
   switch (hint)
@@ -2407,18 +2384,36 @@ window_type_hint_to_shadow (GdkWindowTypeHint hint)
   return FALSE;
 }
 
+static gboolean
+window_type_hint_to_hides_on_deactivate (GdkWindowTypeHint hint)
+{
+  switch (hint)
+    {
+    case GDK_WINDOW_TYPE_HINT_UTILITY:
+    case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
+    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+    case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+    case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+      return TRUE;
+
+    default:
+      break;
+    }
 
-void
-gdk_window_set_type_hint (GdkWindow        *window,
-                         GdkWindowTypeHint hint)
+  return FALSE;
+}
+
+static void
+gdk_quartz_window_set_type_hint (GdkWindow        *window,
+                                 GdkWindowTypeHint hint)
 {
   GdkWindowImplQuartz *impl;
-  
+
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   impl->type_hint = hint;
 
@@ -2428,21 +2423,22 @@ gdk_window_set_type_hint (GdkWindow        *window,
 
   [impl->toplevel setHasShadow: window_type_hint_to_shadow (hint)];
   [impl->toplevel setLevel: window_type_hint_to_level (hint)];
+  [impl->toplevel setHidesOnDeactivate: window_type_hint_to_hides_on_deactivate (hint)];
 }
 
-GdkWindowTypeHint
-gdk_window_get_type_hint (GdkWindow *window)
+static GdkWindowTypeHint
+gdk_quartz_window_get_type_hint (GdkWindow *window)
 {
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
     return GDK_WINDOW_TYPE_HINT_NORMAL;
   
-  return GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl)->type_hint;
+  return GDK_WINDOW_IMPL_QUARTZ (window->impl)->type_hint;
 }
 
-void
-gdk_window_set_modal_hint (GdkWindow *window,
-                          gboolean   modal)
+static void
+gdk_quartz_window_set_modal_hint (GdkWindow *window,
+                                  gboolean   modal)
 {
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
@@ -2451,9 +2447,9 @@ gdk_window_set_modal_hint (GdkWindow *window,
   /* FIXME: Implement */
 }
 
-void
-gdk_window_set_skip_taskbar_hint (GdkWindow *window,
-                                 gboolean   skips_taskbar)
+static void
+gdk_quartz_window_set_skip_taskbar_hint (GdkWindow *window,
+                                         gboolean   skips_taskbar)
 {
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
@@ -2462,9 +2458,9 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
   /* FIXME: Implement */
 }
 
-void
-gdk_window_set_skip_pager_hint (GdkWindow *window,
-                               gboolean   skips_pager)
+static void
+gdk_quartz_window_set_skip_pager_hint (GdkWindow *window,
+                                       gboolean   skips_pager)
 {
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
@@ -2473,15 +2469,15 @@ gdk_window_set_skip_pager_hint (GdkWindow *window,
   /* FIXME: Implement */
 }
 
-void
-gdk_window_begin_resize_drag (GdkWindow     *window,
-                              GdkWindowEdge  edge,
-                              gint           button,
-                              gint           root_x,
-                              gint           root_y,
-                              guint32        timestamp)
-{
-  GdkWindowObject *private;
+static void
+gdk_quartz_window_begin_resize_drag (GdkWindow     *window,
+                                     GdkWindowEdge  edge,
+                                     GdkDevice     *device,
+                                     gint           button,
+                                     gint           root_x,
+                                     gint           root_y,
+                                     guint32        timestamp)
+{
   GdkWindowImplQuartz *impl;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -2495,8 +2491,7 @@ gdk_window_begin_resize_drag (GdkWindow     *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  private = GDK_WINDOW_OBJECT (window);
-  impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (!impl->toplevel)
     {
@@ -2504,25 +2499,24 @@ gdk_window_begin_resize_drag (GdkWindow     *window,
       return;
     }
 
-  [(GdkQuartzWindow *)impl->toplevel beginManualResize];
+  [(GdkQuartzNSWindow *)impl->toplevel beginManualResize];
 }
 
-void
-gdk_window_begin_move_drag (GdkWindow *window,
-                            gint       button,
-                            gint       root_x,
-                            gint       root_y,
-                            guint32    timestamp)
+static void
+gdk_quartz_window_begin_move_drag (GdkWindow *window,
+                                   GdkDevice *device,
+                                   gint       button,
+                                   gint       root_x,
+                                   gint       root_y,
+                                   guint32    timestamp)
 {
-  GdkWindowObject *private;
   GdkWindowImplQuartz *impl;
 
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  private = GDK_WINDOW_OBJECT (window);
-  impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (!impl->toplevel)
     {
@@ -2530,36 +2524,34 @@ gdk_window_begin_move_drag (GdkWindow *window,
       return;
     }
 
-  [(GdkQuartzWindow *)impl->toplevel beginManualMove];
+  [(GdkQuartzNSWindow *)impl->toplevel beginManualMove];
 }
 
-void
-gdk_window_set_icon_list (GdkWindow *window,
-                         GList     *pixbufs)
+static void
+gdk_quartz_window_set_icon_list (GdkWindow *window,
+                                 GList     *pixbufs)
 {
   /* FIXME: Implement */
 }
 
-void
-gdk_window_get_frame_extents (GdkWindow    *window,
-                              GdkRectangle *rect)
+static void
+gdk_quartz_window_get_frame_extents (GdkWindow    *window,
+                                     GdkRectangle *rect)
 {
-  GdkWindowObject *private;
   GdkWindow *toplevel;
   GdkWindowImplQuartz *impl;
   NSRect ns_rect;
 
   g_return_if_fail (rect != NULL);
 
-  private = GDK_WINDOW_OBJECT (window);
 
   rect->x = 0;
   rect->y = 0;
   rect->width = 1;
   rect->height = 1;
   
-  toplevel = gdk_window_get_toplevel (window);
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
+  toplevel = gdk_window_get_effective_toplevel (window);
+  impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
 
   ns_rect = [impl->toplevel frame];
 
@@ -2571,8 +2563,16 @@ gdk_window_get_frame_extents (GdkWindow    *window,
   rect->height = ns_rect.size.height;
 }
 
-void
-gdk_window_set_decorations (GdkWindow       *window,
+/* Fake protocol to make gcc think that it's OK to call setStyleMask
+   even if it isn't. We check to make sure before actually calling
+   it. */
+
+@protocol CanSetStyleMask
+- (void)setStyleMask:(int)mask;
+@end
+
+static void
+gdk_quartz_window_set_decorations (GdkWindow       *window,
                            GdkWMDecoration  decorations)
 {
   GdkWindowImplQuartz *impl;
@@ -2583,7 +2583,7 @@ gdk_window_set_decorations (GdkWindow       *window,
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (decorations == 0 || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP ||
       impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN )
@@ -2601,15 +2601,11 @@ gdk_window_set_decorations (GdkWindow       *window,
 
   old_mask = [impl->toplevel styleMask];
 
-  /* Note, there doesn't seem to be a way to change this without
-   * recreating the toplevel. There might be bad side-effects of doing
-   * that, but it seems alright.
-   */
   if (old_mask != new_mask)
     {
       NSRect rect;
 
-      old_view = [impl->toplevel contentView];
+      old_view = [[impl->toplevel contentView] retain];
 
       rect = [impl->toplevel frame];
 
@@ -2628,30 +2624,75 @@ gdk_window_set_decorations (GdkWindow       *window,
           rect = [NSWindow contentRectForFrameRect:rect styleMask:old_mask];
         }
 
-      impl->toplevel = [impl->toplevel initWithContentRect:rect
-                                                 styleMask:new_mask
-                                                   backing:NSBackingStoreBuffered
-                                                     defer:NO];
+      /* Note, before OS 10.6 there doesn't seem to be a way to change this
+       * without recreating the toplevel. From 10.6 onward, a simple call to
+       * setStyleMask takes care of most of this, except for ensuring that the
+       * title is set.
+       */
+      if ([impl->toplevel respondsToSelector:@selector(setStyleMask:)])
+        {
+          NSString *title = [impl->toplevel title];
+
+          [(id<CanSetStyleMask>)impl->toplevel setStyleMask:new_mask];
+
+          /* It appears that unsetting and then resetting NSTitledWindowMask
+           * does not reset the title in the title bar as might be expected.
+           *
+           * In theory we only need to set this if new_mask includes
+           * NSTitledWindowMask. This behaved extremely oddly when
+           * conditionalized upon that and since it has no side effects (i.e.
+           * if NSTitledWindowMask is not requested, the title will not be
+           * displayed) just do it unconditionally. We also must null check
+           * 'title' before setting it to avoid crashing.
+           */
+          if (title)
+            [impl->toplevel setTitle:title];
+        }
+      else
+        {
+          NSString *title = [impl->toplevel title];
+          NSColor *bg = [impl->toplevel backgroundColor];
+          NSScreen *screen = [impl->toplevel screen];
 
-      [impl->toplevel setHasShadow: window_type_hint_to_shadow (impl->type_hint)];
-      [impl->toplevel setLevel: window_type_hint_to_level (impl->type_hint)];
+          /* Make sure the old window is closed, recall that releasedWhenClosed
+           * is set on GdkQuartzWindows.
+           */
+          [impl->toplevel close];
+
+          impl->toplevel = [[GdkQuartzNSWindow alloc] initWithContentRect:rect
+                                                                styleMask:new_mask
+                                                                  backing:NSBackingStoreBuffered
+                                                                    defer:NO
+                                                                   screen:screen];
+          [impl->toplevel setHasShadow: window_type_hint_to_shadow (impl->type_hint)];
+          [impl->toplevel setLevel: window_type_hint_to_level (impl->type_hint)];
+          if (title)
+            [impl->toplevel setTitle:title];
+          [impl->toplevel setBackgroundColor:bg];
+          [impl->toplevel setHidesOnDeactivate: window_type_hint_to_hides_on_deactivate (impl->type_hint)];
+          [impl->toplevel setContentView:old_view];
+        }
 
-      [impl->toplevel setContentView:old_view];
-      [impl->toplevel setFrame:rect display:YES];
+      if (new_mask == NSBorderlessWindowMask)
+        [impl->toplevel setContentSize:rect.size];
+      else
+        [impl->toplevel setFrame:rect display:YES];
 
       /* Invalidate the window shadow for non-opaque views that have shadow
        * enabled, to get the shadow shape updated.
        */
       if (![old_view isOpaque] && [impl->toplevel hasShadow])
         [(GdkQuartzView*)old_view setNeedsInvalidateShadow:YES];
+
+      [old_view release];
     }
 
   GDK_QUARTZ_RELEASE_POOL;
 }
 
-gboolean
-gdk_window_get_decorations (GdkWindow       *window,
-                           GdkWMDecoration *decorations)
+static gboolean
+gdk_quartz_window_get_decorations (GdkWindow       *window,
+                                   GdkWMDecoration *decorations)
 {
   GdkWindowImplQuartz *impl;
 
@@ -2659,7 +2700,7 @@ gdk_window_get_decorations (GdkWindow       *window,
       !WINDOW_IS_TOPLEVEL (window))
     return FALSE;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (decorations)
     {
@@ -2678,9 +2719,9 @@ gdk_window_get_decorations (GdkWindow       *window,
   return TRUE;
 }
 
-void
-gdk_window_set_functions (GdkWindow    *window,
-                         GdkWMFunction functions)
+static void
+gdk_quartz_window_set_functions (GdkWindow    *window,
+                                 GdkWMFunction functions)
 {
   g_return_if_fail (GDK_IS_WINDOW (window));
 
@@ -2689,29 +2730,29 @@ gdk_window_set_functions (GdkWindow    *window,
 
 gboolean
 _gdk_windowing_window_queue_antiexpose (GdkWindow  *window,
-                                       GdkRegion  *area)
+                                       cairo_region_t  *area)
 {
   return FALSE;
 }
 
-void
-gdk_window_stick (GdkWindow *window)
+static void
+gdk_quartz_window_stick (GdkWindow *window)
 {
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
     return;
 }
 
-void
-gdk_window_unstick (GdkWindow *window)
+static void
+gdk_quartz_window_unstick (GdkWindow *window)
 {
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
     return;
 }
 
-void
-gdk_window_maximize (GdkWindow *window)
+static void
+gdk_quartz_window_maximize (GdkWindow *window)
 {
   GdkWindowImplQuartz *impl;
 
@@ -2719,7 +2760,7 @@ gdk_window_maximize (GdkWindow *window)
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (GDK_WINDOW_IS_MAPPED (window))
     {
@@ -2738,8 +2779,8 @@ gdk_window_maximize (GdkWindow *window)
     }
 }
 
-void
-gdk_window_unmaximize (GdkWindow *window)
+static void
+gdk_quartz_window_unmaximize (GdkWindow *window)
 {
   GdkWindowImplQuartz *impl;
 
@@ -2747,7 +2788,7 @@ gdk_window_unmaximize (GdkWindow *window)
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (GDK_WINDOW_IS_MAPPED (window))
     {
@@ -2766,8 +2807,8 @@ gdk_window_unmaximize (GdkWindow *window)
     }
 }
 
-void
-gdk_window_iconify (GdkWindow *window)
+static void
+gdk_quartz_window_iconify (GdkWindow *window)
 {
   GdkWindowImplQuartz *impl;
 
@@ -2775,7 +2816,7 @@ gdk_window_iconify (GdkWindow *window)
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (GDK_WINDOW_IS_MAPPED (window))
     {
@@ -2794,8 +2835,8 @@ gdk_window_iconify (GdkWindow *window)
     }
 }
 
-void
-gdk_window_deiconify (GdkWindow *window)
+static void
+gdk_quartz_window_deiconify (GdkWindow *window)
 {
   GdkWindowImplQuartz *impl;
 
@@ -2803,7 +2844,7 @@ gdk_window_deiconify (GdkWindow *window)
       !WINDOW_IS_TOPLEVEL (window))
     return;
 
-  impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+  impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
 
   if (GDK_WINDOW_IS_MAPPED (window))
     {
@@ -2828,11 +2869,11 @@ get_fullscreen_geometry (GdkWindow *window)
   return g_object_get_data (G_OBJECT (window), FULLSCREEN_DATA);
 }
 
-void
-gdk_window_fullscreen (GdkWindow *window)
+static void
+gdk_quartz_window_fullscreen (GdkWindow *window)
 {
   FullscreenSavedGeometry *geometry;
-  GdkWindowObject *private = (GdkWindowObject *) window;
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   NSRect frame;
 
   if (GDK_WINDOW_DESTROYED (window) ||
@@ -2844,10 +2885,10 @@ gdk_window_fullscreen (GdkWindow *window)
     {
       geometry = g_new (FullscreenSavedGeometry, 1);
 
-      geometry->x = private->x;
-      geometry->y = private->y;
-      geometry->width = private->width;
-      geometry->height = private->height;
+      geometry->x = window->x;
+      geometry->y = window->y;
+      geometry->width = window->width;
+      geometry->height = window->height;
 
       if (!gdk_window_get_decorations (window, &geometry->decor))
         geometry->decor = GDK_DECOR_ALL;
@@ -2858,10 +2899,14 @@ gdk_window_fullscreen (GdkWindow *window)
 
       gdk_window_set_decorations (window, 0);
 
-      frame = [[NSScreen mainScreen] frame];
+      frame = [[impl->toplevel screen] frame];
       move_resize_window_internal (window,
                                    0, 0, 
                                    frame.size.width, frame.size.height);
+      [impl->toplevel setContentSize:frame.size];
+      [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
+
+      clear_toplevel_order ();
     }
 
   SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar);
@@ -2869,9 +2914,10 @@ gdk_window_fullscreen (GdkWindow *window)
   gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
 }
 
-void
-gdk_window_unfullscreen (GdkWindow *window)
+static void
+gdk_quartz_window_unfullscreen (GdkWindow *window)
 {
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   FullscreenSavedGeometry *geometry;
 
   if (GDK_WINDOW_DESTROYED (window) ||
@@ -2893,15 +2939,18 @@ gdk_window_unfullscreen (GdkWindow *window)
 
       g_object_set_data (G_OBJECT (window), FULLSCREEN_DATA, NULL);
 
+      [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
+      clear_toplevel_order ();
+
       gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
     }
 }
 
-void
-gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
+static void
+gdk_quartz_window_set_keep_above (GdkWindow *window,
+                                  gboolean   setting)
 {
-  GdkWindowObject *private = (GdkWindowObject *) window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   gint level;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -2916,11 +2965,11 @@ gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
   [impl->toplevel setLevel: level + (setting ? 1 : 0)];
 }
 
-void
-gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
+static void
+gdk_quartz_window_set_keep_below (GdkWindow *window,
+                                  gboolean   setting)
 {
-  GdkWindowObject *private = (GdkWindowObject *) window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
   gint level;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
@@ -2935,8 +2984,8 @@ gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
   [impl->toplevel setLevel: level - (setting ? 1 : 0)];
 }
 
-GdkWindow *
-gdk_window_get_group (GdkWindow *window)
+static GdkWindow *
+gdk_quartz_window_get_group (GdkWindow *window)
 {
   g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
 
@@ -2949,133 +2998,285 @@ gdk_window_get_group (GdkWindow *window)
   return NULL;
 }
 
-void          
-gdk_window_set_group (GdkWindow *window, 
-                     GdkWindow *leader)
+static void
+gdk_quartz_window_set_group (GdkWindow *window,
+                             GdkWindow *leader)
 {
   /* FIXME: Implement */       
 }
 
-GdkWindow*
-gdk_window_foreign_new_for_display (GdkDisplay      *display,
-                                   GdkNativeWindow  anid)
+static void
+gdk_quartz_window_destroy_notify (GdkWindow *window)
 {
-  /* Foreign windows aren't supported in Mac OS X */
-  return NULL;
+  check_grab_destroy (window);
 }
 
-GdkWindow*
-gdk_window_lookup (GdkNativeWindow anid)
+static void
+gdk_quartz_window_set_opacity (GdkWindow *window,
+                               gdouble    opacity)
 {
-  /* Foreign windows aren't supported in Mac OS X */
-  return NULL;
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (window->impl);
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
+
+  if (GDK_WINDOW_DESTROYED (window) ||
+      !WINDOW_IS_TOPLEVEL (window))
+    return;
+
+  if (opacity < 0)
+    opacity = 0;
+  else if (opacity > 1)
+    opacity = 1;
+
+  [impl->toplevel setAlphaValue: opacity];
 }
 
-GdkWindow *
-gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
+static cairo_region_t *
+gdk_quartz_window_get_shape (GdkWindow *window)
 {
-  /* Foreign windows aren't supported in Mac OS X */
+  /* FIXME: implement */
   return NULL;
 }
 
-void
-gdk_window_enable_synchronized_configure (GdkWindow *window)
+static cairo_region_t *
+gdk_quartz_window_get_input_shape (GdkWindow *window)
 {
+  /* FIXME: implement */
+  return NULL;
 }
 
-void
-gdk_window_configure_finished (GdkWindow *window)
+
+static void
+gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
+  GdkWindowImplQuartzClass *impl_quartz_class = GDK_WINDOW_IMPL_QUARTZ_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize = gdk_window_impl_quartz_finalize;
+
+  impl_class->ref_cairo_surface = gdk_quartz_ref_cairo_surface;
+  impl_class->show = gdk_window_quartz_show;
+  impl_class->hide = gdk_window_quartz_hide;
+  impl_class->withdraw = gdk_window_quartz_withdraw;
+  impl_class->set_events = gdk_window_quartz_set_events;
+  impl_class->get_events = gdk_window_quartz_get_events;
+  impl_class->raise = gdk_window_quartz_raise;
+  impl_class->lower = gdk_window_quartz_lower;
+  impl_class->restack_toplevel = gdk_window_quartz_restack_toplevel;
+  impl_class->move_resize = gdk_window_quartz_move_resize;
+  impl_class->set_background = gdk_window_quartz_set_background;
+  impl_class->reparent = gdk_window_quartz_reparent;
+  impl_class->set_device_cursor = gdk_window_quartz_set_device_cursor;
+  impl_class->get_geometry = gdk_window_quartz_get_geometry;
+  impl_class->get_root_coords = gdk_window_quartz_get_root_coords;
+  impl_class->get_device_state = gdk_window_quartz_get_device_state;
+  impl_class->shape_combine_region = gdk_window_quartz_shape_combine_region;
+  impl_class->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
+  impl_class->set_static_gravities = gdk_window_quartz_set_static_gravities;
+  impl_class->queue_antiexpose = gdk_quartz_window_queue_antiexpose;
+  impl_class->translate = gdk_quartz_window_translate;
+  impl_class->destroy = gdk_quartz_window_destroy;
+  impl_class->destroy_foreign = gdk_quartz_window_destroy_foreign;
+  impl_class->resize_cairo_surface = gdk_window_quartz_resize_cairo_surface;
+  impl_class->get_shape = gdk_quartz_window_get_shape;
+  impl_class->get_input_shape = gdk_quartz_window_get_input_shape;
+
+  impl_class->focus = gdk_quartz_window_focus;
+  impl_class->set_type_hint = gdk_quartz_window_set_type_hint;
+  impl_class->get_type_hint = gdk_quartz_window_get_type_hint;
+  impl_class->set_modal_hint = gdk_quartz_window_set_modal_hint;
+  impl_class->set_skip_taskbar_hint = gdk_quartz_window_set_skip_taskbar_hint;
+  impl_class->set_skip_pager_hint = gdk_quartz_window_set_skip_pager_hint;
+  impl_class->set_urgency_hint = gdk_quartz_window_set_urgency_hint;
+  impl_class->set_geometry_hints = gdk_quartz_window_set_geometry_hints;
+  impl_class->set_title = gdk_quartz_window_set_title;
+  impl_class->set_role = gdk_quartz_window_set_role;
+  impl_class->set_startup_id = gdk_quartz_window_set_startup_id;
+  impl_class->set_transient_for = gdk_quartz_window_set_transient_for;
+  impl_class->get_root_origin = gdk_quartz_window_get_root_origin;
+  impl_class->get_frame_extents = gdk_quartz_window_get_frame_extents;
+  impl_class->set_override_redirect = gdk_quartz_window_set_override_redirect;
+  impl_class->set_accept_focus = gdk_quartz_window_set_accept_focus;
+  impl_class->set_focus_on_map = gdk_quartz_window_set_focus_on_map;
+  impl_class->set_icon_list = gdk_quartz_window_set_icon_list;
+  impl_class->set_icon_name = gdk_quartz_window_set_icon_name;
+  impl_class->iconify = gdk_quartz_window_iconify;
+  impl_class->deiconify = gdk_quartz_window_deiconify;
+  impl_class->stick = gdk_quartz_window_stick;
+  impl_class->unstick = gdk_quartz_window_unstick;
+  impl_class->maximize = gdk_quartz_window_maximize;
+  impl_class->unmaximize = gdk_quartz_window_unmaximize;
+  impl_class->fullscreen = gdk_quartz_window_fullscreen;
+  impl_class->unfullscreen = gdk_quartz_window_unfullscreen;
+  impl_class->set_keep_above = gdk_quartz_window_set_keep_above;
+  impl_class->set_keep_below = gdk_quartz_window_set_keep_below;
+  impl_class->get_group = gdk_quartz_window_get_group;
+  impl_class->set_group = gdk_quartz_window_set_group;
+  impl_class->set_decorations = gdk_quartz_window_set_decorations;
+  impl_class->get_decorations = gdk_quartz_window_get_decorations;
+  impl_class->set_functions = gdk_quartz_window_set_functions;
+  impl_class->set_functions = gdk_quartz_window_set_functions;
+  impl_class->begin_resize_drag = gdk_quartz_window_begin_resize_drag;
+  impl_class->begin_move_drag = gdk_quartz_window_begin_move_drag;
+  impl_class->set_opacity = gdk_quartz_window_set_opacity;
+  impl_class->destroy_notify = gdk_quartz_window_destroy_notify;
+  impl_class->register_dnd = _gdk_quartz_window_register_dnd;
+  impl_class->drag_begin = _gdk_quartz_window_drag_begin;
+  impl_class->process_updates_recurse = _gdk_quartz_window_process_updates_recurse;
+  impl_class->sync_rendering = _gdk_quartz_window_sync_rendering;
+  impl_class->simulate_key = _gdk_quartz_window_simulate_key;
+  impl_class->simulate_button = _gdk_quartz_window_simulate_button;
+  impl_class->get_property = _gdk_quartz_window_get_property;
+  impl_class->change_property = _gdk_quartz_window_change_property;
+  impl_class->delete_property = _gdk_quartz_window_delete_property;
+
+
+  impl_quartz_class->get_context = gdk_window_impl_quartz_get_context;
+  impl_quartz_class->release_context = gdk_window_impl_quartz_release_context;
 }
 
-void
-gdk_window_destroy_notify (GdkWindow *window)
+GType
+_gdk_window_impl_quartz_get_type (void)
 {
-  check_grab_destroy (window);
+  static GType object_type = 0;
+
+  if (!object_type)
+    {
+      const GTypeInfo object_info =
+       {
+         sizeof (GdkWindowImplQuartzClass),
+         (GBaseInitFunc) NULL,
+         (GBaseFinalizeFunc) NULL,
+         (GClassInitFunc) gdk_window_impl_quartz_class_init,
+         NULL,           /* class_finalize */
+         NULL,           /* class_data */
+         sizeof (GdkWindowImplQuartz),
+         0,              /* n_preallocs */
+         (GInstanceInitFunc) gdk_window_impl_quartz_init,
+       };
+
+      const GInterfaceInfo paintable_info = 
+       {
+         (GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
+         NULL,
+         NULL
+       };
+
+      object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL,
+                                            "GdkWindowImplQuartz",
+                                            &object_info, 0);
+      g_type_add_interface_static (object_type,
+                                  GDK_TYPE_PAINTABLE,
+                                  &paintable_info);
+    }
+
+  return object_type;
 }
 
-void 
-_gdk_windowing_window_beep (GdkWindow *window)
+CGContextRef
+gdk_quartz_window_get_context (GdkWindowImplQuartz  *window,
+                               gboolean             antialias)
 {
-  g_return_if_fail (GDK_IS_WINDOW (window));
+  if (!GDK_WINDOW_IMPL_QUARTZ_GET_CLASS (window)->get_context)
+    {
+      g_warning ("%s doesn't implement GdkWindowImplQuartzClass::get_context()",
+                 G_OBJECT_TYPE_NAME (window));
+      return NULL;
+    }
 
-  gdk_display_beep (_gdk_display);
+  return GDK_WINDOW_IMPL_QUARTZ_GET_CLASS (window)->get_context (window, antialias);
 }
 
 void
-gdk_window_set_opacity (GdkWindow *window,
-                       gdouble    opacity)
+gdk_quartz_window_release_context (GdkWindowImplQuartz  *window,
+                                   CGContextRef          cg_context)
 {
-  GdkWindowObject *private = (GdkWindowObject *) window;
-  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+  if (!GDK_WINDOW_IMPL_QUARTZ_GET_CLASS (window)->release_context)
+    {
+      g_warning ("%s doesn't implement GdkWindowImplQuartzClass::release_context()",
+                 G_OBJECT_TYPE_NAME (window));
+      return;
+    }
 
-  g_return_if_fail (GDK_IS_WINDOW (window));
-  g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
+  GDK_WINDOW_IMPL_QUARTZ_GET_CLASS (window)->release_context (window, cg_context);
+}
 
-  if (GDK_WINDOW_DESTROYED (window) ||
-      !WINDOW_IS_TOPLEVEL (window))
-    return;
 
-  if (opacity < 0)
-    opacity = 0;
-  else if (opacity > 1)
-    opacity = 1;
 
-  [impl->toplevel setAlphaValue: opacity];
+static CGContextRef
+gdk_root_window_impl_quartz_get_context (GdkWindowImplQuartz *window,
+                                         gboolean             antialias)
+{
+  CGColorSpaceRef colorspace;
+  CGContextRef cg_context;
+  GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (window);
+
+  if (GDK_WINDOW_DESTROYED (window_impl->wrapper))
+    return NULL;
+
+  /* We do not have the notion of a root window on OS X.  We fake this
+   * by creating a 1x1 bitmap and return a context to that.
+   */
+  colorspace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
+  cg_context = CGBitmapContextCreate (NULL,
+                                      1, 1, 8, 4, colorspace,
+                                      kCGImageAlphaPremultipliedLast);
+  CGColorSpaceRelease (colorspace);
+
+  return cg_context;
 }
 
-void
-_gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
+static void
+gdk_root_window_impl_quartz_release_context (GdkWindowImplQuartz *window,
+                                             CGContextRef         cg_context)
 {
+  CGContextRelease (cg_context);
 }
 
-GdkRegion *
-_gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
+static void
+gdk_root_window_impl_quartz_class_init (GdkRootWindowImplQuartzClass *klass)
 {
-  /* FIXME: implement */
-  return NULL;
+  GdkWindowImplQuartzClass *window_quartz_class = GDK_WINDOW_IMPL_QUARTZ_CLASS (klass);
+
+  root_window_parent_class = g_type_class_peek_parent (klass);
+
+  window_quartz_class->get_context = gdk_root_window_impl_quartz_get_context;
+  window_quartz_class->release_context = gdk_root_window_impl_quartz_release_context;
 }
 
-GdkRegion *
-_gdk_windowing_window_get_shape (GdkWindow *window)
+static void
+gdk_root_window_impl_quartz_init (GdkRootWindowImplQuartz *impl)
 {
-  /* FIXME: implement */
-  return NULL;
 }
 
-GdkRegion *
-_gdk_windowing_window_get_input_shape (GdkWindow *window)
+GType
+_gdk_root_window_impl_quartz_get_type (void)
 {
-  /* FIXME: implement */
-  return NULL;
-}
+  static GType object_type = 0;
 
-static void
-gdk_window_impl_iface_init (GdkWindowImplIface *iface)
-{
-  iface->show = gdk_window_quartz_show;
-  iface->hide = gdk_window_quartz_hide;
-  iface->withdraw = gdk_window_quartz_withdraw;
-  iface->set_events = gdk_window_quartz_set_events;
-  iface->get_events = gdk_window_quartz_get_events;
-  iface->raise = gdk_window_quartz_raise;
-  iface->lower = gdk_window_quartz_lower;
-  iface->restack_toplevel = gdk_window_quartz_restack_toplevel;
-  iface->move_resize = gdk_window_quartz_move_resize;
-  iface->set_background = gdk_window_quartz_set_background;
-  iface->set_back_pixmap = gdk_window_quartz_set_back_pixmap;
-  iface->reparent = gdk_window_quartz_reparent;
-  iface->set_cursor = gdk_window_quartz_set_cursor;
-  iface->get_geometry = gdk_window_quartz_get_geometry;
-  iface->get_root_coords = gdk_window_quartz_get_root_coords;
-  iface->get_pointer = gdk_window_quartz_get_pointer;
-  iface->get_deskrelative_origin = gdk_window_quartz_get_deskrelative_origin;
-  iface->shape_combine_region = gdk_window_quartz_shape_combine_region;
-  iface->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
-  iface->set_static_gravities = gdk_window_quartz_set_static_gravities;
-  iface->queue_antiexpose = _gdk_quartz_window_queue_antiexpose;
-  iface->queue_translation = _gdk_quartz_window_queue_translation;
-  iface->destroy = _gdk_quartz_window_destroy;
-  iface->input_window_destroy = _gdk_input_window_destroy;
-  iface->input_window_crossing = _gdk_input_window_crossing;
+  if (!object_type)
+    {
+      const GTypeInfo object_info =
+        {
+          sizeof (GdkRootWindowImplQuartzClass),
+          (GBaseInitFunc) NULL,
+          (GBaseFinalizeFunc) NULL,
+          (GClassInitFunc) gdk_root_window_impl_quartz_class_init,
+          NULL,           /* class_finalize */
+          NULL,           /* class_data */
+          sizeof (GdkRootWindowImplQuartz),
+          0,              /* n_preallocs */
+          (GInstanceInitFunc) gdk_root_window_impl_quartz_init,
+        };
+
+      object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL_QUARTZ,
+                                            "GdkRootWindowQuartz",
+                                            &object_info, 0);
+    }
+
+  return object_type;
 }