Hi all, This is Mike's patch tested on my box and a bit reworked (basically, to prevent having the list of GL API calls defined 4 times, I added a gl_api.h header file). As C's preprocessor is single-pass, the list is still here twice (but it's better than four times :-) ). It's also up-to-date with my latest work (ie I had to add about 7 API function calls). It also prints nicer error messages :-) (ie no need to have users panic if GL is not loaded properly as long as D3D is not required) Notes for packagers : I think now you can build with OpenGL activated but remove the dependency on OpenGL at package-creation time. This would have a single Wine version that works well whatever the configuration (as the only DLLs linking GL directly are anyway totally non-functionnal without any GL support : GL, GLU and D3D8). Lionel Changelog : Mike McCormack <mike@codeweavers.com> Lionel Ulmer <lionel.ulmer@free.fr> - make DDraw not linked 'statically' to OpenGL - some warning fixes -- Lionel Ulmer - http://www.bbrox.org/
--- dlls/ddraw_CVS/Makefile.in Sat Nov 23 20:45:28 2002 +++ dlls/ddraw/Makefile.in Thu May 22 23:14:31 2003 @@ -5,7 +5,7 @@ MODULE = ddraw.dll IMPORTS = user32 gdi32 kernel32 EXTRAINCL = @X_CFLAGS@ -EXTRALIBS = $(LIBUUID) @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@ +EXTRALIBS = $(LIBUUID) @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o --- dlls/ddraw_CVS/d3ddevice/mesa.c Thu May 22 00:32:08 2003 +++ dlls/ddraw/d3ddevice/mesa.c Thu May 22 23:24:16 2003 @@ -2511,9 +2511,10 @@ */ if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { if (This->palette) { - color |= ((This->palette->palents[lpbltfx->u5.dwFillColor].peRed << 16) | - (This->palette->palents[lpbltfx->u5.dwFillColor].peGreen << 8) | - (This->palette->palents[lpbltfx->u5.dwFillColor].peBlue)); + color = ((0xFF000000) | + (This->palette->palents[lpbltfx->u5.dwFillColor].peRed << 16) | + (This->palette->palents[lpbltfx->u5.dwFillColor].peGreen << 8) | + (This->palette->palents[lpbltfx->u5.dwFillColor].peBlue)); } else { color = 0xFF000000; } @@ -2538,8 +2539,13 @@ (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) { color = 0xFF000000 | lpbltfx->u5.dwFillColor; } + else { + ERR("Wrong surface type for BLT override !\n"); + return DDERR_INVALIDPARAMS; + } } else { ERR("Wrong surface type for BLT override !\n"); + return DDERR_INVALIDPARAMS; } TRACE(" executing D3D Device override.\n"); --- dlls/ddraw_CVS/ddraw/hal.c Thu Jan 30 22:07:23 2003 +++ dlls/ddraw/ddraw/hal.c Thu May 22 23:14:31 2003 @@ -138,11 +138,10 @@ dd_gbl.lpD3DHALCallbacks2 = (ULONG_PTR)&d3d_hal_cbs2; } -#ifdef HAVE_OPENGL - if (d3d_hal_data.hwCaps.dwFlags & D3DDD_WINE_OPENGL_DEVICE) { + if( opengl_initialized && + (d3d_hal_data.hwCaps.dwFlags & D3DDD_WINE_OPENGL_DEVICE) ) { /*GL_DirectDraw_Init(&dd_gbl);*/ } -#endif return FALSE; } --- dlls/ddraw_CVS/ddraw/main.c Fri May 16 09:51:47 2003 +++ dlls/ddraw/ddraw/main.c Fri May 23 20:27:09 2003 @@ -184,28 +184,44 @@ IsEqualGUID( &IID_IDirect3D3 , refiid ) || IsEqualGUID( &IID_IDirect3D7 , refiid ) ) { - IDirect3DImpl *d3d_impl; - HRESULT ret_value; + if (opengl_initialized) { + IDirect3DImpl *d3d_impl; + HRESULT ret_value; - ret_value = direct3d_create(&d3d_impl, This); - if (FAILED(ret_value)) return ret_value; + ret_value = direct3d_create(&d3d_impl, This); + if (FAILED(ret_value)) return ret_value; + + if ( IsEqualGUID( &IID_IDirect3D , refiid ) ) { + *obj = ICOM_INTERFACE(d3d_impl, IDirect3D); + TRACE(" returning Direct3D interface at %p.\n", *obj); + } else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) ) { + *obj = ICOM_INTERFACE(d3d_impl, IDirect3D2); + TRACE(" returning Direct3D2 interface at %p.\n", *obj); + } else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) ) { + *obj = ICOM_INTERFACE(d3d_impl, IDirect3D3); + TRACE(" returning Direct3D3 interface at %p.\n", *obj); + } else { + *obj = ICOM_INTERFACE(d3d_impl, IDirect3D7); + TRACE(" returning Direct3D7 interface at %p.\n", *obj); + } - if ( IsEqualGUID( &IID_IDirect3D , refiid ) ) { - *obj = ICOM_INTERFACE(d3d_impl, IDirect3D); - TRACE(" returning Direct3D interface at %p.\n", *obj); - } else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) ) { - *obj = ICOM_INTERFACE(d3d_impl, IDirect3D2); - TRACE(" returning Direct3D2 interface at %p.\n", *obj); - } else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) ) { - *obj = ICOM_INTERFACE(d3d_impl, IDirect3D3); - TRACE(" returning Direct3D3 interface at %p.\n", *obj); + /* And store the D3D object */ + This->d3d = d3d_impl; } else { - *obj = ICOM_INTERFACE(d3d_impl, IDirect3D7); - TRACE(" returning Direct3D7 interface at %p.\n", *obj); + ERR("Application requests a Direct3D interface but dynamic OpenGL support loading failed !\n"); + ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj); + return E_NOINTERFACE; } - - /* And store the D3D object */ - This->d3d = d3d_impl; + } +#else + else if ( IsEqualGUID( &IID_IDirect3D , refiid ) || + IsEqualGUID( &IID_IDirect3D2 , refiid ) || + IsEqualGUID( &IID_IDirect3D3 , refiid ) || + IsEqualGUID( &IID_IDirect3D7 , refiid ) ) + { + ERR("Application requests a Direct3D interface but OpenGL support not built-in !\n"); + ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj); + return E_NOINTERFACE; } #endif else --- dlls/ddraw_CVS/ddraw/user.c Sat Mar 15 21:47:04 2003 +++ dlls/ddraw/ddraw/user.c Thu May 22 23:14:31 2003 @@ -173,10 +173,11 @@ | DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN \ | DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN) This->caps.dwCaps |= DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS; -#ifdef HAVE_OPENGL - /* Hack for D3D code */ - This->caps.dwCaps |= DDCAPS_3D; -#endif /* HAVE_OPENGL */ + if( opengl_initialized ) + { + /* Hack for D3D code */ + This->caps.dwCaps |= DDCAPS_3D; + } This->caps.dwCaps2 |= DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_PRIMARYGAMMA | DDCAPS2_WIDESURFACES; This->caps.dwCKeyCaps |= CKEY_CAPS; @@ -198,10 +199,11 @@ DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE; -#ifdef HAVE_OPENGL - /* Hacks for D3D code */ - This->caps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER; -#endif /* HAVE_OPENGL */ + if( opengl_initialized ) + { + /* Hacks for D3D code */ + This->caps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER; + } This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps; #undef BLIT_CAPS --- dlls/ddraw_CVS/ddraw_private.h Wed May 21 22:42:08 2003 +++ dlls/ddraw/ddraw_private.h Thu May 22 23:14:31 2003 @@ -355,6 +355,7 @@ extern Convert ModeEmulations[8]; extern int _common_depth_to_pixelformat(DWORD depth,LPDIRECTDRAW ddraw); +extern BOOL opengl_initialized; /****************************************************************************** * Structure conversion (for thunks) --- dlls/ddraw_CVS/dsurface/main.c Wed May 21 22:42:09 2003 +++ dlls/ddraw/dsurface/main.c Thu May 22 23:14:31 2003 @@ -179,8 +179,12 @@ return S_OK; } #ifdef HAVE_OPENGL - else if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) || - IsEqualGUID( &IID_IDirect3DHALDevice, riid) ) + /* interfaces following here require OpenGL */ + if( !opengl_initialized ) + return E_NOINTERFACE; + + if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) || + IsEqualGUID( &IID_IDirect3DHALDevice, riid) ) { IDirect3DDeviceImpl *d3ddevimpl; HRESULT ret_value; @@ -220,7 +224,7 @@ } This->ref++; return ret_value; - } + } #endif return E_NOINTERFACE; --- dlls/ddraw_CVS/main.c Sat Mar 15 21:47:04 2003 +++ dlls/ddraw/main.c Fri May 23 20:31:06 2003 @@ -22,6 +22,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define GLPRIVATE_NO_REDEFINE + #include "config.h" #include <assert.h> @@ -37,6 +39,12 @@ /* This for all the enumeration and creation of D3D-related objects */ #include "ddraw_private.h" #include "wine/debug.h" +#include "wine/library.h" +#include "wine/port.h" + +#include "gl_private.h" + +#undef GLPRIVATE_NO_REDEFINE #define MAX_DDRAW_DRIVERS 3 static const ddraw_driver* DDRAW_drivers[MAX_DDRAW_DRIVERS]; @@ -55,6 +63,52 @@ LPVOID lpContext; } DirectDrawEnumerateProcData; +BOOL opengl_initialized = 0; + +#ifdef HAVE_OPENGL + +static void *gl_handle = NULL; + +#define GL_API_FUNCTION(f) typeof(f) * p##f; +#include "gl_api.h" +#undef GL_API_FUNCTION + +#ifndef SONAME_LIBGL +#define SONAME_LIBGL "libGL.so" +#endif + +static BOOL DDRAW_bind_to_opengl( void ) +{ + char *glname = SONAME_LIBGL; + + gl_handle = wine_dlopen(glname, RTLD_NOW, NULL, 0); + if (!gl_handle) { + WARN("Wine cannot find the OpenGL graphics library (%s).\n",glname); + return FALSE; + } + +#define GL_API_FUNCTION(f) \ + if((p##f = wine_dlsym(gl_handle, #f, NULL, 0)) == NULL) \ + { \ + WARN("Can't find symbol %s\n", #f); \ + goto sym_not_found; \ + } +#include "gl_api.h" +#undef GL_API_FUNCTION + + return TRUE; + +sym_not_found: + WARN("Wine cannot find certain functions that it needs inside the OpenGL\n" + "graphics library. To enable Wine to use OpenGL please upgrade\n" + "your OpenGL libraries\n"); + wine_dlclose(gl_handle, NULL, 0); + gl_handle = NULL; + return FALSE; +} + +#endif /* HAVE_OPENGL */ + /*********************************************************************** * DirectDrawEnumerateExA (DDRAW.@) */ @@ -531,6 +585,9 @@ wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" ); wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" ); } +#ifdef HAVE_OPENGL + opengl_initialized = DDRAW_bind_to_opengl(); +#endif /* HAVE_OPENGL */ } if (DDRAW_num_drivers > 0) --- dlls/ddraw_CVS/mesa_private.h Wed May 21 22:42:08 2003 +++ dlls/ddraw/mesa_private.h Thu May 22 23:14:31 2003 @@ -26,26 +26,7 @@ #ifdef HAVE_OPENGL -#undef APIENTRY -#undef CALLBACK -#undef WINAPI - -#define XMD_H /* This is to prevent the Xmd.h inclusion bug :-/ */ -#include <GL/gl.h> -#include <GL/glx.h> -#ifdef HAVE_GL_GLEXT_H -# include <GL/glext.h> -#endif -#undef XMD_H - -#undef APIENTRY -#undef CALLBACK -#undef WINAPI - -/* Redefines the constants */ -#define CALLBACK __stdcall -#define WINAPI __stdcall -#define APIENTRY WINAPI +#include "gl_private.h" /* X11 locking */ --- /dev/null Mon Jul 18 01:46:18 1994 +++ dlls/ddraw/gl_private.h Fri May 23 20:10:43 2003 @@ -0,0 +1,138 @@ +/* GL 'hack' private include file + * Copyright (c) 2003 Lionel Ulmer / Mike McCormack + * + * This file contains all structures that are not exported + * through d3d.h and all common macros. + * + * 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 + */ + +#ifndef __GRAPHICS_WINE_GL_PRIVATE_H +#define __GRAPHICS_WINE_GL_PRIVATE_H + +#ifdef HAVE_OPENGL + +#undef APIENTRY +#undef CALLBACK +#undef WINAPI + +#define XMD_H /* This is to prevent the Xmd.h inclusion bug :-/ */ +#include <GL/gl.h> +#include <GL/glx.h> +#ifdef HAVE_GL_GLEXT_H +# include <GL/glext.h> +#endif +#undef XMD_H + +#undef APIENTRY +#undef CALLBACK +#undef WINAPI + +/* Redefines the constants */ +#define CALLBACK __stdcall +#define WINAPI __stdcall +#define APIENTRY WINAPI + +#define GL_API_FUNCTION(f) extern typeof(f) * p##f; +#include "gl_api.h" +#undef GL_API_FUNCTION + +#ifndef GLPRIVATE_NO_REDEFINE + +#define glAlphaFunc pglAlphaFunc +#define glBegin pglBegin +#define glBindTexture pglBindTexture +#define glBlendFunc pglBlendFunc +#define glClear pglClear +#define glClearColor pglClearColor +#define glClearDepth pglClearDepth +#define glClearStencil pglClearStencil +#define glClipPlane pglClipPlane +#define glColor3f pglColor3f +#define glColor3ub pglColor3ub +#define glColor4ub pglColor4ub +#define glColorMaterial pglColorMaterial +#define glCullFace pglCullFace +#define glDeleteTextures pglDeleteTextures +#define glDepthFunc pglDepthFunc +#define glDepthMask pglDepthMask +#define glDepthRange pglDepthRange +#define glDisable pglDisable +#define glDrawBuffer pglDrawBuffer +#define glDrawPixels pglDrawPixels +#define glEnable pglEnable +#define glEnd pglEnd +#define glFlush pglFlush +#define glFogf pglFogf +#define glFogfv pglFogfv +#define glFogi pglFogi +#define glFrontFace pglFrontFace +#define glGenTextures pglGenTextures +#define glGetBooleanv pglGetBooleanv +#define glGetError pglGetError +#define glGetFloatv pglGetFloatv +#define glGetIntegerv pglGetIntegerv +#define glGetTexEnviv pglGetTexEnviv +#define glGetTexParameteriv pglGetTexParameteriv +#define glHint pglHint +#define glLightModelfv pglLightModelfv +#define glLightModeli pglLightModeli +#define glLightfv pglLightfv +#define glLoadIdentity pglLoadIdentity +#define glLoadMatrixf pglLoadMatrixf +#define glMaterialf pglMaterialf +#define glMaterialfv pglMaterialfv +#define glMatrixMode pglMatrixMode +#define glMultMatrixf pglMultMatrixf +#define glNormal3f pglNormal3f +#define glNormal3fv pglNormal3fv +#define glPixelStorei pglPixelStorei +#define glPolygonMode pglPolygonMode +#define glPolygonOffset pglPolygonOffset +#define glPopMatrix pglPopMatrix +#define glPushMatrix pglPushMatrix +#define glRasterPos2f pglRasterPos2f +#define glReadBuffer pglReadBuffer +#define glReadPixels pglReadPixels +#define glScissor pglScissor +#define glShadeModel pglShadeModel +#define glStencilFunc pglStencilFunc +#define glStencilMask pglStencilMask +#define glStencilOp pglStencilOp +#define glTexCoord2f pglTexCoord2f +#define glTexCoord2fv pglTexCoord2fv +#define glTexEnvfv pglTexEnvfv +#define glTexEnvi pglTexEnvi +#define glTexImage2D pglTexImage2D +#define glTexParameteri pglTexParameteri +#define glTexParameterfv pglTexParameterfv +#define glTexSubImage2D pglTexSubImage2D +#define glTranslatef pglTranslatef +#define glVertex3d pglVertex3d +#define glVertex3f pglVertex3f +#define glVertex3fv pglVertex3fv +#define glVertex4f pglVertex4f +#define glViewport pglViewport +#define glXCreateContext pglXCreateContext +#define glXDestroyContext pglXDestroyContext +#define glXMakeCurrent pglXMakeCurrent +#define glXSwapBuffers pglXSwapBuffers + +#endif /* GLPRIVATE_NO_REDEFINE */ + +#endif /* HAVE_OPENGL */ + +#endif /* __GRAPHICS_WINE_GL_PRIVATE_H */ + --- /dev/null Mon Jul 18 01:46:18 1994 +++ dlls/ddraw/gl_api.h Fri May 23 20:14:08 2003 @@ -0,0 +1,106 @@ +/* GL API list + * Copyright (c) 2003 Lionel Ulmer / Mike McCormack + * + * This file contains all structures that are not exported + * through d3d.h and all common macros. + * + * 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 + */ + +/* Note : this file is NOT protected against double-inclusion for pretty good + reasons :-) */ + +#ifndef GL_API_FUNCTION +#error "This file should be included with GL_API_FUNCTION defined !" +#endif + +GL_API_FUNCTION(glAlphaFunc) +GL_API_FUNCTION(glBegin) +GL_API_FUNCTION(glBindTexture) +GL_API_FUNCTION(glBlendFunc) +GL_API_FUNCTION(glClear) +GL_API_FUNCTION(glClearColor) +GL_API_FUNCTION(glClearDepth) +GL_API_FUNCTION(glClearStencil) +GL_API_FUNCTION(glClipPlane) +GL_API_FUNCTION(glColor3f) +GL_API_FUNCTION(glColor3ub) +GL_API_FUNCTION(glColor4ub) +GL_API_FUNCTION(glColorMaterial) +GL_API_FUNCTION(glCullFace) +GL_API_FUNCTION(glDeleteTextures) +GL_API_FUNCTION(glDepthFunc) +GL_API_FUNCTION(glDepthMask) +GL_API_FUNCTION(glDepthRange) +GL_API_FUNCTION(glDisable) +GL_API_FUNCTION(glDrawBuffer) +GL_API_FUNCTION(glDrawPixels) +GL_API_FUNCTION(glEnable) +GL_API_FUNCTION(glEnd) +GL_API_FUNCTION(glFlush) +GL_API_FUNCTION(glFogf) +GL_API_FUNCTION(glFogfv) +GL_API_FUNCTION(glFogi) +GL_API_FUNCTION(glFrontFace) +GL_API_FUNCTION(glGenTextures) +GL_API_FUNCTION(glGetBooleanv) +GL_API_FUNCTION(glGetError) +GL_API_FUNCTION(glGetFloatv) +GL_API_FUNCTION(glGetIntegerv) +GL_API_FUNCTION(glGetTexEnviv) +GL_API_FUNCTION(glGetTexParameteriv) +GL_API_FUNCTION(glHint) +GL_API_FUNCTION(glLightModelfv) +GL_API_FUNCTION(glLightModeli) +GL_API_FUNCTION(glLightfv) +GL_API_FUNCTION(glLoadIdentity) +GL_API_FUNCTION(glLoadMatrixf) +GL_API_FUNCTION(glMaterialf) +GL_API_FUNCTION(glMaterialfv) +GL_API_FUNCTION(glMatrixMode) +GL_API_FUNCTION(glMultMatrixf) +GL_API_FUNCTION(glNormal3f) +GL_API_FUNCTION(glNormal3fv) +GL_API_FUNCTION(glPixelStorei) +GL_API_FUNCTION(glPolygonMode) +GL_API_FUNCTION(glPolygonOffset) +GL_API_FUNCTION(glPopMatrix) +GL_API_FUNCTION(glPushMatrix) +GL_API_FUNCTION(glRasterPos2f) +GL_API_FUNCTION(glReadBuffer) +GL_API_FUNCTION(glReadPixels) +GL_API_FUNCTION(glScissor) +GL_API_FUNCTION(glShadeModel) +GL_API_FUNCTION(glStencilFunc) +GL_API_FUNCTION(glStencilMask) +GL_API_FUNCTION(glStencilOp) +GL_API_FUNCTION(glTexCoord2f) +GL_API_FUNCTION(glTexCoord2fv) +GL_API_FUNCTION(glTexEnvfv) +GL_API_FUNCTION(glTexEnvi) +GL_API_FUNCTION(glTexImage2D) +GL_API_FUNCTION(glTexParameteri) +GL_API_FUNCTION(glTexParameterfv) +GL_API_FUNCTION(glTexSubImage2D) +GL_API_FUNCTION(glTranslatef) +GL_API_FUNCTION(glVertex3d) +GL_API_FUNCTION(glVertex3f) +GL_API_FUNCTION(glVertex3fv) +GL_API_FUNCTION(glVertex4f) +GL_API_FUNCTION(glViewport) +GL_API_FUNCTION(glXCreateContext) +GL_API_FUNCTION(glXDestroyContext) +GL_API_FUNCTION(glXMakeCurrent) +GL_API_FUNCTION(glXSwapBuffers)