]> Pileus Git - ~andy/gtk/blob - gdk/quartz/gdkwindow-quartz.c
quartz: Make backend compile again
[~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-2007 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 #include <Carbon/Carbon.h>
24
25 #include "gdk.h"
26 #include "gdkdeviceprivate.h"
27 #include "gdkwindowimpl.h"
28 #include "gdkprivate-quartz.h"
29 #include "gdkscreen-quartz.h"
30 #include "gdkinputprivate.h"
31
32 static gpointer parent_class;
33
34 static GSList   *update_nswindows;
35 static gboolean  in_process_all_updates = FALSE;
36
37 static GSList *main_window_stack;
38
39 #define FULLSCREEN_DATA "fullscreen-data"
40
41 typedef struct
42 {
43   gint            x, y;
44   gint            width, height;
45   GdkWMDecoration decor;
46 } FullscreenSavedGeometry;
47
48
49 static void update_toplevel_order (void);
50 static void clear_toplevel_order  (void);
51
52 static FullscreenSavedGeometry *get_fullscreen_geometry (GdkWindow *window);
53
54 #define WINDOW_IS_TOPLEVEL(window)                   \
55   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
56    GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
57    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
58
59 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
60
61 NSView *
62 gdk_quartz_window_get_nsview (GdkWindow *window)
63 {
64   GdkWindowObject *private = (GdkWindowObject *)window;
65
66   if (GDK_WINDOW_DESTROYED (window))
67     return NULL;
68
69   return ((GdkWindowImplQuartz *)private->impl)->view;
70 }
71
72 NSWindow *
73 gdk_quartz_window_get_nswindow (GdkWindow *window)
74 {
75   GdkWindowObject *private = (GdkWindowObject *)window;
76
77   if (GDK_WINDOW_DESTROYED (window))
78     return NULL;
79
80   return ((GdkWindowImplQuartz *)private->impl)->toplevel;
81 }
82
83 static CGContextRef
84 gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
85                                     gboolean     antialias)
86 {
87   GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
88   GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
89   CGContextRef cg_context;
90
91   if (GDK_WINDOW_DESTROYED (drawable_impl->wrapper))
92     return NULL;
93
94   /* Lock focus when not called as part of a drawRect call. This
95    * is needed when called from outside "real" expose events, for
96    * example for synthesized expose events when realizing windows
97    * and for widgets that send fake expose events like the arrow
98    * buttons in spinbuttons or the position marker in rulers.
99    */
100   if (window_impl->in_paint_rect_count == 0)
101     {
102       if (![window_impl->view lockFocusIfCanDraw])
103         return NULL;
104     }
105
106   cg_context = [[NSGraphicsContext currentContext] graphicsPort];
107   CGContextSaveGState (cg_context);
108   CGContextSetAllowsAntialiasing (cg_context, antialias);
109
110   /* We'll emulate the clipping caused by double buffering here */
111   if (window_impl->begin_paint_count != 0)
112     {
113       CGRect rect;
114       CGRect *cg_rects;
115       gint n_rects, i;
116
117       n_rects = cairo_region_num_rectangles (window_impl->paint_clip_region);
118
119       if (n_rects == 1)
120         cg_rects = &rect;
121       else
122         cg_rects = g_new (CGRect, n_rects);
123
124       for (i = 0; i < n_rects; i++)
125         {
126           cairo_rectangle_int_t cairo_rect;
127           cairo_region_get_rectangle (window_impl->paint_clip_region,
128                                       i, &cairo_rect);
129           cg_rects[i].origin.x = cairo_rect.x;
130           cg_rects[i].origin.y = cairo_rect.y;
131           cg_rects[i].size.width = cairo_rect.width;
132           cg_rects[i].size.height = cairo_rect.height;
133         }
134
135       CGContextClipToRects (cg_context, cg_rects, n_rects);
136
137       if (cg_rects != &rect)
138         g_free (cg_rects);
139     }
140
141   return cg_context;
142 }
143
144 static void
145 check_grab_unmap (GdkWindow *window)
146 {
147   GList *list, *l;
148   GdkDisplay *display = gdk_drawable_get_display (window);
149   GdkDeviceManager *device_manager;
150
151   device_manager = gdk_display_get_device_manager (display);
152   list = gdk_device_manager_list_devices (device_manager,
153                                           GDK_DEVICE_TYPE_FLOATING);
154   for (l = list; l; l = l->next)
155     {
156       _gdk_display_end_device_grab (display, l->data, 0, window, TRUE);
157     }
158
159   g_list_free (list);
160 }
161
162 static void
163 check_grab_destroy (GdkWindow *window)
164 {
165   GList *list, *l;
166   GdkDisplay *display = gdk_drawable_get_display (window);
167   GdkDeviceManager *device_manager;
168
169   /* Make sure there is no lasting grab in this native window */
170   device_manager = gdk_display_get_device_manager (display);
171   list = gdk_device_manager_list_devices (device_manager,
172                                           GDK_DEVICE_TYPE_MASTER);
173
174   for (l = list; l; l = l->next)
175     {
176       GdkDeviceGrabInfo *grab;
177
178       grab = _gdk_display_get_last_device_grab (display, l->data);
179       if (grab && grab->native_window == window)
180         {
181           /* Serials are always 0 in quartz, but for clarity: */
182           grab->serial_end = grab->serial_start;
183           grab->implicit_ungrab = TRUE;
184         }
185     }
186
187   g_list_free (list);
188 }
189
190 static void
191 gdk_window_impl_quartz_finalize (GObject *object)
192 {
193   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (object);
194
195   check_grab_destroy (GDK_DRAWABLE_IMPL_QUARTZ (object)->wrapper);
196
197   if (impl->paint_clip_region)
198     cairo_region_destroy (impl->paint_clip_region);
199
200   if (impl->transient_for)
201     g_object_unref (impl->transient_for);
202
203   G_OBJECT_CLASS (parent_class)->finalize (object);
204 }
205
206 static void
207 gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
208 {
209   GObjectClass *object_class = G_OBJECT_CLASS (klass);
210   GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass);
211
212   parent_class = g_type_class_peek_parent (klass);
213
214   object_class->finalize = gdk_window_impl_quartz_finalize;
215
216   drawable_quartz_class->get_context = gdk_window_impl_quartz_get_context;
217 }
218
219 static void
220 gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
221 {
222   impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
223 }
224
225 static void
226 gdk_window_impl_quartz_begin_paint_region (GdkPaintable    *paintable,
227                                            GdkWindow       *window,
228                                            const cairo_region_t *region)
229 {
230   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
231   GdkWindowObject *private = (GdkWindowObject*)window;
232   int n_rects;
233   GdkPixmap *bg_pixmap;
234   cairo_region_t *clipped_and_offset_region;
235   gboolean free_clipped_and_offset_region = TRUE;
236
237   bg_pixmap = private->bg_pixmap;
238
239   clipped_and_offset_region = cairo_region_copy (region);
240
241   cairo_region_intersect (clipped_and_offset_region,
242                         private->clip_region_with_children);
243   cairo_region_translate (clipped_and_offset_region,
244                      private->abs_x, private->abs_y);
245
246   if (impl->begin_paint_count == 0)
247     {
248       impl->paint_clip_region = clipped_and_offset_region;
249       free_clipped_and_offset_region = FALSE;
250     }
251   else
252     cairo_region_union (impl->paint_clip_region, clipped_and_offset_region);
253
254   impl->begin_paint_count++;
255
256   if (bg_pixmap == GDK_NO_BG)
257     goto done;
258
259   n_rects = cairo_region_num_rectangles (clipped_and_offset_region);
260
261   if (n_rects == 0)
262     goto done;
263
264   if (bg_pixmap == NULL)
265     {
266       CGContextRef cg_context;
267       CGColorRef color;
268       gint i;
269
270       cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
271       color = _gdk_quartz_colormap_get_cgcolor_from_pixel (window,
272                                                            private->bg_color.pixel);
273       CGContextSetFillColorWithColor (cg_context, color);
274       CGColorRelease (color);
275  
276       for (i = 0; i < n_rects; i++)
277         {
278           cairo_rectangle_int_t rect;
279           cairo_region_get_rectangle (clipped_and_offset_region, i, &rect);
280           CGContextFillRect (cg_context,
281                              CGRectMake (rect.x, rect.y,
282                                          rect.width, rect.height));
283         }
284
285       gdk_quartz_drawable_release_context (GDK_DRAWABLE (impl), cg_context);
286     }
287   else
288     {
289       int x_offset, y_offset;
290       int width, height;
291       cairo_t *cr;
292
293       x_offset = y_offset = 0;
294
295       while (window && bg_pixmap == GDK_PARENT_RELATIVE_BG)
296         {
297           /* If this window should have the same background as the parent,
298            * fetch the parent. (And if the same goes for the parent, fetch
299            * the grandparent, etc.)
300            */
301           x_offset += ((GdkWindowObject *) window)->x;
302           y_offset += ((GdkWindowObject *) window)->y;
303           window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
304           bg_pixmap = ((GdkWindowObject *) window)->bg_pixmap;
305         }
306
307       if (bg_pixmap == NULL || bg_pixmap == GDK_NO_BG || bg_pixmap == GDK_PARENT_RELATIVE_BG)
308         {
309           /* Parent relative background but the parent doesn't have a
310            * pixmap.
311            */ 
312           goto done;
313         }
314
315       gdk_drawable_get_size (GDK_DRAWABLE (bg_pixmap), &width, &height);
316
317       cr = gdk_cairo_create (GDK_DRAWABLE (impl));
318       
319       gdk_cairo_set_source_pixmap (cr, bg_pixmap, x_offset, y_offset);
320       cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
321       gdk_cairo_region (cr, clipped_and_offset_region);
322       cairo_fill (cr);
323
324       cairo_destroy (cr);
325     }
326
327  done:
328   if (free_clipped_and_offset_region)
329     cairo_region_destroy (clipped_and_offset_region);
330 }
331
332 static void
333 gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
334 {
335   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
336
337   impl->begin_paint_count--;
338
339   if (impl->begin_paint_count == 0)
340     {
341       cairo_region_destroy (impl->paint_clip_region);
342       impl->paint_clip_region = NULL;
343     }
344 }
345
346 void
347 _gdk_quartz_window_set_needs_display_in_region (GdkWindow    *window,
348                                                 cairo_region_t    *region)
349 {
350   GdkWindowObject *private;
351   GdkWindowImplQuartz *impl;
352   int i, n_rects;
353
354   private = GDK_WINDOW_OBJECT (window);
355   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
356
357   if (!impl->needs_display_region)
358     impl->needs_display_region = cairo_region_create ();
359
360   cairo_region_union (impl->needs_display_region, region);
361
362   n_rects = cairo_region_num_rectangles (region);
363   for (i = 0; i < n_rects; i++)
364     {
365       cairo_rectangle_int_t rect;
366       cairo_region_get_rectangle (region, i, &rect);
367       [impl->view setNeedsDisplayInRect:NSMakeRect (rect.x, rect.y,
368                                                     rect.width, rect.height)];
369     }
370 }
371
372 void
373 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
374                                                cairo_region_t *region)
375 {
376   /* Make sure to only flush each toplevel at most once if we're called
377    * from process_all_updates.
378    */
379   if (in_process_all_updates)
380     {
381       GdkWindow *toplevel;
382
383       toplevel = gdk_window_get_toplevel (window);
384       if (toplevel)
385         {
386           GdkWindowObject *toplevel_private;
387           GdkWindowImplQuartz *toplevel_impl;
388           NSWindow *nswindow;
389
390           toplevel_private = (GdkWindowObject *)toplevel;
391           toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl;
392           nswindow = toplevel_impl->toplevel;
393
394           /* In theory, we could skip the flush disabling, since we only
395            * have one NSView.
396            */
397           if (nswindow && ![nswindow isFlushWindowDisabled]) 
398             {
399               [nswindow retain];
400               [nswindow disableFlushWindow];
401               update_nswindows = g_slist_prepend (update_nswindows, nswindow);
402             }
403         }
404     }
405
406   _gdk_quartz_window_set_needs_display_in_region (window, region);
407
408   /* NOTE: I'm not sure if we should displayIfNeeded here. It slows down a
409    * lot (since it triggers the beam syncing) and things seem to work
410    * without it.
411    */
412 }
413
414 void
415 _gdk_windowing_before_process_all_updates (void)
416 {
417   in_process_all_updates = TRUE;
418
419   NSDisableScreenUpdates ();
420 }
421
422 void
423 _gdk_windowing_after_process_all_updates (void)
424 {
425   GSList *old_update_nswindows = update_nswindows;
426   GSList *tmp_list = update_nswindows;
427
428   update_nswindows = NULL;
429
430   while (tmp_list)
431     {
432       NSWindow *nswindow = tmp_list->data;
433
434       [[nswindow contentView] displayIfNeeded];
435
436       _gdk_quartz_drawable_flush (NULL);
437
438       [nswindow enableFlushWindow];
439       [nswindow flushWindow];
440       [nswindow release];
441
442       tmp_list = tmp_list->next;
443     }
444
445   g_slist_free (old_update_nswindows);
446
447   in_process_all_updates = FALSE;
448
449   NSEnableScreenUpdates ();
450 }
451
452 static void
453 gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
454 {
455   iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
456   iface->end_paint = gdk_window_impl_quartz_end_paint;
457 }
458
459 GType
460 _gdk_window_impl_quartz_get_type (void)
461 {
462   static GType object_type = 0;
463
464   if (!object_type)
465     {
466       const GTypeInfo object_info =
467         {
468           sizeof (GdkWindowImplQuartzClass),
469           (GBaseInitFunc) NULL,
470           (GBaseFinalizeFunc) NULL,
471           (GClassInitFunc) gdk_window_impl_quartz_class_init,
472           NULL,           /* class_finalize */
473           NULL,           /* class_data */
474           sizeof (GdkWindowImplQuartz),
475           0,              /* n_preallocs */
476           (GInstanceInitFunc) gdk_window_impl_quartz_init,
477         };
478
479       const GInterfaceInfo paintable_info = 
480         {
481           (GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
482           NULL,
483           NULL
484         };
485
486       const GInterfaceInfo window_impl_info = 
487         {
488           (GInterfaceInitFunc) gdk_window_impl_iface_init,
489           NULL,
490           NULL
491         };
492
493       object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
494                                             "GdkWindowImplQuartz",
495                                             &object_info, 0);
496       g_type_add_interface_static (object_type,
497                                    GDK_TYPE_PAINTABLE,
498                                    &paintable_info);
499       g_type_add_interface_static (object_type,
500                                    GDK_TYPE_WINDOW_IMPL,
501                                    &window_impl_info);
502     }
503
504   return object_type;
505 }
506
507 GType
508 _gdk_window_impl_get_type (void)
509 {
510   return _gdk_window_impl_quartz_get_type ();
511 }
512
513 static const gchar *
514 get_default_title (void)
515 {
516   const char *title;
517
518   title = g_get_application_name ();
519   if (!title)
520     title = g_get_prgname ();
521
522   return title;
523 }
524
525 static void
526 get_ancestor_coordinates_from_child (GdkWindow *child_window,
527                                      gint       child_x,
528                                      gint       child_y,
529                                      GdkWindow *ancestor_window, 
530                                      gint      *ancestor_x, 
531                                      gint      *ancestor_y)
532 {
533   GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window);
534   GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window);
535
536   while (child_private != ancestor_private)
537     {
538       child_x += child_private->x;
539       child_y += child_private->y;
540
541       child_private = child_private->parent;
542     }
543
544   *ancestor_x = child_x;
545   *ancestor_y = child_y;
546 }
547
548 void
549 _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number)
550 {
551   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
552   gint x, y;
553   gint gx, gy;
554   GdkWindow *toplevel;
555   gint tx, ty;
556   static NSWindow *debug_window[10];
557   static NSRect old_rect[10];
558   NSRect rect;
559   NSColor *color;
560
561   g_return_if_fail (number >= 0 && number <= 9);
562
563   if (window == _gdk_root)
564     return;
565
566   if (window == NULL)
567     {
568       if (debug_window[number])
569         [debug_window[number] close];
570       debug_window[number] = NULL;
571
572       return;
573     }
574
575   toplevel = gdk_window_get_toplevel (window);
576   get_ancestor_coordinates_from_child (window, 0, 0, toplevel, &x, &y);
577
578   gdk_window_get_origin (toplevel, &tx, &ty);
579   x += tx;
580   y += ty;
581
582   _gdk_quartz_window_gdk_xy_to_xy (x, y + private->height,
583                                    &gx, &gy);
584
585   rect = NSMakeRect (gx, gy, private->width, private->height);
586
587   if (debug_window[number] && NSEqualRects (rect, old_rect[number]))
588     return;
589
590   old_rect[number] = rect;
591
592   if (debug_window[number])
593     [debug_window[number] close];
594
595   debug_window[number] = [[NSWindow alloc] initWithContentRect:rect
596                                                      styleMask:NSBorderlessWindowMask
597                                                        backing:NSBackingStoreBuffered
598                                                          defer:NO];
599
600   switch (number)
601     {
602     case 0:
603       color = [NSColor redColor];
604       break;
605     case 1:
606       color = [NSColor blueColor];
607       break;
608     case 2:
609       color = [NSColor greenColor];
610       break;
611     case 3:
612       color = [NSColor yellowColor];
613       break;
614     case 4:
615       color = [NSColor brownColor];
616       break;
617     case 5:
618       color = [NSColor purpleColor];
619       break;
620     default:
621       color = [NSColor blackColor];
622       break;
623     }
624
625   [debug_window[number] setBackgroundColor:color];
626   [debug_window[number] setAlphaValue:0.4];
627   [debug_window[number] setOpaque:NO];
628   [debug_window[number] setReleasedWhenClosed:YES];
629   [debug_window[number] setIgnoresMouseEvents:YES];
630   [debug_window[number] setLevel:NSFloatingWindowLevel];
631
632   [debug_window[number] orderFront:nil];
633 }
634
635 gboolean
636 _gdk_quartz_window_is_ancestor (GdkWindow *ancestor,
637                                 GdkWindow *window)
638 {
639   if (ancestor == NULL || window == NULL)
640     return FALSE;
641
642   return (gdk_window_get_parent (window) == ancestor ||
643           _gdk_quartz_window_is_ancestor (ancestor, 
644                                           gdk_window_get_parent (window)));
645 }
646
647
648 /* See notes on top of gdkscreen-quartz.c */
649 void
650 _gdk_quartz_window_gdk_xy_to_xy (gint  gdk_x,
651                                  gint  gdk_y,
652                                  gint *ns_x,
653                                  gint *ns_y)
654 {
655   GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen);
656
657   if (ns_y)
658     *ns_y = screen_quartz->height - gdk_y + screen_quartz->min_y;
659
660   if (ns_x)
661     *ns_x = gdk_x + screen_quartz->min_x;
662 }
663
664 void
665 _gdk_quartz_window_xy_to_gdk_xy (gint  ns_x,
666                                  gint  ns_y,
667                                  gint *gdk_x,
668                                  gint *gdk_y)
669 {
670   GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen);
671
672   if (gdk_y)
673     *gdk_y = screen_quartz->height - ns_y + screen_quartz->min_y;
674
675   if (gdk_x)
676     *gdk_x = ns_x - screen_quartz->min_x;
677 }
678
679 void
680 _gdk_quartz_window_nspoint_to_gdk_xy (NSPoint  point,
681                                       gint    *x,
682                                       gint    *y)
683 {
684   _gdk_quartz_window_xy_to_gdk_xy (point.x, point.y,
685                                    x, y);
686 }
687
688 static GdkWindow *
689 find_child_window_helper (GdkWindow *window,
690                           gint       x,
691                           gint       y,
692                           gint       x_offset,
693                           gint       y_offset,
694                           gboolean   get_toplevel)
695 {
696   GdkWindowImplQuartz *impl;
697   GList *l;
698
699   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
700
701   if (window == _gdk_root)
702     update_toplevel_order ();
703
704   for (l = impl->sorted_children; l; l = l->next)
705     {
706       GdkWindowObject *child_private = l->data;
707       GdkWindowImplQuartz *child_impl = GDK_WINDOW_IMPL_QUARTZ (child_private->impl);
708       int temp_x, temp_y;
709
710       if (!GDK_WINDOW_IS_MAPPED (child_private))
711         continue;
712
713       temp_x = x_offset + child_private->x;
714       temp_y = y_offset + child_private->y;
715
716       /* Special-case the root window. We have to include the title
717        * bar in the checks, otherwise the window below the title bar
718        * will be found i.e. events punch through. (If we can find a
719        * better way to deal with the events in gdkevents-quartz, this
720        * might not be needed.)
721        */
722       if (window == _gdk_root)
723         {
724           NSRect frame = NSMakeRect (0, 0, 100, 100);
725           NSRect content;
726           NSUInteger mask;
727           int titlebar_height;
728
729           mask = [child_impl->toplevel styleMask];
730
731           /* Get the title bar height. */
732           content = [NSWindow contentRectForFrameRect:frame
733                                             styleMask:mask];
734           titlebar_height = frame.size.height - content.size.height;
735
736           if (titlebar_height > 0 &&
737               x >= temp_x && y >= temp_y - titlebar_height &&
738               x < temp_x + child_private->width && y < temp_y)
739             {
740               /* The root means "unknown" i.e. a window not managed by
741                * GDK.
742                */
743               return (GdkWindow *)_gdk_root;
744             }
745         }
746
747       if ((!get_toplevel || (get_toplevel && window == _gdk_root)) &&
748           x >= temp_x && y >= temp_y &&
749           x < temp_x + child_private->width && y < temp_y + child_private->height)
750         {
751           /* Look for child windows. */
752           return find_child_window_helper (l->data,
753                                            x, y,
754                                            temp_x, temp_y,
755                                            get_toplevel);
756         }
757     }
758   
759   return window;
760 }
761
762 /* Given a GdkWindow and coordinates relative to it, returns the
763  * innermost subwindow that contains the point. If the coordinates are
764  * outside the passed in window, NULL is returned.
765  */
766 GdkWindow *
767 _gdk_quartz_window_find_child (GdkWindow *window,
768                                gint       x,
769                                gint       y,
770                                gboolean   get_toplevel)
771 {
772   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
773
774   if (x >= 0 && y >= 0 && x < private->width && y < private->height)
775     return find_child_window_helper (window, x, y, 0, 0, get_toplevel);
776
777   return NULL;
778 }
779
780
781 void
782 _gdk_quartz_window_did_become_main (GdkWindow *window)
783 {
784   main_window_stack = g_slist_remove (main_window_stack, window);
785
786   if (GDK_WINDOW_OBJECT (window)->window_type != GDK_WINDOW_TEMP)
787     main_window_stack = g_slist_prepend (main_window_stack, window);
788
789   clear_toplevel_order ();
790 }
791
792 void
793 _gdk_quartz_window_did_resign_main (GdkWindow *window)
794 {
795   GdkWindow *new_window = NULL;
796
797   if (main_window_stack)
798     new_window = main_window_stack->data;
799   else
800     {
801       GList *toplevels;
802
803       toplevels = gdk_screen_get_toplevel_windows (gdk_screen_get_default ());
804       if (toplevels)
805         new_window = toplevels->data;
806       g_list_free (toplevels);
807     }
808
809   if (new_window &&
810       new_window != window &&
811       GDK_WINDOW_IS_MAPPED (new_window) &&
812       GDK_WINDOW_OBJECT (new_window)->window_type != GDK_WINDOW_TEMP)
813     {
814       GdkWindowObject *private = (GdkWindowObject *) new_window;
815       GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
816
817       [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
818     }
819
820   clear_toplevel_order ();
821 }
822
823 static NSScreen *
824 get_nsscreen_for_point (gint x, gint y)
825 {
826   int i;
827   NSArray *screens;
828   NSScreen *screen = NULL;
829
830   GDK_QUARTZ_ALLOC_POOL;
831
832   screens = [NSScreen screens];
833
834   for (i = 0; i < [screens count]; i++)
835     {
836       NSRect rect = [[screens objectAtIndex:i] frame];
837
838       if (x >= rect.origin.x && x <= rect.origin.x + rect.size.width &&
839           y >= rect.origin.y && y <= rect.origin.y + rect.size.height)
840         {
841           screen = [screens objectAtIndex:i];
842           break;
843         }
844     }
845
846   GDK_QUARTZ_RELEASE_POOL;
847
848   return screen;
849 }
850
851 void
852 _gdk_window_impl_new (GdkWindow     *window,
853                       GdkWindow     *real_parent,
854                       GdkScreen     *screen,
855                       GdkVisual     *visual,
856                       GdkEventMask   event_mask,
857                       GdkWindowAttr *attributes,
858                       gint           attributes_mask)
859 {
860   GdkWindowObject *private;
861   GdkWindowImplQuartz *impl;
862   GdkDrawableImplQuartz *draw_impl;
863   GdkWindowImplQuartz *parent_impl;
864
865   GDK_QUARTZ_ALLOC_POOL;
866
867   private = (GdkWindowObject *)window;
868
869   impl = g_object_new (_gdk_window_impl_get_type (), NULL);
870   private->impl = (GdkDrawable *)impl;
871   draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (impl);
872   draw_impl->wrapper = GDK_DRAWABLE (window);
873
874   parent_impl = GDK_WINDOW_IMPL_QUARTZ (private->parent->impl);
875
876   switch (private->window_type)
877     {
878     case GDK_WINDOW_TOPLEVEL:
879     case GDK_WINDOW_DIALOG:
880     case GDK_WINDOW_TEMP:
881       if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
882         {
883           /* The common code warns for this case */
884           parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
885         }
886     }
887
888   if (!private->input_only)
889     {
890       if (attributes_mask & GDK_WA_COLORMAP)
891         {
892           draw_impl->colormap = attributes->colormap;
893           g_object_ref (attributes->colormap);
894         }
895       else
896         {
897           if (visual == gdk_screen_get_system_visual (_gdk_screen))
898             {
899               draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
900               g_object_ref (draw_impl->colormap);
901             }
902           else if (visual == gdk_screen_get_rgba_visual (_gdk_screen))
903             {
904               draw_impl->colormap = gdk_screen_get_rgba_colormap (_gdk_screen);
905               g_object_ref (draw_impl->colormap);
906             }
907           else
908             {
909               draw_impl->colormap = gdk_colormap_new (visual, FALSE);
910             }
911         }
912     }
913   else
914     {
915       draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
916       g_object_ref (draw_impl->colormap);
917     }
918
919   /* Maintain the z-ordered list of children. */
920   if (private->parent != (GdkWindowObject *)_gdk_root)
921     parent_impl->sorted_children = g_list_prepend (parent_impl->sorted_children, window);
922   else
923     clear_toplevel_order ();
924
925   gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
926                                   (attributes->cursor) :
927                                   NULL));
928
929   switch (attributes->window_type) 
930     {
931     case GDK_WINDOW_TOPLEVEL:
932     case GDK_WINDOW_DIALOG:
933     case GDK_WINDOW_TEMP:
934       {
935         NSScreen *screen;
936         NSRect screen_rect;
937         NSRect content_rect;
938         NSUInteger style_mask;
939         int nx, ny;
940         const char *title;
941
942         /* initWithContentRect will place on the mainScreen by default.
943          * We want to select the screen to place on ourselves.  We need
944          * to find the screen the window will be on and correct the
945          * content_rect coordinates to be relative to that screen.
946          */
947         _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y, &nx, &ny);
948
949         screen = get_nsscreen_for_point (nx, ny);
950         screen_rect = [screen frame];
951         nx -= screen_rect.origin.x;
952         ny -= screen_rect.origin.y;
953
954         content_rect = NSMakeRect (nx, ny - private->height,
955                                    private->width,
956                                    private->height);
957
958         if (attributes->window_type == GDK_WINDOW_TEMP ||
959             attributes->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
960           {
961             style_mask = NSBorderlessWindowMask;
962           }
963         else
964           {
965             style_mask = (NSTitledWindowMask |
966                           NSClosableWindowMask |
967                           NSMiniaturizableWindowMask |
968                           NSResizableWindowMask);
969           }
970
971         impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect 
972                                                             styleMask:style_mask
973                                                               backing:NSBackingStoreBuffered
974                                                                 defer:NO
975                                                                 screen:screen];
976
977         if (attributes_mask & GDK_WA_TITLE)
978           title = attributes->title;
979         else
980           title = get_default_title ();
981
982         gdk_window_set_title (window, title);
983   
984         if (draw_impl->colormap == gdk_screen_get_rgba_colormap (_gdk_screen))
985           {
986             [impl->toplevel setOpaque:NO];
987             [impl->toplevel setBackgroundColor:[NSColor clearColor]];
988           }
989
990         content_rect.origin.x = 0;
991         content_rect.origin.y = 0;
992
993         impl->view = [[GdkQuartzView alloc] initWithFrame:content_rect];
994         [impl->view setGdkWindow:window];
995         [impl->toplevel setContentView:impl->view];
996         [impl->view release];
997       }
998       break;
999
1000     case GDK_WINDOW_CHILD:
1001       {
1002         GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (private->parent)->impl);
1003
1004         if (!private->input_only)
1005           {
1006             NSRect frame_rect = NSMakeRect (private->x + private->parent->abs_x,
1007                                             private->y + private->parent->abs_y,
1008                                             private->width,
1009                                             private->height);
1010         
1011             impl->view = [[GdkQuartzView alloc] initWithFrame:frame_rect];
1012             
1013             [impl->view setGdkWindow:window];
1014
1015             /* GdkWindows should be hidden by default */
1016             [impl->view setHidden:YES];
1017             [parent_impl->view addSubview:impl->view];
1018             [impl->view release];
1019           }
1020       }
1021       break;
1022
1023     default:
1024       g_assert_not_reached ();
1025     }
1026
1027   GDK_QUARTZ_RELEASE_POOL;
1028
1029   if (attributes_mask & GDK_WA_TYPE_HINT)
1030     gdk_window_set_type_hint (window, attributes->type_hint);
1031 }
1032
1033 void
1034 _gdk_quartz_window_update_position (GdkWindow *window)
1035 {
1036   NSRect frame_rect;
1037   NSRect content_rect;
1038   GdkWindowObject *private = (GdkWindowObject *)window;
1039   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1040
1041   GDK_QUARTZ_ALLOC_POOL;
1042
1043   frame_rect = [impl->toplevel frame];
1044   content_rect = [impl->toplevel contentRectForFrameRect:frame_rect];
1045
1046   _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x,
1047                                    content_rect.origin.y + content_rect.size.height,
1048                                    &private->x, &private->y);
1049
1050
1051   GDK_QUARTZ_RELEASE_POOL;
1052 }
1053
1054 void
1055 _gdk_windowing_update_window_sizes (GdkScreen *screen)
1056 {
1057   GList *windows, *list;
1058   GdkWindowObject *private = (GdkWindowObject *)_gdk_root;
1059
1060   /* The size of the root window is so that it can contain all
1061    * monitors attached to this machine.  The monitors are laid out
1062    * within this root window.  We calculate the size of the root window
1063    * and the positions of the different monitors in gdkscreen-quartz.c.
1064    *
1065    * This data is updated when the monitor configuration is changed.
1066    */
1067   private->x = 0;
1068   private->y = 0;
1069   private->abs_x = 0;
1070   private->abs_y = 0;
1071   private->width = gdk_screen_get_width (screen);
1072   private->height = gdk_screen_get_height (screen);
1073
1074   windows = gdk_screen_get_toplevel_windows (screen);
1075
1076   for (list = windows; list; list = list->next)
1077     _gdk_quartz_window_update_position (list->data);
1078
1079   g_list_free (windows);
1080 }
1081
1082 void
1083 _gdk_windowing_window_init (void)
1084 {
1085   GdkWindowObject *private;
1086   GdkWindowImplQuartz *impl;
1087   GdkDrawableImplQuartz *drawable_impl;
1088
1089   g_assert (_gdk_root == NULL);
1090
1091   _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
1092
1093   private = (GdkWindowObject *)_gdk_root;
1094   private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
1095   private->impl_window = private;
1096
1097   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
1098
1099   _gdk_windowing_update_window_sizes (_gdk_screen);
1100
1101   private->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */
1102   private->window_type = GDK_WINDOW_ROOT;
1103   private->depth = 24;
1104   private->viewable = TRUE;
1105
1106   drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl);
1107   
1108   drawable_impl->wrapper = GDK_DRAWABLE (private);
1109   drawable_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
1110   g_object_ref (drawable_impl->colormap);
1111 }
1112
1113 static void
1114 _gdk_quartz_window_destroy (GdkWindow *window,
1115                             gboolean   recursing,
1116                             gboolean   foreign_destroy)
1117 {
1118   GdkWindowObject *private;
1119   GdkWindowImplQuartz *impl;
1120   GdkWindowObject *parent;
1121
1122   private = GDK_WINDOW_OBJECT (window);
1123   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1124
1125   main_window_stack = g_slist_remove (main_window_stack, window);
1126
1127   g_list_free (impl->sorted_children);
1128   impl->sorted_children = NULL;
1129
1130   parent = private->parent;
1131   if (parent)
1132     {
1133       GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
1134
1135       parent_impl->sorted_children = g_list_remove (parent_impl->sorted_children, window);
1136     }
1137
1138   _gdk_quartz_drawable_finish (GDK_DRAWABLE (impl));
1139
1140   if (!recursing && !foreign_destroy)
1141     {
1142       GDK_QUARTZ_ALLOC_POOL;
1143
1144       if (impl->toplevel)
1145         [impl->toplevel close];
1146       else if (impl->view)
1147         [impl->view removeFromSuperview];
1148
1149       GDK_QUARTZ_RELEASE_POOL;
1150     }
1151 }
1152
1153 void
1154 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
1155 {
1156   /* Foreign windows aren't supported in OSX. */
1157 }
1158
1159 /* FIXME: This might be possible to simplify with client-side windows. Also
1160  * note that already_mapped is not used yet, see the x11 backend.
1161 */
1162 static void
1163 gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped)
1164 {
1165   GdkWindowObject *private = (GdkWindowObject *)window;
1166   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1167   gboolean focus_on_map;
1168
1169   GDK_QUARTZ_ALLOC_POOL;
1170
1171   if (!GDK_WINDOW_IS_MAPPED (window))
1172     focus_on_map = private->focus_on_map;
1173   else
1174     focus_on_map = TRUE;
1175
1176   if (impl->toplevel)
1177     {
1178       gboolean make_key;
1179
1180       make_key = (private->accept_focus && focus_on_map &&
1181                   private->window_type != GDK_WINDOW_TEMP);
1182
1183       [(GdkQuartzWindow*)impl->toplevel showAndMakeKey:make_key];
1184       clear_toplevel_order ();
1185
1186       _gdk_quartz_events_send_map_event (window);
1187     }
1188   else
1189     {
1190       [impl->view setHidden:NO];
1191     }
1192
1193   [impl->view setNeedsDisplay:YES];
1194
1195   gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0);
1196
1197   if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1198     gdk_window_maximize (window);
1199
1200   if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1201     gdk_window_iconify (window);
1202
1203   if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1204     _gdk_quartz_window_attach_to_parent (window);
1205
1206   GDK_QUARTZ_RELEASE_POOL;
1207 }
1208
1209 /* Temporarily unsets the parent window, if the window is a
1210  * transient. 
1211  */
1212 void
1213 _gdk_quartz_window_detach_from_parent (GdkWindow *window)
1214 {
1215   GdkWindowImplQuartz *impl;
1216
1217   g_return_if_fail (GDK_IS_WINDOW (window));
1218
1219   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1220   
1221   g_return_if_fail (impl->toplevel != NULL);
1222
1223   if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1224     {
1225       GdkWindowImplQuartz *parent_impl;
1226
1227       parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
1228       [parent_impl->toplevel removeChildWindow:impl->toplevel];
1229       clear_toplevel_order ();
1230     }
1231 }
1232
1233 /* Re-sets the parent window, if the window is a transient. */
1234 void
1235 _gdk_quartz_window_attach_to_parent (GdkWindow *window)
1236 {
1237   GdkWindowImplQuartz *impl;
1238
1239   g_return_if_fail (GDK_IS_WINDOW (window));
1240
1241   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1242   
1243   g_return_if_fail (impl->toplevel != NULL);
1244
1245   if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1246     {
1247       GdkWindowImplQuartz *parent_impl;
1248
1249       parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
1250       [parent_impl->toplevel addChildWindow:impl->toplevel ordered:NSWindowAbove];
1251       clear_toplevel_order ();
1252     }
1253 }
1254
1255 void
1256 gdk_window_quartz_hide (GdkWindow *window)
1257 {
1258   GdkWindowObject *private = (GdkWindowObject *)window;
1259   GdkWindowImplQuartz *impl;
1260
1261   /* Make sure we're not stuck in fullscreen mode. */
1262   if (get_fullscreen_geometry (window))
1263     SetSystemUIMode (kUIModeNormal, 0);
1264
1265   check_grab_unmap (window);
1266
1267   _gdk_window_clear_update_area (window);
1268
1269   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1270
1271   if (impl->toplevel) 
1272     {
1273      /* Update main window. */
1274       main_window_stack = g_slist_remove (main_window_stack, window);
1275       if ([NSApp mainWindow] == impl->toplevel)
1276         _gdk_quartz_window_did_resign_main (window);
1277
1278       if (impl->transient_for)
1279         _gdk_quartz_window_detach_from_parent (window);
1280
1281       [(GdkQuartzWindow*)impl->toplevel hide];
1282     }
1283   else if (impl->view)
1284     {
1285       [impl->view setHidden:YES];
1286     }
1287 }
1288
1289 void
1290 gdk_window_quartz_withdraw (GdkWindow *window)
1291 {
1292   gdk_window_hide (window);
1293 }
1294
1295 static void
1296 move_resize_window_internal (GdkWindow *window,
1297                              gint       x,
1298                              gint       y,
1299                              gint       width,
1300                              gint       height)
1301 {
1302   GdkWindowObject *private = (GdkWindowObject *)window;
1303   GdkWindowImplQuartz *impl;
1304   GdkRectangle old_visible;
1305   GdkRectangle new_visible;
1306   GdkRectangle scroll_rect;
1307   cairo_region_t *old_region;
1308   cairo_region_t *expose_region;
1309   NSSize delta;
1310
1311   if (GDK_WINDOW_DESTROYED (window))
1312     return;
1313
1314   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1315
1316   if ((x == -1 || (x == private->x)) &&
1317       (y == -1 || (y == private->y)) &&
1318       (width == -1 || (width == private->width)) &&
1319       (height == -1 || (height == private->height)))
1320     {
1321       return;
1322     }
1323
1324   if (!impl->toplevel)
1325     {
1326       /* The previously visible area of this window in a coordinate
1327        * system rooted at the origin of this window.
1328        */
1329       old_visible.x = -private->x;
1330       old_visible.y = -private->y;
1331
1332       gdk_drawable_get_size (GDK_DRAWABLE (private->parent),
1333                              &old_visible.width,
1334                              &old_visible.height);
1335     }
1336
1337   if (x != -1)
1338     {
1339       delta.width = x - private->x;
1340       private->x = x;
1341     }
1342   else
1343     {
1344       delta.width = 0;
1345     }
1346
1347   if (y != -1)
1348     {
1349       delta.height = y - private->y;
1350       private->y = y;
1351     }
1352   else
1353     {
1354       delta.height = 0;
1355     }
1356
1357   if (width != -1)
1358     private->width = width;
1359
1360   if (height != -1)
1361     private->height = height;
1362
1363   GDK_QUARTZ_ALLOC_POOL;
1364
1365   if (impl->toplevel)
1366     {
1367       NSRect content_rect;
1368       NSRect frame_rect;
1369       gint gx, gy;
1370
1371       _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y + private->height,
1372                                        &gx, &gy);
1373
1374       content_rect = NSMakeRect (gx, gy, private->width, private->height);
1375
1376       frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
1377       [impl->toplevel setFrame:frame_rect display:YES];
1378     }
1379   else 
1380     {
1381       if (!private->input_only)
1382         {
1383           NSRect nsrect;
1384
1385           nsrect = NSMakeRect (private->x, private->y, private->width, private->height);
1386
1387           /* The newly visible area of this window in a coordinate
1388            * system rooted at the origin of this window.
1389            */
1390           new_visible.x = -private->x;
1391           new_visible.y = -private->y;
1392           new_visible.width = old_visible.width;   /* parent has not changed size */
1393           new_visible.height = old_visible.height; /* parent has not changed size */
1394
1395           expose_region = cairo_region_create_rectangle (&new_visible);
1396           old_region = cairo_region_create_rectangle (&old_visible);
1397           cairo_region_subtract (expose_region, old_region);
1398
1399           /* Determine what (if any) part of the previously visible
1400            * part of the window can be copied without a redraw
1401            */
1402           scroll_rect = old_visible;
1403           scroll_rect.x -= delta.width;
1404           scroll_rect.y -= delta.height;
1405           gdk_rectangle_intersect (&scroll_rect, &old_visible, &scroll_rect);
1406
1407           if (!cairo_region_is_empty (expose_region))
1408             {
1409               if (scroll_rect.width != 0 && scroll_rect.height != 0)
1410                 {
1411                   [impl->view scrollRect:NSMakeRect (scroll_rect.x,
1412                                                      scroll_rect.y,
1413                                                      scroll_rect.width,
1414                                                      scroll_rect.height)
1415                                       by:delta];
1416                 }
1417
1418               [impl->view setFrame:nsrect];
1419
1420               _gdk_quartz_window_set_needs_display_in_region (window, expose_region);
1421             }
1422           else
1423             {
1424               [impl->view setFrame:nsrect];
1425               [impl->view setNeedsDisplay:YES];
1426             }
1427
1428           cairo_region_destroy (expose_region);
1429           cairo_region_destroy (old_region);
1430         }
1431     }
1432
1433   GDK_QUARTZ_RELEASE_POOL;
1434 }
1435
1436 static inline void
1437 window_quartz_move (GdkWindow *window,
1438                     gint       x,
1439                     gint       y)
1440 {
1441   g_return_if_fail (GDK_IS_WINDOW (window));
1442
1443   if (((GdkWindowObject *)window)->state & GDK_WINDOW_STATE_FULLSCREEN)
1444     return;
1445
1446   move_resize_window_internal (window, x, y, -1, -1);
1447 }
1448
1449 static inline void
1450 window_quartz_resize (GdkWindow *window,
1451                       gint       width,
1452                       gint       height)
1453 {
1454   g_return_if_fail (GDK_IS_WINDOW (window));
1455
1456   if (((GdkWindowObject *)window)->state & GDK_WINDOW_STATE_FULLSCREEN)
1457     return;
1458
1459   if (width < 1)
1460     width = 1;
1461   if (height < 1)
1462     height = 1;
1463
1464   move_resize_window_internal (window, -1, -1, width, height);
1465 }
1466
1467 static inline void
1468 window_quartz_move_resize (GdkWindow *window,
1469                            gint       x,
1470                            gint       y,
1471                            gint       width,
1472                            gint       height)
1473 {
1474   if (width < 1)
1475     width = 1;
1476   if (height < 1)
1477     height = 1;
1478
1479   move_resize_window_internal (window, x, y, width, height);
1480 }
1481
1482 static void
1483 gdk_window_quartz_move_resize (GdkWindow *window,
1484                                gboolean   with_move,
1485                                gint       x,
1486                                gint       y,
1487                                gint       width,
1488                                gint       height)
1489 {
1490   if (with_move && (width < 0 && height < 0))
1491     window_quartz_move (window, x, y);
1492   else
1493     {
1494       if (with_move)
1495         window_quartz_move_resize (window, x, y, width, height);
1496       else
1497         window_quartz_resize (window, width, height);
1498     }
1499 }
1500
1501 /* FIXME: This might need fixing (reparenting didn't work before client-side
1502  * windows either).
1503  */
1504 static gboolean
1505 gdk_window_quartz_reparent (GdkWindow *window,
1506                             GdkWindow *new_parent,
1507                             gint       x,
1508                             gint       y)
1509 {
1510   GdkWindowObject *private, *old_parent_private, *new_parent_private;
1511   GdkWindowImplQuartz *impl, *old_parent_impl, *new_parent_impl;
1512   NSView *view, *new_parent_view;
1513
1514   if (new_parent == _gdk_root)
1515     {
1516       /* Could be added, just needs implementing. */
1517       g_warning ("Reparenting to root window is not supported yet in the Mac OS X backend");
1518       return FALSE;
1519     }
1520
1521   private = GDK_WINDOW_OBJECT (window);
1522   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1523   view = impl->view;
1524
1525   new_parent_private = GDK_WINDOW_OBJECT (new_parent);
1526   new_parent_impl = GDK_WINDOW_IMPL_QUARTZ (new_parent_private->impl);
1527   new_parent_view = new_parent_impl->view;
1528
1529   old_parent_private = GDK_WINDOW_OBJECT (private->parent);
1530   old_parent_impl = GDK_WINDOW_IMPL_QUARTZ (old_parent_private->impl);
1531
1532   [view retain];
1533
1534   [view removeFromSuperview];
1535   [new_parent_view addSubview:view];
1536
1537   [view release];
1538
1539   private->parent = new_parent_private;
1540
1541   if (old_parent_private)
1542     {
1543       old_parent_impl->sorted_children = g_list_remove (old_parent_impl->sorted_children, window);
1544     }
1545
1546   new_parent_impl->sorted_children = g_list_prepend (new_parent_impl->sorted_children, window);
1547
1548   return FALSE;
1549 }
1550
1551 /* Get the toplevel ordering from NSApp and update our own list. We do
1552  * this on demand since the NSApp's list is not up to date directly
1553  * after we get windowDidBecomeMain.
1554  */
1555 static void
1556 update_toplevel_order (void)
1557 {
1558   GdkWindowObject *root;
1559   GdkWindowImplQuartz *root_impl;
1560   NSEnumerator *enumerator;
1561   id nswindow;
1562   GList *toplevels = NULL;
1563
1564   root = GDK_WINDOW_OBJECT (_gdk_root);
1565   root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
1566
1567   if (root_impl->sorted_children)
1568     return;
1569
1570   GDK_QUARTZ_ALLOC_POOL;
1571
1572   enumerator = [[NSApp orderedWindows] objectEnumerator];
1573   while ((nswindow = [enumerator nextObject]))
1574     {
1575       GdkWindow *window;
1576
1577       if (![[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
1578         continue;
1579
1580       window = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
1581       toplevels = g_list_prepend (toplevels, window);
1582     }
1583
1584   GDK_QUARTZ_RELEASE_POOL;
1585
1586   root_impl->sorted_children = g_list_reverse (toplevels);
1587 }
1588
1589 static void
1590 clear_toplevel_order (void)
1591 {
1592   GdkWindowObject *root;
1593   GdkWindowImplQuartz *root_impl;
1594
1595   root = GDK_WINDOW_OBJECT (_gdk_root);
1596   root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
1597
1598   g_list_free (root_impl->sorted_children);
1599   root_impl->sorted_children = NULL;
1600 }
1601
1602 static void
1603 gdk_window_quartz_raise (GdkWindow *window)
1604 {
1605   if (GDK_WINDOW_DESTROYED (window))
1606     return;
1607
1608   if (WINDOW_IS_TOPLEVEL (window))
1609     {
1610       GdkWindowImplQuartz *impl;
1611
1612       impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1613       [impl->toplevel orderFront:impl->toplevel];
1614
1615       clear_toplevel_order ();
1616     }
1617   else
1618     {
1619       GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
1620
1621       if (parent)
1622         {
1623           GdkWindowImplQuartz *impl;
1624
1625           impl = (GdkWindowImplQuartz *)parent->impl;
1626
1627           impl->sorted_children = g_list_remove (impl->sorted_children, window);
1628           impl->sorted_children = g_list_prepend (impl->sorted_children, window);
1629         }
1630     }
1631 }
1632
1633 static void
1634 gdk_window_quartz_lower (GdkWindow *window)
1635 {
1636   if (GDK_WINDOW_DESTROYED (window))
1637     return;
1638
1639   if (WINDOW_IS_TOPLEVEL (window))
1640     {
1641       GdkWindowImplQuartz *impl;
1642
1643       impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1644       [impl->toplevel orderBack:impl->toplevel];
1645
1646       clear_toplevel_order ();
1647     }
1648   else
1649     {
1650       GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
1651
1652       if (parent)
1653         {
1654           GdkWindowImplQuartz *impl;
1655
1656           impl = (GdkWindowImplQuartz *)parent->impl;
1657
1658           impl->sorted_children = g_list_remove (impl->sorted_children, window);
1659           impl->sorted_children = g_list_append (impl->sorted_children, window);
1660         }
1661     }
1662 }
1663
1664 static void
1665 gdk_window_quartz_restack_toplevel (GdkWindow *window,
1666                                     GdkWindow *sibling,
1667                                     gboolean   above)
1668 {
1669   /* FIXME: Implement this */
1670 }
1671
1672 static void
1673 gdk_window_quartz_set_background (GdkWindow      *window,
1674                                   const GdkColor *color)
1675 {
1676   /* FIXME: We could theoretically set the background color for toplevels
1677    * here. (Currently we draw the background before emitting expose events)
1678    */
1679 }
1680
1681 static void
1682 gdk_window_quartz_set_back_pixmap (GdkWindow *window,
1683                                    GdkPixmap *pixmap)
1684 {
1685   /* FIXME: Could theoretically set some background image here. (Currently
1686    * the back pixmap is drawn before emitting expose events.
1687    */
1688 }
1689
1690 static void
1691 gdk_window_quartz_set_device_cursor (GdkWindow *window,
1692                                      GdkDevice *device,
1693                                      GdkCursor *cursor)
1694 {
1695   GdkCursorPrivate *cursor_private;
1696   NSCursor *nscursor;
1697
1698   cursor_private = (GdkCursorPrivate *)cursor;
1699
1700   if (GDK_WINDOW_DESTROYED (window))
1701     return;
1702
1703   if (!cursor)
1704     nscursor = [NSCursor arrowCursor];
1705   else 
1706     nscursor = cursor_private->nscursor;
1707
1708   [nscursor set];
1709 }
1710
1711 static void
1712 gdk_window_quartz_get_geometry (GdkWindow *window,
1713                                 gint      *x,
1714                                 gint      *y,
1715                                 gint      *width,
1716                                 gint      *height,
1717                                 gint      *depth)
1718 {
1719   GdkWindowImplQuartz *impl;
1720   GdkWindowObject *private;
1721   NSRect ns_rect;
1722
1723   if (GDK_WINDOW_DESTROYED (window))
1724     return;
1725
1726   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1727   private = GDK_WINDOW_OBJECT (window);
1728   if (window == _gdk_root)
1729     {
1730       if (x) 
1731         *x = 0;
1732       if (y) 
1733         *y = 0;
1734
1735       if (width) 
1736         *width = private->width;
1737       if (height)
1738         *height = private->height;
1739     }
1740   else if (WINDOW_IS_TOPLEVEL (window))
1741     {
1742       ns_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
1743
1744       /* This doesn't work exactly as in X. There doesn't seem to be a
1745        * way to get the coords relative to the parent window (usually
1746        * the window frame), but that seems useless except for
1747        * borderless windows where it's relative to the root window. So
1748        * we return (0, 0) (should be something like (0, 22)) for
1749        * windows with borders and the root relative coordinates
1750        * otherwise.
1751        */
1752       if ([impl->toplevel styleMask] == NSBorderlessWindowMask)
1753         {
1754           _gdk_quartz_window_xy_to_gdk_xy (ns_rect.origin.x,
1755                                            ns_rect.origin.y + ns_rect.size.height,
1756                                            x, y);
1757         }
1758       else 
1759         {
1760           if (x)
1761             *x = 0;
1762           if (y)
1763             *y = 0;
1764         }
1765
1766       if (width)
1767         *width = ns_rect.size.width;
1768       if (height)
1769         *height = ns_rect.size.height;
1770     }
1771   else
1772     {
1773       ns_rect = [impl->view frame];
1774       
1775       if (x)
1776         *x = ns_rect.origin.x;
1777       if (y)
1778         *y = ns_rect.origin.y;
1779       if (width)
1780         *width  = ns_rect.size.width;
1781       if (height)
1782         *height = ns_rect.size.height;
1783     }
1784     
1785   if (depth)
1786       *depth = gdk_drawable_get_depth (window);
1787 }
1788
1789 static gint
1790 gdk_window_quartz_get_root_coords (GdkWindow *window,
1791                                    gint       x,
1792                                    gint       y,
1793                                    gint      *root_x,
1794                                    gint      *root_y)
1795 {
1796   GdkWindowObject *private;
1797   int tmp_x = 0, tmp_y = 0;
1798   GdkWindow *toplevel;
1799   NSRect content_rect;
1800   GdkWindowImplQuartz *impl;
1801
1802   if (GDK_WINDOW_DESTROYED (window)) 
1803     {
1804       if (root_x)
1805         *root_x = 0;
1806       if (root_y)
1807         *root_y = 0;
1808       
1809       return 0;
1810     }
1811
1812   if (window == _gdk_root)
1813     {
1814       if (root_x)
1815         *root_x = x;
1816       if (root_y)
1817         *root_y = y;
1818
1819       return 1;
1820     }
1821   
1822   private = GDK_WINDOW_OBJECT (window);
1823
1824   toplevel = gdk_window_get_toplevel (window);
1825   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
1826
1827   content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
1828
1829   _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x,
1830                                    content_rect.origin.y + content_rect.size.height,
1831                                    &tmp_x, &tmp_y);
1832
1833   tmp_x += x;
1834   tmp_y += y;
1835
1836   while (private != GDK_WINDOW_OBJECT (toplevel))
1837     {
1838       if (_gdk_window_has_impl ((GdkWindow *)private))
1839         {
1840           tmp_x += private->x;
1841           tmp_y += private->y;
1842         }
1843
1844       private = private->parent;
1845     }
1846
1847   if (root_x)
1848     *root_x = tmp_x;
1849   if (root_y)
1850     *root_y = tmp_y;
1851
1852   return TRUE;
1853 }
1854
1855 static gboolean
1856 gdk_window_quartz_get_deskrelative_origin (GdkWindow *window,
1857                                            gint      *x,
1858                                            gint      *y)
1859 {
1860   return gdk_window_get_origin (window, x, y);
1861 }
1862
1863 void
1864 gdk_window_get_root_origin (GdkWindow *window,
1865                             gint      *x,
1866                             gint      *y)
1867 {
1868   GdkRectangle rect;
1869
1870   rect.x = 0;
1871   rect.y = 0;
1872   
1873   gdk_window_get_frame_extents (window, &rect);
1874
1875   if (x)
1876     *x = rect.x;
1877
1878   if (y)
1879     *y = rect.y;
1880 }
1881
1882 /* Returns coordinates relative to the passed in window. */
1883 static GdkWindow *
1884 gdk_window_quartz_get_device_state_helper (GdkWindow       *window,
1885                                            GdkDevice       *device,
1886                                            gint            *x,
1887                                            gint            *y,
1888                                            GdkModifierType *mask)
1889 {
1890   GdkWindowObject *toplevel;
1891   GdkWindowObject *private;
1892   NSPoint point;
1893   gint x_tmp, y_tmp;
1894   GdkWindow *found_window;
1895
1896   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1897
1898   if (GDK_WINDOW_DESTROYED (window))
1899     {
1900       *x = 0;
1901       *y = 0;
1902       *mask = 0;
1903       return NULL;
1904     }
1905   
1906   toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (window));
1907
1908   *mask = _gdk_quartz_events_get_current_event_mask ();
1909
1910   /* Get the y coordinate, needs to be flipped. */
1911   if (window == _gdk_root)
1912     {
1913       point = [NSEvent mouseLocation];
1914       _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
1915     }
1916   else
1917     {
1918       GdkWindowImplQuartz *impl;
1919       NSWindow *nswindow;
1920
1921       impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
1922       private = GDK_WINDOW_OBJECT (toplevel);
1923       nswindow = impl->toplevel;
1924
1925       point = [nswindow mouseLocationOutsideOfEventStream];
1926
1927       x_tmp = point.x;
1928       y_tmp = private->height - point.y;
1929
1930       window = (GdkWindow *)toplevel;
1931     }
1932
1933   found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
1934                                                 FALSE);
1935
1936   /* We never return the root window. */
1937   if (found_window == _gdk_root)
1938     found_window = NULL;
1939
1940   *x = x_tmp;
1941   *y = y_tmp;
1942
1943   return found_window;
1944 }
1945
1946 static gboolean
1947 gdk_window_quartz_get_device_state (GdkWindow       *window,
1948                                     GdkDevice       *device,
1949                                     gint            *x,
1950                                     gint            *y,
1951                                     GdkModifierType *mask)
1952 {
1953   return gdk_window_quartz_get_device_state_helper (window,
1954                                                     device,
1955                                                     x, y, mask) != NULL;
1956 }
1957
1958 /* Returns coordinates relative to the root. */
1959 void
1960 _gdk_windowing_get_device_state (GdkDisplay       *display,
1961                                  GdkDevice        *device,
1962                                  GdkScreen       **screen,
1963                                  gint             *x,
1964                                  gint             *y,
1965                                  GdkModifierType  *mask)
1966 {
1967   g_return_if_fail (display == _gdk_display);
1968   
1969   *screen = _gdk_screen;
1970   gdk_window_quartz_get_device_state_helper (_gdk_root, device, x, y, mask);
1971 }
1972
1973 void
1974 gdk_display_warp_pointer (GdkDisplay *display,
1975                           GdkScreen  *screen,
1976                           gint        x,
1977                           gint        y)
1978 {
1979   CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
1980 }
1981
1982 /* Returns coordinates relative to the found window. */
1983 GdkWindow *
1984 _gdk_windowing_window_at_pointer (GdkDisplay      *display,
1985                                   gint            *win_x,
1986                                   gint            *win_y,
1987                                   GdkModifierType *mask,
1988                                   gboolean         get_toplevel)
1989 {
1990   GdkWindow *found_window;
1991   gint x, y;
1992   GdkModifierType tmp_mask = 0;
1993
1994   found_window = gdk_window_quartz_get_device_state_helper (_gdk_root,
1995                                                             display->core_pointer,
1996                                                             &x, &y,
1997                                                             &tmp_mask);
1998   if (found_window)
1999     {
2000       GdkWindowObject *private;
2001
2002       /* The coordinates returned above are relative the root, we want
2003        * coordinates relative the window here. 
2004        */
2005       private = GDK_WINDOW_OBJECT (found_window);
2006       while (private != GDK_WINDOW_OBJECT (_gdk_root))
2007         {
2008           x -= private->x;
2009           y -= private->y;
2010           
2011           private = private->parent;
2012         }
2013
2014       *win_x = x;
2015       *win_y = y;
2016     }
2017   else
2018     {
2019       /* Mimic the X backend here, -1,-1 for unknown windows. */
2020       *win_x = -1;
2021       *win_y = -1;
2022     }
2023
2024   if (mask)
2025     *mask = tmp_mask;
2026
2027   if (get_toplevel)
2028     {
2029       GdkWindowObject *w = (GdkWindowObject *)found_window;
2030       /* Requested toplevel, find it. */
2031       /* TODO: This can be implemented more efficient by never
2032          recursing into children in the first place */
2033       if (w)
2034         {
2035           /* Convert to toplevel */
2036           while (w->parent != NULL &&
2037                  w->parent->window_type != GDK_WINDOW_ROOT)
2038             {
2039               *win_x += w->x;
2040               *win_y += w->y;
2041               w = w->parent;
2042             }
2043           found_window = (GdkWindow *)w;
2044         }
2045     }
2046
2047   return found_window;
2048 }
2049
2050 GdkWindow*
2051 _gdk_windowing_window_at_device_position (GdkDisplay      *display,
2052                                           GdkDevice       *device,
2053                                           gint            *win_x,
2054                                           gint            *win_y,
2055                                           GdkModifierType *mask,
2056                                           gboolean         get_toplevel)
2057 {
2058   return GDK_DEVICE_GET_CLASS (device)->window_at_position (device,
2059                                                             win_x, win_y,
2060                                                             mask,
2061                                                             get_toplevel);
2062 }
2063
2064
2065 static GdkEventMask  
2066 gdk_window_quartz_get_events (GdkWindow *window)
2067 {
2068   if (GDK_WINDOW_DESTROYED (window))
2069     return 0;
2070   else
2071     return GDK_WINDOW_OBJECT (window)->event_mask;
2072 }
2073
2074 static void
2075 gdk_window_quartz_set_events (GdkWindow       *window,
2076                               GdkEventMask     event_mask)
2077 {
2078   /* The mask is set in the common code. */
2079 }
2080
2081 void
2082 gdk_window_set_urgency_hint (GdkWindow *window,
2083                              gboolean   urgent)
2084 {
2085   if (GDK_WINDOW_DESTROYED (window) ||
2086       !WINDOW_IS_TOPLEVEL (window))
2087     return;
2088
2089   /* FIXME: Implement */
2090 }
2091
2092 void 
2093 gdk_window_set_geometry_hints (GdkWindow         *window,
2094                                const GdkGeometry *geometry,
2095                                GdkWindowHints     geom_mask)
2096 {
2097   GdkWindowImplQuartz *impl;
2098
2099   g_return_if_fail (geometry != NULL);
2100
2101   if (GDK_WINDOW_DESTROYED (window) ||
2102       !WINDOW_IS_TOPLEVEL (window))
2103     return;
2104   
2105   impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
2106   if (!impl->toplevel)
2107     return;
2108
2109   if (geom_mask & GDK_HINT_POS)
2110     {
2111       /* FIXME: Implement */
2112     }
2113
2114   if (geom_mask & GDK_HINT_USER_POS)
2115     {
2116       /* FIXME: Implement */
2117     }
2118
2119   if (geom_mask & GDK_HINT_USER_SIZE)
2120     {
2121       /* FIXME: Implement */
2122     }
2123   
2124   if (geom_mask & GDK_HINT_MIN_SIZE)
2125     {
2126       NSSize size;
2127
2128       size.width = geometry->min_width;
2129       size.height = geometry->min_height;
2130
2131       [impl->toplevel setContentMinSize:size];
2132     }
2133   
2134   if (geom_mask & GDK_HINT_MAX_SIZE)
2135     {
2136       NSSize size;
2137
2138       size.width = geometry->max_width;
2139       size.height = geometry->max_height;
2140
2141       [impl->toplevel setContentMaxSize:size];
2142     }
2143   
2144   if (geom_mask & GDK_HINT_BASE_SIZE)
2145     {
2146       /* FIXME: Implement */
2147     }
2148   
2149   if (geom_mask & GDK_HINT_RESIZE_INC)
2150     {
2151       NSSize size;
2152
2153       size.width = geometry->width_inc;
2154       size.height = geometry->height_inc;
2155
2156       [impl->toplevel setContentResizeIncrements:size];
2157     }
2158   
2159   if (geom_mask & GDK_HINT_ASPECT)
2160     {
2161       /* FIXME: Implement */
2162     }
2163
2164   if (geom_mask & GDK_HINT_WIN_GRAVITY)
2165     {
2166       /* FIXME: Implement */
2167     }
2168 }
2169
2170 void
2171 gdk_window_set_title (GdkWindow   *window,
2172                       const gchar *title)
2173 {
2174   GdkWindowImplQuartz *impl;
2175
2176   g_return_if_fail (title != NULL);
2177
2178   if (GDK_WINDOW_DESTROYED (window) ||
2179       !WINDOW_IS_TOPLEVEL (window))
2180     return;
2181
2182   impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)window)->impl);
2183
2184   if (impl->toplevel)
2185     {
2186       GDK_QUARTZ_ALLOC_POOL;
2187       [impl->toplevel setTitle:[NSString stringWithUTF8String:title]];
2188       GDK_QUARTZ_RELEASE_POOL;
2189     }
2190 }
2191
2192 void          
2193 gdk_window_set_role (GdkWindow   *window,
2194                      const gchar *role)
2195 {
2196   if (GDK_WINDOW_DESTROYED (window) ||
2197       WINDOW_IS_TOPLEVEL (window))
2198     return;
2199
2200   /* FIXME: Implement */
2201 }
2202
2203 void
2204 gdk_window_set_transient_for (GdkWindow *window, 
2205                               GdkWindow *parent)
2206 {
2207   GdkWindowImplQuartz *window_impl;
2208   GdkWindowImplQuartz *parent_impl;
2209
2210   if (GDK_WINDOW_DESTROYED (window)  || GDK_WINDOW_DESTROYED (parent) ||
2211       !WINDOW_IS_TOPLEVEL (window))
2212     return;
2213
2214   window_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2215   if (!window_impl->toplevel)
2216     return;
2217
2218   GDK_QUARTZ_ALLOC_POOL;
2219
2220   if (window_impl->transient_for)
2221     {
2222       _gdk_quartz_window_detach_from_parent (window);
2223
2224       g_object_unref (window_impl->transient_for);
2225       window_impl->transient_for = NULL;
2226     }
2227
2228   parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl);
2229   if (parent_impl->toplevel)
2230     {
2231       /* We save the parent because it needs to be unset/reset when
2232        * hiding and showing the window. 
2233        */
2234
2235       /* We don't set transients for tooltips, they are already
2236        * handled by the window level being the top one. If we do, then
2237        * the parent window will be brought to the top just because the
2238        * tooltip is, which is not what we want.
2239        */
2240       if (gdk_window_get_type_hint (window) != GDK_WINDOW_TYPE_HINT_TOOLTIP)
2241         {
2242           window_impl->transient_for = g_object_ref (parent);
2243
2244           /* We only add the window if it is shown, otherwise it will
2245            * be shown unconditionally here. If it is not shown, the
2246            * window will be added in show() instead.
2247            */
2248           if (!(GDK_WINDOW_OBJECT (window)->state & GDK_WINDOW_STATE_WITHDRAWN))
2249             _gdk_quartz_window_attach_to_parent (window);
2250         }
2251     }
2252   
2253   GDK_QUARTZ_RELEASE_POOL;
2254 }
2255
2256 static void
2257 gdk_window_quartz_shape_combine_region (GdkWindow       *window,
2258                                         const cairo_region_t *shape,
2259                                         gint             x,
2260                                         gint             y)
2261 {
2262   /* FIXME: Implement */
2263 }
2264
2265 static void
2266 gdk_window_quartz_input_shape_combine_region (GdkWindow       *window,
2267                                               const cairo_region_t *shape_region,
2268                                               gint             offset_x,
2269                                               gint             offset_y)
2270 {
2271   /* FIXME: Implement */
2272 }
2273
2274 void
2275 gdk_window_set_override_redirect (GdkWindow *window,
2276                                   gboolean override_redirect)
2277 {
2278   /* FIXME: Implement */
2279 }
2280
2281 void
2282 gdk_window_set_accept_focus (GdkWindow *window,
2283                              gboolean accept_focus)
2284 {
2285   GdkWindowObject *private;
2286
2287   private = (GdkWindowObject *)window;  
2288
2289   private->accept_focus = accept_focus != FALSE;
2290 }
2291
2292 static gboolean 
2293 gdk_window_quartz_set_static_gravities (GdkWindow *window,
2294                                         gboolean   use_static)
2295 {
2296   if (GDK_WINDOW_DESTROYED (window) ||
2297       !WINDOW_IS_TOPLEVEL (window))
2298     return FALSE;
2299
2300   /* FIXME: Implement */
2301   return FALSE;
2302 }
2303
2304 void
2305 gdk_window_set_focus_on_map (GdkWindow *window,
2306                              gboolean focus_on_map)
2307 {
2308   GdkWindowObject *private;
2309
2310   private = (GdkWindowObject *)window;  
2311   
2312   private->focus_on_map = focus_on_map != FALSE;
2313 }
2314
2315 void          
2316 gdk_window_set_icon (GdkWindow *window, 
2317                      GdkWindow *icon_window,
2318                      GdkPixmap *pixmap,
2319                      GdkBitmap *mask)
2320 {
2321   /* FIXME: Implement */
2322 }
2323
2324 void          
2325 gdk_window_set_icon_name (GdkWindow   *window, 
2326                           const gchar *name)
2327 {
2328   /* FIXME: Implement */
2329 }
2330
2331 void
2332 gdk_window_focus (GdkWindow *window,
2333                   guint32    timestamp)
2334 {
2335   GdkWindowObject *private;
2336   GdkWindowImplQuartz *impl;
2337         
2338   private = (GdkWindowObject*) window;
2339   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2340
2341   if (GDK_WINDOW_DESTROYED (window) ||
2342       !WINDOW_IS_TOPLEVEL (window))
2343     return;
2344
2345   if (private->accept_focus && private->window_type != GDK_WINDOW_TEMP)
2346     {
2347       GDK_QUARTZ_ALLOC_POOL;
2348       [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
2349       clear_toplevel_order ();
2350       GDK_QUARTZ_RELEASE_POOL;
2351     }
2352 }
2353
2354 static
2355 gint window_type_hint_to_level (GdkWindowTypeHint hint)
2356 {
2357   switch (hint)
2358     {
2359     case GDK_WINDOW_TYPE_HINT_DOCK:
2360     case GDK_WINDOW_TYPE_HINT_UTILITY:
2361       return NSFloatingWindowLevel;
2362
2363     case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
2364     case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
2365       return NSTornOffMenuWindowLevel;
2366
2367     case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
2368     case GDK_WINDOW_TYPE_HINT_TOOLTIP:
2369       return NSStatusWindowLevel;
2370
2371     case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2372     case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
2373     case GDK_WINDOW_TYPE_HINT_COMBO:
2374     case GDK_WINDOW_TYPE_HINT_DND:
2375       return NSPopUpMenuWindowLevel;
2376
2377     case GDK_WINDOW_TYPE_HINT_NORMAL:  /* Normal toplevel window */
2378     case GDK_WINDOW_TYPE_HINT_DIALOG:  /* Dialog window */
2379     case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
2380     case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */
2381       break;
2382
2383     default:
2384       break;
2385     }
2386
2387   return NSNormalWindowLevel;
2388 }
2389
2390 static gboolean 
2391 window_type_hint_to_shadow (GdkWindowTypeHint hint)
2392 {
2393   switch (hint)
2394     {
2395     case GDK_WINDOW_TYPE_HINT_NORMAL:  /* Normal toplevel window */
2396     case GDK_WINDOW_TYPE_HINT_DIALOG:  /* Dialog window */
2397     case GDK_WINDOW_TYPE_HINT_DOCK:
2398     case GDK_WINDOW_TYPE_HINT_UTILITY:
2399     case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
2400     case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
2401     case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2402     case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
2403     case GDK_WINDOW_TYPE_HINT_COMBO:
2404     case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
2405     case GDK_WINDOW_TYPE_HINT_TOOLTIP:
2406       return TRUE;
2407
2408     case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
2409     case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */
2410     case GDK_WINDOW_TYPE_HINT_DND:
2411       break;
2412
2413     default:
2414       break;
2415     }
2416
2417   return FALSE;
2418 }
2419
2420
2421 void
2422 gdk_window_set_type_hint (GdkWindow        *window,
2423                           GdkWindowTypeHint hint)
2424 {
2425   GdkWindowImplQuartz *impl;
2426   
2427   if (GDK_WINDOW_DESTROYED (window) ||
2428       !WINDOW_IS_TOPLEVEL (window))
2429     return;
2430
2431   impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
2432
2433   impl->type_hint = hint;
2434
2435   /* Match the documentation, only do something if we're not mapped yet. */
2436   if (GDK_WINDOW_IS_MAPPED (window))
2437     return;
2438
2439   [impl->toplevel setHasShadow: window_type_hint_to_shadow (hint)];
2440   [impl->toplevel setLevel: window_type_hint_to_level (hint)];
2441 }
2442
2443 GdkWindowTypeHint
2444 gdk_window_get_type_hint (GdkWindow *window)
2445 {
2446   if (GDK_WINDOW_DESTROYED (window) ||
2447       !WINDOW_IS_TOPLEVEL (window))
2448     return GDK_WINDOW_TYPE_HINT_NORMAL;
2449   
2450   return GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl)->type_hint;
2451 }
2452
2453 void
2454 gdk_window_set_modal_hint (GdkWindow *window,
2455                            gboolean   modal)
2456 {
2457   if (GDK_WINDOW_DESTROYED (window) ||
2458       !WINDOW_IS_TOPLEVEL (window))
2459     return;
2460
2461   /* FIXME: Implement */
2462 }
2463
2464 void
2465 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2466                                   gboolean   skips_taskbar)
2467 {
2468   if (GDK_WINDOW_DESTROYED (window) ||
2469       !WINDOW_IS_TOPLEVEL (window))
2470     return;
2471
2472   /* FIXME: Implement */
2473 }
2474
2475 void
2476 gdk_window_set_skip_pager_hint (GdkWindow *window,
2477                                 gboolean   skips_pager)
2478 {
2479   if (GDK_WINDOW_DESTROYED (window) ||
2480       !WINDOW_IS_TOPLEVEL (window))
2481     return;
2482
2483   /* FIXME: Implement */
2484 }
2485
2486 void
2487 gdk_window_begin_resize_drag (GdkWindow     *window,
2488                               GdkWindowEdge  edge,
2489                               gint           button,
2490                               gint           root_x,
2491                               gint           root_y,
2492                               guint32        timestamp)
2493 {
2494   GdkWindowObject *private;
2495   GdkWindowImplQuartz *impl;
2496
2497   g_return_if_fail (GDK_IS_WINDOW (window));
2498
2499   if (edge != GDK_WINDOW_EDGE_SOUTH_EAST)
2500     {
2501       g_warning ("Resizing is only implemented for GDK_WINDOW_EDGE_SOUTH_EAST on Mac OS");
2502       return;
2503     }
2504
2505   if (GDK_WINDOW_DESTROYED (window))
2506     return;
2507
2508   private = GDK_WINDOW_OBJECT (window);
2509   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2510
2511   if (!impl->toplevel)
2512     {
2513       g_warning ("Can't call gdk_window_begin_resize_drag on non-toplevel window");
2514       return;
2515     }
2516
2517   [(GdkQuartzWindow *)impl->toplevel beginManualResize];
2518 }
2519
2520 void
2521 gdk_window_begin_move_drag (GdkWindow *window,
2522                             gint       button,
2523                             gint       root_x,
2524                             gint       root_y,
2525                             guint32    timestamp)
2526 {
2527   GdkWindowObject *private;
2528   GdkWindowImplQuartz *impl;
2529
2530   if (GDK_WINDOW_DESTROYED (window) ||
2531       !WINDOW_IS_TOPLEVEL (window))
2532     return;
2533
2534   private = GDK_WINDOW_OBJECT (window);
2535   impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2536
2537   if (!impl->toplevel)
2538     {
2539       g_warning ("Can't call gdk_window_begin_move_drag on non-toplevel window");
2540       return;
2541     }
2542
2543   [(GdkQuartzWindow *)impl->toplevel beginManualMove];
2544 }
2545
2546 void
2547 gdk_window_set_icon_list (GdkWindow *window,
2548                           GList     *pixbufs)
2549 {
2550   /* FIXME: Implement */
2551 }
2552
2553 void
2554 gdk_window_get_frame_extents (GdkWindow    *window,
2555                               GdkRectangle *rect)
2556 {
2557   GdkWindowObject *private;
2558   GdkWindow *toplevel;
2559   GdkWindowImplQuartz *impl;
2560   NSRect ns_rect;
2561
2562   g_return_if_fail (rect != NULL);
2563
2564   private = GDK_WINDOW_OBJECT (window);
2565
2566   rect->x = 0;
2567   rect->y = 0;
2568   rect->width = 1;
2569   rect->height = 1;
2570   
2571   toplevel = gdk_window_get_toplevel (window);
2572   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
2573
2574   ns_rect = [impl->toplevel frame];
2575
2576   _gdk_quartz_window_xy_to_gdk_xy (ns_rect.origin.x,
2577                                    ns_rect.origin.y + ns_rect.size.height,
2578                                    &rect->x, &rect->y);
2579
2580   rect->width = ns_rect.size.width;
2581   rect->height = ns_rect.size.height;
2582 }
2583
2584 void
2585 gdk_window_set_decorations (GdkWindow       *window,
2586                             GdkWMDecoration  decorations)
2587 {
2588   GdkWindowImplQuartz *impl;
2589   NSUInteger old_mask, new_mask;
2590   NSView *old_view;
2591
2592   if (GDK_WINDOW_DESTROYED (window) ||
2593       !WINDOW_IS_TOPLEVEL (window))
2594     return;
2595
2596   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2597
2598   if (decorations == 0 || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP ||
2599       impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN )
2600     {
2601       new_mask = NSBorderlessWindowMask;
2602     }
2603   else
2604     {
2605       /* FIXME: Honor other GDK_DECOR_* flags. */
2606       new_mask = (NSTitledWindowMask | NSClosableWindowMask |
2607                     NSMiniaturizableWindowMask | NSResizableWindowMask);
2608     }
2609
2610   GDK_QUARTZ_ALLOC_POOL;
2611
2612   old_mask = [impl->toplevel styleMask];
2613
2614   /* Note, there doesn't seem to be a way to change this without
2615    * recreating the toplevel. There might be bad side-effects of doing
2616    * that, but it seems alright.
2617    */
2618   if (old_mask != new_mask)
2619     {
2620       NSRect rect;
2621
2622       old_view = [impl->toplevel contentView];
2623
2624       rect = [impl->toplevel frame];
2625
2626       /* Properly update the size of the window when the titlebar is
2627        * added or removed.
2628        */
2629       if (old_mask == NSBorderlessWindowMask &&
2630           new_mask != NSBorderlessWindowMask)
2631         {
2632           rect = [NSWindow frameRectForContentRect:rect styleMask:new_mask];
2633
2634         }
2635       else if (old_mask != NSBorderlessWindowMask &&
2636                new_mask == NSBorderlessWindowMask)
2637         {
2638           rect = [NSWindow contentRectForFrameRect:rect styleMask:old_mask];
2639         }
2640
2641       impl->toplevel = [impl->toplevel initWithContentRect:rect
2642                                                  styleMask:new_mask
2643                                                    backing:NSBackingStoreBuffered
2644                                                      defer:NO];
2645
2646       [impl->toplevel setHasShadow: window_type_hint_to_shadow (impl->type_hint)];
2647       [impl->toplevel setLevel: window_type_hint_to_level (impl->type_hint)];
2648
2649       [impl->toplevel setContentView:old_view];
2650       [impl->toplevel setFrame:rect display:YES];
2651
2652       /* Invalidate the window shadow for non-opaque views that have shadow
2653        * enabled, to get the shadow shape updated.
2654        */
2655       if (![old_view isOpaque] && [impl->toplevel hasShadow])
2656         [(GdkQuartzView*)old_view setNeedsInvalidateShadow:YES];
2657     }
2658
2659   GDK_QUARTZ_RELEASE_POOL;
2660 }
2661
2662 gboolean
2663 gdk_window_get_decorations (GdkWindow       *window,
2664                             GdkWMDecoration *decorations)
2665 {
2666   GdkWindowImplQuartz *impl;
2667
2668   if (GDK_WINDOW_DESTROYED (window) ||
2669       !WINDOW_IS_TOPLEVEL (window))
2670     return FALSE;
2671
2672   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2673
2674   if (decorations)
2675     {
2676       /* Borderless is 0, so we can't check it as a bit being set. */
2677       if ([impl->toplevel styleMask] == NSBorderlessWindowMask)
2678         {
2679           *decorations = 0;
2680         }
2681       else
2682         {
2683           /* FIXME: Honor the other GDK_DECOR_* flags. */
2684           *decorations = GDK_DECOR_ALL;
2685         }
2686     }
2687
2688   return TRUE;
2689 }
2690
2691 void
2692 gdk_window_set_functions (GdkWindow    *window,
2693                           GdkWMFunction functions)
2694 {
2695   g_return_if_fail (GDK_IS_WINDOW (window));
2696
2697   /* FIXME: Implement */
2698 }
2699
2700 gboolean
2701 _gdk_windowing_window_queue_antiexpose (GdkWindow  *window,
2702                                         cairo_region_t  *area)
2703 {
2704   return FALSE;
2705 }
2706
2707 void
2708 gdk_window_stick (GdkWindow *window)
2709 {
2710   if (GDK_WINDOW_DESTROYED (window) ||
2711       !WINDOW_IS_TOPLEVEL (window))
2712     return;
2713 }
2714
2715 void
2716 gdk_window_unstick (GdkWindow *window)
2717 {
2718   if (GDK_WINDOW_DESTROYED (window) ||
2719       !WINDOW_IS_TOPLEVEL (window))
2720     return;
2721 }
2722
2723 void
2724 gdk_window_maximize (GdkWindow *window)
2725 {
2726   GdkWindowImplQuartz *impl;
2727
2728   if (GDK_WINDOW_DESTROYED (window) ||
2729       !WINDOW_IS_TOPLEVEL (window))
2730     return;
2731
2732   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2733
2734   if (GDK_WINDOW_IS_MAPPED (window))
2735     {
2736       GDK_QUARTZ_ALLOC_POOL;
2737
2738       if (impl->toplevel && ![impl->toplevel isZoomed])
2739         [impl->toplevel zoom:nil];
2740
2741       GDK_QUARTZ_RELEASE_POOL;
2742     }
2743   else
2744     {
2745       gdk_synthesize_window_state (window,
2746                                    0,
2747                                    GDK_WINDOW_STATE_MAXIMIZED);
2748     }
2749 }
2750
2751 void
2752 gdk_window_unmaximize (GdkWindow *window)
2753 {
2754   GdkWindowImplQuartz *impl;
2755
2756   if (GDK_WINDOW_DESTROYED (window) ||
2757       !WINDOW_IS_TOPLEVEL (window))
2758     return;
2759
2760   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2761
2762   if (GDK_WINDOW_IS_MAPPED (window))
2763     {
2764       GDK_QUARTZ_ALLOC_POOL;
2765
2766       if (impl->toplevel && [impl->toplevel isZoomed])
2767         [impl->toplevel zoom:nil];
2768
2769       GDK_QUARTZ_RELEASE_POOL;
2770     }
2771   else
2772     {
2773       gdk_synthesize_window_state (window,
2774                                    GDK_WINDOW_STATE_MAXIMIZED,
2775                                    0);
2776     }
2777 }
2778
2779 void
2780 gdk_window_iconify (GdkWindow *window)
2781 {
2782   GdkWindowImplQuartz *impl;
2783
2784   if (GDK_WINDOW_DESTROYED (window) ||
2785       !WINDOW_IS_TOPLEVEL (window))
2786     return;
2787
2788   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2789
2790   if (GDK_WINDOW_IS_MAPPED (window))
2791     {
2792       GDK_QUARTZ_ALLOC_POOL;
2793
2794       if (impl->toplevel)
2795         [impl->toplevel miniaturize:nil];
2796
2797       GDK_QUARTZ_RELEASE_POOL;
2798     }
2799   else
2800     {
2801       gdk_synthesize_window_state (window,
2802                                    0,
2803                                    GDK_WINDOW_STATE_ICONIFIED);
2804     }
2805 }
2806
2807 void
2808 gdk_window_deiconify (GdkWindow *window)
2809 {
2810   GdkWindowImplQuartz *impl;
2811
2812   if (GDK_WINDOW_DESTROYED (window) ||
2813       !WINDOW_IS_TOPLEVEL (window))
2814     return;
2815
2816   impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2817
2818   if (GDK_WINDOW_IS_MAPPED (window))
2819     {
2820       GDK_QUARTZ_ALLOC_POOL;
2821
2822       if (impl->toplevel)
2823         [impl->toplevel deminiaturize:nil];
2824
2825       GDK_QUARTZ_RELEASE_POOL;
2826     }
2827   else
2828     {
2829       gdk_synthesize_window_state (window,
2830                                    GDK_WINDOW_STATE_ICONIFIED,
2831                                    0);
2832     }
2833 }
2834
2835 static FullscreenSavedGeometry *
2836 get_fullscreen_geometry (GdkWindow *window)
2837 {
2838   return g_object_get_data (G_OBJECT (window), FULLSCREEN_DATA);
2839 }
2840
2841 void
2842 gdk_window_fullscreen (GdkWindow *window)
2843 {
2844   FullscreenSavedGeometry *geometry;
2845   GdkWindowObject *private = (GdkWindowObject *) window;
2846   NSRect frame;
2847
2848   if (GDK_WINDOW_DESTROYED (window) ||
2849       !WINDOW_IS_TOPLEVEL (window))
2850     return;
2851
2852   geometry = get_fullscreen_geometry (window);
2853   if (!geometry)
2854     {
2855       geometry = g_new (FullscreenSavedGeometry, 1);
2856
2857       geometry->x = private->x;
2858       geometry->y = private->y;
2859       geometry->width = private->width;
2860       geometry->height = private->height;
2861
2862       if (!gdk_window_get_decorations (window, &geometry->decor))
2863         geometry->decor = GDK_DECOR_ALL;
2864
2865       g_object_set_data_full (G_OBJECT (window),
2866                               FULLSCREEN_DATA, geometry, 
2867                               g_free);
2868
2869       gdk_window_set_decorations (window, 0);
2870
2871       frame = [[NSScreen mainScreen] frame];
2872       move_resize_window_internal (window,
2873                                    0, 0, 
2874                                    frame.size.width, frame.size.height);
2875     }
2876
2877   SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar);
2878
2879   gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
2880 }
2881
2882 void
2883 gdk_window_unfullscreen (GdkWindow *window)
2884 {
2885   FullscreenSavedGeometry *geometry;
2886
2887   if (GDK_WINDOW_DESTROYED (window) ||
2888       !WINDOW_IS_TOPLEVEL (window))
2889     return;
2890
2891   geometry = get_fullscreen_geometry (window);
2892   if (geometry)
2893     {
2894       SetSystemUIMode (kUIModeNormal, 0);
2895
2896       move_resize_window_internal (window,
2897                                    geometry->x,
2898                                    geometry->y,
2899                                    geometry->width,
2900                                    geometry->height);
2901       
2902       gdk_window_set_decorations (window, geometry->decor);
2903
2904       g_object_set_data (G_OBJECT (window), FULLSCREEN_DATA, NULL);
2905
2906       gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
2907     }
2908 }
2909
2910 void
2911 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
2912 {
2913   GdkWindowObject *private = (GdkWindowObject *) window;
2914   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2915   gint level;
2916
2917   g_return_if_fail (GDK_IS_WINDOW (window));
2918
2919   if (GDK_WINDOW_DESTROYED (window) ||
2920       !WINDOW_IS_TOPLEVEL (window))
2921     return;
2922
2923   level = window_type_hint_to_level (gdk_window_get_type_hint (window));
2924   
2925   /* Adjust normal window level by one if necessary. */
2926   [impl->toplevel setLevel: level + (setting ? 1 : 0)];
2927 }
2928
2929 void
2930 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
2931 {
2932   GdkWindowObject *private = (GdkWindowObject *) window;
2933   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2934   gint level;
2935
2936   g_return_if_fail (GDK_IS_WINDOW (window));
2937
2938   if (GDK_WINDOW_DESTROYED (window) ||
2939       !WINDOW_IS_TOPLEVEL (window))
2940     return;
2941   
2942   level = window_type_hint_to_level (gdk_window_get_type_hint (window));
2943   
2944   /* Adjust normal window level by one if necessary. */
2945   [impl->toplevel setLevel: level - (setting ? 1 : 0)];
2946 }
2947
2948 GdkWindow *
2949 gdk_window_get_group (GdkWindow *window)
2950 {
2951   g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2952
2953   if (GDK_WINDOW_DESTROYED (window) ||
2954       !WINDOW_IS_TOPLEVEL (window))
2955     return NULL;
2956
2957   /* FIXME: Implement */
2958
2959   return NULL;
2960 }
2961
2962 void          
2963 gdk_window_set_group (GdkWindow *window, 
2964                       GdkWindow *leader)
2965 {
2966   /* FIXME: Implement */        
2967 }
2968
2969 GdkWindow*
2970 gdk_window_foreign_new_for_display (GdkDisplay      *display,
2971                                     GdkNativeWindow  anid)
2972 {
2973   /* Foreign windows aren't supported in Mac OS X */
2974   return NULL;
2975 }
2976
2977 GdkWindow*
2978 gdk_window_lookup (GdkNativeWindow anid)
2979 {
2980   /* Foreign windows aren't supported in Mac OS X */
2981   return NULL;
2982 }
2983
2984 GdkWindow *
2985 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
2986 {
2987   /* Foreign windows aren't supported in Mac OS X */
2988   return NULL;
2989 }
2990
2991 void
2992 gdk_window_enable_synchronized_configure (GdkWindow *window)
2993 {
2994 }
2995
2996 void
2997 gdk_window_configure_finished (GdkWindow *window)
2998 {
2999 }
3000
3001 void
3002 gdk_window_destroy_notify (GdkWindow *window)
3003 {
3004   check_grab_destroy (window);
3005 }
3006
3007 void 
3008 _gdk_windowing_window_beep (GdkWindow *window)
3009 {
3010   g_return_if_fail (GDK_IS_WINDOW (window));
3011
3012   gdk_display_beep (_gdk_display);
3013 }
3014
3015 void
3016 gdk_window_set_opacity (GdkWindow *window,
3017                         gdouble    opacity)
3018 {
3019   GdkWindowObject *private = (GdkWindowObject *) window;
3020   GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
3021
3022   g_return_if_fail (GDK_IS_WINDOW (window));
3023   g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3024
3025   if (GDK_WINDOW_DESTROYED (window) ||
3026       !WINDOW_IS_TOPLEVEL (window))
3027     return;
3028
3029   if (opacity < 0)
3030     opacity = 0;
3031   else if (opacity > 1)
3032     opacity = 1;
3033
3034   [impl->toplevel setAlphaValue: opacity];
3035 }
3036
3037 void
3038 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3039 {
3040 }
3041
3042 cairo_region_t *
3043 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
3044 {
3045   /* FIXME: implement */
3046   return NULL;
3047 }
3048
3049 cairo_region_t *
3050 _gdk_windowing_window_get_shape (GdkWindow *window)
3051 {
3052   /* FIXME: implement */
3053   return NULL;
3054 }
3055
3056 cairo_region_t *
3057 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3058 {
3059   /* FIXME: implement */
3060   return NULL;
3061 }
3062
3063 static void
3064 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3065 {
3066   iface->show = gdk_window_quartz_show;
3067   iface->hide = gdk_window_quartz_hide;
3068   iface->withdraw = gdk_window_quartz_withdraw;
3069   iface->set_events = gdk_window_quartz_set_events;
3070   iface->get_events = gdk_window_quartz_get_events;
3071   iface->raise = gdk_window_quartz_raise;
3072   iface->lower = gdk_window_quartz_lower;
3073   iface->restack_toplevel = gdk_window_quartz_restack_toplevel;
3074   iface->move_resize = gdk_window_quartz_move_resize;
3075   iface->set_background = gdk_window_quartz_set_background;
3076   iface->set_back_pixmap = gdk_window_quartz_set_back_pixmap;
3077   iface->reparent = gdk_window_quartz_reparent;
3078   iface->set_device_cursor = gdk_window_quartz_set_device_cursor;
3079   iface->get_geometry = gdk_window_quartz_get_geometry;
3080   iface->get_root_coords = gdk_window_quartz_get_root_coords;
3081   iface->get_device_state = gdk_window_quartz_get_device_state;
3082   iface->get_deskrelative_origin = gdk_window_quartz_get_deskrelative_origin;
3083   iface->shape_combine_region = gdk_window_quartz_shape_combine_region;
3084   iface->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
3085   iface->set_static_gravities = gdk_window_quartz_set_static_gravities;
3086   iface->queue_antiexpose = _gdk_quartz_window_queue_antiexpose;
3087   iface->translate = _gdk_quartz_window_translate;
3088   iface->destroy = _gdk_quartz_window_destroy;
3089 }