summaryrefslogtreecommitdiff
path: root/plugins/gtkui/gtkglext-gtk2/gdk/win32/gdkglcontext-win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gtkui/gtkglext-gtk2/gdk/win32/gdkglcontext-win32.c')
-rw-r--r--plugins/gtkui/gtkglext-gtk2/gdk/win32/gdkglcontext-win32.c490
1 files changed, 490 insertions, 0 deletions
diff --git a/plugins/gtkui/gtkglext-gtk2/gdk/win32/gdkglcontext-win32.c b/plugins/gtkui/gtkglext-gtk2/gdk/win32/gdkglcontext-win32.c
new file mode 100644
index 00000000..408e080a
--- /dev/null
+++ b/plugins/gtkui/gtkglext-gtk2/gdk/win32/gdkglcontext-win32.c
@@ -0,0 +1,490 @@
+/* GdkGLExt - OpenGL Extension to GDK
+ * Copyright (C) 2002-2004 Naofumi Yasufuku
+ *
+ * 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.1 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 "gdkglwin32.h"
+#include "gdkglprivate-win32.h"
+#include "gdkglconfig-win32.h"
+#include "gdkglcontext-win32.h"
+
+static void gdk_gl_context_insert (GdkGLContext *glcontext);
+static void gdk_gl_context_remove (GdkGLContext *glcontext);
+static GdkGLContext *gdk_gl_context_lookup (HGLRC hglrc);
+static guint gdk_gl_context_hash (HGLRC *hglrc);
+static gboolean gdk_gl_context_equal (HGLRC *a,
+ HGLRC *b);
+
+static void gdk_gl_context_impl_win32_class_init (GdkGLContextImplWin32Class *klass);
+static void gdk_gl_context_impl_win32_finalize (GObject *object);
+
+static gpointer parent_class = NULL;
+
+GType
+gdk_gl_context_impl_win32_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info = {
+ sizeof (GdkGLContextImplWin32Class),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_gl_context_impl_win32_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GdkGLContextImplWin32),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL
+ };
+
+ type = g_type_register_static (GDK_TYPE_GL_CONTEXT,
+ "GdkGLContextImplWin32",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+static void
+gdk_gl_context_impl_win32_class_init (GdkGLContextImplWin32Class *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = gdk_gl_context_impl_win32_finalize;
+}
+
+void
+_gdk_gl_context_destroy (GdkGLContext *glcontext)
+{
+ GdkGLContextImplWin32 *impl = GDK_GL_CONTEXT_IMPL_WIN32 (glcontext);
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ if (impl->is_destroyed)
+ return;
+
+ gdk_gl_context_remove (glcontext);
+
+ if (impl->hglrc == wglGetCurrentContext ())
+ {
+ glFinish ();
+
+ GDK_GL_NOTE_FUNC_IMPL ("wglMakeCurrent");
+ wglMakeCurrent (NULL, NULL);
+ }
+
+ if (!impl->is_foreign)
+ {
+ GDK_GL_NOTE_FUNC_IMPL ("wglDeleteContext");
+ wglDeleteContext (impl->hglrc);
+ impl->hglrc = NULL;
+ }
+
+ if (impl->gldrawable != NULL)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (impl->gldrawable),
+ (gpointer *) &(impl->gldrawable));
+ impl->gldrawable = NULL;
+ }
+
+ /* currently unused. */
+ /*
+ if (impl->gldrawable_read != NULL)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (impl->gldrawable_read),
+ (gpointer *) &(impl->gldrawable_read));
+ impl->gldrawable_read = NULL;
+ }
+ */
+
+ impl->is_destroyed = TRUE;
+}
+
+static void
+gdk_gl_context_impl_win32_finalize (GObject *object)
+{
+ GdkGLContextImplWin32 *impl = GDK_GL_CONTEXT_IMPL_WIN32 (object);
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ _gdk_gl_context_destroy (GDK_GL_CONTEXT (object));
+
+ g_object_unref (G_OBJECT (impl->glconfig));
+
+ if (impl->share_list != NULL)
+ g_object_unref (G_OBJECT (impl->share_list));
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static GdkGLContext *
+gdk_gl_context_new_common (GdkGLConfig *glconfig,
+ GdkGLContext *share_list,
+ int render_type,
+ HGLRC hglrc,
+ gboolean is_foreign)
+{
+ GdkGLContext *glcontext;
+ GdkGLContextImplWin32 *impl;
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ /*
+ * Instantiate the GdkGLContextImplWin32 object.
+ */
+
+ glcontext = g_object_new (GDK_TYPE_GL_CONTEXT_IMPL_WIN32, NULL);
+ impl = GDK_GL_CONTEXT_IMPL_WIN32 (glcontext);
+
+ impl->hglrc = hglrc;
+
+ if (share_list != NULL && GDK_IS_GL_CONTEXT (share_list))
+ {
+ impl->share_list = share_list;
+ g_object_ref (G_OBJECT (impl->share_list));
+ }
+ else
+ {
+ impl->share_list = NULL;
+ }
+
+ impl->render_type = render_type;
+
+ impl->glconfig = glconfig;
+ g_object_ref (G_OBJECT (impl->glconfig));
+
+ impl->gldrawable = NULL;
+ impl->gldrawable_read = NULL;
+
+ impl->is_foreign = is_foreign;
+
+ impl->is_destroyed = FALSE;
+
+ /*
+ * Insert into the GL context hash table.
+ */
+
+ gdk_gl_context_insert (glcontext);
+
+ return glcontext;
+}
+
+/*< private >*/
+GdkGLContext *
+_gdk_win32_gl_context_new (GdkGLDrawable *gldrawable,
+ GdkGLContext *share_list,
+ gboolean direct,
+ int render_type)
+{
+ GdkGLConfig *glconfig;
+ HDC hdc;
+ HGLRC hglrc;
+ GdkGLContextImplWin32 *share_impl = NULL;
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ /*
+ * Create an OpenGL rendering context.
+ */
+
+ glconfig = gdk_gl_drawable_get_gl_config (gldrawable);
+
+ /* Get DC. */
+ hdc = gdk_win32_gl_drawable_hdc_get (gldrawable);
+ if (hdc == NULL)
+ return NULL;
+
+ GDK_GL_NOTE_FUNC_IMPL ("wglCreateContext");
+
+ hglrc = wglCreateContext (hdc);
+
+ /* Release DC. */
+ gdk_win32_gl_drawable_hdc_release (gldrawable);
+
+ if (hglrc == NULL)
+ return NULL;
+
+ if (share_list != NULL && GDK_IS_GL_CONTEXT (share_list))
+ {
+ GDK_GL_NOTE_FUNC_IMPL ("wglShareLists");
+
+ share_impl = GDK_GL_CONTEXT_IMPL_WIN32 (share_list);
+ if (!wglShareLists (share_impl->hglrc, hglrc))
+ {
+ wglDeleteContext (hglrc);
+ return NULL;
+ }
+ }
+
+ /*
+ * Instantiate the GdkGLContextImplWin32 object.
+ */
+
+ return gdk_gl_context_new_common (glconfig,
+ share_list,
+ render_type,
+ hglrc,
+ FALSE);
+}
+
+GdkGLContext *
+gdk_win32_gl_context_foreign_new (GdkGLConfig *glconfig,
+ GdkGLContext *share_list,
+ HGLRC hglrc)
+{
+ GDK_GL_NOTE_FUNC ();
+
+ g_return_val_if_fail (GDK_IS_GL_CONFIG_IMPL_WIN32 (glconfig), NULL);
+ g_return_val_if_fail (hglrc != NULL, NULL);
+
+ /*
+ * Instantiate the GdkGLContextImplWin32 object.
+ */
+
+ return gdk_gl_context_new_common (glconfig,
+ share_list,
+ (glconfig->is_rgba) ? GDK_GL_RGBA_TYPE : GDK_GL_COLOR_INDEX_TYPE,
+ hglrc,
+ TRUE);
+}
+
+gboolean
+gdk_gl_context_copy (GdkGLContext *glcontext,
+ GdkGLContext *src,
+ unsigned long mask)
+{
+ HGLRC dst_hglrc, src_hglrc;
+
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext), FALSE);
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (src), FALSE);
+
+ dst_hglrc = GDK_GL_CONTEXT_HGLRC (glcontext);
+ if (dst_hglrc == NULL)
+ return FALSE;
+
+ src_hglrc = GDK_GL_CONTEXT_HGLRC (src);
+ if (src_hglrc == NULL)
+ return FALSE;
+
+ GDK_GL_NOTE_FUNC_IMPL ("wglCopyContext");
+
+ return wglCopyContext (src_hglrc, dst_hglrc, mask);
+}
+
+/*< private >*/
+void
+_gdk_gl_context_set_gl_drawable (GdkGLContext *glcontext,
+ GdkGLDrawable *gldrawable)
+{
+ GdkGLContextImplWin32 *impl = GDK_GL_CONTEXT_IMPL_WIN32 (glcontext);
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ if (impl->gldrawable == gldrawable)
+ return;
+
+ if (impl->gldrawable != NULL)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (impl->gldrawable),
+ (gpointer *) &(impl->gldrawable));
+ impl->gldrawable = NULL;
+ }
+
+ if (gldrawable != NULL && GDK_IS_GL_DRAWABLE (gldrawable))
+ {
+ impl->gldrawable = gldrawable;
+ g_object_add_weak_pointer (G_OBJECT (impl->gldrawable),
+ (gpointer *) &(impl->gldrawable));
+ }
+}
+
+/*< private >*/
+/* currently unused. */
+/*
+void
+_gdk_gl_context_set_gl_drawable_read (GdkGLContext *glcontext,
+ GdkGLDrawable *gldrawable_read)
+{
+ GdkGLContextImplWin32 *impl = GDK_GL_CONTEXT_IMPL_WIN32 (glcontext);
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ if (impl->gldrawable_read == gldrawable_read)
+ return;
+
+ if (impl->gldrawable_read != NULL)
+ {
+ g_object_remove_weak_pointer (G_OBJECT (impl->gldrawable_read),
+ (gpointer *) &(impl->gldrawable_read));
+ impl->gldrawable_read = NULL;
+ }
+
+ if (gldrawable_read != NULL && GDK_IS_GL_DRAWABLE (gldrawable_read))
+ {
+ impl->gldrawable_read = gldrawable_read;
+ g_object_add_weak_pointer (G_OBJECT (impl->gldrawable_read),
+ (gpointer *) &(impl->gldrawable_read));
+ }
+}
+*/
+
+GdkGLDrawable *
+gdk_gl_context_get_gl_drawable (GdkGLContext *glcontext)
+{
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext), NULL);
+
+ return GDK_GL_CONTEXT_IMPL_WIN32 (glcontext)->gldrawable;
+}
+
+GdkGLConfig *
+gdk_gl_context_get_gl_config (GdkGLContext *glcontext)
+{
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext), NULL);
+
+ return GDK_GL_CONTEXT_IMPL_WIN32 (glcontext)->glconfig;
+}
+
+GdkGLContext *
+gdk_gl_context_get_share_list (GdkGLContext *glcontext)
+{
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext), NULL);
+
+ return GDK_GL_CONTEXT_IMPL_WIN32 (glcontext)->share_list;
+}
+
+gboolean
+gdk_gl_context_is_direct (GdkGLContext *glcontext)
+{
+ return FALSE;
+}
+
+int
+gdk_gl_context_get_render_type (GdkGLContext *glcontext)
+{
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext), 0);
+
+ return GDK_GL_CONTEXT_IMPL_WIN32 (glcontext)->render_type;
+}
+
+GdkGLContext *
+gdk_gl_context_get_current (void)
+{
+ static GdkGLContext *current = NULL;
+ HGLRC hglrc;
+
+ GDK_GL_NOTE_FUNC ();
+
+ hglrc = wglGetCurrentContext ();
+
+ if (hglrc == NULL)
+ return NULL;
+
+ if (current && GDK_GL_CONTEXT_HGLRC (current) == hglrc)
+ return current;
+
+ current = gdk_gl_context_lookup (hglrc);
+
+ return current;
+}
+
+HGLRC
+gdk_win32_gl_context_get_hglrc (GdkGLContext *glcontext)
+{
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext), NULL);
+
+ return GDK_GL_CONTEXT_IMPL_WIN32 (glcontext)->hglrc;
+}
+
+/*
+ * GdkGLContext hash table.
+ */
+
+static GHashTable *gl_context_ht = NULL;
+
+static void
+gdk_gl_context_insert (GdkGLContext *glcontext)
+{
+ GdkGLContextImplWin32 *impl;
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ g_return_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext));
+
+ if (gl_context_ht == NULL)
+ {
+ GDK_GL_NOTE (MISC, g_message (" -- Create GL context hash table."));
+ gl_context_ht = g_hash_table_new ((GHashFunc) gdk_gl_context_hash,
+ (GEqualFunc) gdk_gl_context_equal);
+ }
+
+ impl = GDK_GL_CONTEXT_IMPL_WIN32 (glcontext);
+
+ g_hash_table_insert (gl_context_ht, &(impl->hglrc), glcontext);
+}
+
+static void
+gdk_gl_context_remove (GdkGLContext *glcontext)
+{
+ GdkGLContextImplWin32 *impl;
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ g_return_if_fail (GDK_IS_GL_CONTEXT_IMPL_WIN32 (glcontext));
+
+ if (gl_context_ht == NULL)
+ return;
+
+ impl = GDK_GL_CONTEXT_IMPL_WIN32 (glcontext);
+
+ g_hash_table_remove (gl_context_ht, &(impl->hglrc));
+
+ if (g_hash_table_size (gl_context_ht) == 0)
+ {
+ GDK_GL_NOTE (MISC, g_message (" -- Destroy GL context hash table."));
+ g_hash_table_destroy (gl_context_ht);
+ gl_context_ht = NULL;
+ }
+}
+
+static GdkGLContext *
+gdk_gl_context_lookup (HGLRC hglrc)
+{
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ if (gl_context_ht == NULL)
+ return NULL;
+
+ return g_hash_table_lookup (gl_context_ht, &hglrc);
+}
+
+static guint
+gdk_gl_context_hash (HGLRC *hglrc)
+{
+ return (guint) *hglrc;
+}
+
+static gboolean
+gdk_gl_context_equal (HGLRC *a,
+ HGLRC *b)
+{
+ return (*a == *b);
+}