symbian-qemu-0.9.1-12/libsdl-trunk/src/video/wincommon/SDL_wingl.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2006 Sam Lantinga
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Lesser General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2.1 of the License, or (at your option) any later version.
       
     9 
       
    10     This library is distributed in the hope that it will be useful,
       
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13     Lesser General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Lesser General Public
       
    16     License along with this library; if not, write to the Free Software
       
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 
       
    24 /* WGL implementation of SDL OpenGL support */
       
    25 
       
    26 #if SDL_VIDEO_OPENGL
       
    27 #include "SDL_opengl.h"
       
    28 #endif
       
    29 #include "SDL_lowvideo.h"
       
    30 #include "SDL_wingl_c.h"
       
    31 
       
    32 #if SDL_VIDEO_OPENGL
       
    33 #define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL"
       
    34 #endif
       
    35 
       
    36 /* If setting the HDC fails, we may need to recreate the window (MSDN) */
       
    37 static int WIN_GL_ResetWindow(_THIS)
       
    38 {
       
    39 	int status = 0;
       
    40 
       
    41 #ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */
       
    42 	/* This doesn't work with DirectX code (see CVS comments) */
       
    43 	/* If we were passed a window, then we can't create a new one */
       
    44 	if ( !SDL_windowid && SDL_strcmp(this->name, "windib") == 0 ) {
       
    45 		/* Save the existing window attributes */
       
    46 		LONG style;
       
    47 		RECT rect = { 0, 0, 0, 0 };
       
    48 		style = GetWindowLong(SDL_Window, GWL_STYLE);
       
    49 		GetWindowRect(SDL_Window, &rect);
       
    50 		DestroyWindow(SDL_Window);
       
    51 		WIN_FlushMessageQueue();
       
    52 
       
    53 		SDL_resizing = 1;
       
    54 		SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
       
    55 		                          style,
       
    56 		                          rect.left, rect.top,
       
    57 		                          (rect.right-rect.left)+1,
       
    58 		                          (rect.bottom-rect.top)+1,
       
    59 		                          NULL, NULL, SDL_Instance, NULL);
       
    60 		WIN_FlushMessageQueue();
       
    61 		SDL_resizing = 0;
       
    62 
       
    63 		if ( SDL_Window ) {
       
    64 			this->SetCaption(this, this->wm_title, this->wm_icon);
       
    65 		} else {
       
    66 			SDL_SetError("Couldn't create window");
       
    67 			status = -1;
       
    68 		}
       
    69 	} else
       
    70 #endif /* !_WIN32_WCE */
       
    71 	{
       
    72 		SDL_SetError("Unable to reset window for OpenGL context");
       
    73 		status = -1;
       
    74 	}
       
    75 	return(status);
       
    76 }
       
    77 
       
    78 #if SDL_VIDEO_OPENGL
       
    79 
       
    80 static int ExtensionSupported(const char *extension, const char *extensions)
       
    81 {
       
    82 	const char *start;
       
    83 	const char *where, *terminator;
       
    84 
       
    85 	/* Extension names should not have spaces. */
       
    86 	where = SDL_strchr(extension, ' ');
       
    87 	if ( where || *extension == '\0' )
       
    88 	      return 0;
       
    89 	
       
    90 	if ( ! extensions )
       
    91 		return 0;
       
    92 
       
    93 	/* It takes a bit of care to be fool-proof about parsing the
       
    94 	 *      OpenGL extensions string. Don't be fooled by sub-strings,
       
    95 	 *           etc. */
       
    96 	
       
    97 	start = extensions;
       
    98 	
       
    99 	for (;;)
       
   100 	{
       
   101 		where = SDL_strstr(start, extension);
       
   102 		if (!where) break;
       
   103 		
       
   104 		terminator = where + SDL_strlen(extension);
       
   105 		if (where == start || *(where - 1) == ' ')
       
   106 	        if (*terminator == ' ' || *terminator == '\0') return 1;
       
   107 
       
   108 		start = terminator;
       
   109 	}
       
   110 	
       
   111 	return 0;
       
   112 }
       
   113 
       
   114 static int ChoosePixelFormatARB(_THIS, const int *iAttribs, const FLOAT *fAttribs)
       
   115 {
       
   116 	HWND hwnd;
       
   117 	HDC hdc;
       
   118 	HGLRC hglrc;
       
   119 	const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0;
       
   120 	const char *extensions;
       
   121 	int pformat = 0;
       
   122 	UINT matches = 0;
       
   123 
       
   124 	hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED,
       
   125 	                    0, 0, 10, 10,
       
   126 	                    NULL, NULL, SDL_Instance, NULL);
       
   127 	WIN_FlushMessageQueue();
       
   128 
       
   129 	hdc = GetDC(hwnd);
       
   130 
       
   131 	SetPixelFormat(hdc, ChoosePixelFormat(hdc, &GL_pfd), &GL_pfd);
       
   132 
       
   133 	hglrc = this->gl_data->wglCreateContext(hdc);
       
   134 	if ( hglrc ) {
       
   135 		this->gl_data->wglMakeCurrent(hdc, hglrc);
       
   136 	}
       
   137 
       
   138 	wglGetExtensionsStringARB = (const char * (WINAPI *)(HDC))
       
   139 		this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
       
   140 
       
   141 	if( wglGetExtensionsStringARB ) {
       
   142 		extensions = wglGetExtensionsStringARB(hdc);
       
   143 	} else {
       
   144 		extensions = NULL;
       
   145 	}
       
   146 
       
   147 	this->gl_data->WGL_ARB_pixel_format = 0;
       
   148 	if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) {
       
   149 		BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
       
   150 		wglChoosePixelFormatARB =
       
   151 			(BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *))
       
   152 			this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB");
       
   153 		if( wglChoosePixelFormatARB &&
       
   154 		    wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pformat, &matches) && pformat ) {
       
   155 			this->gl_data->WGL_ARB_pixel_format = 1;
       
   156 		}
       
   157 	}
       
   158 	
       
   159 	if ( hglrc ) {
       
   160 		this->gl_data->wglMakeCurrent(NULL, NULL);
       
   161 		this->gl_data->wglDeleteContext(hglrc);
       
   162 	}
       
   163 	ReleaseDC(hwnd, hdc);
       
   164 	DestroyWindow(hwnd);
       
   165 	WIN_FlushMessageQueue();
       
   166 
       
   167 	return pformat;
       
   168 }
       
   169 
       
   170 #endif /* SDL_VIDEO_OPENGL */
       
   171 
       
   172 int WIN_GL_SetupWindow(_THIS)
       
   173 {
       
   174 	int retval;
       
   175 #if SDL_VIDEO_OPENGL
       
   176 	int i;
       
   177 	int iAttribs[64];
       
   178 	int *iAttr;
       
   179 	float fAttribs[1] = { 0 };
       
   180 	const GLubyte *(WINAPI *glGetStringFunc)(GLenum);
       
   181 	const char *wglext;
       
   182 
       
   183 	/* load the gl driver from a default path */
       
   184 	if ( ! this->gl_config.driver_loaded ) {
       
   185 		/* no driver has been loaded, use default (ourselves) */
       
   186 		if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) {
       
   187 			return(-1);
       
   188 		}
       
   189 	}
       
   190 
       
   191 	/* Set up the pixel format descriptor with our needed format */
       
   192 	SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
       
   193 	GL_pfd.nSize = sizeof(GL_pfd);
       
   194 	GL_pfd.nVersion = 1;
       
   195 	GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
       
   196 	if ( this->gl_config.double_buffer ) {
       
   197 		GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
       
   198 	}
       
   199 	if ( this->gl_config.stereo ) {
       
   200 		GL_pfd.dwFlags |= PFD_STEREO;
       
   201 	}
       
   202 	GL_pfd.iPixelType = PFD_TYPE_RGBA;
       
   203 	GL_pfd.cColorBits = this->gl_config.buffer_size;
       
   204 	GL_pfd.cRedBits = this->gl_config.red_size;
       
   205 	GL_pfd.cGreenBits = this->gl_config.green_size;
       
   206 	GL_pfd.cBlueBits = this->gl_config.blue_size;
       
   207 	GL_pfd.cAlphaBits = this->gl_config.alpha_size;
       
   208 	GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
       
   209 	GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
       
   210 	GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
       
   211 	GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
       
   212 	GL_pfd.cAccumBits =
       
   213 		(GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
       
   214 		 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
       
   215 	GL_pfd.cDepthBits = this->gl_config.depth_size;
       
   216 	GL_pfd.cStencilBits = this->gl_config.stencil_size;
       
   217 
       
   218 	/* setup WGL_ARB_pixel_format attribs */
       
   219 	iAttr = &iAttribs[0];
       
   220 
       
   221 	*iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
       
   222 	*iAttr++ = GL_TRUE;
       
   223 	*iAttr++ = WGL_ACCELERATION_ARB;
       
   224 	*iAttr++ = WGL_FULL_ACCELERATION_ARB;
       
   225 	*iAttr++ = WGL_RED_BITS_ARB;
       
   226 	*iAttr++ = this->gl_config.red_size;
       
   227 	*iAttr++ = WGL_GREEN_BITS_ARB;
       
   228 	*iAttr++ = this->gl_config.green_size;
       
   229 	*iAttr++ = WGL_BLUE_BITS_ARB;
       
   230 	*iAttr++ = this->gl_config.blue_size;
       
   231 	
       
   232 	if ( this->gl_config.alpha_size ) {
       
   233 		*iAttr++ = WGL_ALPHA_BITS_ARB;
       
   234 		*iAttr++ = this->gl_config.alpha_size;
       
   235 	}
       
   236 
       
   237 	*iAttr++ = WGL_DOUBLE_BUFFER_ARB;
       
   238 	*iAttr++ = this->gl_config.double_buffer;
       
   239 
       
   240 	*iAttr++ = WGL_DEPTH_BITS_ARB;
       
   241 	*iAttr++ = this->gl_config.depth_size;
       
   242 
       
   243 	if ( this->gl_config.stencil_size ) {
       
   244 		*iAttr++ = WGL_STENCIL_BITS_ARB;
       
   245 		*iAttr++ = this->gl_config.stencil_size;
       
   246 	}
       
   247 
       
   248 	if ( this->gl_config.accum_red_size ) {
       
   249 		*iAttr++ = WGL_ACCUM_RED_BITS_ARB;
       
   250 		*iAttr++ = this->gl_config.accum_red_size;
       
   251 	}
       
   252 
       
   253 	if ( this->gl_config.accum_green_size ) {
       
   254 		*iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
       
   255 		*iAttr++ = this->gl_config.accum_green_size;
       
   256 	}
       
   257 
       
   258 	if ( this->gl_config.accum_blue_size ) {
       
   259 		*iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
       
   260 		*iAttr++ = this->gl_config.accum_blue_size;
       
   261 	}
       
   262 
       
   263 	if ( this->gl_config.accum_alpha_size ) {
       
   264 		*iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
       
   265 		*iAttr++ = this->gl_config.accum_alpha_size;
       
   266 	}
       
   267 
       
   268 	if ( this->gl_config.stereo ) {
       
   269 		*iAttr++ = WGL_STEREO_ARB;
       
   270 		*iAttr++ = GL_TRUE;
       
   271 	}
       
   272 
       
   273 	if ( this->gl_config.multisamplebuffers ) {
       
   274 		*iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
       
   275 		*iAttr++ = this->gl_config.multisamplebuffers;
       
   276 	}
       
   277 
       
   278 	if ( this->gl_config.multisamplesamples ) {
       
   279 		*iAttr++ = WGL_SAMPLES_ARB;
       
   280 		*iAttr++ = this->gl_config.multisamplesamples;
       
   281 	}
       
   282 
       
   283 	if ( this->gl_config.accelerated >= 0 ) {
       
   284 		*iAttr++ = WGL_ACCELERATION_ARB;
       
   285 		*iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB);
       
   286 	}
       
   287 
       
   288 	*iAttr = 0;
       
   289 
       
   290 	for ( i=0; ; ++i ) {
       
   291 		/* Get the window device context for our OpenGL drawing */
       
   292 		GL_hdc = GetDC(SDL_Window);
       
   293 		if ( GL_hdc == NULL ) {
       
   294 			SDL_SetError("Unable to get DC for SDL_Window");
       
   295 			return(-1);
       
   296 		}
       
   297 
       
   298 		/* Choose and set the closest available pixel format */
       
   299 		pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs);
       
   300 		if ( !pixel_format ) {
       
   301 			pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
       
   302 		}
       
   303 		if ( !pixel_format ) {
       
   304 			SDL_SetError("No matching GL pixel format available");
       
   305 			return(-1);
       
   306 		}
       
   307 		if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
       
   308 			if ( i == 0 ) {
       
   309 				/* First time through, try resetting the window */
       
   310 				if ( WIN_GL_ResetWindow(this) < 0 ) {
       
   311 					return(-1);
       
   312 				}
       
   313 				continue;
       
   314 			}
       
   315 			SDL_SetError("Unable to set HDC pixel format");
       
   316 			return(-1);
       
   317 		}
       
   318 		/* We either succeeded or failed by this point */
       
   319 		break;
       
   320 	}
       
   321 	DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);
       
   322 
       
   323 	GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
       
   324 	if ( GL_hrc == NULL ) {
       
   325 		SDL_SetError("Unable to create GL context");
       
   326 		return(-1);
       
   327 	}
       
   328 	if ( WIN_GL_MakeCurrent(this) < 0 ) {
       
   329 		return(-1);
       
   330 	}
       
   331 	gl_active = 1;
       
   332 
       
   333 	/* Get the wglGetPixelFormatAttribivARB pointer for the context */
       
   334 	if ( this->gl_data->WGL_ARB_pixel_format ) {
       
   335 		this->gl_data->wglGetPixelFormatAttribivARB =
       
   336 			(BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *))
       
   337 			this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
       
   338 	} else {
       
   339 		this->gl_data->wglGetPixelFormatAttribivARB = NULL;
       
   340 	}
       
   341 
       
   342 	/* Vsync control under Windows.  Checking glGetString here is
       
   343 	 * somewhat a documented and reliable hack - it was originally
       
   344 	 * as a feature added by mistake, but since so many people rely
       
   345 	 * on it, it will not be removed.  strstr should be safe here.*/
       
   346 	glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString");
       
   347 	if ( glGetStringFunc ) {
       
   348 		wglext = (const char *)glGetStringFunc(GL_EXTENSIONS);
       
   349 	} else {
       
   350 		/* Uh oh, something is seriously wrong here... */
       
   351 		wglext = NULL;
       
   352 	}
       
   353 	if ( wglext && SDL_strstr(wglext, "WGL_EXT_swap_control") ) {
       
   354 		this->gl_data->wglSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT");
       
   355 		this->gl_data->wglGetSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT");
       
   356 	} else {
       
   357 		this->gl_data->wglSwapIntervalEXT = NULL;
       
   358 		this->gl_data->wglGetSwapIntervalEXT = NULL;
       
   359 	}
       
   360 	if ( this->gl_config.swap_control >= 0 ) {
       
   361 		if ( this->gl_data->wglSwapIntervalEXT ) {
       
   362 			this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control);
       
   363 		}
       
   364 	}
       
   365 #else
       
   366 	SDL_SetError("WIN driver not configured with OpenGL");
       
   367 #endif
       
   368 	if ( gl_active ) {
       
   369 		retval = 0;
       
   370 	} else {
       
   371 		retval = -1;
       
   372 	}
       
   373 	return(retval);
       
   374 }
       
   375 
       
   376 void WIN_GL_ShutDown(_THIS)
       
   377 {
       
   378 #if SDL_VIDEO_OPENGL
       
   379 	/* Clean up OpenGL */
       
   380 	if ( GL_hrc ) {
       
   381 		this->gl_data->wglMakeCurrent(NULL, NULL);
       
   382 		this->gl_data->wglDeleteContext(GL_hrc);
       
   383 		GL_hrc = NULL;
       
   384 	}
       
   385 	if ( GL_hdc ) {
       
   386 		ReleaseDC(SDL_Window, GL_hdc);
       
   387 		GL_hdc = NULL;
       
   388 	}
       
   389 	gl_active = 0;
       
   390 
       
   391 	WIN_GL_UnloadLibrary(this);
       
   392 #endif /* SDL_VIDEO_OPENGL */
       
   393 }
       
   394 
       
   395 #if SDL_VIDEO_OPENGL
       
   396 
       
   397 /* Make the current context active */
       
   398 int WIN_GL_MakeCurrent(_THIS)
       
   399 {
       
   400 	int retval;
       
   401 
       
   402 	retval = 0;
       
   403 	if ( ! this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc) ) {
       
   404 		SDL_SetError("Unable to make GL context current");
       
   405 		retval = -1;
       
   406 	}
       
   407 	return(retval);
       
   408 }
       
   409 
       
   410 /* Get attribute data from wgl. */
       
   411 int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
       
   412 {
       
   413 	int retval;
       
   414 
       
   415 	if (attrib == SDL_GL_SWAP_CONTROL) {
       
   416 		if ( this->gl_data->wglGetSwapIntervalEXT ) {
       
   417 			*value = this->gl_data->wglGetSwapIntervalEXT();
       
   418 			return 0;
       
   419 		}
       
   420 		return -1;
       
   421 	}
       
   422 
       
   423 	if ( this->gl_data->wglGetPixelFormatAttribivARB ) {
       
   424 		int wgl_attrib;
       
   425 
       
   426 		switch(attrib) {
       
   427 		    case SDL_GL_RED_SIZE:
       
   428 			wgl_attrib = WGL_RED_BITS_ARB;
       
   429 			break;
       
   430 		    case SDL_GL_GREEN_SIZE:
       
   431 			wgl_attrib = WGL_GREEN_BITS_ARB;
       
   432 			break;
       
   433 		    case SDL_GL_BLUE_SIZE:
       
   434 			wgl_attrib = WGL_BLUE_BITS_ARB;
       
   435 			break;
       
   436 		    case SDL_GL_ALPHA_SIZE:
       
   437 			wgl_attrib = WGL_ALPHA_BITS_ARB;
       
   438 			break;
       
   439 		    case SDL_GL_DOUBLEBUFFER:
       
   440 			wgl_attrib = WGL_DOUBLE_BUFFER_ARB;
       
   441 			break;
       
   442 		    case SDL_GL_BUFFER_SIZE:
       
   443 			wgl_attrib = WGL_COLOR_BITS_ARB;
       
   444 			break;
       
   445 		    case SDL_GL_DEPTH_SIZE:
       
   446 			wgl_attrib = WGL_DEPTH_BITS_ARB;
       
   447 			break;
       
   448 		    case SDL_GL_STENCIL_SIZE:
       
   449 			wgl_attrib = WGL_STENCIL_BITS_ARB;
       
   450 			break;
       
   451 		    case SDL_GL_ACCUM_RED_SIZE:
       
   452 			wgl_attrib = WGL_ACCUM_RED_BITS_ARB;
       
   453 			break;
       
   454 		    case SDL_GL_ACCUM_GREEN_SIZE:
       
   455 			wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB;
       
   456 			break;
       
   457 		    case SDL_GL_ACCUM_BLUE_SIZE:
       
   458 			wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB;
       
   459 			break;
       
   460 		    case SDL_GL_ACCUM_ALPHA_SIZE:
       
   461 			wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB;
       
   462 			break;
       
   463 		    case SDL_GL_STEREO:
       
   464 			wgl_attrib = WGL_STEREO_ARB;
       
   465 			break;
       
   466 		    case SDL_GL_MULTISAMPLEBUFFERS:
       
   467 			wgl_attrib = WGL_SAMPLE_BUFFERS_ARB;
       
   468 			break;
       
   469 		    case SDL_GL_MULTISAMPLESAMPLES:
       
   470 			wgl_attrib = WGL_SAMPLES_ARB;
       
   471 			break;
       
   472 		    case SDL_GL_ACCELERATED_VISUAL:
       
   473 			wgl_attrib = WGL_ACCELERATION_ARB;
       
   474 			this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value);
       
   475 			if ( *value == WGL_NO_ACCELERATION_ARB ) {
       
   476 				*value = SDL_FALSE;
       
   477 			} else {
       
   478 				*value = SDL_TRUE;
       
   479 			}
       
   480 			return 0;
       
   481 		    default:
       
   482 			return(-1);
       
   483 		}
       
   484 		this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value);
       
   485 
       
   486 		return 0;
       
   487 	}
       
   488 
       
   489 	retval = 0;
       
   490 	switch ( attrib ) {
       
   491 	    case SDL_GL_RED_SIZE:
       
   492 		*value = GL_pfd.cRedBits;
       
   493 		break;
       
   494 	    case SDL_GL_GREEN_SIZE:
       
   495 		*value = GL_pfd.cGreenBits;
       
   496 		break;
       
   497 	    case SDL_GL_BLUE_SIZE:
       
   498 		*value = GL_pfd.cBlueBits;
       
   499 		break;
       
   500 	    case SDL_GL_ALPHA_SIZE:
       
   501 		*value = GL_pfd.cAlphaBits;
       
   502 		break;
       
   503 	    case SDL_GL_DOUBLEBUFFER:
       
   504 		if ( GL_pfd.dwFlags & PFD_DOUBLEBUFFER ) {
       
   505 			*value = 1;
       
   506 		} else {
       
   507 			*value = 0;
       
   508 		}
       
   509 		break;
       
   510 	    case SDL_GL_BUFFER_SIZE:
       
   511 		*value = GL_pfd.cColorBits;
       
   512 		break;
       
   513 	    case SDL_GL_DEPTH_SIZE:
       
   514 		*value = GL_pfd.cDepthBits;
       
   515 		break;
       
   516 	    case SDL_GL_STENCIL_SIZE:
       
   517 		*value = GL_pfd.cStencilBits;
       
   518 		break;
       
   519 	    case SDL_GL_ACCUM_RED_SIZE:
       
   520 		*value = GL_pfd.cAccumRedBits;
       
   521 		break;
       
   522 	    case SDL_GL_ACCUM_GREEN_SIZE:
       
   523 		*value = GL_pfd.cAccumGreenBits;
       
   524 		break;
       
   525 	    case SDL_GL_ACCUM_BLUE_SIZE:
       
   526 		*value = GL_pfd.cAccumBlueBits;
       
   527 		break;
       
   528 	    case SDL_GL_ACCUM_ALPHA_SIZE:
       
   529 		*value = GL_pfd.cAccumAlphaBits;
       
   530 		break;
       
   531 	    case SDL_GL_STEREO:
       
   532 		if ( GL_pfd.dwFlags & PFD_STEREO ) {
       
   533 			*value = 1;
       
   534 		} else {
       
   535 			*value = 0;
       
   536 		}
       
   537 		break;
       
   538 	    case SDL_GL_MULTISAMPLEBUFFERS:
       
   539 		*value = 0;
       
   540 		break;
       
   541 	    case SDL_GL_MULTISAMPLESAMPLES:
       
   542 		*value = 1;
       
   543 		break;
       
   544 	    case SDL_GL_SWAP_CONTROL:
       
   545 		if ( this->gl_data->wglGetSwapIntervalEXT ) {
       
   546 			*value = this->gl_data->wglGetSwapIntervalEXT();
       
   547 			return 0;
       
   548 		} else {
       
   549 			return -1;
       
   550 		}
       
   551 		break;
       
   552 	    default:
       
   553 		retval = -1;
       
   554 		break;
       
   555 	}
       
   556 	return retval;
       
   557 }
       
   558 
       
   559 void WIN_GL_SwapBuffers(_THIS)
       
   560 {
       
   561 	SwapBuffers(GL_hdc);
       
   562 }
       
   563 
       
   564 void WIN_GL_UnloadLibrary(_THIS)
       
   565 {
       
   566 	if ( this->gl_config.driver_loaded ) {
       
   567 		FreeLibrary((HMODULE)this->gl_config.dll_handle);
       
   568 
       
   569 		this->gl_data->wglGetProcAddress = NULL;
       
   570 		this->gl_data->wglCreateContext = NULL;
       
   571 		this->gl_data->wglDeleteContext = NULL;
       
   572 		this->gl_data->wglMakeCurrent = NULL;
       
   573 		this->gl_data->wglGetPixelFormatAttribivARB = NULL;
       
   574 		this->gl_data->wglSwapIntervalEXT = NULL;
       
   575 		this->gl_data->wglGetSwapIntervalEXT = NULL;
       
   576 
       
   577 		this->gl_config.dll_handle = NULL;
       
   578 		this->gl_config.driver_loaded = 0;
       
   579 	}
       
   580 }
       
   581 
       
   582 /* Passing a NULL path means load pointers from the application */
       
   583 int WIN_GL_LoadLibrary(_THIS, const char* path) 
       
   584 {
       
   585 	HMODULE handle;
       
   586 
       
   587  	if ( gl_active ) {
       
   588  		SDL_SetError("OpenGL context already created");
       
   589  		return -1;
       
   590  	}
       
   591 
       
   592 	if ( path == NULL ) {
       
   593 		path = DEFAULT_GL_DRIVER_PATH;
       
   594 	}
       
   595 	handle = LoadLibrary(path);
       
   596 	if ( handle == NULL ) {
       
   597 		SDL_SetError("Could not load OpenGL library");
       
   598 		return -1;
       
   599 	}
       
   600 
       
   601 	/* Unload the old driver and reset the pointers */
       
   602 	WIN_GL_UnloadLibrary(this);
       
   603 
       
   604 	/* Load new function pointers */
       
   605 	SDL_memset(this->gl_data, 0, sizeof(*this->gl_data));
       
   606 	this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *))
       
   607 		GetProcAddress(handle, "wglGetProcAddress");
       
   608 	this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC))
       
   609 		GetProcAddress(handle, "wglCreateContext");
       
   610 	this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC))
       
   611 		GetProcAddress(handle, "wglDeleteContext");
       
   612 	this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC))
       
   613 		GetProcAddress(handle, "wglMakeCurrent");
       
   614 	this->gl_data->wglSwapIntervalEXT = (void (WINAPI *)(int))
       
   615 		GetProcAddress(handle, "wglSwapIntervalEXT");
       
   616 	this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *)(void))
       
   617 		GetProcAddress(handle, "wglGetSwapIntervalEXT");
       
   618 
       
   619 	if ( (this->gl_data->wglGetProcAddress == NULL) ||
       
   620 	     (this->gl_data->wglCreateContext == NULL) ||
       
   621 	     (this->gl_data->wglDeleteContext == NULL) ||
       
   622 	     (this->gl_data->wglMakeCurrent == NULL) ) {
       
   623 		SDL_SetError("Could not retrieve OpenGL functions");
       
   624 		FreeLibrary(handle);
       
   625 		return -1;
       
   626 	}
       
   627 
       
   628 	this->gl_config.dll_handle = handle;
       
   629 	SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path));
       
   630 	this->gl_config.driver_loaded = 1;
       
   631 	return 0;
       
   632 }
       
   633 
       
   634 void *WIN_GL_GetProcAddress(_THIS, const char* proc)
       
   635 {
       
   636 	void *func;
       
   637 
       
   638 	/* This is to pick up extensions */
       
   639 	func = this->gl_data->wglGetProcAddress(proc);
       
   640 	if ( ! func ) {
       
   641 		/* This is probably a normal GL function */
       
   642 		func = GetProcAddress(this->gl_config.dll_handle, proc);
       
   643 	}
       
   644 	return func;
       
   645 }
       
   646 
       
   647 #endif /* SDL_VIDEO_OPENGL */