First OpenGL 'optionnal' patch

Lionel Ulmer lionel.ulmer at free.fr
Sat Nov 9 12:50:39 CST 2002


Hi all,

With this patch, a Wine built with OpenGL included will work fine on a
non-OpenGL box. The following problems remain to be solved :

 - when the application is an OpenGL app linked to OpenGL32.DLL, it seems
   that it confuses Linux' loader.

   What happens is that opengl32.dll.so is tried to be loaded first. That
   fails as no libGL.so is found in the box. Later on, x11drv.dll.so is
   tried to be load and I have the following error :

err:module:BUILTIN32_dlopen failed to load .so lib for builtin x11drv.dll:
/usr/local/src/Wine/Build_02/lib/wine/x11drv.dll.so: undefined symbol: XextRemoveDisplay

   But x11drv.dll.so is linked to Xext and this symbol is defined there, so
   I do not know what's happening (I may have a buggy dynamic loader on my
   box as the NVIDIA drivers tell me each time they are linked :-) ).

   Of course, Wine crashes then....

 - as told in my previous mail, DDraw will NOT work on non-OpenGL boxes.
   This will need more work to have it done properly (maybe add a D3DGL
   driver like TG does and have it loaded by DDraw as soon as it detects
   that any 3D stuff is requested by the app).
   
Changelog:
 Make Wine's X11DRV build with OpenGL work on a non-OpenGL box

autoheader and autoconf need to be executed after patching.

              Lionel

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
Index: configure.ac
===================================================================
RCS file: /home/wine/wine/configure.ac,v
retrieving revision 1.90
diff -u -r1.90 configure.ac
--- configure.ac	8 Nov 2002 19:34:52 -0000	1.90
+++ configure.ac	9 Nov 2002 18:42:30 -0000
@@ -139,6 +139,8 @@
 OPENGLFILES=""
 AC_SUBST(GLU32FILES)
 GLU32FILES=""
+AC_SUBST(OPENGL_LIBS)
+OPENGL_LIBS=""
 if test "$have_x" = "yes"
 then
     XLIB="-lXext -lX11"
@@ -280,7 +282,7 @@
             then
 		dnl Check for the presence of the library
 		AC_CHECK_LIB(GL,glXCreateContext,
-			     X_PRE_LIBS="$X_PRE_LIBS -lGL"
+			     OPENGL_LIBS="-lGL"
 			     ,,
 			     $X_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS)
 
@@ -317,10 +319,10 @@
 		fi
 	        dnl Check for GLU32 library.
 		AC_CHECK_LIB(GLU,gluLookAt,
-			     [X_PRE_LIBS="$X_PRE_LIBS -lGLU"
+			     [OPENGL_LIBS="$OPENGL_LIBS -lGLU"
 			     GLU32FILES='$(GLU32FILES)']
 			     ,,
-			     $X_LIBS $X_PRE_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS
+			     $OPENGL_LIBS $X_LIBS $X_PRE_LIBS -lXext -lX11 -lm $X_EXTRA_LIBS
 		)
 	     fi
 	 fi
@@ -856,6 +858,7 @@
   WINE_GET_SONAME(Xext,XextCreateExtension,[$X_LIBS -lX11 $X_EXTRA_LIBS])
   WINE_GET_SONAME(Xrender,XRenderQueryExtension,[$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
   WINE_GET_SONAME(freetype,FT_Init_FreeType,[$X_LIBS])
+  WINE_GET_SONAME(GL,glXQueryExtension,[$X_LIBS $X_EXTRA_LIBS])
 fi
 
 
Index: dlls/d3d8/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/d3d8/Makefile.in,v
retrieving revision 1.3
diff -u -r1.3 Makefile.in
--- dlls/d3d8/Makefile.in	1 Oct 2002 18:16:19 -0000	1.3
+++ dlls/d3d8/Makefile.in	9 Nov 2002 18:42:30 -0000
@@ -5,7 +5,7 @@
 MODULE    = d3d8.dll
 IMPORTS   = user32 gdi32 kernel32
 EXTRAINCL = @X_CFLAGS@
-EXTRALIBS = $(LIBUUID) @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
+EXTRALIBS = $(LIBUUID) @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
 
 LDDLLFLAGS = @LDDLLFLAGS@
 SYMBOLFILE = $(MODULE).tmp.o
Index: dlls/ddraw/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/Makefile.in,v
retrieving revision 1.26
diff -u -r1.26 Makefile.in
--- dlls/ddraw/Makefile.in	1 Oct 2002 18:16:19 -0000	1.26
+++ dlls/ddraw/Makefile.in	9 Nov 2002 18:42:30 -0000
@@ -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@
+EXTRALIBS = $(LIBUUID) @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
 
 LDDLLFLAGS = @LDDLLFLAGS@
 SYMBOLFILE = $(MODULE).tmp.o
Index: dlls/glu32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/glu32/Makefile.in,v
retrieving revision 1.3
diff -u -r1.3 Makefile.in
--- dlls/glu32/Makefile.in	1 Oct 2002 18:16:20 -0000	1.3
+++ dlls/glu32/Makefile.in	9 Nov 2002 18:42:30 -0000
@@ -4,7 +4,7 @@
 VPATH     = @srcdir@
 MODULE    = glu32.dll
 EXTRAINCL = @X_CFLAGS@
-EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
+EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
 
 LDDLLFLAGS = @LDDLLFLAGS@
 SYMBOLFILE = $(MODULE).tmp.o
Index: dlls/opengl32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/opengl32/Makefile.in,v
retrieving revision 1.12
diff -u -r1.12 Makefile.in
--- dlls/opengl32/Makefile.in	1 Oct 2002 18:16:20 -0000	1.12
+++ dlls/opengl32/Makefile.in	9 Nov 2002 18:42:31 -0000
@@ -5,7 +5,7 @@
 MODULE    = opengl32.dll
 IMPORTS   = user32 gdi32 kernel32
 EXTRAINCL = @X_CFLAGS@
-EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
+EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ @OPENGL_LIBS@
 
 LDDLLFLAGS = @LDDLLFLAGS@
 SYMBOLFILE = $(MODULE).tmp.o
Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.63
diff -u -r1.63 x11drv_main.c
--- dlls/x11drv/x11drv_main.c	4 Nov 2002 23:53:42 -0000	1.63
+++ dlls/x11drv/x11drv_main.c	9 Nov 2002 18:42:32 -0000
@@ -64,6 +64,7 @@
 unsigned int X11DRV_server_startticks;
 
 static BOOL synchronous;  /* run in synchronous mode? */
+static BOOL desktop_dbl_buf;
 static char *desktop_geometry;
 static XVisualInfo *desktop_vi;
 
@@ -252,6 +253,10 @@
     if (!get_config_key( hkey, appkey, "Synchronous", buffer, sizeof(buffer) ))
         synchronous = IS_OPTION_TRUE( buffer[0] );
 
+    desktop_dbl_buf = FALSE;
+    if (!get_config_key( hkey, appkey, "DesktopDoubleBuffered", buffer, sizeof(buffer) ))
+        synchronous = IS_OPTION_TRUE( buffer[0] );    
+    
     if (appkey) RegCloseKey( appkey );
     RegCloseKey( hkey );
 }
@@ -297,8 +302,12 @@
     }
     else screen_depth = DefaultDepthOfScreen( screen );
 
+    /* Initialize OpenGL */
+    X11DRV_OpenGL_Init(display);
+    
     /* If OpenGL is available, change the default visual, etc as necessary */
-    if ((desktop_vi = X11DRV_setup_opengl_visual( display )))
+    if ((desktop_dbl_buf == TRUE) &&
+	(desktop_vi = X11DRV_setup_opengl_visual( display )))
     {
         visual       = desktop_vi->visual;
         screen       = ScreenOfDisplay(display, desktop_vi->screen);
@@ -336,10 +345,6 @@
     /* initialize DGA2 */
     X11DRV_XF86DGA2_Init();
 #endif
-#ifdef HAVE_OPENGL
-    /* initialize GLX */
-    /*X11DRV_GLX_Init();*/
-#endif
 
     /* load display.dll */
     LoadLibrary16( "display" );
@@ -369,10 +374,6 @@
  */
 static void process_detach(void)
 {
-#ifdef HAVE_OPENGL
-    /* cleanup GLX */
-    /*X11DRV_GLX_Cleanup();*/
-#endif
 #ifdef HAVE_LIBXXF86DGA2
     /* cleanup DGA2 */
     X11DRV_XF86DGA2_Cleanup();
Index: graphics/x11drv/opengl.c
===================================================================
RCS file: /home/wine/wine/graphics/x11drv/opengl.c,v
retrieving revision 1.12
diff -u -r1.12 opengl.c
--- graphics/x11drv/opengl.c	2 Oct 2002 01:24:27 -0000	1.12
+++ graphics/x11drv/opengl.c	9 Nov 2002 18:42:32 -0000
@@ -19,6 +19,7 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 
 #include "ts_xlib.h"
 
@@ -31,7 +32,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(opengl);
 
-#ifdef HAVE_OPENGL
+#if defined(HAVE_GL_GL_H) && defined(HAVE_GL_GLX_H)
 
 #undef APIENTRY
 #undef CALLBACK
@@ -105,6 +106,50 @@
   DPRINTF("\n");
 }
 
+/* No need to load any other libraries as according to the ABI, libGL should be self-sufficient and
+   include all dependencies
+*/
+#ifndef SONAME_LIBGL
+#define SONAME_LIBGL "libGL.so.1"
+#endif
+
+static void *opengl_handle;
+
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f;
+MAKE_FUNCPTR(glXChooseVisual)
+MAKE_FUNCPTR(glXGetConfig)
+MAKE_FUNCPTR(glXSwapBuffers)
+MAKE_FUNCPTR(glXQueryExtension)
+#undef MAKE_FUNCPTR
+
+void X11DRV_OpenGL_Init(Display *display) {
+    int error_base, event_base;
+
+    opengl_handle = wine_dlopen(SONAME_LIBGL, RTLD_NOW|RTLD_GLOBAL, NULL, 0);
+    if (opengl_handle == NULL) return;
+
+#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(opengl_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
+LOAD_FUNCPTR(glXChooseVisual)
+LOAD_FUNCPTR(glXGetConfig)
+LOAD_FUNCPTR(glXSwapBuffers)
+LOAD_FUNCPTR(glXQueryExtension)
+#undef LOAD_FUNCPTR
+
+    wine_tsx11_lock();
+    if (pglXQueryExtension(display, &event_base, &error_base) == True) {
+	TRACE("GLX is up and running error_base = %d\n", error_base);
+    } else {
+        wine_dlclose(opengl_handle, NULL, 0);
+	opengl_handle = NULL;
+    }
+    wine_tsx11_unlock();
+    return;
+
+sym_not_found:
+    wine_dlclose(opengl_handle, NULL, 0);
+    opengl_handle = NULL;
+}
+
 /* X11DRV_ChoosePixelFormat
 
      Equivalent of glXChooseVisual
@@ -121,6 +166,11 @@
   XVisualInfo *vis;
   int i;
 
+  if (opengl_handle == NULL) {
+    ERR("No libGL on this box - disabling OpenGL support !\n");
+    return 0;
+  }
+  
   if (TRACE_ON(opengl)) {
     TRACE("(%p,%p)\n", physDev, ppfd);
 
@@ -200,6 +250,11 @@
   int value;
   int rb,gb,bb,ab;
 
+  if (opengl_handle == NULL) {
+    ERR("No libGL on this box - disabling OpenGL support !\n");
+    return 0;
+  }
+  
   TRACE("(%p,%d,%d,%p)\n", physDev, iPixelFormat, nBytes, ppfd);
 
   if (ppfd == NULL) {
@@ -225,7 +280,7 @@
 
     /* Create a 'standard' X Visual */
     wine_tsx11_lock();
-    vis = glXChooseVisual(gdi_display, DefaultScreen(gdi_display), dblBuf);
+    vis = pglXChooseVisual(gdi_display, DefaultScreen(gdi_display), dblBuf);
     wine_tsx11_unlock();
 
     WARN("Uninitialized Visual. Creating standard (%p) !\n", vis);
@@ -248,26 +303,26 @@
   ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED;
   /* Now the flags extraced from the Visual */
   wine_tsx11_lock();
-  glXGetConfig(gdi_display, vis, GLX_DOUBLEBUFFER, &value); if (value) ppfd->dwFlags |= PFD_DOUBLEBUFFER;
-  glXGetConfig(gdi_display, vis, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO;
+  pglXGetConfig(gdi_display, vis, GLX_DOUBLEBUFFER, &value); if (value) ppfd->dwFlags |= PFD_DOUBLEBUFFER;
+  pglXGetConfig(gdi_display, vis, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO;
 
   /* Pixel type */
-  glXGetConfig(gdi_display, vis, GLX_RGBA, &value);
+  pglXGetConfig(gdi_display, vis, GLX_RGBA, &value);
   if (value)
     ppfd->iPixelType = PFD_TYPE_RGBA;
   else
     ppfd->iPixelType = PFD_TYPE_COLORINDEX;
 
   /* Color bits */
-  glXGetConfig(gdi_display, vis, GLX_BUFFER_SIZE, &value);
+  pglXGetConfig(gdi_display, vis, GLX_BUFFER_SIZE, &value);
   ppfd->cColorBits = value;
 
   /* Red, green, blue and alpha bits / shifts */
   if (ppfd->iPixelType == PFD_TYPE_RGBA) {
-    glXGetConfig(gdi_display, vis, GLX_RED_SIZE, &rb);
-    glXGetConfig(gdi_display, vis, GLX_GREEN_SIZE, &gb);
-    glXGetConfig(gdi_display, vis, GLX_BLUE_SIZE, &bb);
-    glXGetConfig(gdi_display, vis, GLX_ALPHA_SIZE, &ab);
+    pglXGetConfig(gdi_display, vis, GLX_RED_SIZE, &rb);
+    pglXGetConfig(gdi_display, vis, GLX_GREEN_SIZE, &gb);
+    pglXGetConfig(gdi_display, vis, GLX_BLUE_SIZE, &bb);
+    pglXGetConfig(gdi_display, vis, GLX_ALPHA_SIZE, &ab);
 
     ppfd->cRedBits = rb;
     ppfd->cRedShift = gb + bb + ab;
@@ -290,11 +345,11 @@
   /* Accums : to do ... */
 
   /* Depth bits */
-  glXGetConfig(gdi_display, vis, GLX_DEPTH_SIZE, &value);
+  pglXGetConfig(gdi_display, vis, GLX_DEPTH_SIZE, &value);
   ppfd->cDepthBits = value;
 
   /* stencil bits */
-  glXGetConfig( gdi_display, vis, GLX_STENCIL_SIZE, &value );
+  pglXGetConfig( gdi_display, vis, GLX_STENCIL_SIZE, &value );
   ppfd->cStencilBits = value;
 
   wine_tsx11_unlock();
@@ -315,6 +370,11 @@
      Get the pixel-format id used by this DC
 */
 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
+  if (opengl_handle == NULL) {
+    ERR("No libGL on this box - disabling OpenGL support !\n");
+    return 0;
+  }
+  
   TRACE("(%p): returns %d\n", physDev, physDev->current_pf);
 
   return physDev->current_pf;
@@ -327,6 +387,11 @@
 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
 			   int iPixelFormat,
 			   const PIXELFORMATDESCRIPTOR *ppfd) {
+  if (opengl_handle == NULL) {
+    ERR("No libGL on this box - disabling OpenGL support !\n");
+    return 0;
+  }
+  
   TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
 
   physDev->current_pf = iPixelFormat;
@@ -339,10 +404,15 @@
      Swap the buffers of this DC
 */
 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) {
+  if (opengl_handle == NULL) {
+    ERR("No libGL on this box - disabling OpenGL support !\n");
+    return 0;
+  }
+  
   TRACE("(%p)\n", physDev);
 
   wine_tsx11_lock();
-  glXSwapBuffers(gdi_display, physDev->drawable);
+  pglXSwapBuffers(gdi_display, physDev->drawable);
   wine_tsx11_unlock();
 
   return TRUE;
@@ -357,22 +427,19 @@
  */
 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
 {
-    int err_base, evt_base;
     XVisualInfo *visual = NULL;
+    int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None};
 
-    /* In order to support OpenGL or D3D, we require a double-buffered
-     * visual */
+    if (opengl_handle == NULL) return NULL;
+    
+    /* In order to support OpenGL or D3D, we require a double-buffered visual */
     wine_tsx11_lock();
-    if (glXQueryExtension(display, &err_base, &evt_base) == True)
-    {
-        int dblBuf[]={GLX_RGBA,GLX_DEPTH_SIZE,16,GLX_DOUBLEBUFFER,None};
-        visual = glXChooseVisual(display, DefaultScreen(display), dblBuf);
-    }
+    visual = pglXChooseVisual(display, DefaultScreen(display), dblBuf);
     wine_tsx11_unlock();
     return visual;
 }
 
-#else  /* defined(HAVE_OPENGL) */
+#else  /* no OpenGL includes */
 
 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
 			     const PIXELFORMATDESCRIPTOR *ppfd) {
Index: include/x11drv.h
===================================================================
RCS file: /home/wine/wine/include/x11drv.h,v
retrieving revision 1.116
diff -u -r1.116 x11drv.h
--- include/x11drv.h	25 Sep 2002 00:29:57 -0000	1.116
+++ include/x11drv.h	9 Nov 2002 18:42:33 -0000
@@ -222,6 +222,9 @@
 				      UINT count, const INT *lpDx);
 extern void X11DRV_XRender_UpdateDrawable(X11DRV_PDEVICE *physDev);
 
+extern void X11DRV_OpenGL_Init(Display *display);
+extern XVisualInfo *X11DRV_setup_opengl_visual(Display *display);
+
 /* exported dib functions for now */
 
 /* Additional info for DIB section objects */
@@ -436,6 +439,5 @@
 extern int X11DRV_sync_whole_window_position( Display *display, WND *win, int zorder );
 extern int X11DRV_sync_client_window_position( Display *display, WND *win );
 extern void X11DRV_set_wm_hints( Display *display, WND *win );
-extern XVisualInfo *X11DRV_setup_opengl_visual( Display *display );
 
 #endif  /* __WINE_X11DRV_H */


More information about the wine-patches mailing list