summaryrefslogtreecommitdiff
path: root/plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglpixmap-x11.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglpixmap-x11.c')
-rw-r--r--plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglpixmap-x11.c387
1 files changed, 387 insertions, 0 deletions
diff --git a/plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglpixmap-x11.c b/plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglpixmap-x11.c
new file mode 100644
index 00000000..fcd8fb48
--- /dev/null
+++ b/plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglpixmap-x11.c
@@ -0,0 +1,387 @@
+/* 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 <string.h>
+
+#include "gdkglx.h"
+#include "gdkglprivate-x11.h"
+#include "gdkglconfig-x11.h"
+#include "gdkglcontext-x11.h"
+#include "gdkglpixmap-x11.h"
+
+static gboolean gdk_gl_pixmap_impl_x11_make_context_current (GdkGLDrawable *draw,
+ GdkGLDrawable *read,
+ GdkGLContext *glcontext);
+static gboolean gdk_gl_pixmap_impl_x11_is_double_buffered (GdkGLDrawable *gldrawable);
+static void gdk_gl_pixmap_impl_x11_swap_buffers (GdkGLDrawable *gldrawable);
+/*
+static gboolean gdk_gl_pixmap_impl_x11_gl_begin (GdkGLDrawable *draw,
+ GdkGLDrawable *read,
+ GdkGLContext *glcontext);
+*/
+static void gdk_gl_pixmap_impl_x11_gl_end (GdkGLDrawable *gldrawable);
+static GdkGLConfig *gdk_gl_pixmap_impl_x11_get_gl_config (GdkGLDrawable *gldrawable);
+
+static void gdk_gl_pixmap_impl_x11_class_init (GdkGLPixmapImplX11Class *klass);
+static void gdk_gl_pixmap_impl_x11_finalize (GObject *object);
+static void gdk_gl_pixmap_impl_x11_gl_drawable_interface_init (GdkGLDrawableClass *iface);
+
+static gpointer parent_class = NULL;
+
+GType
+gdk_gl_pixmap_impl_x11_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info = {
+ sizeof (GdkGLPixmapImplX11Class),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gdk_gl_pixmap_impl_x11_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GdkGLPixmapImplX11),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL
+ };
+ static const GInterfaceInfo gl_drawable_interface_info = {
+ (GInterfaceInitFunc) gdk_gl_pixmap_impl_x11_gl_drawable_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
+ type = g_type_register_static (GDK_TYPE_GL_PIXMAP,
+ "GdkGLPixmapImplX11",
+ &type_info, 0);
+ g_type_add_interface_static (type,
+ GDK_TYPE_GL_DRAWABLE,
+ &gl_drawable_interface_info);
+ }
+
+ return type;
+}
+
+static void
+gdk_gl_pixmap_impl_x11_class_init (GdkGLPixmapImplX11Class *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_pixmap_impl_x11_finalize;
+}
+
+void
+_gdk_gl_pixmap_destroy (GdkGLPixmap *glpixmap)
+{
+ GdkGLPixmapImplX11 *impl = GDK_GL_PIXMAP_IMPL_X11 (glpixmap);
+ Display *xdisplay;
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ if (impl->is_destroyed)
+ return;
+
+ xdisplay = GDK_GL_CONFIG_XDISPLAY (impl->glconfig);
+
+ if (impl->glxpixmap == glXGetCurrentDrawable ())
+ {
+ glXWaitGL ();
+
+ GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent");
+ glXMakeCurrent (xdisplay, None, NULL);
+ }
+
+ GDK_GL_NOTE_FUNC_IMPL ("glXDestroyGLXPixmap");
+ glXDestroyGLXPixmap (xdisplay, impl->glxpixmap);
+
+ impl->glxpixmap = None;
+
+ impl->is_destroyed = TRUE;
+}
+
+static void
+gdk_gl_pixmap_impl_x11_finalize (GObject *object)
+{
+ GdkGLPixmapImplX11 *impl = GDK_GL_PIXMAP_IMPL_X11 (object);
+
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ _gdk_gl_pixmap_destroy (GDK_GL_PIXMAP (object));
+
+ g_object_unref (G_OBJECT (impl->glconfig));
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gdk_gl_pixmap_impl_x11_gl_drawable_interface_init (GdkGLDrawableClass *iface)
+{
+ GDK_GL_NOTE_FUNC_PRIVATE ();
+
+ iface->create_new_context = _gdk_x11_gl_context_new;
+ iface->make_context_current = gdk_gl_pixmap_impl_x11_make_context_current;
+ iface->is_double_buffered = gdk_gl_pixmap_impl_x11_is_double_buffered;
+ iface->swap_buffers = gdk_gl_pixmap_impl_x11_swap_buffers;
+ iface->wait_gl = _gdk_gl_drawable_impl_x11_wait_gl;
+ iface->wait_gdk = _gdk_gl_drawable_impl_x11_wait_gdk;
+ iface->gl_begin = gdk_gl_pixmap_impl_x11_make_context_current;
+ iface->gl_end = gdk_gl_pixmap_impl_x11_gl_end;
+ iface->get_gl_config = gdk_gl_pixmap_impl_x11_get_gl_config;
+ iface->get_size = _gdk_gl_pixmap_get_size;
+}
+
+/**
+ * gdk_gl_pixmap_new:
+ * @glconfig: a #GdkGLConfig.
+ * @pixmap: the #GdkPixmap to be used as the rendering area.
+ * @attrib_list: this must be set to NULL or empty (first attribute of None).
+ *
+ * Creates an off-screen rendering area.
+ * attrib_list is currently unused. This must be set to NULL or empty
+ * (first attribute of None). See GLX 1.3 spec.
+ *
+ * Return value: the new #GdkGLPixmap.
+ **/
+GdkGLPixmap *
+gdk_gl_pixmap_new (GdkGLConfig *glconfig,
+ GdkPixmap *pixmap,
+ const int *attrib_list)
+{
+ GdkGLPixmap *glpixmap;
+ GdkGLPixmapImplX11 *impl;
+
+ Display *xdisplay;
+ XVisualInfo *xvinfo;
+ Pixmap xpixmap;
+ GLXPixmap glxpixmap;
+
+ Window root_return;
+ int x_return, y_return;
+ unsigned int width_return, height_return;
+ unsigned int border_width_return;
+ unsigned int depth_return;
+
+ GdkGL_GLX_MESA_pixmap_colormap *mesa_ext;
+
+ GDK_GL_NOTE_FUNC ();
+
+ g_return_val_if_fail (GDK_IS_GL_CONFIG_IMPL_X11 (glconfig), NULL);
+ g_return_val_if_fail (GDK_IS_PIXMAP (pixmap), NULL);
+
+ xdisplay = GDK_GL_CONFIG_XDISPLAY (glconfig);
+ xvinfo = GDK_GL_CONFIG_XVINFO (glconfig);
+
+ /*
+ * Get X Pixmap.
+ */
+
+ xpixmap = GDK_DRAWABLE_XID (GDK_DRAWABLE (pixmap));
+
+ /*
+ * Check depth of the X pixmap.
+ */
+
+ if (!XGetGeometry (xdisplay, xpixmap,
+ &root_return,
+ &x_return, &y_return,
+ &width_return, &height_return,
+ &border_width_return,
+ &depth_return))
+ return NULL;
+
+ if (depth_return != (unsigned int) xvinfo->depth)
+ return NULL;
+
+ /*
+ * Create GLXPixmap.
+ */
+
+ mesa_ext = gdk_gl_get_GLX_MESA_pixmap_colormap (glconfig);
+ if (mesa_ext)
+ {
+ /* If GLX_MESA_pixmap_colormap is supported. */
+
+ GDK_GL_NOTE_FUNC_IMPL ("glXCreateGLXPixmapMESA");
+
+ glxpixmap = mesa_ext->glXCreateGLXPixmapMESA (xdisplay,
+ xvinfo,
+ xpixmap,
+ GDK_GL_CONFIG_XCOLORMAP (glconfig));
+ }
+ else
+ {
+ GDK_GL_NOTE_FUNC_IMPL ("glXCreateGLXPixmap");
+
+ glxpixmap = glXCreateGLXPixmap (xdisplay,
+ xvinfo,
+ xpixmap);
+ }
+
+ if (glxpixmap == None)
+ return NULL;
+
+ /*
+ * Instantiate the GdkGLPixmapImplX11 object.
+ */
+
+ glpixmap = g_object_new (GDK_TYPE_GL_PIXMAP_IMPL_X11, NULL);
+ impl = GDK_GL_PIXMAP_IMPL_X11 (glpixmap);
+
+ glpixmap->drawable = GDK_DRAWABLE (pixmap);
+ g_object_add_weak_pointer (G_OBJECT (glpixmap->drawable),
+ (gpointer *) &(glpixmap->drawable));
+
+ impl->glxpixmap = glxpixmap;
+
+ impl->glconfig = glconfig;
+ g_object_ref (G_OBJECT (impl->glconfig));
+
+ impl->is_destroyed = FALSE;
+
+ return glpixmap;
+}
+
+static gboolean
+gdk_gl_pixmap_impl_x11_make_context_current (GdkGLDrawable *draw,
+ GdkGLDrawable *read,
+ GdkGLContext *glcontext)
+{
+ GdkGLConfig *glconfig;
+ GLXPixmap glxpixmap;
+ GLXContext glxcontext;
+
+ g_return_val_if_fail (GDK_IS_GL_PIXMAP_IMPL_X11 (draw), FALSE);
+ g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_X11 (glcontext), FALSE);
+
+ glconfig = GDK_GL_PIXMAP_IMPL_X11 (draw)->glconfig;
+ glxpixmap = GDK_GL_PIXMAP_IMPL_X11 (draw)->glxpixmap;
+ glxcontext = GDK_GL_CONTEXT_GLXCONTEXT (glcontext);
+
+ if (glxpixmap == None || glxcontext == NULL)
+ return FALSE;
+
+#ifdef GDKGLEXT_MULTIHEAD_SUPPORT
+ GDK_GL_NOTE (MISC,
+ g_message (" -- Pixmap: screen number = %d",
+ GDK_SCREEN_XNUMBER (gdk_drawable_get_screen (GDK_DRAWABLE (draw)))));
+#endif /* GDKGLEXT_MULTIHEAD_SUPPORT */
+ GDK_GL_NOTE (MISC,
+ g_message (" -- Pixmap: visual id = 0x%lx",
+ GDK_VISUAL_XVISUAL (gdk_drawable_get_visual (GDK_DRAWABLE (draw)))->visualid));
+
+ GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent");
+
+ if (!glXMakeCurrent (GDK_GL_CONFIG_XDISPLAY (glconfig), glxpixmap, glxcontext))
+ {
+ g_warning ("glXMakeCurrent() failed");
+ _gdk_gl_context_set_gl_drawable (glcontext, NULL);
+ /* currently unused. */
+ /* _gdk_gl_context_set_gl_drawable_read (glcontext, NULL); */
+ return FALSE;
+ }
+
+ _gdk_gl_context_set_gl_drawable (glcontext, draw);
+ /* currently unused. */
+ /* _gdk_gl_context_set_gl_drawable_read (glcontext, read); */
+
+ if (_GDK_GL_CONFIG_AS_SINGLE_MODE (glconfig))
+ {
+ /* We do this because we are treating a double-buffered frame
+ buffer as a single-buffered frame buffer because the system
+ does not appear to export any suitable single-buffered
+ visuals (in which the following are necessary). */
+ glDrawBuffer (GL_FRONT);
+ glReadBuffer (GL_FRONT);
+ }
+
+ GDK_GL_NOTE (MISC, _gdk_gl_print_gl_info ());
+
+ return TRUE;
+}
+
+static gboolean
+gdk_gl_pixmap_impl_x11_is_double_buffered (GdkGLDrawable *gldrawable)
+{
+ g_return_val_if_fail (GDK_IS_GL_PIXMAP_IMPL_X11 (gldrawable), FALSE);
+
+ return gdk_gl_config_is_double_buffered (GDK_GL_PIXMAP_IMPL_X11 (gldrawable)->glconfig);
+}
+
+static void
+gdk_gl_pixmap_impl_x11_swap_buffers (GdkGLDrawable *gldrawable)
+{
+ Display *xdisplay;
+ GLXPixmap glxpixmap;
+
+ g_return_if_fail (GDK_IS_GL_PIXMAP_IMPL_X11 (gldrawable));
+
+ xdisplay = GDK_GL_CONFIG_XDISPLAY (GDK_GL_PIXMAP_IMPL_X11 (gldrawable)->glconfig);
+ glxpixmap = GDK_GL_PIXMAP_IMPL_X11 (gldrawable)->glxpixmap;
+
+ if (glxpixmap == None)
+ return;
+
+ GDK_GL_NOTE_FUNC_IMPL ("glXSwapBuffers");
+
+ glXSwapBuffers (xdisplay, glxpixmap);
+}
+
+/*
+static gboolean
+gdk_gl_pixmap_impl_x11_gl_begin (GdkGLDrawable *draw,
+ GdkGLDrawable *read,
+ GdkGLContext *glcontext)
+{
+ return gdk_gl_pixmap_impl_x11_make_context_current (draw, read, glcontext);
+}
+*/
+
+static void
+gdk_gl_pixmap_impl_x11_gl_end (GdkGLDrawable *gldrawable)
+{
+ /* do nothing */
+}
+
+static GdkGLConfig *
+gdk_gl_pixmap_impl_x11_get_gl_config (GdkGLDrawable *gldrawable)
+{
+ g_return_val_if_fail (GDK_IS_GL_PIXMAP_IMPL_X11 (gldrawable), NULL);
+
+ return GDK_GL_PIXMAP_IMPL_X11 (gldrawable)->glconfig;
+}
+
+/**
+ * gdk_x11_gl_pixmap_get_glxpixmap:
+ * @glpixmap: a #GdkGLPixmap.
+ *
+ * Gets GLXPixmap.
+ *
+ * Return value: the GLXPixmap.
+ **/
+GLXPixmap
+gdk_x11_gl_pixmap_get_glxpixmap (GdkGLPixmap *glpixmap)
+{
+ g_return_val_if_fail (GDK_IS_GL_PIXMAP_IMPL_X11 (glpixmap), None);
+
+ return GDK_GL_PIXMAP_IMPL_X11 (glpixmap)->glxpixmap;
+}