diff options
Diffstat (limited to 'plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglquery-x11.c')
-rw-r--r-- | plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglquery-x11.c | 503 |
1 files changed, 503 insertions, 0 deletions
diff --git a/plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglquery-x11.c b/plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglquery-x11.c new file mode 100644 index 00000000..562ddf1f --- /dev/null +++ b/plugins/gtkui/gtkglext-gtk2/gdk/x11/gdkglquery-x11.c @@ -0,0 +1,503 @@ +/* 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> + +#ifdef __APPLE__ +#include <mach-o/dyld.h> +#else /* __APPLE__ */ +#include <gmodule.h> +#endif /* __APPLE__ */ + +#include "gdkglx.h" +#include "gdkglprivate-x11.h" +#include "gdkglconfig-x11.h" +#include "gdkglquery.h" + +#ifdef GDKGLEXT_MULTIHEAD_SUPPORT +#include <gdk/gdkdisplay.h> +#endif /* GDKGLEXT_MULTIHEAD_SUPPORT */ + +/** + * gdk_gl_query_extension: + * + * Indicates whether the window system supports the OpenGL extension + * (GLX, WGL, etc.). + * + * Return value: TRUE if OpenGL is supported, FALSE otherwise. + **/ +gboolean +gdk_gl_query_extension (void) +{ +#ifdef GDKGLEXT_MULTIHEAD_SUPPORT + return glXQueryExtension (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + NULL, NULL); +#else /* GDKGLEXT_MULTIHEAD_SUPPORT */ + return glXQueryExtension (gdk_x11_get_default_xdisplay (), + NULL, NULL); +#endif /* GDKGLEXT_MULTIHEAD_SUPPORT */ +} + +#ifdef GDKGLEXT_MULTIHEAD_SUPPORT + +/** + * gdk_gl_query_extension_for_display: + * @display: the #GdkDisplay where the query is sent to. + * + * Indicates whether the window system supports the OpenGL extension + * (GLX, WGL, etc.). + * + * Return value: TRUE if OpenGL is supported, FALSE otherwise. + **/ +gboolean +gdk_gl_query_extension_for_display (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + return glXQueryExtension (GDK_DISPLAY_XDISPLAY (display), + NULL, NULL); +} + +#endif /* GDKGLEXT_MULTIHEAD_SUPPORT */ + +/** + * gdk_gl_query_version: + * @major: returns the major version number of the OpenGL extension. + * @minor: returns the minor version number of the OpenGL extension. + * + * Returns the version numbers of the OpenGL extension to the window system. + * + * In the X Window System, it returns the GLX version. + * + * In the Microsoft Windows, it returns the Windows version. + * + * Return value: FALSE if it fails, TRUE otherwise. + **/ +gboolean +gdk_gl_query_version (int *major, + int *minor) +{ +#ifdef GDKGLEXT_MULTIHEAD_SUPPORT + return glXQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + major, minor); +#else /* GDKGLEXT_MULTIHEAD_SUPPORT */ + return glXQueryVersion (gdk_x11_get_default_xdisplay (), + major, minor); +#endif /* GDKGLEXT_MULTIHEAD_SUPPORT */ +} + +#ifdef GDKGLEXT_MULTIHEAD_SUPPORT + +/** + * gdk_gl_query_version_for_display: + * @display: the #GdkDisplay where the query is sent to. + * @major: returns the major version number of the OpenGL extension. + * @minor: returns the minor version number of the OpenGL extension. + * + * Returns the version numbers of the OpenGL extension to the window system. + * + * In the X Window System, it returns the GLX version. + * + * In the Microsoft Windows, it returns the Windows version. + * + * Return value: FALSE if it fails, TRUE otherwise. + **/ +gboolean +gdk_gl_query_version_for_display (GdkDisplay *display, + int *major, + int *minor) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + return glXQueryVersion (GDK_DISPLAY_XDISPLAY (display), + major, minor); +} + +#endif /* GDKGLEXT_MULTIHEAD_SUPPORT */ + +/* + * This code is based on __glutIsSupportedByGLX(). + */ + +/** + * gdk_x11_gl_query_glx_extension: + * @glconfig: a #GdkGLConfig. + * @extension: name of GLX extension. + * + * Determines whether a given GLX extension is supported. + * + * Return value: TRUE if the GLX extension is supported, FALSE if not + * supported. + **/ +gboolean +gdk_x11_gl_query_glx_extension (GdkGLConfig *glconfig, + const char *extension) +{ + static const char *extensions = NULL; + const char *start; + char *where, *terminator; + int major, minor; + + g_return_val_if_fail (GDK_IS_GL_CONFIG_IMPL_X11 (glconfig), FALSE); + + /* Extension names should not have spaces. */ + where = strchr (extension, ' '); + if (where || *extension == '\0') + return FALSE; + + if (extensions == NULL) + { + /* Be careful not to call glXQueryExtensionsString if it + looks like the server doesn't support GLX 1.1. + Unfortunately, the original GLX 1.0 didn't have the notion + of GLX extensions. */ + + glXQueryVersion (GDK_GL_CONFIG_XDISPLAY (glconfig), + &major, &minor); + + if ((major == 1 && minor < 1) || (major < 1)) + return FALSE; + + extensions = glXQueryExtensionsString (GDK_GL_CONFIG_XDISPLAY (glconfig), + GDK_GL_CONFIG_SCREEN_XNUMBER (glconfig)); + } + + /* It takes a bit of care to be fool-proof about parsing + the GLX extensions string. Don't be fooled by + sub-strings, etc. */ + start = extensions; + for (;;) + { + where = strstr (start, extension); + if (where == NULL) + break; + + terminator = where + strlen (extension); + + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') + { + GDK_GL_NOTE (MISC, g_message (" - %s - supported", extension)); + return TRUE; + } + + start = terminator; + } + + GDK_GL_NOTE (MISC, g_message (" - %s - not supported", extension)); + + return FALSE; +} + +/** + * gdk_gl_get_proc_address: + * @proc_name: function name. + * + * Returns the address of the OpenGL, GLU, or GLX function. + * + * Return value: the address of the function named by @proc_name. + **/ + +#ifdef __APPLE__ + +#define _GDK_GL_LIBGL_PATH "/usr/X11R6/lib/libGL.1.dylib" +#define _GDK_GL_LIBGLU_PATH "/usr/X11R6/lib/libGLU.1.dylib" + +GdkGLProc +gdk_gl_get_proc_address (const char *proc_name) +{ + typedef GdkGLProc (*__glXGetProcAddressProc) (const GLubyte *); + static __glXGetProcAddressProc glx_get_proc_address = (__glXGetProcAddressProc) -1; + const char *image_name; + static const struct mach_header *libgl_image = NULL; + static const struct mach_header *libglu_image = NULL; + NSSymbol symbol; + char *symbol_name; + GdkGLProc proc_address; + + GDK_GL_NOTE_FUNC (); + + if (strncmp ("glu", proc_name, 3) != 0) + { + /* libGL */ + + if (libgl_image == NULL) + { + image_name = g_getenv ("GDK_GL_LIBGL_PATH"); + if (image_name == NULL) + image_name = _GDK_GL_LIBGL_PATH; + + GDK_GL_NOTE (MISC, g_message (" - Add Mach-O image %s", image_name)); + + libgl_image = NSAddImage (image_name, NSADDIMAGE_OPTION_RETURN_ON_ERROR); + if (libgl_image == NULL) + { + g_warning ("Cannot add Mach-O image %s", image_name); + return NULL; + } + } + + if (glx_get_proc_address == (__glXGetProcAddressProc) -1) + { + /* + * Look up glXGetProcAddress () function. + */ + + symbol = NSLookupSymbolInImage (libgl_image, + "_glXGetProcAddress", + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + if (symbol == NULL) + { + symbol = NSLookupSymbolInImage (libgl_image, + "_glXGetProcAddressARB", + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + if (symbol == NULL) + { + symbol = NSLookupSymbolInImage (libgl_image, + "_glXGetProcAddressEXT", + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + } + } + GDK_GL_NOTE (MISC, g_message (" - glXGetProcAddress () - %s", + symbol ? "supported" : "not supported")); + if (symbol != NULL) + glx_get_proc_address = NSAddressOfSymbol (symbol); + else + glx_get_proc_address = NULL; + } + + /* Try glXGetProcAddress () */ + + if (glx_get_proc_address != NULL) + { + proc_address = glx_get_proc_address (proc_name); + GDK_GL_NOTE (IMPL, g_message (" ** glXGetProcAddress () - %s", + proc_address ? "succeeded" : "failed")); + if (proc_address != NULL) + return proc_address; + } + + /* Try Mach-O dyld */ + + symbol_name = g_strconcat ("_", proc_name, NULL); + + symbol = NSLookupSymbolInImage (libgl_image, + symbol_name, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + GDK_GL_NOTE (MISC, g_message (" - NSLookupSymbolInImage () - %s", + symbol ? "succeeded" : "failed")); + + g_free (symbol_name); + + if (symbol != NULL) + return NSAddressOfSymbol (symbol); + } + else + { + /* libGLU */ + + if (libglu_image == NULL) + { + image_name = g_getenv ("GDK_GL_LIBGLU_PATH"); + if (image_name == NULL) + image_name = _GDK_GL_LIBGLU_PATH; + + GDK_GL_NOTE (MISC, g_message (" - Add Mach-O image %s", image_name)); + + libglu_image = NSAddImage (image_name, NSADDIMAGE_OPTION_RETURN_ON_ERROR); + if (libglu_image == NULL) + { + g_warning ("Cannot add Mach-O image %s", image_name); + return NULL; + } + } + + symbol_name = g_strconcat ("_", proc_name, NULL); + + symbol = NSLookupSymbolInImage (libglu_image, + symbol_name, + NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | + NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); + GDK_GL_NOTE (MISC, g_message (" - NSLookupSymbolInImage () - %s", + symbol ? "succeeded" : "failed")); + + g_free (symbol_name); + + if (symbol != NULL) + return NSAddressOfSymbol (symbol); + } + + return NULL; +} + +#else /* __APPLE__ */ + +GdkGLProc +gdk_gl_get_proc_address (const char *proc_name) +{ + typedef GdkGLProc (*__glXGetProcAddressProc) (const GLubyte *); + static __glXGetProcAddressProc glx_get_proc_address = (__glXGetProcAddressProc) -1; + gchar *file_name; + GModule *module; + GdkGLProc proc_address = NULL; + + GDK_GL_NOTE_FUNC (); + + if (strncmp ("glu", proc_name, 3) != 0) + { + if (glx_get_proc_address == (__glXGetProcAddressProc) -1) + { + /* + * Look up glXGetProcAddress () function. + */ + + file_name = g_module_build_path (NULL, "GL"); + GDK_GL_NOTE (MISC, g_message (" - Open %s", file_name)); + module = g_module_open (file_name, G_MODULE_BIND_LAZY); + g_free (file_name); + + if (module != NULL) + { + g_module_symbol (module, "glXGetProcAddress", + (gpointer) &glx_get_proc_address); + if (glx_get_proc_address == NULL) + { + g_module_symbol (module, "glXGetProcAddressARB", + (gpointer) &glx_get_proc_address); + if (glx_get_proc_address == NULL) + { + g_module_symbol (module, "glXGetProcAddressEXT", + (gpointer) &glx_get_proc_address); + } + } + GDK_GL_NOTE (MISC, g_message (" - glXGetProcAddress () - %s", + glx_get_proc_address ? "supported" : "not supported")); + g_module_close (module); + } + else + { + g_warning ("Cannot open %s", file_name); + glx_get_proc_address = NULL; + return NULL; + } + } + + /* Try glXGetProcAddress () */ + + if (glx_get_proc_address != NULL) + { + proc_address = glx_get_proc_address (proc_name); + GDK_GL_NOTE (IMPL, g_message (" ** glXGetProcAddress () - %s", + proc_address ? "succeeded" : "failed")); + if (proc_address != NULL) + return proc_address; + } + + /* Try g_module_symbol () */ + + /* libGL */ + file_name = g_module_build_path (NULL, "GL"); + GDK_GL_NOTE (MISC, g_message (" - Open %s", file_name)); + module = g_module_open (file_name, G_MODULE_BIND_LAZY); + g_free (file_name); + + if (module != NULL) + { + g_module_symbol (module, proc_name, (gpointer) &proc_address); + GDK_GL_NOTE (MISC, g_message (" - g_module_symbol () - %s", + proc_address ? "succeeded" : "failed")); + g_module_close (module); + } + else + { + g_warning ("Cannot open %s", file_name); + } + + if (proc_address == NULL) + { + /* libGLcore */ + file_name = g_module_build_path (NULL, "GLcore"); + GDK_GL_NOTE (MISC, g_message (" - Open %s", file_name)); + module = g_module_open (file_name, G_MODULE_BIND_LAZY); + g_free (file_name); + + if (module != NULL) + { + g_module_symbol (module, proc_name, (gpointer) &proc_address); + GDK_GL_NOTE (MISC, g_message (" - g_module_symbol () - %s", + proc_address ? "succeeded" : "failed")); + g_module_close (module); + } + } + } + else + { + /* libGLU */ + file_name = g_module_build_path (NULL, "GLU"); + GDK_GL_NOTE (MISC, g_message (" - Open %s", file_name)); + module = g_module_open (file_name, G_MODULE_BIND_LAZY); + g_free (file_name); + + if (module != NULL) + { + g_module_symbol (module, proc_name, (gpointer) &proc_address); + GDK_GL_NOTE (MISC, g_message (" - g_module_symbol () - %s", + proc_address ? "succeeded" : "failed")); + g_module_close (module); + } + else + { + g_warning ("Cannot open %s", file_name); + } + } + + return proc_address; +} + +#endif /* __APPLE__ */ + +/*< private >*/ +void +_gdk_x11_gl_print_glx_info (Display *xdisplay, + int screen_num) +{ + static gboolean done = FALSE; + + if (!done) + { + g_message (" -- Server GLX_VENDOR : %s", + glXQueryServerString (xdisplay, screen_num, GLX_VENDOR)); + g_message (" -- Server GLX_VERSION : %s", + glXQueryServerString (xdisplay, screen_num, GLX_VERSION)); + g_message (" -- Server GLX_EXTENSIONS : %s", + glXQueryServerString (xdisplay, screen_num, GLX_EXTENSIONS)); + + g_message (" -- Client GLX_VENDOR : %s", + glXGetClientString (xdisplay, GLX_VENDOR)); + g_message (" -- Client GLX_VERSION : %s", + glXGetClientString (xdisplay, GLX_VERSION)); + g_message (" -- Client GLX_EXTENSIONS : %s", + glXGetClientString (xdisplay, GLX_EXTENSIONS)); + + done = TRUE; + } +} |