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