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