msvcrt: Resolve symbols clashes with FreeBSD libc.
[wine] / dlls / winex11.drv / opengl.c
1 /*
2  * X11DRV OpenGL functions
3  *
4  * Copyright 2000 Lionel Ulmer
5  * Copyright 2005 Alex Woods
6  * Copyright 2005 Raphael Junqueira
7  * Copyright 2006 Roderick Colenbrander
8  * Copyright 2006 Tomas Carnecky
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24
25 #include "config.h"
26 #include "wine/port.h"
27
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "x11drv.h"
33 #include "winternl.h"
34 #include "wine/library.h"
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
38 WINE_DECLARE_DEBUG_CHANNEL(opengl);
39
40 #ifdef SONAME_LIBGL
41
42 #undef APIENTRY
43 #undef CALLBACK
44 #undef WINAPI
45
46 #ifdef HAVE_GL_GL_H
47 # include <GL/gl.h>
48 #endif
49 #ifdef HAVE_GL_GLX_H
50 # include <GL/glx.h>
51 #endif
52 #ifdef HAVE_GL_GLEXT_H
53 # include <GL/glext.h>
54 #endif
55
56 #include "wine/wgl.h"
57
58 #undef APIENTRY
59 #undef CALLBACK
60 #undef WINAPI
61
62 /* Redefines the constants */
63 #define CALLBACK    __stdcall
64 #define WINAPI      __stdcall
65 #define APIENTRY    WINAPI
66
67
68 WINE_DECLARE_DEBUG_CHANNEL(fps);
69
70 typedef struct wine_glextension {
71     const char *extName;
72     struct {
73         const char *funcName;
74         void *funcAddress;
75     } extEntryPoints[8];
76 } WineGLExtension;
77
78 struct WineGLInfo {
79     const char *glVersion;
80     const char *glExtensions;
81
82     int glxVersion[2];
83
84     const char *glxServerVersion;
85     const char *glxServerVendor;
86     const char *glxServerExtensions;
87
88     const char *glxClientVersion;
89     const char *glxClientVendor;
90     const char *glxClientExtensions;
91
92     const char *glxExtensions;
93
94     BOOL glxDirect;
95     char wglExtensions[4096];
96 };
97
98 typedef struct wine_glpixelformat {
99     int         iPixelFormat;
100     GLXFBConfig fbconfig;
101     int         fmt_id;
102     int         render_type;
103     BOOL        offscreenOnly;
104 } WineGLPixelFormat;
105
106 typedef struct wine_glcontext {
107     HDC hdc;
108     XVisualInfo *vis;
109     WineGLPixelFormat *fmt;
110     GLXContext ctx;
111     BOOL do_escape;
112     X11DRV_PDEVICE *physDev;
113     X11DRV_PDEVICE *pReadDev;
114     RECT viewport;
115     RECT scissor;
116     BOOL scissor_enabled;
117     struct wine_glcontext *next;
118     struct wine_glcontext *prev;
119 } Wine_GLContext;
120
121 typedef struct wine_glpbuffer {
122     Drawable   drawable;
123     Display*   display;
124     WineGLPixelFormat* fmt;
125     int        width;
126     int        height;
127     int*       attribList;
128     HDC        hdc;
129
130     int        use_render_texture; /* This is also the internal texture format */
131     int        texture_bind_target;
132     int        texture_bpp;
133     GLint      texture_format;
134     GLuint     texture_target;
135     GLenum     texture_type;
136     GLuint     texture;
137     int        texture_level;
138 } Wine_GLPBuffer;
139
140 static Wine_GLContext *context_list;
141 static struct WineGLInfo WineGLInfo = { 0 };
142 static int use_render_texture_emulation = 1;
143 static int use_render_texture_ati = 0;
144 static int swap_interval = 1;
145
146 #define MAX_EXTENSIONS 16
147 static const WineGLExtension *WineGLExtensionList[MAX_EXTENSIONS];
148 static int WineGLExtensionListSize;
149
150 static WineGLPixelFormat *WineGLPixelFormatList;
151 static int WineGLPixelFormatListSize = 0;
152 static int WineGLPixelFormatOnScreenSize = 0;
153
154 static void X11DRV_WineGL_LoadExtensions(void);
155 static BOOL glxRequireVersion(int requiredVersion);
156 static BOOL glxRequireExtension(const char *requiredExtension);
157
158 static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
159   TRACE("  - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion);
160   TRACE("  - dwFlags : ");
161 #define TEST_AND_DUMP(t,tv) if ((t) & (tv)) TRACE(#tv " ")
162   TEST_AND_DUMP(ppfd->dwFlags, PFD_DEPTH_DONTCARE);
163   TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER);
164   TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER_DONTCARE);
165   TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_WINDOW);
166   TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_BITMAP);
167   TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_ACCELERATED);
168   TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_FORMAT);
169   TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_PALETTE);
170   TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_SYSTEM_PALETTE);
171   TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO);
172   TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO_DONTCARE);
173   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_GDI);
174   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_OPENGL);
175   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_COPY);
176   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_EXCHANGE);
177   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_LAYER_BUFFERS);
178   /* PFD_SUPPORT_COMPOSITION is new in Vista, it is similar to composition
179    * under X e.g. COMPOSITE + GLX_EXT_TEXTURE_FROM_PIXMAP. */
180   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_COMPOSITION);
181 #undef TEST_AND_DUMP
182   TRACE("\n");
183
184   TRACE("  - iPixelType : ");
185   switch (ppfd->iPixelType) {
186   case PFD_TYPE_RGBA: TRACE("PFD_TYPE_RGBA"); break;
187   case PFD_TYPE_COLORINDEX: TRACE("PFD_TYPE_COLORINDEX"); break;
188   }
189   TRACE("\n");
190
191   TRACE("  - Color   : %d\n", ppfd->cColorBits);
192   TRACE("  - Red     : %d\n", ppfd->cRedBits);
193   TRACE("  - Green   : %d\n", ppfd->cGreenBits);
194   TRACE("  - Blue    : %d\n", ppfd->cBlueBits);
195   TRACE("  - Alpha   : %d\n", ppfd->cAlphaBits);
196   TRACE("  - Accum   : %d\n", ppfd->cAccumBits);
197   TRACE("  - Depth   : %d\n", ppfd->cDepthBits);
198   TRACE("  - Stencil : %d\n", ppfd->cStencilBits);
199   TRACE("  - Aux     : %d\n", ppfd->cAuxBuffers);
200
201   TRACE("  - iLayerType : ");
202   switch (ppfd->iLayerType) {
203   case PFD_MAIN_PLANE: TRACE("PFD_MAIN_PLANE"); break;
204   case PFD_OVERLAY_PLANE: TRACE("PFD_OVERLAY_PLANE"); break;
205   case (BYTE)PFD_UNDERLAY_PLANE: TRACE("PFD_UNDERLAY_PLANE"); break;
206   }
207   TRACE("\n");
208 }
209
210 #define PUSH1(attribs,att)        do { attribs[nAttribs++] = (att); } while (0)
211 #define PUSH2(attribs,att,value)  do { attribs[nAttribs++] = (att); attribs[nAttribs++] = (value); } while(0)
212
213 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
214 /* GLX 1.0 */
215 MAKE_FUNCPTR(glXChooseVisual)
216 MAKE_FUNCPTR(glXCreateContext)
217 MAKE_FUNCPTR(glXCreateGLXPixmap)
218 MAKE_FUNCPTR(glXGetCurrentContext)
219 MAKE_FUNCPTR(glXGetCurrentDrawable)
220 MAKE_FUNCPTR(glXDestroyContext)
221 MAKE_FUNCPTR(glXDestroyGLXPixmap)
222 MAKE_FUNCPTR(glXGetConfig)
223 MAKE_FUNCPTR(glXIsDirect)
224 MAKE_FUNCPTR(glXMakeCurrent)
225 MAKE_FUNCPTR(glXSwapBuffers)
226 MAKE_FUNCPTR(glXQueryExtension)
227 MAKE_FUNCPTR(glXQueryVersion)
228 MAKE_FUNCPTR(glXUseXFont)
229
230 /* GLX 1.1 */
231 MAKE_FUNCPTR(glXGetClientString)
232 MAKE_FUNCPTR(glXQueryExtensionsString)
233 MAKE_FUNCPTR(glXQueryServerString)
234
235 /* GLX 1.3 */
236 MAKE_FUNCPTR(glXGetFBConfigs)
237 MAKE_FUNCPTR(glXChooseFBConfig)
238 MAKE_FUNCPTR(glXCreatePbuffer)
239 MAKE_FUNCPTR(glXCreateNewContext)
240 MAKE_FUNCPTR(glXDestroyPbuffer)
241 MAKE_FUNCPTR(glXGetFBConfigAttrib)
242 MAKE_FUNCPTR(glXGetVisualFromFBConfig)
243 MAKE_FUNCPTR(glXMakeContextCurrent)
244 MAKE_FUNCPTR(glXQueryDrawable)
245 MAKE_FUNCPTR(glXGetCurrentReadDrawable)
246
247 /* GLX Extensions */
248 static void* (*pglXGetProcAddressARB)(const GLubyte *);
249 static int   (*pglXSwapIntervalSGI)(int);
250
251 /* ATI GLX Extensions */
252 static BOOL  (*pglXBindTexImageATI)(Display *dpy, GLXPbuffer pbuffer, int buffer);
253 static BOOL  (*pglXReleaseTexImageATI)(Display *dpy, GLXPbuffer pbuffer, int buffer);
254 static BOOL  (*pglXDrawableAttribATI)(Display *dpy, GLXDrawable draw, const int *attribList);
255
256 /* NV GLX Extension */
257 static void* (*pglXAllocateMemoryNV)(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
258 static void  (*pglXFreeMemoryNV)(GLvoid *pointer);
259
260 /* Standard OpenGL */
261 MAKE_FUNCPTR(glBindTexture)
262 MAKE_FUNCPTR(glBitmap)
263 MAKE_FUNCPTR(glCopyTexSubImage1D)
264 MAKE_FUNCPTR(glCopyTexImage2D)
265 MAKE_FUNCPTR(glCopyTexSubImage2D)
266 MAKE_FUNCPTR(glDisable)
267 MAKE_FUNCPTR(glDrawBuffer)
268 MAKE_FUNCPTR(glEnable)
269 MAKE_FUNCPTR(glEndList)
270 MAKE_FUNCPTR(glGetError)
271 MAKE_FUNCPTR(glGetIntegerv)
272 MAKE_FUNCPTR(glGetString)
273 MAKE_FUNCPTR(glIsEnabled)
274 MAKE_FUNCPTR(glNewList)
275 MAKE_FUNCPTR(glPixelStorei)
276 MAKE_FUNCPTR(glReadPixels)
277 MAKE_FUNCPTR(glScissor)
278 MAKE_FUNCPTR(glTexImage2D)
279 MAKE_FUNCPTR(glViewport)
280 #undef MAKE_FUNCPTR
281
282 static BOOL X11DRV_WineGL_InitOpenglInfo(void)
283 {
284     static BOOL infoInitialized = FALSE;
285
286     int screen = DefaultScreen(gdi_display);
287     Window win = RootWindow(gdi_display, screen);
288     Visual *visual;
289     XVisualInfo template;
290     XVisualInfo *vis;
291     int num;
292     GLXContext ctx = NULL;
293
294     if (infoInitialized)
295         return TRUE;
296     infoInitialized = TRUE;
297
298     wine_tsx11_lock();
299
300     visual = DefaultVisual(gdi_display, screen);
301     template.visualid = XVisualIDFromVisual(visual);
302     vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num);
303     if (vis) {
304         WORD old_fs = wine_get_fs();
305         /* Create a GLX Context. Without one we can't query GL information */
306         ctx = pglXCreateContext(gdi_display, vis, None, GL_TRUE);
307         if (wine_get_fs() != old_fs)
308         {
309             wine_set_fs( old_fs );
310             wine_tsx11_unlock();
311             ERR( "%%fs register corrupted, probably broken ATI driver, disabling OpenGL.\n" );
312             ERR( "You need to set the \"UseFastTls\" option to \"2\" in your X config file.\n" );
313             return FALSE;
314         }
315     }
316
317     if (ctx) {
318         pglXMakeCurrent(gdi_display, win, ctx);
319     } else {
320         ERR(" couldn't initialize OpenGL, expect problems\n");
321         wine_tsx11_unlock();
322         return FALSE;
323     }
324
325     WineGLInfo.glVersion = (const char *) pglGetString(GL_VERSION);
326     WineGLInfo.glExtensions = strdup((const char *) pglGetString(GL_EXTENSIONS));
327
328     /* Get the common GLX version supported by GLX client and server ( major/minor) */
329     pglXQueryVersion(gdi_display, &WineGLInfo.glxVersion[0], &WineGLInfo.glxVersion[1]);
330
331     WineGLInfo.glxServerVersion = pglXQueryServerString(gdi_display, screen, GLX_VERSION);
332     WineGLInfo.glxServerVendor = pglXQueryServerString(gdi_display, screen, GLX_VENDOR);
333     WineGLInfo.glxServerExtensions = pglXQueryServerString(gdi_display, screen, GLX_EXTENSIONS);
334
335     WineGLInfo.glxClientVersion = pglXGetClientString(gdi_display, GLX_VERSION);
336     WineGLInfo.glxClientVendor = pglXGetClientString(gdi_display, GLX_VENDOR);
337     WineGLInfo.glxClientExtensions = pglXGetClientString(gdi_display, GLX_EXTENSIONS);
338
339     WineGLInfo.glxExtensions = pglXQueryExtensionsString(gdi_display, screen);
340     WineGLInfo.glxDirect = pglXIsDirect(gdi_display, ctx);
341
342     TRACE("GL version             : %s.\n", WineGLInfo.glVersion);
343     TRACE("GL renderer            : %s.\n", pglGetString(GL_RENDERER));
344     TRACE("GLX version            : %d.%d.\n", WineGLInfo.glxVersion[0], WineGLInfo.glxVersion[1]);
345     TRACE("Server GLX version     : %s.\n", WineGLInfo.glxServerVersion);
346     TRACE("Server GLX vendor:     : %s.\n", WineGLInfo.glxServerVendor);
347     TRACE("Client GLX version     : %s.\n", WineGLInfo.glxClientVersion);
348     TRACE("Client GLX vendor:     : %s.\n", WineGLInfo.glxClientVendor);
349     TRACE("Direct rendering enabled: %s\n", WineGLInfo.glxDirect ? "True" : "False");
350
351     if(vis) XFree(vis);
352     if(ctx) {
353         pglXMakeCurrent(gdi_display, None, NULL);    
354         pglXDestroyContext(gdi_display, ctx);
355     }
356     wine_tsx11_unlock();
357     return TRUE;
358 }
359
360 static BOOL has_opengl(void)
361 {
362     static int init_done;
363     static void *opengl_handle;
364
365     int error_base, event_base;
366
367     if (init_done) return (opengl_handle != NULL);
368     init_done = 1;
369
370     /* No need to load any other libraries as according to the ABI, libGL should be self-sufficient
371        and include all dependencies */
372     opengl_handle = wine_dlopen(SONAME_LIBGL, RTLD_NOW|RTLD_GLOBAL, NULL, 0);
373     if (opengl_handle == NULL) return FALSE;
374
375     pglXGetProcAddressARB = wine_dlsym(opengl_handle, "glXGetProcAddressARB", NULL, 0);
376     if (pglXGetProcAddressARB == NULL) {
377         ERR("could not find glXGetProcAddressARB in libGL.\n");
378         return FALSE;
379     }
380
381 #define LOAD_FUNCPTR(f) if((p##f = (void*)pglXGetProcAddressARB((const unsigned char*)#f)) == NULL) goto sym_not_found;
382 /* GLX 1.0 */
383 LOAD_FUNCPTR(glXChooseVisual)
384 LOAD_FUNCPTR(glXCreateContext)
385 LOAD_FUNCPTR(glXCreateGLXPixmap)
386 LOAD_FUNCPTR(glXGetCurrentContext)
387 LOAD_FUNCPTR(glXGetCurrentDrawable)
388 LOAD_FUNCPTR(glXDestroyContext)
389 LOAD_FUNCPTR(glXDestroyGLXPixmap)
390 LOAD_FUNCPTR(glXGetConfig)
391 LOAD_FUNCPTR(glXIsDirect)
392 LOAD_FUNCPTR(glXMakeCurrent)
393 LOAD_FUNCPTR(glXSwapBuffers)
394 LOAD_FUNCPTR(glXQueryExtension)
395 LOAD_FUNCPTR(glXQueryVersion)
396 LOAD_FUNCPTR(glXUseXFont)
397
398 /* GLX 1.1 */
399 LOAD_FUNCPTR(glXGetClientString)
400 LOAD_FUNCPTR(glXQueryExtensionsString)
401 LOAD_FUNCPTR(glXQueryServerString)
402
403 /* GLX 1.3 */
404 LOAD_FUNCPTR(glXCreatePbuffer)
405 LOAD_FUNCPTR(glXCreateNewContext)
406 LOAD_FUNCPTR(glXDestroyPbuffer)
407 LOAD_FUNCPTR(glXMakeContextCurrent)
408 LOAD_FUNCPTR(glXGetCurrentReadDrawable)
409 LOAD_FUNCPTR(glXGetFBConfigs)
410
411 /* Standard OpenGL calls */
412 LOAD_FUNCPTR(glBindTexture)
413 LOAD_FUNCPTR(glBitmap)
414 LOAD_FUNCPTR(glCopyTexSubImage1D)
415 LOAD_FUNCPTR(glCopyTexImage2D)
416 LOAD_FUNCPTR(glCopyTexSubImage2D)
417 LOAD_FUNCPTR(glDisable)
418 LOAD_FUNCPTR(glDrawBuffer)
419 LOAD_FUNCPTR(glEnable)
420 LOAD_FUNCPTR(glEndList)
421 LOAD_FUNCPTR(glGetError)
422 LOAD_FUNCPTR(glGetIntegerv)
423 LOAD_FUNCPTR(glGetString)
424 LOAD_FUNCPTR(glIsEnabled)
425 LOAD_FUNCPTR(glNewList)
426 LOAD_FUNCPTR(glPixelStorei)
427 LOAD_FUNCPTR(glReadPixels)
428 LOAD_FUNCPTR(glScissor)
429 LOAD_FUNCPTR(glTexImage2D)
430 LOAD_FUNCPTR(glViewport)
431 #undef LOAD_FUNCPTR
432
433 /* It doesn't matter if these fail. They'll only be used if the driver reports
434    the associated extension is available (and if a driver reports the extension
435    is available but fails to provide the functions, it's quite broken) */
436 #define LOAD_FUNCPTR(f) p##f = (void*)pglXGetProcAddressARB((const unsigned char*)#f);
437 /* NV GLX Extension */
438 LOAD_FUNCPTR(glXAllocateMemoryNV)
439 LOAD_FUNCPTR(glXFreeMemoryNV)
440 #undef LOAD_FUNCPTR
441
442     if(!X11DRV_WineGL_InitOpenglInfo()) {
443         wine_dlclose(opengl_handle, NULL, 0);
444         opengl_handle = NULL;
445         return FALSE;
446     }
447
448     wine_tsx11_lock();
449     if (pglXQueryExtension(gdi_display, &error_base, &event_base) == True) {
450         TRACE("GLX is up and running error_base = %d\n", error_base);
451     } else {
452         wine_dlclose(opengl_handle, NULL, 0);
453         opengl_handle = NULL;
454     }
455
456     /* In case of GLX you have direct and indirect rendering. Most of the time direct rendering is used
457      * as in general only that is hardware accelerated. In some cases like in case of remote X indirect
458      * rendering is used.
459      *
460      * The main problem for our OpenGL code is that we need certain GLX calls but their presence
461      * depends on the reported GLX client / server version and on the client / server extension list.
462      * Those don't have to be the same.
463      *
464      * In general the server GLX information lists the capabilities in case of indirect rendering.
465      * When direct rendering is used, the OpenGL client library is responsible for which GLX calls are
466      * available and in that case the client GLX informat can be used.
467      * OpenGL programs should use the 'intersection' of both sets of information which is advertised
468      * in the GLX version/extension list. When a program does this it works for certain for both
469      * direct and indirect rendering.
470      *
471      * The problem we are having in this area is that ATI's Linux drivers are broken. For some reason
472      * they haven't added some very important GLX extensions like GLX_SGIX_fbconfig to their client
473      * extension list which causes this extension not to be listed. (Wine requires this extension).
474      * ATI advertises a GLX client version of 1.3 which implies that this fbconfig extension among
475      * pbuffers is around.
476      *
477      * In order to provide users of Ati's proprietary drivers with OpenGL support, we need to detect
478      * the ATI drivers and from then on use GLX client information for them.
479      */
480
481     if(glxRequireVersion(3)) {
482         pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfig");
483         pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttrib");
484         pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfig");
485         pglXQueryDrawable = (void*)pglXGetProcAddressARB((const GLubyte *) "glXQueryDrawable");
486     } else if(glxRequireExtension("GLX_SGIX_fbconfig")) {
487         pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfigSGIX");
488         pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttribSGIX");
489         pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfigSGIX");
490
491         /* The mesa libGL client library seems to forward glXQueryDrawable to the Xserver, so only
492          * enable this function when the Xserver understand GLX 1.3 or newer
493          */
494         pglXQueryDrawable = NULL;
495      } else if(strcmp("ATI", WineGLInfo.glxClientVendor) == 0) {
496         TRACE("Overriding ATI GLX capabilities!\n");
497         pglXChooseFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfig");
498         pglXGetFBConfigAttrib = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttrib");
499         pglXGetVisualFromFBConfig = (void*)pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfig");
500         pglXQueryDrawable = (void*)pglXGetProcAddressARB((const GLubyte *) "glXQueryDrawable");
501
502         /* Use client GLX information in case of the ATI drivers. We override the
503          * capabilities over here and not somewhere else as ATI might better their
504          * life in the future. In case they release proper drivers this block of
505          * code won't be called. */
506         WineGLInfo.glxExtensions = WineGLInfo.glxClientExtensions;
507     } else {
508          ERR(" glx_version is %s and GLX_SGIX_fbconfig extension is unsupported. Expect problems.\n", WineGLInfo.glxServerVersion);
509     }
510
511     if(glxRequireExtension("GLX_ATI_render_texture")) {
512         use_render_texture_ati = 1;
513         pglXBindTexImageATI = (void*)pglXGetProcAddressARB((const GLubyte *) "glXBindTexImageATI");
514         pglXReleaseTexImageATI = (void*)pglXGetProcAddressARB((const GLubyte *) "glXReleaseTexImageATI");
515         pglXDrawableAttribATI = (void*)pglXGetProcAddressARB((const GLubyte *) "glXDrawableAttribATI");
516     }
517
518     X11DRV_WineGL_LoadExtensions();
519
520     wine_tsx11_unlock();
521     return (opengl_handle != NULL);
522
523 sym_not_found:
524     wine_dlclose(opengl_handle, NULL, 0);
525     opengl_handle = NULL;
526     return FALSE;
527 }
528
529 static inline Wine_GLContext *alloc_context(void)
530 {
531     Wine_GLContext *ret;
532
533     if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLContext))))
534     {
535         ret->next = context_list;
536         if (context_list) context_list->prev = ret;
537         context_list = ret;
538     }
539     return ret;
540 }
541
542 static inline void free_context(Wine_GLContext *context)
543 {
544     if (context->next != NULL) context->next->prev = context->prev;
545     if (context->prev != NULL) context->prev->next = context->next;
546     else context_list = context->next;
547
548     if (context->vis) XFree(context->vis);
549     HeapFree(GetProcessHeap(), 0, context);
550 }
551
552 static inline BOOL is_valid_context( Wine_GLContext *ctx )
553 {
554     Wine_GLContext *ptr;
555     for (ptr = context_list; ptr; ptr = ptr->next) if (ptr == ctx) break;
556     return (ptr != NULL);
557 }
558
559 static int describeContext(Wine_GLContext* ctx) {
560     int tmp;
561     int ctx_vis_id;
562     TRACE(" Context %p have (vis:%p):\n", ctx, ctx->vis);
563     pglXGetFBConfigAttrib(gdi_display, ctx->fmt->fbconfig, GLX_FBCONFIG_ID, &tmp);
564     TRACE(" - FBCONFIG_ID 0x%x\n", tmp);
565     pglXGetFBConfigAttrib(gdi_display, ctx->fmt->fbconfig, GLX_VISUAL_ID, &tmp);
566     TRACE(" - VISUAL_ID 0x%x\n", tmp);
567     ctx_vis_id = tmp;
568     return ctx_vis_id;
569 }
570
571 static int describeDrawable(Wine_GLContext* ctx, Drawable drawable) {
572     int tmp;
573     int nElements;
574     int attribList[3] = { GLX_FBCONFIG_ID, 0, None };
575     GLXFBConfig *fbCfgs;
576
577     if (pglXQueryDrawable == NULL)  {
578         /** glXQueryDrawable not available so returns not supported */
579         return -1;
580     }
581
582     TRACE(" Drawable %p have :\n", (void*) drawable);
583     pglXQueryDrawable(gdi_display, drawable, GLX_WIDTH, (unsigned int*) &tmp);
584     TRACE(" - WIDTH as %d\n", tmp);
585     pglXQueryDrawable(gdi_display, drawable, GLX_HEIGHT, (unsigned int*) &tmp);
586     TRACE(" - HEIGHT as %d\n", tmp);
587     pglXQueryDrawable(gdi_display, drawable, GLX_FBCONFIG_ID, (unsigned int*) &tmp);
588     TRACE(" - FBCONFIG_ID as 0x%x\n", tmp);
589
590     attribList[1] = tmp;
591     fbCfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), attribList, &nElements);
592     if (fbCfgs == NULL) {
593         return -1;
594     }
595
596     pglXGetFBConfigAttrib(gdi_display, fbCfgs[0], GLX_VISUAL_ID, &tmp);
597     TRACE(" - VISUAL_ID as 0x%x\n", tmp);
598
599     XFree(fbCfgs);
600
601     return tmp;
602 }
603
604 static int ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_GLPBuffer* pbuf) {
605   int nAttribs = 0;
606   unsigned cur = 0; 
607   int pop;
608   int drawattrib = 0;
609   int nvfloatattrib = GLX_DONT_CARE;
610   int pixelattrib = 0;
611
612   /* The list of WGL attributes is allowed to be NULL. We don't return here for NULL
613    * because we need to do fixups for GLX_DRAWABLE_TYPE/GLX_RENDER_TYPE/GLX_FLOAT_COMPONENTS_NV. */
614   while (iWGLAttr && 0 != iWGLAttr[cur]) {
615     TRACE("pAttr[%d] = %x\n", cur, iWGLAttr[cur]);
616
617     switch (iWGLAttr[cur]) {
618     case WGL_COLOR_BITS_ARB:
619       pop = iWGLAttr[++cur];
620       PUSH2(oGLXAttr, GLX_BUFFER_SIZE, pop);
621       TRACE("pAttr[%d] = GLX_BUFFER_SIZE: %d\n", cur, pop);
622       break;
623     case WGL_BLUE_BITS_ARB:
624       pop = iWGLAttr[++cur];
625       PUSH2(oGLXAttr, GLX_BLUE_SIZE, pop);
626       TRACE("pAttr[%d] = GLX_BLUE_SIZE: %d\n", cur, pop);
627       break;
628     case WGL_RED_BITS_ARB:
629       pop = iWGLAttr[++cur];
630       PUSH2(oGLXAttr, GLX_RED_SIZE, pop);
631       TRACE("pAttr[%d] = GLX_RED_SIZE: %d\n", cur, pop);
632       break;
633     case WGL_GREEN_BITS_ARB:
634       pop = iWGLAttr[++cur];
635       PUSH2(oGLXAttr, GLX_GREEN_SIZE, pop);
636       TRACE("pAttr[%d] = GLX_GREEN_SIZE: %d\n", cur, pop);
637       break;
638     case WGL_ALPHA_BITS_ARB:
639       pop = iWGLAttr[++cur];
640       PUSH2(oGLXAttr, GLX_ALPHA_SIZE, pop);
641       TRACE("pAttr[%d] = GLX_ALPHA_SIZE: %d\n", cur, pop);
642       break;
643     case WGL_DEPTH_BITS_ARB:
644       pop = iWGLAttr[++cur];
645       PUSH2(oGLXAttr, GLX_DEPTH_SIZE, pop);
646       TRACE("pAttr[%d] = GLX_DEPTH_SIZE: %d\n", cur, pop);
647       break;
648     case WGL_STENCIL_BITS_ARB:
649       pop = iWGLAttr[++cur];
650       PUSH2(oGLXAttr, GLX_STENCIL_SIZE, pop);
651       TRACE("pAttr[%d] = GLX_STENCIL_SIZE: %d\n", cur, pop);
652       break;
653     case WGL_DOUBLE_BUFFER_ARB:
654       pop = iWGLAttr[++cur];
655       PUSH2(oGLXAttr, GLX_DOUBLEBUFFER, pop);
656       TRACE("pAttr[%d] = GLX_DOUBLEBUFFER: %d\n", cur, pop);
657       break;
658
659     case WGL_PIXEL_TYPE_ARB:
660       pop = iWGLAttr[++cur];
661       TRACE("pAttr[%d] = WGL_PIXEL_TYPE_ARB: %d\n", cur, pop);
662       switch (pop) {
663       case WGL_TYPE_COLORINDEX_ARB: pixelattrib = GLX_COLOR_INDEX_BIT; break ;
664       case WGL_TYPE_RGBA_ARB: pixelattrib = GLX_RGBA_BIT; break ;
665       /* This is the same as WGL_TYPE_RGBA_FLOAT_ATI but the GLX constants differ, only the ARB GLX one is widely supported so use that */
666       case WGL_TYPE_RGBA_FLOAT_ATI: pixelattrib = GLX_RGBA_FLOAT_BIT; break ;
667       default:
668         ERR("unexpected PixelType(%x)\n", pop); 
669         pop = 0;
670       }
671       break;
672
673     case WGL_SUPPORT_GDI_ARB:
674       pop = iWGLAttr[++cur];
675       PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
676       TRACE("pAttr[%d] = WGL_SUPPORT_GDI_ARB: %d\n", cur, pop);
677       break;
678
679     case WGL_DRAW_TO_BITMAP_ARB:
680       pop = iWGLAttr[++cur];
681       TRACE("pAttr[%d] = WGL_DRAW_TO_BITMAP_ARB: %d\n", cur, pop);
682       /* GLX_DRAWABLE_TYPE flags need to be OR'd together. See below. */
683       if (pop) {
684         drawattrib |= GLX_PIXMAP_BIT;
685       }
686       break;
687
688     case WGL_DRAW_TO_WINDOW_ARB:
689       pop = iWGLAttr[++cur];
690       TRACE("pAttr[%d] = WGL_DRAW_TO_WINDOW_ARB: %d\n", cur, pop);
691       /* GLX_DRAWABLE_TYPE flags need to be OR'd together. See below. */
692       if (pop) {
693         drawattrib |= GLX_WINDOW_BIT;
694       }
695       break;
696
697     case WGL_DRAW_TO_PBUFFER_ARB:
698       pop = iWGLAttr[++cur];
699       TRACE("pAttr[%d] = WGL_DRAW_TO_PBUFFER_ARB: %d\n", cur, pop);
700       /* GLX_DRAWABLE_TYPE flags need to be OR'd together. See below. */
701       if (pop) {
702         drawattrib |= GLX_PBUFFER_BIT;
703       }
704       break;
705
706     case WGL_ACCELERATION_ARB:
707     case WGL_SUPPORT_OPENGL_ARB:
708       pop = iWGLAttr[++cur];
709       /** nothing to do, if we are here, supposing support Accelerated OpenGL */
710       TRACE("pAttr[%d] = WGL_SUPPORT_OPENGL_ARB: %d\n", cur, pop);
711       break;
712
713     case WGL_PBUFFER_LARGEST_ARB:
714       pop = iWGLAttr[++cur];
715       PUSH2(oGLXAttr, GLX_LARGEST_PBUFFER, pop);
716       TRACE("pAttr[%d] = GLX_LARGEST_PBUFFER: %x\n", cur, pop);
717       break;
718
719     case WGL_SAMPLE_BUFFERS_ARB:
720       pop = iWGLAttr[++cur];
721       PUSH2(oGLXAttr, GLX_SAMPLE_BUFFERS_ARB, pop);
722       TRACE("pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x\n", cur, pop);
723       break;
724
725     case WGL_SAMPLES_ARB:
726       pop = iWGLAttr[++cur];
727       PUSH2(oGLXAttr, GLX_SAMPLES_ARB, pop);
728       TRACE("pAttr[%d] = GLX_SAMPLES_ARB: %x\n", cur, pop);
729       break;
730
731     case WGL_TEXTURE_FORMAT_ARB:
732     case WGL_TEXTURE_TARGET_ARB:
733     case WGL_MIPMAP_TEXTURE_ARB:
734       TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr[cur], iWGLAttr[cur + 1]);
735       pop = iWGLAttr[++cur];
736       if (NULL == pbuf) {
737         ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr[cur]);
738       }
739       if (use_render_texture_ati) {
740         /** nothing to do here */
741       }
742       else if (!use_render_texture_emulation) {
743         if (WGL_NO_TEXTURE_ARB != pop) {
744           ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr[cur]);
745           return -1; /** error: don't support it */
746         } else {
747           PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
748           drawattrib |= GLX_PBUFFER_BIT;
749         }
750       }
751       break ;
752     case WGL_FLOAT_COMPONENTS_NV:
753       nvfloatattrib = iWGLAttr[++cur];
754       TRACE("pAttr[%d] = WGL_FLOAT_COMPONENTS_NV: %x\n", cur, nvfloatattrib);
755       break ;
756     case WGL_BIND_TO_TEXTURE_RGB_ARB:
757     case WGL_BIND_TO_TEXTURE_RGBA_ARB:
758     case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV:
759     case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV:
760     case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV:
761     case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV:
762       pop = iWGLAttr[++cur];
763       /** cannot be converted, see direct handling on 
764        *   - wglGetPixelFormatAttribivARB
765        *  TODO: wglChoosePixelFormat
766        */
767       break ;
768
769     default:
770       FIXME("unsupported %x WGL Attribute\n", iWGLAttr[cur]);
771       break;
772     }
773     ++cur;
774   }
775
776   /* Apply the OR'd drawable type bitmask now EVEN when WGL_DRAW_TO* is unset.
777    * It is needed in all cases because GLX_DRAWABLE_TYPE default to GLX_WINDOW_BIT. */
778   PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, drawattrib);
779   TRACE("pAttr[?] = GLX_DRAWABLE_TYPE: %#x\n", drawattrib);
780
781   /* Set GLX_RENDER_TYPE all the time */
782   PUSH2(oGLXAttr, GLX_RENDER_TYPE, pixelattrib);
783   TRACE("pAttr[?] = GLX_RENDER_TYPE: %#x\n", pixelattrib);
784
785   /* Set GLX_FLOAT_COMPONENTS_NV all the time */
786   if(strstr(WineGLInfo.glxExtensions, "GLX_NV_float_buffer")) {
787     PUSH2(oGLXAttr, GLX_FLOAT_COMPONENTS_NV, nvfloatattrib);
788     TRACE("pAttr[?] = GLX_FLOAT_COMPONENTS_NV: %#x\n", nvfloatattrib);
789   }
790
791   return nAttribs;
792 }
793
794 static int get_render_type_from_fbconfig(Display *display, GLXFBConfig fbconfig)
795 {
796     int render_type=0, render_type_bit;
797     pglXGetFBConfigAttrib(display, fbconfig, GLX_RENDER_TYPE, &render_type_bit);
798     switch(render_type_bit)
799     {
800         case GLX_RGBA_BIT:
801             render_type = GLX_RGBA_TYPE;
802             break;
803         case GLX_COLOR_INDEX_BIT:
804             render_type = GLX_COLOR_INDEX_TYPE;
805             break;
806         case GLX_RGBA_FLOAT_BIT:
807             render_type = GLX_RGBA_FLOAT_TYPE;
808             break;
809         default:
810             ERR("Unknown render_type: %x\n", render_type);
811     }
812     return render_type;
813 }
814
815 static BOOL init_formats(Display *display, int screen, Visual *visual)
816 {
817     int fmt_id, tmp_fmt_id, nCfgs, i;
818     GLXFBConfig* cfgs;
819     GLXFBConfig fbconfig = NULL;
820     XVisualInfo *visinfo;
821     VisualID visualid = XVisualIDFromVisual(visual);
822     int nOffscreenFormats = 0;
823
824     /* As mentioned in various parts of the code only the format of the main visual can be used for onscreen rendering.
825     * Next to this format there are also so called offscreen rendering formats (used for pbuffers) which can be supported
826     * because they don't need a visual. Below we use glXGetFBConfigs instead of glXChooseFBConfig to enumerate the fb configurations
827     * because this call lists both types of formats instead of only onscreen ones. */
828     cfgs = pglXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
829     if (NULL == cfgs || 0 == nCfgs) {
830         ERR("glXChooseFBConfig returns NULL\n");
831         if(cfgs != NULL) XFree(cfgs);
832         return FALSE;
833     }
834
835     /* Count the number of offscreen formats to determine the size for our pixelformat list */
836     for(i=0; i<nCfgs; i++) {
837         pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id);
838
839         visinfo = pglXGetVisualFromFBConfig(display, cfgs[i]);
840         /* Onscreen formats have a corresponding XVisual, offscreen ones don't */
841         if(!visinfo) {
842             nOffscreenFormats++;
843         } else if(visinfo && visinfo->visualid == visualid) {
844             pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &fmt_id);
845             fbconfig = cfgs[i];
846             XFree(visinfo);
847         }
848     }
849     TRACE("Number of offscreen formats: %d\n", nOffscreenFormats);
850
851     /* Allocate memory for all the offscreen pixelformats and the format of Wine's main visual */
852     WineGLPixelFormatList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (1+nOffscreenFormats)*sizeof(WineGLPixelFormat));
853     WineGLPixelFormatList[0].iPixelFormat = 1;
854     WineGLPixelFormatList[0].fbconfig = fbconfig;
855     WineGLPixelFormatList[0].fmt_id = fmt_id;
856     WineGLPixelFormatList[0].render_type = get_render_type_from_fbconfig(display, fbconfig);
857     WineGLPixelFormatList[0].offscreenOnly = FALSE;
858     WineGLPixelFormatListSize = 1;
859     WineGLPixelFormatOnScreenSize = 1;
860
861     /* Fill the list with offscreen formats */
862     for(i=0; i<nCfgs; i++) {
863         pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id);
864
865         visinfo = pglXGetVisualFromFBConfig(display, cfgs[i]);
866         /* We have found an offscreen rendering format when there is no visualinfo :) */
867         if(!visinfo) {
868             TRACE("Found offscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", tmp_fmt_id, WineGLPixelFormatListSize+1, i);
869             WineGLPixelFormatList[WineGLPixelFormatListSize].iPixelFormat = WineGLPixelFormatListSize+1; /* The index starts at 1 */
870             WineGLPixelFormatList[WineGLPixelFormatListSize].fbconfig = cfgs[i];
871             WineGLPixelFormatList[WineGLPixelFormatListSize].fmt_id = tmp_fmt_id;
872             WineGLPixelFormatList[WineGLPixelFormatListSize].render_type = get_render_type_from_fbconfig(display, cfgs[i]);
873             WineGLPixelFormatList[WineGLPixelFormatListSize].offscreenOnly = TRUE;
874             WineGLPixelFormatListSize++;
875         } else {
876             XFree(visinfo);
877         }
878     }
879
880     if(cfgs != NULL) XFree(cfgs);
881
882     return TRUE;
883 }
884
885 /* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones.
886  * In our WGL implementation we only support a subset of these formats namely the format of
887  * Wine's main visual and offscreen formats (if they are available).
888  * This function converts a WGL format to its corresponding GLX one. It returns a WineGLPixelFormat
889  * and it returns the number of supported WGL formats in fmt_count.
890  */
891 static WineGLPixelFormat* ConvertPixelFormatWGLtoGLX(Display *display, int iPixelFormat, BOOL AllowOffscreen, int *fmt_count)
892 {
893     WineGLPixelFormat *res = NULL;
894
895     /* Init the list of pixel formats when we need it */
896     if(!WineGLPixelFormatListSize)
897         init_formats(display, DefaultScreen(display), visual);
898
899     /* Check if the pixelformat is valid. Note that it is legal to pass an invalid
900      * iPixelFormat in case of probing the number of pixelformats.
901      */
902     if((iPixelFormat > 0) && (iPixelFormat <= WineGLPixelFormatListSize) &&
903        ((WineGLPixelFormatList[iPixelFormat-1].offscreenOnly == FALSE) ||
904         AllowOffscreen)) {
905         res = &WineGLPixelFormatList[iPixelFormat-1];
906         TRACE("Returning FBConfig=%p for iPixelFormat=%d\n", res->fbconfig, iPixelFormat);
907     }
908
909     if(AllowOffscreen)
910         *fmt_count = WineGLPixelFormatListSize;
911     else
912         *fmt_count = WineGLPixelFormatOnScreenSize;
913
914     TRACE("Number of returned pixelformats=%d\n", *fmt_count);
915
916     return res;
917 }
918
919 /* Search our internal pixelformat list for the WGL format corresponding to the given fbconfig */
920 static WineGLPixelFormat* ConvertPixelFormatGLXtoWGL(Display *display, int fmt_id)
921 {
922     int i;
923
924     /* Init the list of pixel formats when we need it */
925     if(!WineGLPixelFormatListSize)
926         init_formats(display, DefaultScreen(display), visual);
927
928     for(i=0; i<WineGLPixelFormatListSize; i++) {
929         if(WineGLPixelFormatList[i].fmt_id == fmt_id) {
930             TRACE("Returning iPixelFormat %d for fmt_id 0x%x\n", WineGLPixelFormatList[i].iPixelFormat, fmt_id);
931             return &WineGLPixelFormatList[i];
932         }
933     }
934     TRACE("No compatible format found for fmt_id 0x%x\n", fmt_id);
935     return NULL;
936 }
937
938 int pixelformat_from_fbconfig_id(XID fbconfig_id)
939 {
940     WineGLPixelFormat *fmt;
941
942     if (!fbconfig_id) return 0;
943
944     fmt = ConvertPixelFormatGLXtoWGL(gdi_display, fbconfig_id);
945     if(fmt)
946         return fmt->iPixelFormat;
947     /* This will happen on hwnds without a pixel format set; it's ok */
948     return 0;
949 }
950
951
952 /**
953  * X11DRV_ChoosePixelFormat
954  *
955  * Equivalent to glXChooseVisual.
956  */
957 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev, 
958                              const PIXELFORMATDESCRIPTOR *ppfd) {
959     WineGLPixelFormat *fmt = NULL;
960     int ret = 0;
961     int nPixelFormats;
962     int value = 0;
963     int i = 0;
964     int bestFormat = -1;
965     int bestDBuffer = -1;
966     int bestStereo = -1;
967     int bestColor = -1;
968     int bestAlpha = -1;
969     int bestDepth = -1;
970     int bestStencil = -1;
971     int bestAux = -1;
972     int score;
973
974     if (!has_opengl()) {
975         ERR("No libGL on this box - disabling OpenGL support !\n");
976         return 0;
977     }
978
979     if (TRACE_ON(opengl)) {
980         TRACE("(%p,%p)\n", physDev, ppfd);
981
982         dump_PIXELFORMATDESCRIPTOR((const PIXELFORMATDESCRIPTOR *) ppfd);
983     }
984
985     wine_tsx11_lock();
986     ConvertPixelFormatWGLtoGLX(gdi_display, 0, FALSE /* offscreen */, &nPixelFormats);
987     for(i=0; i<nPixelFormats; i++)
988     {
989         int dwFlags = 0;
990         int iPixelType = 0;
991         int alpha=0, color=0, depth=0, stencil=0, aux=0;
992
993         fmt = ConvertPixelFormatWGLtoGLX(gdi_display, i+1 /* 1-based index */, FALSE /* offscreen */, &value);
994         score = 0;
995
996         /* Pixel type */
997         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RENDER_TYPE, &value);
998         if (value & GLX_RGBA_BIT)
999             iPixelType = PFD_TYPE_RGBA;
1000         else
1001             iPixelType = PFD_TYPE_COLORINDEX;
1002
1003         if (ppfd->iPixelType != iPixelType)
1004         {
1005             TRACE("pixel type mismatch for iPixelFormat=%d\n", i+1);
1006             continue;
1007         }
1008
1009         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value);
1010         if (value) dwFlags |= PFD_DOUBLEBUFFER;
1011         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STEREO, &value);
1012         if (value) dwFlags |= PFD_STEREO;
1013         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BUFFER_SIZE, &color); /* cColorBits */
1014         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ALPHA_SIZE, &alpha); /* cAlphaBits */
1015         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DEPTH_SIZE, &depth); /* cDepthBits */
1016         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STENCIL_SIZE, &stencil); /* cStencilBits */
1017         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_AUX_BUFFERS, &aux); /* cAuxBuffers */
1018
1019         /* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE
1020          * is not very clear on MSDN. They specify that ChoosePixelFormat tries to match pixel formats
1021          * with the flag (PFD_STEREO / PFD_DOUBLEBUFFERING) set. Otherwise it says that it tries to match
1022          * formats without the given flag set.
1023          * A test on Windows using a Radeon 9500pro on WinXP (the driver doesn't support Stereo)
1024          * has indicated that a format without stereo is returned when stereo is unavailable.
1025          * So in case PFD_STEREO is set, formats that support it should have priority above formats
1026          * without. In case PFD_STEREO_DONTCARE is set, stereo is ignored.
1027          *
1028          * To summarize the following is most likely the correct behavior:
1029          * stereo not set -> prefer no-stereo formats, else also accept stereo formats
1030          * stereo set -> prefer stereo formats, else also accept no-stereo formats
1031          * stereo don't care -> it doesn't matter whether we get stereo or not
1032          *
1033          * In Wine we will treat no-stereo the same way as don't care because it makes
1034          * format selection even more complicated and second drivers with Stereo advertise
1035          * each format twice anyway.
1036          */
1037
1038         /* Doublebuffer, see the comments above */
1039         if( !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) ) {
1040             if( ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer) &&
1041                 ((dwFlags & PFD_DOUBLEBUFFER) == (ppfd->dwFlags & PFD_DOUBLEBUFFER)) )
1042             {
1043                 bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1044                 bestStereo = dwFlags & PFD_STEREO;
1045                 bestAlpha = alpha;
1046                 bestColor = color;
1047                 bestDepth = depth;
1048                 bestStencil = stencil;
1049                 bestAux = aux;
1050                 bestFormat = i;
1051                 continue;
1052             }
1053             if(bestDBuffer != -1 && (dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer)
1054                 continue;
1055         }
1056
1057         /* Stereo, see the comments above. */
1058         if( !(ppfd->dwFlags & PFD_STEREO_DONTCARE) ) {
1059             if( ((ppfd->dwFlags & PFD_STEREO) != bestStereo) &&
1060                 ((dwFlags & PFD_STEREO) == (ppfd->dwFlags & PFD_STEREO)) )
1061             {
1062                 bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1063                 bestStereo = dwFlags & PFD_STEREO;
1064                 bestAlpha = alpha;
1065                 bestColor = color;
1066                 bestDepth = depth;
1067                 bestStencil = stencil;
1068                 bestAux = aux;
1069                 bestFormat = i;
1070                 continue;
1071             }
1072             if(bestStereo != -1 && (dwFlags & PFD_STEREO) != bestStereo)
1073                 continue;
1074         }
1075
1076         /* Below we will do a number of checks to select the 'best' pixelformat.
1077          * We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits -> cAuxBuffers.
1078          * The code works by trying to match the most important options as close as possible.
1079          * When a reasonable format is found, we will try to match more options. */
1080
1081         /* Color bits */
1082         if( ((ppfd->cColorBits > bestColor) && (color > bestColor)) ||
1083             ((color >= ppfd->cColorBits) && (color < bestColor)) )
1084         {
1085             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1086             bestStereo = dwFlags & PFD_STEREO;
1087             bestAlpha = alpha;
1088             bestColor = color;
1089             bestDepth = depth;
1090             bestStencil = stencil;
1091             bestAux = aux;
1092             bestFormat = i;
1093             continue;
1094         } else if(bestColor != color) {  /* Do further checks if the format is compatible */
1095             TRACE("color mismatch for iPixelFormat=%d\n", i+1);
1096             continue;
1097         }
1098
1099         /* Alpha bits */
1100         if( ((ppfd->cAlphaBits > bestAlpha) && (alpha > bestAlpha)) ||
1101             ((alpha >= ppfd->cAlphaBits) && (alpha < bestAlpha)) )
1102         {
1103             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1104             bestStereo = dwFlags & PFD_STEREO;
1105             bestAlpha = alpha;
1106             bestColor = color;
1107             bestDepth = depth;
1108             bestStencil = stencil;
1109             bestAux = aux;
1110             bestFormat = i;
1111             continue;
1112         } else if(bestAlpha != alpha) {
1113             TRACE("alpha mismatch for iPixelFormat=%d\n", i+1);
1114             continue;
1115         }
1116
1117         /* Depth bits */
1118         if( ((ppfd->cDepthBits > bestDepth) && (depth > bestDepth)) ||
1119             ((depth >= ppfd->cDepthBits) && (depth < bestDepth)) )
1120         {
1121             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1122             bestStereo = dwFlags & PFD_STEREO;
1123             bestAlpha = alpha;
1124             bestColor = color;
1125             bestDepth = depth;
1126             bestStencil = stencil;
1127             bestAux = aux;
1128             bestFormat = i;
1129             continue;
1130         } else if(bestDepth != depth) {
1131             TRACE("depth mismatch for iPixelFormat=%d\n", i+1);
1132             continue;
1133         }
1134
1135         /* Stencil bits */
1136         if( ((ppfd->cStencilBits > bestStencil) && (stencil > bestStencil)) ||
1137             ((stencil >= ppfd->cStencilBits) && (stencil < bestStencil)) )
1138         {
1139             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1140             bestStereo = dwFlags & PFD_STEREO;
1141             bestAlpha = alpha;
1142             bestColor = color;
1143             bestDepth = depth;
1144             bestStencil = stencil;
1145             bestAux = aux;
1146             bestFormat = i;
1147             continue;
1148         } else if(bestStencil != stencil) {
1149             TRACE("stencil mismatch for iPixelFormat=%d\n", i+1);
1150             continue;
1151         }
1152
1153         /* Aux buffers */
1154         if( ((ppfd->cAuxBuffers > bestAux) && (aux > bestAux)) ||
1155             ((aux >= ppfd->cAuxBuffers) && (aux < bestAux)) )
1156         {
1157             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1158             bestStereo = dwFlags & PFD_STEREO;
1159             bestAlpha = alpha;
1160             bestColor = color;
1161             bestDepth = depth;
1162             bestStencil = stencil;
1163             bestAux = aux;
1164             bestFormat = i;
1165             continue;
1166         } else if(bestAux != aux) {
1167             TRACE("aux mismatch for iPixelFormat=%d\n", i+1);
1168             continue;
1169         }
1170     }
1171
1172     if(bestFormat == -1) {
1173         TRACE("No matching mode was found returning 0\n");
1174         ret = 0;
1175     }
1176     else {
1177         ret = bestFormat+1; /* the return value should be a 1-based index */
1178         TRACE("Successfully found a matching mode, returning index: %d %x\n", ret, WineGLPixelFormatList[bestFormat].fmt_id);
1179     }
1180
1181     wine_tsx11_unlock();
1182
1183     return ret;
1184 }
1185 /**
1186  * X11DRV_DescribePixelFormat
1187  *
1188  * Get the pixel-format descriptor associated to the given id
1189  */
1190 int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
1191                                int iPixelFormat,
1192                                UINT nBytes,
1193                                PIXELFORMATDESCRIPTOR *ppfd) {
1194   /*XVisualInfo *vis;*/
1195   int value;
1196   int rb,gb,bb,ab;
1197   WineGLPixelFormat *fmt;
1198   int ret = 0;
1199   int fmt_count = 0;
1200
1201   if (!has_opengl()) {
1202     ERR("No libGL on this box - disabling OpenGL support !\n");
1203     return 0;
1204   }
1205   
1206   TRACE("(%p,%d,%d,%p)\n", physDev, iPixelFormat, nBytes, ppfd);
1207
1208   /* Look for the iPixelFormat in our list of supported formats. If it is supported we get the index in the FBConfig table and the number of supported formats back */
1209   fmt = ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, FALSE /* Offscreen */, &fmt_count);
1210   if (ppfd == NULL) {
1211       /* The application is only querying the number of pixelformats */
1212       return fmt_count;
1213   } else if(fmt == NULL) {
1214       WARN("unexpected iPixelFormat(%d): not >=1 and <=nFormats(%d), returning NULL!\n", iPixelFormat, fmt_count);
1215       return 0;
1216   }
1217
1218   if (nBytes < sizeof(PIXELFORMATDESCRIPTOR)) {
1219     ERR("Wrong structure size !\n");
1220     /* Should set error */
1221     return 0;
1222   }
1223
1224   ret = fmt_count;
1225
1226   memset(ppfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
1227   ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
1228   ppfd->nVersion = 1;
1229
1230   /* These flags are always the same... */
1231   ppfd->dwFlags = PFD_SUPPORT_OPENGL;
1232   /* Now the flags extracted from the Visual */
1233
1234   wine_tsx11_lock();
1235
1236   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_X_RENDERABLE, &value);
1237   if(value)
1238       ppfd->dwFlags |= PFD_SUPPORT_GDI;
1239
1240   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
1241   if(value & GLX_WINDOW_BIT)
1242       ppfd->dwFlags |= PFD_DRAW_TO_WINDOW;
1243   if(value & GLX_PIXMAP_BIT)
1244       ppfd->dwFlags |= PFD_DRAW_TO_BITMAP;
1245
1246   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_CONFIG_CAVEAT, &value);
1247   if(value == GLX_SLOW_CONFIG)
1248       ppfd->dwFlags |= PFD_GENERIC_ACCELERATED;
1249
1250   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value);
1251   if (value) {
1252       ppfd->dwFlags |= PFD_DOUBLEBUFFER;
1253       ppfd->dwFlags &= ~PFD_SUPPORT_GDI;
1254   }
1255   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO;
1256
1257   /* Pixel type */
1258   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RENDER_TYPE, &value);
1259   if (value & GLX_RGBA_BIT)
1260     ppfd->iPixelType = PFD_TYPE_RGBA;
1261   else
1262     ppfd->iPixelType = PFD_TYPE_COLORINDEX;
1263
1264   /* Color bits */
1265   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BUFFER_SIZE, &value);
1266   ppfd->cColorBits = value;
1267
1268   /* Red, green, blue and alpha bits / shifts */
1269   if (ppfd->iPixelType == PFD_TYPE_RGBA) {
1270     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RED_SIZE, &rb);
1271     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_GREEN_SIZE, &gb);
1272     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BLUE_SIZE, &bb);
1273     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ALPHA_SIZE, &ab);
1274
1275     ppfd->cRedBits = rb;
1276     ppfd->cRedShift = gb + bb + ab;
1277     ppfd->cBlueBits = bb;
1278     ppfd->cBlueShift = ab;
1279     ppfd->cGreenBits = gb;
1280     ppfd->cGreenShift = bb + ab;
1281     ppfd->cAlphaBits = ab;
1282     ppfd->cAlphaShift = 0;
1283   } else {
1284     ppfd->cRedBits = 0;
1285     ppfd->cRedShift = 0;
1286     ppfd->cBlueBits = 0;
1287     ppfd->cBlueShift = 0;
1288     ppfd->cGreenBits = 0;
1289     ppfd->cGreenShift = 0;
1290     ppfd->cAlphaBits = 0;
1291     ppfd->cAlphaShift = 0;
1292   }
1293
1294   /* Accum RGBA bits */
1295   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_RED_SIZE, &rb);
1296   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_GREEN_SIZE, &gb);
1297   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_BLUE_SIZE, &bb);
1298   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_ALPHA_SIZE, &ab);
1299
1300   ppfd->cAccumBits = rb+gb+bb+ab;
1301   ppfd->cAccumRedBits = rb;
1302   ppfd->cAccumGreenBits = gb;
1303   ppfd->cAccumBlueBits = bb;
1304   ppfd->cAccumAlphaBits = ab;
1305
1306   /* Depth bits */
1307   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DEPTH_SIZE, &value);
1308   ppfd->cDepthBits = value;
1309
1310   /* stencil bits */
1311   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STENCIL_SIZE, &value);
1312   ppfd->cStencilBits = value;
1313
1314   wine_tsx11_unlock();
1315
1316   /* Aux : to do ... */
1317
1318   ppfd->iLayerType = PFD_MAIN_PLANE;
1319
1320   if (TRACE_ON(opengl)) {
1321     dump_PIXELFORMATDESCRIPTOR(ppfd);
1322   }
1323
1324   return ret;
1325 }
1326
1327 /**
1328  * X11DRV_GetPixelFormat
1329  *
1330  * Get the pixel-format id used by this DC
1331  */
1332 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
1333   WineGLPixelFormat *fmt;
1334   int tmp;
1335   TRACE("(%p)\n", physDev);
1336
1337   fmt = ConvertPixelFormatWGLtoGLX(gdi_display, physDev->current_pf, TRUE, &tmp);
1338   if(!fmt)
1339   {
1340     /* This happens on HDCs on which SetPixelFormat wasn't called yet */
1341     ERR("Unable to find a WineGLPixelFormat for iPixelFormat=%d\n", physDev->current_pf);
1342     return 0;
1343   }
1344   else if(fmt->offscreenOnly)
1345   {
1346     /* Offscreen formats can't be used with traditional WGL calls.
1347      * As has been verified on Windows GetPixelFormat doesn't fail but returns iPixelFormat=1. */
1348      TRACE("Returning iPixelFormat=1 for offscreen format: %d\n", fmt->iPixelFormat);
1349     return 1;
1350   }
1351
1352   TRACE("(%p): returns %d\n", physDev, physDev->current_pf);
1353   return physDev->current_pf;
1354 }
1355
1356 /**
1357  * X11DRV_SetPixelFormat
1358  *
1359  * Set the pixel-format id used by this DC
1360  */
1361 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
1362                            int iPixelFormat,
1363                            const PIXELFORMATDESCRIPTOR *ppfd) {
1364   WineGLPixelFormat *fmt;
1365   int value;
1366   HWND hwnd;
1367
1368   TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
1369
1370   if (!has_opengl()) {
1371     ERR("No libGL on this box - disabling OpenGL support !\n");
1372     return 0;
1373   }
1374
1375   /* SetPixelFormat is not allowed on the X root_window e.g. GetDC(0) */
1376   if(get_glxdrawable(physDev) == root_window)
1377   {
1378     ERR("Invalid operation on root_window\n");
1379     return 0;
1380   }
1381
1382   /* Check if iPixelFormat is in our list of supported formats to see if it is supported. */
1383   fmt = ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, FALSE /* Offscreen */, &value);
1384   if(!fmt) {
1385     ERR("Invalid iPixelFormat: %d\n", iPixelFormat);
1386     return 0;
1387   }
1388
1389     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
1390
1391     hwnd = WindowFromDC(physDev->hdc);
1392     if(hwnd) {
1393         if(!(value&GLX_WINDOW_BIT)) {
1394             WARN("Pixel format %d is not compatible for window rendering\n", iPixelFormat);
1395             return 0;
1396         }
1397
1398         if(!SendMessageW(hwnd, WM_X11DRV_SET_WIN_FORMAT, (WPARAM)fmt->fmt_id, 0)) {
1399             ERR("Couldn't set format of the window, returning failure\n");
1400             return 0;
1401         }
1402     }
1403
1404   physDev->current_pf = iPixelFormat;
1405
1406   if (TRACE_ON(opengl)) {
1407     int gl_test = 0;
1408
1409     gl_test = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_FBCONFIG_ID, &value);
1410     if (gl_test) {
1411       ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
1412     } else {
1413       TRACE(" FBConfig have :\n");
1414       TRACE(" - FBCONFIG_ID   0x%x\n", value);
1415       pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_VISUAL_ID, &value);
1416       TRACE(" - VISUAL_ID     0x%x\n", value);
1417       pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
1418       TRACE(" - DRAWABLE_TYPE 0x%x\n", value);
1419     }
1420   }
1421   return TRUE;
1422 }
1423
1424 /**
1425  * X11DRV_wglCreateContext
1426  *
1427  * For OpenGL32 wglCreateContext.
1428  */
1429 HGLRC X11DRV_wglCreateContext(X11DRV_PDEVICE *physDev)
1430 {
1431     Wine_GLContext *ret;
1432     WineGLPixelFormat *fmt;
1433     int hdcPF = physDev->current_pf;
1434     int fmt_count = 0;
1435     HDC hdc = physDev->hdc;
1436
1437     TRACE("(%p)->(PF:%d)\n", hdc, hdcPF);
1438
1439     if (!has_opengl()) {
1440         ERR("No libGL on this box - disabling OpenGL support !\n");
1441         return 0;
1442     }
1443
1444     fmt = ConvertPixelFormatWGLtoGLX(gdi_display, hdcPF, TRUE /* Offscreen */, &fmt_count);
1445     /* We can render using the iPixelFormat (1) of Wine's Main visual AND using some offscreen formats.
1446      * Note that standard WGL-calls don't recognize offscreen-only formats. For that reason pbuffers
1447      * use a sort of 'proxy' HDC (wglGetPbufferDCARB).
1448      * If this fails something is very wrong on the system. */
1449     if(!fmt) {
1450         ERR("Cannot get FB Config for iPixelFormat %d, expect problems!\n", hdcPF);
1451         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
1452         return NULL;
1453     }
1454
1455     /* The context will be allocated in the wglMakeCurrent call */
1456     wine_tsx11_lock();
1457     ret = alloc_context();
1458     wine_tsx11_unlock();
1459     ret->hdc = hdc;
1460     ret->physDev = physDev;
1461     ret->fmt = fmt;
1462
1463     /*ret->vis = vis;*/
1464     ret->vis = pglXGetVisualFromFBConfig(gdi_display, fmt->fbconfig);
1465
1466     TRACE(" creating context %p (GL context creation delayed)\n", ret);
1467     return (HGLRC) ret;
1468 }
1469
1470 /**
1471  * X11DRV_wglDeleteContext
1472  *
1473  * For OpenGL32 wglDeleteContext.
1474  */
1475 BOOL X11DRV_wglDeleteContext(HGLRC hglrc)
1476 {
1477     Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
1478     BOOL ret = TRUE;
1479
1480     TRACE("(%p)\n", hglrc);
1481
1482     if (!has_opengl()) {
1483         ERR("No libGL on this box - disabling OpenGL support !\n");
1484         return 0;
1485     }
1486
1487     wine_tsx11_lock();
1488     /* A game (Half Life not to name it) deletes twice the same context,
1489     * so make sure it is valid first */
1490     if (is_valid_context( ctx ))
1491     {
1492         if (ctx->ctx) pglXDestroyContext(gdi_display, ctx->ctx);
1493         free_context(ctx);
1494     }
1495     else
1496     {
1497         WARN("Error deleting context !\n");
1498         SetLastError(ERROR_INVALID_HANDLE);
1499         ret = FALSE;
1500     }
1501     wine_tsx11_unlock();
1502
1503     return ret;
1504 }
1505
1506 /**
1507  * X11DRV_wglGetCurrentReadDCARB
1508  *
1509  * For OpenGL32 wglGetCurrentReadDCARB.
1510  */
1511 static HDC WINAPI X11DRV_wglGetCurrentReadDCARB(void) 
1512 {
1513     HDC ret = 0;
1514     Wine_GLContext *ctx = NtCurrentTeb()->glContext;
1515     X11DRV_PDEVICE *physDev = ctx ? ctx->pReadDev : NULL;
1516
1517     if(physDev)
1518         ret = physDev->hdc;
1519
1520     TRACE(" returning %p (GL drawable %lu)\n", ret, physDev ? physDev->drawable : 0);
1521     return ret;
1522 }
1523
1524 /**
1525  * X11DRV_wglGetProcAddress
1526  *
1527  * For OpenGL32 wglGetProcAddress.
1528  */
1529 PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc)
1530 {
1531     int i, j;
1532     const WineGLExtension *ext;
1533
1534     int padding = 32 - strlen(lpszProc);
1535     if (padding < 0)
1536         padding = 0;
1537
1538     if (!has_opengl()) {
1539         ERR("No libGL on this box - disabling OpenGL support !\n");
1540         return 0;
1541     }
1542
1543     /* Check the table of WGL extensions to see if we need to return a WGL extension
1544      * or a function pointer to a native OpenGL function. */
1545     if(strncmp(lpszProc, "wgl", 3) != 0) {
1546         return pglXGetProcAddressARB((const GLubyte*)lpszProc);
1547     } else {
1548         TRACE("('%s'):%*s", lpszProc, padding, " ");
1549         for (i = 0; i < WineGLExtensionListSize; ++i) {
1550             ext = WineGLExtensionList[i];
1551             for (j = 0; ext->extEntryPoints[j].funcName; ++j) {
1552                 if (strcmp(ext->extEntryPoints[j].funcName, lpszProc) == 0) {
1553                     TRACE("(%p) - WineGL\n", ext->extEntryPoints[j].funcAddress);
1554                     return ext->extEntryPoints[j].funcAddress;
1555                 }
1556             }
1557         }
1558     }
1559
1560     WARN("(%s) - not found\n", lpszProc);
1561     return NULL;
1562 }
1563
1564 /***********************************************************************
1565  *              sync_current_drawable
1566  *
1567  * Adjust the current viewport and scissor in order to position
1568  * and size the current drawable correctly on the parent window.
1569  */
1570 static void sync_current_drawable(BOOL updatedc)
1571 {
1572     int dy;
1573     int width;
1574     int height;
1575     RECT rc;
1576     Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
1577
1578     TRACE("\n");
1579
1580     if (ctx && ctx->physDev)
1581     {
1582         if (updatedc)
1583             GetClipBox(ctx->physDev->hdc, &rc); /* Make sure physDev is up to date */
1584
1585         dy = ctx->physDev->drawable_rect.bottom - ctx->physDev->drawable_rect.top -
1586             ctx->physDev->dc_rect.bottom;
1587         width = ctx->physDev->dc_rect.right - ctx->physDev->dc_rect.left;
1588         height = ctx->physDev->dc_rect.bottom - ctx->physDev->dc_rect.top;
1589
1590         wine_tsx11_lock();
1591
1592         pglViewport(ctx->physDev->dc_rect.left + ctx->viewport.left,
1593             dy + ctx->viewport.top,
1594             ctx->viewport.right ? (ctx->viewport.right - ctx->viewport.left) : width,
1595             ctx->viewport.bottom ? (ctx->viewport.bottom - ctx->viewport.top) : height);
1596
1597         pglEnable(GL_SCISSOR_TEST);
1598
1599         if (ctx->scissor_enabled)
1600             pglScissor(ctx->physDev->dc_rect.left + min(width, max(0, ctx->scissor.left)),
1601                 dy + min(height, max(0, ctx->scissor.top)),
1602                 min(width, max(0, ctx->scissor.right - ctx->scissor.left)),
1603                 min(height, max(0, ctx->scissor.bottom - ctx->scissor.top)));
1604         else
1605             pglScissor(ctx->physDev->dc_rect.left, dy, width, height);
1606
1607         wine_tsx11_unlock();
1608     }
1609 }
1610
1611 /**
1612  * X11DRV_wglMakeCurrent
1613  *
1614  * For OpenGL32 wglMakeCurrent.
1615  */
1616 BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
1617     BOOL ret;
1618     HDC hdc = physDev->hdc;
1619     DWORD type = GetObjectType(hdc);
1620
1621     TRACE("(%p,%p)\n", hdc, hglrc);
1622
1623     if (!has_opengl()) {
1624         ERR("No libGL on this box - disabling OpenGL support !\n");
1625         return 0;
1626     }
1627
1628     wine_tsx11_lock();
1629     if (hglrc == NULL) {
1630         ret = pglXMakeCurrent(gdi_display, None, NULL);
1631         NtCurrentTeb()->glContext = NULL;
1632     } else {
1633         Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
1634         Drawable drawable = get_glxdrawable(physDev);
1635         if (ctx->ctx == NULL) {
1636             /* The describe lines below are for debugging purposes only */
1637             if (TRACE_ON(wgl)) {
1638                 describeDrawable(ctx, drawable);
1639                 describeContext(ctx);
1640             }
1641
1642             /* Create a GLX context using the same visual as chosen earlier in wglCreateContext.
1643              * We are certain that the drawable and context are compatible as we only allow compatible formats.
1644              */
1645             TRACE(" Creating GLX Context\n");
1646             if(ctx->vis)
1647                 ctx->ctx = pglXCreateContext(gdi_display, ctx->vis, NULL, type == OBJ_MEMDC ? False : True);
1648             else /* Create a GLX Context for a pbuffer */
1649                 ctx->ctx = pglXCreateNewContext(gdi_display, ctx->fmt->fbconfig, ctx->fmt->render_type, NULL, True);
1650
1651             TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
1652         }
1653         TRACE(" make current for dis %p, drawable %p, ctx %p\n", gdi_display, (void*) drawable, ctx->ctx);
1654         ret = pglXMakeCurrent(gdi_display, drawable, ctx->ctx);
1655         NtCurrentTeb()->glContext = ctx;
1656         if(ret)
1657         {
1658             ctx->hdc = hdc;
1659             ctx->physDev = physDev;
1660             ctx->pReadDev = physDev;
1661
1662             if (type == OBJ_MEMDC)
1663             {
1664                 ctx->do_escape = TRUE;
1665                 pglDrawBuffer(GL_FRONT_LEFT);
1666             }
1667             else
1668             {
1669                 sync_current_drawable(FALSE);
1670             }
1671         }
1672     }
1673     wine_tsx11_unlock();
1674     TRACE(" returning %s\n", (ret ? "True" : "False"));
1675     return ret;
1676 }
1677
1678 /**
1679  * X11DRV_wglMakeContextCurrentARB
1680  *
1681  * For OpenGL32 wglMakeContextCurrentARB
1682  */
1683 BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* pDrawDev, X11DRV_PDEVICE* pReadDev, HGLRC hglrc)
1684 {
1685     BOOL ret;
1686     TRACE("(%p,%p,%p)\n", pDrawDev, pReadDev, hglrc);
1687
1688     if (!has_opengl()) {
1689         ERR("No libGL on this box - disabling OpenGL support !\n");
1690         return 0;
1691     }
1692
1693     wine_tsx11_lock();
1694     if (hglrc == NULL) {
1695         ret = pglXMakeCurrent(gdi_display, None, NULL);
1696         NtCurrentTeb()->glContext = NULL;
1697     } else {
1698         if (NULL == pglXMakeContextCurrent) {
1699             ret = FALSE;
1700         } else {
1701             Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
1702             Drawable d_draw = get_glxdrawable(pDrawDev);
1703             Drawable d_read = get_glxdrawable(pReadDev);
1704
1705             if (ctx->ctx == NULL) {
1706                 ctx->ctx = pglXCreateContext(gdi_display, ctx->vis, NULL, GetObjectType(pDrawDev->hdc) == OBJ_MEMDC ? False : True);
1707                 TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
1708             }
1709             ctx->hdc = pDrawDev->hdc;
1710             ctx->physDev = pDrawDev;
1711             ctx->pReadDev = pReadDev;
1712             ret = pglXMakeContextCurrent(gdi_display, d_draw, d_read, ctx->ctx);
1713             NtCurrentTeb()->glContext = ctx;
1714         }
1715     }
1716     wine_tsx11_unlock();
1717
1718     TRACE(" returning %s\n", (ret ? "True" : "False"));
1719     return ret;
1720 }
1721
1722 /**
1723  * X11DRV_wglShareLists
1724  *
1725  * For OpenGL32 wglShaderLists.
1726  */
1727 BOOL X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
1728     Wine_GLContext *org  = (Wine_GLContext *) hglrc1;
1729     Wine_GLContext *dest = (Wine_GLContext *) hglrc2;
1730
1731     TRACE("(%p, %p)\n", org, dest);
1732
1733     if (!has_opengl()) {
1734         ERR("No libGL on this box - disabling OpenGL support !\n");
1735         return 0;
1736     }
1737
1738     if (NULL != dest && dest->ctx != NULL) {
1739         ERR("Could not share display lists, context already created !\n");
1740         return FALSE;
1741     } else {
1742         if (org->ctx == NULL) {
1743             wine_tsx11_lock();
1744             describeContext(org);
1745
1746             if(org->vis)
1747                 org->ctx = pglXCreateContext(gdi_display, org->vis, NULL, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
1748             else /* Create a GLX Context for a pbuffer */
1749                 org->ctx = pglXCreateNewContext(gdi_display, org->fmt->fbconfig, org->fmt->render_type, NULL, True);
1750             wine_tsx11_unlock();
1751             TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org);
1752         }
1753         if (NULL != dest) {
1754             wine_tsx11_lock();
1755             describeContext(dest);
1756             /* Create the destination context with display lists shared */
1757             if(dest->vis)
1758                 dest->ctx = pglXCreateContext(gdi_display, dest->vis, org->ctx, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
1759             else /* Create a GLX Context for a pbuffer */
1760                 dest->ctx = pglXCreateNewContext(gdi_display, dest->fmt->fbconfig, dest->fmt->render_type, org->ctx, True);
1761             wine_tsx11_unlock();
1762             TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx);
1763             return TRUE;
1764         }
1765     }
1766     return FALSE;
1767 }
1768
1769 static BOOL internal_wglUseFontBitmaps(HDC hdc, DWORD first, DWORD count, DWORD listBase, DWORD (WINAPI *GetGlyphOutline_ptr)(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*))
1770 {
1771      /* We are running using client-side rendering fonts... */
1772      GLYPHMETRICS gm;
1773      unsigned int glyph;
1774      int size = 0;
1775      void *bitmap = NULL, *gl_bitmap = NULL;
1776      int org_alignment;
1777
1778      wine_tsx11_lock();
1779      pglGetIntegerv(GL_UNPACK_ALIGNMENT, &org_alignment);
1780      pglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1781      wine_tsx11_unlock();
1782
1783      for (glyph = first; glyph < first + count; glyph++) {
1784          unsigned int needed_size = GetGlyphOutline_ptr(hdc, glyph, GGO_BITMAP, &gm, 0, NULL, NULL);
1785          int height, width_int;
1786
1787          TRACE("Glyph : %3d / List : %d\n", glyph, listBase);
1788          if (needed_size == GDI_ERROR) {
1789              TRACE("  - needed size : %d (GDI_ERROR)\n", needed_size);
1790              goto error;
1791          } else {
1792              TRACE("  - needed size : %d\n", needed_size);
1793          }
1794
1795          if (needed_size > size) {
1796              size = needed_size;
1797              HeapFree(GetProcessHeap(), 0, bitmap);
1798              HeapFree(GetProcessHeap(), 0, gl_bitmap);
1799              bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
1800              gl_bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
1801          }
1802          if (GetGlyphOutline_ptr(hdc, glyph, GGO_BITMAP, &gm, size, bitmap, NULL) == GDI_ERROR) goto error;
1803          if (TRACE_ON(opengl)) {
1804              unsigned int height, width, bitmask;
1805              unsigned char *bitmap_ = (unsigned char *) bitmap;
1806
1807              TRACE("  - bbox : %d x %d\n", gm.gmBlackBoxX, gm.gmBlackBoxY);
1808              TRACE("  - origin : (%d , %d)\n", gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y);
1809              TRACE("  - increment : %d - %d\n", gm.gmCellIncX, gm.gmCellIncY);
1810              if (needed_size != 0) {
1811                  TRACE("  - bitmap :\n");
1812                  for (height = 0; height < gm.gmBlackBoxY; height++) {
1813                      TRACE("      ");
1814                      for (width = 0, bitmask = 0x80; width < gm.gmBlackBoxX; width++, bitmask >>= 1) {
1815                          if (bitmask == 0) {
1816                              bitmap_ += 1;
1817                              bitmask = 0x80;
1818                          }
1819                          if (*bitmap_ & bitmask)
1820                              TRACE("*");
1821                          else
1822                              TRACE(" ");
1823                      }
1824                      bitmap_ += (4 - ((UINT_PTR)bitmap_ & 0x03));
1825                      TRACE("\n");
1826                  }
1827              }
1828          }
1829
1830          /* In OpenGL, the bitmap is drawn from the bottom to the top... So we need to invert the
1831          * glyph for it to be drawn properly.
1832          */
1833          if (needed_size != 0) {
1834              width_int = (gm.gmBlackBoxX + 31) / 32;
1835              for (height = 0; height < gm.gmBlackBoxY; height++) {
1836                  int width;
1837                  for (width = 0; width < width_int; width++) {
1838                      ((int *) gl_bitmap)[(gm.gmBlackBoxY - height - 1) * width_int + width] =
1839                      ((int *) bitmap)[height * width_int + width];
1840                  }
1841              }
1842          }
1843
1844          wine_tsx11_lock();
1845          pglNewList(listBase++, GL_COMPILE);
1846          if (needed_size != 0) {
1847              pglBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
1848                      0 - (int) gm.gmptGlyphOrigin.x, (int) gm.gmBlackBoxY - (int) gm.gmptGlyphOrigin.y,
1849                      gm.gmCellIncX, gm.gmCellIncY,
1850                      gl_bitmap);
1851          } else {
1852              /* This is the case of 'empty' glyphs like the space character */
1853              pglBitmap(0, 0, 0, 0, gm.gmCellIncX, gm.gmCellIncY, NULL);
1854          }
1855          pglEndList();
1856          wine_tsx11_unlock();
1857      }
1858
1859      wine_tsx11_lock();
1860      pglPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
1861      wine_tsx11_unlock();
1862
1863      HeapFree(GetProcessHeap(), 0, bitmap);
1864      HeapFree(GetProcessHeap(), 0, gl_bitmap);
1865      return TRUE;
1866
1867   error:
1868      wine_tsx11_lock();
1869      pglPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
1870      wine_tsx11_unlock();
1871
1872      HeapFree(GetProcessHeap(), 0, bitmap);
1873      HeapFree(GetProcessHeap(), 0, gl_bitmap);
1874      return FALSE;
1875 }
1876
1877 /**
1878  * X11DRV_wglUseFontBitmapsA
1879  *
1880  * For OpenGL32 wglUseFontBitmapsA.
1881  */
1882 BOOL X11DRV_wglUseFontBitmapsA(X11DRV_PDEVICE *physDev, DWORD first, DWORD count, DWORD listBase)
1883 {
1884      Font fid = physDev->font;
1885
1886      TRACE("(%p, %d, %d, %d) using font %ld\n", physDev->hdc, first, count, listBase, fid);
1887
1888      if (!has_opengl()) {
1889         ERR("No libGL on this box - disabling OpenGL support !\n");
1890         return 0;
1891      }
1892
1893      if (fid == 0) {
1894          return internal_wglUseFontBitmaps(physDev->hdc, first, count, listBase, GetGlyphOutlineA);
1895      }
1896
1897      wine_tsx11_lock();
1898      /* I assume that the glyphs are at the same position for X and for Windows */
1899      pglXUseXFont(fid, first, count, listBase);
1900      wine_tsx11_unlock();
1901      return TRUE;
1902 }
1903
1904 /**
1905  * X11DRV_wglUseFontBitmapsW
1906  *
1907  * For OpenGL32 wglUseFontBitmapsW.
1908  */
1909 BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count, DWORD listBase)
1910 {
1911      Font fid = physDev->font;
1912
1913      TRACE("(%p, %d, %d, %d) using font %ld\n", physDev->hdc, first, count, listBase, fid);
1914
1915      if (!has_opengl()) {
1916         ERR("No libGL on this box - disabling OpenGL support !\n");
1917         return 0;
1918      }
1919
1920      if (fid == 0) {
1921          return internal_wglUseFontBitmaps(physDev->hdc, first, count, listBase, GetGlyphOutlineW);
1922      }
1923
1924      WARN("Using the glX API for the WCHAR variant - some characters may come out incorrectly !\n");
1925
1926      wine_tsx11_lock();
1927      /* I assume that the glyphs are at the same position for X and for Windows */
1928      pglXUseXFont(fid, first, count, listBase);
1929      wine_tsx11_unlock();
1930      return TRUE;
1931 }
1932
1933 static void WINAPI X11DRV_wglDisable(GLenum cap)
1934 {
1935     if (cap == GL_SCISSOR_TEST)
1936     {
1937        Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
1938
1939        if (ctx)
1940           ctx->scissor_enabled = FALSE;
1941     }
1942     else
1943     {
1944         wine_tsx11_lock();
1945         pglDisable(cap);
1946         wine_tsx11_unlock();
1947     }
1948 }
1949
1950 static void WINAPI X11DRV_wglEnable(GLenum cap)
1951 {
1952     if (cap == GL_SCISSOR_TEST)
1953     {
1954        Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
1955
1956        if (ctx)
1957            ctx->scissor_enabled = TRUE;
1958     }
1959     else
1960     {
1961         wine_tsx11_lock();
1962         pglEnable(cap);
1963         wine_tsx11_unlock();
1964     }
1965 }
1966
1967 /* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */
1968 static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params)
1969 {
1970     wine_tsx11_lock();
1971     switch(pname)
1972     {
1973     case GL_DEPTH_BITS:
1974         {
1975             Wine_GLContext *ctx = NtCurrentTeb()->glContext;
1976
1977             pglGetIntegerv(pname, params);
1978             /**
1979              * if we cannot find a Wine Context
1980              * we only have the default wine desktop context,
1981              * so if we have only a 24 depth say we have 32
1982              */
1983             if (!ctx && *params == 24) {
1984                 *params = 32;
1985             }
1986             TRACE("returns GL_DEPTH_BITS as '%d'\n", *params);
1987             break;
1988         }
1989     case GL_ALPHA_BITS:
1990         {
1991             Wine_GLContext *ctx = NtCurrentTeb()->glContext;
1992
1993             pglXGetFBConfigAttrib(gdi_display, ctx->fmt->fbconfig, GLX_ALPHA_SIZE, params);
1994             TRACE("returns GL_ALPHA_BITS as '%d'\n", *params);
1995             break;
1996         }
1997     default:
1998         pglGetIntegerv(pname, params);
1999         break;
2000     }
2001     wine_tsx11_unlock();
2002 }
2003
2004 static GLboolean WINAPI X11DRV_wglIsEnabled(GLenum cap)
2005 {
2006     GLboolean enabled = False;
2007
2008     if (cap == GL_SCISSOR_TEST)
2009     {
2010        Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
2011
2012        if (ctx)
2013            enabled = ctx->scissor_enabled;
2014     }
2015     else
2016     {
2017         wine_tsx11_lock();
2018         enabled = pglIsEnabled(cap);
2019         wine_tsx11_unlock();
2020     }
2021     return enabled;
2022 }
2023
2024 static void WINAPI X11DRV_wglScissor(GLint x, GLint y, GLsizei width, GLsizei height)
2025 {
2026     Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
2027
2028     if (ctx)
2029     {
2030         ctx->scissor.left = x;
2031         ctx->scissor.top = y;
2032         ctx->scissor.right = x + width;
2033         ctx->scissor.bottom = y + height;
2034
2035         sync_current_drawable(TRUE);
2036     }
2037 }
2038
2039 static void WINAPI X11DRV_wglViewport(GLint x, GLint y, GLsizei width, GLsizei height)
2040 {
2041     Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
2042
2043     if (ctx)
2044     {
2045         ctx->viewport.left = x;
2046         ctx->viewport.top = y;
2047         ctx->viewport.right = x + width;
2048         ctx->viewport.bottom = y + height;
2049
2050         sync_current_drawable(TRUE);
2051     }
2052 }
2053
2054 /**
2055  * X11DRV_wglGetExtensionsStringARB
2056  *
2057  * WGL_ARB_extensions_string: wglGetExtensionsStringARB
2058  */
2059 static const char * WINAPI X11DRV_wglGetExtensionsStringARB(HDC hdc) {
2060     TRACE("() returning \"%s\"\n", WineGLInfo.wglExtensions);
2061     return WineGLInfo.wglExtensions;
2062 }
2063
2064 /**
2065  * X11DRV_wglCreatePbufferARB
2066  *
2067  * WGL_ARB_pbuffer: wglCreatePbufferARB
2068  */
2069 static HPBUFFERARB WINAPI X11DRV_wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList)
2070 {
2071     Wine_GLPBuffer* object = NULL;
2072     WineGLPixelFormat *fmt = NULL;
2073     int nCfgs = 0;
2074     int attribs[256];
2075     int nAttribs = 0;
2076
2077     TRACE("(%p, %d, %d, %d, %p)\n", hdc, iPixelFormat, iWidth, iHeight, piAttribList);
2078
2079     if (0 >= iPixelFormat) {
2080         ERR("(%p): unexpected iPixelFormat(%d) <= 0, returns NULL\n", hdc, iPixelFormat);
2081         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2082         return NULL; /* unexpected error */
2083     }
2084
2085     /* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */
2086     fmt = ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, TRUE /* Offscreen */, &nCfgs);
2087     if(!fmt) {
2088         ERR("(%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, iPixelFormat, nCfgs);
2089         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2090         goto create_failed; /* unexpected error */
2091     }
2092
2093     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLPBuffer));
2094     if (NULL == object) {
2095         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
2096         goto create_failed; /* unexpected error */
2097     }
2098     object->hdc = hdc;
2099     object->display = gdi_display;
2100     object->width = iWidth;
2101     object->height = iHeight;
2102     object->fmt = fmt;
2103
2104     PUSH2(attribs, GLX_PBUFFER_WIDTH,  iWidth);
2105     PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight); 
2106     while (piAttribList && 0 != *piAttribList) {
2107         int attr_v;
2108         switch (*piAttribList) {
2109             case WGL_PBUFFER_LARGEST_ARB: {
2110                 ++piAttribList;
2111                 attr_v = *piAttribList;
2112                 TRACE("WGL_LARGEST_PBUFFER_ARB = %d\n", attr_v);
2113                 PUSH2(attribs, GLX_LARGEST_PBUFFER, attr_v);
2114                 break;
2115             }
2116
2117             case WGL_TEXTURE_FORMAT_ARB: {
2118                 ++piAttribList;
2119                 attr_v = *piAttribList;
2120                 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v);
2121                 if (use_render_texture_ati) {
2122                     int type = 0;
2123                     switch (attr_v) {
2124                         case WGL_NO_TEXTURE_ARB: type = GLX_NO_TEXTURE_ATI; break ;
2125                         case WGL_TEXTURE_RGB_ARB: type = GLX_TEXTURE_RGB_ATI; break ;
2126                         case WGL_TEXTURE_RGBA_ARB: type = GLX_TEXTURE_RGBA_ATI; break ;
2127                         default:
2128                             SetLastError(ERROR_INVALID_DATA);
2129                             goto create_failed;
2130                     }
2131                     object->use_render_texture = 1;
2132                     PUSH2(attribs, GLX_TEXTURE_FORMAT_ATI, type);
2133                 } else {
2134                     if (WGL_NO_TEXTURE_ARB == attr_v) {
2135                         object->use_render_texture = 0;
2136                     } else {
2137                         if (!use_render_texture_emulation) {
2138                             SetLastError(ERROR_INVALID_DATA);
2139                             goto create_failed;
2140                         }
2141                         switch (attr_v) {
2142                             case WGL_TEXTURE_RGB_ARB:
2143                                 object->use_render_texture = GL_RGB;
2144                                 object->texture_bpp = 3;
2145                                 object->texture_format = GL_RGB;
2146                                 object->texture_type = GL_UNSIGNED_BYTE;
2147                                 break;
2148                             case WGL_TEXTURE_RGBA_ARB:
2149                                 object->use_render_texture = GL_RGBA;
2150                                 object->texture_bpp = 4;
2151                                 object->texture_format = GL_RGBA;
2152                                 object->texture_type = GL_UNSIGNED_BYTE;
2153                                 break;
2154
2155                             /* WGL_FLOAT_COMPONENTS_NV */
2156                             case WGL_TEXTURE_FLOAT_R_NV:
2157                                 object->use_render_texture = GL_FLOAT_R_NV;
2158                                 object->texture_bpp = 4;
2159                                 object->texture_format = GL_RED;
2160                                 object->texture_type = GL_FLOAT;
2161                                 break;
2162                             case WGL_TEXTURE_FLOAT_RG_NV:
2163                                 object->use_render_texture = GL_FLOAT_RG_NV;
2164                                 object->texture_bpp = 8;
2165                                 object->texture_format = GL_LUMINANCE_ALPHA;
2166                                 object->texture_type = GL_FLOAT;
2167                                 break;
2168                             case WGL_TEXTURE_FLOAT_RGB_NV:
2169                                 object->use_render_texture = GL_FLOAT_RGB_NV;
2170                                 object->texture_bpp = 12;
2171                                 object->texture_format = GL_RGB;
2172                                 object->texture_type = GL_FLOAT;
2173                                 break;
2174                             case WGL_TEXTURE_FLOAT_RGBA_NV:
2175                                 object->use_render_texture = GL_FLOAT_RGBA_NV;
2176                                 object->texture_bpp = 16;
2177                                 object->texture_format = GL_RGBA;
2178                                 object->texture_type = GL_FLOAT;
2179                                 break;
2180                             default:
2181                                 ERR("Unknown texture format: %x\n", attr_v);
2182                                 SetLastError(ERROR_INVALID_DATA);
2183                                 goto create_failed;
2184                         }
2185                     }
2186                 }
2187                 break;
2188             }
2189
2190             case WGL_TEXTURE_TARGET_ARB: {
2191                 ++piAttribList;
2192                 attr_v = *piAttribList;
2193                 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v);
2194                 if (use_render_texture_ati) {
2195                     int type = 0;
2196                     switch (attr_v) {
2197                         case WGL_NO_TEXTURE_ARB: type = GLX_NO_TEXTURE_ATI; break ;
2198                         case WGL_TEXTURE_CUBE_MAP_ARB: type = GLX_TEXTURE_CUBE_MAP_ATI; break ;
2199                         case WGL_TEXTURE_1D_ARB: type = GLX_TEXTURE_1D_ATI; break ;
2200                         case WGL_TEXTURE_2D_ARB: type = GLX_TEXTURE_2D_ATI; break ;
2201                         default:
2202                             SetLastError(ERROR_INVALID_DATA);
2203                             goto create_failed;
2204                     }
2205                     PUSH2(attribs, GLX_TEXTURE_TARGET_ATI, type);
2206                 } else {
2207                     if (WGL_NO_TEXTURE_ARB == attr_v) {
2208                         object->texture_target = 0;
2209                     } else {
2210                         if (!use_render_texture_emulation) {
2211                             SetLastError(ERROR_INVALID_DATA);
2212                             goto create_failed;
2213                         }
2214                         switch (attr_v) {
2215                             case WGL_TEXTURE_CUBE_MAP_ARB: {
2216                                 if (iWidth != iHeight) {
2217                                     SetLastError(ERROR_INVALID_DATA);
2218                                     goto create_failed;
2219                                 }
2220                                 object->texture_target = GL_TEXTURE_CUBE_MAP;
2221                                 object->texture_bind_target = GL_TEXTURE_BINDING_CUBE_MAP;
2222                                break;
2223                             }
2224                             case WGL_TEXTURE_1D_ARB: {
2225                                 if (1 != iHeight) {
2226                                     SetLastError(ERROR_INVALID_DATA);
2227                                     goto create_failed;
2228                                 }
2229                                 object->texture_target = GL_TEXTURE_1D;
2230                                 object->texture_bind_target = GL_TEXTURE_BINDING_1D;
2231                                 break;
2232                             }
2233                             case WGL_TEXTURE_2D_ARB: {
2234                                 object->texture_target = GL_TEXTURE_2D;
2235                                 object->texture_bind_target = GL_TEXTURE_BINDING_2D;
2236                                 break;
2237                             }
2238                             case WGL_TEXTURE_RECTANGLE_NV: {
2239                                 object->texture_target = GL_TEXTURE_RECTANGLE_NV;
2240                                 object->texture_bind_target = GL_TEXTURE_BINDING_RECTANGLE_NV;
2241                                 break;
2242                             }
2243                             default:
2244                                 ERR("Unknown texture target: %x\n", attr_v);
2245                                 SetLastError(ERROR_INVALID_DATA);
2246                                 goto create_failed;
2247                         }
2248                     }
2249                 }
2250                 break;
2251             }
2252
2253             case WGL_MIPMAP_TEXTURE_ARB: {
2254                 ++piAttribList;
2255                 attr_v = *piAttribList;
2256                 TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v);
2257                 if (use_render_texture_ati) {
2258                     PUSH2(attribs, GLX_MIPMAP_TEXTURE_ATI, attr_v);
2259                 } else {
2260                     if (!use_render_texture_emulation) {
2261                         SetLastError(ERROR_INVALID_DATA);
2262                         goto create_failed;
2263                     }
2264                 }
2265                 break;
2266             }
2267         }
2268         ++piAttribList;
2269     }
2270
2271     PUSH1(attribs, None);
2272     object->drawable = pglXCreatePbuffer(gdi_display, fmt->fbconfig, attribs);
2273     TRACE("new Pbuffer drawable as %p\n", (void*) object->drawable);
2274     if (!object->drawable) {
2275         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
2276         goto create_failed; /* unexpected error */
2277     }
2278     TRACE("->(%p)\n", object);
2279     return (HPBUFFERARB) object;
2280
2281 create_failed:
2282     HeapFree(GetProcessHeap(), 0, object);
2283     TRACE("->(FAILED)\n");
2284     return (HPBUFFERARB) NULL;
2285 }
2286
2287 /**
2288  * X11DRV_wglDestroyPbufferARB
2289  *
2290  * WGL_ARB_pbuffer: wglDestroyPbufferARB
2291  */
2292 static GLboolean WINAPI X11DRV_wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
2293 {
2294     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2295     TRACE("(%p)\n", hPbuffer);
2296     if (NULL == object) {
2297         SetLastError(ERROR_INVALID_HANDLE);
2298         return GL_FALSE;
2299     }
2300     pglXDestroyPbuffer(object->display, object->drawable);
2301     HeapFree(GetProcessHeap(), 0, object);
2302     return GL_TRUE;
2303 }
2304
2305 /**
2306  * X11DRV_wglGetPbufferDCARB
2307  *
2308  * WGL_ARB_pbuffer: wglGetPbufferDCARB
2309  * The function wglGetPbufferDCARB returns a device context for a pbuffer.
2310  * Gdi32 implements the part of this function which creates a device context.
2311  * This part associates the physDev with the X drawable of the pbuffer.
2312  */
2313 HDC X11DRV_wglGetPbufferDCARB(X11DRV_PDEVICE *physDev, HPBUFFERARB hPbuffer)
2314 {
2315     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2316     if (NULL == object) {
2317         SetLastError(ERROR_INVALID_HANDLE);
2318         return NULL;
2319     }
2320
2321     /* The function wglGetPbufferDCARB returns a DC to which the pbuffer can be connected.
2322      * All formats in our pixelformat list are compatible with each other and the main drawable. */
2323     physDev->current_pf = object->fmt->iPixelFormat;
2324     physDev->drawable = object->drawable;
2325     SetRect( &physDev->drawable_rect, 0, 0, object->width, object->height );
2326     physDev->dc_rect = physDev->drawable_rect;
2327
2328     TRACE("(%p)->(%p)\n", hPbuffer, physDev->hdc);
2329     return physDev->hdc;
2330 }
2331
2332 /**
2333  * X11DRV_wglQueryPbufferARB
2334  *
2335  * WGL_ARB_pbuffer: wglQueryPbufferARB
2336  */
2337 static GLboolean WINAPI X11DRV_wglQueryPbufferARB(HPBUFFERARB hPbuffer, int iAttribute, int *piValue)
2338 {
2339     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2340     TRACE("(%p, 0x%x, %p)\n", hPbuffer, iAttribute, piValue);
2341     if (NULL == object) {
2342         SetLastError(ERROR_INVALID_HANDLE);
2343         return GL_FALSE;
2344     }
2345     switch (iAttribute) {
2346         case WGL_PBUFFER_WIDTH_ARB:
2347             pglXQueryDrawable(object->display, object->drawable, GLX_WIDTH, (unsigned int*) piValue);
2348             break;
2349         case WGL_PBUFFER_HEIGHT_ARB:
2350             pglXQueryDrawable(object->display, object->drawable, GLX_HEIGHT, (unsigned int*) piValue);
2351             break;
2352
2353         case WGL_PBUFFER_LOST_ARB:
2354             /* GLX Pbuffers cannot be lost by default. We can support this by
2355              * setting GLX_PRESERVED_CONTENTS to False and using glXSelectEvent
2356              * to receive pixel buffer clobber events, however that may or may
2357              * not give any benefit */
2358             *piValue = GL_FALSE;
2359             break;
2360
2361         case WGL_TEXTURE_FORMAT_ARB:
2362             if (use_render_texture_ati) {
2363                 unsigned int tmp;
2364                 int type = WGL_NO_TEXTURE_ARB;
2365                 pglXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_FORMAT_ATI, &tmp);
2366                 switch (tmp) {
2367                     case GLX_NO_TEXTURE_ATI: type = WGL_NO_TEXTURE_ARB; break ;
2368                     case GLX_TEXTURE_RGB_ATI: type = WGL_TEXTURE_RGB_ARB; break ;
2369                     case GLX_TEXTURE_RGBA_ATI: type = WGL_TEXTURE_RGBA_ARB; break ;
2370                 }
2371                 *piValue = type;
2372             } else {
2373                 if (!object->use_render_texture) {
2374                     *piValue = WGL_NO_TEXTURE_ARB;
2375                 } else {
2376                     if (!use_render_texture_emulation) {
2377                         SetLastError(ERROR_INVALID_HANDLE);
2378                         return GL_FALSE;
2379                     }
2380                     switch(object->use_render_texture) {
2381                         case GL_RGB:
2382                             *piValue = WGL_TEXTURE_RGB_ARB;
2383                             break;
2384                         case GL_RGBA:
2385                             *piValue = WGL_TEXTURE_RGBA_ARB;
2386                             break;
2387                         /* WGL_FLOAT_COMPONENTS_NV */
2388                         case GL_FLOAT_R_NV:
2389                             *piValue = WGL_TEXTURE_FLOAT_R_NV;
2390                             break;
2391                         case GL_FLOAT_RG_NV:
2392                             *piValue = WGL_TEXTURE_FLOAT_RG_NV;
2393                             break;
2394                         case GL_FLOAT_RGB_NV:
2395                             *piValue = WGL_TEXTURE_FLOAT_RGB_NV;
2396                             break;
2397                         case GL_FLOAT_RGBA_NV:
2398                             *piValue = WGL_TEXTURE_FLOAT_RGBA_NV;
2399                             break;
2400                         default:
2401                             ERR("Unknown texture format: %x\n", object->use_render_texture);
2402                     }
2403                 }
2404             }
2405             break;
2406
2407         case WGL_TEXTURE_TARGET_ARB:
2408             if (use_render_texture_ati) {
2409                 unsigned int tmp;
2410                 int type = WGL_NO_TEXTURE_ARB;
2411                 pglXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_TARGET_ATI, &tmp);
2412                 switch (tmp) {
2413                     case GLX_NO_TEXTURE_ATI: type = WGL_NO_TEXTURE_ARB; break ;
2414                     case GLX_TEXTURE_CUBE_MAP_ATI: type = WGL_TEXTURE_CUBE_MAP_ARB; break ;
2415                     case GLX_TEXTURE_1D_ATI: type = WGL_TEXTURE_1D_ARB; break ;
2416                     case GLX_TEXTURE_2D_ATI: type = WGL_TEXTURE_2D_ARB; break ;
2417                 }
2418                 *piValue = type;
2419             } else {
2420             if (!object->texture_target) {
2421                 *piValue = WGL_NO_TEXTURE_ARB;
2422             } else {
2423                 if (!use_render_texture_emulation) {
2424                     SetLastError(ERROR_INVALID_DATA);      
2425                     return GL_FALSE;
2426                 }
2427                 switch (object->texture_target) {
2428                     case GL_TEXTURE_1D:       *piValue = WGL_TEXTURE_1D_ARB; break;
2429                     case GL_TEXTURE_2D:       *piValue = WGL_TEXTURE_2D_ARB; break;
2430                     case GL_TEXTURE_CUBE_MAP: *piValue = WGL_TEXTURE_CUBE_MAP_ARB; break;
2431                     case GL_TEXTURE_RECTANGLE_NV: *piValue = WGL_TEXTURE_RECTANGLE_NV; break;
2432                 }
2433             }
2434         }
2435         break;
2436
2437     case WGL_MIPMAP_TEXTURE_ARB:
2438         if (use_render_texture_ati) {
2439             pglXQueryDrawable(object->display, object->drawable, GLX_MIPMAP_TEXTURE_ATI, (unsigned int*) piValue);
2440         } else {
2441             *piValue = GL_FALSE; /** don't support that */
2442             FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute);
2443         }
2444         break;
2445
2446     default:
2447         FIXME("unexpected attribute %x\n", iAttribute);
2448         break;
2449     }
2450
2451     return GL_TRUE;
2452 }
2453
2454 /**
2455  * X11DRV_wglReleasePbufferDCARB
2456  *
2457  * WGL_ARB_pbuffer: wglReleasePbufferDCARB
2458  */
2459 static int WINAPI X11DRV_wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, HDC hdc)
2460 {
2461     TRACE("(%p, %p)\n", hPbuffer, hdc);
2462     DeleteDC(hdc);
2463     return 0;
2464 }
2465
2466 /**
2467  * X11DRV_wglSetPbufferAttribARB
2468  *
2469  * WGL_ARB_pbuffer: wglSetPbufferAttribARB
2470  */
2471 static GLboolean WINAPI X11DRV_wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int *piAttribList)
2472 {
2473     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2474     WARN("(%p, %p): alpha-testing, report any problem\n", hPbuffer, piAttribList);
2475     if (NULL == object) {
2476         SetLastError(ERROR_INVALID_HANDLE);
2477         return GL_FALSE;
2478     }
2479     if (!object->use_render_texture) {
2480         SetLastError(ERROR_INVALID_HANDLE);
2481         return GL_FALSE;
2482     }
2483     if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
2484         return GL_TRUE;
2485     }
2486     if (NULL != pglXDrawableAttribATI) {
2487         if (use_render_texture_ati) {
2488             FIXME("Need conversion for GLX_ATI_render_texture\n");
2489         }
2490         return pglXDrawableAttribATI(object->display, object->drawable, piAttribList);
2491     }
2492     return GL_FALSE;
2493 }
2494
2495 /**
2496  * X11DRV_wglChoosePixelFormatARB
2497  *
2498  * WGL_ARB_pixel_format: wglChoosePixelFormatARB
2499  */
2500 static GLboolean WINAPI X11DRV_wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats)
2501 {
2502     int gl_test = 0;
2503     int attribs[256];
2504     int nAttribs = 0;
2505     GLXFBConfig* cfgs = NULL;
2506     int nCfgs = 0;
2507     UINT it;
2508     int fmt_id;
2509     WineGLPixelFormat *fmt;
2510     int pfmt_it = 0;
2511     int run;
2512
2513     TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
2514     if (NULL != pfAttribFList) {
2515         FIXME("unused pfAttribFList\n");
2516     }
2517
2518     nAttribs = ConvertAttribWGLtoGLX(piAttribIList, attribs, NULL);
2519     if (-1 == nAttribs) {
2520         WARN("Cannot convert WGL to GLX attributes\n");
2521         return GL_FALSE;
2522     }
2523     PUSH1(attribs, None);
2524
2525     /* Search for FB configurations matching the requirements in attribs */
2526     cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), attribs, &nCfgs);
2527     if (NULL == cfgs) {
2528         WARN("Compatible Pixel Format not found\n");
2529         return GL_FALSE;
2530     }
2531
2532     /* Loop through all matching formats and check if they are suitable.
2533     * Note that this function should at max return nMaxFormats different formats */
2534     for(run=0; run < 2; run++)
2535     {
2536         for (it = 0; it < nCfgs; ++it) {
2537             gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id);
2538             if (gl_test) {
2539                 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
2540                 continue;
2541             }
2542
2543             /* Search for the format in our list of compatible formats */
2544             fmt = ConvertPixelFormatGLXtoWGL(gdi_display, fmt_id);
2545             if(!fmt)
2546                 continue;
2547
2548             /* During the first run we only want onscreen formats and during the second only offscreen 'XOR' */
2549             if( ((run == 0) && fmt->offscreenOnly) || ((run == 1) && !fmt->offscreenOnly) )
2550                 continue;
2551
2552             if(pfmt_it < nMaxFormats) {
2553                 piFormats[pfmt_it] = fmt->iPixelFormat;
2554                 TRACE("at %d/%d found FBCONFIG_ID 0x%x (%d)\n", it + 1, nCfgs, fmt_id, piFormats[pfmt_it]);
2555             }
2556             pfmt_it++;
2557         }
2558     }
2559
2560     *nNumFormats = pfmt_it;
2561     /** free list */
2562     XFree(cfgs);
2563     return GL_TRUE;
2564 }
2565
2566 /**
2567  * X11DRV_wglGetPixelFormatAttribivARB
2568  *
2569  * WGL_ARB_pixel_format: wglGetPixelFormatAttribivARB
2570  */
2571 static GLboolean WINAPI X11DRV_wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues)
2572 {
2573     UINT i;
2574     WineGLPixelFormat *fmt = NULL;
2575     int hTest;
2576     int tmp;
2577     int curGLXAttr = 0;
2578     int nWGLFormats = 0;
2579
2580     TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues);
2581
2582     if (0 < iLayerPlane) {
2583         FIXME("unsupported iLayerPlane(%d) > 0, returns FALSE\n", iLayerPlane);
2584         return GL_FALSE;
2585     }
2586
2587     /* Convert the WGL pixelformat to a GLX one, if this fails then most likely the iPixelFormat isn't supoprted.
2588     * We don't have to fail yet as a program can specify an invaled iPixelFormat (lets say 0) if it wants to query
2589     * the number of supported WGL formats. Whether the iPixelFormat is valid is handled in the for-loop below. */
2590     fmt = ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, TRUE /* Offscreen */, &nWGLFormats);
2591     if(!fmt) {
2592         WARN("Unable to convert iPixelFormat %d to a GLX one!\n", iPixelFormat);
2593     }
2594
2595     for (i = 0; i < nAttributes; ++i) {
2596         const int curWGLAttr = piAttributes[i];
2597         TRACE("pAttr[%d] = %x\n", i, curWGLAttr);
2598
2599         switch (curWGLAttr) {
2600             case WGL_NUMBER_PIXEL_FORMATS_ARB:
2601                 piValues[i] = nWGLFormats; 
2602                 continue;
2603
2604             case WGL_SUPPORT_OPENGL_ARB:
2605                 piValues[i] = GL_TRUE; 
2606                 continue;
2607
2608             case WGL_ACCELERATION_ARB:
2609                 curGLXAttr = GLX_CONFIG_CAVEAT;
2610                 if (!fmt) goto pix_error;
2611                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2612                 if (hTest) goto get_error;
2613                 switch (tmp) {
2614                     case GLX_NONE: piValues[i] = WGL_FULL_ACCELERATION_ARB; break;
2615                     case GLX_SLOW_CONFIG: piValues[i] = WGL_GENERIC_ACCELERATION_ARB; break;
2616                     case GLX_NON_CONFORMANT_CONFIG: piValues[i] = WGL_FULL_ACCELERATION_ARB; break;
2617                     default:
2618                         ERR("unexpected Config Caveat(%x)\n", tmp);
2619                         piValues[i] = WGL_NO_ACCELERATION_ARB;
2620                 }
2621                 continue;
2622
2623             case WGL_TRANSPARENT_ARB:
2624                 curGLXAttr = GLX_TRANSPARENT_TYPE;
2625                 if (!fmt) goto pix_error;
2626                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2627                 if (hTest) goto get_error;
2628                     piValues[i] = GL_FALSE;
2629                 if (GLX_NONE != tmp) piValues[i] = GL_TRUE;
2630                     continue;
2631
2632             case WGL_PIXEL_TYPE_ARB:
2633                 curGLXAttr = GLX_RENDER_TYPE;
2634                 if (!fmt) goto pix_error;
2635                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2636                 if (hTest) goto get_error;
2637                 TRACE("WGL_PIXEL_TYPE_ARB: GLX_RENDER_TYPE = 0x%x\n", tmp);
2638                 if      (tmp & GLX_RGBA_BIT)           { piValues[i] = WGL_TYPE_RGBA_ARB; }
2639                 else if (tmp & GLX_COLOR_INDEX_BIT)    { piValues[i] = WGL_TYPE_COLORINDEX_ARB; }
2640                 else if (tmp & GLX_RGBA_FLOAT_BIT)     { piValues[i] = WGL_TYPE_RGBA_FLOAT_ATI; }
2641                 else if (tmp & GLX_RGBA_FLOAT_ATI_BIT) { piValues[i] = WGL_TYPE_RGBA_FLOAT_ATI; }
2642                 else {
2643                     ERR("unexpected RenderType(%x)\n", tmp);
2644                     piValues[i] = WGL_TYPE_RGBA_ARB;
2645                 }
2646                 continue;
2647
2648             case WGL_COLOR_BITS_ARB:
2649                 curGLXAttr = GLX_BUFFER_SIZE;
2650                 break;
2651
2652             case WGL_BIND_TO_TEXTURE_RGB_ARB:
2653                 if (use_render_texture_ati) {
2654                     curGLXAttr = GLX_BIND_TO_TEXTURE_RGB_ATI;
2655                     break;
2656                 }
2657             case WGL_BIND_TO_TEXTURE_RGBA_ARB:
2658                 if (use_render_texture_ati) {
2659                     curGLXAttr = GLX_BIND_TO_TEXTURE_RGBA_ATI;
2660                     break;
2661                 }
2662                 if (!use_render_texture_emulation) {
2663                     piValues[i] = GL_FALSE;
2664                     continue;   
2665                 }
2666                 curGLXAttr = GLX_RENDER_TYPE;
2667                 if (!fmt) goto pix_error;
2668                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2669                 if (hTest) goto get_error;
2670                 if (GLX_COLOR_INDEX_BIT == tmp) {
2671                     piValues[i] = GL_FALSE;  
2672                     continue;
2673                 }
2674                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &tmp);
2675                 if (hTest) goto get_error;
2676                     piValues[i] = (tmp & GLX_PBUFFER_BIT) ? GL_TRUE : GL_FALSE;
2677                 continue;
2678
2679             case WGL_BLUE_BITS_ARB:
2680                 curGLXAttr = GLX_BLUE_SIZE;
2681                 break;
2682             case WGL_RED_BITS_ARB:
2683                 curGLXAttr = GLX_RED_SIZE;
2684                 break;
2685             case WGL_GREEN_BITS_ARB:
2686                 curGLXAttr = GLX_GREEN_SIZE;
2687                 break;
2688             case WGL_ALPHA_BITS_ARB:
2689                 curGLXAttr = GLX_ALPHA_SIZE;
2690                 break;
2691             case WGL_DEPTH_BITS_ARB:
2692                 curGLXAttr = GLX_DEPTH_SIZE;
2693                 break;
2694             case WGL_STENCIL_BITS_ARB:
2695                 curGLXAttr = GLX_STENCIL_SIZE;
2696                 break;
2697             case WGL_DOUBLE_BUFFER_ARB:
2698                 curGLXAttr = GLX_DOUBLEBUFFER;
2699                 break;
2700             case WGL_STEREO_ARB:
2701                 curGLXAttr = GLX_STEREO;
2702                 break;
2703             case WGL_AUX_BUFFERS_ARB:
2704                 curGLXAttr = GLX_AUX_BUFFERS;
2705                 break;
2706
2707             case WGL_SUPPORT_GDI_ARB:
2708                 if (!fmt) goto pix_error;
2709                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &tmp);
2710                 if (hTest) goto get_error;
2711                 if(tmp) {
2712                     piValues[i] = GL_FALSE;
2713                     continue;
2714                 }
2715                 curGLXAttr = GLX_X_RENDERABLE;
2716                 break;
2717
2718             case WGL_DRAW_TO_WINDOW_ARB:
2719             case WGL_DRAW_TO_BITMAP_ARB:
2720             case WGL_DRAW_TO_PBUFFER_ARB:
2721                 if (!fmt) goto pix_error;
2722                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &tmp);
2723                 if (hTest) goto get_error;
2724                 if((curWGLAttr == WGL_DRAW_TO_WINDOW_ARB && (tmp&GLX_WINDOW_BIT)) ||
2725                    (curWGLAttr == WGL_DRAW_TO_BITMAP_ARB && (tmp&GLX_PIXMAP_BIT)) ||
2726                    (curWGLAttr == WGL_DRAW_TO_PBUFFER_ARB && (tmp&GLX_PBUFFER_BIT)))
2727                     piValues[i] = GL_TRUE;
2728                 else
2729                     piValues[i] = GL_FALSE;
2730                 continue;
2731
2732             case WGL_PBUFFER_LARGEST_ARB:
2733                 curGLXAttr = GLX_LARGEST_PBUFFER;
2734                 break;
2735
2736             case WGL_SAMPLE_BUFFERS_ARB:
2737                 curGLXAttr = GLX_SAMPLE_BUFFERS_ARB;
2738                 break;
2739
2740             case WGL_SAMPLES_ARB:
2741                 curGLXAttr = GLX_SAMPLES_ARB;
2742                 break;
2743
2744             case WGL_FLOAT_COMPONENTS_NV:
2745                 curGLXAttr = GLX_FLOAT_COMPONENTS_NV;
2746                 break;
2747
2748             case WGL_ACCUM_RED_BITS_ARB:
2749                 curGLXAttr = GLX_ACCUM_RED_SIZE;
2750                 break;
2751             case WGL_ACCUM_GREEN_BITS_ARB:
2752                 curGLXAttr = GLX_ACCUM_GREEN_SIZE;
2753                 break;
2754             case WGL_ACCUM_BLUE_BITS_ARB:
2755                 curGLXAttr = GLX_ACCUM_BLUE_SIZE;
2756                 break;
2757             case WGL_ACCUM_ALPHA_BITS_ARB:
2758                 curGLXAttr = GLX_ACCUM_ALPHA_SIZE;
2759                 break;
2760             case WGL_ACCUM_BITS_ARB:
2761                 if (!fmt) goto pix_error;
2762                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_RED_SIZE, &tmp);
2763                 if (hTest) goto get_error;
2764                 piValues[i] = tmp;
2765                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_GREEN_SIZE, &tmp);
2766                 if (hTest) goto get_error;
2767                 piValues[i] += tmp;
2768                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_BLUE_SIZE, &tmp);
2769                 if (hTest) goto get_error;
2770                 piValues[i] += tmp;
2771                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_ALPHA_SIZE, &tmp);
2772                 if (hTest) goto get_error;
2773                 piValues[i] += tmp;
2774                 continue;
2775
2776             default:
2777                 FIXME("unsupported %x WGL Attribute\n", curWGLAttr);
2778         }
2779
2780         /* Retrieve a GLX FBConfigAttrib when the attribute to query is valid and
2781          * iPixelFormat != 0. When iPixelFormat is 0 the only value which makes
2782          * sense to query is WGL_NUMBER_PIXEL_FORMATS_ARB.
2783          *
2784          * TODO: properly test the behavior of wglGetPixelFormatAttrib*v on Windows
2785          *       and check which options can work using iPixelFormat=0 and which not.
2786          *       A problem would be that this function is an extension. This would
2787          *       mean that the behavior could differ between different vendors (ATI, Nvidia, ..).
2788          */
2789         if (0 != curGLXAttr && iPixelFormat != 0) {
2790             if (!fmt) goto pix_error;
2791             hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, piValues + i);
2792             if (hTest) goto get_error;
2793             curGLXAttr = 0;
2794         } else { 
2795             piValues[i] = GL_FALSE; 
2796         }
2797     }
2798     return GL_TRUE;
2799
2800 get_error:
2801     ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc, curGLXAttr);
2802     return GL_FALSE;
2803
2804 pix_error:
2805     ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc, iPixelFormat, nWGLFormats);
2806     return GL_FALSE;
2807 }
2808
2809 /**
2810  * X11DRV_wglGetPixelFormatAttribfvARB
2811  *
2812  * WGL_ARB_pixel_format: wglGetPixelFormatAttribfvARB
2813  */
2814 static GLboolean WINAPI X11DRV_wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues)
2815 {
2816     int *attr;
2817     int ret;
2818     int i;
2819
2820     TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues);
2821
2822     /* Allocate a temporary array to store integer values */
2823     attr = HeapAlloc(GetProcessHeap(), 0, nAttributes * sizeof(int));
2824     if (!attr) {
2825         ERR("couldn't allocate %d array\n", nAttributes);
2826         return GL_FALSE;
2827     }
2828
2829     /* Piggy-back on wglGetPixelFormatAttribivARB */
2830     ret = X11DRV_wglGetPixelFormatAttribivARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, attr);
2831     if (ret) {
2832         /* Convert integer values to float. Should also check for attributes
2833            that can give decimal values here */
2834         for (i=0; i<nAttributes;i++) {
2835             pfValues[i] = attr[i];
2836         }
2837     }
2838
2839     HeapFree(GetProcessHeap(), 0, attr);
2840     return ret;
2841 }
2842
2843 /**
2844  * X11DRV_wglBindTexImageARB
2845  *
2846  * WGL_ARB_render_texture: wglBindTexImageARB
2847  */
2848 static GLboolean WINAPI X11DRV_wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
2849 {
2850     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2851     TRACE("(%p, %d)\n", hPbuffer, iBuffer);
2852     if (NULL == object) {
2853         SetLastError(ERROR_INVALID_HANDLE);
2854         return GL_FALSE;
2855     }
2856     if (!object->use_render_texture) {
2857         SetLastError(ERROR_INVALID_HANDLE);
2858         return GL_FALSE;
2859     }
2860
2861     if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
2862         static int init = 0;
2863         int prev_binded_texture = 0;
2864         GLXContext prev_context = pglXGetCurrentContext();
2865         Drawable prev_drawable = pglXGetCurrentDrawable();
2866         GLXContext tmp_context;
2867
2868         /* Our render_texture emulation is basic and lacks some features (1D/Cube support).
2869            This is mostly due to lack of demos/games using them. Further the use of glReadPixels
2870            isn't ideal performance wise but I wasn't able to get other ways working.
2871         */
2872         if(!init) {
2873             init = 1; /* Only show the FIXME once for performance reasons */
2874             FIXME("partial stub!\n");
2875         }
2876
2877         TRACE("drawable=%p, context=%p\n", (void*)object->drawable, prev_context);
2878         tmp_context = pglXCreateNewContext(gdi_display, object->fmt->fbconfig, object->fmt->render_type, prev_context, True);
2879
2880         pglGetIntegerv(object->texture_bind_target, &prev_binded_texture);
2881
2882         /* Switch to our pbuffer */
2883         pglXMakeCurrent(gdi_display, object->drawable, tmp_context);
2884
2885         /* Make sure that the prev_binded_texture is set as the current texture state isn't shared between contexts.
2886          * After that upload the pbuffer texture data. */
2887         pglBindTexture(object->texture_target, prev_binded_texture);
2888         pglCopyTexImage2D(object->texture_target, 0, object->use_render_texture, 0, 0, object->width, object->height, 0);
2889
2890         /* Switch back to the original drawable and upload the pbuffer-texture */
2891         pglXMakeCurrent(object->display, prev_drawable, prev_context);
2892         pglXDestroyContext(gdi_display, tmp_context);
2893         return GL_TRUE;
2894     }
2895
2896     if (NULL != pglXBindTexImageATI) {
2897         int buffer;
2898
2899         switch(iBuffer)
2900         {
2901             case WGL_FRONT_LEFT_ARB:
2902                 buffer = GLX_FRONT_LEFT_ATI;
2903                 break;
2904             case WGL_FRONT_RIGHT_ARB:
2905                 buffer = GLX_FRONT_RIGHT_ATI;
2906                 break;
2907             case WGL_BACK_LEFT_ARB:
2908                 buffer = GLX_BACK_LEFT_ATI;
2909                 break;
2910             case WGL_BACK_RIGHT_ARB:
2911                 buffer = GLX_BACK_RIGHT_ATI;
2912                 break;
2913             default:
2914                 ERR("Unknown iBuffer=%#x\n", iBuffer);
2915                 return FALSE;
2916         }
2917
2918         /* In the sample 'ogl_offscreen_rendering_3' from codesampler.net I get garbage on the screen.
2919          * I'm not sure if that's a bug in the ATI extension or in the program. I think that the program
2920          * expected a single buffering format since it didn't ask for double buffering. A buffer swap
2921          * fixed the program. I don't know what the correct behavior is. On the other hand that demo
2922          * works fine using our pbuffer emulation path.
2923          */
2924         return pglXBindTexImageATI(object->display, object->drawable, buffer);
2925     }
2926     return GL_FALSE;
2927 }
2928
2929 /**
2930  * X11DRV_wglReleaseTexImageARB
2931  *
2932  * WGL_ARB_render_texture: wglReleaseTexImageARB
2933  */
2934 static GLboolean WINAPI X11DRV_wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
2935 {
2936     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2937     TRACE("(%p, %d)\n", hPbuffer, iBuffer);
2938     if (NULL == object) {
2939         SetLastError(ERROR_INVALID_HANDLE);
2940         return GL_FALSE;
2941     }
2942     if (!object->use_render_texture) {
2943         SetLastError(ERROR_INVALID_HANDLE);
2944         return GL_FALSE;
2945     }
2946     if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
2947         return GL_TRUE;
2948     }
2949     if (NULL != pglXReleaseTexImageATI) {
2950         int buffer;
2951
2952         switch(iBuffer)
2953         {
2954             case WGL_FRONT_LEFT_ARB:
2955                 buffer = GLX_FRONT_LEFT_ATI;
2956                 break;
2957             case WGL_FRONT_RIGHT_ARB:
2958                 buffer = GLX_FRONT_RIGHT_ATI;
2959                 break;
2960             case WGL_BACK_LEFT_ARB:
2961                 buffer = GLX_BACK_LEFT_ATI;
2962                 break;
2963             case WGL_BACK_RIGHT_ARB:
2964                 buffer = GLX_BACK_RIGHT_ATI;
2965                 break;
2966             default:
2967                 ERR("Unknown iBuffer=%#x\n", iBuffer);
2968                 return FALSE;
2969         }
2970         return pglXReleaseTexImageATI(object->display, object->drawable, buffer);
2971     }
2972     return GL_FALSE;
2973 }
2974
2975 /**
2976  * X11DRV_wglGetExtensionsStringEXT
2977  *
2978  * WGL_EXT_extensions_string: wglGetExtensionsStringEXT
2979  */
2980 static const char * WINAPI X11DRV_wglGetExtensionsStringEXT(void) {
2981     TRACE("() returning \"%s\"\n", WineGLInfo.wglExtensions);
2982     return WineGLInfo.wglExtensions;
2983 }
2984
2985 /**
2986  * X11DRV_wglGetSwapIntervalEXT
2987  *
2988  * WGL_EXT_swap_control: wglGetSwapIntervalEXT
2989  */
2990 static int WINAPI X11DRV_wglGetSwapIntervalEXT(VOID) {
2991     FIXME("(),stub!\n");
2992     return swap_interval;
2993 }
2994
2995 /**
2996  * X11DRV_wglSwapIntervalEXT
2997  *
2998  * WGL_EXT_swap_control: wglSwapIntervalEXT
2999  */
3000 static BOOL WINAPI X11DRV_wglSwapIntervalEXT(int interval) {
3001     TRACE("(%d)\n", interval);
3002     swap_interval = interval;
3003     if (NULL != pglXSwapIntervalSGI) {
3004         return 0 == pglXSwapIntervalSGI(interval);
3005     }
3006     WARN("(): GLX_SGI_swap_control extension seems not supported\n");
3007     return TRUE;
3008 }
3009
3010 /**
3011  * X11DRV_wglAllocateMemoryNV
3012  *
3013  * WGL_NV_vertex_array_range: wglAllocateMemoryNV
3014  */
3015 static void* WINAPI X11DRV_wglAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority) {
3016     TRACE("(%d, %f, %f, %f)\n", size, readfreq, writefreq, priority );
3017     if (pglXAllocateMemoryNV == NULL)
3018         return NULL;
3019
3020     return pglXAllocateMemoryNV(size, readfreq, writefreq, priority);
3021 }
3022
3023 /**
3024  * X11DRV_wglFreeMemoryNV
3025  *
3026  * WGL_NV_vertex_array_range: wglFreeMemoryNV
3027  */
3028 static void WINAPI X11DRV_wglFreeMemoryNV(GLvoid* pointer) {
3029     TRACE("(%p)\n", pointer);
3030     if (pglXFreeMemoryNV == NULL)
3031         return;
3032
3033     pglXFreeMemoryNV(pointer);
3034 }
3035
3036 /**
3037  * glxRequireVersion (internal)
3038  *
3039  * Check if the supported GLX version matches requiredVersion.
3040  */
3041 static BOOL glxRequireVersion(int requiredVersion)
3042 {
3043     /* Both requiredVersion and glXVersion[1] contains the minor GLX version */
3044     if(requiredVersion <= WineGLInfo.glxVersion[1])
3045         return TRUE;
3046
3047     return FALSE;
3048 }
3049
3050 static BOOL glxRequireExtension(const char *requiredExtension)
3051 {
3052     if (strstr(WineGLInfo.glxExtensions, requiredExtension) == NULL) {
3053         return FALSE;
3054     }
3055
3056     return TRUE;
3057 }
3058
3059 static void register_extension_string(const char *ext)
3060 {
3061     if (WineGLInfo.wglExtensions[0])
3062         strcat(WineGLInfo.wglExtensions, " ");
3063     strcat(WineGLInfo.wglExtensions, ext);
3064
3065     TRACE("'%s'\n", ext);
3066 }
3067
3068 static BOOL register_extension(const WineGLExtension * ext)
3069 {
3070     int i;
3071
3072     assert( WineGLExtensionListSize < MAX_EXTENSIONS );
3073     WineGLExtensionList[WineGLExtensionListSize++] = ext;
3074
3075     register_extension_string(ext->extName);
3076
3077     for (i = 0; ext->extEntryPoints[i].funcName; ++i)
3078         TRACE("    - '%s'\n", ext->extEntryPoints[i].funcName);
3079
3080     return TRUE;
3081 }
3082
3083 static const WineGLExtension WGL_internal_functions =
3084 {
3085   "",
3086   {
3087     { "wglDisable", X11DRV_wglDisable },
3088     { "wglEnable", X11DRV_wglEnable },
3089     { "wglGetIntegerv", X11DRV_wglGetIntegerv },
3090     { "wglIsEnabled", X11DRV_wglIsEnabled },
3091     { "wglScissor", X11DRV_wglScissor },
3092     { "wglViewport", X11DRV_wglViewport },
3093   }
3094 };
3095
3096
3097 static const WineGLExtension WGL_ARB_extensions_string =
3098 {
3099   "WGL_ARB_extensions_string",
3100   {
3101     { "wglGetExtensionsStringARB", X11DRV_wglGetExtensionsStringARB },
3102   }
3103 };
3104
3105 static const WineGLExtension WGL_ARB_make_current_read =
3106 {
3107   "WGL_ARB_make_current_read",
3108   {
3109     { "wglGetCurrentReadDCARB", X11DRV_wglGetCurrentReadDCARB },
3110     { "wglMakeContextCurrentARB", X11DRV_wglMakeContextCurrentARB },
3111   }
3112 };
3113
3114 static const WineGLExtension WGL_ARB_multisample =
3115 {
3116   "WGL_ARB_multisample",
3117 };
3118
3119 static const WineGLExtension WGL_ARB_pbuffer =
3120 {
3121   "WGL_ARB_pbuffer",
3122   {
3123     { "wglCreatePbufferARB", X11DRV_wglCreatePbufferARB },
3124     { "wglDestroyPbufferARB", X11DRV_wglDestroyPbufferARB },
3125     { "wglGetPbufferDCARB", X11DRV_wglGetPbufferDCARB },
3126     { "wglQueryPbufferARB", X11DRV_wglQueryPbufferARB },
3127     { "wglReleasePbufferDCARB", X11DRV_wglReleasePbufferDCARB },
3128     { "wglSetPbufferAttribARB", X11DRV_wglSetPbufferAttribARB },
3129   }
3130 };
3131
3132 static const WineGLExtension WGL_ARB_pixel_format =
3133 {
3134   "WGL_ARB_pixel_format",
3135   {
3136     { "wglChoosePixelFormatARB", X11DRV_wglChoosePixelFormatARB },
3137     { "wglGetPixelFormatAttribfvARB", X11DRV_wglGetPixelFormatAttribfvARB },
3138     { "wglGetPixelFormatAttribivARB", X11DRV_wglGetPixelFormatAttribivARB },
3139   }
3140 };
3141
3142 static const WineGLExtension WGL_ARB_render_texture =
3143 {
3144   "WGL_ARB_render_texture",
3145   {
3146     { "wglBindTexImageARB", X11DRV_wglBindTexImageARB },
3147     { "wglReleaseTexImageARB", X11DRV_wglReleaseTexImageARB },
3148   }
3149 };
3150
3151 static const WineGLExtension WGL_EXT_extensions_string =
3152 {
3153   "WGL_EXT_extensions_string",
3154   {
3155     { "wglGetExtensionsStringEXT", X11DRV_wglGetExtensionsStringEXT },
3156   }
3157 };
3158
3159 static const WineGLExtension WGL_EXT_swap_control =
3160 {
3161   "WGL_EXT_swap_control",
3162   {
3163     { "wglSwapIntervalEXT", X11DRV_wglSwapIntervalEXT },
3164     { "wglGetSwapIntervalEXT", X11DRV_wglGetSwapIntervalEXT },
3165   }
3166 };
3167
3168 static const WineGLExtension WGL_NV_vertex_array_range =
3169 {
3170   "WGL_NV_vertex_array_range",
3171   {
3172     { "wglAllocateMemoryNV", X11DRV_wglAllocateMemoryNV },
3173     { "wglFreeMemoryNV", X11DRV_wglFreeMemoryNV },
3174   }
3175 };
3176
3177 /**
3178  * X11DRV_WineGL_LoadExtensions
3179  */
3180 static void X11DRV_WineGL_LoadExtensions(void)
3181 {
3182     WineGLInfo.wglExtensions[0] = 0;
3183
3184     /* Load Wine internal functions */
3185     register_extension(&WGL_internal_functions);
3186
3187     /* ARB Extensions */
3188
3189     if(glxRequireExtension("GLX_ARB_fbconfig_float"))
3190     {
3191         register_extension_string("WGL_ARB_pixel_format_float");
3192         register_extension_string("WGL_ATI_pixel_format_float");
3193     }
3194
3195     register_extension(&WGL_ARB_extensions_string);
3196
3197     if (glxRequireVersion(3))
3198         register_extension(&WGL_ARB_make_current_read);
3199
3200     if (glxRequireExtension("GLX_ARB_multisample"))
3201         register_extension(&WGL_ARB_multisample);
3202
3203     /* In general pbuffer functionality requires support in the X-server. The functionality is
3204      * available either when the GLX_SGIX_pbuffer is present or when the GLX server version is 1.3.
3205      * All display drivers except for Nvidia's use the GLX module from Xfree86/Xorg which only
3206      * supports GLX 1.2. The endresult is that only Nvidia's drivers support pbuffers.
3207      *
3208      * The only other drive which has pbuffer support is Ati's FGLRX driver. They provide clientside GLX 1.3 support
3209      * without support in the X-server (which other Mesa based drivers require).
3210      *
3211      * Support pbuffers when the GLX version is 1.3 and GLX_SGIX_pbuffer is available. Further pbuffers can
3212      * also be supported when GLX_ATI_render_texture is available. This extension depends on pbuffers, so when it
3213      * is available pbuffers must be available too. */
3214     if ( (glxRequireVersion(3) && glxRequireExtension("GLX_SGIX_pbuffer")) || glxRequireExtension("GLX_ATI_render_texture"))
3215         register_extension(&WGL_ARB_pbuffer);
3216
3217     register_extension(&WGL_ARB_pixel_format);
3218
3219     /* Support WGL_ARB_render_texture when there's support or pbuffer based emulation */
3220     if (glxRequireExtension("GLX_ATI_render_texture") ||
3221         glxRequireExtension("GLX_ARB_render_texture") ||
3222         (glxRequireVersion(3) && glxRequireExtension("GLX_SGIX_pbuffer") && use_render_texture_emulation))
3223     {
3224         register_extension(&WGL_ARB_render_texture);
3225
3226         /* The WGL version of GLX_NV_float_buffer requires render_texture */
3227         if(glxRequireExtension("GLX_NV_float_buffer"))
3228             register_extension_string("WGL_NV_float_buffer");
3229
3230         /* Again there's no GLX equivalent for this extension, so depend on the required GL extension */
3231         if(strstr(WineGLInfo.glExtensions, "GL_NV_texture_rectangle") != NULL)
3232             register_extension_string("WGL_NV_texture_rectangle");
3233     }
3234
3235     /* EXT Extensions */
3236
3237     register_extension(&WGL_EXT_extensions_string);
3238
3239     /* Load this extension even when it isn't backed by a GLX extension because it is has been around for ages.
3240      * Games like Call of Duty and K.O.T.O.R. rely on it. Further our emulation is good enough. */
3241     register_extension(&WGL_EXT_swap_control);
3242
3243     /* The OpenGL extension GL_NV_vertex_array_range adds wgl/glX functions which aren't exported as 'real' wgl/glX extensions. */
3244     if(strstr(WineGLInfo.glExtensions, "GL_NV_vertex_array_range") != NULL)
3245         register_extension(&WGL_NV_vertex_array_range);
3246 }
3247
3248
3249 static XID create_glxpixmap(X11DRV_PDEVICE *physDev)
3250 {
3251     GLXPixmap ret;
3252     XVisualInfo *vis;
3253     XVisualInfo template;
3254     int num;
3255
3256     wine_tsx11_lock();
3257
3258     /* Retrieve the visualid from our main visual which is the only visual we can use */
3259     template.visualid =  XVisualIDFromVisual(visual);
3260     vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num);
3261
3262     ret = pglXCreateGLXPixmap(gdi_display, vis, physDev->bitmap->pixmap);
3263     XFree(vis);
3264     wine_tsx11_unlock(); 
3265     TRACE("return %lx\n", ret);
3266     return ret;
3267 }
3268
3269 Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
3270 {
3271     Drawable ret;
3272
3273     if(physDev->bitmap)
3274     {
3275         if (physDev->bitmap->hbitmap == BITMAP_stock_phys_bitmap.hbitmap)
3276             ret = physDev->drawable; /* PBuffer */
3277         else
3278         {
3279             if(!physDev->bitmap->glxpixmap)
3280                 physDev->bitmap->glxpixmap = create_glxpixmap(physDev);
3281             ret = physDev->bitmap->glxpixmap;
3282         }
3283     }
3284     else
3285         ret = physDev->drawable;
3286     return ret;
3287 }
3288
3289 BOOL destroy_glxpixmap(XID glxpixmap)
3290 {
3291     wine_tsx11_lock(); 
3292     pglXDestroyGLXPixmap(gdi_display, glxpixmap);
3293     wine_tsx11_unlock(); 
3294     return TRUE;
3295 }
3296
3297 /**
3298  * X11DRV_SwapBuffers
3299  *
3300  * Swap the buffers of this DC
3301  */
3302 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev)
3303 {
3304   GLXDrawable drawable;
3305   if (!has_opengl()) {
3306     ERR("No libGL on this box - disabling OpenGL support !\n");
3307     return 0;
3308   }
3309   
3310   TRACE_(opengl)("(%p)\n", physDev);
3311
3312   drawable = get_glxdrawable(physDev);
3313   wine_tsx11_lock();
3314   pglXSwapBuffers(gdi_display, drawable);
3315   wine_tsx11_unlock();
3316
3317   /* FPS support */
3318   if (TRACE_ON(fps))
3319   {
3320       static long prev_time, frames;
3321
3322       DWORD time = GetTickCount();
3323       frames++;
3324       /* every 1.5 seconds */
3325       if (time - prev_time > 1500) {
3326           TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
3327           prev_time = time;
3328           frames = 0;
3329       }
3330   }
3331
3332   return TRUE;
3333 }
3334
3335 /***********************************************************************
3336  *              X11DRV_setup_opengl_visual
3337  *
3338  * Setup the default visual used for OpenGL and Direct3D, and the desktop
3339  * window (if it exists).  If OpenGL isn't available, the visual is simply
3340  * set to the default visual for the display
3341  */
3342 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
3343 {
3344     XVisualInfo *visual = NULL;
3345     int i;
3346
3347     /* In order to support OpenGL or D3D, we require a double-buffered visual and stencil buffer support,
3348      * D3D and some applications can make use of aux buffers.
3349      */
3350     int visualProperties[][11] = {
3351         { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_AUX_BUFFERS, 1, None },
3352         { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_ALPHA_SIZE, 8, None },
3353         { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, None },
3354         { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, None },
3355     };
3356
3357     if (!has_opengl())
3358         return NULL;
3359
3360     wine_tsx11_lock();
3361     for (i = 0; i < sizeof(visualProperties)/sizeof(visualProperties[0]); ++i) {
3362         visual = pglXChooseVisual(display, DefaultScreen(display), visualProperties[i]);
3363         if (visual)
3364             break;
3365     }
3366     wine_tsx11_unlock();
3367
3368     if (visual)
3369         TRACE("Visual ID %lx Chosen\n", visual->visualid);
3370     else
3371         WARN("No suitable visual found\n");
3372
3373     return visual;
3374 }
3375
3376 #else  /* no OpenGL includes */
3377
3378 int pixelformat_from_fbconfig_id(XID fbconfig_id)
3379 {
3380     return 0;
3381 }
3382
3383 /***********************************************************************
3384  *              ChoosePixelFormat (X11DRV.@)
3385  */
3386 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
3387                              const PIXELFORMATDESCRIPTOR *ppfd) {
3388   ERR("No OpenGL support compiled in.\n");
3389
3390   return 0;
3391 }
3392
3393 /***********************************************************************
3394  *              DescribePixelFormat (X11DRV.@)
3395  */
3396 int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
3397                                int iPixelFormat,
3398                                UINT nBytes,
3399                                PIXELFORMATDESCRIPTOR *ppfd) {
3400   ERR("No OpenGL support compiled in.\n");
3401
3402   return 0;
3403 }
3404
3405 /***********************************************************************
3406  *              GetPixelFormat (X11DRV.@)
3407  */
3408 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
3409   ERR("No OpenGL support compiled in.\n");
3410
3411   return 0;
3412 }
3413
3414 /***********************************************************************
3415  *              SetPixelFormat (X11DRV.@)
3416  */
3417 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
3418                            int iPixelFormat,
3419                            const PIXELFORMATDESCRIPTOR *ppfd) {
3420   ERR("No OpenGL support compiled in.\n");
3421
3422   return FALSE;
3423 }
3424
3425 /***********************************************************************
3426  *              SwapBuffers (X11DRV.@)
3427  */
3428 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) {
3429   ERR_(opengl)("No OpenGL support compiled in.\n");
3430
3431   return FALSE;
3432 }
3433
3434 /**
3435  * X11DRV_wglCreateContext
3436  *
3437  * For OpenGL32 wglCreateContext.
3438  */
3439 HGLRC X11DRV_wglCreateContext(X11DRV_PDEVICE *physDev) {
3440     ERR_(opengl)("No OpenGL support compiled in.\n");
3441     return NULL;
3442 }
3443
3444 /**
3445  * X11DRV_wglDeleteContext
3446  *
3447  * For OpenGL32 wglDeleteContext.
3448  */
3449 BOOL X11DRV_wglDeleteContext(HGLRC hglrc) {
3450     ERR_(opengl)("No OpenGL support compiled in.\n");
3451     return FALSE;
3452 }
3453
3454 /**
3455  * X11DRV_wglGetProcAddress
3456  *
3457  * For OpenGL32 wglGetProcAddress.
3458  */
3459 PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc) {
3460     ERR_(opengl)("No OpenGL support compiled in.\n");
3461     return NULL;
3462 }
3463
3464 HDC X11DRV_wglGetPbufferDCARB(X11DRV_PDEVICE *hDevice, void *hPbuffer)
3465 {
3466     ERR_(opengl)("No OpenGL support compiled in.\n");
3467     return NULL;
3468 }
3469
3470 BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* hDrawDev, X11DRV_PDEVICE* hReadDev, HGLRC hglrc) {
3471     ERR_(opengl)("No OpenGL support compiled in.\n");
3472     return FALSE;
3473 }
3474
3475 /**
3476  * X11DRV_wglMakeCurrent
3477  *
3478  * For OpenGL32 wglMakeCurrent.
3479  */
3480 BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
3481     ERR_(opengl)("No OpenGL support compiled in.\n");
3482     return FALSE;
3483 }
3484
3485 /**
3486  * X11DRV_wglShareLists
3487  *
3488  * For OpenGL32 wglShaderLists.
3489  */
3490 BOOL X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
3491     ERR_(opengl)("No OpenGL support compiled in.\n");
3492     return FALSE;
3493 }
3494
3495 /**
3496  * X11DRV_wglUseFontBitmapsA
3497  *
3498  * For OpenGL32 wglUseFontBitmapsA.
3499  */
3500 BOOL X11DRV_wglUseFontBitmapsA(X11DRV_PDEVICE *physDev, DWORD first, DWORD count, DWORD listBase)
3501 {
3502     ERR_(opengl)("No OpenGL support compiled in.\n");
3503     return FALSE;
3504 }
3505
3506 /**
3507  * X11DRV_wglUseFontBitmapsW
3508  *
3509  * For OpenGL32 wglUseFontBitmapsW.
3510  */
3511 BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count, DWORD listBase)
3512 {
3513     ERR_(opengl)("No OpenGL support compiled in.\n");
3514     return FALSE;
3515 }
3516
3517 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
3518 {
3519   return NULL;
3520 }
3521
3522 Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
3523 {
3524     return 0;
3525 }
3526
3527 BOOL destroy_glxpixmap(XID glxpixmap)
3528 {
3529     return FALSE;
3530 }
3531
3532 #endif /* defined(HAVE_OPENGL) */