winex11.drv: Import glx context code.
[wine] / dlls / winex11.drv / opengl.c
1 /*
2  * X11DRV OpenGL functions
3  *
4  * Copyright 2000 Lionel Ulmer
5  * Copyright 2006 Roderick Colenbrander
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "x11drv.h"
29 #include "wine/library.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
33 WINE_DECLARE_DEBUG_CHANNEL(opengl);
34
35 #if defined(HAVE_GL_GL_H) && defined(HAVE_GL_GLX_H)
36
37 #undef APIENTRY
38 #undef CALLBACK
39 #undef WINAPI
40
41 #ifdef HAVE_GL_GL_H
42 # include <GL/gl.h>
43 #endif
44 #ifdef HAVE_GL_GLX_H
45 # include <GL/glx.h>
46 #endif
47 #ifdef HAVE_GL_GLEXT_H
48 # include <GL/glext.h>
49 #endif
50
51 #undef APIENTRY
52 #undef CALLBACK
53 #undef WINAPI
54
55 /* Redefines the constants */
56 #define CALLBACK    __stdcall
57 #define WINAPI      __stdcall
58 #define APIENTRY    WINAPI
59
60 WINE_DECLARE_DEBUG_CHANNEL(fps);
61
62 typedef struct wine_glcontext {
63   HDC hdc;
64   Display *display;
65   XVisualInfo *vis;
66   GLXFBConfig fb_conf;
67   GLXContext ctx;
68   BOOL do_escape;
69   struct wine_glcontext *next;
70   struct wine_glcontext *prev;
71 } Wine_GLContext;
72 static Wine_GLContext *context_list;
73
74 static void dump_PIXELFORMATDESCRIPTOR(const PIXELFORMATDESCRIPTOR *ppfd) {
75   TRACE("  - size / version : %d / %d\n", ppfd->nSize, ppfd->nVersion);
76   TRACE("  - dwFlags : ");
77 #define TEST_AND_DUMP(t,tv) if ((t) & (tv)) TRACE(#tv " ")
78   TEST_AND_DUMP(ppfd->dwFlags, PFD_DEPTH_DONTCARE);
79   TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER);
80   TEST_AND_DUMP(ppfd->dwFlags, PFD_DOUBLEBUFFER_DONTCARE);
81   TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_WINDOW);
82   TEST_AND_DUMP(ppfd->dwFlags, PFD_DRAW_TO_BITMAP);
83   TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_ACCELERATED);
84   TEST_AND_DUMP(ppfd->dwFlags, PFD_GENERIC_FORMAT);
85   TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_PALETTE);
86   TEST_AND_DUMP(ppfd->dwFlags, PFD_NEED_SYSTEM_PALETTE);
87   TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO);
88   TEST_AND_DUMP(ppfd->dwFlags, PFD_STEREO_DONTCARE);
89   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_GDI);
90   TEST_AND_DUMP(ppfd->dwFlags, PFD_SUPPORT_OPENGL);
91   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_COPY);
92   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_EXCHANGE);
93   TEST_AND_DUMP(ppfd->dwFlags, PFD_SWAP_LAYER_BUFFERS);
94 #undef TEST_AND_DUMP
95   TRACE("\n");
96
97   TRACE("  - iPixelType : ");
98   switch (ppfd->iPixelType) {
99   case PFD_TYPE_RGBA: TRACE("PFD_TYPE_RGBA"); break;
100   case PFD_TYPE_COLORINDEX: TRACE("PFD_TYPE_COLORINDEX"); break;
101   }
102   TRACE("\n");
103
104   TRACE("  - Color   : %d\n", ppfd->cColorBits);
105   TRACE("  - Red     : %d\n", ppfd->cRedBits);
106   TRACE("  - Green   : %d\n", ppfd->cGreenBits);
107   TRACE("  - Blue    : %d\n", ppfd->cBlueBits);
108   TRACE("  - Alpha   : %d\n", ppfd->cAlphaBits);
109   TRACE("  - Accum   : %d\n", ppfd->cAccumBits);
110   TRACE("  - Depth   : %d\n", ppfd->cDepthBits);
111   TRACE("  - Stencil : %d\n", ppfd->cStencilBits);
112   TRACE("  - Aux     : %d\n", ppfd->cAuxBuffers);
113
114   TRACE("  - iLayerType : ");
115   switch (ppfd->iLayerType) {
116   case PFD_MAIN_PLANE: TRACE("PFD_MAIN_PLANE"); break;
117   case PFD_OVERLAY_PLANE: TRACE("PFD_OVERLAY_PLANE"); break;
118   case (BYTE)PFD_UNDERLAY_PLANE: TRACE("PFD_UNDERLAY_PLANE"); break;
119   }
120   TRACE("\n");
121 }
122
123 /* No need to load any other libraries as according to the ABI, libGL should be self-sufficient and
124    include all dependencies
125 */
126 #ifndef SONAME_LIBGL
127 #define SONAME_LIBGL "libGL.so"
128 #endif
129
130 #define MAKE_FUNCPTR(f) static typeof(f) * p##f;
131 MAKE_FUNCPTR(glGetError)
132 MAKE_FUNCPTR(glXChooseVisual)
133 MAKE_FUNCPTR(glXGetConfig)
134 MAKE_FUNCPTR(glXSwapBuffers)
135 MAKE_FUNCPTR(glXQueryExtension)
136
137 MAKE_FUNCPTR(glXGetFBConfigs)
138 MAKE_FUNCPTR(glXChooseFBConfig)
139 MAKE_FUNCPTR(glXGetFBConfigAttrib)
140 MAKE_FUNCPTR(glXGetVisualFromFBConfig)
141 MAKE_FUNCPTR(glXCreateGLXPixmap)
142 MAKE_FUNCPTR(glXDestroyGLXPixmap)
143 MAKE_FUNCPTR(glXCreateContext)
144 MAKE_FUNCPTR(glXDestroyContext)
145 MAKE_FUNCPTR(glXGetCurrentContext)
146 MAKE_FUNCPTR(glXGetCurrentReadDrawable)
147 /* MAKE_FUNCPTR(glXQueryDrawable) */
148 #undef MAKE_FUNCPTR
149
150 static BOOL has_opengl(void)
151 {
152     static int init_done;
153     static void *opengl_handle;
154
155     int error_base, event_base;
156
157     if (init_done) return (opengl_handle != NULL);
158     init_done = 1;
159
160     opengl_handle = wine_dlopen(SONAME_LIBGL, RTLD_NOW|RTLD_GLOBAL, NULL, 0);
161     if (opengl_handle == NULL) return FALSE;
162
163 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(RTLD_DEFAULT, #f, NULL, 0)) == NULL) goto sym_not_found;
164 LOAD_FUNCPTR(glGetError)
165 LOAD_FUNCPTR(glXChooseVisual)
166 LOAD_FUNCPTR(glXGetConfig)
167 LOAD_FUNCPTR(glXSwapBuffers)
168 LOAD_FUNCPTR(glXQueryExtension)
169
170 LOAD_FUNCPTR(glXGetFBConfigs)
171 LOAD_FUNCPTR(glXChooseFBConfig)
172 LOAD_FUNCPTR(glXGetFBConfigAttrib)
173 LOAD_FUNCPTR(glXGetVisualFromFBConfig)
174 LOAD_FUNCPTR(glXCreateGLXPixmap)
175 LOAD_FUNCPTR(glXDestroyGLXPixmap)
176 LOAD_FUNCPTR(glXCreateContext)
177 LOAD_FUNCPTR(glXDestroyContext)
178 LOAD_FUNCPTR(glXGetCurrentContext)
179 LOAD_FUNCPTR(glXGetCurrentReadDrawable)
180 #undef LOAD_FUNCPTR
181
182     wine_tsx11_lock();
183     if (pglXQueryExtension(gdi_display, &error_base, &event_base) == True) {
184         TRACE("GLX is up and running error_base = %d\n", error_base);
185     } else {
186         wine_dlclose(opengl_handle, NULL, 0);
187         opengl_handle = NULL;
188     }
189     wine_tsx11_unlock();
190     return (opengl_handle != NULL);
191
192 sym_not_found:
193     wine_dlclose(opengl_handle, NULL, 0);
194     opengl_handle = NULL;
195     return FALSE;
196 }
197
198 static inline Wine_GLContext *alloc_context(void)
199 {
200     Wine_GLContext *ret;
201
202     if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLContext))))
203     {
204         ret->next = context_list;
205         if (context_list) context_list->prev = ret;
206         context_list = ret;
207     }
208     return ret;
209 }
210
211 static inline void free_context(Wine_GLContext *context)
212 {
213     if (context->next != NULL) context->next->prev = context->prev;
214     if (context->prev != NULL) context->prev->next = context->next;
215     else context_list = context->next;
216
217     HeapFree(GetProcessHeap(), 0, context);
218 }
219
220 static inline Wine_GLContext *get_context_from_GLXContext(GLXContext ctx)
221 {
222     Wine_GLContext *ret;
223     if (!ctx) return NULL;
224     for (ret = context_list; ret; ret = ret->next) if (ctx == ret->ctx) break;
225     return ret;
226 }
227
228 /* retrieve the GLX drawable to use on a given DC */
229 inline static Drawable get_drawable( HDC hdc )
230 {
231     GLXDrawable drawable;
232     enum x11drv_escape_codes escape = X11DRV_GET_GLX_DRAWABLE;
233
234     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
235                     sizeof(drawable), (LPSTR)&drawable )) drawable = 0;
236     return drawable;
237 }
238
239 /** for use of wglGetCurrentReadDCARB */
240 inline static HDC get_hdc_from_Drawable(GLXDrawable d)
241 {
242     Wine_GLContext *ret;
243     for (ret = context_list; ret; ret = ret->next) {
244         if (d == get_drawable( ret->hdc )) {
245             return ret->hdc;
246         }
247     }
248     return NULL;
249 }
250
251 inline static BOOL is_valid_context( Wine_GLContext *ctx )
252 {
253     Wine_GLContext *ptr;
254     for (ptr = context_list; ptr; ptr = ptr->next) if (ptr == ctx) break;
255     return (ptr != NULL);
256 }
257
258 /* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones.
259  * In our WGL implementation we only support a subset of these formats namely the format of
260  * Wine's main visual and offscreen formats (if they are available).
261  * This function converts a WGL format to its corresponding GLX one. It returns the index (zero-based)
262  * into the GLX FB config table and it returns the number of supported WGL formats in fmt_count.
263  */
264 static BOOL ConvertPixelFormatWGLtoGLX(Display *display, int iPixelFormat, int *fmt_index, int *fmt_count)
265 {
266   int res = FALSE;
267   int i = 0;
268   GLXFBConfig* cfgs = NULL;
269   int nCfgs = 0;
270   int tmp_fmt_id = 0;
271   int tmp_vis_id = 0;
272   int nFormats = 1; /* Start at 1 as we always have a main visual */
273   VisualID visualid = 0;
274
275   /* Request to look up the format of the main visual when iPixelFormat = 1 */
276   if(iPixelFormat == 1) visualid = XVisualIDFromVisual(visual);
277
278   /* As mentioned in various parts of the code only the format of the main visual can be used for onscreen rendering.
279    * Next to this format there are also so called offscreen rendering formats (used for pbuffers) which can be supported
280    * because they don't need a visual. Below we use glXGetFBConfigs instead of glXChooseFBConfig to enumerate the fb configurations
281    * bas this call lists both types of formats instead of only onscreen ones. */
282   cfgs = pglXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
283   if (NULL == cfgs || 0 == nCfgs) {
284     ERR("glXChooseFBConfig returns NULL\n");
285     if(cfgs != NULL) XFree(cfgs);
286     return FALSE;
287   }
288
289   /* Find the requested offscreen format and count the number of offscreen formats */
290   for(i=0; i<nCfgs; i++) {
291     pglXGetFBConfigAttrib(display, cfgs[i], GLX_VISUAL_ID, &tmp_vis_id);
292     pglXGetFBConfigAttrib(display, cfgs[i], GLX_FBCONFIG_ID, &tmp_fmt_id);
293
294     /* We are looking up the GLX index of our main visual and have found it :) */
295     if(iPixelFormat == 1 && visualid == tmp_vis_id) {
296       *fmt_index = i;
297       TRACE("Found FBCONFIG_ID 0x%x at index %d for VISUAL_ID 0x%x\n", tmp_fmt_id, *fmt_index, tmp_vis_id);
298       res = TRUE;
299     }
300     /* We found an offscreen rendering format :) */
301     else if(tmp_vis_id == 0) {
302       nFormats++;
303       TRACE("Checking offscreen format FBCONFIG_ID 0x%x at index %d\n", tmp_fmt_id, i);
304
305       if(iPixelFormat == nFormats) {
306         *fmt_index = i;
307         TRACE("Found offscreen format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", tmp_fmt_id, iPixelFormat, i);
308         res = TRUE;
309       }
310     }
311   }
312   *fmt_count = nFormats;
313   TRACE("Number of offscreen formats: %d; returning index: %d\n", *fmt_count, *fmt_index);
314
315   if(cfgs != NULL) XFree(cfgs);
316
317   if(res == FALSE && iPixelFormat == 1)
318     ERR("Can't find a matching FBCONFIG_ID for VISUAL_ID 0x%lx!\n", visualid);
319
320   return res;
321 }
322
323 /**
324  * X11DRV_ChoosePixelFormat
325  *
326  * Equivalent of glXChooseVisual
327  */
328 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev, 
329                              const PIXELFORMATDESCRIPTOR *ppfd) {
330   GLXFBConfig* cfgs = NULL;
331   int ret = 0;
332   int nCfgs = 0;
333   int value = 0;
334   int fmt_index = 0;
335
336   if (!has_opengl()) {
337     ERR("No libGL on this box - disabling OpenGL support !\n");
338     return 0;
339   }
340
341   if (TRACE_ON(opengl)) {
342     TRACE("(%p,%p)\n", physDev, ppfd);
343
344     dump_PIXELFORMATDESCRIPTOR((const PIXELFORMATDESCRIPTOR *) ppfd);
345   }
346
347   wine_tsx11_lock(); 
348   if(!visual) {
349     ERR("Can't get an opengl visual!\n");
350     goto choose_exit;
351   }
352
353   /* Get a list containing all supported FB configurations */
354   cfgs = pglXChooseFBConfig(gdi_display, DefaultScreen(gdi_display), NULL, &nCfgs);
355   if (NULL == cfgs || 0 == nCfgs) {
356     ERR("glXChooseFBConfig returns NULL (glError: %d)\n", pglGetError());
357     goto choose_exit;
358   }
359
360   /* In case an fbconfig was found, check if it matches to the requirements of the ppfd */
361   if(!ConvertPixelFormatWGLtoGLX(gdi_display, 1 /* main visual */, &fmt_index, &value)) {
362     ERR("Can't find a matching FBCONFIG_ID for VISUAL_ID 0x%lx!\n", visual->visualid);
363   } else {
364     int dwFlags = 0;
365     int iPixelType = 0;
366     int value = 0;
367
368     /* Pixel type */
369     pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_RENDER_TYPE, &value);
370     if (value & GLX_RGBA_BIT)
371       iPixelType = PFD_TYPE_RGBA;
372     else
373       iPixelType = PFD_TYPE_COLORINDEX;
374
375     if (ppfd->iPixelType != iPixelType) {
376       goto choose_exit;
377     }
378
379     /* Doublebuffer */
380     pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_DOUBLEBUFFER, &value); if (value) dwFlags |= PFD_DOUBLEBUFFER;
381     if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE)) {
382       if ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (dwFlags & PFD_DOUBLEBUFFER)) {
383         goto choose_exit;
384       }
385     }
386
387     /* Stereo */
388     pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_STEREO, &value); if (value) dwFlags |= PFD_STEREO;
389     if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE)) {
390       if ((ppfd->dwFlags & PFD_STEREO) != (dwFlags & PFD_STEREO)) {
391         goto choose_exit;
392       }
393     }
394
395     /* Alpha bits */
396     pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_ALPHA_SIZE, &value);
397     if (ppfd->iPixelType==PFD_TYPE_RGBA && ppfd->cAlphaBits && !value) {
398       goto choose_exit;
399     }
400
401     /* Depth bits */
402     pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_DEPTH_SIZE, &value);
403     if (ppfd->cDepthBits && !value) {
404       goto choose_exit;
405     }
406
407     /* Stencil bits */
408     pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_STENCIL_SIZE, &value);
409     if (ppfd->cStencilBits && !value) {
410       goto choose_exit;
411     }
412
413     /* Aux buffers */
414     pglXGetFBConfigAttrib(gdi_display, cfgs[fmt_index], GLX_AUX_BUFFERS, &value);
415     if (ppfd->cAuxBuffers && !value) {
416       goto choose_exit;
417     }
418
419     /* When we pass all the checks we have found a matching format :) */
420     ret = 1;
421     TRACE("Successfully found a matching mode, returning index: %d\n", ret);
422   }
423
424 choose_exit:
425   if(!ret)
426     TRACE("No matching mode was found returning 0\n");
427
428   if (NULL != cfgs) XFree(cfgs);
429   wine_tsx11_unlock();
430   return ret;
431 }
432
433 /**
434  * X11DRV_DescribePixelFormat
435  *
436  * Get the pixel-format descriptor associated to the given id
437  */
438 int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
439                                int iPixelFormat,
440                                UINT nBytes,
441                                PIXELFORMATDESCRIPTOR *ppfd) {
442   /*XVisualInfo *vis;*/
443   int value;
444   int rb,gb,bb,ab;
445
446   GLXFBConfig* cfgs = NULL;
447   GLXFBConfig cur;
448   int nCfgs = 0;
449   int ret = 0;
450   int fmt_index = 0;
451
452   if (!has_opengl()) {
453     ERR("No libGL on this box - disabling OpenGL support !\n");
454     return 0;
455   }
456   
457   TRACE("(%p,%d,%d,%p)\n", physDev, iPixelFormat, nBytes, ppfd);
458
459   wine_tsx11_lock();
460   cfgs = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs);
461   wine_tsx11_unlock();
462
463   if (NULL == cfgs || 0 == nCfgs) {
464     ERR("unexpected iPixelFormat(%d), returns NULL\n", iPixelFormat);
465     return 0; /* unespected error */
466   }
467
468   /* This function always reports the total number of supported pixel formats.
469    * At the moment we only support the pixel format corresponding to the main
470    * visual which got created at x11drv initialization. More formats could be
471    * supported if there was a way to recreate x11 windows in x11drv. 
472    * Because we only support one format nCfgs needs to be set to 1.
473    */
474   nCfgs = 1;
475
476   if (ppfd == NULL) {
477     /* The application is only querying the number of visuals */
478     wine_tsx11_lock();
479     if (NULL != cfgs) XFree(cfgs);
480     wine_tsx11_unlock();
481     return nCfgs;
482   }
483
484   if (nBytes < sizeof(PIXELFORMATDESCRIPTOR)) {
485     ERR("Wrong structure size !\n");
486     /* Should set error */
487     return 0;
488   }
489
490   if (nCfgs < iPixelFormat || 1 > iPixelFormat) {
491     WARN("unexpected iPixelFormat(%d): not >=1 and <=nFormats(%d), returning NULL\n", iPixelFormat, nCfgs);
492     return 0;
493   }
494
495   /* Retrieve the index in the FBConfig table corresponding to the visual ID from the main visual */
496   if(!ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, &fmt_index, &value)) {
497       ERR("Can't find a valid pixel format index from the main visual, expect problems!\n");
498       return 0;
499   }
500
501   ret = nCfgs;
502   cur = cfgs[fmt_index];
503
504   memset(ppfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
505   ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
506   ppfd->nVersion = 1;
507
508   /* These flags are always the same... */
509   ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
510   /* Now the flags extracted from the Visual */
511
512   wine_tsx11_lock();
513
514   pglXGetFBConfigAttrib(gdi_display, cur, GLX_CONFIG_CAVEAT, &value);
515   if(value == GLX_SLOW_CONFIG)
516       ppfd->dwFlags |= PFD_GENERIC_ACCELERATED;
517
518   pglXGetFBConfigAttrib(gdi_display, cur, GLX_DOUBLEBUFFER, &value); if (value) ppfd->dwFlags |= PFD_DOUBLEBUFFER;
519   pglXGetFBConfigAttrib(gdi_display, cur, GLX_STEREO, &value); if (value) ppfd->dwFlags |= PFD_STEREO;
520
521   /* Pixel type */
522   pglXGetFBConfigAttrib(gdi_display, cur, GLX_RENDER_TYPE, &value);
523   if (value & GLX_RGBA_BIT)
524     ppfd->iPixelType = PFD_TYPE_RGBA;
525   else
526     ppfd->iPixelType = PFD_TYPE_COLORINDEX;
527
528   /* Color bits */
529   pglXGetFBConfigAttrib(gdi_display, cur, GLX_BUFFER_SIZE, &value);
530   ppfd->cColorBits = value;
531
532   /* Red, green, blue and alpha bits / shifts */
533   if (ppfd->iPixelType == PFD_TYPE_RGBA) {
534     pglXGetFBConfigAttrib(gdi_display, cur, GLX_RED_SIZE, &rb);
535     pglXGetFBConfigAttrib(gdi_display, cur, GLX_GREEN_SIZE, &gb);
536     pglXGetFBConfigAttrib(gdi_display, cur, GLX_BLUE_SIZE, &bb);
537     pglXGetFBConfigAttrib(gdi_display, cur, GLX_ALPHA_SIZE, &ab);
538
539     ppfd->cRedBits = rb;
540     ppfd->cRedShift = gb + bb + ab;
541     ppfd->cBlueBits = bb;
542     ppfd->cBlueShift = ab;
543     ppfd->cGreenBits = gb;
544     ppfd->cGreenShift = bb + ab;
545     ppfd->cAlphaBits = ab;
546     ppfd->cAlphaShift = 0;
547   } else {
548     ppfd->cRedBits = 0;
549     ppfd->cRedShift = 0;
550     ppfd->cBlueBits = 0;
551     ppfd->cBlueShift = 0;
552     ppfd->cGreenBits = 0;
553     ppfd->cGreenShift = 0;
554     ppfd->cAlphaBits = 0;
555     ppfd->cAlphaShift = 0;
556   }
557   /* Accums : to do ... */
558
559   /* Depth bits */
560   pglXGetFBConfigAttrib(gdi_display, cur, GLX_DEPTH_SIZE, &value);
561   ppfd->cDepthBits = value;
562
563   /* stencil bits */
564   pglXGetFBConfigAttrib(gdi_display, cur, GLX_STENCIL_SIZE, &value);
565   ppfd->cStencilBits = value;
566
567   wine_tsx11_unlock();
568
569   /* Aux : to do ... */
570
571   ppfd->iLayerType = PFD_MAIN_PLANE;
572
573   if (TRACE_ON(opengl)) {
574     dump_PIXELFORMATDESCRIPTOR(ppfd);
575   }
576
577   wine_tsx11_lock();
578   if (NULL != cfgs) XFree(cfgs);
579   wine_tsx11_unlock();
580
581   return ret;
582 }
583
584 /**
585  * X11DRV_GetPixelFormat
586  *
587  * Get the pixel-format id used by this DC
588  */
589 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
590   TRACE("(%p): returns %d\n", physDev, physDev->current_pf);
591
592   return physDev->current_pf;
593 }
594
595 /**
596  * X11DRV_SetPixelFormat
597  *
598  * Set the pixel-format id used by this DC
599  */
600 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
601                            int iPixelFormat,
602                            const PIXELFORMATDESCRIPTOR *ppfd) {
603   TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
604
605   /* At the moment we only support the pixelformat corresponding to the main
606    * x11drv visual which got created at x11drv initialization. More formats
607    * can be supported if there was a way to recreate x11 windows in x11drv
608    */
609   if(iPixelFormat != 1) {
610     TRACE("Invalid iPixelFormat: %d\n", iPixelFormat);
611     return 0;
612   }
613
614   physDev->current_pf = iPixelFormat;
615
616   if (TRACE_ON(opengl)) {
617     int nCfgs_fmt = 0;
618     GLXFBConfig* cfgs_fmt = NULL;
619     GLXFBConfig cur_cfg;
620     int value;
621     int gl_test = 0;
622     int fmt_index = 0;
623
624     if(!ConvertPixelFormatWGLtoGLX(gdi_display, iPixelFormat, &fmt_index, &value)) {
625       ERR("Can't find a valid pixel format index from the main visual, expect problems!\n");
626       return TRUE; /* Return true because the SetPixelFormat stuff itself passed */
627     }
628
629     /*
630      * How to test if hdc current drawable is compatible (visual/FBConfig) ?
631      *
632      * in case of root window created HDCs we crash here :(
633      *
634     Drawable drawable =  get_drawable( physDev->hdc );
635     TRACE(" drawable (%p,%p) have :\n", drawable, root_window);
636     pglXQueryDrawable(gdi_display, drawable, GLX_FBCONFIG_ID, (unsigned int*) &value);
637     TRACE(" - FBCONFIG_ID as 0x%x\n", tmp);
638     pglXQueryDrawable(gdi_display, drawable, GLX_VISUAL_ID, (unsigned int*) &value);
639     TRACE(" - VISUAL_ID as 0x%x\n", tmp);
640     pglXQueryDrawable(gdi_display, drawable, GLX_WIDTH, (unsigned int*) &value);
641     TRACE(" - WIDTH as %d\n", tmp);
642     pglXQueryDrawable(gdi_display, drawable, GLX_HEIGHT, (unsigned int*) &value);
643     TRACE(" - HEIGHT as %d\n", tmp);
644     */
645     cfgs_fmt = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs_fmt);
646     cur_cfg = cfgs_fmt[fmt_index];
647     gl_test = pglXGetFBConfigAttrib(gdi_display, cur_cfg, GLX_FBCONFIG_ID, &value);
648     if (gl_test) {
649       ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
650     } else {
651       TRACE(" FBConfig have :\n");
652       TRACE(" - FBCONFIG_ID   0x%x\n", value);
653       pglXGetFBConfigAttrib(gdi_display, cur_cfg, GLX_VISUAL_ID, &value);
654       TRACE(" - VISUAL_ID     0x%x\n", value);
655       pglXGetFBConfigAttrib(gdi_display, cur_cfg, GLX_DRAWABLE_TYPE, &value);
656       TRACE(" - DRAWABLE_TYPE 0x%x\n", value);
657     }
658     XFree(cfgs_fmt);
659   }
660   return TRUE;
661 }
662
663 /* OpenGL32 wglCreateContext */
664 HGLRC WINAPI X11DRV_wglCreateContext(HDC hdc)
665 {
666     Wine_GLContext *ret;
667     GLXFBConfig* cfgs_fmt = NULL;
668     GLXFBConfig cur_cfg;
669     int hdcPF = 1; /* We can only use the Wine's main visual which has an index of 1 */
670     int tmp = 0;
671     int fmt_index = 0;
672     int nCfgs_fmt = 0;
673     int value = 0;
674     int gl_test = 0;
675
676     TRACE("(%p)->(PF:%d)\n", hdc, hdcPF);
677
678     /* First, get the visual in use by the X11DRV */
679     if (!gdi_display) return 0;
680
681     /* We can only render using the iPixelFormat (1) of Wine's Main visual, we need to get the correspondig GLX format.
682     * If this fails something is very wrong on the system. */
683     if(!ConvertPixelFormatWGLtoGLX(gdi_display, hdcPF, &tmp, &fmt_index)) {
684         ERR("Cannot get FB Config for main iPixelFormat 1, expect problems!\n");
685         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
686         return NULL;
687     }
688
689     cfgs_fmt = pglXGetFBConfigs(gdi_display, DefaultScreen(gdi_display), &nCfgs_fmt);
690     if (NULL == cfgs_fmt || 0 == nCfgs_fmt) {
691         ERR("Cannot get FB Configs, expect problems.\n");
692         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
693         return NULL;
694     }
695
696     if (nCfgs_fmt < fmt_index) {
697         ERR("(%p): unexpected pixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, fmt_index, nCfgs_fmt);
698         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
699         return NULL;
700     }
701
702     cur_cfg = cfgs_fmt[fmt_index];
703     gl_test = pglXGetFBConfigAttrib(gdi_display, cur_cfg, GLX_FBCONFIG_ID, &value);
704     if (gl_test) {
705         ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
706         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
707         return NULL;
708     }
709     XFree(cfgs_fmt);
710
711     /* The context will be allocated in the wglMakeCurrent call */
712     wine_tsx11_lock();
713     ret = alloc_context();
714     wine_tsx11_unlock();
715     ret->hdc = hdc;
716     ret->display = gdi_display;
717     ret->fb_conf = cur_cfg;
718     /*ret->vis = vis;*/
719     ret->vis = pglXGetVisualFromFBConfig(gdi_display, cur_cfg);
720
721     TRACE(" creating context %p (GL context creation delayed)\n", ret);
722     return (HGLRC) ret;
723 }
724
725 /* OpenGL32 wglDeleteContext */
726 BOOL WINAPI X11DRV_wglDeleteContext(HGLRC hglrc)
727 {
728     Wine_GLContext *ctx = (Wine_GLContext *) hglrc;
729     BOOL ret = TRUE;
730
731     TRACE("(%p)\n", hglrc);
732
733     wine_tsx11_lock();
734     /* A game (Half Life not to name it) deletes twice the same context,
735     * so make sure it is valid first */
736     if (is_valid_context( ctx ))
737     {
738         if (ctx->ctx) pglXDestroyContext(ctx->display, ctx->ctx);
739         free_context(ctx);
740     }
741     else
742     {
743         WARN("Error deleting context !\n");
744         SetLastError(ERROR_INVALID_HANDLE);
745         ret = FALSE;
746     }
747     wine_tsx11_unlock();
748
749     return ret;
750 }
751
752 /* OpenGL32 wglGetCurrentContext() */
753 HGLRC WINAPI X11DRV_wglGetCurrentContext(void) {
754     GLXContext gl_ctx;
755     Wine_GLContext *ret;
756
757     TRACE("()\n");
758
759     wine_tsx11_lock();
760     gl_ctx = pglXGetCurrentContext();
761     ret = get_context_from_GLXContext(gl_ctx);
762     wine_tsx11_unlock();
763
764     TRACE(" returning %p (GL context %p)\n", ret, gl_ctx);
765
766     return (HGLRC)ret;
767 }
768
769 /* OpenGL32 wglGetCurrentDC */
770 HDC WINAPI X11DRV_wglGetCurrentDC(void) {
771     GLXContext gl_ctx;
772     Wine_GLContext *ret;
773
774     TRACE("()\n");
775
776     wine_tsx11_lock();
777     gl_ctx = pglXGetCurrentContext();
778     ret = get_context_from_GLXContext(gl_ctx);
779     wine_tsx11_unlock();
780
781     if (ret) {
782         TRACE(" returning %p (GL context %p - Wine context %p)\n", ret->hdc, gl_ctx, ret);
783         return ret->hdc;
784     } else {
785         TRACE(" no Wine context found for GLX context %p\n", gl_ctx);
786         return 0;
787     }
788 }
789
790 /* OpenGL32 wglGetCurrentReadDCARB */
791 HDC WINAPI X11DRV_wglGetCurrentReadDCARB(void) 
792 {
793     GLXDrawable gl_d;
794     HDC ret;
795
796     TRACE("()\n");
797
798     wine_tsx11_lock();
799     gl_d = pglXGetCurrentReadDrawable();
800     ret = get_hdc_from_Drawable(gl_d);
801     wine_tsx11_unlock();
802
803     TRACE(" returning %p (GL drawable %lu)\n", ret, gl_d);
804     return ret;
805 }
806
807 /* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */ 
808 void X11DRV_wglGetIntegerv(GLenum pname, GLint* params) {
809     TRACE("pname: 0x%x, params: %p\n", pname, params);
810     if (pname == GL_DEPTH_BITS) { 
811         GLXContext gl_ctx = pglXGetCurrentContext();
812         Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
813         /*TRACE("returns Wine Ctx as %p\n", ret);*/
814         /** 
815         * if we cannot find a Wine Context
816         * we only have the default wine desktop context, 
817         * so if we have only a 24 depth say we have 32
818         */
819         if (NULL == ret && 24 == *params) { 
820             *params = 32;
821         }
822         TRACE("returns GL_DEPTH_BITS as '%d'\n", *params);
823     }
824     if (pname == GL_ALPHA_BITS) {
825         GLint tmp;
826         GLXContext gl_ctx = pglXGetCurrentContext();
827         Wine_GLContext* ret = get_context_from_GLXContext(gl_ctx);
828         pglXGetFBConfigAttrib(ret->display, ret->fb_conf, GLX_ALPHA_SIZE, &tmp);
829         TRACE("returns GL_ALPHA_BITS as '%d'\n", tmp);
830         *params = tmp;
831     }
832 }
833
834 static XID create_glxpixmap(X11DRV_PDEVICE *physDev)
835 {
836     GLXPixmap ret;
837     XVisualInfo *vis;
838     XVisualInfo template;
839     int num;
840
841     wine_tsx11_lock();
842
843     /* Retrieve the visualid from our main visual which is the only visual we can use */
844     template.visualid =  XVisualIDFromVisual(visual);
845     vis = XGetVisualInfo(gdi_display, VisualIDMask, &template, &num);
846
847     ret = pglXCreateGLXPixmap(gdi_display, vis, physDev->bitmap->pixmap);
848     XFree(vis);
849     wine_tsx11_unlock(); 
850     TRACE("return %lx\n", ret);
851     return ret;
852 }
853
854 Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
855 {
856     Drawable ret;
857
858     if(physDev->bitmap)
859     {
860         if (physDev->bitmap->hbitmap == BITMAP_stock_phys_bitmap.hbitmap)
861             ret = physDev->drawable; /* PBuffer */
862         else
863         {
864             if(!physDev->bitmap->glxpixmap)
865                 physDev->bitmap->glxpixmap = create_glxpixmap(physDev);
866             ret = physDev->bitmap->glxpixmap;
867         }
868     }
869     else
870         ret = physDev->drawable;
871     return ret;
872 }
873
874 BOOL destroy_glxpixmap(XID glxpixmap)
875 {
876     wine_tsx11_lock(); 
877     pglXDestroyGLXPixmap(gdi_display, glxpixmap);
878     wine_tsx11_unlock(); 
879     return TRUE;
880 }
881
882 /**
883  * X11DRV_SwapBuffers
884  *
885  * Swap the buffers of this DC
886  */
887 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev)
888 {
889   GLXDrawable drawable;
890   if (!has_opengl()) {
891     ERR("No libGL on this box - disabling OpenGL support !\n");
892     return 0;
893   }
894   
895   TRACE_(opengl)("(%p)\n", physDev);
896
897   drawable = get_glxdrawable(physDev);
898   wine_tsx11_lock();
899   pglXSwapBuffers(gdi_display, drawable);
900   wine_tsx11_unlock();
901
902   /* FPS support */
903   if (TRACE_ON(fps))
904   {
905       static long prev_time, frames;
906
907       DWORD time = GetTickCount();
908       frames++;
909       /* every 1.5 seconds */
910       if (time - prev_time > 1500) {
911           TRACE_(fps)("@ approx %.2ffps\n", 1000.0*frames/(time - prev_time));
912           prev_time = time;
913           frames = 0;
914       }
915   }
916
917   return TRUE;
918 }
919
920 /***********************************************************************
921  *              X11DRV_setup_opengl_visual
922  *
923  * Setup the default visual used for OpenGL and Direct3D, and the desktop
924  * window (if it exists).  If OpenGL isn't available, the visual is simply
925  * set to the default visual for the display
926  */
927 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
928 {
929     XVisualInfo *visual = NULL;
930     /* In order to support OpenGL or D3D, we require a double-buffered visual and stencil buffer support, */
931     int dblBuf[] = {GLX_RGBA,GLX_DEPTH_SIZE, 24, GLX_STENCIL_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DOUBLEBUFFER, None};
932     if (!has_opengl()) return NULL;
933
934     wine_tsx11_lock();
935     visual = pglXChooseVisual(display, DefaultScreen(display), dblBuf);
936     wine_tsx11_unlock();
937     if (visual == NULL) {
938         /* fallback to 16 bits depth, no alpha */
939         int dblBuf2[] = {GLX_RGBA,GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, GLX_DOUBLEBUFFER, None};
940         WARN("Failed to get a visual with at least 24 bits depth\n");
941
942         wine_tsx11_lock();
943         visual = pglXChooseVisual(display, DefaultScreen(display), dblBuf2);
944         wine_tsx11_unlock();
945         if (visual == NULL) {
946             /* fallback to no stencil */
947             int dblBuf2[] = {GLX_RGBA,GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None};
948             WARN("Failed to get a visual with at least 8 bits of stencil\n");
949
950             wine_tsx11_lock();
951             visual = pglXChooseVisual(display, DefaultScreen(display), dblBuf2);
952             wine_tsx11_unlock();
953             if (visual == NULL) {
954                 /* This should only happen if we cannot find a match with a depth size 16 */
955                 FIXME("Failed to find a suitable visual\n");
956                 return visual;
957             }
958         }
959     }
960     TRACE("Visual ID %lx Chosen\n",visual->visualid);
961     return visual;
962 }
963
964 #else  /* no OpenGL includes */
965
966 void X11DRV_OpenGL_Init(Display *display)
967 {
968 }
969
970 /***********************************************************************
971  *              ChoosePixelFormat (X11DRV.@)
972  */
973 int X11DRV_ChoosePixelFormat(X11DRV_PDEVICE *physDev,
974                              const PIXELFORMATDESCRIPTOR *ppfd) {
975   ERR("No OpenGL support compiled in.\n");
976
977   return 0;
978 }
979
980 /***********************************************************************
981  *              DescribePixelFormat (X11DRV.@)
982  */
983 int X11DRV_DescribePixelFormat(X11DRV_PDEVICE *physDev,
984                                int iPixelFormat,
985                                UINT nBytes,
986                                PIXELFORMATDESCRIPTOR *ppfd) {
987   ERR("No OpenGL support compiled in.\n");
988
989   return 0;
990 }
991
992 /***********************************************************************
993  *              GetPixelFormat (X11DRV.@)
994  */
995 int X11DRV_GetPixelFormat(X11DRV_PDEVICE *physDev) {
996   ERR("No OpenGL support compiled in.\n");
997
998   return 0;
999 }
1000
1001 /***********************************************************************
1002  *              SetPixelFormat (X11DRV.@)
1003  */
1004 BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
1005                            int iPixelFormat,
1006                            const PIXELFORMATDESCRIPTOR *ppfd) {
1007   ERR("No OpenGL support compiled in.\n");
1008
1009   return FALSE;
1010 }
1011
1012 /***********************************************************************
1013  *              SwapBuffers (X11DRV.@)
1014  */
1015 BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev) {
1016   ERR_(opengl)("No OpenGL support compiled in.\n");
1017
1018   return FALSE;
1019 }
1020
1021 /* OpenGL32 wglCreateContext */
1022 HGLRC WINAPI X11DRV_wglCreateContext(HDC hdc) {
1023     ERR_(opengl)("No OpenGL support compiled in.\n");
1024     return NULL;
1025 }
1026
1027 /* OpenGL32 wglDeleteContext */
1028 BOOL WINAPI X11DRV_wglDeleteContext(HGLRC hglrc) {
1029     ERR_(opengl)("No OpenGL support compiled in.\n");
1030     return FALSE;
1031 }
1032
1033 /* OpenGL32 wglGetCurrentContext() */
1034 HGLRC WINAPI X11DRV_wglGetCurrentContext(void) {
1035     ERR_(opengl)("No OpenGL support compiled in.\n");
1036     return NULL;
1037 }
1038
1039 /* OpenGL32 wglGetCurrentDC */
1040 HDC WINAPI X11DRV_wglGetCurrentDC(void) {
1041     ERR_(opengl)("No OpenGL support compiled in.\n");
1042     return 0;
1043 }
1044
1045 /* WGL helper function which handles differences in glGetIntegerv from WGL and GLX */ 
1046 void X11DRV_wglGetIntegerv(GLenum pname, GLint* params) {
1047     ERR_(opengl)("No OpenGL support compiled in.\n");
1048 }
1049
1050 XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
1051 {
1052   return NULL;
1053 }
1054
1055 Drawable get_glxdrawable(X11DRV_PDEVICE *physDev)
1056 {
1057     return 0;
1058 }
1059
1060 BOOL destroy_glxpixmap(XID glxpixmap)
1061 {
1062     return FALSE;
1063 }
1064
1065 #endif /* defined(HAVE_OPENGL) */