summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Figuiere <hub@src.gnome.org>2005-06-14 02:25:58 +0000
committerHubert Figuiere <hub@src.gnome.org>2005-06-14 02:25:58 +0000
commit01f5b89802686d23c37648040ff13f962d15c79a (patch)
treeb70f275a8b0f265c325cc8beea67cf1e47ffdc45
parentd9441df224dbc95fdff19947fbbae5f61e4aad5b (diff)
downloadgtk+-01f5b89802686d23c37648040ff13f962d15c79a.tar.gz
beginning of a MacOS X port
-rw-r--r--configure.in66
-rw-r--r--gdk/Makefile.am12
-rw-r--r--gdk/macosx/Makefile.am37
-rw-r--r--gdk/macosx/gdkdisplay-macosx.h71
-rw-r--r--gdk/macosx/gdkdisplay-macosx.m547
-rw-r--r--gdk/macosx/gdkdrawable-macosx.h103
-rw-r--r--gdk/macosx/gdkevents-macosx.c88
-rw-r--r--gdk/macosx/gdkevents-macosx.m2485
-rw-r--r--gdk/macosx/gdkgc-macosx.m1306
-rw-r--r--gdk/macosx/gdkmacosx.h55
-rw-r--r--gdk/macosx/gdkmain-macosx.c42
-rw-r--r--gdk/macosx/gdknsview-macosx.m127
-rw-r--r--gdk/macosx/gdkpango-macosx.c11
-rw-r--r--gdk/macosx/gdkpixmap-macosx.h70
-rw-r--r--gdk/macosx/gdkprivate-macosx.h217
-rw-r--r--gdk/macosx/gdkscreen-macosx.h70
-rw-r--r--gdk/macosx/gdkscreen-macosx.m452
-rw-r--r--gdk/macosx/gdkwindow-macosx.h106
-rw-r--r--gdk/macosx/gdkwindow-macosx.m5540
-rw-r--r--gtk/Makefile.am5
20 files changed, 11404 insertions, 6 deletions
diff --git a/configure.in b/configure.in
index fcf55c3206..2f2879a5a8 100644
--- a/configure.in
+++ b/configure.in
@@ -111,6 +111,17 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE")
AC_CANONICAL_HOST
MATH_LIB=-lm
+AC_MSG_CHECKING([for native MacOS X])
+case "$host" in
+ *-*-darwin*)
+ os_macosx=yes
+ ;;
+ *)
+ os_macosx=no
+ ;;
+esac
+AC_MSG_RESULT([$os_macosx])
+
AC_MSG_CHECKING([for native Win32])
case "$host" in
*-*-mingw*)
@@ -130,6 +141,7 @@ case $host in
esac
dnl Initialize libtool
AC_PROG_CC
+
AM_DISABLE_STATIC
if test "$os_win32" = "yes"; then
@@ -166,7 +178,22 @@ esac
AC_MSG_RESULT([$platform_win32])
AM_CONDITIONAL(PLATFORM_WIN32, test "$platform_win32" = "yes")
+
+AC_MSG_CHECKING([for some MacOS X platform])
+case "$host" in
+ *-*-darwin*|*-*-darwin*)
+ platform_macosx=yes
+ ;;
+ *)
+ platform_macosx=no
+ ;;
+esac
+AC_MSG_RESULT([$platform_macosx])
+AM_CONDITIONAL(PLATFORM_MACOSX, test "$platform_macosx" = "yes")
+
+
AM_CONDITIONAL(OS_WIN32, test "$os_win32" = "yes")
+AM_CONDITIONAL(OS_MACOSX, test "$os_macosx" = "yes")
AM_CONDITIONAL(OS_UNIX, test "$os_win32" != "yes")
AM_CONDITIONAL(OS_LINUX, test "$os_linux" = "yes")
@@ -217,18 +244,29 @@ AC_ARG_WITH(ie55,
GLIB_AC_DIVERT_BEFORE_HELP([
if test "$platform_win32" = yes; then
gdktarget=win32
+elif test "$platform_macosx" = yes; then
+ gdktarget=macosx
else
gdktarget=x11
fi
])
+# this because the macro above is broken.... and doesn't work.
+if test "$platform_win32" = yes; then
+ gdktarget=win32
+elif test "$platform_macosx" = yes; then
+ gdktarget=macosx
+else
+ gdktarget=x11
+fi
+
AC_ARG_WITH(gdktarget, [ --with-gdktarget=[[x11/linux-fb/win32]] select GDK target [default=$gdktarget]],
gdktarget=$with_gdktarget)
AC_SUBST(gdktarget)
case $gdktarget in
- x11|linux-fb|win32) ;;
- *) AC_MSG_ERROR([Invalid target for GDK: use x11, linux-fb or win32.]);;
+ x11|linux-fb|win32|macosx) ;;
+ *) AC_MSG_ERROR([Invalid target for GDK: use x11, linux-fb, win32 or macosx.]);;
esac
gdktargetlib=libgdk-$gdktarget-$GTK_API_VERSION.la
@@ -331,6 +369,15 @@ if test x"$os_win32" = xyes; then
fi
fi
+# objective-C
+OBJC="gcc"
+OBJCFLAGS=""
+AC_SUBST(OBJC)
+AC_SUBST(OBJCFLAGS)
+dnl Make Objective-C work with automake 1.7.x
+dnl see http://lists.gnu.org/archive/html/automake/2003-05/msg00027.html
+AM_CONDITIONAL([am__fastdepOBJC], false)
+
# Honor aclocal flags
ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
@@ -1343,6 +1390,13 @@ else
AM_CONDITIONAL(USE_WIN32, false)
fi
+if test "x$gdktarget" = "xmacosx"; then
+ GDK_EXTRA_LIBS="$GDK_EXTRA_LIBS -framework Cocoa -framework ApplicationServices"
+ AM_CONDITIONAL(USE_MACOSX, true)
+else
+ AM_CONDITIONAL(USE_MACOSX, false)
+fi
+
GDK_PIXBUF_XLIB_PACKAGES=
GDK_PIXBUF_XLIB_DEP_LIBS="`$PKG_CONFIG --libs $GDK_PIXBUF_PACKAGES $GDK_PIXBUF_XLIB_PACKAGES` $GDK_PIXBUF_XLIB_EXTRA_LIBS $GDK_PIXBUF_EXTRA_LIBS"
GDK_PIXBUF_XLIB_DEP_CFLAGS="`$PKG_CONFIG --cflags gthread-2.0 $GDK_PIXBUF_PACKAGES $GDK_PIXBUF_XLIB_PACKAGES` $GDK_PIXBUF_EXTRA_CFLAGS $GDK_PIXBUF_XLIB_EXTRA_CFLAGS"
@@ -1401,6 +1455,8 @@ if test "x$gdktarget" = "xx11"; then
if $PKG_CONFIG --exists pangox ; then
PANGO_PACKAGES="$PANGO_PACKAGES pangox"
fi
+elif test "x$gdktarget" = "xmacosx"; then
+ PANGO_PACKAGES=pangoft2
elif test "x$gdktarget" = "xwin32"; then
PANGO_PACKAGES=pangowin32
elif test "x$gdktarget" = "xlinux-fb"; then
@@ -1614,6 +1670,10 @@ elif test "x$gdktarget" = "xlinux-fb" ; then
gdk_windowing='
#define GDK_WINDOWING_FB
#define GDK_NATIVE_WINDOW_POINTER'
+elif test "x$gdktarget" = "xmacosx" ; then
+ gdk_windowing='
+#define GDK_WINDOWING_MACOSX
+#define GDK_NATIVE_WINDOW_POINTER'
fi
if test x$gdk_wchar_h = xyes; then
@@ -1673,6 +1733,8 @@ gdk/win32/Makefile
gdk/win32/rc/Makefile
gdk/win32/rc/gdk.rc
gdk/linux-fb/Makefile
+gdk/macosx/Makefile
+gdk/test/Makefile
gtk/Makefile
gtk/makefile.msc
gtk/gtkversion.h
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index 139ea8419b..07cecd586a 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -1,7 +1,8 @@
## Makefile.am for gtk+/gdk
-SUBDIRS = $(gdktarget)
-DIST_SUBDIRS = linux-fb win32 x11
+SUBDIRS = $(gdktarget) test
+DIST_SUBDIRS = linux-fb win32 x11 macosx
+check_SUBDIRS = test
EXTRA_DIST = \
gdkconfig.h.win32 \
@@ -138,6 +139,11 @@ libgdk_linux_fb_2_0_la_LIBADD = linux-fb/libgdk-linux-fb.la $(GDK_DEP_LIBS) \
$(top_builddir)/gdk-pixbuf/libgdk_pixbuf-$(GTK_API_VERSION).la
libgdk_linux_fb_2_0_la_LDFLAGS = $(LDADD)
+libgdk_macosx_2_0_la_SOURCES = $(common_sources)
+libgdk_macosx_2_0_la_LIBADD = macosx/libgdk-macosx.la $(GDK_DEP_LIBS) \
+ $(top_builddir)/gdk-pixbuf/libgdk_pixbuf-$(GTK_API_VERSION).la
+libgdk_macosx_2_0_la_LDFLAGS = $(LDADD)
+
libgdk_win32_2_0_la_SOURCES = $(common_sources) gdkkeynames.c
libgdk_win32_2_0_la_LIBADD = win32/libgdk-win32.la $(GDK_DEP_LIBS) \
$(top_builddir)/gdk-pixbuf/libgdk_pixbuf-$(GTK_API_VERSION).la
@@ -192,7 +198,7 @@ endif
lib_LTLIBRARIES = $(gdktargetlib)
-EXTRA_LTLIBRARIES = libgdk-x11-2.0.la libgdk-linux-fb-2.0.la libgdk-win32-2.0.la
+EXTRA_LTLIBRARIES = libgdk-x11-2.0.la libgdk-linux-fb-2.0.la libgdk-win32-2.0.la libgdk-macosx-2.0.la
MAINTAINERCLEANFILES = gdkenumtypes.h stamp-gdkenumtypes.h gdkenumtypes.c \
gdkmarshalers.h gdkmarshalers.c gdkalias.h gdkaliasdef.c
diff --git a/gdk/macosx/Makefile.am b/gdk/macosx/Makefile.am
new file mode 100644
index 0000000000..7cc646ba6b
--- /dev/null
+++ b/gdk/macosx/Makefile.am
@@ -0,0 +1,37 @@
+## Process this file with automake to produce Makefile.in
+
+libgdkincludedir = $(includedir)/gtk-2.0/gdk
+
+AUTOMAKE_OPTIONS = no-dependencies
+
+INCLUDES = \
+ -DG_LOG_DOMAIN=\"Gdk\" \
+ -DGDK_COMPILATION \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/gdk \
+ -I$(top_builddir)/gdk \
+ -DG_DISABLE_DEPRECATED \
+ -DGDK_PIXBUF_DISABLE_DEPRECATED \
+ -DGDK_DISABLE_DEPRECATED \
+ $(GTK_DEBUG_FLAGS) \
+ $(GDK_DEP_CFLAGS)
+
+LDADDS = $(GDK_DEP_LIBS)
+
+noinst_LTLIBRARIES = libgdk-macosx.la
+
+libgdk_macosx_la_SOURCES = gdkpango-macosx.c \
+ gdkevents-macosx.m \
+ gdkdisplay-macosx.m \
+ gdkgc-macosx.m \
+ gdkmain-macosx.m \
+ gdknsview-macosx.m \
+ gdkscreen-macosx.m \
+ gdkwindow-macosx.m
+
+
+libgdkinclude_HEADERS =
+
+# We need to include all these C files here since the conditionals
+# don't seem to be correctly expanded for the dist files.
+EXTRA_DIST =
diff --git a/gdk/macosx/gdkdisplay-macosx.h b/gdk/macosx/gdkdisplay-macosx.h
new file mode 100644
index 0000000000..ad01410fe2
--- /dev/null
+++ b/gdk/macosx/gdkdisplay-macosx.h
@@ -0,0 +1,71 @@
+/*
+ * gdkdisplay-macosx.h
+ *
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * Erwann Chenede <erwann.chenede@sun.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ */
+
+#ifndef __GDK_DISPLAY_MACOSX__
+#define __GDK_DISPLAY_MACOSX__
+
+#include <glib.h>
+#include <gdk/gdkdisplay.h>
+#include <gdk/gdkkeys.h>
+#include <gdk/gdkwindow.h>
+#include <gdk/gdk.h> /* For gdk_get_program_class() */
+
+G_BEGIN_DECLS
+
+typedef struct _GdkDisplayMacOSX GdkDisplayMacOSX;
+typedef struct _GdkDisplayMacOSXClass GdkDisplayMacOSXClass;
+
+#define GDK_TYPE_DISPLAY_MACOSX (_gdk_display_macosx_get_type())
+#define GDK_DISPLAY_MACOSX(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY_MACOSX, GdkDisplayMacOSX))
+#define GDK_DISPLAY_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DISPLAY_MACOSX, GdkDisplayMacOSXClass))
+#define GDK_IS_DISPLAY_MACOSX(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DISPLAY_MACOSX))
+#define GDK_IS_DISPLAY_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DISPLAY_MACOSX))
+#define GDK_DISPLAY_MACOSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DISPLAY_MACOSX, GdkDisplayMacOSXClass))
+
+typedef enum
+{
+ GDK_UNKNOWN,
+ GDK_NO,
+ GDK_YES
+} GdkTristate;
+
+struct _GdkDisplayMacOSX
+{
+ GdkDisplay parent_instance;
+ GdkScreen *default_screen;
+ GdkScreen **screens;
+ int num_screens;
+ /* NSView to GdkWindow pointers */
+ GHashTable *nsview_ht;
+};
+
+struct _GdkDisplayMacOSXClass
+{
+ GdkDisplayClass parent_class;
+};
+
+GType _gdk_display_macosx_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GDK_DISPLAY_MacOSX__ */
diff --git a/gdk/macosx/gdkdisplay-macosx.m b/gdk/macosx/gdkdisplay-macosx.m
new file mode 100644
index 0000000000..079b905b6e
--- /dev/null
+++ b/gdk/macosx/gdkdisplay-macosx.m
@@ -0,0 +1,547 @@
+/* GDK - The GIMP Drawing Kit
+ * gdkdisplay-macosx.c
+ *
+ * Copyright 2001 Sun Microsystems Inc.
+ * Copyright (C) 2004 Nokia Corporation
+ * Copyright (C) 2005 Hubert Figuiere
+ *
+ * Hubert Figuiere <hub@figuiere.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ */
+
+/*
+ * derived from GdkDisplay-X11....
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include "gdkalias.h"
+#include "gdkdisplay.h"
+#include "gdkdisplay-macosx.h"
+#include "gdkscreen.h"
+#include "gdkscreen-macosx.h"
+#include "gdkinternals.h"
+
+#include <Cocoa/Cocoa.h>
+
+static void gdk_display_macosx_class_init (GdkDisplayMacOSXClass *class);
+static void gdk_display_macosx_dispose (GObject *object);
+static void gdk_display_macosx_finalize (GObject *object);
+
+
+static gpointer parent_class = NULL;
+
+
+GType
+_gdk_display_macosx_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkDisplayMacOSXClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_display_macosx_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkDisplayMacOSX),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (GDK_TYPE_DISPLAY,
+ "GdkDisplayMacOSX",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+static void
+gdk_display_macosx_class_init (GdkDisplayMacOSXClass * class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->dispose = gdk_display_macosx_dispose;
+ object_class->finalize = gdk_display_macosx_finalize;
+
+ parent_class = g_type_class_peek_parent (class);
+}
+
+
+/**
+ * gdk_display_open:
+ * @display_name: the name of the display to open
+ * @returns: a #GdkDisplay, or %NULL if the display
+ * could not be opened.
+ *
+ * Opens a display.
+ *
+ * Since: 2.2
+ */
+GdkDisplay *
+gdk_display_open (const gchar *display_name)
+{
+ GdkDisplay *display;
+ GdkDisplayMacOSX *display_macosx;
+ GdkWindowAttr attr;
+ NSArray *screens;
+ NSScreen *current_screen;
+ NSScreen *default_screen;
+ NSEnumerator *iter;
+ int screen_count, i;
+
+ display = g_object_new (GDK_TYPE_DISPLAY_MACOSX, NULL);
+ display_macosx = GDK_DISPLAY_MACOSX (display);
+
+ /* initialize the display's screens */
+
+ screens = [NSScreen screens];
+ screen_count = [screens count];
+
+ display_macosx->screens = g_new (GdkScreen *, screen_count);
+ default_screen = [NSScreen mainScreen];
+ iter = [screens objectEnumerator];
+ i = 0;
+ while (current_screen = [iter nextObject]) {
+ display_macosx->screens[i] = _gdk_macosx_screen_new (display, current_screen);
+ if (current_screen == default_screen) {
+ display_macosx->default_screen = display_macosx->screens[i];
+ }
+ i++;
+ if(i == screen_count) {
+ g_warning("screen count changes\n");
+ /* FIXME don't leake */
+ return NULL;
+ }
+ }
+ display_macosx->num_screens = i;
+ display_macosx->nsview_ht = NULL;
+
+ /* just make sure we have a NSApplication created */
+ [NSApplication sharedApplication];
+
+ /* FIXME make all of this is OK */
+ /*
+ _gdk_windowing_image_init (display);
+ _gdk_events_init (display);
+ _gdk_input_init (display);
+ _gdk_dnd_init (display);
+ */
+ g_signal_emit_by_name (gdk_display_manager_get(),
+ "display_opened", display);
+
+ return display;
+}
+
+
+/**
+ * gdk_display_get_name:
+ * @display: a #GdkDisplay
+ *
+ * Gets the name of the display.
+ *
+ * Returns: a string representing the display name. This string is owned
+ * by GDK and should not be modified or freed.
+ *
+ * Since: 2.2
+ */
+G_CONST_RETURN gchar *
+gdk_display_get_name (GdkDisplay * display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+ return "";
+}
+
+/**
+ * gdk_display_get_n_screens:
+ * @display: a #GdkDisplay
+ *
+ * Gets the number of screen managed by the @display.
+ *
+ * Returns: number of screens.
+ *
+ * Since: 2.2
+ */
+gint
+gdk_display_get_n_screens (GdkDisplay * display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
+
+ return [[NSScreen screens] count];
+}
+
+/**
+ * gdk_display_get_screen:
+ * @display: a #GdkDisplay
+ * @screen_num: the screen number
+ *
+ * Returns a screen object for one of the screens of the display.
+ *
+ * Returns: the #GdkScreen object
+ *
+ * Since: 2.2
+ */
+GdkScreen *
+gdk_display_get_screen (GdkDisplay * display, gint screen_num)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ g_return_val_if_fail ((GDK_DISPLAY_MACOSX (display)->num_screens) > screen_num, NULL);
+
+ return GDK_DISPLAY_MACOSX (display)->screens[screen_num];
+}
+
+/**
+ * gdk_display_get_default_screen:
+ * @display: a #GdkDisplay
+ *
+ * Get the default #GdkScreen for @display.
+ *
+ * Returns: the default #GdkScreen object for @display
+ *
+ * Since: 2.2
+ */
+GdkScreen *
+gdk_display_get_default_screen (GdkDisplay * display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+ return GDK_DISPLAY_MACOSX (display)->default_screen;
+}
+
+
+/**
+ * gdk_display_pointer_ungrab:
+ * @display: a #GdkDisplay.
+ * @time_: a timestap (e.g. GDK_CURRENT_TIME).
+ *
+ * Release any pointer grab.
+ *
+ * Since: 2.2
+ */
+void
+gdk_display_pointer_ungrab (GdkDisplay *display,
+ guint32 time)
+{
+ // FIXME nothing to do
+}
+
+/**
+ * gdk_display_pointer_is_grabbed:
+ * @display: a #GdkDisplay
+ *
+ * Test if the pointer is grabbed.
+ *
+ * Returns: %TRUE if an active X pointer grab is in effect
+ *
+ * Since: 2.2
+ */
+gboolean
+gdk_display_pointer_is_grabbed (GdkDisplay * display)
+{
+ // FIXME I don't think we have grabs. Maybe should we
+ // store that state in the GdkDisplay....
+ return false;
+}
+
+/**
+ * gdk_display_keyboard_ungrab:
+ * @display: a #GdkDisplay.
+ * @time_: a timestap (e.g #GDK_CURRENT_TIME).
+ *
+ * Release any keyboard grab
+ *
+ * Since: 2.2
+ */
+void
+gdk_display_keyboard_ungrab (GdkDisplay *display,
+ guint32 time)
+{
+
+}
+
+/**
+ * gdk_display_beep:
+ * @display: a #GdkDisplay
+ *
+ * Emits a short beep on @display
+ *
+ * Since: 2.2
+ */
+void
+gdk_display_beep (GdkDisplay * display)
+{
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+
+ NSBeep();
+}
+
+/**
+ * gdk_display_sync:
+ * @display: a #GdkDisplay
+ *
+ * Flushes any requests queued for the windowing system and waits until all
+ * requests have been handled. This is often used for making sure that the
+ * display is synchronized with the current state of the program. Calling
+ * gdk_display_sync() before gdk_error_trap_pop() makes sure that any errors
+ * generated from earlier requests are handled before the error trap is
+ * removed.
+ *
+ * This is most useful for X11. On windowing systems where requests are
+ * handled synchronously, this function will do nothing.
+ *
+ * Since: 2.2
+ */
+void
+gdk_display_sync (GdkDisplay * display)
+{
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+ /* FIXME see if we can do something with CoreGraphics */
+}
+
+/**
+ * gdk_display_flush:
+ * @display: a #GdkDisplay
+ *
+ * Flushes any requests queued for the windowing system; this happens automatically
+ * when the main loop blocks waiting for new events, but if your application
+ * is drawing without returning control to the main loop, you may need
+ * to call this function explicitely. A common case where this function
+ * needs to be called is when an application is executing drawing commands
+ * from a thread other than the thread where the main loop is running.
+ *
+ * This is most useful for X11. On windowing systems where requests are
+ * handled synchronously, this function will do nothing.
+ *
+ * Since: 2.4
+ */
+void
+gdk_display_flush (GdkDisplay *display)
+{
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+
+ /* FIXME see if we can do something with CoreGraphics */
+}
+
+/**
+ * gdk_display_get_default_group:
+ * @display: a #GdkDisplay
+ *
+ * Returns the default group leader window for all toplevel windows
+ * on @display. This window is implicitly created by GDK.
+ * See gdk_window_set_group().
+ *
+ * Return value: The default group leader window for @display
+ *
+ * Since: 2.4
+ **/
+GdkWindow *gdk_display_get_default_group (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+ g_warning ("gdk_display_get_default_group not yet implemented");
+
+ return NULL;
+}
+
+/**
+ * gdk_macosx_display_grab:
+ * @display: a #GdkDisplay
+ *
+ * Call XGrabServer() on @display.
+ * To ungrab the display again, use gdk_macosx_display_ungrab().
+ *
+ * gdk_macosx_display_grab()/gdk_macosx_display_ungrab() calls can be nested.
+ *
+ * Since: 2.2
+ **/
+void
+gdk_macosx_display_grab (GdkDisplay * display)
+{
+
+}
+
+/**
+ * gdk_macosx_display_ungrab:
+ * @display: a #GdkDisplay
+ *
+ * Ungrab @display after it has been grabbed with
+ * gdk_macosx_display_grab().
+ *
+ * Since: 2.2
+ **/
+void
+gdk_macosx_display_ungrab (GdkDisplay * display)
+{
+
+}
+
+static void
+gdk_display_macosx_dispose (GObject *object)
+{
+ GdkDisplayMacOSX *display_macosx;
+ gint i;
+
+ display_macosx = GDK_DISPLAY_MACOSX (object);
+
+ for (i = 0; i < display_macosx->num_screens; i++) {
+ _gdk_screen_close (display_macosx->screens[i]);
+ }
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gdk_display_macosx_finalize (GObject *object)
+{
+ GdkDisplayMacOSX *display_macosx = GDK_DISPLAY_MACOSX (object);
+
+ g_free (display_macosx->screens);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+void
+_gdk_windowing_set_default_display (GdkDisplay *display)
+{
+ /* FIXME */
+ g_warning ("_gdk_windowing_set_default_display() not implemented on MacOS X\n");
+}
+
+
+
+/**
+ * gdk_notify_startup_complete:
+ *
+ * Indicates to the GUI environment that the application has finished
+ * loading. If the applications opens windows, this function is
+ * normally called after opening the application's initial set of
+ * windows.
+ *
+ * GTK+ will call this function automatically after opening the first
+ * #GtkWindow unless gtk_window_set_auto_startup_notification() is called
+ * to disable that feature.
+ *
+ * Since: 2.2
+ **/
+void
+gdk_notify_startup_complete (void)
+{
+ /* FIXME */
+ g_warning ("gdk_notify_startup_complete () not implemented on MacOS X\n");
+}
+
+
+/**
+ * gdk_display_supports_selection_notification:
+ * @display: a #GdkDisplay
+ *
+ * Returns whether #GdkEventOwnerChange events will be
+ * sent when the owner of a selection changes.
+ *
+ * Return value: whether #GdkEventOwnerChange events will
+ * be sent.
+ *
+ * Since: 2.6
+ **/
+gboolean
+gdk_display_supports_selection_notification (GdkDisplay *display)
+{
+ /* FIXME I'm not sure we support that */
+
+ return FALSE;
+}
+
+/**
+ * gdk_display_request_selection_notification:
+ * @display: a #GdkDisplay
+ * @selection: the #GdkAtom naming the selection for which
+ * ownership change notification is requested
+ *
+ * Request #GdkEventOwnerChange events for ownership changes
+ * of the selection named by the given atom.
+ *
+ * Return value: whether #GdkEventOwnerChange events will
+ * be sent.
+ *
+ * Since: 2.6
+ **/
+gboolean gdk_display_request_selection_notification (GdkDisplay *display,
+ GdkAtom selection)
+
+{
+ /* FIXME I'm not sure we support that */
+
+ return FALSE;
+}
+
+/**
+ * gdk_display_supports_clipboard_persistence
+ * @display: a #GdkDisplay
+ *
+ * Returns whether the speicifed display supports clipboard
+ * persistance; i.e. if it's possible to store the clipboard data after an
+ * application has quit. On MacOSX this checks if a clipboard daemon is
+ * running.
+ *
+ * Returns: %TRUE if the display supports clipboard persistance.
+ *
+ * Since: 2.6
+ */
+gboolean
+gdk_display_supports_clipboard_persistence (GdkDisplay *display)
+{
+ /* It might make sense to cache this */
+ return TRUE;
+}
+
+/**
+ * gdk_display_store_clipboard
+ * @display: a #GdkDisplay
+ * @clipboard_window: a #GdkWindow belonging to the clipboard owner
+ * @time_: a timestamp
+ * @targets: an array of targets that should be saved, or %NULL
+ * if all available targets should be saved.
+ * @n_targets: length of the @targets array
+ *
+ * Issues a request to the clipboard manager to store the
+ * clipboard data.
+ *
+ * Since: 2.6
+ */
+void
+gdk_display_store_clipboard (GdkDisplay *display,
+ GdkWindow *clipboard_window,
+ guint32 time_,
+ GdkAtom *targets,
+ gint n_targets)
+{
+ /* FIXME */
+ g_warning ("gdk_display_store_clipboard() not implemented on MacOS X\n");
+}
+
diff --git a/gdk/macosx/gdkdrawable-macosx.h b/gdk/macosx/gdkdrawable-macosx.h
new file mode 100644
index 0000000000..895c60513e
--- /dev/null
+++ b/gdk/macosx/gdkdrawable-macosx.h
@@ -0,0 +1,103 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GDK_DRAWABLE_MACOSX_H__
+#define __GDK_DRAWABLE_MACOSX_H__
+
+#include <config.h>
+#include <gdk/gdkdrawable.h>
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Drawable implementation for MacOSX
+ */
+
+typedef enum
+{
+ GDK_MACOSX_FORMAT_NONE,
+ GDK_MACOSX_FORMAT_EXACT_MASK,
+ GDK_MACOSX_FORMAT_ARGB_MASK,
+ GDK_MACOSX_FORMAT_ARGB
+} GdkMacOSXFormatType;
+
+typedef struct _GdkDrawableImplMacOSX GdkDrawableImplMacOSX;
+typedef struct _GdkDrawableImplMacOSXClass GdkDrawableImplMacOSXClass;
+
+#define GDK_TYPE_DRAWABLE_IMPL_MACOSX (_gdk_drawable_impl_macosx_get_type ())
+#define GDK_DRAWABLE_IMPL_MACOSX(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DRAWABLE_IMPL_MACOSX, GdkDrawableImplMacOSX))
+#define GDK_DRAWABLE_IMPL_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAWABLE_IMPL_MACOSX, GdkDrawableImplMacOSXClass))
+#define GDK_IS_DRAWABLE_IMPL_MACOSX(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DRAWABLE_IMPL_MACOSX))
+#define GDK_IS_DRAWABLE_IMPL_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DRAWABLE_IMPL_MACOSX))
+#define GDK_DRAWABLE_IMPL_MACOSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DRAWABLE_IMPL_MACOSX, GdkDrawableImplMacOSXClass))
+
+
+struct _GdkDrawableImplMacOSX
+{
+ GdkDrawable parent_instance;
+
+ GdkDrawable *wrapper;
+
+ GdkColormap *colormap;
+
+ CGContextRef cg;
+};
+
+struct _GdkDrawableImplMacOSXClass
+{
+ GdkDrawableClass parent_class;
+};
+
+GType _gdk_drawable_impl_macosx_get_type (void);
+
+void _gdk_macosx_convert_to_format (guchar *src_buf,
+ gint src_rowstride,
+ guchar *dest_buf,
+ gint dest_rowstride,
+ GdkMacOSXFormatType dest_format,
+ GdkByteOrder dest_byteorder,
+ gint width,
+ gint height);
+/* Note that the following take GdkDrawableImplMacOSX, not the wrapper drawable */
+/*
+void _gdk_macosx_drawable_draw_xtrapezoids (GdkDrawable *drawable,
+ GdkGC *gc,
+ XTrapezoid *xtrapezoids,
+ int n_trapezoids);
+void _gdk_macosx_drawable_draw_xft_glyphs (GdkDrawable *drawable,
+ GdkGC *gc,
+ XftFont *xft_font,
+ XftGlyphSpec *glyphs,
+ gint n_glyphs);
+*/
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GDK_DRAWABLE_MacOSX_H__ */
diff --git a/gdk/macosx/gdkevents-macosx.c b/gdk/macosx/gdkevents-macosx.c
new file mode 100644
index 0000000000..82ee6de833
--- /dev/null
+++ b/gdk/macosx/gdkevents-macosx.c
@@ -0,0 +1,88 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Copyright (C) 2005 Hubert Figuiere
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+/*
+ * MacOS X port by Hubert Figuiere
+ */
+
+
+#include <config.h>
+
+#include "gdk.h"
+#include "gdkinternals.h"
+
+#include <Carbon/Carbon.h>
+
+
+
+/*
+ * Currently does nothing
+ */
+void
+gdk_flush (void)
+{
+
+}
+
+
+
+/**
+ * gdk_event_send_client_message_for_display:
+ * @display: the #GdkDisplay for the window where the message is to be sent.
+ * @event: the #GdkEvent to send, which should be a #GdkEventClient.
+ * @winid: the window to send the client message to.
+ *
+ * On X11, sends an X ClientMessage event to a given window. On
+ * Windows, sends a message registered with the name
+ * GDK_WIN32_CLIENT_MESSAGE.
+ *
+ * This could be used for communicating between different
+ * applications, though the amount of data is limited to 20 bytes on
+ * X11, and to just four bytes on Windows.
+ *
+ * Returns: non-zero on success.
+ *
+ * Since: 2.2
+ */
+gboolean
+gdk_event_send_client_message_for_display (GdkDisplay *display,
+ GdkEvent *event,
+ GdkNativeWindow winid)
+{
+ /* FIXME */
+ g_assert(false);
+ return false;
+}
+
+
+void
+_gdk_events_queue (GdkDisplay *display)
+{
+ while (!_gdk_event_queue_find_first(display))
+ {
+ /* FIXME */
+ }
+}
diff --git a/gdk/macosx/gdkevents-macosx.m b/gdk/macosx/gdkevents-macosx.m
new file mode 100644
index 0000000000..94b067e41b
--- /dev/null
+++ b/gdk/macosx/gdkevents-macosx.m
@@ -0,0 +1,2485 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include <config.h>
+
+#include "gdkalias.h"
+#include "gdk.h"
+#include "gdkprivate-macosx.h"
+#include "gdkinternals.h"
+#include "gdkscreen-macosx.h"
+#include "gdkdisplay-macosx.h"
+
+#include <string.h>
+
+#include <Cocoa/Cocoa.h>
+
+typedef struct _GdkIOClosure GdkIOClosure;
+typedef struct _GdkDisplaySource GdkDisplaySource;
+typedef struct _GdkEventTypeMacOSX GdkEventTypeMacOSX;
+
+
+#define GDK_NS_CLIENT_MESSAGE 1
+
+
+struct _GdkIOClosure
+{
+ GdkInputFunction function;
+ GdkInputCondition condition;
+ GdkDestroyNotify notify;
+ gpointer data;
+};
+
+struct _GdkDisplaySource
+{
+ GSource source;
+
+ GdkDisplay *display;
+ GPollFD event_poll_fd;
+};
+
+struct _GdkEventTypeMacOSX
+{
+ gint base;
+ gint n_events;
+};
+
+/*
+ * Private function declarations
+ */
+#if 0
+static gint gdk_event_apply_filters (XEvent *xevent,
+ GdkEvent *event,
+ GList *filters);
+static gboolean gdk_event_translate (GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent,
+ gboolean return_exposes);
+
+static gboolean gdk_event_prepare (GSource *source,
+ gint *timeout);
+static gboolean gdk_event_check (GSource *source);
+static gboolean gdk_event_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data);
+
+static GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer data);
+
+static GSource *gdk_display_source_new (GdkDisplay *display);
+static gboolean gdk_check_xpending (GdkDisplay *display);
+
+static void gdk_xsettings_watch_cb (Window window,
+ Bool is_start,
+ long mask,
+ void *cb_data);
+static void gdk_xsettings_notify_cb (const char *name,
+ XSettingsAction action,
+ XSettingsSetting *setting,
+ void *data);
+
+/* Private variable declarations
+ */
+
+static GList *display_sources;
+
+static GSourceFuncs event_funcs = {
+ gdk_event_prepare,
+ gdk_event_check,
+ gdk_event_dispatch,
+ NULL
+};
+
+static GSource *
+gdk_display_source_new (GdkDisplay *display)
+{
+ GSource *source = g_source_new (&event_funcs, sizeof (GdkDisplaySource));
+ GdkDisplaySource *display_source = (GdkDisplaySource *)source;
+
+ display_source->display = display;
+
+ return source;
+}
+
+static gboolean
+gdk_check_xpending (GdkDisplay *display)
+{
+ return XPending (GDK_DISPLAY_XDISPLAY (display));
+}
+
+/*********************************************
+ * Functions for maintaining the event queue *
+ *********************************************/
+
+static void
+refcounted_grab_server (Display *xdisplay)
+{
+ GdkDisplay *display = gdk_macosx_lookup_xdisplay (xdisplay);
+
+ gdk_macosx_display_grab (display);
+}
+
+static void
+refcounted_ungrab_server (Display *xdisplay)
+{
+ GdkDisplay *display = gdk_macosx_lookup_xdisplay (xdisplay);
+
+ gdk_macosx_display_ungrab (display);
+}
+
+void
+_gdk_macosx_events_init_screen (GdkScreen *screen)
+{
+ GdkScreenMacOSX *screen_macosx = GDK_SCREEN_MACOSX (screen);
+
+ /* Keep a flag to avoid extra notifies that we don't need
+ */
+ screen_macosx->xsettings_in_init = TRUE;
+ screen_macosx->xsettings_client = xsettings_client_new (screen_macosx->xdisplay,
+ screen_macosx->screen_num,
+ gdk_xsettings_notify_cb,
+ gdk_xsettings_watch_cb,
+ screen);
+ xsettings_client_set_grab_func (screen_macosx->xsettings_client,
+ refcounted_grab_server);
+ xsettings_client_set_ungrab_func (screen_macosx->xsettings_client,
+ refcounted_ungrab_server);
+ screen_macosx->xsettings_in_init = FALSE;
+}
+
+void
+_gdk_macosx_events_uninit_screen (GdkScreen *screen)
+{
+ GdkScreenMacOSX *screen_macosx = GDK_SCREEN_MACOSX (screen);
+
+ xsettings_client_destroy (screen_macosx->xsettings_client);
+ screen_macosx->xsettings_client = NULL;
+}
+
+void
+_gdk_events_init (GdkDisplay *display)
+{
+ GSource *source;
+ GdkDisplaySource *display_source;
+ GdkDisplayMacOSX *display_macosx = GDK_DISPLAY_MACOSX (display);
+
+ int connection_number = ConnectionNumber (display_macosx->xdisplay);
+ GDK_NOTE (MISC, g_message ("connection number: %d", connection_number));
+
+
+ source = display_macosx->event_source = gdk_display_source_new (display);
+ display_source = (GdkDisplaySource*) source;
+ g_source_set_priority (source, GDK_PRIORITY_EVENTS);
+
+ display_source->event_poll_fd.fd = connection_number;
+ display_source->event_poll_fd.events = G_IO_IN;
+
+ g_source_add_poll (source, &display_source->event_poll_fd);
+ g_source_set_can_recurse (source, TRUE);
+ g_source_attach (source, NULL);
+
+ display_sources = g_list_prepend (display_sources,display_source);
+
+ gdk_display_add_client_message_filter (display,
+ gdk_atom_intern ("WM_PROTOCOLS", FALSE),
+ gdk_wm_protocols_filter,
+ NULL);
+}
+
+
+/**
+ * gdk_events_pending:
+ *
+ * Checks if any events are ready to be processed for any display.
+ *
+ * Return value: %TRUE if any events are pending.
+ **/
+gboolean
+gdk_events_pending (void)
+{
+ GList *tmp_list;
+
+ for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next)
+ {
+ GdkDisplaySource *tmp_source = tmp_list->data;
+ GdkDisplay *display = tmp_source->display;
+
+ if (_gdk_event_queue_find_first (display))
+ return TRUE;
+ }
+
+ for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next)
+ {
+ GdkDisplaySource *tmp_source = tmp_list->data;
+ GdkDisplay *display = tmp_source->display;
+
+ if (gdk_check_xpending (display))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static Bool
+graphics_expose_predicate (Display *display,
+ XEvent *xevent,
+ XPointer arg)
+{
+ if (xevent->xany.window == GDK_DRAWABLE_XID ((GdkDrawable *)arg) &&
+ (xevent->xany.type == GraphicsExpose ||
+ xevent->xany.type == NoExpose))
+ return True;
+ else
+ return False;
+}
+
+/**
+ * gdk_event_get_graphics_expose:
+ * @window: the #GdkWindow to wait for the events for.
+ *
+ * Waits for a GraphicsExpose or NoExpose event from the X server.
+ * This is used in the #GtkText and #GtkCList widgets in GTK+ to make sure any
+ * GraphicsExpose events are handled before the widget is scrolled.
+ *
+ * Return value: a #GdkEventExpose if a GraphicsExpose was received, or %NULL if a
+ * NoExpose event was received.
+ **/
+GdkEvent*
+gdk_event_get_graphics_expose (GdkWindow *window)
+{
+ XEvent xevent;
+ GdkEvent *event;
+
+ g_return_val_if_fail (window != NULL, NULL);
+
+ XIfEvent (GDK_WINDOW_XDISPLAY (window), &xevent,
+ graphics_expose_predicate, (XPointer) window);
+
+ if (xevent.xany.type == GraphicsExpose)
+ {
+ event = gdk_event_new (GDK_NOTHING);
+
+ if (gdk_event_translate (GDK_WINDOW_DISPLAY (window), event,
+ &xevent, TRUE))
+ return event;
+ else
+ gdk_event_free (event);
+ }
+
+ return NULL;
+}
+
+static gint
+gdk_event_apply_filters (XEvent *xevent,
+ GdkEvent *event,
+ GList *filters)
+{
+ GList *tmp_list;
+ GdkFilterReturn result;
+
+ tmp_list = filters;
+
+ while (tmp_list)
+ {
+ GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data;
+
+ tmp_list = tmp_list->next;
+ result = filter->function (xevent, event, filter->data);
+ if (result != GDK_FILTER_CONTINUE)
+ return result;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+/**
+ * gdk_display_add_client_message_filter:
+ * @display: a #GdkDisplay for which this message filter applies
+ * @message_type: the type of ClientMessage events to receive.
+ * This will be checked against the @message_type field
+ * of the XClientMessage event struct.
+ * @func: the function to call to process the event.
+ * @data: user data to pass to @func.
+ *
+ * Adds a filter to be called when X ClientMessage events are received.
+ *
+ * Since: 2.2
+ **/
+void
+gdk_display_add_client_message_filter (GdkDisplay *display,
+ GdkAtom message_type,
+ GdkFilterFunc func,
+ gpointer data)
+{
+ GdkClientFilter *filter;
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+ filter = g_new (GdkClientFilter, 1);
+
+ filter->type = message_type;
+ filter->function = func;
+ filter->data = data;
+
+ GDK_DISPLAY_MACOSX(display)->client_filters =
+ g_list_append (GDK_DISPLAY_MacOSX (display)->client_filters,
+ filter);
+}
+
+/**
+ * gdk_add_client_message_filter:
+ * @message_type: the type of ClientMessage events to receive. This will be
+ * checked against the <structfield>message_type</structfield> field of the
+ * XClientMessage event struct.
+ * @func: the function to call to process the event.
+ * @data: user data to pass to @func.
+ *
+ * Adds a filter to the default display to be called when X ClientMessage events
+ * are received. See gdk_display_add_client_message_filter().
+ **/
+void
+gdk_add_client_message_filter (GdkAtom message_type,
+ GdkFilterFunc func,
+ gpointer data)
+{
+ gdk_display_add_client_message_filter (gdk_display_get_default (),
+ message_type, func, data);
+}
+
+
+#define HAS_FOCUS(toplevel) \
+ ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
+
+static void
+generate_focus_event (GdkWindow *window,
+ gboolean in)
+{
+ GdkEvent event;
+
+ event.type = GDK_FOCUS_CHANGE;
+ event.focus_change.window = window;
+ event.focus_change.send_event = FALSE;
+ event.focus_change.in = in;
+
+ gdk_event_put (&event);
+}
+
+static void
+set_screen_from_root (GdkDisplay *display,
+ GdkEvent *event,
+ Window xrootwin)
+{
+ GdkScreen *screen;
+
+ screen = _gdk_macosx_display_screen_for_xrootwin (display, xrootwin);
+ g_assert (screen);
+
+ gdk_event_set_screen (event, screen);
+}
+
+static void
+translate_key_event (GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent)
+{
+ GdkKeymap *keymap = gdk_keymap_get_for_display (display);
+ gunichar c = 0;
+ guchar buf[7];
+
+ event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
+ event->key.time = xevent->xkey.time;
+
+ event->key.state = (GdkModifierType) xevent->xkey.state;
+ event->key.group = _gdk_macosx_get_group_for_state (display, xevent->xkey.state);
+ event->key.hardware_keycode = xevent->xkey.keycode;
+
+ event->key.keyval = GDK_VoidSymbol;
+
+ gdk_keymap_translate_keyboard_state (keymap,
+ event->key.hardware_keycode,
+ event->key.state,
+ event->key.group,
+ &event->key.keyval,
+ NULL, NULL, NULL);
+
+ /* Fill in event->string crudely, since various programs
+ * depend on it.
+ */
+ event->key.string = NULL;
+
+ if (event->key.keyval != GDK_VoidSymbol)
+ c = gdk_keyval_to_unicode (event->key.keyval);
+
+ if (c)
+ {
+ gsize bytes_written;
+ gint len;
+
+ /* Apply the control key - Taken from Xlib
+ */
+ if (event->key.state & GDK_CONTROL_MASK)
+ {
+ if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
+ else if (c == '2')
+ {
+ event->key.string = g_memdup ("\0\0", 2);
+ event->key.length = 1;
+ buf[0] = '\0';
+ goto out;
+ }
+ else if (c >= '3' && c <= '7') c -= ('3' - '\033');
+ else if (c == '8') c = '\177';
+ else if (c == '/') c = '_' & 0x1F;
+ }
+
+ len = g_unichar_to_utf8 (c, buf);
+ buf[len] = '\0';
+
+ event->key.string = g_locale_from_utf8 (buf, len,
+ NULL, &bytes_written,
+ NULL);
+ if (event->key.string)
+ event->key.length = bytes_written;
+ }
+ else if (event->key.keyval == GDK_Escape)
+ {
+ event->key.length = 1;
+ event->key.string = g_strdup ("\033");
+ }
+ else if (event->key.keyval == GDK_Return ||
+ event->key.keyval == GDK_KP_Enter)
+ {
+ event->key.length = 1;
+ event->key.string = g_strdup ("\r");
+ }
+
+ if (!event->key.string)
+ {
+ event->key.length = 0;
+ event->key.string = g_strdup ("");
+ }
+
+ out:
+#ifdef G_ENABLE_DEBUG
+ if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
+ {
+ g_message ("%s:\t\twindow: %ld key: %12s %d",
+ event->type == GDK_KEY_PRESS ? "key press " : "key release",
+ xevent->xkey.window,
+ event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
+ event->key.keyval);
+
+ if (event->key.length > 0)
+ g_message ("\t\tlength: %4d string: \"%s\"",
+ event->key.length, buf);
+ }
+#endif /* G_ENABLE_DEBUG */
+ return;
+}
+
+/**
+ * gdk_macosx_register_standard_event_type:
+ * @display: a #GdkDisplay
+ * @event_base: first event type code to register
+ * @n_events: number of event type codes to register
+ *
+ * Registers interest in receiving extension events with type codes
+ * between @event_base and <literal>event_base + n_events - 1</literal>.
+ * The registered events must have the window field in the same place
+ * as core X events (this is not the case for e.g. XKB extension events).
+ *
+ * If an event type is registered, events of this type will go through
+ * global and window-specific filters (see gdk_window_add_filter()).
+ * Unregistered events will only go through global filters.
+ * GDK may register the events of some X extensions on its own.
+ *
+ * This function should only be needed in unusual circumstances, e.g.
+ * when filtering XInput extension events on the root window.
+ *
+ * Since: 2.4
+ **/
+void
+gdk_macosx_register_standard_event_type (GdkDisplay *display,
+ gint event_base,
+ gint n_events)
+{
+ GdkEventTypeMacOSX *event_type;
+ GdkDisplayMacOSX *display_macosx;
+
+ display_macosx = GDK_DISPLAY_MACOSX (display);
+ event_type = g_new (GdkEventTypeMacOSX, 1);
+
+ event_type->base = event_base;
+ event_type->n_events = n_events;
+
+ display_macosx->event_types = g_slist_prepend (display_macosx->event_types, event_type);
+}
+
+/* Return the window this has to do with, if any, rather
+ * than the frame or root window that was selecting
+ * for substructure
+ */
+static void
+get_real_window (GdkDisplay *display,
+ XEvent *event,
+ Window *event_window,
+ Window *filter_window)
+{
+ /* Core events all have an event->xany.window field, but that's
+ * not true for extension events
+ */
+ if (event->type >= KeyPress &&
+ event->type <= MappingNotify)
+ {
+ *filter_window = event->xany.window;
+ switch (event->type)
+ {
+ case CreateNotify:
+ *event_window = event->xcreatewindow.window;
+ break;
+ case DestroyNotify:
+ *event_window = event->xdestroywindow.window;
+ break;
+ case UnmapNotify:
+ *event_window = event->xunmap.window;
+ break;
+ case MapNotify:
+ *event_window = event->xmap.window;
+ break;
+ case MapRequest:
+ *event_window = event->xmaprequest.window;
+ break;
+ case ReparentNotify:
+ *event_window = event->xreparent.window;
+ break;
+ case ConfigureNotify:
+ *event_window = event->xconfigure.window;
+ break;
+ case ConfigureRequest:
+ *event_window = event->xconfigurerequest.window;
+ break;
+ case GravityNotify:
+ *event_window = event->xgravity.window;
+ break;
+ case CirculateNotify:
+ *event_window = event->xcirculate.window;
+ break;
+ case CirculateRequest:
+ *event_window = event->xcirculaterequest.window;
+ break;
+ default:
+ *event_window = event->xany.window;
+ }
+ }
+ else
+ {
+ GdkDisplayMacOSX *display_macosx = GDK_DISPLAY_MacOSX (display);
+ GSList *tmp_list;
+
+ for (tmp_list = display_macosx->event_types;
+ tmp_list;
+ tmp_list = tmp_list->next)
+ {
+ GdkEventTypeMacOSX *event_type = tmp_list->data;
+
+ if (event->type >= event_type->base &&
+ event->type < event_type->base + event_type->n_events)
+ {
+ *event_window = event->xany.window;
+ *filter_window = event->xany.window;
+ return;
+ }
+ }
+
+ *event_window = None;
+ *filter_window = None;
+ }
+}
+
+#ifdef G_ENABLE_DEBUG
+static const char notify_modes[][19] = {
+ "NotifyNormal",
+ "NotifyGrab",
+ "NotifyUngrab",
+ "NotifyWhileGrabbed"
+};
+
+static const char notify_details[][23] = {
+ "NotifyAncestor",
+ "NotifyVirtual",
+ "NotifyInferior",
+ "NotifyNonlinear",
+ "NotifyNonlinearVirtual",
+ "NotifyPointer",
+ "NotifyPointerRoot",
+ "NotifyDetailNone"
+};
+#endif
+
+static void
+set_user_time (GdkWindow *window,
+ GdkEvent *event)
+{
+ g_return_if_fail (event != NULL);
+
+ window = gdk_window_get_toplevel (event->client.window);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* If an event doesn't have a valid timestamp, we shouldn't use it
+ * to update the latest user interaction time.
+ */
+ if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
+ gdk_macosx_window_set_user_time (gdk_window_get_toplevel (window),
+ gdk_event_get_time (event));
+}
+
+static gboolean
+gdk_event_translate (GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent,
+ gboolean return_exposes)
+{
+
+ GdkWindow *window;
+ GdkWindowObject *window_private;
+ GdkWindow *filter_window;
+ GdkWindowImplMacOSX *window_impl = NULL;
+ gboolean return_val;
+ gint xoffset, yoffset;
+ GdkScreen *screen = NULL;
+ GdkScreenMacOSX *screen_macosx = NULL;
+ GdkToplevelMacOSX *toplevel = NULL;
+ GdkDisplayMacOSX *display_macosx = GDK_DISPLAY_MacOSX (display);
+ Window xwindow, filter_xwindow;
+
+ return_val = FALSE;
+
+ /* init these, since the done: block uses them */
+ window = NULL;
+ window_private = NULL;
+ event->any.window = NULL;
+
+ if (_gdk_default_filters)
+ {
+ /* Apply global filters */
+ GdkFilterReturn result;
+ result = gdk_event_apply_filters (xevent, event,
+ _gdk_default_filters);
+
+ if (result != GDK_FILTER_CONTINUE)
+ {
+ return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+ goto done;
+ }
+ }
+
+ /* Find the GdkWindow that this event relates to.
+ * Basically this means substructure events
+ * are reported same as structure events
+ */
+ get_real_window (display, xevent, &xwindow, &filter_xwindow);
+
+ window = gdk_window_lookup_for_display (display, xwindow);
+ /* We may receive events such as NoExpose/GraphicsExpose
+ * and ShmCompletion for pixmaps
+ */
+ if (window && !GDK_IS_WINDOW (window))
+ window = NULL;
+ window_private = (GdkWindowObject *) window;
+
+ /* We always run the filters for the window where the event
+ * is delivered, not the window that it relates to
+ */
+ if (filter_xwindow == xwindow)
+ filter_window = window;
+ else
+ {
+ filter_window = gdk_window_lookup_for_display (display, filter_xwindow);
+ if (filter_window && !GDK_IS_WINDOW (filter_window))
+ filter_window = NULL;
+ }
+
+ if (window)
+ {
+ screen = GDK_WINDOW_SCREEN (window);
+ screen_macosx = GDK_SCREEN_MacOSX (screen);
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+ }
+
+ if (window != NULL)
+ {
+ window_impl = GDK_WINDOW_IMPL_MacOSX (window_private->impl);
+
+ /* Move key events on focus window to the real toplevel, and
+ * filter out all other events on focus window
+ */
+ if (toplevel && xwindow == toplevel->focus_window)
+ {
+ switch (xevent->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ xwindow = GDK_WINDOW_XID (window);
+ xevent->xany.window = xwindow;
+ break;
+ default:
+ return FALSE;
+ }
+ }
+
+ g_object_ref (window);
+ }
+
+ event->any.window = window;
+ event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
+
+ if (window_private && GDK_WINDOW_DESTROYED (window))
+ {
+ if (xevent->type != DestroyNotify)
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+ else if (filter_window)
+ {
+ /* Apply per-window filters */
+ GdkWindowObject *filter_private = (GdkWindowObject *) filter_window;
+ GdkFilterReturn result;
+
+ if (filter_private->filters)
+ {
+ g_object_ref (filter_window);
+
+ result = gdk_event_apply_filters (xevent, event,
+ filter_private->filters);
+
+ g_object_unref (filter_window);
+
+ if (result != GDK_FILTER_CONTINUE)
+ {
+ return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+ goto done;
+ }
+ }
+ }
+
+ if (screen_macosx && screen_macosx->wmspec_check_window != None &&
+ xwindow == screen_macosx->wmspec_check_window)
+ {
+ if (xevent->type == DestroyNotify)
+ {
+ screen_macosx->wmspec_check_window = None;
+ g_free (screen_macosx->window_manager_name);
+ screen_macosx->window_manager_name = g_strdup ("unknown");
+
+ /* careful, reentrancy */
+ _gdk_macosx_screen_window_manager_changed (GDK_SCREEN (screen_macosx));
+ }
+
+ /* Eat events on this window unless someone had wrapped
+ * it as a foreign window
+ */
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+
+ if (window &&
+ (xevent->xany.type == MotionNotify ||
+ xevent->xany.type == ButtonRelease))
+ {
+ if (_gdk_moveresize_handle_event (xevent))
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+
+ /* We do a "manual" conversion of the XEvent to a
+ * GdkEvent. The structures are mostly the same so
+ * the conversion is fairly straightforward. We also
+ * optionally print debugging info regarding events
+ * received.
+ */
+
+ return_val = TRUE;
+
+ if (window)
+ {
+ _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
+ }
+ else
+ {
+ xoffset = 0;
+ yoffset = 0;
+ }
+
+ switch (xevent->type)
+ {
+ case KeyPress:
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+ translate_key_event (display, event, xevent);
+ set_user_time (window, event);
+ break;
+
+ case KeyRelease:
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* Emulate detectable auto-repeat by checking to see
+ * if the next event is a key press with the same
+ * keycode and timestamp, and if so, ignoring the event.
+ */
+
+ if (!display_macosx->have_xkb_autorepeat && XPending (xevent->xkey.display))
+ {
+ XEvent next_event;
+
+ XPeekEvent (xevent->xkey.display, &next_event);
+
+ if (next_event.type == KeyPress &&
+ next_event.xkey.keycode == xevent->xkey.keycode &&
+ next_event.xkey.time == xevent->xkey.time)
+ {
+ return_val = FALSE;
+ break;
+ }
+ }
+
+ translate_key_event (display, event, xevent);
+ break;
+
+ case ButtonPress:
+ GDK_NOTE (EVENTS,
+ g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d",
+ xevent->xbutton.window,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.button));
+
+ if (window_private == NULL ||
+ ((window_private->extension_events != 0) &&
+ display_macosx->input_ignore_core))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* If we get a ButtonPress event where the button is 4 or 5,
+ it's a Scroll event */
+ switch (xevent->xbutton.button)
+ {
+ case 4: /* up */
+ case 5: /* down */
+ case 6: /* left */
+ case 7: /* right */
+ event->scroll.type = GDK_SCROLL;
+
+ if (xevent->xbutton.button == 4)
+ event->scroll.direction = GDK_SCROLL_UP;
+ else if (xevent->xbutton.button == 5)
+ event->scroll.direction = GDK_SCROLL_DOWN;
+ else if (xevent->xbutton.button == 6)
+ event->scroll.direction = GDK_SCROLL_LEFT;
+ else
+ event->scroll.direction = GDK_SCROLL_RIGHT;
+
+ event->scroll.window = window;
+ event->scroll.time = xevent->xbutton.time;
+ event->scroll.x = xevent->xbutton.x + xoffset;
+ event->scroll.y = xevent->xbutton.y + yoffset;
+ event->scroll.x_root = (gfloat)xevent->xbutton.x_root;
+ event->scroll.y_root = (gfloat)xevent->xbutton.y_root;
+ event->scroll.state = (GdkModifierType) xevent->xbutton.state;
+ event->scroll.device = display->core_pointer;
+
+ set_screen_from_root (display, event, xevent->xbutton.root);
+
+ break;
+
+ default:
+ event->button.type = GDK_BUTTON_PRESS;
+ event->button.window = window;
+ event->button.time = xevent->xbutton.time;
+ event->button.x = xevent->xbutton.x + xoffset;
+ event->button.y = xevent->xbutton.y + yoffset;
+ event->button.x_root = (gfloat)xevent->xbutton.x_root;
+ event->button.y_root = (gfloat)xevent->xbutton.y_root;
+ event->button.axes = NULL;
+ event->button.state = (GdkModifierType) xevent->xbutton.state;
+ event->button.button = xevent->xbutton.button;
+ event->button.device = display->core_pointer;
+
+ set_screen_from_root (display, event, xevent->xbutton.root);
+
+ _gdk_event_button_generate (display, event);
+ break;
+ }
+
+ set_user_time (window, event);
+ break;
+
+ case ButtonRelease:
+ GDK_NOTE (EVENTS,
+ g_message ("button release:\twindow: %ld x,y: %d %d button: %d",
+ xevent->xbutton.window,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.button));
+
+ if (window_private == NULL ||
+ ((window_private->extension_events != 0) &&
+ display_macosx->input_ignore_core))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* We treat button presses as scroll wheel events, so ignore the release */
+ if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
+ xevent->xbutton.button == 6 || xevent->xbutton.button ==7)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ event->button.type = GDK_BUTTON_RELEASE;
+ event->button.window = window;
+ event->button.time = xevent->xbutton.time;
+ event->button.x = xevent->xbutton.x + xoffset;
+ event->button.y = xevent->xbutton.y + yoffset;
+ event->button.x_root = (gfloat)xevent->xbutton.x_root;
+ event->button.y_root = (gfloat)xevent->xbutton.y_root;
+ event->button.axes = NULL;
+ event->button.state = (GdkModifierType) xevent->xbutton.state;
+ event->button.button = xevent->xbutton.button;
+ event->button.device = display->core_pointer;
+
+ set_screen_from_root (display, event, xevent->xbutton.root);
+
+ break;
+
+ case MotionNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s",
+ xevent->xmotion.window,
+ xevent->xmotion.x, xevent->xmotion.y,
+ (xevent->xmotion.is_hint) ? "true" : "false"));
+
+ if (window_private == NULL ||
+ ((window_private->extension_events != 0) &&
+ display_macosx->input_ignore_core))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ event->motion.type = GDK_MOTION_NOTIFY;
+ event->motion.window = window;
+ event->motion.time = xevent->xmotion.time;
+ event->motion.x = xevent->xmotion.x + xoffset;
+ event->motion.y = xevent->xmotion.y + yoffset;
+ event->motion.x_root = (gfloat)xevent->xmotion.x_root;
+ event->motion.y_root = (gfloat)xevent->xmotion.y_root;
+ event->motion.axes = NULL;
+ event->motion.state = (GdkModifierType) xevent->xmotion.state;
+ event->motion.is_hint = xevent->xmotion.is_hint;
+ event->motion.device = display->core_pointer;
+
+ set_screen_from_root (display, event, xevent->xmotion.root);
+
+ break;
+
+ case EnterNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld",
+ xevent->xcrossing.window,
+ xevent->xcrossing.detail,
+ xevent->xcrossing.subwindow));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* Handle focusing (in the case where no window manager is running */
+ if (toplevel &&
+ xevent->xcrossing.detail != NotifyInferior &&
+ xevent->xcrossing.focus && !toplevel->has_focus_window)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ toplevel->has_pointer_focus = TRUE;
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, TRUE);
+ }
+
+ /* Tell XInput stuff about it if appropriate */
+ if (window_private &&
+ !GDK_WINDOW_DESTROYED (window) &&
+ window_private->extension_events != 0)
+ _gdk_input_enter_event (&xevent->xcrossing, window);
+
+ event->crossing.type = GDK_ENTER_NOTIFY;
+ event->crossing.window = window;
+
+ /* If the subwindow field of the XEvent is non-NULL, then
+ * lookup the corresponding GdkWindow.
+ */
+ if (xevent->xcrossing.subwindow != None)
+ event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow);
+ else
+ event->crossing.subwindow = NULL;
+
+ event->crossing.time = xevent->xcrossing.time;
+ event->crossing.x = xevent->xcrossing.x + xoffset;
+ event->crossing.y = xevent->xcrossing.y + yoffset;
+ event->crossing.x_root = xevent->xcrossing.x_root;
+ event->crossing.y_root = xevent->xcrossing.y_root;
+
+ set_screen_from_root (display, event, xevent->xcrossing.root);
+
+ /* Translate the crossing mode into Gdk terms.
+ */
+ switch (xevent->xcrossing.mode)
+ {
+ case NotifyNormal:
+ event->crossing.mode = GDK_CROSSING_NORMAL;
+ break;
+ case NotifyGrab:
+ event->crossing.mode = GDK_CROSSING_GRAB;
+ break;
+ case NotifyUngrab:
+ event->crossing.mode = GDK_CROSSING_UNGRAB;
+ break;
+ };
+
+ /* Translate the crossing detail into Gdk terms.
+ */
+ switch (xevent->xcrossing.detail)
+ {
+ case NotifyInferior:
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ break;
+ case NotifyAncestor:
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ break;
+ case NotifyVirtual:
+ event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+ break;
+ case NotifyNonlinear:
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+ break;
+ case NotifyNonlinearVirtual:
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+ break;
+ default:
+ event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+ break;
+ }
+
+ event->crossing.focus = xevent->xcrossing.focus;
+ event->crossing.state = xevent->xcrossing.state;
+
+ break;
+
+ case LeaveNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld",
+ xevent->xcrossing.window,
+ xevent->xcrossing.detail, xevent->xcrossing.subwindow));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* Handle focusing (in the case where no window manager is running */
+ if (toplevel &&
+ xevent->xcrossing.detail != NotifyInferior &&
+ xevent->xcrossing.focus && !toplevel->has_focus_window)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ toplevel->has_pointer_focus = FALSE;
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, FALSE);
+ }
+
+ event->crossing.type = GDK_LEAVE_NOTIFY;
+ event->crossing.window = window;
+
+ /* If the subwindow field of the XEvent is non-NULL, then
+ * lookup the corresponding GdkWindow.
+ */
+ if (xevent->xcrossing.subwindow != None)
+ event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow);
+ else
+ event->crossing.subwindow = NULL;
+
+ event->crossing.time = xevent->xcrossing.time;
+ event->crossing.x = xevent->xcrossing.x + xoffset;
+ event->crossing.y = xevent->xcrossing.y + yoffset;
+ event->crossing.x_root = xevent->xcrossing.x_root;
+ event->crossing.y_root = xevent->xcrossing.y_root;
+
+ set_screen_from_root (display, event, xevent->xcrossing.root);
+
+ /* Translate the crossing mode into Gdk terms.
+ */
+ switch (xevent->xcrossing.mode)
+ {
+ case NotifyNormal:
+ event->crossing.mode = GDK_CROSSING_NORMAL;
+ break;
+ case NotifyGrab:
+ event->crossing.mode = GDK_CROSSING_GRAB;
+ break;
+ case NotifyUngrab:
+ event->crossing.mode = GDK_CROSSING_UNGRAB;
+ break;
+ };
+
+ /* Translate the crossing detail into Gdk terms.
+ */
+ switch (xevent->xcrossing.detail)
+ {
+ case NotifyInferior:
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ break;
+ case NotifyAncestor:
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ break;
+ case NotifyVirtual:
+ event->crossing.detail = GDK_NOTIFY_VIRTUAL;
+ break;
+ case NotifyNonlinear:
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+ break;
+ case NotifyNonlinearVirtual:
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
+ break;
+ default:
+ event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+ break;
+ }
+
+ event->crossing.focus = xevent->xcrossing.focus;
+ event->crossing.state = xevent->xcrossing.state;
+
+ break;
+
+ /* We only care about focus events that indicate that _this_
+ * window (not a ancestor or child) got or lost the focus
+ */
+ case FocusIn:
+ GDK_NOTE (EVENTS,
+ g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
+ xevent->xfocus.window,
+ notify_details[xevent->xfocus.detail],
+ notify_modes[xevent->xfocus.mode]));
+
+ if (toplevel)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ switch (xevent->xfocus.detail)
+ {
+ case NotifyAncestor:
+ case NotifyNonlinear:
+ case NotifyVirtual:
+ case NotifyNonlinearVirtual:
+ toplevel->has_focus_window = TRUE;
+ /* We pretend that the focus moves to the grab
+ * window, so we pay attention to NotifyGrab
+ * NotifyUngrab, and ignore NotifyWhileGrabbed
+ */
+ if (xevent->xfocus.mode != NotifyWhileGrabbed)
+ toplevel->has_focus = TRUE;
+ break;
+ case NotifyPointer:
+ /* The X server sends NotifyPointer/NotifyGrab,
+ * but the pointer focus is ignored while a
+ * grab is in effect
+ */
+ if (xevent->xfocus.mode != NotifyGrab)
+ toplevel->has_pointer_focus = TRUE;
+ break;
+ case NotifyInferior:
+ case NotifyPointerRoot:
+ case NotifyDetailNone:
+ break;
+ }
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, TRUE);
+ }
+ break;
+ case FocusOut:
+ GDK_NOTE (EVENTS,
+ g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
+ xevent->xfocus.window,
+ notify_details[xevent->xfocus.detail],
+ notify_modes[xevent->xfocus.mode]));
+
+ if (toplevel)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ switch (xevent->xfocus.detail)
+ {
+ case NotifyAncestor:
+ case NotifyNonlinear:
+ case NotifyVirtual:
+ case NotifyNonlinearVirtual:
+ toplevel->has_focus_window = FALSE;
+ if (xevent->xfocus.mode != NotifyWhileGrabbed)
+ toplevel->has_focus = FALSE;
+ break;
+ case NotifyPointer:
+ if (xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = FALSE;
+ break;
+ case NotifyInferior:
+ case NotifyPointerRoot:
+ case NotifyDetailNone:
+ break;
+ }
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, FALSE);
+ }
+ break;
+
+#if 0
+ /* gdk_keyboard_grab() causes following events. These events confuse
+ * the XIM focus, so ignore them.
+ */
+ if (xevent->xfocus.mode == NotifyGrab ||
+ xevent->xfocus.mode == NotifyUngrab)
+ break;
+#endif
+
+ case KeymapNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("keymap notify"));
+
+ /* Not currently handled */
+ return_val = FALSE;
+ break;
+
+ case Expose:
+ GDK_NOTE (EVENTS,
+ g_message ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s",
+ xevent->xexpose.window, xevent->xexpose.count,
+ xevent->xexpose.x, xevent->xexpose.y,
+ xevent->xexpose.width, xevent->xexpose.height,
+ event->any.send_event ? " (send)" : ""));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ {
+ GdkRectangle expose_rect;
+
+ expose_rect.x = xevent->xexpose.x + xoffset;
+ expose_rect.y = xevent->xexpose.y + yoffset;
+ expose_rect.width = xevent->xexpose.width;
+ expose_rect.height = xevent->xexpose.height;
+
+ if (return_exposes)
+ {
+ event->expose.type = GDK_EXPOSE;
+ event->expose.area = expose_rect;
+ event->expose.region = gdk_region_rectangle (&expose_rect);
+ event->expose.window = window;
+ event->expose.count = xevent->xexpose.count;
+
+ return_val = TRUE;
+ }
+ else
+ {
+ _gdk_window_process_expose (window, xevent->xexpose.serial, &expose_rect);
+ return_val = FALSE;
+ }
+
+ return_val = FALSE;
+ }
+
+ break;
+
+ case GraphicsExpose:
+ {
+ GdkRectangle expose_rect;
+
+ GDK_NOTE (EVENTS,
+ g_message ("graphics expose:\tdrawable: %ld",
+ xevent->xgraphicsexpose.drawable));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ expose_rect.x = xevent->xgraphicsexpose.x + xoffset;
+ expose_rect.y = xevent->xgraphicsexpose.y + yoffset;
+ expose_rect.width = xevent->xgraphicsexpose.width;
+ expose_rect.height = xevent->xgraphicsexpose.height;
+
+ if (return_exposes)
+ {
+ event->expose.type = GDK_EXPOSE;
+ event->expose.area = expose_rect;
+ event->expose.region = gdk_region_rectangle (&expose_rect);
+ event->expose.window = window;
+ event->expose.count = xevent->xgraphicsexpose.count;
+
+ return_val = TRUE;
+ }
+ else
+ {
+ _gdk_window_process_expose (window, xevent->xgraphicsexpose.serial, &expose_rect);
+
+ return_val = FALSE;
+ }
+
+ }
+ break;
+
+ case NoExpose:
+ GDK_NOTE (EVENTS,
+ g_message ("no expose:\t\tdrawable: %ld",
+ xevent->xnoexpose.drawable));
+
+ event->no_expose.type = GDK_NO_EXPOSE;
+ event->no_expose.window = window;
+
+ break;
+
+ case VisibilityNotify:
+#ifdef G_ENABLE_DEBUG
+ if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
+ switch (xevent->xvisibility.state)
+ {
+ case VisibilityFullyObscured:
+ g_message ("visibility notify:\twindow: %ld none",
+ xevent->xvisibility.window);
+ break;
+ case VisibilityPartiallyObscured:
+ g_message ("visibility notify:\twindow: %ld partial",
+ xevent->xvisibility.window);
+ break;
+ case VisibilityUnobscured:
+ g_message ("visibility notify:\twindow: %ld full",
+ xevent->xvisibility.window);
+ break;
+ }
+#endif /* G_ENABLE_DEBUG */
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ event->visibility.type = GDK_VISIBILITY_NOTIFY;
+ event->visibility.window = window;
+
+ switch (xevent->xvisibility.state)
+ {
+ case VisibilityFullyObscured:
+ event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED;
+ break;
+
+ case VisibilityPartiallyObscured:
+ event->visibility.state = GDK_VISIBILITY_PARTIAL;
+ break;
+
+ case VisibilityUnobscured:
+ event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
+ break;
+ }
+
+ break;
+
+ case CreateNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d",
+ xevent->xcreatewindow.window,
+ xevent->xcreatewindow.x,
+ xevent->xcreatewindow.y,
+ xevent->xcreatewindow.width,
+ xevent->xcreatewindow.height,
+ xevent->xcreatewindow.border_width,
+ xevent->xcreatewindow.parent,
+ xevent->xcreatewindow.override_redirect));
+ /* not really handled */
+ break;
+
+ case DestroyNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("destroy notify:\twindow: %ld",
+ xevent->xdestroywindow.window));
+
+ /* Ignore DestroyNotify from SubstructureNotifyMask */
+ if (xevent->xdestroywindow.window == xevent->xdestroywindow.event)
+ {
+ event->any.type = GDK_DESTROY;
+ event->any.window = window;
+
+ return_val = window_private && !GDK_WINDOW_DESTROYED (window);
+
+ if (window && GDK_WINDOW_XID (window) != screen_macosx->xroot_window)
+ gdk_window_destroy_notify (window);
+ }
+ else
+ return_val = FALSE;
+
+ break;
+
+ case UnmapNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("unmap notify:\t\twindow: %ld",
+ xevent->xmap.window));
+
+ event->any.type = GDK_UNMAP;
+ event->any.window = window;
+
+ /* If we are shown (not withdrawn) and get an unmap, it means we
+ * were iconified in the X sense. If we are withdrawn, and get
+ * an unmap, it means we hid the window ourselves, so we
+ * will have already flipped the iconified bit off.
+ */
+ if (window)
+ {
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_ICONIFIED);
+
+ _gdk_xgrab_check_unmap (window, xevent->xany.serial);
+ }
+
+ break;
+
+ case MapNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("map notify:\t\twindow: %ld",
+ xevent->xmap.window));
+
+ event->any.type = GDK_MAP;
+ event->any.window = window;
+
+ /* Unset iconified if it was set */
+ if (window && (((GdkWindowObject*)window)->state & GDK_WINDOW_STATE_ICONIFIED))
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_ICONIFIED,
+ 0);
+
+ break;
+
+ case ReparentNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d",
+ xevent->xreparent.window,
+ xevent->xreparent.x,
+ xevent->xreparent.y,
+ xevent->xreparent.parent,
+ xevent->xreparent.override_redirect));
+
+ /* Not currently handled */
+ return_val = FALSE;
+ break;
+
+ case ConfigureNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s",
+ xevent->xconfigure.window,
+ xevent->xconfigure.x,
+ xevent->xconfigure.y,
+ xevent->xconfigure.width,
+ xevent->xconfigure.height,
+ xevent->xconfigure.border_width,
+ xevent->xconfigure.above,
+ xevent->xconfigure.override_redirect,
+ !window
+ ? " (discarding)"
+ : GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD
+ ? " (discarding child)"
+ : xevent->xconfigure.event != xevent->xconfigure.window
+ ? " (discarding substructure)"
+ : ""));
+ if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
+ _gdk_macosx_screen_size_changed (screen, xevent);
+
+ if (window &&
+ xevent->xconfigure.event == xevent->xconfigure.window &&
+ !GDK_WINDOW_DESTROYED (window) &&
+ (window_private->extension_events != 0))
+ _gdk_input_configure_event (&xevent->xconfigure, window);
+
+#ifdef HAVE_XSYNC
+ if (toplevel && display_macosx->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
+ {
+ toplevel->current_counter_value = toplevel->pending_counter_value;
+ XSyncIntToValue (&toplevel->pending_counter_value, 0);
+ }
+#endif
+
+ if (!window ||
+ xevent->xconfigure.event != xevent->xconfigure.window ||
+ GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
+ GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
+ return_val = FALSE;
+ else
+ {
+ event->configure.type = GDK_CONFIGURE;
+ event->configure.window = window;
+ event->configure.width = xevent->xconfigure.width;
+ event->configure.height = xevent->xconfigure.height;
+
+ if (!xevent->xconfigure.send_event &&
+ !xevent->xconfigure.override_redirect &&
+ !GDK_WINDOW_DESTROYED (window))
+ {
+ gint tx = 0;
+ gint ty = 0;
+ Window child_window = 0;
+
+ gdk_error_trap_push ();
+ if (XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
+ GDK_DRAWABLE_XID (window),
+ screen_macosx->xroot_window,
+ 0, 0,
+ &tx, &ty,
+ &child_window))
+ {
+ event->configure.x = tx;
+ event->configure.y = ty;
+ }
+ gdk_error_trap_pop ();
+ }
+ else
+ {
+ event->configure.x = xevent->xconfigure.x;
+ event->configure.y = xevent->xconfigure.y;
+ }
+ window_private->x = event->configure.x;
+ window_private->y = event->configure.y;
+ window_impl->width = xevent->xconfigure.width;
+ window_impl->height = xevent->xconfigure.height;
+ if (window_private->resize_count >= 1)
+ {
+ window_private->resize_count -= 1;
+
+ if (window_private->resize_count == 0)
+ _gdk_moveresize_configure_done (display, window);
+ }
+ }
+ break;
+
+ case PropertyNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("property notify:\twindow: %ld, atom(%ld): %s%s%s",
+ xevent->xproperty.window,
+ xevent->xproperty.atom,
+ "\"",
+ gdk_macosx_get_xatom_name_for_display (display, xevent->xproperty.atom),
+ "\""));
+
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* We compare with the serial of the last time we mapped the
+ * window to avoid refetching properties that we set ourselves
+ */
+ if (toplevel &&
+ xevent->xproperty.serial >= toplevel->map_serial)
+ {
+ if (xevent->xproperty.atom == gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_STATE"))
+ gdk_check_wm_state_changed (window);
+
+ if (xevent->xproperty.atom == gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
+ gdk_check_wm_desktop_changed (window);
+ }
+
+ if (window_private->event_mask & GDK_PROPERTY_CHANGE_MASK)
+ {
+ event->property.type = GDK_PROPERTY_NOTIFY;
+ event->property.window = window;
+ event->property.atom = gdk_macosx_xatom_to_atom_for_display (display, xevent->xproperty.atom);
+ event->property.time = xevent->xproperty.time;
+ event->property.state = xevent->xproperty.state;
+ }
+ else
+ return_val = FALSE;
+
+ break;
+
+ case SelectionClear:
+ GDK_NOTE (EVENTS,
+ g_message ("selection clear:\twindow: %ld",
+ xevent->xproperty.window));
+
+ if (_gdk_selection_filter_clear_event (&xevent->xselectionclear))
+ {
+ event->selection.type = GDK_SELECTION_CLEAR;
+ event->selection.window = window;
+ event->selection.selection = gdk_macosx_xatom_to_atom_for_display (display, xevent->xselectionclear.selection);
+ event->selection.time = xevent->xselectionclear.time;
+ }
+ else
+ return_val = FALSE;
+
+ break;
+
+ case SelectionRequest:
+ GDK_NOTE (EVENTS,
+ g_message ("selection request:\twindow: %ld",
+ xevent->xproperty.window));
+
+ event->selection.type = GDK_SELECTION_REQUEST;
+ event->selection.window = window;
+ event->selection.selection = gdk_macosx_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection);
+ event->selection.target = gdk_macosx_xatom_to_atom_for_display (display, xevent->xselectionrequest.target);
+ event->selection.property = gdk_macosx_xatom_to_atom_for_display (display, xevent->xselectionrequest.property);
+ event->selection.requestor = xevent->xselectionrequest.requestor;
+ event->selection.time = xevent->xselectionrequest.time;
+
+ break;
+
+ case SelectionNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("selection notify:\twindow: %ld",
+ xevent->xproperty.window));
+
+
+ event->selection.type = GDK_SELECTION_NOTIFY;
+ event->selection.window = window;
+ event->selection.selection = gdk_macosx_xatom_to_atom_for_display (display, xevent->xselection.selection);
+ event->selection.target = gdk_macosx_xatom_to_atom_for_display (display, xevent->xselection.target);
+ event->selection.property = gdk_macosx_xatom_to_atom_for_display (display, xevent->xselection.property);
+ event->selection.time = xevent->xselection.time;
+
+ break;
+
+ case ColormapNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("colormap notify:\twindow: %ld",
+ xevent->xcolormap.window));
+
+ /* Not currently handled */
+ return_val = FALSE;
+ break;
+
+ case ClientMessage:
+ {
+ GList *tmp_list;
+ GdkFilterReturn result = GDK_FILTER_CONTINUE;
+ GdkAtom message_type = gdk_macosx_xatom_to_atom_for_display (display, xevent->xclient.message_type);
+
+ GDK_NOTE (EVENTS,
+ g_message ("client message:\twindow: %ld",
+ xevent->xclient.window));
+
+ tmp_list = display_macosx->client_filters;
+ while (tmp_list)
+ {
+ GdkClientFilter *filter = tmp_list->data;
+ tmp_list = tmp_list->next;
+
+ if (filter->type == message_type)
+ {
+ result = (*filter->function) (xevent, event, filter->data);
+ if (result != GDK_FILTER_CONTINUE)
+ break;
+ }
+ }
+
+ switch (result)
+ {
+ case GDK_FILTER_REMOVE:
+ return_val = FALSE;
+ break;
+ case GDK_FILTER_TRANSLATE:
+ return_val = TRUE;
+ break;
+ case GDK_FILTER_CONTINUE:
+ /* Send unknown ClientMessage's on to Gtk for it to use */
+ if (window_private == NULL)
+ {
+ return_val = FALSE;
+ }
+ else
+ {
+ event->client.type = GDK_CLIENT_EVENT;
+ event->client.window = window;
+ event->client.message_type = message_type;
+ event->client.data_format = xevent->xclient.format;
+ memcpy(&event->client.data, &xevent->xclient.data,
+ sizeof(event->client.data));
+ }
+ break;
+ }
+ }
+
+ break;
+
+ case MappingNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("mapping notify"));
+
+ /* Let XLib know that there is a new keyboard mapping.
+ */
+ XRefreshKeyboardMapping (&xevent->xmapping);
+ _gdk_keymap_keys_changed (display);
+ return_val = FALSE;
+ break;
+
+ default:
+#ifdef HAVE_XKB
+ if (xevent->type == display_macosx->xkb_event_type)
+ {
+ XkbEvent *xkb_event = (XkbEvent *)xevent;
+
+ switch (xkb_event->any.xkb_type)
+ {
+ case XkbNewKeyboardNotify:
+ case XkbMapNotify:
+ _gdk_keymap_keys_changed (display);
+
+ return_val = FALSE;
+ break;
+
+ case XkbStateNotify:
+ _gdk_keymap_state_changed (display);
+ break;
+ }
+ }
+ else
+#endif
+#ifdef HAVE_XFIXES
+ if (xevent->type - display_macosx->xfixes_event_base == XFixesSelectionNotify)
+ {
+ XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
+ event->owner_change.type = GDK_OWNER_CHANGE;
+ event->owner_change.window = window;
+ event->owner_change.owner = selection_notify->owner;
+ event->owner_change.reason = selection_notify->subtype;
+ event->owner_change.selection =
+ gdk_macosx_xatom_to_atom_for_display (display,
+ selection_notify->selection);
+ event->owner_change.time = selection_notify->timestamp;
+ event->owner_change.selection_time = selection_notify->selection_timestamp;
+
+ return_val = TRUE;
+ }
+ else
+#endif
+ {
+ /* something else - (e.g., a Xinput event) */
+
+ if (window_private &&
+ !GDK_WINDOW_DESTROYED (window_private) &&
+ (window_private->extension_events != 0))
+ return_val = _gdk_input_other_event(event, xevent, window);
+ else
+ return_val = FALSE;
+
+ break;
+ }
+ }
+
+ done:
+ if (return_val)
+ {
+ if (event->any.window)
+ g_object_ref (event->any.window);
+ if (((event->any.type == GDK_ENTER_NOTIFY) ||
+ (event->any.type == GDK_LEAVE_NOTIFY)) &&
+ (event->crossing.subwindow != NULL))
+ g_object_ref (event->crossing.subwindow);
+ }
+ else
+ {
+ /* Mark this event as having no resources to be freed */
+ event->any.window = NULL;
+ event->any.type = GDK_NOTHING;
+ }
+
+ if (window)
+ g_object_unref (window);
+
+ return return_val;
+}
+
+static GdkFilterReturn
+gdk_wm_protocols_filter (GdkXEvent *xev,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent *xevent = (XEvent *)xev;
+ GdkWindow *win = event->any.window;
+ GdkDisplay *display;
+ Atom atom;
+
+ if (!win)
+ return GDK_FILTER_REMOVE;
+
+ display = GDK_WINDOW_DISPLAY (win);
+ atom = (Atom)xevent->xclient.data.l[0];
+
+ if (atom == gdk_macosx_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
+ {
+ /* The delete window request specifies a window
+ * to delete. We don't actually destroy the
+ * window because "it is only a request". (The
+ * window might contain vital data that the
+ * program does not want destroyed). Instead
+ * the event is passed along to the program,
+ * which should then destroy the window.
+ */
+ GDK_NOTE (EVENTS,
+ g_message ("delete window:\t\twindow: %ld",
+ xevent->xclient.window));
+
+ event->any.type = GDK_DELETE;
+
+ gdk_macosx_window_set_user_time (win, xevent->xclient.data.l[1]);
+
+ return GDK_FILTER_TRANSLATE;
+ }
+ else if (atom == gdk_macosx_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
+ {
+ GdkToplevelMacOSX *toplevel = _gdk_macosx_window_get_toplevel (event->any.window);
+ GdkWindowObject *private = (GdkWindowObject *)win;
+
+ /* There is no way of knowing reliably whether we are viewable;
+ * _gdk_macosx_set_input_focus_safe() traps errors asynchronously.
+ */
+ if (toplevel && private->accept_focus)
+ _gdk_macosx_set_input_focus_safe (display, toplevel->focus_window,
+ RevertToParent,
+ xevent->xclient.data.l[1]);
+
+ return GDK_FILTER_REMOVE;
+ }
+ else if (atom == gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
+ !_gdk_macosx_display_is_root_window (display,
+ xevent->xclient.window))
+ {
+ XEvent xev = *xevent;
+
+ xev.xclient.window = GDK_WINDOW_XROOTWIN (win);
+ XSendEvent (GDK_WINDOW_XDISPLAY (win),
+ xev.xclient.window,
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+
+ return GDK_FILTER_REMOVE;
+ }
+ else if (atom == gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") &&
+ GDK_DISPLAY_MacOSX (display)->use_sync)
+ {
+ GdkToplevelMacOSX *toplevel = _gdk_macosx_window_get_toplevel (event->any.window);
+ if (toplevel)
+ {
+#ifdef HAVE_XSYNC
+ XSyncIntsToValue (&toplevel->pending_counter_value,
+ xevent->xclient.data.l[2],
+ xevent->xclient.data.l[3]);
+#endif
+ }
+ return GDK_FILTER_REMOVE;
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+#endif
+
+void
+_gdk_events_queue (GdkDisplay *display)
+{
+ while (!_gdk_event_queue_find_first(display))
+ {
+ /* FIXME */
+ }
+}
+
+
+#if 0
+static gboolean
+gdk_event_prepare (GSource *source,
+ gint *timeout)
+{
+ GdkDisplay *display = ((GdkDisplaySource*)source)->display;
+ gboolean retval;
+
+ GDK_THREADS_ENTER ();
+
+ *timeout = -1;
+ retval = (_gdk_event_queue_find_first (display) != NULL ||
+ gdk_check_xpending (display));
+
+ GDK_THREADS_LEAVE ();
+
+ return retval;
+}
+
+static gboolean
+gdk_event_check (GSource *source)
+{
+ GdkDisplaySource *display_source = (GdkDisplaySource*)source;
+ gboolean retval;
+
+ GDK_THREADS_ENTER ();
+
+ if (display_source->event_poll_fd.revents & G_IO_IN)
+ retval = (_gdk_event_queue_find_first (display_source->display) != NULL ||
+ gdk_check_xpending (display_source->display));
+ else
+ retval = FALSE;
+
+ GDK_THREADS_LEAVE ();
+
+ return retval;
+}
+
+static gboolean
+gdk_event_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ GdkDisplay *display = ((GdkDisplaySource*)source)->display;
+ GdkEvent *event;
+
+ GDK_THREADS_ENTER ();
+
+ _gdk_events_queue (display);
+ event = _gdk_event_unqueue (display);
+
+ if (event)
+ {
+ if (_gdk_event_func)
+ (*_gdk_event_func) (event, _gdk_event_data);
+
+ gdk_event_free (event);
+ }
+
+ GDK_THREADS_LEAVE ();
+
+ return TRUE;
+}
+#endif
+
+/**
+ * gdk_event_send_client_message_for_display:
+ * @display: the #GdkDisplay for the window where the message is to be sent.
+ * @event: the #GdkEvent to send, which should be a #GdkEventClient.
+ * @winid: the window to send the client message to.
+ *
+ * On X11, sends an X ClientMessage event to a given window. On
+ * Windows, sends a message registered with the name
+ * GDK_WIN32_CLIENT_MESSAGE.
+ *
+ * This could be used for communicating between different
+ * applications, though the amount of data is limited to 20 bytes on
+ * X11, and to just four bytes on Windows.
+ *
+ * Returns: non-zero on success.
+ *
+ * Since: 2.2
+ */
+gboolean
+gdk_event_send_client_message_for_display (GdkDisplay *display,
+ GdkEvent *event,
+ GdkNativeWindow winid)
+{
+ NSEvent *sev;
+
+ g_return_if_fail (event != NULL);
+
+ sev = [NSEvent otherEventWithType:NSApplicationDefined
+ location:NSMakePoint(0,0)
+ modifierFlags:0
+ timestamp:0
+ windowNumber:[(NSWindow*)winid windowNumber]
+ context:nil
+ subtype:GDK_NS_CLIENT_MESSAGE
+ data1:event->client.data.l[0]
+ data2:event->client.data.l[1]];
+
+
+ [(NSWindow*)winid sendEvent:sev];
+
+ return TRUE;
+}
+
+
+#if 0
+/* Sends a ClientMessage to all toplevel client windows */
+static gboolean
+gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
+ XEvent *xev,
+ guint32 xid,
+ guint level)
+{
+ Atom type = None;
+ int format;
+ unsigned long nitems, after;
+ unsigned char *data;
+ Window *ret_children, ret_root, ret_parent;
+ unsigned int ret_nchildren;
+ gboolean send = FALSE;
+ gboolean found = FALSE;
+ gboolean result = FALSE;
+ int i;
+
+ gdk_error_trap_push ();
+
+ if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid,
+ gdk_macosx_get_xatom_by_name_for_display (display, "WM_STATE"),
+ 0, 0, False, AnyPropertyType,
+ &type, &format, &nitems, &after, &data) != Success)
+ goto out;
+
+ if (type)
+ {
+ send = TRUE;
+ XFree (data);
+ }
+ else
+ {
+ /* OK, we're all set, now let's find some windows to send this to */
+ if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xid,
+ &ret_root, &ret_parent,
+ &ret_children, &ret_nchildren))
+ goto out;
+
+ for(i = 0; i < ret_nchildren; i++)
+ if (gdk_event_send_client_message_to_all_recurse (display, xev, ret_children[i], level + 1))
+ found = TRUE;
+
+ XFree (ret_children);
+ }
+
+ if (send || (!found && (level == 1)))
+ {
+ xev->xclient.window = xid;
+ _gdk_send_xevent (display, xid, False, NoEventMask, xev);
+ }
+
+ result = send || found;
+
+ out:
+ gdk_error_trap_pop ();
+
+ return result;
+}
+#endif
+
+/**
+ * gdk_screen_broadcast_client_message:
+ * @screen: the #GdkScreen where the event will be broadcasted.
+ * @event: the #GdkEvent.
+ *
+ * On MacOSX, sends an X ClientMessage event to all toplevel windows on
+ * @screen.
+ *
+ * Toplevel windows are determined by checking for the WM_STATE property,
+ * as described in the Inter-Client Communication Conventions Manual (ICCCM).
+ * If no windows are found with the WM_STATE property set, the message is
+ * sent to all children of the root window.
+ *
+ * On Windows, broadcasts a message registered with the name
+ * GDK_WIN32_CLIENT_MESSAGE to all top-level windows. The amount of
+ * data is limited to one long, i.e. four bytes.
+ *
+ * Since: 2.2
+ */
+
+void
+gdk_screen_broadcast_client_message (GdkScreen *screen,
+ GdkEvent *event)
+{
+ NSEvent *sev;
+ GdkWindow *root_window;
+
+ g_return_if_fail (event != NULL);
+
+ root_window = gdk_screen_get_root_window (screen);
+
+ sev = [NSEvent otherEventWithType:NSApplicationDefined
+ location:NSMakePoint(0,0)
+ modifierFlags:0
+ timestamp:0
+ windowNumber:0
+ context:nil
+ subtype:GDK_NS_CLIENT_MESSAGE
+ data1:event->client.data.l[0]
+ data2:event->client.data.l[1]];
+
+
+ // FIXME
+
+// gdk_event_send_client_message_to_all_recurse (gdk_screen_get_display (screen),
+// &sev,
+// GDK_WINDOW_XID (root_window),
+// 0);
+}
+
+/*
+ *--------------------------------------------------------------
+ * gdk_flush
+ *
+ * Flushes the Xlib output buffer and then waits
+ * until all requests have been received and processed
+ * by the X server. The only real use for this function
+ * is in dealing with XShm.
+ *
+ * Arguments:
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+gdk_flush (void)
+{
+ /* do nothing on MacOS X */
+}
+
+
+
+#if 0
+static Bool
+timestamp_predicate (Display *display,
+ XEvent *xevent,
+ XPointer arg)
+{
+ Window xwindow = GPOINTER_TO_UINT (arg);
+ GdkDisplay *gdk_display = gdk_macosx_lookup_xdisplay (display);
+
+ if (xevent->type == PropertyNotify &&
+ xevent->xproperty.window == xwindow &&
+ xevent->xproperty.atom == gdk_macosx_get_xatom_by_name_for_display (gdk_display,
+ "GDK_TIMESTAMP_PROP"))
+ return True;
+
+ return False;
+}
+
+/**
+ * gdk_macosx_get_server_time:
+ * @window: a #GdkWindow, used for communication with the server.
+ * The window must have GDK_PROPERTY_CHANGE_MASK in its
+ * events mask or a hang will result.
+ *
+ * Routine to get the current X server time stamp.
+ *
+ * Return value: the time stamp.
+ **/
+guint32
+gdk_macosx_get_server_time (GdkWindow *window)
+{
+ Display *xdisplay;
+ Window xwindow;
+ guchar c = 'a';
+ XEvent xevent;
+ Atom timestamp_prop_atom;
+
+ g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+ g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), 0);
+
+ xdisplay = GDK_WINDOW_XDISPLAY (window);
+ xwindow = GDK_WINDOW_XWINDOW (window);
+ timestamp_prop_atom =
+ gdk_macosx_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+ "GDK_TIMESTAMP_PROP");
+
+ XChangeProperty (xdisplay, xwindow, timestamp_prop_atom,
+ timestamp_prop_atom,
+ 8, PropModeReplace, &c, 1);
+
+ XIfEvent (xdisplay, &xevent,
+ timestamp_predicate, GUINT_TO_POINTER(xwindow));
+
+ return xevent.xproperty.time;
+}
+
+static void
+fetch_net_wm_check_window (GdkScreen *screen)
+{
+ GdkScreenMacOSX *screen_macosx;
+ GdkDisplay *display;
+ Atom type;
+ gint format;
+ gulong n_items;
+ gulong bytes_after;
+ guchar *data;
+ Window *xwindow;
+
+ /* This function is very slow on every call if you are not running a
+ * spec-supporting WM. For now not optimized, because it isn't in
+ * any critical code paths, but if you used it somewhere that had to
+ * be fast you want to avoid "GTK is slow with old WMs" complaints.
+ * Probably at that point the function should be changed to query
+ * _NET_SUPPORTING_WM_CHECK only once every 10 seconds or something.
+ */
+
+ screen_macosx = GDK_SCREEN_MacOSX (screen);
+ display = screen_macosx->display;
+
+ if (screen_macosx->wmspec_check_window != None)
+ return; /* already have it */
+
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_macosx->xroot_window,
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"),
+ 0, G_MAXLONG, False, XA_WINDOW, &type, &format,
+ &n_items, &bytes_after, &data);
+
+ if (type != XA_WINDOW)
+ return;
+
+ xwindow = (Window *)data;
+
+ gdk_error_trap_push ();
+
+ /* Find out if this WM goes away, so we can reset everything. */
+ XSelectInput (screen_macosx->xdisplay, *xwindow, StructureNotifyMask);
+ gdk_display_sync (display);
+
+ if (gdk_error_trap_pop () == Success)
+ {
+ screen_macosx->wmspec_check_window = *xwindow;
+ XFree (xwindow);
+
+ screen_macosx->need_refetch_net_supported = TRUE;
+ screen_macosx->need_refetch_wm_name = TRUE;
+
+ /* Careful, reentrancy */
+ _gdk_macosx_screen_window_manager_changed (GDK_SCREEN (screen_macosx));
+ }
+}
+
+/**
+ * gdk_macosx_screen_get_window_manager_name:
+ * @screen: a #GdkScreen
+ *
+ * Returns the name of the window manager for @screen.
+ *
+ * Return value: the name of the window manager screen @screen, or
+ * "unknown" if the window manager is unknown. The string is owned by GDK
+ * and should not be freed.
+ *
+ * Since: 2.2
+ **/
+const char*
+gdk_macosx_screen_get_window_manager_name (GdkScreen *screen)
+{
+ GdkScreenMacOSX *screen_macosx;
+
+ screen_macosx = GDK_SCREEN_MacOSX (screen);
+
+ fetch_net_wm_check_window (screen);
+
+ if (screen_macosx->need_refetch_wm_name)
+ {
+ /* Get the name of the window manager */
+ screen_macosx->need_refetch_wm_name = FALSE;
+
+ g_free (screen_macosx->window_manager_name);
+ screen_macosx->window_manager_name = g_strdup ("unknown");
+
+ if (screen_macosx->wmspec_check_window != None)
+ {
+ Atom type;
+ gint format;
+ gulong n_items;
+ gulong bytes_after;
+ guchar *name;
+
+ name = NULL;
+
+ gdk_error_trap_push ();
+
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (screen_macosx->display),
+ screen_macosx->wmspec_check_window,
+ gdk_macosx_get_xatom_by_name_for_display (screen_macosx->display,
+ "_NET_WM_NAME"),
+ 0, G_MAXLONG, False,
+ gdk_macosx_get_xatom_by_name_for_display (screen_macosx->display,
+ "UTF8_STRING"),
+ &type, &format,
+ &n_items, &bytes_after,
+ (guchar **)&name);
+
+ gdk_display_sync (screen_macosx->display);
+
+ gdk_error_trap_pop ();
+
+ if (name != NULL)
+ {
+ g_free (screen_macosx->window_manager_name);
+ screen_macosx->window_manager_name = g_strdup (name);
+ XFree (name);
+ }
+ }
+ }
+
+ return GDK_SCREEN_MacOSX (screen)->window_manager_name;
+}
+#endif
+
+/**
+ * gdk_screen_get_setting:
+ * @screen: the #GdkScreen where the setting is located
+ * @name: the name of the setting
+ * @value: location to store the value of the setting
+ *
+ * Retrieves a desktop-wide setting such as double-click time
+ * for the #GdkScreen @screen.
+ *
+ * FIXME needs a list of valid settings here, or a link to
+ * more information.
+ *
+ * Returns: %TRUE if the setting existed and a value was stored
+ * in @value, %FALSE otherwise.
+ *
+ * Since: 2.2
+ **/
+gboolean
+gdk_screen_get_setting (GdkScreen *screen,
+ const gchar *name,
+ GValue *value)
+{
+
+ if (strcmp ("gtk-theme-name", name) == 0)
+ {
+ g_value_set_string (value, "aqua");
+ return TRUE;
+ }
+#if 0
+ /*stolen from Win32*/
+ else if (strcmp ("gtk-double-click-time", name) == 0)
+ {
+ gint i = GetDoubleClickTime ();
+ GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
+ g_value_set_int (value, i);
+ return TRUE;
+ }
+ else if (strcmp ("gtk-double-click-distance", name) == 0)
+ {
+ gint i = MAX(GetSystemMetrics (SM_CXDOUBLECLK), GetSystemMetrics (SM_CYDOUBLECLK));
+ GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
+ g_value_set_int (value, i);
+ return TRUE;
+ }
+ else if (strcmp ("gtk-dnd-drag-threshold", name) == 0)
+ {
+ gint i = MAX(GetSystemMetrics (SM_CXDRAG), GetSystemMetrics (SM_CYDRAG));
+ GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %d\n", name, i));
+ g_value_set_int (value, i);
+ return TRUE;
+ }
+ else if (strcmp ("gtk-split-cursor", name) == 0)
+ {
+ GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : FALSE\n", name));
+ g_value_set_boolean (value, FALSE);
+ return TRUE;
+ }
+#endif
+ else {
+ GDK_NOTE(MSIC, g_print("Requested setting %s that is unknown\n", name));
+ }
+ return FALSE;
+}
+
+#if 0
+static GdkFilterReturn
+gdk_xsettings_client_event_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ GdkScreenMacOSX *screen = data;
+
+ if (xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent))
+ return GDK_FILTER_REMOVE;
+ else
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+gdk_xsettings_watch_cb (Window window,
+ Bool is_start,
+ long mask,
+ void *cb_data)
+{
+ GdkWindow *gdkwin;
+ GdkScreen *screen = cb_data;
+
+ gdkwin = gdk_window_lookup_for_display (gdk_screen_get_display (screen), window);
+
+ if (is_start)
+ {
+ if (!gdkwin)
+ gdkwin = gdk_window_foreign_new_for_display (gdk_screen_get_display (screen), window);
+ else
+ g_object_ref (gdkwin);
+
+ gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
+ }
+ else
+ {
+ g_assert (gdkwin);
+ gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
+ g_object_unref (gdkwin);
+ }
+}
+
+
+#endif
diff --git a/gdk/macosx/gdkgc-macosx.m b/gdk/macosx/gdkgc-macosx.m
new file mode 100644
index 0000000000..f7744893e4
--- /dev/null
+++ b/gdk/macosx/gdkgc-macosx.m
@@ -0,0 +1,1306 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include <config.h>
+
+#include "gdkalias.h"
+#include "gdkgc.h"
+#include "gdkprivate-macosx.h"*/
+#include "gdkregion-generic.h"
+
+#include <string.h>
+
+typedef enum {
+ GDK_GC_DIRTY_CLIP = 1 << 0,
+ GDK_GC_DIRTY_TS = 1 << 1
+} GdkGCDirtyValues;
+
+#if 0
+
+static void gdk_macosx_gc_values_to_xvalues (GdkGCValues *values,
+ GdkGCValuesMask mask,
+ XGCValues *xvalues,
+ unsigned long *xvalues_mask);
+#endif
+
+static void gdk_macosx_gc_get_values (GdkGC *gc,
+ GdkGCValues *values);
+static void gdk_macosx_gc_set_values (GdkGC *gc,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask);
+static void gdk_macosx_gc_set_dashes (GdkGC *gc,
+ gint dash_offset,
+ gint8 dash_list[],
+ gint n);
+
+static void gdk_gc_macosx_class_init (GdkGCMacOSXClass *klass);
+static void gdk_gc_macosx_finalize (GObject *object);
+
+static gpointer parent_class = NULL;
+
+
+GType
+_gdk_gc_macosx_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkGCMacOSXClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_gc_macosx_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkGCMacOSX),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (GDK_TYPE_GC,
+ "GdkGCMacOSX",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+static void
+gdk_gc_macosx_class_init (GdkGCMacOSXClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GdkGCClass *gc_class = GDK_GC_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = gdk_gc_macosx_finalize;
+
+ gc_class->get_values = gdk_macosx_gc_get_values;
+ gc_class->set_values = gdk_macosx_gc_set_values;
+ gc_class->set_dashes = gdk_macosx_gc_set_dashes;
+}
+
+#if 0
+static void
+gdk_gc_macosx_finalize (GObject *object)
+{
+ GdkGCMacOSX *macosx_gc = GDK_GC_MacOSX (object);
+
+ if (macosx_gc->clip_region)
+ gdk_region_destroy (macosx_gc->clip_region);
+
+ if (macosx_gc->fg_picture != None)
+ XRenderFreePicture (GDK_GC_XDISPLAY (macosx_gc), macosx_gc->fg_picture);
+
+ if (macosx_gc->stipple)
+ g_object_unref (macosx_gc->stipple);
+ if (macosx_gc->tile)
+ g_object_unref (macosx_gc->tile);
+
+// XFreeGC (GDK_GC_XDISPLAY (macosx_gc), GDK_GC_XGC (macosx_gc));
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+#endif
+
+#if 0
+GdkGC *
+_gdk_macosx_gc_new (GdkDrawable *drawable,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask)
+{
+ GdkGC *gc;
+ GdkGCMacOSX *private;
+
+ XGCValues xvalues;
+ unsigned long xvalues_mask;
+
+ /* NOTICE that the drawable here has to be the impl drawable,
+ * not the publically-visible drawables.
+ */
+ g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_MACOSX (drawable), NULL);
+
+ gc = g_object_new (_gdk_gc_macosx_get_type (), NULL);
+ private = GDK_GC_MacOSX (gc);
+
+ private->dirty_mask = 0;
+ private->have_clip_mask = FALSE;
+ private->clip_region = NULL;
+
+ private->screen = GDK_DRAWABLE_IMPL_MacOSX (drawable)->screen;
+
+ private->depth = gdk_drawable_get_depth (drawable);
+
+ if (values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN))
+ {
+ values_mask &= ~(GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
+ private->dirty_mask |= GDK_GC_DIRTY_CLIP;
+ }
+
+ if (values_mask & (GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN))
+ {
+ values_mask &= ~(GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
+ private->dirty_mask |= GDK_GC_DIRTY_TS;
+ }
+
+ if (values_mask & GDK_GC_FOREGROUND)
+ private->fg_pixel = values->foreground.pixel;
+
+ if (values_mask & GDK_GC_BACKGROUND)
+ private->bg_pixel = values->background.pixel;
+
+ if (values_mask & GDK_GC_FILL)
+ private->fill = values->fill;
+
+ if (values_mask & GDK_GC_STIPPLE)
+ {
+ private->stipple = values->stipple;
+ if (private->stipple)
+ g_object_ref (private->stipple);
+ }
+
+ if (values_mask & GDK_GC_TILE)
+ {
+ private->tile = values->tile;
+ if (private->tile)
+ g_object_ref (private->tile);
+ }
+
+ if ((values_mask & GDK_GC_CLIP_MASK) && values->clip_mask)
+ private->have_clip_mask = TRUE;
+
+ xvalues.function = GXcopy;
+ xvalues.fill_style = FillSolid;
+ xvalues.arc_mode = ArcPieSlice;
+ xvalues.subwindow_mode = ClipByChildren;
+ xvalues.graphics_exposures = False;
+ xvalues_mask = GCFunction | GCFillStyle | GCArcMode | GCSubwindowMode | GCGraphicsExposures;
+
+ gdk_macosx_gc_values_to_xvalues (values, values_mask, &xvalues, &xvalues_mask);
+
+ private->xgc = XCreateGC (GDK_GC_XDISPLAY (gc),
+ GDK_DRAWABLE_IMPL_MacOSX (drawable)->xid,
+ xvalues_mask, &xvalues);
+
+ return gc;
+}
+
+GC
+_gdk_macosx_gc_flush (GdkGC *gc)
+{
+ Display *xdisplay = GDK_GC_XDISPLAY (gc);
+ GdkGCMacOSX *private = GDK_GC_MacOSX (gc);
+ GC xgc = private->xgc;
+
+ if (private->dirty_mask & GDK_GC_DIRTY_CLIP)
+ {
+ if (!private->clip_region)
+ XSetClipOrigin (xdisplay, xgc,
+ gc->clip_x_origin, gc->clip_y_origin);
+ else
+ {
+ XRectangle *rectangles;
+ gint n_rects;
+
+ _gdk_region_get_xrectangles (private->clip_region,
+ gc->clip_x_origin,
+ gc->clip_y_origin,
+ &rectangles,
+ &n_rects);
+
+ XSetClipRectangles (xdisplay, xgc, 0, 0,
+ rectangles,
+ n_rects, YXBanded);
+
+ g_free (rectangles);
+ }
+ }
+
+ if (private->dirty_mask & GDK_GC_DIRTY_TS)
+ {
+ XSetTSOrigin (xdisplay, xgc,
+ gc->ts_x_origin, gc->ts_y_origin);
+ }
+
+ private->dirty_mask = 0;
+ return xgc;
+}
+
+static void
+gdk_macosx_gc_get_values (GdkGC *gc,
+ GdkGCValues *values)
+{
+ XGCValues xvalues;
+
+ if (XGetGCValues (GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc),
+ GCForeground | GCBackground | GCFont |
+ GCFunction | GCTile | GCStipple | /* GCClipMask | */
+ GCSubwindowMode | GCGraphicsExposures |
+ GCTileStipXOrigin | GCTileStipYOrigin |
+ GCClipXOrigin | GCClipYOrigin |
+ GCLineWidth | GCLineStyle | GCCapStyle |
+ GCFillStyle | GCJoinStyle, &xvalues))
+ {
+ values->foreground.pixel = xvalues.foreground;
+ values->background.pixel = xvalues.background;
+ values->font = gdk_font_lookup_for_display (GDK_GC_DISPLAY (gc),
+ xvalues.font);
+
+ switch (xvalues.function)
+ {
+ case GXcopy:
+ values->function = GDK_COPY;
+ break;
+ case GXinvert:
+ values->function = GDK_INVERT;
+ break;
+ case GXxor:
+ values->function = GDK_XOR;
+ break;
+ case GXclear:
+ values->function = GDK_CLEAR;
+ break;
+ case GXand:
+ values->function = GDK_AND;
+ break;
+ case GXandReverse:
+ values->function = GDK_AND_REVERSE;
+ break;
+ case GXandInverted:
+ values->function = GDK_AND_INVERT;
+ break;
+ case GXnoop:
+ values->function = GDK_NOOP;
+ break;
+ case GXor:
+ values->function = GDK_OR;
+ break;
+ case GXequiv:
+ values->function = GDK_EQUIV;
+ break;
+ case GXorReverse:
+ values->function = GDK_OR_REVERSE;
+ break;
+ case GXcopyInverted:
+ values->function =GDK_COPY_INVERT;
+ break;
+ case GXorInverted:
+ values->function = GDK_OR_INVERT;
+ break;
+ case GXnand:
+ values->function = GDK_NAND;
+ break;
+ case GXset:
+ values->function = GDK_SET;
+ break;
+ case GXnor:
+ values->function = GDK_NOR;
+ break;
+ }
+
+ switch (xvalues.fill_style)
+ {
+ case FillSolid:
+ values->fill = GDK_SOLID;
+ break;
+ case FillTiled:
+ values->fill = GDK_TILED;
+ break;
+ case FillStippled:
+ values->fill = GDK_STIPPLED;
+ break;
+ case FillOpaqueStippled:
+ values->fill = GDK_OPAQUE_STIPPLED;
+ break;
+ }
+
+ values->tile = gdk_pixmap_lookup_for_display (GDK_GC_DISPLAY (gc),
+ xvalues.tile);
+ values->stipple = gdk_pixmap_lookup_for_display (GDK_GC_DISPLAY (gc),
+ xvalues.stipple);
+ values->clip_mask = NULL;
+ values->subwindow_mode = xvalues.subwindow_mode;
+ values->ts_x_origin = xvalues.ts_x_origin;
+ values->ts_y_origin = xvalues.ts_y_origin;
+ values->clip_x_origin = xvalues.clip_x_origin;
+ values->clip_y_origin = xvalues.clip_y_origin;
+ values->graphics_exposures = xvalues.graphics_exposures;
+ values->line_width = xvalues.line_width;
+
+ switch (xvalues.line_style)
+ {
+ case LineSolid:
+ values->line_style = GDK_LINE_SOLID;
+ break;
+ case LineOnOffDash:
+ values->line_style = GDK_LINE_ON_OFF_DASH;
+ break;
+ case LineDoubleDash:
+ values->line_style = GDK_LINE_DOUBLE_DASH;
+ break;
+ }
+
+ switch (xvalues.cap_style)
+ {
+ case CapNotLast:
+ values->cap_style = GDK_CAP_NOT_LAST;
+ break;
+ case CapButt:
+ values->cap_style = GDK_CAP_BUTT;
+ break;
+ case CapRound:
+ values->cap_style = GDK_CAP_ROUND;
+ break;
+ case CapProjecting:
+ values->cap_style = GDK_CAP_PROJECTING;
+ break;
+ }
+
+ switch (xvalues.join_style)
+ {
+ case JoinMiter:
+ values->join_style = GDK_JOIN_MITER;
+ break;
+ case JoinRound:
+ values->join_style = GDK_JOIN_ROUND;
+ break;
+ case JoinBevel:
+ values->join_style = GDK_JOIN_BEVEL;
+ break;
+ }
+ }
+ else
+ {
+ memset (values, 0, sizeof (GdkGCValues));
+ }
+}
+
+static void
+clear_fg_picture (GdkGC *gc)
+{
+ GdkGCMacOSX *macosx_gc = GDK_GC_MacOSX (gc);
+
+ if (macosx_gc->fg_picture != None)
+ {
+ XRenderFreePicture (GDK_GC_XDISPLAY (macosx_gc), macosx_gc->fg_picture);
+ macosx_gc->fg_picture = None;
+ }
+}
+
+static void
+gdk_macosx_gc_set_values (GdkGC *gc,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask)
+{
+ GdkGCMacOSX *macosx_gc;
+ XGCValues xvalues;
+ unsigned long xvalues_mask = 0;
+
+ macosx_gc = GDK_GC_MacOSX (gc);
+
+ if (values_mask & (GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN))
+ {
+ values_mask &= ~(GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN);
+ macosx_gc->dirty_mask |= GDK_GC_DIRTY_CLIP;
+ }
+
+ if (values_mask & (GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN))
+ {
+ values_mask &= ~(GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
+ macosx_gc->dirty_mask |= GDK_GC_DIRTY_TS;
+ }
+
+ if (values_mask & GDK_GC_CLIP_MASK)
+ {
+ if (macosx_gc->clip_region)
+ {
+ gdk_region_destroy (macosx_gc->clip_region);
+ macosx_gc->clip_region = NULL;
+ }
+
+ macosx_gc->have_clip_mask = values->clip_mask != NULL;
+ }
+
+ if (values_mask & GDK_GC_FOREGROUND)
+ macosx_gc->fg_pixel = values->foreground.pixel;
+
+ if (values_mask & GDK_GC_BACKGROUND)
+ {
+ if (macosx_gc->bg_pixel != values->background.pixel)
+ {
+ macosx_gc->bg_pixel = values->background.pixel;
+ if (macosx_gc->fill == GDK_OPAQUE_STIPPLED)
+ clear_fg_picture (gc);
+ }
+ }
+
+ if (values_mask & GDK_GC_FILL)
+ {
+ if (macosx_gc->fill != values->fill)
+ {
+ clear_fg_picture (gc);
+ macosx_gc->fill = values->fill;
+ }
+ }
+
+ if (values_mask & GDK_GC_STIPPLE)
+ {
+ if (macosx_gc->stipple != values->stipple)
+ {
+ if (macosx_gc->fill == GDK_STIPPLED || macosx_gc->fill == GDK_OPAQUE_STIPPLED)
+ clear_fg_picture (gc);
+ if (macosx_gc->stipple)
+ g_object_unref (macosx_gc->stipple);
+ macosx_gc->stipple = values->stipple;
+ if (macosx_gc->stipple)
+ g_object_ref (macosx_gc->stipple);
+ }
+ }
+
+ if (values_mask & GDK_GC_TILE)
+ {
+ if (macosx_gc->tile != values->tile)
+ {
+ if (macosx_gc->fill == GDK_TILED)
+ clear_fg_picture (gc);
+ if (macosx_gc->tile)
+ g_object_unref (macosx_gc->tile);
+ macosx_gc->tile = values->tile;
+ if (macosx_gc->tile)
+ g_object_ref (macosx_gc->tile);
+ }
+ }
+
+ gdk_macosx_gc_values_to_xvalues (values, values_mask, &xvalues, &xvalues_mask);
+
+ XChangeGC (GDK_GC_XDISPLAY (gc),
+ GDK_GC_XGC (gc),
+ xvalues_mask,
+ &xvalues);
+}
+
+static void
+gdk_macosx_gc_set_dashes (GdkGC *gc,
+ gint dash_offset,
+ gint8 dash_list[],
+ gint n)
+{
+ g_return_if_fail (GDK_IS_GC (gc));
+ g_return_if_fail (dash_list != NULL);
+
+ XSetDashes (GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc),
+ dash_offset, dash_list, n);
+}
+
+static void
+gdk_macosx_gc_values_to_xvalues (GdkGCValues *values,
+ GdkGCValuesMask mask,
+ XGCValues *xvalues,
+ unsigned long *xvalues_mask)
+{
+ /* Optimization for the common case (gdk_gc_new()) */
+ if (values == NULL || mask == 0)
+ return;
+
+ if (mask & GDK_GC_FOREGROUND)
+ {
+ xvalues->foreground = values->foreground.pixel;
+ *xvalues_mask |= GCForeground;
+ }
+ if (mask & GDK_GC_BACKGROUND)
+ {
+ xvalues->background = values->background.pixel;
+ *xvalues_mask |= GCBackground;
+ }
+ if ((mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT))
+ {
+ xvalues->font = ((XFontStruct *) (GDK_FONT_XFONT (values->font)))->fid;
+ *xvalues_mask |= GCFont;
+ }
+ if (mask & GDK_GC_FUNCTION)
+ {
+ switch (values->function)
+ {
+ case GDK_COPY:
+ xvalues->function = GXcopy;
+ break;
+ case GDK_INVERT:
+ xvalues->function = GXinvert;
+ break;
+ case GDK_XOR:
+ xvalues->function = GXxor;
+ break;
+ case GDK_CLEAR:
+ xvalues->function = GXclear;
+ break;
+ case GDK_AND:
+ xvalues->function = GXand;
+ break;
+ case GDK_AND_REVERSE:
+ xvalues->function = GXandReverse;
+ break;
+ case GDK_AND_INVERT:
+ xvalues->function = GXandInverted;
+ break;
+ case GDK_NOOP:
+ xvalues->function = GXnoop;
+ break;
+ case GDK_OR:
+ xvalues->function = GXor;
+ break;
+ case GDK_EQUIV:
+ xvalues->function = GXequiv;
+ break;
+ case GDK_OR_REVERSE:
+ xvalues->function = GXorReverse;
+ break;
+ case GDK_COPY_INVERT:
+ xvalues->function = GXcopyInverted;
+ break;
+ case GDK_OR_INVERT:
+ xvalues->function = GXorInverted;
+ break;
+ case GDK_NAND:
+ xvalues->function = GXnand;
+ break;
+ case GDK_SET:
+ xvalues->function = GXset;
+ break;
+ case GDK_NOR:
+ xvalues->function = GXnor;
+ break;
+ }
+ *xvalues_mask |= GCFunction;
+ }
+ if (mask & GDK_GC_FILL)
+ {
+ switch (values->fill)
+ {
+ case GDK_SOLID:
+ xvalues->fill_style = FillSolid;
+ break;
+ case GDK_TILED:
+ xvalues->fill_style = FillTiled;
+ break;
+ case GDK_STIPPLED:
+ xvalues->fill_style = FillStippled;
+ break;
+ case GDK_OPAQUE_STIPPLED:
+ xvalues->fill_style = FillOpaqueStippled;
+ break;
+ }
+ *xvalues_mask |= GCFillStyle;
+ }
+ if (mask & GDK_GC_TILE)
+ {
+ if (values->tile)
+ xvalues->tile = GDK_DRAWABLE_XID (values->tile);
+ else
+ xvalues->tile = None;
+
+ *xvalues_mask |= GCTile;
+ }
+ if (mask & GDK_GC_STIPPLE)
+ {
+ if (values->stipple)
+ xvalues->stipple = GDK_DRAWABLE_XID (values->stipple);
+ else
+ xvalues->stipple = None;
+
+ *xvalues_mask |= GCStipple;
+ }
+ if (mask & GDK_GC_CLIP_MASK)
+ {
+ if (values->clip_mask)
+ xvalues->clip_mask = GDK_DRAWABLE_XID (values->clip_mask);
+ else
+ xvalues->clip_mask = None;
+
+ *xvalues_mask |= GCClipMask;
+
+ }
+ if (mask & GDK_GC_SUBWINDOW)
+ {
+ xvalues->subwindow_mode = values->subwindow_mode;
+ *xvalues_mask |= GCSubwindowMode;
+ }
+ if (mask & GDK_GC_TS_X_ORIGIN)
+ {
+ xvalues->ts_x_origin = values->ts_x_origin;
+ *xvalues_mask |= GCTileStipXOrigin;
+ }
+ if (mask & GDK_GC_TS_Y_ORIGIN)
+ {
+ xvalues->ts_y_origin = values->ts_y_origin;
+ *xvalues_mask |= GCTileStipYOrigin;
+ }
+ if (mask & GDK_GC_CLIP_X_ORIGIN)
+ {
+ xvalues->clip_x_origin = values->clip_x_origin;
+ *xvalues_mask |= GCClipXOrigin;
+ }
+ if (mask & GDK_GC_CLIP_Y_ORIGIN)
+ {
+ xvalues->clip_y_origin = values->clip_y_origin;
+ *xvalues_mask |= GCClipYOrigin;
+ }
+
+ if (mask & GDK_GC_EXPOSURES)
+ {
+ xvalues->graphics_exposures = values->graphics_exposures;
+ *xvalues_mask |= GCGraphicsExposures;
+ }
+
+ if (mask & GDK_GC_LINE_WIDTH)
+ {
+ xvalues->line_width = values->line_width;
+ *xvalues_mask |= GCLineWidth;
+ }
+ if (mask & GDK_GC_LINE_STYLE)
+ {
+ switch (values->line_style)
+ {
+ case GDK_LINE_SOLID:
+ xvalues->line_style = LineSolid;
+ break;
+ case GDK_LINE_ON_OFF_DASH:
+ xvalues->line_style = LineOnOffDash;
+ break;
+ case GDK_LINE_DOUBLE_DASH:
+ xvalues->line_style = LineDoubleDash;
+ break;
+ }
+ *xvalues_mask |= GCLineStyle;
+ }
+ if (mask & GDK_GC_CAP_STYLE)
+ {
+ switch (values->cap_style)
+ {
+ case GDK_CAP_NOT_LAST:
+ xvalues->cap_style = CapNotLast;
+ break;
+ case GDK_CAP_BUTT:
+ xvalues->cap_style = CapButt;
+ break;
+ case GDK_CAP_ROUND:
+ xvalues->cap_style = CapRound;
+ break;
+ case GDK_CAP_PROJECTING:
+ xvalues->cap_style = CapProjecting;
+ break;
+ }
+ *xvalues_mask |= GCCapStyle;
+ }
+ if (mask & GDK_GC_JOIN_STYLE)
+ {
+ switch (values->join_style)
+ {
+ case GDK_JOIN_MITER:
+ xvalues->join_style = JoinMiter;
+ break;
+ case GDK_JOIN_ROUND:
+ xvalues->join_style = JoinRound;
+ break;
+ case GDK_JOIN_BEVEL:
+ xvalues->join_style = JoinBevel;
+ break;
+ }
+ *xvalues_mask |= GCJoinStyle;
+ }
+
+}
+
+/**
+ * gdk_gc_set_clip_rectangle:
+ * @gc: a #GdkGC.
+ * @rectangle: the rectangle to clip to.
+ *
+ * Sets the clip mask for a graphics context from a
+ * rectangle. The clip mask is interpreted relative to the clip
+ * origin. (See gdk_gc_set_clip_origin()).
+ **/
+void
+gdk_gc_set_clip_rectangle (GdkGC *gc,
+ GdkRectangle *rectangle)
+{
+ GdkGCMacOSX *macosx_gc;
+ gboolean had_region = FALSE;
+
+ g_return_if_fail (GDK_IS_GC (gc));
+
+ macosx_gc = GDK_GC_MacOSX (gc);
+
+ if (macosx_gc->clip_region)
+ {
+ had_region = TRUE;
+ gdk_region_destroy (macosx_gc->clip_region);
+ }
+
+ if (rectangle)
+ macosx_gc->clip_region = gdk_region_rectangle (rectangle);
+ else
+ macosx_gc->clip_region = NULL;
+
+ /* Unset immediately, to make sure Xlib doesn't keep the
+ * XID of an old clip mask cached
+ */
+ if ((had_region && !rectangle) || macosx_gc->have_clip_mask)
+ {
+ XSetClipMask (GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc), None);
+ macosx_gc->have_clip_mask = FALSE;
+ }
+
+ gc->clip_x_origin = 0;
+ gc->clip_y_origin = 0;
+
+ macosx_gc->dirty_mask |= GDK_GC_DIRTY_CLIP;
+}
+#endif
+
+/**
+ * gdk_gc_set_clip_region:
+ * @gc: a #GdkGC.
+ * @region: the #GdkRegion.
+ *
+ * Sets the clip mask for a graphics context from a region structure.
+ * The clip mask is interpreted relative to the clip origin. (See
+ * gdk_gc_set_clip_origin()).
+ **/
+void
+gdk_gc_set_clip_region (GdkGC *gc,
+ GdkRegion *region)
+{
+ GdkGCMacOSX *macosx_gc;
+ gboolean had_region = FALSE;
+
+ g_return_if_fail (GDK_IS_GC (gc));
+
+ macosx_gc = GDK_GC_MACOSX (gc);
+
+ if (macosx_gc->clip_region)
+ {
+ had_region = TRUE;
+ gdk_region_destroy (macosx_gc->clip_region);
+ }
+
+ if (region)
+ macosx_gc->clip_region = gdk_region_copy (region);
+ else
+ macosx_gc->clip_region = NULL;
+
+ if ((had_region && !region) || macosx_gc->have_clip_mask)
+ {
+ // FIXME
+ CGContextRestoreGState(macosx_gc->cggc);
+ CGContextSaveGState(macosx_gc->cggc);
+ //CGContextClip(macosx_gc->gccg);
+// XSetClipMask (GDK_GC_XDISPLAY (gc), GDK_GC_XGC (gc), None);
+ macosx_gc->have_clip_mask = FALSE;
+ }
+
+ gc->clip_x_origin = 0;
+ gc->clip_y_origin = 0;
+
+ macosx_gc->dirty_mask |= GDK_GC_DIRTY_CLIP;
+}
+
+#if 0
+
+/**
+ * gdk_gc_copy:
+ * @dst_gc: the destination graphics context.
+ * @src_gc: the source graphics context.
+ *
+ * Copy the set of values from one graphics context
+ * onto another graphics context.
+ **/
+void
+gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc)
+{
+ GdkGCMacOSX *macosx_src_gc;
+ GdkGCMacOSX *macosx_dst_gc;
+
+ g_return_if_fail (GDK_IS_GC_MacOSX (dst_gc));
+ g_return_if_fail (GDK_IS_GC_MacOSX (src_gc));
+
+ macosx_dst_gc = GDK_GC_MacOSX (dst_gc);
+ macosx_src_gc = GDK_GC_MacOSX (src_gc);
+
+ XCopyGC (GDK_GC_XDISPLAY (src_gc), GDK_GC_XGC (src_gc), ~((~1) << GCLastBit),
+ GDK_GC_XGC (dst_gc));
+
+ dst_gc->clip_x_origin = src_gc->clip_x_origin;
+ dst_gc->clip_y_origin = src_gc->clip_y_origin;
+ dst_gc->ts_x_origin = src_gc->ts_x_origin;
+ dst_gc->ts_y_origin = src_gc->ts_y_origin;
+
+ if (src_gc->colormap)
+ g_object_ref (src_gc->colormap);
+
+ if (dst_gc->colormap)
+ g_object_unref (dst_gc->colormap);
+
+ dst_gc->colormap = src_gc->colormap;
+
+ if (macosx_dst_gc->clip_region)
+ gdk_region_destroy (macosx_dst_gc->clip_region);
+
+ if (macosx_src_gc->clip_region)
+ macosx_dst_gc->clip_region = gdk_region_copy (macosx_src_gc->clip_region);
+ else
+ macosx_dst_gc->clip_region = NULL;
+
+ macosx_dst_gc->dirty_mask = macosx_src_gc->dirty_mask;
+ macosx_dst_gc->fg_pixel = macosx_src_gc->fg_pixel;
+ macosx_dst_gc->fill = macosx_src_gc->fill;
+
+ if (macosx_dst_gc->stipple)
+ g_object_unref (macosx_dst_gc->stipple);
+ macosx_dst_gc->stipple = macosx_src_gc->stipple;
+ if (macosx_dst_gc->stipple)
+ g_object_ref (macosx_dst_gc->stipple);
+
+ if (macosx_dst_gc->tile)
+ g_object_unref (macosx_dst_gc->tile);
+ macosx_dst_gc->tile = macosx_src_gc->tile;
+ if (macosx_dst_gc->tile)
+ g_object_ref (macosx_dst_gc->tile);
+
+ clear_fg_picture (dst_gc);
+}
+
+/**
+ * gdk_gc_get_screen:
+ * @gc: a #GdkGC.
+ *
+ * Gets the #GdkScreen for which @gc was created
+ *
+ * Returns: the #GdkScreen for @gc.
+ *
+ * Since: 2.2
+ */
+GdkScreen *
+gdk_gc_get_screen (GdkGC *gc)
+{
+ g_return_val_if_fail (GDK_IS_GC_MacOSX (gc), NULL);
+
+ return GDK_GC_MacOSX (gc)->screen;
+}
+
+/**
+ * gdk_macosx_gc_get_xdisplay:
+ * @gc: a #GdkGC.
+ *
+ * Returns the display of a #GdkGC.
+ *
+ * Return value: an Xlib <type>Display*</type>.
+ **/
+Display *
+gdk_macosx_gc_get_xdisplay (GdkGC *gc)
+{
+ g_return_val_if_fail (GDK_IS_GC_MacOSX (gc), NULL);
+
+ return GDK_SCREEN_XDISPLAY (gdk_gc_get_screen (gc));
+}
+
+/**
+ * gdk_macosx_gc_get_xgc:
+ * @gc: a #GdkGC.
+ *
+ * Returns the X GC of a #GdkGC.
+ *
+ * Return value: an Xlib <type>GC</type>.
+ **/
+GC
+gdk_macosx_gc_get_xgc (GdkGC *gc)
+{
+ GdkGCMacOSX *gc_macosx;
+
+ g_return_val_if_fail (GDK_IS_GC_MacOSX (gc), NULL);
+
+ gc_macosx = GDK_GC_MacOSX (gc);
+
+ if (gc_macosx->dirty_mask)
+ _gdk_macosx_gc_flush (gc);
+
+ return gc_macosx->xgc;
+}
+
+/* Various bits of the below are roughly cribbed from XFree86
+ * lib/Xft/xftdraw.c, Copyright 2000, Keith Packard
+ */
+
+static XRenderPictFormat *
+foreground_format (GdkGC *gc)
+{
+ XRenderPictFormat pf;
+
+ pf.type = PictTypeDirect;
+ pf.depth = 32;
+ pf.direct.redMask = 0xff;
+ pf.direct.greenMask = 0xff;
+ pf.direct.blueMask = 0xff;
+ pf.direct.alphaMask = 0xff;
+
+ return XRenderFindFormat (GDK_GC_XDISPLAY (gc),
+ (PictFormatType |
+ PictFormatDepth |
+ PictFormatRedMask |
+ PictFormatGreenMask |
+ PictFormatBlueMask |
+ PictFormatAlphaMask),
+ &pf,
+ 0);
+}
+
+static Picture
+make_fg_tile_picture (GdkGC *gc)
+{
+ GdkGCMacOSX *macosx_gc = GDK_GC_MacOSX (gc);
+ GdkVisual *visual = gdk_drawable_get_visual (macosx_gc->tile);
+ XRenderPictFormat *format = NULL;
+
+ if (visual)
+ {
+ format = XRenderFindVisualFormat (GDK_GC_XDISPLAY (gc),
+ GDK_VISUAL_XVISUAL (visual));
+ }
+ else if (macosx_gc->depth == 1)
+ {
+ format = XRenderFindStandardFormat (GDK_GC_XDISPLAY (gc),
+ PictStandardA1);
+ }
+
+ if (format)
+ {
+ XRenderPictureAttributes pa;
+ pa.repeat = True;
+
+ return XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
+ GDK_PIXMAP_XID (macosx_gc->tile),
+ format,
+ CPRepeat, &pa);
+ }
+
+ return None;
+}
+
+static Picture
+make_stipple_picture (GdkGC *gc)
+{
+ GdkGCMacOSX *macosx_gc = GDK_GC_MacOSX (gc);
+ XRenderPictFormat *format = NULL;
+ XRenderPictureAttributes pa;
+
+ format = XRenderFindStandardFormat (GDK_GC_XDISPLAY (gc),
+ PictStandardA1);
+
+ pa.repeat = True;
+ return XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
+ GDK_PIXMAP_XID (macosx_gc->stipple),
+ format,
+ CPRepeat, &pa);
+}
+
+static Picture
+make_color_picture (GdkGC *gc,
+ XRenderColor *color)
+{
+ GdkGCMacOSX *macosx_gc = GDK_GC_MacOSX (gc);
+ XRenderPictureAttributes pa;
+ XRenderPictFormat *pix_format = foreground_format (gc);
+ Pixmap pix;
+ Picture picture;
+
+ if (!pix_format)
+ return None;
+
+ pix = XCreatePixmap (GDK_GC_XDISPLAY (gc),
+ GDK_SCREEN_XROOTWIN (macosx_gc->screen),
+ 1, 1, pix_format->depth);
+ pa.repeat = True;
+ picture = XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
+ pix,
+ pix_format,
+ CPRepeat, &pa);
+ XFreePixmap (GDK_GC_XDISPLAY (gc), pix);
+
+ XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
+ picture, color,
+ 0, 0, 1, 1);
+
+ return picture;
+}
+
+static void
+get_bg_color (GdkGC *gc,
+ XRenderColor *render_color)
+{
+ GdkGCMacOSX *macosx_gc = GDK_GC_MacOSX (gc);
+ GdkColormap *cmap;
+
+ cmap = gdk_gc_get_colormap (gc);
+
+ if (cmap)
+ {
+ GdkColor color;
+
+ gdk_colormap_query_color (cmap, macosx_gc->bg_pixel, &color);
+
+ render_color->alpha = 0xffff;
+ render_color->red = color.red;
+ render_color->green = color.green;
+ render_color->blue = color.blue;
+ }
+ else /* Not worth warning, just use black */
+ {
+ render_color->alpha = 0xffff;
+ render_color->red = 0;
+ render_color->green = 0;
+ render_color->blue = 0;
+ }
+}
+
+/**
+ * _gdk_macosx_gc_get_fg_picture:
+ * @gc: a #GdkGC
+ *
+ * Gets a Xrender Picture object suitable for being the source
+ * drawable for drawing with the foreground the graphics context.
+ *
+ * Return value: a Picture, owned by the GC; this cannot be
+ * used over subsequent modification of the GC.
+ **/
+Picture
+_gdk_macosx_gc_get_fg_picture (GdkGC *gc)
+{
+ GdkGCMacOSX *macosx_gc;
+ gboolean new = FALSE;
+ XftColor xftcolor;
+ GdkFill fill;
+ int width, height;
+
+ g_return_val_if_fail (GDK_IS_GC_MacOSX (gc), None);
+
+ if (!_gdk_macosx_have_render (GDK_GC_DISPLAY (gc)))
+ return None;
+
+ macosx_gc = GDK_GC_MacOSX (gc);
+
+ fill = GDK_SOLID;
+ width = 1;
+ height = 1;
+
+ switch (macosx_gc->fill)
+ {
+ case GDK_SOLID:
+ break;
+ case GDK_TILED:
+ if (macosx_gc->tile)
+ {
+ if (!macosx_gc->fg_picture)
+ macosx_gc->fg_picture = make_fg_tile_picture (gc);
+
+ if (macosx_gc->fg_picture != None)
+ return macosx_gc->fg_picture;
+ }
+ break;
+ case GDK_STIPPLED:
+ case GDK_OPAQUE_STIPPLED:
+ if (macosx_gc->stipple)
+ {
+ gdk_drawable_get_size (macosx_gc->stipple, &width, &height);
+ fill = macosx_gc->fill;
+ }
+ break;
+ }
+
+ if (macosx_gc->fg_picture == None)
+ {
+ XRenderPictureAttributes pa;
+ XRenderPictFormat *pix_format = foreground_format (gc);
+ Pixmap pix;
+
+ if (!pix_format)
+ return None;
+
+ pix = XCreatePixmap (GDK_GC_XDISPLAY (gc),
+ GDK_SCREEN_XROOTWIN (macosx_gc->screen),
+ width, height, pix_format->depth);
+ pa.repeat = True;
+ macosx_gc->fg_picture = XRenderCreatePicture (GDK_GC_XDISPLAY (gc),
+ pix,
+ pix_format,
+ CPRepeat, &pa);
+ XFreePixmap (GDK_GC_XDISPLAY (gc), pix);
+
+ new = TRUE;
+ }
+
+ _gdk_gc_macosx_get_fg_xft_color (gc, &xftcolor);
+
+ if (macosx_gc->fg_picture_color.alpha != 0xffff ||
+ macosx_gc->fg_picture_color.red != xftcolor.color.red ||
+ macosx_gc->fg_picture_color.green != xftcolor.color.green ||
+ macosx_gc->fg_picture_color.blue != xftcolor.color.blue)
+ {
+ macosx_gc->fg_picture_color.alpha = 0xffff;
+ macosx_gc->fg_picture_color.red = xftcolor.color.red;
+ macosx_gc->fg_picture_color.green = xftcolor.color.green;
+ macosx_gc->fg_picture_color.blue = xftcolor.color.blue;
+
+ new = TRUE;
+ }
+
+ switch (fill)
+ {
+ case GDK_SOLID:
+ XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
+ macosx_gc->fg_picture, &macosx_gc->fg_picture_color,
+ 0, 0, width, height);
+ break;
+ case GDK_STIPPLED:
+ {
+ Picture stipple_picture = make_stipple_picture (gc);
+
+ XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
+ macosx_gc->fg_picture, &macosx_gc->fg_picture_color,
+ 0, 0, width, height);
+ XRenderComposite (GDK_GC_XDISPLAY (gc),
+ PictOpInReverse,
+ stipple_picture, None, macosx_gc->fg_picture,
+ 0, 0, 0, 0, 0, 0, width, height);
+
+ XRenderFreePicture (GDK_GC_XDISPLAY (macosx_gc), stipple_picture);
+ }
+ break;
+ case GDK_OPAQUE_STIPPLED:
+ {
+ XRenderColor bg_color;
+
+ Picture stipple_picture = make_stipple_picture (gc);
+ Picture fg_picture = make_color_picture (gc, &macosx_gc->fg_picture_color);
+
+ get_bg_color (gc, &bg_color);
+
+ XRenderFillRectangle (GDK_GC_XDISPLAY (gc), PictOpSrc,
+ macosx_gc->fg_picture, &bg_color,
+ 0, 0, width, height);
+ XRenderComposite (GDK_GC_XDISPLAY (gc),
+ PictOpOver,
+ fg_picture, stipple_picture, macosx_gc->fg_picture,
+ 0, 0, 0, 0, 0, 0, width, height);
+
+ XRenderFreePicture (GDK_GC_XDISPLAY (macosx_gc), stipple_picture);
+ XRenderFreePicture (GDK_GC_XDISPLAY (macosx_gc), fg_picture);
+ }
+ break;
+ case GDK_TILED:
+ g_assert_not_reached (); /* handled above */
+ break;
+ }
+
+ return macosx_gc->fg_picture;
+}
+
+/**
+ * _gdk_gc_macosx_get_fg_xft_color:
+ * @gc: a #GdkGC
+ * @xftcolor: location to store the color
+ *
+ * Gets the foreground color of the GC as a XftColor.
+ **/
+void
+_gdk_gc_macosx_get_fg_xft_color (GdkGC *gc,
+ XftColor *xftcolor)
+{
+ GdkGCMacOSX *macosx_gc;
+ GdkColormap *cmap;
+ GdkColor color;
+
+ g_return_if_fail (GDK_IS_GC_MacOSX (gc));
+
+ macosx_gc = GDK_GC_MacOSX (gc);
+
+ cmap = gdk_gc_get_colormap (gc);
+
+ xftcolor->pixel = macosx_gc->fg_pixel;
+
+ if (cmap)
+ {
+ gdk_colormap_query_color (cmap, xftcolor->pixel, &color);
+ xftcolor->color.alpha = 0xffff;
+ xftcolor->color.red = color.red;
+ xftcolor->color.green = color.green;
+ xftcolor->color.blue = color.blue;
+ }
+ else if (macosx_gc->depth == 1)
+ {
+ /* Drawing with Xft on a bitmap is a bit bizzare; it
+ * takes alpha >= 0x8000 to mean 'set to 1' and
+ * alpha < 0x8000 to mean 'set to 0'.
+ */
+ if (xftcolor->pixel)
+ {
+ xftcolor->color.red = 0xffff;
+ xftcolor->color.green = 0xffff;
+ xftcolor->color.blue = 0xffff;
+ xftcolor->color.alpha = 0xffff;
+ }
+ else
+ {
+ xftcolor->color.red = 0;
+ xftcolor->color.green = 0;
+ xftcolor->color.blue = 0;
+ xftcolor->color.alpha = 0;
+ }
+ }
+ else
+ {
+ g_warning ("Using Xft rendering requires the GC argument to have a\n"
+ "specified colormap. If the GC was created for a drawable\n"
+ "with a colormap, the colormap will be set on the GC\n"
+ "automatically. Otherwise, a colormap must be set on it with"
+ "gdk_gc_set_colormap");
+ }
+}
+
+#endif
+
+void
+_gdk_windowing_gc_get_foreground (GdkGC *gc,
+ GdkColor *color)
+{
+ GdkGCMacOSX *macosx_gc;
+
+ g_return_if_fail (GDK_IS_GC_MACOSX (gc));
+
+ macosx_gc = GDK_GC_MACOSX (gc);
+
+ _gdk_color_get_from_cgcolor(macosx_gc->stroke_color, color);
+}
diff --git a/gdk/macosx/gdkmacosx.h b/gdk/macosx/gdkmacosx.h
new file mode 100644
index 0000000000..c14e8f7c54
--- /dev/null
+++ b/gdk/macosx/gdkmacosx.h
@@ -0,0 +1,55 @@
+
+
+
+#ifndef __GDK_MACOSX_H__
+#define __GDK_MACOSX_H__
+
+#include <gdk/gdk.h>
+#include <Cocoa/Cocoa.h>
+
+#define GDK_WINDOW_NSVIEW(win) (GDK_WINDOW_IMPL_MACOSX(win)->v)
+
+
+GdkWindow *gdk_nsview_table_lookup_for_display(GdkDisplay *display,
+ GdkNativeWindow anid);
+void _gdk_nsview_table_insert (GdkDisplay *display,
+ GdkNativeWindow anid,
+ GdkWindow *window);
+
+
+inline static GdkRectangle ns_to_gdkrect(NSRect r)
+{
+ GdkRectangle dest;
+ dest.x = r.origin.x;
+ dest.y = r.origin.y;
+ dest.width = r.size.width;
+ dest.height = r.size.height;
+
+ return dest;
+}
+
+inline static GdkModifierType ns_to_gdk_modifier(int modifier)
+{
+ GdkModifierType dest = 0;
+
+ if (modifier & NSAlphaShiftKeyMask) {
+ dest |= GDK_LOCK_MASK;
+ }
+ if (modifier & NSShiftKeyMask) {
+ dest |= GDK_SHIFT_MASK;
+ }
+ if (modifier & NSControlKeyMask) {
+ dest |= GDK_CONTROL_MASK;
+ }
+ if (modifier & NSAlternateKeyMask) {
+ dest |= GDK_MOD1_MASK;
+ }
+ if (modifier & NSCommandKeyMask) {
+ dest != GDK_MOD2_MASK;
+ }
+
+ return dest;
+}
+
+#endif
+
diff --git a/gdk/macosx/gdkmain-macosx.c b/gdk/macosx/gdkmain-macosx.c
new file mode 100644
index 0000000000..bceecbb065
--- /dev/null
+++ b/gdk/macosx/gdkmain-macosx.c
@@ -0,0 +1,42 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Copyright (C) 1998-2002 Tor Lillqvist
+ * Copyright (C) 2005 Hubert Figuiere
+ *
+ * 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 "gdk.h"
+
+
+
+
+
+
+
+
+void
+_gdk_windowing_display_set_sm_client_id (GdkDisplay *display,
+ const gchar *sm_client_id)
+{
+ g_warning("gdk_set_sm_client_id %s", sm_client_id ? sm_client_id : "NULL");
+}
diff --git a/gdk/macosx/gdknsview-macosx.m b/gdk/macosx/gdknsview-macosx.m
new file mode 100644
index 0000000000..88df9b40dc
--- /dev/null
+++ b/gdk/macosx/gdknsview-macosx.m
@@ -0,0 +1,127 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include <config.h>
+#include "gdkalias.h"
+#include "gdkprivate-macosx.h"
+#include "gdkdisplay-macosx.h"
+#include <stdio.h>
+
+@class NSView;
+
+static guint gdk_nsview_hash (NSView **v);
+static gboolean gdk_nsview_equal (NSView **a, NSView **b);
+
+
+void
+_gdk_nsview_table_insert (GdkDisplay *display,
+ NSView *v,
+ gpointer data)
+{
+ GdkDisplayMacOSX *display_macosx;
+
+ g_return_if_fail (v != NULL);
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+
+ display_macosx = GDK_DISPLAY_MACOSX (display);
+
+ if (!display_macosx->nsview_ht)
+ display_macosx->nsview_ht = g_hash_table_new ((GHashFunc) gdk_nsview_hash,
+ (GEqualFunc) gdk_nsview_equal);
+
+ g_hash_table_insert (display_macosx->nsview_ht, v, data);
+}
+
+void
+_gdk_xid_table_remove (GdkDisplay *display,
+ NSView *v)
+{
+ GdkDisplayMacOSX *display_macosx;
+
+ g_return_if_fail (GDK_IS_DISPLAY(display));
+
+ display_macosx = GDK_DISPLAY_MACOSX(display);
+
+ if (display_macosx->nsview_ht)
+ g_hash_table_remove (display_macosx->nsview_ht, &v);
+}
+
+/**
+ * gdk_xid_table_lookup_for_display:
+ * @display: the #GdkDisplay.
+ * @xid: an X id.
+ *
+ * Returns the GDK object associated with the given X id.
+ *
+ * Returns: a GDK object associated with the given X id.
+ *
+ * Since: 2.2
+ */
+gpointer
+gdk_nsview_table_lookup_for_display (GdkDisplay *display,
+ NSView *v)
+{
+ GdkDisplayMacOSX *display_macosx;
+ gpointer data = NULL;
+
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+ display_macosx = GDK_DISPLAY_MACOSX (display);
+
+ if (display_macosx->nsview_ht)
+ data = g_hash_table_lookup (display_macosx->nsview_ht, &v);
+
+ return data;
+}
+
+
+/**
+ * gdk_xid_table_lookup:
+ * @xid: an X id.
+ *
+ * Returns the Gdk object associated with the given X id.
+ *
+ * Return value: the associated Gdk object, which may be a #GdkPixmap,
+ * a #GdkWindow or a #GdkFont.
+ **/
+gpointer
+gdk_nsview_table_lookup (NSView *v)
+{
+ return gdk_nsview_table_lookup_for_display (gdk_display_get_default (), v);
+}
+
+static guint
+gdk_nsview_hash (NSView **v)
+{
+ return (guint)*v;
+}
+
+static gboolean
+gdk_nsview_equal (NSView **a,
+ NSView **b)
+{
+ return (*a == *b);
+}
diff --git a/gdk/macosx/gdkpango-macosx.c b/gdk/macosx/gdkpango-macosx.c
new file mode 100644
index 0000000000..0b18065969
--- /dev/null
+++ b/gdk/macosx/gdkpango-macosx.c
@@ -0,0 +1,11 @@
+#include <config.h>
+#include <glib.h>
+#include "gdkpango.h"
+
+#include <pango/pangoft2.h>
+
+PangoContext *
+gdk_pango_context_get_for_screen (GdkScreen *screen)
+{
+ return pango_ft2_get_context (75.0, 75.0);
+}
diff --git a/gdk/macosx/gdkpixmap-macosx.h b/gdk/macosx/gdkpixmap-macosx.h
new file mode 100644
index 0000000000..c0b9a1f9df
--- /dev/null
+++ b/gdk/macosx/gdkpixmap-macosx.h
@@ -0,0 +1,70 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GDK_PIXMAP_MACOSX_H__
+#define __GDK_PIXMAP_MACOSX_H__
+
+#include <gdk/macosx/gdkdrawable-macosx.h>
+#include <gdk/gdkpixmap.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Pixmap implementation for MacOSX
+ */
+
+typedef struct _GdkPixmapImplMacOSX GdkPixmapImplMacOSX;
+typedef struct _GdkPixmapImplMacOSXClass GdkPixmapImplMacOSXClass;
+
+#define GDK_TYPE_PIXMAP_IMPL_MacOSX (gdk_pixmap_impl_macosx_get_type ())
+#define GDK_PIXMAP_IMPL_MACOSX(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXMAP_IMPL_MacOSX, GdkPixmapImplMacOSX))
+#define GDK_PIXMAP_IMPL_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXMAP_IMPL_MACOSX, GdkPixmapImplMacOSXClass))
+#define GDK_IS_PIXMAP_IMPL_MACOSX(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXMAP_IMPL_MacOSX))
+#define GDK_IS_PIXMAP_IMPL_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXMAP_IMPL_MACOSX))
+#define GDK_PIXMAP_IMPL_MACOSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXMAP_IMPL_MACOSX, GdkPixmapImplMacOSXClass))
+
+struct _GdkPixmapImplMacOSX
+{
+ GdkDrawableImplMacOSX parent_instance;
+
+ gint width;
+ gint height;
+
+ guint is_foreign : 1;
+};
+
+struct _GdkPixmapImplMacOSXClass
+{
+ GdkDrawableImplMacOSXClass parent_class;
+
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GDK_PIXMAP_MacOSX_H__ */
diff --git a/gdk/macosx/gdkprivate-macosx.h b/gdk/macosx/gdkprivate-macosx.h
new file mode 100644
index 0000000000..a88ad41784
--- /dev/null
+++ b/gdk/macosx/gdkprivate-macosx.h
@@ -0,0 +1,217 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * Private uninstalled header defining things local to X windowing code
+ */
+
+#ifndef __GDK_PRIVATE_MacOSX_H__
+#define __GDK_PRIVATE_MacOSX_H__
+
+#include <gdk/gdkcursor.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/macosx/gdkwindow-macosx.h>
+#include <gdk/macosx/gdkpixmap-macosx.h>
+#include <gdk/macosx/gdkdisplay-macosx.h>
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#include "gdkinternals.h"
+
+#include <config.h>
+
+#define GDK_TYPE_GC_MACOSX (_gdk_gc_macosx_get_type ())
+#define GDK_GC_MACOSX(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_GC_MACOSX, GdkGCMacOSX))
+#define GDK_GC_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GC_MACOSX, GdkGCMacOSXClass))
+#define GDK_IS_GC_MACOSX(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_GC_MACOSX))
+#define GDK_IS_GC_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GC_MACOSX))
+#define GDK_GC_MACOSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GC_MACOSX, GdkGCMacOSXClass))
+
+typedef struct _GdkCursorPrivate GdkCursorPrivate;
+typedef struct _GdkVisualPrivate GdkVisualPrivate;
+typedef struct _GdkGCMacOSX GdkGCMacOSX;
+typedef struct _GdkGCMacOSXClass GdkGCMacOSXClass;
+
+struct _GdkGCMacOSX
+{
+ GdkGC parent_instance;
+
+ CGContextRef cggc;
+ GdkScreen *screen;
+ GdkRegion *clip_region;
+ guint16 dirty_mask;
+ guint have_clip_mask : 1;
+ guint depth : 8;
+
+ GdkFill fill;
+ GdkBitmap *stipple;
+ GdkPixmap *tile;
+
+ //cture fg_picture;
+ //enderColor fg_picture_color;
+ CGColorRef stroke_color;
+ CGColorRef fill_color;
+};
+
+struct _GdkGCMacOSXClass
+{
+ GdkGCClass parent_class;
+};
+
+struct _GdkCursorPrivate
+{
+ GdkCursor cursor;
+ Cursor xcursor;
+ GdkDisplay *display;
+};
+
+struct _GdkVisualPrivate
+{
+ GdkVisual visual;
+ //Visual *xvisual;
+ GdkScreen *screen;
+};
+
+/*
+void _gdk_xid_table_insert (GdkDisplay *display,
+ XID *xid,
+ gpointer data);
+void _gdk_xid_table_remove (GdkDisplay *display,
+ XID xid);
+gint _gdk_send_xevent (GdkDisplay *display,
+ Window window,
+ gboolean propagate,
+ glong event_mask,
+ XEvent *event_send);
+*/
+GType _gdk_gc_macosx_get_type (void);
+
+gboolean _gdk_macosx_have_render (GdkDisplay *display);
+gboolean _gdk_macosx_have_render_with_trapezoids (GdkDisplay *display);
+
+/*
+Picture _gdk_macosx_gc_get_fg_picture (GdkGC *gc);
+void _gdk_gc_macosx_get_fg_xft_color (GdkGC *gc,
+ XftColor *xftcolor);
+*/
+
+GdkGC *_gdk_macosx_gc_new (GdkDrawable *drawable,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask);
+
+GdkImage *_gdk_macosx_copy_to_image (GdkDrawable *drawable,
+ GdkImage *image,
+ gint src_x,
+ gint src_y,
+ gint dest_x,
+ gint dest_y,
+ gint width,
+ gint height);
+//Pixmap _gdk_macosx_image_get_shm_pixmap (GdkImage *image);
+
+/* Routines from gdkgeometry-macosx.c */
+void _gdk_window_init_position (GdkWindow *window);
+void _gdk_window_move_resize_child (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height);
+void _gdk_window_process_expose (GdkWindow *window,
+ gulong serial,
+ GdkRectangle *area);
+
+void _gdk_selection_window_destroyed (GdkWindow *window);
+//gboolean _gdk_selection_filter_clear_event (XSelectionClearEvent *event);
+
+/*
+void _gdk_region_get_xrectangles (GdkRegion *region,
+ gint x_offset,
+ gint y_offset,
+ XRectangle **rects,
+ gint *n_rects);
+*/
+//gboolean _gdk_moveresize_handle_event (XEvent *event);
+gboolean _gdk_moveresize_configure_done (GdkDisplay *display,
+ GdkWindow *window);
+
+void _gdk_keymap_state_changed (GdkDisplay *display);
+void _gdk_keymap_keys_changed (GdkDisplay *display);
+gint _gdk_macosx_get_group_for_state (GdkDisplay *display,
+ GdkModifierType state);
+
+CGContextRef _gdk_macosx_gc_flush (GdkGC *gc);
+
+void _gdk_macosx_initialize_locale (void);
+
+/*
+void _gdk_xgrab_check_unmap (GdkWindow *window,
+ gulong serial);
+void _gdk_xgrab_check_destroy (GdkWindow *window);
+
+gboolean _gdk_macosx_display_is_root_window (GdkDisplay *display,
+ Window xroot_window);
+
+void _gdk_macosx_precache_atoms (GdkDisplay *display,
+ const gchar * const *atom_names,
+ gint n_atoms);
+*/
+
+void _gdk_macosx_events_init_screen (GdkScreen *screen);
+void _gdk_macosx_events_uninit_screen (GdkScreen *screen);
+
+void _gdk_events_init (GdkDisplay *display);
+void _gdk_windowing_window_init (GdkScreen *screen);
+void _gdk_visual_init (GdkScreen *screen);
+void _gdk_dnd_init (GdkDisplay *display);
+void _gdk_windowing_image_init (GdkDisplay *display);
+void _gdk_input_init (GdkDisplay *display);
+
+/*
+PangoRenderer *_gdk_macosx_renderer_get (GdkDrawable *drawable,
+ GdkGC *gc);
+*/
+
+extern GdkDrawableClass _gdk_macosx_drawable_class;
+extern gboolean _gdk_use_xshm;
+extern const int _gdk_nenvent_masks;
+extern const int _gdk_event_mask_table[];
+extern GdkAtom _gdk_selection_property;
+extern gboolean _gdk_synchronize;
+
+#define GDK_PIXMAP_SCREEN(pix) (GDK_DRAWABLE_IMPL_MACOSX (((GdkPixmapObject *)pix)->impl)->screen)
+#define GDK_PIXMAP_DISPLAY(pix) (GDK_SCREEN_MACOSX (GDK_PIXMAP_SCREEN (pix))->display)
+#define GDK_PIXMAP_XROOTWIN(pix) (GDK_SCREEN_MACOSX (GDK_PIXMAP_SCREEN (pix))->xroot_window)
+#define GDK_DRAWABLE_DISPLAY(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_DISPLAY (win) : GDK_PIXMAP_DISPLAY (win))
+#define GDK_DRAWABLE_SCREEN(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_SCREEN (win) : GDK_PIXMAP_SCREEN (win))
+#define GDK_DRAWABLE_XROOTWIN(win) (GDK_IS_WINDOW (win) ? GDK_WINDOW_XROOTWIN (win) : GDK_PIXMAP_XROOTWIN (win))
+#define GDK_SCREEN_DISPLAY(screen) (GDK_SCREEN_MACOSX (screen)->display)
+#define GDK_SCREEN_XROOTWIN(screen) (GDK_SCREEN_MACOSX (screen)->xroot_window)
+#define GDK_WINDOW_SCREEN(win) (GDK_DRAWABLE_IMPL_MACOSX (((GdkWindowObject *)win)->impl)->screen)
+#define GDK_WINDOW_DISPLAY(win) (GDK_SCREEN_MACOSX (GDK_WINDOW_SCREEN (win))->display)
+#define GDK_WINDOW_XROOTWIN(win) (GDK_SCREEN_MACOSX (GDK_WINDOW_SCREEN (win))->xroot_window)
+#define GDK_GC_DISPLAY(gc) (GDK_SCREEN_DISPLAY (GDK_GC_MACOSX(gc)->screen))
+
+#endif /* __GDK_PRIVATE_MACOSX_H__ */
diff --git a/gdk/macosx/gdkscreen-macosx.h b/gdk/macosx/gdkscreen-macosx.h
new file mode 100644
index 0000000000..3b22473405
--- /dev/null
+++ b/gdk/macosx/gdkscreen-macosx.h
@@ -0,0 +1,70 @@
+/*
+ * gdkscreen-macosx.h
+ *
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * Erwann Chenede <erwann.chenede@sun.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ */
+
+#ifndef __GDK_SCREEN_MACOSX_H__
+#define __GDK_SCREEN_MACOSX_H__
+
+#include "gdkprivate-macosx.h"
+//#include "xsettings-client.h"
+#include <gdk/gdkscreen.h>
+#include <gdk/gdkvisual.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GdkScreenMacOSX GdkScreenMacOSX;
+typedef struct _GdkScreenMacOSXClass GdkScreenMacOSXClass;
+
+#define GDK_TYPE_SCREEN_MACOSX (_gdk_screen_macosx_get_type ())
+#define GDK_SCREEN_MACOSX(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SCREEN_MACOSX, GdkScreenMacOSX))
+#define GDK_SCREEN_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SCREEN_MACOSX, GdkScreenMacOSXClass))
+#define GDK_IS_SCREEN_MACOSX(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SCREEN_MACOSX))
+#define GDK_IS_SCREEN_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SCREEN_MACOSX))
+#define GDK_SCREEN_MACOSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SCREEN_MACOSX, GdkScreenMacOSXClass))
+
+@class NSEvent;
+@class NSScreen;
+
+struct _GdkScreenMacOSX
+{
+ GdkScreen parent_instance;
+
+ GdkDisplay *display;
+ GdkWindow *root_window;
+ GdkColormap *default_colormap;
+};
+
+struct _GdkScreenMacOSXClass
+{
+ GdkScreenClass parent_class;
+};
+
+GType _gdk_screen_macosx_get_type (void);
+GdkScreen * _gdk_macosx_screen_new (GdkDisplay *display,
+ NSScreen *screen);
+
+void _gdk_macosx_screen_size_changed (GdkScreen *screen,
+ NSEvent *event);
+
+G_END_DECLS
+
+#endif /* __GDK_SCREEN_MacOSX_H__ */
diff --git a/gdk/macosx/gdkscreen-macosx.m b/gdk/macosx/gdkscreen-macosx.m
new file mode 100644
index 0000000000..5aa2762075
--- /dev/null
+++ b/gdk/macosx/gdkscreen-macosx.m
@@ -0,0 +1,452 @@
+/*
+ * gdkscreen-macosx.c
+ *
+ * Copyright 2001 Sun Microsystems Inc.
+ * Copyright 2005 Hubert Figuiere
+ *
+ * Hubert Figuiere <hub@figuiere.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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 <stdlib.h>
+#include <string.h>
+
+#include <Cocoa/Cocoa.h>
+
+#include <glib.h>
+#include "gdkmacosx.h"
+#include "gdkalias.h"
+#include "gdkscreen.h"
+#include "gdkscreen-macosx.h"
+#include "gdkdisplay.h"
+#include "gdkdisplay-macosx.h"
+
+
+static void gdk_screen_macosx_class_init (GdkScreenMacOSXClass *klass);
+static void gdk_screen_macosx_dispose (GObject *object);
+static void gdk_screen_macosx_finalize (GObject *object);
+static void init_xinerama_support (GdkScreen *screen);
+static void init_randr_support (GdkScreen *screen);
+
+enum
+{
+ WINDOW_MANAGER_CHANGED,
+ LAST_SIGNAL
+};
+
+static gpointer parent_class = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GType
+_gdk_screen_macosx_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkScreenMacOSXClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_screen_macosx_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkScreenMacOSX),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+ object_type = g_type_register_static (GDK_TYPE_SCREEN,
+ "GdkScreenMacOSX",
+ &object_info, 0);
+ }
+ return object_type;
+}
+
+static void
+gdk_screen_macosx_class_init (GdkScreenMacOSXClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gdk_screen_macosx_dispose;
+ object_class->finalize = gdk_screen_macosx_finalize;
+
+ parent_class = g_type_class_peek_parent (klass);
+}
+
+/**
+ * gdk_screen_get_display:
+ * @screen: a #GdkScreen
+ *
+ * Gets the display to which the @screen belongs.
+ *
+ * Returns: the display to which @screen belongs
+ *
+ * Since: 2.2
+ **/
+GdkDisplay *
+gdk_screen_get_display (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return GDK_SCREEN_MACOSX (screen)->display;
+}
+/**
+ * gdk_screen_get_width:
+ * @screen: a #GdkScreen
+ *
+ * Gets the width of @screen in pixels
+ *
+ * Returns: the width of @screen in pixels.
+ *
+ * Since: 2.2
+ **/
+gint
+gdk_screen_get_width (GdkScreen *screen)
+{
+ NSArray *all_screens;
+ NSRect frame;
+ NSScreen *ns_screen;
+ NSEnumerator *iter;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ frame = NSMakeRect(0,0,0,0);
+
+ all_screens = [NSScreen screens];
+ iter = [all_screens objectEnumerator];
+
+ while(ns_screen = [iter nextObject])
+ {
+ frame = NSUnionRect(frame, [ns_screen frame]);
+ }
+
+ return frame.size.width;
+}
+
+/**
+ * gdk_screen_get_height:
+ * @screen: a #GdkScreen
+ *
+ * Gets the height of @screen in pixels
+ *
+ * Returns: the height of @screen in pixels.
+ *
+ * Since: 2.2
+ **/
+gint
+gdk_screen_get_height (GdkScreen *screen)
+{
+ NSArray *all_screens;
+ NSRect frame;
+ NSScreen *ns_screen;
+ NSEnumerator *iter;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ frame = NSMakeRect(0,0,0,0);
+
+ all_screens = [NSScreen screens];
+ iter = [all_screens objectEnumerator];
+
+ while(ns_screen = [iter nextObject])
+ {
+ frame = NSUnionRect(frame, [ns_screen frame]);
+ }
+
+ return frame.size.height;
+}
+
+
+static NSSize
+_gdk_screen_get_dpi(GdkScreen *screen)
+{
+ NSSize s;
+ NSScreen *ns_screen = [NSScreen mainScreen];
+
+ NSDictionary *props = [ns_screen deviceDescription];
+
+ s = [[props objectForKey:NSDeviceResolution] size];
+
+ return s;
+}
+/*
+@"NSScreenNumber"
+*/
+
+/**
+ * gdk_screen_get_width_mm:
+ * @screen: a #GdkScreen
+ *
+ * Gets the width of @screen in millimeters.
+ * Note that on some X servers this value will not be correct.
+ *
+ * Returns: the width of @screen in pixels.
+ *
+ * Since: 2.2
+ **/
+gint
+gdk_screen_get_width_mm (GdkScreen *screen)
+{
+ NSSize s;
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ s = _gdk_screen_get_dpi(screen);
+ return gdk_screen_get_width(screen) / (s.width / 25.4);
+}
+
+/**
+ * gdk_screen_get_height_mm:
+ * @screen: a #GdkScreen
+ *
+ * Returns the height of @screen in millimeters.
+ * Note that on some X servers this value will not be correct.
+ *
+ * Returns: the heigth of @screen in pixels.
+ *
+ * Since: 2.2
+ **/
+gint
+gdk_screen_get_height_mm (GdkScreen *screen)
+{
+ NSSize s;
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ s = _gdk_screen_get_dpi(screen);
+ return gdk_screen_get_height(screen) / (s.height / 25.4);
+}
+
+/**
+ * gdk_screen_get_number:
+ * @screen: a #GdkScreen
+ *
+ * Gets the index of @screen among the screens in the display
+ * to which it belongs. (See gdk_screen_get_display())
+ *
+ * Returns: the index
+ *
+ * Since: 2.2
+ **/
+gint
+gdk_screen_get_number (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ return 0;
+}
+
+/**
+ * gdk_screen_get_root_window:
+ * @screen: a #GdkScreen
+ *
+ * Gets the root window of @screen.
+ *
+ * Returns: the root window
+ *
+ * Since: 2.2
+ **/
+GdkWindow *
+gdk_screen_get_root_window (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ // FIXME
+
+ return NULL;
+}
+
+/**
+ * gdk_screen_get_default_colormap:
+ * @screen: a #GdkScreen
+ *
+ * Gets the default colormap for @screen.
+ *
+ * Returns: the default #GdkColormap.
+ *
+ * Since: 2.2
+ **/
+GdkColormap *
+gdk_screen_get_default_colormap (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return GDK_SCREEN_MACOSX (screen)->default_colormap;
+}
+
+/**
+ * gdk_screen_set_default_colormap:
+ * @screen: a #GdkScreen
+ * @colormap: a #GdkColormap
+ *
+ * Sets the default @colormap for @screen.
+ *
+ * Since: 2.2
+ **/
+void
+gdk_screen_set_default_colormap (GdkScreen *screen,
+ GdkColormap *colormap)
+{
+ GdkColormap *old_colormap;
+
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+ g_return_if_fail (GDK_IS_COLORMAP (colormap));
+
+ old_colormap = GDK_SCREEN_MACOSX (screen)->default_colormap;
+
+ GDK_SCREEN_MACOSX (screen)->default_colormap = g_object_ref (colormap);
+
+ if (old_colormap)
+ g_object_unref (old_colormap);
+}
+
+static void
+gdk_screen_macosx_dispose (GObject *object)
+{
+ GdkScreenMacOSX *screen_macosx = GDK_SCREEN_MACOSX (object);
+
+ //_gdk_macosx_events_uninit_screen (GDK_SCREEN (object));
+
+ g_object_unref (screen_macosx->default_colormap);
+ screen_macosx->default_colormap = NULL;
+
+ screen_macosx->root_window = NULL;
+
+ screen_macosx->display = NULL;
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gdk_screen_macosx_finalize (GObject *object)
+{
+ GdkScreenMacOSX *screen_macosx = GDK_SCREEN_MACOSX (object);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+/**
+ * gdk_screen_get_n_monitors:
+ * @screen: a #GdkScreen.
+ *
+ * Returns the number of monitors which @screen consists of.
+ *
+ * Returns: number of monitors which @screen consists of.
+ *
+ * Since: 2.2
+ **/
+gint
+gdk_screen_get_n_monitors (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+ return [[NSScreen screens] count];
+}
+
+/**
+ * gdk_screen_get_monitor_geometry:
+ * @screen : a #GdkScreen.
+ * @monitor_num: the monitor number.
+ * @dest : a #GdkRectangle to be filled with the monitor geometry
+ *
+ * Retrieves the #GdkRectangle representing the size and position of
+ * the individual monitor within the entire screen area.
+ *
+ * Note that the size of the entire screen area can be retrieved via
+ * gdk_screen_get_width() and gdk_screen_get_height().
+ *
+ * Since: 2.2
+ **/
+void
+gdk_screen_get_monitor_geometry (GdkScreen *screen,
+ gint monitor_num,
+ GdkRectangle *dest)
+{
+ NSRect rect;
+
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+/* g_return_if_fail (monitor_num < GDK_SCREEN_MACOSX (screen)->num_monitors);
+ g_return_if_fail (monitor_num >= 0);*/
+
+ rect = [[[NSScreen screens] objectAtIndex:monitor_num] frame];
+
+ *dest = ns_to_gdkrect(rect);
+}
+
+
+
+GdkScreen *
+_gdk_macosx_screen_new (GdkDisplay *display,
+ NSScreen *screen)
+{
+ GdkScreen *gscreen;
+ GdkScreenMacOSX *screen_macosx;
+ GdkDisplayMacOSX *display_macosx = GDK_DISPLAY_MACOSX (display);
+
+ gscreen = g_object_new (GDK_TYPE_SCREEN_MACOSX, NULL);
+
+ screen_macosx = GDK_SCREEN_MACOSX (gscreen);
+ screen_macosx->display = display;
+ screen_macosx->default_colormap = NULL;
+// screen_macosx->xroot_window = RootWindow (display_macosx->xdisplay,screen_number);
+
+ _gdk_visual_init (gscreen);
+ _gdk_windowing_window_init (gscreen);
+
+ return gscreen;
+}
+
+
+
+/**
+ * _gdk_windowing_substitute_screen_number:
+ * @display_name : The name of a display, in the form used by
+ * gdk_display_open (). If %NULL a default value
+ * will be used. On MacOSX, this is derived from the DISPLAY
+ * environment variable.
+ * @screen_number : The number of a screen within the display
+ * referred to by @display_name.
+ *
+ * Modifies a @display_name to make @screen_number the default
+ * screen when the display is opened.
+ *
+ * Return value: a newly allocated string holding the resulting
+ * display name. Free with g_free().
+ */
+gchar *
+_gdk_windowing_substitute_screen_number (const gchar *display_name,
+ gint screen_number)
+{
+ return g_strdup (display_name);
+}
+
+/**
+ * gdk_screen_make_display_name:
+ * @screen: a #GdkScreen
+ *
+ * Determines the name to pass to gdk_display_open() to get
+ * a #GdkDisplay with this screen as the default screen.
+ *
+ * Return value: a newly allocated string, free with g_free()
+ *
+ * Since: 2.2
+ **/
+gchar *
+gdk_screen_make_display_name (GdkScreen *screen)
+{
+ return g_strdup ("");
+}
diff --git a/gdk/macosx/gdkwindow-macosx.h b/gdk/macosx/gdkwindow-macosx.h
new file mode 100644
index 0000000000..cfcbd25530
--- /dev/null
+++ b/gdk/macosx/gdkwindow-macosx.h
@@ -0,0 +1,106 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GDK_WINDOW_MACOSX_H__
+#define __GDK_WINDOW_MACOSX_H__
+
+#include <gdk/macosx/gdkdrawable-macosx.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GdkToplevelMacOSX GdkToplevelMacOSX;
+typedef struct _GdkWindowImplMacOSX GdkWindowImplMacOSX;
+typedef struct _GdkWindowImplMacOSXClass GdkWindowImplMacOSXClass;
+typedef struct _GdkMacPositionInfo GdkMacPositionInfo;
+
+struct _GdkMacPositionInfo
+{
+ gint x;
+ gint y;
+ gint width;
+ gint height;
+ gint x_offset; /* Offsets to add to X coordinates within window */
+ gint y_offset; /* to get GDK coodinates within window */
+ guint big : 1;
+ guint mapped : 1;
+ guint no_bg : 1; /* Set when the window background is temporarily
+ * unset during resizing and scaling */
+ GdkRectangle clip_rect; /* visible rectangle of window */
+};
+
+
+/* Window implementation for MacOSX
+ */
+
+#define GDK_TYPE_WINDOW_IMPL_MACOSX (gdk_window_impl_macosx_get_type ())
+#define GDK_WINDOW_IMPL_MACOSX(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_MACOSX, GdkWindowImplMacOSX))
+#define GDK_WINDOW_IMPL_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_MACOSX, GdkWindowImplMacOSXClass))
+#define GDK_IS_WINDOW_IMPL_MACOSX(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_MACOSX))
+#define GDK_IS_WINDOW_IMPL_MACOSX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_MACOSX))
+#define GDK_WINDOW_IMPL_MACOSX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_MACOSX, GdkWindowImplMacOSXClass))
+
+@class NSWindow;
+@class NSView;
+
+struct _GdkWindowImplMacOSX
+{
+ GdkDrawableImplMacOSX parent_instance;
+
+ gint width;
+ gint height;
+
+
+ GdkMacPositionInfo position_info;
+ GdkToplevelMacOSX *toplevel; /* Toplevel-specific information */
+ gint8 toplevel_window_type;
+ NSView *v;
+};
+
+struct _GdkWindowImplMacOSXClass
+{
+ GdkDrawableImplMacOSXClass parent_class;
+};
+
+struct _GdkToplevelMacOSX
+{
+ NSWindow *w;
+};
+
+GType gdk_window_impl_macosx_get_type (void);
+
+void gdk_macosx_window_set_user_time (GdkWindow *window,
+ guint32 timestamp);
+
+GdkToplevelMacOSX *_gdk_macosx_window_get_toplevel (GdkWindow *window);
+void _gdk_macosx_window_tmp_unset_bg (GdkWindow *window,
+ gboolean recurse);
+void _gdk_macosx_window_tmp_reset_bg (GdkWindow *window,
+ gboolean recurse);
+
+
+G_END_DECLS
+
+#endif /* __GDK_WINDOW_MACOSX_H__ */
diff --git a/gdk/macosx/gdkwindow-macosx.m b/gdk/macosx/gdkwindow-macosx.m
new file mode 100644
index 0000000000..c1baa4e99e
--- /dev/null
+++ b/gdk/macosx/gdkwindow-macosx.m
@@ -0,0 +1,5540 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+/*
+ * Mac Port by Hubert Figuiere <hfiguiere@teaser.fr>
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "gdkalias.h"
+#include "gdk.h"
+
+#include "gdkwindow.h"
+#include "gdkmacosx.h"
+//#include "gdkinputprivate.h"
+#include "gdkdisplay-macosx.h"
+#include "gdkscreen-macosx.h"
+//#include "gdkprivate-x11.h"
+#include "gdkregion.h"
+#include "gdkinternals.h"
+#include "gdkwindow-macosx.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <Cocoa/Cocoa.h>
+
+
+static GdkWindow *_gdk_parent_root = NULL;
+
+/* Forward declarations */
+static void gdk_window_set_static_win_gravity (GdkWindow *window,
+ gboolean on);
+static gboolean gdk_window_have_shape_ext (GdkDisplay *display);
+static gboolean gdk_window_icon_name_set (GdkWindow *window);
+static void gdk_window_add_colormap_windows (GdkWindow *window);
+
+
+static GdkColormap* gdk_window_impl_macosx_get_colormap (GdkDrawable *drawable);
+static void gdk_window_impl_macosx_set_colormap (GdkDrawable *drawable,
+ GdkColormap *cmap);
+static void gdk_window_impl_macosx_get_size (GdkDrawable *drawable,
+ gint *width,
+ gint *height);
+static GdkRegion* gdk_window_impl_macosx_get_visible_region (GdkDrawable *drawable);
+static void gdk_window_impl_macosx_init (GdkWindowImplMacOSX *window);
+static void gdk_window_impl_macosx_class_init (GdkWindowImplMacOSXClass *klass);
+static void gdk_window_impl_macosx_finalize (GObject *object);
+
+static gpointer parent_class = NULL;
+
+#define WINDOW_IS_TOPLEVEL(window) \
+ (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
+ GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
+
+
+GType
+gdk_window_impl_macosx_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkWindowImplMacOSXClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_window_impl_macosx_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkWindowImplMacOSX),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gdk_window_impl_macosx_init,
+ };
+
+ object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_MACOSX,
+ "GdkWindowImplMacOSX",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+GType
+_gdk_window_impl_get_type (void)
+{
+ return gdk_window_impl_macosx_get_type ();
+}
+
+static void
+gdk_window_impl_macosx_init (GdkWindowImplMacOSX *impl)
+{
+ impl->width = 1;
+ impl->height = 1;
+ impl->toplevel_window_type = -1;
+}
+
+GdkToplevelMacOSX *
+_gdk_macosx_window_get_toplevel (GdkWindow *window)
+{
+ GdkWindowObject *private;
+ GdkWindowImplMacOSX *impl;
+
+ g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+
+ if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
+ return NULL;
+
+ private = (GdkWindowObject *)window;
+ impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+
+ if (!impl->toplevel)
+ impl->toplevel = g_new0 (GdkToplevelMacOSX, 1);
+
+ return impl->toplevel;
+}
+
+static void
+gdk_window_impl_macosx_class_init (GdkWindowImplMacOSXClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = gdk_window_impl_macosx_finalize;
+
+ drawable_class->set_colormap = gdk_window_impl_macosx_set_colormap;
+ drawable_class->get_colormap = gdk_window_impl_macosx_get_colormap;
+ drawable_class->get_size = gdk_window_impl_macosx_get_size;
+
+ /* Visible and clip regions are the same */
+ drawable_class->get_clip_region = gdk_window_impl_macosx_get_visible_region;
+ drawable_class->get_visible_region = gdk_window_impl_macosx_get_visible_region;
+}
+
+static void
+gdk_window_impl_macosx_finalize (GObject *object)
+{
+ GdkWindowObject *wrapper;
+ GdkDrawableImplMacOSX *draw_impl;
+ GdkWindowImplMacOSX *window_impl;
+
+ g_return_if_fail (GDK_IS_WINDOW_IMPL_MACOSX (object));
+
+ draw_impl = GDK_DRAWABLE_IMPL_MACOSX (object);
+ window_impl = GDK_WINDOW_IMPL_MACOSX (object);
+
+ wrapper = (GdkWindowObject*) draw_impl->wrapper;
+
+ if (window_impl->toplevel)
+ g_free (window_impl->toplevel);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+#if 0
+
+static void
+tmp_unset_bg (GdkWindow *window)
+{
+ GdkWindowImplMacOSX *impl;
+ GdkWindowObject *obj;
+
+ obj = (GdkWindowObject *) window;
+ impl = GDK_WINDOW_IMPL_MACOSX (obj->impl);
+
+ /* For windows without EXPOSURE_MASK, we can't do this
+ * unsetting because such windows depend on the drawing
+ * that the X server is going to do
+ */
+ if (!(obj->event_mask & GDK_EXPOSURE_MASK))
+ return;
+
+ impl->position_info.no_bg = TRUE;
+
+// if (obj->bg_pixmap != GDK_NO_BG)
+// XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
+// GDK_DRAWABLE_XID (window), None);
+}
+
+
+void
+_gdk_macosx_window_tmp_unset_bg (GdkWindow *window,
+ gboolean recurse)
+{
+ GdkWindowObject *private;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ private = (GdkWindowObject *)window;
+
+ if (private->input_only || private->destroyed ||
+ (private->window_type != GDK_WINDOW_ROOT &&
+ !GDK_WINDOW_IS_MAPPED (window)))
+ {
+ return;
+ }
+
+ if (private->window_type != GDK_WINDOW_ROOT &&
+ private->window_type != GDK_WINDOW_FOREIGN)
+ {
+ tmp_unset_bg (window);
+ }
+
+ if (recurse)
+ {
+ GList *l;
+
+ for (l = private->children; l != NULL; l = l->next)
+ _gdk_macosx_window_tmp_unset_bg (l->data, TRUE);
+ }
+}
+
+#endif
+
+static GdkColormap*
+gdk_window_impl_macosx_get_colormap (GdkDrawable *drawable)
+{
+ GdkDrawableImplMacOSX *drawable_impl;
+
+ drawable_impl = GDK_DRAWABLE_IMPL_MACOSX (drawable);
+
+ if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
+ drawable_impl->colormap == NULL)
+ {
+ drawable_impl->colormap = gdk_screen_get_system_colormap (gdk_drawable_get_screen (drawable));
+ g_object_ref (drawable_impl->colormap);
+ }
+
+ return drawable_impl->colormap;
+}
+
+
+static void
+gdk_window_impl_macosx_set_colormap (GdkDrawable *drawable,
+ GdkColormap *cmap)
+{
+ GdkWindowImplMacOSX *impl;
+ GdkDrawableImplMacOSX *draw_impl;
+
+ g_return_if_fail (GDK_IS_WINDOW_IMPL_MACOSX (drawable));
+
+ impl = GDK_WINDOW_IMPL_MACOSX (drawable);
+ draw_impl = GDK_DRAWABLE_IMPL_MACOSX (drawable);
+
+ if (cmap && GDK_WINDOW_DESTROYED (draw_impl->wrapper))
+ return;
+
+ /* chain up */
+ GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
+}
+
+
+static void
+gdk_window_impl_macosx_get_size (GdkDrawable *drawable,
+ gint *width,
+ gint *height)
+{
+ g_return_if_fail (GDK_IS_WINDOW_IMPL_MACOSX (drawable));
+
+ if (width)
+ *width = GDK_WINDOW_IMPL_MACOSX (drawable)->width;
+ if (height)
+ *height = GDK_WINDOW_IMPL_MACOSX (drawable)->height;
+}
+
+static GdkRegion*
+gdk_window_impl_macosx_get_visible_region (GdkDrawable *drawable)
+{
+ GdkWindowImplMacOSX *impl = GDK_WINDOW_IMPL_MACOSX (drawable);
+ GdkRectangle result_rect;
+
+ result_rect.x = 0;
+ result_rect.y = 0;
+ result_rect.width = impl->width;
+ result_rect.height = impl->height;
+
+ gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
+
+ return gdk_region_rectangle (&result_rect);
+}
+
+void
+_gdk_windowing_window_init (GdkScreen * screen)
+{
+ GdkWindowObject *private;
+ GdkWindowImplMacOSX *impl;
+ GdkDrawableImplMacOSX *draw_impl;
+ GdkScreenMacOSX *screen_macosx;
+ NSRect *screen_frame;
+
+ screen_macosx = GDK_SCREEN_MACOSX (screen);
+
+ g_assert (screen_macosx->root_window == NULL);
+
+ gdk_screen_set_default_colormap (screen,
+ gdk_screen_get_system_colormap (screen));
+
+ screen_macosx->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
+ private = (GdkWindowObject *)screen_macosx->root_window;
+ impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+ draw_impl = GDK_DRAWABLE_IMPL_MACOSX (private->impl);
+
+ impl->v = NULL;
+
+ /* FIXME */
+ _gdk_window_init_position (GDK_WINDOW (private));
+}
+
+#if 0
+static const gchar *
+get_default_title (void)
+{
+ const char *title;
+
+ title = g_get_application_name ();
+ if (!title)
+ title = g_get_prgname ();
+
+ return title;
+}
+
+
+/**
+ * gdk_window_new:
+ * @parent: a #GdkWindow, or %NULL to create the window as a child of
+ * the default root window for the default display.
+ * @attributes: attributes of the new window
+ * @attributes_mask: mask indicating which fields in @attributes are valid
+ *
+ * Creates a new #GdkWindow using the attributes from
+ * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
+ * more details. Note: to use this on displays other than the default
+ * display, @parent must be specified.
+ *
+ * Return value: the new #GdkWindow
+ **/
+GdkWindow*
+gdk_window_new (GdkWindow *parent,
+ GdkWindowAttr *attributes,
+ gint attributes_mask)
+{
+ GdkWindow *window;
+ GdkWindowObject *private;
+ GdkWindowImplMacOSX *impl;
+ GdkDrawableImplMacOSX *draw_impl;
+ GdkScreenMacOSX *screen_macosx;
+ GdkScreen *screen;
+
+ GdkVisual *visual;
+
+ int x, y, depth;
+
+ unsigned int class;
+ const char *title;
+ int i;
+
+ NSRect bounds;
+ NSWindow *w;
+ GdkNSView *v;
+
+ g_return_val_if_fail (attributes != NULL, NULL);
+
+ if (!parent)
+ {
+ GDK_NOTE (MULTIHEAD,
+ g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
+
+ screen = gdk_screen_get_default ();
+ parent = gdk_screen_get_root_window (screen);
+ }
+ else
+ screen = gdk_drawable_get_screen (parent);
+
+ screen_macosx = GDK_SCREEN_MACOSX (screen);
+
+ g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
+
+ if (GDK_WINDOW_DESTROYED (parent))
+ return NULL;
+
+ window = g_object_new (GDK_TYPE_WINDOW, NULL);
+ private = (GdkWindowObject *)window;
+ impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+ draw_impl = GDK_DRAWABLE_IMPL_MACOSX (private->impl);
+ draw_impl->wrapper = GDK_DRAWABLE (window);
+
+ draw_impl->screen = screen;
+
+ /* Windows with a foreign parent are treated as if they are children
+ * of the root window, except for actual creation.
+ */
+ if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
+ parent = gdk_screen_get_root_window (screen);
+
+ private->parent = (GdkWindowObject *)parent;
+
+ private->accept_focus = TRUE;
+ private->focus_on_map = TRUE;
+
+ xattributes_mask = 0;
+
+ if (attributes_mask & GDK_WA_X)
+ x = attributes->x;
+ else
+ x = 0;
+
+ if (attributes_mask & GDK_WA_Y)
+ y = attributes->y;
+ else
+ y = 0;
+
+ private->x = x;
+ private->y = y;
+ impl->width = (attributes->width > 1) ? (attributes->width) : (1);
+ impl->height = (attributes->height > 1) ? (attributes->height) : (1);
+
+ if (attributes->wclass == GDK_INPUT_ONLY)
+ {
+ /* Backwards compatiblity - we've always ignored
+ * attributes->window_type for input-only windows
+ * before
+ */
+ if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
+ private->window_type = GDK_WINDOW_TEMP;
+ else
+ private->window_type = GDK_WINDOW_CHILD;
+ }
+ else
+ private->window_type = attributes->window_type;
+
+ _gdk_window_init_position (GDK_WINDOW (private));
+ if (impl->position_info.big)
+ private->guffaw_gravity = TRUE;
+
+ if (attributes_mask & GDK_WA_VISUAL)
+ visual = attributes->visual;
+ else
+ visual = gdk_screen_get_system_visual (screen);
+ xvisual = ((GdkVisualPrivate*) visual)->xvisual;
+
+ xattributes.event_mask = StructureNotifyMask | PropertyChangeMask;
+ for (i = 0; i < _gdk_nenvent_masks; i++)
+ {
+ if (attributes->event_mask & (1 << (i + 1)))
+ xattributes.event_mask |= _gdk_event_mask_table[i];
+ }
+ private->event_mask = attributes->event_mask;
+
+ if (xattributes.event_mask)
+ xattributes_mask |= CWEventMask;
+
+ if (attributes_mask & GDK_WA_NOREDIR)
+ {
+ xattributes.override_redirect =
+ (attributes->override_redirect == FALSE)?False:True;
+ xattributes_mask |= CWOverrideRedirect;
+ }
+ else
+ xattributes.override_redirect = False;
+
+ impl->override_redirect = xattributes.override_redirect;
+
+ if (private->parent && private->parent->guffaw_gravity)
+ {
+ xattributes.win_gravity = StaticGravity;
+ xattributes_mask |= CWWinGravity;
+ }
+
+ /* 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");
+ xparent = GDK_SCREEN_XROOTWIN (screen);
+ }
+ case GDK_WINDOW_CHILD:
+ break;
+ default:
+ g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
+ return NULL;
+ }
+
+ if (attributes->wclass == GDK_INPUT_OUTPUT)
+ {
+ class = InputOutput;
+ depth = visual->depth;
+
+ private->input_only = FALSE;
+ private->depth = depth;
+
+ if (attributes_mask & GDK_WA_COLORMAP)
+ {
+ draw_impl->colormap = attributes->colormap;
+ g_object_ref (attributes->colormap);
+ }
+ else
+ {
+ if ((((GdkVisualPrivate *)gdk_screen_get_system_visual (screen))->xvisual) == xvisual)
+ {
+ draw_impl->colormap = gdk_screen_get_system_colormap (screen);
+ g_object_ref (draw_impl->colormap);
+ }
+ else
+ {
+ draw_impl->colormap = gdk_colormap_new (visual, FALSE);
+ }
+ }
+
+ private->bg_color.pixel = BlackPixel (xdisplay, screen_macosx->screen_num);
+ xattributes.background_pixel = private->bg_color.pixel;
+
+ private->bg_pixmap = NULL;
+
+ xattributes.border_pixel = BlackPixel (xdisplay, screen_macosx->screen_num);
+ xattributes_mask |= CWBorderPixel | CWBackPixel;
+
+ if (private->guffaw_gravity)
+ xattributes.bit_gravity = StaticGravity;
+ else
+ xattributes.bit_gravity = NorthWestGravity;
+
+ xattributes_mask |= CWBitGravity;
+
+ xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
+ xattributes_mask |= CWColormap;
+
+ if (private->window_type == GDK_WINDOW_TEMP)
+ {
+ xattributes.save_under = True;
+ xattributes.override_redirect = True;
+ xattributes.cursor = None;
+ xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
+
+ impl->override_redirect = TRUE;
+ }
+ }
+ else
+ {
+ depth = 0;
+ private->depth = 0;
+ class = InputOnly;
+ private->input_only = TRUE;
+ draw_impl->colormap = gdk_screen_get_system_colormap (screen);
+ g_object_ref (draw_impl->colormap);
+ }
+
+ // FIXME, map Gdk to Cocoa window styles...
+ unsigned int style_mask = NSBorderlessWindowMask;
+
+ bounds = NSMakeRect(impl->position_info.x,
+ NSHeight([[NSScreen mainScreen] frame]) -
+ impl->position_info.y - impl->position_info.height,
+ impl->position_info.width, impl->position_info.height);
+
+
+ w = [[NSWindow alloc] initWithContentRect:bounds
+ styleMask:theStyleMask
+ backing:NSBackingStoreBuffered
+ defer:YES];
+ window_impl->w = w;
+
+ [w setBackgroundColor:[NSColor clearColor]]; // erase transparent
+ [w setAlphaValue:1.0]; // draw opaque
+ [w setOpaque:YES]; // changed when window is shaped
+
+ [w useOptimizedDrawing:YES]; // Has no overlapping sub-views
+ [w setAutodisplay:NO]; // See comment above
+ [w disableFlushWindow]; // We do all the flushing manually
+ [w setHasShadow:YES]; // All windows have shadows
+ [w setReleasedWhenClosed:YES]; // Default, but we want to be sure
+
+ v = [[GdkNSView alloc] initWithFrame:bounds];
+ [w setContentView:v];
+ [w setInitialFirstResponder:v];
+
+ draw_impl->v = v;
+
+// xid = draw_impl->xid = XCreateWindow (xdisplay, xparent,
+// impl->position_info.x, impl->position_info.y,
+// impl->position_info.width, impl->position_info.height,
+// 0, depth, class, xvisual,
+// xattributes_mask, &xattributes);
+
+ g_object_ref (window);
+ _gdk_nsview_table_insert(screen_macosx->display, &draw_impl->v, window);
+
+ gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
+ (attributes->cursor) :
+ NULL));
+
+ if (private->parent)
+ private->parent->children = g_list_prepend (private->parent->children, window);
+
+ switch (GDK_WINDOW_TYPE (private))
+ {
+ case GDK_WINDOW_DIALOG:
+ case GDK_WINDOW_TOPLEVEL:
+ case GDK_WINDOW_TEMP:
+ if (attributes_mask & GDK_WA_TITLE)
+ title = attributes->title;
+ else
+ title = get_default_title ();
+
+ gdk_window_set_title (window, title);
+
+ if (attributes_mask & GDK_WA_WMCLASS)
+ {
+ class_hint = XAllocClassHint ();
+ class_hint->res_name = attributes->wmclass_name;
+ class_hint->res_class = attributes->wmclass_class;
+ XSetClassHint (xdisplay, xid, class_hint);
+ XFree (class_hint);
+ }
+
+ setup_toplevel_window (window, parent);
+ break;
+
+ case GDK_WINDOW_CHILD:
+ if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
+ (draw_impl->colormap != gdk_screen_get_system_colormap (screen)) &&
+ (draw_impl->colormap != gdk_drawable_get_colormap (gdk_window_get_toplevel (window))))
+ {
+ GDK_NOTE (MISC, g_message ("adding colormap window\n"));
+ gdk_window_add_colormap_windows (window);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return window;
+}
+
+static GdkEventMask
+x_event_mask_to_gdk_event_mask (long mask)
+{
+ GdkEventMask event_mask = 0;
+ int i;
+
+ for (i = 0; i < _gdk_nenvent_masks; i++)
+ {
+ if (mask & _gdk_event_mask_table[i])
+ event_mask |= 1 << (i + 1);
+ }
+
+ return event_mask;
+}
+#endif
+
+/**
+ * gdk_window_foreign_new_for_display:
+ * @display: the #GdkDisplay where the window handle comes from.
+ * @anid: a native window handle.
+ *
+ * Wraps a native window in a #GdkWindow.
+ * This may fail if the window has been destroyed. If the window
+ * was already known to GDK, a new reference to the existing
+ * #GdkWindow is returned.
+ *
+ * For example in the X backend, a native window handle is an Xlib
+ * <type>XID</type>.
+ *
+ * Return value: a #GdkWindow wrapper for the native window or
+ * %NULL if the window has been destroyed. The wrapper will be
+ * newly created, if one doesn't exist already.
+ *
+ * Since: 2.2
+ **/
+GdkWindow *
+gdk_window_foreign_new_for_display (GdkDisplay *display,
+ GdkNativeWindow anid)
+{
+ GdkWindow *window;
+ GdkWindowObject *private;
+ GdkWindowImplMacOSX *impl;
+ GdkDrawableImplMacOSX *draw_impl;
+ GdkDisplayMacOSX *display_macosx;
+ NSRect frame;
+ NSWindowDepth wdepth;
+
+ guint nchildren;
+ gboolean result;
+
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+ display_macosx = GDK_DISPLAY_MACOSX (display);
+
+ if ((window = gdk_nsview_table_lookup_for_display(display, anid)) != NULL)
+ return g_object_ref (window);
+
+ window = g_object_new (GDK_TYPE_WINDOW, NULL);
+ private = (GdkWindowObject *)window;
+ impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+ draw_impl = GDK_DRAWABLE_IMPL_MACOSX (private->impl);
+ draw_impl->wrapper = GDK_DRAWABLE (window);
+
+ private->parent = gdk_nsview_table_lookup_for_display(display, [(NSView *)anid superview]);
+
+ if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
+ private->parent = _gdk_parent_root;
+
+ private->parent->children = g_list_prepend (private->parent->children, window);
+
+ impl->v = anid;
+
+ frame = [impl->v frame];
+ private->x = frame.origin.x;
+ private->y = frame.origin.y;
+ impl->width = frame.size.width;
+ impl->height = frame.size.height;
+ private->window_type = GDK_WINDOW_FOREIGN;
+ private->destroyed = FALSE;
+
+ // FIXME
+ private->event_mask = 0; //x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
+/*
+ if (attrs.map_state == IsUnmapped)
+ private->state = GDK_WINDOW_STATE_WITHDRAWN;
+ else */
+ private->state = 0;
+
+ wdepth = [[(NSView *)anid window] depthLimit];
+ private->depth = NSBitsPerPixelFromDepth(wdepth);
+
+ _gdk_window_init_position (GDK_WINDOW (private));
+
+ g_object_ref (window);
+ _gdk_nsview_table_insert(display, GDK_WINDOW_NSVIEW (window), window);
+ return window;
+}
+
+#if 0
+/**
+ * gdk_window_lookup_for_display:
+ * @display: the #GdkDisplay corresponding to the window handle
+ * @anid: a native window handle.
+ *
+ * Looks up the #GdkWindow that wraps the given native window handle.
+ *
+ * For example in the X backend, a native window handle is an Xlib
+ * <type>XID</type>.
+ *
+ * Return value: the #GdkWindow wrapper for the native window,
+ * or %NULL if there is none.
+ *
+ * Since: 2.2
+ **/
+GdkWindow *
+gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
+{
+ return (GdkWindow*) gdk_xid_table_lookup_for_display (display, anid);
+}
+
+/**
+ * gdk_window_lookup:
+ * @anid: a native window handle.
+ *
+ * Looks up the #GdkWindow that wraps the given native window handle.
+ *
+ * For example in the X backend, a native window handle is an Xlib
+ * <type>XID</type>.
+ *
+ * Return value: the #GdkWindow wrapper for the native window,
+ * or %NULL if there is none.
+ **/
+GdkWindow *
+gdk_window_lookup (GdkNativeWindow anid)
+{
+ return (GdkWindow*) gdk_xid_table_lookup (anid);
+}
+
+static void
+gdk_toplevel_macosx_free_contents (GdkDisplay *display,
+ GdkToplevelMacOSX *toplevel)
+{
+ if (toplevel->icon_window)
+ {
+ g_object_unref (toplevel->icon_window);
+ toplevel->icon_window = NULL;
+ }
+ if (toplevel->icon_pixmap)
+ {
+ g_object_unref (toplevel->icon_pixmap);
+ toplevel->icon_pixmap = NULL;
+ }
+ if (toplevel->icon_mask)
+ {
+ g_object_unref (toplevel->icon_mask);
+ toplevel->icon_mask = NULL;
+ }
+ if (toplevel->group_leader)
+ {
+ g_object_unref (toplevel->group_leader);
+ toplevel->group_leader = NULL;
+ }
+#ifdef HAVE_XSYNC
+ if (toplevel->update_counter != None)
+ {
+ XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display),
+ toplevel->update_counter);
+ toplevel->update_counter = None;
+
+ XSyncIntToValue (&toplevel->current_counter_value, 0);
+ }
+#endif
+}
+
+void
+_gdk_windowing_window_destroy (GdkWindow *window,
+ gboolean recursing,
+ gboolean foreign_destroy)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkToplevelMacOSX *toplevel;
+ GdkDrawableImplMacOSX *draw_impl;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ _gdk_selection_window_destroyed (window);
+
+ if (private->extension_events != 0)
+ _gdk_input_window_destroy (window);
+
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+ if (toplevel)
+ gdk_toplevel_macosx_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
+
+ draw_impl = GDK_DRAWABLE_IMPL_MACOSX (private->impl);
+
+ if (draw_impl->xft_draw)
+ XftDrawDestroy (draw_impl->xft_draw);
+
+ if (!recursing && !foreign_destroy)
+ {
+ XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
+ }
+}
+
+void
+_gdk_windowing_window_destroy_foreign (GdkWindow *window)
+{
+ /* It's somebody else's window, but in our heirarchy,
+ * so reparent it to the root window, and then send
+ * it a delete event, as if we were a WM
+ */
+ XClientMessageEvent xevent;
+
+ gdk_error_trap_push ();
+ gdk_window_hide (window);
+ gdk_window_reparent (window, NULL, 0, 0);
+
+ xevent.type = ClientMessage;
+ xevent.window = GDK_WINDOW_XID (window);
+ xevent.message_type = gdk_macosx_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+ "WM_PROTOCOLS");
+ xevent.format = 32;
+ xevent.data.l[0] = gdk_macosx_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+ "WM_DELETE_WINDOW");
+ xevent.data.l[1] = CurrentTime;
+ xevent.data.l[2] = 0;
+ xevent.data.l[3] = 0;
+ xevent.data.l[4] = 0;
+
+ XSendEvent (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ False, 0, (XEvent *)&xevent);
+ gdk_display_sync (GDK_WINDOW_DISPLAY (window));
+ gdk_error_trap_pop ();
+}
+
+static GdkWindow *
+get_root (GdkWindow *window)
+{
+ GdkScreen *screen = gdk_drawable_get_screen (window);
+
+ return gdk_screen_get_root_window (screen);
+}
+
+/* This function is called when the XWindow is really gone.
+ */
+void
+gdk_window_destroy_notify (GdkWindow *window)
+{
+ GdkWindowImplMacOSX *window_impl;
+
+ g_return_if_fail (window != NULL);
+
+ window_impl = GDK_WINDOW_IMPL_MACOSX (((GdkWindowObject *)window)->impl);
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
+ g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
+
+ _gdk_window_destroy (window, TRUE);
+ }
+
+ _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), GDK_WINDOW_XID (window));
+ if (window_impl->toplevel && window_impl->toplevel->focus_window)
+ _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), window_impl->toplevel->focus_window);
+
+ _gdk_xgrab_check_destroy (window);
+
+ g_object_unref (window);
+}
+
+static void
+update_wm_hints (GdkWindow *window,
+ gboolean force)
+{
+ GdkToplevelMacOSX *toplevel = _gdk_macosx_window_get_toplevel (window);
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+ XWMHints wm_hints;
+
+ if (!force &&
+ !toplevel->is_leader &&
+ private->state & GDK_WINDOW_STATE_WITHDRAWN)
+ return;
+
+ wm_hints.flags = StateHint | InputHint;
+ wm_hints.input = private->accept_focus ? True : False;
+ wm_hints.initial_state = NormalState;
+
+ if (private->state & GDK_WINDOW_STATE_ICONIFIED)
+ {
+ wm_hints.flags |= StateHint;
+ wm_hints.initial_state = IconicState;
+ }
+
+ if (toplevel->icon_window && !GDK_WINDOW_DESTROYED (toplevel->icon_window))
+ {
+ wm_hints.flags |= IconWindowHint;
+ wm_hints.icon_window = GDK_WINDOW_XID (toplevel->icon_window);
+ }
+
+ if (toplevel->icon_pixmap)
+ {
+ wm_hints.flags |= IconPixmapHint;
+ wm_hints.icon_pixmap = GDK_PIXMAP_XID (toplevel->icon_pixmap);
+ }
+
+ if (toplevel->icon_mask)
+ {
+ wm_hints.flags |= IconMaskHint;
+ wm_hints.icon_mask = GDK_PIXMAP_XID (toplevel->icon_mask);
+ }
+
+ wm_hints.flags |= WindowGroupHint;
+ if (toplevel->group_leader && !GDK_WINDOW_DESTROYED (toplevel->group_leader))
+ {
+ wm_hints.flags |= WindowGroupHint;
+ wm_hints.window_group = GDK_WINDOW_XID (toplevel->group_leader);
+ }
+ else
+ wm_hints.window_group = GDK_DISPLAY_MACOSX (display)->leader_window;
+
+ XSetWMHints (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &wm_hints);
+}
+
+static void
+set_initial_hints (GdkWindow *window)
+{
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ Window xwindow = GDK_WINDOW_XID (window);
+ GdkWindowObject *private;
+ GdkToplevelMacOSX *toplevel;
+ Atom atoms[7];
+ gint i;
+
+ private = (GdkWindowObject*) window;
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+
+ if (!toplevel)
+ return;
+
+ update_wm_hints (window, TRUE);
+
+ /* We set the spec hints regardless of whether the spec is supported,
+ * since it can't hurt and it's kind of expensive to check whether
+ * it's supported.
+ */
+
+ i = 0;
+
+ if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
+ {
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_MAXIMIZED_VERT");
+ ++i;
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_MAXIMIZED_HORZ");
+ ++i;
+ }
+
+ if (private->state & GDK_WINDOW_STATE_ABOVE)
+ {
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_ABOVE");
+ ++i;
+ }
+
+ if (private->state & GDK_WINDOW_STATE_BELOW)
+ {
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_BELOW");
+ ++i;
+ }
+
+ if (private->state & GDK_WINDOW_STATE_STICKY)
+ {
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_STICKY");
+ ++i;
+ }
+
+ if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_FULLSCREEN");
+ ++i;
+ }
+
+ if (private->modal_hint)
+ {
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_MODAL");
+ ++i;
+ }
+
+ if (toplevel->skip_taskbar_hint)
+ {
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_SKIP_TASKBAR");
+ ++i;
+ }
+
+ if (toplevel->skip_pager_hint)
+ {
+ atoms[i] = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_WM_STATE_SKIP_PAGER");
+ ++i;
+ }
+
+ if (i > 0)
+ {
+ XChangeProperty (xdisplay,
+ xwindow,
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+ XA_ATOM, 32, PropModeReplace,
+ (guchar*) atoms, i);
+ }
+ else
+ {
+ XDeleteProperty (xdisplay,
+ xwindow,
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_STATE"));
+ }
+
+ if (private->state & GDK_WINDOW_STATE_STICKY)
+ {
+ atoms[0] = 0xFFFFFFFF;
+ XChangeProperty (xdisplay,
+ xwindow,
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
+ XA_CARDINAL, 32, PropModeReplace,
+ (guchar*) atoms, 1);
+ }
+ else
+ {
+ XDeleteProperty (xdisplay,
+ xwindow,
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"));
+ }
+
+ toplevel->map_serial = NextRequest (xdisplay);
+}
+
+static void
+show_window_internal (GdkWindow *window,
+ gboolean raise)
+{
+ GdkWindowObject *private;
+ GdkDisplay *display;
+ GdkDisplayMacOSX *display_macosx;
+ GdkToplevelMacOSX *toplevel;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ private = (GdkWindowObject*) window;
+ if (!private->destroyed)
+ {
+ GdkWindowImplMacOSX *impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+ Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
+ Window xwindow = GDK_WINDOW_XID (window);
+
+ if (raise)
+ XRaiseWindow (xdisplay, xwindow);
+
+ if (!GDK_WINDOW_IS_MAPPED (window))
+ {
+ set_initial_hints (window);
+
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_WITHDRAWN,
+ 0);
+ }
+
+ g_assert (GDK_WINDOW_IS_MAPPED (window));
+
+ if (WINDOW_IS_TOPLEVEL (window))
+ {
+ display = gdk_drawable_get_display (window);
+ display_macosx = GDK_DISPLAY_MACOSX (display);
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+
+ if (toplevel->user_time != 0 &&
+ display_macosx->user_time != 0 &&
+ XSERVER_TIME_IS_LATER (display_macosx->user_time, toplevel->user_time))
+ gdk_macosx_window_set_user_time (window, display_macosx->user_time);
+ }
+
+ if (impl->position_info.mapped)
+ {
+ gboolean unset_bg = !private->input_only &&
+ (private->window_type == GDK_WINDOW_CHILD ||
+ impl->override_redirect) &&
+ gdk_window_is_viewable (window);
+
+ if (unset_bg)
+ _gdk_macosx_window_tmp_unset_bg (window, TRUE);
+
+ XMapWindow (xdisplay, xwindow);
+
+ if (unset_bg)
+ {
+ _gdk_macosx_window_tmp_reset_bg (window, TRUE);
+ gdk_window_invalidate_rect (window, NULL, TRUE);
+ }
+ }
+ }
+}
+
+/**
+ * gdk_window_show_unraised:
+ * @window: a #GdkWindow
+ *
+ * Shows a #GdkWindow onscreen, but does not modify its stacking
+ * order. In contrast, gdk_window_show() will raise the window
+ * to the top of the window stack.
+ *
+ * On the MACOSX platform, in Xlib terms, this function calls
+ * XMapWindow() (it also updates some internal GDK state, which means
+ * that you can't really use XMapWindow() directly on a GDK window).
+ *
+ **/
+void
+gdk_window_show_unraised (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ show_window_internal (window, FALSE);
+}
+
+/**
+ * gdk_window_show:
+ * @window: a #GdkWindow
+ *
+ * Like gdk_window_show_unraised(), but also raises the window to the
+ * top of the window stack (moves the window to the front of the
+ * Z-order).
+ *
+ * This function maps a window so it's visible onscreen. Its opposite
+ * is gdk_window_hide().
+ *
+ * When implementing a #GtkWidget, you should call this function on the widget's
+ * #GdkWindow as part of the "map" method.
+ *
+ **/
+void
+gdk_window_show (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ show_window_internal (window, TRUE);
+}
+
+static void
+pre_unmap (GdkWindow *window)
+{
+ GdkWindow *start_window = NULL;
+ GdkWindowObject *private = (GdkWindowObject *)window;
+
+ if (private->input_only)
+ return;
+
+ if (private->window_type == GDK_WINDOW_CHILD)
+ start_window = (GdkWindow *)private->parent;
+ else if (private->window_type == GDK_WINDOW_TEMP)
+ start_window = get_root (window);
+
+ if (start_window)
+ _gdk_macosx_window_tmp_unset_bg (start_window, TRUE);
+}
+
+static void
+post_unmap (GdkWindow *window)
+{
+ GdkWindow *start_window = NULL;
+ GdkWindowObject *private = (GdkWindowObject *)window;
+
+ if (private->input_only)
+ return;
+
+ if (private->window_type == GDK_WINDOW_CHILD)
+ start_window = (GdkWindow *)private->parent;
+ else if (private->window_type == GDK_WINDOW_TEMP)
+ start_window = get_root (window);
+
+ if (start_window)
+ {
+ _gdk_macosx_window_tmp_reset_bg (start_window, TRUE);
+
+ if (private->window_type == GDK_WINDOW_CHILD && private->parent)
+ {
+ GdkRectangle invalid_rect;
+
+ gdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y);
+ gdk_drawable_get_size (GDK_DRAWABLE (window),
+ &invalid_rect.width, &invalid_rect.height);
+ gdk_window_invalidate_rect ((GdkWindow *)private->parent,
+ &invalid_rect, TRUE);
+ }
+ }
+}
+
+/**
+ * gdk_window_hide:
+ * @window: a #GdkWindow
+ *
+ * For toplevel windows, withdraws them, so they will no longer be
+ * known to the window manager; for all windows, unmaps them, so
+ * they won't be displayed. Normally done automatically as
+ * part of gtk_widget_hide().
+ *
+ **/
+void
+gdk_window_hide (GdkWindow *window)
+{
+ GdkWindowObject *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowObject*) window;
+
+ /* We'll get the unmap notify eventually, and handle it then,
+ * but checking here makes things more consistent if we are
+ * just doing stuff ourself.
+ */
+ _gdk_xgrab_check_unmap (window,
+ NextRequest (GDK_WINDOW_XDISPLAY (window)));
+
+ /* You can't simply unmap toplevel windows. */
+ switch (private->window_type)
+ {
+ case GDK_WINDOW_TOPLEVEL:
+ case GDK_WINDOW_DIALOG:
+ case GDK_WINDOW_TEMP: /* ? */
+ gdk_window_withdraw (window);
+ return;
+ break;
+
+ case GDK_WINDOW_FOREIGN:
+ case GDK_WINDOW_ROOT:
+ case GDK_WINDOW_CHILD:
+ break;
+ }
+
+ if (!private->destroyed)
+ {
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_WITHDRAWN);
+
+ g_assert (!GDK_WINDOW_IS_MAPPED (window));
+
+ _gdk_window_clear_update_area (window);
+
+ pre_unmap (window);
+
+ XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window));
+
+ post_unmap (window);
+ }
+}
+
+/**
+ * gdk_window_withdraw:
+ * @window: a toplevel #GdkWindow
+ *
+ * Withdraws a window (unmaps it and asks the window manager to forget about it).
+ * This function is not really useful as gdk_window_hide() automatically
+ * withdraws toplevel windows before hiding them.
+ *
+ **/
+void
+gdk_window_withdraw (GdkWindow *window)
+{
+ GdkWindowObject *private;
+
+ g_return_if_fail (window != NULL);
+
+ private = (GdkWindowObject*) window;
+ if (!private->destroyed)
+ {
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_WITHDRAWN);
+
+ g_assert (!GDK_WINDOW_IS_MAPPED (window));
+
+ pre_unmap (window);
+
+ XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window), 0);
+
+ post_unmap (window);
+ }
+}
+
+/**
+ * gdk_window_move:
+ * @window: a #GdkWindow
+ * @x: X coordinate relative to window's parent
+ * @y: Y coordinate relative to window's parent
+ *
+ * Repositions a window relative to its parent window.
+ * For toplevel windows, window managers may ignore or modify the move;
+ * you should probably use gtk_window_move() on a #GtkWindow widget
+ * anyway, instead of using GDK functions. For child windows,
+ * the move will reliably succeed.
+ *
+ * If you're also planning to resize the window, use gdk_window_move_resize()
+ * to both move and resize simultaneously, for a nicer visual effect.
+ **/
+void
+gdk_window_move (GdkWindow *window,
+ gint x,
+ gint y)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindowImplMacOSX *impl;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
+ {
+ _gdk_window_move_resize_child (window, x, y,
+ impl->width, impl->height);
+ }
+ else
+ {
+ XMoveWindow (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ x, y);
+
+ if (impl->override_redirect)
+ {
+ private->x = x;
+ private->y = y;
+ }
+ }
+ }
+}
+
+/**
+ * gdk_window_resize:
+ * @window: a #GdkWindow
+ * @width: new width of the window
+ * @height: new height of the window
+ *
+ * Resizes @window; for toplevel windows, asks the window manager to resize
+ * the window. The window manager may not allow the resize. When using GTK+,
+ * use gtk_window_resize() instead of this low-level GDK function.
+ *
+ * Windows may not be resized below 1x1.
+ *
+ * If you're also planning to move the window, use gdk_window_move_resize()
+ * to both move and resize simultaneously, for a nicer visual effect.
+ **/
+void
+gdk_window_resize (GdkWindow *window,
+ gint width,
+ gint height)
+{
+ GdkWindowObject *private;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (width < 1)
+ width = 1;
+ if (height < 1)
+ height = 1;
+
+ private = (GdkWindowObject*) window;
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
+ {
+ _gdk_window_move_resize_child (window, private->x, private->y,
+ width, height);
+ }
+ else
+ {
+ GdkWindowImplMacOSX *impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+
+ XResizeWindow (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ width, height);
+
+ if (impl->override_redirect)
+ {
+ impl->width = width;
+ impl->height = height;
+ }
+ else
+ {
+ if (width != impl->width || height != impl->height)
+ private->resize_count += 1;
+ }
+ }
+ }
+}
+
+/**
+ * gdk_window_move_resize:
+ * @window: a #GdkWindow
+ * @x: new X position relative to window's parent
+ * @y: new Y position relative to window's parent
+ * @width: new width
+ * @height: new height
+ *
+ * Equivalent to calling gdk_window_move() and gdk_window_resize(),
+ * except that both operations are performed at once, avoiding strange
+ * visual effects. (i.e. the user may be able to see the window first
+ * move, then resize, if you don't use gdk_window_move_resize().)
+ **/
+void
+gdk_window_move_resize (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GdkWindowObject *private;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (width < 1)
+ width = 1;
+ if (height < 1)
+ height = 1;
+
+ private = (GdkWindowObject*) window;
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
+ {
+ _gdk_window_move_resize_child (window, x, y, width, height);
+ }
+ else
+ {
+ GdkWindowImplMacOSX *impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+
+ XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ x, y, width, height);
+ if (impl->override_redirect)
+ {
+ private->x = x;
+ private->y = y;
+ impl->width = width;
+ impl->height = height;
+ }
+ else
+ {
+ if (width != impl->width || height != impl->height)
+ private->resize_count += 1;
+ }
+ }
+ }
+}
+
+/**
+ * gdk_window_reparent:
+ * @window: a #GdkWindow
+ * @new_parent: new parent to move @window into
+ * @x: X location inside the new parent
+ * @y: Y location inside the new parent
+ *
+ * Reparents @window into the given @new_parent. The window being
+ * reparented will be unmapped as a side effect.
+ *
+ **/
+void
+gdk_window_reparent (GdkWindow *window,
+ GdkWindow *new_parent,
+ gint x,
+ gint y)
+{
+ GdkDisplay *display;
+ GdkWindowObject *window_private;
+ GdkWindowObject *parent_private;
+ GdkWindowObject *old_parent_private;
+ GdkWindowImplMacOSX *impl;
+ gboolean was_toplevel;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
+ g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
+
+ if (GDK_WINDOW_DESTROYED (window) ||
+ (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
+ {
+ return;
+ }
+
+ if (!new_parent)
+ new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
+
+ display = GDK_WINDOW_DISPLAY (window);
+
+ window_private = (GdkWindowObject*) window;
+ old_parent_private = (GdkWindowObject*)window_private->parent;
+ parent_private = (GdkWindowObject*) new_parent;
+ impl = GDK_WINDOW_IMPL_MACOSX (window_private->impl);
+
+ XReparentWindow (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ GDK_WINDOW_XID (new_parent),
+ x, y);
+
+ window_private->x = x;
+ window_private->y = y;
+
+ /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
+ * the root window
+ */
+ if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
+ new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
+
+ window_private->parent = (GdkWindowObject *)new_parent;
+
+ /* Switch the window type as appropriate */
+
+ switch (GDK_WINDOW_TYPE (new_parent))
+ {
+ case GDK_WINDOW_ROOT:
+ case GDK_WINDOW_FOREIGN:
+ was_toplevel = WINDOW_IS_TOPLEVEL (window);
+
+ if (impl->toplevel_window_type != -1)
+ GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
+ else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
+ GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
+
+ if (WINDOW_IS_TOPLEVEL (window) && !was_toplevel)
+ setup_toplevel_window (window, new_parent);
+ break;
+ case GDK_WINDOW_TOPLEVEL:
+ case GDK_WINDOW_CHILD:
+ case GDK_WINDOW_DIALOG:
+ case GDK_WINDOW_TEMP:
+ if (WINDOW_IS_TOPLEVEL (window))
+ {
+ /* Save the original window type so we can restore it if the
+ * window is reparented back to be a toplevel
+ */
+ impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
+ GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
+ if (impl->toplevel)
+ {
+ if (impl->toplevel->focus_window)
+ {
+ XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window);
+ _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
+ }
+
+ gdk_toplevel_macosx_free_contents (GDK_WINDOW_DISPLAY (window),
+ impl->toplevel);
+ g_free (impl->toplevel);
+ impl->toplevel = NULL;
+ }
+ }
+ }
+
+ if (old_parent_private)
+ old_parent_private->children = g_list_remove (old_parent_private->children, window);
+
+ if ((old_parent_private &&
+ (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
+ (!old_parent_private && parent_private->guffaw_gravity))
+ gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
+
+ parent_private->children = g_list_prepend (parent_private->children, window);
+ _gdk_window_init_position (GDK_WINDOW (window_private));
+}
+#endif
+
+void
+_gdk_windowing_window_clear_area (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (!GDK_WINDOW_DESTROYED (window)) {
+ CGRect rect = CGRectMake(x,y,width,height);
+ CGContextRef context = [GDK_WINDOW_NSVIEW(window) cg];
+ CGContextClearRect(context, rect);
+ }
+}
+
+void
+_gdk_windowing_window_clear_area_e (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (!GDK_WINDOW_DESTROYED (window)) {
+ CGRect rect = CGRectMake(x,y,width,height);
+ CGContextRef context = [GDK_WINDOW_NSVIEW(window) cg];
+ CGContextClearRect(context, rect);
+ [GDK_WINDOW_NSVIEW(window) setNeedsDisplayInRect:NSMakeRect(x,y,width,height)];
+ }
+}
+
+
+#if 0
+/**
+ * gdk_window_raise:
+ * @window: a #GdkWindow
+ *
+ * Raises @window to the top of the Z-order (stacking order), so that
+ * other windows with the same parent window appear below @window.
+ * This is true whether or not the windows are visible.
+ *
+ * If @window is a toplevel, the window manager may choose to deny the
+ * request to move the window in the Z-order, gdk_window_raise() only
+ * requests the restack, does not guarantee it.
+ *
+ **/
+void
+gdk_window_raise (GdkWindow *window)
+{
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
+}
+
+/**
+ * gdk_window_lower:
+ * @window: a #GdkWindow
+ *
+ * Lowers @window to the bottom of the Z-order (stacking order), so that
+ * other windows with the same parent window appear above @window.
+ * This is true whether or not the other windows are visible.
+ *
+ * If @window is a toplevel, the window manager may choose to deny the
+ * request to move the window in the Z-order, gdk_window_lower() only
+ * requests the restack, does not guarantee it.
+ *
+ * Note that gdk_window_show() raises the window again, so don't call this
+ * function before gdk_window_show(). (Try gdk_window_show_unraised().)
+ *
+ **/
+void
+gdk_window_lower (GdkWindow *window)
+{
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
+}
+
+/**
+ * gdk_window_focus:
+ * @window: a #GdkWindow
+ * @timestamp: timestamp of the event triggering the window focus
+ *
+ * Sets keyboard focus to @window. If @window is not onscreen this
+ * will not work. In most cases, gtk_window_present() should be used on
+ * a #GtkWindow, rather than calling this function.
+ *
+ **/
+void
+gdk_window_focus (GdkWindow *window,
+ guint32 timestamp)
+{
+ GdkDisplay *display;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ display = GDK_WINDOW_DISPLAY (window);
+
+ if (gdk_macosx_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
+ gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
+ {
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = GDK_WINDOW_XWINDOW (window);
+ xev.xclient.message_type = gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_ACTIVE_WINDOW");
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1; /* requestor type; we're an app */
+ xev.xclient.data.l[1] = timestamp;
+ xev.xclient.data.l[2] = None; /* currently active window */
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+ }
+ else
+ {
+ XRaiseWindow (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window));
+
+ /* There is no way of knowing reliably whether we are viewable;
+ * _gdk_macosx_set_input_focus_safe() traps errors asynchronously.
+ */
+ _gdk_macosx_set_input_focus_safe (display, GDK_WINDOW_XID (window),
+ RevertToParent,
+ timestamp);
+ }
+}
+
+/**
+ * gdk_window_set_hints:
+ * @window: a #GdkWindow
+ * @x: ignored field, does not matter
+ * @y: ignored field, does not matter
+ * @min_width: minimum width hint
+ * @min_height: minimum height hint
+ * @max_width: max width hint
+ * @max_height: max height hint
+ * @flags: logical OR of GDK_HINT_POS, GDK_HINT_MIN_SIZE, and/or GDK_HINT_MAX_SIZE
+ *
+ * This function is broken and useless and you should ignore it.
+ * If using GTK+, use functions such as gtk_window_resize(), gtk_window_set_size_request(),
+ * gtk_window_move(), gtk_window_parse_geometry(), and gtk_window_set_geometry_hints(),
+ * depending on what you're trying to do.
+ *
+ * If using GDK directly, use gdk_window_set_geometry_hints().
+ *
+ **/
+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)
+{
+ XSizeHints size_hints;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ size_hints.flags = 0;
+
+ if (flags & GDK_HINT_POS)
+ {
+ size_hints.flags |= PPosition;
+ size_hints.x = x;
+ size_hints.y = y;
+ }
+
+ if (flags & GDK_HINT_MIN_SIZE)
+ {
+ size_hints.flags |= PMinSize;
+ size_hints.min_width = min_width;
+ size_hints.min_height = min_height;
+ }
+
+ if (flags & GDK_HINT_MAX_SIZE)
+ {
+ size_hints.flags |= PMaxSize;
+ size_hints.max_width = max_width;
+ size_hints.max_height = max_height;
+ }
+
+ /* FIXME: Would it be better to delete this property if
+ * flags == 0? It would save space on the server
+ */
+ XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &size_hints);
+}
+
+/**
+ * gdk_window_set_type_hint:
+ * @window: A toplevel #GdkWindow
+ * @hint: A hint of the function this window will have
+ *
+ * The application can use this call to provide a hint to the window
+ * manager about the functionality of a window. The window manager
+ * can use this information when determining the decoration and behaviour
+ * of the window.
+ *
+ * The hint must be set before the window is mapped.
+ **/
+void
+gdk_window_set_type_hint (GdkWindow *window,
+ GdkWindowTypeHint hint)
+{
+ GdkDisplay *display;
+ Atom atom;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ display = gdk_drawable_get_display (window);
+
+ switch (hint)
+ {
+ case GDK_WINDOW_TYPE_HINT_DIALOG:
+ atom = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG");
+ break;
+ case GDK_WINDOW_TYPE_HINT_MENU:
+ atom = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU");
+ break;
+ case GDK_WINDOW_TYPE_HINT_TOOLBAR:
+ atom = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR");
+ break;
+ case GDK_WINDOW_TYPE_HINT_UTILITY:
+ atom = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY");
+ break;
+ case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+ atom = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH");
+ break;
+ case GDK_WINDOW_TYPE_HINT_DOCK:
+ atom = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK");
+ break;
+ case GDK_WINDOW_TYPE_HINT_DESKTOP:
+ atom = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
+ break;
+ default:
+ g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
+ /* Fall thru */
+ case GDK_WINDOW_TYPE_HINT_NORMAL:
+ atom = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NORMAL");
+ break;
+ }
+
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
+ XA_ATOM, 32, PropModeReplace,
+ (guchar *)&atom, 1);
+}
+
+
+static void
+gdk_wmspec_change_state (gboolean add,
+ GdkWindow *window,
+ GdkAtom state1,
+ GdkAtom state2)
+{
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+ XEvent xev;
+
+#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
+#define _NET_WM_STATE_ADD 1 /* add/set property */
+#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = GDK_WINDOW_XID (window);
+ xev.xclient.message_type = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_STATE");
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
+ xev.xclient.data.l[1] = gdk_macosx_atom_to_xatom_for_display (display, state1);
+ xev.xclient.data.l[2] = gdk_macosx_atom_to_xatom_for_display (display, state2);
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+/**
+ * gdk_window_set_modal_hint:
+ * @window: A toplevel #GdkWindow
+ * @modal: TRUE if the window is modal, FALSE otherwise.
+ *
+ * The application can use this hint to tell the window manager
+ * that a certain window has modal behaviour. The window manager
+ * can use this information to handle modal windows in a special
+ * way.
+ *
+ * You should only use this on windows for which you have
+ * previously called #gdk_window_set_transient_for()
+ **/
+void
+gdk_window_set_modal_hint (GdkWindow *window,
+ gboolean modal)
+{
+ GdkWindowObject *private;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ private = (GdkWindowObject*) window;
+
+ private->modal_hint = modal;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_wmspec_change_state (modal, window,
+ gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE),
+ NULL);
+}
+
+/**
+ * gdk_window_set_skip_taskbar_hint:
+ * @window: a toplevel #GdkWindow
+ * @skips_taskbar: %TRUE to skip the taskbar
+ *
+ * Toggles whether a window should appear in a task list or window
+ * list. If a window's semantic type as specified with
+ * gdk_window_set_type_hint() already fully describes the window, this
+ * function should NOT be called in addition, instead you should allow
+ * the window to be treated according to standard policy for its
+ * semantic type.
+ *
+ * Since: 2.2
+ **/
+void
+gdk_window_set_skip_taskbar_hint (GdkWindow *window,
+ gboolean skips_taskbar)
+{
+ GdkToplevelMacOSX *toplevel;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+ toplevel->skip_taskbar_hint = skips_taskbar;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_wmspec_change_state (skips_taskbar, window,
+ gdk_atom_intern ("_NET_WM_STATE_SKIP_TASKBAR", FALSE),
+ NULL);
+}
+
+/**
+ * gdk_window_set_skip_pager_hint:
+ * @window: a toplevel #GdkWindow
+ * @skips_pager: %TRUE to skip the pager
+ *
+ * Toggles whether a window should appear in a pager (workspace
+ * switcher, or other desktop utility program that displays a small
+ * thumbnail representation of the windows on the desktop). If a
+ * window's semantic type as specified with gdk_window_set_type_hint()
+ * already fully describes the window, this function should NOT be
+ * called in addition, instead you should allow the window to be
+ * treated according to standard policy for its semantic type.
+ *
+ * Since: 2.2
+ **/
+void
+gdk_window_set_skip_pager_hint (GdkWindow *window,
+ gboolean skips_pager)
+{
+ GdkToplevelMacOSX *toplevel;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+ toplevel->skip_pager_hint = skips_pager;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_wmspec_change_state (skips_pager, window,
+ gdk_atom_intern ("_NET_WM_STATE_SKIP_PAGER", FALSE),
+ NULL);
+}
+
+/**
+ * gdk_window_set_geometry_hints:
+ * @window: a toplevel #GdkWindow
+ * @geometry: geometry hints
+ * @geom_mask: bitmask indicating fields of @geometry to pay attention to
+ *
+ * Sets the geometry hints for @window. Hints flagged in @geom_mask
+ * are set, hints not flagged in @geom_mask are unset.
+ * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
+ *
+ * This function provides hints to the windowing system about
+ * acceptable sizes for a toplevel window. The purpose of
+ * this is to constrain user resizing, but the windowing system
+ * will typically (but is not required to) also constrain the
+ * current size of the window to the provided values and
+ * constrain programatic resizing via gdk_window_resize() or
+ * gdk_window_move_resize().
+ *
+ * Note that on X11, this effect has no effect on windows
+ * of type GDK_WINDOW_TEMP or windows where override_redirect
+ * has been turned on via gdk_window_set_override_redirect()
+ * since these windows are not resizable by the user.
+ *
+ * Since you can't count on the windowing system doing the
+ * constraints for programmatic resizes, you should generally
+ * call gdk_window_constrain_size() yourself to determine
+ * appropriate sizes.
+ *
+ **/
+void
+gdk_window_set_geometry_hints (GdkWindow *window,
+ GdkGeometry *geometry,
+ GdkWindowHints geom_mask)
+{
+ XSizeHints size_hints;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ size_hints.flags = 0;
+
+ if (geom_mask & GDK_HINT_POS)
+ {
+ size_hints.flags |= PPosition;
+ /* We need to initialize the following obsolete fields because KWM
+ * apparently uses these fields if they are non-zero.
+ * #@#!#!$!.
+ */
+ size_hints.x = 0;
+ size_hints.y = 0;
+ }
+
+ if (geom_mask & GDK_HINT_USER_POS)
+ {
+ size_hints.flags |= USPosition;
+ }
+
+ if (geom_mask & GDK_HINT_USER_SIZE)
+ {
+ size_hints.flags |= USSize;
+ }
+
+ if (geom_mask & GDK_HINT_MIN_SIZE)
+ {
+ size_hints.flags |= PMinSize;
+ size_hints.min_width = geometry->min_width;
+ size_hints.min_height = geometry->min_height;
+ }
+
+ if (geom_mask & GDK_HINT_MAX_SIZE)
+ {
+ size_hints.flags |= PMaxSize;
+ size_hints.max_width = MAX (geometry->max_width, 1);
+ size_hints.max_height = MAX (geometry->max_height, 1);
+ }
+
+ if (geom_mask & GDK_HINT_BASE_SIZE)
+ {
+ size_hints.flags |= PBaseSize;
+ size_hints.base_width = geometry->base_width;
+ size_hints.base_height = geometry->base_height;
+ }
+
+ if (geom_mask & GDK_HINT_RESIZE_INC)
+ {
+ size_hints.flags |= PResizeInc;
+ size_hints.width_inc = geometry->width_inc;
+ size_hints.height_inc = geometry->height_inc;
+ }
+
+ if (geom_mask & GDK_HINT_ASPECT)
+ {
+ size_hints.flags |= PAspect;
+ if (geometry->min_aspect <= 1)
+ {
+ size_hints.min_aspect.x = 65536 * geometry->min_aspect;
+ size_hints.min_aspect.y = 65536;
+ }
+ else
+ {
+ size_hints.min_aspect.x = 65536;
+ size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
+ }
+ if (geometry->max_aspect <= 1)
+ {
+ size_hints.max_aspect.x = 65536 * geometry->max_aspect;
+ size_hints.max_aspect.y = 65536;
+ }
+ else
+ {
+ size_hints.max_aspect.x = 65536;
+ size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
+ }
+ }
+
+ if (geom_mask & GDK_HINT_WIN_GRAVITY)
+ {
+ size_hints.flags |= PWinGravity;
+ size_hints.win_gravity = geometry->win_gravity;
+ }
+
+ /* FIXME: Would it be better to delete this property if
+ * geom_mask == 0? It would save space on the server
+ */
+ XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &size_hints);
+}
+
+static void
+gdk_window_get_geometry_hints (GdkWindow *window,
+ GdkGeometry *geometry,
+ GdkWindowHints *geom_mask)
+{
+ XSizeHints size_hints;
+ glong junk_size_mask = 0;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (geometry != NULL);
+ g_return_if_fail (geom_mask != NULL);
+
+ *geom_mask = 0;
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &size_hints,
+ &junk_size_mask))
+ return;
+
+ if (size_hints.flags & PMinSize)
+ {
+ *geom_mask |= GDK_HINT_MIN_SIZE;
+ geometry->min_width = size_hints.min_width;
+ geometry->min_height = size_hints.min_height;
+ }
+
+ if (size_hints.flags & PMaxSize)
+ {
+ *geom_mask |= GDK_HINT_MAX_SIZE;
+ geometry->max_width = MAX (size_hints.max_width, 1);
+ geometry->max_height = MAX (size_hints.max_height, 1);
+ }
+
+ if (size_hints.flags & PResizeInc)
+ {
+ *geom_mask |= GDK_HINT_RESIZE_INC;
+ geometry->width_inc = size_hints.width_inc;
+ geometry->height_inc = size_hints.height_inc;
+ }
+
+ if (size_hints.flags & PAspect)
+ {
+ *geom_mask |= GDK_HINT_ASPECT;
+
+ geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
+ geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
+ }
+
+ if (size_hints.flags & PWinGravity)
+ {
+ *geom_mask |= GDK_HINT_WIN_GRAVITY;
+ geometry->win_gravity = size_hints.win_gravity;
+ }
+}
+
+static gboolean
+utf8_is_latin1 (const gchar *str)
+{
+ const char *p = str;
+
+ while (*p)
+ {
+ gunichar ch = g_utf8_get_char (p);
+
+ if (ch > 0xff)
+ return FALSE;
+
+ p = g_utf8_next_char (p);
+ }
+
+ return TRUE;
+}
+
+/* Set the property to @utf8_str as STRING if the @utf8_str is fully
+ * convertable to STRING, otherwise, set it as compound text
+ */
+static void
+set_text_property (GdkDisplay *display,
+ Window xwindow,
+ Atom property,
+ const gchar *utf8_str)
+{
+ guchar *prop_text = NULL;
+ Atom prop_type;
+ gint prop_length;
+ gint prop_format;
+ gboolean is_compound_text;
+
+ if (utf8_is_latin1 (utf8_str))
+ {
+ prop_type = XA_STRING;
+ prop_text = gdk_utf8_to_string_target (utf8_str);
+ prop_length = prop_text ? strlen (prop_text) : 0;
+ prop_format = 8;
+ is_compound_text = FALSE;
+ }
+ else
+ {
+ GdkAtom gdk_type;
+
+ gdk_utf8_to_compound_text_for_display (display,
+ utf8_str, &gdk_type, &prop_format,
+ &prop_text, &prop_length);
+ prop_type = gdk_macosx_atom_to_xatom_for_display (display, gdk_type);
+ is_compound_text = TRUE;
+ }
+
+ if (prop_text)
+ {
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ xwindow,
+ property,
+ prop_type, prop_format,
+ PropModeReplace, prop_text,
+ prop_length);
+
+ if (is_compound_text)
+ gdk_free_compound_text (prop_text);
+ else
+ g_free (prop_text);
+ }
+}
+
+/* Set WM_NAME and _NET_WM_NAME
+ */
+static void
+set_wm_name (GdkDisplay *display,
+ Window xwindow,
+ const gchar *name)
+{
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_NAME"),
+ gdk_macosx_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
+ PropModeReplace, name, strlen (name));
+
+ set_text_property (display, xwindow,
+ gdk_macosx_get_xatom_by_name_for_display (display, "WM_NAME"),
+ name);
+}
+
+/**
+ * gdk_window_set_title:
+ * @window: a toplevel #GdkWindow
+ * @title: title of @window
+ *
+ * Sets the title of a toplevel window, to be displayed in the titlebar.
+ * If you haven't explicitly set the icon name for the window
+ * (using gdk_window_set_icon_name()), the icon name will be set to
+ * @title as well. @title must be in UTF-8 encoding (as with all
+ * user-readable strings in GDK/GTK+). @title may not be %NULL.
+ **/
+void
+gdk_window_set_title (GdkWindow *window,
+ const gchar *title)
+{
+ GdkDisplay *display;
+ Display *xdisplay;
+ Window xwindow;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (title != NULL);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ display = gdk_drawable_get_display (window);
+ xdisplay = GDK_DISPLAY_XDISPLAY (display);
+ xwindow = GDK_WINDOW_XID (window);
+
+ set_wm_name (display, xwindow, title);
+
+ if (!gdk_window_icon_name_set (window))
+ {
+ XChangeProperty (xdisplay, xwindow,
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
+ gdk_macosx_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
+ PropModeReplace, title, strlen (title));
+
+ set_text_property (display, xwindow,
+ gdk_macosx_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
+ title);
+ }
+}
+
+/**
+ * gdk_window_set_role:
+ * @window: a toplevel #GdkWindow
+ * @role: a string indicating its role
+ *
+ * When using GTK+, typically you should use gtk_window_set_role() instead
+ * of this low-level function.
+ *
+ * The window manager and session manager use a window's role to
+ * distinguish it from other kinds of window in the same application.
+ * When an application is restarted after being saved in a previous
+ * session, all windows with the same title and role are treated as
+ * interchangeable. So if you have two windows with the same title
+ * that should be distinguished for session management purposes, you
+ * should set the role on those windows. It doesn't matter what string
+ * you use for the role, as long as you have a different role for each
+ * non-interchangeable kind of window.
+ *
+ **/
+void
+gdk_window_set_role (GdkWindow *window,
+ const gchar *role)
+{
+ GdkDisplay *display;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ display = gdk_drawable_get_display (window);
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ if (role)
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
+ XA_STRING, 8, PropModeReplace, role, strlen (role));
+ else
+ XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
+ }
+}
+
+/**
+ * gdk_window_set_transient_for:
+ * @window: a toplevel #GdkWindow
+ * @parent: another toplevel #GdkWindow
+ *
+ * Indicates to the window manager that @window is a transient dialog
+ * associated with the application window @parent. This allows the
+ * window manager to do things like center @window on @parent and
+ * keep @window above @parent.
+ *
+ * See gtk_window_set_transient_for() if you're using #GtkWindow or
+ * #GtkDialog.
+ *
+ **/
+void
+gdk_window_set_transient_for (GdkWindow *window,
+ GdkWindow *parent)
+{
+ GdkWindowObject *private;
+ GdkWindowObject *parent_private;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ private = (GdkWindowObject*) window;
+ parent_private = (GdkWindowObject*) parent;
+
+ if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
+ XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ GDK_WINDOW_XID (parent));
+}
+
+/**
+ * gdk_window_set_background:
+ * @window: a #GdkWindow
+ * @color: an allocated #GdkColor
+ *
+ * Sets the background color of @window. (However, when using GTK+,
+ * set the background of a widget with gtk_widget_modify_bg() - if
+ * you're an application - or gtk_style_set_background() - if you're
+ * implementing a custom widget.)
+ *
+ * The @color must be allocated; gdk_rgb_find_color() is the best way
+ * to allocate a color.
+ *
+ * See also gdk_window_set_back_pixmap().
+ *
+ **/
+void
+gdk_window_set_background (GdkWindow *window,
+ const GdkColor *color)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window), color->pixel);
+
+ 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;
+}
+
+/**
+ * gdk_window_set_back_pixmap:
+ * @window: a #GdkWindow
+ * @pixmap: a #GdkPixmap, or %NULL
+ * @parent_relative: whether the tiling origin is at the origin of @window's parent
+ *
+ * Sets the background pixmap of @window. May also be used to set a background of
+ * "None" on @window, by setting a background pixmap of %NULL.
+ * A background pixmap will be tiled, positioning the first tile at the origin of
+ * @window, or if @parent_relative is %TRUE, the tiling will be done based on the
+ * origin of the parent window (useful to align tiles in a parent with tiles
+ * in a child).
+ *
+ * A background pixmap of %NULL means that the window will have no
+ * background. A window with no background will never have its
+ * background filled by the windowing system, instead the window will
+ * contain whatever pixels were already in the corresponding area of
+ * the display.
+ *
+ * The windowing system will normally fill a window with its background
+ * when the window is obscured then exposed, and when you call
+ * gdk_window_clear().
+ *
+ **/
+void
+gdk_window_set_back_pixmap (GdkWindow *window,
+ GdkPixmap *pixmap,
+ gboolean parent_relative)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ Pixmap xpixmap;
+
+ g_return_if_fail (window != NULL);
+ 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 (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)
+ {
+ xpixmap = ParentRelative;
+ private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
+ }
+ else
+ {
+ if (pixmap)
+ {
+ g_object_ref (pixmap);
+ private->bg_pixmap = pixmap;
+ xpixmap = GDK_PIXMAP_XID (pixmap);
+ }
+ else
+ {
+ xpixmap = None;
+ private->bg_pixmap = GDK_NO_BG;
+ }
+ }
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window), xpixmap);
+}
+
+/**
+ * gdk_window_set_cursor:
+ * @window: a #GdkWindow
+ * @cursor: a cursor
+ *
+ * Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new() or
+ * gdk_cursor_new_from_pixmap() to create the cursor.
+ * To make the cursor invisible, use gdk_cursor_new_from_pixmap() to create
+ * a cursor with no pixels in it. Passing %NULL for the @cursor argument
+ * to gdk_window_set_cursor() means that @window will use the cursor of
+ * its parent window. Most windows should use this default.
+ *
+ **/
+void
+gdk_window_set_cursor (GdkWindow *window,
+ GdkCursor *cursor)
+{
+ GdkCursorPrivate *cursor_private;
+ Cursor xcursor;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ cursor_private = (GdkCursorPrivate*) cursor;
+
+ if (!cursor)
+ xcursor = None;
+ else
+ xcursor = cursor_private->xcursor;
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ XDefineCursor (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ xcursor);
+}
+#endif
+
+/**
+ * gdk_window_get_geometry:
+ * @window: a #GdkWindow
+ * @x: return location for X coordinate of window (relative to its parent)
+ * @y: return location for Y coordinate of window (relative to its parent)
+ * @width: return location for width of window
+ * @height: return location for height of window
+ * @depth: return location for bit depth of window
+ *
+ * Any of the return location arguments to this function may be %NULL,
+ * if you aren't interested in getting the value of that field.
+ *
+ * The X and Y coordinates returned are relative to the parent window
+ * of @window, which for toplevels usually means relative to the
+ * window decorations (titlebar, etc.) rather than relative to the
+ * root window (screen-size background window).
+ *
+ * On the X11 platform, the geometry is obtained from the X server,
+ * so reflects the latest position of @window; this may be out-of-sync
+ * with the position of @window delivered in the most-recently-processed
+ * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
+ * position from the most recent configure event.
+ *
+ * <note>
+ * If @window is not a toplevel, it is <emphasis>much</emphasis> better
+ * to call gdk_window_get_position() and gdk_drawable_get_size() instead,
+ * because it avoids the roundtrip to the X server and because
+ * gdk_drawable_get_size() supports the full 32-bit coordinate space,
+ * whereas gdk_window_get_geometry() is restricted to the 16-bit
+ * coordinates of X11.
+ *</note>
+ **/
+void
+gdk_window_get_geometry (GdkWindow *window,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ gint *depth)
+{
+ g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
+
+ if (!window)
+ {
+ GDK_NOTE (MULTIHEAD,
+ g_message ("gdk_window_get_geometry(): Window needs to be non-NULL to be multi head safe"));
+ window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
+ }
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ NSRect frame = [GDK_WINDOW_NSVIEW(window) frame];
+
+ if (x)
+ *x = frame.origin.x;
+ if (y)
+ *y = frame.origin.y;
+ if (width)
+ *width = frame.size.width;
+ if (height)
+ *height = frame.size.height;
+ if (depth) {
+ NSWindowDepth wdepth = [[GDK_WINDOW_NSVIEW(window) window] depthLimit];
+ *depth = NSBitsPerPixelFromDepth(wdepth);
+ }
+ }
+}
+
+
+/**
+ * gdk_window_get_origin:
+ * @window: a #GdkWindow
+ * @x: return location for X coordinate
+ * @y: return location for Y coordinate
+ *
+ * Obtains the position of a window in root window coordinates.
+ * (Compare with gdk_window_get_position() and
+ * gdk_window_get_geometry() which return the position of a window
+ * relative to its parent window.)
+ *
+ * Return value: not meaningful, ignore
+ **/
+gint
+gdk_window_get_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ NSRect frame;
+ gint return_val;
+ gint tx = 0;
+ gint ty = 0;
+
+ g_return_val_if_fail (window != NULL, 0);
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+
+ frame = [GDK_WINDOW_NSVIEW(window) frame];
+
+ return_val = 1;
+ }
+ else
+ return_val = 0;
+
+ if (x)
+ *x = frame.origin.x;
+ if (y)
+ *y = frame.origin.y;
+
+ return return_val;
+}
+
+#if 0
+/**
+ * gdk_window_get_deskrelative_origin:
+ * @window: a toplevel #GdkWindow
+ * @x: return location for X coordinate
+ * @y: return location for Y coordinate
+ *
+ * This gets the origin of a #GdkWindow relative to
+ * an Enlightenment-window-manager desktop. As long as you don't
+ * assume that the user's desktop/workspace covers the entire
+ * root window (i.e. you don't assume that the desktop begins
+ * at root window coordinate 0,0) this function is not necessary.
+ * It's deprecated for that reason.
+ *
+ * Return value: not meaningful
+ **/
+gboolean
+gdk_window_get_deskrelative_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ gboolean return_val = FALSE;
+ gint num_children, format_return;
+ Window win, *child, parent, root;
+ gint tx = 0;
+ gint ty = 0;
+ Atom type_return;
+ Atom atom;
+ gulong number_return, bytes_after_return;
+ guchar *data_return;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ atom = gdk_macosx_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+ "ENLIGHTENMENT_DESKTOP");
+ win = GDK_WINDOW_XID (window);
+
+ while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
+ &child, (unsigned int *)&num_children))
+ {
+ if ((child) && (num_children > 0))
+ XFree (child);
+
+ if (!parent)
+ break;
+ else
+ win = parent;
+
+ if (win == root)
+ break;
+
+ data_return = NULL;
+ XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
+ False, XA_CARDINAL, &type_return, &format_return,
+ &number_return, &bytes_after_return, &data_return);
+
+ if (type_return == XA_CARDINAL)
+ {
+ XFree (data_return);
+ break;
+ }
+ }
+
+ return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ win,
+ 0, 0, &tx, &ty,
+ &root);
+ if (x)
+ *x = tx;
+ if (y)
+ *y = ty;
+ }
+
+
+ return return_val;
+}
+
+/**
+ * gdk_window_get_root_origin:
+ * @window: a toplevel #GdkWindow
+ * @x: return location for X position of window frame
+ * @y: return location for Y position of window frame
+ *
+ * Obtains the top-left corner of the window manager frame in root
+ * window coordinates.
+ *
+ **/
+void
+gdk_window_get_root_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ GdkRectangle rect;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ gdk_window_get_frame_extents (window, &rect);
+
+ if (x)
+ *x = rect.x;
+
+ if (y)
+ *y = rect.y;
+}
+
+/**
+ * gdk_window_get_frame_extents:
+ * @window: a toplevel #GdkWindow
+ * @rect: rectangle to fill with bounding box of the window frame
+ *
+ * Obtains the bounding box of the window, including window manager
+ * titlebar/borders if any. The frame position is given in root window
+ * coordinates. To get the position of the window itself (rather than
+ * the frame) in root window coordinates, use gdk_window_get_origin().
+ *
+ **/
+void
+gdk_window_get_frame_extents (GdkWindow *window,
+ GdkRectangle *rect)
+{
+ GdkDisplay *display;
+ GdkWindowObject *private;
+ Window xwindow;
+ Window xparent;
+ Window root;
+ Window *children;
+ guchar *data;
+ Window *vroots;
+ Atom type_return;
+ guint nchildren;
+ guint nvroots;
+ gulong nitems_return;
+ gulong bytes_after_return;
+ gint format_return;
+ gint i;
+ guint ww, wh, wb, wd;
+ gint wx, wy;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (rect != NULL);
+
+ private = (GdkWindowObject*) window;
+
+ rect->x = 0;
+ rect->y = 0;
+ rect->width = 1;
+ rect->height = 1;
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ while (private->parent && ((GdkWindowObject*) private->parent)->parent)
+ private = (GdkWindowObject*) private->parent;
+
+ /* Refine our fallback answer a bit using local information */
+ rect->x = private->x;
+ rect->y = private->y;
+ gdk_drawable_get_size ((GdkDrawable *)private, &rect->width, &rect->height);
+
+ if (GDK_WINDOW_DESTROYED (private))
+ return;
+
+ gdk_error_trap_push();
+
+ /* use NETWM_VIRTUAL_ROOTS if available */
+ display = gdk_drawable_get_display (window);
+ root = GDK_WINDOW_XROOTWIN (window);
+
+ nvroots = 0;
+ vroots = NULL;
+
+ if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), root,
+ gdk_macosx_get_xatom_by_name_for_display (display,
+ "_NET_VIRTUAL_ROOTS"),
+ 0, G_MAXLONG, False, XA_WINDOW, &type_return,
+ &format_return, &nitems_return, &bytes_after_return,
+ &data)
+ == Success)
+ {
+ if ((type_return == XA_WINDOW) && (format_return == 32) && (data))
+ {
+ nvroots = nitems_return;
+ vroots = (Window *)data;
+ }
+ }
+
+ xparent = GDK_WINDOW_XID (window);
+
+ do
+ {
+ xwindow = xparent;
+
+ if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xwindow,
+ &root, &xparent,
+ &children, &nchildren))
+ goto fail;
+
+ if (children)
+ XFree (children);
+
+ /* check virtual roots */
+ for (i = 0; i < nvroots; i++)
+ {
+ if (xparent == vroots[i])
+ {
+ root = xparent;
+ break;
+ }
+ }
+ }
+ while (xparent != root);
+
+ if (XGetGeometry (GDK_DISPLAY_XDISPLAY (display), xwindow,
+ &root, &wx, &wy, &ww, &wh, &wb, &wd))
+ {
+ rect->x = wx;
+ rect->y = wy;
+ rect->width = ww;
+ rect->height = wh;
+ }
+
+ fail:
+ if (vroots)
+ XFree (vroots);
+
+ gdk_error_trap_pop ();
+}
+
+#endif
+
+
+void
+_gdk_windowing_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ GdkWindow *return_val = NULL;
+ NSPoint cursor_loc;
+
+ cursor_loc = [NSEvent mouseLocation];
+
+ if (x) {
+ *x = cursor_loc.x;
+ }
+ if (y) {
+ *y = cursor_loc.y;
+ }
+ if (screen) {
+ *screen = gdk_display_get_default_screen (display);
+ }
+ if (mask) {
+ *mask = ns_to_gdk_modifier([[[NSApplication sharedApplication] currentEvent] modifierFlags]);
+ }
+}
+
+
+GdkWindow*
+_gdk_windowing_window_get_pointer (GdkDisplay *display,
+ GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ GdkWindow *return_val = NULL;
+
+ g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
+
+ NSPoint cursor_loc;
+
+ cursor_loc = [NSEvent mouseLocation];
+
+ if (x) {
+ *x = cursor_loc.x;
+ }
+ if (y) {
+ *y = cursor_loc.y;
+ }
+
+ *mask = ns_to_gdk_modifier([[[NSApplication sharedApplication] currentEvent] modifierFlags]);
+
+ //FIXME return the GdkWindow it is in
+
+ return return_val;
+}
+
+
+GdkWindow*
+_gdk_windowing_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y)
+{
+ GdkWindow *window = NULL;
+ GdkScreen *screen;
+ NSPoint cursor_loc;
+
+ cursor_loc = [NSEvent mouseLocation];
+ *win_x = cursor_loc.x;
+ *win_y = cursor_loc.y;
+
+ //FIXME
+
+ return window;
+}
+
+
+#if 0
+/**
+ * gdk_window_get_events:
+ * @window: a #GdkWindow
+ *
+ * Gets the event mask for @window. See gdk_window_set_events().
+ *
+ * Return value: event mask for @window
+ **/
+GdkEventMask
+gdk_window_get_events (GdkWindow *window)
+{
+ XWindowAttributes attrs;
+ GdkEventMask event_mask;
+
+ g_return_val_if_fail (window != NULL, 0);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return 0;
+ else
+ {
+ XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &attrs);
+
+ event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
+ GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
+
+ return event_mask;
+ }
+}
+
+/**
+ * gdk_window_set_events:
+ * @window: a #GdkWindow
+ * @event_mask: event mask for @window
+ *
+ * The event mask for a window determines which events will be reported
+ * for that window. For example, an event mask including #GDK_BUTTON_PRESS_MASK
+ * means the window should report button press events. The event mask
+ * is the bitwise OR of values from the #GdkEventMask enumeration.
+ *
+ **/
+void
+gdk_window_set_events (GdkWindow *window,
+ GdkEventMask event_mask)
+{
+ long xevent_mask;
+ int i;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
+ xevent_mask = StructureNotifyMask | PropertyChangeMask;
+ for (i = 0; i < _gdk_nenvent_masks; i++)
+ {
+ if (event_mask & (1 << (i + 1)))
+ xevent_mask |= _gdk_event_mask_table[i];
+ }
+
+ XSelectInput (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ xevent_mask);
+ }
+}
+
+static void
+gdk_window_add_colormap_windows (GdkWindow *window)
+{
+ GdkWindow *toplevel;
+ Window *old_windows;
+ Window *new_windows;
+ int i, count;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+ toplevel = gdk_window_get_toplevel (window);
+
+ old_windows = NULL;
+ if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
+ GDK_WINDOW_XID (toplevel),
+ &old_windows, &count))
+ {
+ count = 0;
+ }
+
+ for (i = 0; i < count; i++)
+ if (old_windows[i] == GDK_WINDOW_XID (window))
+ {
+ XFree (old_windows);
+ return;
+ }
+
+ new_windows = g_new (Window, count + 1);
+
+ for (i = 0; i < count; i++)
+ new_windows[i] = old_windows[i];
+ new_windows[count] = GDK_WINDOW_XID (window);
+
+ XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
+ GDK_WINDOW_XID (toplevel),
+ new_windows, count + 1);
+
+ g_free (new_windows);
+ if (old_windows)
+ XFree (old_windows);
+}
+
+static gboolean
+gdk_window_have_shape_ext (GdkDisplay *display)
+{
+#ifdef HAVE_SHAPE_EXT
+ int ignore;
+
+ return XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display),
+ &ignore, &ignore);
+#else
+ return 0;
+#endif
+}
+
+#define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
+
+/*
+ * This needs the X11 shape extension.
+ * If not available, shaped windows will look
+ * ugly, but programs still work. Stefan Wille
+ */
+/**
+ * gdk_window_shape_combine_mask:
+ * @window: a #GdkWindow
+ * @mask: shape mask
+ * @x: X position of shape mask with respect to @window
+ * @y: Y position of shape mask with respect to @window
+ *
+ * Applies a shape mask to @window. Pixels in @window corresponding to
+ * set bits in the @mask will be visible; pixels in @window
+ * corresponding to unset bits in the @mask will be transparent. This
+ * gives a non-rectangular window.
+ *
+ * If @mask is %NULL, the shape mask will be unset, and the @x/@y
+ * parameters are not used.
+ *
+ * On the X11 platform, this uses an X server extension which is
+ * widely available on most common platforms, but not available on
+ * very old X servers, and occasionally the implementation will be
+ * buggy. On servers without the shape extension, this function
+ * will do nothing.
+ *
+ * This function works on both toplevel and child windows.
+ *
+ **/
+void
+gdk_window_shape_combine_mask (GdkWindow *window,
+ GdkBitmap *mask,
+ gint x, gint y)
+{
+ Pixmap pixmap;
+ gint xoffset, yoffset;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_SHAPE_EXT
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
+
+ if (xoffset != 0 || yoffset != 0)
+ {
+ WARN_SHAPE_TOO_BIG ();
+ return;
+ }
+
+ if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+ {
+ if (mask)
+ {
+ pixmap = GDK_PIXMAP_XID (mask);
+ }
+ else
+ {
+ x = 0;
+ y = 0;
+ pixmap = None;
+ }
+
+ XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ ShapeBounding,
+ x, y,
+ pixmap,
+ ShapeSet);
+ }
+#endif /* HAVE_SHAPE_EXT */
+}
+
+/**
+ * gdk_window_shape_combine_region:
+ * @window: a #GdkWindow
+ * @shape_region: region of window to be non-transparent
+ * @offset_x: X position of @shape_region in @window coordinates
+ * @offset_y: Y position of @shape_region in @window coordinates
+ *
+ * Makes pixels in @window outside @shape_region be transparent,
+ * so that the window may be nonrectangular. See also
+ * gdk_window_shape_combine_mask() to use a bitmap as the mask.
+ *
+ * If @shape_region is %NULL, the shape will be unset, so the whole
+ * window will be opaque again. @offset_x and @offset_y are ignored
+ * if @shape_region is %NULL.
+ *
+ * On the X11 platform, this uses an X server extension which is
+ * widely available on most common platforms, but not available on
+ * very old X servers, and occasionally the implementation will be
+ * buggy. On servers without the shape extension, this function
+ * will do nothing.
+ *
+ * This function works on both toplevel and child windows.
+ *
+ **/
+void
+gdk_window_shape_combine_region (GdkWindow *window,
+ GdkRegion *shape_region,
+ gint offset_x,
+ gint offset_y)
+{
+ gint xoffset, yoffset;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_SHAPE_EXT
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
+
+ if (xoffset != 0 || yoffset != 0)
+ {
+ WARN_SHAPE_TOO_BIG ();
+ return;
+ }
+
+ if (shape_region == NULL)
+ {
+ /* Use NULL mask to unset the shape */
+ gdk_window_shape_combine_mask (window, NULL, 0, 0);
+ return;
+ }
+
+ if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+ {
+ gint n_rects = 0;
+ XRectangle *xrects = NULL;
+
+ _gdk_region_get_xrectangles (shape_region,
+ 0, 0,
+ &xrects, &n_rects);
+
+ XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ ShapeBounding,
+ offset_x, offset_y,
+ xrects, n_rects,
+ ShapeSet,
+ YXBanded);
+
+ g_free (xrects);
+ }
+#endif /* HAVE_SHAPE_EXT */
+}
+
+
+/**
+ * gdk_window_set_override_redirect:
+ * @window: a toplevel #GdkWindow
+ * @override_redirect: %TRUE if window should be override redirect
+ *
+ * An override redirect window is not under the control of the window manager.
+ * This means it won't have a titlebar, won't be minimizable, etc. - it will
+ * be entirely under the control of the application. The window manager
+ * can't see the override redirect window at all.
+ *
+ * Override redirect should only be used for short-lived temporary
+ * windows, such as popup menus. #GtkMenu uses an override redirect
+ * window in its implementation, for example.
+ *
+ **/
+void
+gdk_window_set_override_redirect (GdkWindow *window,
+ gboolean override_redirect)
+{
+ XSetWindowAttributes attr;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindowImplMacOSX *impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+
+ attr.override_redirect = (override_redirect? True : False);
+ XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ CWOverrideRedirect,
+ &attr);
+
+ impl->override_redirect = attr.override_redirect;
+ }
+}
+
+/**
+ * gdk_window_set_accept_focus:
+ * @window: a toplevel #GdkWindow
+ * @accept_focus: %TRUE if the window should receive input focus
+ *
+ * Setting @accept_focus to %FALSE hints the desktop environment that the
+ * window doesn't want to receive input focus.
+ *
+ * On X, it is the responsibility of the window manager to interpret this
+ * hint. ICCCM-compliant window manager usually respect it.
+ *
+ * Since: 2.4
+ **/
+void
+gdk_window_set_accept_focus (GdkWindow *window,
+ gboolean accept_focus)
+{
+ GdkWindowObject *private;
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ private = (GdkWindowObject *)window;
+
+ accept_focus = accept_focus != FALSE;
+
+ if (private->accept_focus != accept_focus)
+ {
+ private->accept_focus = accept_focus;
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ update_wm_hints (window, FALSE);
+ }
+}
+
+/**
+ * gdk_window_set_focus_on_map:
+ * @window: a toplevel #GdkWindow
+ * @focus_on_map: %TRUE if the window should receive input focus when mapped
+ *
+ * Setting @focus_on_map to %FALSE hints the desktop environment that the
+ * window doesn't want to receive input focus when it is mapped.
+ * focus_on_map should be turned off for windows that aren't triggered
+ * interactively (such as popups from network activity).
+ *
+ * On X, it is the responsibility of the window manager to interpret
+ * this hint. Window managers following the freedesktop.org window
+ * manager extension specification should respect it.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_window_set_focus_on_map (GdkWindow *window,
+ gboolean focus_on_map)
+{
+ GdkWindowObject *private;
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ private = (GdkWindowObject *)window;
+
+ focus_on_map = focus_on_map != FALSE;
+
+ if (private->focus_on_map != focus_on_map)
+ {
+ private->focus_on_map = focus_on_map;
+
+ if ((!GDK_WINDOW_DESTROYED (window)) && (!private->focus_on_map))
+ gdk_macosx_window_set_user_time (window, 0);
+ }
+}
+
+/**
+ * gdk_macosx_window_set_user_time:
+ * @window: A toplevel #GdkWindow
+ * @timestamp: An XServer timestamp to which the property should be set
+ *
+ * The application can use this call to update the _NET_WM_USER_TIME
+ * property on a toplevel window. This property stores an Xserver
+ * time which represents the time of the last user input event
+ * received for this window. This property may be used by the window
+ * manager to alter the focus, stacking, and/or placement behavior of
+ * windows when they are mapped depending on whether the new window
+ * was created by a user action or is a "pop-up" window activated by a
+ * timer or some other event.
+ *
+ * Note that this property is automatically updated by GDK, so this
+ * function should only be used by applications which handle input
+ * events bypassing GDK.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_macosx_window_set_user_time (GdkWindow *window,
+ guint32 timestamp)
+{
+ GdkDisplay *display;
+ GdkDisplayMacOSX *display_macosx;
+ GdkToplevelMacOSX *toplevel;
+ glong timestamp_long = (glong)timestamp;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ display = gdk_drawable_get_display (window);
+ display_macosx = GDK_DISPLAY_MACOSX (display);
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
+ XA_CARDINAL, 32, PropModeReplace,
+ (guchar *)&timestamp_long, 1);
+
+ if (timestamp_long != GDK_CURRENT_TIME)
+ display_macosx->user_time = timestamp_long;
+
+ toplevel->user_time = timestamp_long;
+}
+
+/**
+ * gdk_window_set_icon_list:
+ * @window: The #GdkWindow toplevel window to set the icon of.
+ * @pixbufs: A list of pixbufs, of different sizes.
+ *
+ * Sets a list of icons for the window. One of these will be used
+ * to represent the window when it has been iconified. The icon is
+ * usually shown in an icon box or some sort of task bar. Which icon
+ * size is shown depends on the window manager. The window manager
+ * can scale the icon but setting several size icons can give better
+ * image quality since the window manager may only need to scale the
+ * icon by a small amount or not at all.
+ *
+ **/
+void
+gdk_window_set_icon_list (GdkWindow *window,
+ GList *pixbufs)
+{
+ gulong *data;
+ guchar *pixels;
+ gulong *p;
+ gint size;
+ GList *l;
+ GdkPixbuf *pixbuf;
+ gint width, height, stride;
+ gint x, y;
+ gint n_channels;
+ GdkDisplay *display;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ display = gdk_drawable_get_display (window);
+
+ l = pixbufs;
+ size = 0;
+
+ while (l)
+ {
+ pixbuf = l->data;
+ g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+
+ size += 2 + width * height;
+
+ l = g_list_next (l);
+ }
+
+ data = g_malloc (size * sizeof (gulong));
+
+ l = pixbufs;
+ p = data;
+ while (l)
+ {
+ pixbuf = l->data;
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ stride = gdk_pixbuf_get_rowstride (pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+
+ *p++ = width;
+ *p++ = height;
+
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ guchar r, g, b, a;
+
+ r = pixels[y*stride + x*n_channels + 0];
+ g = pixels[y*stride + x*n_channels + 1];
+ b = pixels[y*stride + x*n_channels + 2];
+ if (n_channels >= 4)
+ a = pixels[y*stride + x*n_channels + 3];
+ else
+ a = 255;
+
+ *p++ = a << 24 | r << 16 | g << 8 | b ;
+ }
+ }
+
+ l = g_list_next (l);
+ }
+
+ if (size > 0)
+ {
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XID (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_ICON"),
+ XA_CARDINAL, 32,
+ PropModeReplace,
+ (guchar*) data, size);
+ }
+ else
+ {
+ XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XID (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_ICON"));
+ }
+
+ g_free (data);
+}
+
+/**
+ * gdk_window_set_icon:
+ * @window: a toplevel #GdkWindow
+ * @icon_window: a #GdkWindow to use for the icon, or %NULL to unset
+ * @pixmap: a #GdkPixmap to use as the icon, or %NULL to unset
+ * @mask: a 1-bit pixmap (#GdkBitmap) to use as mask for @pixmap, or %NULL to have none
+ *
+ * Sets the icon of @window as a pixmap or window. If using GTK+, investigate
+ * gtk_window_set_default_icon_list() first, and then gtk_window_set_icon_list()
+ * and gtk_window_set_icon(). If those don't meet your needs, look at
+ * gdk_window_set_icon_list(). Only if all those are too high-level do you
+ * want to fall back to gdk_window_set_icon().
+ *
+ **/
+void
+gdk_window_set_icon (GdkWindow *window,
+ GdkWindow *icon_window,
+ GdkPixmap *pixmap,
+ GdkBitmap *mask)
+{
+ GdkToplevelMacOSX *toplevel;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+
+ if (toplevel->icon_window != icon_window)
+ {
+ if (toplevel->icon_window)
+ g_object_unref (toplevel->icon_window);
+ toplevel->icon_window = g_object_ref (icon_window);
+ }
+
+ if (toplevel->icon_pixmap != pixmap)
+ {
+ if (pixmap)
+ g_object_ref (pixmap);
+ if (toplevel->icon_pixmap)
+ g_object_unref (toplevel->icon_pixmap);
+ toplevel->icon_pixmap = pixmap;
+ }
+
+ if (toplevel->icon_mask != mask)
+ {
+ if (mask)
+ g_object_ref (mask);
+ if (toplevel->icon_mask)
+ g_object_unref (toplevel->icon_mask);
+ toplevel->icon_mask = mask;
+ }
+
+ update_wm_hints (window, FALSE);
+}
+
+static gboolean
+gdk_window_icon_name_set (GdkWindow *window)
+{
+ return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
+ g_quark_from_static_string ("gdk-icon-name-set")));
+}
+
+/**
+ * gdk_window_set_icon_name:
+ * @window: a toplevel #GdkWindow
+ * @name: name of window while iconified (minimized)
+ *
+ * Windows may have a name used while minimized, distinct from the
+ * name they display in their titlebar. Most of the time this is a bad
+ * idea from a user interface standpoint. But you can set such a name
+ * with this function, if you like.
+ *
+ **/
+void
+gdk_window_set_icon_name (GdkWindow *window,
+ const gchar *name)
+{
+ GdkDisplay *display;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ display = gdk_drawable_get_display (window);
+
+ g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
+ GUINT_TO_POINTER (TRUE));
+
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XID (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
+ gdk_macosx_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
+ PropModeReplace, name, strlen (name));
+
+ set_text_property (display, GDK_WINDOW_XID (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
+ name);
+}
+
+/**
+ * gdk_window_iconify:
+ * @window: a toplevel #GdkWindow
+ *
+ * Asks to iconify (minimize) @window. The window manager may choose
+ * to ignore the request, but normally will honor it. Using
+ * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
+ *
+ * This function only makes sense when @window is a toplevel window.
+ *
+ **/
+void
+gdk_window_iconify (GdkWindow *window)
+{
+ GdkWindowObject *private;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ private = (GdkWindowObject*) window;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ {
+ XIconifyWindow (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XWINDOW (window),
+ gdk_screen_get_number (GDK_WINDOW_SCREEN (window)));
+ }
+ else
+ {
+ /* Flip our client side flag, the real work happens on map. */
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_ICONIFIED);
+ }
+}
+
+/**
+ * gdk_window_deiconify:
+ * @window: a toplevel #GdkWindow
+ *
+ * Attempt to deiconify (unminimize) @window. On X11 the window manager may
+ * choose to ignore the request to deiconify. When using GTK+,
+ * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
+ * you probably want to use gtk_window_present(), which raises the window, focuses it,
+ * unminimizes it, and puts it on the current desktop.
+ *
+ **/
+void
+gdk_window_deiconify (GdkWindow *window)
+{
+ GdkWindowObject *private;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ private = (GdkWindowObject*) window;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ {
+ gdk_window_show (window);
+ }
+ else
+ {
+ /* Flip our client side flag, the real work happens on map. */
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_ICONIFIED,
+ 0);
+ }
+}
+
+/**
+ * gdk_window_stick:
+ * @window: a toplevel #GdkWindow
+ *
+ * "Pins" a window such that it's on all workspaces and does not scroll
+ * with viewports, for window managers that have scrollable viewports.
+ * (When using #GtkWindow, gtk_window_stick() may be more useful.)
+ *
+ * On the X11 platform, this function depends on window manager
+ * support, so may have no effect with many window managers. However,
+ * GDK will do the best it can to convince the window manager to stick
+ * the window. For window managers that don't support this operation,
+ * there's nothing you can do to force it to happen.
+ *
+ **/
+void
+gdk_window_stick (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ {
+ /* "stick" means stick to all desktops _and_ do not scroll with the
+ * viewport. i.e. glue to the monitor glass in all cases.
+ */
+
+ XEvent xev;
+
+ /* Request stick during viewport scroll */
+ gdk_wmspec_change_state (TRUE, window,
+ gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
+ NULL);
+
+ /* Request desktop 0xFFFFFFFF */
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = GDK_WINDOW_XWINDOW (window);
+ xev.xclient.display = GDK_WINDOW_XDISPLAY (window);
+ xev.xclient.message_type = gdk_macosx_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
+ "_NET_WM_DESKTOP");
+ xev.xclient.format = 32;
+
+ xev.xclient.data.l[0] = 0xFFFFFFFF;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+ }
+ else
+ {
+ /* Flip our client side flag, the real work happens on map. */
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_STICKY);
+ }
+}
+
+/**
+ * gdk_window_unstick:
+ * @window: a toplevel #GdkWindow
+ *
+ * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
+ * and gtk_window_unstick().
+ *
+ **/
+void
+gdk_window_unstick (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ {
+ XEvent xev;
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+ gulong *current_desktop;
+ GdkDisplay *display = gdk_drawable_get_display (window);
+
+ /* Request unstick from viewport */
+ gdk_wmspec_change_state (FALSE, window,
+ gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
+ NULL);
+
+ /* Get current desktop, then set it; this is a race, but not
+ * one that matters much in practice.
+ */
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window),
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
+ 0, G_MAXLONG,
+ False, XA_CARDINAL, &type, &format, &nitems,
+ &bytes_after, &data);
+
+ if (type == XA_CARDINAL)
+ {
+ current_desktop = (gulong *)data;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = GDK_WINDOW_XWINDOW (window);
+ xev.xclient.message_type = gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
+ xev.xclient.format = 32;
+
+ xev.xclient.data.l[0] = *current_desktop;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+
+ XFree (current_desktop);
+ }
+ }
+ else
+ {
+ /* Flip our client side flag, the real work happens on map. */
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_STICKY,
+ 0);
+
+ }
+}
+
+/**
+ * gdk_window_maximize:
+ * @window: a toplevel #GdkWindow
+ *
+ * Maximizes the window. If the window was already maximized, then
+ * this function does nothing.
+ *
+ * On X11, asks the window manager to maximize @window, if the window
+ * manager supports this operation. Not all window managers support
+ * this, and some deliberately ignore it or don't have a concept of
+ * "maximized"; so you can't rely on the maximization actually
+ * happening. But it will happen with most standard window managers,
+ * and GDK makes a best effort to get it to happen.
+ *
+ * On Windows, reliably maximizes the window.
+ *
+ **/
+void
+gdk_window_maximize (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_wmspec_change_state (TRUE, window,
+ gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
+ gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
+ else
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_MAXIMIZED);
+}
+
+/**
+ * gdk_window_unmaximize:
+ * @window: a toplevel #GdkWindow
+ *
+ * Unmaximizes the window. If the window wasn't maximized, then this
+ * function does nothing.
+ *
+ * On X11, asks the window manager to unmaximize @window, if the
+ * window manager supports this operation. Not all window managers
+ * support this, and some deliberately ignore it or don't have a
+ * concept of "maximized"; so you can't rely on the unmaximization
+ * actually happening. But it will happen with most standard window
+ * managers, and GDK makes a best effort to get it to happen.
+ *
+ * On Windows, reliably unmaximizes the window.
+ *
+ **/
+void
+gdk_window_unmaximize (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_wmspec_change_state (FALSE, window,
+ gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
+ gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
+ else
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_MAXIMIZED,
+ 0);
+}
+
+/**
+ * gdk_window_fullscreen:
+ * @window: a toplevel #GdkWindow
+ *
+ * Moves the window into fullscreen mode. This means the
+ * window covers the entire screen and is above any panels
+ * or task bars.
+ *
+ * If the window was already fullscreen, then this function does nothing.
+ *
+ * On X11, asks the window manager to put @window in a fullscreen
+ * state, if the window manager supports this operation. Not all
+ * window managers support this, and some deliberately ignore it or
+ * don't have a concept of "fullscreen"; so you can't rely on the
+ * fullscreenification actually happening. But it will happen with
+ * most standard window managers, and GDK makes a best effort to get
+ * it to happen.
+ *
+ * Since: 2.2
+ **/
+void
+gdk_window_fullscreen (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_wmspec_change_state (TRUE, window,
+ gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE),
+ GDK_NONE);
+
+ else
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_FULLSCREEN);
+}
+
+/**
+ * gdk_window_unfullscreen:
+ * @window: a toplevel #GdkWindow
+ *
+ * Moves the window out of fullscreen mode. If the window was not
+ * fullscreen, does nothing.
+ *
+ * On X11, asks the window manager to move @window out of the fullscreen
+ * state, if the window manager supports this operation. Not all
+ * window managers support this, and some deliberately ignore it or
+ * don't have a concept of "fullscreen"; so you can't rely on the
+ * unfullscreenification actually happening. But it will happen with
+ * most standard window managers, and GDK makes a best effort to get
+ * it to happen.
+ *
+ * Since: 2.2
+ **/
+void
+gdk_window_unfullscreen (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_wmspec_change_state (FALSE, window,
+ gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE),
+ GDK_NONE);
+
+ else
+ gdk_synthesize_window_state (window,
+ GDK_WINDOW_STATE_FULLSCREEN,
+ 0);
+}
+
+/**
+ * gdk_window_set_keep_above:
+ * @window: a toplevel #GdkWindow
+ * @setting: whether to keep @window above other windows
+ *
+ * Set if @window must be kept above other windows. If the
+ * window was already above, then this function does nothing.
+ *
+ * On X11, asks the window manager to keep @window above, if the window
+ * manager supports this operation. Not all window managers support
+ * this, and some deliberately ignore it or don't have a concept of
+ * "keep above"; so you can't rely on the window being kept above.
+ * But it will happen with most standard window managers,
+ * and GDK makes a best effort to get it to happen.
+ *
+ * Since: 2.4
+ **/
+void
+gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ {
+ if (setting)
+ gdk_wmspec_change_state (FALSE, window,
+ gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE),
+ GDK_NONE);
+ gdk_wmspec_change_state (setting, window,
+ gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE),
+ GDK_NONE);
+ }
+ else
+ gdk_synthesize_window_state (window,
+ setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
+ setting ? GDK_WINDOW_STATE_ABOVE : 0);
+}
+
+/**
+ * gdk_window_set_keep_below:
+ * @window: a toplevel #GdkWindow
+ * @setting: whether to keep @window below other windows
+ *
+ * Set if @window must be kept below other windows. If the
+ * window was already below, then this function does nothing.
+ *
+ * On X11, asks the window manager to keep @window below, if the window
+ * manager supports this operation. Not all window managers support
+ * this, and some deliberately ignore it or don't have a concept of
+ * "keep below"; so you can't rely on the window being kept below.
+ * But it will happen with most standard window managers,
+ * and GDK makes a best effort to get it to happen.
+ *
+ * Since: 2.4
+ **/
+void
+gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ {
+ if (setting)
+ gdk_wmspec_change_state (FALSE, window,
+ gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE),
+ GDK_NONE);
+ gdk_wmspec_change_state (setting, window,
+ gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE),
+ GDK_NONE);
+ }
+ else
+ gdk_synthesize_window_state (window,
+ setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
+ setting ? GDK_WINDOW_STATE_BELOW : 0);
+}
+
+/**
+ * gdk_window_get_group:
+ * @window: a toplevel #GdkWindow
+ *
+ * Returns the group leader window for @window. See gdk_window_set_group().
+ *
+ * Return value: the group leader window for @window
+ *
+ * Since: 2.4
+ **/
+GdkWindow *
+gdk_window_get_group (GdkWindow *window)
+{
+ GdkToplevelMacOSX *toplevel;
+
+ g_return_val_if_fail (window != NULL, NULL);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+ g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return NULL;
+
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+
+ return toplevel->group_leader;
+}
+
+/**
+ * gdk_window_set_group:
+ * @window: a toplevel #GdkWindow
+ * @leader: group leader window, or %NULL to restore the default group leader window
+ *
+ * Sets the group leader window for @window. By default,
+ * GDK sets the group leader for all toplevel windows
+ * to a global window implicitly created by GDK. With this function
+ * you can override this default.
+ *
+ * The group leader window allows the window manager to distinguish
+ * all windows that belong to a single application. It may for example
+ * allow users to minimize/unminimize all windows belonging to an
+ * application at once. You should only set a non-default group window
+ * if your application pretends to be multiple applications.
+ **/
+void
+gdk_window_set_group (GdkWindow *window,
+ GdkWindow *leader)
+{
+ GdkToplevelMacOSX *toplevel;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
+ g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
+
+ if (GDK_WINDOW_DESTROYED (window) || (leader != NULL && GDK_WINDOW_DESTROYED (leader)))
+ return;
+
+ toplevel = _gdk_macosx_window_get_toplevel (window);
+
+ if (leader == NULL)
+ leader = gdk_display_get_default_group (gdk_drawable_get_display (window));
+
+ if (toplevel->group_leader != leader)
+ {
+ if (toplevel->group_leader)
+ g_object_unref (toplevel->group_leader);
+ toplevel->group_leader = g_object_ref (leader);
+ (_gdk_macosx_window_get_toplevel (leader))->is_leader = TRUE;
+ }
+
+ update_wm_hints (window, FALSE);
+}
+
+static MotifWmHints *
+gdk_window_get_mwm_hints (GdkWindow *window)
+{
+ GdkDisplay *display;
+ Atom hints_atom = None;
+ guchar *data;
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return NULL;
+
+ display = gdk_drawable_get_display (window);
+
+ hints_atom = gdk_macosx_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
+
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+ False, AnyPropertyType, &type, &format, &nitems,
+ &bytes_after, &data);
+
+ if (type == None)
+ return NULL;
+
+ return (MotifWmHints *)data;
+}
+
+static void
+gdk_window_set_mwm_hints (GdkWindow *window,
+ MotifWmHints *new_hints)
+{
+ GdkDisplay *display;
+ Atom hints_atom = None;
+ guchar *data;
+ MotifWmHints *hints;
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ display = gdk_drawable_get_display (window);
+
+ hints_atom = gdk_macosx_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
+
+ XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
+ hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
+ False, AnyPropertyType, &type, &format, &nitems,
+ &bytes_after, &data);
+
+ if (type == None)
+ hints = new_hints;
+ else
+ {
+ hints = (MotifWmHints *)data;
+
+ if (new_hints->flags & MWM_HINTS_FUNCTIONS)
+ {
+ hints->flags |= MWM_HINTS_FUNCTIONS;
+ hints->functions = new_hints->functions;
+ }
+ if (new_hints->flags & MWM_HINTS_DECORATIONS)
+ {
+ hints->flags |= MWM_HINTS_DECORATIONS;
+ hints->decorations = new_hints->decorations;
+ }
+ }
+
+ XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
+ hints_atom, hints_atom, 32, PropModeReplace,
+ (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
+
+ if (hints != new_hints)
+ XFree (hints);
+}
+
+/**
+ * gdk_window_set_decorations:
+ * @window: a toplevel #GdkWindow
+ * @decorations: decoration hint mask
+ *
+ * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
+ * This function sets the traditional Motif window manager hints that tell the
+ * window manager which decorations you would like your window to have.
+ * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
+ * using the GDK function directly.
+ *
+ * The @decorations argument is the logical OR of the fields in
+ * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
+ * mask, the other bits indicate which decorations should be turned off.
+ * If #GDK_DECOR_ALL is not included, then the other bits indicate
+ * which decorations should be turned on.
+ *
+ * Most window managers honor a decorations hint of 0 to disable all decorations,
+ * but very few honor all possible combinations of bits.
+ *
+ **/
+void
+gdk_window_set_decorations (GdkWindow *window,
+ GdkWMDecoration decorations)
+{
+ MotifWmHints hints;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ hints.flags = MWM_HINTS_DECORATIONS;
+ hints.decorations = decorations;
+
+ gdk_window_set_mwm_hints (window, &hints);
+}
+
+/**
+ * gdk_window_get_decorations:
+ * @window: The toplevel #GdkWindow to get the decorations from
+ * @decorations: The window decorations will be written here
+ *
+ * Returns the decorations set on the GdkWindow with #gdk_window_set_decorations
+ * Returns: TRUE if the window has decorations set, FALSE otherwise.
+ **/
+gboolean
+gdk_window_get_decorations(GdkWindow *window,
+ GdkWMDecoration *decorations)
+{
+ MotifWmHints *hints;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+ hints = gdk_window_get_mwm_hints (window);
+
+ if (hints)
+ {
+ if (hints->flags & MWM_HINTS_DECORATIONS)
+ {
+ if (decorations)
+ *decorations = hints->decorations;
+ result = TRUE;
+ }
+
+ XFree (hints);
+ }
+
+ return result;
+}
+
+/**
+ * gdk_window_set_functions:
+ * @window: a toplevel #GdkWindow
+ * @functions: bitmask of operations to allow on @window
+ *
+ * This function isn't really good for much. It sets the traditional
+ * Motif window manager hint for which operations the window manager
+ * should allow on a toplevel window. However, few window managers do
+ * anything reliable or interesting with this hint. Many ignore it
+ * entirely.
+ *
+ * The @functions argument is the logical OR of values from the
+ * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
+ * then the other bits indicate which functions to disable; if
+ * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
+ * enable.
+ *
+ **/
+void
+gdk_window_set_functions (GdkWindow *window,
+ GdkWMFunction functions)
+{
+ MotifWmHints hints;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ hints.flags = MWM_HINTS_FUNCTIONS;
+ hints.functions = functions;
+
+ gdk_window_set_mwm_hints (window, &hints);
+}
+
+#ifdef HAVE_SHAPE_EXT
+
+/*
+ * propagate the shapes from all child windows of a GDK window to the parent
+ * window. Shamelessly ripped from Enlightenment's code
+ *
+ * - Raster
+ */
+struct _gdk_span
+{
+ gint start;
+ gint end;
+ struct _gdk_span *next;
+};
+
+static void
+gdk_add_to_span (struct _gdk_span **s,
+ gint x,
+ gint xx)
+{
+ struct _gdk_span *ptr1, *ptr2, *noo, *ss;
+ gchar spanning;
+
+ ptr2 = NULL;
+ ptr1 = *s;
+ spanning = 0;
+ ss = NULL;
+ /* scan the spans for this line */
+ while (ptr1)
+ {
+ /* -- -> new span */
+ /* == -> existing span */
+ /* ## -> spans intersect */
+ /* if we are in the middle of spanning the span into the line */
+ if (spanning)
+ {
+ /* case: ---- ==== */
+ if (xx < ptr1->start - 1)
+ {
+ /* ends before next span - extend to here */
+ ss->end = xx;
+ return;
+ }
+ /* case: ----##=== */
+ else if (xx <= ptr1->end)
+ {
+ /* crosses into next span - delete next span and append */
+ ss->end = ptr1->end;
+ ss->next = ptr1->next;
+ g_free (ptr1);
+ return;
+ }
+ /* case: ---###--- */
+ else
+ {
+ /* overlaps next span - delete and keep checking */
+ ss->next = ptr1->next;
+ g_free (ptr1);
+ ptr1 = ss;
+ }
+ }
+ /* otherwise havent started spanning it in yet */
+ else
+ {
+ /* case: ---- ==== */
+ if (xx < ptr1->start - 1)
+ {
+ /* insert span here in list */
+ noo = g_malloc (sizeof (struct _gdk_span));
+
+ if (noo)
+ {
+ noo->start = x;
+ noo->end = xx;
+ noo->next = ptr1;
+ if (ptr2)
+ ptr2->next = noo;
+ else
+ *s = noo;
+ }
+ return;
+ }
+ /* case: ----##=== */
+ else if ((x < ptr1->start) && (xx <= ptr1->end))
+ {
+ /* expand this span to the left point of the new one */
+ ptr1->start = x;
+ return;
+ }
+ /* case: ===###=== */
+ else if ((x >= ptr1->start) && (xx <= ptr1->end))
+ {
+ /* throw the span away */
+ return;
+ }
+ /* case: ---###--- */
+ else if ((x < ptr1->start) && (xx > ptr1->end))
+ {
+ ss = ptr1;
+ spanning = 1;
+ ptr1->start = x;
+ ptr1->end = xx;
+ }
+ /* case: ===##---- */
+ else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
+ {
+ ss = ptr1;
+ spanning = 1;
+ ptr1->end = xx;
+ }
+ /* case: ==== ---- */
+ /* case handled by next loop iteration - first case */
+ }
+ ptr2 = ptr1;
+ ptr1 = ptr1->next;
+ }
+ /* it started in the middle but spans beyond your current list */
+ if (spanning)
+ {
+ ptr2->end = xx;
+ return;
+ }
+ /* it does not start inside a span or in the middle, so add it to the end */
+ noo = g_malloc (sizeof (struct _gdk_span));
+
+ if (noo)
+ {
+ noo->start = x;
+ noo->end = xx;
+ if (ptr2)
+ {
+ noo->next = ptr2->next;
+ ptr2->next = noo;
+ }
+ else
+ {
+ noo->next = NULL;
+ *s = noo;
+ }
+ }
+ return;
+}
+
+static void
+gdk_add_rectangles (Display *disp,
+ Window win,
+ struct _gdk_span **spans,
+ gint basew,
+ gint baseh,
+ gint x,
+ gint y)
+{
+ gint a, k;
+ gint x1, y1, x2, y2;
+ gint rn, ord;
+ XRectangle *rl;
+
+ rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
+ if (rl)
+ {
+ /* go through all clip rects in this window's shape */
+ for (k = 0; k < rn; k++)
+ {
+ /* for each clip rect, add it to each line's spans */
+ x1 = x + rl[k].x;
+ x2 = x + rl[k].x + (rl[k].width - 1);
+ y1 = y + rl[k].y;
+ y2 = y + rl[k].y + (rl[k].height - 1);
+ if (x1 < 0)
+ x1 = 0;
+ if (y1 < 0)
+ y1 = 0;
+ if (x2 >= basew)
+ x2 = basew - 1;
+ if (y2 >= baseh)
+ y2 = baseh - 1;
+ for (a = y1; a <= y2; a++)
+ {
+ if ((x2 - x1) >= 0)
+ gdk_add_to_span (&spans[a], x1, x2);
+ }
+ }
+ XFree (rl);
+ }
+}
+
+static void
+gdk_propagate_shapes (Display *disp,
+ Window win,
+ gboolean merge)
+{
+ Window rt, par, *list = NULL;
+ gint i, j, num = 0, num_rects = 0;
+ gint x, y, contig;
+ guint w, h, d;
+ gint baseh, basew;
+ XRectangle *rects = NULL;
+ struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
+ XWindowAttributes xatt;
+
+ XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
+ if (h <= 0)
+ return;
+ basew = w;
+ baseh = h;
+ spans = g_malloc (sizeof (struct _gdk_span *) * h);
+
+ for (i = 0; i < h; i++)
+ spans[i] = NULL;
+ XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
+ if (list)
+ {
+ /* go through all child windows and create/insert spans */
+ for (i = 0; i < num; i++)
+ {
+ if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
+ if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
+ gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
+ }
+ if (merge)
+ gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
+
+ /* go through the spans list and build a list of rects */
+ rects = g_malloc (sizeof (XRectangle) * 256);
+ num_rects = 0;
+ for (i = 0; i < baseh; i++)
+ {
+ ptr1 = spans[i];
+ /* go through the line for all spans */
+ while (ptr1)
+ {
+ rects[num_rects].x = ptr1->start;
+ rects[num_rects].y = i;
+ rects[num_rects].width = ptr1->end - ptr1->start + 1;
+ rects[num_rects].height = 1;
+ j = i + 1;
+ /* if there are more lines */
+ contig = 1;
+ /* while contigous rects (same start/end coords) exist */
+ while ((contig) && (j < baseh))
+ {
+ /* search next line for spans matching this one */
+ contig = 0;
+ ptr2 = spans[j];
+ ptr3 = NULL;
+ while (ptr2)
+ {
+ /* if we have an exact span match set contig */
+ if ((ptr2->start == ptr1->start) &&
+ (ptr2->end == ptr1->end))
+ {
+ contig = 1;
+ /* remove the span - not needed */
+ if (ptr3)
+ {
+ ptr3->next = ptr2->next;
+ g_free (ptr2);
+ ptr2 = NULL;
+ }
+ else
+ {
+ spans[j] = ptr2->next;
+ g_free (ptr2);
+ ptr2 = NULL;
+ }
+ break;
+ }
+ /* gone past the span point no point looking */
+ else if (ptr2->start < ptr1->start)
+ break;
+ if (ptr2)
+ {
+ ptr3 = ptr2;
+ ptr2 = ptr2->next;
+ }
+ }
+ /* if a contiguous span was found increase the rect h */
+ if (contig)
+ {
+ rects[num_rects].height++;
+ j++;
+ }
+ }
+ /* up the rect count */
+ num_rects++;
+ /* every 256 new rects increase the rect array */
+ if ((num_rects % 256) == 0)
+ rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
+ ptr1 = ptr1->next;
+ }
+ }
+ /* set the rects as the shape mask */
+ if (rects)
+ {
+ XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
+ ShapeSet, YXSorted);
+ g_free (rects);
+ }
+ XFree (list);
+ }
+ /* free up all the spans we made */
+ for (i = 0; i < baseh; i++)
+ {
+ ptr1 = spans[i];
+ while (ptr1)
+ {
+ ptr2 = ptr1;
+ ptr1 = ptr1->next;
+ g_free (ptr2);
+ }
+ }
+ g_free (spans);
+}
+
+#endif /* HAVE_SHAPE_EXT */
+
+/**
+ * gdk_window_set_child_shapes:
+ * @window: a #GdkWindow
+ *
+ * Sets the shape mask of @window to the union of shape masks
+ * for all children of @window, ignoring the shape mask of @window
+ * itself. Contrast with gdk_window_merge_child_shapes() which includes
+ * the shape mask of @window in the masks to be merged.
+ **/
+void
+gdk_window_set_child_shapes (GdkWindow *window)
+{
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_SHAPE_EXT
+ if (!GDK_WINDOW_DESTROYED (window) &&
+ gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+ gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window), FALSE);
+#endif
+}
+
+/**
+ * gdk_window_merge_child_shapes:
+ * @window: a #GdkWindow
+ *
+ * Merges the shape masks for any child windows into the
+ * shape mask for @window. i.e. the union of all masks
+ * for @window and its children will become the new mask
+ * for @window. See gdk_window_shape_combine_mask().
+ *
+ * This function is distinct from gdk_window_set_child_shapes()
+ * because it includes @window's shape mask in the set of shapes to
+ * be merged.
+ *
+ **/
+void
+gdk_window_merge_child_shapes (GdkWindow *window)
+{
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_SHAPE_EXT
+ if (!GDK_WINDOW_DESTROYED (window) &&
+ gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+ gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window), TRUE);
+#endif
+}
+
+static void
+gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
+{
+ XSetWindowAttributes xattributes;
+ GdkWindowObject *private;
+ guint xattributes_mask = 0;
+
+ g_return_if_fail (window != NULL);
+
+ private = GDK_WINDOW_OBJECT (window);
+ if (private->input_only)
+ return;
+
+ xattributes.bit_gravity = StaticGravity;
+ xattributes_mask |= CWBitGravity;
+ xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
+ XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ CWBitGravity, &xattributes);
+}
+
+static void
+gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
+{
+ XSetWindowAttributes xattributes;
+
+ g_return_if_fail (window != NULL);
+
+ xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
+
+ XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ CWWinGravity, &xattributes);
+}
+
+/**
+ * gdk_window_set_static_gravities:
+ * @window: a #GdkWindow
+ * @use_static: %TRUE to turn on static gravity
+ *
+ * Set the bit gravity of the given window to static, and flag it so
+ * all children get static subwindow gravity. This is used if you are
+ * implementing scary features that involve deep knowledge of the
+ * windowing system. Don't worry about it unless you have to.
+ *
+ * Return value: %TRUE if the server supports static gravity
+ **/
+gboolean
+gdk_window_set_static_gravities (GdkWindow *window,
+ gboolean use_static)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GList *tmp_list;
+
+ g_return_val_if_fail (window != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+ if (!use_static == !private->guffaw_gravity)
+ return TRUE;
+
+ private->guffaw_gravity = use_static;
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ gdk_window_set_static_bit_gravity (window, use_static);
+
+ tmp_list = private->children;
+ while (tmp_list)
+ {
+ gdk_window_set_static_win_gravity (tmp_list->data, use_static);
+
+ tmp_list = tmp_list->next;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+wmspec_moveresize (GdkWindow *window,
+ gint direction,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+
+ XEvent xev;
+
+ /* Release passive grab */
+ gdk_display_pointer_ungrab (display, timestamp);
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.window = GDK_WINDOW_XID (window);
+ xev.xclient.message_type =
+ gdk_macosx_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = root_x;
+ xev.xclient.data.l[1] = root_y;
+ xev.xclient.data.l[2] = direction;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+typedef struct _MoveResizeData MoveResizeData;
+
+struct _MoveResizeData
+{
+ GdkDisplay *display;
+
+ GdkWindow *moveresize_window;
+ GdkWindow *moveresize_emulation_window;
+ gboolean is_resize;
+ GdkWindowEdge resize_edge;
+ gint moveresize_button;
+ gint moveresize_x;
+ gint moveresize_y;
+ gint moveresize_orig_x;
+ gint moveresize_orig_y;
+ gint moveresize_orig_width;
+ gint moveresize_orig_height;
+ GdkWindowHints moveresize_geom_mask;
+ GdkGeometry moveresize_geometry;
+ Time moveresize_process_time;
+ XEvent *moveresize_pending_event;
+};
+
+/* From the WM spec */
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
+#define _NET_WM_MOVERESIZE_SIZE_TOP 1
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
+#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
+#define _NET_WM_MOVERESIZE_MOVE 8
+
+static void
+wmspec_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ gint direction;
+
+ /* Let the compiler turn a switch into a table, instead
+ * of doing the table manually, this way is easier to verify.
+ */
+ switch (edge)
+ {
+ case GDK_WINDOW_EDGE_NORTH_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_NORTH:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOP;
+ break;
+
+ case GDK_WINDOW_EDGE_NORTH_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
+ break;
+
+ case GDK_WINDOW_EDGE_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH_WEST:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
+ break;
+
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
+ direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
+ break;
+
+ default:
+ g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
+ edge);
+ return;
+ break;
+ }
+
+ wmspec_moveresize (window, direction, root_x, root_y, timestamp);
+}
+
+static MoveResizeData *
+get_move_resize_data (GdkDisplay *display,
+ gboolean create)
+{
+ MoveResizeData *mv_resize;
+ static GQuark move_resize_quark = 0;
+
+ if (!move_resize_quark)
+ move_resize_quark = g_quark_from_static_string ("gdk-window-moveresize");
+
+ mv_resize = g_object_get_qdata (G_OBJECT (display), move_resize_quark);
+
+ if (!mv_resize && create)
+ {
+ mv_resize = g_new0 (MoveResizeData, 1);
+ mv_resize->display = display;
+
+ g_object_set_qdata (G_OBJECT (display), move_resize_quark, mv_resize);
+ }
+
+ return mv_resize;
+}
+
+static void
+update_pos (MoveResizeData *mv_resize,
+ gint new_root_x,
+ gint new_root_y)
+{
+ gint dx, dy;
+
+ dx = new_root_x - mv_resize->moveresize_x;
+ dy = new_root_y - mv_resize->moveresize_y;
+
+ if (mv_resize->is_resize)
+ {
+ gint x, y, w, h;
+
+ x = mv_resize->moveresize_orig_x;
+ y = mv_resize->moveresize_orig_y;
+
+ w = mv_resize->moveresize_orig_width;
+ h = mv_resize->moveresize_orig_height;
+
+ switch (mv_resize->resize_edge)
+ {
+ case GDK_WINDOW_EDGE_NORTH_WEST:
+ x += dx;
+ y += dy;
+ w -= dx;
+ h -= dy;
+ break;
+ case GDK_WINDOW_EDGE_NORTH:
+ y += dy;
+ h -= dy;
+ break;
+ case GDK_WINDOW_EDGE_NORTH_EAST:
+ y += dy;
+ h -= dy;
+ w += dx;
+ break;
+ case GDK_WINDOW_EDGE_SOUTH_WEST:
+ h += dy;
+ x += dx;
+ w -= dx;
+ break;
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
+ w += dx;
+ h += dy;
+ break;
+ case GDK_WINDOW_EDGE_SOUTH:
+ h += dy;
+ break;
+ case GDK_WINDOW_EDGE_EAST:
+ w += dx;
+ break;
+ case GDK_WINDOW_EDGE_WEST:
+ x += dx;
+ w -= dx;
+ break;
+ }
+
+ x = MAX (x, 0);
+ y = MAX (y, 0);
+ w = MAX (w, 1);
+ h = MAX (h, 1);
+
+ if (mv_resize->moveresize_geom_mask)
+ {
+ gdk_window_constrain_size (&mv_resize->moveresize_geometry,
+ mv_resize->moveresize_geom_mask,
+ w, h, &w, &h);
+ }
+
+ gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
+ }
+ else
+ {
+ gint x, y;
+
+ x = mv_resize->moveresize_orig_x + dx;
+ y = mv_resize->moveresize_orig_y + dy;
+
+ gdk_window_move (mv_resize->moveresize_window, x, y);
+ }
+}
+
+static void
+finish_drag (MoveResizeData *mv_resize)
+{
+ gdk_window_destroy (mv_resize->moveresize_emulation_window);
+ mv_resize->moveresize_emulation_window = NULL;
+ mv_resize->moveresize_window = NULL;
+
+ if (mv_resize->moveresize_pending_event)
+ {
+ g_free (mv_resize->moveresize_pending_event);
+ mv_resize->moveresize_pending_event = NULL;
+ }
+}
+
+static int
+lookahead_motion_predicate (Display *xdisplay,
+ XEvent *event,
+ XPointer arg)
+{
+ gboolean *seen_release = (gboolean *)arg;
+ GdkDisplay *display = gdk_macosx_lookup_xdisplay (xdisplay);
+ MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
+
+ if (*seen_release)
+ return False;
+
+ switch (event->xany.type)
+ {
+ case ButtonRelease:
+ *seen_release = TRUE;
+ break;
+ case MotionNotify:
+ mv_resize->moveresize_process_time = event->xmotion.time;
+ break;
+ default:
+ break;
+ }
+
+ return False;
+}
+
+static gboolean
+moveresize_lookahead (MoveResizeData *mv_resize,
+ XEvent *event)
+{
+ XEvent tmp_event;
+ gboolean seen_release = FALSE;
+
+ if (mv_resize->moveresize_process_time)
+ {
+ if (event->xmotion.time == mv_resize->moveresize_process_time)
+ {
+ mv_resize->moveresize_process_time = 0;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ XCheckIfEvent (event->xany.display, &tmp_event,
+ lookahead_motion_predicate, (XPointer) & seen_release);
+
+ return mv_resize->moveresize_process_time == 0;
+}
+
+gboolean
+_gdk_moveresize_handle_event (XEvent *event)
+{
+ guint button_mask = 0;
+ GdkWindowObject *window_private;
+ GdkDisplay *display = gdk_macosx_lookup_xdisplay (event->xany.display);
+ MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
+
+ if (!mv_resize || !mv_resize->moveresize_window)
+ return FALSE;
+
+ window_private = (GdkWindowObject *) mv_resize->moveresize_window;
+
+ button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
+
+ switch (event->xany.type)
+ {
+ case MotionNotify:
+ if (window_private->resize_count > 0)
+ {
+ if (mv_resize->moveresize_pending_event)
+ *mv_resize->moveresize_pending_event = *event;
+ else
+ mv_resize->moveresize_pending_event =
+ g_memdup (event, sizeof (XEvent));
+
+ break;
+ }
+ if (!moveresize_lookahead (mv_resize, event))
+ break;
+
+ update_pos (mv_resize,
+ event->xmotion.x_root,
+ event->xmotion.y_root);
+
+ /* This should never be triggered in normal cases, but in the
+ * case where the drag started without an implicit grab being
+ * in effect, we could miss the release if it occurs before
+ * we grab the pointer; this ensures that we will never
+ * get a permanently stuck grab.
+ */
+ if ((event->xmotion.state & button_mask) == 0)
+ finish_drag (mv_resize);
+ break;
+
+ case ButtonRelease:
+ update_pos (mv_resize,
+ event->xbutton.x_root,
+ event->xbutton.y_root);
+
+ if (event->xbutton.button == mv_resize->moveresize_button)
+ finish_drag (mv_resize);
+ break;
+ }
+ return TRUE;
+}
+
+gboolean
+_gdk_moveresize_configure_done (GdkDisplay *display,
+ GdkWindow *window)
+{
+ XEvent *tmp_event;
+ MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
+
+ if (!mv_resize || window != mv_resize->moveresize_window)
+ return FALSE;
+
+ if (mv_resize->moveresize_pending_event)
+ {
+ tmp_event = mv_resize->moveresize_pending_event;
+ mv_resize->moveresize_pending_event = NULL;
+ _gdk_moveresize_handle_event (tmp_event);
+ g_free (tmp_event);
+ }
+
+ return TRUE;
+}
+
+static void
+create_moveresize_window (MoveResizeData *mv_resize,
+ guint32 timestamp)
+{
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ GdkGrabStatus status;
+
+ g_assert (mv_resize->moveresize_emulation_window == NULL);
+
+ attributes.x = -100;
+ attributes.y = -100;
+ attributes.width = 10;
+ attributes.height = 10;
+ attributes.window_type = GDK_WINDOW_TEMP;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.override_redirect = TRUE;
+ attributes.event_mask = 0;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
+
+ mv_resize->moveresize_emulation_window =
+ gdk_window_new (gdk_screen_get_root_window (gdk_display_get_default_screen (mv_resize->display)),
+ &attributes,
+ attributes_mask);
+
+ gdk_window_show (mv_resize->moveresize_emulation_window);
+
+ status = gdk_pointer_grab (mv_resize->moveresize_emulation_window,
+ FALSE,
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK,
+ NULL,
+ NULL,
+ timestamp);
+
+ if (status != GDK_GRAB_SUCCESS)
+ {
+ /* If this fails, some other client has grabbed the window
+ * already.
+ */
+ gdk_window_destroy (mv_resize->moveresize_emulation_window);
+ mv_resize->moveresize_emulation_window = NULL;
+ }
+
+ mv_resize->moveresize_process_time = 0;
+}
+
+/*
+ Calculate mv_resize->moveresize_orig_x and mv_resize->moveresize_orig_y
+ so that calling XMoveWindow with these coordinates will not move the
+ window.
+ Note that this depends on the WM to implement ICCCM-compliant reference
+ point handling.
+*/
+static void
+calculate_unmoving_origin (MoveResizeData *mv_resize)
+{
+ GdkRectangle rect;
+ gint width, height;
+
+ if (mv_resize->moveresize_geom_mask & GDK_HINT_WIN_GRAVITY &&
+ mv_resize->moveresize_geometry.win_gravity == GDK_GRAVITY_STATIC)
+ {
+ gdk_window_get_origin (mv_resize->moveresize_window,
+ &mv_resize->moveresize_orig_x,
+ &mv_resize->moveresize_orig_y);
+ }
+ else
+ {
+ gdk_window_get_frame_extents (mv_resize->moveresize_window, &rect);
+ gdk_window_get_geometry (mv_resize->moveresize_window,
+ NULL, NULL, &width, &height, NULL);
+
+ switch (mv_resize->moveresize_geometry.win_gravity)
+ {
+ case GDK_GRAVITY_NORTH_WEST:
+ mv_resize->moveresize_orig_x = rect.x;
+ mv_resize->moveresize_orig_y = rect.y;
+ break;
+ case GDK_GRAVITY_NORTH:
+ mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
+ mv_resize->moveresize_orig_y = rect.y;
+ break;
+ case GDK_GRAVITY_NORTH_EAST:
+ mv_resize->moveresize_orig_x = rect.x + rect.width - width;
+ mv_resize->moveresize_orig_y = rect.y;
+ break;
+ case GDK_GRAVITY_WEST:
+ mv_resize->moveresize_orig_x = rect.x;
+ mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
+ break;
+ case GDK_GRAVITY_CENTER:
+ mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
+ mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
+ break;
+ case GDK_GRAVITY_EAST:
+ mv_resize->moveresize_orig_x = rect.x + rect.width - width;
+ mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
+ break;
+ case GDK_GRAVITY_SOUTH_WEST:
+ mv_resize->moveresize_orig_x = rect.x;
+ mv_resize->moveresize_orig_y = rect.y + rect.height - height;
+ break;
+ case GDK_GRAVITY_SOUTH:
+ mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
+ mv_resize->moveresize_orig_y = rect.y + rect.height - height;
+ break;
+ case GDK_GRAVITY_SOUTH_EAST:
+ mv_resize->moveresize_orig_x = rect.x + rect.width - width;
+ mv_resize->moveresize_orig_y = rect.y + rect.height - height;
+ break;
+ default:
+ mv_resize->moveresize_orig_x = rect.x;
+ mv_resize->moveresize_orig_y = rect.y;
+ break;
+ }
+ }
+}
+
+static void
+emulate_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
+
+ mv_resize->is_resize = TRUE;
+ mv_resize->moveresize_button = button;
+ mv_resize->resize_edge = edge;
+ mv_resize->moveresize_x = root_x;
+ mv_resize->moveresize_y = root_y;
+ mv_resize->moveresize_window = g_object_ref (window);
+
+ gdk_drawable_get_size (window,
+ &mv_resize->moveresize_orig_width,
+ &mv_resize->moveresize_orig_height);
+
+ mv_resize->moveresize_geom_mask = 0;
+ gdk_window_get_geometry_hints (window,
+ &mv_resize->moveresize_geometry,
+ &mv_resize->moveresize_geom_mask);
+
+ calculate_unmoving_origin (mv_resize);
+
+ create_moveresize_window (mv_resize, timestamp);
+}
+
+static void
+emulate_move_drag (GdkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
+
+ mv_resize->is_resize = FALSE;
+ mv_resize->moveresize_button = button;
+ mv_resize->moveresize_x = root_x;
+ mv_resize->moveresize_y = root_y;
+
+ mv_resize->moveresize_window = g_object_ref (window);
+
+ calculate_unmoving_origin (mv_resize);
+
+ create_moveresize_window (mv_resize, timestamp);
+}
+
+/**
+ * gdk_window_begin_resize_drag:
+ * @window: a toplevel #GdkWindow
+ * @edge: the edge or corner from which the drag is started
+ * @button: the button being used to drag
+ * @root_x: root window X coordinate of mouse click that began the drag
+ * @root_y: root window Y coordinate of mouse click that began the drag
+ * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
+ *
+ * Begins a window resize operation (for a toplevel window).
+ * You might use this function to implement a "window resize grip," for
+ * example; in fact #GtkStatusbar uses it. The function works best
+ * with window managers that support the Extended Window Manager Hints spec
+ * (see http://www.freedesktop.org), but has a fallback implementation
+ * for other window managers.
+ *
+ **/
+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));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (gdk_macosx_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
+ gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
+ wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
+ else
+ emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
+}
+
+/**
+ * gdk_window_begin_move_drag:
+ * @window: a toplevel #GdkWindow
+ * @button: the button being used to drag
+ * @root_x: root window X coordinate of mouse click that began the drag
+ * @root_y: root window Y coordinate of mouse click that began the drag
+ * @timestamp: timestamp of mouse click that began the drag
+ *
+ * Begins a window move operation (for a toplevel window). You might
+ * use this function to implement a "window move grip," for
+ * example. The function works best with window managers that support
+ * the Extended Window Manager Hints spec (see
+ * http://www.freedesktop.org), but has a fallback implementation for
+ * other window managers.
+ *
+ **/
+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));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (gdk_macosx_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
+ gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
+ wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, root_x, root_y,
+ timestamp);
+ else
+ emulate_move_drag (window, button, root_x, root_y, timestamp);
+}
+
+/**
+ * gdk_window_enable_synchronized_configure:
+ * @window: a toplevel #GdkWindow
+ *
+ * Indicates that the application will cooperate with the window
+ * system in synchronizing the window repaint with the window
+ * manager during resizing operations. After an application calls
+ * this function, it must call gdk_window_configure_finished() every
+ * time it has finished all processing associated with a set of
+ * Configure events. Toplevel GTK+ windows automatically use this
+ * protocol.
+ *
+ * On X, calling this function makes @window participate in the
+ * _NET_WM_SYNC_REQUEST window manager protocol.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindowImplMacOSX *impl;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ impl = GDK_WINDOW_IMPL_MACOSX (private->impl);
+
+ if (!impl->use_synchronized_configure)
+ {
+ impl->use_synchronized_configure = TRUE;
+ ensure_sync_counter (window);
+ }
+}
+
+/**
+ * gdk_window_configure_finished:
+ * @window: a toplevel #GdkWindow
+ *
+ * Signal to the window system that the application has finished
+ * handling Configure events it has received. Window Managers can
+ * use this to better synchronize the frame repaint with the
+ * application. GTK+ applications will automatically call this
+ * function when appropriate.
+ *
+ * This function can only be called if gdk_window_enable_synchronized_configure()
+ * was called previously.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_window_configure_finished (GdkWindow *window)
+{
+ GdkWindowImplMacOSX *impl;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ impl = GDK_WINDOW_IMPL_MACOSX (((GdkWindowObject *)window)->impl);
+ if (!impl->use_synchronized_configure)
+ return;
+
+#ifdef HAVE_XSYNC
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+ GdkToplevelMacOSX *toplevel = _gdk_macosx_window_get_toplevel (window);
+
+ if (toplevel && toplevel->update_counter != None &&
+ GDK_DISPLAY_MACOSX (display)->use_sync &&
+ !XSyncValueIsZero (toplevel->current_counter_value))
+ {
+ XSyncSetCounter (GDK_WINDOW_XDISPLAY (window),
+ toplevel->update_counter,
+ toplevel->current_counter_value);
+
+ XSyncIntToValue (&toplevel->current_counter_value, 0);
+ }
+ }
+#endif
+}
+
+
+#endif
+
+void
+_gdk_window_init_position (GdkWindow *window)
+{
+
+}
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 623df1cb39..bc30bdd882 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -658,20 +658,23 @@ gtkinclude_HEADERS = $(gtk_public_h_sources) $(gtk_semi_private_h_sources) $(gtk
libgtk_x11_2_0_la_SOURCES = $(gtk_c_sources) $(gtk_plug_c_sources)
libgtk_linux_fb_2_0_la_SOURCES = $(gtk_c_sources)
libgtk_win32_2_0_la_SOURCES = $(gtk_c_sources)
+libgtk_macosx_2_0_la_SOURCES = $(gtk_c_sources)
libgtk_x11_2_0_la_LDFLAGS = $(libtool_opts)
libgtk_linux_fb_2_0_la_LDFLAGS = $(libtool_opts)
libgtk_win32_2_0_la_LDFLAGS = $(libtool_opts)
+libgtk_macosx_2_0_la_LDFLAGS = $(libtool_opts)
libgtk_x11_2_0_la_LIBADD = $(libadd)
libgtk_linux_fb_2_0_la_LIBADD = $(libadd)
libgtk_win32_2_0_la_LIBADD = $(libadd) $(gtk_win32res_lo) -lole32 -lwsock32 -lgdi32
libgtk_win32_2_0_la_DEPENDENCIES = $(gtk_def) $(gtk_win32res_lo)
+libgtk_macosx_2_0_la_LIBADD = $(libadd)
if USE_WIN32
libgtk_target_ldflags = $(gtk_win32_symbols)
endif
-EXTRA_LTLIBRARIES = libgtk-x11-2.0.la libgtk-linux-fb-2.0.la libgtk-win32-2.0.la
+EXTRA_LTLIBRARIES = libgtk-x11-2.0.la libgtk-linux-fb-2.0.la libgtk-win32-2.0.la libgtk-macosx-2.0.la
install-exec-hook:
if DISABLE_EXPLICIT_DEPS