[PATCH] Dynamicly load libGLU at runtime. This also fixes bug 12494.

Roderick Colenbrander thunderbird2k at gmx.net
Wed Apr 30 13:57:20 CDT 2008


---
 configure.ac        |   21 ++++------
 dlls/opengl32/wgl.c |  109 +++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 101 insertions(+), 29 deletions(-)

diff --git a/configure.ac b/configure.ac
index e38f5e7..f2bb61c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -743,18 +743,15 @@ This probably prevents linking to OpenGL. Try deleting the file and restarting c
 				    $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS -dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib)],
 			     $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS)
 
-	        dnl Check for GLU32 library.
-		AC_CHECK_LIB(GLU,gluLookAt,
-			     [OPENGL_LIBS="$OPENGL_LIBS -lGLU"
-			     GLU32FILES='$(GLU32FILES)']
-			     ,,
-			     $OPENGL_LIBS $X_LIBS $X_PRE_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS)
-             else
-                 opengl_msg="Old Mesa headers detected. Consider upgrading your Mesa libraries."
-	     fi
-         else
-             opengl_msg="OpenGL development headers not found."
-	 fi
+                dnl Check for GLU32 library.
+                WINE_CHECK_SONAME(GLU,gluLookAt)
+                WINE_NOTICE_WITH(glu,[test "x$ac_cv_lib_soname_GLU" = "x"], [libGLU not found, opengl32 will be incomplete but functional for most programs])
+            else
+                opengl_msg="Old Mesa headers detected. Consider upgrading your Mesa libraries."
+            fi
+        else
+            opengl_msg="OpenGL development headers not found."
+        fi
     fi
     WINE_WARNING_WITH(opengl,[test -n "$opengl_msg"],[$opengl_msg
 OpenGL and Direct3D won't be supported.])
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index df15b5b..d9f7afc 100644
--- a/dlls/opengl32/wgl.c
+++ b/dlls/opengl32/wgl.c
@@ -56,6 +56,19 @@ typedef struct wine_wgl_s {
 /** global wgl object */
 static wine_wgl_t wine_wgl;
 
+#ifdef SONAME_LIBGLU
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f;
+MAKE_FUNCPTR(gluNewTess)
+MAKE_FUNCPTR(gluDeleteTess)
+MAKE_FUNCPTR(gluTessBeginContour)
+MAKE_FUNCPTR(gluTessBeginPolygon)
+MAKE_FUNCPTR(gluTessCallback)
+MAKE_FUNCPTR(gluTessEndContour)
+MAKE_FUNCPTR(gluTessEndPolygon)
+MAKE_FUNCPTR(gluTessVertex)
+#undef MAKE_FUNCPTR
+#endif /* SONAME_LIBGLU */
+
 /* x11drv GDI escapes */
 #define X11DRV_ESCAPE 6789
 enum x11drv_escape_codes
@@ -76,6 +89,7 @@ void (*wine_tsx11_lock_ptr)(void) = NULL;
 void (*wine_tsx11_unlock_ptr)(void) = NULL;
 
 static HMODULE opengl32_handle;
+static void* libglu_handle = NULL;
 
 static char* internal_gl_disabled_extensions = NULL;
 static char* internal_gl_extensions = NULL;
@@ -316,7 +330,7 @@ BOOL WINAPI wglSwapLayerBuffers(HDC hdc,
   return TRUE;
 }
 
-#ifdef HAVE_GL_GLU_H
+#ifdef SONAME_LIBGLU
 
 static void fixed_to_double(POINTFX fixed, UINT em_size, GLdouble vertex[3])
 {
@@ -368,14 +382,20 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc,
     TRACE("(%p, %d, %d, %d, %f, %f, %d, %p, %s)\n", hdc, first, count,
           listBase, deviation, extrusion, format, lpgmf, unicode ? "W" : "A");
 
+    if(!libglu_handle)
+    {
+        ERR("libGLU is required for this function but isn't loaded\n");
+        return FALSE;
+    }
+
 
     ENTER_GL();
-    tess = gluNewTess();
+    tess = pgluNewTess();
     if(tess)
     {
-        gluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)tess_callback_vertex);
-        gluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)tess_callback_begin);
-        gluTessCallback(tess, GLU_TESS_END, tess_callback_end);
+        pgluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)tess_callback_vertex);
+        pgluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)tess_callback_begin);
+        pgluTessCallback(tess, GLU_TESS_END, tess_callback_end);
     }
     LEAVE_GL();
 
@@ -433,17 +453,17 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc,
 
 	ENTER_GL();
 	glNewList(listBase++, GL_COMPILE);
-        gluTessBeginPolygon(tess, NULL);
+        pgluTessBeginPolygon(tess, NULL);
 
         pph = (TTPOLYGONHEADER*)buf;
         while((BYTE*)pph < buf + needed)
         {
             TRACE("\tstart %d, %d\n", pph->pfxStart.x.value, pph->pfxStart.y.value);
 
-            gluTessBeginContour(tess);
+            pgluTessBeginContour(tess);
 
             fixed_to_double(pph->pfxStart, em_size, vertices);
-            gluTessVertex(tess, vertices, vertices);
+            pgluTessVertex(tess, vertices, vertices);
             vertices += 3;
 
             ppc = (TTPOLYCURVE*)((char*)pph + sizeof(*pph));
@@ -457,7 +477,7 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc,
                     {
                         TRACE("\t\tline to %d, %d\n", ppc->apfx[i].x.value, ppc->apfx[i].y.value);
                         fixed_to_double(ppc->apfx[i], em_size, vertices); 
-                        gluTessVertex(tess, vertices, vertices);
+                        pgluTessVertex(tess, vertices, vertices);
                         vertices += 3;
                     }
                     break;
@@ -470,28 +490,28 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc,
                               ppc->apfx[i * 2].x.value,     ppc->apfx[i * 3].y.value,
                               ppc->apfx[i * 2 + 1].x.value, ppc->apfx[i * 3 + 1].y.value);
                         fixed_to_double(ppc->apfx[i * 2], em_size, vertices); 
-                        gluTessVertex(tess, vertices, vertices);
+                        pgluTessVertex(tess, vertices, vertices);
                         vertices += 3;
                         fixed_to_double(ppc->apfx[i * 2 + 1], em_size, vertices); 
-                        gluTessVertex(tess, vertices, vertices);
+                        pgluTessVertex(tess, vertices, vertices);
                         vertices += 3;
                     }
                     break;
                 default:
                     ERR("\t\tcurve type = %d\n", ppc->wType);
-                    gluTessEndContour(tess);
+                    pgluTessEndContour(tess);
                     goto error_in_list;
                 }
 
                 ppc = (TTPOLYCURVE*)((char*)ppc + sizeof(*ppc) +
                                      (ppc->cpfx - 1) * sizeof(POINTFX));
             }
-            gluTessEndContour(tess);
+            pgluTessEndContour(tess);
             pph = (TTPOLYGONHEADER*)((char*)pph + pph->cb);
         }
 
 error_in_list:
-        gluTessEndPolygon(tess);
+        pgluTessEndPolygon(tess);
         glTranslated((GLdouble)gm.gmCellIncX / em_size, (GLdouble)gm.gmCellIncY / em_size, 0.0);
         glEndList();
         LEAVE_GL();
@@ -501,12 +521,12 @@ error_in_list:
 
  error:
     DeleteObject(SelectObject(hdc, old_font));
-    gluDeleteTess(tess);
+    pgluDeleteTess(tess);
     return TRUE;
 
 }
 
-#else /* HAVE_GL_GLU_H */
+#else /* SONAME_LIBGLU */
 
 static BOOL WINAPI wglUseFontOutlines_common(HDC hdc,
                                       DWORD first,
@@ -522,7 +542,7 @@ static BOOL WINAPI wglUseFontOutlines_common(HDC hdc,
     return FALSE;
 }
 
-#endif /* HAVE_GL_GLU_H */
+#endif /* SONAME_LIBGLU */
 
 /***********************************************************************
  *		wglUseFontOutlinesA (OPENGL32.@)
@@ -633,6 +653,44 @@ void WINAPI wine_glGetIntegerv( GLenum pname, GLint* params )
     wine_wgl.p_wglGetIntegerv(pname, params);
 }
 
+#ifdef SONAME_LIBGLU
+static int load_libglu()
+{
+    int res = 0;
+
+    TRACE("Trying to load GLU library: %s\n", SONAME_LIBGLU);
+    libglu_handle = wine_dlopen(SONAME_LIBGLU, RTLD_NOW, NULL, 0);
+    if(!libglu_handle)
+    {
+        WARN("Unable to load %s opengl32 will be incomplete but functional for most programs\n", SONAME_LIBGLU);
+        return 0;
+    }
+
+#define LOAD_FUNCPTR(f) if((p##f = (void*)wine_dlsym(libglu_handle, ((const char*)#f), NULL, 0)) == NULL) goto sym_not_found;
+LOAD_FUNCPTR(gluNewTess)
+LOAD_FUNCPTR(gluDeleteTess)
+LOAD_FUNCPTR(gluTessBeginContour)
+LOAD_FUNCPTR(gluTessBeginPolygon)
+LOAD_FUNCPTR(gluTessCallback)
+LOAD_FUNCPTR(gluTessEndContour)
+LOAD_FUNCPTR(gluTessEndPolygon)
+LOAD_FUNCPTR(gluTessVertex)
+#undef LOAD_FUNCPTR
+
+    res = 1;
+
+sym_not_found:
+    if (!res)
+    {
+        WARN("Unable to load function ptrs from libGLU library, opengl32 will be incomplete but functional for most programs\n");
+
+        /* Close the library as we won't use it */
+        wine_dlclose(libglu_handle, NULL, 0);
+        libglu_handle = NULL;
+    }
+    return res;
+}
+#endif /* SONAME_LIBGLU */
 
 /* This is for brain-dead applications that use OpenGL functions before even
    creating a rendering context.... */
@@ -662,6 +720,16 @@ static BOOL process_attach(void)
   wine_wgl.p_wglFinish = (void *)wine_wgl.p_wglGetProcAddress("wglFinish");
   wine_wgl.p_wglFlush = (void *)wine_wgl.p_wglGetProcAddress("wglFlush");
 
+  /* Load libGLU */
+#ifdef SONAME_LIBGLU
+  if(!libglu_handle)
+  {
+      load_libglu();
+  }
+#else
+  WARN("OpenGL32.dll is incomplete because libGLU support wasn't compiled in\n");
+#endif /* SONAME_LIBGLU */
+
   if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\OpenGL", &hkey)) {
     if (!RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, NULL, &size)) {
       internal_gl_disabled_extensions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
@@ -679,6 +747,13 @@ static BOOL process_attach(void)
 
 static void process_detach(void)
 {
+  if(libglu_handle && (libglu_handle != (void*)-1))
+  {
+      TRACE("calling wine_dlclose() on libglu_handle\n");
+      wine_dlclose(libglu_handle, NULL, 0);
+      libglu_handle = NULL;
+  }
+
   HeapFree(GetProcessHeap(), 0, internal_gl_extensions);
   HeapFree(GetProcessHeap(), 0, internal_gl_disabled_extensions);
 }
-- 
1.5.3.4


--========GMX284061209574573442665--



More information about the wine-patches mailing list