diff --git a/dlls/ddraw/Makefile.in b/dlls/ddraw/Makefile.in index 79e462205d1..137a4762e53 100644 --- a/dlls/ddraw/Makefile.in +++ b/dlls/ddraw/Makefile.in @@ -5,7 +5,7 @@ VPATH = @srcdir@ 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 diff --git a/dlls/ddraw/ddraw/hal.c b/dlls/ddraw/ddraw/hal.c index cf69316f9d2..144b2ba3377 100644 --- a/dlls/ddraw/ddraw/hal.c +++ b/dlls/ddraw/ddraw/hal.c @@ -138,11 +138,10 @@ static BOOL WINAPI set_hal_info(LPDDHALINFO lpDDHalInfo, BOOL reset) 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; } diff --git a/dlls/ddraw/ddraw/main.c b/dlls/ddraw/ddraw/main.c index 8e8a9fa477f..f3c87b03466 100644 --- a/dlls/ddraw/ddraw/main.c +++ b/dlls/ddraw/ddraw/main.c @@ -184,28 +184,44 @@ HRESULT WINAPI Main_DirectDraw_QueryInterface( 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 diff --git a/dlls/ddraw/ddraw/user.c b/dlls/ddraw/ddraw/user.c index 0ba30a6f12f..737100898e4 100644 --- a/dlls/ddraw/ddraw/user.c +++ b/dlls/ddraw/ddraw/user.c @@ -173,10 +173,11 @@ HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex) | 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 @@ HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex) 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 diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index e44712404cb..2c52efc4103 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -355,6 +355,7 @@ typedef struct { extern Convert ModeEmulations[8]; extern int _common_depth_to_pixelformat(DWORD depth,LPDIRECTDRAW ddraw); +extern BOOL opengl_initialized; /****************************************************************************** * Structure conversion (for thunks) diff --git a/dlls/ddraw/dsurface/main.c b/dlls/ddraw/dsurface/main.c index a2b8fe0d8f7..4f78f3096cc 100644 --- a/dlls/ddraw/dsurface/main.c +++ b/dlls/ddraw/dsurface/main.c @@ -179,8 +179,12 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, 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 @@ Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, } This->ref++; return ret_value; - } + } #endif return E_NOINTERFACE; diff --git a/dlls/ddraw/gl_api.h b/dlls/ddraw/gl_api.h new file mode 100644 index 00000000000..e19d6873dda --- /dev/null +++ b/dlls/ddraw/gl_api.h @@ -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) diff --git a/dlls/ddraw/gl_private.h b/dlls/ddraw/gl_private.h new file mode 100644 index 00000000000..a043424d58a --- /dev/null +++ b/dlls/ddraw/gl_private.h @@ -0,0 +1,137 @@ +/* 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 +#include +#ifdef HAVE_GL_GLEXT_H +# include +#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 */ diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index d621d0e5c1b..a3b39cae6eb 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -22,6 +22,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#define GLPRIVATE_NO_REDEFINE + #include "config.h" #include @@ -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 @@ typedef struct { 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 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) 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) diff --git a/dlls/ddraw/mesa_private.h b/dlls/ddraw/mesa_private.h index 72136b9497e..633d092a872 100644 --- a/dlls/ddraw/mesa_private.h +++ b/dlls/ddraw/mesa_private.h @@ -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 -#include -#ifdef HAVE_GL_GLEXT_H -# include -#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 */