Move standard WGL function declarations to wingdi.h.
[wine] / dlls / opengl32 / wgl_ext.c
1 /* Support for window-specific OpenGL extensions.
2  *
3  * Copyright (c) 2004 Lionel Ulmer
4  * Copyright (c) 2005 Alex Woods
5  * Copyright (c) 2005 Raphael Junqueira
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winuser.h"
32 #include "winerror.h"
33
34 #include "gdi.h"
35 #include "wgl_ext.h"
36 #include "opengl_ext.h"
37 #include "wine/library.h"
38 #include "wine/debug.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(opengl);
41
42
43 /* x11drv GDI escapes */
44 #define X11DRV_ESCAPE 6789
45 enum x11drv_escape_codes
46 {
47     X11DRV_GET_DISPLAY,   /* get X11 display for a DC */
48     X11DRV_GET_DRAWABLE,  /* get current drawable for a DC */
49     X11DRV_GET_FONT,      /* get current X font for a DC */
50     X11DRV_SET_DRAWABLE,     /* set current drawable for a DC */
51 };
52 struct x11drv_escape_set_drawable
53 {
54     enum x11drv_escape_codes code;         /* escape code (X11DRV_SET_DRAWABLE) */
55     Drawable                 drawable;     /* X drawable */
56     int                      mode;         /* ClipByChildren or IncludeInferiors */
57     POINT                    org;          /* origin of DC relative to drawable */
58     POINT                    drawable_org; /* origin of drawable relative to screen */
59 };
60
61 /* retrieve the X display to use on a given DC */
62 inline static Display *get_display( HDC hdc )
63 {
64     Display *display;
65     enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY;
66
67     if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape,
68                     sizeof(display), (LPSTR)&display )) display = NULL;
69     return display;
70 }
71 inline static void set_drawable( HDC hdc, Drawable drawable )
72 {
73     struct x11drv_escape_set_drawable escape;
74
75     escape.code = X11DRV_SET_DRAWABLE;
76     escape.drawable = drawable;
77     escape.mode = IncludeInferiors;
78     escape.org.x = escape.org.y = 0;
79     escape.drawable_org.x = escape.drawable_org.y = 0;
80
81     ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, 0, NULL );
82 }
83
84 /* Some WGL extensions... */
85 static const char *WGL_extensions_base = "WGL_ARB_extensions_string WGL_EXT_extensions_string";
86 static char *WGL_extensions = NULL;
87
88 /**
89  * Extensions-query functions 
90  *
91  * @TODO: use a struct to handle parameters 
92  */
93 BOOL query_function_make_current_read(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions, 
94                                       const char* glx_version, const char *glx_extensions,
95                                       const char *server_glx_extensions, const char *client_glx_extensions)
96 {
97   return 0 <= strcmp("1.3", glx_version);
98 }
99
100 BOOL query_function_multisample(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions, 
101                                 const char* glx_version, const char *glx_extensions,
102                                 const char *server_glx_extensions, const char *client_glx_extensions)
103 {
104   return NULL != strstr(glx_extensions, "GLX_ARB_multisample");
105 }
106
107 BOOL query_function_pbuffer(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions, 
108                             const char* glx_version, const char *glx_extensions,
109                             const char *server_glx_extensions, const char *client_glx_extensions)
110 {
111   TRACE("gl_version is: \"%s\"\n", gl_version);
112   TRACE("glx_exts is: \"%s\"\n", glx_extensions);
113
114   return 0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGIX_pbuffer");
115 }
116
117 BOOL query_function_pixel_format(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions, 
118                                  const char* glx_version, const char *glx_extensions,
119                                  const char *server_glx_extensions, const char *client_glx_extensions)
120 {
121   return TRUE;
122 }
123
124 /** GLX_ARB_render_texture */
125 /**
126  * http://oss.sgi.com/projects/ogl-sample/registry/ARB/wgl_render_texture.txt
127  * ~/tmp/ogl/ogl_offscreen_rendering_3
128  */
129 Bool (*p_glXBindTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer);
130 Bool (*p_glXReleaseTexImageARB)(Display *dpy, GLXPbuffer pbuffer, int buffer);
131 Bool (*p_glXDrawableAttribARB)(Display *dpy, GLXDrawable draw, const int *attribList);
132 int  use_render_texture_emulation = 0;
133 BOOL query_function_render_texture(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions, 
134                                    const char* glx_version, const char *glx_extensions,
135                                    const char *server_glx_extensions, const char *client_glx_extensions)
136 {
137   BOOL bTest = (0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGIX_pbuffer"));
138   if (bTest) {
139     if (NULL != strstr(glx_extensions, "GLX_ARB_render_texture")) {
140       p_glXBindTexImageARB = proc( (const GLubyte *) "glXBindTexImageARB");
141       p_glXReleaseTexImageARB = proc( (const GLubyte *) "glXReleaseTexImageARB");
142       p_glXDrawableAttribARB = proc( (const GLubyte *) "glXDrawableAttribARB");
143       bTest = (NULL != p_glXBindTexImageARB && NULL != p_glXReleaseTexImageARB && NULL != p_glXDrawableAttribARB);
144     } else {
145       use_render_texture_emulation = 0;
146     }
147   }
148   return bTest;
149 }
150
151 int (*p_glXSwapIntervalSGI)(int);
152 BOOL query_function_swap_control(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions, 
153                                  const char* glx_version, const char *glx_extensions,
154                                  const char *server_glx_extensions, const char *client_glx_extensions)
155 {
156   BOOL bTest = (0 <= strcmp("1.3", glx_version) || NULL != strstr(glx_extensions, "GLX_SGI_swap_control"));
157   if (bTest) {
158     p_glXSwapIntervalSGI = proc( (const GLubyte *) "glXSwapIntervalSGI");
159     bTest = (NULL != p_glXSwapIntervalSGI);
160   }
161   return bTest;
162 }
163
164 /***********************************************************************
165  *              wglGetExtensionsStringEXT(OPENGL32.@)
166  */
167 const char * WINAPI wglGetExtensionsStringEXT(void) {
168     TRACE("() returning \"%s\"\n", WGL_extensions);
169
170     return WGL_extensions;
171 }
172
173 /***********************************************************************
174  *              wglGetExtensionsStringARB(OPENGL32.@)
175  */
176 const char * WINAPI wglGetExtensionsStringARB(HDC hdc) {
177     TRACE("() returning \"%s\"\n", WGL_extensions);
178
179     return WGL_extensions;    
180 }
181
182 static int swap_interval = 1;
183
184 /***********************************************************************
185  *              wglSwapIntervalEXT(OPENGL32.@)
186  */
187 BOOL WINAPI wglSwapIntervalEXT(int interval) {
188   TRACE("(%d)\n", interval);
189   swap_interval = interval;
190   if (NULL != p_glXSwapIntervalSGI) {
191     return 0 == p_glXSwapIntervalSGI(interval);
192   }
193   WARN("(): GLX_SGI_swap_control extension seems not supported\n");
194   return TRUE;
195 }
196
197 /***********************************************************************
198  *              wglGetSwapIntervalEXT(OPENGL32.@)
199  */
200 int WINAPI wglGetSwapIntervalEXT(VOID) {
201     FIXME("(),stub!\n");
202     return swap_interval;
203 }
204
205 typedef struct wine_glpbuffer {
206   Drawable   drawable;
207   Display*   display;
208   int        pixelFormat;
209   int        width;
210   int        height;
211   int*       attribList;
212   HDC        hdc;
213
214   int        use_render_texture;
215   GLuint     texture_target;
216   GLuint     texture_bind_target;
217   GLuint     texture;
218   int        texture_level;
219 } Wine_GLPBuffer;
220
221 #define PUSH1(attribs,att)        attribs[nAttribs++] = (att); 
222 #define PUSH2(attribs,att,value)  attribs[nAttribs++] = (att); attribs[nAttribs++] = (value);
223
224 #define WGL_NUMBER_PIXEL_FORMATS_ARB            0x2000
225 #define WGL_DRAW_TO_WINDOW_ARB                  0x2001
226 #define WGL_DRAW_TO_BITMAP_ARB                  0x2002
227 #define WGL_ACCELERATION_ARB                    0x2003
228 #define WGL_NEED_PALETTE_ARB                    0x2004
229 #define WGL_NEED_SYSTEM_PALETTE_ARB             0x2005
230 #define WGL_SWAP_LAYER_BUFFERS_ARB              0x2006
231 #define WGL_SWAP_METHOD_ARB                     0x2007
232 #define WGL_NUMBER_OVERLAYS_ARB                 0x2008
233 #define WGL_NUMBER_UNDERLAYS_ARB                0x2009
234 #define WGL_TRANSPARENT_ARB                     0x200A
235 #define WGL_TRANSPARENT_RED_VALUE_ARB           0x2037
236 #define WGL_TRANSPARENT_GREEN_VALUE_ARB         0x2038
237 #define WGL_TRANSPARENT_BLUE_VALUE_ARB          0x2039
238 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB         0x203A
239 #define WGL_TRANSPARENT_INDEX_VALUE_ARB         0x203B
240 #define WGL_SHARE_DEPTH_ARB                     0x200C
241 #define WGL_SHARE_STENCIL_ARB                   0x200D
242 #define WGL_SHARE_ACCUM_ARB                     0x200E
243 #define WGL_SUPPORT_GDI_ARB                     0x200F
244 #define WGL_SUPPORT_OPENGL_ARB                  0x2010
245 #define WGL_DOUBLE_BUFFER_ARB                   0x2011
246 #define WGL_STEREO_ARB                          0x2012
247 #define WGL_PIXEL_TYPE_ARB                      0x2013
248 #define WGL_COLOR_BITS_ARB                      0x2014
249 #define WGL_RED_BITS_ARB                        0x2015
250 #define WGL_RED_SHIFT_ARB                       0x2016
251 #define WGL_GREEN_BITS_ARB                      0x2017
252 #define WGL_GREEN_SHIFT_ARB                     0x2018
253 #define WGL_BLUE_BITS_ARB                       0x2019
254 #define WGL_BLUE_SHIFT_ARB                      0x201A
255 #define WGL_ALPHA_BITS_ARB                      0x201B
256 #define WGL_ALPHA_SHIFT_ARB                     0x201C
257 #define WGL_ACCUM_BITS_ARB                      0x201D
258 #define WGL_ACCUM_RED_BITS_ARB                  0x201E
259 #define WGL_ACCUM_GREEN_BITS_ARB                0x201F
260 #define WGL_ACCUM_BLUE_BITS_ARB                 0x2020
261 #define WGL_ACCUM_ALPHA_BITS_ARB                0x2021
262 #define WGL_DEPTH_BITS_ARB                      0x2022
263 #define WGL_STENCIL_BITS_ARB                    0x2023
264 #define WGL_AUX_BUFFERS_ARB                     0x2024
265
266 #define WGL_NO_ACCELERATION_ARB                 0x2025
267 #define WGL_GENERIC_ACCELERATION_ARB            0x2026
268 #define WGL_FULL_ACCELERATION_ARB               0x2027
269
270 #define WGL_PBUFFER_WIDTH_ARB                   0x2034
271 #define WGL_PBUFFER_HEIGHT_ARB                  0x2035
272 #define WGL_PBUFFER_LOST_ARB                    0x2036
273 #define WGL_DRAW_TO_PBUFFER_ARB                 0x202D
274 #define WGL_MAX_PBUFFER_PIXELS_ARB              0x202E
275 #define WGL_MAX_PBUFFER_WIDTH_ARB               0x202F
276 #define WGL_MAX_PBUFFER_HEIGHT_ARB              0x2030
277 #define WGL_PBUFFER_LARGEST_ARB                 0x2033
278
279 #define WGL_TYPE_RGBA_ARB                       0x202B
280 #define WGL_TYPE_COLORINDEX_ARB                 0x202C
281
282 #define WGL_SAMPLE_BUFFERS_ARB                  0x2041
283 #define WGL_SAMPLES_ARB                         0x2042
284
285 /**
286  * WGL_render_texture 
287  */
288 /** GetPixelFormat/ChoosePixelFormat */
289 #define WGL_BIND_TO_TEXTURE_RGB_ARB             0x2070
290 #define WGL_BIND_TO_TEXTURE_RGBA_ARB            0x2071
291 /** CreatePbuffer / QueryPbuffer */
292 #define WGL_TEXTURE_FORMAT_ARB                  0x2072
293 #define WGL_TEXTURE_TARGET_ARB                  0x2073
294 #define WGL_MIPMAP_TEXTURE_ARB                  0x2074
295 /** CreatePbuffer / QueryPbuffer */
296 #define WGL_TEXTURE_RGB_ARB                     0x2075
297 #define WGL_TEXTURE_RGBA_ARB                    0x2076
298 #define WGL_NO_TEXTURE_ARB                      0x2077
299 /** CreatePbuffer / QueryPbuffer */
300 #define WGL_TEXTURE_CUBE_MAP_ARB                0x2078
301 #define WGL_TEXTURE_1D_ARB                      0x2079
302 #define WGL_TEXTURE_2D_ARB                      0x207A
303 #define WGL_NO_TEXTURE_ARB                      0x2077
304 /** SetPbufferAttribARB/QueryPbufferARB parameters */
305 #define WGL_MIPMAP_LEVEL_ARB                    0x207B
306 #define WGL_CUBE_MAP_FACE_ARB                   0x207C
307 /** SetPbufferAttribARB/QueryPbufferARB attribs */
308 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB     0x207D
309 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB     0x207E
310 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB     0x207F
311 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB     0x2080
312 #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB     0x2081 
313 #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB     0x2082
314 /** BindTexImageARB/ReleaseTexImageARB */
315 #define WGL_FRONT_LEFT_ARB                  0x2083
316 #define WGL_FRONT_RIGHT_ARB                 0x2084
317 #define WGL_BACK_LEFT_ARB                   0x2085
318 #define WGL_BACK_RIGHT_ARB                  0x2086
319 #define WGL_AUX0_ARB                        0x2087 
320 #define WGL_AUX1_ARB                        0x2088 
321 #define WGL_AUX2_ARB                        0x2089 
322 #define WGL_AUX3_ARB                        0x208A 
323 #define WGL_AUX4_ARB                        0x208B 
324 #define WGL_AUX5_ARB                        0x208C 
325 #define WGL_AUX6_ARB                        0x208D
326 #define WGL_AUX7_ARB                        0x208E 
327 #define WGL_AUX8_ARB                        0x208F 
328 #define WGL_AUX9_ARB                        0x2090
329
330 #if 0 /* not used yet */
331 static unsigned ConvertAttribGLXtoWGL(const int* iWGLAttr, int* oGLXAttr) {
332   unsigned nAttribs = 0;
333   FIXME("not yet implemented!\n");
334   return nAttribs;
335 }
336 #endif
337
338 static unsigned ConvertAttribWGLtoGLX(const int* iWGLAttr, int* oGLXAttr, Wine_GLPBuffer* pbuf) {
339   unsigned nAttribs = 0;
340   unsigned cur = 0; 
341   int pop;
342   int isColor = 0;
343   int wantColorBits = 0;
344   int sz_alpha = 0;
345
346   while (0 != iWGLAttr[cur]) {
347     TRACE("pAttr[%d] = %x\n", cur, iWGLAttr[cur]);
348
349     switch (iWGLAttr[cur]) {
350     case WGL_COLOR_BITS_ARB:
351       pop = iWGLAttr[++cur];
352       wantColorBits = pop; /** see end */
353       break;
354     case WGL_BLUE_BITS_ARB:
355       pop = iWGLAttr[++cur];
356       PUSH2(oGLXAttr, GLX_BLUE_SIZE, pop);
357       TRACE("pAttr[%d] = GLX_BLUE_SIZE: %d\n", cur, pop);
358       break;
359     case WGL_RED_BITS_ARB:
360       pop = iWGLAttr[++cur];
361       PUSH2(oGLXAttr, GLX_RED_SIZE, pop);
362       TRACE("pAttr[%d] = GLX_RED_SIZE: %d\n", cur, pop);
363       break;
364     case WGL_GREEN_BITS_ARB:
365       pop = iWGLAttr[++cur];
366       PUSH2(oGLXAttr, GLX_GREEN_SIZE, pop);
367       TRACE("pAttr[%d] = GLX_GREEN_SIZE: %d\n", cur, pop);
368       break;
369     case WGL_ALPHA_BITS_ARB:
370       pop = iWGLAttr[++cur];
371       sz_alpha = pop;
372       PUSH2(oGLXAttr, GLX_ALPHA_SIZE, pop);
373       TRACE("pAttr[%d] = GLX_ALPHA_SIZE: %d\n", cur, pop);
374       break;
375     case WGL_DEPTH_BITS_ARB:
376       pop = iWGLAttr[++cur];
377       PUSH2(oGLXAttr, GLX_DEPTH_SIZE, pop);
378       TRACE("pAttr[%d] = GLX_DEPTH_SIZE: %d\n", cur, pop);
379       break;
380     case WGL_STENCIL_BITS_ARB:
381       pop = iWGLAttr[++cur];
382       PUSH2(oGLXAttr, GLX_STENCIL_SIZE, pop);
383       TRACE("pAttr[%d] = GLX_STENCIL_SIZE: %d\n", cur, pop);
384       break;
385     case WGL_DOUBLE_BUFFER_ARB:
386       pop = iWGLAttr[++cur];
387       PUSH2(oGLXAttr, GLX_DOUBLEBUFFER, pop);
388       TRACE("pAttr[%d] = GLX_DOUBLEBUFFER: %d\n", cur, pop);
389       break;
390
391     case WGL_PIXEL_TYPE_ARB:
392       pop = iWGLAttr[++cur];
393       switch (pop) {
394       case WGL_TYPE_RGBA_ARB:  pop = GLX_RGBA_BIT; break ; 
395       case WGL_TYPE_COLORINDEX_ARB: pop = GLX_COLOR_INDEX_BIT; isColor = 1; break ;
396       default:
397         ERR("unexpected PixelType(%x)\n", pop); 
398         pop = 0;
399       }
400       PUSH2(oGLXAttr, GLX_RENDER_TYPE, pop);
401       TRACE("pAttr[%d] = GLX_RENDER_TYPE: %d\n", cur, pop);
402       break;
403
404     case WGL_SUPPORT_GDI_ARB:
405     case WGL_DRAW_TO_WINDOW_ARB:
406     case WGL_DRAW_TO_BITMAP_ARB:
407     case WGL_DRAW_TO_PBUFFER_ARB:
408       pop = iWGLAttr[++cur];
409       PUSH2(oGLXAttr, GLX_X_RENDERABLE, pop);
410       TRACE("pAttr[%d] = GLX_RENDERABLE: %d\n", cur, pop);
411       break;
412
413     case WGL_ACCELERATION_ARB:
414     case WGL_SUPPORT_OPENGL_ARB:
415       pop = iWGLAttr[++cur];
416       /** nothing to do, if we are here, supposing support Accelerated OpenGL */
417       TRACE("pAttr[%d] = WGL_SUPPORT_OPENGL_ARB: %d\n", cur, pop);
418       break;
419
420     case WGL_PBUFFER_LARGEST_ARB:
421       pop = iWGLAttr[++cur];
422       PUSH2(oGLXAttr, GLX_LARGEST_PBUFFER, pop);
423       TRACE("pAttr[%d] = GLX_LARGEST_PBUFFER: %x\n", cur, pop);
424       break;
425
426     case WGL_SAMPLE_BUFFERS_ARB:
427       pop = iWGLAttr[++cur];
428       PUSH2(oGLXAttr, GLX_SAMPLE_BUFFERS_ARB, pop);
429       TRACE("pAttr[%d] = GLX_SAMPLE_BUFFERS_ARB: %x\n", cur, pop);
430       break;
431       
432     case WGL_SAMPLES_ARB:
433       pop = iWGLAttr[++cur];
434       PUSH2(oGLXAttr, GLX_SAMPLES_ARB, pop);
435       TRACE("pAttr[%d] = GLX_SAMPLES_ARB: %x\n", cur, pop);
436       break;
437
438     case WGL_TEXTURE_FORMAT_ARB:
439     case WGL_TEXTURE_TARGET_ARB:
440     case WGL_MIPMAP_TEXTURE_ARB:
441       TRACE("WGL_render_texture Attributes: %x as %x\n", iWGLAttr[cur], iWGLAttr[cur + 1]);
442       if (NULL == pbuf) {
443         ERR("trying to use GLX_Pbuffer Attributes without Pbuffer (was %x)\n", iWGLAttr[cur]);
444       }
445       if (!use_render_texture_emulation) {
446         ERR("trying to use WGL_render_texture Attributes without support (was %x)\n", iWGLAttr[cur]);
447       }
448       pop = iWGLAttr[++cur];
449       break ;
450
451     default:
452       FIXME("unsupported %x WGL Attribute\n", iWGLAttr[cur]);
453       break;
454     }
455     ++cur;
456   }
457
458   /**
459    * Trick as WGL_COLOR_BITS_ARB != GLX_BUFFER_SIZE
460    *    WGL_COLOR_BITS_ARB + WGL_ALPHA_BITS_ARB == GLX_BUFFER_SIZE
461    *
462    *  WGL_COLOR_BITS_ARB
463    *     The number of color bitplanes in each color buffer. For RGBA
464    *     pixel types, it is the size of the color buffer, excluding the
465    *     alpha bitplanes. For color-index pixels, it is the size of the
466    *     color index buffer.
467    *
468    *  GLX_BUFFER_SIZE   
469    *     This attribute defines the number of bits per color buffer. 
470    *     For GLX FBConfigs that correspond to a PseudoColor or StaticColor visual, 
471    *     this is equal to the depth value reported in the X11 visual. 
472    *     For GLX FBConfigs that correspond to TrueColor or DirectColor visual, 
473    *     this is the sum of GLX_RED_SIZE, GLX_GREEN_SIZE, GLX_BLUE_SIZE, and GLX_ALPHA_SIZE.
474    * 
475    */
476   if (0 < wantColorBits) {
477     if (!isColor) { 
478       wantColorBits += sz_alpha; 
479     }
480     if (32 < wantColorBits) {
481       ERR("buggy %d GLX_BUFFER_SIZE default to 32\n", wantColorBits);
482       wantColorBits = 32;
483     }
484     PUSH2(oGLXAttr, GLX_BUFFER_SIZE, wantColorBits);
485     TRACE("pAttr[%d] = WGL_COLOR_BITS_ARB: %d\n", cur, wantColorBits);
486   }
487
488   return nAttribs;
489 }
490
491 GLboolean WINAPI wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues)
492 {
493   Display* display = get_display( hdc );
494   UINT i;
495   GLXFBConfig* cfgs = NULL;
496   GLXFBConfig  curCfg = NULL;
497   int nCfgs = 0;
498   int hTest;
499   int tmp;
500   int curGLXAttr = 0;
501
502   TRACE("(%p, %d, %d, %d, %p, %p)\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues);
503   
504   if (0 < iLayerPlane) {
505     FIXME("unsupported iLayerPlane(%d) > 0, returns FALSE\n", iLayerPlane);
506     return GL_FALSE;
507   }
508
509   cfgs = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
510   if (NULL == cfgs) {
511     ERR("no FB Configs found for display(%p)\n", display);
512     return GL_FALSE;
513   }
514
515   for (i = 0; i < nAttributes; ++i) {
516     const int curWGLAttr = piAttributes[i];
517     TRACE("pAttr[%d] = %x\n", i, curWGLAttr);
518     
519     switch (curWGLAttr) {
520     case WGL_NUMBER_PIXEL_FORMATS_ARB:
521       piValues[i] = nCfgs; 
522       continue ;
523
524     case WGL_SUPPORT_OPENGL_ARB:
525       piValues[i] = GL_TRUE; 
526       continue ;
527
528     case WGL_ACCELERATION_ARB:
529       curGLXAttr = GLX_CONFIG_CAVEAT;
530       if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
531       curCfg = cfgs[iPixelFormat - 1];
532       hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
533       if (hTest) goto get_error;
534       switch (tmp) {
535       case GLX_NONE: piValues[i] = WGL_FULL_ACCELERATION_ARB; break;
536       case GLX_SLOW_CONFIG: piValues[i] = WGL_NO_ACCELERATION_ARB; break;
537       case GLX_NON_CONFORMANT_CONFIG: piValues[i] = WGL_FULL_ACCELERATION_ARB; break;
538       default:
539         ERR("unexpected Config Caveat(%x)\n", tmp);
540         piValues[i] = WGL_NO_ACCELERATION_ARB;
541       }
542       continue ;
543
544     case WGL_TRANSPARENT_ARB:
545       curGLXAttr = GLX_TRANSPARENT_TYPE;
546       if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
547       curCfg = cfgs[iPixelFormat - 1];
548       hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
549       if (hTest) goto get_error;
550       piValues[i] = GL_FALSE;
551       if (GLX_NONE != tmp) piValues[i] = GL_TRUE;
552       continue ;
553
554     case WGL_PIXEL_TYPE_ARB:
555       curGLXAttr = GLX_RENDER_TYPE;
556       if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
557       curCfg = cfgs[iPixelFormat - 1];
558       hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
559       if (hTest) goto get_error;
560       switch (tmp) {
561       case GLX_RGBA_BIT: piValues[i] = WGL_TYPE_RGBA_ARB; break;
562       case GLX_COLOR_INDEX_BIT: piValues[i] = WGL_TYPE_COLORINDEX_ARB; break ;
563       default:
564         ERR("unexpected RenderType(%x)\n", tmp);
565         piValues[i] = WGL_TYPE_RGBA_ARB;
566       }
567       continue ;
568       
569     case WGL_COLOR_BITS_ARB:
570       /** see ConvertAttribWGLtoGLX for explain */
571       if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
572       curCfg = cfgs[iPixelFormat - 1];
573       hTest = glXGetFBConfigAttrib(display, curCfg, GLX_BUFFER_SIZE, piValues + i);
574       if (hTest) goto get_error;
575       hTest = glXGetFBConfigAttrib(display, curCfg, GLX_ALPHA_SIZE, &tmp);
576       if (hTest) goto get_error;
577       piValues[i] = piValues[i] - tmp;
578       break;
579
580     case WGL_BLUE_BITS_ARB:
581       curGLXAttr = GLX_BLUE_SIZE;
582       break;
583     case WGL_RED_BITS_ARB:
584       curGLXAttr = GLX_RED_SIZE;
585       break;
586     case WGL_GREEN_BITS_ARB:
587       curGLXAttr = GLX_GREEN_SIZE;
588       break;
589     case WGL_ALPHA_BITS_ARB:
590       curGLXAttr = GLX_ALPHA_SIZE;
591       break;
592     case WGL_DEPTH_BITS_ARB:
593       curGLXAttr = GLX_DEPTH_SIZE;
594       break;
595     case WGL_STENCIL_BITS_ARB:
596       curGLXAttr = GLX_STENCIL_SIZE;
597       break;
598     case WGL_DOUBLE_BUFFER_ARB:
599       curGLXAttr = GLX_DOUBLEBUFFER;
600       break;
601     case WGL_STEREO_ARB:
602       curGLXAttr = GLX_STEREO;
603       break;
604     case WGL_AUX_BUFFERS_ARB:
605       curGLXAttr = GLX_AUX_BUFFERS;
606       break;
607
608     case WGL_SUPPORT_GDI_ARB:
609     case WGL_DRAW_TO_WINDOW_ARB:
610     case WGL_DRAW_TO_BITMAP_ARB:
611     case WGL_DRAW_TO_PBUFFER_ARB:
612       curGLXAttr = GLX_X_RENDERABLE;
613       break;
614
615     case WGL_PBUFFER_LARGEST_ARB:
616       curGLXAttr = GLX_LARGEST_PBUFFER;
617       break;
618
619     case WGL_SAMPLE_BUFFERS_ARB:
620       curGLXAttr = GLX_SAMPLE_BUFFERS_ARB;
621       break;
622       
623     case WGL_SAMPLES_ARB:
624       curGLXAttr = GLX_SAMPLES_ARB;
625       break;
626
627     case WGL_BIND_TO_TEXTURE_RGB_ARB: 
628     case WGL_BIND_TO_TEXTURE_RGBA_ARB:
629       if (!use_render_texture_emulation) {
630         piValues[i] = GL_FALSE;
631         continue ;      
632       }
633       curGLXAttr = GLX_RENDER_TYPE;
634       if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
635       curCfg = cfgs[iPixelFormat - 1];
636       hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, &tmp);
637       if (hTest) goto get_error;
638       if (GLX_COLOR_INDEX_BIT == tmp) {
639         piValues[i] = GL_FALSE;  
640         continue ;
641       }
642       curGLXAttr = GLX_X_RENDERABLE;
643       break;
644
645     default:
646       FIXME("unsupported %x WGL Attribute\n", curWGLAttr);
647     }
648     
649     if (0 != curGLXAttr) {
650       if (nCfgs < iPixelFormat || 0 >= iPixelFormat) goto pix_error;
651       curCfg = cfgs[iPixelFormat - 1];
652       hTest = glXGetFBConfigAttrib(display, curCfg, curGLXAttr, piValues + i);
653       if (hTest) goto get_error;
654     } else { 
655       piValues[i] = GL_FALSE; 
656     }
657   }
658   
659   return GL_TRUE;
660
661 get_error:
662   ERR("(%p): unexpected failure on GetFBConfigAttrib(%x) returns FALSE\n", hdc, curGLXAttr);
663   XFree(cfgs);
664   return GL_FALSE;
665
666 pix_error:
667   ERR("(%p): unexpected iPixelFormat(%d) vs nFormats(%d), returns FALSE\n", hdc, iPixelFormat, nCfgs);
668   XFree(cfgs);
669   return GL_FALSE;
670 }
671
672 GLboolean WINAPI wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues)
673 {
674     FIXME("(%p, %d, %d, %d, %p, %p): stub\n", hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues);
675     return GL_FALSE;
676 }
677 /**
678  * http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.aix.doc/libs/openglrf/glXChooseFBConfig.htm
679  */
680 GLboolean WINAPI wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats)
681 {
682   Display* display = get_display( hdc );
683   int gl_test = 0;
684   int attribs[256];
685   unsigned nAttribs = 0;
686
687   GLXFBConfig* cfgs = NULL;
688   int nCfgs = 0;
689   UINT it;
690   int fmt_id;
691
692   GLXFBConfig* cfgs_fmt = NULL;
693   int nCfgs_fmt = 0;
694   UINT it_fmt;
695   int tmp_fmt_id;
696
697   int pfmt_it = 0;
698
699   TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
700   if (NULL != pfAttribFList) {
701     FIXME("unused pfAttribFList\n");
702   }
703
704   nAttribs = ConvertAttribWGLtoGLX(piAttribIList, attribs, NULL);
705   PUSH1(attribs, None);
706
707   cfgs = glXChooseFBConfig(display, DefaultScreen(display), attribs, &nCfgs);
708   if (NULL == cfgs) {
709     WARN("Compatible Pixel Format not found\n");
710     return GL_FALSE;
711   }
712
713   cfgs_fmt = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs_fmt);
714   if (NULL == cfgs_fmt) {
715     ERR("Failed to get All FB Configs\n");
716     XFree(cfgs);
717     return GL_FALSE;
718   }
719
720   for (it = 0; it < nMaxFormats && it < nCfgs; ++it) {
721     gl_test = glXGetFBConfigAttrib(display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id);
722     if (gl_test) {
723       ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
724       continue ;
725     }
726     for (it_fmt = 0; it_fmt < nCfgs_fmt; ++it_fmt) {
727       gl_test = glXGetFBConfigAttrib(display, cfgs_fmt[it_fmt], GLX_FBCONFIG_ID, &tmp_fmt_id);
728       if (gl_test) {
729         ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
730         continue ;
731       }
732       if (fmt_id == tmp_fmt_id) {
733         int tmp;
734         piFormats[pfmt_it] = it_fmt + 1;
735         ++pfmt_it;
736         glXGetFBConfigAttrib(display, cfgs_fmt[it_fmt], GLX_ALPHA_SIZE, &tmp);
737         TRACE("for FBCONFIG_ID(%d/%d) found '%d'\n", it_fmt + 1, nCfgs_fmt, tmp);
738         break ;
739       }
740     }
741     if (it_fmt == nCfgs_fmt) {
742       ERR("Failed to get valid fmt for %d. Try next.\n", it);
743       continue ;
744     }
745     TRACE("at %d/%d found FBCONFIG_ID(%d/%d)\n", it + 1, nCfgs, piFormats[it], nCfgs_fmt);
746   }
747   
748   *nNumFormats = pfmt_it;
749   /** free list */
750   XFree(cfgs);
751   XFree(cfgs_fmt);
752   return GL_TRUE;
753 }
754
755 #define HPBUFFERARB void *
756 HPBUFFERARB WINAPI wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList)
757 {
758   Wine_GLPBuffer* object = NULL;
759   Display* display = get_display( hdc );
760   GLXFBConfig* cfgs = NULL;
761   int nCfgs = 0;
762   int attribs[256];
763   unsigned nAttribs = 0;
764
765   TRACE("(%p, %d, %d, %d, %p)\n", hdc, iPixelFormat, iWidth, iHeight, piAttribList);
766
767   if (0 >= iPixelFormat) {
768     ERR("(%p): unexpected iPixelFormat(%d) <= 0, returns NULL\n", hdc, iPixelFormat);
769     SetLastError(ERROR_INVALID_PIXEL_FORMAT);
770     return NULL; /* unespected error */
771   }
772
773   cfgs = glXGetFBConfigs(display, DefaultScreen(display), &nCfgs);
774
775   if (NULL == cfgs || 0 == nCfgs) {
776     ERR("(%p): Cannot get FB Configs for iPixelFormat(%d), returns NULL\n", hdc, iPixelFormat);
777     SetLastError(ERROR_INVALID_PIXEL_FORMAT);
778     return NULL; /* unespected error */
779   }
780   if (nCfgs < iPixelFormat) {
781     ERR("(%p): unexpected iPixelFormat(%d) > nFormats(%d), returns NULL\n", hdc, iPixelFormat, nCfgs);
782     SetLastError(ERROR_INVALID_PIXEL_FORMAT);
783     goto create_failed; /* unespected error */
784   }
785
786   object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Wine_GLPBuffer));
787   if (NULL == object) {
788     SetLastError(ERROR_NO_SYSTEM_RESOURCES);
789     goto create_failed; /* unespected error */
790   }
791   object->hdc = hdc;
792   object->display = display;
793   object->width = iWidth;
794   object->height = iHeight;
795   object->pixelFormat = iPixelFormat;
796
797   nAttribs = ConvertAttribWGLtoGLX(piAttribList, attribs, object);
798   PUSH2(attribs, GLX_PBUFFER_WIDTH,  iWidth);
799   PUSH2(attribs, GLX_PBUFFER_HEIGHT, iHeight); 
800   PUSH1(attribs, None);
801
802   while (0 != *piAttribList) {
803     int attr_v;
804     switch (*piAttribList) {
805     case WGL_TEXTURE_FORMAT_ARB: {
806       if (!use_render_texture_emulation) {
807         SetLastError(ERROR_INVALID_DATA);         
808         goto create_failed;
809       }
810       ++piAttribList;
811       attr_v = *piAttribList;
812       TRACE("WGL_render_texture Attribute: WGL_TEXTURE_FORMAT_ARB as %x\n", attr_v);
813       switch (attr_v) {
814       case WGL_TEXTURE_RGB_ARB:
815       case WGL_TEXTURE_RGBA_ARB:
816       case WGL_NO_TEXTURE_ARB:
817         break;
818       default:
819         SetLastError(ERROR_INVALID_DATA);         
820         goto create_failed;
821       }
822       break;
823     }
824     
825     case WGL_TEXTURE_TARGET_ARB: {
826       if (!use_render_texture_emulation) {
827         SetLastError(ERROR_INVALID_DATA);         
828         goto create_failed;
829       }
830       ++piAttribList;
831       attr_v = *piAttribList;
832       TRACE("WGL_render_texture Attribute: WGL_TEXTURE_TARGET_ARB as %x\n", attr_v);
833       switch (attr_v) {
834       case WGL_TEXTURE_CUBE_MAP_ARB: {
835         if (iWidth != iHeight) {
836           SetLastError(ERROR_INVALID_DATA);       
837           goto create_failed;
838         }
839         object->texture_target = GL_TEXTURE_CUBE_MAP;
840         object->texture_bind_target = GL_TEXTURE_CUBE_MAP;
841         break;
842       }
843       case WGL_TEXTURE_1D_ARB: {
844         if (1 != iHeight) {
845           SetLastError(ERROR_INVALID_DATA);       
846           goto create_failed;
847         }
848         object->texture_target = GL_TEXTURE_1D;
849         object->texture_bind_target = GL_TEXTURE_1D;
850         break;
851       }
852       case WGL_TEXTURE_2D_ARB: {
853         object->texture_target = GL_TEXTURE_2D;
854         object->texture_bind_target = GL_TEXTURE_2D;
855         break;
856       }
857       case WGL_NO_TEXTURE_ARB:
858         break;
859       default:
860         SetLastError(ERROR_INVALID_DATA);         
861         goto create_failed;
862       }
863       break;
864     }
865
866     case WGL_MIPMAP_TEXTURE_ARB: {
867       if (!use_render_texture_emulation) {
868         SetLastError(ERROR_INVALID_DATA);         
869         goto create_failed;
870       }
871       ++piAttribList;
872       attr_v = *piAttribList;
873       TRACE("WGL_render_texture Attribute: WGL_MIPMAP_TEXTURE_ARB as %x\n", attr_v);
874       if (0 != attr_v) {
875         SetLastError(ERROR_INVALID_DATA);         
876         goto create_failed;     
877       }
878       break ;
879     }
880
881     }
882     ++piAttribList;
883   }
884
885   object->drawable = glXCreatePbuffer(display, cfgs[iPixelFormat - 1], attribs);
886   TRACE("new Pbuffer drawable as %p\n", (void*) object->drawable);
887   if (!object->drawable) {
888     SetLastError(ERROR_NO_SYSTEM_RESOURCES);
889     goto create_failed; /* unespected error */
890   }
891   TRACE("->(%p)\n", object);
892
893   /** free list */
894   XFree(cfgs);
895   return (HPBUFFERARB) object;
896
897 create_failed:
898   if (NULL != cfgs) XFree(cfgs);
899   if (NULL != object) HeapFree(GetProcessHeap(), 0, object);
900   TRACE("->(FAILED)\n");
901   return (HPBUFFERARB) NULL;
902 }
903
904 HDC WINAPI wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
905 {
906   Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
907   HDC hDC;
908   if (NULL == object) {
909     SetLastError(ERROR_INVALID_HANDLE);
910     return NULL;
911   }
912   hDC = CreateCompatibleDC(object->hdc);
913   set_drawable(hDC, object->drawable); /* works ?? */
914   TRACE("(%p)->(%p)\n", hPbuffer, hDC);
915   return hDC;
916 }
917
918 int WINAPI wglReleasePbufferDCARB(HPBUFFERARB hPbuffer, HDC hdc)
919 {
920   TRACE("(%p, %p)\n", hPbuffer, hdc);
921   DeleteDC(hdc);
922   return 0;
923 }
924
925 GLboolean WINAPI wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
926 {
927   Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
928   TRACE("(%p)\n", hPbuffer);
929   if (NULL == object) {
930     SetLastError(ERROR_INVALID_HANDLE);
931     return GL_FALSE;
932   }
933   glXDestroyPbuffer(object->display, object->drawable);
934   HeapFree(GetProcessHeap(), 0, object);
935   return GL_TRUE;
936 }
937
938 GLboolean WINAPI wglQueryPbufferARB(HPBUFFERARB hPbuffer, int iAttribute, int *piValue)
939 {
940   Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
941   TRACE("(%p, 0x%x, %p)\n", hPbuffer, iAttribute, piValue);
942   if (NULL == object) {
943     SetLastError(ERROR_INVALID_HANDLE);
944     return GL_FALSE;
945   }
946   switch (iAttribute) {
947   case WGL_PBUFFER_WIDTH_ARB:
948     glXQueryDrawable(object->display, object->drawable, GLX_WIDTH, (unsigned int*) piValue);
949     break;
950   case WGL_PBUFFER_HEIGHT_ARB:
951     glXQueryDrawable(object->display, object->drawable, GLX_HEIGHT, (unsigned int*) piValue);
952     break;
953
954   case WGL_PBUFFER_LOST_ARB:
955     FIXME("unsupported WGL_PBUFFER_LOST_ARB (need glXSelectEvent/GLX_DAMAGED work)\n");
956     break;
957
958   case WGL_TEXTURE_FORMAT_ARB:
959   case WGL_TEXTURE_TARGET_ARB:
960   case WGL_MIPMAP_TEXTURE_ARB:
961     if (!object->use_render_texture) {
962       SetLastError(ERROR_INVALID_HANDLE);
963       return GL_FALSE;
964     }
965     if (!use_render_texture_emulation) {
966       SetLastError(ERROR_INVALID_DATA);      
967       return GL_FALSE; /** how to FIX ? */
968     }
969     FIXME("unsupported WGL_ARB_render_texture attribute query for 0x%x\n", iAttribute);
970     break;
971
972   default:
973     FIXME("unexpected attribute %x\n", iAttribute);
974     break;
975   }
976
977   return GL_TRUE;
978 }
979
980 GLboolean WINAPI wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
981 {
982   Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
983   TRACE("(%p, %d)\n", hPbuffer, iBuffer);
984   if (NULL == object) {
985     SetLastError(ERROR_INVALID_HANDLE);
986     return GL_FALSE;
987   }
988   if (!object->use_render_texture) {
989     SetLastError(ERROR_INVALID_HANDLE);
990     return GL_FALSE;
991   }
992   if (1 == use_render_texture_emulation) {
993     return GL_TRUE;
994   }
995   if (NULL != p_glXBindTexImageARB) {
996     return p_glXBindTexImageARB(object->display, object->drawable, iBuffer);
997   }
998   return GL_FALSE;
999 }
1000
1001 GLboolean WINAPI wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
1002 {
1003   Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
1004   TRACE("(%p, %d)\n", hPbuffer, iBuffer);
1005   if (NULL == object) {
1006     SetLastError(ERROR_INVALID_HANDLE);
1007     return GL_FALSE;
1008   }
1009   if (!object->use_render_texture) {
1010     SetLastError(ERROR_INVALID_HANDLE);
1011     return GL_FALSE;
1012   }
1013   if (1 == use_render_texture_emulation) {
1014     GLint prev_binded_tex;
1015     glGetIntegerv(object->texture_target, &prev_binded_tex);
1016     glBindTexture(object->texture_target, object->texture);
1017     if (GL_TEXTURE_1D == object->texture_target) {
1018       glCopyTexSubImage1D(object->texture_bind_target, object->texture_level, 0, 0, 0, object->width);
1019     } else {
1020       glCopyTexSubImage2D(object->texture_bind_target, object->texture_level, 0, 0, 0, 0, object->width, object->height);
1021     }
1022     glBindTexture(object->texture_target, prev_binded_tex);
1023     return GL_TRUE;
1024   }
1025   if (NULL != p_glXReleaseTexImageARB) {
1026     return p_glXReleaseTexImageARB(object->display, object->drawable, iBuffer);
1027   }
1028   return GL_FALSE;
1029 }
1030
1031 GLboolean WINAPI wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int *piAttribList)
1032 {
1033   Wine_GLPBuffer* object = (Wine_GLPBuffer*) hPbuffer;
1034   WARN("(%p, %p): alpha-testing, report any problem\n", hPbuffer, piAttribList);
1035   if (NULL == object) {
1036     SetLastError(ERROR_INVALID_HANDLE);
1037     return GL_FALSE;
1038   }
1039   if (!object->use_render_texture) {
1040     SetLastError(ERROR_INVALID_HANDLE);
1041     return GL_FALSE;
1042   }
1043   if (1 == use_render_texture_emulation) {
1044     return GL_TRUE;
1045   }
1046   if (NULL != p_glXDrawableAttribARB) {
1047     return p_glXDrawableAttribARB(object->display, object->drawable, piAttribList); 
1048   }
1049   return GL_FALSE;
1050 }
1051
1052 static const struct {
1053     const char *name;
1054     BOOL (*query_function)(glXGetProcAddressARB_t proc, const char *gl_version, const char *gl_extensions,
1055                            const char *glx_version, const char *glx_extensions,
1056                            const char *server_glx_extensions, const char *client_glx_extensions);
1057 } extension_list[] = {
1058   { "WGL_ARB_make_current_read", query_function_make_current_read },
1059   { "WGL_ARB_multisample",       query_function_multisample },
1060   { "WGL_ARB_pbuffer",           query_function_pbuffer },
1061   { "WGL_ARB_pixel_format" ,     query_function_pixel_format },
1062   { "WGL_ARB_render_texture",    query_function_render_texture },
1063   { "WGL_EXT_swap_control",      query_function_swap_control }
1064 };
1065
1066 /* Used to initialize the WGL extension string at DLL loading */
1067 void wgl_ext_initialize_extensions(Display *display, int screen, glXGetProcAddressARB_t proc, const char* disabled_extensions)
1068 {
1069     int size = strlen(WGL_extensions_base);
1070     const char *glx_extensions = glXQueryExtensionsString(display, screen);
1071     const char *server_glx_extensions = glXQueryServerString(display, screen, GLX_EXTENSIONS);
1072     const char *client_glx_extensions = glXGetClientString(display, GLX_EXTENSIONS);
1073     const char *gl_extensions = (const char *) glGetString(GL_EXTENSIONS);
1074     const char *gl_version = (const char *) glGetString(GL_VERSION);
1075     const char *glx_version = glXGetClientString(display, GLX_VERSION);
1076     int i;
1077
1078     TRACE("GL version      : %s.\n", debugstr_a(gl_version));
1079     TRACE("GL exts         : %s.\n", debugstr_a(gl_extensions));
1080     TRACE("GLX exts        : %s.\n", debugstr_a(glx_extensions));
1081     TRACE("Server GLX exts : %s.\n", debugstr_a(server_glx_extensions));
1082     TRACE("Client GLX exts : %s.\n", debugstr_a(client_glx_extensions));
1083
1084     for (i = 0; i < (sizeof(extension_list) / sizeof(extension_list[0])); i++) {
1085         if (strstr(disabled_extensions, extension_list[i].name)) continue ; /* disabled by config, next */
1086         if (extension_list[i].query_function(proc, 
1087                                              gl_version, gl_extensions, 
1088                                              glx_version, glx_extensions,
1089                                              server_glx_extensions, client_glx_extensions)) {
1090             size += strlen(extension_list[i].name) + 1;
1091         }
1092     }
1093
1094     /* For the moment, only 'base' extensions are supported. */
1095     WGL_extensions = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1);
1096     if (WGL_extensions == NULL) {
1097         WGL_extensions = (char *) WGL_extensions_base;
1098     } else {
1099         strcpy(WGL_extensions, WGL_extensions_base);
1100         for (i = 0; i < (sizeof(extension_list) / sizeof(extension_list[0])); i++) {
1101             if (strstr(disabled_extensions, extension_list[i].name)) continue ; /* disabled by config, next */
1102             if (extension_list[i].query_function(proc, 
1103                                                  gl_version, gl_extensions, 
1104                                                  glx_version, glx_extensions,
1105                                                  server_glx_extensions, client_glx_extensions)) {
1106                 strcat(WGL_extensions, " ");
1107                 strcat(WGL_extensions, extension_list[i].name);
1108             }
1109         }
1110     }
1111
1112     TRACE("Supporting following WGL extensions : %s.\n", debugstr_a(WGL_extensions));
1113 }
1114
1115 void wgl_ext_finalize_extensions(void)
1116 {
1117     if (WGL_extensions != WGL_extensions_base) {
1118         HeapFree(GetProcessHeap(), 0, WGL_extensions);
1119     }
1120 }
1121
1122
1123 /* these are located in wgl.c for convenience of implementation */
1124 BOOL    WINAPI wglMakeContextCurrentARB(HDC,HDC,HGLRC);
1125 HDC     WINAPI wglGetCurrentReadDCARB(void);
1126
1127
1128 /*
1129  * Putting this at the end to prevent having to write the prototypes :-) 
1130  *
1131  * @WARNING: this list must be ordered by name
1132  *
1133  * @TODO: real handle caps on providing some func_init functions (third param, ex: to check extensions)
1134  */
1135 WGL_extension wgl_extension_registry[] = {
1136     { "wglBindTexImageARB", (void *) wglBindTexImageARB, NULL, NULL},
1137     { "wglChoosePixelFormatARB", (void *) wglChoosePixelFormatARB, NULL, NULL},
1138     { "wglCreatePbufferARB", (void *) wglCreatePbufferARB, NULL, NULL},
1139     { "wglDestroyPbufferARB", (void *) wglDestroyPbufferARB, NULL, NULL},
1140     { "wglGetCurrentReadDCARB", (void *) wglGetCurrentReadDCARB, NULL, NULL},
1141     { "wglGetExtensionsStringARB", (void *) wglGetExtensionsStringARB, NULL, NULL},
1142     { "wglGetExtensionsStringEXT", (void *) wglGetExtensionsStringEXT, NULL, NULL},
1143     { "wglGetPbufferDCARB", (void *) wglGetPbufferDCARB, NULL, NULL},
1144     { "wglGetPixelFormatAttribfvARB", (void *) wglGetPixelFormatAttribfvARB, NULL, NULL},
1145     { "wglGetPixelFormatAttribivARB", (void *) wglGetPixelFormatAttribivARB, NULL, NULL},
1146     { "wglGetSwapIntervalEXT", (void *) wglGetSwapIntervalEXT, NULL, NULL},
1147     { "wglMakeContextCurrentARB", (void *) wglMakeContextCurrentARB, NULL, NULL },
1148     { "wglQueryPbufferARB", (void *) wglQueryPbufferARB, NULL, NULL},
1149     { "wglReleasePbufferDCARB", (void *) wglReleasePbufferDCARB, NULL, NULL},
1150     { "wglReleaseTexImageARB", (void *) wglReleaseTexImageARB, NULL, NULL},
1151     { "wglSetPbufferAttribARB", (void *) wglSetPbufferAttribARB, NULL, NULL},
1152     { "wglSwapIntervalEXT", (void *) wglSwapIntervalEXT, NULL, NULL}
1153 };
1154 int wgl_extension_registry_size = sizeof(wgl_extension_registry) / sizeof(wgl_extension_registry[0]);