gtk/gdk/quartz/gdkwindow-quartz.c

2226 lines
51 KiB
C
Raw Normal View History

/* gdkwindow-quartz.c
*
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
* Copyright (C) 2005-2007 Imendio AB
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include "gdk.h"
#include "gdkprivate-quartz.h"
static gpointer parent_class;
static GSList *update_windows = NULL;
static guint update_idle = 0;
#define WINDOW_IS_TOPLEVEL(window) \
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
NSView *
gdk_quartz_window_get_nsview (GdkWindow *window)
{
GdkWindowObject *private = (GdkWindowObject *)window;
return ((GdkWindowImplQuartz *)private->impl)->view;
}
static void
gdk_window_impl_quartz_get_size (GdkDrawable *drawable,
gint *width,
gint *height)
{
g_return_if_fail (GDK_IS_WINDOW_IMPL_QUARTZ (drawable));
if (width)
*width = GDK_WINDOW_IMPL_QUARTZ (drawable)->width;
if (height)
*height = GDK_WINDOW_IMPL_QUARTZ (drawable)->height;
}
static GdkRegion*
gdk_window_impl_quartz_get_visible_region (GdkDrawable *drawable)
{
GdkWindowObject *private = GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper);
GdkRectangle rect;
GdkWindowImplQuartz *impl;
GList *windows = NULL, *l;
/* FIXME: The clip rectangle should really be cached
* and recalculated when the window rectangle changes.
*/
while (private)
{
windows = g_list_prepend (windows, private);
if (private->parent == GDK_WINDOW_OBJECT (_gdk_root))
break;
private = private->parent;
}
/* Get rectangle for toplevel window */
private = GDK_WINDOW_OBJECT (windows->data);
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
rect.x = 0;
rect.y = 0;
rect.width = impl->width;
rect.height = impl->height;
/* Skip toplevel window since we have its rect */
for (l = windows->next; l; l = l->next)
{
private = GDK_WINDOW_OBJECT (l->data);
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
GdkRectangle tmp_rect;
tmp_rect.x = -MIN (0, private->x - rect.x);
tmp_rect.y = -MIN (0, private->y - rect.y);
tmp_rect.width = MIN (rect.width, impl->width + private->x - rect.x) - MAX (0, private->x - rect.x);
tmp_rect.height = MIN (rect.height, impl->height + private->y - rect.y) - MAX (0, private->y - rect.y);
rect = tmp_rect;
}
g_list_free (windows);
return gdk_region_rectangle (&rect);
}
static void
gdk_window_impl_quartz_finalize (GObject *object)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (object);
if (impl->nscursor)
[impl->nscursor release];
if (impl->paint_clip_region)
gdk_region_destroy (impl->paint_clip_region);
if (impl->transient_for)
g_object_unref (impl->transient_for);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
{
GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
object_class->finalize = gdk_window_impl_quartz_finalize;
drawable_class->get_size = gdk_window_impl_quartz_get_size;
/* Visible and clip regions are the same */
drawable_class->get_clip_region = gdk_window_impl_quartz_get_visible_region;
drawable_class->get_visible_region = gdk_window_impl_quartz_get_visible_region;
}
static void
gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
{
impl->width = 1;
impl->height = 1;
impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
}
static void
gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
GdkRegion *region)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
GdkDrawableImplQuartz *drawable_impl;
int n_rects;
GdkRectangle *rects;
GdkPixmap *bg_pixmap;
GdkWindow *window;
drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (impl);
bg_pixmap = GDK_WINDOW_OBJECT (drawable_impl->wrapper)->bg_pixmap;
if (impl->begin_paint_count == 0)
impl->paint_clip_region = gdk_region_copy (region);
else
gdk_region_union (impl->paint_clip_region, region);
impl->begin_paint_count++;
if (bg_pixmap == GDK_NO_BG)
return;
gdk_region_get_rectangles (region, &rects, &n_rects);
if (bg_pixmap == NULL)
{
CGContextRef cg_context;
gfloat r, g, b, a;
gint i;
cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
_gdk_quartz_colormap_get_rgba_from_pixel (gdk_drawable_get_colormap (drawable_impl->wrapper),
GDK_WINDOW_OBJECT (drawable_impl->wrapper)->bg_color.pixel,
&r, &g, &b, &a);
for (i = 0; i < n_rects; i++)
{
CGContextSetRGBFillColor (cg_context, r, g, b, a);
CGContextFillRect (cg_context,
Implement lots of value setters for GdkGC, based on a heavily modified 2006-09-21 Michael Natterer <mitch@imendio.com> Implement lots of value setters for GdkGC, based on a heavily modified patch from Thomas Broyer (bug #328853): * gdk/quartz/gdkcolor-quartz.c: removed functions which set colors on the CGContext. Instead, added gdk_quartz_get_rgba_from_pixel() which simply returns RGBA values from a GdkColor's pixel value. See gdk_quartz_update_context_from_gc() below. * gdk/quartz/gdkprivate-quartz.h (struct GdkGCQuartz): added lots of members for the newly suppored GC values. Added enum GdkQuartzContextValuesMask which is used for setting up the CGContext for filling and/or stroking. * gdk/quartz/gdkgc-quartz.c (gdk_quartz_gc_get_values) (gdk_quartz_gc_set_values) (_gdk_windowing_gc_copy): support a lot more GC values. (gdk_quartz_update_context_from_gc): added GdkQuartzContextValuesMask parameter and set filling/stroking parameters accordingly. This function also gained full control over the FG and BG colors (they can't be set separately any more). The stipple mask part of the patch doesn't work but seems to take the right approach and doesn't make things worse, so I applied it. Did *not* apply the clipping part of the patch since I don't understand it (I don't understand the version in CVS either, but it at least works :-) * gdk/quartz/gdkdrawable-quartz.c: pass the right masks to gdk_quartz_update_context_from_gc() and removed separate color setting calls. Some minor fixes. * gdk/quartz/gdkwindow-quartz.c (gdk_window_impl_quartz_begin_paint_region): set the CGContext's fill color manually. We don't have/need a GC here.
2006-09-21 17:05:33 +00:00
CGRectMake (rects[i].x, rects[i].y,
rects[i].width, rects[i].height));
}
gdk_quartz_drawable_release_context (GDK_DRAWABLE (impl), cg_context);
}
else
{
int x, y;
int x_offset, y_offset;
int width, height;
GdkGC *gc;
x_offset = y_offset = 0;
window = GDK_WINDOW (drawable_impl->wrapper);
while (window && ((GdkWindowObject *) window)->bg_pixmap == GDK_PARENT_RELATIVE_BG)
{
/* If this window should have the same background as the parent,
* fetch the parent. (And if the same goes for the parent, fetch
* the grandparent, etc.)
*/
x_offset += ((GdkWindowObject *) window)->x;
y_offset += ((GdkWindowObject *) window)->y;
window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
}
/* Note: There should be a CG API to draw tiled images, we might
* want to look into that for this.
*/
gc = gdk_gc_new (GDK_DRAWABLE (impl));
gdk_drawable_get_size (GDK_DRAWABLE (bg_pixmap), &width, &height);
x = -x_offset;
while (x < (rects[0].x + rects[0].width))
{
if (x + width >= rects[0].x)
{
y = -y_offset;
while (y < (rects[0].y + rects[0].height))
{
if (y + height >= rects[0].y)
gdk_draw_drawable (GDK_DRAWABLE (impl), gc, bg_pixmap, 0, 0, x, y, width, height);
y += height;
}
}
x += width;
}
g_object_unref (gc);
}
g_free (rects);
}
static void
gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
impl->begin_paint_count--;
if (impl->begin_paint_count == 0)
{
gdk_region_destroy (impl->paint_clip_region);
impl->paint_clip_region = NULL;
}
}
static void
gdk_window_quartz_process_updates_internal (GdkWindow *window)
{
GdkWindowObject *private = (GdkWindowObject *) window;
GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *) private->impl;
if (private->update_area)
{
int i, n_rects;
GdkRectangle *rects;
gdk_region_get_rectangles (private->update_area, &rects, &n_rects);
gdk_region_destroy (private->update_area);
private->update_area = NULL;
for (i = 0; i < n_rects; i++)
{
[impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y,
rects[i].width, rects[i].height)];
}
[impl->view displayIfNeeded];
g_free (rects);
}
}
static void
gdk_window_quartz_process_all_updates (void)
{
GSList *old_update_windows = update_windows;
GSList *tmp_list = update_windows;
update_idle = 0;
update_windows = NULL;
g_slist_foreach (old_update_windows, (GFunc) g_object_ref, NULL);
GDK_QUARTZ_ALLOC_POOL;
while (tmp_list)
{
gdk_window_quartz_process_updates_internal (tmp_list->data);
g_object_unref (tmp_list->data);
tmp_list = tmp_list->next;
}
GDK_QUARTZ_RELEASE_POOL;
g_slist_free (old_update_windows);
}
static gboolean
gdk_window_quartz_update_idle (gpointer data)
{
GDK_THREADS_ENTER ();
gdk_window_quartz_process_all_updates ();
GDK_THREADS_LEAVE ();
return FALSE;
}
static void
gdk_window_impl_quartz_invalidate_maybe_recurse (GdkPaintable *paintable,
GdkRegion *region,
gboolean (*child_func) (GdkWindow *, gpointer),
gpointer user_data)
{
GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
GdkDrawableImplQuartz *drawable_impl = (GdkDrawableImplQuartz *) window_impl;
GdkWindow *window = (GdkWindow *) drawable_impl->wrapper;
GdkWindowObject *private = (GdkWindowObject *) window;
GdkRegion *visible_region;
visible_region = gdk_drawable_get_visible_region (window);
gdk_region_intersect (visible_region, region);
if (private->update_area)
{
gdk_region_union (private->update_area, visible_region);
gdk_region_destroy (visible_region);
}
else
{
update_windows = g_slist_prepend (update_windows, window);
private->update_area = visible_region;
if (update_idle == 0)
update_idle = g_idle_add_full (GDK_PRIORITY_REDRAW,
gdk_window_quartz_update_idle, NULL, NULL);
}
}
static void
gdk_window_impl_quartz_process_updates (GdkPaintable *paintable,
gboolean update_children)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
GdkDrawableImplQuartz *drawable_impl = (GdkDrawableImplQuartz *) impl;
GdkWindowObject *private = (GdkWindowObject *) drawable_impl->wrapper;
if (private->update_area)
{
gdk_window_quartz_process_updates_internal ((GdkWindow *) private);
update_windows = g_slist_remove (update_windows, private);
}
}
static void
gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
{
iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
iface->end_paint = gdk_window_impl_quartz_end_paint;
iface->invalidate_maybe_recurse = gdk_window_impl_quartz_invalidate_maybe_recurse;
iface->process_updates = gdk_window_impl_quartz_process_updates;
}
GType
_gdk_window_impl_quartz_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
const GTypeInfo object_info =
{
sizeof (GdkWindowImplQuartzClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gdk_window_impl_quartz_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GdkWindowImplQuartz),
0, /* n_preallocs */
(GInstanceInitFunc) gdk_window_impl_quartz_init,
};
const GInterfaceInfo paintable_info =
{
(GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
NULL,
NULL
};
object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
"GdkWindowImplQuartz",
&object_info, 0);
g_type_add_interface_static (object_type,
GDK_TYPE_PAINTABLE,
&paintable_info);
}
return object_type;
}
GType
_gdk_window_impl_get_type (void)
{
return _gdk_window_impl_quartz_get_type ();
}
static const gchar *
get_default_title (void)
{
const char *title;
title = g_get_application_name ();
if (!title)
title = g_get_prgname ();
return title;
}
/* FIXME: It would be nice to have one function that takes an NSPoint
* and flips the coords for any window.
*/
gint
_gdk_quartz_window_get_inverted_screen_y (gint y)
{
NSRect rect = [[NSScreen mainScreen] frame];
return rect.size.height - y;
}
static GdkWindow *
find_child_window_helper (GdkWindow *window,
gint x,
gint y,
gint x_offset,
gint y_offset)
{
GList *l;
for (l = GDK_WINDOW_OBJECT (window)->children; l; l = l->next)
{
GdkWindowObject *private = l->data;
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
int temp_x, temp_y;
if (!GDK_WINDOW_IS_MAPPED (private))
continue;
temp_x = x_offset + private->x;
temp_y = y_offset + private->y;
/* FIXME: Are there off by one errors here? */
if (x >= temp_x && y >= temp_y &&
x < temp_x + impl->width && y < temp_y + impl->height)
{
/* Look for child windows. */
return find_child_window_helper (l->data,
x, y,
temp_x, temp_y);
}
}
return window;
}
/* Given a GdkWindow and coordinates relative to it, returns the
* innermost subwindow that contains the point. If the coordinates are
* outside the passed in window, NULL is returned.
*/
GdkWindow *
_gdk_quartz_window_find_child (GdkWindow *window,
gint x,
gint y)
{
GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
if (x >= 0 && y >= 0 && x < impl->width && y < impl->height)
return find_child_window_helper (window, x, y, 0, 0);
return NULL;
}
GdkWindow *
gdk_window_new (GdkWindow *parent,
GdkWindowAttr *attributes,
gint attributes_mask)
{
GdkWindow *window;
GdkWindowObject *private;
GdkWindowImplQuartz *impl;
GdkDrawableImplQuartz *draw_impl;
GdkVisual *visual;
if (parent && GDK_WINDOW_DESTROYED (parent))
return NULL;
GDK_QUARTZ_ALLOC_POOL;
if (!parent)
parent = _gdk_root;
window = g_object_new (GDK_TYPE_WINDOW, NULL);
private = (GdkWindowObject *)window;
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl);
draw_impl->wrapper = GDK_DRAWABLE (window);
private->parent = (GdkWindowObject *)parent;
private->accept_focus = TRUE;
private->focus_on_map = TRUE;
if (attributes_mask & GDK_WA_X)
private->x = attributes->x;
else
private->x = 0;
if (attributes_mask & GDK_WA_Y)
private->y = attributes->y;
else if (attributes_mask & GDK_WA_X)
private->y = 100;
else
private->y = 0;
private->event_mask = attributes->event_mask;
impl->width = attributes->width > 1 ? attributes->width : 1;
impl->height = attributes->height > 1 ? attributes->height : 1;
if (attributes_mask & GDK_WA_VISUAL)
visual = attributes->visual;
else
visual = gdk_screen_get_system_visual (_gdk_screen);
if (attributes->wclass == GDK_INPUT_ONLY)
{
/* Backwards compatiblity - we've always ignored
* attributes->window_type for input-only windows
* before
*/
if (parent == _gdk_root)
private->window_type = GDK_WINDOW_TEMP;
else
private->window_type = GDK_WINDOW_CHILD;
}
else
private->window_type = attributes->window_type;
/* Sanity checks */
switch (private->window_type)
{
case GDK_WINDOW_TOPLEVEL:
case GDK_WINDOW_DIALOG:
case GDK_WINDOW_TEMP:
if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
{
g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
"of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
}
case GDK_WINDOW_CHILD:
break;
default:
g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
GDK_QUARTZ_RELEASE_POOL;
return NULL;
}
if (attributes->wclass == GDK_INPUT_OUTPUT)
{
private->input_only = FALSE;
private->depth = visual->depth;
if (attributes_mask & GDK_WA_COLORMAP)
{
draw_impl->colormap = attributes->colormap;
g_object_ref (attributes->colormap);
}
else
{
if (visual == gdk_screen_get_system_visual (_gdk_screen))
{
draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
g_object_ref (draw_impl->colormap);
}
else if (visual == gdk_screen_get_rgba_visual (_gdk_screen))
{
draw_impl->colormap = gdk_screen_get_rgba_colormap (_gdk_screen);
g_object_ref (draw_impl->colormap);
}
else
{
draw_impl->colormap = gdk_colormap_new (visual, FALSE);
}
}
private->bg_color.pixel = 0;
private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
}
else
{
private->depth = 0;
private->input_only = TRUE;
draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
g_object_ref (draw_impl->colormap);
}
if (private->parent)
private->parent->children = g_list_prepend (private->parent->children, window);
gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
(attributes->cursor) :
NULL));
switch (attributes->window_type)
{
case GDK_WINDOW_TOPLEVEL:
case GDK_WINDOW_DIALOG:
case GDK_WINDOW_TEMP:
{
NSRect content_rect =
NSMakeRect (private->x,
_gdk_quartz_window_get_inverted_screen_y (private->y) - impl->height,
impl->width, impl->height);
const char *title;
int style_mask;
switch (attributes->window_type)
{
case GDK_WINDOW_TEMP:
style_mask = NSBorderlessWindowMask;
break;
default:
style_mask = (NSTitledWindowMask |
NSClosableWindowMask |
NSMiniaturizableWindowMask |
NSResizableWindowMask);
}
impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO];
if (attributes_mask & GDK_WA_TITLE)
title = attributes->title;
else
title = get_default_title ();
gdk_window_set_title (window, title);
if (draw_impl->colormap == gdk_screen_get_rgba_colormap (_gdk_screen))
{
[impl->toplevel setOpaque:NO];
[impl->toplevel setBackgroundColor:[NSColor clearColor]];
}
impl->view = [[GdkQuartzView alloc] initWithFrame:content_rect];
[impl->view setGdkWindow:window];
[impl->toplevel setContentView:impl->view];
}
break;
case GDK_WINDOW_CHILD:
{
GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl);
if (attributes->wclass == GDK_INPUT_OUTPUT)
{
NSRect frame_rect = NSMakeRect (private->x, private->y, impl->width, impl->height);
impl->view = [[GdkQuartzView alloc] initWithFrame:frame_rect];
[impl->view setGdkWindow:window];
/* GdkWindows should be hidden by default */
[impl->view setHidden:YES];
[parent_impl->view addSubview:impl->view];
}
}
break;
default:
g_assert_not_reached ();
}
GDK_QUARTZ_RELEASE_POOL;
if (attributes_mask & GDK_WA_TYPE_HINT)
gdk_window_set_type_hint (window, attributes->type_hint);
return window;
}
void
_gdk_windowing_window_init (void)
{
GdkWindowObject *private;
GdkWindowImplQuartz *impl;
NSRect rect;
g_assert (_gdk_root == NULL);
_gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
/* Note: This needs to be reworked for multi-screen support. */
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
rect = [[NSScreen mainScreen] frame];
impl->width = rect.size.width;
impl->height = rect.size.height;
private = (GdkWindowObject *)_gdk_root;
private->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */
private->window_type = GDK_WINDOW_ROOT;
private->depth = 24;
}
void
_gdk_windowing_window_destroy (GdkWindow *window,
gboolean recursing,
gboolean foreign_destroy)
{
update_windows = g_slist_remove (update_windows, window);
if (!recursing && !foreign_destroy)
{
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
if (window == _gdk_quartz_events_get_mouse_window ())
_gdk_quartz_events_update_mouse_window (_gdk_root);
GDK_QUARTZ_ALLOC_POOL;
_gdk_quartz_drawable_finish (GDK_DRAWABLE (impl));
if (impl->toplevel)
[impl->toplevel close];
else if (impl->view)
[impl->view release];
GDK_QUARTZ_RELEASE_POOL;
}
}
void
_gdk_windowing_window_destroy_foreign (GdkWindow *window)
{
/* Foreign windows aren't supported in OSX. */
}
static gboolean
all_parents_shown (GdkWindowObject *private)
{
while (GDK_WINDOW_IS_MAPPED (private))
{
if (private->parent)
private = (GdkWindowObject *)private->parent;
else
return TRUE;
}
return FALSE;
}
/* Note: the raise argument is not really used, it doesn't seem
* possible to show a window without raising it?
*/
static void
show_window_internal (GdkWindow *window,
gboolean raise)
{
GdkWindowObject *private;
GdkWindowImplQuartz *impl;
gboolean focus_on_map;
if (GDK_WINDOW_DESTROYED (window))
return;
GDK_QUARTZ_ALLOC_POOL;
private = (GdkWindowObject *)window;
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
if (!GDK_WINDOW_IS_MAPPED (window))
focus_on_map = private->focus_on_map;
else
focus_on_map = TRUE;
if (impl->toplevel)
{
/* We should make the window not raise for !raise, but at least
* this will keep it from getting focused in that case.
*/
if (private->accept_focus && focus_on_map && raise &&
private->window_type != GDK_WINDOW_TEMP)
[impl->toplevel makeKeyAndOrderFront:impl->toplevel];
else
[impl->toplevel orderFront:nil];
[impl->view setNeedsDisplay:YES];
}
else
{
[impl->view setHidden:NO];
[impl->view setNeedsDisplay:YES];
}
if (all_parents_shown (private->parent))
_gdk_quartz_events_send_map_events (window);
gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0);
if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
gdk_window_maximize (window);
if (private->state & GDK_WINDOW_STATE_ICONIFIED)
gdk_window_iconify (window);
if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
{
GdkWindowImplQuartz *parent_impl;
parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
[parent_impl->toplevel addChildWindow:impl->toplevel ordered:NSWindowAbove];
}
GDK_QUARTZ_RELEASE_POOL;
}
void
gdk_window_show_unraised (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
show_window_internal (window, FALSE);
}
void
gdk_window_show (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
show_window_internal (window, TRUE);
}
void
gdk_window_hide (GdkWindow *window)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowImplQuartz *impl;
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
if (GDK_WINDOW_IS_MAPPED (window))
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_WITHDRAWN);
_gdk_window_clear_update_area (window);
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
if (impl->toplevel)
{
/* We must unset the transient while it is hidden, otherwise
* quartz won't hide the window.
*/
if (impl->transient_for)
{
if (!GDK_WINDOW_DESTROYED (impl->transient_for))
{
GdkWindowImplQuartz *parent_impl;
parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
[parent_impl->toplevel removeChildWindow:impl->toplevel];
}
}
[impl->toplevel orderOut:nil];
}
else if (impl->view)
{
[impl->view setHidden:YES];
}
if (window == _gdk_quartz_pointer_grab_window)
gdk_pointer_ungrab (0);
if (window == _gdk_quartz_keyboard_grab_window)
gdk_keyboard_ungrab (0);
}
void
gdk_window_withdraw (GdkWindow *window)
{
gdk_window_hide (window);
}
static void
move_resize_window_internal (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowImplQuartz *impl;
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
if (x != -1)
private->x = x;
if (y != -1)
private->y = y;
if (width != -1)
impl->width = width;
if (height != -1)
impl->height = height;
GDK_QUARTZ_ALLOC_POOL;
if (impl->toplevel)
{
NSRect content_rect =
NSMakeRect (private->x,
_gdk_quartz_window_get_inverted_screen_y (private->y),
impl->width, impl->height);
NSRect frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
frame_rect.origin.y -= frame_rect.size.height;
[impl->toplevel setFrame:frame_rect display:YES];
}
else
{
if (!private->input_only)
{
NSRect nsrect;
nsrect = NSMakeRect (private->x, private->y, impl->width, impl->height);
[impl->view setFrame: nsrect];
[impl->view setNeedsDisplay:YES];
}
}
GDK_QUARTZ_RELEASE_POOL;
}
void
gdk_window_move (GdkWindow *window,
gint x,
gint y)
{
g_return_if_fail (GDK_IS_WINDOW (window));
move_resize_window_internal (window, x, y, -1, -1);
}
void
gdk_window_resize (GdkWindow *window,
gint width,
gint height)
{
g_return_if_fail (GDK_IS_WINDOW (window));
if (width < 1)
width = 1;
if (height < 1)
height = 1;
move_resize_window_internal (window, -1, -1, width, height);
}
void
gdk_window_move_resize (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
if (width < 1)
width = 1;
if (height < 1)
height = 1;
move_resize_window_internal (window, x, y, width, height);
}
void
gdk_window_reparent (GdkWindow *window,
GdkWindow *new_parent,
gint x,
gint y)
{
g_warning ("gdk_window_reparent: %p %p (%d, %d)",
window, new_parent, x, y);
/* FIXME: Implement */
}
void
_gdk_windowing_window_clear_area (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
/* FIXME: Implement */
}
void
_gdk_windowing_window_clear_area_e (GdkWindow *window,
gint x,
gint y,
gint width,
gint height)
{
/* FIXME: Implement */
}
void
gdk_window_raise (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
/* FIXME: Only supported for toplevels currently. */
if (WINDOW_IS_TOPLEVEL (window))
{
GdkWindowImplQuartz *impl;
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
[impl->toplevel orderFront:impl->toplevel];
}
}
void
gdk_window_lower (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
/* FIXME: Only supported for toplevels currently. */
if (WINDOW_IS_TOPLEVEL (window))
{
GdkWindowImplQuartz *impl;
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
[impl->toplevel orderBack:impl->toplevel];
}
}
void
gdk_window_set_background (GdkWindow *window,
const GdkColor *color)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowImplQuartz *impl;
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
private->bg_color = *color;
if (private->bg_pixmap &&
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
private->bg_pixmap != GDK_NO_BG)
g_object_unref (private->bg_pixmap);
private->bg_pixmap = NULL;
}
void
gdk_window_set_back_pixmap (GdkWindow *window,
GdkPixmap *pixmap,
gboolean parent_relative)
{
GdkWindowObject *private = (GdkWindowObject *)window;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (pixmap == NULL || !parent_relative);
g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
if (GDK_WINDOW_DESTROYED (window))
return;
if (private->bg_pixmap &&
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
private->bg_pixmap != GDK_NO_BG)
g_object_unref (private->bg_pixmap);
if (parent_relative)
{
private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
GDK_NOTE (MISC, g_print (G_STRLOC ": setting background pixmap to parent_relative\n"));
}
else
{
if (pixmap)
{
g_object_ref (pixmap);
private->bg_pixmap = pixmap;
}
else
{
private->bg_pixmap = GDK_NO_BG;
}
}
}
void
gdk_window_set_cursor (GdkWindow *window,
GdkCursor *cursor)
{
GdkWindowImplQuartz *impl;
GdkCursorPrivate *cursor_private;
NSCursor *nscursor;
g_return_if_fail (GDK_IS_WINDOW (window));
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
cursor_private = (GdkCursorPrivate *)cursor;
if (GDK_WINDOW_DESTROYED (window))
return;
if (!cursor)
nscursor = NULL;
else
nscursor = [cursor_private->nscursor retain];
if (impl->nscursor)
[impl->nscursor release];
impl->nscursor = nscursor;
_gdk_quartz_events_update_cursor (_gdk_quartz_events_get_mouse_window ());
}
void
gdk_window_get_geometry (GdkWindow *window,
gint *x,
gint *y,
gint *width,
gint *height,
gint *depth)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
gboolean
gdk_window_get_origin (GdkWindow *window,
gint *x,
gint *y)
{
GdkWindowObject *private;
int tmp_x = 0, tmp_y = 0;
GdkWindow *toplevel;
NSRect content_rect;
GdkWindowImplQuartz *impl;
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
if (GDK_WINDOW_DESTROYED (window))
{
if (x)
*x = 0;
if (y)
*y = 0;
return FALSE;
}
if (window == _gdk_root)
{
*x = 0;
*y = 0;
return TRUE;
}
private = GDK_WINDOW_OBJECT (window);
toplevel = gdk_window_get_toplevel (window);
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
tmp_x = content_rect.origin.x;
tmp_y = _gdk_quartz_window_get_inverted_screen_y (content_rect.origin.y + content_rect.size.height);
while (private != GDK_WINDOW_OBJECT (toplevel))
{
tmp_x += private->x;
tmp_y += private->y;
private = private->parent;
}
if (x)
*x = tmp_x;
if (y)
*y = tmp_y;
return TRUE;
}
gboolean
gdk_window_get_deskrelative_origin (GdkWindow *window,
gint *x,
gint *y)
{
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
return gdk_window_get_origin (window, x, y);
}
void
gdk_window_get_root_origin (GdkWindow *window,
gint *x,
gint *y)
{
GdkRectangle rect;
g_return_if_fail (GDK_IS_WINDOW (window));
rect.x = 0;
rect.y = 0;
gdk_window_get_frame_extents (window, &rect);
if (x)
*x = rect.x;
if (y)
*y = rect.y;
}
/* Returns coordinates relative to the root. */
void
_gdk_windowing_get_pointer (GdkDisplay *display,
GdkScreen **screen,
gint *x,
gint *y,
GdkModifierType *mask)
{
g_return_if_fail (display == _gdk_display);
*screen = _gdk_screen;
_gdk_windowing_window_get_pointer (_gdk_display, _gdk_root, x, y, mask);
}
/* Returns coordinates relative to the passed in window. */
GdkWindow *
_gdk_windowing_window_get_pointer (GdkDisplay *display,
GdkWindow *window,
gint *x,
gint *y,
GdkModifierType *mask)
{
GdkWindowObject *toplevel;
GdkWindowObject *private;
NSPoint point;
gint x_tmp, y_tmp;
GdkWindow *found_window;
if (GDK_WINDOW_DESTROYED (window))
{
*x = 0;
*y = 0;
*mask = 0;
return NULL;
}
toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (window));
*mask = _gdk_quartz_events_get_current_event_mask ();
/* Get the y coordinate, needs to be flipped. */
if (window == _gdk_root)
{
point = [NSEvent mouseLocation];
x_tmp = point.x;
y_tmp = _gdk_quartz_window_get_inverted_screen_y (point.y);
}
else
{
GdkWindowImplQuartz *impl;
NSWindow *nswindow;
impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
nswindow = impl->toplevel;
point = [nswindow mouseLocationOutsideOfEventStream];
x_tmp = point.x;
y_tmp = impl->height - point.y;
}
/* The coords are relative to the toplevel of the passed in window
* at this point, make them relative to the passed in window:
*/
private = GDK_WINDOW_OBJECT (window);
while (private != toplevel)
{
x_tmp -= private->x;
y_tmp -= private->y;
private = private->parent;
}
found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp);
/* We never return the root window. */
if (found_window == _gdk_root)
found_window = NULL;
*x = x_tmp;
*y = y_tmp;
return found_window;
}
void
gdk_display_warp_pointer (GdkDisplay *display,
GdkScreen *screen,
gint x,
gint y)
{
CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
}
/* Returns coordinates relative to the found window. */
GdkWindow *
_gdk_windowing_window_at_pointer (GdkDisplay *display,
gint *win_x,
gint *win_y)
{
GdkModifierType mask;
GdkWindow *found_window;
gint x, y;
found_window = _gdk_windowing_window_get_pointer (display,
_gdk_root,
&x, &y,
&mask);
if (found_window)
{
GdkWindowObject *private;
/* The coordinates returned above are relative the root, we want
* coordinates relative the window here.
*/
private = GDK_WINDOW_OBJECT (found_window);
while (private != GDK_WINDOW_OBJECT (_gdk_root))
{
x -= private->x;
y -= private->y;
private = private->parent;
}
*win_x = x;
*win_y = y;
}
else
{
/* Mimic the X backend here, -1,-1 for unknown windows. */
*win_x = -1;
*win_y = -1;
}
return found_window;
}
GdkEventMask
gdk_window_get_events (GdkWindow *window)
{
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
if (GDK_WINDOW_DESTROYED (window))
return 0;
else
return GDK_WINDOW_OBJECT (window)->event_mask;
}
void
gdk_window_set_events (GdkWindow *window,
GdkEventMask event_mask)
{
g_return_if_fail (GDK_IS_WINDOW (window));
if (!GDK_WINDOW_DESTROYED (window))
{
GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
}
}
void
gdk_window_set_urgency_hint (GdkWindow *window,
gboolean urgent)
{
/* FIXME: Implement */
}
void
gdk_window_set_geometry_hints (GdkWindow *window,
GdkGeometry *geometry,
GdkWindowHints geom_mask)
{
GdkWindowImplQuartz *impl;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (geometry != NULL);
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
if (!impl->toplevel)
return;
if (geom_mask & GDK_HINT_POS)
{
/* FIXME: Implement */
}
if (geom_mask & GDK_HINT_USER_POS)
{
/* FIXME: Implement */
}
if (geom_mask & GDK_HINT_USER_SIZE)
{
/* FIXME: Implement */
}
if (geom_mask & GDK_HINT_MIN_SIZE)
{
NSSize size;
size.width = geometry->min_width;
size.height = geometry->min_height;
[impl->toplevel setContentMinSize:size];
}
if (geom_mask & GDK_HINT_MAX_SIZE)
{
NSSize size;
size.width = geometry->max_width;
size.height = geometry->max_height;
[impl->toplevel setContentMaxSize:size];
}
if (geom_mask & GDK_HINT_BASE_SIZE)
{
/* FIXME: Implement */
}
if (geom_mask & GDK_HINT_RESIZE_INC)
{
NSSize size;
size.width = geometry->width_inc;
size.height = geometry->height_inc;
[impl->toplevel setContentResizeIncrements:size];
}
if (geom_mask & GDK_HINT_ASPECT)
{
/* FIXME: Implement */
}
if (geom_mask & GDK_HINT_WIN_GRAVITY)
{
/* FIXME: Implement */
}
}
void
gdk_window_set_title (GdkWindow *window,
const gchar *title)
{
GdkWindowImplQuartz *impl;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (title != NULL);
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)window)->impl);
if (impl->toplevel)
{
GDK_QUARTZ_ALLOC_POOL;
[impl->toplevel setTitle:[NSString stringWithUTF8String:title]];
GDK_QUARTZ_RELEASE_POOL;
}
}
void
gdk_window_set_role (GdkWindow *window,
const gchar *role)
{
/* FIXME: Implement */
}
void
gdk_window_set_transient_for (GdkWindow *window,
GdkWindow *parent)
{
GdkWindowImplQuartz *window_impl;
GdkWindowImplQuartz *parent_impl;
if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent))
return;
window_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
if (!window_impl->toplevel)
return;
GDK_QUARTZ_ALLOC_POOL;
if (window_impl->transient_for)
{
if (!GDK_WINDOW_DESTROYED (window_impl->transient_for))
{
parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window_impl->transient_for)->impl);
[parent_impl->toplevel removeChildWindow:window_impl->toplevel];
}
g_object_unref (window_impl->transient_for);
window_impl->transient_for = NULL;
}
parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl);
if (parent_impl->toplevel)
{
/* We save the parent because it needs to be unset/reset when
* hiding and showing the window.
*/
/* We don't set transients for tooltips, they are already
* handled by the window level being the top one. If we do, then
* the parent window will be brought to the top just because the
* tooltip is, which is not what we want.
*/
if (gdk_window_get_type_hint (window) != GDK_WINDOW_TYPE_HINT_TOOLTIP)
{
window_impl->transient_for = g_object_ref (parent);
/* We only add the window if it is shown, otherwise it will
* be shown unconditionally here. If it is not shown, the
* window will be added in show() instead.
*/
if (!(GDK_WINDOW_OBJECT (window)->state & GDK_WINDOW_STATE_WITHDRAWN))
[parent_impl->toplevel addChildWindow:window_impl->toplevel ordered:NSWindowAbove];
}
}
GDK_QUARTZ_RELEASE_POOL;
}
void
gdk_window_shape_combine_region (GdkWindow *window,
GdkRegion *shape,
gint x,
gint y)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_shape_combine_mask (GdkWindow *window,
GdkBitmap *mask,
gint x, gint y)
{
/* FIXME: Implement */
}
void
gdk_window_input_shape_combine_mask (GdkWindow *window,
GdkBitmap *mask,
gint x,
gint y)
{
/* FIXME: Implement */
}
void
gdk_window_input_shape_combine_region (GdkWindow *window,
GdkRegion *shape_region,
gint offset_x,
gint offset_y)
{
/* FIXME: Implement */
}
void
gdk_window_set_child_input_shapes (GdkWindow *window)
{
/* FIXME: IMplement */
}
void
gdk_window_set_override_redirect (GdkWindow *window,
gboolean override_redirect)
{
/* FIXME: Implement */
}
void
gdk_window_set_accept_focus (GdkWindow *window,
gboolean accept_focus)
{
GdkWindowObject *private;
g_return_if_fail (GDK_IS_WINDOW (window));
private = (GdkWindowObject *)window;
private->accept_focus = accept_focus != FALSE;
}
void
gdk_window_set_child_shapes (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_merge_child_shapes (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_merge_child_input_shapes (GdkWindow *window)
{
/* FIXME: Implement */
}
gboolean
gdk_window_set_static_gravities (GdkWindow *window,
gboolean use_static)
{
/* FIXME: Implement */
return FALSE;
}
void
gdk_window_set_focus_on_map (GdkWindow *window,
gboolean focus_on_map)
{
GdkWindowObject *private;
g_return_if_fail (GDK_IS_WINDOW (window));
private = (GdkWindowObject *)window;
private->focus_on_map = focus_on_map != FALSE;
}
void
gdk_window_set_icon (GdkWindow *window,
GdkWindow *icon_window,
GdkPixmap *pixmap,
GdkBitmap *mask)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_set_icon_name (GdkWindow *window,
const gchar *name)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_focus (GdkWindow *window,
guint32 timestamp)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_set_hints (GdkWindow *window,
gint x,
gint y,
gint min_width,
gint min_height,
gint max_width,
gint max_height,
gint flags)
{
/* FIXME: Implement */
}
void
gdk_window_set_type_hint (GdkWindow *window,
GdkWindowTypeHint hint)
{
GdkWindowImplQuartz *impl;
gint level;
gboolean shadow;
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
impl->type_hint = hint;
/* Match the documentation, only do something if we're not mapped yet. */
if (GDK_WINDOW_IS_MAPPED (window))
return;
switch (hint)
{
case GDK_WINDOW_TYPE_HINT_NORMAL: /* Normal toplevel window */
case GDK_WINDOW_TYPE_HINT_DIALOG: /* Dialog window */
level = NSNormalWindowLevel;
shadow = TRUE;
break;
case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */
level = NSNormalWindowLevel;
shadow = FALSE;
break;
case GDK_WINDOW_TYPE_HINT_DOCK:
case GDK_WINDOW_TYPE_HINT_UTILITY:
level = NSFloatingWindowLevel;
shadow = TRUE;
break;
case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
level = NSTornOffMenuWindowLevel;
shadow = TRUE;
break;
case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
level = NSTornOffMenuWindowLevel;
shadow = TRUE;
break;
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
level = NSPopUpMenuWindowLevel;
shadow = TRUE;
break;
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
case GDK_WINDOW_TYPE_HINT_COMBO:
level = NSPopUpMenuWindowLevel;
shadow = TRUE;
break;
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
level = NSStatusWindowLevel;
shadow = TRUE;
break;
case GDK_WINDOW_TYPE_HINT_DND:
level = NSPopUpMenuWindowLevel;
shadow = FALSE;
break;
default:
level = NSNormalWindowLevel;
shadow = FALSE;
break;
}
[impl->toplevel setHasShadow:shadow];
[impl->toplevel setLevel:level];
}
GdkWindowTypeHint
gdk_window_get_type_hint (GdkWindow *window)
{
if (GDK_WINDOW_DESTROYED (window))
return GDK_WINDOW_TYPE_HINT_NORMAL;
return GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl)->type_hint;
}
void
gdk_window_set_modal_hint (GdkWindow *window,
gboolean modal)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_set_skip_taskbar_hint (GdkWindow *window,
gboolean skips_taskbar)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_set_skip_pager_hint (GdkWindow *window,
gboolean skips_pager)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_begin_resize_drag (GdkWindow *window,
GdkWindowEdge edge,
gint button,
gint root_x,
gint root_y,
guint32 timestamp)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_begin_move_drag (GdkWindow *window,
gint button,
gint root_x,
gint root_y,
guint32 timestamp)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_set_icon_list (GdkWindow *window,
GList *pixbufs)
{
/* FIXME: Implement */
}
void
gdk_window_get_frame_extents (GdkWindow *window,
GdkRectangle *rect)
{
GdkWindowObject *private;
GdkWindow *toplevel;
GdkWindowImplQuartz *impl;
NSRect ns_rect;
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (rect != NULL);
private = GDK_WINDOW_OBJECT (window);
rect->x = 0;
rect->y = 0;
rect->width = 1;
rect->height = 1;
if (GDK_WINDOW_DESTROYED (window))
return;
toplevel = gdk_window_get_toplevel (window);
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
ns_rect = [impl->toplevel frame];
rect->x = ns_rect.origin.x;
rect->y = _gdk_quartz_window_get_inverted_screen_y (ns_rect.origin.y + ns_rect.size.height);
rect->width = ns_rect.size.width;
rect->height = ns_rect.size.height;
}
void
gdk_window_set_decorations (GdkWindow *window,
GdkWMDecoration decorations)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
gboolean
gdk_window_get_decorations (GdkWindow *window,
GdkWMDecoration *decorations)
{
/* FIXME: Implement */
return FALSE;
}
void
gdk_window_set_functions (GdkWindow *window,
GdkWMFunction functions)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
_gdk_windowing_window_get_offsets (GdkWindow *window,
gint *x_offset,
gint *y_offset)
{
*x_offset = *y_offset = 0;
}
gboolean
_gdk_windowing_window_queue_antiexpose (GdkWindow *window,
GdkRegion *area)
{
return FALSE;
}
void
gdk_window_stick (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
}
void
gdk_window_unstick (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
}
void
gdk_window_maximize (GdkWindow *window)
{
GdkWindowImplQuartz *impl;
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
if (GDK_WINDOW_IS_MAPPED (window))
{
GDK_QUARTZ_ALLOC_POOL;
if (impl->toplevel && ![impl->toplevel isZoomed])
[impl->toplevel zoom:nil];
GDK_QUARTZ_RELEASE_POOL;
}
else
{
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_MAXIMIZED);
}
}
void
gdk_window_unmaximize (GdkWindow *window)
{
GdkWindowImplQuartz *impl;
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
if (GDK_WINDOW_IS_MAPPED (window))
{
GDK_QUARTZ_ALLOC_POOL;
if (impl->toplevel && [impl->toplevel isZoomed])
[impl->toplevel zoom:nil];
GDK_QUARTZ_RELEASE_POOL;
}
else
{
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_MAXIMIZED,
0);
}
}
void
gdk_window_iconify (GdkWindow *window)
{
GdkWindowImplQuartz *impl;
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
if (GDK_WINDOW_IS_MAPPED (window))
{
GDK_QUARTZ_ALLOC_POOL;
if (impl->toplevel)
[impl->toplevel miniaturize:nil];
GDK_QUARTZ_RELEASE_POOL;
}
else
{
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_ICONIFIED);
}
}
void
gdk_window_deiconify (GdkWindow *window)
{
GdkWindowImplQuartz *impl;
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
if (GDK_WINDOW_IS_MAPPED (window))
{
GDK_QUARTZ_ALLOC_POOL;
if (impl->toplevel)
[impl->toplevel deminiaturize:nil];
GDK_QUARTZ_RELEASE_POOL;
}
else
{
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_ICONIFIED,
0);
}
}
void
gdk_window_fullscreen (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_unfullscreen (GdkWindow *window)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
void
gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
{
g_return_if_fail (GDK_IS_WINDOW (window));
/* FIXME: Implement */
}
GdkWindow *
gdk_window_get_group (GdkWindow *window)
{
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
/* FIXME: Implement */
return NULL;
}
void
gdk_window_set_group (GdkWindow *window,
GdkWindow *leader)
{
/* FIXME: Implement */
}
GdkWindow*
gdk_window_foreign_new_for_display (GdkDisplay *display,
GdkNativeWindow anid)
{
/* Foreign windows aren't supported in Mac OS X */
return NULL;
}
GdkWindow*
gdk_window_lookup (GdkNativeWindow anid)
{
/* Foreign windows aren't supported in Mac OS X */
return NULL;
}
GdkWindow *
gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
{
/* Foreign windows aren't supported in Mac OS X */
return NULL;
}
void
gdk_window_enable_synchronized_configure (GdkWindow *window)
{
}
void
gdk_window_configure_finished (GdkWindow *window)
{
}
void
gdk_window_destroy_notify (GdkWindow *window)
{
/* FIXME: Implement. We should call this from -[GdkQuartzWindow dealloc] or
* -[GdkQuartzView dealloc], although I suspect that currently they leak
* anyway. */
}
void
gdk_window_beep (GdkWindow *window)
{
gdk_display_beep (_gdk_display);
}
void
gdk_window_set_opacity (GdkWindow *window,
gdouble opacity)
{
GdkWindowObject *private = (GdkWindowObject *) window;
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
g_return_if_fail (GDK_IS_WINDOW (window));
g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
if (GDK_WINDOW_DESTROYED (window))
return;
if (opacity < 0)
opacity = 0;
else if (opacity > 1)
opacity = 1;
[impl->toplevel setAlphaValue: opacity];
}
void
_gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
{
}