Alexandre Julliard : opengl32: Dynamically load libGLU.
Alexandre Julliard
julliard at winehq.org
Thu May 1 13:36:16 CDT 2008
Module: wine
Branch: master
Commit: 06640efa613fc4e707614eaca6facc7fb26c5f4a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=06640efa613fc4e707614eaca6facc7fb26c5f4a
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu May 1 14:44:49 2008 +0200
opengl32: Dynamically load libGLU.
Based on a patch by Roderick Colenbrander.
---
configure | 3 +-
configure.ac | 3 +-
dlls/glu32/Makefile.in | 2 +-
dlls/opengl32/wgl.c | 84 ++++++++++++++++++++++++++++++++++++++++--------
4 files changed, 73 insertions(+), 19 deletions(-)
diff --git a/configure b/configure
index b732efd..0ee0b8c 100755
--- a/configure
+++ b/configure
@@ -11173,8 +11173,7 @@ cat >>confdefs.h <<_ACEOF
#define SONAME_LIBGLU "$ac_cv_lib_soname_GLU"
_ACEOF
- OPENGL_LIBS="$OPENGL_LIBS -lGLU"
- GLU32FILES='$(GLU32FILES)'
+ GLU32FILES='$(GLU32FILES)'
fi
fi
diff --git a/configure.ac b/configure.ac
index 946fa94..33562e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -746,8 +746,7 @@ This probably prevents linking to OpenGL. Try deleting the file and restarting c
$X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS)
if test "$ac_cv_header_GL_glu_h" = "yes"
then
- WINE_CHECK_SONAME(GLU,gluLookAt,[OPENGL_LIBS="$OPENGL_LIBS -lGLU"
- GLU32FILES='$(GLU32FILES)'],,
+ WINE_CHECK_SONAME(GLU,gluLookAt,[GLU32FILES='$(GLU32FILES)'],,
[$OPENGL_LIBS $X_LIBS $X_PRE_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS])
fi
WINE_NOTICE_WITH(glu,[test "x$ac_cv_lib_soname_GLU" = "x"],
diff --git a/dlls/glu32/Makefile.in b/dlls/glu32/Makefile.in
index 98d15e8..2fdbd99 100644
--- a/dlls/glu32/Makefile.in
+++ b/dlls/glu32/Makefile.in
@@ -6,7 +6,7 @@ MODULE = glu32.dll
IMPORTLIB = glu32
IMPORTS = kernel32
EXTRAINCL = @X_CFLAGS@
-EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
+EXTRALIBS = -lGLU @OPENGL_LIBS@ @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
C_SRCS = \
glu.c
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index 2e3d118..6fbdeb4 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;
@@ -315,6 +329,42 @@ BOOL WINAPI wglSwapLayerBuffers(HDC hdc,
#ifdef SONAME_LIBGLU
+static void *load_libglu(void)
+{
+ static int already_loaded;
+ void *handle;
+
+ if (already_loaded) return libglu_handle;
+ already_loaded = 1;
+
+ TRACE("Trying to load GLU library: %s\n", SONAME_LIBGLU);
+ handle = wine_dlopen(SONAME_LIBGLU, RTLD_NOW, NULL, 0);
+ if (!handle)
+ {
+ WARN("Failed to load %s\n", SONAME_LIBGLU);
+ return NULL;
+ }
+
+#define LOAD_FUNCPTR(f) if((p##f = (void*)wine_dlsym(handle, #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
+ libglu_handle = handle;
+ return handle;
+
+sym_not_found:
+ WARN("Unable to load function ptrs from libGLU\n");
+ /* Close the library as we won't use it */
+ wine_dlclose(handle, NULL, 0);
+ return NULL;
+}
+
static void fixed_to_double(POINTFX fixed, UINT em_size, GLdouble vertex[3])
{
vertex[0] = (fixed.x.value + (GLdouble)fixed.x.fract / (1 << 16)) / em_size;
@@ -365,14 +415,19 @@ 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 (!load_libglu())
+ {
+ 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();
@@ -430,17 +485,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));
@@ -454,7 +509,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;
@@ -467,28 +522,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();
@@ -498,7 +553,7 @@ error_in_list:
error:
DeleteObject(SelectObject(hdc, old_font));
- gluDeleteTess(tess);
+ pgluDeleteTess(tess);
return TRUE;
}
@@ -676,6 +731,7 @@ static BOOL process_attach(void)
static void process_detach(void)
{
+ if (libglu_handle) wine_dlclose(libglu_handle, NULL, 0);
HeapFree(GetProcessHeap(), 0, internal_gl_extensions);
HeapFree(GetProcessHeap(), 0, internal_gl_disabled_extensions);
}
More information about the wine-cvs
mailing list