]> Pileus Git - ~andy/gtk/blob - gdk/quartz/gdkwindow-quartz.c
b3428f715210f4266c9e620a6821db5cd6419001
[~andy/gtk] / gdk / quartz / gdkwindow-quartz.c
1 /* gdkwindow-quartz.c
2  *
3  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4  * Copyright (C) 2005 Imendio AB
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <config.h>
23
24 #include "gdk.h"
25 #include "gdkprivate-quartz.h"
26
27 static gpointer parent_class;
28
29 static GSList *update_windows = NULL;
30 static guint update_idle = 0;
31
32
33 NSView *
34 gdk_quartz_window_get_nsview (GdkWindow *window)
35 {
36   GdkWindowObject *private = (GdkWindowObject *)window;
37
38   return ((GdkWindowImplQuartz *)private->impl)->view;
39 }
40
41 static void
42 gdk_window_impl_quartz_get_size (GdkDrawable *drawable,
43                                 gint        *width,
44                                 gint        *height)
45 {
46   g_return_if_fail (GDK_IS_WINDOW_IMPL_QUARTZ (drawable));
47
48   if (width)
49     *width = GDK_WINDOW_IMPL_QUARTZ (drawable)->width;
50   if (height)
51     *height = GDK_WINDOW_IMPL_QUARTZ (drawable)->height;
52 }
53
54 static GdkRegion*
55 gdk_window_impl_quartz_get_visible_region (GdkDrawable *drawable)
56 {
57   GdkWindowObject *private = GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper);
58   GdkRectangle rect;
59   GdkWindowImplQuartz *impl;
60   GList *windows = NULL, *l;
61
62   /* FIXME: The clip rectangle should really be cached
63    * and recalculated when the window rectangle changes.
64    */
65   while (private)
66     {
67       windows = g_list_prepend (windows, private);
68
69       if (private->parent == GDK_WINDOW_OBJECT (_gdk_root))
70         break;
71
72       private = private->parent;
73     }
74
75   /* Get rectangle for toplevel window */
76   private = GDK_WINDOW_OBJECT (windows->data);
77   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
78   
79   rect.x = 0;
80   rect.y = 0;
81   rect.width = impl->width;
82   rect.height = impl->height;
83
84   /* Skip toplevel window since we have its rect */
85   for (l = windows->next; l; l = l->next)
86     {
87       private = GDK_WINDOW_OBJECT (l->data);
88       impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
89       GdkRectangle tmp_rect;
90
91       tmp_rect.x = -MIN (0, private->x - rect.x);
92       tmp_rect.y = -MIN (0, private->y - rect.y);
93       tmp_rect.width = MIN (rect.width, impl->width + private->x - rect.x) - MAX (0, private->x - rect.x);
94       tmp_rect.height = MIN (rect.height, impl->height + private->y - rect.y) - MAX (0, private->y - rect.y);
95
96       rect = tmp_rect;
97     }
98   
99   g_list_free (windows);
100   
101   return gdk_region_rectangle (&rect);
102 }
103
104 static void
105 gdk_window_impl_quartz_finalize (GObject *object)
106 {
107   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (object);
108
109   if (impl->nscursor)
110     [impl->nscursor release];
111
112   if (impl->paint_clip_region)
113     gdk_region_destroy (impl->paint_clip_region);
114
115   G_OBJECT_CLASS (parent_class)->finalize (object);
116 }
117
118 static void
119 gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
120 {
121   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
122   GObjectClass *object_class = G_OBJECT_CLASS (klass);
123
124   parent_class = g_type_class_peek_parent (klass);
125
126   object_class->finalize = gdk_window_impl_quartz_finalize;
127
128   drawable_class->get_size = gdk_window_impl_quartz_get_size;
129
130   /* Visible and clip regions are the same */
131   drawable_class->get_clip_region = gdk_window_impl_quartz_get_visible_region;
132   drawable_class->get_visible_region = gdk_window_impl_quartz_get_visible_region;
133 }
134
135 static void
136 gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
137 {
138   impl->width = 1;
139   impl->height = 1;
140   impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
141 }
142
143 static void
144 gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
145                                            GdkRegion    *region)
146 {
147   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
148   int n_rects;
149   GdkRectangle *rects;
150   GdkPixmap *bg_pixmap;
151   GdkWindow *window;
152   
153   bg_pixmap = GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper)->bg_pixmap;
154
155   if (impl->begin_paint_count == 0)
156     impl->paint_clip_region = gdk_region_copy (region);
157   else
158     gdk_region_union (impl->paint_clip_region, region);
159
160   impl->begin_paint_count ++;
161
162   if (bg_pixmap == GDK_NO_BG)
163     return;
164         
165   gdk_region_get_rectangles (region, &rects, &n_rects);
166   
167   if (bg_pixmap == NULL)
168     {
169       CGContextRef context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
170       gint i;
171     
172       for (i = 0; i < n_rects; i++) 
173         {
174           gdk_quartz_set_context_fill_color_from_pixel 
175             (context, gdk_drawable_get_colormap (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper),
176              GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper)->bg_color.pixel);
177           
178           CGContextFillRect (context, CGRectMake (rects[i].x, rects[i].y, rects[i].width, rects[i].height));
179         }
180       
181       gdk_quartz_drawable_release_context (GDK_DRAWABLE (impl), context);
182     }
183   else
184     {
185       int x, y;
186       int x_offset, y_offset;
187       int width, height;
188       GdkGC *gc;
189       
190       x_offset = y_offset = 0;
191       
192       window = GDK_WINDOW (GDK_DRAWABLE_IMPL_QUARTZ (impl));
193       while (window && ((GdkWindowObject *) window)->bg_pixmap == GDK_PARENT_RELATIVE_BG)
194         {
195           /* If this window should have the same background as the parent,
196            * fetch the parent. (And if the same goes for the parent, fetch
197            * the grandparent, etc.)
198            */
199           x_offset += ((GdkWindowObject *) window)->x;
200           y_offset += ((GdkWindowObject *) window)->y;
201           window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
202         }
203
204       /* Note: There should be a CG API to draw tiled images, we might
205        * want to look into that for this. 
206        */
207       gc = gdk_gc_new (GDK_DRAWABLE (impl));
208       
209       gdk_drawable_get_size (GDK_DRAWABLE (bg_pixmap), &width, &height);
210       
211       x = -x_offset;
212       while (x < (rects[0].x + rects[0].width))
213         {
214           if (x + width >= rects[0].x)
215             {
216               y = -y_offset;
217               while (y < (rects[0].y + rects[0].height))
218                 {
219                   if (y + height >= rects[0].y)
220                     gdk_draw_drawable (GDK_DRAWABLE (impl), gc, bg_pixmap, 0, 0, x, y, width, height);
221                   
222                   y += height;
223                 }
224             }
225           x += width;
226         }
227       
228       g_object_unref (G_OBJECT (gc));
229     }
230   
231   g_free (rects);
232 }
233
234 static void
235 gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
236 {
237   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
238
239   impl->begin_paint_count --;
240
241   if (impl->begin_paint_count == 0)
242     {
243       gdk_region_destroy (impl->paint_clip_region);
244       impl->paint_clip_region = NULL;
245     }
246 }
247
248 static void
249 gdk_window_quartz_process_all_updates (void)
250 {
251   GSList *old_update_windows = update_windows;
252   GSList *tmp_list = update_windows;
253
254   update_idle = 0;
255   update_windows = NULL;
256
257   g_slist_foreach (old_update_windows, (GFunc) g_object_ref, NULL);
258   
259   while (tmp_list)
260     {
261       GdkWindowObject *private = tmp_list->data;
262       GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *) private->impl;
263       int i, n_rects;
264       GdkRectangle *rects;
265       
266       if (private->update_area)
267         {
268           gdk_region_get_rectangles (private->update_area, &rects, &n_rects);
269
270           gdk_region_destroy (private->update_area);
271           private->update_area = NULL;
272           
273           for (i = 0; i < n_rects; i++) 
274             {
275               [impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y,
276                                                             rects[i].width, rects[i].height)];
277             }
278           
279           [impl->view displayIfNeeded];
280
281           g_free (rects);
282         }
283
284       g_object_unref (tmp_list->data);
285       tmp_list = tmp_list->next;
286     }
287
288   g_slist_free (old_update_windows);
289 }
290
291 static gboolean
292 gdk_window_quartz_update_idle (gpointer data)
293 {
294   GDK_THREADS_ENTER ();
295   gdk_window_quartz_process_all_updates ();
296   GDK_THREADS_LEAVE ();
297
298   return FALSE;
299 }
300
301 static void
302 gdk_window_impl_quartz_invalidate_maybe_recurse (GdkPaintable *paintable,
303                                                  GdkRegion    *region,
304                                                  gboolean    (*child_func) (GdkWindow *, gpointer),
305                                                  gpointer      user_data)
306 {
307   GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
308   GdkDrawableImplQuartz *drawable_impl = (GdkDrawableImplQuartz *) window_impl;
309   GdkWindow *window = (GdkWindow *) drawable_impl->wrapper;
310   GdkWindowObject *private = (GdkWindowObject *) window;
311   GdkRegion *visible_region;
312
313   visible_region = gdk_drawable_get_visible_region (window);
314   gdk_region_intersect (visible_region, region);
315
316   if (private->update_area)
317     {
318       gdk_region_union (private->update_area, visible_region);
319       gdk_region_destroy (visible_region);
320     }
321   else
322     {
323       update_windows = g_slist_prepend (update_windows, window);
324       private->update_area = visible_region;
325
326       if (update_idle == 0)
327         update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
328                                        gdk_window_quartz_update_idle, NULL, NULL);
329     }
330 }
331
332 static void
333 gdk_window_impl_quartz_process_updates (GdkPaintable *paintable,
334                                         gboolean      update_children)
335 {
336   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
337   GdkDrawableImplQuartz *drawable_impl = (GdkDrawableImplQuartz *) impl;
338   GdkWindowObject *private = (GdkWindowObject *) drawable_impl->wrapper;
339
340   if (private->update_area)
341     {
342       gdk_region_destroy (private->update_area);
343       private->update_area = NULL;
344     }  
345
346   [impl->view setNeedsDisplay: YES];
347   update_windows = g_slist_remove (update_windows, private);
348 }
349
350 static void
351 gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
352 {
353   iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
354   iface->end_paint = gdk_window_impl_quartz_end_paint;
355
356   iface->invalidate_maybe_recurse = gdk_window_impl_quartz_invalidate_maybe_recurse;
357   iface->process_updates = gdk_window_impl_quartz_process_updates;
358 }
359
360 GType
361 _gdk_window_impl_quartz_get_type (void)
362 {
363   static GType object_type = 0;
364
365   if (!object_type)
366     {
367       static const GTypeInfo object_info =
368       {
369         sizeof (GdkWindowImplQuartzClass),
370         (GBaseInitFunc) NULL,
371         (GBaseFinalizeFunc) NULL,
372         (GClassInitFunc) gdk_window_impl_quartz_class_init,
373         NULL,           /* class_finalize */
374         NULL,           /* class_data */
375         sizeof (GdkWindowImplQuartz),
376         0,              /* n_preallocs */
377         (GInstanceInitFunc) gdk_window_impl_quartz_init,
378       };
379       
380       static const GInterfaceInfo paintable_info = 
381       {
382         (GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
383         NULL,
384         NULL
385       };
386
387       object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
388                                             "GdkWindowImplQuartz",
389                                             &object_info, 0);
390       g_type_add_interface_static (object_type,
391                                    GDK_TYPE_PAINTABLE,
392                                    &paintable_info);
393     }
394   
395   return object_type;
396 }
397
398 GType
399 _gdk_window_impl_get_type (void)
400 {
401   return _gdk_window_impl_quartz_get_type ();
402 }
403
404 static const gchar *
405 get_default_title (void)
406 {
407   const char *title;
408
409   title = g_get_application_name ();
410   if (!title)
411     title = g_get_prgname ();
412
413   return title;
414 }
415
416 gint 
417 _gdk_quartz_get_inverted_screen_y (gint y)
418 {
419   NSRect rect = [[NSScreen mainScreen] frame];
420
421   return rect.size.height - y;
422 }
423
424 static GdkWindow *
425 find_child_window_by_point_helper (GdkWindow *window,
426                                    int        x,
427                                    int        y,
428                                    int        x_offset,
429                                    int        y_offset,
430                                    int       *x_ret,
431                                    int       *y_ret)
432 {
433   GList *l;
434
435   for (l = GDK_WINDOW_OBJECT (window)->children; l; l = l->next)
436     {
437       GdkWindowObject *private = GDK_WINDOW_OBJECT (l->data);
438       GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
439       int temp_x, temp_y;
440
441       if (!GDK_WINDOW_IS_MAPPED (private))
442         continue;
443
444       temp_x = x_offset + private->x;
445       temp_y = y_offset + private->y;
446       
447       /* FIXME: Are there off by one errors here? */
448       if (x >= temp_x && y >= temp_y &&
449           x < temp_x + impl->width && y < temp_y + impl->height) 
450         {
451           *x_ret = x - x_offset - private->x;
452           *y_ret = y - y_offset - private->y;
453           
454           /* Look for child windows */
455           return find_child_window_by_point_helper (GDK_WINDOW (l->data),
456                                                     x, y,
457                                                     temp_x, temp_y,
458                                                     x_ret, y_ret);
459         }
460     }
461
462   return window;
463 }
464
465 /* Given a toplevel window and coordinates, returns the window
466  * in which the point is. Note that x and y should be non-flipped
467  * (and relative the toplevel), while the returned positions are
468  * flipped.
469  */
470 GdkWindow *
471 _gdk_quartz_find_child_window_by_point (GdkWindow *toplevel,
472                                         int        x,
473                                         int        y,
474                                         int       *x_ret,
475                                         int       *y_ret)
476 {
477   GdkWindowObject *private = (GdkWindowObject *)toplevel;
478   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
479
480   /* If the point is in the title bar, ignore it */
481   if (y > impl->height)
482     return NULL;
483
484   /* First flip the y coordinate */
485   y = impl->height - y;
486
487   return find_child_window_by_point_helper (toplevel, x, y, 0, 0, x_ret, y_ret);
488 }
489
490 GdkWindow *
491 gdk_window_new (GdkWindow     *parent,
492                 GdkWindowAttr *attributes,
493                 gint           attributes_mask)
494 {
495   GdkWindow *window;
496   GdkWindowObject *private;
497   GdkWindowImplQuartz *impl;
498   GdkDrawableImplQuartz *draw_impl;
499   GdkVisual *visual;
500
501   if (parent && GDK_WINDOW_DESTROYED (parent))
502     return NULL;
503
504   GDK_QUARTZ_ALLOC_POOL;
505
506   if (!parent)
507     parent = _gdk_root;
508
509   window = g_object_new (GDK_TYPE_WINDOW, NULL);
510   private = (GdkWindowObject *)window;
511   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
512   draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl);
513   draw_impl->wrapper = GDK_DRAWABLE (window);
514
515   private->parent = (GdkWindowObject *)parent;
516
517   if (attributes_mask & GDK_WA_X)
518     private->x = attributes->x;
519   else
520     private->x = 0;
521   
522   if (attributes_mask & GDK_WA_Y)
523     private->y = attributes->y;
524   else if (attributes_mask & GDK_WA_X)
525     private->y = 100;
526   else
527     private->y = 0;
528
529   private->event_mask = attributes->event_mask;
530
531   impl->width = attributes->width > 1 ? attributes->width : 1;
532   impl->height = attributes->height > 1 ? attributes->height : 1;
533
534   if (attributes_mask & GDK_WA_VISUAL)
535     visual = attributes->visual;
536   else
537     visual = gdk_screen_get_system_visual (_gdk_screen);
538
539   if (attributes->wclass == GDK_INPUT_ONLY)
540     {
541       /* Backwards compatiblity - we've always ignored
542        * attributes->window_type for input-only windows
543        * before
544        */
545       if (parent == _gdk_root)
546         private->window_type = GDK_WINDOW_TEMP;
547       else
548         private->window_type = GDK_WINDOW_CHILD;
549     }
550   else
551     private->window_type = attributes->window_type;
552
553   /* Sanity checks */
554   switch (private->window_type)
555     {
556     case GDK_WINDOW_TOPLEVEL:
557     case GDK_WINDOW_DIALOG:
558     case GDK_WINDOW_TEMP:
559       if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
560         {
561           g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
562                      "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
563         }
564     case GDK_WINDOW_CHILD:
565       break;
566     default:
567       g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
568       GDK_QUARTZ_RELEASE_POOL;
569       return NULL;
570     }
571
572   if (attributes->wclass == GDK_INPUT_OUTPUT)
573     {
574       private->input_only = FALSE;
575       private->depth = visual->depth;
576
577       if (attributes_mask & GDK_WA_COLORMAP)
578         {
579           draw_impl->colormap = attributes->colormap;
580           g_object_ref (attributes->colormap);
581         }
582       else
583         {
584           if (visual == gdk_screen_get_system_visual (_gdk_screen))
585             {
586               draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
587               g_object_ref (draw_impl->colormap);
588             }
589           else if (visual == gdk_screen_get_rgba_visual (_gdk_screen))
590             {
591               draw_impl->colormap = gdk_screen_get_rgba_colormap (_gdk_screen);
592               g_object_ref (draw_impl->colormap);
593             }
594           else
595             {
596               draw_impl->colormap = gdk_colormap_new (visual, FALSE);
597             }
598         }
599
600       private->bg_color.pixel = 0;
601       private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
602     }
603   else
604     {
605       private->depth = 0;
606       private->input_only = TRUE;
607       draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
608       g_object_ref (draw_impl->colormap);
609     }
610
611   if (private->parent)
612     private->parent->children = g_list_prepend (private->parent->children, window);
613
614   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
615                                   (attributes->cursor) :
616                                   NULL));
617
618   switch (attributes->window_type) 
619     {
620     case GDK_WINDOW_TOPLEVEL:
621     case GDK_WINDOW_DIALOG:
622     case GDK_WINDOW_TEMP:
623       {
624         NSRect content_rect = NSMakeRect (private->x, 
625                                           _gdk_quartz_get_inverted_screen_y (private->y) - impl->height,
626                                           impl->width, impl->height);
627         const char *title;
628         int style_mask;
629
630         switch (attributes->window_type) {
631         case GDK_WINDOW_TEMP:
632           style_mask = NSBorderlessWindowMask;
633           break;
634         default:
635           style_mask = (NSTitledWindowMask |
636                         NSClosableWindowMask |
637                         NSMiniaturizableWindowMask |
638                         NSResizableWindowMask);
639         } 
640
641         impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect 
642                                                             styleMask:style_mask
643                                                               backing:NSBackingStoreBuffered
644                                                                 defer:NO];
645
646         if (attributes_mask & GDK_WA_TITLE)
647           title = attributes->title;
648         else
649           title = get_default_title ();
650
651         gdk_window_set_title (window, title);
652           
653         if (draw_impl->colormap == gdk_screen_get_rgba_colormap (_gdk_screen))
654           {
655             [impl->toplevel setOpaque:NO];
656             [impl->toplevel setBackgroundColor:[NSColor clearColor]];
657           }
658
659         impl->view = [[GdkQuartzView alloc] initWithFrame:content_rect];
660         [impl->view setGdkWindow:window];
661         [impl->toplevel setContentView:impl->view];
662
663         /* Add a tracking rect */
664         impl->tracking_rect = [impl->view addTrackingRect:NSMakeRect(0, 0, impl->width, impl->height) 
665                                                     owner:impl->view
666                                                  userData:nil
667                                              assumeInside:NO];
668       }
669       break;
670     case GDK_WINDOW_CHILD:
671       {
672         GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl);
673
674         if (attributes->wclass == GDK_INPUT_OUTPUT)
675           {
676             NSRect frame_rect = NSMakeRect (private->x, private->y, impl->width, impl->height);
677         
678             impl->view = [[GdkQuartzView alloc] initWithFrame:frame_rect];
679             
680             [impl->view setGdkWindow:window];
681
682             /* GdkWindows should be hidden by default */
683             [impl->view setHidden:YES];
684             [parent_impl->view addSubview:impl->view];
685           }
686       }
687       break;
688     default:
689       g_assert_not_reached ();
690     }
691
692   GDK_QUARTZ_RELEASE_POOL;
693
694   return window;
695 }
696
697 void
698 _gdk_windowing_window_init (void)
699 {
700   GdkWindowObject *private;
701
702   g_assert (_gdk_root == NULL);
703
704   _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
705
706   private = (GdkWindowObject *)_gdk_root;
707
708   private->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */
709   private->window_type = GDK_WINDOW_ROOT;
710   private->depth = 24;
711 }
712
713 void
714 _gdk_windowing_window_destroy (GdkWindow *window,
715                                gboolean   recursing,
716                                gboolean   foreign_destroy)
717 {
718   update_windows = g_slist_remove (update_windows, window);
719
720   if (!recursing && !foreign_destroy)
721     {
722       GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
723
724       if (window == _gdk_quartz_get_mouse_window ()) 
725         {
726           _gdk_quartz_update_mouse_window (_gdk_root);
727         }
728
729       if (impl->toplevel)
730         [impl->toplevel close];
731       else if (impl->view)
732         [impl->view release];
733     }
734 }
735
736 void
737 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
738 {
739   /* Foreign windows aren't supported in OSX. */
740 }
741
742 static gboolean
743 all_parents_shown (GdkWindowObject *private)
744 {
745   while (GDK_WINDOW_IS_MAPPED (private))
746     {
747       if (private->parent)
748         private = (GdkWindowObject *)private->parent;
749       else
750         return TRUE;
751     }
752
753   return FALSE;
754 }
755
756 static void
757 show_window_internal (GdkWindow *window,
758                       gboolean   raise)
759 {
760   GdkWindowObject *private;
761   GdkWindowImplQuartz *impl;
762
763   if (GDK_WINDOW_DESTROYED (window))
764     return;
765
766   GDK_QUARTZ_ALLOC_POOL;
767
768   private = (GdkWindowObject *)window;
769   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
770
771   if (impl->toplevel)
772     {
773       [impl->toplevel orderFront:nil];
774       [impl->view setNeedsDisplay:YES];
775     }
776   else
777     {
778       [impl->view setHidden:NO];
779       [impl->view setNeedsDisplay:YES];
780     }
781
782   if (all_parents_shown (private->parent))
783     _gdk_quartz_send_map_events (window);
784
785   gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0);
786
787   if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
788     gdk_window_maximize (window);
789
790   if (private->state & GDK_WINDOW_STATE_ICONIFIED)
791     gdk_window_iconify (window);
792
793   GDK_QUARTZ_RELEASE_POOL;
794 }
795
796 void
797 gdk_window_show_unraised (GdkWindow *window)
798 {
799   g_return_if_fail (GDK_IS_WINDOW (window));
800
801   show_window_internal (window, FALSE);
802 }
803
804 void
805 gdk_window_show (GdkWindow *window)
806 {
807   g_return_if_fail (GDK_IS_WINDOW (window));
808
809   show_window_internal (window, TRUE);
810 }
811
812 void
813 gdk_window_hide (GdkWindow *window)
814 {
815   GdkWindowObject *private = (GdkWindowObject *)window;
816   GdkWindowImplQuartz *impl;
817
818   g_return_if_fail (GDK_IS_WINDOW (window));
819
820   if (GDK_WINDOW_DESTROYED (window))
821     return;
822
823   if (GDK_WINDOW_IS_MAPPED (window))
824     gdk_synthesize_window_state (window,
825                                  0,
826                                  GDK_WINDOW_STATE_WITHDRAWN);
827   
828   _gdk_window_clear_update_area (window);
829
830   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
831
832   if (impl->toplevel) 
833     {
834       [impl->toplevel orderOut:nil];
835     }
836   else if (impl->view)
837     {
838       [impl->view setHidden:YES];
839     }
840
841   if (window == _gdk_quartz_pointer_grab_window)
842     gdk_pointer_ungrab (0);
843
844   if (window == _gdk_quartz_keyboard_grab_window)
845     gdk_keyboard_ungrab (0);
846 }
847
848 void
849 gdk_window_withdraw (GdkWindow *window)
850 {
851   gdk_window_hide (window);
852 }
853
854 static void
855 move_resize_window_internal (GdkWindow *window,
856                              gint       x,
857                              gint       y,
858                              gint       width,
859                              gint       height)
860 {
861   GdkWindowObject *private = (GdkWindowObject *)window;
862   GdkWindowImplQuartz *impl;
863
864   if (GDK_WINDOW_DESTROYED (window))
865     return;
866
867   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
868
869   if (x != -1)
870     private->x = x;
871
872   if (y != -1)
873     private->y = y;
874
875   if (width != -1)
876     impl->width = width;
877
878   if (height != -1)
879     impl->height = height;
880
881   GDK_QUARTZ_ALLOC_POOL;
882
883   if (impl->toplevel)
884     {
885       NSRect content_rect = NSMakeRect (private->x, 
886                                         _gdk_quartz_get_inverted_screen_y (private->y) ,
887                                         impl->width, impl->height);
888       NSRect frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
889       
890       frame_rect.origin.y -= frame_rect.size.height;
891
892       [impl->toplevel setFrame:frame_rect display:YES];
893     }
894   else 
895     {
896       if (!private->input_only)
897         {
898           [impl->view setFrame:NSMakeRect (private->x, private->y, 
899                                            impl->width, impl->height)];
900
901           /* FIXME: Maybe we should use setNeedsDisplayInRect instead */
902           [impl->view setNeedsDisplay:YES];
903         }
904     }
905
906   GDK_QUARTZ_RELEASE_POOL;
907 }
908
909 void
910 gdk_window_move (GdkWindow *window,
911                  gint       x,
912                  gint       y)
913 {
914   g_return_if_fail (GDK_IS_WINDOW (window));
915
916   move_resize_window_internal (window, x, y, -1, -1);
917 }
918
919 void
920 gdk_window_resize (GdkWindow *window,
921                    gint       width,
922                    gint       height)
923 {
924   g_return_if_fail (GDK_IS_WINDOW (window));
925
926   if (width < 1)
927     width = 1;
928   if (height < 1)
929     height = 1;
930
931   move_resize_window_internal (window, -1, -1, width, height);
932 }
933
934 void
935 gdk_window_move_resize (GdkWindow *window,
936                         gint       x,
937                         gint       y,
938                         gint       width,
939                         gint       height)
940 {
941   if (width < 1)
942     width = 1;
943   if (height < 1)
944     height = 1;
945
946   move_resize_window_internal (window, x, y, width, height);
947 }
948
949 void
950 gdk_window_reparent (GdkWindow *window,
951                      GdkWindow *new_parent,
952                      gint       x,
953                      gint       y)
954 {
955   g_warning ("gdk_window_reparent: %p %p (%d, %d)", 
956              window, new_parent, x, y);
957
958   /* FIXME: Implement */
959 }
960
961 void
962 _gdk_windowing_window_clear_area (GdkWindow *window,
963                                   gint       x,
964                                   gint       y,
965                                   gint       width,
966                                   gint       height)
967 {
968   /* FIXME: Implement */
969 }
970
971 void
972 _gdk_windowing_window_clear_area_e (GdkWindow *window,
973                                     gint       x,
974                                     gint       y,
975                                     gint       width,
976                                     gint       height)
977 {
978   /* FIXME: Implement */
979 }
980
981 void
982 gdk_window_raise (GdkWindow *window)
983 {
984   g_return_if_fail (GDK_IS_WINDOW (window));
985   
986   /* FIXME: Implement */
987 }
988
989 void
990 gdk_window_lower (GdkWindow *window)
991 {
992   g_return_if_fail (GDK_IS_WINDOW (window));
993   
994   /* FIXME: Implement */
995 }
996
997 void
998 gdk_window_set_background (GdkWindow      *window,
999                            const GdkColor *color)
1000 {
1001   GdkWindowObject *private = (GdkWindowObject *)window;
1002   GdkWindowImplQuartz *impl;
1003
1004   g_return_if_fail (GDK_IS_WINDOW (window));
1005
1006   if (GDK_WINDOW_DESTROYED (window))
1007       return;
1008
1009   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1010
1011   private->bg_color = *color;
1012
1013   if (private->bg_pixmap &&
1014       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1015       private->bg_pixmap != GDK_NO_BG)
1016     g_object_unref (private->bg_pixmap);
1017   
1018   private->bg_pixmap = NULL;
1019 }
1020
1021 void
1022 gdk_window_set_back_pixmap (GdkWindow *window,
1023                             GdkPixmap *pixmap,
1024                             gboolean   parent_relative)
1025 {
1026   GdkWindowObject *private = (GdkWindowObject *)window;
1027
1028   g_return_if_fail (GDK_IS_WINDOW (window));
1029   g_return_if_fail (pixmap == NULL || !parent_relative);
1030   g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
1031
1032   if (GDK_WINDOW_DESTROYED (window))
1033     return;
1034
1035   if (private->bg_pixmap &&
1036       private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1037       private->bg_pixmap != GDK_NO_BG)
1038     g_object_unref (private->bg_pixmap);
1039
1040   if (parent_relative)
1041     {
1042       private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
1043       GDK_NOTE (MISC, g_print (G_STRLOC ": setting background pixmap to parent_relative\n"));
1044     }
1045   else
1046     {
1047       if (pixmap)
1048         {
1049           g_object_ref (pixmap);
1050           private->bg_pixmap = pixmap;
1051         }
1052       else
1053         {
1054           private->bg_pixmap = GDK_NO_BG;
1055         }
1056     }
1057 }
1058
1059 void
1060 gdk_window_set_cursor (GdkWindow *window,
1061                        GdkCursor *cursor)
1062 {
1063   GdkWindowImplQuartz *impl;
1064   GdkCursorPrivate *cursor_private;
1065   NSCursor *nscursor;
1066
1067   g_return_if_fail (GDK_IS_WINDOW (window));
1068
1069   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1070   cursor_private = (GdkCursorPrivate *)cursor;
1071
1072   if (GDK_WINDOW_DESTROYED (window))
1073     return;
1074
1075   if (!cursor)
1076     nscursor = NULL;
1077   else 
1078     nscursor = [cursor_private->nscursor retain];
1079
1080   if (impl->nscursor)
1081     [impl->nscursor release];
1082
1083   impl->nscursor = nscursor;
1084
1085   _gdk_quartz_update_cursor (_gdk_quartz_get_mouse_window ());
1086 }
1087
1088 void
1089 gdk_window_get_geometry (GdkWindow *window,
1090                          gint      *x,
1091                          gint      *y,
1092                          gint      *width,
1093                          gint      *height,
1094                          gint      *depth)
1095 {
1096   g_return_if_fail (GDK_IS_WINDOW (window));
1097
1098   /* FIXME: Implement */
1099 }
1100
1101 gboolean
1102 gdk_window_get_origin (GdkWindow *window,
1103                        gint      *x,
1104                        gint      *y)
1105 {
1106   GdkWindowObject *private;
1107   int tmp_x = 0, tmp_y = 0;
1108   GdkWindow *toplevel;
1109   NSRect content_rect;
1110   GdkWindowImplQuartz *impl;
1111
1112   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1113
1114   if (GDK_WINDOW_DESTROYED (window)) 
1115     {
1116       if (x) 
1117         *x = 0;
1118       if (y) 
1119         *y = 0;
1120       
1121       return FALSE;
1122     }
1123   
1124   private = GDK_WINDOW_OBJECT (window);
1125
1126   toplevel = gdk_window_get_toplevel (window);
1127   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
1128
1129   content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
1130
1131   tmp_x = content_rect.origin.x;
1132   tmp_y = _gdk_quartz_get_inverted_screen_y (content_rect.origin.y + content_rect.size.height);
1133
1134   while (private != GDK_WINDOW_OBJECT (toplevel))
1135     {
1136       tmp_x += private->x;
1137       tmp_y += private->y;
1138
1139       private = private->parent;
1140     }
1141
1142   if (x)
1143     *x = tmp_x;
1144   if (y)
1145     *y = tmp_y;
1146
1147   return TRUE;
1148 }
1149
1150 gboolean
1151 gdk_window_get_deskrelative_origin (GdkWindow *window,
1152                                     gint      *x,
1153                                     gint      *y)
1154 {
1155   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1156
1157   return gdk_window_get_origin (window, x, y);
1158 }
1159
1160 void
1161 gdk_window_get_root_origin (GdkWindow *window,
1162                             gint      *x,
1163                             gint      *y)
1164 {
1165   GdkRectangle rect;
1166
1167   g_return_if_fail (GDK_IS_WINDOW (window));
1168
1169   rect.x = 0;
1170   rect.y = 0;
1171   
1172   gdk_window_get_frame_extents (window, &rect);
1173
1174   if (x)
1175     *x = rect.x;
1176
1177   if (y)
1178     *y = rect.y;
1179 }
1180
1181 void
1182 _gdk_windowing_get_pointer (GdkDisplay       *display,
1183                             GdkScreen       **screen,
1184                             gint             *x,
1185                             gint             *y,
1186                             GdkModifierType  *mask)
1187 {
1188   g_return_if_fail (display == _gdk_display);
1189   
1190   *screen = _gdk_screen;
1191   _gdk_windowing_window_get_pointer (_gdk_display, _gdk_root, x, y, mask);
1192 }
1193
1194 /* Returns coordinates relative to the upper left corner of window. */
1195 GdkWindow *
1196 _gdk_windowing_window_get_pointer (GdkDisplay      *display,
1197                                    GdkWindow       *window,
1198                                    gint            *x,
1199                                    gint            *y,
1200                                    GdkModifierType *mask)
1201 {
1202   GdkWindow *toplevel;
1203   GdkWindowImplQuartz *impl;
1204   GdkWindowObject *private;
1205   NSPoint point;
1206   gint x_tmp, y_tmp;
1207
1208   if (GDK_WINDOW_DESTROYED (window))
1209     {
1210       *x = 0;
1211       *y = 0;
1212       *mask = 0;
1213       return NULL;
1214     }
1215   
1216   toplevel = gdk_window_get_toplevel (window);
1217   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
1218   private = GDK_WINDOW_OBJECT (window);
1219
1220   /* Must flip the y coordinate. */
1221   if (window == _gdk_root)
1222     {
1223       point = [NSEvent mouseLocation];
1224       y_tmp = _gdk_quartz_get_inverted_screen_y (point.y);
1225       *mask = _gdk_quartz_get_current_event_mask ();
1226     }
1227   else
1228     {
1229       NSWindow *nswindow = impl->toplevel;
1230       point = [nswindow mouseLocationOutsideOfEventStream];
1231       y_tmp = impl->height - point.y;
1232       *mask = _gdk_quartz_get_current_event_mask ();
1233     }
1234   x_tmp = point.x;
1235
1236   while (private != GDK_WINDOW_OBJECT (toplevel))
1237     {
1238       x_tmp -= private->x;
1239       y_tmp -= private->y;
1240     
1241       private = private->parent;
1242     }
1243
1244   *x = x_tmp;
1245   *y = y_tmp;
1246
1247   return _gdk_quartz_find_child_window_by_point (window,
1248                                                  point.x, point.y,
1249                                                  &x_tmp, &y_tmp);
1250 }
1251
1252 void
1253 gdk_display_warp_pointer (GdkDisplay *display,
1254                           GdkScreen  *screen,
1255                           gint        x,
1256                           gint        y)
1257 {
1258   CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
1259 }
1260
1261 GdkWindow *
1262 _gdk_windowing_window_at_pointer (GdkDisplay *display,
1263                                   gint       *win_x,
1264                                   gint       *win_y)
1265 {
1266   GdkModifierType mask;
1267
1268   return _gdk_windowing_window_get_pointer (display,
1269                                             _gdk_root,
1270                                             win_x, win_y,
1271                                             &mask);
1272 }
1273
1274 GdkEventMask  
1275 gdk_window_get_events (GdkWindow *window)
1276 {
1277   g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
1278
1279   if (GDK_WINDOW_DESTROYED (window))
1280     return 0;
1281   else
1282     return GDK_WINDOW_OBJECT (window)->event_mask;
1283 }
1284
1285 void          
1286 gdk_window_set_events (GdkWindow       *window,
1287                        GdkEventMask     event_mask)
1288 {
1289   g_return_if_fail (GDK_IS_WINDOW (window));
1290
1291   if (!GDK_WINDOW_DESTROYED (window))
1292     {
1293       GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
1294     }
1295 }
1296
1297 void
1298 gdk_window_set_urgency_hint (GdkWindow *window,
1299                              gboolean   urgent)
1300 {
1301   /* FIXME: Implement */
1302 }
1303
1304 void 
1305 gdk_window_set_geometry_hints (GdkWindow      *window,
1306                                GdkGeometry    *geometry,
1307                                GdkWindowHints  geom_mask)
1308 {
1309   GdkWindowImplQuartz *impl;
1310
1311   g_return_if_fail (GDK_IS_WINDOW (window));
1312   g_return_if_fail (geometry != NULL);
1313
1314   if (GDK_WINDOW_DESTROYED (window))
1315     return;
1316   
1317   impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
1318   if (!impl->toplevel)
1319     return;
1320
1321   if (geom_mask & GDK_HINT_POS)
1322     {
1323       /* FIXME: Implement */
1324     }
1325
1326   if (geom_mask & GDK_HINT_USER_POS)
1327     {
1328       /* FIXME: Implement */
1329     }
1330
1331   if (geom_mask & GDK_HINT_USER_SIZE)
1332     {
1333       /* FIXME: Implement */
1334     }
1335   
1336   if (geom_mask & GDK_HINT_MIN_SIZE)
1337     {
1338       NSSize size;
1339
1340       size.width = geometry->min_width;
1341       size.height = geometry->min_height;
1342
1343       [impl->toplevel setContentMinSize:size];
1344     }
1345   
1346   if (geom_mask & GDK_HINT_MAX_SIZE)
1347     {
1348       NSSize size;
1349
1350       size.width = geometry->max_width;
1351       size.height = geometry->max_height;
1352
1353       [impl->toplevel setContentMaxSize:size];
1354     }
1355   
1356   if (geom_mask & GDK_HINT_BASE_SIZE)
1357     {
1358       /* FIXME: Implement */
1359     }
1360   
1361   if (geom_mask & GDK_HINT_RESIZE_INC)
1362     {
1363       NSSize size;
1364
1365       size.width = geometry->width_inc;
1366       size.height = geometry->height_inc;
1367
1368       [impl->toplevel setContentResizeIncrements:size];
1369     }
1370   
1371   if (geom_mask & GDK_HINT_ASPECT)
1372     {
1373       /* FIXME: Implement */
1374     }
1375
1376   if (geom_mask & GDK_HINT_WIN_GRAVITY)
1377     {
1378       /* FIXME: Implement */
1379     }
1380 }
1381
1382 void
1383 gdk_window_set_title (GdkWindow   *window,
1384                       const gchar *title)
1385 {
1386   GdkWindowImplQuartz *impl;
1387
1388   g_return_if_fail (GDK_IS_WINDOW (window));
1389   g_return_if_fail (title != NULL);
1390
1391   if (GDK_WINDOW_DESTROYED (window))
1392     return;
1393
1394   impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)window)->impl);
1395
1396   if (impl->toplevel)
1397     {
1398       GDK_QUARTZ_ALLOC_POOL;
1399       [impl->toplevel setTitle:[NSString stringWithUTF8String:title]];
1400       GDK_QUARTZ_RELEASE_POOL;
1401     }
1402 }
1403
1404 void          
1405 gdk_window_set_role (GdkWindow   *window,
1406                      const gchar *role)
1407 {
1408   /* FIXME: Implement */
1409 }
1410
1411 void
1412 gdk_window_set_transient_for (GdkWindow *window, 
1413                               GdkWindow *parent)
1414 {
1415   /* FIXME: Implement */
1416 }
1417
1418 void
1419 gdk_window_shape_combine_region (GdkWindow *window,
1420                                  GdkRegion *shape,
1421                                  gint       x,
1422                                  gint       y)
1423 {
1424   g_return_if_fail (GDK_IS_WINDOW (window));
1425
1426   /* FIXME: Implement */
1427 }
1428
1429 void
1430 gdk_window_shape_combine_mask (GdkWindow *window,
1431                                GdkBitmap *mask,
1432                                gint x, gint y)
1433 {
1434   /* FIXME: Implement */
1435 }
1436
1437 void 
1438 gdk_window_input_shape_combine_mask (GdkWindow *window,
1439                                      GdkBitmap *mask,
1440                                      gint       x,
1441                                      gint       y)
1442 {
1443   /* FIXME: Implement */
1444 }
1445
1446 void 
1447 gdk_window_input_shape_combine_region (GdkWindow *window,
1448                                        GdkRegion *shape_region,
1449                                        gint       offset_x,
1450                                        gint       offset_y)
1451 {
1452   /* FIXME: Implement */
1453 }
1454
1455 void 
1456 gdk_window_set_child_input_shapes (GdkWindow *window)
1457 {
1458   /* FIXME: IMplement */
1459 }
1460
1461 void
1462 gdk_window_set_override_redirect (GdkWindow *window,
1463                                   gboolean override_redirect)
1464 {
1465   /* FIXME: Implement */
1466 }
1467
1468 void
1469 gdk_window_set_accept_focus (GdkWindow *window,
1470                              gboolean accept_focus)
1471 {
1472   /* FIXME: Implement */
1473 }
1474
1475 void
1476 gdk_window_set_child_shapes (GdkWindow *window)
1477 {
1478   g_return_if_fail (GDK_IS_WINDOW (window));
1479
1480   /* FIXME: Implement */
1481 }
1482
1483 void
1484 gdk_window_merge_child_shapes (GdkWindow *window)
1485 {
1486   g_return_if_fail (GDK_IS_WINDOW (window));
1487
1488   /* FIXME: Implement */
1489 }
1490
1491 void 
1492 gdk_window_merge_child_input_shapes (GdkWindow *window)
1493 {
1494   /* FIXME: Implement */
1495 }
1496
1497 gboolean 
1498 gdk_window_set_static_gravities (GdkWindow *window,
1499                                  gboolean   use_static)
1500 {
1501   /* FIXME: Implement */
1502   return FALSE;
1503 }
1504
1505 void
1506 gdk_window_set_focus_on_map (GdkWindow *window,
1507                              gboolean focus_on_map)
1508 {
1509   /* FIXME: Implement */
1510 }
1511
1512 void          
1513 gdk_window_set_icon (GdkWindow *window, 
1514                      GdkWindow *icon_window,
1515                      GdkPixmap *pixmap,
1516                      GdkBitmap *mask)
1517 {
1518   g_return_if_fail (GDK_IS_WINDOW (window));
1519
1520   /* FIXME: Implement */
1521 }
1522
1523 void          
1524 gdk_window_set_icon_name (GdkWindow   *window, 
1525                           const gchar *name)
1526 {
1527   g_return_if_fail (GDK_IS_WINDOW (window));
1528
1529   /* FIXME: Implement */
1530 }
1531
1532 void
1533 gdk_window_focus (GdkWindow *window,
1534                   guint32    timestamp)
1535 {
1536   g_return_if_fail (GDK_IS_WINDOW (window));
1537
1538   /* FIXME: Implement */
1539 }
1540
1541 void
1542 gdk_window_set_hints (GdkWindow *window,
1543                       gint       x,
1544                       gint       y,
1545                       gint       min_width,
1546                       gint       min_height,
1547                       gint       max_width,
1548                       gint       max_height,
1549                       gint       flags)
1550 {
1551   /* FIXME: Implement */
1552 }
1553
1554 void
1555 gdk_window_set_type_hint (GdkWindow        *window,
1556                           GdkWindowTypeHint hint)
1557 {
1558   GdkWindowImplQuartz *impl;
1559   gint                 level;
1560   gboolean             shadow;
1561   
1562   g_return_if_fail (GDK_IS_WINDOW (window));
1563
1564   if (GDK_WINDOW_DESTROYED (window))
1565     return;
1566
1567   impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
1568
1569   impl->type_hint = hint;
1570
1571   /* Match the documentation, only do something if we're not mapped yet. */
1572   if (GDK_WINDOW_IS_MAPPED (window))
1573     return;
1574
1575   switch (hint)
1576     {
1577     case GDK_WINDOW_TYPE_HINT_NORMAL:  /* Normal toplevel window */
1578     case GDK_WINDOW_TYPE_HINT_DIALOG:  /* Dialog window */
1579       level = NSNormalWindowLevel;
1580       shadow = TRUE;
1581       break;
1582
1583     case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
1584     case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */
1585       level = NSNormalWindowLevel;
1586       shadow = FALSE;
1587       break;
1588
1589     case GDK_WINDOW_TYPE_HINT_DOCK:
1590     case GDK_WINDOW_TYPE_HINT_UTILITY:
1591       level = NSFloatingWindowLevel;
1592       shadow = TRUE;
1593       break;
1594
1595     case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
1596       level = NSTornOffMenuWindowLevel;
1597       shadow = TRUE;
1598       break;
1599       
1600     case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
1601       level = NSTornOffMenuWindowLevel;
1602       shadow = TRUE;
1603       break;
1604
1605     case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1606       level = NSPopUpMenuWindowLevel;
1607       shadow = TRUE;
1608       break;
1609
1610     case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
1611     case GDK_WINDOW_TYPE_HINT_COMBO:
1612       level = NSPopUpMenuWindowLevel;
1613       shadow = TRUE;
1614       break;
1615       
1616     case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
1617     case GDK_WINDOW_TYPE_HINT_TOOLTIP:
1618       level = NSStatusWindowLevel;
1619       shadow = TRUE;
1620       break;
1621
1622     case GDK_WINDOW_TYPE_HINT_DND:
1623       level = NSPopUpMenuWindowLevel;
1624       shadow = FALSE;
1625       break;
1626
1627     default:
1628       level = NSNormalWindowLevel;
1629       shadow = FALSE;
1630       break;
1631     }
1632
1633   [impl->toplevel setHasShadow:shadow];
1634   [impl->toplevel setLevel:level];
1635 }
1636
1637 GdkWindowTypeHint
1638 gdk_window_get_type_hint (GdkWindow *window)
1639 {
1640   if (GDK_WINDOW_DESTROYED (window))
1641     return GDK_WINDOW_TYPE_HINT_NORMAL;
1642   
1643   return GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl)->type_hint;
1644 }
1645
1646 void
1647 gdk_window_set_modal_hint (GdkWindow *window,
1648                            gboolean   modal)
1649 {
1650   g_return_if_fail (GDK_IS_WINDOW (window));
1651
1652   /* FIXME: Implement */
1653 }
1654
1655 void
1656 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
1657                                   gboolean   skips_taskbar)
1658 {
1659   g_return_if_fail (GDK_IS_WINDOW (window));
1660
1661   /* FIXME: Implement */
1662 }
1663
1664 void
1665 gdk_window_set_skip_pager_hint (GdkWindow *window,
1666                                 gboolean   skips_pager)
1667 {
1668   g_return_if_fail (GDK_IS_WINDOW (window));
1669
1670   /* FIXME: Implement */
1671 }
1672
1673 void
1674 gdk_window_begin_resize_drag (GdkWindow     *window,
1675                               GdkWindowEdge  edge,
1676                               gint           button,
1677                               gint           root_x,
1678                               gint           root_y,
1679                               guint32        timestamp)
1680 {
1681   g_return_if_fail (GDK_IS_WINDOW (window));
1682
1683   /* FIXME: Implement */  
1684 }
1685
1686 void
1687 gdk_window_begin_move_drag (GdkWindow *window,
1688                             gint       button,
1689                             gint       root_x,
1690                             gint       root_y,
1691                             guint32    timestamp)
1692 {
1693   g_return_if_fail (GDK_IS_WINDOW (window));
1694
1695   /* FIXME: Implement */
1696 }
1697
1698 void
1699 gdk_window_set_icon_list (GdkWindow *window,
1700                           GList     *pixbufs)
1701 {
1702   /* FIXME: Implement */
1703 }
1704
1705 void
1706 gdk_window_get_frame_extents (GdkWindow    *window,
1707                               GdkRectangle *rect)
1708 {
1709   GdkWindowObject *private;
1710   GdkWindow *toplevel;
1711   GdkWindowImplQuartz *impl;
1712   NSRect ns_rect;
1713
1714   g_return_if_fail (GDK_IS_WINDOW (window));
1715   g_return_if_fail (rect != NULL);
1716
1717   private = GDK_WINDOW_OBJECT (window);
1718
1719   rect->x = 0;
1720   rect->y = 0;
1721   rect->width = 1;
1722   rect->height = 1;
1723   
1724   if (GDK_WINDOW_DESTROYED (window))
1725     return;
1726
1727   toplevel = gdk_window_get_toplevel (window);
1728   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
1729
1730   ns_rect = [impl->toplevel frame];
1731
1732   rect->x = ns_rect.origin.x;
1733   rect->y = _gdk_quartz_get_inverted_screen_y (ns_rect.origin.y + ns_rect.size.height);
1734   rect->width = ns_rect.size.width;
1735   rect->height = ns_rect.size.height;
1736 }
1737
1738 void
1739 gdk_window_set_decorations (GdkWindow      *window,
1740                             GdkWMDecoration decorations)
1741 {
1742   g_return_if_fail (GDK_IS_WINDOW (window));
1743
1744   /* FIXME: Implement */
1745 }
1746
1747 gboolean
1748 gdk_window_get_decorations (GdkWindow       *window,
1749                             GdkWMDecoration *decorations)
1750 {
1751   /* FIXME: Implement */
1752   return FALSE;
1753 }
1754
1755 void
1756 gdk_window_set_functions (GdkWindow    *window,
1757                           GdkWMFunction functions)
1758 {
1759   g_return_if_fail (GDK_IS_WINDOW (window));
1760
1761   /* FIXME: Implement */
1762 }
1763
1764 void
1765 _gdk_windowing_window_get_offsets (GdkWindow  *window,
1766                                    gint       *x_offset,
1767                                    gint       *y_offset)
1768 {
1769   *x_offset = *y_offset = 0;
1770 }
1771
1772 gboolean
1773 _gdk_windowing_window_queue_antiexpose (GdkWindow  *window,
1774                                         GdkRegion  *area)
1775 {
1776   return FALSE;
1777 }
1778
1779 void
1780 gdk_window_stick (GdkWindow *window)
1781 {
1782   g_return_if_fail (GDK_IS_WINDOW (window));
1783 }
1784
1785 void
1786 gdk_window_unstick (GdkWindow *window)
1787 {
1788   g_return_if_fail (GDK_IS_WINDOW (window));
1789 }
1790
1791 void
1792 gdk_window_maximize (GdkWindow *window)
1793 {
1794   GdkWindowImplQuartz *impl;
1795
1796   g_return_if_fail (GDK_IS_WINDOW (window));
1797
1798   if (GDK_WINDOW_DESTROYED (window))
1799     return;
1800
1801   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1802
1803   if (GDK_WINDOW_IS_MAPPED (window))
1804     {
1805       GDK_QUARTZ_ALLOC_POOL;
1806
1807       if (impl->toplevel && ![impl->toplevel isZoomed])
1808         [impl->toplevel zoom:nil];
1809
1810       GDK_QUARTZ_RELEASE_POOL;
1811     }
1812   else
1813     {
1814       gdk_synthesize_window_state (window,
1815                                    0,
1816                                    GDK_WINDOW_STATE_MAXIMIZED);
1817     }
1818 }
1819
1820 void
1821 gdk_window_unmaximize (GdkWindow *window)
1822 {
1823   GdkWindowImplQuartz *impl;
1824
1825   g_return_if_fail (GDK_IS_WINDOW (window));
1826
1827   if (GDK_WINDOW_DESTROYED (window))
1828     return;
1829
1830   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1831
1832   if (GDK_WINDOW_IS_MAPPED (window))
1833     {
1834       GDK_QUARTZ_ALLOC_POOL;
1835
1836       if (impl->toplevel && [impl->toplevel isZoomed])
1837         [impl->toplevel zoom:nil];
1838
1839       GDK_QUARTZ_RELEASE_POOL;
1840     }
1841   else
1842     {
1843       gdk_synthesize_window_state (window,
1844                                    GDK_WINDOW_STATE_MAXIMIZED,
1845                                    0);
1846     }
1847 }
1848
1849 void
1850 gdk_window_iconify (GdkWindow *window)
1851 {
1852   GdkWindowImplQuartz *impl;
1853
1854   g_return_if_fail (GDK_IS_WINDOW (window));
1855   
1856   if (GDK_WINDOW_DESTROYED (window))
1857     return;
1858   
1859   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1860
1861   if (GDK_WINDOW_IS_MAPPED (window))
1862     {
1863       GDK_QUARTZ_ALLOC_POOL;
1864
1865       if (impl->toplevel)
1866         [impl->toplevel miniaturize:nil];
1867
1868       GDK_QUARTZ_RELEASE_POOL;
1869     }
1870   else
1871     {
1872       gdk_synthesize_window_state (window,
1873                                    0,
1874                                    GDK_WINDOW_STATE_ICONIFIED);
1875     }
1876 }
1877
1878 void
1879 gdk_window_deiconify (GdkWindow *window)
1880 {
1881   GdkWindowImplQuartz *impl;
1882
1883   g_return_if_fail (GDK_IS_WINDOW (window));
1884   
1885   if (GDK_WINDOW_DESTROYED (window))
1886     return;
1887
1888   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1889
1890   if (GDK_WINDOW_IS_MAPPED (window))
1891     {
1892       GDK_QUARTZ_ALLOC_POOL;
1893
1894       if (impl->toplevel)
1895         [impl->toplevel deminiaturize:nil];
1896
1897       GDK_QUARTZ_RELEASE_POOL;
1898     }
1899   else
1900     {
1901       gdk_synthesize_window_state (window,
1902                                    GDK_WINDOW_STATE_ICONIFIED,
1903                                    0);
1904     }
1905 }
1906
1907 void
1908 gdk_window_fullscreen (GdkWindow *window)
1909 {
1910   g_return_if_fail (GDK_IS_WINDOW (window));
1911
1912   /* FIXME: Implement */
1913 }
1914
1915 void
1916 gdk_window_unfullscreen (GdkWindow *window)
1917 {
1918   g_return_if_fail (GDK_IS_WINDOW (window));
1919
1920   /* FIXME: Implement */
1921 }
1922
1923 void
1924 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
1925 {
1926   g_return_if_fail (GDK_IS_WINDOW (window));
1927
1928   /* FIXME: Implement */
1929 }
1930
1931 void
1932 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
1933 {
1934   g_return_if_fail (GDK_IS_WINDOW (window));
1935
1936   /* FIXME: Implement */
1937 }
1938
1939 GdkWindow *
1940 gdk_window_get_group (GdkWindow *window)
1941 {
1942   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
1943   g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
1944
1945   /* FIXME: Implement */
1946
1947   return NULL;
1948 }
1949
1950 void          
1951 gdk_window_set_group (GdkWindow *window, 
1952                       GdkWindow *leader)
1953 {
1954   /* FIXME: Implement */        
1955 }
1956
1957 GdkWindow*
1958 gdk_window_foreign_new_for_display (GdkDisplay      *display,
1959                                     GdkNativeWindow  anid)
1960 {
1961   /* Foreign windows aren't supported in Mac OS X */
1962   return NULL;
1963 }
1964
1965 GdkWindow*
1966 gdk_window_lookup (GdkNativeWindow anid)
1967 {
1968   /* Foreign windows aren't supported in Mac OS X */
1969   return NULL;
1970 }
1971
1972 GdkWindow *
1973 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
1974 {
1975   /* Foreign windows aren't supported in Mac OS X */
1976   return NULL;
1977 }
1978
1979 void
1980 gdk_window_enable_synchronized_configure (GdkWindow *window)
1981 {
1982 }
1983
1984 void
1985 gdk_window_configure_finished (GdkWindow *window)
1986 {
1987 }
1988
1989 void
1990 gdk_window_destroy_notify (GdkWindow *window)
1991 {
1992   /* FIXME: Implement. We should call this from -[GdkQuartzWindow dealloc] or
1993    * -[GdkQuartzView dealloc], although I suspect that currently they leak
1994    * anyway. */
1995 }