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