summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@imendio.com>2005-11-22 10:03:32 +0000
committerAnders Carlsson <andersca@src.gnome.org>2005-11-22 10:03:32 +0000
commit1097260aa7ed40e508e181feed4d736727268eb5 (patch)
treefc2cf27583bbe96d0e464d90e9fbec2f07d7b76a
parentfbebb232db61324e89406a27bc914ace62c68e79 (diff)
downloadgdk-pixbuf-1097260aa7ed40e508e181feed4d736727268eb5.tar.gz
Add quartz backend.
2005-11-21 Anders Carlsson <andersca@imendio.com> * configure.in: * gtk/Makefile.am: * gdk/Makefile.am: * gdk/quartz/*: Add quartz backend. * docs/tools/Makefile.am: Only build docshooter when the X11 backend is used. * gtk/gtkplug-stub.c: Include gtkplug.h here. * gtk/gtksocket-stub.c: Include gtksocket.h here.
-rw-r--r--ChangeLog1
-rw-r--r--ChangeLog.pre-2-101
-rw-r--r--configure.in17
-rw-r--r--docs/tools/Makefile.am2
-rw-r--r--gdk/Makefile.am9
-rw-r--r--gdk/quartz/GdkQuartzView.c83
-rw-r--r--gdk/quartz/GdkQuartzView.h35
-rw-r--r--gdk/quartz/GdkQuartzWindow.c114
-rw-r--r--gdk/quartz/GdkQuartzWindow.h31
-rw-r--r--gdk/quartz/Makefile.am45
-rw-r--r--gdk/quartz/gdkcolor-quartz.c195
-rw-r--r--gdk/quartz/gdkcursor-quartz.c310
-rw-r--r--gdk/quartz/gdkdisplay-quartz.c143
-rw-r--r--gdk/quartz/gdkdnd-quartz.c178
-rw-r--r--gdk/quartz/gdkdrawable-quartz.c597
-rw-r--r--gdk/quartz/gdkdrawable-quartz.h63
-rw-r--r--gdk/quartz/gdkevents-quartz.c1286
-rw-r--r--gdk/quartz/gdkfont-quartz.c114
-rw-r--r--gdk/quartz/gdkgc-quartz.c216
-rw-r--r--gdk/quartz/gdkgeometry-quartz.c34
-rw-r--r--gdk/quartz/gdkglobals-quartz.c27
-rw-r--r--gdk/quartz/gdkim-quartz.c73
-rw-r--r--gdk/quartz/gdkimage-quartz.c176
-rw-r--r--gdk/quartz/gdkinput-old.c68
-rw-r--r--gdk/quartz/gdkinput.c387
-rw-r--r--gdk/quartz/gdkinputprivate.h153
-rw-r--r--gdk/quartz/gdkkeys-quartz.c487
-rw-r--r--gdk/quartz/gdkmain-quartz.c78
-rw-r--r--gdk/quartz/gdkpixmap-quartz.c232
-rw-r--r--gdk/quartz/gdkpixmap-quartz.h64
-rw-r--r--gdk/quartz/gdkprivate-quartz.h113
-rw-r--r--gdk/quartz/gdkproperty-quartz.c85
-rw-r--r--gdk/quartz/gdkquartz.h7
-rw-r--r--gdk/quartz/gdkscreen-quartz.c196
-rw-r--r--gdk/quartz/gdkselection-quartz.c132
-rw-r--r--gdk/quartz/gdkvisual-quartz.c219
-rw-r--r--gdk/quartz/gdkwindow-quartz.c1187
-rw-r--r--gdk/quartz/gdkwindow-quartz.h72
-rw-r--r--gtk/Makefile.am5
-rw-r--r--gtk/gtkplug-stub.c1
-rw-r--r--gtk/gtksocket-stub.c1
41 files changed, 7228 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index a71cfecf5..951070137 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -38,7 +38,6 @@
(gtk_combo_box_child_show, gtk_combo_box_child_hide): Use
g_signal_emit, not g_signal_emit_by_name.
->>>>>>> 1.7265
2005-11-18 Matthias Clasen <mclasen@redhat.com>
Fix crashes in connection with pathbar scrolling (#321560,
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index a71cfecf5..951070137 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -38,7 +38,6 @@
(gtk_combo_box_child_show, gtk_combo_box_child_hide): Use
g_signal_emit, not g_signal_emit_by_name.
->>>>>>> 1.7265
2005-11-18 Matthias Clasen <mclasen@redhat.com>
Fix crashes in connection with pathbar scrolling (#321560,
diff --git a/configure.in b/configure.in
index 7741c3720..3fb359992 100644
--- a/configure.in
+++ b/configure.in
@@ -224,13 +224,13 @@ else
gdktarget=x11
fi
-AC_ARG_WITH(gdktarget, [ --with-gdktarget=[[x11/linux-fb/win32]] select non-default GDK target],
+AC_ARG_WITH(gdktarget, [ --with-gdktarget=[[x11/linux-fb/win32/quartz]] select non-default GDK target],
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|quartz) ;;
+ *) AC_MSG_ERROR([Invalid target for GDK: use x11, linux-fb, quartz or win32.]);;
esac
gdktargetlib=libgdk-$gdktarget-$GTK_API_VERSION.la
@@ -1325,6 +1325,13 @@ else
AM_CONDITIONAL(USE_WIN32, false)
fi
+if test "x$gdktarget" = "xquartz"; then
+ GDK_EXTRA_LIBS="$GDK_EXTRA_LIBS -framework Cocoa"
+ AM_CONDITIONAL(USE_QUARTZ, true)
+else
+ AM_CONDITIONAL(USE_QUARTZ, false)
+fi
+
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"
@@ -1569,6 +1576,9 @@ elif test "x$gdktarget" = "xlinux-fb" ; then
gdk_windowing='
#define GDK_WINDOWING_FB
#define GDK_NATIVE_WINDOW_POINTER'
+elif test "x$gdktarget" = "xquartz" ; then
+ gdk_windowing='
+#define GDK_WINDOWING_QUARTZ'
fi
if test x$gdk_wchar_h = xyes; then
@@ -1625,6 +1635,7 @@ gdk/win32/Makefile
gdk/win32/rc/Makefile
gdk/win32/rc/gdk.rc
gdk/linux-fb/Makefile
+gdk/quartz/Makefile
gtk/Makefile
gtk/makefile.msc
gtk/gtkversion.h
diff --git a/docs/tools/Makefile.am b/docs/tools/Makefile.am
index 6d6c95631..97ec058f2 100644
--- a/docs/tools/Makefile.am
+++ b/docs/tools/Makefile.am
@@ -17,7 +17,7 @@ LDADDS = \
$(top_builddir)/gtk/$(gtktargetlib) \
$(GTK_DEP_LIBS)
-if OS_UNIX
+if USE_X11
noinst_PROGRAMS = \
doc-shooter
endif
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index 56c47b199..c2a4f8de8 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -1,7 +1,7 @@
## Makefile.am for gtk+/gdk
SUBDIRS = $(gdktarget)
-DIST_SUBDIRS = linux-fb win32 x11
+DIST_SUBDIRS = linux-fb win32 x11 quartz
EXTRA_DIST = \
keynames.txt \
@@ -144,6 +144,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_quartz_2_0_la_SOURCES = $(common_sources) gdkkeynames.c
+libgdk_quartz_2_0_la_LIBADD = quartz/libgdk-quartz.la $(GDK_DEP_LIBS) \
+ $(top_builddir)/gdk-pixbuf/libgdk_pixbuf-$(GTK_API_VERSION).la
+libgdk_quartz_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
@@ -198,7 +203,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-quartz-2.0.la
MAINTAINERCLEANFILES = gdkenumtypes.h stamp-gdkenumtypes.h gdkenumtypes.c \
gdkmarshalers.h gdkmarshalers.c
diff --git a/gdk/quartz/GdkQuartzView.c b/gdk/quartz/GdkQuartzView.c
new file mode 100644
index 000000000..979e0e354
--- /dev/null
+++ b/gdk/quartz/GdkQuartzView.c
@@ -0,0 +1,83 @@
+/* GdkQuartzView.m
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#import "GdkQuartzView.h"
+#include "gdkwindow-quartz.h"
+#include "gdkprivate-quartz.h"
+
+@implementation GdkQuartzView
+
+-(void)setGdkWindow:(GdkWindow *)window
+{
+ gdk_window = window;
+}
+
+-(GdkWindow *)gdkWindow
+{
+ return gdk_window;
+}
+
+-(BOOL)isFlipped
+{
+ return YES;
+}
+
+-(BOOL)isOpaque
+{
+ /* A view is opaque if its GdkWindow doesn't have the RGBA colormap */
+ return gdk_drawable_get_colormap (gdk_window) != gdk_screen_get_rgba_colormap (_gdk_screen);
+}
+
+-(void)drawRect:(NSRect)rect
+{
+ NSRect bounds = [self bounds];
+ GdkRectangle gdk_rect;
+
+ GDK_QUARTZ_ALLOC_POOL;
+
+ /* Draw background */
+ if (GDK_WINDOW_OBJECT (gdk_window)->bg_pixmap == NULL)
+ {
+ CGContextRef context;
+
+ context = [[NSGraphicsContext currentContext] graphicsPort];
+ CGContextSaveGState (context);
+
+ _gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (gdk_window),
+ GDK_WINDOW_OBJECT (gdk_window)->bg_color.pixel);
+
+ CGContextFillRect (context, CGRectMake (bounds.origin.x, bounds.origin.y,
+ bounds.size.width, bounds.size.height));
+ CGContextRestoreGState (context);
+ }
+
+ gdk_rect.x = bounds.origin.x;
+ gdk_rect.y = bounds.origin.y;
+ gdk_rect.width = bounds.size.width;
+ gdk_rect.height = bounds.size.height;
+
+ gdk_window_invalidate_rect (gdk_window, &gdk_rect, FALSE);
+ gdk_window_process_updates (gdk_window, FALSE);
+
+ GDK_QUARTZ_RELEASE_POOL;
+}
+
+@end
diff --git a/gdk/quartz/GdkQuartzView.h b/gdk/quartz/GdkQuartzView.h
new file mode 100644
index 000000000..0e25b2ecc
--- /dev/null
+++ b/gdk/quartz/GdkQuartzView.h
@@ -0,0 +1,35 @@
+/* GdkQuartzView.h
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Quartz/Quartz.h>
+#include "gdkwindow.h"
+
+@interface GdkQuartzView : NSView {
+ GdkWindow *gdk_window;
+}
+
+-(void)setGdkWindow:(GdkWindow *)window;
+-(GdkWindow *)gdkWindow;
+
+@end
+
+
+
+
diff --git a/gdk/quartz/GdkQuartzWindow.c b/gdk/quartz/GdkQuartzWindow.c
new file mode 100644
index 000000000..2365dd4a4
--- /dev/null
+++ b/gdk/quartz/GdkQuartzWindow.c
@@ -0,0 +1,114 @@
+/* GdkQuartzWindow.m
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#import "GdkQuartzWindow.h"
+#include "gdkwindow-quartz.h"
+#include "gdkprivate-quartz.h"
+
+@implementation GdkQuartzWindow
+
+-(BOOL)windowShouldClose:(id)sender
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkEvent *event;
+
+ event = gdk_event_new (GDK_DELETE);
+
+ event->any.window = g_object_ref (window);
+ event->any.send_event = FALSE;
+
+ _gdk_event_queue_append (gdk_display_get_default (), event);
+
+ return NO;
+}
+
+-(void)windowDidMiniaturize:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ gdk_synthesize_window_state (window, 0,
+ GDK_WINDOW_STATE_ICONIFIED);
+}
+
+-(void)windowDidDeminiaturize:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0);
+}
+
+-(void)windowDidBecomeKey:(NSNotification *)aNotification
+{
+ GdkWindow *window = [[self contentView] gdkWindow];
+
+ _gdk_quartz_update_focus_window (window);
+}
+
+-(void)windowDidResize:(NSNotification *)aNotification
+{
+ NSRect content_rect = [self contentRectForFrameRect:[self frame]];
+ GdkWindow *window = [[self contentView] gdkWindow];
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+ GdkEvent *event;
+
+ impl->width = content_rect.size.width;
+ impl->height = content_rect.size.height;
+
+ /* Synthesize a configure event */
+
+ event = gdk_event_new (GDK_CONFIGURE);
+ event->configure.window = g_object_ref (window);
+ event->configure.x = private->x;
+ event->configure.y = private->y;
+ event->configure.width = impl->width;
+ event->configure.height = impl->height;
+
+ _gdk_event_queue_append (gdk_display_get_default (), event);
+
+ /* Update tracking rectangle */
+ [[self contentView] removeTrackingRect:impl->tracking_rect];
+ impl->tracking_rect = [impl->view addTrackingRect:NSMakeRect(0, 0, impl->width, impl->height)
+ owner:impl->view
+ userData:nil
+ assumeInside:NO];
+}
+
+-(id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag
+{
+ self = [super initWithContentRect:contentRect
+ styleMask:styleMask
+ backing:backingType
+ defer:flag];
+
+
+ /* A possible modification here would be to only accept mouse moved events
+ * if any of the child GdkWindows are interested in mouse moved events.
+ */
+ [self setAcceptsMouseMovedEvents:YES];
+
+ [self setDelegate:self];
+ [self setReleasedWhenClosed:YES];
+
+ return self;
+}
+
+@end
diff --git a/gdk/quartz/GdkQuartzWindow.h b/gdk/quartz/GdkQuartzWindow.h
new file mode 100644
index 000000000..c73da5582
--- /dev/null
+++ b/gdk/quartz/GdkQuartzWindow.h
@@ -0,0 +1,31 @@
+/* GdkQuartzWindow.h
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#import <Quartz/Quartz.h>
+#include "gdkwindow.h"
+
+@interface GdkQuartzWindow : NSWindow {
+}
+
+@end
+
+
+
+
diff --git a/gdk/quartz/Makefile.am b/gdk/quartz/Makefile.am
new file mode 100644
index 000000000..b9d0b98a2
--- /dev/null
+++ b/gdk/quartz/Makefile.am
@@ -0,0 +1,45 @@
+libgdkincludedir = $(includedir)/gtk-2.0/gdk
+
+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) \
+ "-xobjective-c"
+
+LDADDS = $(GDK_DEP_LIBS)
+
+noinst_LTLIBRARIES = libgdk-quartz.la
+
+libgdk_quartz_la_SOURCES = \
+ GdkQuartzView.c \
+ GdkQuartzView.h \
+ GdkQuartzWindow.c \
+ GdkQuartzWindow.h \
+ gdkcolor-quartz.c \
+ gdkcursor-quartz.c \
+ gdkdisplay-quartz.c \
+ gdkdnd-quartz.c \
+ gdkdrawable-quartz.c \
+ gdkevents-quartz.c \
+ gdkfont-quartz.c \
+ gdkgc-quartz.c \
+ gdkgeometry-quartz.c \
+ gdkglobals-quartz.c \
+ gdkim-quartz.c \
+ gdkimage-quartz.c \
+ gdkinput.c \
+ gdkkeys-quartz.c \
+ gdkmain-quartz.c \
+ gdkpixmap-quartz.c \
+ gdkproperty-quartz.c \
+ gdkscreen-quartz.c \
+ gdkselection-quartz.c \
+ gdkvisual-quartz.c \
+ gdkwindow-quartz.c
diff --git a/gdk/quartz/gdkcolor-quartz.c b/gdk/quartz/gdkcolor-quartz.c
new file mode 100644
index 000000000..92a9e3f2a
--- /dev/null
+++ b/gdk/quartz/gdkcolor-quartz.c
@@ -0,0 +1,195 @@
+/* gdkcolor-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkcolor.h"
+#include "gdkprivate-quartz.h"
+
+GType
+gdk_colormap_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkColormapClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkColormap),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "GdkColormap",
+ &object_info,
+ 0);
+ }
+
+ return object_type;
+}
+
+GdkColormap *
+gdk_colormap_new (GdkVisual *visual,
+ gint private_cmap)
+{
+ g_return_val_if_fail (visual != NULL, NULL);
+
+ /* FIXME: Implement */
+ return NULL;
+}
+
+GdkColormap *
+gdk_screen_get_system_colormap (GdkScreen *screen)
+{
+ static GdkColormap *colormap = NULL;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ if (!colormap)
+ {
+ colormap = g_object_new (GDK_TYPE_COLORMAP, NULL);
+
+ colormap->visual = gdk_visual_get_system ();
+ colormap->size = colormap->visual->colormap_size;
+ }
+
+ return colormap;
+}
+
+
+GdkColormap *
+gdk_screen_get_rgba_colormap (GdkScreen *screen)
+{
+ static GdkColormap *colormap = NULL;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ if (!colormap)
+ {
+ colormap = g_object_new (GDK_TYPE_COLORMAP, NULL);
+
+ colormap->visual = gdk_screen_get_rgba_visual (screen);
+ colormap->size = colormap->visual->colormap_size;
+ }
+
+ return colormap;
+}
+
+void
+gdk_colormap_change (GdkColormap *colormap,
+ gint ncolors)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_colormap_free_colors (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors)
+{
+ /* This function shouldn't do anything since
+ * colors are neve allocated.
+ */
+}
+
+gint
+gdk_colormap_alloc_colors (GdkColormap *colormap,
+ GdkColor *colors,
+ gint ncolors,
+ gboolean writeable,
+ gboolean best_match,
+ gboolean *success)
+{
+ int i;
+
+ for (i = 0; i < ncolors; i++)
+ {
+ colors[i].pixel = ((colors[i].red >> 8) & 0xff) << 16 |
+ ((colors[i].green >> 8) & 0xff) << 8 |
+ ((colors[i].blue >> 8) & 0xff);
+ }
+
+ return ncolors;
+}
+
+void
+gdk_colormap_query_color (GdkColormap *colormap,
+ gulong pixel,
+ GdkColor *result)
+{
+ result->red = pixel >> 16 & 0xff;
+ result->red += result->red << 8;
+
+ result->green = pixel >> 8 & 0xff;
+ result->green += result->green << 8;
+
+ result->blue = pixel & 0xff;
+ result->blue += result->blue << 8;
+}
+
+GdkScreen*
+gdk_colormap_get_screen (GdkColormap *cmap)
+{
+ g_return_val_if_fail (cmap != NULL, NULL);
+
+ return gdk_screen_get_default ();
+}
+
+void
+_gdk_quartz_set_context_fill_color_from_pixel (CGContextRef context, GdkColormap *colormap, guint32 pixel)
+{
+ float red, green, blue, alpha;
+
+ red = (pixel >> 16 & 0xff) / 255.0;
+ green = (pixel >> 8 & 0xff) / 255.0;
+ blue = (pixel & 0xff) / 255.0;
+
+ if (colormap && gdk_colormap_get_visual (colormap)->depth == 32)
+ alpha = (pixel >> 24 & 0xff) / 255.0;
+ else
+ alpha = 1.0;
+
+ CGContextSetRGBFillColor (context, red, green, blue, alpha);
+}
+
+void
+_gdk_quartz_set_context_stroke_color_from_pixel (CGContextRef context, GdkColormap *colormap, guint32 pixel)
+{
+ float red, green, blue, alpha;
+
+ red = (pixel >> 16 & 0xff) / 255.0;
+ green = (pixel >> 8 & 0xff) / 255.0;
+ blue = (pixel & 0xff) / 255.0;
+
+ if (colormap && gdk_colormap_get_visual (colormap)->depth == 32)
+ alpha = (pixel >> 24 & 0xff) / 255.0;
+ else
+ alpha = 1.0;
+
+ CGContextSetRGBStrokeColor (context, red, green, blue, 1.0);
+}
+
diff --git a/gdk/quartz/gdkcursor-quartz.c b/gdk/quartz/gdkcursor-quartz.c
new file mode 100644
index 000000000..e87d0481b
--- /dev/null
+++ b/gdk/quartz/gdkcursor-quartz.c
@@ -0,0 +1,310 @@
+/* gdkcursor-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkdisplay.h"
+#include "gdkcursor.h"
+#include "gdkprivate-quartz.h"
+
+static GdkCursor *
+gdk_quartz_cursor_new_from_nscursor (NSCursor *nscursor, GdkCursorType cursor_type)
+{
+ GdkCursorPrivate *private;
+ GdkCursor *cursor;
+
+ private = g_new (GdkCursorPrivate, 1);
+ private->nscursor = nscursor;
+ cursor = (GdkCursor *)private;
+ cursor->type = cursor_type;
+ cursor->ref_count = 1;
+
+ return cursor;
+}
+
+GdkCursor*
+gdk_cursor_new_for_display (GdkDisplay *display,
+ GdkCursorType cursor_type)
+{
+ NSCursor *nscursor;
+
+ g_return_val_if_fail (display == gdk_display_get_default (), NULL);
+
+ switch (cursor_type)
+ {
+ case GDK_XTERM:
+ nscursor = [NSCursor IBeamCursor];
+ break;
+ case GDK_SB_H_DOUBLE_ARROW:
+ nscursor = [NSCursor resizeLeftRightCursor];
+ break;
+ case GDK_SB_V_DOUBLE_ARROW:
+ nscursor = [NSCursor resizeUpDownCursor];
+ break;
+ default:
+ g_warning ("Unsupported cursor type %d, using default", cursor_type);
+ nscursor = [NSCursor arrowCursor];
+ }
+
+ [nscursor retain];
+
+ return gdk_quartz_cursor_new_from_nscursor (nscursor, cursor_type);
+}
+
+GdkCursor*
+gdk_cursor_new_from_pixmap (GdkPixmap *source,
+ GdkPixmap *mask,
+ const GdkColor *fg,
+ const GdkColor *bg,
+ gint x,
+ gint y)
+{
+ NSAutoreleasePool *pool;
+ NSBitmapImageRep *bitmap_rep;
+ NSImage *image;
+ NSCursor *nscursor;
+ GdkCursor *cursor;
+ gint width, height;
+ gint tmp_x, tmp_y;
+ guchar *dst_data, *mask_data, *src_data;
+ guchar *mask_start, *src_start;
+ int dst_stride;
+
+ gdk_drawable_get_size (source, &width, &height);
+
+ g_return_val_if_fail (GDK_IS_PIXMAP (source), NULL);
+ g_return_val_if_fail (GDK_IS_PIXMAP (mask), NULL);
+ g_return_val_if_fail (fg != NULL, NULL);
+ g_return_val_if_fail (bg != NULL, NULL);
+
+ pool = [[NSAutoreleasePool alloc] init];
+
+ bitmap_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+ pixelsWide:width pixelsHigh:height
+ bitsPerSample:8 samplesPerPixel:4
+ hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:0 bitsPerPixel:0];
+
+ dst_stride = [bitmap_rep bytesPerRow];
+ mask_start = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (mask)->impl)->data;
+ src_start = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (source)->impl)->data;
+
+ for (tmp_y = 0; tmp_y < height; tmp_y++)
+ {
+ dst_data = [bitmap_rep bitmapData] + tmp_y * dst_stride;
+ mask_data = mask_start + tmp_y * width;
+ src_data = src_start + tmp_y * width;
+
+ for (tmp_x = 0; tmp_x < width; tmp_x++)
+ {
+ if (*mask_data++)
+ {
+ const GdkColor *color;
+
+ if (*src_data++)
+ color = fg;
+ else
+ color = bg;
+
+ *dst_data++ = (color->red >> 8) & 0xff;
+ *dst_data++ = (color->green >> 8) & 0xff;
+ *dst_data++ = (color->blue >> 8) & 0xff;
+ *dst_data++ = 0xff;
+
+ }
+ else
+ {
+ *dst_data++ = 0x00;
+ *dst_data++ = 0x00;
+ *dst_data++ = 0x00;
+ *dst_data++ = 0x00;
+
+ src_data++;
+ }
+ }
+ }
+ image = [[NSImage alloc] init];
+ [image addRepresentation:bitmap_rep];
+ [bitmap_rep release];
+
+ nscursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(x, y)];
+ [image release];
+
+ cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP);
+ [pool release];
+
+ return cursor;
+}
+
+GdkCursor *
+gdk_cursor_new_from_pixbuf (GdkDisplay *display,
+ GdkPixbuf *pixbuf,
+ gint x,
+ gint y)
+{
+ NSAutoreleasePool *pool;
+ NSBitmapImageRep *bitmap_rep;
+ NSImage *image;
+ NSCursor *nscursor;
+ GdkCursor *cursor;
+ gboolean has_alpha;
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+ g_return_val_if_fail (0 <= x && x < gdk_pixbuf_get_width (pixbuf), NULL);
+ g_return_val_if_fail (0 <= y && y < gdk_pixbuf_get_height (pixbuf), NULL);
+
+ pool = [[NSAutoreleasePool alloc] init];
+
+ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+
+ /* Create a bitmap image rep */
+ bitmap_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+ pixelsWide:gdk_pixbuf_get_width (pixbuf)
+ pixelsHigh:gdk_pixbuf_get_height (pixbuf)
+ bitsPerSample:8 samplesPerPixel:has_alpha ? 4 : 3
+ hasAlpha:has_alpha isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:0 bitsPerPixel:0];
+
+ {
+ /* Add pixel data to bitmap rep */
+ guchar *src, *dst;
+ int src_stride, dst_stride;
+ int x, y;
+
+ src_stride = gdk_pixbuf_get_rowstride (pixbuf);
+ dst_stride = [bitmap_rep bytesPerRow];
+
+ for (y = 0; y < gdk_pixbuf_get_height (pixbuf); y++)
+ {
+ src = gdk_pixbuf_get_pixels (pixbuf) + y * src_stride;
+ dst = [bitmap_rep bitmapData] + y * dst_stride;
+
+ for (x = 0; x < gdk_pixbuf_get_width (pixbuf); x++)
+ {
+ if (has_alpha)
+ {
+ guchar red, green, blue, alpha;
+
+ red = *src++;
+ green = *src++;
+ blue = *src++;
+ alpha = *src++;
+
+ *dst++ = (red * alpha) / 255;
+ *dst++ = (green * alpha) / 255;
+ *dst++ = (blue * alpha) / 255;
+ *dst++ = alpha;
+ }
+ else
+ {
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ }
+ }
+ }
+ }
+
+ image = [[NSImage alloc] init];
+ [image addRepresentation:bitmap_rep];
+ [bitmap_rep release];
+
+ nscursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(x, y)];
+ [image release];
+
+ cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP);
+ [pool release];
+
+ return cursor;
+}
+
+GdkCursor*
+gdk_cursor_new_from_name (GdkDisplay *display,
+ const gchar *name)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+void
+_gdk_cursor_destroy (GdkCursor *cursor)
+{
+ GdkCursorPrivate *private;
+
+ g_return_if_fail (cursor != NULL);
+ g_return_if_fail (cursor->ref_count == 0);
+
+ private = (GdkCursorPrivate *)cursor;
+ [private->nscursor release];
+
+ g_free (private);
+}
+
+gboolean
+gdk_display_supports_cursor_alpha (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+ return TRUE;
+}
+
+gboolean
+gdk_display_supports_cursor_color (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+ return TRUE;
+}
+
+guint
+gdk_display_get_default_cursor_size (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
+
+ /* Mac OS X doesn't have the notion of a default size */
+ return 32;
+}
+
+void
+gdk_display_get_maximal_cursor_size (GdkDisplay *display,
+ guint *width,
+ guint *height)
+{
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+
+ /* Cursor sizes in Mac OS X can be arbitrarily large */
+ *width = 65536;
+ *height = 65536;
+}
+
+GdkDisplay *
+gdk_cursor_get_display (GdkCursor *cursor)
+{
+ g_return_val_if_fail (cursor != NULL, NULL);
+
+ return gdk_display_get_default ();
+}
+
+GdkPixbuf *
+gdk_cursor_get_image (GdkCursor *cursor)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
diff --git a/gdk/quartz/gdkdisplay-quartz.c b/gdk/quartz/gdkdisplay-quartz.c
new file mode 100644
index 000000000..5d064716d
--- /dev/null
+++ b/gdk/quartz/gdkdisplay-quartz.c
@@ -0,0 +1,143 @@
+/* gdkdisplay-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdk.h"
+#include "gdkprivate-quartz.h"
+
+void
+_gdk_windowing_set_default_display (GdkDisplay *display)
+{
+ g_assert (_gdk_display == display);
+}
+
+GdkDisplay *
+gdk_display_open (const gchar *display_name)
+{
+ if (_gdk_display != NULL)
+ return NULL;
+
+ _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL);
+ _gdk_screen = g_object_new (GDK_TYPE_SCREEN, NULL);
+
+ /* Initialize application */
+ [NSApplication sharedApplication];
+
+ _gdk_visual_init ();
+ gdk_screen_set_default_colormap (_gdk_screen,
+ gdk_screen_get_system_colormap (_gdk_screen));
+ _gdk_windowing_window_init ();
+
+
+ _gdk_events_init ();
+#if 0
+ /* FIXME: Remove the #if 0 when we have these functions */
+ _gdk_input_init ();
+ _gdk_dnd_init ();
+#endif
+
+ g_signal_emit_by_name (gdk_display_manager_get (),
+ "display_opened", _gdk_display);
+
+ return _gdk_display;
+}
+
+G_CONST_RETURN gchar *
+gdk_display_get_name (GdkDisplay *display)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+int
+gdk_display_get_n_screens (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);
+
+ return 1;
+}
+
+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 (screen_num == 0, NULL);
+
+ return _gdk_screen;
+}
+
+GdkScreen *
+gdk_display_get_default_screen (GdkDisplay *display)
+{
+ return _gdk_screen;
+}
+
+void
+gdk_display_keyboard_ungrab (GdkDisplay *display,
+ guint32 time)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_display_beep (GdkDisplay *display)
+{
+ g_return_if_fail (GDK_IS_DISPLAY (display));
+
+ NSBeep();
+}
+
+gboolean
+gdk_display_supports_selection_notification (GdkDisplay *display)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
+
+ /* FIXME: Implement */
+ return FALSE;
+}
+
+gboolean
+gdk_display_request_selection_notification (GdkDisplay *display,
+ GdkAtom selection)
+
+{
+ /* FIXME: Implement */
+ return FALSE;
+}
+
+gboolean
+gdk_display_supports_clipboard_persistence (GdkDisplay *display)
+{
+ /* FIXME: Implement */
+ return FALSE;
+}
+
+void
+gdk_display_store_clipboard (GdkDisplay *display,
+ GdkWindow *clipboard_window,
+ guint32 time_,
+ GdkAtom *targets,
+ gint n_targets)
+{
+ /* FIXME: Implement */
+}
+
diff --git a/gdk/quartz/gdkdnd-quartz.c b/gdk/quartz/gdkdnd-quartz.c
new file mode 100644
index 000000000..9ff4c1c8b
--- /dev/null
+++ b/gdk/quartz/gdkdnd-quartz.c
@@ -0,0 +1,178 @@
+/* gdkdnd-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gdkdnd.h"
+
+static void
+gdk_drag_context_init (GdkDragContext *dragcontext)
+{
+ /* FIXME: Implement */
+}
+
+static void
+gdk_drag_context_class_init (GdkDragContextClass *klass)
+{
+ /* FIXME: Implement */
+}
+
+GType
+gdk_drag_context_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkDragContextClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_drag_context_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkDragContext),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gdk_drag_context_init,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "GdkDragContext",
+ &object_info,
+ 0);
+ }
+
+ return object_type;
+}
+
+GdkDragContext *
+gdk_drag_context_new (void)
+{
+ return (GdkDragContext *)g_object_new (gdk_drag_context_get_type (), NULL);
+}
+
+void
+gdk_drag_context_ref (GdkDragContext *context)
+{
+ g_object_ref (context);
+}
+
+void
+gdk_drag_context_unref (GdkDragContext *context)
+{
+ g_object_unref (context);
+}
+
+GdkDragContext *
+gdk_drag_begin (GdkWindow *window,
+ GList *targets)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+gboolean
+gdk_drag_motion (GdkDragContext *context,
+ GdkWindow *dest_window,
+ GdkDragProtocol protocol,
+ gint x_root,
+ gint y_root,
+ GdkDragAction suggested_action,
+ GdkDragAction possible_actions,
+ guint32 time)
+{
+ /* FIXME: Implement */
+ return FALSE;
+}
+
+guint32
+gdk_drag_get_protocol_for_display (GdkDisplay *display,
+ guint32 xid,
+ GdkDragProtocol *protocol)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+void
+gdk_drag_find_window_for_screen (GdkDragContext *context,
+ GdkWindow *drag_window,
+ GdkScreen *screen,
+ gint x_root,
+ gint y_root,
+ GdkWindow **dest_window,
+ GdkDragProtocol *protocol)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_drag_drop (GdkDragContext *context,
+ guint32 time)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_drag_abort (GdkDragContext *context,
+ guint32 time)
+{
+ g_return_if_fail (context != NULL);
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_drag_status (GdkDragContext *context,
+ GdkDragAction action,
+ guint32 time)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_drop_reply (GdkDragContext *context,
+ gboolean ok,
+ guint32 time)
+{
+ g_return_if_fail (context != NULL);
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_drop_finish (GdkDragContext *context,
+ gboolean success,
+ guint32 time)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_register_dnd (GdkWindow *window)
+{
+ /* FIXME: Implement */
+}
+
+GdkAtom
+gdk_drag_get_selection (GdkDragContext *context)
+{
+ /* FIXME: Implement */
+ return GDK_NONE;
+}
diff --git a/gdk/quartz/gdkdrawable-quartz.c b/gdk/quartz/gdkdrawable-quartz.c
new file mode 100644
index 000000000..d3adb8d2d
--- /dev/null
+++ b/gdk/quartz/gdkdrawable-quartz.c
@@ -0,0 +1,597 @@
+/* gdkdrawable-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <cairo/cairo-quartz.h>
+#include "gdkprivate-quartz.h"
+
+static gpointer parent_class;
+
+typedef struct {
+ GdkDrawable *drawable;
+ CGContextRef context;
+} SurfaceInfo;
+
+static cairo_user_data_key_t surface_info_key;
+
+static void
+surface_info_destroy (void *data)
+{
+ SurfaceInfo *info = data;
+
+ _gdk_quartz_drawable_release_context (info->drawable, info->context);
+
+ g_free (info);
+}
+
+static cairo_surface_t *
+gdk_quartz_ref_cairo_surface (GdkDrawable *drawable)
+{
+ GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
+ CGContextRef context;
+ int width, height;
+ cairo_surface_t *surface;
+ SurfaceInfo *info;
+
+ if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) &&
+ GDK_WINDOW_DESTROYED (impl->wrapper))
+ return NULL;
+
+ context = _gdk_quartz_drawable_get_context (drawable, TRUE, FALSE);
+ if (!context)
+ return NULL;
+
+ gdk_drawable_get_size (drawable, &width, &height);
+
+ surface = cairo_quartz_surface_create (context, TRUE, width, height);
+
+ info = g_new (SurfaceInfo, 1);
+ info->drawable = drawable;
+ info->context = context;
+
+ cairo_surface_set_user_data (surface, &surface_info_key,
+ info, surface_info_destroy);
+ return surface;
+}
+
+static void
+gdk_quartz_set_colormap (GdkDrawable *drawable,
+ GdkColormap *colormap)
+{
+ GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
+
+ if (impl->colormap == colormap)
+ return;
+
+ if (impl->colormap)
+ g_object_unref (impl->colormap);
+ impl->colormap = colormap;
+ if (impl->colormap)
+ g_object_ref (impl->colormap);
+}
+
+static GdkColormap*
+gdk_quartz_get_colormap (GdkDrawable *drawable)
+{
+ return GDK_DRAWABLE_IMPL_QUARTZ (drawable)->colormap;
+}
+
+static GdkScreen*
+gdk_quartz_get_screen (GdkDrawable *drawable)
+{
+ return _gdk_screen;
+}
+
+static GdkVisual*
+gdk_quartz_get_visual (GdkDrawable *drawable)
+{
+ return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper);
+}
+
+static int
+gdk_quartz_get_depth (GdkDrawable *drawable)
+{
+ /* This is a bit bogus but I'm not sure the other way is better */
+
+ return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper);
+}
+
+static void
+gdk_quartz_draw_rectangle (GdkDrawable *drawable,
+ GdkGC *gc,
+ gboolean filled,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ CGContextRef context = _gdk_quartz_drawable_get_context (drawable, FALSE, TRUE);
+ CGRect rect = CGRectMake (x, y, width, height);
+
+ if (!context)
+ return;
+
+ _gdk_quartz_update_context_from_gc (context, gc);
+
+ if (filled)
+ {
+ _gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
+ _gdk_gc_get_fg_pixel (gc));
+ CGContextFillRect (context, rect);
+ }
+ else
+ {
+ _gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
+ _gdk_gc_get_fg_pixel (gc));
+ CGContextStrokeRect (context, rect);
+ }
+
+ _gdk_quartz_drawable_release_context (drawable, context);
+}
+
+static void
+gdk_quartz_draw_arc (GdkDrawable *drawable,
+ GdkGC *gc,
+ gboolean filled,
+ gint x,
+ gint y,
+ gint width,
+ gint height,
+ gint angle1,
+ gint angle2)
+{
+ CGContextRef context = _gdk_quartz_drawable_get_context (drawable, FALSE, TRUE);
+ float start_angle, end_angle;
+
+ if (!context)
+ return;
+
+ _gdk_quartz_update_context_from_gc (context, gc);
+
+ CGContextSaveGState (context);
+
+ CGContextTranslateCTM (context,
+ x + width / 2,
+ y + height / 2);
+ CGContextScaleCTM (context, 1.0, (float)height / width);
+ start_angle = (2 - (angle1 / (180.0 * 64.0))) * G_PI;
+ end_angle = start_angle - (angle2 / (180.0 * 64.0)) * G_PI;
+
+ if (filled)
+ {
+ _gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
+ _gdk_gc_get_fg_pixel (gc));
+
+ CGContextMoveToPoint (context, 0, 0);
+ CGContextAddArc (context, 0, 0, width / 2,
+ start_angle, end_angle,
+ TRUE);
+ CGContextClosePath (context);
+ CGContextFillPath (context);
+ }
+ else
+ {
+ _gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
+ _gdk_gc_get_fg_pixel (gc));
+ CGContextAddArc (context, 0, 0, width / 2,
+ start_angle, end_angle,
+ TRUE);
+ CGContextStrokePath (context);
+ }
+
+ CGContextRestoreGState (context);
+
+ _gdk_quartz_drawable_release_context (drawable, context);
+}
+
+static void
+gdk_quartz_draw_polygon (GdkDrawable *drawable,
+ GdkGC *gc,
+ gboolean filled,
+ GdkPoint *points,
+ gint npoints)
+{
+ /* FIXME: Implement */
+}
+
+static void
+gdk_quartz_draw_text (GdkDrawable *drawable,
+ GdkFont *font,
+ GdkGC *gc,
+ gint x,
+ gint y,
+ const gchar *text,
+ gint text_length)
+{
+ /* FIXME: Implement */
+}
+
+static void
+gdk_quartz_draw_text_wc (GdkDrawable *drawable,
+ GdkFont *font,
+ GdkGC *gc,
+ gint x,
+ gint y,
+ const GdkWChar *text,
+ gint text_length)
+{
+ /* FIXME: Implement */
+}
+
+static void
+gdk_quartz_draw_drawable (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPixmap *src,
+ gint xsrc,
+ gint ysrc,
+ gint xdest,
+ gint ydest,
+ gint width,
+ gint height)
+{
+ int src_depth = gdk_drawable_get_depth (src);
+ int dest_depth = gdk_drawable_get_depth (drawable);
+ GdkDrawableImplQuartz *impl;
+ GdkDrawableImplQuartz *src_impl;
+
+ impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
+
+ if (GDK_IS_DRAWABLE_IMPL_QUARTZ (src))
+ src_impl = GDK_DRAWABLE_IMPL_QUARTZ (src);
+ else
+ src_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (src)->impl);
+
+ if (src_depth == 1)
+ {
+ /* FIXME: src depth 1 is not supported yet */
+ }
+ else if (dest_depth != 0 && src_depth == dest_depth)
+ {
+ CGContextRef context = _gdk_quartz_drawable_get_context (drawable, FALSE, FALSE);
+
+ if (!context)
+ return;
+
+ _gdk_quartz_update_context_from_gc (context, gc);
+
+ CGContextSetBlendMode (context, kCGBlendModeNormal);
+
+ CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height));
+ CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc);
+ CGContextDrawImage (context, CGRectMake(0, 0,
+ GDK_PIXMAP_IMPL_QUARTZ (src_impl)->width,
+ GDK_PIXMAP_IMPL_QUARTZ (src_impl)->height),
+ GDK_PIXMAP_IMPL_QUARTZ (src_impl)->image);
+
+ _gdk_quartz_drawable_release_context (drawable, context);
+ }
+ else
+ g_warning ("Attempt to draw a drawable with depth %d to a drawable with depth %d",
+ src_depth, dest_depth);
+}
+
+static void
+gdk_quartz_draw_points (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPoint *points,
+ gint npoints)
+{
+ int i;
+
+ /* Just draw 1x1 rectangles */
+ for (i = 0; i < npoints; i++)
+ {
+ gdk_draw_rectangle (drawable, gc, TRUE,
+ points[i].x, points[i].y,
+ 1, 1);
+ }
+}
+
+static void
+gdk_quartz_draw_segments (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkSegment *segs,
+ gint nsegs)
+{
+ CGContextRef context = _gdk_quartz_drawable_get_context (drawable, FALSE, TRUE);
+ int i;
+
+ if (!context)
+ return;
+
+ _gdk_quartz_update_context_from_gc (context, gc);
+ _gdk_quartz_set_context_stroke_color_from_pixel (context, gdk_drawable_get_colormap (drawable),
+ _gdk_gc_get_fg_pixel (gc));
+
+ for (i = 0; i < nsegs; i++)
+ {
+ CGContextMoveToPoint (context, segs[i].x1, segs[i].y1);
+ CGContextAddLineToPoint (context, segs[i].x2, segs[i].y2);
+ }
+
+ CGContextStrokePath (context);
+
+ _gdk_quartz_drawable_release_context (drawable, context);
+}
+
+static void
+gdk_quartz_draw_lines (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPoint *points,
+ gint npoints)
+{
+ /* FIXME: Implement */
+}
+
+static void
+gdk_quartz_draw_pixbuf (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkPixbuf *pixbuf,
+ gint src_x,
+ gint src_y,
+ gint dest_x,
+ gint dest_y,
+ gint width,
+ gint height,
+ GdkRgbDither dither,
+ gint x_dither,
+ gint y_dither)
+{
+ CGContextRef context = _gdk_quartz_drawable_get_context (drawable, FALSE, FALSE);
+ CGColorSpaceRef colorspace;
+ CGDataProviderRef data_provider;
+ CGImageRef image;
+ void *data;
+ int rowstride, pixbuf_width, pixbuf_height;
+ gboolean has_alpha;
+
+ if (!context)
+ return;
+
+ pixbuf_width = gdk_pixbuf_get_width (pixbuf);
+ pixbuf_height = gdk_pixbuf_get_height (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+
+ data = gdk_pixbuf_get_pixels (pixbuf);
+
+ colorspace = CGColorSpaceCreateDeviceRGB ();
+ data_provider = CGDataProviderCreateWithData (NULL, data, pixbuf_height * rowstride, NULL);
+
+ image = CGImageCreate (pixbuf_width, pixbuf_height, 8,
+ has_alpha ? 32 : 24, rowstride,
+ colorspace,
+ has_alpha ? kCGImageAlphaLast : 0,
+ data_provider, NULL, FALSE,
+ kCGRenderingIntentDefault);
+
+ CGDataProviderRelease (data_provider);
+ CGColorSpaceRelease (colorspace);
+
+ _gdk_quartz_update_context_from_gc (context, gc);
+
+ CGContextSetBlendMode (context, kCGBlendModeNormal);
+
+ CGContextClipToRect (context, CGRectMake (dest_x, dest_y, width, height));
+ CGContextTranslateCTM (context, dest_x - src_x, dest_y - src_y + pixbuf_height);
+ CGContextScaleCTM (context, 1, -1);
+
+ CGContextDrawImage (context, CGRectMake(0, 0, pixbuf_width, pixbuf_height), image);
+ CGImageRelease (image);
+
+ _gdk_quartz_drawable_release_context (drawable, context);
+}
+
+static void
+gdk_quartz_draw_image (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkImage *image,
+ gint xsrc,
+ gint ysrc,
+ gint xdest,
+ gint ydest,
+ gint width,
+ gint height)
+{
+ CGContextRef context = _gdk_quartz_drawable_get_context (drawable, FALSE, FALSE);
+ CGColorSpaceRef colorspace;
+ CGDataProviderRef data_provider;
+ CGImageRef cgimage;
+
+ if (!context)
+ return;
+
+ colorspace = CGColorSpaceCreateDeviceRGB ();
+ data_provider = CGDataProviderCreateWithData (NULL, image->mem, image->height * image->bpl, NULL);
+
+ /* FIXME: Make sure that this function draws 32-bit images correctly,
+ * also check endianness wrt kCGImageAlphaNoneSkipFirst */
+ cgimage = CGImageCreate (image->width, image->height, 8,
+ 32, image->bpl,
+ colorspace,
+ kCGImageAlphaNoneSkipFirst,
+ data_provider, NULL, FALSE, kCGRenderingIntentDefault);
+
+ CGDataProviderRelease (data_provider);
+ CGColorSpaceRelease (colorspace);
+
+ _gdk_quartz_update_context_from_gc (context, gc);
+
+ CGContextSetBlendMode (context, kCGBlendModeNormal);
+
+ CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height));
+ CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc + image->height);
+ CGContextScaleCTM (context, 1, -1);
+
+ CGContextDrawImage (context, CGRectMake (0, 0, image->width, image->height), cgimage);
+ CGImageRelease (cgimage);
+
+ _gdk_quartz_drawable_release_context (drawable, context);
+}
+
+static void
+gdk_drawable_impl_quartz_finalize (GObject *object)
+{
+ GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (object);
+
+ if (impl->colormap)
+ g_object_unref (impl->colormap);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gdk_drawable_impl_quartz_class_init (GdkDrawableImplQuartzClass *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_drawable_impl_quartz_finalize;
+
+ drawable_class->create_gc = _gdk_quartz_gc_new;
+ drawable_class->draw_rectangle = gdk_quartz_draw_rectangle;
+ drawable_class->draw_arc = gdk_quartz_draw_arc;
+ drawable_class->draw_polygon = gdk_quartz_draw_polygon;
+ drawable_class->draw_text = gdk_quartz_draw_text;
+ drawable_class->draw_text_wc = gdk_quartz_draw_text_wc;
+ drawable_class->draw_drawable = gdk_quartz_draw_drawable;
+ drawable_class->draw_points = gdk_quartz_draw_points;
+ drawable_class->draw_segments = gdk_quartz_draw_segments;
+ drawable_class->draw_lines = gdk_quartz_draw_lines;
+ drawable_class->draw_image = gdk_quartz_draw_image;
+ drawable_class->draw_pixbuf = gdk_quartz_draw_pixbuf;
+
+ drawable_class->ref_cairo_surface = gdk_quartz_ref_cairo_surface;
+
+ drawable_class->set_colormap = gdk_quartz_set_colormap;
+ drawable_class->get_colormap = gdk_quartz_get_colormap;
+
+ drawable_class->get_depth = gdk_quartz_get_depth;
+ drawable_class->get_screen = gdk_quartz_get_screen;
+ drawable_class->get_visual = gdk_quartz_get_visual;
+
+ drawable_class->_copy_to_image = _gdk_quartz_copy_to_image;
+}
+
+GType
+gdk_drawable_impl_quartz_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkDrawableImplQuartzClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_drawable_impl_quartz_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkDrawableImplQuartz),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
+ "GdkDrawableImplQuartz",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+CGContextRef
+_gdk_quartz_drawable_get_context (GdkDrawable *drawable, gboolean antialias, gboolean y_axis_is_off_by_one)
+{
+ if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
+ {
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
+ CGContextRef context;
+
+ impl->pool = [[NSAutoreleasePool alloc] init];
+
+ if (![impl->view lockFocusIfCanDraw])
+ {
+ [impl->pool release];
+ return NULL;
+ }
+
+ context = [[NSGraphicsContext currentContext] graphicsPort];
+
+ CGContextSaveGState (context);
+ CGContextSetAllowsAntialiasing (context, antialias);
+
+ /* Sometimes when drawing certain primitives there's a one pixel
+ * difference when drawing to a CGImage and when drawing to a window,
+ * so we translate the ctm by 1 pixel here.
+ */
+ if (y_axis_is_off_by_one)
+ CGContextTranslateCTM (context, 0, 1);
+
+ return context;
+ }
+ else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
+ {
+ GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (drawable);
+ CGContextRef context;
+
+ context = CGBitmapContextCreate (impl->data,
+ CGImageGetWidth (impl->image),
+ CGImageGetHeight (impl->image),
+ CGImageGetBitsPerComponent (impl->image),
+ CGImageGetBytesPerRow (impl->image),
+ CGImageGetColorSpace (impl->image),
+ CGImageGetBitmapInfo (impl->image));
+ CGContextSetAllowsAntialiasing (context, antialias);
+
+ return context;
+ }
+
+ g_assert_not_reached ();
+
+ return NULL;
+}
+
+void
+_gdk_quartz_drawable_release_context (GdkDrawable *drawable, CGContextRef context)
+{
+ if (!context)
+ return;
+
+ if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable))
+ {
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
+
+ CGContextRestoreGState (context);
+ CGContextSetAllowsAntialiasing (context, TRUE);
+
+ [[NSGraphicsContext currentContext] flushGraphics];
+ [impl->view unlockFocus];
+ [impl->pool release];
+ }
+ else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
+ {
+ CGContextRelease (context);
+ }
+}
diff --git a/gdk/quartz/gdkdrawable-quartz.h b/gdk/quartz/gdkdrawable-quartz.h
new file mode 100644
index 000000000..36b996840
--- /dev/null
+++ b/gdk/quartz/gdkdrawable-quartz.h
@@ -0,0 +1,63 @@
+/* gdkdrawable-quartz.h
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_DRAWABLE_QUARTZ_H__
+#define __GDK_DRAWABLE_QUARTZ_H__
+
+#include <gdk/gdkdrawable.h>
+#include <gdk/quartz/gdkquartz.h>
+
+G_BEGIN_DECLS
+
+/* Drawable implementation for Quartz
+ */
+
+typedef struct _GdkDrawableImplQuartz GdkDrawableImplQuartz;
+typedef struct _GdkDrawableImplQuartzClass GdkDrawableImplQuartzClass;
+
+#define GDK_TYPE_DRAWABLE_IMPL_QUARTZ (gdk_drawable_impl_quartz_get_type ())
+#define GDK_DRAWABLE_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DRAWABLE_IMPL_QUARTZ, GdkDrawableImplQuartz))
+#define GDK_DRAWABLE_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DRAWABLE_IMPL_QUARTZ, GdkDrawableImplQuartzClass))
+#define GDK_IS_DRAWABLE_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DRAWABLE_IMPL_QUARTZ))
+#define GDK_IS_DRAWABLE_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DRAWABLE_IMPL_QUARTZ))
+#define GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DRAWABLE_IMPL_QUARTZ, GdkDrawableImplQuartzClass))
+
+struct _GdkDrawableImplQuartz
+{
+ GdkDrawable parent_instance;
+
+ GdkDrawable *wrapper;
+
+ GdkColormap *colormap;
+};
+
+struct _GdkDrawableImplQuartzClass
+{
+ GdkDrawableClass parent_class;
+};
+
+GType gdk_drawable_impl_quartz_get_type (void);
+
+CGContextRef _gdk_quartz_drawable_get_context (GdkDrawable *drawable, gboolean antialias, gboolean translate_y_axis);
+void _gdk_quartz_drawable_release_context (GdkDrawable *drawable, CGContextRef context);
+
+G_END_DECLS
+
+#endif /* __GDK_DRAWABLE_QUARTZ_H__ */
diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c
new file mode 100644
index 000000000..ac9eaf131
--- /dev/null
+++ b/gdk/quartz/gdkevents-quartz.c
@@ -0,0 +1,1286 @@
+/* gdkevents-quartz.c
+ *
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Copyright (C) 1998-2002 Tor Lillqvist
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include "gdkscreen.h"
+#include "gdkprivate-quartz.h"
+
+static GPollFD event_poll_fd;
+static NSEvent *current_event;
+
+/* This is the window the mouse is currently over */
+static GdkWindow *current_mouse_window;
+
+/* This is the window corresponding to the key window */
+static GdkWindow *current_keyboard_window;
+
+/* This is the pointer grab window */
+static GdkWindow *pointer_grab_window;
+static gboolean pointer_grab_owner_events;
+static GdkEventMask pointer_grab_event_mask;
+static gboolean pointer_grab_implicit;
+
+static gboolean
+gdk_event_prepare (GSource *source,
+ gint *timeout)
+{
+ NSEvent *event;
+ gboolean retval;
+
+ GDK_QUARTZ_ALLOC_POOL;
+
+ *timeout = -1;
+
+ event = [NSApp nextEventMatchingMask: NSAnyEventMask
+ untilDate: [NSDate distantPast]
+ inMode: NSDefaultRunLoopMode
+ dequeue: NO];
+
+ retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
+ event != NULL);
+
+ GDK_QUARTZ_RELEASE_POOL;
+
+ return retval;
+}
+
+static gboolean
+gdk_event_check (GSource *source)
+{
+ if (_gdk_event_queue_find_first (_gdk_display) != NULL ||
+ current_event)
+ return TRUE;
+
+ /* FIXME: We should maybe try to fetch an event again here */
+
+ return FALSE;
+}
+
+static gboolean
+gdk_event_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ GdkEvent *event;
+
+ GDK_QUARTZ_ALLOC_POOL;
+
+ _gdk_events_queue (_gdk_display);
+
+ event = _gdk_event_unqueue (_gdk_display);
+
+ if (event)
+ {
+ if (_gdk_event_func)
+ (*_gdk_event_func) (event, _gdk_event_data);
+
+ gdk_event_free (event);
+ }
+
+ GDK_QUARTZ_RELEASE_POOL;
+
+ return TRUE;
+}
+
+static GSourceFuncs event_funcs = {
+ gdk_event_prepare,
+ gdk_event_check,
+ gdk_event_dispatch,
+ NULL
+};
+
+static GPollFunc old_poll_func;
+
+static gint
+poll_func (GPollFD *ufds, guint nfds, gint timeout_)
+{
+ NSEvent *event;
+ NSDate *limit_date;
+ int n_active = 0;
+
+ GDK_QUARTZ_ALLOC_POOL;
+
+ /* FIXME: Support more than one pollfd */
+ g_assert (nfds == 1);
+
+ if (timeout_ == -1)
+ limit_date = [NSDate distantFuture];
+ else if (timeout_ == 0)
+ limit_date = [NSDate distantPast];
+ else
+ limit_date = [NSDate dateWithTimeIntervalSinceNow:timeout_/1000.0];
+
+ event = [NSApp nextEventMatchingMask: NSAnyEventMask
+ untilDate: limit_date
+ inMode: NSDefaultRunLoopMode
+ dequeue: YES];
+
+ if (event)
+ {
+ ufds[0].revents = G_IO_IN;
+
+ g_assert (current_event == NULL);
+
+ current_event = [event retain];
+
+ n_active ++;
+ }
+
+ GDK_QUARTZ_RELEASE_POOL;
+
+ return n_active;
+}
+
+void
+_gdk_events_init (void)
+{
+ GSource *source;
+
+ event_poll_fd.events = G_IO_IN;
+ event_poll_fd.fd = -1;
+
+ source = g_source_new (&event_funcs, sizeof (GSource));
+ g_source_add_poll (source, &event_poll_fd);
+ g_source_set_priority (source, GDK_PRIORITY_EVENTS);
+ g_source_set_can_recurse (source, TRUE);
+ g_source_attach (source, NULL);
+
+ /* FIXME: I really hate it that we need a custom poll function here.
+ * I think we can do better using threads.
+ */
+ old_poll_func = g_main_context_get_poll_func (NULL);
+ g_main_context_set_poll_func (NULL, poll_func);
+
+ current_mouse_window = g_object_ref (_gdk_root);
+ current_keyboard_window = g_object_ref (_gdk_root);
+}
+
+gboolean
+gdk_events_pending (void)
+{
+ /* FIXME: Implement */
+ return FALSE;
+}
+
+GdkEvent*
+gdk_event_get_graphics_expose (GdkWindow *window)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+static void
+pointer_ungrab_internal (gboolean implicit)
+{
+ if (!pointer_grab_window)
+ return;
+
+ if (pointer_grab_implicit && !implicit)
+ return;
+
+ g_object_unref (pointer_grab_window);
+
+ pointer_grab_window = NULL;
+ /* FIXME: Send crossing events */
+}
+
+
+gboolean
+gdk_display_pointer_is_grabbed (GdkDisplay *display)
+{
+ return pointer_grab_window != NULL;
+}
+
+gboolean
+gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
+ GdkWindow **grab_window,
+ gboolean *owner_events)
+{
+ if (!pointer_grab_window)
+ return FALSE;
+
+ if (grab_window)
+ *grab_window = pointer_grab_window;
+
+ if (owner_events)
+ *owner_events = pointer_grab_owner_events;
+
+ return FALSE;
+}
+
+void
+gdk_display_pointer_ungrab (GdkDisplay *display,
+ guint32 time)
+{
+ pointer_ungrab_internal (FALSE);
+}
+
+static GdkGrabStatus
+pointer_grab_internal (GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ gboolean implicit)
+{
+ /* FIXME: Send crossing events */
+
+ pointer_grab_window = g_object_ref (window);
+ pointer_grab_owner_events = owner_events;
+ pointer_grab_event_mask = event_mask;
+ pointer_grab_implicit = implicit;
+
+ /* FIXME: Implement */
+ return GDK_GRAB_SUCCESS;
+}
+
+GdkGrabStatus
+gdk_pointer_grab (GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time)
+{
+ g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+ g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
+
+ if (pointer_grab_window)
+ {
+ if (!pointer_grab_implicit)
+ return GDK_GRAB_ALREADY_GRABBED;
+ else
+ pointer_ungrab_internal (TRUE);
+ }
+
+ return pointer_grab_internal (window, owner_events, event_mask,
+ confine_to, cursor, FALSE);
+}
+
+static void
+fixup_event (GdkEvent *event)
+{
+ 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);
+ event->any.send_event = FALSE;
+}
+
+static void
+append_event (GdkEvent *event)
+{
+ fixup_event (event);
+ _gdk_event_queue_append (_gdk_display, event);
+}
+
+static GdkFilterReturn
+apply_filters (GdkWindow *window,
+ NSEvent *nsevent,
+ GList *filters)
+{
+ GdkFilterReturn result = GDK_FILTER_CONTINUE;
+ GdkEvent *event;
+ GList *node;
+ GList *tmp_list;
+
+ event = gdk_event_new (GDK_NOTHING);
+ if (window != NULL)
+ event->any.window = g_object_ref (window);
+ ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
+
+ /* I think GdkFilterFunc semantics require the passed-in event
+ * to already be in the queue. The filter func can generate
+ * more events and append them after it if it likes.
+ */
+ node = _gdk_event_queue_append (_gdk_display, event);
+
+ tmp_list = filters;
+ while (tmp_list)
+ {
+ GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data;
+
+ tmp_list = tmp_list->next;
+ result = filter->function (nsevent, event, filter->data);
+ if (result != GDK_FILTER_CONTINUE)
+ break;
+ }
+
+ if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE)
+ {
+ _gdk_event_queue_remove_link (_gdk_display, node);
+ g_list_free_1 (node);
+ gdk_event_free (event);
+ }
+ else /* GDK_FILTER_TRANSLATE */
+ {
+ ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
+ fixup_event (event);
+ }
+ return result;
+}
+
+static GdkWindow *
+find_child_window_by_point_helper (GdkWindow *window, int x, int y, int x_offset, int y_offset, int *x_ret, int *y_ret)
+{
+ GList *children;
+
+ for (children = GDK_WINDOW_OBJECT (window)->children;
+ children; children = children->next)
+ {
+ GdkWindowObject *private = GDK_WINDOW_OBJECT (children->data);
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+ int temp_x, temp_y;
+
+ if (!GDK_WINDOW_IS_MAPPED (private))
+ continue;
+
+ temp_x = x_offset + private->x;
+ temp_y = y_offset + private->y;
+
+ /* FIXME: Are there off by one errors here? */
+ if (x >= temp_x && y >= temp_y &&
+ x < temp_x + impl->width && y < temp_y + impl->height)
+ {
+ *x_ret = x - private->x;
+ *y_ret = y - private->y;
+
+ /* Look for child windows */
+ return find_child_window_by_point_helper (GDK_WINDOW (children->data), x, y, temp_x, temp_y, x_ret, y_ret);
+ }
+ }
+
+ return window;
+}
+
+/* Given a toplevel window and coordinates, returns the window
+ * in which the point is.
+ */
+static GdkWindow *
+find_child_window_by_point (GdkWindow *toplevel, int x, int y, int *x_ret, int *y_ret)
+{
+ GdkWindowObject *private = (GdkWindowObject *)toplevel;
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+ /* If the point is in the title bar, ignore it */
+ if (y > impl->height)
+ return NULL;
+
+ /* FIXME: Check this for off-by-one errors */
+ /* First flip the y coordinate */
+ y = impl->height - y;
+
+ return find_child_window_by_point_helper (toplevel, x, y, 0, 0, x_ret, y_ret);
+}
+
+/* Returns the current keyboard window */
+static GdkWindow *
+find_current_keyboard_window (void)
+{
+ /* FIXME: Handle keyboard grabs */
+
+ return current_keyboard_window;
+}
+
+/* this function checks if the passed in window is interested in the
+ * event mask. If so, it's returned. If not, the event can be propagated
+ * to its parent.
+ */
+static GdkWindow *
+find_window_interested_in_event_mask (GdkWindow *window,
+ GdkEventMask event_mask,
+ gboolean propagate)
+{
+ while (window)
+ {
+ GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
+
+ if (private->event_mask & event_mask)
+ return window;
+
+ if (!propagate)
+ return NULL;
+ else
+ window = GDK_WINDOW (private->parent);
+ }
+
+ return NULL;
+}
+
+static guint32
+get_event_time (NSEvent *event)
+{
+ double time = [event timestamp];
+
+ return time * 1000.0;
+}
+
+static int
+convert_mouse_button_number (int button)
+{
+ switch (button)
+ {
+ case 0:
+ return 1;
+ case 1:
+ return 3;
+ case 2:
+ return 2;
+ default:
+ return button + 1;
+ }
+}
+
+/* Return an event mask from an NSEvent */
+static GdkEventMask
+get_event_mask_from_ns_event (NSEvent *nsevent)
+{
+ NSEventType event_type = [nsevent type];
+
+ switch (event_type)
+ {
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ return GDK_BUTTON_PRESS_MASK;
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ return GDK_BUTTON_RELEASE_MASK;
+ case NSMouseMoved:
+ return GDK_POINTER_MOTION_MASK|GDK_POINTER_MOTION_HINT_MASK;
+ case NSScrollWheel:
+ /* Since applications that want button press events can get
+ * scroll events on X11 (since scroll wheel events are really
+ * button press events there), we need to use GDK_BUTTON_PRESS_MASK too.
+ */
+ return GDK_SCROLL_MASK|GDK_BUTTON_PRESS_MASK;
+ case NSLeftMouseDragged:
+ return GDK_POINTER_MOTION_MASK|GDK_POINTER_MOTION_HINT_MASK|
+ GDK_BUTTON_MOTION_MASK|GDK_BUTTON1_MOTION_MASK;
+ case NSRightMouseDragged:
+ return GDK_POINTER_MOTION_MASK|GDK_POINTER_MOTION_HINT_MASK|
+ GDK_BUTTON_MOTION_MASK|GDK_BUTTON3_MOTION_MASK;
+ case NSOtherMouseDragged:
+ {
+ GdkEventMask mask = GDK_POINTER_MOTION_MASK|GDK_POINTER_MOTION_HINT_MASK|
+ GDK_BUTTON_MOTION_MASK;
+ if (convert_mouse_button_number ([nsevent buttonNumber]) == 2)
+ mask |= GDK_BUTTON2_MOTION_MASK;
+
+ return mask;
+ }
+ case NSKeyDown:
+ return GDK_KEY_PRESS_MASK;
+ case NSKeyUp:
+ return GDK_KEY_RELEASE_MASK;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return 0;
+}
+
+static GdkEvent *
+create_focus_event (GdkWindow *window,
+ gboolean in)
+{
+ GdkEvent *event;
+
+ event = gdk_event_new (GDK_FOCUS_CHANGE);
+ event->focus_change.window = window;
+ /* FIXME: send event */
+ event->focus_change.in = in;
+
+ return event;
+}
+
+void
+_gdk_quartz_update_focus_window (GdkWindow *new_window)
+{
+ /* FIXME: Don't do this when grabbed */
+
+ if (new_window != current_keyboard_window)
+ {
+ GdkEvent *event;
+
+ event = create_focus_event (current_keyboard_window, FALSE);
+ append_event (event);
+
+ event = create_focus_event (new_window, TRUE);
+ append_event (event);
+
+ g_object_unref (current_keyboard_window);
+
+ current_keyboard_window = g_object_ref (new_window);
+ }
+}
+
+static gboolean
+gdk_window_is_ancestor (GdkWindow *ancestor,
+ GdkWindow *window)
+{
+ if (ancestor == NULL || window == NULL)
+ return FALSE;
+
+ return (gdk_window_get_parent (window) == ancestor ||
+ gdk_window_is_ancestor (ancestor, gdk_window_get_parent (window)));
+}
+
+static GdkModifierType
+get_keyboard_modifiers_from_nsevent (NSEvent *nsevent)
+{
+ GdkModifierType modifiers = 0;
+ int nsflags;
+
+ nsflags = [nsevent modifierFlags];
+
+ if (nsflags & NSAlphaShiftKeyMask)
+ modifiers |= GDK_LOCK_MASK;
+ if (nsflags & NSShiftKeyMask)
+ modifiers |= GDK_SHIFT_MASK;
+ if (nsflags & NSControlKeyMask)
+ modifiers |= GDK_CONTROL_MASK;
+ if (nsflags & NSControlKeyMask)
+ modifiers |= GDK_MOD1_MASK;
+
+ /* FIXME: Support GDK_BUTTON_MASK */
+
+ return modifiers;
+}
+
+static void
+convert_window_coordinates_to_root (GdkWindow *window, gdouble x, gdouble y,
+ gdouble *x_root, gdouble *y_root)
+{
+ /* FIXME: Implement */
+ *x_root = 0;
+ *y_root = 0;
+}
+
+static GdkEvent *
+create_crossing_event (GdkWindow *window,
+ NSEvent *nsevent,
+ GdkEventType event_type,
+ GdkCrossingMode mode,
+ GdkNotifyType detail)
+{
+ GdkEvent *event;
+
+ event = gdk_event_new (event_type);
+
+ event->crossing.window = window;
+ event->crossing.subwindow = NULL; /* FIXME */
+ event->crossing.time = get_event_time (nsevent);
+ /* FIXME: x, y, x_root, y_root */
+ event->crossing.mode = mode;
+ event->crossing.detail = detail;
+ /* FIXME: focus */
+ /* FIXME: state, (button state too) */
+
+ return event;
+}
+
+static void
+synthesize_enter_event (GdkWindow *window,
+ NSEvent *nsevent,
+ GdkCrossingMode mode,
+ GdkNotifyType detail)
+{
+ GdkEvent *event;
+
+ if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_ENTER_NOTIFY_MASK))
+ return;
+
+ event = create_crossing_event (window, nsevent, GDK_ENTER_NOTIFY,
+ mode, detail);
+
+ append_event (event);
+}
+
+static void
+synthesize_enter_events (GdkWindow *from,
+ GdkWindow *to,
+ NSEvent *nsevent,
+ GdkCrossingMode mode,
+ GdkNotifyType detail)
+{
+ GdkWindow *prev = gdk_window_get_parent (to);
+
+ if (prev != from)
+ synthesize_enter_events (from, prev, nsevent, mode, detail);
+ synthesize_enter_event (to, nsevent, mode, detail);
+}
+
+static void
+synthesize_leave_event (GdkWindow *window,
+ NSEvent *nsevent,
+ GdkCrossingMode mode,
+ GdkNotifyType detail)
+{
+ GdkEvent *event;
+
+ if (!(GDK_WINDOW_OBJECT (window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
+ return;
+
+ event = create_crossing_event (window, nsevent, GDK_LEAVE_NOTIFY,
+ mode, detail);
+
+ append_event (event);
+}
+
+static void
+synthesize_leave_events (GdkWindow *from,
+ GdkWindow *to,
+ NSEvent *nsevent,
+ GdkCrossingMode mode,
+ GdkNotifyType detail)
+{
+ GdkWindow *next = gdk_window_get_parent (from);
+
+ synthesize_leave_event (from, nsevent, mode, detail);
+ if (next != to)
+ synthesize_leave_events (next, to, nsevent, mode, detail);
+}
+
+static void
+synthesize_crossing_events (GdkWindow *window,
+ GdkCrossingMode mode,
+ NSEvent *nsevent,
+ gint x,
+ gint y)
+{
+ GdkWindow *intermediate, *tem, *common_ancestor;
+
+ if (gdk_window_is_ancestor (current_mouse_window, window))
+ {
+ /* Pointer has moved to an inferior window. */
+ synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_INFERIOR);
+
+ /* If there are intermediate windows, generate ENTER_NOTIFY
+ * events for them
+ */
+ intermediate = gdk_window_get_parent (window);
+
+ if (intermediate != current_mouse_window)
+ {
+ synthesize_enter_events (current_mouse_window, intermediate, nsevent, mode, GDK_NOTIFY_VIRTUAL);
+ }
+
+ synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_ANCESTOR);
+ }
+ else if (gdk_window_is_ancestor (window, current_mouse_window))
+ {
+ /* Pointer has moved to an ancestor window. */
+ synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_ANCESTOR);
+
+ /* If there are intermediate windows, generate LEAVE_NOTIFY
+ * events for them
+ */
+ intermediate = gdk_window_get_parent (current_mouse_window);
+ if (intermediate != window)
+ {
+ synthesize_leave_events (intermediate, window, nsevent, mode, GDK_NOTIFY_VIRTUAL);
+ }
+
+ synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_INFERIOR);
+ }
+ else if (current_mouse_window)
+ {
+ /* Find least common ancestor of current_mouse_window and window */
+ tem = current_mouse_window;
+ do {
+ common_ancestor = gdk_window_get_parent (tem);
+ tem = common_ancestor;
+ } while (common_ancestor &&
+ !gdk_window_is_ancestor (common_ancestor, window));
+ if (common_ancestor)
+ {
+ synthesize_leave_event (current_mouse_window, nsevent, mode, GDK_NOTIFY_NONLINEAR);
+ intermediate = gdk_window_get_parent (current_mouse_window);
+ if (intermediate != common_ancestor)
+ {
+ synthesize_leave_events (intermediate, common_ancestor,
+ nsevent, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
+ }
+ intermediate = gdk_window_get_parent (window);
+ if (intermediate != common_ancestor)
+ {
+ synthesize_enter_events (common_ancestor, intermediate,
+ nsevent, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
+ }
+ synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_NONLINEAR);
+ }
+ }
+ else
+ {
+ /* Dunno where we are coming from */
+ synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_UNKNOWN);
+ }
+
+ _gdk_quartz_update_mouse_window (window);
+}
+
+/* Get current mouse window */
+GdkWindow *
+_gdk_quartz_get_mouse_window (void)
+{
+ /* FIXME: What about grabs? */
+ return current_mouse_window;
+}
+
+/* Update mouse window */
+void
+_gdk_quartz_update_mouse_window (GdkWindow *window)
+{
+ if (window)
+ g_object_ref (window);
+ if (current_mouse_window)
+ g_object_unref (current_mouse_window);
+
+ current_mouse_window = window;
+}
+
+/* Update current cursor */
+void
+_gdk_quartz_update_cursor (GdkWindow *window)
+{
+ GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
+ NSCursor *nscursor = nil;
+
+ while (private) {
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+ nscursor = impl->nscursor;
+ if (nscursor)
+ break;
+
+ private = private->parent;
+ }
+
+ if (!nscursor)
+ nscursor = [NSCursor arrowCursor];
+
+ if ([NSCursor currentCursor] != nscursor)
+ [nscursor set];
+}
+
+/* This function finds the correct window to send an event to,
+ * taking into account grabs (FIXME: not done yet), event propagation,
+ * and event masks.
+ */
+static GdkWindow *
+find_window_for_event (NSEvent *nsevent, gint *x, gint *y)
+{
+ NSWindow *nswindow = [nsevent window];
+ NSEventType event_type = [nsevent type];
+
+ if (!nswindow)
+ return NULL;
+
+ if (event_type == NSMouseMoved ||
+ event_type == NSLeftMouseDragged ||
+ event_type == NSRightMouseDragged ||
+ event_type == NSOtherMouseDragged)
+ {
+ GdkWindow *toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
+ NSPoint point = [nsevent locationInWindow];
+ GdkWindow *mouse_window;
+
+ mouse_window = find_child_window_by_point (toplevel, point.x, point.y, x, y);
+
+ if (!mouse_window)
+ mouse_window = _gdk_root;
+
+ if (pointer_grab_window)
+ {
+ if (mouse_window != current_mouse_window)
+ synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, *x, *y);
+ }
+ else
+ {
+ if (current_mouse_window != mouse_window)
+ {
+ synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, *x, *y);
+
+ _gdk_quartz_update_cursor (mouse_window);
+ }
+ }
+ }
+
+ switch (event_type)
+ {
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ case NSMouseMoved:
+ case NSScrollWheel:
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ {
+ GdkWindow *toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
+ NSPoint point = [nsevent locationInWindow];
+ GdkWindow *mouse_window;
+ GdkEventMask event_mask;
+ GdkWindow *real_window;
+
+
+ if (pointer_grab_window)
+ {
+ if (pointer_grab_event_mask & get_event_mask_from_ns_event (nsevent))
+ {
+ int tempx, tempy;
+ GdkWindowObject *w = GDK_WINDOW_OBJECT (pointer_grab_window);
+
+ tempx = point.x;
+ tempy = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl)->height -
+ point.y;
+
+ while (w != GDK_WINDOW_OBJECT (toplevel))
+ {
+ tempx -= w->x;
+ tempy -= w->y;
+
+ w = w->parent;
+ }
+
+ *x = tempx;
+ *y = tempy;
+
+ return pointer_grab_window;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+ if (!nswindow)
+ {
+ mouse_window = _gdk_root;
+ }
+ else
+ {
+ mouse_window = find_child_window_by_point (toplevel, point.x, point.y, x, y);
+ }
+
+ event_mask = get_event_mask_from_ns_event (nsevent);
+ real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE);
+
+ return real_window;
+ }
+ case NSMouseEntered:
+ {
+ NSPoint point;
+ GdkWindow *toplevel;
+ GdkWindow *mouse_window;
+
+ point = [nsevent locationInWindow];
+
+ toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
+
+ mouse_window = find_child_window_by_point (toplevel, point.x, point.y, x, y);
+
+ synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, *x, *y);
+
+ break;
+ }
+ case NSMouseExited:
+ synthesize_crossing_events (_gdk_root, GDK_CROSSING_NORMAL, nsevent, *x, *y);
+ break;
+
+ case NSKeyDown:
+ case NSKeyUp:
+ {
+ GdkWindow *keyboard_window;
+ GdkEventMask event_mask;
+ GdkWindow *real_window;
+
+ keyboard_window = find_current_keyboard_window ();
+ event_mask = get_event_mask_from_ns_event (nsevent);
+ real_window = find_window_interested_in_event_mask (keyboard_window, event_mask, TRUE);
+
+ return real_window;
+ }
+ break;
+
+ case NSAppKitDefined:
+ case NSSystemDefined:
+ /* We ignore these events */
+ break;
+ default:
+ NSLog(@"Unhandled event %@", nsevent);
+ }
+
+ return NULL;
+}
+
+static GdkEvent *
+create_button_event (GdkWindow *window, NSEvent *nsevent,
+ gint x, gint y)
+{
+ GdkEvent *event;
+ GdkEventType type;
+ guint button;
+
+ switch ([nsevent type])
+ {
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ type = GDK_BUTTON_PRESS;
+ button = convert_mouse_button_number ([nsevent buttonNumber]);
+ break;
+ case NSLeftMouseUp:
+ type = GDK_BUTTON_RELEASE;
+ button = 1;
+ break;
+ case NSRightMouseUp:
+ type = GDK_BUTTON_RELEASE;
+ button = 3;
+ break;
+ case NSOtherMouseUp:
+ type = GDK_BUTTON_RELEASE;
+ button = convert_mouse_button_number ([nsevent buttonNumber]);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ event = gdk_event_new (type);
+ event->button.window = window;
+ event->button.time = get_event_time (nsevent);
+ event->button.x = x;
+ event->button.y = y;
+ /* FIXME event->axes */
+ event->button.state = get_keyboard_modifiers_from_nsevent (nsevent);
+ event->button.button = button;
+ event->button.device = _gdk_display->core_pointer;
+ convert_window_coordinates_to_root (window, x, y,
+ &event->button.x_root,
+ &event->button.y_root);
+
+ return event;
+}
+
+static GdkEvent *
+create_motion_event (GdkWindow *window, NSEvent *nsevent, gint x, gint y)
+{
+ GdkEvent *event;
+ GdkEventType type;
+ GdkModifierType state = 0;
+ int button = 0;
+
+ switch ([nsevent type])
+ {
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ button = convert_mouse_button_number ([nsevent buttonNumber]);
+ /* Fall through */
+ case NSMouseMoved:
+ type = GDK_MOTION_NOTIFY;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ /* This maps buttons 1 to 5 to GDK_BUTTON[1-5]_MASK */
+ if (button >= 1 && button <= 5)
+ state = (1 << (button + 7));
+
+ state |= get_keyboard_modifiers_from_nsevent (nsevent);
+
+ event = gdk_event_new (type);
+ event->motion.window = window;
+ event->motion.time = get_event_time (nsevent);
+ event->motion.x = x;
+ event->motion.y = y;
+ /* FIXME event->axes */
+ event->motion.state = state;
+ event->motion.is_hint = FALSE;
+ event->motion.device = _gdk_display->core_pointer;
+ convert_window_coordinates_to_root (window, x, y,
+ &event->motion.x_root, &event->motion.y_root);
+
+ return event;
+}
+
+static GdkEvent *
+create_scroll_event (GdkWindow *window, NSEvent *nsevent, GdkScrollDirection direction)
+{
+ GdkEvent *event;
+
+ event = gdk_event_new (GDK_SCROLL);
+ event->scroll.window = window;
+ event->scroll.time = get_event_time (nsevent);
+ /* FIXME event->x, event->y */
+ /* FIXME event->state; */
+ /* FIXME event->is_hint; */
+ event->scroll.direction = direction;
+ event->scroll.device = _gdk_display->core_pointer;
+ /* FIXME: event->x_root, event->y_root */
+
+ return event;
+}
+
+static GdkEvent *
+create_key_event (GdkWindow *window, NSEvent *nsevent)
+{
+ GdkEventType event_type;
+ GdkEvent *event;
+
+ switch ([nsevent type])
+ {
+ case NSKeyDown:
+ event_type = GDK_KEY_PRESS;
+ break;
+ case NSKeyUp:
+ event_type = GDK_KEY_RELEASE;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ event = gdk_event_new (event_type);
+ event->key.window = window;
+ event->key.time = get_event_time (nsevent);
+ event->key.state = get_keyboard_modifiers_from_nsevent (nsevent);
+ event->key.hardware_keycode = [nsevent keyCode];
+ event->key.group = ([nsevent modifierFlags] & NSAlternateKeyMask) ? 1 : 0;
+
+ gdk_keymap_translate_keyboard_state (NULL,
+ event->key.hardware_keycode,
+ event->key.state,
+ event->key.group,
+ &event->key.keyval,
+ NULL, NULL, NULL);
+
+ return event;
+}
+
+static gboolean
+gdk_event_translate (NSEvent *nsevent)
+{
+ NSWindow *nswindow = [nsevent window];
+ GdkWindow *window;
+ GdkFilterReturn result;
+ GdkEvent *event;
+ int x, y;
+
+ if (_gdk_default_filters)
+ {
+ /* Apply global filters */
+
+ GdkFilterReturn result = apply_filters (NULL, nsevent, _gdk_default_filters);
+
+ /* If result is GDK_FILTER_CONTINUE, we continue as if nothing
+ * happened. If it is GDK_FILTER_REMOVE,
+ * we return TRUE and won't send the message to Quartz.
+ */
+ if (result == GDK_FILTER_REMOVE)
+ return TRUE;
+ }
+
+ window = find_window_for_event (nsevent, &x, &y);
+
+ if (!window)
+ return FALSE;
+
+ result = apply_filters (window, nsevent, ((GdkWindowObject *) window)->filters);
+
+ if (result == GDK_FILTER_REMOVE)
+ return TRUE;
+
+ switch ([nsevent type])
+ {
+ case NSLeftMouseDown:
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ /* Emulate implicit grab */
+ if (!pointer_grab_window)
+ {
+ pointer_grab_internal (window, FALSE, GDK_WINDOW_OBJECT (window)->event_mask,
+ NULL, NULL, TRUE);
+ }
+
+ event = create_button_event (window, nsevent, x, y);
+ append_event (event);
+
+ _gdk_event_button_generate (_gdk_display, event);
+ break;
+
+ case NSLeftMouseUp:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ event = create_button_event (window, nsevent, x, y);
+
+ append_event (event);
+
+ _gdk_event_button_generate (_gdk_display, event);
+
+ /* Ungrab implicit grab */
+ if (pointer_grab_window &&
+ pointer_grab_implicit)
+ pointer_ungrab_internal (TRUE);
+ break;
+
+ case NSLeftMouseDragged:
+ case NSRightMouseDragged:
+ case NSOtherMouseDragged:
+ case NSMouseMoved:
+ event = create_motion_event (window, nsevent, x, y);
+ append_event (event);
+ break;
+
+ case NSScrollWheel:
+ {
+ float dx = [nsevent deltaX];
+ float dy = [nsevent deltaY];
+ GdkScrollDirection direction;
+
+ /* The delta is how much the mouse wheel has moved. Since there's no such thing in GTK+
+ * we accomodate by sending a different number of scroll wheel events.
+ */
+
+ /* First do y events */
+ if (dy < 0.0)
+ {
+ dy = -dy;
+ direction = GDK_SCROLL_DOWN;
+ }
+ else
+ direction = GDK_SCROLL_UP;
+
+ while (dy > 0.0)
+ {
+ event = create_scroll_event (window, nsevent, direction);
+ append_event (event);
+ dy--;
+ }
+
+ /* Now do x events */
+ if (dx < 0.0)
+ {
+ dx = -dx;
+ direction = GDK_SCROLL_RIGHT;
+ }
+ else
+ direction = GDK_SCROLL_LEFT;
+
+ while (dx > 0.0)
+ {
+ event = create_scroll_event (window, nsevent, direction);
+ append_event (event);
+ dx--;
+ }
+
+ break;
+ }
+ case NSKeyDown:
+ case NSKeyUp:
+ event = create_key_event (window, nsevent);
+ append_event (event);
+ return TRUE;
+ break;
+
+ default:
+ NSLog(@"Untranslated: %@", nsevent);
+ }
+
+ return FALSE;
+}
+
+void
+_gdk_events_queue (GdkDisplay *display)
+{
+ if (current_event)
+ {
+
+ if (!gdk_event_translate (current_event))
+ {
+ [NSApp sendEvent:current_event];
+ }
+
+ [current_event release];
+ current_event = NULL;
+ }
+}
+
+void
+gdk_flush (void)
+{
+ gdk_display_flush (NULL);
+}
+
+void
+gdk_display_sync (GdkDisplay *display)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_display_flush (GdkDisplay *display)
+{
+ /* FIXME: Implement */
+}
+
+gboolean
+gdk_event_send_client_message_for_display (GdkDisplay *display,
+ GdkEvent *event,
+ GdkNativeWindow winid)
+{
+ return FALSE;
+}
+
+void
+gdk_screen_broadcast_client_message (GdkScreen *screen,
+ GdkEvent *event)
+{
+}
+
+gboolean
+gdk_screen_get_setting (GdkScreen *screen,
+ const gchar *name,
+ GValue *value)
+{
+ if (strcmp (name, "gtk-font-name") == 0)
+ {
+ /* FIXME: This should be fetched from the correct preference value */
+ g_value_set_string (value, "Lucida Grande 13");
+ return TRUE;
+ }
+
+ /* FIXME: Add more settings */
+
+ return FALSE;
+}
+
diff --git a/gdk/quartz/gdkfont-quartz.c b/gdk/quartz/gdkfont-quartz.c
new file mode 100644
index 000000000..e179bd4c7
--- /dev/null
+++ b/gdk/quartz/gdkfont-quartz.c
@@ -0,0 +1,114 @@
+/* gdkwindow-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+
+#include "gdkfont.h"
+
+GdkFont*
+gdk_font_load_for_display (GdkDisplay *display,
+ const gchar *font_name)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+GdkFont*
+gdk_font_from_description_for_display (GdkDisplay *display,
+ PangoFontDescription *desc)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+gint
+gdk_text_width (GdkFont *font,
+ const gchar *text,
+ gint text_length)
+{
+ /* FIXME: Implement */
+ return -1;
+}
+
+void
+gdk_text_extents (GdkFont *font,
+ const gchar *text,
+ gint text_length,
+ gint *lbearing,
+ gint *rbearing,
+ gint *width,
+ gint *ascent,
+ gint *descent)
+{
+ /* FIXME: Implement */
+}
+
+gint
+gdk_text_width_wc (GdkFont *font,
+ const GdkWChar *text,
+ gint text_length)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+
+void
+gdk_text_extents_wc (GdkFont *font,
+ const GdkWChar *text,
+ gint text_length,
+ gint *lbearing,
+ gint *rbearing,
+ gint *width,
+ gint *ascent,
+ gint *descent)
+{
+ /* FIXME: Implement */
+}
+
+void
+_gdk_font_destroy (GdkFont *font)
+{
+ /* FIXME: Implement */
+}
+
+gint
+_gdk_font_strlen (GdkFont *font,
+ const gchar *str)
+{
+ /* FIXME: Implement */
+ return -1;
+}
+
+gint
+gdk_font_id (const GdkFont *font)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+gboolean
+gdk_font_equal (const GdkFont *fonta,
+ const GdkFont *fontb)
+{
+ /* FIXME: Implement */
+ return FALSE;
+}
diff --git a/gdk/quartz/gdkgc-quartz.c b/gdk/quartz/gdkgc-quartz.c
new file mode 100644
index 000000000..c68e3bab2
--- /dev/null
+++ b/gdk/quartz/gdkgc-quartz.c
@@ -0,0 +1,216 @@
+/* gdkgc-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkgc.h"
+#include "gdkprivate-quartz.h"
+
+static gpointer parent_class = NULL;
+
+static void
+gdk_quartz_gc_get_values (GdkGC *gc,
+ GdkGCValues *values)
+{
+ /* FIXME: Implement */
+}
+
+static void
+gdk_quartz_gc_set_values (GdkGC *gc,
+ GdkGCValues *values,
+ GdkGCValuesMask mask)
+{
+ GdkGCQuartz *private = GDK_GC_QUARTZ (gc);
+
+ private->values_mask |= mask;
+
+ if (mask & GDK_GC_CLIP_MASK)
+ {
+ private->have_clip_region = FALSE;
+ private->have_clip_mask = values->clip_mask != NULL;
+ if (private->clip_mask)
+ CGImageRelease (private->clip_mask);
+
+ if (values->clip_mask)
+ private->clip_mask = CGImageCreateCopy (GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (values->clip_mask)->impl)->image);
+ else
+ private->clip_mask = NULL;
+ }
+}
+
+static void
+gdk_quartz_gc_set_dashes (GdkGC *gc,
+ gint dash_offset,
+ gint8 dash_list[],
+ gint n)
+{
+ /* FIXME: Implement */
+}
+
+static void
+gdk_gc_quartz_finalize (GObject *object)
+{
+ GdkGCQuartz *private = GDK_GC_QUARTZ (object);
+
+ if (private->clip_mask)
+ CGImageRelease (private->clip_mask);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gdk_gc_quartz_class_init (GdkGCQuartzClass *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_quartz_finalize;
+
+ gc_class->get_values = gdk_quartz_gc_get_values;
+ gc_class->set_values = gdk_quartz_gc_set_values;
+ gc_class->set_dashes = gdk_quartz_gc_set_dashes;
+}
+
+GType
+_gdk_gc_quartz_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkGCQuartzClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_gc_quartz_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkGCQuartz),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (GDK_TYPE_GC,
+ "GdkGCQuartz",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+GdkGC *
+_gdk_quartz_gc_new (GdkDrawable *drawable,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask)
+{
+ GdkGC *gc;
+
+ gc = g_object_new (GDK_TYPE_GC_QUARTZ, NULL);
+
+ _gdk_gc_init (gc, drawable, values, values_mask);
+
+ gdk_quartz_gc_set_values (gc, values, values_mask);
+
+ return gc;
+}
+
+void
+_gdk_windowing_gc_set_clip_region (GdkGC *gc,
+ GdkRegion *region)
+{
+ GdkGCQuartz *private = GDK_GC_QUARTZ (gc);
+
+ if ((private->have_clip_region && ! region) || private->have_clip_mask)
+ {
+ if (private->clip_mask)
+ {
+ CGImageRelease (private->clip_mask);
+ private->clip_mask = NULL;
+ }
+ private->have_clip_mask = FALSE;
+ }
+
+ private->have_clip_region = region != NULL;
+
+ gc->clip_x_origin = 0;
+ gc->clip_y_origin = 0;
+}
+
+void
+_gdk_windowing_gc_copy (GdkGC *dst_gc,
+ GdkGC *src_gc)
+{
+ /* FIXME: Implement */
+}
+
+void
+_gdk_quartz_update_context_from_gc (CGContextRef context, GdkGC *gc)
+{
+ GdkGCQuartz *private;
+
+ if (gc == NULL)
+ return;
+
+ private = GDK_GC_QUARTZ (gc);
+
+ if (private->have_clip_region)
+ {
+ CGRect rect;
+ CGRect *cg_rects;
+ GdkRectangle *rects;
+ gint n_rects, i;
+
+ gdk_region_get_rectangles (_gdk_gc_get_clip_region (gc),
+ &rects, &n_rects);
+
+ if (n_rects == 1)
+ cg_rects = &rect;
+ else
+ cg_rects = g_new (CGRect, n_rects);
+
+ for (i = 0; i < n_rects; i++)
+ {
+ cg_rects[i].origin.x = rects[i].x + gc->clip_x_origin;
+ cg_rects[i].origin.y = rects[i].y + gc->clip_y_origin;
+ cg_rects[i].size.width = rects[i].width;
+ cg_rects[i].size.height = rects[i].height;
+ }
+
+ CGContextClipToRects (context, cg_rects, n_rects);
+
+ g_free (rects);
+ if (cg_rects != &rect)
+ g_free (cg_rects);
+ }
+ else if (private->have_clip_mask && private->clip_mask)
+ {
+ /* FIXME: This is 10.4 only. For lower versions, we need to transform the
+ * mask into a region.
+ */
+ CGContextClipToMask (context,
+ CGRectMake(gc->clip_x_origin, gc->clip_y_origin,
+ CGImageGetWidth (private->clip_mask),
+ CGImageGetHeight (private->clip_mask)),
+ private->clip_mask);
+ }
+}
diff --git a/gdk/quartz/gdkgeometry-quartz.c b/gdk/quartz/gdkgeometry-quartz.c
new file mode 100644
index 000000000..b7ad4c95b
--- /dev/null
+++ b/gdk/quartz/gdkgeometry-quartz.c
@@ -0,0 +1,34 @@
+/* gdkgeometry-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkprivate-quartz.h"
+
+void
+gdk_window_scroll (GdkWindow *window,
+ gint dx,
+ gint dy)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
diff --git a/gdk/quartz/gdkglobals-quartz.c b/gdk/quartz/gdkglobals-quartz.c
new file mode 100644
index 000000000..d60485604
--- /dev/null
+++ b/gdk/quartz/gdkglobals-quartz.c
@@ -0,0 +1,27 @@
+/* gdkglobals-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "gdktypes.h"
+#include "gdkprivate.h"
+
+GdkDisplay *_gdk_display = NULL;
+GdkScreen *_gdk_screen = NULL;
+GdkWindow *_gdk_root = NULL;
diff --git a/gdk/quartz/gdkim-quartz.c b/gdk/quartz/gdkim-quartz.c
new file mode 100644
index 000000000..37bd5f777
--- /dev/null
+++ b/gdk/quartz/gdkim-quartz.c
@@ -0,0 +1,73 @@
+/* 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 <locale.h>
+
+#include "gdki18n.h"
+#include "gdkinternals.h"
+#include "gdkprivate-quartz.h"
+
+gchar*
+gdk_set_locale (void)
+{
+ if (!setlocale (LC_ALL,""))
+ g_warning ("locale not supported by C library");
+
+ return setlocale (LC_ALL, NULL);
+}
+
+gchar *
+gdk_wcstombs (const GdkWChar *src)
+{
+ gchar *mbstr;
+
+ gint length = 0;
+ gint i;
+
+ while (src[length] != 0)
+ length++;
+
+ mbstr = g_new (gchar, length + 1);
+
+ for (i = 0; i < length + 1; i++)
+ mbstr[i] = src[i];
+
+ return mbstr;
+}
+
+gint
+gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
+{
+ gint i;
+
+ for (i = 0; i < dest_max && src[i]; i++)
+ dest[i] = src[i];
+
+ return i;
+}
+
diff --git a/gdk/quartz/gdkimage-quartz.c b/gdk/quartz/gdkimage-quartz.c
new file mode 100644
index 000000000..ca4d654ca
--- /dev/null
+++ b/gdk/quartz/gdkimage-quartz.c
@@ -0,0 +1,176 @@
+/* gdkimage-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdk.h"
+#include "gdkimage.h"
+#include "gdkprivate-quartz.h"
+
+static GObjectClass *parent_class;
+
+GdkImage *
+_gdk_quartz_copy_to_image (GdkDrawable *drawable,
+ GdkImage *image,
+ gint src_x,
+ gint src_y,
+ gint dest_x,
+ gint dest_y,
+ gint width,
+ gint height)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+static void
+gdk_image_finalize (GObject *object)
+{
+ GdkImage *image = GDK_IMAGE (object);
+
+ g_free (image->mem);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gdk_image_class_init (GdkImageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = gdk_image_finalize;
+}
+
+GType
+gdk_image_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkImageClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_image_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkImage),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "GdkImage",
+ &object_info,
+ 0);
+ }
+
+ return object_type;
+}
+
+GdkImage *
+gdk_image_new_bitmap (GdkVisual *visual, gpointer data, gint width, gint height)
+{
+ /* We don't implement this function because it's broken, deprecated and
+ * tricky to implement. */
+ g_warning ("This function is unimplemented");
+
+ return NULL;
+}
+
+GdkImage*
+_gdk_image_new_for_depth (GdkScreen *screen,
+ GdkImageType type,
+ GdkVisual *visual,
+ gint width,
+ gint height,
+ gint depth)
+{
+ GdkImage *image;
+
+ if (visual)
+ depth = visual->depth;
+
+ g_assert (depth == 24 || depth == 32);
+
+ image = g_object_new (gdk_image_get_type (), NULL);
+ image->type = type;
+ image->visual = visual;
+ image->width = width;
+ image->height = height;
+ image->depth = depth;
+
+ image->byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? GDK_LSB_FIRST : GDK_MSB_FIRST;
+
+ /* We only support images with bpp 4 */
+ image->bpp = 4;
+ image->bpl = image->width * image->bpp;
+ image->bits_per_pixel = image->bpp * 8;
+
+ image->mem = g_malloc (image->bpl * image->height);
+ memset (image->mem, 0x00, image->bpl * image->height);
+
+ return image;
+}
+
+guint32
+gdk_image_get_pixel (GdkImage *image,
+ gint x,
+ gint y)
+{
+ guchar *ptr;
+
+ g_return_val_if_fail (image != NULL, 0);
+ g_return_val_if_fail (x >= 0 && x < image->width, 0);
+ g_return_val_if_fail (y >= 0 && y < image->height, 0);
+
+ ptr = image->mem + y * image->bpl + x * image->bpp;
+
+ return *(guint32 *)ptr;
+}
+
+void
+gdk_image_put_pixel (GdkImage *image,
+ gint x,
+ gint y,
+ guint32 pixel)
+{
+ guchar *ptr;
+
+ ptr = image->mem + y * image->bpl + x * image->bpp;
+
+ *(guint32 *)ptr = pixel;
+}
+
+gint
+_gdk_windowing_get_bits_for_depth (GdkDisplay *display,
+ gint depth)
+{
+ if (depth == 24 || depth == 32)
+ return 32;
+ else
+ g_assert_not_reached ();
+
+ return 0;
+}
diff --git a/gdk/quartz/gdkinput-old.c b/gdk/quartz/gdkinput-old.c
new file mode 100644
index 000000000..d3b79d71c
--- /dev/null
+++ b/gdk/quartz/gdkinput-old.c
@@ -0,0 +1,68 @@
+/* gdkinput.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkinput.h"
+
+GType
+gdk_device_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkDeviceClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkDevicePrivate),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "GdkDevice",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+void
+gdk_device_set_key (GdkDevice *device,
+ guint index,
+ guint keyval,
+ GdkModifierType modifiers)
+{
+ /* FIXME: Implement */
+}
+
+gboolean
+gdk_device_get_axis (GdkDevice *device, gdouble *axes, GdkAxisUse use, gdouble *value)
+{
+ /* FIXME: Implement */
+ return FALSE;
+}
+
diff --git a/gdk/quartz/gdkinput.c b/gdk/quartz/gdkinput.c
new file mode 100644
index 000000000..7615fbe94
--- /dev/null
+++ b/gdk/quartz/gdkinput.c
@@ -0,0 +1,387 @@
+/* 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 <stdlib.h>
+
+#include "gdkprivate-quartz.h"
+#include "gdkinput.h"
+#include "gdkprivate.h"
+#include "gdkinputprivate.h"
+
+static GdkDeviceAxis gdk_input_core_axes[] = {
+ { GDK_AXIS_X, 0, 0 },
+ { GDK_AXIS_Y, 0, 0 }
+};
+
+GdkDevice *_gdk_core_pointer = NULL;
+
+/* Global variables */
+
+gchar *_gdk_input_gxid_host;
+gint _gdk_input_gxid_port;
+gint _gdk_input_ignore_core;
+GList *_gdk_input_windows;
+GList *_gdk_input_devices;
+
+void
+_gdk_init_input_core (void)
+{
+ _gdk_core_pointer = g_object_new (GDK_TYPE_DEVICE, NULL);
+
+ _gdk_core_pointer->name = "Core Pointer";
+ _gdk_core_pointer->source = GDK_SOURCE_MOUSE;
+ _gdk_core_pointer->mode = GDK_MODE_SCREEN;
+ _gdk_core_pointer->has_cursor = TRUE;
+ _gdk_core_pointer->num_axes = 2;
+ _gdk_core_pointer->axes = gdk_input_core_axes;
+ _gdk_core_pointer->num_keys = 0;
+ _gdk_core_pointer->keys = NULL;
+
+ _gdk_display->core_pointer = _gdk_core_pointer;
+}
+
+static void
+gdk_device_finalize (GObject *object)
+{
+ g_error ("A GdkDevice object was finalized. This should not happen");
+}
+
+static void
+gdk_device_class_init (GObjectClass *class)
+{
+ class->finalize = gdk_device_finalize;
+}
+
+GType
+gdk_device_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkDeviceClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_device_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkDevicePrivate),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "GdkDevice",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+GList *
+gdk_devices_list (void)
+{
+ return _gdk_input_devices;
+}
+
+GList *
+gdk_display_list_devices (GdkDisplay *dpy)
+{
+ return _gdk_input_devices;
+}
+
+void
+gdk_device_set_source (GdkDevice *device,
+ GdkInputSource source)
+{
+ device->source = source;
+}
+
+
+void
+gdk_device_set_key (GdkDevice *device,
+ guint index,
+ guint keyval,
+ GdkModifierType modifiers)
+{
+ g_return_if_fail (device != NULL);
+ g_return_if_fail (index < device->num_keys);
+
+ device->keys[index].keyval = keyval;
+ device->keys[index].modifiers = modifiers;
+}
+
+void
+gdk_device_set_axis_use (GdkDevice *device,
+ guint index,
+ GdkAxisUse use)
+{
+ g_return_if_fail (device != NULL);
+ g_return_if_fail (index < device->num_axes);
+
+ device->axes[index].use = use;
+
+ switch (use)
+ {
+ case GDK_AXIS_X:
+ case GDK_AXIS_Y:
+ device->axes[index].min = 0.;
+ device->axes[index].max = 0.;
+ break;
+ case GDK_AXIS_XTILT:
+ case GDK_AXIS_YTILT:
+ device->axes[index].min = -1.;
+ device->axes[index].max = 1;
+ break;
+ default:
+ device->axes[index].min = 0.;
+ device->axes[index].max = 1;
+ break;
+ }
+}
+
+void
+gdk_device_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask)
+{
+ gint x_int, y_int;
+
+ g_assert (device == _gdk_core_pointer);
+
+ gdk_window_get_pointer (window, &x_int, &y_int, mask);
+
+ if (axes)
+ {
+ axes[0] = x_int;
+ axes[1] = y_int;
+ }
+}
+
+void
+gdk_device_free_history (GdkTimeCoord **events,
+ gint n_events)
+{
+ gint i;
+
+ for (i = 0; i < n_events; i++)
+ g_free (events[i]);
+
+ g_free (events);
+}
+
+gboolean
+gdk_device_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ gint *n_events)
+{
+ g_return_val_if_fail (window != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+ g_return_val_if_fail (events != NULL, FALSE);
+ g_return_val_if_fail (n_events != NULL, FALSE);
+
+ *n_events = 0;
+ *events = NULL;
+ return FALSE;
+}
+
+gboolean
+gdk_device_set_mode (GdkDevice *device,
+ GdkInputMode mode)
+{
+ return FALSE;
+}
+
+gint
+_gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+ return TRUE;
+}
+
+gint
+_gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+ return TRUE;
+}
+
+
+GdkInputWindow *
+_gdk_input_window_find(GdkWindow *window)
+{
+ GList *tmp_list;
+
+ for (tmp_list=_gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
+ if (((GdkInputWindow *)(tmp_list->data))->window == window)
+ return (GdkInputWindow *)(tmp_list->data);
+
+ return NULL; /* Not found */
+}
+
+/* FIXME: this routine currently needs to be called between creation
+ and the corresponding configure event (because it doesn't get the
+ root_relative_geometry). This should work with
+ gtk_window_set_extension_events, but will likely fail in other
+ cases */
+
+void
+gdk_input_set_extension_events (GdkWindow *window, gint mask,
+ GdkExtensionMode mode)
+{
+ GdkWindowObject *window_private;
+ GList *tmp_list;
+ GdkInputWindow *iw;
+
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ window_private = (GdkWindowObject*) window;
+
+ if (mode == GDK_EXTENSION_EVENTS_NONE)
+ mask = 0;
+
+ if (mask != 0)
+ {
+ iw = g_new(GdkInputWindow,1);
+
+ iw->window = window;
+ iw->mode = mode;
+
+ iw->obscuring = NULL;
+ iw->num_obscuring = 0;
+ iw->grabbed = FALSE;
+
+ _gdk_input_windows = g_list_append (_gdk_input_windows,iw);
+ window_private->extension_events = mask;
+
+ /* Add enter window events to the event mask */
+ /* FIXME, this is not needed for XINPUT_NONE */
+ gdk_window_set_events (window,
+ gdk_window_get_events (window) |
+ GDK_ENTER_NOTIFY_MASK);
+ }
+ else
+ {
+ iw = _gdk_input_window_find (window);
+ if (iw)
+ {
+ _gdk_input_windows = g_list_remove (_gdk_input_windows,iw);
+ g_free (iw);
+ }
+
+ window_private->extension_events = 0;
+ }
+
+ for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
+ {
+ GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+
+ if (gdkdev != (GdkDevicePrivate *)_gdk_core_pointer)
+ {
+ if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
+ && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
+ _gdk_input_enable_window (window,gdkdev);
+ else
+ _gdk_input_disable_window (window,gdkdev);
+ }
+ }
+}
+
+void
+_gdk_input_window_destroy (GdkWindow *window)
+{
+ GdkInputWindow *input_window;
+
+ input_window = _gdk_input_window_find (window);
+ g_return_if_fail (input_window != NULL);
+
+ _gdk_input_windows = g_list_remove (_gdk_input_windows,input_window);
+ g_free (input_window);
+}
+
+void
+_gdk_input_init (void)
+{
+ _gdk_init_input_core ();
+ _gdk_input_devices = g_list_append (NULL, _gdk_core_pointer);
+ _gdk_input_ignore_core = FALSE;
+}
+
+void
+_gdk_input_exit (void)
+{
+ GList *tmp_list;
+ GdkDevicePrivate *gdkdev;
+
+ for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
+ {
+ gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+ if (gdkdev != (GdkDevicePrivate *)_gdk_core_pointer)
+ {
+ gdk_device_set_mode ((GdkDevice *)gdkdev, GDK_MODE_DISABLED);
+
+ g_free (gdkdev->info.name);
+ g_free (gdkdev->info.axes);
+ g_free (gdkdev->info.keys);
+ g_free (gdkdev);
+ }
+ }
+
+ g_list_free (_gdk_input_devices);
+
+ for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+ {
+ g_free (tmp_list->data);
+ }
+ g_list_free (_gdk_input_windows);
+}
+
+gboolean
+gdk_device_get_axis (GdkDevice *device, gdouble *axes, GdkAxisUse use, gdouble *value)
+{
+ gint i;
+
+ g_return_val_if_fail (device != NULL, FALSE);
+
+ if (axes == NULL)
+ return FALSE;
+
+ for (i = 0; i < device->num_axes; i++)
+ if (device->axes[i].use == use)
+ {
+ if (value)
+ *value = axes[i];
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/gdk/quartz/gdkinputprivate.h b/gdk/quartz/gdkinputprivate.h
new file mode 100644
index 000000000..8dbfa0b68
--- /dev/null
+++ b/gdk/quartz/gdkinputprivate.h
@@ -0,0 +1,153 @@
+/* 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_INPUTPRIVATE_H__
+#define __GDK_INPUTPRIVATE_H__
+
+#include "config.h"
+#include "gdkinput.h"
+#include "gdkevents.h"
+#include "gdkquartz.h"
+
+typedef struct _GdkAxisInfo GdkAxisInfo;
+typedef struct _GdkInputVTable GdkInputVTable;
+typedef struct _GdkDevicePrivate GdkDevicePrivate;
+typedef struct _GdkInputWindow GdkInputWindow;
+
+struct _GdkInputVTable {
+ gint (*set_mode) (guint32 deviceid, GdkInputMode mode);
+ void (*set_axes) (guint32 deviceid, GdkAxisUse *axes);
+ void (*set_key) (guint32 deviceid,
+ guint index,
+ guint keyval,
+ GdkModifierType modifiers);
+
+ GdkTimeCoord* (*motion_events) (GdkWindow *window,
+ guint32 deviceid,
+ guint32 start,
+ guint32 stop,
+ gint *nevents_return);
+ void (*get_pointer) (GdkWindow *window,
+ guint32 deviceid,
+ gdouble *x,
+ gdouble *y,
+ gdouble *pressure,
+ gdouble *xtilt,
+ gdouble *ytilt,
+ GdkModifierType *mask);
+ gint (*grab_pointer) (GdkWindow * window,
+ gint owner_events,
+ GdkEventMask event_mask,
+ GdkWindow * confine_to,
+ guint32 time);
+ void (*ungrab_pointer) (guint32 time);
+
+ void (*configure_event) (GdkEventConfigure *event, GdkWindow *window);
+ void (*enter_event) (GdkEventCrossing *event, GdkWindow *window);
+ gint (*other_event) (GdkEvent *event, GdkWindow *window);
+ /* Handle an unidentified event. Returns TRUE if handled, FALSE
+ otherwise */
+ gint (*window_none_event) (GdkEvent *event);
+ gint (*enable_window) (GdkWindow *window, GdkDevicePrivate *gdkdev);
+ gint (*disable_window) (GdkWindow *window, GdkDevicePrivate *gdkdev);
+};
+
+/* information about a device axis */
+struct _GdkAxisInfo
+{
+ /* reported x resolution */
+ gint xresolution;
+
+ /* reported x minimum/maximum values */
+ gint xmin_value, xmax_value;
+
+ /* calibrated resolution (for aspect ration) - only relative values
+ between axes used */
+ gint resolution;
+
+ /* calibrated minimum/maximum values */
+ gint min_value, max_value;
+};
+
+#define GDK_INPUT_NUM_EVENTC 6
+
+struct _GdkDevicePrivate {
+ GdkDevice info;
+};
+
+struct _GdkDeviceClass
+{
+ GObjectClass parent_class;
+};
+
+struct _GdkInputWindow
+{
+ /* gdk window */
+ GdkWindow *window;
+
+ /* Extension mode (GDK_EXTENSION_EVENTS_ALL/CURSOR) */
+ GdkExtensionMode mode;
+
+ /* position relative to root window */
+ gint root_x;
+ gint root_y;
+
+ /* rectangles relative to window of windows obscuring this one */
+ GdkRectangle *obscuring;
+ gint num_obscuring;
+
+ /* Is there a pointer grab for this window ? */
+ gint grabbed;
+};
+
+/* Global data */
+
+extern const GdkDevice gdk_input_core_info;
+extern GdkDevice *_gdk_core_pointer;
+extern GList *_gdk_input_devices;
+extern GList *_gdk_input_windows;
+
+extern GdkInputVTable gdk_input_vtable;
+/* information about network port and host for gxid daemon */
+extern gchar *_gdk_input_gxid_host;
+extern gint _gdk_input_gxid_port;
+extern gint _gdk_input_ignore_core;
+
+/* Function declarations */
+
+GdkInputWindow * _gdk_input_window_find (GdkWindow *window);
+void _gdk_input_window_destroy (GdkWindow *window);
+void _gdk_input_init (void);
+void _gdk_input_exit (void);
+gint _gdk_input_enable_window (GdkWindow *window,
+ GdkDevicePrivate *gdkdev);
+gint _gdk_input_disable_window (GdkWindow *window,
+ GdkDevicePrivate *gdkdev);
+void _gdk_init_input_core (void);
+
+void _gdk_input_exit (void);
+
+#endif /* __GDK_INPUTPRIVATE_H__ */
diff --git a/gdk/quartz/gdkkeys-quartz.c b/gdk/quartz/gdkkeys-quartz.c
new file mode 100644
index 000000000..55ff3d407
--- /dev/null
+++ b/gdk/quartz/gdkkeys-quartz.c
@@ -0,0 +1,487 @@
+/* gdkkeys-quartz.c
+ *
+ * Copyright (C) 2000 Red Hat, Inc.
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* Some parts of this code come from quartzKeyboard.c,
+ * from the Apple X11 Server.
+ *
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
+ * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above
+ * copyright holders shall not be used in advertising or otherwise to
+ * promote the sale, use or other dealings in this Software without
+ * prior written authorization.
+ */
+
+#include <config.h>
+
+#include <Carbon/Carbon.h>
+#include "gdk.h"
+#include "gdkkeysyms.h"
+
+#define NUM_KEYCODES 128
+#define KEYVALS_PER_KEYCODE 4
+
+static GdkKeymap *default_keymap = NULL;
+
+static KeyboardLayoutRef current_layout = NULL;
+
+/* This is a table of all keyvals. Each keycode gets KEYVALS_PER_KEYCODE entries.
+ * TThere is 1 keyval per modifier (Nothing, Shift, Alt, Shift+Alt);
+ */
+static guint *keyval_array = NULL;
+
+static inline UniChar
+macroman2ucs (unsigned char c)
+{
+ /* Precalculated table mapping MacRoman-128 to Unicode. Generated
+ by creating single element CFStringRefs then extracting the
+ first character. */
+
+ static const unsigned short table[128] = {
+ 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1,
+ 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8,
+ 0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3,
+ 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc,
+ 0x2020, 0xb0, 0xa2, 0xa3, 0xa7, 0x2022, 0xb6, 0xdf,
+ 0xae, 0xa9, 0x2122, 0xb4, 0xa8, 0x2260, 0xc6, 0xd8,
+ 0x221e, 0xb1, 0x2264, 0x2265, 0xa5, 0xb5, 0x2202, 0x2211,
+ 0x220f, 0x3c0, 0x222b, 0xaa, 0xba, 0x3a9, 0xe6, 0xf8,
+ 0xbf, 0xa1, 0xac, 0x221a, 0x192, 0x2248, 0x2206, 0xab,
+ 0xbb, 0x2026, 0xa0, 0xc0, 0xc3, 0xd5, 0x152, 0x153,
+ 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0xf7, 0x25ca,
+ 0xff, 0x178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02,
+ 0x2021, 0xb7, 0x201a, 0x201e, 0x2030, 0xc2, 0xca, 0xc1,
+ 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4,
+ 0xf8ff, 0xd2, 0xda, 0xdb, 0xd9, 0x131, 0x2c6, 0x2dc,
+ 0xaf, 0x2d8, 0x2d9, 0x2da, 0xb8, 0x2dd, 0x2db, 0x2c7,
+ };
+
+ if (c < 128)
+ return c;
+ else
+ return table[c - 128];
+}
+
+const static struct {
+ guint keycode;
+ guint keyval;
+} known_keys[] = {
+ { 55, GDK_Meta_L },
+ { 56, GDK_Shift_L },
+ { 57, GDK_Caps_Lock },
+ { 58, GDK_Alt_L },
+ { 59, GDK_Control_L },
+ { 60, GDK_Shift_R },
+ { 61, GDK_Alt_R },
+ { 62, GDK_Control_R },
+ { 122, GDK_F1 },
+ { 120, GDK_F2 },
+ { 99, GDK_F3 },
+ { 118, GDK_F4 },
+ { 96, GDK_F5 },
+ { 97, GDK_F6 },
+ { 98, GDK_F7 },
+ { 100, GDK_F8 },
+ { 101, GDK_F9 },
+ { 109, GDK_F10 },
+ { 103, GDK_F11 },
+ { 111, GDK_F12 },
+ { 105, GDK_F13 },
+ { 107, GDK_F14 },
+ { 113, GDK_F15 },
+};
+
+const static struct {
+ guint keycode;
+ guint normal_keyval, keypad_keyval;
+} known_numeric_keys[] = {
+ { 65, GDK_period, GDK_KP_Decimal },
+ { 67, GDK_asterisk, GDK_KP_Multiply },
+ { 69, GDK_plus, GDK_KP_Add },
+ { 75, GDK_slash, GDK_KP_Divide },
+ { 76, 0x01000003, GDK_KP_Enter },
+ { 78, GDK_minus, GDK_KP_Subtract },
+ { 81, GDK_equal, GDK_KP_Equal },
+ { 82, GDK_0, GDK_KP_0 },
+ { 83, GDK_1, GDK_KP_1 },
+ { 84, GDK_2, GDK_KP_2 },
+ { 85, GDK_3, GDK_KP_3 },
+ { 86, GDK_4, GDK_KP_4 },
+ { 87, GDK_5, GDK_KP_5 },
+ { 88, GDK_6, GDK_KP_6 },
+ { 89, GDK_7, GDK_KP_7 },
+ { 91, GDK_8, GDK_KP_8 },
+ { 92, GDK_9, GDK_KP_9 },
+};
+
+/* These values aren't covered by gdk_unicode_to_keyval */
+const static struct {
+ gunichar ucs_value;
+ guint keyval;
+} special_ucs_table [] = {
+ { 0x0001, GDK_Home },
+ { 0x0008, GDK_BackSpace },
+ { 0x0009, GDK_Tab },
+ { 0x000d, GDK_Return },
+ { 0x001c, GDK_Left },
+ { 0x001d, GDK_Right },
+ { 0x001e, GDK_Up },
+ { 0x001f, GDK_Down },
+};
+
+static void
+maybe_update_keymap (void)
+{
+ KeyboardLayoutRef new_layout;
+
+ KLGetCurrentKeyboardLayout (&new_layout);
+
+ if (new_layout != current_layout)
+ {
+ guint *p;
+ int i;
+
+ KeyboardLayoutKind layout_kind;
+
+ g_free (keyval_array);
+ keyval_array = g_new0 (guint, NUM_KEYCODES * KEYVALS_PER_KEYCODE);
+
+ /* Get the layout kind */
+ KLGetKeyboardLayoutProperty (new_layout, kKLKind, &layout_kind);
+
+ /* FIXME: When we have UCHR support, I think that should be preffered
+ * if a keymap has both.
+ */
+ if (layout_kind == kKLKCHRuchrKind || layout_kind == kKLKCHRKind)
+ {
+ const void *chr_data;
+
+ /* Get chr data */
+ KLGetKeyboardLayoutProperty (new_layout, kKLKCHRData, (void **)&chr_data);
+
+ for (i = 0; i < NUM_KEYCODES; i++)
+ {
+ int j;
+ UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey|optionKey};
+
+ p = keyval_array + i * KEYVALS_PER_KEYCODE;
+
+ for (j = 0; j < KEYVALS_PER_KEYCODE; j++)
+ {
+ UInt32 c, state = 0;
+ UInt16 key_code;
+ UniChar uc;
+
+ key_code = modifiers[j]|i;
+ c = KeyTranslate (chr_data, key_code, &state);
+
+ if (state != 0)
+ {
+ UInt32 state2 = 0;
+ c = KeyTranslate (chr_data, key_code | 128, &state2);
+ }
+
+ if (c != 0 && c != 0x10)
+ {
+ guint keyval;
+ int k;
+ gboolean found = FALSE;
+
+ uc = macroman2ucs (c);
+
+ for (k = 0; k < G_N_ELEMENTS (special_ucs_table); k++)
+ {
+ if (special_ucs_table[k].ucs_value == uc)
+ {
+ p[j] = special_ucs_table[k].keyval;
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ p[j] = gdk_unicode_to_keyval (uc);
+ }
+ }
+
+ if (p[3] == p[2])
+ p[3] = 0;
+ if (p[2] == p[1])
+ p[2] = 0;
+ if (p[1] == p[0])
+ p[1] = 0;
+ if (p[0] == p[2] &&
+ p[1] == p[3])
+ p[2] = p[3] = 0;
+ }
+ }
+ else
+ {
+ g_error ("uchr type layouts aren't supported right now");
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (known_keys); i++)
+ {
+ p = keyval_array + known_keys[i].keycode * KEYVALS_PER_KEYCODE;
+
+ if (p[0] == 0 && p[1] == 0 &&
+ p[2] == 0 && p[3] == 0)
+ p[0] = known_keys[i].keyval;
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (known_numeric_keys); i++)
+ {
+ p = keyval_array + known_numeric_keys[i].keycode * KEYVALS_PER_KEYCODE;
+
+ if (p[0] == known_numeric_keys[i].normal_keyval);
+ p[0] = known_numeric_keys[i].keypad_keyval;
+ }
+
+ if (current_layout)
+ g_signal_emit_by_name (default_keymap, "keys_changed");
+
+ current_layout = new_layout;
+ }
+}
+
+GdkKeymap *
+gdk_keymap_get_for_display (GdkDisplay *display)
+{
+ g_return_val_if_fail (display == gdk_display_get_default (), NULL);
+
+ if (default_keymap == NULL)
+ default_keymap = g_object_new (gdk_keymap_get_type (), NULL);
+
+ return default_keymap;
+}
+
+PangoDirection
+gdk_keymap_get_direction (GdkKeymap *keymap)
+{
+ return PANGO_DIRECTION_NEUTRAL;
+}
+
+gboolean
+gdk_keymap_get_entries_for_keyval (GdkKeymap *keymap,
+ guint keyval,
+ GdkKeymapKey **keys,
+ gint *n_keys)
+{
+ GArray *keys_array;
+ int i;
+
+ g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
+ g_return_val_if_fail (keys != NULL, FALSE);
+ g_return_val_if_fail (n_keys != NULL, FALSE);
+ g_return_val_if_fail (keyval != 0, FALSE);
+
+ maybe_update_keymap ();
+
+ *n_keys = 0;
+ keys_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
+
+ for (i = 0; i < NUM_KEYCODES * KEYVALS_PER_KEYCODE; i++)
+ {
+ GdkKeymapKey key;
+
+ if (keyval_array[i] != keyval)
+ continue;
+
+ (*n_keys)++;
+
+ key.keycode = i / KEYVALS_PER_KEYCODE;
+ key.group = 0;
+ key.level = i % KEYVALS_PER_KEYCODE;
+
+ g_array_append_val (keys_array, key);
+ }
+
+ *keys = (GdkKeymapKey *)g_array_free (keys_array, FALSE);
+
+ return *n_keys > 0;;
+}
+
+gboolean
+gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap,
+ guint hardware_keycode,
+ GdkKeymapKey **keys,
+ guint **keyvals,
+ gint *n_entries)
+{
+ GArray *keys_array, *keyvals_array;
+ int i;
+ guint *p;
+
+ g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
+ g_return_val_if_fail (n_entries != NULL, FALSE);
+
+ maybe_update_keymap ();
+
+ *n_entries = 0;
+
+ if (hardware_keycode > NUM_KEYCODES)
+ return FALSE;
+
+ if (keys)
+ keys_array = g_array_new (FALSE, FALSE, sizeof (GdkKeymapKey));
+ else
+ keys_array = NULL;
+
+ if (keyvals)
+ keyvals_array = g_array_new (FALSE, FALSE, sizeof (guint));
+ else
+ keyvals_array = NULL;
+
+ p = keyval_array + hardware_keycode * KEYVALS_PER_KEYCODE;
+
+ for (i = 0; i < KEYVALS_PER_KEYCODE; i++)
+ {
+ if (!p[i])
+ continue;
+
+ (*n_entries)++;
+
+ if (keyvals_array)
+ g_array_append_val (keyvals_array, p[i]);
+
+ if (keys_array)
+ {
+ GdkKeymapKey key;
+
+ key.keycode = hardware_keycode;
+ key.group = i / 2;
+ key.level = i % 2;
+
+ g_array_append_val (keys_array, key);
+ }
+ }
+
+ if (keys)
+ *keys = (GdkKeymapKey *)g_array_free (keys_array, FALSE);
+
+ if (keyvals)
+ *keyvals = (guint *)g_array_free (keyvals_array, FALSE);
+
+ return *n_entries > 0;
+}
+
+#define GET_KEYVAL(keycode, group, level) (keyval_array[(keycode * KEYVALS_PER_KEYCODE + group * 2 + level)])
+
+static guint
+translate_keysym (guint hardware_keycode,
+ gint group,
+ GdkModifierType state,
+ guint *effective_group,
+ guint *effective_level)
+{
+ gint level;
+ guint tmp_keyval;
+
+ level = (state & GDK_SHIFT_MASK) ? 1 : 0;
+
+ if (!(GET_KEYVAL (hardware_keycode, group, 0) || GET_KEYVAL (hardware_keycode, group, 1)) &&
+ (GET_KEYVAL (hardware_keycode, 0, 0) || GET_KEYVAL (hardware_keycode, 0, 1)))
+ group = 0;
+
+ if (!GET_KEYVAL (hardware_keycode, group, level) &&
+ GET_KEYVAL (hardware_keycode, group, 0))
+ level = 0;
+
+ tmp_keyval = GET_KEYVAL (hardware_keycode, group, level);
+
+ if (state & GDK_LOCK_MASK)
+ {
+ guint upper = gdk_keyval_to_upper (tmp_keyval);
+ if (upper != tmp_keyval)
+ tmp_keyval = upper;
+ }
+
+ return tmp_keyval;
+}
+
+gboolean
+gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
+ guint hardware_keycode,
+ GdkModifierType state,
+ gint group,
+ guint *keyval,
+ gint *effective_group,
+ gint *level,
+ GdkModifierType *consumed_modifiers)
+{
+ guint tmp_keyval;
+ GdkModifierType bit;
+ guint tmp_modifiers = 0;
+
+ g_return_val_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap), FALSE);
+ g_return_val_if_fail (group >= 0 && group <= 1, FALSE);
+
+ maybe_update_keymap ();
+
+ if (keyval)
+ *keyval = 0;
+ if (effective_group)
+ *effective_group = 0;
+ if (level)
+ *level = 0;
+ if (consumed_modifiers)
+ *consumed_modifiers = 0;
+
+ if (hardware_keycode < 0 || hardware_keycode >= NUM_KEYCODES)
+ return FALSE;
+
+ /* Check if shift or capslock modify the keyval */
+ for (bit = GDK_SHIFT_MASK; bit < GDK_CONTROL_MASK; bit <<= 1)
+ {
+ if (translate_keysym (hardware_keycode, group, state & ~bit, NULL, NULL) !=
+ translate_keysym (hardware_keycode, group, state | bit, NULL, NULL))
+ tmp_modifiers |= bit;
+ }
+
+ tmp_keyval = translate_keysym (hardware_keycode, group, state, level, effective_group);
+
+ if (consumed_modifiers)
+ *consumed_modifiers = tmp_modifiers;
+
+ if (keyval)
+ *keyval = tmp_keyval;
+
+ return TRUE;
+}
diff --git a/gdk/quartz/gdkmain-quartz.c b/gdk/quartz/gdkmain-quartz.c
new file mode 100644
index 000000000..1c066ab89
--- /dev/null
+++ b/gdk/quartz/gdkmain-quartz.c
@@ -0,0 +1,78 @@
+/* gdkmain-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdk.h"
+
+GOptionEntry _gdk_windowing_args[] = {
+ { NULL }
+};
+
+void
+_gdk_windowing_init (void)
+{
+}
+
+GdkGrabStatus
+gdk_keyboard_grab (GdkWindow *window,
+ gint owner_events,
+ guint32 time)
+{
+ /* FIXME: Implement */
+
+ return GDK_GRAB_SUCCESS;
+}
+
+
+gboolean
+gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
+ GdkWindow **grab_window,
+ gboolean *owner_events)
+{
+ /* FIXME: Implement */
+ return FALSE;
+}
+
+void
+gdk_error_trap_push (void)
+{
+}
+
+gint
+gdk_error_trap_pop (void)
+{
+ return 0;
+}
+
+void
+gdk_notify_startup_complete (void)
+{
+ /* FIXME: Implement */
+}
+
+
+void
+_gdk_windowing_display_set_sm_client_id (GdkDisplay *display,
+ const gchar *sm_client_id)
+{
+}
+
+
diff --git a/gdk/quartz/gdkpixmap-quartz.c b/gdk/quartz/gdkpixmap-quartz.c
new file mode 100644
index 000000000..b1297f770
--- /dev/null
+++ b/gdk/quartz/gdkpixmap-quartz.c
@@ -0,0 +1,232 @@
+/* gdkpixmap-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkpixmap.h"
+#include "gdkprivate-quartz.h"
+
+static gpointer parent_class;
+
+static void
+gdk_pixmap_impl_quartz_init (GdkPixmapImplQuartz *impl)
+{
+}
+
+static void
+gdk_pixmap_impl_quartz_get_size (GdkDrawable *drawable,
+ gint *width,
+ gint *height)
+{
+ if (width)
+ *width = GDK_PIXMAP_IMPL_QUARTZ (drawable)->width;
+ if (height)
+ *height = GDK_PIXMAP_IMPL_QUARTZ (drawable)->height;
+}
+
+static void
+gdk_pixmap_impl_quartz_finalize (GObject *object)
+{
+ GdkPixmapImplQuartz *impl = GDK_PIXMAP_IMPL_QUARTZ (object);
+
+ CGImageRelease (impl->image);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gdk_pixmap_impl_quartz_class_init (GdkPixmapImplQuartzClass *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_pixmap_impl_quartz_finalize;
+
+ drawable_class->get_size = gdk_pixmap_impl_quartz_get_size;
+}
+
+GType
+_gdk_pixmap_impl_quartz_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkPixmapImplQuartzClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_pixmap_impl_quartz_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkPixmapImplQuartz),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gdk_pixmap_impl_quartz_init
+ };
+
+ object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
+ "GdkPixmapImplQuartz",
+ &object_info,
+ 0);
+ }
+
+ return object_type;
+}
+
+GType
+_gdk_pixmap_impl_get_type (void)
+{
+ return _gdk_pixmap_impl_quartz_get_type ();
+}
+
+static void
+data_provider_release (void *info, const void *data, size_t size)
+{
+ g_free (info);
+}
+
+GdkPixmap*
+gdk_pixmap_new (GdkDrawable *drawable,
+ gint width,
+ gint height,
+ gint depth)
+{
+ GdkPixmap *pixmap;
+ GdkDrawableImplQuartz *draw_impl;
+ GdkPixmapImplQuartz *pix_impl;
+ GdkColormap *cmap;
+ gint window_depth;
+ CGColorSpaceRef colorspace;
+ CGDataProviderRef data_provider;
+ CGImageAlphaInfo alpha_info;
+ gint bytes_per_row, bits_per_pixel;
+
+ g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
+ g_return_val_if_fail ((drawable != NULL) || (depth != -1), NULL);
+ g_return_val_if_fail ((width != 0) && (height != 0), NULL);
+
+ if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
+ return NULL;
+
+ if (!drawable)
+ drawable = gdk_screen_get_root_window (gdk_screen_get_default ());
+
+ window_depth = gdk_drawable_get_depth (GDK_DRAWABLE (drawable));
+
+ if (depth == -1)
+ depth = window_depth;
+
+ switch (depth)
+ {
+ case 24:
+ alpha_info = kCGImageAlphaNoneSkipLast;
+ bytes_per_row = width * 4;
+ bits_per_pixel = 32;
+ colorspace = CGColorSpaceCreateDeviceRGB ();
+ break;
+ case 32:
+ alpha_info = kCGImageAlphaPremultipliedFirst;
+ bytes_per_row = width * 4;
+ bits_per_pixel = 32;
+ colorspace = CGColorSpaceCreateDeviceRGB ();
+ break;
+ case 1:
+ alpha_info = kCGImageAlphaNone;
+ bytes_per_row = width;
+ bits_per_pixel = 8;
+ colorspace = CGColorSpaceCreateDeviceGray ();
+ break;
+ default:
+ g_warning ("Unsupported bit depth %d\n", depth);
+ return NULL;
+ }
+
+ pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
+ draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
+ pix_impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
+ draw_impl->wrapper = GDK_DRAWABLE (pixmap);
+
+ g_assert (depth == 24 || depth == 32 || depth == 1);
+
+ pix_impl->data = g_malloc (height * bytes_per_row);
+ data_provider = CGDataProviderCreateWithData (pix_impl->data, pix_impl->data,
+ height * bytes_per_row, data_provider_release);
+ pix_impl->image = CGImageCreate (width, height, 8, bits_per_pixel,
+ bytes_per_row, colorspace,
+ alpha_info,
+ data_provider, NULL, FALSE,
+ kCGRenderingIntentDefault);
+ CGDataProviderRelease (data_provider);
+ CGColorSpaceRelease (colorspace);
+
+ pix_impl->width = width;
+ pix_impl->height = height;
+ GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
+
+ if (depth == window_depth) {
+ GdkColormap *colormap = gdk_drawable_get_colormap (drawable);
+
+ if (colormap)
+ gdk_drawable_set_colormap (pixmap, colormap);
+ }
+
+ return pixmap;
+}
+
+GdkPixmap *
+gdk_bitmap_create_from_data (GdkDrawable *window,
+ const gchar *data,
+ gint width,
+ gint height)
+{
+ GdkPixmap *pixmap;
+ GdkPixmapImplQuartz *impl;
+ int x, y;
+
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail ((width != 0) && (height != 0), NULL);
+ g_return_val_if_fail (window == NULL || GDK_IS_DRAWABLE (window), NULL);
+
+ pixmap = gdk_pixmap_new (window, width, height, 1);
+ impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (pixmap)->impl);
+
+ g_assert (CGImageGetBytesPerRow (impl->image) == width);
+
+ for (y = 0; y < height; y++)
+ {
+ guchar *ptr = impl->data + y * width;
+ gint idx;
+
+ for (x = 0; x < width; x++)
+ {
+ if ((data[(y * width + x) / 8] >> x % 8) & 1)
+ *ptr = 0xff;
+ else
+ *ptr = 0;
+
+ ptr++;
+ }
+ }
+
+ return pixmap;
+}
diff --git a/gdk/quartz/gdkpixmap-quartz.h b/gdk/quartz/gdkpixmap-quartz.h
new file mode 100644
index 000000000..bb2122ad4
--- /dev/null
+++ b/gdk/quartz/gdkpixmap-quartz.h
@@ -0,0 +1,64 @@
+/* gdkdrawable-quartz.h
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_PIXMAP_QUARTZ_H__
+#define __GDK_PIXMAP_QUARTZ_H__
+
+#include <ApplicationServices/ApplicationServices.h>
+#include <gdk/quartz/gdkdrawable-quartz.h>
+#include <gdk/gdkpixmap.h>
+
+G_BEGIN_DECLS
+
+/* Pixmap implementation for Quartz
+ */
+
+typedef struct _GdkPixmapImplQuartz GdkPixmapImplQuartz;
+typedef struct _GdkPixmapImplQuartzClass GdkPixmapImplQuartzClass;
+
+#define GDK_TYPE_PIXMAP_IMPL_QUARTZ (_gdk_pixmap_impl_quartz_get_type ())
+#define GDK_PIXMAP_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXMAP_IMPL_QUARTZ, GdkPixmapImplQuartz))
+#define GDK_PIXMAP_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXMAP_IMPL_QUARTZ, GdkPixmapImplQuartzClass))
+#define GDK_IS_PIXMAP_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXMAP_IMPL_QUARTZ))
+#define GDK_IS_PIXMAP_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXMAP_IMPL_QUARTZ))
+#define GDK_PIXMAP_IMPL_QUARTZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXMAP_IMPL_QUARTZ, GdkPixmapImplQuartzClass))
+
+struct _GdkPixmapImplQuartz
+{
+ GdkDrawableImplQuartz parent_instance;
+
+ gint width;
+ gint height;
+
+ void *data;
+
+ CGImageRef image;
+};
+
+struct _GdkPixmapImplQuartzClass
+{
+ GdkDrawableImplQuartzClass parent_class;
+};
+
+GType _gdk_pixmap_impl_quartz_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GDK_PIXMAP_QUARTZ_H__ */
diff --git a/gdk/quartz/gdkprivate-quartz.h b/gdk/quartz/gdkprivate-quartz.h
new file mode 100644
index 000000000..181d3a5fa
--- /dev/null
+++ b/gdk/quartz/gdkprivate-quartz.h
@@ -0,0 +1,113 @@
+/* gdkwindow-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_PRIVATE_QUARTZ_H__
+#define __GDK_PRIVATE_QUARTZ_H__
+
+#include <config.h>
+
+#define GDK_QUARTZ_ALLOC_POOL NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
+#define GDK_QUARTZ_RELEASE_POOL [pool release]
+
+#include <gdk/gdkprivate.h>
+#include <gdk/quartz/gdkpixmap-quartz.h>
+#include <gdk/quartz/gdkwindow-quartz.h>
+
+#include <gdk/gdk.h>
+
+#include "gdkinternals.h"
+
+#define GDK_TYPE_GC_QUARTZ (_gdk_gc_quartz_get_type ())
+#define GDK_GC_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_GC_QUARTZ, GdkGCQuartz))
+#define GDK_GC_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GC_QUARTZ, GdkGCQuartzClass))
+#define GDK_IS_GC_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_GC_QUARTZ))
+#define GDK_IS_GC_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GC_QUARTZ))
+#define GDK_GC_QUARTZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GC_QUARTZ, GdkGCQuartzClass))
+
+typedef struct _GdkCursorPrivate GdkCursorPrivate;
+typedef struct _GdkGCQuartz GdkGCQuartz;
+typedef struct _GdkGCQuartzClass GdkGCQuartzClass;
+
+struct _GdkGCQuartz
+{
+ GdkGC parent_instance;
+
+ GdkGCValuesMask values_mask;
+
+ gboolean have_clip_region;
+ gboolean have_clip_mask;
+ CGImageRef clip_mask;
+};
+
+struct _GdkGCQuartzClass
+{
+ GdkGCClass parent_class;
+};
+
+struct _GdkVisualClass
+{
+ GObjectClass parent_class;
+};
+
+struct _GdkCursorPrivate
+{
+ GdkCursor cursor;
+ NSCursor *nscursor;
+};
+
+extern GdkDisplay *_gdk_display;
+extern GdkScreen *_gdk_screen;
+extern GdkWindow *_gdk_root;
+
+GType _gdk_gc_quartz_get_type (void);
+
+GdkGC *_gdk_quartz_gc_new (GdkDrawable *drawable,
+ GdkGCValues *values,
+ GdkGCValuesMask values_mask);
+
+/* Initialization */
+void _gdk_windowing_window_init (void);
+void _gdk_events_init (void);
+void _gdk_visual_init (void);
+
+void _gdk_quartz_set_context_fill_color_from_pixel (CGContextRef context, GdkColormap *colormap, guint32 pixel);
+void _gdk_quartz_set_context_stroke_color_from_pixel (CGContextRef context, GdkColormap *colormap, guint32 pixel);
+
+void _gdk_quartz_update_context_from_gc (CGContextRef context, GdkGC *gc);
+
+void _gdk_quartz_update_focus_window (GdkWindow *new_window);
+
+gint _gdk_quartz_get_inverted_screen_y (gint y);
+
+GdkWindow *_gdk_quartz_get_mouse_window (void);
+void _gdk_quartz_update_mouse_window (GdkWindow *window);
+
+void _gdk_quartz_update_cursor (GdkWindow *window);
+
+GdkImage *_gdk_quartz_copy_to_image (GdkDrawable *drawable,
+ GdkImage *image,
+ gint src_x,
+ gint src_y,
+ gint dest_x,
+ gint dest_y,
+ gint width,
+ gint height);
+
+#endif /* __GDK_PRIVATE_QUARTZ_H__ */
diff --git a/gdk/quartz/gdkproperty-quartz.c b/gdk/quartz/gdkproperty-quartz.c
new file mode 100644
index 000000000..e0da15214
--- /dev/null
+++ b/gdk/quartz/gdkproperty-quartz.c
@@ -0,0 +1,85 @@
+/* gdkproperty-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkproperty.h"
+
+GdkAtom
+gdk_atom_intern (const gchar *atom_name,
+ gboolean only_if_exists)
+{
+ g_return_val_if_fail (atom_name != NULL, GDK_NONE);
+
+ /* FIXME: Implement */
+ return GDK_NONE;
+}
+
+GdkAtom
+gdk_atom_intern_static_string (const gchar *atom_name)
+{
+ g_return_val_if_fail (atom_name != NULL, GDK_NONE);
+
+ /* FIXME: Implement */
+ return GDK_NONE;
+}
+
+
+gchar *
+gdk_atom_name (GdkAtom atom)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+void
+gdk_property_delete (GdkWindow *window,
+ GdkAtom property)
+{
+ /* FIXME: Implement */
+}
+
+gint
+gdk_property_get (GdkWindow *window,
+ GdkAtom property,
+ GdkAtom type,
+ gulong offset,
+ gulong length,
+ gint pdelete,
+ GdkAtom *actual_property_type,
+ gint *actual_format_type,
+ gint *actual_length,
+ guchar **data)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+void
+gdk_property_change (GdkWindow *window,
+ GdkAtom property,
+ GdkAtom type,
+ gint format,
+ GdkPropMode mode,
+ const guchar *data,
+ gint nelements)
+{
+ /* FIXME: Implement */
+}
diff --git a/gdk/quartz/gdkquartz.h b/gdk/quartz/gdkquartz.h
new file mode 100644
index 000000000..d9cd548cd
--- /dev/null
+++ b/gdk/quartz/gdkquartz.h
@@ -0,0 +1,7 @@
+#ifndef __GDK_QUARTZ_H__
+#define __GDK_QUARTZ_H__
+
+#include <Quartz/Quartz.h>
+#include "gdk/gdkprivate.h"
+
+#endif /* __GDK_QUARTZ_H__ */
diff --git a/gdk/quartz/gdkscreen-quartz.c b/gdk/quartz/gdkscreen-quartz.c
new file mode 100644
index 000000000..dbb82bce1
--- /dev/null
+++ b/gdk/quartz/gdkscreen-quartz.c
@@ -0,0 +1,196 @@
+/* gdkscreen-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "gdk.h"
+#include "gdkprivate-quartz.h"
+
+static GdkColormap *default_colormap = NULL;
+
+GdkDisplay *
+gdk_screen_get_display (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return _gdk_display;
+}
+
+
+GdkWindow *
+gdk_screen_get_root_window (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return _gdk_root;
+}
+
+gint
+gdk_screen_get_number (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ return 0;
+}
+
+gchar *
+_gdk_windowing_substitute_screen_number (const gchar *display_name,
+ int screen_number)
+{
+ if (screen_number != 0)
+ return NULL;
+
+ return g_strdup (display_name);
+}
+
+GdkColormap*
+gdk_screen_get_default_colormap (GdkScreen *screen)
+{
+ return default_colormap;
+}
+
+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 = default_colormap;
+
+ default_colormap = g_object_ref (colormap);
+
+ if (old_colormap)
+ g_object_unref (old_colormap);
+}
+
+gint
+gdk_screen_get_width (GdkScreen *screen)
+{
+ int i;
+ int width;
+ NSArray *array;
+ NSAutoreleasePool *pool;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ pool = [[NSAutoreleasePool alloc] init];
+ array = [NSScreen screens];
+
+ width = 0;
+ for (i = 0; i < [array count]; i++)
+ {
+ NSRect rect = [[array objectAtIndex:i] frame];
+ width += rect.size.width;
+ }
+
+ [pool release];
+
+ return width;
+}
+
+gint
+gdk_screen_get_height (GdkScreen *screen)
+{
+ int i;
+ int height;
+ NSArray *array;
+ NSAutoreleasePool *pool;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ pool = [[NSAutoreleasePool alloc] init];
+ array = [NSScreen screens];
+
+ height = 0;
+ for (i = 0; i < [array count]; i++)
+ {
+ NSRect rect = [[array objectAtIndex:i] frame];
+ height = MAX (height, rect.size.height);
+ }
+
+ [pool release];
+
+ return height;
+}
+
+gint
+gdk_screen_get_width_mm (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ /* FIXME: Implement */
+ return 0;
+}
+
+gint
+gdk_screen_get_height_mm (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+ /* FIXME: Implement */
+ return 0;
+}
+
+int
+gdk_screen_get_n_monitors (GdkScreen *screen)
+{
+ int n;
+ GDK_QUARTZ_ALLOC_POOL;
+ NSArray *array = [NSScreen screens];
+
+ n = [array count];
+
+ GDK_QUARTZ_RELEASE_POOL;
+
+ return n;
+}
+
+void
+gdk_screen_get_monitor_geometry (GdkScreen *screen,
+ gint monitor_num,
+ GdkRectangle *dest)
+{
+ NSArray *array;
+ NSRect rect;
+ NSAutoreleasePool *pool;
+
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+ g_return_if_fail (monitor_num < gdk_screen_get_n_monitors (screen));
+ g_return_if_fail (monitor_num >= 0);
+
+ pool = [[NSAutoreleasePool alloc] init];
+ array = [NSScreen screens];
+ rect = [[array objectAtIndex:monitor_num] frame];
+
+ dest->x = rect.origin.x;
+ dest->y = rect.origin.y;
+ dest->width = rect.size.width;
+ dest->height = rect.size.height;
+
+ [pool release];
+}
+
+gchar *
+gdk_screen_make_display_name (GdkScreen *screen)
+{
+ return g_strdup (gdk_display_get_name (_gdk_display));
+}
diff --git a/gdk/quartz/gdkselection-quartz.c b/gdk/quartz/gdkselection-quartz.c
new file mode 100644
index 000000000..375c36672
--- /dev/null
+++ b/gdk/quartz/gdkselection-quartz.c
@@ -0,0 +1,132 @@
+/* gdkselection-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkselection.h"
+
+gboolean
+gdk_selection_owner_set_for_display (GdkDisplay *display,
+ GdkWindow *owner,
+ GdkAtom selection,
+ guint32 time,
+ gint send_event)
+{
+ /* FIXME: Implement */
+ return TRUE;
+}
+
+GdkWindow*
+gdk_selection_owner_get_for_display (GdkDisplay *display,
+ GdkAtom selection)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+void
+gdk_selection_convert (GdkWindow *requestor,
+ GdkAtom selection,
+ GdkAtom target,
+ guint32 time)
+{
+ /* FIXME: Implement */
+}
+
+gint
+gdk_selection_property_get (GdkWindow *requestor,
+ guchar **data,
+ GdkAtom *ret_type,
+ gint *ret_format)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+void
+gdk_selection_send_notify_for_display (GdkDisplay *display,
+ guint32 requestor,
+ GdkAtom selection,
+ GdkAtom target,
+ GdkAtom property,
+ guint32 time)
+{
+ /* FIXME: Implement */
+}
+
+gint
+gdk_text_property_to_text_list_for_display (GdkDisplay *display,
+ GdkAtom encoding,
+ gint format,
+ const guchar *text,
+ gint length,
+ gchar ***list)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+gint
+gdk_string_to_compound_text_for_display (GdkDisplay *display,
+ const gchar *str,
+ GdkAtom *encoding,
+ gint *format,
+ guchar **ctext,
+ gint *length)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+void gdk_free_compound_text (guchar *ctext)
+{
+ /* FIXME: Implement */
+}
+
+gchar *
+gdk_utf8_to_string_target (const gchar *str)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+gboolean
+gdk_utf8_to_compound_text_for_display (GdkDisplay *display,
+ const gchar *str,
+ GdkAtom *encoding,
+ gint *format,
+ guchar **ctext,
+ gint *length)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+gint
+gdk_text_property_to_utf8_list_for_display (GdkDisplay *display,
+ GdkAtom encoding,
+ gint format,
+ const guchar *text,
+ gint length,
+ gchar ***list)
+{
+ /* FIXME: Implement */
+ return 0;
+}
diff --git a/gdk/quartz/gdkvisual-quartz.c b/gdk/quartz/gdkvisual-quartz.c
new file mode 100644
index 000000000..1dd068e2e
--- /dev/null
+++ b/gdk/quartz/gdkvisual-quartz.c
@@ -0,0 +1,219 @@
+/* gdkvisual-quartz.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdkvisual.h"
+#include "gdkprivate-quartz.h"
+
+/* FIXME: We might want to include the rgba visual in the query functions */
+
+static GdkVisual *system_visual;
+static GdkVisual *rgba_visual;
+
+static void
+gdk_visual_finalize (GObject *object)
+{
+ g_error ("A GdkVisual object was finalized. This should not happen");
+}
+
+static void
+gdk_visual_class_init (GObjectClass *class)
+{
+ class->finalize = gdk_visual_finalize;
+}
+
+GType
+gdk_visual_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkVisualClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_visual_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkVisual),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "GdkVisual",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+static void
+gdk_visual_decompose_mask (gulong mask,
+ gint *shift,
+ gint *prec)
+{
+ *shift = 0;
+ *prec = 0;
+
+ while (!(mask & 0x1))
+ {
+ (*shift)++;
+ mask >>= 1;
+ }
+
+ while (mask & 0x1)
+ {
+ (*prec)++;
+ mask >>= 1;
+ }
+}
+
+static GdkVisual *
+create_standard_visual (gint depth)
+{
+ GdkVisual *visual = g_object_new (GDK_TYPE_VISUAL, NULL);
+
+ visual->depth = depth;
+ visual->byte_order = GDK_MSB_FIRST; /* FIXME: Should this be different on intel macs? */
+ visual->colormap_size = 0;
+
+ visual->type = GDK_VISUAL_TRUE_COLOR;
+
+ visual->red_mask = 0xff0000;
+ visual->green_mask = 0xff00;
+ visual->blue_mask = 0xff;
+
+ gdk_visual_decompose_mask (visual->red_mask,
+ &visual->red_shift,
+ &visual->red_prec);
+ gdk_visual_decompose_mask (visual->green_mask,
+ &visual->green_shift,
+ &visual->green_prec);
+ gdk_visual_decompose_mask (visual->blue_mask,
+ &visual->blue_shift,
+ &visual->blue_prec);
+
+ return visual;
+}
+
+void
+_gdk_visual_init (void)
+{
+ system_visual = create_standard_visual (24);
+ rgba_visual = create_standard_visual (32);
+}
+
+gint
+gdk_visual_get_best_depth (void)
+{
+ return system_visual->depth;
+}
+
+GdkVisualType
+gdk_visual_get_best_type (void)
+{
+ return system_visual->type;
+}
+
+GdkVisual *
+gdk_screen_get_rgba_visual (GdkScreen *screen)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return rgba_visual;
+}
+
+GdkVisual*
+gdk_screen_get_system_visual (GdkScreen *screen)
+{
+ return system_visual;
+}
+
+GdkVisual*
+gdk_visual_get_best (void)
+{
+ return system_visual;
+}
+
+GdkVisual*
+gdk_visual_get_best_with_depth (gint depth)
+{
+ if (system_visual->depth != depth)
+ return NULL;
+
+ return system_visual;
+}
+
+GdkVisual*
+gdk_visual_get_best_with_type (GdkVisualType visual_type)
+{
+ if (system_visual->type != visual_type)
+ return NULL;
+
+ return system_visual;
+}
+
+GdkVisual*
+gdk_visual_get_best_with_both (gint depth,
+ GdkVisualType visual_type)
+{
+ if (system_visual->depth != depth)
+ return NULL;
+
+ if (system_visual->type != visual_type)
+ return NULL;
+
+ return system_visual;
+}
+
+void
+gdk_query_depths (gint **depths,
+ gint *count)
+{
+ *count = 1;
+ *depths = &system_visual->depth;
+}
+
+void
+gdk_query_visual_types (GdkVisualType **visual_types,
+ gint *count)
+{
+ *count = 1;
+ *visual_types = &system_visual->type;
+}
+
+GList*
+gdk_screen_list_visuals (GdkScreen *screen)
+{
+ return g_list_append (NULL, gdk_visual_get_system ());
+}
+
+GdkScreen *
+gdk_visual_get_screen (GdkVisual *visual)
+{
+ g_return_val_if_fail (GDK_IS_VISUAL (visual), NULL);
+
+ return gdk_screen_get_default ();
+}
+
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
new file mode 100644
index 000000000..0d6e4c4c9
--- /dev/null
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -0,0 +1,1187 @@
+/* gdkwindow-quartz.c
+ *
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "gdk.h"
+#include "gdkprivate-quartz.h"
+
+static gpointer parent_class;
+
+static void
+gdk_window_impl_quartz_get_size (GdkDrawable *drawable,
+ gint *width,
+ gint *height)
+{
+ g_return_if_fail (GDK_IS_WINDOW_IMPL_QUARTZ (drawable));
+
+ if (width)
+ *width = GDK_WINDOW_IMPL_QUARTZ (drawable)->width;
+ if (height)
+ *height = GDK_WINDOW_IMPL_QUARTZ (drawable)->height;
+}
+
+static GdkRegion*
+gdk_window_impl_quartz_get_visible_region (GdkDrawable *drawable)
+{
+ GdkWindowObject *private = GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper);
+ GdkRectangle rect;
+ GdkWindowImplQuartz *impl;
+ GList *windows = NULL, *l;
+
+ /* FIXME: The clip rectangle should really be cached
+ * and recalculated when the window rectangle changes.
+ */
+ while (private)
+ {
+ windows = g_list_prepend (windows, private);
+
+ if (private->parent == GDK_WINDOW_OBJECT (_gdk_root))
+ break;
+
+ private = private->parent;
+ }
+
+ /* Get rectangle for toplevel window */
+ private = GDK_WINDOW_OBJECT (windows->data);
+ impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = impl->width;
+ rect.height = impl->height;
+
+ /* Skip toplevel window since we have its rect */
+ for (l = windows->next; l; l = l->next)
+ {
+ private = GDK_WINDOW_OBJECT (l->data);
+ impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+ GdkRectangle tmp_rect;
+
+ tmp_rect.x = -MIN (0, private->x - rect.x);
+ tmp_rect.y = -MIN (0, private->y - rect.y);
+ tmp_rect.width = MIN (rect.width, impl->width + private->x - rect.x) - MAX (0, private->x - rect.x);
+ tmp_rect.height = MIN (rect.height, impl->height + private->y - rect.y) - MAX (0, private->y - rect.y);
+
+ rect = tmp_rect;
+ }
+
+ g_list_free (windows);
+
+ return gdk_region_rectangle (&rect);
+}
+
+static void
+gdk_window_impl_quartz_finalize (GObject *object)
+{
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (object);
+
+ if (impl->nscursor)
+ [impl->nscursor release];
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
+{
+ GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ drawable_class->get_size = gdk_window_impl_quartz_get_size;
+
+ /* Visible and clip regions are the same */
+ drawable_class->get_clip_region = gdk_window_impl_quartz_get_visible_region;
+ drawable_class->get_visible_region = gdk_window_impl_quartz_get_visible_region;
+}
+
+
+static void
+gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
+{
+ impl->width = 1;
+ impl->height = 1;
+}
+
+GType
+_gdk_window_impl_quartz_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (GdkWindowImplQuartzClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_window_impl_quartz_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GdkWindowImplQuartz),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gdk_window_impl_quartz_init,
+ };
+
+ object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
+ "GdkWindowImplQuartz",
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+GType
+_gdk_window_impl_get_type (void)
+{
+ return _gdk_window_impl_quartz_get_type ();
+}
+
+static const gchar *
+get_default_title (void)
+{
+ const char *title;
+
+ title = g_get_application_name ();
+ if (!title)
+ title = g_get_prgname ();
+
+ return title;
+}
+
+gint
+_gdk_quartz_get_inverted_screen_y (gint y)
+{
+ NSRect rect = [[NSScreen mainScreen] frame];
+
+ return rect.size.height - y;
+}
+
+GdkWindow *
+gdk_window_new (GdkWindow *parent,
+ GdkWindowAttr *attributes,
+ gint attributes_mask)
+{
+ GdkWindow *window;
+ GdkWindowObject *private;
+ GdkWindowImplQuartz *impl;
+ GdkDrawableImplQuartz *draw_impl;
+ GdkVisual *visual;
+
+ GDK_QUARTZ_ALLOC_POOL;
+
+ if (parent && GDK_WINDOW_DESTROYED (parent))
+ {
+ GDK_QUARTZ_RELEASE_POOL;
+ return NULL;
+ }
+
+ if (!parent)
+ parent = _gdk_root;
+
+ window = g_object_new (GDK_TYPE_WINDOW, NULL);
+ private = (GdkWindowObject *)window;
+ impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+ draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl);
+ draw_impl->wrapper = GDK_DRAWABLE (window);
+
+ private->parent = (GdkWindowObject *)parent;
+
+ if (attributes_mask & GDK_WA_X)
+ private->x = attributes->x;
+ else
+ private->x = 0;
+
+ if (attributes_mask & GDK_WA_Y)
+ private->y = attributes->y;
+ else if (attributes_mask & GDK_WA_X)
+ private->y = 100;
+ else
+ private->y = 0;
+
+ private->event_mask = attributes->event_mask;
+
+ impl->width = attributes->width > 1 ? attributes->width : 1;
+ impl->height = attributes->height > 1 ? attributes->height : 1;
+
+ if (attributes_mask & GDK_WA_VISUAL)
+ visual = attributes->visual;
+ else
+ visual = gdk_screen_get_system_visual (_gdk_screen);
+
+ if (attributes->wclass == GDK_INPUT_ONLY)
+ {
+ /* Backwards compatiblity - we've always ignored
+ * attributes->window_type for input-only windows
+ * before
+ */
+ if (parent == _gdk_root)
+ private->window_type = GDK_WINDOW_TEMP;
+ else
+ private->window_type = GDK_WINDOW_CHILD;
+ }
+ else
+ private->window_type = attributes->window_type;
+
+ /* Sanity checks */
+ switch (private->window_type)
+ {
+ case GDK_WINDOW_TOPLEVEL:
+ case GDK_WINDOW_DIALOG:
+ case GDK_WINDOW_TEMP:
+ if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
+ {
+ g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
+ "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
+ }
+ case GDK_WINDOW_CHILD:
+ break;
+ default:
+ g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
+ return NULL;
+ }
+
+ if (attributes->wclass == GDK_INPUT_OUTPUT)
+ {
+ private->input_only = FALSE;
+ private->depth = visual->depth;
+
+ if (attributes_mask & GDK_WA_COLORMAP)
+ {
+ draw_impl->colormap = attributes->colormap;
+ g_object_ref (attributes->colormap);
+ }
+ else
+ {
+ if (visual == gdk_screen_get_system_visual (_gdk_screen))
+ {
+ draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
+ g_object_ref (draw_impl->colormap);
+ }
+ else if (visual == gdk_screen_get_rgba_visual (_gdk_screen))
+ {
+ draw_impl->colormap = gdk_screen_get_rgba_colormap (_gdk_screen);
+ g_object_ref (draw_impl->colormap);
+ }
+ else
+ {
+ draw_impl->colormap = gdk_colormap_new (visual, FALSE);
+ }
+ }
+
+ private->bg_color.pixel = 0;
+ private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
+ }
+ else
+ {
+ private->depth = 0;
+ private->input_only = TRUE;
+ draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
+ }
+
+ if (private->parent)
+ private->parent->children = g_list_prepend (private->parent->children, window);
+
+ gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
+ (attributes->cursor) :
+ NULL));
+
+ switch (attributes->window_type)
+ {
+ case GDK_WINDOW_TOPLEVEL:
+ case GDK_WINDOW_DIALOG:
+ case GDK_WINDOW_TEMP:
+ {
+ NSRect content_rect = NSMakeRect (private->x,
+ _gdk_quartz_get_inverted_screen_y (private->y) - impl->height,
+ impl->width, impl->height);
+ const char *title;
+ int style_mask = NSTitledWindowMask|
+ NSClosableWindowMask|
+ NSMiniaturizableWindowMask|
+ NSResizableWindowMask;
+
+ impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect
+ styleMask:style_mask
+ backing:NSBackingStoreBuffered defer:NO];
+ if (attributes_mask & GDK_WA_TITLE)
+ title = attributes->title;
+ else
+ title = get_default_title ();
+
+ gdk_window_set_title (window, title);
+
+
+ if (draw_impl->colormap == gdk_screen_get_rgba_colormap (_gdk_screen))
+ {
+ [impl->toplevel setOpaque:NO];
+ [impl->toplevel setBackgroundColor:[NSColor clearColor]];
+ }
+
+ impl->view = [[GdkQuartzView alloc] initWithFrame:content_rect];
+ [impl->view setGdkWindow:window];
+ [impl->toplevel setContentView:impl->view];
+
+ /* Add a tracking rect */
+ impl->tracking_rect = [impl->view addTrackingRect:NSMakeRect(0, 0, impl->width, impl->height)
+ owner:impl->view
+ userData:nil
+ assumeInside:NO];
+ }
+ break;
+ case GDK_WINDOW_CHILD:
+ {
+ GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl);
+
+ if (attributes->wclass == GDK_INPUT_OUTPUT)
+ {
+ NSRect frame_rect = NSMakeRect (private->x, private->y, impl->width, impl->height);
+
+ impl->view = [[GdkQuartzView alloc] initWithFrame:frame_rect];
+
+ [impl->view setGdkWindow:window];
+
+ /* GdkWindows should be hidden by default */
+ [impl->view setHidden:YES];
+ [parent_impl->view addSubview:impl->view];
+ }
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ GDK_QUARTZ_RELEASE_POOL;
+
+ return window;
+}
+
+void
+_gdk_windowing_window_init (void)
+{
+ GdkWindowObject *private;
+
+ g_assert (_gdk_root == NULL);
+
+ _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
+ private = (GdkWindowObject *)_gdk_root;
+
+ private->window_type = GDK_WINDOW_ROOT;
+ private->depth = 24;
+}
+
+void
+_gdk_windowing_window_destroy (GdkWindow *window,
+ gboolean recursing,
+ gboolean foreign_destroy)
+{
+ if (!recursing && ! foreign_destroy)
+ {
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+
+ if (window == _gdk_quartz_get_mouse_window ())
+ {
+ _gdk_quartz_update_mouse_window (_gdk_root);
+ }
+
+ if (impl->toplevel)
+ [impl->toplevel close];
+ else if (impl->view)
+ [impl->view release];
+
+ }
+}
+
+void
+_gdk_windowing_window_destroy_foreign (GdkWindow *window)
+{
+ /* FIXME: Implement */
+}
+
+static void
+show_window_internal (GdkWindow *window, gboolean raise)
+{
+ GdkWindowObject *private;
+ GdkWindowImplQuartz *impl;
+
+ private = (GdkWindowObject *)window;
+
+ if (private->destroyed)
+ return;
+
+ GDK_QUARTZ_ALLOC_POOL;
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+ /* FIXME: We need to raise the window (move it to the top in the list)*/
+
+ if (impl->toplevel)
+ {
+ [impl->toplevel orderFront:nil];
+ [impl->view setNeedsDisplay:YES];
+ }
+ else
+ {
+ [impl->view setHidden:NO];
+ [impl->view setNeedsDisplay:YES];
+ }
+
+ gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0);
+
+ GDK_QUARTZ_RELEASE_POOL;
+}
+
+void
+gdk_window_show_unraised (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ show_window_internal (window, FALSE);
+}
+
+void
+gdk_window_show (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ show_window_internal (window, TRUE);
+}
+
+void
+gdk_window_hide (GdkWindow *window)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindowImplQuartz *impl;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (GDK_WINDOW_IS_MAPPED (window))
+ gdk_synthesize_window_state (window,
+ 0,
+ GDK_WINDOW_STATE_WITHDRAWN);
+
+ _gdk_window_clear_update_area (window);
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+ if (impl->toplevel)
+ {
+ /* FIXME: Support hiding toplevel windows */
+ }
+ else if (impl->view)
+ {
+ [impl->view setHidden:YES];
+ }
+}
+
+void
+gdk_window_withdraw (GdkWindow *window)
+{
+ gdk_window_hide (window);
+}
+
+static void
+move_resize_window_internal (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindowImplQuartz *impl;
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+ if (x != -1)
+ private->x = x;
+
+ if (y != -1)
+ private->y = y;
+
+ if (width != -1)
+ impl->width = width;
+
+ if (height != -1)
+ impl->height = height;
+
+ if (impl->toplevel)
+ {
+ NSRect content_rect = NSMakeRect (private->x,
+ _gdk_quartz_get_inverted_screen_y (private->y) ,
+ impl->width, impl->height);
+ NSRect frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
+
+ frame_rect.origin.y -= frame_rect.size.height;
+
+ [impl->toplevel setFrame:frame_rect display:YES];
+ }
+ else
+ {
+ if (!private->input_only)
+ {
+ [impl->view setFrame:NSMakeRect (private->x, private->y,
+ impl->width, impl->height)];
+
+ /* FIXME: Maybe we should use setNeedsDisplayInRect instead */
+ [impl->view setNeedsDisplay:YES];
+ }
+ }
+}
+
+void
+gdk_window_move (GdkWindow *window,
+ gint x,
+ gint y)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ move_resize_window_internal (window, x, y, -1, -1);
+}
+
+void
+gdk_window_resize (GdkWindow *window,
+ gint width,
+ gint height)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (width < 1)
+ width = 1;
+ if (height < 1)
+ height = 1;
+
+ move_resize_window_internal (window, -1, -1, width, height);
+}
+
+void
+gdk_window_move_resize (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ if (width < 1)
+ width = 1;
+ if (height < 1)
+ height = 1;
+
+ move_resize_window_internal (window, x, y, width, height);
+}
+
+void
+gdk_window_reparent (GdkWindow *window,
+ GdkWindow *new_parent,
+ gint x,
+ gint y)
+{
+ g_warning ("gdk_window_reparent: %p %p (%d, %d)",
+ window, new_parent, x, y);
+
+ /* FIXME: Implement */
+}
+
+void
+_gdk_windowing_window_clear_area (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ /* FIXME: Implement */
+}
+
+void
+_gdk_windowing_window_clear_area_e (GdkWindow *window,
+ gint x,
+ gint y,
+ gint width,
+ gint height)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_raise (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_lower (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_background (GdkWindow *window,
+ const GdkColor *color)
+{
+ GdkWindowObject *private = (GdkWindowObject *)window;
+ GdkWindowImplQuartz *impl;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
+
+ private->bg_color = *color;
+
+ if (private->bg_pixmap &&
+ private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
+ private->bg_pixmap != GDK_NO_BG)
+ g_object_unref (private->bg_pixmap);
+
+ private->bg_pixmap = NULL;
+}
+
+void
+gdk_window_set_back_pixmap (GdkWindow *window,
+ GdkPixmap *pixmap,
+ gboolean parent_relative)
+{
+ 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));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_cursor (GdkWindow *window,
+ GdkCursor *cursor)
+{
+ GdkWindowImplQuartz *impl;
+ GdkCursorPrivate *cursor_private;
+ NSCursor *nscursor;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+ cursor_private = (GdkCursorPrivate *)cursor;
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ if (!cursor)
+ nscursor = NULL;
+ else
+ nscursor = [cursor_private->nscursor retain];
+
+ if (impl->nscursor)
+ [impl->nscursor release];
+
+ impl->nscursor = nscursor;
+
+ _gdk_quartz_update_cursor (_gdk_quartz_get_mouse_window ());
+}
+
+void
+gdk_window_get_geometry (GdkWindow *window,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ gint *depth)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+gboolean
+gdk_window_get_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+ /* FIXME: Implement */
+ return FALSE;
+}
+
+gboolean
+gdk_window_get_deskrelative_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+ /* FIXME: Implement */
+ return FALSE;
+}
+
+void
+gdk_window_get_root_origin (GdkWindow *window,
+ gint *x,
+ gint *y)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+_gdk_windowing_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+}
+
+GdkWindow *
+_gdk_windowing_window_get_pointer (GdkDisplay *display,
+ GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ if (window == _gdk_root)
+ {
+ g_error ("FIXME: support get_pointer with root window");
+ }
+ else
+ {
+ GdkWindow *toplevel = gdk_window_get_toplevel (window);
+ GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
+ GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
+ NSWindow *nswindow = impl->toplevel;
+ NSPoint point = [nswindow mouseLocationOutsideOfEventStream];
+ int x_tmp, y_tmp;
+
+ /* First flip the y coordinate */
+ x_tmp = point.x;
+ y_tmp = impl->height - point.y;
+
+ while (private != GDK_WINDOW_OBJECT (toplevel)) {
+ x_tmp -= private->x;
+ y_tmp -= private->y;
+
+ private = private->parent;
+ }
+
+ if (x)
+ *x = x_tmp;
+ if (y)
+ *y = y_tmp;
+ }
+
+ /* FIXME: Implement return value */
+ return NULL;
+}
+
+GdkWindow *
+_gdk_windowing_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+GdkEventMask
+gdk_window_get_events (GdkWindow *window)
+{
+ g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return 0;
+ else
+ return GDK_WINDOW_OBJECT (window)->event_mask;
+}
+
+void
+gdk_window_set_events (GdkWindow *window,
+ GdkEventMask event_mask)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (!GDK_WINDOW_DESTROYED (window))
+ {
+ GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
+ }
+}
+
+void
+gdk_window_set_urgency_hint (GdkWindow *window,
+ gboolean urgent)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_geometry_hints (GdkWindow *window,
+ GdkGeometry *geometry,
+ GdkWindowHints geom_mask)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_title (GdkWindow *window,
+ const gchar *title)
+{
+ GdkWindowImplQuartz *impl;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+ g_return_if_fail (title != NULL);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)window)->impl);
+
+ if (impl->toplevel)
+ {
+ [impl->toplevel setTitle:[NSString stringWithUTF8String:title]];
+ }
+}
+
+void
+gdk_window_set_role (GdkWindow *window,
+ const gchar *role)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_transient_for (GdkWindow *window,
+ GdkWindow *parent)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_shape_combine_region (GdkWindow *window,
+ GdkRegion *shape,
+ gint x,
+ gint y)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_shape_combine_mask (GdkWindow *window,
+ GdkBitmap *mask,
+ gint x, gint y)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_accept_focus (GdkWindow *window,
+ gboolean accept_focus)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_focus_on_map (GdkWindow *window,
+ gboolean focus_on_map)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_icon (GdkWindow *window,
+ GdkWindow *icon_window,
+ GdkPixmap *pixmap,
+ GdkBitmap *mask)
+{
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_icon_name (GdkWindow *window,
+ const gchar *name)
+{
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_focus (GdkWindow *window,
+ guint32 timestamp)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_type_hint (GdkWindow *window,
+ GdkWindowTypeHint hint)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_modal_hint (GdkWindow *window,
+ gboolean modal)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_skip_taskbar_hint (GdkWindow *window,
+ gboolean skips_taskbar)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_skip_pager_hint (GdkWindow *window,
+ gboolean skips_pager)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_begin_resize_drag (GdkWindow *window,
+ GdkWindowEdge edge,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_begin_move_drag (GdkWindow *window,
+ gint button,
+ gint root_x,
+ gint root_y,
+ guint32 timestamp)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_icon_list (GdkWindow *window,
+ GList *pixbufs)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_get_frame_extents (GdkWindow *window,
+ GdkRectangle *rect)
+{
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_decorations (GdkWindow *window,
+ GdkWMDecoration decorations)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_functions (GdkWindow *window,
+ GdkWMFunction functions)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+_gdk_windowing_window_get_offsets (GdkWindow *window,
+ gint *x_offset,
+ gint *y_offset)
+{
+ *x_offset = *y_offset = 0;
+}
+
+gboolean
+_gdk_windowing_window_queue_antiexpose (GdkWindow *window,
+ GdkRegion *area)
+{
+ return FALSE;
+}
+
+void
+gdk_window_stick (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+}
+
+void
+gdk_window_unstick (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+}
+
+void
+gdk_window_maximize (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_unmaximize (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_iconify (GdkWindow *window)
+{
+ GdkWindowImplQuartz *impl;
+ NSAutoreleasePool *pool;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+ if (!impl->toplevel)
+ return;
+
+ pool = [[NSAutoreleasePool alloc] init];
+ [impl->toplevel miniaturize:nil];
+ [pool release];
+}
+
+void
+gdk_window_deiconify (GdkWindow *window)
+{
+ GdkWindowImplQuartz *impl;
+ NSAutoreleasePool *pool;
+
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return;
+
+ impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
+ if (!impl->toplevel)
+ return;
+
+ pool = [[NSAutoreleasePool alloc] init];
+ [impl->toplevel deminiaturize:nil];
+ [pool release];
+}
+
+void
+gdk_window_fullscreen (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_unfullscreen (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+void
+gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* FIXME: Implement */
+}
+
+GdkWindow*
+gdk_window_foreign_new_for_display (GdkDisplay *display,
+ GdkNativeWindow anid)
+{
+ /* Foreign windows aren't supported in Mac OS X */
+ return NULL;
+}
+
+GdkWindow*
+gdk_window_lookup (GdkNativeWindow anid)
+{
+ /* Foreign windows aren't supported in Mac OS X */
+ return NULL;
+}
+
+GdkWindow *
+gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
+{
+ /* Foreign windows aren't supported in Mac OS X */
+ return NULL;
+}
+
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+}
+
+void
+gdk_window_configure_finished (GdkWindow *window)
+{
+}
diff --git a/gdk/quartz/gdkwindow-quartz.h b/gdk/quartz/gdkwindow-quartz.h
new file mode 100644
index 000000000..0fe45d1f2
--- /dev/null
+++ b/gdk/quartz/gdkwindow-quartz.h
@@ -0,0 +1,72 @@
+/* gdkdrawable-quartz.h
+ *
+ * Copyright (C) 2005 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_WINDOW_QUARTZ_H__
+#define __GDK_WINDOW_QUARTZ_H__
+
+#include <gdk/quartz/gdkdrawable-quartz.h>
+#import <gdk/quartz/GdkQuartzView.h>
+#import <gdk/quartz/GdkQuartzWindow.h>
+
+
+G_BEGIN_DECLS
+
+/* Window implementation for Quartz
+ */
+
+typedef struct _GdkWindowImplQuartz GdkWindowImplQuartz;
+typedef struct _GdkWindowImplQuartzClass GdkWindowImplQuartzClass;
+
+#define GDK_TYPE_WINDOW_IMPL_QUARTZ (_gdk_window_impl_quartz_get_type ())
+#define GDK_WINDOW_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_QUARTZ, GdkWindowImplQuartz))
+#define GDK_WINDOW_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_QUARTZ, GdkWindowImplQuartzClass))
+#define GDK_IS_WINDOW_IMPL_QUARTZ(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_QUARTZ))
+#define GDK_IS_WINDOW_IMPL_QUARTZ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_QUARTZ))
+#define GDK_WINDOW_IMPL_QUARTZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_QUARTZ, GdkWindowImplQuartzClass))
+
+struct _GdkWindowImplQuartz
+{
+ GdkDrawableImplQuartz parent_instance;
+
+ gint width;
+ gint height;
+
+ NSWindow *toplevel;
+ NSTrackingRectTag tracking_rect;
+ GdkQuartzView *view;
+
+ /* This is the autorelease pool which is retained
+ * while the context is being held
+ */
+ NSAutoreleasePool *pool;
+
+ NSCursor *nscursor;
+};
+
+struct _GdkWindowImplQuartzClass
+{
+ GdkDrawableImplQuartzClass parent_class;
+};
+
+GType _gdk_window_impl_quartz_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GDK_WINDOW_QUARTZ_H__ */
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index c6a1f01e8..eb5e7b916 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -675,20 +675,23 @@ gtkinclude_HEADERS = $(gtk_public_h_sources) $(gtk_semi_private_h_sources) $(gtk
libgtk_x11_2_0_la_SOURCES = $(gtk_c_sources)
libgtk_linux_fb_2_0_la_SOURCES = $(gtk_c_sources)
libgtk_win32_2_0_la_SOURCES = $(gtk_c_sources)
+libgtk_quartz_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_quartz_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) -lole32 -lgdi32
libgtk_win32_2_0_la_DEPENDENCIES = $(gtk_def) $(gtk_win32_res)
+libgtk_quartz_2_0_la_LIBADD = $(libadd)
if USE_WIN32
libgtk_target_ldflags = $(gtk_win32_res_ldflag) $(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-quartz-2.0.la
install-exec-hook:
if DISABLE_EXPLICIT_DEPS
diff --git a/gtk/gtkplug-stub.c b/gtk/gtkplug-stub.c
index 3346f36ed..3bd1024aa 100644
--- a/gtk/gtkplug-stub.c
+++ b/gtk/gtkplug-stub.c
@@ -25,6 +25,7 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include "gtkplug.h"
#include "gtkplugprivate.h"
GdkNativeWindow
diff --git a/gtk/gtksocket-stub.c b/gtk/gtksocket-stub.c
index 9895c227b..b839048b8 100644
--- a/gtk/gtksocket-stub.c
+++ b/gtk/gtksocket-stub.c
@@ -25,6 +25,7 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include "gtksocket.h"
#include "gtksocketprivate.h"
GdkNativeWindow