winex11: Store a format pointer instead of an index in the drawable structures.
[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-2009 Roderick Colenbrander
8  * Copyright 2006 Tomas Carnecky
9  * Copyright 2012 Alexandre Julliard
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25
26 #include "config.h"
27 #include "wine/port.h"
28
29 #include <assert.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #ifdef HAVE_SYS_SOCKET_H
34 #include <sys/socket.h>
35 #endif
36 #ifdef HAVE_SYS_UN_H
37 #include <sys/un.h>
38 #endif
39 #ifdef HAVE_GL_GL_H
40 # include <GL/gl.h>
41 #endif
42 #ifdef HAVE_GL_GLX_H
43 # include <GL/glx.h>
44 #endif
45 #undef APIENTRY
46 #undef GLAPI
47 #undef WINGDIAPI
48
49 #include "x11drv.h"
50 #include "xcomposite.h"
51 #include "winternl.h"
52 #include "wine/library.h"
53 #include "wine/debug.h"
54
55 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
56
57 #ifdef SONAME_LIBGL
58
59 WINE_DECLARE_DEBUG_CHANNEL(winediag);
60 WINE_DECLARE_DEBUG_CHANNEL(fps);
61
62 #include "wine/wgl_driver.h"
63 #include "wine/wglext.h"
64
65 /* For compatibility with old Mesa headers */
66 #ifndef GLX_SAMPLE_BUFFERS_ARB
67 # define GLX_SAMPLE_BUFFERS_ARB           100000
68 #endif
69 #ifndef GLX_SAMPLES_ARB
70 # define GLX_SAMPLES_ARB                  100001
71 #endif
72 #ifndef GL_TEXTURE_CUBE_MAP
73 # define GL_TEXTURE_CUBE_MAP              0x8513
74 #endif
75 #ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT
76 # define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
77 #endif
78 #ifndef GLX_EXT_fbconfig_packed_float
79 # define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
80 # define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT  0x00000008
81 #endif
82 #ifndef GLX_ARB_create_context
83 # define GLX_CONTEXT_MAJOR_VERSION_ARB    0x2091
84 # define GLX_CONTEXT_MINOR_VERSION_ARB    0x2092
85 # define GLX_CONTEXT_FLAGS_ARB            0x2094
86 #endif
87 #ifndef GLX_ARB_create_context_profile
88 # define GLX_CONTEXT_PROFILE_MASK_ARB     0x9126
89 #endif
90 /** GLX_ATI_pixel_format_float */
91 #define GLX_RGBA_FLOAT_ATI_BIT            0x00000100
92 /** GLX_ARB_pixel_format_float */
93 #define GLX_RGBA_FLOAT_BIT                0x00000004
94 #define GLX_RGBA_FLOAT_TYPE               0x20B9
95 /** GL_NV_float_buffer */
96 #define GL_FLOAT_R_NV                     0x8880
97 #define GL_FLOAT_RG_NV                    0x8881
98 #define GL_FLOAT_RGB_NV                   0x8882
99 #define GL_FLOAT_RGBA_NV                  0x8883
100 #define GL_FLOAT_R16_NV                   0x8884
101 #define GL_FLOAT_R32_NV                   0x8885
102 #define GL_FLOAT_RG16_NV                  0x8886
103 #define GL_FLOAT_RG32_NV                  0x8887
104 #define GL_FLOAT_RGB16_NV                 0x8888
105 #define GL_FLOAT_RGB32_NV                 0x8889
106 #define GL_FLOAT_RGBA16_NV                0x888A
107 #define GL_FLOAT_RGBA32_NV                0x888B
108 #define GL_TEXTURE_FLOAT_COMPONENTS_NV    0x888C
109 #define GL_FLOAT_CLEAR_COLOR_VALUE_NV     0x888D
110 #define GL_FLOAT_RGBA_MODE_NV             0x888E
111 /** GLX_NV_float_buffer */
112 #define GLX_FLOAT_COMPONENTS_NV           0x20B0
113
114
115 struct WineGLInfo {
116     const char *glVersion;
117     char *glExtensions;
118
119     int glxVersion[2];
120
121     const char *glxServerVersion;
122     const char *glxServerVendor;
123     const char *glxServerExtensions;
124
125     const char *glxClientVersion;
126     const char *glxClientVendor;
127     const char *glxClientExtensions;
128
129     const char *glxExtensions;
130
131     BOOL glxDirect;
132     char wglExtensions[4096];
133 };
134
135 struct wgl_pixel_format
136 {
137     GLXFBConfig fbconfig;
138     int         fmt_id;
139     int         render_type;
140     DWORD       dwFlags; /* We store some PFD_* flags in here for emulated bitmap formats */
141 };
142
143 struct wgl_context
144 {
145     HDC hdc;
146     BOOL has_been_current;
147     BOOL sharing;
148     BOOL gl3_context;
149     XVisualInfo *vis;
150     const struct wgl_pixel_format *fmt;
151     int numAttribs; /* This is needed for delaying wglCreateContextAttribsARB */
152     int attribList[16]; /* This is needed for delaying wglCreateContextAttribsARB */
153     GLXContext ctx;
154     Drawable drawables[2];
155     BOOL refresh_drawables;
156     struct list entry;
157 };
158
159 struct wgl_pbuffer
160 {
161     Drawable   drawable;
162     const struct wgl_pixel_format* fmt;
163     int        width;
164     int        height;
165     int*       attribList;
166     int        use_render_texture; /* This is also the internal texture format */
167     int        texture_bind_target;
168     int        texture_bpp;
169     GLint      texture_format;
170     GLuint     texture_target;
171     GLenum     texture_type;
172     GLuint     texture;
173     int        texture_level;
174 };
175
176 enum dc_gl_type
177 {
178     DC_GL_NONE,       /* no GL support (pixel format not set yet) */
179     DC_GL_WINDOW,     /* normal top-level window */
180     DC_GL_CHILD_WIN,  /* child window using XComposite */
181     DC_GL_PIXMAP_WIN, /* child window using intermediate pixmap */
182     DC_GL_PBUFFER     /* pseudo memory DC using a PBuffer */
183 };
184
185 struct glx_physdev
186 {
187     struct gdi_physdev             dev;
188     X11DRV_PDEVICE                *x11dev;
189     enum dc_gl_type                type;          /* type of GL device context */
190     const struct wgl_pixel_format *format;
191     Drawable                       drawable;
192     Pixmap                         pixmap;        /* pixmap for a DL_GL_PIXMAP_WIN drawable */
193 };
194
195 struct gl_drawable
196 {
197     enum dc_gl_type                type;         /* type of GL surface */
198     Drawable                       drawable;     /* drawable for rendering to the client area */
199     Pixmap                         pixmap;       /* base pixmap if drawable is a GLXPixmap */
200     Colormap                       colormap;     /* colormap used for the drawable */
201     const struct wgl_pixel_format *format;       /* pixel format for the drawable */
202     XVisualInfo                   *visual;       /* information about the GL visual */
203     RECT                           rect;         /* drawable rect, relative to whole window drawable */
204 };
205
206 /* X context to associate a struct gl_drawable to an hwnd */
207 static XContext gl_hwnd_context;
208 /* X context to associate a struct gl_drawable to a pbuffer hdc */
209 static XContext gl_pbuffer_context;
210
211 static const struct gdi_dc_funcs glxdrv_funcs;
212
213 static inline struct glx_physdev *get_glxdrv_dev( PHYSDEV dev )
214 {
215     return (struct glx_physdev *)dev;
216 }
217
218 static struct list context_list = LIST_INIT( context_list );
219 static struct WineGLInfo WineGLInfo = { 0 };
220 static struct wgl_pixel_format *pixel_formats;
221 static int nb_pixel_formats, nb_onscreen_formats;
222 static int use_render_texture_emulation = 1;
223 static BOOL has_swap_control;
224 static int swap_interval = 1;
225
226 static CRITICAL_SECTION context_section;
227 static CRITICAL_SECTION_DEBUG critsect_debug =
228 {
229     0, 0, &context_section,
230     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
231       0, 0, { (DWORD_PTR)(__FILE__ ": context_section") }
232 };
233 static CRITICAL_SECTION context_section = { &critsect_debug, -1, 0, 0, 0, 0 };
234
235 static struct opengl_funcs opengl_funcs;
236
237 #define USE_GL_FUNC(name) #name,
238 static const char *opengl_func_names[] = { ALL_WGL_FUNCS };
239 #undef USE_GL_FUNC
240
241 static void X11DRV_WineGL_LoadExtensions(void);
242 static void init_pixel_formats( Display *display );
243 static BOOL glxRequireVersion(int requiredVersion);
244
245 static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
246   TRACE("  - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion);
247   TRACE("  - dwFlags : ");
248 #define TEST_AND_DUMP(t,tv) if ((t) & (tv)) TRACE(#tv " ")
249   TEST_AND_DUMP(ppfd->dwFlags, PFD_DEPTH_DONTCARE);
250   TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER);
251   TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER_DONTCARE);
252   TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_WINDOW);
253   TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_BITMAP);
254   TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_ACCELERATED);
255   TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_FORMAT);
256   TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_PALETTE);
257   TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_SYSTEM_PALETTE);
258   TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO);
259   TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO_DONTCARE);
260   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_GDI);
261   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_OPENGL);
262   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_COPY);
263   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_EXCHANGE);
264   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_LAYER_BUFFERS);
265   /* PFD_SUPPORT_COMPOSITION is new in Vista, it is similar to composition
266    * under X e.g. COMPOSITE + GLX_EXT_TEXTURE_FROM_PIXMAP. */
267   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_COMPOSITION);
268 #undef TEST_AND_DUMP
269   TRACE("\n");
270
271   TRACE("  - iPixelType : ");
272   switch (ppfd->iPixelType) {
273   case PFD_TYPE_RGBA: TRACE("PFD_TYPE_RGBA"); break;
274   case PFD_TYPE_COLORINDEX: TRACE("PFD_TYPE_COLORINDEX"); break;
275   }
276   TRACE("\n");
277
278   TRACE("  - Color   : %d\n", ppfd->cColorBits);
279   TRACE("  - Red     : %d\n", ppfd->cRedBits);
280   TRACE("  - Green   : %d\n", ppfd->cGreenBits);
281   TRACE("  - Blue    : %d\n", ppfd->cBlueBits);
282   TRACE("  - Alpha   : %d\n", ppfd->cAlphaBits);
283   TRACE("  - Accum   : %d\n", ppfd->cAccumBits);
284   TRACE("  - Depth   : %d\n", ppfd->cDepthBits);
285   TRACE("  - Stencil : %d\n", ppfd->cStencilBits);
286   TRACE("  - Aux     : %d\n", ppfd->cAuxBuffers);
287
288   TRACE("  - iLayerType : ");
289   switch (ppfd->iLayerType) {
290   case PFD_MAIN_PLANE: TRACE("PFD_MAIN_PLANE"); break;
291   case PFD_OVERLAY_PLANE: TRACE("PFD_OVERLAY_PLANE"); break;
292   case (BYTE)PFD_UNDERLAY_PLANE: TRACE("PFD_UNDERLAY_PLANE"); break;
293   }
294   TRACE("\n");
295 }
296
297 #define PUSH1(attribs,att)        do { attribs[nAttribs++] = (att); } while (0)
298 #define PUSH2(attribs,att,value)  do { attribs[nAttribs++] = (att); attribs[nAttribs++] = (value); } while(0)
299
300 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
301 /* GLX 1.0 */
302 MAKE_FUNCPTR(glXChooseVisual)
303 MAKE_FUNCPTR(glXCopyContext)
304 MAKE_FUNCPTR(glXCreateContext)
305 MAKE_FUNCPTR(glXCreateGLXPixmap)
306 MAKE_FUNCPTR(glXGetCurrentContext)
307 MAKE_FUNCPTR(glXGetCurrentDrawable)
308 MAKE_FUNCPTR(glXDestroyContext)
309 MAKE_FUNCPTR(glXDestroyGLXPixmap)
310 MAKE_FUNCPTR(glXGetConfig)
311 MAKE_FUNCPTR(glXIsDirect)
312 MAKE_FUNCPTR(glXMakeCurrent)
313 MAKE_FUNCPTR(glXSwapBuffers)
314 MAKE_FUNCPTR(glXQueryExtension)
315 MAKE_FUNCPTR(glXQueryVersion)
316
317 /* GLX 1.1 */
318 MAKE_FUNCPTR(glXGetClientString)
319 MAKE_FUNCPTR(glXQueryExtensionsString)
320 MAKE_FUNCPTR(glXQueryServerString)
321
322 /* GLX 1.3 */
323 MAKE_FUNCPTR(glXGetFBConfigs)
324 MAKE_FUNCPTR(glXChooseFBConfig)
325 MAKE_FUNCPTR(glXCreatePbuffer)
326 MAKE_FUNCPTR(glXCreateNewContext)
327 MAKE_FUNCPTR(glXDestroyPbuffer)
328 MAKE_FUNCPTR(glXGetFBConfigAttrib)
329 MAKE_FUNCPTR(glXGetVisualFromFBConfig)
330 MAKE_FUNCPTR(glXMakeContextCurrent)
331 MAKE_FUNCPTR(glXQueryDrawable)
332 MAKE_FUNCPTR(glXGetCurrentReadDrawable)
333 #undef MAKE_FUNCPTR
334
335 /* GLX Extensions */
336 static GLXContext (*pglXCreateContextAttribsARB)(Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
337 static void* (*pglXGetProcAddressARB)(const GLubyte *);
338 static int   (*pglXSwapIntervalSGI)(int);
339
340 /* NV GLX Extension */
341 static void* (*pglXAllocateMemoryNV)(GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
342 static void  (*pglXFreeMemoryNV)(GLvoid *pointer);
343
344 /* MESA GLX Extensions */
345 static void (*pglXCopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
346
347 /* Standard OpenGL */
348 static void (*pglFinish)(void);
349 static void (*pglFlush)(void);
350
351 static void wglFinish(void);
352 static void wglFlush(void);
353
354 /* check if the extension is present in the list */
355 static BOOL has_extension( const char *list, const char *ext )
356 {
357     size_t len = strlen( ext );
358
359     while (list)
360     {
361         while (*list == ' ') list++;
362         if (!strncmp( list, ext, len ) && (!list[len] || list[len] == ' ')) return TRUE;
363         list = strchr( list, ' ' );
364     }
365     return FALSE;
366 }
367
368 static int GLXErrorHandler(Display *dpy, XErrorEvent *event, void *arg)
369 {
370     /* In the future we might want to find the exact X or GLX error to report back to the app */
371     return 1;
372 }
373
374 static BOOL X11DRV_WineGL_InitOpenglInfo(void)
375 {
376     int screen = DefaultScreen(gdi_display);
377     Window win = 0, root = 0;
378     const char *gl_renderer;
379     const char* str;
380     XVisualInfo *vis;
381     GLXContext ctx = NULL;
382     XSetWindowAttributes attr;
383     BOOL ret = FALSE;
384     int attribList[] = {GLX_RGBA, GLX_DOUBLEBUFFER, None};
385
386     attr.override_redirect = True;
387     attr.colormap = None;
388     attr.border_pixel = 0;
389
390     vis = pglXChooseVisual(gdi_display, screen, attribList);
391     if (vis) {
392 #ifdef __i386__
393         WORD old_fs = wine_get_fs();
394         /* Create a GLX Context. Without one we can't query GL information */
395         ctx = pglXCreateContext(gdi_display, vis, None, GL_TRUE);
396         if (wine_get_fs() != old_fs)
397         {
398             wine_set_fs( old_fs );
399             ERR( "%%fs register corrupted, probably broken ATI driver, disabling OpenGL.\n" );
400             ERR( "You need to set the \"UseFastTls\" option to \"2\" in your X config file.\n" );
401             goto done;
402         }
403 #else
404         ctx = pglXCreateContext(gdi_display, vis, None, GL_TRUE);
405 #endif
406     }
407     if (!ctx) goto done;
408
409     root = RootWindow( gdi_display, vis->screen );
410     if (vis->visual != DefaultVisual( gdi_display, vis->screen ))
411         attr.colormap = XCreateColormap( gdi_display, root, vis->visual, AllocNone );
412     if ((win = XCreateWindow( gdi_display, root, -1, -1, 1, 1, 0, vis->depth, InputOutput,
413                               vis->visual, CWBorderPixel | CWOverrideRedirect | CWColormap, &attr )))
414         XMapWindow( gdi_display, win );
415     else
416         win = root;
417
418     if(pglXMakeCurrent(gdi_display, win, ctx) == 0)
419     {
420         ERR_(winediag)( "Unable to activate OpenGL context, most likely your OpenGL drivers haven't been installed correctly\n" );
421         goto done;
422     }
423     gl_renderer = (const char *)opengl_funcs.gl.p_glGetString(GL_RENDERER);
424     WineGLInfo.glVersion = (const char *) opengl_funcs.gl.p_glGetString(GL_VERSION);
425     str = (const char *) opengl_funcs.gl.p_glGetString(GL_EXTENSIONS);
426     WineGLInfo.glExtensions = HeapAlloc(GetProcessHeap(), 0, strlen(str)+1);
427     strcpy(WineGLInfo.glExtensions, str);
428
429     /* Get the common GLX version supported by GLX client and server ( major/minor) */
430     pglXQueryVersion(gdi_display, &WineGLInfo.glxVersion[0], &WineGLInfo.glxVersion[1]);
431
432     WineGLInfo.glxServerVersion = pglXQueryServerString(gdi_display, screen, GLX_VERSION);
433     WineGLInfo.glxServerVendor = pglXQueryServerString(gdi_display, screen, GLX_VENDOR);
434     WineGLInfo.glxServerExtensions = pglXQueryServerString(gdi_display, screen, GLX_EXTENSIONS);
435
436     WineGLInfo.glxClientVersion = pglXGetClientString(gdi_display, GLX_VERSION);
437     WineGLInfo.glxClientVendor = pglXGetClientString(gdi_display, GLX_VENDOR);
438     WineGLInfo.glxClientExtensions = pglXGetClientString(gdi_display, GLX_EXTENSIONS);
439
440     WineGLInfo.glxExtensions = pglXQueryExtensionsString(gdi_display, screen);
441     WineGLInfo.glxDirect = pglXIsDirect(gdi_display, ctx);
442
443     TRACE("GL version             : %s.\n", WineGLInfo.glVersion);
444     TRACE("GL renderer            : %s.\n", gl_renderer);
445     TRACE("GLX version            : %d.%d.\n", WineGLInfo.glxVersion[0], WineGLInfo.glxVersion[1]);
446     TRACE("Server GLX version     : %s.\n", WineGLInfo.glxServerVersion);
447     TRACE("Server GLX vendor:     : %s.\n", WineGLInfo.glxServerVendor);
448     TRACE("Client GLX version     : %s.\n", WineGLInfo.glxClientVersion);
449     TRACE("Client GLX vendor:     : %s.\n", WineGLInfo.glxClientVendor);
450     TRACE("Direct rendering enabled: %s\n", WineGLInfo.glxDirect ? "True" : "False");
451
452     if(!WineGLInfo.glxDirect)
453     {
454         int fd = ConnectionNumber(gdi_display);
455         struct sockaddr_un uaddr;
456         unsigned int uaddrlen = sizeof(struct sockaddr_un);
457
458         /* In general indirect rendering on a local X11 server indicates a driver problem.
459          * Detect a local X11 server by checking whether the X11 socket is a Unix socket.
460          */
461         if(!getsockname(fd, (struct sockaddr *)&uaddr, &uaddrlen) && uaddr.sun_family == AF_UNIX)
462             ERR_(winediag)("Direct rendering is disabled, most likely your OpenGL drivers "
463                            "haven't been installed correctly (using GL renderer %s, version %s).\n",
464                            debugstr_a(gl_renderer), debugstr_a(WineGLInfo.glVersion));
465     }
466     else
467     {
468         /* In general you would expect that if direct rendering is returned, that you receive hardware
469          * accelerated OpenGL rendering. The definition of direct rendering is that rendering is performed
470          * client side without sending all GL commands to X using the GLX protocol. When Mesa falls back to
471          * software rendering, it shows direct rendering.
472          *
473          * Depending on the cause of software rendering a different rendering string is shown. In case Mesa fails
474          * to load a DRI module 'Software Rasterizer' is returned. When Mesa is compiled as a OpenGL reference driver
475          * it shows 'Mesa X11'.
476          */
477         if(!strcmp(gl_renderer, "Software Rasterizer") || !strcmp(gl_renderer, "Mesa X11"))
478             ERR_(winediag)("The Mesa OpenGL driver is using software rendering, most likely your OpenGL "
479                            "drivers haven't been installed correctly (using GL renderer %s, version %s).\n",
480                            debugstr_a(gl_renderer), debugstr_a(WineGLInfo.glVersion));
481     }
482     ret = TRUE;
483
484 done:
485     if(vis) XFree(vis);
486     if(ctx) {
487         pglXMakeCurrent(gdi_display, None, NULL);    
488         pglXDestroyContext(gdi_display, ctx);
489     }
490     if (win != root) XDestroyWindow( gdi_display, win );
491     if (attr.colormap) XFreeColormap( gdi_display, attr.colormap );
492     if (!ret) ERR(" couldn't initialize OpenGL, expect problems\n");
493     return ret;
494 }
495
496 static BOOL has_opengl(void)
497 {
498     static int init_done;
499     static void *opengl_handle;
500
501     char buffer[200];
502     int error_base, event_base;
503     unsigned int i;
504
505     if (init_done) return (opengl_handle != NULL);
506     init_done = 1;
507
508     /* No need to load any other libraries as according to the ABI, libGL should be self-sufficient
509        and include all dependencies */
510     opengl_handle = wine_dlopen(SONAME_LIBGL, RTLD_NOW|RTLD_GLOBAL, buffer, sizeof(buffer));
511     if (opengl_handle == NULL)
512     {
513         ERR( "Failed to load libGL: %s\n", buffer );
514         ERR( "OpenGL support is disabled.\n");
515         return FALSE;
516     }
517
518     for (i = 0; i < sizeof(opengl_func_names)/sizeof(opengl_func_names[0]); i++)
519     {
520         if (!(((void **)&opengl_funcs.gl)[i] = wine_dlsym( opengl_handle, opengl_func_names[i], NULL, 0 )))
521         {
522             ERR( "%s not found in libGL, disabling OpenGL.\n", opengl_func_names[i] );
523             goto failed;
524         }
525     }
526
527     /* redirect some standard OpenGL functions */
528 #define REDIRECT(func) \
529     do { p##func = opengl_funcs.gl.p_##func; opengl_funcs.gl.p_##func = w##func; } while(0)
530     REDIRECT( glFinish );
531     REDIRECT( glFlush );
532 #undef REDIRECT
533
534     pglXGetProcAddressARB = wine_dlsym(opengl_handle, "glXGetProcAddressARB", NULL, 0);
535     if (pglXGetProcAddressARB == NULL) {
536         ERR("Could not find glXGetProcAddressARB in libGL, disabling OpenGL.\n");
537         goto failed;
538     }
539
540 #define LOAD_FUNCPTR(f) do if((p##f = (void*)pglXGetProcAddressARB((const unsigned char*)#f)) == NULL) \
541     { \
542         ERR( "%s not found in libGL, disabling OpenGL.\n", #f ); \
543         goto failed; \
544     } while(0)
545
546     /* GLX 1.0 */
547     LOAD_FUNCPTR(glXChooseVisual);
548     LOAD_FUNCPTR(glXCopyContext);
549     LOAD_FUNCPTR(glXCreateContext);
550     LOAD_FUNCPTR(glXCreateGLXPixmap);
551     LOAD_FUNCPTR(glXGetCurrentContext);
552     LOAD_FUNCPTR(glXGetCurrentDrawable);
553     LOAD_FUNCPTR(glXDestroyContext);
554     LOAD_FUNCPTR(glXDestroyGLXPixmap);
555     LOAD_FUNCPTR(glXGetConfig);
556     LOAD_FUNCPTR(glXIsDirect);
557     LOAD_FUNCPTR(glXMakeCurrent);
558     LOAD_FUNCPTR(glXSwapBuffers);
559     LOAD_FUNCPTR(glXQueryExtension);
560     LOAD_FUNCPTR(glXQueryVersion);
561
562     /* GLX 1.1 */
563     LOAD_FUNCPTR(glXGetClientString);
564     LOAD_FUNCPTR(glXQueryExtensionsString);
565     LOAD_FUNCPTR(glXQueryServerString);
566
567     /* GLX 1.3 */
568     LOAD_FUNCPTR(glXCreatePbuffer);
569     LOAD_FUNCPTR(glXCreateNewContext);
570     LOAD_FUNCPTR(glXDestroyPbuffer);
571     LOAD_FUNCPTR(glXMakeContextCurrent);
572     LOAD_FUNCPTR(glXGetCurrentReadDrawable);
573     LOAD_FUNCPTR(glXGetFBConfigs);
574 #undef LOAD_FUNCPTR
575
576 /* It doesn't matter if these fail. They'll only be used if the driver reports
577    the associated extension is available (and if a driver reports the extension
578    is available but fails to provide the functions, it's quite broken) */
579 #define LOAD_FUNCPTR(f) p##f = pglXGetProcAddressARB((const GLubyte *)#f)
580     /* ARB GLX Extension */
581     LOAD_FUNCPTR(glXCreateContextAttribsARB);
582     /* SGI GLX Extension */
583     LOAD_FUNCPTR(glXSwapIntervalSGI);
584     /* NV GLX Extension */
585     LOAD_FUNCPTR(glXAllocateMemoryNV);
586     LOAD_FUNCPTR(glXFreeMemoryNV);
587 #undef LOAD_FUNCPTR
588
589     if(!X11DRV_WineGL_InitOpenglInfo()) goto failed;
590
591     if (pglXQueryExtension(gdi_display, &error_base, &event_base)) {
592         TRACE("GLX is up and running error_base = %d\n", error_base);
593     } else {
594         ERR( "GLX extension is missing, disabling OpenGL.\n" );
595         goto failed;
596     }
597     gl_hwnd_context = XUniqueContext();
598     gl_pbuffer_context = XUniqueContext();
599
600     /* In case of GLX you have direct and indirect rendering. Most of the time direct rendering is used
601      * as in general only that is hardware accelerated. In some cases like in case of remote X indirect
602      * rendering is used.
603      *
604      * The main problem for our OpenGL code is that we need certain GLX calls but their presence
605      * depends on the reported GLX client / server version and on the client / server extension list.
606      * Those don't have to be the same.
607      *
608      * In general the server GLX information lists the capabilities in case of indirect rendering.
609      * When direct rendering is used, the OpenGL client library is responsible for which GLX calls are
610      * available and in that case the client GLX informat can be used.
611      * OpenGL programs should use the 'intersection' of both sets of information which is advertised
612      * in the GLX version/extension list. When a program does this it works for certain for both
613      * direct and indirect rendering.
614      *
615      * The problem we are having in this area is that ATI's Linux drivers are broken. For some reason
616      * they haven't added some very important GLX extensions like GLX_SGIX_fbconfig to their client
617      * extension list which causes this extension not to be listed. (Wine requires this extension).
618      * ATI advertises a GLX client version of 1.3 which implies that this fbconfig extension among
619      * pbuffers is around.
620      *
621      * In order to provide users of Ati's proprietary drivers with OpenGL support, we need to detect
622      * the ATI drivers and from then on use GLX client information for them.
623      */
624
625     if(glxRequireVersion(3)) {
626         pglXChooseFBConfig = pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfig");
627         pglXGetFBConfigAttrib = pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttrib");
628         pglXGetVisualFromFBConfig = pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfig");
629         pglXQueryDrawable = pglXGetProcAddressARB((const GLubyte *) "glXQueryDrawable");
630     } else if (has_extension( WineGLInfo.glxExtensions, "GLX_SGIX_fbconfig")) {
631         pglXChooseFBConfig = pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfigSGIX");
632         pglXGetFBConfigAttrib = pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttribSGIX");
633         pglXGetVisualFromFBConfig = pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfigSGIX");
634
635         /* The mesa libGL client library seems to forward glXQueryDrawable to the Xserver, so only
636          * enable this function when the Xserver understand GLX 1.3 or newer
637          */
638         pglXQueryDrawable = NULL;
639      } else if(strcmp("ATI", WineGLInfo.glxClientVendor) == 0) {
640         TRACE("Overriding ATI GLX capabilities!\n");
641         pglXChooseFBConfig = pglXGetProcAddressARB((const GLubyte *) "glXChooseFBConfig");
642         pglXGetFBConfigAttrib = pglXGetProcAddressARB((const GLubyte *) "glXGetFBConfigAttrib");
643         pglXGetVisualFromFBConfig = pglXGetProcAddressARB((const GLubyte *) "glXGetVisualFromFBConfig");
644         pglXQueryDrawable = pglXGetProcAddressARB((const GLubyte *) "glXQueryDrawable");
645
646         /* Use client GLX information in case of the ATI drivers. We override the
647          * capabilities over here and not somewhere else as ATI might better their
648          * life in the future. In case they release proper drivers this block of
649          * code won't be called. */
650         WineGLInfo.glxExtensions = WineGLInfo.glxClientExtensions;
651     } else {
652          ERR(" glx_version is %s and GLX_SGIX_fbconfig extension is unsupported. Expect problems.\n", WineGLInfo.glxServerVersion);
653     }
654
655     if (has_extension( WineGLInfo.glxExtensions, "GLX_MESA_copy_sub_buffer")) {
656         pglXCopySubBufferMESA = pglXGetProcAddressARB((const GLubyte *) "glXCopySubBufferMESA");
657     }
658
659     X11DRV_WineGL_LoadExtensions();
660     init_pixel_formats( gdi_display );
661     return TRUE;
662
663 failed:
664     wine_dlclose(opengl_handle, NULL, 0);
665     opengl_handle = NULL;
666     return FALSE;
667 }
668
669 static int describeContext( struct wgl_context *ctx ) {
670     int tmp;
671     int ctx_vis_id;
672     TRACE(" Context %p have (vis:%p):\n", ctx, ctx->vis);
673     pglXGetFBConfigAttrib(gdi_display, ctx->fmt->fbconfig, GLX_FBCONFIG_ID, &tmp);
674     TRACE(" - FBCONFIG_ID 0x%x\n", tmp);
675     pglXGetFBConfigAttrib(gdi_display, ctx->fmt->fbconfig, GLX_VISUAL_ID, &tmp);
676     TRACE(" - VISUAL_ID 0x%x\n", tmp);
677     ctx_vis_id = tmp;
678     return ctx_vis_id;
679 }
680
681 static int ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, struct wgl_pbuffer* pbuf) {
682   int nAttribs = 0;
683   unsigned cur = 0; 
684   int pop;
685   int drawattrib = 0;
686   int nvfloatattrib = GLX_DONT_CARE;
687   int pixelattrib = GLX_DONT_CARE;
688
689   /* The list of WGL attributes is allowed to be NULL. We don't return here for NULL
690    * because we need to do fixups for GLX_DRAWABLE_TYPE/GLX_RENDER_TYPE/GLX_FLOAT_COMPONENTS_NV. */
691   while (iWGLAttr && 0 != iWGLAttr[cur]) {
692     TRACE("pAttr[%d] = %x\n", cur, iWGLAttr[cur]);
693
694     switch (iWGLAttr[cur]) {
695     case WGL_AUX_BUFFERS_ARB:
696       pop = iWGLAttr[++cur];
697       PUSH2(oGLXAttr, GLX_AUX_BUFFERS, pop);
698       TRACE("pAttr[%d] = GLX_AUX_BUFFERS: %d\n", cur, pop);
699       break;
700     case WGL_COLOR_BITS_ARB:
701       pop = iWGLAttr[++cur];
702       PUSH2(oGLXAttr, GLX_BUFFER_SIZE, pop);
703       TRACE("pAttr[%d] = GLX_BUFFER_SIZE: %d\n", cur, pop);
704       break;
705     case WGL_BLUE_BITS_ARB:
706       pop = iWGLAttr[++cur];
707       PUSH2(oGLXAttr, GLX_BLUE_SIZE, pop);
708       TRACE("pAttr[%d] = GLX_BLUE_SIZE: %d\n", cur, pop);
709       break;
710     case WGL_RED_BITS_ARB:
711       pop = iWGLAttr[++cur];
712       PUSH2(oGLXAttr, GLX_RED_SIZE, pop);
713       TRACE("pAttr[%d] = GLX_RED_SIZE: %d\n", cur, pop);
714       break;
715     case WGL_GREEN_BITS_ARB:
716       pop = iWGLAttr[++cur];
717       PUSH2(oGLXAttr, GLX_GREEN_SIZE, pop);
718       TRACE("pAttr[%d] = GLX_GREEN_SIZE: %d\n", cur, pop);
719       break;
720     case WGL_ALPHA_BITS_ARB:
721       pop = iWGLAttr[++cur];
722       PUSH2(oGLXAttr, GLX_ALPHA_SIZE, pop);
723       TRACE("pAttr[%d] = GLX_ALPHA_SIZE: %d\n", cur, pop);
724       break;
725     case WGL_DEPTH_BITS_ARB:
726       pop = iWGLAttr[++cur];
727       PUSH2(oGLXAttr, GLX_DEPTH_SIZE, pop);
728       TRACE("pAttr[%d] = GLX_DEPTH_SIZE: %d\n", cur, pop);
729       break;
730     case WGL_STENCIL_BITS_ARB:
731       pop = iWGLAttr[++cur];
732       PUSH2(oGLXAttr, GLX_STENCIL_SIZE, pop);
733       TRACE("pAttr[%d] = GLX_STENCIL_SIZE: %d\n", cur, pop);
734       break;
735     case WGL_DOUBLE_BUFFER_ARB:
736       pop = iWGLAttr[++cur];
737       PUSH2(oGLXAttr, GLX_DOUBLEBUFFER, pop);
738       TRACE("pAttr[%d] = GLX_DOUBLEBUFFER: %d\n", cur, pop);
739       break;
740     case WGL_STEREO_ARB:
741       pop = iWGLAttr[++cur];
742       PUSH2(oGLXAttr, GLX_STEREO, pop);
743       TRACE("pAttr[%d] = GLX_STEREO: %d\n", cur, pop);
744       break;
745
746     case WGL_PIXEL_TYPE_ARB:
747       pop = iWGLAttr[++cur];
748       TRACE("pAttr[%d] = WGL_PIXEL_TYPE_ARB: %d\n", cur, pop);
749       switch (pop) {
750       case WGL_TYPE_COLORINDEX_ARB: pixelattrib = GLX_COLOR_INDEX_BIT; break ;
751       case WGL_TYPE_RGBA_ARB: pixelattrib = GLX_RGBA_BIT; break ;
752       /* 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 */
753       case WGL_TYPE_RGBA_FLOAT_ATI: pixelattrib = GLX_RGBA_FLOAT_BIT; break ;
754       case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT: pixelattrib = GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT; break ;
755       default:
756         ERR("unexpected PixelType(%x)\n", pop); 
757         pop = 0;
758       }
759       break;
760
761     case WGL_SUPPORT_GDI_ARB:
762       /* This flag is set in a pixel format */
763       pop = iWGLAttr[++cur];
764       TRACE("pAttr[%d] = WGL_SUPPORT_GDI_ARB: %d\n", cur, pop);
765       break;
766
767     case WGL_DRAW_TO_BITMAP_ARB:
768       /* This flag is set in a pixel format */
769       pop = iWGLAttr[++cur];
770       TRACE("pAttr[%d] = WGL_DRAW_TO_BITMAP_ARB: %d\n", cur, pop);
771       break;
772
773     case WGL_DRAW_TO_WINDOW_ARB:
774       pop = iWGLAttr[++cur];
775       TRACE("pAttr[%d] = WGL_DRAW_TO_WINDOW_ARB: %d\n", cur, pop);
776       /* GLX_DRAWABLE_TYPE flags need to be OR'd together. See below. */
777       if (pop) {
778         drawattrib |= GLX_WINDOW_BIT;
779       }
780       break;
781
782     case WGL_DRAW_TO_PBUFFER_ARB:
783       pop = iWGLAttr[++cur];
784       TRACE("pAttr[%d] = WGL_DRAW_TO_PBUFFER_ARB: %d\n", cur, pop);
785       /* GLX_DRAWABLE_TYPE flags need to be OR'd together. See below. */
786       if (pop) {
787         drawattrib |= GLX_PBUFFER_BIT;
788       }
789       break;
790
791     case WGL_ACCELERATION_ARB:
792       /* This flag is set in a pixel format */
793       pop = iWGLAttr[++cur];
794       TRACE("pAttr[%d] = WGL_ACCELERATION_ARB: %d\n", cur, pop);
795       break;
796
797     case WGL_SUPPORT_OPENGL_ARB:
798       pop = iWGLAttr[++cur];
799       /** nothing to do, if we are here, supposing support Accelerated OpenGL */
800       TRACE("pAttr[%d] = WGL_SUPPORT_OPENGL_ARB: %d\n", cur, pop);
801       break;
802
803     case WGL_SWAP_METHOD_ARB:
804       pop = iWGLAttr[++cur];
805       /* For now we ignore this and just return SWAP_EXCHANGE */
806       TRACE("pAttr[%d] = WGL_SWAP_METHOD_ARB: %#x\n", cur, pop);
807       break;
808
809     case WGL_PBUFFER_LARGEST_ARB:
810       pop = iWGLAttr[++cur];
811       PUSH2(oGLXAttr, GLX_LARGEST_PBUFFER, pop);
812       TRACE("pAttr[%d] = GLX_LARGEST_PBUFFER: %x\n", cur, pop);
813       break;
814
815     case WGL_SAMPLE_BUFFERS_ARB:
816       pop = iWGLAttr[++cur];
817       PUSH2(oGLXAttr, GLX_SAMPLE_BUFFERS_ARB, pop);
818       TRACE("pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x\n", cur, pop);
819       break;
820
821     case WGL_SAMPLES_ARB:
822       pop = iWGLAttr[++cur];
823       PUSH2(oGLXAttr, GLX_SAMPLES_ARB, pop);
824       TRACE("pAttr[%d] = GLX_SAMPLES_ARB: %x\n", cur, pop);
825       break;
826
827     case WGL_TEXTURE_FORMAT_ARB:
828     case WGL_TEXTURE_TARGET_ARB:
829     case WGL_MIPMAP_TEXTURE_ARB:
830       TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr[cur], iWGLAttr[cur + 1]);
831       pop = iWGLAttr[++cur];
832       if (NULL == pbuf) {
833         ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr[cur]);
834       }
835       if (!use_render_texture_emulation) {
836         if (WGL_NO_TEXTURE_ARB != pop) {
837           ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr[cur]);
838           return -1; /** error: don't support it */
839         } else {
840           drawattrib |= GLX_PBUFFER_BIT;
841         }
842       }
843       break ;
844     case WGL_FLOAT_COMPONENTS_NV:
845       nvfloatattrib = iWGLAttr[++cur];
846       TRACE("pAttr[%d] = WGL_FLOAT_COMPONENTS_NV: %x\n", cur, nvfloatattrib);
847       break ;
848     case WGL_BIND_TO_TEXTURE_DEPTH_NV:
849     case WGL_BIND_TO_TEXTURE_RGB_ARB:
850     case WGL_BIND_TO_TEXTURE_RGBA_ARB:
851     case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV:
852     case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV:
853     case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV:
854     case WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV:
855       pop = iWGLAttr[++cur];
856       /** cannot be converted, see direct handling on 
857        *   - wglGetPixelFormatAttribivARB
858        *  TODO: wglChoosePixelFormat
859        */
860       break ;
861     case WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT:
862       pop = iWGLAttr[++cur];
863       PUSH2(oGLXAttr, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, pop);
864       TRACE("pAttr[%d] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT: %x\n", cur, pop);
865       break ;
866
867     case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT:
868       pop = iWGLAttr[++cur];
869       PUSH2(oGLXAttr, GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT, pop);
870       TRACE("pAttr[%d] = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT: %x\n", cur, pop);
871       break ;
872     default:
873       FIXME("unsupported %x WGL Attribute\n", iWGLAttr[cur]);
874       break;
875     }
876     ++cur;
877   }
878
879   /* By default glXChooseFBConfig defaults to GLX_WINDOW_BIT. wglChoosePixelFormatARB searches through
880    * all formats. Unless drawattrib is set to a non-zero value override it with GLX_DONT_CARE, so that
881    * pixmap and pbuffer formats appear as well. */
882   if (!drawattrib) drawattrib = GLX_DONT_CARE;
883   PUSH2(oGLXAttr, GLX_DRAWABLE_TYPE, drawattrib);
884   TRACE("pAttr[?] = GLX_DRAWABLE_TYPE: %#x\n", drawattrib);
885
886   /* By default glXChooseFBConfig uses GLX_RGBA_BIT as the default value. Since wglChoosePixelFormatARB
887    * searches in all formats we have to do the same. For this reason we set GLX_RENDER_TYPE to
888    * GLX_DONT_CARE unless it is overridden. */
889   PUSH2(oGLXAttr, GLX_RENDER_TYPE, pixelattrib);
890   TRACE("pAttr[?] = GLX_RENDER_TYPE: %#x\n", pixelattrib);
891
892   /* Set GLX_FLOAT_COMPONENTS_NV all the time */
893   if (has_extension(WineGLInfo.glxExtensions, "GLX_NV_float_buffer")) {
894     PUSH2(oGLXAttr, GLX_FLOAT_COMPONENTS_NV, nvfloatattrib);
895     TRACE("pAttr[?] = GLX_FLOAT_COMPONENTS_NV: %#x\n", nvfloatattrib);
896   }
897
898   return nAttribs;
899 }
900
901 static int get_render_type_from_fbconfig(Display *display, GLXFBConfig fbconfig)
902 {
903     int render_type=0, render_type_bit;
904     pglXGetFBConfigAttrib(display, fbconfig, GLX_RENDER_TYPE, &render_type_bit);
905     switch(render_type_bit)
906     {
907         case GLX_RGBA_BIT:
908             render_type = GLX_RGBA_TYPE;
909             break;
910         case GLX_COLOR_INDEX_BIT:
911             render_type = GLX_COLOR_INDEX_TYPE;
912             break;
913         case GLX_RGBA_FLOAT_BIT:
914             render_type = GLX_RGBA_FLOAT_TYPE;
915             break;
916         case GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT:
917             render_type = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT;
918             break;
919         default:
920             ERR("Unknown render_type: %x\n", render_type_bit);
921     }
922     return render_type;
923 }
924
925 /* Check whether a fbconfig is suitable for Windows-style bitmap rendering */
926 static BOOL check_fbconfig_bitmap_capability(Display *display, GLXFBConfig fbconfig)
927 {
928     int dbuf, value;
929     pglXGetFBConfigAttrib(display, fbconfig, GLX_DOUBLEBUFFER, &dbuf);
930     pglXGetFBConfigAttrib(gdi_display, fbconfig, GLX_DRAWABLE_TYPE, &value);
931
932     /* Windows only supports bitmap rendering on single buffered formats, further the fbconfig needs to have
933      * the GLX_PIXMAP_BIT set. */
934     return !dbuf && (value & GLX_PIXMAP_BIT);
935 }
936
937 static void init_pixel_formats( Display *display )
938 {
939     struct wgl_pixel_format *list;
940     int size = 0, onscreen_size = 0;
941     int fmt_id, nCfgs, i, run, bmp_formats;
942     GLXFBConfig* cfgs;
943     XVisualInfo *visinfo;
944
945     cfgs = pglXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
946     if (NULL == cfgs || 0 == nCfgs) {
947         if(cfgs != NULL) XFree(cfgs);
948         ERR("glXChooseFBConfig returns NULL\n");
949         return;
950     }
951
952     /* Bitmap rendering on Windows implies the use of the Microsoft GDI software renderer.
953      * Further most GLX drivers only offer pixmap rendering using indirect rendering (except for modern drivers which support 'AIGLX' / composite).
954      * Indirect rendering can indicate software rendering (on Nvidia it is hw accelerated)
955      * Since bitmap rendering implies the use of software rendering we can safely use indirect rendering for bitmaps.
956      *
957      * Below we count the number of formats which are suitable for bitmap rendering. Windows restricts bitmap rendering to single buffered formats.
958      */
959     for(i=0, bmp_formats=0; i<nCfgs; i++)
960     {
961         if(check_fbconfig_bitmap_capability(display, cfgs[i]))
962             bmp_formats++;
963     }
964     TRACE("Found %d bitmap capable fbconfigs\n", bmp_formats);
965
966     list = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nCfgs + bmp_formats) * sizeof(*list));
967
968     /* Fill the pixel format list. Put onscreen formats at the top and offscreen ones at the bottom.
969      * Do this as GLX doesn't guarantee that the list is sorted */
970     for(run=0; run < 2; run++)
971     {
972         for(i=0; i<nCfgs; i++) {
973             pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &fmt_id);
974             visinfo = pglXGetVisualFromFBConfig(display, cfgs[i]);
975
976             /* The first run we only add onscreen formats (ones which have an associated X Visual).
977              * The second run we only set offscreen formats. */
978             if(!run && visinfo)
979             {
980                 /* We implement child window rendering using offscreen buffers (using composite or an XPixmap).
981                  * The contents is copied to the destination using XCopyArea. For the copying to work
982                  * the depth of the source and destination window should be the same. In general this should
983                  * not be a problem for OpenGL as drivers only advertise formats with a similar depth (or no depth).
984                  * As of the introduction of composition managers at least Nvidia now also offers ARGB visuals
985                  * with a depth of 32 in addition to the default 24 bit. In order to prevent BadMatch errors we only
986                  * list formats with the same depth. */
987                 if(visinfo->depth != screen_depth)
988                 {
989                     XFree(visinfo);
990                     continue;
991                 }
992
993                 TRACE("Found onscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", fmt_id, size+1, i);
994                 list[size].fbconfig = cfgs[i];
995                 list[size].fmt_id = fmt_id;
996                 list[size].render_type = get_render_type_from_fbconfig(display, cfgs[i]);
997                 list[size].dwFlags = 0;
998                 size++;
999                 onscreen_size++;
1000
1001                 /* Clone a format if it is bitmap capable for indirect rendering to bitmaps */
1002                 if(check_fbconfig_bitmap_capability(display, cfgs[i]))
1003                 {
1004                     TRACE("Found bitmap capable format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", fmt_id, size+1, i);
1005                     list[size].fbconfig = cfgs[i];
1006                     list[size].fmt_id = fmt_id;
1007                     list[size].render_type = get_render_type_from_fbconfig(display, cfgs[i]);
1008                     list[size].dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_GENERIC_FORMAT;
1009                     size++;
1010                     onscreen_size++;
1011                 }
1012             } else if(run && !visinfo) {
1013                 int window_drawable=0;
1014                 pglXGetFBConfigAttrib(gdi_display, cfgs[i], GLX_DRAWABLE_TYPE, &window_drawable);
1015
1016                 /* Recent Nvidia drivers and DRI drivers offer window drawable formats without a visual.
1017                  * This are formats like 16-bit rgb on a 24-bit desktop. In order to support these formats
1018                  * onscreen we would have to use glXCreateWindow instead of XCreateWindow. Further it will
1019                  * likely make our child window opengl rendering more complicated since likely you can't use
1020                  * XCopyArea on a GLX Window.
1021                  * For now ignore fbconfigs which are window drawable but lack a visual. */
1022                 if(window_drawable & GLX_WINDOW_BIT)
1023                 {
1024                     TRACE("Skipping FBCONFIG_ID 0x%x as an offscreen format because it is window_drawable\n", fmt_id);
1025                     continue;
1026                 }
1027
1028                 TRACE("Found offscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", fmt_id, size+1, i);
1029                 list[size].fbconfig = cfgs[i];
1030                 list[size].fmt_id = fmt_id;
1031                 list[size].render_type = get_render_type_from_fbconfig(display, cfgs[i]);
1032                 list[size].dwFlags = 0;
1033                 size++;
1034             }
1035
1036             if (visinfo) XFree(visinfo);
1037         }
1038     }
1039
1040     XFree(cfgs);
1041
1042     pixel_formats = list;
1043     nb_pixel_formats = size;
1044     nb_onscreen_formats = onscreen_size;
1045 }
1046
1047 static inline BOOL is_valid_pixel_format( int format )
1048 {
1049     return format > 0 && format <= nb_pixel_formats;
1050 }
1051
1052 static inline BOOL is_onscreen_pixel_format( int format )
1053 {
1054     return format > 0 && format <= nb_onscreen_formats;
1055 }
1056
1057 /* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones.
1058  * In our WGL implementation we only support a subset of these formats namely the format of
1059  * Wine's main visual and offscreen formats (if they are available).
1060  * This function converts a WGL format to its corresponding GLX one.
1061  */
1062 static const struct wgl_pixel_format *get_pixel_format(Display *display, int iPixelFormat, BOOL AllowOffscreen)
1063 {
1064     /* Check if the pixelformat is valid. Note that it is legal to pass an invalid
1065      * iPixelFormat in case of probing the number of pixelformats.
1066      */
1067     if (is_valid_pixel_format( iPixelFormat ) &&
1068         (is_onscreen_pixel_format( iPixelFormat ) || AllowOffscreen)) {
1069         TRACE("Returning fmt_id=%#x for iPixelFormat=%d\n",
1070               pixel_formats[iPixelFormat-1].fmt_id, iPixelFormat);
1071         return &pixel_formats[iPixelFormat-1];
1072     }
1073     return NULL;
1074 }
1075
1076 static int pixelformat_from_fbconfig_id(XID fbconfig_id)
1077 {
1078     int i;
1079
1080     if (!fbconfig_id) return 0;
1081
1082     for (i = 0; i < nb_pixel_formats; i++)
1083         if (pixel_formats[i].fmt_id == fbconfig_id) return i + 1;
1084
1085     /* This will happen on hwnds without a pixel format set; it's ok */
1086     return 0;
1087 }
1088
1089
1090 /* Mark any allocated context using the glx drawable 'old' to use 'new' */
1091 static void mark_drawable_dirty(Drawable old, Drawable new)
1092 {
1093     struct wgl_context *ctx;
1094
1095     LIST_FOR_EACH_ENTRY( ctx, &context_list, struct wgl_context, entry )
1096     {
1097         if (old == ctx->drawables[0]) {
1098             ctx->drawables[0] = new;
1099             ctx->refresh_drawables = TRUE;
1100         }
1101         if (old == ctx->drawables[1]) {
1102             ctx->drawables[1] = new;
1103             ctx->refresh_drawables = TRUE;
1104         }
1105     }
1106 }
1107
1108 /* Given the current context, make sure its drawable is sync'd */
1109 static inline void sync_context(struct wgl_context *context)
1110 {
1111     EnterCriticalSection( &context_section );
1112     if (context->refresh_drawables) {
1113         if (glxRequireVersion(3))
1114             pglXMakeContextCurrent(gdi_display, context->drawables[0],
1115                                    context->drawables[1], context->ctx);
1116         else
1117             pglXMakeCurrent(gdi_display, context->drawables[0], context->ctx);
1118         context->refresh_drawables = FALSE;
1119     }
1120     LeaveCriticalSection( &context_section );
1121 }
1122
1123
1124 static GLXContext create_glxcontext(Display *display, struct wgl_context *context, GLXContext shareList)
1125 {
1126     GLXContext ctx;
1127
1128     /* We use indirect rendering for rendering to bitmaps. See get_formats for a comment about this. */
1129     BOOL indirect = !(context->fmt->dwFlags & PFD_DRAW_TO_BITMAP);
1130
1131     if(context->gl3_context)
1132     {
1133         if(context->numAttribs)
1134             ctx = pglXCreateContextAttribsARB(gdi_display, context->fmt->fbconfig, shareList, indirect, context->attribList);
1135         else
1136             ctx = pglXCreateContextAttribsARB(gdi_display, context->fmt->fbconfig, shareList, indirect, NULL);
1137     }
1138     else if(context->vis)
1139         ctx = pglXCreateContext(gdi_display, context->vis, shareList, indirect);
1140     else /* Create a GLX Context for a pbuffer */
1141         ctx = pglXCreateNewContext(gdi_display, context->fmt->fbconfig, context->fmt->render_type, shareList, TRUE);
1142
1143     return ctx;
1144 }
1145
1146
1147 /***********************************************************************
1148  *              free_gl_drawable
1149  */
1150 static void free_gl_drawable( struct gl_drawable *gl )
1151 {
1152     switch (gl->type)
1153     {
1154     case DC_GL_WINDOW:
1155     case DC_GL_CHILD_WIN:
1156         XDestroyWindow( gdi_display, gl->drawable );
1157         XFreeColormap( gdi_display, gl->colormap );
1158         break;
1159     case DC_GL_PIXMAP_WIN:
1160         pglXDestroyGLXPixmap( gdi_display, gl->drawable );
1161         XFreePixmap( gdi_display, gl->pixmap );
1162         break;
1163     default:
1164         break;
1165     }
1166     if (gl->visual) XFree( gl->visual );
1167     HeapFree( GetProcessHeap(), 0, gl );
1168 }
1169
1170
1171 /***********************************************************************
1172  *              set_win_format
1173  */
1174 BOOL set_win_format( HWND hwnd, XID fbconfig_id )
1175 {
1176     XSetWindowAttributes attrib;
1177     struct gl_drawable *gl, *prev;
1178     int format;
1179
1180     if (!(format = pixelformat_from_fbconfig_id( fbconfig_id ))) return FALSE;
1181
1182     gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) );
1183     gl->format = &pixel_formats[format - 1];
1184     gl->visual = pglXGetVisualFromFBConfig( gdi_display, gl->format->fbconfig );
1185     if (!gl->visual)
1186     {
1187         HeapFree( GetProcessHeap(), 0, gl );
1188         return FALSE;
1189     }
1190
1191     GetClientRect( hwnd, &gl->rect );
1192     gl->rect.right  = min( max( 1, gl->rect.right ), 65535 );
1193     gl->rect.bottom = min( max( 1, gl->rect.bottom ), 65535 );
1194
1195     if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())  /* top-level window */
1196     {
1197         Window parent = X11DRV_get_whole_window( hwnd );
1198
1199         gl->type = DC_GL_WINDOW;
1200         gl->colormap = XCreateColormap( gdi_display, root_window, gl->visual->visual,
1201                                         (gl->visual->class == PseudoColor ||
1202                                          gl->visual->class == GrayScale ||
1203                                          gl->visual->class == DirectColor) ? AllocAll : AllocNone );
1204         attrib.colormap = gl->colormap;
1205         attrib.bit_gravity = NorthWestGravity;
1206         attrib.win_gravity = NorthWestGravity;
1207         attrib.backing_store = NotUseful;
1208         /* put the initial rect outside of the window, it will be moved into place by SetWindowPos */
1209         OffsetRect( &gl->rect, gl->rect.right, gl->rect.bottom );
1210         if (parent)
1211             gl->drawable = XCreateWindow( gdi_display, parent, gl->rect.left, gl->rect.top,
1212                                           gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
1213                                           0, screen_depth, InputOutput, gl->visual->visual,
1214                                           CWBitGravity | CWWinGravity | CWBackingStore | CWColormap,
1215                                           &attrib );
1216         if (gl->drawable)
1217             XMapWindow( gdi_display, gl->drawable );
1218         else
1219             XFreeColormap( gdi_display, gl->colormap );
1220     }
1221 #ifdef SONAME_LIBXCOMPOSITE
1222     else if(usexcomposite)
1223     {
1224         static Window dummy_parent;
1225
1226         attrib.override_redirect = True;
1227         if (!dummy_parent)
1228         {
1229             dummy_parent = XCreateWindow( gdi_display, root_window, -1, -1, 1, 1, 0, screen_depth,
1230                                          InputOutput, visual, CWOverrideRedirect, &attrib );
1231             XMapWindow( gdi_display, dummy_parent );
1232         }
1233         gl->colormap = XCreateColormap(gdi_display, dummy_parent, gl->visual->visual,
1234                                        (gl->visual->class == PseudoColor ||
1235                                         gl->visual->class == GrayScale ||
1236                                         gl->visual->class == DirectColor) ?
1237                                        AllocAll : AllocNone);
1238         attrib.colormap = gl->colormap;
1239         XInstallColormap(gdi_display, attrib.colormap);
1240
1241         gl->type = DC_GL_CHILD_WIN;
1242         gl->drawable = XCreateWindow( gdi_display, dummy_parent, 0, 0,
1243                                       gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
1244                                       0, gl->visual->depth, InputOutput, gl->visual->visual,
1245                                       CWColormap | CWOverrideRedirect, &attrib );
1246         if (gl->drawable)
1247         {
1248             pXCompositeRedirectWindow(gdi_display, gl->drawable, CompositeRedirectManual);
1249             XMapWindow(gdi_display, gl->drawable);
1250         }
1251         else XFreeColormap( gdi_display, gl->colormap );
1252     }
1253 #endif
1254     else
1255     {
1256         WARN("XComposite is not available, using GLXPixmap hack\n");
1257
1258         gl->type = DC_GL_PIXMAP_WIN;
1259         gl->pixmap = XCreatePixmap( gdi_display, root_window,
1260                                     gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top,
1261                                     gl->visual->depth );
1262         if (gl->pixmap)
1263         {
1264             gl->drawable = pglXCreateGLXPixmap( gdi_display, gl->visual, gl->pixmap );
1265             if (!gl->drawable) XFreePixmap( gdi_display, gl->pixmap );
1266         }
1267     }
1268
1269     if (!gl->drawable)
1270     {
1271         XFree( gl->visual );
1272         HeapFree( GetProcessHeap(), 0, gl );
1273         return FALSE;
1274     }
1275
1276     TRACE("Created GL drawable 0x%lx, using FBConfigID 0x%lx\n", gl->drawable, fbconfig_id);
1277
1278     XFlush( gdi_display );
1279
1280     EnterCriticalSection( &context_section );
1281     if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev ))
1282         free_gl_drawable( prev );
1283     XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl );
1284     LeaveCriticalSection( &context_section );
1285
1286     /* force DCE invalidation */
1287     SetWindowPos( hwnd, 0, 0, 0, 0, 0,
1288                   SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE |
1289                   SWP_NOREDRAW | SWP_DEFERERASE | SWP_NOSENDCHANGING | SWP_STATECHANGED);
1290     return TRUE;
1291 }
1292
1293 /***********************************************************************
1294  *              sync_gl_drawable
1295  */
1296 void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_rect )
1297 {
1298     struct gl_drawable *gl;
1299     Drawable glxp;
1300     Pixmap pix;
1301     int mask = 0;
1302     XWindowChanges changes;
1303
1304     changes.x      = client_rect->left - visible_rect->left;
1305     changes.y      = client_rect->top - visible_rect->top;
1306     changes.width  = min( max( 1, client_rect->right - client_rect->left ), 65535 );
1307     changes.height = min( max( 1, client_rect->bottom - client_rect->top ), 65535 );
1308
1309     EnterCriticalSection( &context_section );
1310
1311     if (XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) goto done;
1312
1313     if (changes.width  != gl->rect.right - gl->rect.left) mask |= CWWidth;
1314     if (changes.height != gl->rect.bottom - gl->rect.top) mask |= CWHeight;
1315
1316     TRACE( "setting drawable %lx pos %d,%d,%dx%d\n",
1317            gl->drawable, changes.x, changes.y, changes.width, changes.height );
1318
1319     switch (gl->type)
1320     {
1321     case DC_GL_WINDOW:
1322         if (changes.x != gl->rect.left) mask |= CWX;
1323         if (changes.y != gl->rect.top)  mask |= CWY;
1324         /* fallthrough */
1325     case DC_GL_CHILD_WIN:
1326         if (mask) XConfigureWindow( gdi_display, gl->drawable, mask, &changes );
1327         break;
1328     case DC_GL_PIXMAP_WIN:
1329         if (!mask) break;
1330         pix = XCreatePixmap(gdi_display, root_window, changes.width, changes.height, gl->visual->depth);
1331         if (!pix) goto done;
1332         glxp = pglXCreateGLXPixmap(gdi_display, gl->visual, pix);
1333         if (!glxp)
1334         {
1335             XFreePixmap(gdi_display, pix);
1336             goto done;
1337         }
1338         mark_drawable_dirty(gl->drawable, glxp);
1339         XFlush( gdi_display );
1340
1341         XFreePixmap(gdi_display, gl->pixmap);
1342         pglXDestroyGLXPixmap(gdi_display, gl->drawable);
1343         TRACE( "Recreated GL drawable %lx to replace %lx\n", glxp, gl->drawable );
1344
1345         gl->pixmap = pix;
1346         gl->drawable = glxp;
1347         break;
1348     default:
1349         break;
1350     }
1351     SetRect( &gl->rect, changes.x, changes.y, changes.x + changes.width, changes.y + changes.height );
1352 done:
1353     LeaveCriticalSection( &context_section );
1354 }
1355
1356 /***********************************************************************
1357  *              destroy_gl_drawable
1358  */
1359 void destroy_gl_drawable( HWND hwnd )
1360 {
1361     struct gl_drawable *gl;
1362
1363     EnterCriticalSection( &context_section );
1364     if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ))
1365     {
1366         XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context );
1367         free_gl_drawable( gl );
1368     }
1369     LeaveCriticalSection( &context_section );
1370 }
1371
1372
1373 /**
1374  * glxdrv_DescribePixelFormat
1375  *
1376  * Get the pixel-format descriptor associated to the given id
1377  */
1378 static int glxdrv_wglDescribePixelFormat( HDC hdc, int iPixelFormat,
1379                                           UINT nBytes, PIXELFORMATDESCRIPTOR *ppfd)
1380 {
1381   /*XVisualInfo *vis;*/
1382   int value;
1383   int rb,gb,bb,ab;
1384   const struct wgl_pixel_format *fmt;
1385
1386   if (!has_opengl()) return 0;
1387
1388   TRACE("(%p,%d,%d,%p)\n", hdc, iPixelFormat, nBytes, ppfd);
1389
1390   if (!ppfd) return nb_onscreen_formats;
1391
1392   /* 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 */
1393   fmt = get_pixel_format(gdi_display, iPixelFormat, FALSE /* Offscreen */);
1394   if (!fmt) {
1395       WARN("unexpected format %d\n", iPixelFormat);
1396       return 0;
1397   }
1398
1399   if (nBytes < sizeof(PIXELFORMATDESCRIPTOR)) {
1400     ERR("Wrong structure size !\n");
1401     /* Should set error */
1402     return 0;
1403   }
1404
1405   memset(ppfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
1406   ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
1407   ppfd->nVersion = 1;
1408
1409   /* These flags are always the same... */
1410   ppfd->dwFlags = PFD_SUPPORT_OPENGL;
1411   /* Now the flags extracted from the Visual */
1412
1413   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
1414   if(value & GLX_WINDOW_BIT)
1415       ppfd->dwFlags |= PFD_DRAW_TO_WINDOW;
1416
1417   /* On Windows bitmap rendering is only offered using the GDI Software renderer. We reserve some formats (see get_formats for more info)
1418    * for bitmap rendering since we require indirect rendering for this. Further pixel format logs of a GeforceFX, Geforce8800GT, Radeon HD3400 and a
1419    * Radeon 9000 indicated that all bitmap formats have PFD_SUPPORT_GDI. Except for 2 formats on the Radeon 9000 none of the hw accelerated formats
1420    * offered the GDI bit either. */
1421   ppfd->dwFlags |= fmt->dwFlags & (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI);
1422
1423   /* PFD_GENERIC_FORMAT - gdi software rendering
1424    * PFD_GENERIC_ACCELERATED - some parts are accelerated by a display driver (MCD e.g. 3dfx minigl)
1425    * none set - full hardware accelerated by a ICD
1426    *
1427    * We only set PFD_GENERIC_FORMAT on bitmap formats (see get_formats) as that's what ATI and Nvidia Windows drivers do  */
1428   ppfd->dwFlags |= fmt->dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED);
1429
1430   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DOUBLEBUFFER, &value);
1431   if (value) {
1432       ppfd->dwFlags |= PFD_DOUBLEBUFFER;
1433       ppfd->dwFlags &= ~PFD_SUPPORT_GDI;
1434   }
1435   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO;
1436
1437   /* Pixel type */
1438   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RENDER_TYPE, &value);
1439   if (value & GLX_RGBA_BIT)
1440     ppfd->iPixelType = PFD_TYPE_RGBA;
1441   else
1442     ppfd->iPixelType = PFD_TYPE_COLORINDEX;
1443
1444   /* Color bits */
1445   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BUFFER_SIZE, &value);
1446   ppfd->cColorBits = value;
1447
1448   /* Red, green, blue and alpha bits / shifts */
1449   if (ppfd->iPixelType == PFD_TYPE_RGBA) {
1450     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_RED_SIZE, &rb);
1451     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_GREEN_SIZE, &gb);
1452     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_BLUE_SIZE, &bb);
1453     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ALPHA_SIZE, &ab);
1454
1455     ppfd->cRedBits = rb;
1456     ppfd->cRedShift = gb + bb + ab;
1457     ppfd->cBlueBits = bb;
1458     ppfd->cBlueShift = ab;
1459     ppfd->cGreenBits = gb;
1460     ppfd->cGreenShift = bb + ab;
1461     ppfd->cAlphaBits = ab;
1462     ppfd->cAlphaShift = 0;
1463   } else {
1464     ppfd->cRedBits = 0;
1465     ppfd->cRedShift = 0;
1466     ppfd->cBlueBits = 0;
1467     ppfd->cBlueShift = 0;
1468     ppfd->cGreenBits = 0;
1469     ppfd->cGreenShift = 0;
1470     ppfd->cAlphaBits = 0;
1471     ppfd->cAlphaShift = 0;
1472   }
1473
1474   /* Accum RGBA bits */
1475   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_RED_SIZE, &rb);
1476   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_GREEN_SIZE, &gb);
1477   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_BLUE_SIZE, &bb);
1478   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_ALPHA_SIZE, &ab);
1479
1480   ppfd->cAccumBits = rb+gb+bb+ab;
1481   ppfd->cAccumRedBits = rb;
1482   ppfd->cAccumGreenBits = gb;
1483   ppfd->cAccumBlueBits = bb;
1484   ppfd->cAccumAlphaBits = ab;
1485
1486   /* Aux bits */
1487   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_AUX_BUFFERS, &value);
1488   ppfd->cAuxBuffers = value;
1489
1490   /* Depth bits */
1491   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DEPTH_SIZE, &value);
1492   ppfd->cDepthBits = value;
1493
1494   /* stencil bits */
1495   pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_STENCIL_SIZE, &value);
1496   ppfd->cStencilBits = value;
1497
1498   ppfd->iLayerType = PFD_MAIN_PLANE;
1499
1500   if (TRACE_ON(wgl)) {
1501     dump_PIXELFORMATDESCRIPTOR(ppfd);
1502   }
1503
1504   return nb_onscreen_formats;
1505 }
1506
1507 /***********************************************************************
1508  *              glxdrv_wglGetPixelFormat
1509  */
1510 static int glxdrv_wglGetPixelFormat( HDC hdc )
1511 {
1512     HWND hwnd = WindowFromDC( hdc );
1513     struct gl_drawable *gl;
1514     int ret = 0;
1515
1516     EnterCriticalSection( &context_section );
1517     if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) ||
1518         !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
1519         ret = gl->format - pixel_formats + 1;
1520     LeaveCriticalSection( &context_section );
1521
1522     /* Offscreen formats can't be used with traditional WGL calls.
1523      * As has been verified on Windows GetPixelFormat doesn't fail but returns iPixelFormat=1. */
1524     if (ret && !is_onscreen_pixel_format( ret )) ret = 1;
1525
1526     TRACE( "%p -> %d\n", hdc, ret );
1527     return ret;
1528 }
1529
1530 /***********************************************************************
1531  *              glxdrv_wglSetPixelFormat
1532  */
1533 static BOOL glxdrv_wglSetPixelFormat( HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd )
1534 {
1535     const struct wgl_pixel_format *fmt;
1536     int value, prev = 0;
1537     struct gl_drawable *gl;
1538     HWND hwnd = WindowFromDC( hdc );
1539
1540     TRACE("(%p,%d,%p)\n", hdc, iPixelFormat, ppfd);
1541
1542     if (!hwnd || hwnd == GetDesktopWindow())
1543     {
1544         WARN( "not a proper window DC %p/%p\n", hdc, hwnd );
1545         return FALSE;
1546     }
1547
1548     /* Check if iPixelFormat is in our list of supported formats to see if it is supported. */
1549     fmt = get_pixel_format(gdi_display, iPixelFormat, FALSE /* Offscreen */);
1550     if(!fmt) {
1551         ERR("Invalid iPixelFormat: %d\n", iPixelFormat);
1552         return FALSE;
1553     }
1554
1555     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
1556     if (!(value & GLX_WINDOW_BIT))
1557     {
1558         WARN("Pixel format %d is not compatible for window rendering\n", iPixelFormat);
1559         return FALSE;
1560     }
1561
1562     EnterCriticalSection( &context_section );
1563     if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ))
1564         prev = gl->format - pixel_formats + 1;
1565     LeaveCriticalSection( &context_section );
1566
1567     if (prev) return prev == iPixelFormat;  /* cannot change it if already set */
1568
1569     if(!SendMessageW(hwnd, WM_X11DRV_SET_WIN_FORMAT, fmt->fmt_id, 0)) {
1570         ERR("Couldn't set format of the window, returning failure\n");
1571         return FALSE;
1572     }
1573     /* physDev->current_pf will be set by the DCE update */
1574
1575     if (TRACE_ON(wgl)) {
1576         int gl_test = 0;
1577
1578         gl_test = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_FBCONFIG_ID, &value);
1579         if (gl_test) {
1580            ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
1581         } else {
1582             TRACE(" FBConfig have :\n");
1583             TRACE(" - FBCONFIG_ID   0x%x\n", value);
1584             pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_VISUAL_ID, &value);
1585             TRACE(" - VISUAL_ID     0x%x\n", value);
1586             pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
1587             TRACE(" - DRAWABLE_TYPE 0x%x\n", value);
1588         }
1589     }
1590     return TRUE;
1591 }
1592
1593 /***********************************************************************
1594  *              glxdrv_wglCopyContext
1595  */
1596 static BOOL glxdrv_wglCopyContext(struct wgl_context *src, struct wgl_context *dst, UINT mask)
1597 {
1598     TRACE("%p -> %p mask %#x\n", src, dst, mask);
1599
1600     pglXCopyContext(gdi_display, src->ctx, dst->ctx, mask);
1601
1602     /* As opposed to wglCopyContext, glXCopyContext doesn't return anything, so hopefully we passed */
1603     return TRUE;
1604 }
1605
1606 /***********************************************************************
1607  *              glxdrv_wglCreateContext
1608  */
1609 static struct wgl_context *glxdrv_wglCreateContext( HDC hdc )
1610 {
1611     struct x11drv_escape_get_drawable escape;
1612     struct wgl_context *ret;
1613     const struct wgl_pixel_format *fmt;
1614
1615     TRACE( "(%p)\n", hdc );
1616
1617     escape.code = X11DRV_GET_DRAWABLE;
1618     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape.code), (LPCSTR)&escape.code,
1619                     sizeof(escape), (LPSTR)&escape ))
1620         return 0;
1621
1622     fmt = get_pixel_format(gdi_display, escape.pixel_format, TRUE /* Offscreen */);
1623     /* We can render using the iPixelFormat (1) of Wine's Main visual AND using some offscreen formats.
1624      * Note that standard WGL-calls don't recognize offscreen-only formats. For that reason pbuffers
1625      * use a sort of 'proxy' HDC (wglGetPbufferDCARB).
1626      * If this fails something is very wrong on the system. */
1627     if(!fmt) {
1628         ERR("Cannot get FB Config for iPixelFormat %d, expect problems!\n", escape.pixel_format);
1629         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
1630         return NULL;
1631     }
1632
1633     if (!(ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)))) return 0;
1634
1635     ret->hdc = hdc;
1636     ret->fmt = fmt;
1637     ret->has_been_current = FALSE;
1638     ret->sharing = FALSE;
1639
1640     ret->vis = pglXGetVisualFromFBConfig(gdi_display, fmt->fbconfig);
1641     ret->ctx = create_glxcontext(gdi_display, ret, NULL);
1642
1643     EnterCriticalSection( &context_section );
1644     list_add_head( &context_list, &ret->entry );
1645     LeaveCriticalSection( &context_section );
1646
1647     TRACE(" creating context %p (GL context creation delayed)\n", ret);
1648     return ret;
1649 }
1650
1651 /***********************************************************************
1652  *              glxdrv_wglDeleteContext
1653  */
1654 static void glxdrv_wglDeleteContext(struct wgl_context *ctx)
1655 {
1656     TRACE("(%p)\n", ctx);
1657
1658     EnterCriticalSection( &context_section );
1659     list_remove( &ctx->entry );
1660     LeaveCriticalSection( &context_section );
1661
1662     if (ctx->ctx) pglXDestroyContext( gdi_display, ctx->ctx );
1663     if (ctx->vis) XFree( ctx->vis );
1664     HeapFree( GetProcessHeap(), 0, ctx );
1665 }
1666
1667 /***********************************************************************
1668  *              glxdrv_wglGetProcAddress
1669  */
1670 static PROC glxdrv_wglGetProcAddress(LPCSTR lpszProc)
1671 {
1672     if (!strncmp(lpszProc, "wgl", 3)) return NULL;
1673     return pglXGetProcAddressARB((const GLubyte*)lpszProc);
1674 }
1675
1676 /***********************************************************************
1677  *              glxdrv_wglMakeCurrent
1678  */
1679 static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx)
1680 {
1681     BOOL ret;
1682     struct x11drv_escape_get_drawable escape;
1683
1684     TRACE("(%p,%p)\n", hdc, ctx);
1685
1686     if (!ctx)
1687     {
1688         pglXMakeCurrent(gdi_display, None, NULL);
1689         NtCurrentTeb()->glContext = NULL;
1690         return TRUE;
1691     }
1692
1693     escape.code = X11DRV_GET_DRAWABLE;
1694     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape.code), (LPCSTR)&escape.code,
1695                     sizeof(escape), (LPSTR)&escape ))
1696         return FALSE;
1697
1698     if (!escape.pixel_format)
1699     {
1700         WARN("Trying to use an invalid drawable\n");
1701         SetLastError(ERROR_INVALID_HANDLE);
1702         return FALSE;
1703     }
1704     if (ctx->fmt - pixel_formats != escape.pixel_format - 1)
1705     {
1706         WARN( "mismatched pixel format hdc %p %u ctx %p\n", hdc, escape.pixel_format, ctx );
1707         SetLastError( ERROR_INVALID_PIXEL_FORMAT );
1708         return FALSE;
1709     }
1710     else
1711     {
1712         if (TRACE_ON(wgl)) {
1713             int vis_id;
1714             pglXGetFBConfigAttrib(gdi_display, ctx->fmt->fbconfig, GLX_VISUAL_ID, &vis_id);
1715             describeContext(ctx);
1716             TRACE("hdc %p drawable %lx fmt %u vis %x ctx %p\n", hdc,
1717                   escape.gl_drawable, escape.pixel_format, vis_id, ctx->ctx);
1718         }
1719
1720         ret = pglXMakeCurrent(gdi_display, escape.gl_drawable, ctx->ctx);
1721
1722         if (ret)
1723         {
1724             NtCurrentTeb()->glContext = ctx;
1725
1726             EnterCriticalSection( &context_section );
1727             ctx->has_been_current = TRUE;
1728             ctx->hdc = hdc;
1729             ctx->drawables[0] = escape.gl_drawable;
1730             ctx->drawables[1] = escape.gl_drawable;
1731             ctx->refresh_drawables = FALSE;
1732             LeaveCriticalSection( &context_section );
1733         }
1734         else
1735             SetLastError(ERROR_INVALID_HANDLE);
1736     }
1737     TRACE(" returning %s\n", (ret ? "True" : "False"));
1738     return ret;
1739 }
1740
1741 /***********************************************************************
1742  *              X11DRV_wglMakeContextCurrentARB
1743  */
1744 static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *ctx )
1745 {
1746     struct x11drv_escape_get_drawable escape_draw, escape_read;
1747     BOOL ret;
1748
1749     TRACE("(%p,%p,%p)\n", draw_hdc, read_hdc, ctx);
1750
1751     if (!ctx)
1752     {
1753         pglXMakeCurrent(gdi_display, None, NULL);
1754         NtCurrentTeb()->glContext = NULL;
1755         return TRUE;
1756     }
1757
1758     escape_draw.code = X11DRV_GET_DRAWABLE;
1759     if (!ExtEscape( draw_hdc, X11DRV_ESCAPE, sizeof(escape_draw.code), (LPCSTR)&escape_draw.code,
1760                     sizeof(escape_draw), (LPSTR)&escape_draw ))
1761         return FALSE;
1762
1763     escape_read.code = X11DRV_GET_DRAWABLE;
1764     if (!ExtEscape( read_hdc, X11DRV_ESCAPE, sizeof(escape_read.code), (LPCSTR)&escape_read.code,
1765                     sizeof(escape_read), (LPSTR)&escape_read ))
1766         return FALSE;
1767
1768     if (!escape_draw.pixel_format)
1769     {
1770         WARN("Trying to use an invalid drawable\n");
1771         SetLastError(ERROR_INVALID_HANDLE);
1772         return FALSE;
1773     }
1774     else
1775     {
1776         if (!pglXMakeContextCurrent) return FALSE;
1777
1778         ret = pglXMakeContextCurrent(gdi_display, escape_draw.gl_drawable, escape_read.gl_drawable, ctx->ctx);
1779         if (ret)
1780         {
1781             EnterCriticalSection( &context_section );
1782             ctx->has_been_current = TRUE;
1783             ctx->hdc = draw_hdc;
1784             ctx->drawables[0] = escape_draw.gl_drawable;
1785             ctx->drawables[1] = escape_read.gl_drawable;
1786             ctx->refresh_drawables = FALSE;
1787             LeaveCriticalSection( &context_section );
1788             NtCurrentTeb()->glContext = ctx;
1789         }
1790         else
1791             SetLastError(ERROR_INVALID_HANDLE);
1792     }
1793
1794     TRACE(" returning %s\n", (ret ? "True" : "False"));
1795     return ret;
1796 }
1797
1798 /***********************************************************************
1799  *              glxdrv_wglShareLists
1800  */
1801 static BOOL glxdrv_wglShareLists(struct wgl_context *org, struct wgl_context *dest)
1802 {
1803     TRACE("(%p, %p)\n", org, dest);
1804
1805     /* Sharing of display lists works differently in GLX and WGL. In case of GLX it is done
1806      * at context creation time but in case of WGL it is done using wglShareLists.
1807      * In the past we tried to emulate wglShareLists by delaying GLX context creation until
1808      * either a wglMakeCurrent or wglShareLists. This worked fine for most apps but it causes
1809      * issues for OpenGL 3 because there wglCreateContextAttribsARB can fail in a lot of cases,
1810      * so there delaying context creation doesn't work.
1811      *
1812      * The new approach is to create a GLX context in wglCreateContext / wglCreateContextAttribsARB
1813      * and when a program requests sharing we recreate the destination context if it hasn't been made
1814      * current or when it hasn't shared display lists before.
1815      */
1816
1817     if((org->has_been_current && dest->has_been_current) || dest->has_been_current)
1818     {
1819         ERR("Could not share display lists, one of the contexts has been current already !\n");
1820         return FALSE;
1821     }
1822     else if(dest->sharing)
1823     {
1824         ERR("Could not share display lists because hglrc2 has already shared lists before\n");
1825         return FALSE;
1826     }
1827     else
1828     {
1829         describeContext(org);
1830         describeContext(dest);
1831
1832         /* Re-create the GLX context and share display lists */
1833         pglXDestroyContext(gdi_display, dest->ctx);
1834         dest->ctx = create_glxcontext(gdi_display, dest, org->ctx);
1835         TRACE(" re-created an OpenGL context (%p) for Wine context %p sharing lists with OpenGL ctx %p\n", dest->ctx, dest, org->ctx);
1836
1837         org->sharing = TRUE;
1838         dest->sharing = TRUE;
1839         return TRUE;
1840     }
1841     return FALSE;
1842 }
1843
1844 static void flush_gl_drawable( struct glx_physdev *physdev )
1845 {
1846     RECT rect;
1847     int w = physdev->x11dev->dc_rect.right - physdev->x11dev->dc_rect.left;
1848     int h = physdev->x11dev->dc_rect.bottom - physdev->x11dev->dc_rect.top;
1849     Drawable src = physdev->drawable;
1850
1851     if (w <= 0 || h <= 0) return;
1852
1853     switch (physdev->type)
1854     {
1855     case DC_GL_PIXMAP_WIN:
1856         src = physdev->pixmap;
1857         /* fall through */
1858     case DC_GL_CHILD_WIN:
1859         /* The GL drawable may be lagged behind if we don't flush first, so
1860          * flush the display make sure we copy up-to-date data */
1861         XFlush(gdi_display);
1862         XSetFunction(gdi_display, physdev->x11dev->gc, GXcopy);
1863         XCopyArea(gdi_display, src, physdev->x11dev->drawable, physdev->x11dev->gc, 0, 0, w, h,
1864                   physdev->x11dev->dc_rect.left, physdev->x11dev->dc_rect.top);
1865         SetRect( &rect, 0, 0, w, h );
1866         add_device_bounds( physdev->x11dev, &rect );
1867     default:
1868         break;
1869     }
1870 }
1871
1872
1873 static void wglFinish(void)
1874 {
1875     struct wgl_context *ctx = NtCurrentTeb()->glContext;
1876     enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE;
1877
1878     sync_context(ctx);
1879     pglFinish();
1880     ExtEscape( ctx->hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
1881 }
1882
1883 static void wglFlush(void)
1884 {
1885     struct wgl_context *ctx = NtCurrentTeb()->glContext;
1886     enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE;
1887
1888     sync_context(ctx);
1889     pglFlush();
1890     ExtEscape( ctx->hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
1891 }
1892
1893 /***********************************************************************
1894  *              X11DRV_wglCreateContextAttribsARB
1895  */
1896 static struct wgl_context *X11DRV_wglCreateContextAttribsARB( HDC hdc, struct wgl_context *hShareContext,
1897                                                               const int* attribList )
1898 {
1899     struct x11drv_escape_get_drawable escape;
1900     struct wgl_context *ret;
1901     const struct wgl_pixel_format *fmt;
1902
1903     TRACE("(%p %p %p)\n", hdc, hShareContext, attribList);
1904
1905     escape.code = X11DRV_GET_DRAWABLE;
1906     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape.code), (LPCSTR)&escape.code,
1907                     sizeof(escape), (LPSTR)&escape ))
1908         return 0;
1909
1910     fmt = get_pixel_format(gdi_display, escape.pixel_format, TRUE /* Offscreen */);
1911     /* wglCreateContextAttribsARB supports ALL pixel formats, so also offscreen ones.
1912      * If this fails something is very wrong on the system. */
1913     if(!fmt)
1914     {
1915         ERR("Cannot get FB Config for iPixelFormat %d, expect problems!\n", escape.pixel_format);
1916         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
1917         return NULL;
1918     }
1919
1920     if (!(ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)))) return 0;
1921
1922     ret->hdc = hdc;
1923     ret->fmt = fmt;
1924     ret->vis = NULL; /* glXCreateContextAttribsARB requires a fbconfig instead of a visual */
1925     ret->gl3_context = TRUE;
1926
1927     ret->numAttribs = 0;
1928     if(attribList)
1929     {
1930         int *pAttribList = (int*)attribList;
1931         int *pContextAttribList = &ret->attribList[0];
1932         /* attribList consists of pairs {token, value] terminated with 0 */
1933         while(pAttribList[0] != 0)
1934         {
1935             TRACE("%#x %#x\n", pAttribList[0], pAttribList[1]);
1936             switch(pAttribList[0])
1937             {
1938                 case WGL_CONTEXT_MAJOR_VERSION_ARB:
1939                     pContextAttribList[0] = GLX_CONTEXT_MAJOR_VERSION_ARB;
1940                     pContextAttribList[1] = pAttribList[1];
1941                     break;
1942                 case WGL_CONTEXT_MINOR_VERSION_ARB:
1943                     pContextAttribList[0] = GLX_CONTEXT_MINOR_VERSION_ARB;
1944                     pContextAttribList[1] = pAttribList[1];
1945                     break;
1946                 case WGL_CONTEXT_LAYER_PLANE_ARB:
1947                     break;
1948                 case WGL_CONTEXT_FLAGS_ARB:
1949                     pContextAttribList[0] = GLX_CONTEXT_FLAGS_ARB;
1950                     pContextAttribList[1] = pAttribList[1];
1951                     break;
1952                 case WGL_CONTEXT_PROFILE_MASK_ARB:
1953                     pContextAttribList[0] = GLX_CONTEXT_PROFILE_MASK_ARB;
1954                     pContextAttribList[1] = pAttribList[1];
1955                     break;
1956                 default:
1957                     ERR("Unhandled attribList pair: %#x %#x\n", pAttribList[0], pAttribList[1]);
1958             }
1959
1960             ret->numAttribs++;
1961             pAttribList += 2;
1962             pContextAttribList += 2;
1963         }
1964     }
1965
1966     X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL);
1967     ret->ctx = create_glxcontext(gdi_display, ret, NULL);
1968
1969     XSync(gdi_display, False);
1970     if(X11DRV_check_error() || !ret->ctx)
1971     {
1972         /* In the future we should convert the GLX error to a win32 one here if needed */
1973         ERR("Context creation failed\n");
1974         HeapFree( GetProcessHeap(), 0, ret );
1975         return NULL;
1976     }
1977
1978     EnterCriticalSection( &context_section );
1979     list_add_head( &context_list, &ret->entry );
1980     LeaveCriticalSection( &context_section );
1981
1982     TRACE(" creating context %p\n", ret);
1983     return ret;
1984 }
1985
1986 /**
1987  * X11DRV_wglGetExtensionsStringARB
1988  *
1989  * WGL_ARB_extensions_string: wglGetExtensionsStringARB
1990  */
1991 static const GLubyte *X11DRV_wglGetExtensionsStringARB(HDC hdc)
1992 {
1993     TRACE("() returning \"%s\"\n", WineGLInfo.wglExtensions);
1994     return (const GLubyte *)WineGLInfo.wglExtensions;
1995 }
1996
1997 /**
1998  * X11DRV_wglCreatePbufferARB
1999  *
2000  * WGL_ARB_pbuffer: wglCreatePbufferARB
2001  */
2002 static struct wgl_pbuffer *X11DRV_wglCreatePbufferARB( HDC hdc, int iPixelFormat, int iWidth, int iHeight,
2003                                                        const int *piAttribList )
2004 {
2005     struct wgl_pbuffer* object = NULL;
2006     const struct wgl_pixel_format *fmt = NULL;
2007     int attribs[256];
2008     int nAttribs = 0;
2009
2010     TRACE("(%p, %d, %d, %d, %p)\n", hdc, iPixelFormat, iWidth, iHeight, piAttribList);
2011
2012     /* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */
2013     fmt = get_pixel_format(gdi_display, iPixelFormat, TRUE /* Offscreen */);
2014     if(!fmt) {
2015         ERR("(%p): invalid pixel format %d\n", hdc, iPixelFormat);
2016         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2017         return NULL;
2018     }
2019
2020     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2021     if (NULL == object) {
2022         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
2023         return NULL;
2024     }
2025     object->width = iWidth;
2026     object->height = iHeight;
2027     object->fmt = fmt;
2028
2029     PUSH2(attribs, GLX_PBUFFER_WIDTH,  iWidth);
2030     PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight); 
2031     while (piAttribList && 0 != *piAttribList) {
2032         int attr_v;
2033         switch (*piAttribList) {
2034             case WGL_PBUFFER_LARGEST_ARB: {
2035                 ++piAttribList;
2036                 attr_v = *piAttribList;
2037                 TRACE("WGL_LARGEST_PBUFFER_ARB = %d\n", attr_v);
2038                 PUSH2(attribs, GLX_LARGEST_PBUFFER, attr_v);
2039                 break;
2040             }
2041
2042             case WGL_TEXTURE_FORMAT_ARB: {
2043                 ++piAttribList;
2044                 attr_v = *piAttribList;
2045                 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v);
2046                 if (WGL_NO_TEXTURE_ARB == attr_v) {
2047                     object->use_render_texture = 0;
2048                 } else {
2049                     if (!use_render_texture_emulation) {
2050                         SetLastError(ERROR_INVALID_DATA);
2051                         goto create_failed;
2052                     }
2053                     switch (attr_v) {
2054                         case WGL_TEXTURE_RGB_ARB:
2055                             object->use_render_texture = GL_RGB;
2056                             object->texture_bpp = 3;
2057                             object->texture_format = GL_RGB;
2058                             object->texture_type = GL_UNSIGNED_BYTE;
2059                             break;
2060                         case WGL_TEXTURE_RGBA_ARB:
2061                             object->use_render_texture = GL_RGBA;
2062                             object->texture_bpp = 4;
2063                             object->texture_format = GL_RGBA;
2064                             object->texture_type = GL_UNSIGNED_BYTE;
2065                             break;
2066
2067                         /* WGL_FLOAT_COMPONENTS_NV */
2068                         case WGL_TEXTURE_FLOAT_R_NV:
2069                             object->use_render_texture = GL_FLOAT_R_NV;
2070                             object->texture_bpp = 4;
2071                             object->texture_format = GL_RED;
2072                             object->texture_type = GL_FLOAT;
2073                             break;
2074                         case WGL_TEXTURE_FLOAT_RG_NV:
2075                             object->use_render_texture = GL_FLOAT_RG_NV;
2076                             object->texture_bpp = 8;
2077                             object->texture_format = GL_LUMINANCE_ALPHA;
2078                             object->texture_type = GL_FLOAT;
2079                             break;
2080                         case WGL_TEXTURE_FLOAT_RGB_NV:
2081                             object->use_render_texture = GL_FLOAT_RGB_NV;
2082                             object->texture_bpp = 12;
2083                             object->texture_format = GL_RGB;
2084                             object->texture_type = GL_FLOAT;
2085                             break;
2086                         case WGL_TEXTURE_FLOAT_RGBA_NV:
2087                             object->use_render_texture = GL_FLOAT_RGBA_NV;
2088                             object->texture_bpp = 16;
2089                             object->texture_format = GL_RGBA;
2090                             object->texture_type = GL_FLOAT;
2091                             break;
2092                         default:
2093                             ERR("Unknown texture format: %x\n", attr_v);
2094                             SetLastError(ERROR_INVALID_DATA);
2095                             goto create_failed;
2096                     }
2097                 }
2098                 break;
2099             }
2100
2101             case WGL_TEXTURE_TARGET_ARB: {
2102                 ++piAttribList;
2103                 attr_v = *piAttribList;
2104                 TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v);
2105                 if (WGL_NO_TEXTURE_ARB == attr_v) {
2106                     object->texture_target = 0;
2107                 } else {
2108                     if (!use_render_texture_emulation) {
2109                         SetLastError(ERROR_INVALID_DATA);
2110                         goto create_failed;
2111                     }
2112                     switch (attr_v) {
2113                         case WGL_TEXTURE_CUBE_MAP_ARB: {
2114                             if (iWidth != iHeight) {
2115                                 SetLastError(ERROR_INVALID_DATA);
2116                                 goto create_failed;
2117                             }
2118                             object->texture_target = GL_TEXTURE_CUBE_MAP;
2119                             object->texture_bind_target = GL_TEXTURE_BINDING_CUBE_MAP;
2120                            break;
2121                         }
2122                         case WGL_TEXTURE_1D_ARB: {
2123                             if (1 != iHeight) {
2124                                 SetLastError(ERROR_INVALID_DATA);
2125                                 goto create_failed;
2126                             }
2127                             object->texture_target = GL_TEXTURE_1D;
2128                             object->texture_bind_target = GL_TEXTURE_BINDING_1D;
2129                             break;
2130                         }
2131                         case WGL_TEXTURE_2D_ARB: {
2132                             object->texture_target = GL_TEXTURE_2D;
2133                             object->texture_bind_target = GL_TEXTURE_BINDING_2D;
2134                             break;
2135                         }
2136                         case WGL_TEXTURE_RECTANGLE_NV: {
2137                             object->texture_target = GL_TEXTURE_RECTANGLE_NV;
2138                             object->texture_bind_target = GL_TEXTURE_BINDING_RECTANGLE_NV;
2139                             break;
2140                         }
2141                         default:
2142                             ERR("Unknown texture target: %x\n", attr_v);
2143                             SetLastError(ERROR_INVALID_DATA);
2144                             goto create_failed;
2145                     }
2146                 }
2147                 break;
2148             }
2149
2150             case WGL_MIPMAP_TEXTURE_ARB: {
2151                 ++piAttribList;
2152                 attr_v = *piAttribList;
2153                 TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v);
2154                 if (!use_render_texture_emulation) {
2155                     SetLastError(ERROR_INVALID_DATA);
2156                     goto create_failed;
2157                 }
2158                 break;
2159             }
2160         }
2161         ++piAttribList;
2162     }
2163
2164     PUSH1(attribs, None);
2165     object->drawable = pglXCreatePbuffer(gdi_display, fmt->fbconfig, attribs);
2166     TRACE("new Pbuffer drawable as %lx\n", object->drawable);
2167     if (!object->drawable) {
2168         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
2169         goto create_failed; /* unexpected error */
2170     }
2171     TRACE("->(%p)\n", object);
2172     return object;
2173
2174 create_failed:
2175     HeapFree(GetProcessHeap(), 0, object);
2176     TRACE("->(FAILED)\n");
2177     return NULL;
2178 }
2179
2180 /**
2181  * X11DRV_wglDestroyPbufferARB
2182  *
2183  * WGL_ARB_pbuffer: wglDestroyPbufferARB
2184  */
2185 static BOOL X11DRV_wglDestroyPbufferARB( struct wgl_pbuffer *object )
2186 {
2187     TRACE("(%p)\n", object);
2188
2189     pglXDestroyPbuffer(gdi_display, object->drawable);
2190     HeapFree(GetProcessHeap(), 0, object);
2191     return GL_TRUE;
2192 }
2193
2194 /**
2195  * X11DRV_wglGetPbufferDCARB
2196  *
2197  * WGL_ARB_pbuffer: wglGetPbufferDCARB
2198  */
2199 static HDC X11DRV_wglGetPbufferDCARB( struct wgl_pbuffer *object )
2200 {
2201     struct x11drv_escape_set_drawable escape;
2202     struct gl_drawable *gl, *prev;
2203     HDC hdc;
2204
2205     hdc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
2206     if (!hdc) return 0;
2207
2208     if (!(gl = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*gl) )))
2209     {
2210         DeleteDC( hdc );
2211         return 0;
2212     }
2213     gl->type = DC_GL_PBUFFER;
2214     gl->drawable = object->drawable;
2215     gl->format = object->fmt;
2216
2217     EnterCriticalSection( &context_section );
2218     if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&prev ))
2219         free_gl_drawable( prev );
2220     XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)gl );
2221     LeaveCriticalSection( &context_section );
2222
2223     escape.code = X11DRV_SET_DRAWABLE;
2224     escape.hwnd = 0;
2225     escape.drawable = object->drawable;
2226     escape.mode = IncludeInferiors;
2227     SetRect( &escape.dc_rect, 0, 0, object->width, object->height );
2228     escape.fbconfig_id = object->fmt->fmt_id;
2229     ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
2230
2231     TRACE( "(%p)->(%p)\n", object, hdc );
2232     return hdc;
2233 }
2234
2235 /**
2236  * X11DRV_wglQueryPbufferARB
2237  *
2238  * WGL_ARB_pbuffer: wglQueryPbufferARB
2239  */
2240 static BOOL X11DRV_wglQueryPbufferARB( struct wgl_pbuffer *object, int iAttribute, int *piValue )
2241 {
2242     TRACE("(%p, 0x%x, %p)\n", object, iAttribute, piValue);
2243
2244     switch (iAttribute) {
2245         case WGL_PBUFFER_WIDTH_ARB:
2246             pglXQueryDrawable(gdi_display, object->drawable, GLX_WIDTH, (unsigned int*) piValue);
2247             break;
2248         case WGL_PBUFFER_HEIGHT_ARB:
2249             pglXQueryDrawable(gdi_display, object->drawable, GLX_HEIGHT, (unsigned int*) piValue);
2250             break;
2251
2252         case WGL_PBUFFER_LOST_ARB:
2253             /* GLX Pbuffers cannot be lost by default. We can support this by
2254              * setting GLX_PRESERVED_CONTENTS to False and using glXSelectEvent
2255              * to receive pixel buffer clobber events, however that may or may
2256              * not give any benefit */
2257             *piValue = GL_FALSE;
2258             break;
2259
2260         case WGL_TEXTURE_FORMAT_ARB:
2261             if (!object->use_render_texture) {
2262                 *piValue = WGL_NO_TEXTURE_ARB;
2263             } else {
2264                 if (!use_render_texture_emulation) {
2265                     SetLastError(ERROR_INVALID_HANDLE);
2266                     return GL_FALSE;
2267                 }
2268                 switch(object->use_render_texture) {
2269                     case GL_RGB:
2270                         *piValue = WGL_TEXTURE_RGB_ARB;
2271                         break;
2272                     case GL_RGBA:
2273                         *piValue = WGL_TEXTURE_RGBA_ARB;
2274                         break;
2275                     /* WGL_FLOAT_COMPONENTS_NV */
2276                     case GL_FLOAT_R_NV:
2277                         *piValue = WGL_TEXTURE_FLOAT_R_NV;
2278                         break;
2279                     case GL_FLOAT_RG_NV:
2280                         *piValue = WGL_TEXTURE_FLOAT_RG_NV;
2281                         break;
2282                     case GL_FLOAT_RGB_NV:
2283                         *piValue = WGL_TEXTURE_FLOAT_RGB_NV;
2284                         break;
2285                     case GL_FLOAT_RGBA_NV:
2286                         *piValue = WGL_TEXTURE_FLOAT_RGBA_NV;
2287                         break;
2288                     default:
2289                         ERR("Unknown texture format: %x\n", object->use_render_texture);
2290                 }
2291             }
2292             break;
2293
2294         case WGL_TEXTURE_TARGET_ARB:
2295             if (!object->texture_target){
2296                 *piValue = WGL_NO_TEXTURE_ARB;
2297             } else {
2298                 if (!use_render_texture_emulation) {
2299                     SetLastError(ERROR_INVALID_DATA);
2300                     return GL_FALSE;
2301                 }
2302                 switch (object->texture_target) {
2303                     case GL_TEXTURE_1D:       *piValue = WGL_TEXTURE_1D_ARB; break;
2304                     case GL_TEXTURE_2D:       *piValue = WGL_TEXTURE_2D_ARB; break;
2305                     case GL_TEXTURE_CUBE_MAP: *piValue = WGL_TEXTURE_CUBE_MAP_ARB; break;
2306                     case GL_TEXTURE_RECTANGLE_NV: *piValue = WGL_TEXTURE_RECTANGLE_NV; break;
2307                 }
2308             }
2309             break;
2310
2311         case WGL_MIPMAP_TEXTURE_ARB:
2312             *piValue = GL_FALSE; /** don't support that */
2313             FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute);
2314             break;
2315
2316         default:
2317             FIXME("unexpected attribute %x\n", iAttribute);
2318             break;
2319     }
2320
2321     return GL_TRUE;
2322 }
2323
2324 /**
2325  * X11DRV_wglReleasePbufferDCARB
2326  *
2327  * WGL_ARB_pbuffer: wglReleasePbufferDCARB
2328  */
2329 static int X11DRV_wglReleasePbufferDCARB( struct wgl_pbuffer *object, HDC hdc )
2330 {
2331     struct gl_drawable *gl;
2332
2333     TRACE("(%p, %p)\n", object, hdc);
2334
2335     EnterCriticalSection( &context_section );
2336     if (!XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl ))
2337     {
2338         XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context );
2339         free_gl_drawable( gl );
2340     }
2341     LeaveCriticalSection( &context_section );
2342
2343     return DeleteDC(hdc);
2344 }
2345
2346 /**
2347  * X11DRV_wglSetPbufferAttribARB
2348  *
2349  * WGL_ARB_pbuffer: wglSetPbufferAttribARB
2350  */
2351 static BOOL X11DRV_wglSetPbufferAttribARB( struct wgl_pbuffer *object, const int *piAttribList )
2352 {
2353     GLboolean ret = GL_FALSE;
2354
2355     WARN("(%p, %p): alpha-testing, report any problem\n", object, piAttribList);
2356
2357     if (!object->use_render_texture) {
2358         SetLastError(ERROR_INVALID_HANDLE);
2359         return GL_FALSE;
2360     }
2361     if (1 == use_render_texture_emulation) {
2362         return GL_TRUE;
2363     }
2364     return ret;
2365 }
2366
2367 /**
2368  * X11DRV_wglChoosePixelFormatARB
2369  *
2370  * WGL_ARB_pixel_format: wglChoosePixelFormatARB
2371  */
2372 static BOOL X11DRV_wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList,
2373                                             UINT nMaxFormats, int *piFormats, UINT *nNumFormats )
2374 {
2375     int attribs[256];
2376     int nAttribs = 0;
2377     GLXFBConfig* cfgs = NULL;
2378     int nCfgs = 0;
2379     int it;
2380     int fmt_id;
2381     int start, end;
2382     UINT pfmt_it = 0;
2383     int run;
2384     int i;
2385     DWORD dwFlags = 0;
2386
2387     TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
2388     if (NULL != pfAttribFList) {
2389         FIXME("unused pfAttribFList\n");
2390     }
2391
2392     nAttribs = ConvertAttribWGLtoGLX(piAttribIList, attribs, NULL);
2393     if (-1 == nAttribs) {
2394         WARN("Cannot convert WGL to GLX attributes\n");
2395         return GL_FALSE;
2396     }
2397     PUSH1(attribs, None);
2398
2399     /* There is no 1:1 mapping between GLX and WGL formats because we duplicate some GLX formats for bitmap rendering (see get_formats).
2400      * Flags like PFD_SUPPORT_GDI, PFD_DRAW_TO_BITMAP and others are a property of the pixel format. We don't query these attributes
2401      * using glXChooseFBConfig but we filter the result of glXChooseFBConfig later on.
2402      */
2403     for(i=0; piAttribIList[i] != 0; i+=2)
2404     {
2405         switch(piAttribIList[i])
2406         {
2407             case WGL_DRAW_TO_BITMAP_ARB:
2408                 if(piAttribIList[i+1])
2409                     dwFlags |= PFD_DRAW_TO_BITMAP;
2410                 break;
2411             case WGL_ACCELERATION_ARB:
2412                 switch(piAttribIList[i+1])
2413                 {
2414                     case WGL_NO_ACCELERATION_ARB:
2415                         dwFlags |= PFD_GENERIC_FORMAT;
2416                         break;
2417                     case WGL_GENERIC_ACCELERATION_ARB:
2418                         dwFlags |= PFD_GENERIC_ACCELERATED;
2419                         break;
2420                     case WGL_FULL_ACCELERATION_ARB:
2421                         /* Nothing to do */
2422                         break;
2423                 }
2424                 break;
2425             case WGL_SUPPORT_GDI_ARB:
2426                 if(piAttribIList[i+1])
2427                     dwFlags |= PFD_SUPPORT_GDI;
2428                 break;
2429         }
2430     }
2431
2432     /* Search for FB configurations matching the requirements in attribs */
2433     cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), attribs, &nCfgs);
2434     if (NULL == cfgs) {
2435         WARN("Compatible Pixel Format not found\n");
2436         return GL_FALSE;
2437     }
2438
2439     /* Loop through all matching formats and check if they are suitable.
2440      * Note that this function should at max return nMaxFormats different formats */
2441     for(run=0; run < 2; run++)
2442     {
2443         for (it = 0; it < nCfgs && pfmt_it < nMaxFormats; ++it)
2444         {
2445             if (pglXGetFBConfigAttrib(gdi_display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id))
2446             {
2447                 ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
2448                 continue;
2449             }
2450
2451             /* During the first run we only want onscreen formats and during the second only offscreen */
2452             start = run == 1 ? nb_onscreen_formats : 0;
2453             end = run == 1 ? nb_pixel_formats : nb_onscreen_formats;
2454
2455             for (i = start; i < end; i++)
2456             {
2457                 if (pixel_formats[i].fmt_id == fmt_id && (pixel_formats[i].dwFlags & dwFlags) == dwFlags)
2458                 {
2459                     piFormats[pfmt_it++] = i + 1;
2460                     TRACE("at %d/%d found FBCONFIG_ID 0x%x (%d)\n",
2461                           it + 1, nCfgs, fmt_id, piFormats[pfmt_it]);
2462                     break;
2463                 }
2464             }
2465         }
2466     }
2467
2468     *nNumFormats = pfmt_it;
2469     /** free list */
2470     XFree(cfgs);
2471     return GL_TRUE;
2472 }
2473
2474 /**
2475  * X11DRV_wglGetPixelFormatAttribivARB
2476  *
2477  * WGL_ARB_pixel_format: wglGetPixelFormatAttribivARB
2478  */
2479 static BOOL X11DRV_wglGetPixelFormatAttribivARB( HDC hdc, int iPixelFormat, int iLayerPlane,
2480                                                  UINT nAttributes, const int *piAttributes, int *piValues )
2481 {
2482     UINT i;
2483     const struct wgl_pixel_format *fmt = NULL;
2484     int hTest;
2485     int tmp;
2486     int curGLXAttr = 0;
2487
2488     TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues);
2489
2490     if (0 < iLayerPlane) {
2491         FIXME("unsupported iLayerPlane(%d) > 0, returns FALSE\n", iLayerPlane);
2492         return GL_FALSE;
2493     }
2494
2495     /* Convert the WGL pixelformat to a GLX one, if this fails then most likely the iPixelFormat isn't supported.
2496     * We don't have to fail yet as a program can specify an invalid iPixelFormat (lets say 0) if it wants to query
2497     * the number of supported WGL formats. Whether the iPixelFormat is valid is handled in the for-loop below. */
2498     fmt = get_pixel_format(gdi_display, iPixelFormat, TRUE /* Offscreen */);
2499     if(!fmt) {
2500         WARN("Unable to convert iPixelFormat %d to a GLX one!\n", iPixelFormat);
2501     }
2502
2503     for (i = 0; i < nAttributes; ++i) {
2504         const int curWGLAttr = piAttributes[i];
2505         TRACE("pAttr[%d] = %x\n", i, curWGLAttr);
2506
2507         switch (curWGLAttr) {
2508             case WGL_NUMBER_PIXEL_FORMATS_ARB:
2509                 piValues[i] = nb_pixel_formats;
2510                 continue;
2511
2512             case WGL_SUPPORT_OPENGL_ARB:
2513                 piValues[i] = GL_TRUE; 
2514                 continue;
2515
2516             case WGL_ACCELERATION_ARB:
2517                 curGLXAttr = GLX_CONFIG_CAVEAT;
2518                 if (!fmt) goto pix_error;
2519                 if(fmt->dwFlags & PFD_GENERIC_FORMAT)
2520                     piValues[i] = WGL_NO_ACCELERATION_ARB;
2521                 else if(fmt->dwFlags & PFD_GENERIC_ACCELERATED)
2522                     piValues[i] = WGL_GENERIC_ACCELERATION_ARB;
2523                 else
2524                     piValues[i] = WGL_FULL_ACCELERATION_ARB;
2525                 continue;
2526
2527             case WGL_TRANSPARENT_ARB:
2528                 curGLXAttr = GLX_TRANSPARENT_TYPE;
2529                 if (!fmt) goto pix_error;
2530                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2531                 if (hTest) goto get_error;
2532                     piValues[i] = GL_FALSE;
2533                 if (GLX_NONE != tmp) piValues[i] = GL_TRUE;
2534                     continue;
2535
2536             case WGL_PIXEL_TYPE_ARB:
2537                 curGLXAttr = GLX_RENDER_TYPE;
2538                 if (!fmt) goto pix_error;
2539                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2540                 if (hTest) goto get_error;
2541                 TRACE("WGL_PIXEL_TYPE_ARB: GLX_RENDER_TYPE = 0x%x\n", tmp);
2542                 if      (tmp & GLX_RGBA_BIT)           { piValues[i] = WGL_TYPE_RGBA_ARB; }
2543                 else if (tmp & GLX_COLOR_INDEX_BIT)    { piValues[i] = WGL_TYPE_COLORINDEX_ARB; }
2544                 else if (tmp & GLX_RGBA_FLOAT_BIT)     { piValues[i] = WGL_TYPE_RGBA_FLOAT_ATI; }
2545                 else if (tmp & GLX_RGBA_FLOAT_ATI_BIT) { piValues[i] = WGL_TYPE_RGBA_FLOAT_ATI; }
2546                 else if (tmp & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) { piValues[i] = WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT; }
2547                 else {
2548                     ERR("unexpected RenderType(%x)\n", tmp);
2549                     piValues[i] = WGL_TYPE_RGBA_ARB;
2550                 }
2551                 continue;
2552
2553             case WGL_COLOR_BITS_ARB:
2554                 curGLXAttr = GLX_BUFFER_SIZE;
2555                 break;
2556
2557             case WGL_BIND_TO_TEXTURE_RGB_ARB:
2558             case WGL_BIND_TO_TEXTURE_RGBA_ARB:
2559                 if (!use_render_texture_emulation) {
2560                     piValues[i] = GL_FALSE;
2561                     continue;   
2562                 }
2563                 curGLXAttr = GLX_RENDER_TYPE;
2564                 if (!fmt) goto pix_error;
2565                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, &tmp);
2566                 if (hTest) goto get_error;
2567                 if (GLX_COLOR_INDEX_BIT == tmp) {
2568                     piValues[i] = GL_FALSE;  
2569                     continue;
2570                 }
2571                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &tmp);
2572                 if (hTest) goto get_error;
2573                 piValues[i] = (tmp & GLX_PBUFFER_BIT) ? GL_TRUE : GL_FALSE;
2574                 continue;
2575
2576             case WGL_BLUE_BITS_ARB:
2577                 curGLXAttr = GLX_BLUE_SIZE;
2578                 break;
2579             case WGL_RED_BITS_ARB:
2580                 curGLXAttr = GLX_RED_SIZE;
2581                 break;
2582             case WGL_GREEN_BITS_ARB:
2583                 curGLXAttr = GLX_GREEN_SIZE;
2584                 break;
2585             case WGL_ALPHA_BITS_ARB:
2586                 curGLXAttr = GLX_ALPHA_SIZE;
2587                 break;
2588             case WGL_DEPTH_BITS_ARB:
2589                 curGLXAttr = GLX_DEPTH_SIZE;
2590                 break;
2591             case WGL_STENCIL_BITS_ARB:
2592                 curGLXAttr = GLX_STENCIL_SIZE;
2593                 break;
2594             case WGL_DOUBLE_BUFFER_ARB:
2595                 curGLXAttr = GLX_DOUBLEBUFFER;
2596                 break;
2597             case WGL_STEREO_ARB:
2598                 curGLXAttr = GLX_STEREO;
2599                 break;
2600             case WGL_AUX_BUFFERS_ARB:
2601                 curGLXAttr = GLX_AUX_BUFFERS;
2602                 break;
2603
2604             case WGL_SUPPORT_GDI_ARB:
2605                 if (!fmt) goto pix_error;
2606                 piValues[i] = (fmt->dwFlags & PFD_SUPPORT_GDI) != 0;
2607                 continue;
2608
2609             case WGL_DRAW_TO_BITMAP_ARB:
2610                 if (!fmt) goto pix_error;
2611                 piValues[i] = (fmt->dwFlags & PFD_DRAW_TO_BITMAP) != 0;
2612                 continue;
2613
2614             case WGL_DRAW_TO_WINDOW_ARB:
2615             case WGL_DRAW_TO_PBUFFER_ARB:
2616                 if (!fmt) goto pix_error;
2617                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &tmp);
2618                 if (hTest) goto get_error;
2619                 if((curWGLAttr == WGL_DRAW_TO_WINDOW_ARB && (tmp&GLX_WINDOW_BIT)) ||
2620                    (curWGLAttr == WGL_DRAW_TO_PBUFFER_ARB && (tmp&GLX_PBUFFER_BIT)))
2621                     piValues[i] = GL_TRUE;
2622                 else
2623                     piValues[i] = GL_FALSE;
2624                 continue;
2625
2626             case WGL_SWAP_METHOD_ARB:
2627                 /* For now return SWAP_EXCHANGE_ARB which is the best type of buffer switch available.
2628                  * Later on we can also use GLX_OML_swap_method on drivers which support this. At this
2629                  * point only ATI offers this.
2630                  */
2631                 piValues[i] = WGL_SWAP_EXCHANGE_ARB;
2632                 break;
2633
2634             case WGL_PBUFFER_LARGEST_ARB:
2635                 curGLXAttr = GLX_LARGEST_PBUFFER;
2636                 break;
2637
2638             case WGL_SAMPLE_BUFFERS_ARB:
2639                 curGLXAttr = GLX_SAMPLE_BUFFERS_ARB;
2640                 break;
2641
2642             case WGL_SAMPLES_ARB:
2643                 curGLXAttr = GLX_SAMPLES_ARB;
2644                 break;
2645
2646             case WGL_FLOAT_COMPONENTS_NV:
2647                 curGLXAttr = GLX_FLOAT_COMPONENTS_NV;
2648                 break;
2649
2650             case WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT:
2651                 curGLXAttr = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT;
2652                 break;
2653
2654             case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT:
2655                 curGLXAttr = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT;
2656                 break;
2657
2658             case WGL_ACCUM_RED_BITS_ARB:
2659                 curGLXAttr = GLX_ACCUM_RED_SIZE;
2660                 break;
2661             case WGL_ACCUM_GREEN_BITS_ARB:
2662                 curGLXAttr = GLX_ACCUM_GREEN_SIZE;
2663                 break;
2664             case WGL_ACCUM_BLUE_BITS_ARB:
2665                 curGLXAttr = GLX_ACCUM_BLUE_SIZE;
2666                 break;
2667             case WGL_ACCUM_ALPHA_BITS_ARB:
2668                 curGLXAttr = GLX_ACCUM_ALPHA_SIZE;
2669                 break;
2670             case WGL_ACCUM_BITS_ARB:
2671                 if (!fmt) goto pix_error;
2672                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_RED_SIZE, &tmp);
2673                 if (hTest) goto get_error;
2674                 piValues[i] = tmp;
2675                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_GREEN_SIZE, &tmp);
2676                 if (hTest) goto get_error;
2677                 piValues[i] += tmp;
2678                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_BLUE_SIZE, &tmp);
2679                 if (hTest) goto get_error;
2680                 piValues[i] += tmp;
2681                 hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_ACCUM_ALPHA_SIZE, &tmp);
2682                 if (hTest) goto get_error;
2683                 piValues[i] += tmp;
2684                 continue;
2685
2686             default:
2687                 FIXME("unsupported %x WGL Attribute\n", curWGLAttr);
2688         }
2689
2690         /* Retrieve a GLX FBConfigAttrib when the attribute to query is valid and
2691          * iPixelFormat != 0. When iPixelFormat is 0 the only value which makes
2692          * sense to query is WGL_NUMBER_PIXEL_FORMATS_ARB.
2693          *
2694          * TODO: properly test the behavior of wglGetPixelFormatAttrib*v on Windows
2695          *       and check which options can work using iPixelFormat=0 and which not.
2696          *       A problem would be that this function is an extension. This would
2697          *       mean that the behavior could differ between different vendors (ATI, Nvidia, ..).
2698          */
2699         if (0 != curGLXAttr && iPixelFormat != 0) {
2700             if (!fmt) goto pix_error;
2701             hTest = pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, curGLXAttr, piValues + i);
2702             if (hTest) goto get_error;
2703             curGLXAttr = 0;
2704         } else { 
2705             piValues[i] = GL_FALSE; 
2706         }
2707     }
2708     return GL_TRUE;
2709
2710 get_error:
2711     ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc, curGLXAttr);
2712     return GL_FALSE;
2713
2714 pix_error:
2715     ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc, iPixelFormat, nb_pixel_formats);
2716     return GL_FALSE;
2717 }
2718
2719 /**
2720  * X11DRV_wglGetPixelFormatAttribfvARB
2721  *
2722  * WGL_ARB_pixel_format: wglGetPixelFormatAttribfvARB
2723  */
2724 static BOOL X11DRV_wglGetPixelFormatAttribfvARB( HDC hdc, int iPixelFormat, int iLayerPlane,
2725                                                  UINT nAttributes, const int *piAttributes, FLOAT *pfValues )
2726 {
2727     int *attr;
2728     int ret;
2729     UINT i;
2730
2731     TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues);
2732
2733     /* Allocate a temporary array to store integer values */
2734     attr = HeapAlloc(GetProcessHeap(), 0, nAttributes * sizeof(int));
2735     if (!attr) {
2736         ERR("couldn't allocate %d array\n", nAttributes);
2737         return GL_FALSE;
2738     }
2739
2740     /* Piggy-back on wglGetPixelFormatAttribivARB */
2741     ret = X11DRV_wglGetPixelFormatAttribivARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, attr);
2742     if (ret) {
2743         /* Convert integer values to float. Should also check for attributes
2744            that can give decimal values here */
2745         for (i=0; i<nAttributes;i++) {
2746             pfValues[i] = attr[i];
2747         }
2748     }
2749
2750     HeapFree(GetProcessHeap(), 0, attr);
2751     return ret;
2752 }
2753
2754 /**
2755  * X11DRV_wglBindTexImageARB
2756  *
2757  * WGL_ARB_render_texture: wglBindTexImageARB
2758  */
2759 static BOOL X11DRV_wglBindTexImageARB( struct wgl_pbuffer *object, int iBuffer )
2760 {
2761     GLboolean ret = GL_FALSE;
2762
2763     TRACE("(%p, %d)\n", object, iBuffer);
2764
2765     if (!object->use_render_texture) {
2766         SetLastError(ERROR_INVALID_HANDLE);
2767         return GL_FALSE;
2768     }
2769
2770     if (1 == use_render_texture_emulation) {
2771         static int init = 0;
2772         int prev_binded_texture = 0;
2773         GLXContext prev_context;
2774         Drawable prev_drawable;
2775         GLXContext tmp_context;
2776
2777         prev_context = pglXGetCurrentContext();
2778         prev_drawable = pglXGetCurrentDrawable();
2779
2780         /* Our render_texture emulation is basic and lacks some features (1D/Cube support).
2781            This is mostly due to lack of demos/games using them. Further the use of glReadPixels
2782            isn't ideal performance wise but I wasn't able to get other ways working.
2783         */
2784         if(!init) {
2785             init = 1; /* Only show the FIXME once for performance reasons */
2786             FIXME("partial stub!\n");
2787         }
2788
2789         TRACE("drawable=%lx, context=%p\n", object->drawable, prev_context);
2790         tmp_context = pglXCreateNewContext(gdi_display, object->fmt->fbconfig, object->fmt->render_type, prev_context, True);
2791
2792         opengl_funcs.gl.p_glGetIntegerv(object->texture_bind_target, &prev_binded_texture);
2793
2794         /* Switch to our pbuffer */
2795         pglXMakeCurrent(gdi_display, object->drawable, tmp_context);
2796
2797         /* Make sure that the prev_binded_texture is set as the current texture state isn't shared between contexts.
2798          * After that upload the pbuffer texture data. */
2799         opengl_funcs.gl.p_glBindTexture(object->texture_target, prev_binded_texture);
2800         opengl_funcs.gl.p_glCopyTexImage2D(object->texture_target, 0, object->use_render_texture, 0, 0, object->width, object->height, 0);
2801
2802         /* Switch back to the original drawable and upload the pbuffer-texture */
2803         pglXMakeCurrent(gdi_display, prev_drawable, prev_context);
2804         pglXDestroyContext(gdi_display, tmp_context);
2805         return GL_TRUE;
2806     }
2807
2808     return ret;
2809 }
2810
2811 /**
2812  * X11DRV_wglReleaseTexImageARB
2813  *
2814  * WGL_ARB_render_texture: wglReleaseTexImageARB
2815  */
2816 static BOOL X11DRV_wglReleaseTexImageARB( struct wgl_pbuffer *object, int iBuffer )
2817 {
2818     GLboolean ret = GL_FALSE;
2819
2820     TRACE("(%p, %d)\n", object, iBuffer);
2821
2822     if (!object->use_render_texture) {
2823         SetLastError(ERROR_INVALID_HANDLE);
2824         return GL_FALSE;
2825     }
2826     if (1 == use_render_texture_emulation) {
2827         return GL_TRUE;
2828     }
2829     return ret;
2830 }
2831
2832 /**
2833  * X11DRV_wglGetExtensionsStringEXT
2834  *
2835  * WGL_EXT_extensions_string: wglGetExtensionsStringEXT
2836  */
2837 static const GLubyte *X11DRV_wglGetExtensionsStringEXT(void)
2838 {
2839     TRACE("() returning \"%s\"\n", WineGLInfo.wglExtensions);
2840     return (const GLubyte *)WineGLInfo.wglExtensions;
2841 }
2842
2843 /**
2844  * X11DRV_wglGetSwapIntervalEXT
2845  *
2846  * WGL_EXT_swap_control: wglGetSwapIntervalEXT
2847  */
2848 static int X11DRV_wglGetSwapIntervalEXT(void)
2849 {
2850     /* GLX_SGI_swap_control doesn't have any provisions for getting the swap
2851      * interval, so the swap interval has to be tracked. */
2852     TRACE("()\n");
2853     return swap_interval;
2854 }
2855
2856 /**
2857  * X11DRV_wglSwapIntervalEXT
2858  *
2859  * WGL_EXT_swap_control: wglSwapIntervalEXT
2860  */
2861 static BOOL X11DRV_wglSwapIntervalEXT(int interval)
2862 {
2863     BOOL ret = TRUE;
2864
2865     TRACE("(%d)\n", interval);
2866
2867     if (interval < 0)
2868     {
2869         SetLastError(ERROR_INVALID_DATA);
2870         return FALSE;
2871     }
2872     else if (!has_swap_control && interval == 0)
2873     {
2874         /* wglSwapIntervalEXT considers an interval value of zero to mean that
2875          * vsync should be disabled, but glXSwapIntervalSGI considers such a
2876          * value to be an error. Just silently ignore the request for now. */
2877         WARN("Request to disable vertical sync is not handled\n");
2878         swap_interval = 0;
2879     }
2880     else
2881     {
2882         if (pglXSwapIntervalSGI)
2883             ret = !pglXSwapIntervalSGI(interval);
2884         else
2885             WARN("GLX_SGI_swap_control extension is not available\n");
2886
2887         if (ret)
2888             swap_interval = interval;
2889         else
2890             SetLastError(ERROR_DC_NOT_FOUND);
2891     }
2892
2893     return ret;
2894 }
2895
2896 /**
2897  * X11DRV_wglSetPixelFormatWINE
2898  *
2899  * WGL_WINE_pixel_format_passthrough: wglSetPixelFormatWINE
2900  * This is a WINE-specific wglSetPixelFormat which can set the pixel format multiple times.
2901  */
2902 static BOOL X11DRV_wglSetPixelFormatWINE(HDC hdc, int format)
2903 {
2904     const struct wgl_pixel_format *fmt;
2905     int value;
2906     HWND hwnd;
2907
2908     TRACE("(%p,%d)\n", hdc, format);
2909
2910     fmt = get_pixel_format(gdi_display, format, FALSE /* Offscreen */);
2911     if (!fmt)
2912     {
2913         ERR( "Invalid format %d\n", format );
2914         return FALSE;
2915     }
2916
2917     hwnd = WindowFromDC( hdc );
2918     if (!hwnd || hwnd == GetDesktopWindow())
2919     {
2920         ERR( "not a valid window DC %p\n", hdc );
2921         return FALSE;
2922     }
2923
2924     pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
2925     if (!(value & GLX_WINDOW_BIT))
2926     {
2927         WARN( "Pixel format %d is not compatible for window rendering\n", format );
2928         return FALSE;
2929     }
2930
2931     return SendMessageW(hwnd, WM_X11DRV_SET_WIN_FORMAT, fmt->fmt_id, 0);
2932     /* DC pixel format will be set by the DCE update */
2933 }
2934
2935 /**
2936  * glxRequireVersion (internal)
2937  *
2938  * Check if the supported GLX version matches requiredVersion.
2939  */
2940 static BOOL glxRequireVersion(int requiredVersion)
2941 {
2942     /* Both requiredVersion and glXVersion[1] contains the minor GLX version */
2943     if(requiredVersion <= WineGLInfo.glxVersion[1])
2944         return TRUE;
2945
2946     return FALSE;
2947 }
2948
2949 static void register_extension(const char *ext)
2950 {
2951     if (WineGLInfo.wglExtensions[0])
2952         strcat(WineGLInfo.wglExtensions, " ");
2953     strcat(WineGLInfo.wglExtensions, ext);
2954
2955     TRACE("'%s'\n", ext);
2956 }
2957
2958 /**
2959  * X11DRV_WineGL_LoadExtensions
2960  */
2961 static void X11DRV_WineGL_LoadExtensions(void)
2962 {
2963     WineGLInfo.wglExtensions[0] = 0;
2964
2965     /* ARB Extensions */
2966
2967     if (has_extension( WineGLInfo.glxExtensions, "GLX_ARB_create_context"))
2968     {
2969         register_extension( "WGL_ARB_create_context" );
2970         opengl_funcs.ext.p_wglCreateContextAttribsARB = X11DRV_wglCreateContextAttribsARB;
2971
2972         if (has_extension( WineGLInfo.glxExtensions, "GLX_ARB_create_context_profile"))
2973             register_extension("WGL_ARB_create_context_profile");
2974     }
2975
2976     if (has_extension( WineGLInfo.glxExtensions, "GLX_ARB_fbconfig_float"))
2977     {
2978         register_extension("WGL_ARB_pixel_format_float");
2979         register_extension("WGL_ATI_pixel_format_float");
2980     }
2981
2982     register_extension( "WGL_ARB_extensions_string" );
2983     opengl_funcs.ext.p_wglGetExtensionsStringARB = X11DRV_wglGetExtensionsStringARB;
2984
2985     if (glxRequireVersion(3))
2986     {
2987         register_extension( "WGL_ARB_make_current_read" );
2988         opengl_funcs.ext.p_wglGetCurrentReadDCARB   = (void *)1;  /* never called */
2989         opengl_funcs.ext.p_wglMakeContextCurrentARB = X11DRV_wglMakeContextCurrentARB;
2990     }
2991
2992     if (has_extension( WineGLInfo.glxExtensions, "GLX_ARB_multisample")) register_extension( "WGL_ARB_multisample" );
2993
2994     /* In general pbuffer functionality requires support in the X-server. The functionality is
2995      * available either when the GLX_SGIX_pbuffer is present or when the GLX server version is 1.3.
2996      */
2997     if ( glxRequireVersion(3) && has_extension( WineGLInfo.glxExtensions, "GLX_SGIX_pbuffer") )
2998     {
2999         register_extension( "WGL_ARB_pbuffer" );
3000         opengl_funcs.ext.p_wglCreatePbufferARB    = X11DRV_wglCreatePbufferARB;
3001         opengl_funcs.ext.p_wglDestroyPbufferARB   = X11DRV_wglDestroyPbufferARB;
3002         opengl_funcs.ext.p_wglGetPbufferDCARB     = X11DRV_wglGetPbufferDCARB;
3003         opengl_funcs.ext.p_wglQueryPbufferARB     = X11DRV_wglQueryPbufferARB;
3004         opengl_funcs.ext.p_wglReleasePbufferDCARB = X11DRV_wglReleasePbufferDCARB;
3005         opengl_funcs.ext.p_wglSetPbufferAttribARB = X11DRV_wglSetPbufferAttribARB;
3006     }
3007
3008     register_extension( "WGL_ARB_pixel_format" );
3009     opengl_funcs.ext.p_wglChoosePixelFormatARB      = X11DRV_wglChoosePixelFormatARB;
3010     opengl_funcs.ext.p_wglGetPixelFormatAttribfvARB = X11DRV_wglGetPixelFormatAttribfvARB;
3011     opengl_funcs.ext.p_wglGetPixelFormatAttribivARB = X11DRV_wglGetPixelFormatAttribivARB;
3012
3013     /* Support WGL_ARB_render_texture when there's support or pbuffer based emulation */
3014     if (has_extension( WineGLInfo.glxExtensions, "GLX_ARB_render_texture") ||
3015         (glxRequireVersion(3) && has_extension( WineGLInfo.glxExtensions, "GLX_SGIX_pbuffer") && use_render_texture_emulation))
3016     {
3017         register_extension( "WGL_ARB_render_texture" );
3018         opengl_funcs.ext.p_wglBindTexImageARB    = X11DRV_wglBindTexImageARB;
3019         opengl_funcs.ext.p_wglReleaseTexImageARB = X11DRV_wglReleaseTexImageARB;
3020
3021         /* The WGL version of GLX_NV_float_buffer requires render_texture */
3022         if (has_extension( WineGLInfo.glxExtensions, "GLX_NV_float_buffer"))
3023             register_extension("WGL_NV_float_buffer");
3024
3025         /* Again there's no GLX equivalent for this extension, so depend on the required GL extension */
3026         if (has_extension(WineGLInfo.glExtensions, "GL_NV_texture_rectangle"))
3027             register_extension("WGL_NV_texture_rectangle");
3028     }
3029
3030     /* EXT Extensions */
3031
3032     register_extension( "WGL_EXT_extensions_string" );
3033     opengl_funcs.ext.p_wglGetExtensionsStringEXT = X11DRV_wglGetExtensionsStringEXT;
3034
3035     /* Load this extension even when it isn't backed by a GLX extension because it is has been around for ages.
3036      * Games like Call of Duty and K.O.T.O.R. rely on it. Further our emulation is good enough. */
3037     register_extension( "WGL_EXT_swap_control" );
3038     opengl_funcs.ext.p_wglSwapIntervalEXT = X11DRV_wglSwapIntervalEXT;
3039     opengl_funcs.ext.p_wglGetSwapIntervalEXT = X11DRV_wglGetSwapIntervalEXT;
3040
3041     if (has_extension( WineGLInfo.glxExtensions, "GLX_EXT_framebuffer_sRGB"))
3042         register_extension("WGL_EXT_framebuffer_sRGB");
3043
3044     if (has_extension( WineGLInfo.glxExtensions, "GLX_EXT_fbconfig_packed_float"))
3045         register_extension("WGL_EXT_pixel_format_packed_float");
3046
3047     if (has_extension( WineGLInfo.glxExtensions, "GLX_EXT_swap_control"))
3048         has_swap_control = TRUE;
3049
3050     /* The OpenGL extension GL_NV_vertex_array_range adds wgl/glX functions which aren't exported as 'real' wgl/glX extensions. */
3051     if (has_extension(WineGLInfo.glExtensions, "GL_NV_vertex_array_range"))
3052     {
3053         register_extension( "WGL_NV_vertex_array_range" );
3054         opengl_funcs.ext.p_wglAllocateMemoryNV = pglXAllocateMemoryNV;
3055         opengl_funcs.ext.p_wglFreeMemoryNV = pglXFreeMemoryNV;
3056     }
3057
3058     /* WINE-specific WGL Extensions */
3059
3060     /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset).
3061      * The default wglSetPixelFormat doesn't allow this, so add our own which allows it.
3062      */
3063     register_extension( "WGL_WINE_pixel_format_passthrough" );
3064     opengl_funcs.ext.p_wglSetPixelFormatWINE = X11DRV_wglSetPixelFormatWINE;
3065 }
3066
3067
3068 /**
3069  * glxdrv_SwapBuffers
3070  *
3071  * Swap the buffers of this DC
3072  */
3073 static BOOL glxdrv_SwapBuffers(PHYSDEV dev)
3074 {
3075   struct glx_physdev *physdev = get_glxdrv_dev( dev );
3076   struct wgl_context *ctx = NtCurrentTeb()->glContext;
3077
3078   TRACE("(%p)\n", dev->hdc);
3079
3080   if (!ctx)
3081   {
3082       WARN("Using a NULL context, skipping\n");
3083       SetLastError(ERROR_INVALID_HANDLE);
3084       return FALSE;
3085   }
3086
3087   if (!physdev->drawable)
3088   {
3089       WARN("Using an invalid drawable, skipping\n");
3090       SetLastError(ERROR_INVALID_HANDLE);
3091       return FALSE;
3092   }
3093
3094   sync_context(ctx);
3095   switch (physdev->type)
3096   {
3097   case DC_GL_PIXMAP_WIN:
3098       if(pglXCopySubBufferMESA) {
3099           int w = physdev->x11dev->dc_rect.right - physdev->x11dev->dc_rect.left;
3100           int h = physdev->x11dev->dc_rect.bottom - physdev->x11dev->dc_rect.top;
3101
3102           /* (glX)SwapBuffers has an implicit glFlush effect, however
3103            * GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before
3104            * copying */
3105           pglFlush();
3106           if(w > 0 && h > 0)
3107               pglXCopySubBufferMESA(gdi_display, physdev->drawable, 0, 0, w, h);
3108           break;
3109       }
3110       /* fall through */
3111   default:
3112       pglXSwapBuffers(gdi_display, physdev->drawable);
3113       break;
3114   }
3115
3116   flush_gl_drawable( physdev );
3117
3118   /* FPS support */
3119   if (TRACE_ON(fps))
3120   {
3121       static long prev_time, start_time;
3122       static unsigned long frames, frames_total;
3123
3124       DWORD time = GetTickCount();
3125       frames++;
3126       frames_total++;
3127       /* every 1.5 seconds */
3128       if (time - prev_time > 1500) {
3129           TRACE_(fps)("@ approx %.2ffps, total %.2ffps\n",
3130                       1000.0*frames/(time - prev_time), 1000.0*frames_total/(time - start_time));
3131           prev_time = time;
3132           frames = 0;
3133           if(start_time == 0) start_time = time;
3134       }
3135   }
3136
3137   return TRUE;
3138 }
3139
3140 static BOOL create_glx_dc( PHYSDEV *pdev )
3141 {
3142     /* assume that only the main x11 device implements GetDeviceCaps */
3143     X11DRV_PDEVICE *x11dev = get_x11drv_dev( GET_NEXT_PHYSDEV( *pdev, pGetDeviceCaps ));
3144     struct glx_physdev *physdev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*physdev) );
3145
3146     if (!physdev) return FALSE;
3147     physdev->x11dev = x11dev;
3148     push_dc_driver( pdev, &physdev->dev, &glxdrv_funcs );
3149     return TRUE;
3150 }
3151
3152 /**********************************************************************
3153  *           glxdrv_CreateDC
3154  */
3155 static BOOL glxdrv_CreateDC( PHYSDEV *pdev, LPCWSTR driver, LPCWSTR device,
3156                              LPCWSTR output, const DEVMODEW* initData )
3157 {
3158     return create_glx_dc( pdev );
3159 }
3160
3161 /**********************************************************************
3162  *           glxdrv_CreateCompatibleDC
3163  */
3164 static BOOL glxdrv_CreateCompatibleDC( PHYSDEV orig, PHYSDEV *pdev )
3165 {
3166     if (orig)  /* chain to next driver first */
3167     {
3168         orig = GET_NEXT_PHYSDEV( orig, pCreateCompatibleDC );
3169         if (!orig->funcs->pCreateCompatibleDC( orig, pdev )) return FALSE;
3170     }
3171     /* otherwise we have been called by x11drv */
3172     return create_glx_dc( pdev );
3173 }
3174
3175 /**********************************************************************
3176  *           glxdrv_DeleteDC
3177  */
3178 static BOOL glxdrv_DeleteDC( PHYSDEV dev )
3179 {
3180     struct glx_physdev *physdev = get_glxdrv_dev( dev );
3181     HeapFree( GetProcessHeap(), 0, physdev );
3182     return TRUE;
3183 }
3184
3185 /**********************************************************************
3186  *           glxdrv_ExtEscape
3187  */
3188 static INT glxdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data,
3189                              INT out_count, LPVOID out_data )
3190 {
3191     struct glx_physdev *physdev = get_glxdrv_dev( dev );
3192
3193     dev = GET_NEXT_PHYSDEV( dev, pExtEscape );
3194
3195     if (escape == X11DRV_ESCAPE && in_data && in_count >= sizeof(enum x11drv_escape_codes))
3196     {
3197         switch (*(const enum x11drv_escape_codes *)in_data)
3198         {
3199         case X11DRV_SET_DRAWABLE:
3200             if (in_count >= sizeof(struct x11drv_escape_set_drawable))
3201             {
3202                 struct gl_drawable *gl;
3203                 const struct x11drv_escape_set_drawable *data = in_data;
3204
3205                 EnterCriticalSection( &context_section );
3206                 if (!XFindContext( gdi_display, (XID)data->hwnd, gl_hwnd_context, (char **)&gl ) ||
3207                     !XFindContext( gdi_display, (XID)dev->hdc, gl_pbuffer_context, (char **)&gl ))
3208                 {
3209                     physdev->format       = gl->format;
3210                     physdev->type         = gl->type;
3211                     physdev->drawable     = gl->drawable;
3212                     physdev->pixmap       = gl->pixmap;
3213                 }
3214                 else
3215                 {
3216                     physdev->format       = NULL;
3217                     physdev->type         = DC_GL_NONE;
3218                     physdev->drawable     = 0;
3219                     physdev->pixmap       = 0;
3220                 }
3221                 LeaveCriticalSection( &context_section );
3222                 TRACE( "SET_DRAWABLE hdc %p drawable %lx pf %p type %u\n",
3223                        dev->hdc, physdev->drawable, physdev->format, physdev->type );
3224             }
3225             break;
3226         case X11DRV_GET_DRAWABLE:
3227             if (out_count >= sizeof(struct x11drv_escape_get_drawable))
3228             {
3229                 struct x11drv_escape_get_drawable *data = out_data;
3230                 data->pixel_format = physdev->format ? physdev->format - pixel_formats + 1 : 0;
3231                 data->gl_drawable  = physdev->drawable;
3232             }
3233             break;
3234         case X11DRV_FLUSH_GL_DRAWABLE:
3235             flush_gl_drawable( physdev );
3236             return TRUE;
3237         default:
3238             break;
3239         }
3240     }
3241     return dev->funcs->pExtEscape( dev, escape, in_count, in_data, out_count, out_data );
3242 }
3243
3244 /**********************************************************************
3245  *           glxdrv_wine_get_wgl_driver
3246  */
3247 static struct opengl_funcs * glxdrv_wine_get_wgl_driver( PHYSDEV dev, UINT version )
3248 {
3249     if (version != WINE_WGL_DRIVER_VERSION)
3250     {
3251         ERR( "version mismatch, opengl32 wants %u but driver has %u\n", version, WINE_WGL_DRIVER_VERSION );
3252         return NULL;
3253     }
3254
3255     if (has_opengl()) return &opengl_funcs;
3256
3257     dev = GET_NEXT_PHYSDEV( dev, wine_get_wgl_driver );
3258     return dev->funcs->wine_get_wgl_driver( dev, version );
3259 }
3260
3261 static const struct gdi_dc_funcs glxdrv_funcs =
3262 {
3263     NULL,                               /* pAbortDoc */
3264     NULL,                               /* pAbortPath */
3265     NULL,                               /* pAlphaBlend */
3266     NULL,                               /* pAngleArc */
3267     NULL,                               /* pArc */
3268     NULL,                               /* pArcTo */
3269     NULL,                               /* pBeginPath */
3270     NULL,                               /* pBlendImage */
3271     NULL,                               /* pChord */
3272     NULL,                               /* pCloseFigure */
3273     glxdrv_CreateCompatibleDC,          /* pCreateCompatibleDC */
3274     glxdrv_CreateDC,                    /* pCreateDC */
3275     glxdrv_DeleteDC,                    /* pDeleteDC */
3276     NULL,                               /* pDeleteObject */
3277     NULL,                               /* pDeviceCapabilities */
3278     NULL,                               /* pEllipse */
3279     NULL,                               /* pEndDoc */
3280     NULL,                               /* pEndPage */
3281     NULL,                               /* pEndPath */
3282     NULL,                               /* pEnumFonts */
3283     NULL,                               /* pEnumICMProfiles */
3284     NULL,                               /* pExcludeClipRect */
3285     NULL,                               /* pExtDeviceMode */
3286     glxdrv_ExtEscape,                   /* pExtEscape */
3287     NULL,                               /* pExtFloodFill */
3288     NULL,                               /* pExtSelectClipRgn */
3289     NULL,                               /* pExtTextOut */
3290     NULL,                               /* pFillPath */
3291     NULL,                               /* pFillRgn */
3292     NULL,                               /* pFlattenPath */
3293     NULL,                               /* pFontIsLinked */
3294     NULL,                               /* pFrameRgn */
3295     NULL,                               /* pGdiComment */
3296     NULL,                               /* pGdiRealizationInfo */
3297     NULL,                               /* pGetBoundsRect */
3298     NULL,                               /* pGetCharABCWidths */
3299     NULL,                               /* pGetCharABCWidthsI */
3300     NULL,                               /* pGetCharWidth */
3301     NULL,                               /* pGetDeviceCaps */
3302     NULL,                               /* pGetDeviceGammaRamp */
3303     NULL,                               /* pGetFontData */
3304     NULL,                               /* pGetFontUnicodeRanges */
3305     NULL,                               /* pGetGlyphIndices */
3306     NULL,                               /* pGetGlyphOutline */
3307     NULL,                               /* pGetICMProfile */
3308     NULL,                               /* pGetImage */
3309     NULL,                               /* pGetKerningPairs */
3310     NULL,                               /* pGetNearestColor */
3311     NULL,                               /* pGetOutlineTextMetrics */
3312     NULL,                               /* pGetPixel */
3313     NULL,                               /* pGetSystemPaletteEntries */
3314     NULL,                               /* pGetTextCharsetInfo */
3315     NULL,                               /* pGetTextExtentExPoint */
3316     NULL,                               /* pGetTextExtentExPointI */
3317     NULL,                               /* pGetTextFace */
3318     NULL,                               /* pGetTextMetrics */
3319     NULL,                               /* pGradientFill */
3320     NULL,                               /* pIntersectClipRect */
3321     NULL,                               /* pInvertRgn */
3322     NULL,                               /* pLineTo */
3323     NULL,                               /* pModifyWorldTransform */
3324     NULL,                               /* pMoveTo */
3325     NULL,                               /* pOffsetClipRgn */
3326     NULL,                               /* pOffsetViewportOrg */
3327     NULL,                               /* pOffsetWindowOrg */
3328     NULL,                               /* pPaintRgn */
3329     NULL,                               /* pPatBlt */
3330     NULL,                               /* pPie */
3331     NULL,                               /* pPolyBezier */
3332     NULL,                               /* pPolyBezierTo */
3333     NULL,                               /* pPolyDraw */
3334     NULL,                               /* pPolyPolygon */
3335     NULL,                               /* pPolyPolyline */
3336     NULL,                               /* pPolygon */
3337     NULL,                               /* pPolyline */
3338     NULL,                               /* pPolylineTo */
3339     NULL,                               /* pPutImage */
3340     NULL,                               /* pRealizeDefaultPalette */
3341     NULL,                               /* pRealizePalette */
3342     NULL,                               /* pRectangle */
3343     NULL,                               /* pResetDC */
3344     NULL,                               /* pRestoreDC */
3345     NULL,                               /* pRoundRect */
3346     NULL,                               /* pSaveDC */
3347     NULL,                               /* pScaleViewportExt */
3348     NULL,                               /* pScaleWindowExt */
3349     NULL,                               /* pSelectBitmap */
3350     NULL,                               /* pSelectBrush */
3351     NULL,                               /* pSelectClipPath */
3352     NULL,                               /* pSelectFont */
3353     NULL,                               /* pSelectPalette */
3354     NULL,                               /* pSelectPen */
3355     NULL,                               /* pSetArcDirection */
3356     NULL,                               /* pSetBkColor */
3357     NULL,                               /* pSetBkMode */
3358     NULL,                               /* pSetBoundsRect */
3359     NULL,                               /* pSetDCBrushColor */
3360     NULL,                               /* pSetDCPenColor */
3361     NULL,                               /* pSetDIBitsToDevice */
3362     NULL,                               /* pSetDeviceClipping */
3363     NULL,                               /* pSetDeviceGammaRamp */
3364     NULL,                               /* pSetLayout */
3365     NULL,                               /* pSetMapMode */
3366     NULL,                               /* pSetMapperFlags */
3367     NULL,                               /* pSetPixel */
3368     NULL,                               /* pSetPolyFillMode */
3369     NULL,                               /* pSetROP2 */
3370     NULL,                               /* pSetRelAbs */
3371     NULL,                               /* pSetStretchBltMode */
3372     NULL,                               /* pSetTextAlign */
3373     NULL,                               /* pSetTextCharacterExtra */
3374     NULL,                               /* pSetTextColor */
3375     NULL,                               /* pSetTextJustification */
3376     NULL,                               /* pSetViewportExt */
3377     NULL,                               /* pSetViewportOrg */
3378     NULL,                               /* pSetWindowExt */
3379     NULL,                               /* pSetWindowOrg */
3380     NULL,                               /* pSetWorldTransform */
3381     NULL,                               /* pStartDoc */
3382     NULL,                               /* pStartPage */
3383     NULL,                               /* pStretchBlt */
3384     NULL,                               /* pStretchDIBits */
3385     NULL,                               /* pStrokeAndFillPath */
3386     NULL,                               /* pStrokePath */
3387     glxdrv_SwapBuffers,                 /* pSwapBuffers */
3388     NULL,                               /* pUnrealizePalette */
3389     NULL,                               /* pWidenPath */
3390     glxdrv_wine_get_wgl_driver,         /* wine_get_wgl_driver */
3391     GDI_PRIORITY_GRAPHICS_DRV + 20      /* priority */
3392 };
3393
3394 static struct opengl_funcs opengl_funcs =
3395 {
3396     {
3397         glxdrv_wglCopyContext,              /* p_wglCopyContext */
3398         glxdrv_wglCreateContext,            /* p_wglCreateContext */
3399         glxdrv_wglDeleteContext,            /* p_wglDeleteContext */
3400         glxdrv_wglDescribePixelFormat,      /* p_wglDescribePixelFormat */
3401         glxdrv_wglGetPixelFormat,           /* p_wglGetPixelFormat */
3402         glxdrv_wglGetProcAddress,           /* p_wglGetProcAddress */
3403         glxdrv_wglMakeCurrent,              /* p_wglMakeCurrent */
3404         glxdrv_wglSetPixelFormat,           /* p_wglSetPixelFormat */
3405         glxdrv_wglShareLists,               /* p_wglShareLists */
3406     }
3407 };
3408
3409 const struct gdi_dc_funcs *get_glx_driver(void)
3410 {
3411     return &glxdrv_funcs;
3412 }
3413
3414 #else  /* no OpenGL includes */
3415
3416 const struct gdi_dc_funcs *get_glx_driver(void)
3417 {
3418     return NULL;
3419 }
3420
3421 BOOL set_win_format( HWND hwnd, XID fbconfig_id )
3422 {
3423     return FALSE;
3424 }
3425
3426 void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_rect )
3427 {
3428 }
3429
3430 void destroy_gl_drawable( HWND hwnd )
3431 {
3432 }
3433
3434 #endif /* defined(SONAME_LIBGL) */