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