wined3d: Check more thoroughly if a stage references a texture.
[wine/hacks.git] / dlls / opengl32 / wgl.c
blobca6702f179df1d7a9e5dcf42f565cff4b43e0ece
1 /* Window-specific OpenGL functions implementation.
3 * Copyright (c) 1999 Lionel Ulmer
4 * Copyright (c) 2005 Raphael Junqueira
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "winreg.h"
32 #include "wingdi.h"
33 #include "winternl.h"
34 #include "winnt.h"
36 #include "opengl_ext.h"
37 #ifdef HAVE_GL_GLU_H
38 #undef far
39 #undef near
40 #include <GL/glu.h>
41 #endif
42 #include "wine/library.h"
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
46 WINE_DECLARE_DEBUG_CHANNEL(opengl);
48 typedef struct wine_wgl_s {
49 PROC WINAPI (*p_wglGetProcAddress)(LPCSTR lpszProc);
51 void WINAPI (*p_wglDisable)(GLenum cap);
52 void WINAPI (*p_wglEnable)(GLenum cap);
53 void WINAPI (*p_wglGetIntegerv)(GLenum pname, GLint* params);
54 GLboolean WINAPI (*p_wglIsEnabled)(GLenum cap);
55 void WINAPI (*p_wglScissor)(GLint x, GLint y, GLsizei width, GLsizei height);
56 void WINAPI (*p_wglViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
57 } wine_wgl_t;
59 /** global wgl object */
60 static wine_wgl_t wine_wgl;
62 /* x11drv GDI escapes */
63 #define X11DRV_ESCAPE 6789
64 enum x11drv_escape_codes
66 X11DRV_GET_DISPLAY, /* get X11 display for a DC */
67 X11DRV_GET_DRAWABLE, /* get current drawable for a DC */
68 X11DRV_GET_FONT, /* get current X font for a DC */
69 X11DRV_SET_DRAWABLE, /* set current drawable for a DC */
70 X11DRV_START_EXPOSURES, /* start graphics exposures */
71 X11DRV_END_EXPOSURES, /* end graphics exposures */
72 X11DRV_GET_DCE, /* get the DCE pointer */
73 X11DRV_SET_DCE, /* set the DCE pointer */
74 X11DRV_GET_GLX_DRAWABLE, /* get current glx drawable for a DC */
75 X11DRV_SYNC_PIXMAP /* sync the dibsection to its pixmap */
78 void (*wine_tsx11_lock_ptr)(void) = NULL;
79 void (*wine_tsx11_unlock_ptr)(void) = NULL;
81 static HMODULE opengl32_handle;
83 static char internal_gl_disabled_extensions[512];
84 static char* internal_gl_extensions = NULL;
86 typedef struct wine_glcontext {
87 HDC hdc;
88 XVisualInfo *vis;
89 GLXFBConfig fb_conf;
90 GLXContext ctx;
91 BOOL do_escape;
92 /* ... more stuff here */
93 } Wine_GLContext;
95 void enter_gl(void)
97 Wine_GLContext *curctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
99 if (curctx && curctx->do_escape)
101 enum x11drv_escape_codes escape = X11DRV_SYNC_PIXMAP;
102 ExtEscape(curctx->hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, 0, NULL);
105 wine_tsx11_lock_ptr();
106 return;
109 const GLubyte * WINAPI wine_glGetString( GLenum name );
111 /***********************************************************************
112 * wglCreateLayerContext (OPENGL32.@)
114 HGLRC WINAPI wglCreateLayerContext(HDC hdc,
115 int iLayerPlane) {
116 TRACE("(%p,%d)\n", hdc, iLayerPlane);
118 if (iLayerPlane == 0) {
119 return wglCreateContext(hdc);
121 FIXME(" no handler for layer %d\n", iLayerPlane);
123 return NULL;
126 /***********************************************************************
127 * wglCopyContext (OPENGL32.@)
129 BOOL WINAPI wglCopyContext(HGLRC hglrcSrc,
130 HGLRC hglrcDst,
131 UINT mask) {
132 FIXME("(%p,%p,%d)\n", hglrcSrc, hglrcDst, mask);
134 return FALSE;
137 /***********************************************************************
138 * wglDescribeLayerPlane (OPENGL32.@)
140 BOOL WINAPI wglDescribeLayerPlane(HDC hdc,
141 int iPixelFormat,
142 int iLayerPlane,
143 UINT nBytes,
144 LPLAYERPLANEDESCRIPTOR plpd) {
145 FIXME("(%p,%d,%d,%d,%p)\n", hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
147 return FALSE;
150 /***********************************************************************
151 * wglGetLayerPaletteEntries (OPENGL32.@)
153 int WINAPI wglGetLayerPaletteEntries(HDC hdc,
154 int iLayerPlane,
155 int iStart,
156 int cEntries,
157 const COLORREF *pcr) {
158 FIXME("(): stub !\n");
160 return 0;
163 static int compar(const void *elt_a, const void *elt_b) {
164 return strcmp(((const OpenGL_extension *) elt_a)->name,
165 ((const OpenGL_extension *) elt_b)->name);
168 /* Check if a GL extension is supported */
169 static BOOL is_extension_supported(const char* extension)
171 const char *gl_ext_string = (const char*)wine_glGetString(GL_EXTENSIONS);
173 TRACE("Checking for extension '%s'\n", extension);
175 if(!gl_ext_string) {
176 ERR("No OpenGL extensions found, check if your OpenGL setup is correct!\n");
177 return FALSE;
180 /* We use the GetProcAddress function from the display driver to retrieve function pointers
181 * for OpenGL and WGL extensions. In case of winex11.drv the OpenGL extension lookup is done
182 * using glXGetProcAddress. This function is quite unreliable in the sense that its specs don't
183 * require the function to return NULL when a extension isn't found. For this reason we check
184 * if the OpenGL extension required for the function we are looking up is supported. */
186 /* Check if the extension is part of the GL extension string to see if it is supported. */
187 if(strstr(gl_ext_string, extension) != NULL)
188 return TRUE;
190 /* In general an OpenGL function starts as an ARB/EXT extension and at some stage
191 * it becomes part of the core OpenGL library and can be reached without the ARB/EXT
192 * suffix as well. In the extension table, these functions contain GL_VERSION_major_minor.
193 * Check if we are searching for a core GL function */
194 if(strncmp(extension, "GL_VERSION_", 11) == 0)
196 const GLubyte *gl_version = glGetString(GL_VERSION);
197 const char *version = extension + 11; /* Move past 'GL_VERSION_' */
199 if(!gl_version) {
200 ERR("Error no OpenGL version found,\n");
201 return FALSE;
204 /* Compare the major/minor version numbers of the native OpenGL library and what is required by the function.
205 * The gl_version string is guaranteed to have at least a major/minor and sometimes it has a release number as well. */
206 if( (gl_version[0] >= version[0]) || ((gl_version[0] == version[0]) && (gl_version[2] >= version[2])) ) {
207 return TRUE;
209 WARN("The function requires OpenGL version '%c.%c' while your drivers only provide '%c.%c'\n", version[0], version[2], gl_version[0], gl_version[2]);
212 return FALSE;
215 /***********************************************************************
216 * wglGetProcAddress (OPENGL32.@)
218 PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) {
219 void *local_func;
220 OpenGL_extension ext;
221 const OpenGL_extension *ext_ret;
223 TRACE("(%s)\n", lpszProc);
225 if(lpszProc == NULL)
226 return NULL;
228 /* First, look if it's not already defined in the 'standard' OpenGL functions */
229 if ((local_func = GetProcAddress(opengl32_handle, lpszProc)) != NULL) {
230 TRACE(" found function in 'standard' OpenGL functions (%p)\n", local_func);
231 return local_func;
234 /* After that, search in the thunks to find the real name of the extension */
235 ext.name = lpszProc;
236 ext_ret = (const OpenGL_extension *) bsearch(&ext, extension_registry,
237 extension_registry_size, sizeof(OpenGL_extension), compar);
239 /* If nothing was found, we are looking for a WGL extension or an unknown GL extension. */
240 if (ext_ret == NULL) {
241 /* If the function name starts with a w it is a WGL extension */
242 if(lpszProc[0] == 'w')
243 return wine_wgl.p_wglGetProcAddress(lpszProc);
245 /* We are dealing with an unknown GL extension. */
246 WARN("Extension '%s' not defined in opengl32.dll's function table!\n", lpszProc);
247 return NULL;
248 } else { /* We are looking for an OpenGL extension */
250 /* Check if the GL extension required by the function is available */
251 if(!is_extension_supported(ext_ret->extension)) {
252 WARN("Extension '%s' required by function '%s' not supported!\n", ext_ret->extension, lpszProc);
253 return NULL;
256 local_func = wine_wgl.p_wglGetProcAddress(ext_ret->name);
258 /* After that, look at the extensions defined in the Linux OpenGL library */
259 if (local_func == NULL) {
260 char buf[256];
261 void *ret = NULL;
263 /* Remove the 3 last letters (EXT, ARB, ...).
265 I know that some extensions have more than 3 letters (MESA, NV,
266 INTEL, ...), but this is only a stop-gap measure to fix buggy
267 OpenGL drivers (moreover, it is only useful for old 1.0 apps
268 that query the glBindTextureEXT extension).
270 memcpy(buf, ext_ret->name, strlen(ext_ret->name) - 3);
271 buf[strlen(ext_ret->name) - 3] = '\0';
272 TRACE(" extension not found in the Linux OpenGL library, checking against libGL bug with %s..\n", buf);
274 ret = GetProcAddress(opengl32_handle, buf);
275 if (ret != NULL) {
276 TRACE(" found function in main OpenGL library (%p) !\n", ret);
277 } else {
278 WARN("Did not find function %s (%s) in your OpenGL library !\n", lpszProc, ext_ret->name);
281 return ret;
282 } else {
283 TRACE(" returning function (%p)\n", ext_ret->func);
284 extension_funcs[ext_ret - extension_registry] = local_func;
286 return ext_ret->func;
291 /***********************************************************************
292 * wglRealizeLayerPalette (OPENGL32.@)
294 BOOL WINAPI wglRealizeLayerPalette(HDC hdc,
295 int iLayerPlane,
296 BOOL bRealize) {
297 FIXME("()\n");
299 return FALSE;
302 /***********************************************************************
303 * wglSetLayerPaletteEntries (OPENGL32.@)
305 int WINAPI wglSetLayerPaletteEntries(HDC hdc,
306 int iLayerPlane,
307 int iStart,
308 int cEntries,
309 const COLORREF *pcr) {
310 FIXME("(): stub !\n");
312 return 0;
315 /***********************************************************************
316 * wglSwapLayerBuffers (OPENGL32.@)
318 BOOL WINAPI wglSwapLayerBuffers(HDC hdc,
319 UINT fuPlanes) {
320 TRACE_(opengl)("(%p, %08x)\n", hdc, fuPlanes);
322 if (fuPlanes & WGL_SWAP_MAIN_PLANE) {
323 if (!SwapBuffers(hdc)) return FALSE;
324 fuPlanes &= ~WGL_SWAP_MAIN_PLANE;
327 if (fuPlanes) {
328 WARN("Following layers unhandled : %08x\n", fuPlanes);
331 return TRUE;
334 #ifdef HAVE_GL_GLU_H
336 static void fixed_to_double(POINTFX fixed, UINT em_size, GLdouble vertex[3])
338 vertex[0] = (fixed.x.value + (GLdouble)fixed.x.fract / (1 << 16)) / em_size;
339 vertex[1] = (fixed.y.value + (GLdouble)fixed.y.fract / (1 << 16)) / em_size;
340 vertex[2] = 0.0;
343 static void tess_callback_vertex(GLvoid *vertex)
345 GLdouble *dbl = vertex;
346 TRACE("%f, %f, %f\n", dbl[0], dbl[1], dbl[2]);
347 glVertex3dv(vertex);
350 static void tess_callback_begin(GLenum which)
352 TRACE("%d\n", which);
353 glBegin(which);
356 static void tess_callback_end(void)
358 TRACE("\n");
359 glEnd();
362 /***********************************************************************
363 * wglUseFontOutlines_common
365 static BOOL WINAPI wglUseFontOutlines_common(HDC hdc,
366 DWORD first,
367 DWORD count,
368 DWORD listBase,
369 FLOAT deviation,
370 FLOAT extrusion,
371 int format,
372 LPGLYPHMETRICSFLOAT lpgmf,
373 BOOL unicode)
375 UINT glyph;
376 const MAT2 identity = {{0,1},{0,0},{0,0},{0,1}};
377 GLUtesselator *tess;
378 LOGFONTW lf;
379 HFONT old_font, unscaled_font;
380 UINT em_size = 1024;
381 RECT rc;
383 TRACE("(%p, %d, %d, %d, %f, %f, %d, %p, %s)\n", hdc, first, count,
384 listBase, deviation, extrusion, format, lpgmf, unicode ? "W" : "A");
387 ENTER_GL();
388 tess = gluNewTess();
389 if(tess)
391 gluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)tess_callback_vertex);
392 gluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)tess_callback_begin);
393 gluTessCallback(tess, GLU_TESS_END, tess_callback_end);
395 LEAVE_GL();
397 if(!tess) return FALSE;
399 GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
400 rc.left = rc.right = rc.bottom = 0;
401 rc.top = em_size;
402 DPtoLP(hdc, (POINT*)&rc, 2);
403 lf.lfHeight = -abs(rc.top - rc.bottom);
404 lf.lfOrientation = lf.lfEscapement = 0;
405 unscaled_font = CreateFontIndirectW(&lf);
406 old_font = SelectObject(hdc, unscaled_font);
408 for (glyph = first; glyph < first + count; glyph++)
410 DWORD needed;
411 GLYPHMETRICS gm;
412 BYTE *buf;
413 TTPOLYGONHEADER *pph;
414 TTPOLYCURVE *ppc;
415 GLdouble *vertices;
417 if(unicode)
418 needed = GetGlyphOutlineW(hdc, glyph, GGO_NATIVE, &gm, 0, NULL, &identity);
419 else
420 needed = GetGlyphOutlineA(hdc, glyph, GGO_NATIVE, &gm, 0, NULL, &identity);
422 if(needed == GDI_ERROR)
423 goto error;
425 buf = HeapAlloc(GetProcessHeap(), 0, needed);
426 vertices = HeapAlloc(GetProcessHeap(), 0, needed / sizeof(POINTFX) * 3 * sizeof(GLdouble));
428 if(unicode)
429 GetGlyphOutlineW(hdc, glyph, GGO_NATIVE, &gm, needed, buf, &identity);
430 else
431 GetGlyphOutlineA(hdc, glyph, GGO_NATIVE, &gm, needed, buf, &identity);
433 TRACE("glyph %d\n", glyph);
435 if(lpgmf)
437 lpgmf->gmfBlackBoxX = (float)gm.gmBlackBoxX / em_size;
438 lpgmf->gmfBlackBoxY = (float)gm.gmBlackBoxY / em_size;
439 lpgmf->gmfptGlyphOrigin.x = (float)gm.gmptGlyphOrigin.x / em_size;
440 lpgmf->gmfptGlyphOrigin.y = (float)gm.gmptGlyphOrigin.y / em_size;
441 lpgmf->gmfCellIncX = (float)gm.gmCellIncX / em_size;
442 lpgmf->gmfCellIncY = (float)gm.gmCellIncY / em_size;
444 TRACE("%fx%f at %f,%f inc %f,%f\n", lpgmf->gmfBlackBoxX, lpgmf->gmfBlackBoxY,
445 lpgmf->gmfptGlyphOrigin.x, lpgmf->gmfptGlyphOrigin.y, lpgmf->gmfCellIncX, lpgmf->gmfCellIncY);
446 lpgmf++;
449 ENTER_GL();
450 glNewList(listBase++, GL_COMPILE);
451 gluTessBeginPolygon(tess, NULL);
453 pph = (TTPOLYGONHEADER*)buf;
454 while((BYTE*)pph < buf + needed)
456 TRACE("\tstart %d, %d\n", pph->pfxStart.x.value, pph->pfxStart.y.value);
458 gluTessBeginContour(tess);
460 fixed_to_double(pph->pfxStart, em_size, vertices);
461 gluTessVertex(tess, vertices, vertices);
462 vertices += 3;
464 ppc = (TTPOLYCURVE*)((char*)pph + sizeof(*pph));
465 while((char*)ppc < (char*)pph + pph->cb)
467 int i;
469 switch(ppc->wType) {
470 case TT_PRIM_LINE:
471 for(i = 0; i < ppc->cpfx; i++)
473 TRACE("\t\tline to %d, %d\n", ppc->apfx[i].x.value, ppc->apfx[i].y.value);
474 fixed_to_double(ppc->apfx[i], em_size, vertices);
475 gluTessVertex(tess, vertices, vertices);
476 vertices += 3;
478 break;
480 case TT_PRIM_QSPLINE:
481 for(i = 0; i < ppc->cpfx/2; i++)
483 /* FIXME just connecting the control points for now */
484 TRACE("\t\tcurve %d,%d %d,%d\n",
485 ppc->apfx[i * 2].x.value, ppc->apfx[i * 3].y.value,
486 ppc->apfx[i * 2 + 1].x.value, ppc->apfx[i * 3 + 1].y.value);
487 fixed_to_double(ppc->apfx[i * 2], em_size, vertices);
488 gluTessVertex(tess, vertices, vertices);
489 vertices += 3;
490 fixed_to_double(ppc->apfx[i * 2 + 1], em_size, vertices);
491 gluTessVertex(tess, vertices, vertices);
492 vertices += 3;
494 break;
495 default:
496 ERR("\t\tcurve type = %d\n", ppc->wType);
497 gluTessEndContour(tess);
498 goto error_in_list;
501 ppc = (TTPOLYCURVE*)((char*)ppc + sizeof(*ppc) +
502 (ppc->cpfx - 1) * sizeof(POINTFX));
504 gluTessEndContour(tess);
505 pph = (TTPOLYGONHEADER*)((char*)pph + pph->cb);
508 error_in_list:
509 gluTessEndPolygon(tess);
510 glTranslated((GLdouble)gm.gmCellIncX / em_size, (GLdouble)gm.gmCellIncY / em_size, 0.0);
511 glEndList();
512 LEAVE_GL();
513 HeapFree(GetProcessHeap(), 0, buf);
514 HeapFree(GetProcessHeap(), 0, vertices);
517 error:
518 DeleteObject(SelectObject(hdc, old_font));
519 gluDeleteTess(tess);
520 return TRUE;
524 #else /* HAVE_GL_GLU_H */
526 static BOOL WINAPI wglUseFontOutlines_common(HDC hdc,
527 DWORD first,
528 DWORD count,
529 DWORD listBase,
530 FLOAT deviation,
531 FLOAT extrusion,
532 int format,
533 LPGLYPHMETRICSFLOAT lpgmf,
534 BOOL unicode)
536 FIXME("Unable to compile in wglUseFontOutlines support without GL/glu.h\n");
537 return FALSE;
540 #endif /* HAVE_GL_GLU_H */
542 /***********************************************************************
543 * wglUseFontOutlinesA (OPENGL32.@)
545 BOOL WINAPI wglUseFontOutlinesA(HDC hdc,
546 DWORD first,
547 DWORD count,
548 DWORD listBase,
549 FLOAT deviation,
550 FLOAT extrusion,
551 int format,
552 LPGLYPHMETRICSFLOAT lpgmf)
554 return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, FALSE);
557 /***********************************************************************
558 * wglUseFontOutlinesW (OPENGL32.@)
560 BOOL WINAPI wglUseFontOutlinesW(HDC hdc,
561 DWORD first,
562 DWORD count,
563 DWORD listBase,
564 FLOAT deviation,
565 FLOAT extrusion,
566 int format,
567 LPGLYPHMETRICSFLOAT lpgmf)
569 return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, TRUE);
572 /***********************************************************************
573 * glEnable (OPENGL32.@)
575 void WINAPI wine_glEnable( GLenum cap )
577 TRACE("(%d)\n", cap );
578 wine_wgl.p_wglEnable(cap);
581 /***********************************************************************
582 * glIsEnabled (OPENGL32.@)
584 GLboolean WINAPI wine_glIsEnabled( GLenum cap )
586 TRACE("(%d)\n", cap );
587 return wine_wgl.p_wglIsEnabled(cap);
590 /***********************************************************************
591 * glDisable (OPENGL32.@)
593 void WINAPI wine_glDisable( GLenum cap )
595 TRACE("(%d)\n", cap );
596 wine_wgl.p_wglDisable(cap);
599 /***********************************************************************
600 * glScissor (OPENGL32.@)
602 void WINAPI wine_glScissor( GLint x, GLint y, GLsizei width, GLsizei height )
604 TRACE("(%d, %d, %d, %d)\n", x, y, width, height );
605 wine_wgl.p_wglScissor(x, y, width, height);
608 /***********************************************************************
609 * glViewport (OPENGL32.@)
611 void WINAPI wine_glViewport( GLint x, GLint y, GLsizei width, GLsizei height )
613 TRACE("(%d, %d, %d, %d)\n", x, y, width, height );
614 wine_wgl.p_wglViewport(x, y, width, height);
617 /***********************************************************************
618 * glGetString (OPENGL32.@)
620 const GLubyte * WINAPI wine_glGetString( GLenum name )
622 const GLubyte *ret;
623 const char* GL_Extensions = NULL;
625 if (GL_EXTENSIONS != name) {
626 ENTER_GL();
627 ret = glGetString(name);
628 LEAVE_GL();
629 return ret;
632 if (NULL == internal_gl_extensions) {
633 ENTER_GL();
634 GL_Extensions = (const char *) glGetString(GL_EXTENSIONS);
636 if (GL_Extensions)
638 size_t len = strlen(GL_Extensions);
639 internal_gl_extensions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len + 2);
641 TRACE("GL_EXTENSIONS reported:\n");
642 while (*GL_Extensions != 0x00) {
643 const char* Start = GL_Extensions;
644 char ThisExtn[256];
646 while (*GL_Extensions != ' ' && *GL_Extensions != 0x00) {
647 GL_Extensions++;
649 memcpy(ThisExtn, Start, (GL_Extensions - Start));
650 ThisExtn[GL_Extensions - Start] = 0;
651 TRACE("- %s:", ThisExtn);
653 /* test if supported API is disabled by config */
654 if (NULL == strstr(internal_gl_disabled_extensions, ThisExtn)) {
655 strcat(internal_gl_extensions, " ");
656 strcat(internal_gl_extensions, ThisExtn);
657 TRACE(" active\n");
658 } else {
659 TRACE(" deactived (by config)\n");
662 if (*GL_Extensions == ' ') GL_Extensions++;
665 LEAVE_GL();
667 return (const GLubyte *) internal_gl_extensions;
670 /***********************************************************************
671 * glGetIntegerv (OPENGL32.@)
673 void WINAPI wine_glGetIntegerv( GLenum pname, GLint* params )
675 wine_wgl.p_wglGetIntegerv(pname, params);
679 /* No need to load any other libraries as according to the ABI, libGL should be self-sufficient and
680 include all dependencies
682 #ifndef SONAME_LIBGL
683 #define SONAME_LIBGL "libGL.so"
684 #endif
686 /* This is for brain-dead applications that use OpenGL functions before even
687 creating a rendering context.... */
688 static BOOL process_attach(void)
690 HMODULE mod_x11, mod_gdi32;
691 DWORD size = sizeof(internal_gl_disabled_extensions);
692 HKEY hkey = 0;
694 GetDesktopWindow(); /* make sure winex11 is loaded (FIXME) */
695 mod_x11 = GetModuleHandleA( "winex11.drv" );
696 mod_gdi32 = GetModuleHandleA( "gdi32.dll" );
698 if (!mod_x11 || !mod_gdi32)
700 ERR("X11DRV or GDI32 not loaded. Cannot create default context.\n");
701 return FALSE;
704 wine_tsx11_lock_ptr = (void *)GetProcAddress( mod_x11, "wine_tsx11_lock" );
705 wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod_x11, "wine_tsx11_unlock" );
707 wine_wgl.p_wglGetProcAddress = (void *)GetProcAddress(mod_gdi32, "wglGetProcAddress");
709 /* Interal WGL function */
710 wine_wgl.p_wglDisable = (void *)wine_wgl.p_wglGetProcAddress("wglDisable");
711 wine_wgl.p_wglEnable = (void *)wine_wgl.p_wglGetProcAddress("wglEnable");
712 wine_wgl.p_wglGetIntegerv = (void *)wine_wgl.p_wglGetProcAddress("wglGetIntegerv");
713 wine_wgl.p_wglIsEnabled = (void *)wine_wgl.p_wglGetProcAddress("wglIsEnabled");
714 wine_wgl.p_wglScissor = (void *)wine_wgl.p_wglGetProcAddress("wglScissor");
715 wine_wgl.p_wglViewport = (void *)wine_wgl.p_wglGetProcAddress("wglViewport");
717 internal_gl_disabled_extensions[0] = 0;
718 if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\OpenGL", &hkey)) {
719 if (!RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, (LPBYTE)internal_gl_disabled_extensions, &size)) {
720 TRACE("found DisabledExtensions=\"%s\"\n", internal_gl_disabled_extensions);
722 RegCloseKey(hkey);
725 return TRUE;
729 /**********************************************************************/
731 static void process_detach(void)
733 HeapFree(GetProcessHeap(), 0, internal_gl_extensions);
736 /***********************************************************************
737 * OpenGL initialisation routine
739 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
741 switch(reason)
743 case DLL_PROCESS_ATTACH:
744 opengl32_handle = hinst;
745 DisableThreadLibraryCalls(hinst);
746 return process_attach();
747 case DLL_PROCESS_DETACH:
748 process_detach();
749 break;
751 return TRUE;