[OpenGL] Start of infrastructure to support WGL extensions.

Lionel Ulmer lionel.ulmer at free.fr
Fri Feb 6 12:10:59 CST 2004


Hi all,

WGL extensions are apart from 'core' GL extensions in the sense that we
cannot do a direct mapping between the Unix and Windows world.

The first target is to try to get PBuffers working using the SGIX extension
(for the moment it seems doable, but I did not go much further than reading
the relevant WGL and GLX extensions).

So this patch adds the relevant infrastructure to enable anyone to add
support for these extensions.

Anyway, this helped me have a non-boring flight back :-) (that and the
Wininet patch whose submission is waiting on any verdict on Mike's handle
patch).

             Lionel

Changelog:
 Beginning of infrastructure to support WGL extensions.

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
? dlls/opengl32/wgl_ext.c
? dlls/opengl32/wgl_ext.h
Index: dlls/opengl32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/opengl32/Makefile.in,v
retrieving revision 1.14
diff -u -r1.14 Makefile.in
--- dlls/opengl32/Makefile.in	11 Oct 2003 01:09:18 -0000	1.14
+++ dlls/opengl32/Makefile.in	6 Feb 2004 18:05:28 -0000
@@ -9,6 +9,7 @@
 
 C_SRCS = \
 	wgl.c \
+	wgl_ext.c \
 	opengl_norm.c \
 	opengl_ext.c
 
Index: dlls/opengl32/make_opengl
===================================================================
RCS file: /home/wine/wine/dlls/opengl32/make_opengl,v
retrieving revision 1.21
diff -u -r1.21 make_opengl
--- dlls/opengl32/make_opengl	6 Jan 2004 00:36:13 -0000	1.21
+++ dlls/opengl32/make_opengl	6 Feb 2004 18:05:29 -0000
@@ -544,8 +544,6 @@
 @  stdcall wglDescribeLayerPlane(long long long long ptr)
 @  stdcall wglGetCurrentContext()
 @  stdcall wglGetCurrentDC()
-@  stdcall wglGetExtensionsStringEXT()
-@  stdcall wglGetExtensionsStringARB(long)
 @  stdcall wglGetLayerPaletteEntries(long long long long ptr)
 @  stdcall wglGetProcAddress(str)
 @  stdcall wglMakeCurrent(long long)
Index: dlls/opengl32/opengl32.spec
===================================================================
RCS file: /home/wine/wine/dlls/opengl32/opengl32.spec,v
retrieving revision 1.22
diff -u -r1.22 opengl32.spec
--- dlls/opengl32/opengl32.spec	6 Jan 2004 00:36:13 -0000	1.22
+++ dlls/opengl32/opengl32.spec	6 Feb 2004 18:05:29 -0000
@@ -5,8 +5,6 @@
 @  stdcall wglDescribeLayerPlane(long long long long ptr)
 @  stdcall wglGetCurrentContext()
 @  stdcall wglGetCurrentDC()
-@  stdcall wglGetExtensionsStringEXT()
-@  stdcall wglGetExtensionsStringARB(long)
 @  stdcall wglGetLayerPaletteEntries(long long long long ptr)
 @  stdcall wglGetProcAddress(str)
 @  stdcall wglMakeCurrent(long long)
Index: dlls/opengl32/wgl.c
===================================================================
RCS file: /home/wine/wine/dlls/opengl32/wgl.c,v
retrieving revision 1.43
diff -u -r1.43 wgl.c
--- dlls/opengl32/wgl.c	20 Jan 2004 22:48:57 -0000	1.43
+++ dlls/opengl32/wgl.c	6 Feb 2004 18:05:29 -0000
@@ -30,6 +30,7 @@
 #include "winerror.h"
 
 #include "wgl.h"
+#include "wgl_ext.h"
 #include "opengl_ext.h"
 #include "wine/library.h"
 #include "wine/debug.h"
@@ -302,6 +303,11 @@
 		((OpenGL_extension *) elt_b)->name);
 }
 
+static int wgl_compar(const void *elt_a, const void *elt_b) {
+  return strcmp(((WGL_extension *) elt_a)->func_name,
+		((WGL_extension *) elt_b)->func_name);
+}
+
 void* WINAPI wglGetProcAddress(LPCSTR  lpszProc) {
   void *local_func;
   static HMODULE hm = 0;
@@ -331,17 +337,45 @@
 					 extension_registry_size, sizeof(OpenGL_extension), compar);
 
   if (ext_ret == NULL) {
-    /* Some sanity checks :-) */
-    ENTER_GL();
-    local_func = p_glXGetProcAddressARB(lpszProc);
-    LEAVE_GL();
-    if (local_func != NULL) {
-      ERR("Extension %s defined in the OpenGL library but NOT in opengl_ext.c... Please report (lionel.ulmer at free.fr) !\n", lpszProc);
+    WGL_extension wgl_ext, *wgl_ext_ret;
+
+    /* Try to find the function in the WGL extensions ... */
+    wgl_ext.func_name = (char *) lpszProc;
+    wgl_ext_ret = (WGL_extension *) bsearch(&wgl_ext, wgl_extension_registry,
+					    wgl_extension_registry_size, sizeof(WGL_extension), wgl_compar);
+
+    if (wgl_ext_ret == NULL) {
+      /* Some sanity checks :-) */
+      ENTER_GL();
+      local_func = p_glXGetProcAddressARB(lpszProc);
+      LEAVE_GL();
+      if (local_func != NULL) {
+	ERR("Extension %s defined in the OpenGL library but NOT in opengl_ext.c... Please report (lionel.ulmer at free.fr) !\n", lpszProc);
+	return NULL;
+      }
+      
+      WARN("Did not find extension %s in either Wine or your OpenGL library.\n", lpszProc);
       return NULL;
-    }
+    } else {
+	void *ret = NULL;
 
-    WARN("Did not find extension %s in either Wine or your OpenGL library.\n", lpszProc);
-    return NULL;
+	if (wgl_ext_ret->func_init != NULL) {
+	    const char *err_msg;
+	    if ((err_msg = wgl_ext_ret->func_init(p_glXGetProcAddressARB,
+						  wgl_ext_ret->context)) == NULL) {
+		ret = wgl_ext_ret->func_address;
+	    } else {
+		WARN("Error when getting WGL extension '%s' : %s.\n", debugstr_a(lpszProc), err_msg);
+		return NULL;
+	    }
+	} else {
+	  ret = wgl_ext_ret->func_address;
+	}
+
+	if (ret)
+	    TRACE(" returning WGL function  (%p)\n", ret);
+	return ret;
+    }
   } else {
     ENTER_GL();
     local_func = p_glXGetProcAddressARB(ext_ret->glx_name);
@@ -712,6 +746,9 @@
    if (p_glXGetProcAddressARB == NULL)
 	   TRACE("could not find glXGetProcAddressARB in libGL.\n");
   }
+
+  /* Initialize also the list of supported WGL extensions. */
+  wgl_ext_initialize_extensions(default_display, DefaultScreen(default_display));
   
   if (default_cx == NULL) {
     ERR("Could not create default context.\n");
@@ -719,34 +756,16 @@
   return TRUE;
 }
 
-/**********************************************************************/
-
-/* Some WGL extensions... */
-static const char *WGL_extensions = "WGL_ARB_extensions_string WGL_EXT_extensions_string";
-
-/**********************************************************************/
-
-const char * WINAPI wglGetExtensionsStringEXT(void) {
-    TRACE("() returning \"%s\"\n", WGL_extensions);
-
-    return WGL_extensions;
-}
 
 /**********************************************************************/
 
 static void process_detach(void)
 {
   glXDestroyContext(default_display, default_cx);
-}
 
-/***********************************************************************
- *              wglGetExtensionsStringARB(OPENGL32.@)
- */
-const char * WINAPI wglGetExtensionsStringARB(HDC hdc) {
-
-  return wglGetExtensionsStringEXT();
+  /* Do not leak memory... */
+  wgl_ext_finalize_extensions();
 }
-
 
 /***********************************************************************
  *           OpenGL initialisation routine
--- /dev/null	Mon Jul 18 01:46:18 1994
+++ dlls/opengl32/wgl_ext.c	Fri Feb  6 19:02:14 2004
@@ -0,0 +1,132 @@
+/* Support for window-specific OpenGL extensions.
+ *
+ * Copyright (c) 2004 Lionel Ulmer
+ *
+ * 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
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winerror.h"
+
+#include "wgl.h"
+#include "wgl_ext.h"
+#include "opengl_ext.h"
+#include "wine/library.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(opengl);
+
+/* Some WGL extensions... */
+static const char *WGL_extensions_base = "WGL_ARB_extensions_string WGL_EXT_extensions_string";
+static char *WGL_extensions = NULL;
+
+/* Extensions-query functions */
+BOOL query_function_pbuffers(const char *gl_version, const char *gl_extensions, const char *glx_extensions,
+			     const char *server_glx_extensions, const char *client_glx_extensions)
+{
+    return FALSE;
+}
+
+/***********************************************************************
+ *              wglGetExtensionsStringEXT(OPENGL32.@)
+ */
+const char * WINAPI wglGetExtensionsStringEXT(void) {
+    TRACE("() returning \"%s\"\n", WGL_extensions);
+
+    return WGL_extensions;
+}
+
+/***********************************************************************
+ *              wglGetExtensionsStringARB(OPENGL32.@)
+ */
+const char * WINAPI wglGetExtensionsStringARB(HDC hdc) {
+    TRACE("() returning \"%s\"\n", WGL_extensions);
+
+    return WGL_extensions;    
+}
+
+static const struct {
+    const char *name;
+    BOOL (*query_function)(const char *gl_version, const char *gl_extensions, const char *glx_extensions,
+			   const char *server_glx_extensions, const char *client_glx_extensions);
+} extension_list[] = {
+    { "WGL_ARB_pbuffer", query_function_pbuffers }
+};
+
+/* Used to initialize the WGL extension string at DLL loading */
+void wgl_ext_initialize_extensions(Display *display, int screen)
+{
+    int size = strlen(WGL_extensions_base);
+    const char *glx_extensions = glXQueryExtensionsString(display, screen);
+    const char *server_glx_extensions = glXQueryServerString(display, screen, GLX_EXTENSIONS);
+    const char *client_glx_extensions = glXGetClientString(display, GLX_EXTENSIONS);
+    const char *gl_extensions = (const char *) glGetString(GL_EXTENSIONS);
+    const char *gl_version = (const char *) glGetString(GL_VERSION);
+    int i;
+
+    TRACE("GL version      : %s.\n", debugstr_a(gl_version));
+    TRACE("GL exts         : %s.\n", debugstr_a(gl_extensions));
+    TRACE("GLX exts        : %s.\n", debugstr_a(glx_extensions));
+    TRACE("Server GLX exts : %s.\n", debugstr_a(server_glx_extensions));
+    TRACE("Client GLX exts : %s.\n", debugstr_a(client_glx_extensions));
+
+    for (i = 0; i < (sizeof(extension_list) / sizeof(extension_list[0])); i++) {
+	if (extension_list[i].query_function(gl_version, gl_extensions, glx_extensions,
+					     server_glx_extensions, client_glx_extensions)) {
+	    size += strlen(extension_list[i].name) + 1;
+	}
+    }
+
+    /* For the moment, only 'base' extensions are supported. */
+    WGL_extensions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1);
+    if (WGL_extensions == NULL) {
+	WGL_extensions = (char *) WGL_extensions_base;
+    } else {
+	strcpy(WGL_extensions, WGL_extensions_base);
+	for (i = 0; i < (sizeof(extension_list) / sizeof(extension_list[0])); i++) {
+	    if (extension_list[i].query_function(gl_version, gl_extensions, glx_extensions,
+						 server_glx_extensions, client_glx_extensions)) {
+		strcat(WGL_extensions, " ");
+		strcat(WGL_extensions, extension_list[i].name);
+	    }
+	}
+    }
+
+    TRACE("Supporting following WGL extensions : %s.\n", debugstr_a(WGL_extensions));
+}
+
+void wgl_ext_finalize_extensions(void)
+{
+    if (WGL_extensions != WGL_extensions_base) {
+	HeapFree(GetProcessHeap(), 0, WGL_extensions);
+    }
+}
+
+/* Putting this at the end to prevent having to write the prototypes :-) */
+WGL_extension wgl_extension_registry[] = {
+    { "wglGetExtensionsStringARB", (void *) wglGetExtensionsStringARB, NULL, NULL},
+    { "wglGetExtensionsStringEXT", (void *) wglGetExtensionsStringEXT, NULL, NULL}
+};
+int wgl_extension_registry_size = sizeof(wgl_extension_registry) / sizeof(wgl_extension_registry[0]);
+
--- /dev/null	Mon Jul 18 01:46:18 1994
+++ dlls/opengl32/wgl_ext.h	Fri Feb  6 11:43:21 2004
@@ -0,0 +1,39 @@
+/* Support for window-specific OpenGL extensions.
+ *
+ * Copyright (c) 2004 Lionel Ulmer
+ *
+ * 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 __DLLS_OPENGL32_WGL_EXT_H
+#define __DLLS_OPENGL32_WGL_EXT_H
+
+#include "opengl_ext.h"
+
+/* Used to initialize the WGL extension string at DLL loading */
+void wgl_ext_initialize_extensions(Display *display, int screen);
+void wgl_ext_finalize_extensions(void);
+
+typedef struct {
+    const char *func_name;
+    void *func_address;
+    const char *(*func_init)(void *(*p_glXGetProcAddressARB)(const GLubyte *), void *context);
+    void *context;
+} WGL_extension;
+
+extern WGL_extension wgl_extension_registry[];
+extern int wgl_extension_registry_size;
+
+#endif /* __DLLS_OPENGL32_WGL_EXT_H */


More information about the wine-patches mailing list