wintrust: Implement SoftpubCleanup.
[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_vis_id, tmp_fmt_id, nCfgs, i;
818     GLXFBConfig* cfgs;
819     GLXFBConfig fbconfig = NULL;
820     VisualID visualid = XVisualIDFromVisual(visual);
821     int nOffscreenFormats = 0;
822
823     /* As mentioned in various parts of the code only the format of the main visual can be used for onscreen rendering.
824     * Next to this format there are also so called offscreen rendering formats (used for pbuffers) which can be supported
825     * because they don't need a visual. Below we use glXGetFBConfigs instead of glXChooseFBConfig to enumerate the fb configurations
826     * because this call lists both types of formats instead of only onscreen ones. */
827     cfgs = pglXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
828     if (NULL == cfgs || 0 == nCfgs) {
829         ERR("glXChooseFBConfig returns NULL\n");
830         if(cfgs != NULL) XFree(cfgs);
831         return FALSE;
832     }
833
834     /* Count the number of offscreen formats to determine the size for our pixelformat list */
835     for(i=0; i<nCfgs; i++) {
836         pglXGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &tmp_vis_id);
837
838         /* We have found Wine's main visual */
839         if(tmp_vis_id == visualid) {
840             pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &fmt_id);
841             fbconfig = cfgs[i];
842         }
843
844         /* We have found an offscreen rendering format :) */
845         if(tmp_vis_id == 0) {
846             nOffscreenFormats++;
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_VISUAL_ID, &tmp_vis_id);
864         pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id);
865
866         /* We have found an offscreen rendering format :) */
867         if(tmp_vis_id == 0) {
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         }
876     }
877
878     if(cfgs != NULL) XFree(cfgs);
879
880     return TRUE;
881 }
882
883 /* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones.
884  * In our WGL implementation we only support a subset of these formats namely the format of
885  * Wine's main visual and offscreen formats (if they are available).
886  * This function converts a WGL format to its corresponding GLX one. It returns a WineGLPixelFormat
887  * and it returns the number of supported WGL formats in fmt_count.
888  */
889 static WineGLPixelFormat* ConvertPixelFormatWGLtoGLX(Display *display, int iPixelFormat, BOOL AllowOffscreen, int *fmt_count)
890 {
891     WineGLPixelFormat *res = NULL;
892
893     /* Init the list of pixel formats when we need it */
894     if(!WineGLPixelFormatListSize)
895         init_formats(display, DefaultScreen(display), visual);
896
897     /* Check if the pixelformat is valid. Note that it is legal to pass an invalid
898      * iPixelFormat in case of probing the number of pixelformats.
899      */
900     if((iPixelFormat > 0) && (iPixelFormat <= WineGLPixelFormatListSize) &&
901        ((WineGLPixelFormatList[iPixelFormat-1].offscreenOnly == FALSE) ||
902         AllowOffscreen)) {
903         res = &WineGLPixelFormatList[iPixelFormat-1];
904         TRACE("Returning FBConfig=%p for iPixelFormat=%d\n", res->fbconfig, iPixelFormat);
905     }
906
907     if(AllowOffscreen)
908         *fmt_count = WineGLPixelFormatListSize;
909     else
910         *fmt_count = WineGLPixelFormatOnScreenSize;
911
912     TRACE("Number of returned pixelformats=%d\n", *fmt_count);
913
914     return res;
915 }
916
917 /* Search our internal pixelformat list for the WGL format corresponding to the given fbconfig */
918 static WineGLPixelFormat* ConvertPixelFormatGLXtoWGL(Display *display, int fmt_id)
919 {
920     int i;
921
922     /* Init the list of pixel formats when we need it */
923     if(!WineGLPixelFormatListSize)
924         init_formats(display, DefaultScreen(display), visual);
925
926     for(i=0; i<WineGLPixelFormatListSize; i++) {
927         if(WineGLPixelFormatList[i].fmt_id == fmt_id) {
928             TRACE("Returning iPixelFormat %d for fmt_id 0x%x\n", WineGLPixelFormatList[i].iPixelFormat, fmt_id);
929             return &WineGLPixelFormatList[i];
930         }
931     }
932     TRACE("No compatible format found for fmt_id 0x%x\n", fmt_id);
933     return NULL;
934 }
935
936 /**
937  * X11DRV_ChoosePixelFormat
938  *
939  * Equivalent to glXChooseVisual.
940  */
941 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev, 
942                              const PIXELFORMATDESCRIPTOR *ppfd) {
943     WineGLPixelFormat *fmt = NULL;
944     int ret = 0;
945     int nPixelFormats;
946     int value = 0;
947     int i = 0;
948     int bestFormat = -1;
949     int bestDBuffer = -1;
950     int bestStereo = -1;
951     int bestColor = -1;
952     int bestAlpha = -1;
953     int bestDepth = -1;
954     int bestStencil = -1;
955     int bestAux = -1;
956     int score;
957
958     if (!has_opengl()) {
959         ERR("No libGL on this box - disabling OpenGL support !\n");
960         return 0;
961     }
962
963     if (TRACE_ON(opengl)) {
964         TRACE("(%p,%p)\n", physDev, ppfd);
965
966         dump_PIXELFORMATDESCRIPTOR((const PIXELFORMATDESCRIPTOR *) ppfd);
967     }
968
969     wine_tsx11_lock();
970     ConvertPixelFormatWGLtoGLX(gdi_display, 0, FALSE /* offscreen */, &nPixelFormats);
971     for(i=0; i<nPixelFormats; i++)
972     {
973         int dwFlags = 0;
974         int iPixelType = 0;
975         int alpha=0, color=0, depth=0, stencil=0, aux=0;
976
977         fmt = ConvertPixelFormatWGLtoGLX(gdi_display, i+1 /* 1-based index */, FALSE /* offscreen */, &value);
978         score = 0;
979
980         /* Pixel type */
981         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RENDER_TYPE, &value);
982         if (value & GLX_RGBA_BIT)
983             iPixelType = PFD_TYPE_RGBA;
984         else
985             iPixelType = PFD_TYPE_COLORINDEX;
986
987         if (ppfd->iPixelType != iPixelType)
988         {
989             TRACE("pixel type mismatch for iPixelFormat=%d\n", i+1);
990             continue;
991         }
992
993         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value);
994         if (value) dwFlags |= PFD_DOUBLEBUFFER;
995         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STEREO, &value);
996         if (value) dwFlags |= PFD_STEREO;
997         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BUFFER_SIZE, &color); /* cColorBits */
998         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ALPHA_SIZE, &alpha); /* cAlphaBits */
999         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DEPTH_SIZE, &depth); /* cDepthBits */
1000         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STENCIL_SIZE, &stencil); /* cStencilBits */
1001         pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_AUX_BUFFERS, &aux); /* cAuxBuffers */
1002
1003         /* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE
1004          * is not very clear on MSDN. They specify that ChoosePixelFormat tries to match pixel formats
1005          * with the flag (PFD_STEREO / PFD_DOUBLEBUFFERING) set. Otherwise it says that it tries to match
1006          * formats without the given flag set.
1007          * A test on Windows using a Radeon 9500pro on WinXP (the driver doesn't support Stereo)
1008          * has indicated that a format without stereo is returned when stereo is unavailable.
1009          * So in case PFD_STEREO is set, formats that support it should have priority above formats
1010          * without. In case PFD_STEREO_DONTCARE is set, stereo is ignored.
1011          *
1012          * To summarize the following is most likely the correct behavior:
1013          * stereo not set -> prefer no-stereo formats, else also accept stereo formats
1014          * stereo set -> prefer stereo formats, else also accept no-stereo formats
1015          * stereo don't care -> it doesn't matter whether we get stereo or not
1016          *
1017          * In Wine we will treat no-stereo the same way as don't care because it makes
1018          * format selection even more complicated and second drivers with Stereo advertise
1019          * each format twice anyway.
1020          */
1021
1022         /* Doublebuffer, see the comments above */
1023         if( !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) ) {
1024             if( ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer) &&
1025                 ((dwFlags & PFD_DOUBLEBUFFER) == (ppfd->dwFlags & PFD_DOUBLEBUFFER)) )
1026             {
1027                 bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1028                 bestStereo = dwFlags & PFD_STEREO;
1029                 bestAlpha = alpha;
1030                 bestColor = color;
1031                 bestDepth = depth;
1032                 bestStencil = stencil;
1033                 bestAux = aux;
1034                 bestFormat = i;
1035                 continue;
1036             }
1037             if(bestDBuffer != -1 && (dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer)
1038                 continue;
1039         }
1040
1041         /* Stereo, see the comments above. */
1042         if( !(ppfd->dwFlags & PFD_STEREO_DONTCARE) ) {
1043             if( ((ppfd->dwFlags & PFD_STEREO) != bestStereo) &&
1044                 ((dwFlags & PFD_STEREO) == (ppfd->dwFlags & PFD_STEREO)) )
1045             {
1046                 bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1047                 bestStereo = dwFlags & PFD_STEREO;
1048                 bestAlpha = alpha;
1049                 bestColor = color;
1050                 bestDepth = depth;
1051                 bestStencil = stencil;
1052                 bestAux = aux;
1053                 bestFormat = i;
1054                 continue;
1055             }
1056             if(bestStereo != -1 && (dwFlags & PFD_STEREO) != bestStereo)
1057                 continue;
1058         }
1059
1060         /* Below we will do a number of checks to select the 'best' pixelformat.
1061          * We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits -> cAuxBuffers.
1062          * The code works by trying to match the most important options as close as possible.
1063          * When a reasonable format is found, we will try to match more options. */
1064
1065         /* Color bits */
1066         if( ((ppfd->cColorBits > bestColor) && (color > bestColor)) ||
1067             ((color >= ppfd->cColorBits) && (color < bestColor)) )
1068         {
1069             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1070             bestStereo = dwFlags & PFD_STEREO;
1071             bestAlpha = alpha;
1072             bestColor = color;
1073             bestDepth = depth;
1074             bestStencil = stencil;
1075             bestAux = aux;
1076             bestFormat = i;
1077             continue;
1078         } else if(bestColor != color) {  /* Do further checks if the format is compatible */
1079             TRACE("color mismatch for iPixelFormat=%d\n", i+1);
1080             continue;
1081         }
1082
1083         /* Alpha bits */
1084         if( ((ppfd->cAlphaBits > bestAlpha) && (alpha > bestAlpha)) ||
1085             ((alpha >= ppfd->cAlphaBits) && (alpha < bestAlpha)) )
1086         {
1087             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1088             bestStereo = dwFlags & PFD_STEREO;
1089             bestAlpha = alpha;
1090             bestColor = color;
1091             bestDepth = depth;
1092             bestStencil = stencil;
1093             bestAux = aux;
1094             bestFormat = i;
1095             continue;
1096         } else if(bestAlpha != alpha) {
1097             TRACE("alpha mismatch for iPixelFormat=%d\n", i+1);
1098             continue;
1099         }
1100
1101         /* Depth bits */
1102         if( ((ppfd->cDepthBits > bestDepth) && (depth > bestDepth)) ||
1103             ((depth >= ppfd->cDepthBits) && (depth < bestDepth)) )
1104         {
1105             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1106             bestStereo = dwFlags & PFD_STEREO;
1107             bestAlpha = alpha;
1108             bestColor = color;
1109             bestDepth = depth;
1110             bestStencil = stencil;
1111             bestAux = aux;
1112             bestFormat = i;
1113             continue;
1114         } else if(bestDepth != depth) {
1115             TRACE("depth mismatch for iPixelFormat=%d\n", i+1);
1116             continue;
1117         }
1118
1119         /* Stencil bits */
1120         if( ((ppfd->cStencilBits > bestStencil) && (stencil > bestStencil)) ||
1121             ((stencil >= ppfd->cStencilBits) && (stencil < bestStencil)) )
1122         {
1123             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1124             bestStereo = dwFlags & PFD_STEREO;
1125             bestAlpha = alpha;
1126             bestColor = color;
1127             bestDepth = depth;
1128             bestStencil = stencil;
1129             bestAux = aux;
1130             bestFormat = i;
1131             continue;
1132         } else if(bestStencil != stencil) {
1133             TRACE("stencil mismatch for iPixelFormat=%d\n", i+1);
1134             continue;
1135         }
1136
1137         /* Aux buffers */
1138         if( ((ppfd->cAuxBuffers > bestAux) && (aux > bestAux)) ||
1139             ((aux >= ppfd->cAuxBuffers) && (aux < bestAux)) )
1140         {
1141             bestDBuffer = dwFlags & PFD_DOUBLEBUFFER;
1142             bestStereo = dwFlags & PFD_STEREO;
1143             bestAlpha = alpha;
1144             bestColor = color;
1145             bestDepth = depth;
1146             bestStencil = stencil;
1147             bestAux = aux;
1148             bestFormat = i;
1149             continue;
1150         } else if(bestAux != aux) {
1151             TRACE("aux mismatch for iPixelFormat=%d\n", i+1);
1152             continue;
1153         }
1154     }
1155
1156     if(bestFormat == -1) {
1157         TRACE("No matching mode was found returning 0\n");
1158         ret = 0;
1159     }
1160     else {
1161         ret = bestFormat+1; /* the return value should be a 1-based index */
1162         TRACE("Successfully found a matching mode, returning index: %d %x\n", ret, WineGLPixelFormatList[bestFormat].fmt_id);
1163     }
1164
1165     wine_tsx11_unlock();
1166
1167     return ret;
1168 }
1169 /**
1170  * X11DRV_DescribePixelFormat
1171  *
1172  * Get the pixel-format descriptor associated to the given id
1173  */
1174 int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
1175                                int iPixelFormat,
1176                                UINT nBytes,
1177                                PIXELFORMATDESCRIPTOR *ppfd) {
1178   /*XVisualInfo *vis;*/
1179   int value;
1180   int rb,gb,bb,ab;
1181   WineGLPixelFormat *fmt;
1182   int ret = 0;
1183   int fmt_count = 0;
1184
1185   if (!has_opengl()) {
1186     ERR("No libGL on this box - disabling OpenGL support !\n");
1187     return 0;
1188   }
1189   
1190   TRACE("(%p,%d,%d,%p)\n", physDev, iPixelFormat, nBytes, ppfd);
1191
1192   /* 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 */
1193   fmt = ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, FALSE /* Offscreen */, &fmt_count);
1194   if (ppfd == NULL) {
1195       /* The application is only querying the number of pixelformats */
1196       return fmt_count;
1197   } else if(fmt == NULL) {
1198       WARN("unexpected iPixelFormat(%d): not >=1 and <=nFormats(%d), returning NULL!\n", iPixelFormat, fmt_count);
1199       return 0;
1200   }
1201
1202   if (nBytes < sizeof(PIXELFORMATDESCRIPTOR)) {
1203     ERR("Wrong structure size !\n");
1204     /* Should set error */
1205     return 0;
1206   }
1207
1208   ret = fmt_count;
1209
1210   memset(ppfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
1211   ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
1212   ppfd->nVersion = 1;
1213
1214   /* These flags are always the same... */
1215   ppfd->dwFlags = PFD_SUPPORT_OPENGL;
1216   /* Now the flags extracted from the Visual */
1217
1218   wine_tsx11_lock();
1219
1220   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_X_RENDERABLE, &value);
1221   if(value)
1222       ppfd->dwFlags |= PFD_SUPPORT_GDI;
1223
1224   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
1225   if(value & GLX_WINDOW_BIT)
1226       ppfd->dwFlags |= PFD_DRAW_TO_WINDOW;
1227   if(value & GLX_PIXMAP_BIT)
1228       ppfd->dwFlags |= PFD_DRAW_TO_BITMAP;
1229
1230   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_CONFIG_CAVEAT, &value);
1231   if(value == GLX_SLOW_CONFIG)
1232       ppfd->dwFlags |= PFD_GENERIC_ACCELERATED;
1233
1234   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value);
1235   if (value) {
1236       ppfd->dwFlags |= PFD_DOUBLEBUFFER;
1237       ppfd->dwFlags &= ~PFD_SUPPORT_GDI;
1238   }
1239   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO;
1240
1241   /* Pixel type */
1242   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RENDER_TYPE, &value);
1243   if (value & GLX_RGBA_BIT)
1244     ppfd->iPixelType = PFD_TYPE_RGBA;
1245   else
1246     ppfd->iPixelType = PFD_TYPE_COLORINDEX;
1247
1248   /* Color bits */
1249   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BUFFER_SIZE, &value);
1250   ppfd->cColorBits = value;
1251
1252   /* Red, green, blue and alpha bits / shifts */
1253   if (ppfd->iPixelType == PFD_TYPE_RGBA) {
1254     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RED_SIZE, &rb);
1255     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_GREEN_SIZE, &gb);
1256     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BLUE_SIZE, &bb);
1257     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ALPHA_SIZE, &ab);
1258
1259     ppfd->cRedBits = rb;
1260     ppfd->cRedShift = gb + bb + ab;
1261     ppfd->cBlueBits = bb;
1262     ppfd->cBlueShift = ab;
1263     ppfd->cGreenBits = gb;
1264     ppfd->cGreenShift = bb + ab;
1265     ppfd->cAlphaBits = ab;
1266     ppfd->cAlphaShift = 0;
1267   } else {
1268     ppfd->cRedBits = 0;
1269     ppfd->cRedShift = 0;
1270     ppfd->cBlueBits = 0;
1271     ppfd->cBlueShift = 0;
1272     ppfd->cGreenBits = 0;
1273     ppfd->cGreenShift = 0;
1274     ppfd->cAlphaBits = 0;
1275     ppfd->cAlphaShift = 0;
1276   }
1277
1278   /* Accum RGBA bits */
1279   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_RED_SIZE, &rb);
1280   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_GREEN_SIZE, &gb);
1281   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_BLUE_SIZE, &bb);
1282   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_ALPHA_SIZE, &ab);
1283
1284   ppfd->cAccumBits = rb+gb+bb+ab;
1285   ppfd->cAccumRedBits = rb;
1286   ppfd->cAccumGreenBits = gb;
1287   ppfd->cAccumBlueBits = bb;
1288   ppfd->cAccumAlphaBits = ab;
1289
1290   /* Depth bits */
1291   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DEPTH_SIZE, &value);
1292   ppfd->cDepthBits = value;
1293
1294   /* stencil bits */
1295   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STENCIL_SIZE, &value);
1296   ppfd->cStencilBits = value;
1297
1298   wine_tsx11_unlock();
1299
1300   /* Aux : to do ... */
1301
1302   ppfd->iLayerType = PFD_MAIN_PLANE;
1303
1304   if (TRACE_ON(opengl)) {
1305     dump_PIXELFORMATDESCRIPTOR(ppfd);
1306   }
1307
1308   return ret;
1309 }
1310
1311 /**
1312  * X11DRV_GetPixelFormat
1313  *
1314  * Get the pixel-format id used by this DC
1315  */
1316 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
1317   WineGLPixelFormat *fmt;
1318   int tmp;
1319   TRACE("(%p)\n", physDev);
1320
1321   fmt = ConvertPixelFormatWGLtoGLX(gdi_display, physDev->current_pf, TRUE, &tmp);
1322   if(!fmt)
1323   {
1324     /* This happens on HDCs on which SetPixelFormat wasn't called yet */
1325     ERR("Unable to find a WineGLPixelFormat for iPixelFormat=%d\n", physDev->current_pf);
1326     return 0;
1327   }
1328   else if(fmt->offscreenOnly)
1329   {
1330     /* Offscreen formats can't be used with traditional WGL calls.
1331      * As has been verified on Windows GetPixelFormat doesn't fail but returns iPixelFormat=1. */
1332      TRACE("Returning iPixelFormat=1 for offscreen format: %d\n", fmt->iPixelFormat);
1333     return 1;
1334   }
1335
1336   TRACE("(%p): returns %d\n", physDev, physDev->current_pf);
1337   return physDev->current_pf;
1338 }
1339
1340 /**
1341  * X11DRV_SetPixelFormat
1342  *
1343  * Set the pixel-format id used by this DC
1344  */
1345 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
1346                            int iPixelFormat,
1347                            const PIXELFORMATDESCRIPTOR *ppfd) {
1348   WineGLPixelFormat *fmt;
1349   int value;
1350
1351   TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
1352
1353   if (!has_opengl()) {
1354     ERR("No libGL on this box - disabling OpenGL support !\n");
1355     return 0;
1356   }
1357
1358   /* SetPixelFormat is not allowed on the X root_window e.g. GetDC(0) */
1359   if(get_glxdrawable(physDev) == root_window)
1360   {
1361     ERR("Invalid operation on root_window\n");
1362     return 0;
1363   }
1364
1365   /* Check if iPixelFormat is in our list of supported formats to see if it is supported. */
1366   fmt = ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, FALSE /* Offscreen */, &value);
1367   if(!fmt) {
1368     ERR("Invalid iPixelFormat: %d\n", iPixelFormat);
1369     return 0;
1370   }
1371
1372   physDev->current_pf = iPixelFormat;
1373
1374   if (TRACE_ON(opengl)) {
1375     int gl_test = 0;
1376
1377     gl_test = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_FBCONFIG_ID, &value);
1378     if (gl_test) {
1379       ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
1380     } else {
1381       TRACE(" FBConfig have :\n");
1382       TRACE(" - FBCONFIG_ID   0x%x\n", value);
1383       pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_VISUAL_ID, &value);
1384       TRACE(" - VISUAL_ID     0x%x\n", value);
1385       pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
1386       TRACE(" - DRAWABLE_TYPE 0x%x\n", value);
1387     }
1388   }
1389   return TRUE;
1390 }
1391
1392 /**
1393  * X11DRV_wglCreateContext
1394  *
1395  * For OpenGL32 wglCreateContext.
1396  */
1397 HGLRC X11DRV_wglCreateContext(X11DRV_PDEVICE *physDev)
1398 {
1399     Wine_GLContext *ret;
1400     WineGLPixelFormat *fmt;
1401     int hdcPF = physDev->current_pf;
1402     int fmt_count = 0;
1403     HDC hdc = physDev->hdc;
1404
1405     TRACE("(%p)->(PF:%d)\n", hdc, hdcPF);
1406
1407     if (!has_opengl()) {
1408         ERR("No libGL on this box - disabling OpenGL support !\n");
1409         return 0;
1410     }
1411
1412     fmt = ConvertPixelFormatWGLtoGLX(gdi_display, hdcPF, TRUE /* Offscreen */, &fmt_count);
1413     /* We can render using the iPixelFormat (1) of Wine's Main visual AND using some offscreen formats.
1414      * Note that standard WGL-calls don't recognize offscreen-only formats. For that reason pbuffers
1415      * use a sort of 'proxy' HDC (wglGetPbufferDCARB).
1416      * If this fails something is very wrong on the system. */
1417     if(!fmt) {
1418         ERR("Cannot get FB Config for iPixelFormat %d, expect problems!\n", hdcPF);
1419         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
1420         return NULL;
1421     }
1422
1423     /* The context will be allocated in the wglMakeCurrent call */
1424     wine_tsx11_lock();
1425     ret = alloc_context();
1426     wine_tsx11_unlock();
1427     ret->hdc = hdc;
1428     ret->physDev = physDev;
1429     ret->fmt = fmt;
1430
1431     /*ret->vis = vis;*/
1432     ret->vis = pglXGetVisualFromFBConfig(gdi_display, fmt->fbconfig);
1433
1434     TRACE(" creating context %p (GL context creation delayed)\n", ret);
1435     return (HGLRC) ret;
1436 }
1437
1438 /**
1439  * X11DRV_wglDeleteContext
1440  *
1441  * For OpenGL32 wglDeleteContext.
1442  */
1443 BOOL X11DRV_wglDeleteContext(HGLRC hglrc)
1444 {
1445     Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
1446     BOOL ret = TRUE;
1447
1448     TRACE("(%p)\n", hglrc);
1449
1450     if (!has_opengl()) {
1451         ERR("No libGL on this box - disabling OpenGL support !\n");
1452         return 0;
1453     }
1454
1455     wine_tsx11_lock();
1456     /* A game (Half Life not to name it) deletes twice the same context,
1457     * so make sure it is valid first */
1458     if (is_valid_context( ctx ))
1459     {
1460         if (ctx->ctx) pglXDestroyContext(gdi_display, ctx->ctx);
1461         free_context(ctx);
1462     }
1463     else
1464     {
1465         WARN("Error deleting context !\n");
1466         SetLastError(ERROR_INVALID_HANDLE);
1467         ret = FALSE;
1468     }
1469     wine_tsx11_unlock();
1470
1471     return ret;
1472 }
1473
1474 /**
1475  * X11DRV_wglGetCurrentReadDCARB
1476  *
1477  * For OpenGL32 wglGetCurrentReadDCARB.
1478  */
1479 static HDC WINAPI X11DRV_wglGetCurrentReadDCARB(void) 
1480 {
1481     HDC ret = 0;
1482     Wine_GLContext *ctx = NtCurrentTeb()->glContext;
1483     X11DRV_PDEVICE *physDev = ctx ? ctx->pReadDev : NULL;
1484
1485     if(physDev)
1486         ret = physDev->hdc;
1487
1488     TRACE(" returning %p (GL drawable %lu)\n", ret, physDev ? physDev->drawable : 0);
1489     return ret;
1490 }
1491
1492 /**
1493  * X11DRV_wglGetProcAddress
1494  *
1495  * For OpenGL32 wglGetProcAddress.
1496  */
1497 PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc)
1498 {
1499     int i, j;
1500     const WineGLExtension *ext;
1501
1502     int padding = 32 - strlen(lpszProc);
1503     if (padding < 0)
1504         padding = 0;
1505
1506     if (!has_opengl()) {
1507         ERR("No libGL on this box - disabling OpenGL support !\n");
1508         return 0;
1509     }
1510
1511     /* Check the table of WGL extensions to see if we need to return a WGL extension
1512      * or a function pointer to a native OpenGL function. */
1513     if(strncmp(lpszProc, "wgl", 3) != 0) {
1514         return pglXGetProcAddressARB((const GLubyte*)lpszProc);
1515     } else {
1516         TRACE("('%s'):%*s", lpszProc, padding, " ");
1517         for (i = 0; i < WineGLExtensionListSize; ++i) {
1518             ext = WineGLExtensionList[i];
1519             for (j = 0; ext->extEntryPoints[j].funcName; ++j) {
1520                 if (strcmp(ext->extEntryPoints[j].funcName, lpszProc) == 0) {
1521                     TRACE("(%p) - WineGL\n", ext->extEntryPoints[j].funcAddress);
1522                     return ext->extEntryPoints[j].funcAddress;
1523                 }
1524             }
1525         }
1526     }
1527
1528     WARN("(%s) - not found\n", lpszProc);
1529     return NULL;
1530 }
1531
1532 /***********************************************************************
1533  *              sync_current_drawable
1534  *
1535  * Adjust the current viewport and scissor in order to position
1536  * and size the current drawable correctly on the parent window.
1537  */
1538 static void sync_current_drawable(BOOL updatedc)
1539 {
1540     int dy;
1541     int width;
1542     int height;
1543     RECT rc;
1544     Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
1545
1546     TRACE("\n");
1547
1548     if (ctx && ctx->physDev)
1549     {
1550         if (updatedc)
1551             GetClipBox(ctx->physDev->hdc, &rc); /* Make sure physDev is up to date */
1552
1553         dy = ctx->physDev->drawable_rect.bottom - ctx->physDev->drawable_rect.top -
1554             ctx->physDev->dc_rect.bottom;
1555         width = ctx->physDev->dc_rect.right - ctx->physDev->dc_rect.left;
1556         height = ctx->physDev->dc_rect.bottom - ctx->physDev->dc_rect.top;
1557
1558         wine_tsx11_lock();
1559
1560         pglViewport(ctx->physDev->dc_rect.left + ctx->viewport.left,
1561             dy + ctx->viewport.top,
1562             ctx->viewport.right ? (ctx->viewport.right - ctx->viewport.left) : width,
1563             ctx->viewport.bottom ? (ctx->viewport.bottom - ctx->viewport.top) : height);
1564
1565         pglEnable(GL_SCISSOR_TEST);
1566
1567         if (ctx->scissor_enabled)
1568             pglScissor(ctx->physDev->dc_rect.left + min(width, max(0, ctx->scissor.left)),
1569                 dy + min(height, max(0, ctx->scissor.top)),
1570                 min(width, max(0, ctx->scissor.right - ctx->scissor.left)),
1571                 min(height, max(0, ctx->scissor.bottom - ctx->scissor.top)));
1572         else
1573             pglScissor(ctx->physDev->dc_rect.left, dy, width, height);
1574
1575         wine_tsx11_unlock();
1576     }
1577 }
1578
1579 /**
1580  * X11DRV_wglMakeCurrent
1581  *
1582  * For OpenGL32 wglMakeCurrent.
1583  */
1584 BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
1585     BOOL ret;
1586     HDC hdc = physDev->hdc;
1587     DWORD type = GetObjectType(hdc);
1588
1589     TRACE("(%p,%p)\n", hdc, hglrc);
1590
1591     if (!has_opengl()) {
1592         ERR("No libGL on this box - disabling OpenGL support !\n");
1593         return 0;
1594     }
1595
1596     wine_tsx11_lock();
1597     if (hglrc == NULL) {
1598         ret = pglXMakeCurrent(gdi_display, None, NULL);
1599         NtCurrentTeb()->glContext = NULL;
1600     } else {
1601         Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
1602         Drawable drawable = get_glxdrawable(physDev);
1603         if (ctx->ctx == NULL) {
1604             /* The describe lines below are for debugging purposes only */
1605             if (TRACE_ON(wgl)) {
1606                 describeDrawable(ctx, drawable);
1607                 describeContext(ctx);
1608             }
1609
1610             /* Create a GLX context using the same visual as chosen earlier in wglCreateContext.
1611              * We are certain that the drawable and context are compatible as we only allow compatible formats.
1612              */
1613             TRACE(" Creating GLX Context\n");
1614             if(ctx->vis)
1615                 ctx->ctx = pglXCreateContext(gdi_display, ctx->vis, NULL, type == OBJ_MEMDC ? False : True);
1616             else /* Create a GLX Context for a pbuffer */
1617                 ctx->ctx = pglXCreateNewContext(gdi_display, ctx->fmt->fbconfig, ctx->fmt->render_type, NULL, True);
1618
1619             TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
1620         }
1621         TRACE(" make current for dis %p, drawable %p, ctx %p\n", gdi_display, (void*) drawable, ctx->ctx);
1622         ret = pglXMakeCurrent(gdi_display, drawable, ctx->ctx);
1623         NtCurrentTeb()->glContext = ctx;
1624         if(ret)
1625         {
1626             ctx->hdc = hdc;
1627             ctx->physDev = physDev;
1628             ctx->pReadDev = physDev;
1629
1630             if (type == OBJ_MEMDC)
1631             {
1632                 ctx->do_escape = TRUE;
1633                 pglDrawBuffer(GL_FRONT_LEFT);
1634             }
1635             else
1636             {
1637                 sync_current_drawable(FALSE);
1638             }
1639         }
1640     }
1641     wine_tsx11_unlock();
1642     TRACE(" returning %s\n", (ret ? "True" : "False"));
1643     return ret;
1644 }
1645
1646 /**
1647  * X11DRV_wglMakeContextCurrentARB
1648  *
1649  * For OpenGL32 wglMakeContextCurrentARB
1650  */
1651 BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* pDrawDev, X11DRV_PDEVICE* pReadDev, HGLRC hglrc)
1652 {
1653     BOOL ret;
1654     TRACE("(%p,%p,%p)\n", pDrawDev, pReadDev, hglrc);
1655
1656     if (!has_opengl()) {
1657         ERR("No libGL on this box - disabling OpenGL support !\n");
1658         return 0;
1659     }
1660
1661     wine_tsx11_lock();
1662     if (hglrc == NULL) {
1663         ret = pglXMakeCurrent(gdi_display, None, NULL);
1664         NtCurrentTeb()->glContext = NULL;
1665     } else {
1666         if (NULL == pglXMakeContextCurrent) {
1667             ret = FALSE;
1668         } else {
1669             Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
1670             Drawable d_draw = get_glxdrawable(pDrawDev);
1671             Drawable d_read = get_glxdrawable(pReadDev);
1672
1673             if (ctx->ctx == NULL) {
1674                 ctx->ctx = pglXCreateContext(gdi_display, ctx->vis, NULL, GetObjectType(pDrawDev->hdc) == OBJ_MEMDC ? False : True);
1675                 TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
1676             }
1677             ctx->hdc = pDrawDev->hdc;
1678             ctx->physDev = pDrawDev;
1679             ctx->pReadDev = pReadDev;
1680             ret = pglXMakeContextCurrent(gdi_display, d_draw, d_read, ctx->ctx);
1681             NtCurrentTeb()->glContext = ctx;
1682         }
1683     }
1684     wine_tsx11_unlock();
1685
1686     TRACE(" returning %s\n", (ret ? "True" : "False"));
1687     return ret;
1688 }
1689
1690 /**
1691  * X11DRV_wglShareLists
1692  *
1693  * For OpenGL32 wglShaderLists.
1694  */
1695 BOOL X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
1696     Wine_GLContext *org  = (Wine_GLContext *) hglrc1;
1697     Wine_GLContext *dest = (Wine_GLContext *) hglrc2;
1698
1699     TRACE("(%p, %p)\n", org, dest);
1700
1701     if (!has_opengl()) {
1702         ERR("No libGL on this box - disabling OpenGL support !\n");
1703         return 0;
1704     }
1705
1706     if (NULL != dest && dest->ctx != NULL) {
1707         ERR("Could not share display lists, context already created !\n");
1708         return FALSE;
1709     } else {
1710         if (org->ctx == NULL) {
1711             wine_tsx11_lock();
1712             describeContext(org);
1713
1714             if(org->vis)
1715                 org->ctx = pglXCreateContext(gdi_display, org->vis, NULL, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
1716             else /* Create a GLX Context for a pbuffer */
1717                 org->ctx = pglXCreateNewContext(gdi_display, org->fmt->fbconfig, org->fmt->render_type, NULL, True);
1718             wine_tsx11_unlock();
1719             TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org);
1720         }
1721         if (NULL != dest) {
1722             wine_tsx11_lock();
1723             describeContext(dest);
1724             /* Create the destination context with display lists shared */
1725             if(dest->vis)
1726                 dest->ctx = pglXCreateContext(gdi_display, dest->vis, org->ctx, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
1727             else /* Create a GLX Context for a pbuffer */
1728                 dest->ctx = pglXCreateNewContext(gdi_display, dest->fmt->fbconfig, dest->fmt->render_type, org->ctx, True);
1729             wine_tsx11_unlock();
1730             TRACE(" created a delayed OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx);
1731             return TRUE;
1732         }
1733     }
1734     return FALSE;
1735 }
1736
1737 static BOOL internal_wglUseFontBitmaps(HDC hdc, DWORD first, DWORD count, DWORD listBase, DWORD (WINAPI *GetGlyphOutline_ptr)(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,LPVOID,const MAT2*))
1738 {
1739      /* We are running using client-side rendering fonts... */
1740      GLYPHMETRICS gm;
1741      unsigned int glyph;
1742      int size = 0;
1743      void *bitmap = NULL, *gl_bitmap = NULL;
1744      int org_alignment;
1745
1746      wine_tsx11_lock();
1747      pglGetIntegerv(GL_UNPACK_ALIGNMENT, &org_alignment);
1748      pglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1749      wine_tsx11_unlock();
1750
1751      for (glyph = first; glyph < first + count; glyph++) {
1752          unsigned int needed_size = GetGlyphOutline_ptr(hdc, glyph, GGO_BITMAP, &gm, 0, NULL, NULL);
1753          int height, width_int;
1754
1755          TRACE("Glyph : %3d / List : %d\n", glyph, listBase);
1756          if (needed_size == GDI_ERROR) {
1757              TRACE("  - needed size : %d (GDI_ERROR)\n", needed_size);
1758              goto error;
1759          } else {
1760              TRACE("  - needed size : %d\n", needed_size);
1761          }
1762
1763          if (needed_size > size) {
1764              size = needed_size;
1765              HeapFree(GetProcessHeap(), 0, bitmap);
1766              HeapFree(GetProcessHeap(), 0, gl_bitmap);
1767              bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
1768              gl_bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
1769          }
1770          if (GetGlyphOutline_ptr(hdc, glyph, GGO_BITMAP, &gm, size, bitmap, NULL) == GDI_ERROR) goto error;
1771          if (TRACE_ON(opengl)) {
1772              unsigned int height, width, bitmask;
1773              unsigned char *bitmap_ = (unsigned char *) bitmap;
1774
1775              TRACE("  - bbox : %d x %d\n", gm.gmBlackBoxX, gm.gmBlackBoxY);
1776              TRACE("  - origin : (%d , %d)\n", gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y);
1777              TRACE("  - increment : %d - %d\n", gm.gmCellIncX, gm.gmCellIncY);
1778              if (needed_size != 0) {
1779                  TRACE("  - bitmap :\n");
1780                  for (height = 0; height < gm.gmBlackBoxY; height++) {
1781                      TRACE("      ");
1782                      for (width = 0, bitmask = 0x80; width < gm.gmBlackBoxX; width++, bitmask >>= 1) {
1783                          if (bitmask == 0) {
1784                              bitmap_ += 1;
1785                              bitmask = 0x80;
1786                          }
1787                          if (*bitmap_ & bitmask)
1788                              TRACE("*");
1789                          else
1790                              TRACE(" ");
1791                      }
1792                      bitmap_ += (4 - ((UINT_PTR)bitmap_ & 0x03));
1793                      TRACE("\n");
1794                  }
1795              }
1796          }
1797
1798          /* In OpenGL, the bitmap is drawn from the bottom to the top... So we need to invert the
1799          * glyph for it to be drawn properly.
1800          */
1801          if (needed_size != 0) {
1802              width_int = (gm.gmBlackBoxX + 31) / 32;
1803              for (height = 0; height < gm.gmBlackBoxY; height++) {
1804                  int width;
1805                  for (width = 0; width < width_int; width++) {
1806                      ((int *) gl_bitmap)[(gm.gmBlackBoxY - height - 1) * width_int + width] =
1807                      ((int *) bitmap)[height * width_int + width];
1808                  }
1809              }
1810          }
1811
1812          wine_tsx11_lock();
1813          pglNewList(listBase++, GL_COMPILE);
1814          if (needed_size != 0) {
1815              pglBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY,
1816                      0 - (int) gm.gmptGlyphOrigin.x, (int) gm.gmBlackBoxY - (int) gm.gmptGlyphOrigin.y,
1817                      gm.gmCellIncX, gm.gmCellIncY,
1818                      gl_bitmap);
1819          } else {
1820              /* This is the case of 'empty' glyphs like the space character */
1821              pglBitmap(0, 0, 0, 0, gm.gmCellIncX, gm.gmCellIncY, NULL);
1822          }
1823          pglEndList();
1824          wine_tsx11_unlock();
1825      }
1826
1827      wine_tsx11_lock();
1828      pglPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
1829      wine_tsx11_unlock();
1830
1831      HeapFree(GetProcessHeap(), 0, bitmap);
1832      HeapFree(GetProcessHeap(), 0, gl_bitmap);
1833      return TRUE;
1834
1835   error:
1836      wine_tsx11_lock();
1837      pglPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment);
1838      wine_tsx11_unlock();
1839
1840      HeapFree(GetProcessHeap(), 0, bitmap);
1841      HeapFree(GetProcessHeap(), 0, gl_bitmap);
1842      return FALSE;
1843 }
1844
1845 /**
1846  * X11DRV_wglUseFontBitmapsA
1847  *
1848  * For OpenGL32 wglUseFontBitmapsA.
1849  */
1850 BOOL X11DRV_wglUseFontBitmapsA(X11DRV_PDEVICE *physDev, DWORD first, DWORD count, DWORD listBase)
1851 {
1852      Font fid = physDev->font;
1853
1854      TRACE("(%p, %d, %d, %d) using font %ld\n", physDev->hdc, first, count, listBase, fid);
1855
1856      if (!has_opengl()) {
1857         ERR("No libGL on this box - disabling OpenGL support !\n");
1858         return 0;
1859      }
1860
1861      if (fid == 0) {
1862          return internal_wglUseFontBitmaps(physDev->hdc, first, count, listBase, GetGlyphOutlineA);
1863      }
1864
1865      wine_tsx11_lock();
1866      /* I assume that the glyphs are at the same position for X and for Windows */
1867      pglXUseXFont(fid, first, count, listBase);
1868      wine_tsx11_unlock();
1869      return TRUE;
1870 }
1871
1872 /**
1873  * X11DRV_wglUseFontBitmapsW
1874  *
1875  * For OpenGL32 wglUseFontBitmapsW.
1876  */
1877 BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count, DWORD listBase)
1878 {
1879      Font fid = physDev->font;
1880
1881      TRACE("(%p, %d, %d, %d) using font %ld\n", physDev->hdc, first, count, listBase, fid);
1882
1883      if (!has_opengl()) {
1884         ERR("No libGL on this box - disabling OpenGL support !\n");
1885         return 0;
1886      }
1887
1888      if (fid == 0) {
1889          return internal_wglUseFontBitmaps(physDev->hdc, first, count, listBase, GetGlyphOutlineW);
1890      }
1891
1892      WARN("Using the glX API for the WCHAR variant - some characters may come out incorrectly !\n");
1893
1894      wine_tsx11_lock();
1895      /* I assume that the glyphs are at the same position for X and for Windows */
1896      pglXUseXFont(fid, first, count, listBase);
1897      wine_tsx11_unlock();
1898      return TRUE;
1899 }
1900
1901 static void WINAPI X11DRV_wglDisable(GLenum cap)
1902 {
1903     if (cap == GL_SCISSOR_TEST)
1904     {
1905        Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
1906
1907        if (ctx)
1908           ctx->scissor_enabled = FALSE;
1909     }
1910     else
1911     {
1912         wine_tsx11_lock();
1913         pglDisable(cap);
1914         wine_tsx11_unlock();
1915     }
1916 }
1917
1918 static void WINAPI X11DRV_wglEnable(GLenum cap)
1919 {
1920     if (cap == GL_SCISSOR_TEST)
1921     {
1922        Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
1923
1924        if (ctx)
1925            ctx->scissor_enabled = TRUE;
1926     }
1927     else
1928     {
1929         wine_tsx11_lock();
1930         pglEnable(cap);
1931         wine_tsx11_unlock();
1932     }
1933 }
1934
1935 /* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */
1936 static void WINAPI X11DRV_wglGetIntegerv(GLenum pname, GLint* params)
1937 {
1938     wine_tsx11_lock();
1939     switch(pname)
1940     {
1941     case GL_DEPTH_BITS:
1942         {
1943             Wine_GLContext *ctx = NtCurrentTeb()->glContext;
1944
1945             pglGetIntegerv(pname, params);
1946             /**
1947              * if we cannot find a Wine Context
1948              * we only have the default wine desktop context,
1949              * so if we have only a 24 depth say we have 32
1950              */
1951             if (!ctx && *params == 24) {
1952                 *params = 32;
1953             }
1954             TRACE("returns GL_DEPTH_BITS as '%d'\n", *params);
1955             break;
1956         }
1957     case GL_ALPHA_BITS:
1958         {
1959             Wine_GLContext *ctx = NtCurrentTeb()->glContext;
1960
1961             pglXGetFBConfigAttrib(gdi_display, ctx->fmt->fbconfig, GLX_ALPHA_SIZE, params);
1962             TRACE("returns GL_ALPHA_BITS as '%d'\n", *params);
1963             break;
1964         }
1965     default:
1966         pglGetIntegerv(pname, params);
1967         break;
1968     }
1969     wine_tsx11_unlock();
1970 }
1971
1972 static GLboolean WINAPI X11DRV_wglIsEnabled(GLenum cap)
1973 {
1974     GLboolean enabled = False;
1975
1976     if (cap == GL_SCISSOR_TEST)
1977     {
1978        Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
1979
1980        if (ctx)
1981            enabled = ctx->scissor_enabled;
1982     }
1983     else
1984     {
1985         wine_tsx11_lock();
1986         enabled = pglIsEnabled(cap);
1987         wine_tsx11_unlock();
1988     }
1989     return enabled;
1990 }
1991
1992 static void WINAPI X11DRV_wglScissor(GLint x, GLint y, GLsizei width, GLsizei height)
1993 {
1994     Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
1995
1996     if (ctx)
1997     {
1998         ctx->scissor.left = x;
1999         ctx->scissor.top = y;
2000         ctx->scissor.right = x + width;
2001         ctx->scissor.bottom = y + height;
2002
2003         sync_current_drawable(TRUE);
2004     }
2005 }
2006
2007 static void WINAPI X11DRV_wglViewport(GLint x, GLint y, GLsizei width, GLsizei height)
2008 {
2009     Wine_GLContext *ctx = (Wine_GLContext *) NtCurrentTeb()->glContext;
2010
2011     if (ctx)
2012     {
2013         ctx->viewport.left = x;
2014         ctx->viewport.top = y;
2015         ctx->viewport.right = x + width;
2016         ctx->viewport.bottom = y + height;
2017
2018         sync_current_drawable(TRUE);
2019     }
2020 }
2021
2022 /**
2023  * X11DRV_wglGetExtensionsStringARB
2024  *
2025  * WGL_ARB_extensions_string: wglGetExtensionsStringARB
2026  */
2027 static const char * WINAPI X11DRV_wglGetExtensionsStringARB(HDC hdc) {
2028     TRACE("() returning \"%s\"\n", WineGLInfo.wglExtensions);
2029     return WineGLInfo.wglExtensions;
2030 }
2031
2032 /**
2033  * X11DRV_wglCreatePbufferARB
2034  *
2035  * WGL_ARB_pbuffer: wglCreatePbufferARB
2036  */
2037 static HPBUFFERARB WINAPI X11DRV_wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList)
2038 {
2039     Wine_GLPBuffer* object = NULL;
2040     WineGLPixelFormat *fmt = NULL;
2041     int nCfgs = 0;
2042     int attribs[256];
2043     int nAttribs = 0;
2044
2045     TRACE("(%p, %d, %d, %d, %p)\n", hdc, iPixelFormat, iWidth, iHeight, piAttribList);
2046
2047     if (0 >= iPixelFormat) {
2048         ERR("(%p): unexpected iPixelFormat(%d) <= 0, returns NULL\n", hdc, iPixelFormat);
2049         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2050         return NULL; /* unexpected error */
2051     }
2052
2053     /* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */
2054     fmt = ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, TRUE /* Offscreen */, &nCfgs);
2055     if(!fmt) {
2056         ERR("(%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, iPixelFormat, nCfgs);
2057         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2058         goto create_failed; /* unexpected error */
2059     }
2060
2061     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLPBuffer));
2062     if (NULL == object) {
2063         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
2064         goto create_failed; /* unexpected error */
2065     }
2066     object->hdc = hdc;
2067     object->display = gdi_display;
2068     object->width = iWidth;
2069     object->height = iHeight;
2070     object->fmt = fmt;
2071
2072     PUSH2(attribs, GLX_PBUFFER_WIDTH,  iWidth);
2073     PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight); 
2074     while (piAttribList && 0 != *piAttribList) {
2075         int attr_v;
2076         switch (*piAttribList) {
2077             case WGL_PBUFFER_LARGEST_ARB: {
2078                 ++piAttribList;
2079                 attr_v = *piAttribList;
2080                 TRACE("WGL_LARGEST_PBUFFER_ARB = %d\n", attr_v);
2081                 PUSH2(attribs, GLX_LARGEST_PBUFFER, attr_v);
2082                 break;
2083             }
2084
2085             case WGL_TEXTURE_FORMAT_ARB: {
2086                 ++piAttribList;
2087                 attr_v = *piAttribList;
2088                 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v);
2089                 if (use_render_texture_ati) {
2090                     int type = 0;
2091                     switch (attr_v) {
2092                         case WGL_NO_TEXTURE_ARB: type = GLX_NO_TEXTURE_ATI; break ;
2093                         case WGL_TEXTURE_RGB_ARB: type = GLX_TEXTURE_RGB_ATI; break ;
2094                         case WGL_TEXTURE_RGBA_ARB: type = GLX_TEXTURE_RGBA_ATI; break ;
2095                         default:
2096                             SetLastError(ERROR_INVALID_DATA);
2097                             goto create_failed;
2098                     }
2099                     object->use_render_texture = 1;
2100                     PUSH2(attribs, GLX_TEXTURE_FORMAT_ATI, type);
2101                 } else {
2102                     if (WGL_NO_TEXTURE_ARB == attr_v) {
2103                         object->use_render_texture = 0;
2104                     } else {
2105                         if (!use_render_texture_emulation) {
2106                             SetLastError(ERROR_INVALID_DATA);
2107                             goto create_failed;
2108                         }
2109                         switch (attr_v) {
2110                             case WGL_TEXTURE_RGB_ARB:
2111                                 object->use_render_texture = GL_RGB;
2112                                 object->texture_bpp = 3;
2113                                 object->texture_format = GL_RGB;
2114                                 object->texture_type = GL_UNSIGNED_BYTE;
2115                                 break;
2116                             case WGL_TEXTURE_RGBA_ARB:
2117                                 object->use_render_texture = GL_RGBA;
2118                                 object->texture_bpp = 4;
2119                                 object->texture_format = GL_RGBA;
2120                                 object->texture_type = GL_UNSIGNED_BYTE;
2121                                 break;
2122
2123                             /* WGL_FLOAT_COMPONENTS_NV */
2124                             case WGL_TEXTURE_FLOAT_R_NV:
2125                                 object->use_render_texture = GL_FLOAT_R_NV;
2126                                 object->texture_bpp = 4;
2127                                 object->texture_format = GL_RED;
2128                                 object->texture_type = GL_FLOAT;
2129                                 break;
2130                             case WGL_TEXTURE_FLOAT_RG_NV:
2131                                 object->use_render_texture = GL_FLOAT_RG_NV;
2132                                 object->texture_bpp = 8;
2133                                 object->texture_format = GL_LUMINANCE_ALPHA;
2134                                 object->texture_type = GL_FLOAT;
2135                                 break;
2136                             case WGL_TEXTURE_FLOAT_RGB_NV:
2137                                 object->use_render_texture = GL_FLOAT_RGB_NV;
2138                                 object->texture_bpp = 12;
2139                                 object->texture_format = GL_RGB;
2140                                 object->texture_type = GL_FLOAT;
2141                                 break;
2142                             case WGL_TEXTURE_FLOAT_RGBA_NV:
2143                                 object->use_render_texture = GL_FLOAT_RGBA_NV;
2144                                 object->texture_bpp = 16;
2145                                 object->texture_format = GL_RGBA;
2146                                 object->texture_type = GL_FLOAT;
2147                                 break;
2148                             default:
2149                                 ERR("Unknown texture format: %x\n", attr_v);
2150                                 SetLastError(ERROR_INVALID_DATA);
2151                                 goto create_failed;
2152                         }
2153                     }
2154                 }
2155                 break;
2156             }
2157
2158             case WGL_TEXTURE_TARGET_ARB: {
2159                 ++piAttribList;
2160                 attr_v = *piAttribList;
2161                 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v);
2162                 if (use_render_texture_ati) {
2163                     int type = 0;
2164                     switch (attr_v) {
2165                         case WGL_NO_TEXTURE_ARB: type = GLX_NO_TEXTURE_ATI; break ;
2166                         case WGL_TEXTURE_CUBE_MAP_ARB: type = GLX_TEXTURE_CUBE_MAP_ATI; break ;
2167                         case WGL_TEXTURE_1D_ARB: type = GLX_TEXTURE_1D_ATI; break ;
2168                         case WGL_TEXTURE_2D_ARB: type = GLX_TEXTURE_2D_ATI; break ;
2169                         default:
2170                             SetLastError(ERROR_INVALID_DATA);
2171                             goto create_failed;
2172                     }
2173                     PUSH2(attribs, GLX_TEXTURE_TARGET_ATI, type);
2174                 } else {
2175                     if (WGL_NO_TEXTURE_ARB == attr_v) {
2176                         object->texture_target = 0;
2177                     } else {
2178                         if (!use_render_texture_emulation) {
2179                             SetLastError(ERROR_INVALID_DATA);
2180                             goto create_failed;
2181                         }
2182                         switch (attr_v) {
2183                             case WGL_TEXTURE_CUBE_MAP_ARB: {
2184                                 if (iWidth != iHeight) {
2185                                     SetLastError(ERROR_INVALID_DATA);
2186                                     goto create_failed;
2187                                 }
2188                                 object->texture_target = GL_TEXTURE_CUBE_MAP;
2189                                 object->texture_bind_target = GL_TEXTURE_BINDING_CUBE_MAP;
2190                                break;
2191                             }
2192                             case WGL_TEXTURE_1D_ARB: {
2193                                 if (1 != iHeight) {
2194                                     SetLastError(ERROR_INVALID_DATA);
2195                                     goto create_failed;
2196                                 }
2197                                 object->texture_target = GL_TEXTURE_1D;
2198                                 object->texture_bind_target = GL_TEXTURE_BINDING_1D;
2199                                 break;
2200                             }
2201                             case WGL_TEXTURE_2D_ARB: {
2202                                 object->texture_target = GL_TEXTURE_2D;
2203                                 object->texture_bind_target = GL_TEXTURE_BINDING_2D;
2204                                 break;
2205                             }
2206                             case WGL_TEXTURE_RECTANGLE_NV: {
2207                                 object->texture_target = GL_TEXTURE_RECTANGLE_NV;
2208                                 object->texture_bind_target = GL_TEXTURE_BINDING_RECTANGLE_NV;
2209                                 break;
2210                             }
2211                             default:
2212                                 ERR("Unknown texture target: %x\n", attr_v);
2213                                 SetLastError(ERROR_INVALID_DATA);
2214                                 goto create_failed;
2215                         }
2216                     }
2217                 }
2218                 break;
2219             }
2220
2221             case WGL_MIPMAP_TEXTURE_ARB: {
2222                 ++piAttribList;
2223                 attr_v = *piAttribList;
2224                 TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v);
2225                 if (use_render_texture_ati) {
2226                     PUSH2(attribs, GLX_MIPMAP_TEXTURE_ATI, attr_v);
2227                 } else {
2228                     if (!use_render_texture_emulation) {
2229                         SetLastError(ERROR_INVALID_DATA);
2230                         goto create_failed;
2231                     }
2232                 }
2233                 break;
2234             }
2235         }
2236         ++piAttribList;
2237     }
2238
2239     PUSH1(attribs, None);
2240     object->drawable = pglXCreatePbuffer(gdi_display, fmt->fbconfig, attribs);
2241     TRACE("new Pbuffer drawable as %p\n", (void*) object->drawable);
2242     if (!object->drawable) {
2243         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
2244         goto create_failed; /* unexpected error */
2245     }
2246     TRACE("->(%p)\n", object);
2247     return (HPBUFFERARB) object;
2248
2249 create_failed:
2250     HeapFree(GetProcessHeap(), 0, object);
2251     TRACE("->(FAILED)\n");
2252     return (HPBUFFERARB) NULL;
2253 }
2254
2255 /**
2256  * X11DRV_wglDestroyPbufferARB
2257  *
2258  * WGL_ARB_pbuffer: wglDestroyPbufferARB
2259  */
2260 static GLboolean WINAPI X11DRV_wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
2261 {
2262     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2263     TRACE("(%p)\n", hPbuffer);
2264     if (NULL == object) {
2265         SetLastError(ERROR_INVALID_HANDLE);
2266         return GL_FALSE;
2267     }
2268     pglXDestroyPbuffer(object->display, object->drawable);
2269     HeapFree(GetProcessHeap(), 0, object);
2270     return GL_TRUE;
2271 }
2272
2273 /**
2274  * X11DRV_wglGetPbufferDCARB
2275  *
2276  * WGL_ARB_pbuffer: wglGetPbufferDCARB
2277  * The function wglGetPbufferDCARB returns a device context for a pbuffer.
2278  * Gdi32 implements the part of this function which creates a device context.
2279  * This part associates the physDev with the X drawable of the pbuffer.
2280  */
2281 HDC X11DRV_wglGetPbufferDCARB(X11DRV_PDEVICE *physDev, HPBUFFERARB hPbuffer)
2282 {
2283     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2284     if (NULL == object) {
2285         SetLastError(ERROR_INVALID_HANDLE);
2286         return NULL;
2287     }
2288
2289     /* The function wglGetPbufferDCARB returns a DC to which the pbuffer can be connected.
2290      * All formats in our pixelformat list are compatible with each other and the main drawable. */
2291     physDev->current_pf = object->fmt->iPixelFormat;
2292     physDev->drawable = object->drawable;
2293     SetRect( &physDev->drawable_rect, 0, 0, object->width, object->height );
2294     physDev->dc_rect = physDev->drawable_rect;
2295
2296     TRACE("(%p)->(%p)\n", hPbuffer, physDev->hdc);
2297     return physDev->hdc;
2298 }
2299
2300 /**
2301  * X11DRV_wglQueryPbufferARB
2302  *
2303  * WGL_ARB_pbuffer: wglQueryPbufferARB
2304  */
2305 static GLboolean WINAPI X11DRV_wglQueryPbufferARB(HPBUFFERARB hPbuffer, int iAttribute, int *piValue)
2306 {
2307     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2308     TRACE("(%p, 0x%x, %p)\n", hPbuffer, iAttribute, piValue);
2309     if (NULL == object) {
2310         SetLastError(ERROR_INVALID_HANDLE);
2311         return GL_FALSE;
2312     }
2313     switch (iAttribute) {
2314         case WGL_PBUFFER_WIDTH_ARB:
2315             pglXQueryDrawable(object->display, object->drawable, GLX_WIDTH, (unsigned int*) piValue);
2316             break;
2317         case WGL_PBUFFER_HEIGHT_ARB:
2318             pglXQueryDrawable(object->display, object->drawable, GLX_HEIGHT, (unsigned int*) piValue);
2319             break;
2320
2321         case WGL_PBUFFER_LOST_ARB:
2322             /* GLX Pbuffers cannot be lost by default. We can support this by
2323              * setting GLX_PRESERVED_CONTENTS to False and using glXSelectEvent
2324              * to receive pixel buffer clobber events, however that may or may
2325              * not give any benefit */
2326             *piValue = GL_FALSE;
2327             break;
2328
2329         case WGL_TEXTURE_FORMAT_ARB:
2330             if (use_render_texture_ati) {
2331                 unsigned int tmp;
2332                 int type = WGL_NO_TEXTURE_ARB;
2333                 pglXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_FORMAT_ATI, &tmp);
2334                 switch (tmp) {
2335                     case GLX_NO_TEXTURE_ATI: type = WGL_NO_TEXTURE_ARB; break ;
2336                     case GLX_TEXTURE_RGB_ATI: type = WGL_TEXTURE_RGB_ARB; break ;
2337                     case GLX_TEXTURE_RGBA_ATI: type = WGL_TEXTURE_RGBA_ARB; break ;
2338                 }
2339                 *piValue = type;
2340             } else {
2341                 if (!object->use_render_texture) {
2342                     *piValue = WGL_NO_TEXTURE_ARB;
2343                 } else {
2344                     if (!use_render_texture_emulation) {
2345                         SetLastError(ERROR_INVALID_HANDLE);
2346                         return GL_FALSE;
2347                     }
2348                     switch(object->use_render_texture) {
2349                         case GL_RGB:
2350                             *piValue = WGL_TEXTURE_RGB_ARB;
2351                             break;
2352                         case GL_RGBA:
2353                             *piValue = WGL_TEXTURE_RGBA_ARB;
2354                             break;
2355                         /* WGL_FLOAT_COMPONENTS_NV */
2356                         case GL_FLOAT_R_NV:
2357                             *piValue = WGL_TEXTURE_FLOAT_R_NV;
2358                             break;
2359                         case GL_FLOAT_RG_NV:
2360                             *piValue = WGL_TEXTURE_FLOAT_RG_NV;
2361                             break;
2362                         case GL_FLOAT_RGB_NV:
2363                             *piValue = WGL_TEXTURE_FLOAT_RGB_NV;
2364                             break;
2365                         case GL_FLOAT_RGBA_NV:
2366                             *piValue = WGL_TEXTURE_FLOAT_RGBA_NV;
2367                             break;
2368                         default:
2369                             ERR("Unknown texture format: %x\n", object->use_render_texture);
2370                     }
2371                 }
2372             }
2373             break;
2374
2375         case WGL_TEXTURE_TARGET_ARB:
2376             if (use_render_texture_ati) {
2377                 unsigned int tmp;
2378                 int type = WGL_NO_TEXTURE_ARB;
2379                 pglXQueryDrawable(object->display, object->drawable, GLX_TEXTURE_TARGET_ATI, &tmp);
2380                 switch (tmp) {
2381                     case GLX_NO_TEXTURE_ATI: type = WGL_NO_TEXTURE_ARB; break ;
2382                     case GLX_TEXTURE_CUBE_MAP_ATI: type = WGL_TEXTURE_CUBE_MAP_ARB; break ;
2383                     case GLX_TEXTURE_1D_ATI: type = WGL_TEXTURE_1D_ARB; break ;
2384                     case GLX_TEXTURE_2D_ATI: type = WGL_TEXTURE_2D_ARB; break ;
2385                 }
2386                 *piValue = type;
2387             } else {
2388             if (!object->texture_target) {
2389                 *piValue = WGL_NO_TEXTURE_ARB;
2390             } else {
2391                 if (!use_render_texture_emulation) {
2392                     SetLastError(ERROR_INVALID_DATA);      
2393                     return GL_FALSE;
2394                 }
2395                 switch (object->texture_target) {
2396                     case GL_TEXTURE_1D:       *piValue = WGL_TEXTURE_1D_ARB; break;
2397                     case GL_TEXTURE_2D:       *piValue = WGL_TEXTURE_2D_ARB; break;
2398                     case GL_TEXTURE_CUBE_MAP: *piValue = WGL_TEXTURE_CUBE_MAP_ARB; break;
2399                     case GL_TEXTURE_RECTANGLE_NV: *piValue = WGL_TEXTURE_RECTANGLE_NV; break;
2400                 }
2401             }
2402         }
2403         break;
2404
2405     case WGL_MIPMAP_TEXTURE_ARB:
2406         if (use_render_texture_ati) {
2407             pglXQueryDrawable(object->display, object->drawable, GLX_MIPMAP_TEXTURE_ATI, (unsigned int*) piValue);
2408         } else {
2409             *piValue = GL_FALSE; /** don't support that */
2410             FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute);
2411         }
2412         break;
2413
2414     default:
2415         FIXME("unexpected attribute %x\n", iAttribute);
2416         break;
2417     }
2418
2419     return GL_TRUE;
2420 }
2421
2422 /**
2423  * X11DRV_wglReleasePbufferDCARB
2424  *
2425  * WGL_ARB_pbuffer: wglReleasePbufferDCARB
2426  */
2427 static int WINAPI X11DRV_wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, HDC hdc)
2428 {
2429     TRACE("(%p, %p)\n", hPbuffer, hdc);
2430     DeleteDC(hdc);
2431     return 0;
2432 }
2433
2434 /**
2435  * X11DRV_wglSetPbufferAttribARB
2436  *
2437  * WGL_ARB_pbuffer: wglSetPbufferAttribARB
2438  */
2439 static GLboolean WINAPI X11DRV_wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int *piAttribList)
2440 {
2441     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2442     WARN("(%p, %p): alpha-testing, report any problem\n", hPbuffer, piAttribList);
2443     if (NULL == object) {
2444         SetLastError(ERROR_INVALID_HANDLE);
2445         return GL_FALSE;
2446     }
2447     if (!object->use_render_texture) {
2448         SetLastError(ERROR_INVALID_HANDLE);
2449         return GL_FALSE;
2450     }
2451     if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
2452         return GL_TRUE;
2453     }
2454     if (NULL != pglXDrawableAttribATI) {
2455         if (use_render_texture_ati) {
2456             FIXME("Need conversion for GLX_ATI_render_texture\n");
2457         }
2458         return pglXDrawableAttribATI(object->display, object->drawable, piAttribList);
2459     }
2460     return GL_FALSE;
2461 }
2462
2463 /**
2464  * X11DRV_wglChoosePixelFormatARB
2465  *
2466  * WGL_ARB_pixel_format: wglChoosePixelFormatARB
2467  */
2468 static GLboolean WINAPI X11DRV_wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats)
2469 {
2470     int gl_test = 0;
2471     int attribs[256];
2472     int nAttribs = 0;
2473     GLXFBConfig* cfgs = NULL;
2474     int nCfgs = 0;
2475     UINT it;
2476     int fmt_id;
2477     WineGLPixelFormat *fmt;
2478     int pfmt_it = 0;
2479     int run;
2480
2481     TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
2482     if (NULL != pfAttribFList) {
2483         FIXME("unused pfAttribFList\n");
2484     }
2485
2486     nAttribs = ConvertAttribWGLtoGLX(piAttribIList, attribs, NULL);
2487     if (-1 == nAttribs) {
2488         WARN("Cannot convert WGL to GLX attributes\n");
2489         return GL_FALSE;
2490     }
2491     PUSH1(attribs, None);
2492
2493     /* Search for FB configurations matching the requirements in attribs */
2494     cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), attribs, &nCfgs);
2495     if (NULL == cfgs) {
2496         WARN("Compatible Pixel Format not found\n");
2497         return GL_FALSE;
2498     }
2499
2500     /* Loop through all matching formats and check if they are suitable.
2501     * Note that this function should at max return nMaxFormats different formats */
2502     for(run=0; run < 2; run++)
2503     {
2504         for (it = 0; it < nCfgs; ++it) {
2505             gl_test = pglXGetFBConfigAttrib(gdi_display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id);
2506             if (gl_test) {
2507                 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
2508                 continue;
2509             }
2510
2511             /* Search for the format in our list of compatible formats */
2512             fmt = ConvertPixelFormatGLXtoWGL(gdi_display, fmt_id);
2513             if(!fmt)
2514                 continue;
2515
2516             /* During the first run we only want onscreen formats and during the second only offscreen 'XOR' */
2517             if( ((run == 0) && fmt->offscreenOnly) || ((run == 1) && !fmt->offscreenOnly) )
2518                 continue;
2519
2520             if(pfmt_it < nMaxFormats) {
2521                 piFormats[pfmt_it] = fmt->iPixelFormat;
2522                 TRACE("at %d/%d found FBCONFIG_ID 0x%x (%d)\n", it + 1, nCfgs, fmt_id, piFormats[pfmt_it]);
2523             }
2524             pfmt_it++;
2525         }
2526     }
2527
2528     *nNumFormats = pfmt_it;
2529     /** free list */
2530     XFree(cfgs);
2531     return GL_TRUE;
2532 }
2533
2534 /**
2535  * X11DRV_wglGetPixelFormatAttribivARB
2536  *
2537  * WGL_ARB_pixel_format: wglGetPixelFormatAttribivARB
2538  */
2539 static GLboolean WINAPI X11DRV_wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues)
2540 {
2541     UINT i;
2542     WineGLPixelFormat *fmt = NULL;
2543     int hTest;
2544     int tmp;
2545     int curGLXAttr = 0;
2546     int nWGLFormats = 0;
2547
2548     TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues);
2549
2550     if (0 < iLayerPlane) {
2551         FIXME("unsupported iLayerPlane(%d) > 0, returns FALSE\n", iLayerPlane);
2552         return GL_FALSE;
2553     }
2554
2555     /* Convert the WGL pixelformat to a GLX one, if this fails then most likely the iPixelFormat isn't supoprted.
2556     * We don't have to fail yet as a program can specify an invaled iPixelFormat (lets say 0) if it wants to query
2557     * the number of supported WGL formats. Whether the iPixelFormat is valid is handled in the for-loop below. */
2558     fmt = ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, TRUE /* Offscreen */, &nWGLFormats);
2559     if(!fmt) {
2560         WARN("Unable to convert iPixelFormat %d to a GLX one!\n", iPixelFormat);
2561     }
2562
2563     for (i = 0; i < nAttributes; ++i) {
2564         const int curWGLAttr = piAttributes[i];
2565         TRACE("pAttr[%d] = %x\n", i, curWGLAttr);
2566
2567         switch (curWGLAttr) {
2568             case WGL_NUMBER_PIXEL_FORMATS_ARB:
2569                 piValues[i] = nWGLFormats; 
2570                 continue;
2571
2572             case WGL_SUPPORT_OPENGL_ARB:
2573                 piValues[i] = GL_TRUE; 
2574                 continue;
2575
2576             case WGL_ACCELERATION_ARB:
2577                 curGLXAttr = GLX_CONFIG_CAVEAT;
2578                 if (!fmt) goto pix_error;
2579                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2580                 if (hTest) goto get_error;
2581                 switch (tmp) {
2582                     case GLX_NONE: piValues[i] = WGL_FULL_ACCELERATION_ARB; break;
2583                     case GLX_SLOW_CONFIG: piValues[i] = WGL_GENERIC_ACCELERATION_ARB; break;
2584                     case GLX_NON_CONFORMANT_CONFIG: piValues[i] = WGL_FULL_ACCELERATION_ARB; break;
2585                     default:
2586                         ERR("unexpected Config Caveat(%x)\n", tmp);
2587                         piValues[i] = WGL_NO_ACCELERATION_ARB;
2588                 }
2589                 continue;
2590
2591             case WGL_TRANSPARENT_ARB:
2592                 curGLXAttr = GLX_TRANSPARENT_TYPE;
2593                 if (!fmt) goto pix_error;
2594                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2595                 if (hTest) goto get_error;
2596                     piValues[i] = GL_FALSE;
2597                 if (GLX_NONE != tmp) piValues[i] = GL_TRUE;
2598                     continue;
2599
2600             case WGL_PIXEL_TYPE_ARB:
2601                 curGLXAttr = GLX_RENDER_TYPE;
2602                 if (!fmt) goto pix_error;
2603                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2604                 if (hTest) goto get_error;
2605                 TRACE("WGL_PIXEL_TYPE_ARB: GLX_RENDER_TYPE = 0x%x\n", tmp);
2606                 if      (tmp & GLX_RGBA_BIT)           { piValues[i] = WGL_TYPE_RGBA_ARB; }
2607                 else if (tmp & GLX_COLOR_INDEX_BIT)    { piValues[i] = WGL_TYPE_COLORINDEX_ARB; }
2608                 else if (tmp & GLX_RGBA_FLOAT_BIT)     { piValues[i] = WGL_TYPE_RGBA_FLOAT_ATI; }
2609                 else if (tmp & GLX_RGBA_FLOAT_ATI_BIT) { piValues[i] = WGL_TYPE_RGBA_FLOAT_ATI; }
2610                 else {
2611                     ERR("unexpected RenderType(%x)\n", tmp);
2612                     piValues[i] = WGL_TYPE_RGBA_ARB;
2613                 }
2614                 continue;
2615
2616             case WGL_COLOR_BITS_ARB:
2617                 curGLXAttr = GLX_BUFFER_SIZE;
2618                 break;
2619
2620             case WGL_BIND_TO_TEXTURE_RGB_ARB:
2621                 if (use_render_texture_ati) {
2622                     curGLXAttr = GLX_BIND_TO_TEXTURE_RGB_ATI;
2623                     break;
2624                 }
2625             case WGL_BIND_TO_TEXTURE_RGBA_ARB:
2626                 if (use_render_texture_ati) {
2627                     curGLXAttr = GLX_BIND_TO_TEXTURE_RGBA_ATI;
2628                     break;
2629                 }
2630                 if (!use_render_texture_emulation) {
2631                     piValues[i] = GL_FALSE;
2632                     continue;   
2633                 }
2634                 curGLXAttr = GLX_RENDER_TYPE;
2635                 if (!fmt) goto pix_error;
2636                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2637                 if (hTest) goto get_error;
2638                 if (GLX_COLOR_INDEX_BIT == tmp) {
2639                     piValues[i] = GL_FALSE;  
2640                     continue;
2641                 }
2642                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &tmp);
2643                 if (hTest) goto get_error;
2644                     piValues[i] = (tmp & GLX_PBUFFER_BIT) ? GL_TRUE : GL_FALSE;
2645                 continue;
2646
2647             case WGL_BLUE_BITS_ARB:
2648                 curGLXAttr = GLX_BLUE_SIZE;
2649                 break;
2650             case WGL_RED_BITS_ARB:
2651                 curGLXAttr = GLX_RED_SIZE;
2652                 break;
2653             case WGL_GREEN_BITS_ARB:
2654                 curGLXAttr = GLX_GREEN_SIZE;
2655                 break;
2656             case WGL_ALPHA_BITS_ARB:
2657                 curGLXAttr = GLX_ALPHA_SIZE;
2658                 break;
2659             case WGL_DEPTH_BITS_ARB:
2660                 curGLXAttr = GLX_DEPTH_SIZE;
2661                 break;
2662             case WGL_STENCIL_BITS_ARB:
2663                 curGLXAttr = GLX_STENCIL_SIZE;
2664                 break;
2665             case WGL_DOUBLE_BUFFER_ARB:
2666                 curGLXAttr = GLX_DOUBLEBUFFER;
2667                 break;
2668             case WGL_STEREO_ARB:
2669                 curGLXAttr = GLX_STEREO;
2670                 break;
2671             case WGL_AUX_BUFFERS_ARB:
2672                 curGLXAttr = GLX_AUX_BUFFERS;
2673                 break;
2674
2675             case WGL_SUPPORT_GDI_ARB:
2676                 if (!fmt) goto pix_error;
2677                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &tmp);
2678                 if (hTest) goto get_error;
2679                 if(tmp) {
2680                     piValues[i] = GL_FALSE;
2681                     continue;
2682                 }
2683                 curGLXAttr = GLX_X_RENDERABLE;
2684                 break;
2685
2686             case WGL_DRAW_TO_WINDOW_ARB:
2687             case WGL_DRAW_TO_BITMAP_ARB:
2688             case WGL_DRAW_TO_PBUFFER_ARB:
2689                 if (!fmt) goto pix_error;
2690                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &tmp);
2691                 if (hTest) goto get_error;
2692                 if((curWGLAttr == WGL_DRAW_TO_WINDOW_ARB && (tmp&GLX_WINDOW_BIT)) ||
2693                    (curWGLAttr == WGL_DRAW_TO_BITMAP_ARB && (tmp&GLX_PIXMAP_BIT)) ||
2694                    (curWGLAttr == WGL_DRAW_TO_PBUFFER_ARB && (tmp&GLX_PBUFFER_BIT)))
2695                     piValues[i] = GL_TRUE;
2696                 else
2697                     piValues[i] = GL_FALSE;
2698                 continue;
2699
2700             case WGL_PBUFFER_LARGEST_ARB:
2701                 curGLXAttr = GLX_LARGEST_PBUFFER;
2702                 break;
2703
2704             case WGL_SAMPLE_BUFFERS_ARB:
2705                 curGLXAttr = GLX_SAMPLE_BUFFERS_ARB;
2706                 break;
2707
2708             case WGL_SAMPLES_ARB:
2709                 curGLXAttr = GLX_SAMPLES_ARB;
2710                 break;
2711
2712             case WGL_FLOAT_COMPONENTS_NV:
2713                 curGLXAttr = GLX_FLOAT_COMPONENTS_NV;
2714                 break;
2715
2716             case WGL_ACCUM_RED_BITS_ARB:
2717                 curGLXAttr = GLX_ACCUM_RED_SIZE;
2718                 break;
2719             case WGL_ACCUM_GREEN_BITS_ARB:
2720                 curGLXAttr = GLX_ACCUM_GREEN_SIZE;
2721                 break;
2722             case WGL_ACCUM_BLUE_BITS_ARB:
2723                 curGLXAttr = GLX_ACCUM_BLUE_SIZE;
2724                 break;
2725             case WGL_ACCUM_ALPHA_BITS_ARB:
2726                 curGLXAttr = GLX_ACCUM_ALPHA_SIZE;
2727                 break;
2728             case WGL_ACCUM_BITS_ARB:
2729                 if (!fmt) goto pix_error;
2730                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_RED_SIZE, &tmp);
2731                 if (hTest) goto get_error;
2732                 piValues[i] = tmp;
2733                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_GREEN_SIZE, &tmp);
2734                 if (hTest) goto get_error;
2735                 piValues[i] += tmp;
2736                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_BLUE_SIZE, &tmp);
2737                 if (hTest) goto get_error;
2738                 piValues[i] += tmp;
2739                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_ALPHA_SIZE, &tmp);
2740                 if (hTest) goto get_error;
2741                 piValues[i] += tmp;
2742                 continue;
2743
2744             default:
2745                 FIXME("unsupported %x WGL Attribute\n", curWGLAttr);
2746         }
2747
2748         /* Retrieve a GLX FBConfigAttrib when the attribute to query is valid and
2749          * iPixelFormat != 0. When iPixelFormat is 0 the only value which makes
2750          * sense to query is WGL_NUMBER_PIXEL_FORMATS_ARB.
2751          *
2752          * TODO: properly test the behavior of wglGetPixelFormatAttrib*v on Windows
2753          *       and check which options can work using iPixelFormat=0 and which not.
2754          *       A problem would be that this function is an extension. This would
2755          *       mean that the behavior could differ between different vendors (ATI, Nvidia, ..).
2756          */
2757         if (0 != curGLXAttr && iPixelFormat != 0) {
2758             if (!fmt) goto pix_error;
2759             hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, piValues + i);
2760             if (hTest) goto get_error;
2761             curGLXAttr = 0;
2762         } else { 
2763             piValues[i] = GL_FALSE; 
2764         }
2765     }
2766     return GL_TRUE;
2767
2768 get_error:
2769     ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc, curGLXAttr);
2770     return GL_FALSE;
2771
2772 pix_error:
2773     ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc, iPixelFormat, nWGLFormats);
2774     return GL_FALSE;
2775 }
2776
2777 /**
2778  * X11DRV_wglGetPixelFormatAttribfvARB
2779  *
2780  * WGL_ARB_pixel_format: wglGetPixelFormatAttribfvARB
2781  */
2782 static GLboolean WINAPI X11DRV_wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues)
2783 {
2784     int *attr;
2785     int ret;
2786     int i;
2787
2788     TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues);
2789
2790     /* Allocate a temporary array to store integer values */
2791     attr = HeapAlloc(GetProcessHeap(), 0, nAttributes * sizeof(int));
2792     if (!attr) {
2793         ERR("couldn't allocate %d array\n", nAttributes);
2794         return GL_FALSE;
2795     }
2796
2797     /* Piggy-back on wglGetPixelFormatAttribivARB */
2798     ret = X11DRV_wglGetPixelFormatAttribivARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, attr);
2799     if (ret) {
2800         /* Convert integer values to float. Should also check for attributes
2801            that can give decimal values here */
2802         for (i=0; i<nAttributes;i++) {
2803             pfValues[i] = attr[i];
2804         }
2805     }
2806
2807     HeapFree(GetProcessHeap(), 0, attr);
2808     return ret;
2809 }
2810
2811 /**
2812  * X11DRV_wglBindTexImageARB
2813  *
2814  * WGL_ARB_render_texture: wglBindTexImageARB
2815  */
2816 static GLboolean WINAPI X11DRV_wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
2817 {
2818     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2819     TRACE("(%p, %d)\n", hPbuffer, iBuffer);
2820     if (NULL == object) {
2821         SetLastError(ERROR_INVALID_HANDLE);
2822         return GL_FALSE;
2823     }
2824     if (!object->use_render_texture) {
2825         SetLastError(ERROR_INVALID_HANDLE);
2826         return GL_FALSE;
2827     }
2828
2829     if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
2830         static int init = 0;
2831         int prev_binded_texture = 0;
2832         GLXContext prev_context = pglXGetCurrentContext();
2833         Drawable prev_drawable = pglXGetCurrentDrawable();
2834         GLXContext tmp_context;
2835
2836         /* Our render_texture emulation is basic and lacks some features (1D/Cube support).
2837            This is mostly due to lack of demos/games using them. Further the use of glReadPixels
2838            isn't ideal performance wise but I wasn't able to get other ways working.
2839         */
2840         if(!init) {
2841             init = 1; /* Only show the FIXME once for performance reasons */
2842             FIXME("partial stub!\n");
2843         }
2844
2845         TRACE("drawable=%p, context=%p\n", (void*)object->drawable, prev_context);
2846         tmp_context = pglXCreateNewContext(gdi_display, object->fmt->fbconfig, object->fmt->render_type, prev_context, True);
2847
2848         pglGetIntegerv(object->texture_bind_target, &prev_binded_texture);
2849
2850         /* Switch to our pbuffer */
2851         pglXMakeCurrent(gdi_display, object->drawable, tmp_context);
2852
2853         /* Make sure that the prev_binded_texture is set as the current texture state isn't shared between contexts.
2854          * After that upload the pbuffer texture data. */
2855         pglBindTexture(object->texture_target, prev_binded_texture);
2856         pglCopyTexImage2D(object->texture_target, 0, object->use_render_texture, 0, 0, object->width, object->height, 0);
2857
2858         /* Switch back to the original drawable and upload the pbuffer-texture */
2859         pglXMakeCurrent(object->display, prev_drawable, prev_context);
2860         pglXDestroyContext(gdi_display, tmp_context);
2861         return GL_TRUE;
2862     }
2863
2864     if (NULL != pglXBindTexImageATI) {
2865         int buffer;
2866
2867         switch(iBuffer)
2868         {
2869             case WGL_FRONT_LEFT_ARB:
2870                 buffer = GLX_FRONT_LEFT_ATI;
2871                 break;
2872             case WGL_FRONT_RIGHT_ARB:
2873                 buffer = GLX_FRONT_RIGHT_ATI;
2874                 break;
2875             case WGL_BACK_LEFT_ARB:
2876                 buffer = GLX_BACK_LEFT_ATI;
2877                 break;
2878             case WGL_BACK_RIGHT_ARB:
2879                 buffer = GLX_BACK_RIGHT_ATI;
2880                 break;
2881             default:
2882                 ERR("Unknown iBuffer=%#x\n", iBuffer);
2883                 return FALSE;
2884         }
2885
2886         /* In the sample 'ogl_offscreen_rendering_3' from codesampler.net I get garbage on the screen.
2887          * I'm not sure if that's a bug in the ATI extension or in the program. I think that the program
2888          * expected a single buffering format since it didn't ask for double buffering. A buffer swap
2889          * fixed the program. I don't know what the correct behavior is. On the other hand that demo
2890          * works fine using our pbuffer emulation path.
2891          */
2892         return pglXBindTexImageATI(object->display, object->drawable, buffer);
2893     }
2894     return GL_FALSE;
2895 }
2896
2897 /**
2898  * X11DRV_wglReleaseTexImageARB
2899  *
2900  * WGL_ARB_render_texture: wglReleaseTexImageARB
2901  */
2902 static GLboolean WINAPI X11DRV_wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
2903 {
2904     Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
2905     TRACE("(%p, %d)\n", hPbuffer, iBuffer);
2906     if (NULL == object) {
2907         SetLastError(ERROR_INVALID_HANDLE);
2908         return GL_FALSE;
2909     }
2910     if (!object->use_render_texture) {
2911         SetLastError(ERROR_INVALID_HANDLE);
2912         return GL_FALSE;
2913     }
2914     if (!use_render_texture_ati && 1 == use_render_texture_emulation) {
2915         return GL_TRUE;
2916     }
2917     if (NULL != pglXReleaseTexImageATI) {
2918         int buffer;
2919
2920         switch(iBuffer)
2921         {
2922             case WGL_FRONT_LEFT_ARB:
2923                 buffer = GLX_FRONT_LEFT_ATI;
2924                 break;
2925             case WGL_FRONT_RIGHT_ARB:
2926                 buffer = GLX_FRONT_RIGHT_ATI;
2927                 break;
2928             case WGL_BACK_LEFT_ARB:
2929                 buffer = GLX_BACK_LEFT_ATI;
2930                 break;
2931             case WGL_BACK_RIGHT_ARB:
2932                 buffer = GLX_BACK_RIGHT_ATI;
2933                 break;
2934             default:
2935                 ERR("Unknown iBuffer=%#x\n", iBuffer);
2936                 return FALSE;
2937         }
2938         return pglXReleaseTexImageATI(object->display, object->drawable, buffer);
2939     }
2940     return GL_FALSE;
2941 }
2942
2943 /**
2944  * X11DRV_wglGetExtensionsStringEXT
2945  *
2946  * WGL_EXT_extensions_string: wglGetExtensionsStringEXT
2947  */
2948 static const char * WINAPI X11DRV_wglGetExtensionsStringEXT(void) {
2949     TRACE("() returning \"%s\"\n", WineGLInfo.wglExtensions);
2950     return WineGLInfo.wglExtensions;
2951 }
2952
2953 /**
2954  * X11DRV_wglGetSwapIntervalEXT
2955  *
2956  * WGL_EXT_swap_control: wglGetSwapIntervalEXT
2957  */
2958 static int WINAPI X11DRV_wglGetSwapIntervalEXT(VOID) {
2959     FIXME("(),stub!\n");
2960     return swap_interval;
2961 }
2962
2963 /**
2964  * X11DRV_wglSwapIntervalEXT
2965  *
2966  * WGL_EXT_swap_control: wglSwapIntervalEXT
2967  */
2968 static BOOL WINAPI X11DRV_wglSwapIntervalEXT(int interval) {
2969     TRACE("(%d)\n", interval);
2970     swap_interval = interval;
2971     if (NULL != pglXSwapIntervalSGI) {
2972         return 0 == pglXSwapIntervalSGI(interval);
2973     }
2974     WARN("(): GLX_SGI_swap_control extension seems not supported\n");
2975     return TRUE;
2976 }
2977
2978 /**
2979  * X11DRV_wglAllocateMemoryNV
2980  *
2981  * WGL_NV_vertex_array_range: wglAllocateMemoryNV
2982  */
2983 static void* WINAPI X11DRV_wglAllocateMemoryNV(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority) {
2984     TRACE("(%d, %f, %f, %f)\n", size, readfreq, writefreq, priority );
2985     if (pglXAllocateMemoryNV == NULL)
2986         return NULL;
2987
2988     return pglXAllocateMemoryNV(size, readfreq, writefreq, priority);
2989 }
2990
2991 /**
2992  * X11DRV_wglFreeMemoryNV
2993  *
2994  * WGL_NV_vertex_array_range: wglFreeMemoryNV
2995  */
2996 static void WINAPI X11DRV_wglFreeMemoryNV(GLvoid* pointer) {
2997     TRACE("(%p)\n", pointer);
2998     if (pglXFreeMemoryNV == NULL)
2999         return;
3000
3001     pglXFreeMemoryNV(pointer);
3002 }
3003
3004 /**
3005  * glxRequireVersion (internal)
3006  *
3007  * Check if the supported GLX version matches requiredVersion.
3008  */
3009 static BOOL glxRequireVersion(int requiredVersion)
3010 {
3011     /* Both requiredVersion and glXVersion[1] contains the minor GLX version */
3012     if(requiredVersion <= WineGLInfo.glxVersion[1])
3013         return TRUE;
3014
3015     return FALSE;
3016 }
3017
3018 static BOOL glxRequireExtension(const char *requiredExtension)
3019 {
3020     if (strstr(WineGLInfo.glxExtensions, requiredExtension) == NULL) {
3021         return FALSE;
3022     }
3023
3024     return TRUE;
3025 }
3026
3027 static void register_extension_string(const char *ext)
3028 {
3029     if (WineGLInfo.wglExtensions[0])
3030         strcat(WineGLInfo.wglExtensions, " ");
3031     strcat(WineGLInfo.wglExtensions, ext);
3032
3033     TRACE("'%s'\n", ext);
3034 }
3035
3036 static BOOL register_extension(const WineGLExtension * ext)
3037 {
3038     int i;
3039
3040     assert( WineGLExtensionListSize < MAX_EXTENSIONS );
3041     WineGLExtensionList[WineGLExtensionListSize++] = ext;
3042
3043     register_extension_string(ext->extName);
3044
3045     for (i = 0; ext->extEntryPoints[i].funcName; ++i)
3046         TRACE("    - '%s'\n", ext->extEntryPoints[i].funcName);
3047
3048     return TRUE;
3049 }
3050
3051 static const WineGLExtension WGL_internal_functions =
3052 {
3053   "",
3054   {
3055     { "wglDisable", X11DRV_wglDisable },
3056     { "wglEnable", X11DRV_wglEnable },
3057     { "wglGetIntegerv", X11DRV_wglGetIntegerv },
3058     { "wglIsEnabled", X11DRV_wglIsEnabled },
3059     { "wglScissor", X11DRV_wglScissor },
3060     { "wglViewport", X11DRV_wglViewport },
3061   }
3062 };
3063
3064
3065 static const WineGLExtension WGL_ARB_extensions_string =
3066 {
3067   "WGL_ARB_extensions_string",
3068   {
3069     { "wglGetExtensionsStringARB", X11DRV_wglGetExtensionsStringARB },
3070   }
3071 };
3072
3073 static const WineGLExtension WGL_ARB_make_current_read =
3074 {
3075   "WGL_ARB_make_current_read",
3076   {
3077     { "wglGetCurrentReadDCARB", X11DRV_wglGetCurrentReadDCARB },
3078     { "wglMakeContextCurrentARB", X11DRV_wglMakeContextCurrentARB },
3079   }
3080 };
3081
3082 static const WineGLExtension WGL_ARB_multisample =
3083 {
3084   "WGL_ARB_multisample",
3085 };
3086
3087 static const WineGLExtension WGL_ARB_pbuffer =
3088 {
3089   "WGL_ARB_pbuffer",
3090   {
3091     { "wglCreatePbufferARB", X11DRV_wglCreatePbufferARB },
3092     { "wglDestroyPbufferARB", X11DRV_wglDestroyPbufferARB },
3093     { "wglGetPbufferDCARB", X11DRV_wglGetPbufferDCARB },
3094     { "wglQueryPbufferARB", X11DRV_wglQueryPbufferARB },
3095     { "wglReleasePbufferDCARB", X11DRV_wglReleasePbufferDCARB },
3096     { "wglSetPbufferAttribARB", X11DRV_wglSetPbufferAttribARB },
3097   }
3098 };
3099
3100 static const WineGLExtension WGL_ARB_pixel_format =
3101 {
3102   "WGL_ARB_pixel_format",
3103   {
3104     { "wglChoosePixelFormatARB", X11DRV_wglChoosePixelFormatARB },
3105     { "wglGetPixelFormatAttribfvARB", X11DRV_wglGetPixelFormatAttribfvARB },
3106     { "wglGetPixelFormatAttribivARB", X11DRV_wglGetPixelFormatAttribivARB },
3107   }
3108 };
3109
3110 static const WineGLExtension WGL_ARB_render_texture =
3111 {
3112   "WGL_ARB_render_texture",
3113   {
3114     { "wglBindTexImageARB", X11DRV_wglBindTexImageARB },
3115     { "wglReleaseTexImageARB", X11DRV_wglReleaseTexImageARB },
3116   }
3117 };
3118
3119 static const WineGLExtension WGL_EXT_extensions_string =
3120 {
3121   "WGL_EXT_extensions_string",
3122   {
3123     { "wglGetExtensionsStringEXT", X11DRV_wglGetExtensionsStringEXT },
3124   }
3125 };
3126
3127 static const WineGLExtension WGL_EXT_swap_control =
3128 {
3129   "WGL_EXT_swap_control",
3130   {
3131     { "wglSwapIntervalEXT", X11DRV_wglSwapIntervalEXT },
3132     { "wglGetSwapIntervalEXT", X11DRV_wglGetSwapIntervalEXT },
3133   }
3134 };
3135
3136 static const WineGLExtension WGL_NV_vertex_array_range =
3137 {
3138   "WGL_NV_vertex_array_range",
3139   {
3140     { "wglAllocateMemoryNV", X11DRV_wglAllocateMemoryNV },
3141     { "wglFreeMemoryNV", X11DRV_wglFreeMemoryNV },
3142   }
3143 };
3144
3145 /**
3146  * X11DRV_WineGL_LoadExtensions
3147  */
3148 static void X11DRV_WineGL_LoadExtensions(void)
3149 {
3150     WineGLInfo.wglExtensions[0] = 0;
3151
3152     /* Load Wine internal functions */
3153     register_extension(&WGL_internal_functions);
3154
3155     /* ARB Extensions */
3156
3157     if(glxRequireExtension("GLX_ARB_fbconfig_float"))
3158     {
3159         register_extension_string("WGL_ARB_pixel_format_float");
3160         register_extension_string("WGL_ATI_pixel_format_float");
3161     }
3162
3163     register_extension(&WGL_ARB_extensions_string);
3164
3165     if (glxRequireVersion(3))
3166         register_extension(&WGL_ARB_make_current_read);
3167
3168     if (glxRequireExtension("GLX_ARB_multisample"))
3169         register_extension(&WGL_ARB_multisample);
3170
3171     /* In general pbuffer functionality requires support in the X-server. The functionality is
3172      * available either when the GLX_SGIX_pbuffer is present or when the GLX server version is 1.3.
3173      * All display drivers except for Nvidia's use the GLX module from Xfree86/Xorg which only
3174      * supports GLX 1.2. The endresult is that only Nvidia's drivers support pbuffers.
3175      *
3176      * The only other drive which has pbuffer support is Ati's FGLRX driver. They provide clientside GLX 1.3 support
3177      * without support in the X-server (which other Mesa based drivers require).
3178      *
3179      * Support pbuffers when the GLX version is 1.3 and GLX_SGIX_pbuffer is available. Further pbuffers can
3180      * also be supported when GLX_ATI_render_texture is available. This extension depends on pbuffers, so when it
3181      * is available pbuffers must be available too. */
3182     if ( (glxRequireVersion(3) && glxRequireExtension("GLX_SGIX_pbuffer")) || glxRequireExtension("GLX_ATI_render_texture"))
3183         register_extension(&WGL_ARB_pbuffer);
3184
3185     register_extension(&WGL_ARB_pixel_format);
3186
3187     /* Support WGL_ARB_render_texture when there's support or pbuffer based emulation */
3188     if (glxRequireExtension("GLX_ATI_render_texture") ||
3189         glxRequireExtension("GLX_ARB_render_texture") ||
3190         (glxRequireVersion(3) && glxRequireExtension("GLX_SGIX_pbuffer") && use_render_texture_emulation))
3191     {
3192         register_extension(&WGL_ARB_render_texture);
3193
3194         /* The WGL version of GLX_NV_float_buffer requires render_texture */
3195         if(glxRequireExtension("GLX_NV_float_buffer"))
3196             register_extension_string("WGL_NV_float_buffer");
3197
3198         /* Again there's no GLX equivalent for this extension, so depend on the required GL extension */
3199         if(strstr(WineGLInfo.glExtensions, "GL_NV_texture_rectangle") != NULL)
3200             register_extension_string("WGL_NV_texture_rectangle");
3201     }
3202
3203     /* EXT Extensions */
3204
3205     register_extension(&WGL_EXT_extensions_string);
3206
3207     /* Load this extension even when it isn't backed by a GLX extension because it is has been around for ages.
3208      * Games like Call of Duty and K.O.T.O.R. rely on it. Further our emulation is good enough. */
3209     register_extension(&WGL_EXT_swap_control);
3210
3211     /* The OpenGL extension GL_NV_vertex_array_range adds wgl/glX functions which aren't exported as 'real' wgl/glX extensions. */
3212     if(strstr(WineGLInfo.glExtensions, "GL_NV_vertex_array_range") != NULL)
3213         register_extension(&WGL_NV_vertex_array_range);
3214 }
3215
3216
3217 static XID create_glxpixmap(X11DRV_PDEVICE *physDev)
3218 {
3219     GLXPixmap ret;
3220     XVisualInfo *vis;
3221     XVisualInfo template;
3222     int num;
3223
3224     wine_tsx11_lock();
3225
3226     /* Retrieve the visualid from our main visual which is the only visual we can use */
3227     template.visualid =  XVisualIDFromVisual(visual);
3228     vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num);
3229
3230     ret = pglXCreateGLXPixmap(gdi_display, vis, physDev->bitmap->pixmap);
3231     XFree(vis);
3232     wine_tsx11_unlock(); 
3233     TRACE("return %lx\n", ret);
3234     return ret;
3235 }
3236
3237 Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
3238 {
3239     Drawable ret;
3240
3241     if(physDev->bitmap)
3242     {
3243         if (physDev->bitmap->hbitmap == BITMAP_stock_phys_bitmap.hbitmap)
3244             ret = physDev->drawable; /* PBuffer */
3245         else
3246         {
3247             if(!physDev->bitmap->glxpixmap)
3248                 physDev->bitmap->glxpixmap = create_glxpixmap(physDev);
3249             ret = physDev->bitmap->glxpixmap;
3250         }
3251     }
3252     else
3253         ret = physDev->drawable;
3254     return ret;
3255 }
3256
3257 BOOL destroy_glxpixmap(XID glxpixmap)
3258 {
3259     wine_tsx11_lock(); 
3260     pglXDestroyGLXPixmap(gdi_display, glxpixmap);
3261     wine_tsx11_unlock(); 
3262     return TRUE;
3263 }
3264
3265 /**
3266  * X11DRV_SwapBuffers
3267  *
3268  * Swap the buffers of this DC
3269  */
3270 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev)
3271 {
3272   GLXDrawable drawable;
3273   if (!has_opengl()) {
3274     ERR("No libGL on this box - disabling OpenGL support !\n");
3275     return 0;
3276   }
3277   
3278   TRACE_(opengl)("(%p)\n", physDev);
3279
3280   drawable = get_glxdrawable(physDev);
3281   wine_tsx11_lock();
3282   pglXSwapBuffers(gdi_display, drawable);
3283   wine_tsx11_unlock();
3284
3285   /* FPS support */
3286   if (TRACE_ON(fps))
3287   {
3288       static long prev_time, frames;
3289
3290       DWORD time = GetTickCount();
3291       frames++;
3292       /* every 1.5 seconds */
3293       if (time - prev_time > 1500) {
3294           TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
3295           prev_time = time;
3296           frames = 0;
3297       }
3298   }
3299
3300   return TRUE;
3301 }
3302
3303 /***********************************************************************
3304  *              X11DRV_setup_opengl_visual
3305  *
3306  * Setup the default visual used for OpenGL and Direct3D, and the desktop
3307  * window (if it exists).  If OpenGL isn't available, the visual is simply
3308  * set to the default visual for the display
3309  */
3310 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
3311 {
3312     XVisualInfo *visual = NULL;
3313     int i;
3314
3315     /* In order to support OpenGL or D3D, we require a double-buffered visual and stencil buffer support,
3316      * D3D and some applications can make use of aux buffers.
3317      */
3318     int visualProperties[][11] = {
3319         { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_AUX_BUFFERS, 1, None },
3320         { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_ALPHA_SIZE, 8, None },
3321         { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, None },
3322         { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, None },
3323     };
3324
3325     if (!has_opengl())
3326         return NULL;
3327
3328     wine_tsx11_lock();
3329     for (i = 0; i < sizeof(visualProperties)/sizeof(visualProperties[0]); ++i) {
3330         visual = pglXChooseVisual(display, DefaultScreen(display), visualProperties[i]);
3331         if (visual)
3332             break;
3333     }
3334     wine_tsx11_unlock();
3335
3336     if (visual)
3337         TRACE("Visual ID %lx Chosen\n", visual->visualid);
3338     else
3339         WARN("No suitable visual found\n");
3340
3341     return visual;
3342 }
3343
3344 #else  /* no OpenGL includes */
3345
3346 /***********************************************************************
3347  *              ChoosePixelFormat (X11DRV.@)
3348  */
3349 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
3350                              const PIXELFORMATDESCRIPTOR *ppfd) {
3351   ERR("No OpenGL support compiled in.\n");
3352
3353   return 0;
3354 }
3355
3356 /***********************************************************************
3357  *              DescribePixelFormat (X11DRV.@)
3358  */
3359 int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
3360                                int iPixelFormat,
3361                                UINT nBytes,
3362                                PIXELFORMATDESCRIPTOR *ppfd) {
3363   ERR("No OpenGL support compiled in.\n");
3364
3365   return 0;
3366 }
3367
3368 /***********************************************************************
3369  *              GetPixelFormat (X11DRV.@)
3370  */
3371 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
3372   ERR("No OpenGL support compiled in.\n");
3373
3374   return 0;
3375 }
3376
3377 /***********************************************************************
3378  *              SetPixelFormat (X11DRV.@)
3379  */
3380 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
3381                            int iPixelFormat,
3382                            const PIXELFORMATDESCRIPTOR *ppfd) {
3383   ERR("No OpenGL support compiled in.\n");
3384
3385   return FALSE;
3386 }
3387
3388 /***********************************************************************
3389  *              SwapBuffers (X11DRV.@)
3390  */
3391 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) {
3392   ERR_(opengl)("No OpenGL support compiled in.\n");
3393
3394   return FALSE;
3395 }
3396
3397 /**
3398  * X11DRV_wglCreateContext
3399  *
3400  * For OpenGL32 wglCreateContext.
3401  */
3402 HGLRC X11DRV_wglCreateContext(X11DRV_PDEVICE *physDev) {
3403     ERR_(opengl)("No OpenGL support compiled in.\n");
3404     return NULL;
3405 }
3406
3407 /**
3408  * X11DRV_wglDeleteContext
3409  *
3410  * For OpenGL32 wglDeleteContext.
3411  */
3412 BOOL X11DRV_wglDeleteContext(HGLRC hglrc) {
3413     ERR_(opengl)("No OpenGL support compiled in.\n");
3414     return FALSE;
3415 }
3416
3417 /**
3418  * X11DRV_wglGetProcAddress
3419  *
3420  * For OpenGL32 wglGetProcAddress.
3421  */
3422 PROC X11DRV_wglGetProcAddress(LPCSTR lpszProc) {
3423     ERR_(opengl)("No OpenGL support compiled in.\n");
3424     return NULL;
3425 }
3426
3427 HDC X11DRV_wglGetPbufferDCARB(X11DRV_PDEVICE *hDevice, void *hPbuffer)
3428 {
3429     ERR_(opengl)("No OpenGL support compiled in.\n");
3430     return NULL;
3431 }
3432
3433 BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* hDrawDev, X11DRV_PDEVICE* hReadDev, HGLRC hglrc) {
3434     ERR_(opengl)("No OpenGL support compiled in.\n");
3435     return FALSE;
3436 }
3437
3438 /**
3439  * X11DRV_wglMakeCurrent
3440  *
3441  * For OpenGL32 wglMakeCurrent.
3442  */
3443 BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
3444     ERR_(opengl)("No OpenGL support compiled in.\n");
3445     return FALSE;
3446 }
3447
3448 /**
3449  * X11DRV_wglShareLists
3450  *
3451  * For OpenGL32 wglShaderLists.
3452  */
3453 BOOL X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
3454     ERR_(opengl)("No OpenGL support compiled in.\n");
3455     return FALSE;
3456 }
3457
3458 /**
3459  * X11DRV_wglUseFontBitmapsA
3460  *
3461  * For OpenGL32 wglUseFontBitmapsA.
3462  */
3463 BOOL X11DRV_wglUseFontBitmapsA(X11DRV_PDEVICE *physDev, DWORD first, DWORD count, DWORD listBase)
3464 {
3465     ERR_(opengl)("No OpenGL support compiled in.\n");
3466     return FALSE;
3467 }
3468
3469 /**
3470  * X11DRV_wglUseFontBitmapsW
3471  *
3472  * For OpenGL32 wglUseFontBitmapsW.
3473  */
3474 BOOL X11DRV_wglUseFontBitmapsW(X11DRV_PDEVICE *physDev, DWORD first, DWORD count, DWORD listBase)
3475 {
3476     ERR_(opengl)("No OpenGL support compiled in.\n");
3477     return FALSE;
3478 }
3479
3480 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
3481 {
3482   return NULL;
3483 }
3484
3485 Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
3486 {
3487     return 0;
3488 }
3489
3490 BOOL destroy_glxpixmap(XID glxpixmap)
3491 {
3492     return FALSE;
3493 }
3494
3495 #endif /* defined(HAVE_OPENGL) */