mshtml: Unescape script from javascript: URLs before executing them.
[wine] / dlls / opengl32 / wgl.c
1 /* Window-specific OpenGL functions implementation.
2  *
3  * Copyright (c) 1999 Lionel Ulmer
4  * Copyright (c) 2005 Raphael Junqueira
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27
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"
35
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 #define WGL_WGLEXT_PROTOTYPES
43 #include "wine/wglext.h"
44 #include "wine/gdi_driver.h"
45 #include "wine/wgl_driver.h"
46 #include "wine/library.h"
47 #include "wine/debug.h"
48
49 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
50 WINE_DECLARE_DEBUG_CHANNEL(opengl);
51
52 #ifdef SONAME_LIBGLU
53 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
54 MAKE_FUNCPTR(gluNewTess)
55 MAKE_FUNCPTR(gluDeleteTess)
56 MAKE_FUNCPTR(gluTessBeginContour)
57 MAKE_FUNCPTR(gluTessBeginPolygon)
58 MAKE_FUNCPTR(gluTessCallback)
59 MAKE_FUNCPTR(gluTessEndContour)
60 MAKE_FUNCPTR(gluTessEndPolygon)
61 MAKE_FUNCPTR(gluTessVertex)
62 #undef MAKE_FUNCPTR
63 #endif /* SONAME_LIBGLU */
64
65 static HMODULE opengl32_handle;
66 static void* libglu_handle = NULL;
67
68 extern struct opengl_funcs null_opengl_funcs;
69
70 const GLubyte * WINAPI wine_glGetString( GLenum name );
71
72 /* internal GDI functions */
73 extern INT WINAPI GdiDescribePixelFormat( HDC hdc, INT fmt, UINT size, PIXELFORMATDESCRIPTOR *pfd );
74 extern BOOL WINAPI GdiSetPixelFormat( HDC hdc, INT fmt, const PIXELFORMATDESCRIPTOR *pfd );
75 extern BOOL WINAPI GdiSwapBuffers( HDC hdc );
76
77 /* handle management */
78
79 #define MAX_WGL_HANDLES 1024
80
81 enum wgl_handle_type
82 {
83     HANDLE_CONTEXT = 0 << 12,
84     HANDLE_PBUFFER = 1 << 12,
85     HANDLE_TYPE_MASK = 15 << 12
86 };
87
88 struct wgl_handle
89 {
90     UINT                 handle;
91     DWORD                tid;
92     struct opengl_funcs *funcs;
93     union
94     {
95         struct wgl_context *context;  /* for HANDLE_CONTEXT */
96         struct wgl_pbuffer *pbuffer;  /* for HANDLE_PBUFFER */
97         struct wgl_handle  *next;     /* for free handles */
98     } u;
99 };
100
101 static struct wgl_handle wgl_handles[MAX_WGL_HANDLES];
102 static struct wgl_handle *next_free;
103 static unsigned int handle_count;
104
105 static CRITICAL_SECTION wgl_section;
106 static CRITICAL_SECTION_DEBUG critsect_debug =
107 {
108     0, 0, &wgl_section,
109     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
110       0, 0, { (DWORD_PTR)(__FILE__ ": wgl_section") }
111 };
112 static CRITICAL_SECTION wgl_section = { &critsect_debug, -1, 0, 0, 0, 0 };
113
114 static inline struct opengl_funcs *get_dc_funcs( HDC hdc )
115 {
116     struct opengl_funcs *funcs = __wine_get_wgl_driver( hdc, WINE_WGL_DRIVER_VERSION );
117     if (funcs == (void *)-1) funcs = &null_opengl_funcs;
118     return funcs;
119 }
120
121 static inline HANDLE next_handle( struct wgl_handle *ptr, enum wgl_handle_type type )
122 {
123     WORD generation = HIWORD( ptr->handle ) + 1;
124     if (!generation) generation++;
125     ptr->handle = MAKELONG( ptr - wgl_handles, generation ) | type;
126     return ULongToHandle( ptr->handle );
127 }
128
129 /* the current context is assumed valid and doesn't need locking */
130 static inline struct wgl_handle *get_current_context_ptr(void)
131 {
132     if (!NtCurrentTeb()->glCurrentRC) return NULL;
133     return &wgl_handles[LOWORD(NtCurrentTeb()->glCurrentRC) & ~HANDLE_TYPE_MASK];
134 }
135
136 static struct wgl_handle *get_handle_ptr( HANDLE handle, enum wgl_handle_type type )
137 {
138     unsigned int index = LOWORD( handle ) & ~HANDLE_TYPE_MASK;
139
140     EnterCriticalSection( &wgl_section );
141     if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle)
142         return &wgl_handles[index];
143
144     LeaveCriticalSection( &wgl_section );
145     SetLastError( ERROR_INVALID_HANDLE );
146     return NULL;
147 }
148
149 static void release_handle_ptr( struct wgl_handle *ptr )
150 {
151     if (ptr) LeaveCriticalSection( &wgl_section );
152 }
153
154 static HANDLE alloc_handle( enum wgl_handle_type type, struct opengl_funcs *funcs, void *user_ptr )
155 {
156     HANDLE handle = 0;
157     struct wgl_handle *ptr = NULL;
158
159     EnterCriticalSection( &wgl_section );
160     if ((ptr = next_free))
161         next_free = next_free->u.next;
162     else if (handle_count < MAX_WGL_HANDLES)
163         ptr = &wgl_handles[handle_count++];
164
165     if (ptr)
166     {
167         ptr->funcs = funcs;
168         ptr->u.context = user_ptr;
169         handle = next_handle( ptr, type );
170     }
171     else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
172     LeaveCriticalSection( &wgl_section );
173     return handle;
174 }
175
176 static void free_handle_ptr( struct wgl_handle *ptr )
177 {
178     ptr->handle |= 0xffff;
179     ptr->u.next = next_free;
180     ptr->funcs = NULL;
181     next_free = ptr;
182     LeaveCriticalSection( &wgl_section );
183 }
184
185 /***********************************************************************
186  *               wglSetPixelFormat(OPENGL32.@)
187  */
188 BOOL WINAPI wglSetPixelFormat( HDC hdc, INT iPixelFormat,
189                                const PIXELFORMATDESCRIPTOR *ppfd)
190 {
191     return GdiSetPixelFormat(hdc, iPixelFormat, ppfd);
192 }
193
194 /***********************************************************************
195  *              wglCopyContext (OPENGL32.@)
196  */
197 BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
198 {
199     struct wgl_handle *src, *dst;
200     BOOL ret = FALSE;
201
202     if (!(src = get_handle_ptr( hglrcSrc, HANDLE_CONTEXT ))) return FALSE;
203     if ((dst = get_handle_ptr( hglrcDst, HANDLE_CONTEXT )))
204     {
205         if (src->funcs != dst->funcs) SetLastError( ERROR_INVALID_HANDLE );
206         else ret = src->funcs->wgl.p_wglCopyContext( src->u.context, dst->u.context, mask );
207     }
208     release_handle_ptr( dst );
209     release_handle_ptr( src );
210     return ret;
211 }
212
213 /***********************************************************************
214  *              wglDeleteContext (OPENGL32.@)
215  */
216 BOOL WINAPI wglDeleteContext(HGLRC hglrc)
217 {
218     struct wgl_handle *ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT );
219
220     if (!ptr) return FALSE;
221
222     if (ptr->tid && ptr->tid != GetCurrentThreadId())
223     {
224         SetLastError( ERROR_BUSY );
225         release_handle_ptr( ptr );
226         return FALSE;
227     }
228     if (hglrc == NtCurrentTeb()->glCurrentRC) wglMakeCurrent( 0, 0 );
229     ptr->funcs->wgl.p_wglDeleteContext( ptr->u.context );
230     free_handle_ptr( ptr );
231     return TRUE;
232 }
233
234 /***********************************************************************
235  *              wglMakeCurrent (OPENGL32.@)
236  */
237 BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
238 {
239     BOOL ret = TRUE;
240     struct wgl_handle *ptr, *prev = get_current_context_ptr();
241
242     if (hglrc)
243     {
244         if (!(ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ))) return FALSE;
245         if (!ptr->tid || ptr->tid == GetCurrentThreadId())
246         {
247             ret = ptr->funcs->wgl.p_wglMakeCurrent( hdc, ptr->u.context );
248             if (ret)
249             {
250                 if (prev) prev->tid = 0;
251                 ptr->tid = GetCurrentThreadId();
252                 NtCurrentTeb()->glCurrentRC = hglrc;
253                 NtCurrentTeb()->glTable = ptr->funcs;
254             }
255         }
256         else
257         {
258             SetLastError( ERROR_BUSY );
259             ret = FALSE;
260         }
261         release_handle_ptr( ptr );
262     }
263     else if (prev)
264     {
265         if (!prev->funcs->wgl.p_wglMakeCurrent( 0, NULL )) return FALSE;
266         prev->tid = 0;
267         NtCurrentTeb()->glCurrentRC = 0;
268         NtCurrentTeb()->glTable = &null_opengl_funcs;
269     }
270     else if (!hdc)
271     {
272         SetLastError( ERROR_INVALID_HANDLE );
273         ret = FALSE;
274     }
275     return ret;
276 }
277
278 /***********************************************************************
279  *              wglCreateContextAttribsARB
280  *
281  * Provided by the WGL_ARB_create_context extension.
282  */
283 HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attribs )
284 {
285     HGLRC ret = 0;
286     struct wgl_context *context;
287     struct wgl_handle *share_ptr = NULL;
288     struct opengl_funcs *funcs = get_dc_funcs( hdc );
289
290     if (!funcs || !funcs->ext.p_wglCreateContextAttribsARB) return 0;
291     if (share && !(share_ptr = get_handle_ptr( share, HANDLE_CONTEXT ))) return 0;
292     if ((context = funcs->ext.p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->u.context : NULL,
293                                                             attribs )))
294     {
295         ret = alloc_handle( HANDLE_CONTEXT, funcs, context );
296         if (!ret) funcs->wgl.p_wglDeleteContext( context );
297     }
298     release_handle_ptr( share_ptr );
299     return ret;
300
301 }
302
303 /***********************************************************************
304  *              wglMakeContextCurrentARB
305  *
306  * Provided by the WGL_ARB_make_current_read extension.
307  */
308 BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc )
309 {
310     BOOL ret = TRUE;
311     struct wgl_handle *ptr, *prev = get_current_context_ptr();
312
313     if (hglrc)
314     {
315         if (!(ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ))) return FALSE;
316         if (!ptr->tid || ptr->tid == GetCurrentThreadId())
317         {
318             ret = (ptr->funcs->ext.p_wglMakeContextCurrentARB &&
319                    ptr->funcs->ext.p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ptr->u.context ));
320             if (ret)
321             {
322                 if (prev) prev->tid = 0;
323                 ptr->tid = GetCurrentThreadId();
324                 NtCurrentTeb()->glCurrentRC = hglrc;
325                 NtCurrentTeb()->glTable = ptr->funcs;
326             }
327         }
328         else
329         {
330             SetLastError( ERROR_BUSY );
331             ret = FALSE;
332         }
333         release_handle_ptr( ptr );
334     }
335     else if (prev)
336     {
337         if (!prev->funcs->wgl.p_wglMakeCurrent( 0, NULL )) return FALSE;
338         prev->tid = 0;
339         NtCurrentTeb()->glCurrentRC = 0;
340         NtCurrentTeb()->glTable = &null_opengl_funcs;
341     }
342     return ret;
343 }
344
345 /***********************************************************************
346  *              wglGetCurrentReadDCARB
347  *
348  * Provided by the WGL_ARB_make_current_read extension.
349  */
350 HDC WINAPI wglGetCurrentReadDCARB(void)
351 {
352     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
353
354     if (!funcs->ext.p_wglGetCurrentReadDCARB) return 0;
355     return funcs->ext.p_wglGetCurrentReadDCARB();
356 }
357
358 /***********************************************************************
359  *              wglShareLists (OPENGL32.@)
360  */
361 BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst)
362 {
363     BOOL ret = FALSE;
364     struct wgl_handle *src, *dst;
365
366     if (!(src = get_handle_ptr( hglrcSrc, HANDLE_CONTEXT ))) return FALSE;
367     if ((dst = get_handle_ptr( hglrcDst, HANDLE_CONTEXT )))
368     {
369         if (src->funcs != dst->funcs) SetLastError( ERROR_INVALID_HANDLE );
370         else ret = src->funcs->wgl.p_wglShareLists( src->u.context, dst->u.context );
371     }
372     release_handle_ptr( dst );
373     release_handle_ptr( src );
374     return ret;
375 }
376
377 /***********************************************************************
378  *              wglGetCurrentDC (OPENGL32.@)
379  */
380 HDC WINAPI wglGetCurrentDC(void)
381 {
382     struct wgl_handle *context = get_current_context_ptr();
383     if (!context) return 0;
384     return context->funcs->wgl.p_wglGetCurrentDC( context->u.context );
385 }
386
387 /***********************************************************************
388  *              wglCreateContext (OPENGL32.@)
389  */
390 HGLRC WINAPI wglCreateContext(HDC hdc)
391 {
392     HGLRC ret = 0;
393     struct wgl_context *context;
394     struct opengl_funcs *funcs = get_dc_funcs( hdc );
395
396     if (!funcs) return 0;
397     if (!(context = funcs->wgl.p_wglCreateContext( hdc ))) return 0;
398     ret = alloc_handle( HANDLE_CONTEXT, funcs, context );
399     if (!ret) funcs->wgl.p_wglDeleteContext( context );
400     return ret;
401 }
402
403 /***********************************************************************
404  *              wglGetCurrentContext (OPENGL32.@)
405  */
406 HGLRC WINAPI wglGetCurrentContext(void)
407 {
408     return NtCurrentTeb()->glCurrentRC;
409 }
410
411 /***********************************************************************
412  *              wglChoosePixelFormat (OPENGL32.@)
413  */
414 INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd)
415 {
416     PIXELFORMATDESCRIPTOR format, best;
417     int i, count, best_format;
418     int bestDBuffer = -1, bestStereo = -1;
419
420     TRACE_(wgl)( "%p %p: size %u version %u flags %u type %u color %u %u,%u,%u,%u "
421                  "accum %u depth %u stencil %u aux %u\n",
422                  hdc, ppfd, ppfd->nSize, ppfd->nVersion, ppfd->dwFlags, ppfd->iPixelType,
423                  ppfd->cColorBits, ppfd->cRedBits, ppfd->cGreenBits, ppfd->cBlueBits, ppfd->cAlphaBits,
424                  ppfd->cAccumBits, ppfd->cDepthBits, ppfd->cStencilBits, ppfd->cAuxBuffers );
425
426     count = GdiDescribePixelFormat( hdc, 0, 0, NULL );
427     if (!count) return 0;
428
429     best_format = 0;
430     best.dwFlags = 0;
431     best.cAlphaBits = -1;
432     best.cColorBits = -1;
433     best.cDepthBits = -1;
434     best.cStencilBits = -1;
435     best.cAuxBuffers = -1;
436
437     for (i = 1; i <= count; i++)
438     {
439         if (!GdiDescribePixelFormat( hdc, i, sizeof(format), &format )) continue;
440
441         if (ppfd->iPixelType != format.iPixelType)
442         {
443             TRACE( "pixel type mismatch for iPixelFormat=%d\n", i );
444             continue;
445         }
446
447         /* only use bitmap capable for formats for bitmap rendering */
448         if( (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) != (format.dwFlags & PFD_DRAW_TO_BITMAP))
449         {
450             TRACE( "PFD_DRAW_TO_BITMAP mismatch for iPixelFormat=%d\n", i );
451             continue;
452         }
453
454         /* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE
455          * is not very clear on MSDN. They specify that ChoosePixelFormat tries to match pixel formats
456          * with the flag (PFD_STEREO / PFD_DOUBLEBUFFERING) set. Otherwise it says that it tries to match
457          * formats without the given flag set.
458          * A test on Windows using a Radeon 9500pro on WinXP (the driver doesn't support Stereo)
459          * has indicated that a format without stereo is returned when stereo is unavailable.
460          * So in case PFD_STEREO is set, formats that support it should have priority above formats
461          * without. In case PFD_STEREO_DONTCARE is set, stereo is ignored.
462          *
463          * To summarize the following is most likely the correct behavior:
464          * stereo not set -> prefer non-stereo formats, but also accept stereo formats
465          * stereo set -> prefer stereo formats, but also accept non-stereo formats
466          * stereo don't care -> it doesn't matter whether we get stereo or not
467          *
468          * In Wine we will treat non-stereo the same way as don't care because it makes
469          * format selection even more complicated and second drivers with Stereo advertise
470          * each format twice anyway.
471          */
472
473         /* Doublebuffer, see the comments above */
474         if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE))
475         {
476             if (((ppfd->dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer) &&
477                 ((format.dwFlags & PFD_DOUBLEBUFFER) == (ppfd->dwFlags & PFD_DOUBLEBUFFER)))
478                 goto found;
479
480             if (bestDBuffer != -1 && (format.dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer) continue;
481         }
482
483         /* Stereo, see the comments above. */
484         if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE))
485         {
486             if (((ppfd->dwFlags & PFD_STEREO) != bestStereo) &&
487                 ((format.dwFlags & PFD_STEREO) == (ppfd->dwFlags & PFD_STEREO)))
488                 goto found;
489
490             if (bestStereo != -1 && (format.dwFlags & PFD_STEREO) != bestStereo) continue;
491         }
492
493         /* Below we will do a number of checks to select the 'best' pixelformat.
494          * We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits -> cAuxBuffers.
495          * The code works by trying to match the most important options as close as possible.
496          * When a reasonable format is found, we will try to match more options.
497          * It appears (see the opengl32 test) that Windows opengl drivers ignore options
498          * like cColorBits, cAlphaBits and friends if they are set to 0, so they are considered
499          * as DONTCARE. At least Serious Sam TSE relies on this behavior. */
500
501         if (ppfd->cColorBits)
502         {
503             if (((ppfd->cColorBits > best.cColorBits) && (format.cColorBits > best.cColorBits)) ||
504                 ((format.cColorBits >= ppfd->cColorBits) && (format.cColorBits < best.cColorBits)))
505                 goto found;
506
507             if (best.cColorBits != format.cColorBits)  /* Do further checks if the format is compatible */
508             {
509                 TRACE( "color mismatch for iPixelFormat=%d\n", i );
510                 continue;
511             }
512         }
513         if (ppfd->cAlphaBits)
514         {
515             if (((ppfd->cAlphaBits > best.cAlphaBits) && (format.cAlphaBits > best.cAlphaBits)) ||
516                 ((format.cAlphaBits >= ppfd->cAlphaBits) && (format.cAlphaBits < best.cAlphaBits)))
517                 goto found;
518
519             if (best.cAlphaBits != format.cAlphaBits)
520             {
521                 TRACE( "alpha mismatch for iPixelFormat=%d\n", i );
522                 continue;
523             }
524         }
525         if (ppfd->cDepthBits)
526         {
527             if (((ppfd->cDepthBits > best.cDepthBits) && (format.cDepthBits > best.cDepthBits)) ||
528                 ((format.cDepthBits >= ppfd->cDepthBits) && (format.cDepthBits < best.cDepthBits)))
529                 goto found;
530
531             if (best.cDepthBits != format.cDepthBits)
532             {
533                 TRACE( "depth mismatch for iPixelFormat=%d\n", i );
534                 continue;
535             }
536         }
537         if (ppfd->cStencilBits)
538         {
539             if (((ppfd->cStencilBits > best.cStencilBits) && (format.cStencilBits > best.cStencilBits)) ||
540                 ((format.cStencilBits >= ppfd->cStencilBits) && (format.cStencilBits < best.cStencilBits)))
541                 goto found;
542
543             if (best.cStencilBits != format.cStencilBits)
544             {
545                 TRACE( "stencil mismatch for iPixelFormat=%d\n", i );
546                 continue;
547             }
548         }
549         if (ppfd->cAuxBuffers)
550         {
551             if (((ppfd->cAuxBuffers > best.cAuxBuffers) && (format.cAuxBuffers > best.cAuxBuffers)) ||
552                 ((format.cAuxBuffers >= ppfd->cAuxBuffers) && (format.cAuxBuffers < best.cAuxBuffers)))
553                 goto found;
554
555             if (best.cAuxBuffers != format.cAuxBuffers)
556             {
557                 TRACE( "aux mismatch for iPixelFormat=%d\n", i );
558                 continue;
559             }
560         }
561         continue;
562
563     found:
564         best_format = i;
565         best = format;
566         bestDBuffer = format.dwFlags & PFD_DOUBLEBUFFER;
567         bestStereo = format.dwFlags & PFD_STEREO;
568     }
569
570     TRACE( "returning %u\n", best_format );
571     return best_format;
572 }
573
574 /***********************************************************************
575  *              wglDescribePixelFormat (OPENGL32.@)
576  */
577 INT WINAPI wglDescribePixelFormat(HDC hdc, INT iPixelFormat, UINT nBytes,
578                                 LPPIXELFORMATDESCRIPTOR ppfd)
579 {
580   return GdiDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd);
581 }
582
583 /***********************************************************************
584  *              wglGetPixelFormat (OPENGL32.@)
585  */
586 INT WINAPI wglGetPixelFormat(HDC hdc)
587 {
588     struct opengl_funcs *funcs = get_dc_funcs( hdc );
589     if (!funcs) return 0;
590     return funcs->wgl.p_wglGetPixelFormat( hdc );
591 }
592
593 /***********************************************************************
594  *              wglCreateLayerContext (OPENGL32.@)
595  */
596 HGLRC WINAPI wglCreateLayerContext(HDC hdc,
597                                    int iLayerPlane) {
598   TRACE("(%p,%d)\n", hdc, iLayerPlane);
599
600   if (iLayerPlane == 0) {
601       return wglCreateContext(hdc);
602   }
603   FIXME("no handler for layer %d\n", iLayerPlane);
604
605   return NULL;
606 }
607
608 /***********************************************************************
609  *              wglDescribeLayerPlane (OPENGL32.@)
610  */
611 BOOL WINAPI wglDescribeLayerPlane(HDC hdc,
612                                   int iPixelFormat,
613                                   int iLayerPlane,
614                                   UINT nBytes,
615                                   LPLAYERPLANEDESCRIPTOR plpd) {
616   FIXME("(%p,%d,%d,%d,%p)\n", hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
617
618   return FALSE;
619 }
620
621 /***********************************************************************
622  *              wglGetLayerPaletteEntries (OPENGL32.@)
623  */
624 int WINAPI wglGetLayerPaletteEntries(HDC hdc,
625                                      int iLayerPlane,
626                                      int iStart,
627                                      int cEntries,
628                                      const COLORREF *pcr) {
629   FIXME("(): stub!\n");
630
631   return 0;
632 }
633
634 /* check if the extension is present in the list */
635 static BOOL has_extension( const char *list, const char *ext )
636 {
637     size_t len = strlen( ext );
638
639     while (list)
640     {
641         while (*list == ' ') list++;
642         if (!strncmp( list, ext, len ) && (!list[len] || list[len] == ' ')) return TRUE;
643         list = strchr( list, ' ' );
644     }
645     return FALSE;
646 }
647
648 static int compar(const void *elt_a, const void *elt_b) {
649   return strcmp(((const OpenGL_extension *) elt_a)->name,
650                 ((const OpenGL_extension *) elt_b)->name);
651 }
652
653 /* Check if a GL extension is supported */
654 static BOOL is_extension_supported(const char* extension)
655 {
656     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
657     const char *gl_ext_string = (const char*)wine_glGetString(GL_EXTENSIONS);
658
659     TRACE("Checking for extension '%s'\n", extension);
660
661     if(!gl_ext_string) {
662         ERR("No OpenGL extensions found, check if your OpenGL setup is correct!\n");
663         return FALSE;
664     }
665
666     /* We use the GetProcAddress function from the display driver to retrieve function pointers
667      * for OpenGL and WGL extensions. In case of winex11.drv the OpenGL extension lookup is done
668      * using glXGetProcAddress. This function is quite unreliable in the sense that its specs don't
669      * require the function to return NULL when an extension isn't found. For this reason we check
670      * if the OpenGL extension required for the function we are looking up is supported. */
671
672     /* Check if the extension is part of the GL extension string to see if it is supported. */
673     if (has_extension(gl_ext_string, extension))
674         return TRUE;
675
676     /* In general an OpenGL function starts as an ARB/EXT extension and at some stage
677      * it becomes part of the core OpenGL library and can be reached without the ARB/EXT
678      * suffix as well. In the extension table, these functions contain GL_VERSION_major_minor.
679      * Check if we are searching for a core GL function */
680     if(strncmp(extension, "GL_VERSION_", 11) == 0)
681     {
682         const GLubyte *gl_version = funcs->gl.p_glGetString(GL_VERSION);
683         const char *version = extension + 11; /* Move past 'GL_VERSION_' */
684
685         if(!gl_version) {
686             ERR("No OpenGL version found!\n");
687             return FALSE;
688         }
689
690         /* Compare the major/minor version numbers of the native OpenGL library and what is required by the function.
691          * The gl_version string is guaranteed to have at least a major/minor and sometimes it has a release number as well. */
692         if( (gl_version[0] >= version[0]) || ((gl_version[0] == version[0]) && (gl_version[2] >= version[2])) ) {
693             return TRUE;
694         }
695         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]);
696     }
697
698     return FALSE;
699 }
700
701 /***********************************************************************
702  *              wglGetProcAddress (OPENGL32.@)
703  */
704 PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
705 {
706   struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
707   void **func_ptr;
708   void *local_func;
709   OpenGL_extension  ext;
710   const OpenGL_extension *ext_ret;
711   struct wgl_handle *context = get_current_context_ptr();
712
713   TRACE("(%s)\n", lpszProc);
714
715   if (lpszProc == NULL)
716     return NULL;
717
718   /* Without an active context opengl32 doesn't know to what
719    * driver it has to dispatch wglGetProcAddress.
720    */
721   if (!context)
722   {
723     WARN("No active WGL context found\n");
724     return NULL;
725   }
726
727   /* Search in the thunks to find the real name of the extension */
728   ext.name = lpszProc;
729   ext_ret = bsearch(&ext, extension_registry, extension_registry_size,
730                     sizeof(OpenGL_extension), compar);
731   if (!ext_ret)
732   {
733       WARN("Extension '%s' not defined in opengl32.dll's function table!\n", lpszProc);
734       return NULL;
735   }
736
737   func_ptr = (void **)&funcs->ext + (ext_ret - extension_registry);
738   if (!*func_ptr)
739   {
740     /* Check if the GL extension required by the function is available */
741     if(!is_extension_supported(ext_ret->extension)) {
742         WARN("Extension '%s' required by function '%s' not supported!\n", ext_ret->extension, lpszProc);
743     }
744
745     local_func = context->funcs->wgl.p_wglGetProcAddress( ext_ret->name );
746
747     /* After that, look at the extensions defined in the Linux OpenGL library */
748     if (local_func == NULL) {
749       char buf[256];
750       void *ret = NULL;
751
752       /* Remove the last 3 letters (EXT, ARB, ...).
753
754          I know that some extensions have more than 3 letters (MESA, NV,
755          INTEL, ...), but this is only a stop-gap measure to fix buggy
756          OpenGL drivers (moreover, it is only useful for old 1.0 apps
757          that query the glBindTextureEXT extension).
758       */
759       memcpy(buf, ext_ret->name, strlen(ext_ret->name) - 3);
760       buf[strlen(ext_ret->name) - 3] = '\0';
761       TRACE("Extension not found in the Linux OpenGL library, checking against libGL bug with %s..\n", buf);
762
763       ret = GetProcAddress(opengl32_handle, buf);
764       if (ret != NULL) {
765         TRACE("Found function in main OpenGL library (%p)!\n", ret);
766       } else {
767         WARN("Did not find function %s (%s) in your OpenGL library!\n", lpszProc, ext_ret->name);
768       }
769
770       return ret;
771     }
772     *func_ptr = local_func;
773   }
774
775   TRACE("returning function (%p)\n", ext_ret->func);
776   return ext_ret->func;
777 }
778
779 /***********************************************************************
780  *              wglRealizeLayerPalette (OPENGL32.@)
781  */
782 BOOL WINAPI wglRealizeLayerPalette(HDC hdc,
783                                    int iLayerPlane,
784                                    BOOL bRealize) {
785   FIXME("()\n");
786
787   return FALSE;
788 }
789
790 /***********************************************************************
791  *              wglSetLayerPaletteEntries (OPENGL32.@)
792  */
793 int WINAPI wglSetLayerPaletteEntries(HDC hdc,
794                                      int iLayerPlane,
795                                      int iStart,
796                                      int cEntries,
797                                      const COLORREF *pcr) {
798   FIXME("(): stub!\n");
799
800   return 0;
801 }
802
803 /***********************************************************************
804  *              wglSwapLayerBuffers (OPENGL32.@)
805  */
806 BOOL WINAPI wglSwapLayerBuffers(HDC hdc,
807                                 UINT fuPlanes) {
808   TRACE_(opengl)("(%p, %08x)\n", hdc, fuPlanes);
809
810   if (fuPlanes & WGL_SWAP_MAIN_PLANE) {
811     if (!GdiSwapBuffers(hdc)) return FALSE;
812     fuPlanes &= ~WGL_SWAP_MAIN_PLANE;
813   }
814
815   if (fuPlanes) {
816     WARN("Following layers unhandled: %08x\n", fuPlanes);
817   }
818
819   return TRUE;
820 }
821
822 /***********************************************************************
823  *              wglAllocateMemoryNV
824  *
825  * Provided by the WGL_NV_vertex_array_range extension.
826  */
827 void * WINAPI wglAllocateMemoryNV( GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority )
828 {
829     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
830
831     if (!funcs->ext.p_wglAllocateMemoryNV) return NULL;
832     return funcs->ext.p_wglAllocateMemoryNV( size, readfreq, writefreq, priority );
833 }
834
835 /***********************************************************************
836  *              wglFreeMemoryNV
837  *
838  * Provided by the WGL_NV_vertex_array_range extension.
839  */
840 void WINAPI wglFreeMemoryNV( void *pointer )
841 {
842     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
843
844     if (funcs->ext.p_wglFreeMemoryNV) funcs->ext.p_wglFreeMemoryNV( pointer );
845 }
846
847 /***********************************************************************
848  *              wglBindTexImageARB
849  *
850  * Provided by the WGL_ARB_render_texture extension.
851  */
852 BOOL WINAPI wglBindTexImageARB( HPBUFFERARB handle, int buffer )
853 {
854     struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER );
855     BOOL ret;
856
857     if (!ptr) return FALSE;
858     ret = ptr->funcs->ext.p_wglBindTexImageARB( ptr->u.pbuffer, buffer );
859     release_handle_ptr( ptr );
860     return ret;
861 }
862
863 /***********************************************************************
864  *              wglReleaseTexImageARB
865  *
866  * Provided by the WGL_ARB_render_texture extension.
867  */
868 BOOL WINAPI wglReleaseTexImageARB( HPBUFFERARB handle, int buffer )
869 {
870     struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER );
871     BOOL ret;
872
873     if (!ptr) return FALSE;
874     ret = ptr->funcs->ext.p_wglReleaseTexImageARB( ptr->u.pbuffer, buffer );
875     release_handle_ptr( ptr );
876     return ret;
877 }
878
879 /***********************************************************************
880  *              wglSetPbufferAttribARB
881  *
882  * Provided by the WGL_ARB_render_texture extension.
883  */
884 BOOL WINAPI wglSetPbufferAttribARB( HPBUFFERARB handle, const int *attribs )
885 {
886     struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER );
887     BOOL ret;
888
889     if (!ptr) return FALSE;
890     ret = ptr->funcs->ext.p_wglSetPbufferAttribARB( ptr->u.pbuffer, attribs );
891     release_handle_ptr( ptr );
892     return ret;
893 }
894
895 /***********************************************************************
896  *              wglChoosePixelFormatARB
897  *
898  * Provided by the WGL_ARB_pixel_format extension.
899  */
900 BOOL WINAPI wglChoosePixelFormatARB( HDC hdc, const int *iattribs, const FLOAT *fattribs,
901                                      UINT max, int *formats, UINT *count )
902 {
903     const struct opengl_funcs *funcs = get_dc_funcs( hdc );
904
905     if (!funcs || !funcs->ext.p_wglChoosePixelFormatARB) return FALSE;
906     return funcs->ext.p_wglChoosePixelFormatARB( hdc, iattribs, fattribs, max, formats, count );
907 }
908
909 /***********************************************************************
910  *              wglGetPixelFormatAttribivARB
911  *
912  * Provided by the WGL_ARB_pixel_format extension.
913  */
914 BOOL WINAPI wglGetPixelFormatAttribivARB( HDC hdc, int format, int layer, UINT count, const int *attribs,
915                                           int *values )
916 {
917     const struct opengl_funcs *funcs = get_dc_funcs( hdc );
918
919     if (!funcs || !funcs->ext.p_wglGetPixelFormatAttribivARB) return FALSE;
920     return funcs->ext.p_wglGetPixelFormatAttribivARB( hdc, format, layer, count, attribs, values );
921 }
922
923 /***********************************************************************
924  *              wglGetPixelFormatAttribfvARB
925  *
926  * Provided by the WGL_ARB_pixel_format extension.
927  */
928 BOOL WINAPI wglGetPixelFormatAttribfvARB( HDC hdc, int format, int layer, UINT count, const int *attribs,
929                                           FLOAT *values )
930 {
931     const struct opengl_funcs *funcs = get_dc_funcs( hdc );
932
933     if (!funcs || !funcs->ext.p_wglGetPixelFormatAttribfvARB) return FALSE;
934     return funcs->ext.p_wglGetPixelFormatAttribfvARB( hdc, format, layer, count, attribs, values );
935 }
936
937 /***********************************************************************
938  *              wglCreatePbufferARB
939  *
940  * Provided by the WGL_ARB_pbuffer extension.
941  */
942 HPBUFFERARB WINAPI wglCreatePbufferARB( HDC hdc, int format, int width, int height, const int *attribs )
943 {
944     HPBUFFERARB ret = 0;
945     struct wgl_pbuffer *pbuffer;
946     struct opengl_funcs *funcs = get_dc_funcs( hdc );
947
948     if (!funcs || !funcs->ext.p_wglCreatePbufferARB) return 0;
949     if (!(pbuffer = funcs->ext.p_wglCreatePbufferARB( hdc, format, width, height, attribs ))) return 0;
950     ret = alloc_handle( HANDLE_PBUFFER, funcs, pbuffer );
951     if (!ret) funcs->ext.p_wglDestroyPbufferARB( pbuffer );
952     return ret;
953 }
954
955 /***********************************************************************
956  *              wglGetPbufferDCARB
957  *
958  * Provided by the WGL_ARB_pbuffer extension.
959  */
960 HDC WINAPI wglGetPbufferDCARB( HPBUFFERARB handle )
961 {
962     struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER );
963     HDC ret;
964
965     if (!ptr) return 0;
966     ret = ptr->funcs->ext.p_wglGetPbufferDCARB( ptr->u.pbuffer );
967     release_handle_ptr( ptr );
968     return ret;
969 }
970
971 /***********************************************************************
972  *              wglReleasePbufferDCARB
973  *
974  * Provided by the WGL_ARB_pbuffer extension.
975  */
976 int WINAPI wglReleasePbufferDCARB( HPBUFFERARB handle, HDC hdc )
977 {
978     struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER );
979     BOOL ret;
980
981     if (!ptr) return FALSE;
982     ret = ptr->funcs->ext.p_wglReleasePbufferDCARB( ptr->u.pbuffer, hdc );
983     release_handle_ptr( ptr );
984     return ret;
985 }
986
987 /***********************************************************************
988  *              wglDestroyPbufferARB
989  *
990  * Provided by the WGL_ARB_pbuffer extension.
991  */
992 BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB handle )
993 {
994     struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER );
995
996     if (!ptr) return FALSE;
997     ptr->funcs->ext.p_wglDestroyPbufferARB( ptr->u.pbuffer );
998     free_handle_ptr( ptr );
999     return TRUE;
1000 }
1001
1002 /***********************************************************************
1003  *              wglQueryPbufferARB
1004  *
1005  * Provided by the WGL_ARB_pbuffer extension.
1006  */
1007 BOOL WINAPI wglQueryPbufferARB( HPBUFFERARB handle, int attrib, int *value )
1008 {
1009     struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER );
1010     BOOL ret;
1011
1012     if (!ptr) return FALSE;
1013     ret = ptr->funcs->ext.p_wglQueryPbufferARB( ptr->u.pbuffer, attrib, value );
1014     release_handle_ptr( ptr );
1015     return ret;
1016 }
1017
1018 /***********************************************************************
1019  *              wglGetExtensionsStringARB
1020  *
1021  * Provided by the WGL_ARB_extensions_string extension.
1022  */
1023 const char * WINAPI wglGetExtensionsStringARB( HDC hdc )
1024 {
1025     const struct opengl_funcs *funcs = get_dc_funcs( hdc );
1026
1027     if (!funcs || !funcs->ext.p_wglGetExtensionsStringARB) return NULL;
1028     return (const char *)funcs->ext.p_wglGetExtensionsStringARB( hdc );
1029 }
1030
1031 /***********************************************************************
1032  *              wglGetExtensionsStringEXT
1033  *
1034  * Provided by the WGL_EXT_extensions_string extension.
1035  */
1036 const char * WINAPI wglGetExtensionsStringEXT(void)
1037 {
1038     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1039
1040     if (!funcs->ext.p_wglGetExtensionsStringEXT) return NULL;
1041     return (const char *)funcs->ext.p_wglGetExtensionsStringEXT();
1042 }
1043
1044 /***********************************************************************
1045  *              wglSwapIntervalEXT
1046  *
1047  * Provided by the WGL_EXT_swap_control extension.
1048  */
1049 BOOL WINAPI wglSwapIntervalEXT( int interval )
1050 {
1051     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1052
1053     if (!funcs->ext.p_wglSwapIntervalEXT) return FALSE;
1054     return funcs->ext.p_wglSwapIntervalEXT( interval );
1055 }
1056
1057 /***********************************************************************
1058  *              wglGetSwapIntervalEXT
1059  *
1060  * Provided by the WGL_EXT_swap_control extension.
1061  */
1062 int WINAPI wglGetSwapIntervalEXT(void)
1063 {
1064     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1065
1066     if (!funcs->ext.p_wglGetSwapIntervalEXT) return FALSE;
1067     return funcs->ext.p_wglGetSwapIntervalEXT();
1068 }
1069
1070 /***********************************************************************
1071  *              wglSetPixelFormatWINE
1072  *
1073  * Provided by the WGL_WINE_pixel_format_passthrough extension.
1074  */
1075 BOOL WINAPI wglSetPixelFormatWINE( HDC hdc, int format )
1076 {
1077     const struct opengl_funcs *funcs = get_dc_funcs( hdc );
1078
1079     if (!funcs || !funcs->ext.p_wglSetPixelFormatWINE) return FALSE;
1080     return funcs->ext.p_wglSetPixelFormatWINE( hdc, format );
1081 }
1082
1083 /***********************************************************************
1084  *              wglUseFontBitmaps_common
1085  */
1086 static BOOL wglUseFontBitmaps_common( HDC hdc, DWORD first, DWORD count, DWORD listBase, BOOL unicode )
1087 {
1088     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1089      GLYPHMETRICS gm;
1090      unsigned int glyph, size = 0;
1091      void *bitmap = NULL, *gl_bitmap = NULL;
1092      int org_alignment;
1093      BOOL ret = TRUE;
1094
1095      funcs->gl.p_glGetIntegerv(GL_UNPACK_ALIGNMENT, &org_alignment);
1096      funcs->gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1097
1098      for (glyph = first; glyph < first + count; glyph++) {
1099          static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
1100          unsigned int needed_size, height, width, width_int;
1101
1102          if (unicode)
1103              needed_size = GetGlyphOutlineW(hdc, glyph, GGO_BITMAP, &gm, 0, NULL, &identity);
1104          else
1105              needed_size = GetGlyphOutlineA(hdc, glyph, GGO_BITMAP, &gm, 0, NULL, &identity);
1106
1107          TRACE("Glyph: %3d / List: %d size %d\n", glyph, listBase, needed_size);
1108          if (needed_size == GDI_ERROR) {
1109              ret = FALSE;
1110              break;
1111          }
1112
1113          if (needed_size > size) {
1114              size = needed_size;
1115              HeapFree(GetProcessHeap(), 0, bitmap);
1116              HeapFree(GetProcessHeap(), 0, gl_bitmap);
1117              bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
1118              gl_bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
1119          }
1120          if (unicode)
1121              ret = (GetGlyphOutlineW(hdc, glyph, GGO_BITMAP, &gm, size, bitmap, &identity) != GDI_ERROR);
1122          else
1123              ret = (GetGlyphOutlineA(hdc, glyph, GGO_BITMAP, &gm, size, bitmap, &identity) != GDI_ERROR);
1124          if (!ret) break;
1125
1126          if (TRACE_ON(wgl)) {
1127              unsigned int bitmask;
1128              unsigned char *bitmap_ = bitmap;
1129
1130              TRACE("  - bbox: %d x %d\n", gm.gmBlackBoxX, gm.gmBlackBoxY);
1131              TRACE("  - origin: (%d, %d)\n", gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y);
1132              TRACE("  - increment: %d - %d\n", gm.gmCellIncX, gm.gmCellIncY);
1133              if (needed_size != 0) {
1134                  TRACE("  - bitmap:\n");
1135                  for (height = 0; height < gm.gmBlackBoxY; height++) {
1136                      TRACE("      ");
1137                      for (width = 0, bitmask = 0x80; width < gm.gmBlackBoxX; width++, bitmask >>= 1) {
1138                          if (bitmask == 0) {
1139                              bitmap_ += 1;
1140                              bitmask = 0x80;
1141                          }
1142                          if (*bitmap_ & bitmask)
1143                              TRACE("*");
1144                          else
1145                              TRACE(" ");
1146                      }
1147                      bitmap_ += (4 - ((UINT_PTR)bitmap_ & 0x03));
1148                      TRACE("\n");
1149                  }
1150              }
1151          }
1152
1153          /* In OpenGL, the bitmap is drawn from the bottom to the top... So we need to invert the
1154          * glyph for it to be drawn properly.
1155          */
1156          if (needed_size != 0) {
1157              width_int = (gm.gmBlackBoxX + 31) / 32;
1158              for (height = 0; height < gm.gmBlackBoxY; height++) {
1159                  for (width = 0; width < width_int; width++) {
1160                      ((int *) gl_bitmap)[(gm.gmBlackBoxY - height - 1) * width_int + width] =
1161                      ((int *) bitmap)[height * width_int + width];
1162                  }
1163              }
1164          }
1165
1166          funcs->gl.p_glNewList(listBase++, GL_COMPILE);
1167          if (needed_size != 0) {
1168              funcs->gl.p_glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
1169                      0 - gm.gmptGlyphOrigin.x, (int) gm.gmBlackBoxY - gm.gmptGlyphOrigin.y,
1170                      gm.gmCellIncX, gm.gmCellIncY,
1171                      gl_bitmap);
1172          } else {
1173              /* This is the case of 'empty' glyphs like the space character */
1174              funcs->gl.p_glBitmap(0, 0, 0, 0, gm.gmCellIncX, gm.gmCellIncY, NULL);
1175          }
1176          funcs->gl.p_glEndList();
1177      }
1178
1179      funcs->gl.p_glPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
1180      HeapFree(GetProcessHeap(), 0, bitmap);
1181      HeapFree(GetProcessHeap(), 0, gl_bitmap);
1182      return ret;
1183 }
1184
1185 /***********************************************************************
1186  *              wglUseFontBitmapsA (OPENGL32.@)
1187  */
1188 BOOL WINAPI wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD listBase)
1189 {
1190     return wglUseFontBitmaps_common( hdc, first, count, listBase, FALSE );
1191 }
1192
1193 /***********************************************************************
1194  *              wglUseFontBitmapsW (OPENGL32.@)
1195  */
1196 BOOL WINAPI wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD listBase)
1197 {
1198     return wglUseFontBitmaps_common( hdc, first, count, listBase, TRUE );
1199 }
1200
1201 #ifdef SONAME_LIBGLU
1202
1203 static void *load_libglu(void)
1204 {
1205     static int already_loaded;
1206     void *handle;
1207
1208     if (already_loaded) return libglu_handle;
1209     already_loaded = 1;
1210
1211     TRACE("Trying to load GLU library: %s\n", SONAME_LIBGLU);
1212     handle = wine_dlopen(SONAME_LIBGLU, RTLD_NOW, NULL, 0);
1213     if (!handle)
1214     {
1215         WARN("Failed to load %s\n", SONAME_LIBGLU);
1216         return NULL;
1217     }
1218
1219 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(handle, #f, NULL, 0)) == NULL) goto sym_not_found;
1220 LOAD_FUNCPTR(gluNewTess)
1221 LOAD_FUNCPTR(gluDeleteTess)
1222 LOAD_FUNCPTR(gluTessBeginContour)
1223 LOAD_FUNCPTR(gluTessBeginPolygon)
1224 LOAD_FUNCPTR(gluTessCallback)
1225 LOAD_FUNCPTR(gluTessEndContour)
1226 LOAD_FUNCPTR(gluTessEndPolygon)
1227 LOAD_FUNCPTR(gluTessVertex)
1228 #undef LOAD_FUNCPTR
1229     libglu_handle = handle;
1230     return handle;
1231
1232 sym_not_found:
1233     WARN("Unable to load function ptrs from libGLU\n");
1234     /* Close the library as we won't use it */
1235     wine_dlclose(handle, NULL, 0);
1236     return NULL;
1237 }
1238
1239 static void fixed_to_double(POINTFX fixed, UINT em_size, GLdouble vertex[3])
1240 {
1241     vertex[0] = (fixed.x.value + (GLdouble)fixed.x.fract / (1 << 16)) / em_size;  
1242     vertex[1] = (fixed.y.value + (GLdouble)fixed.y.fract / (1 << 16)) / em_size;  
1243     vertex[2] = 0.0;
1244 }
1245
1246 static void tess_callback_vertex(GLvoid *vertex)
1247 {
1248     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1249     GLdouble *dbl = vertex;
1250     TRACE("%f, %f, %f\n", dbl[0], dbl[1], dbl[2]);
1251     funcs->gl.p_glVertex3dv(vertex);
1252 }
1253
1254 static void tess_callback_begin(GLenum which)
1255 {
1256     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1257     TRACE("%d\n", which);
1258     funcs->gl.p_glBegin(which);
1259 }
1260
1261 static void tess_callback_end(void)
1262 {
1263     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1264     TRACE("\n");
1265     funcs->gl.p_glEnd();
1266 }
1267
1268 /***********************************************************************
1269  *              wglUseFontOutlines_common
1270  */
1271 static BOOL wglUseFontOutlines_common(HDC hdc,
1272                                       DWORD first,
1273                                       DWORD count,
1274                                       DWORD listBase,
1275                                       FLOAT deviation,
1276                                       FLOAT extrusion,
1277                                       int format,
1278                                       LPGLYPHMETRICSFLOAT lpgmf,
1279                                       BOOL unicode)
1280 {
1281     const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1282     UINT glyph;
1283     const MAT2 identity = {{0,1},{0,0},{0,0},{0,1}};
1284     GLUtesselator *tess;
1285     LOGFONTW lf;
1286     HFONT old_font, unscaled_font;
1287     UINT em_size = 1024;
1288     RECT rc;
1289
1290     TRACE("(%p, %d, %d, %d, %f, %f, %d, %p, %s)\n", hdc, first, count,
1291           listBase, deviation, extrusion, format, lpgmf, unicode ? "W" : "A");
1292
1293     if (!load_libglu())
1294     {
1295         ERR("libGLU is required for this function but isn't loaded\n");
1296         return FALSE;
1297     }
1298
1299     tess = pgluNewTess();
1300     if(!tess) return FALSE;
1301     pgluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)tess_callback_vertex);
1302     pgluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)tess_callback_begin);
1303     pgluTessCallback(tess, GLU_TESS_END, tess_callback_end);
1304
1305     GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf);
1306     rc.left = rc.right = rc.bottom = 0;
1307     rc.top = em_size;
1308     DPtoLP(hdc, (POINT*)&rc, 2);
1309     lf.lfHeight = -abs(rc.top - rc.bottom);
1310     lf.lfOrientation = lf.lfEscapement = 0;
1311     unscaled_font = CreateFontIndirectW(&lf);
1312     old_font = SelectObject(hdc, unscaled_font);
1313
1314     for (glyph = first; glyph < first + count; glyph++)
1315     {
1316         DWORD needed;
1317         GLYPHMETRICS gm;
1318         BYTE *buf;
1319         TTPOLYGONHEADER *pph;
1320         TTPOLYCURVE *ppc;
1321         GLdouble *vertices;
1322
1323         if(unicode)
1324             needed = GetGlyphOutlineW(hdc, glyph, GGO_NATIVE, &gm, 0, NULL, &identity);
1325         else
1326             needed = GetGlyphOutlineA(hdc, glyph, GGO_NATIVE, &gm, 0, NULL, &identity);
1327
1328         if(needed == GDI_ERROR)
1329             goto error;
1330
1331         buf = HeapAlloc(GetProcessHeap(), 0, needed);
1332         vertices = HeapAlloc(GetProcessHeap(), 0, needed / sizeof(POINTFX) * 3 * sizeof(GLdouble));
1333
1334         if(unicode)
1335             GetGlyphOutlineW(hdc, glyph, GGO_NATIVE, &gm, needed, buf, &identity);
1336         else
1337             GetGlyphOutlineA(hdc, glyph, GGO_NATIVE, &gm, needed, buf, &identity);
1338
1339         TRACE("glyph %d\n", glyph);
1340
1341         if(lpgmf)
1342         {
1343             lpgmf->gmfBlackBoxX = (float)gm.gmBlackBoxX / em_size;
1344             lpgmf->gmfBlackBoxY = (float)gm.gmBlackBoxY / em_size;
1345             lpgmf->gmfptGlyphOrigin.x = (float)gm.gmptGlyphOrigin.x / em_size;
1346             lpgmf->gmfptGlyphOrigin.y = (float)gm.gmptGlyphOrigin.y / em_size;
1347             lpgmf->gmfCellIncX = (float)gm.gmCellIncX / em_size;
1348             lpgmf->gmfCellIncY = (float)gm.gmCellIncY / em_size;
1349
1350             TRACE("%fx%f at %f,%f inc %f,%f\n", lpgmf->gmfBlackBoxX, lpgmf->gmfBlackBoxY,
1351                   lpgmf->gmfptGlyphOrigin.x, lpgmf->gmfptGlyphOrigin.y, lpgmf->gmfCellIncX, lpgmf->gmfCellIncY); 
1352             lpgmf++;
1353         }
1354
1355         funcs->gl.p_glNewList(listBase++, GL_COMPILE);
1356         pgluTessBeginPolygon(tess, NULL);
1357
1358         pph = (TTPOLYGONHEADER*)buf;
1359         while((BYTE*)pph < buf + needed)
1360         {
1361             TRACE("\tstart %d, %d\n", pph->pfxStart.x.value, pph->pfxStart.y.value);
1362
1363             pgluTessBeginContour(tess);
1364
1365             fixed_to_double(pph->pfxStart, em_size, vertices);
1366             pgluTessVertex(tess, vertices, vertices);
1367             vertices += 3;
1368
1369             ppc = (TTPOLYCURVE*)((char*)pph + sizeof(*pph));
1370             while((char*)ppc < (char*)pph + pph->cb)
1371             {
1372                 int i;
1373
1374                 switch(ppc->wType) {
1375                 case TT_PRIM_LINE:
1376                     for(i = 0; i < ppc->cpfx; i++)
1377                     {
1378                         TRACE("\t\tline to %d, %d\n", ppc->apfx[i].x.value, ppc->apfx[i].y.value);
1379                         fixed_to_double(ppc->apfx[i], em_size, vertices); 
1380                         pgluTessVertex(tess, vertices, vertices);
1381                         vertices += 3;
1382                     }
1383                     break;
1384
1385                 case TT_PRIM_QSPLINE:
1386                     for(i = 0; i < ppc->cpfx/2; i++)
1387                     {
1388                         /* FIXME: just connecting the control points for now */
1389                         TRACE("\t\tcurve  %d,%d %d,%d\n",
1390                               ppc->apfx[i * 2].x.value,     ppc->apfx[i * 3].y.value,
1391                               ppc->apfx[i * 2 + 1].x.value, ppc->apfx[i * 3 + 1].y.value);
1392                         fixed_to_double(ppc->apfx[i * 2], em_size, vertices); 
1393                         pgluTessVertex(tess, vertices, vertices);
1394                         vertices += 3;
1395                         fixed_to_double(ppc->apfx[i * 2 + 1], em_size, vertices); 
1396                         pgluTessVertex(tess, vertices, vertices);
1397                         vertices += 3;
1398                     }
1399                     break;
1400                 default:
1401                     ERR("\t\tcurve type = %d\n", ppc->wType);
1402                     pgluTessEndContour(tess);
1403                     goto error_in_list;
1404                 }
1405
1406                 ppc = (TTPOLYCURVE*)((char*)ppc + sizeof(*ppc) +
1407                                      (ppc->cpfx - 1) * sizeof(POINTFX));
1408             }
1409             pgluTessEndContour(tess);
1410             pph = (TTPOLYGONHEADER*)((char*)pph + pph->cb);
1411         }
1412
1413 error_in_list:
1414         pgluTessEndPolygon(tess);
1415         funcs->gl.p_glTranslated((GLdouble)gm.gmCellIncX / em_size, (GLdouble)gm.gmCellIncY / em_size, 0.0);
1416         funcs->gl.p_glEndList();
1417         HeapFree(GetProcessHeap(), 0, buf);
1418         HeapFree(GetProcessHeap(), 0, vertices);
1419     }
1420
1421  error:
1422     DeleteObject(SelectObject(hdc, old_font));
1423     pgluDeleteTess(tess);
1424     return TRUE;
1425
1426 }
1427
1428 #else /* SONAME_LIBGLU */
1429
1430 static BOOL wglUseFontOutlines_common(HDC hdc,
1431                                       DWORD first,
1432                                       DWORD count,
1433                                       DWORD listBase,
1434                                       FLOAT deviation,
1435                                       FLOAT extrusion,
1436                                       int format,
1437                                       LPGLYPHMETRICSFLOAT lpgmf,
1438                                       BOOL unicode)
1439 {
1440     FIXME("Unable to compile in wglUseFontOutlines support without GL/glu.h\n");
1441     return FALSE;
1442 }
1443
1444 #endif /* SONAME_LIBGLU */
1445
1446 /***********************************************************************
1447  *              wglUseFontOutlinesA (OPENGL32.@)
1448  */
1449 BOOL WINAPI wglUseFontOutlinesA(HDC hdc,
1450                                 DWORD first,
1451                                 DWORD count,
1452                                 DWORD listBase,
1453                                 FLOAT deviation,
1454                                 FLOAT extrusion,
1455                                 int format,
1456                                 LPGLYPHMETRICSFLOAT lpgmf)
1457 {
1458     return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, FALSE);
1459 }
1460
1461 /***********************************************************************
1462  *              wglUseFontOutlinesW (OPENGL32.@)
1463  */
1464 BOOL WINAPI wglUseFontOutlinesW(HDC hdc,
1465                                 DWORD first,
1466                                 DWORD count,
1467                                 DWORD listBase,
1468                                 FLOAT deviation,
1469                                 FLOAT extrusion,
1470                                 int format,
1471                                 LPGLYPHMETRICSFLOAT lpgmf)
1472 {
1473     return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, TRUE);
1474 }
1475
1476 /***********************************************************************
1477  *              glDebugEntry (OPENGL32.@)
1478  */
1479 GLint WINAPI wine_glDebugEntry( GLint unknown1, GLint unknown2 )
1480 {
1481     return 0;
1482 }
1483
1484 /* build the extension string by filtering out the disabled extensions */
1485 static char *build_gl_extensions( const char *extensions )
1486 {
1487     char *p, *str, *disabled = NULL;
1488     const char *end;
1489     HKEY hkey;
1490
1491     TRACE( "GL_EXTENSIONS:\n" );
1492
1493     if (!extensions) extensions = "";
1494
1495     /* @@ Wine registry key: HKCU\Software\Wine\OpenGL */
1496     if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\OpenGL", &hkey ))
1497     {
1498         DWORD size, ret = RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, NULL, &size );
1499         if (!ret && (disabled = HeapAlloc( GetProcessHeap(), 0, size )))
1500             ret = RegQueryValueExA( hkey, "DisabledExtensions", 0, NULL, (BYTE *)disabled, &size );
1501         RegCloseKey( hkey );
1502         if (ret) *disabled = 0;
1503     }
1504
1505     if ((str = HeapAlloc( GetProcessHeap(), 0, strlen(extensions) + 2 )))
1506     {
1507         p = str;
1508         for (;;)
1509         {
1510             while (*extensions == ' ') extensions++;
1511             if (!*extensions) break;
1512             if (!(end = strchr( extensions, ' ' ))) end = extensions + strlen( extensions );
1513             memcpy( p, extensions, end - extensions );
1514             p[end - extensions] = 0;
1515             if (!has_extension( disabled, p ))
1516             {
1517                 TRACE("++ %s\n", p );
1518                 p += end - extensions;
1519                 *p++ = ' ';
1520             }
1521             else TRACE("-- %s (disabled by config)\n", p );
1522             extensions = end;
1523         }
1524         *p = 0;
1525     }
1526     HeapFree( GetProcessHeap(), 0, disabled );
1527     return str;
1528 }
1529
1530 /***********************************************************************
1531  *              glGetString (OPENGL32.@)
1532  */
1533 const GLubyte * WINAPI wine_glGetString( GLenum name )
1534 {
1535   const struct opengl_funcs *funcs = NtCurrentTeb()->glTable;
1536   static const GLubyte *gl_extensions;
1537
1538   /* this is for buggy nvidia driver, crashing if called from a different
1539      thread with no context */
1540   if(wglGetCurrentContext() == NULL)
1541     return NULL;
1542
1543   if (name != GL_EXTENSIONS) return funcs->gl.p_glGetString(name);
1544
1545   if (!gl_extensions)
1546   {
1547       const char *orig_ext = (const char *)funcs->gl.p_glGetString(GL_EXTENSIONS);
1548       char *new_ext = build_gl_extensions( orig_ext );
1549       if (InterlockedCompareExchangePointer( (void **)&gl_extensions, new_ext, NULL ))
1550           HeapFree( GetProcessHeap(), 0, new_ext );
1551   }
1552   return gl_extensions;
1553 }
1554
1555 /***********************************************************************
1556  *              wglSwapBuffers (OPENGL32.@)
1557  */
1558 BOOL WINAPI DECLSPEC_HOTPATCH wglSwapBuffers( HDC hdc )
1559 {
1560     return GdiSwapBuffers(hdc);
1561 }
1562
1563 /**********************************************************************/
1564
1565 static void process_detach(void)
1566 {
1567   if (libglu_handle) wine_dlclose(libglu_handle, NULL, 0);
1568 }
1569
1570 /***********************************************************************
1571  *           OpenGL initialisation routine
1572  */
1573 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
1574 {
1575     switch(reason)
1576     {
1577     case DLL_PROCESS_ATTACH:
1578         opengl32_handle = hinst;
1579         DisableThreadLibraryCalls(hinst);
1580         NtCurrentTeb()->glTable = &null_opengl_funcs;
1581         break;
1582     case DLL_THREAD_ATTACH:
1583         NtCurrentTeb()->glTable = &null_opengl_funcs;
1584         break;
1585     case DLL_PROCESS_DETACH:
1586         process_detach();
1587         break;
1588     }
1589     return TRUE;
1590 }