/* scivi - visualization plugin for XMMS * Copyright (C) 2003 Vitaly V. Bursov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include "common.h" #include "glstuff.h" #ifndef GL_LIB_NAME #define GL_LIB_NAME "libGL.so.1" #endif #define DEF_EXT(e) int scivi_gl_has_##e = 0; DEF_EXT(GL_ARB_imaging) DEF_EXT(GL_SGIS_generate_mipmap) #undef DEF_EXT int scivi_check_gl_extensions() { const char *glext; #if 0 eprintf("Version: %s\n", sc_glGetString(GL_VERSION)); eprintf("Vendor: %s\n", sc_glGetString(GL_VENDOR)); eprintf("Extensions: %s\n", sc_glGetString(GL_EXTENSIONS)); #endif glext = sc_glGetString(GL_EXTENSIONS); if (glext){ #define CHECK_EXT(e) \ (scivi_gl_has_##e) = strstr(glext, #e) != 0 && \ (strstr(glext, #e)[strlen(#e)] == '\0' ||\ strstr(glext, #e)[strlen(#e)] == ' '); CHECK_EXT(GL_ARB_imaging) CHECK_EXT(GL_SGIS_generate_mipmap) #undef CHECK_EXT dprintf("GL_ARB_imaging: %d\n",GL_HAS(GL_ARB_imaging)); dprintf("GL_SGIS_generate_mipmap: %d\n",GL_HAS(GL_SGIS_generate_mipmap)); } else { scivi_gl_has_GL_ARB_imaging = 0; scivi_gl_has_GL_SGIS_generate_mipmap = 0; } return 0; } static void stub_func() { /* stub */ fprintf(stderr, "stub function called!\n"); fflush(stderr); } static void *dlhandle = NULL; static int load_gl_lib(const char *libname) { const char *soname = libname ? libname : GL_LIB_NAME; if (dlhandle) return 0; dlhandle = dlopen(soname, RTLD_NOW); if (dlhandle == NULL){ eprintf("Failed to load '%s' library.\n", libname); return 1; } sc_glXGetProcAddress = dlsym (dlhandle, "glXGetProcAddressARB"); return 0; } static void unload_gl_lib() { if (dlhandle){ dlclose(dlhandle); dlhandle = NULL; } } static void *dl_load_gl_func(const char *name) { return dlsym(dlhandle, name); } static int load_gl_funcs(const int dontload) { int failed = 0; void (*(*getaddr)(const char *procname))(void); #define GET(_fatal_, _n_)\ if (!dontload){\ sc_##_n_ = (void *)getaddr(#_n_); \ if ((sc_##_n_) == NULL) { \ sc_##_n_ = (void *)stub_func; \ eprintf("failed to get address of '%s'\n", #_n_);\ if ((_fatal_)) failed++;\ }\ /* eprintf("func %s @ %p\n", #_n_, sc_##_n_);*/ \ } else \ sc_##_n_ = (void *)stub_func; getaddr = sc_glXGetProcAddress ? ((void*)sc_glXGetProcAddress) : ((void*)dl_load_gl_func); GET(1, glMatrixMode); GET(1, glLoadIdentity); GET(1, glOrtho); GET(1, glPushMatrix); GET(1, glPopMatrix); GET(1, glLightModelfv); GET(1, glTexEnvi); GET(1, glBlendFunc); GET(1, glViewport); GET(1, glClearColor); GET(1, glTexParameteri); GET(1, glScalef); GET(1, glRotatef); GET(1, glTranslatef); GET(1, glLineWidth); GET(1, glPointSize); GET(1, glBegin); GET(1, glTexCoord2f); GET(1, glMaterialfv); GET(1, glVertex2f); GET(1, glEnd); GET(1, glPushAttrib); GET(1, glPopAttrib); GET(1, glNewList); GET(1, glCallList); GET(1, glEndList); GET(1, glBindTexture); GET(1, glEnable); GET(1, glDisable); GET(1, glBlendEquation); GET(1, glClear); GET(1, glCopyTexImage2D); GET(1, glDeleteTextures); GET(1, glGenTextures); GET(1, glGenLists); GET(1, glDeleteLists); GET(1, glFlush); GET(1, glGetString); GET(1, glGetError); /* GLX 1.2 functions */ GET(1, glXSwapBuffers); GET(1, glXChooseVisual); GET(1, glXCreateContext); GET(1, glXMakeCurrent); GET(1, glXQueryExtension); GET(1, glXQueryVersion); GET(1, glXDestroyContext); GET(1, glXIsDirect); GET(1, glXCreateGLXPixmap); /* GLX 1.3 functions*/ GET(0, glXGetFBConfigs); GET(0, glXChooseFBConfig); GET(0, glXGetFBConfigAttrib); GET(0, glXGetVisualFromFBConfig); GET(0, glXCreateWindow); GET(0, glXDestroyWindow); GET(0, glXCreatePixmap); GET(0, glXDestroyPixmap); GET(0, glXCreatePbuffer); GET(0, glXDestroyPbuffer); GET(0, glXQueryDrawable); GET(0, glXCreateNewContext); GET(0, glXMakeContextCurrent); GET(0, glXGetCurrentReadDrawable); GET(0, glXGetCurrentDisplay); GET(0, glXQueryContext); GET(0, glXSelectEvent); GET(0, glXGetSelectedEvent); /* GLX extensions */ GET(0, glXGetVideoSyncSGI); GET(0, glXWaitVideoSyncSGI); #undef GET return failed; } int scivi_initialize_gl_funcs(const char *libglso) { if (load_gl_lib(libglso)){ load_gl_funcs(1); return -1; } if (load_gl_funcs(0)){ return 1; } return 0; } void scivi_finalize_gl_funcs() { unload_gl_lib(); }