symbian-qemu-0.9.1-12/libsdl-trunk/src/video/wincommon/SDL_wingl.c
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/libsdl-trunk/src/video/wincommon/SDL_wingl.c	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,647 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2006 Sam Lantinga
+
+    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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/* WGL implementation of SDL OpenGL support */
+
+#if SDL_VIDEO_OPENGL
+#include "SDL_opengl.h"
+#endif
+#include "SDL_lowvideo.h"
+#include "SDL_wingl_c.h"
+
+#if SDL_VIDEO_OPENGL
+#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
+#endif
+
+/* If setting the HDC fails, we may need to recreate the window (MSDN) */
+static int WIN_GL_ResetWindow(_THIS)
+{
+	int status = 0;
+
+#ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */
+	/* This doesn't work with DirectX code (see CVS comments) */
+	/* If we were passed a window, then we can't create a new one */
+	if ( !SDL_windowid && SDL_strcmp(this->name, "windib") == 0 ) {
+		/* Save the existing window attributes */
+		LONG style;
+		RECT rect = { 0, 0, 0, 0 };
+		style = GetWindowLong(SDL_Window, GWL_STYLE);
+		GetWindowRect(SDL_Window, &rect);
+		DestroyWindow(SDL_Window);
+		WIN_FlushMessageQueue();
+
+		SDL_resizing = 1;
+		SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
+		                          style,
+		                          rect.left, rect.top,
+		                          (rect.right-rect.left)+1,
+		                          (rect.bottom-rect.top)+1,
+		                          NULL, NULL, SDL_Instance, NULL);
+		WIN_FlushMessageQueue();
+		SDL_resizing = 0;
+
+		if ( SDL_Window ) {
+			this->SetCaption(this, this->wm_title, this->wm_icon);
+		} else {
+			SDL_SetError("Couldn't create window");
+			status = -1;
+		}
+	} else
+#endif /* !_WIN32_WCE */
+	{
+		SDL_SetError("Unable to reset window for OpenGL context");
+		status = -1;
+	}
+	return(status);
+}
+
+#if SDL_VIDEO_OPENGL
+
+static int ExtensionSupported(const char *extension, const char *extensions)
+{
+	const char *start;
+	const char *where, *terminator;
+
+	/* Extension names should not have spaces. */
+	where = SDL_strchr(extension, ' ');
+	if ( where || *extension == '\0' )
+	      return 0;
+	
+	if ( ! extensions )
+		return 0;
+
+	/* It takes a bit of care to be fool-proof about parsing the
+	 *      OpenGL extensions string. Don't be fooled by sub-strings,
+	 *           etc. */
+	
+	start = extensions;
+	
+	for (;;)
+	{
+		where = SDL_strstr(start, extension);
+		if (!where) break;
+		
+		terminator = where + SDL_strlen(extension);
+		if (where == start || *(where - 1) == ' ')
+	        if (*terminator == ' ' || *terminator == '\0') return 1;
+
+		start = terminator;
+	}
+	
+	return 0;
+}
+
+static int ChoosePixelFormatARB(_THIS, const int *iAttribs, const FLOAT *fAttribs)
+{
+	HWND hwnd;
+	HDC hdc;
+	HGLRC hglrc;
+	const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0;
+	const char *extensions;
+	int pformat = 0;
+	UINT matches = 0;
+
+	hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED,
+	                    0, 0, 10, 10,
+	                    NULL, NULL, SDL_Instance, NULL);
+	WIN_FlushMessageQueue();
+
+	hdc = GetDC(hwnd);
+
+	SetPixelFormat(hdc, ChoosePixelFormat(hdc, &GL_pfd), &GL_pfd);
+
+	hglrc = this->gl_data->wglCreateContext(hdc);
+	if ( hglrc ) {
+		this->gl_data->wglMakeCurrent(hdc, hglrc);
+	}
+
+	wglGetExtensionsStringARB = (const char * (WINAPI *)(HDC))
+		this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
+
+	if( wglGetExtensionsStringARB ) {
+		extensions = wglGetExtensionsStringARB(hdc);
+	} else {
+		extensions = NULL;
+	}
+
+	this->gl_data->WGL_ARB_pixel_format = 0;
+	if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) {
+		BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+		wglChoosePixelFormatARB =
+			(BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *))
+			this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB");
+		if( wglChoosePixelFormatARB &&
+		    wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pformat, &matches) && pformat ) {
+			this->gl_data->WGL_ARB_pixel_format = 1;
+		}
+	}
+	
+	if ( hglrc ) {
+		this->gl_data->wglMakeCurrent(NULL, NULL);
+		this->gl_data->wglDeleteContext(hglrc);
+	}
+	ReleaseDC(hwnd, hdc);
+	DestroyWindow(hwnd);
+	WIN_FlushMessageQueue();
+
+	return pformat;
+}
+
+#endif /* SDL_VIDEO_OPENGL */
+
+int WIN_GL_SetupWindow(_THIS)
+{
+	int retval;
+#if SDL_VIDEO_OPENGL
+	int i;
+	int iAttribs[64];
+	int *iAttr;
+	float fAttribs[1] = { 0 };
+	const GLubyte *(WINAPI *glGetStringFunc)(GLenum);
+	const char *wglext;
+
+	/* load the gl driver from a default path */
+	if ( ! this->gl_config.driver_loaded ) {
+		/* no driver has been loaded, use default (ourselves) */
+		if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) {
+			return(-1);
+		}
+	}
+
+	/* Set up the pixel format descriptor with our needed format */
+	SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
+	GL_pfd.nSize = sizeof(GL_pfd);
+	GL_pfd.nVersion = 1;
+	GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
+	if ( this->gl_config.double_buffer ) {
+		GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
+	}
+	if ( this->gl_config.stereo ) {
+		GL_pfd.dwFlags |= PFD_STEREO;
+	}
+	GL_pfd.iPixelType = PFD_TYPE_RGBA;
+	GL_pfd.cColorBits = this->gl_config.buffer_size;
+	GL_pfd.cRedBits = this->gl_config.red_size;
+	GL_pfd.cGreenBits = this->gl_config.green_size;
+	GL_pfd.cBlueBits = this->gl_config.blue_size;
+	GL_pfd.cAlphaBits = this->gl_config.alpha_size;
+	GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
+	GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
+	GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
+	GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
+	GL_pfd.cAccumBits =
+		(GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
+		 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
+	GL_pfd.cDepthBits = this->gl_config.depth_size;
+	GL_pfd.cStencilBits = this->gl_config.stencil_size;
+
+	/* setup WGL_ARB_pixel_format attribs */
+	iAttr = &iAttribs[0];
+
+	*iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
+	*iAttr++ = GL_TRUE;
+	*iAttr++ = WGL_ACCELERATION_ARB;
+	*iAttr++ = WGL_FULL_ACCELERATION_ARB;
+	*iAttr++ = WGL_RED_BITS_ARB;
+	*iAttr++ = this->gl_config.red_size;
+	*iAttr++ = WGL_GREEN_BITS_ARB;
+	*iAttr++ = this->gl_config.green_size;
+	*iAttr++ = WGL_BLUE_BITS_ARB;
+	*iAttr++ = this->gl_config.blue_size;
+	
+	if ( this->gl_config.alpha_size ) {
+		*iAttr++ = WGL_ALPHA_BITS_ARB;
+		*iAttr++ = this->gl_config.alpha_size;
+	}
+
+	*iAttr++ = WGL_DOUBLE_BUFFER_ARB;
+	*iAttr++ = this->gl_config.double_buffer;
+
+	*iAttr++ = WGL_DEPTH_BITS_ARB;
+	*iAttr++ = this->gl_config.depth_size;
+
+	if ( this->gl_config.stencil_size ) {
+		*iAttr++ = WGL_STENCIL_BITS_ARB;
+		*iAttr++ = this->gl_config.stencil_size;
+	}
+
+	if ( this->gl_config.accum_red_size ) {
+		*iAttr++ = WGL_ACCUM_RED_BITS_ARB;
+		*iAttr++ = this->gl_config.accum_red_size;
+	}
+
+	if ( this->gl_config.accum_green_size ) {
+		*iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
+		*iAttr++ = this->gl_config.accum_green_size;
+	}
+
+	if ( this->gl_config.accum_blue_size ) {
+		*iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
+		*iAttr++ = this->gl_config.accum_blue_size;
+	}
+
+	if ( this->gl_config.accum_alpha_size ) {
+		*iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
+		*iAttr++ = this->gl_config.accum_alpha_size;
+	}
+
+	if ( this->gl_config.stereo ) {
+		*iAttr++ = WGL_STEREO_ARB;
+		*iAttr++ = GL_TRUE;
+	}
+
+	if ( this->gl_config.multisamplebuffers ) {
+		*iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
+		*iAttr++ = this->gl_config.multisamplebuffers;
+	}
+
+	if ( this->gl_config.multisamplesamples ) {
+		*iAttr++ = WGL_SAMPLES_ARB;
+		*iAttr++ = this->gl_config.multisamplesamples;
+	}
+
+	if ( this->gl_config.accelerated >= 0 ) {
+		*iAttr++ = WGL_ACCELERATION_ARB;
+		*iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB);
+	}
+
+	*iAttr = 0;
+
+	for ( i=0; ; ++i ) {
+		/* Get the window device context for our OpenGL drawing */
+		GL_hdc = GetDC(SDL_Window);
+		if ( GL_hdc == NULL ) {
+			SDL_SetError("Unable to get DC for SDL_Window");
+			return(-1);
+		}
+
+		/* Choose and set the closest available pixel format */
+		pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs);
+		if ( !pixel_format ) {
+			pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
+		}
+		if ( !pixel_format ) {
+			SDL_SetError("No matching GL pixel format available");
+			return(-1);
+		}
+		if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
+			if ( i == 0 ) {
+				/* First time through, try resetting the window */
+				if ( WIN_GL_ResetWindow(this) < 0 ) {
+					return(-1);
+				}
+				continue;
+			}
+			SDL_SetError("Unable to set HDC pixel format");
+			return(-1);
+		}
+		/* We either succeeded or failed by this point */
+		break;
+	}
+	DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
+
+	GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
+	if ( GL_hrc == NULL ) {
+		SDL_SetError("Unable to create GL context");
+		return(-1);
+	}
+	if ( WIN_GL_MakeCurrent(this) < 0 ) {
+		return(-1);
+	}
+	gl_active = 1;
+
+	/* Get the wglGetPixelFormatAttribivARB pointer for the context */
+	if ( this->gl_data->WGL_ARB_pixel_format ) {
+		this->gl_data->wglGetPixelFormatAttribivARB =
+			(BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *))
+			this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
+	} else {
+		this->gl_data->wglGetPixelFormatAttribivARB = NULL;
+	}
+
+	/* Vsync control under Windows.  Checking glGetString here is
+	 * somewhat a documented and reliable hack - it was originally
+	 * as a feature added by mistake, but since so many people rely
+	 * on it, it will not be removed.  strstr should be safe here.*/
+	glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString");
+	if ( glGetStringFunc ) {
+		wglext = (const char *)glGetStringFunc(GL_EXTENSIONS);
+	} else {
+		/* Uh oh, something is seriously wrong here... */
+		wglext = NULL;
+	}
+	if ( wglext && SDL_strstr(wglext, "WGL_EXT_swap_control") ) {
+		this->gl_data->wglSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT");
+		this->gl_data->wglGetSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT");
+	} else {
+		this->gl_data->wglSwapIntervalEXT = NULL;
+		this->gl_data->wglGetSwapIntervalEXT = NULL;
+	}
+	if ( this->gl_config.swap_control >= 0 ) {
+		if ( this->gl_data->wglSwapIntervalEXT ) {
+			this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control);
+		}
+	}
+#else
+	SDL_SetError("WIN driver not configured with OpenGL");
+#endif
+	if ( gl_active ) {
+		retval = 0;
+	} else {
+		retval = -1;
+	}
+	return(retval);
+}
+
+void WIN_GL_ShutDown(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+	/* Clean up OpenGL */
+	if ( GL_hrc ) {
+		this->gl_data->wglMakeCurrent(NULL, NULL);
+		this->gl_data->wglDeleteContext(GL_hrc);
+		GL_hrc = NULL;
+	}
+	if ( GL_hdc ) {
+		ReleaseDC(SDL_Window, GL_hdc);
+		GL_hdc = NULL;
+	}
+	gl_active = 0;
+
+	WIN_GL_UnloadLibrary(this);
+#endif /* SDL_VIDEO_OPENGL */
+}
+
+#if SDL_VIDEO_OPENGL
+
+/* Make the current context active */
+int WIN_GL_MakeCurrent(_THIS)
+{
+	int retval;
+
+	retval = 0;
+	if ( ! this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc) ) {
+		SDL_SetError("Unable to make GL context current");
+		retval = -1;
+	}
+	return(retval);
+}
+
+/* Get attribute data from wgl. */
+int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+	int retval;
+
+	if (attrib == SDL_GL_SWAP_CONTROL) {
+		if ( this->gl_data->wglGetSwapIntervalEXT ) {
+			*value = this->gl_data->wglGetSwapIntervalEXT();
+			return 0;
+		}
+		return -1;
+	}
+
+	if ( this->gl_data->wglGetPixelFormatAttribivARB ) {
+		int wgl_attrib;
+
+		switch(attrib) {
+		    case SDL_GL_RED_SIZE:
+			wgl_attrib = WGL_RED_BITS_ARB;
+			break;
+		    case SDL_GL_GREEN_SIZE:
+			wgl_attrib = WGL_GREEN_BITS_ARB;
+			break;
+		    case SDL_GL_BLUE_SIZE:
+			wgl_attrib = WGL_BLUE_BITS_ARB;
+			break;
+		    case SDL_GL_ALPHA_SIZE:
+			wgl_attrib = WGL_ALPHA_BITS_ARB;
+			break;
+		    case SDL_GL_DOUBLEBUFFER:
+			wgl_attrib = WGL_DOUBLE_BUFFER_ARB;
+			break;
+		    case SDL_GL_BUFFER_SIZE:
+			wgl_attrib = WGL_COLOR_BITS_ARB;
+			break;
+		    case SDL_GL_DEPTH_SIZE:
+			wgl_attrib = WGL_DEPTH_BITS_ARB;
+			break;
+		    case SDL_GL_STENCIL_SIZE:
+			wgl_attrib = WGL_STENCIL_BITS_ARB;
+			break;
+		    case SDL_GL_ACCUM_RED_SIZE:
+			wgl_attrib = WGL_ACCUM_RED_BITS_ARB;
+			break;
+		    case SDL_GL_ACCUM_GREEN_SIZE:
+			wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB;
+			break;
+		    case SDL_GL_ACCUM_BLUE_SIZE:
+			wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB;
+			break;
+		    case SDL_GL_ACCUM_ALPHA_SIZE:
+			wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB;
+			break;
+		    case SDL_GL_STEREO:
+			wgl_attrib = WGL_STEREO_ARB;
+			break;
+		    case SDL_GL_MULTISAMPLEBUFFERS:
+			wgl_attrib = WGL_SAMPLE_BUFFERS_ARB;
+			break;
+		    case SDL_GL_MULTISAMPLESAMPLES:
+			wgl_attrib = WGL_SAMPLES_ARB;
+			break;
+		    case SDL_GL_ACCELERATED_VISUAL:
+			wgl_attrib = WGL_ACCELERATION_ARB;
+			this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value);
+			if ( *value == WGL_NO_ACCELERATION_ARB ) {
+				*value = SDL_FALSE;
+			} else {
+				*value = SDL_TRUE;
+			}
+			return 0;
+		    default:
+			return(-1);
+		}
+		this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value);
+
+		return 0;
+	}
+
+	retval = 0;
+	switch ( attrib ) {
+	    case SDL_GL_RED_SIZE:
+		*value = GL_pfd.cRedBits;
+		break;
+	    case SDL_GL_GREEN_SIZE:
+		*value = GL_pfd.cGreenBits;
+		break;
+	    case SDL_GL_BLUE_SIZE:
+		*value = GL_pfd.cBlueBits;
+		break;
+	    case SDL_GL_ALPHA_SIZE:
+		*value = GL_pfd.cAlphaBits;
+		break;
+	    case SDL_GL_DOUBLEBUFFER:
+		if ( GL_pfd.dwFlags & PFD_DOUBLEBUFFER ) {
+			*value = 1;
+		} else {
+			*value = 0;
+		}
+		break;
+	    case SDL_GL_BUFFER_SIZE:
+		*value = GL_pfd.cColorBits;
+		break;
+	    case SDL_GL_DEPTH_SIZE:
+		*value = GL_pfd.cDepthBits;
+		break;
+	    case SDL_GL_STENCIL_SIZE:
+		*value = GL_pfd.cStencilBits;
+		break;
+	    case SDL_GL_ACCUM_RED_SIZE:
+		*value = GL_pfd.cAccumRedBits;
+		break;
+	    case SDL_GL_ACCUM_GREEN_SIZE:
+		*value = GL_pfd.cAccumGreenBits;
+		break;
+	    case SDL_GL_ACCUM_BLUE_SIZE:
+		*value = GL_pfd.cAccumBlueBits;
+		break;
+	    case SDL_GL_ACCUM_ALPHA_SIZE:
+		*value = GL_pfd.cAccumAlphaBits;
+		break;
+	    case SDL_GL_STEREO:
+		if ( GL_pfd.dwFlags & PFD_STEREO ) {
+			*value = 1;
+		} else {
+			*value = 0;
+		}
+		break;
+	    case SDL_GL_MULTISAMPLEBUFFERS:
+		*value = 0;
+		break;
+	    case SDL_GL_MULTISAMPLESAMPLES:
+		*value = 1;
+		break;
+	    case SDL_GL_SWAP_CONTROL:
+		if ( this->gl_data->wglGetSwapIntervalEXT ) {
+			*value = this->gl_data->wglGetSwapIntervalEXT();
+			return 0;
+		} else {
+			return -1;
+		}
+		break;
+	    default:
+		retval = -1;
+		break;
+	}
+	return retval;
+}
+
+void WIN_GL_SwapBuffers(_THIS)
+{
+	SwapBuffers(GL_hdc);
+}
+
+void WIN_GL_UnloadLibrary(_THIS)
+{
+	if ( this->gl_config.driver_loaded ) {
+		FreeLibrary((HMODULE)this->gl_config.dll_handle);
+
+		this->gl_data->wglGetProcAddress = NULL;
+		this->gl_data->wglCreateContext = NULL;
+		this->gl_data->wglDeleteContext = NULL;
+		this->gl_data->wglMakeCurrent = NULL;
+		this->gl_data->wglGetPixelFormatAttribivARB = NULL;
+		this->gl_data->wglSwapIntervalEXT = NULL;
+		this->gl_data->wglGetSwapIntervalEXT = NULL;
+
+		this->gl_config.dll_handle = NULL;
+		this->gl_config.driver_loaded = 0;
+	}
+}
+
+/* Passing a NULL path means load pointers from the application */
+int WIN_GL_LoadLibrary(_THIS, const char* path) 
+{
+	HMODULE handle;
+
+ 	if ( gl_active ) {
+ 		SDL_SetError("OpenGL context already created");
+ 		return -1;
+ 	}
+
+	if ( path == NULL ) {
+		path = DEFAULT_GL_DRIVER_PATH;
+	}
+	handle = LoadLibrary(path);
+	if ( handle == NULL ) {
+		SDL_SetError("Could not load OpenGL library");
+		return -1;
+	}
+
+	/* Unload the old driver and reset the pointers */
+	WIN_GL_UnloadLibrary(this);
+
+	/* Load new function pointers */
+	SDL_memset(this->gl_data, 0, sizeof(*this->gl_data));
+	this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *))
+		GetProcAddress(handle, "wglGetProcAddress");
+	this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC))
+		GetProcAddress(handle, "wglCreateContext");
+	this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC))
+		GetProcAddress(handle, "wglDeleteContext");
+	this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC))
+		GetProcAddress(handle, "wglMakeCurrent");
+	this->gl_data->wglSwapIntervalEXT = (void (WINAPI *)(int))
+		GetProcAddress(handle, "wglSwapIntervalEXT");
+	this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *)(void))
+		GetProcAddress(handle, "wglGetSwapIntervalEXT");
+
+	if ( (this->gl_data->wglGetProcAddress == NULL) ||
+	     (this->gl_data->wglCreateContext == NULL) ||
+	     (this->gl_data->wglDeleteContext == NULL) ||
+	     (this->gl_data->wglMakeCurrent == NULL) ) {
+		SDL_SetError("Could not retrieve OpenGL functions");
+		FreeLibrary(handle);
+		return -1;
+	}
+
+	this->gl_config.dll_handle = handle;
+	SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path));
+	this->gl_config.driver_loaded = 1;
+	return 0;
+}
+
+void *WIN_GL_GetProcAddress(_THIS, const char* proc)
+{
+	void *func;
+
+	/* This is to pick up extensions */
+	func = this->gl_data->wglGetProcAddress(proc);
+	if ( ! func ) {
+		/* This is probably a normal GL function */
+		func = GetProcAddress(this->gl_config.dll_handle, proc);
+	}
+	return func;
+}
+
+#endif /* SDL_VIDEO_OPENGL */