winemac: Improve logging from wglChoosePixelFormatARB() and wglGetPixelFormatAttribiv...
[wine] / dlls / winemac.drv / opengl.c
1 /*
2  * Mac driver OpenGL support
3  *
4  * Copyright 2012 Alexandre Julliard
5  * Copyright 2012, 2013 Ken Thomases for CodeWeavers Inc.
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 "macdrv.h"
26
27 #include "winuser.h"
28 #include "winternl.h"
29 #include "wine/library.h"
30 #include "wine/debug.h"
31 #include "wine/wgl.h"
32 #include "wine/wgl_driver.h"
33 #include "wine/wglext.h"
34
35 #define __gl_h_
36 #define __gltypes_h_
37 #include <OpenGL/OpenGL.h>
38 #include <OpenGL/glu.h>
39 #include <OpenGL/CGLRenderers.h>
40 #include <dlfcn.h>
41
42 WINE_DEFAULT_DEBUG_CHANNEL(wgl);
43
44
45 struct gl_info {
46     char *glVersion;
47     char *glExtensions;
48
49     char wglExtensions[4096];
50
51     GLint max_viewport_dims[2];
52 };
53
54 static struct gl_info gl_info;
55
56
57 struct wgl_context
58 {
59     HDC                     hdc;
60     int                     format;
61     macdrv_opengl_context   context;
62     CGLContextObj           cglcontext;
63     macdrv_view             draw_view;
64     struct wgl_pbuffer     *draw_pbuffer;
65     macdrv_view             read_view;
66     struct wgl_pbuffer     *read_pbuffer;
67     BOOL                    has_been_current;
68     BOOL                    sharing;
69 };
70
71
72 struct wgl_pbuffer
73 {
74     CGLPBufferObj   pbuffer;
75     int             format;
76     BOOL            no_texture;
77     int             max_level;
78     GLint           level;
79     GLenum          face;
80 };
81
82 static CFMutableDictionaryRef dc_pbuffers;
83
84 static CRITICAL_SECTION dc_pbuffers_section;
85 static CRITICAL_SECTION_DEBUG dc_pbuffers_section_debug =
86 {
87     0, 0, &dc_pbuffers_section,
88     { &dc_pbuffers_section_debug.ProcessLocksList, &dc_pbuffers_section_debug.ProcessLocksList },
89       0, 0, { (DWORD_PTR)(__FILE__ ": dc_pbuffers_section") }
90 };
91 static CRITICAL_SECTION dc_pbuffers_section = { &dc_pbuffers_section_debug, -1, 0, 0, 0, 0 };
92
93
94 static struct opengl_funcs opengl_funcs;
95
96 #define USE_GL_FUNC(name) #name,
97 static const char *opengl_func_names[] = { ALL_WGL_FUNCS };
98 #undef USE_GL_FUNC
99
100
101 static void (*pglCopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y,
102                                  GLsizei width);
103 static void (*pglCopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
104 static void (*pglReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height,
105                              GLenum format, GLenum type, void *pixels);
106 static void (*pglViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
107
108
109 struct color_mode {
110     GLint   mode;
111     int     bits_per_pixel;
112     GLint   color_bits; /* including alpha_bits */
113     int     red_bits, red_shift;
114     int     green_bits, green_shift;
115     int     blue_bits, blue_shift;
116     GLint   alpha_bits, alpha_shift;
117     BOOL    is_float;
118     int     color_ordering;
119 };
120
121 /* The value of "color_ordering" is somewhat arbitrary.  It incorporates some
122    observations of the behavior of Windows systems, but also subjective judgments
123    about what color formats are more "normal" than others.
124
125    On at least some Windows systems, integer color formats are listed before
126    floating-point formats.  Within the integer formats, higher color bits were
127    usually listed before lower color bits, while for floating-point formats it
128    was the reverse.  However, that leads D3D to select 64-bit integer formats in
129    preference to 32-bit formats when the latter would be sufficient.  It seems
130    that a 32-bit format is much more likely to be normally used in that case.
131
132    Also, there are certain odd color formats supported on the Mac which seem like
133    they would be less appropriate than more common ones.  For instance, the color
134    formats with alpha in a separate byte (e.g. kCGLRGB888A8Bit with R8G8B8 in one
135    32-bit value and A8 in a separate 8-bit value) and the formats with 10-bit RGB
136    components.
137
138    For two color formats which differ only in whether or not they have alpha bits,
139    we use the same ordering.  pixel_format_comparator() gives alpha bits a
140    different weight than color formats.
141  */
142 static const struct color_mode color_modes[] = {
143     { kCGLRGB444Bit,        16,     12,     4,  8,      4,  4,      4,  0,      0,  0,  FALSE,  5 },
144     { kCGLARGB4444Bit,      16,     16,     4,  8,      4,  4,      4,  0,      4,  12, FALSE,  5 },
145     { kCGLRGB444A8Bit,      24,     20,     4,  8,      4,  4,      4,  0,      8,  16, FALSE,  10 },
146     { kCGLRGB555Bit,        16,     15,     5,  10,     5,  5,      5,  0,      0,  0,  FALSE,  4 },
147     { kCGLARGB1555Bit,      16,     16,     5,  10,     5,  5,      5,  0,      1,  15, FALSE,  4 },
148     { kCGLRGB555A8Bit,      24,     23,     5,  10,     5,  5,      5,  0,      8,  16, FALSE,  9 },
149     { kCGLRGB565Bit,        16,     16,     5,  11,     6,  5,      5,  0,      0,  0,  FALSE,  3 },
150     { kCGLRGB565A8Bit,      24,     24,     5,  11,     6,  5,      5,  0,      8,  16, FALSE,  8 },
151     { kCGLRGB888Bit,        32,     24,     8,  16,     8,  8,      8,  0,      0,  0,  FALSE,  0 },
152     { kCGLARGB8888Bit,      32,     32,     8,  16,     8,  8,      8,  0,      8,  24, FALSE,  0 },
153     { kCGLRGB888A8Bit,      40,     32,     8,  16,     8,  8,      8,  0,      8,  32, FALSE,  7 },
154     { kCGLRGB101010Bit,     32,     30,     10, 20,     10, 10,     10, 0,      0,  0,  FALSE,  6 },
155     { kCGLARGB2101010Bit,   32,     32,     10, 20,     10, 10,     10, 0,      2,  30, FALSE,  6 },
156     { kCGLRGB101010_A8Bit,  40,     38,     10, 20,     10, 10,     10, 0,      8,  32, FALSE,  11 },
157     { kCGLRGB121212Bit,     48,     36,     12, 24,     12, 12,     12, 0,      0,  0,  FALSE,  2 },
158     { kCGLARGB12121212Bit,  48,     48,     12, 24,     12, 12,     12, 0,      12, 36, FALSE,  2 },
159     { kCGLRGB161616Bit,     64,     48,     16, 48,     16, 32,     16, 16,     0,  0,  FALSE,  1 },
160     { kCGLRGBA16161616Bit,  64,     64,     16, 48,     16, 32,     16, 16,     16, 0,  FALSE,  1 },
161     { kCGLRGBFloat64Bit,    64,     48,     16, 32,     16, 16,     16, 0,      0,  0,  TRUE,   12 },
162     { kCGLRGBAFloat64Bit,   64,     64,     16, 48,     16, 32,     16, 16,     16, 0,  TRUE,   12 },
163     { kCGLRGBFloat128Bit,   128,    96,     32, 96,     32, 64,     32, 32,     0,  0,  TRUE,   13 },
164     { kCGLRGBAFloat128Bit,  128,    128,    32, 96,     32, 64,     32, 32,     32, 0,  TRUE,   13 },
165     { kCGLRGBFloat256Bit,   256,    192,    64, 192,    64, 128,    64, 64,     0,  0,  TRUE,   14 },
166     { kCGLRGBAFloat256Bit,  256,    256,    64, 192,    64, 128,    64, 64,     64, 0,  TRUE,   15 },
167 };
168
169
170 static const struct {
171     GLint   mode;
172     int     bits;
173 } depth_stencil_modes[] = {
174     { kCGL0Bit,     0 },
175     { kCGL1Bit,     1 },
176     { kCGL2Bit,     2 },
177     { kCGL3Bit,     3 },
178     { kCGL4Bit,     4 },
179     { kCGL5Bit,     5 },
180     { kCGL6Bit,     6 },
181     { kCGL8Bit,     8 },
182     { kCGL10Bit,    10 },
183     { kCGL12Bit,    12 },
184     { kCGL16Bit,    16 },
185     { kCGL24Bit,    24 },
186     { kCGL32Bit,    32 },
187     { kCGL48Bit,    48 },
188     { kCGL64Bit,    64 },
189     { kCGL96Bit,    96 },
190     { kCGL128Bit,   128 },
191 };
192
193
194 typedef struct {
195     GLint   renderer_id;
196     GLint   buffer_modes;
197     GLint   color_modes;
198     GLint   accum_modes;
199     GLint   depth_modes;
200     GLint   stencil_modes;
201     GLint   max_aux_buffers;
202     GLint   max_sample_buffers;
203     GLint   max_samples;
204     BOOL    offscreen;
205     BOOL    accelerated;
206     BOOL    backing_store;
207     BOOL    window;
208     BOOL    online;
209 } renderer_properties;
210
211
212 typedef struct {
213     unsigned int window:1;
214     unsigned int pbuffer:1;
215     unsigned int accelerated:1;
216     unsigned int color_mode:5; /* index into color_modes table */
217     unsigned int aux_buffers:3;
218     unsigned int depth_bits:8;
219     unsigned int stencil_bits:8;
220     unsigned int accum_mode:5; /* 1 + index into color_modes table (0 means no accum buffer) */
221     unsigned int double_buffer:1;
222     unsigned int stereo:1;
223     unsigned int sample_buffers:1;
224     unsigned int samples:5;
225     unsigned int backing_store:1;
226 } pixel_format;
227
228
229 typedef union
230 {
231     pixel_format    format;
232     UInt64          code;
233 } pixel_format_or_code;
234
235
236 static pixel_format *pixel_formats;
237 static int nb_formats, nb_displayable_formats;
238
239
240 static void *opengl_handle;
241
242
243 static const char* debugstr_attrib(int attrib, int value)
244 {
245     static const struct {
246         int attrib;
247         const char *name;
248     } attrib_names[] = {
249 #define ATTRIB(a) { a, #a }
250         ATTRIB(WGL_ACCELERATION_ARB),
251         ATTRIB(WGL_ACCUM_ALPHA_BITS_ARB),
252         ATTRIB(WGL_ACCUM_BITS_ARB),
253         ATTRIB(WGL_ACCUM_BLUE_BITS_ARB),
254         ATTRIB(WGL_ACCUM_GREEN_BITS_ARB),
255         ATTRIB(WGL_ACCUM_RED_BITS_ARB),
256         ATTRIB(WGL_ALPHA_BITS_ARB),
257         ATTRIB(WGL_ALPHA_SHIFT_ARB),
258         ATTRIB(WGL_AUX_BUFFERS_ARB),
259         ATTRIB(WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV),
260         ATTRIB(WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV),
261         ATTRIB(WGL_BIND_TO_TEXTURE_RGB_ARB),
262         ATTRIB(WGL_BIND_TO_TEXTURE_RGBA_ARB),
263         ATTRIB(WGL_BLUE_BITS_ARB),
264         ATTRIB(WGL_BLUE_SHIFT_ARB),
265         ATTRIB(WGL_COLOR_BITS_ARB),
266         ATTRIB(WGL_DEPTH_BITS_ARB),
267         ATTRIB(WGL_DOUBLE_BUFFER_ARB),
268         ATTRIB(WGL_DRAW_TO_BITMAP_ARB),
269         ATTRIB(WGL_DRAW_TO_PBUFFER_ARB),
270         ATTRIB(WGL_DRAW_TO_WINDOW_ARB),
271         ATTRIB(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB),
272         ATTRIB(WGL_GREEN_BITS_ARB),
273         ATTRIB(WGL_GREEN_SHIFT_ARB),
274         ATTRIB(WGL_NEED_PALETTE_ARB),
275         ATTRIB(WGL_NEED_SYSTEM_PALETTE_ARB),
276         ATTRIB(WGL_NUMBER_OVERLAYS_ARB),
277         ATTRIB(WGL_NUMBER_PIXEL_FORMATS_ARB),
278         ATTRIB(WGL_NUMBER_UNDERLAYS_ARB),
279         ATTRIB(WGL_PIXEL_TYPE_ARB),
280         ATTRIB(WGL_RED_BITS_ARB),
281         ATTRIB(WGL_RED_SHIFT_ARB),
282         ATTRIB(WGL_SAMPLE_BUFFERS_ARB),
283         ATTRIB(WGL_SAMPLES_ARB),
284         ATTRIB(WGL_SHARE_ACCUM_ARB),
285         ATTRIB(WGL_SHARE_DEPTH_ARB),
286         ATTRIB(WGL_SHARE_STENCIL_ARB),
287         ATTRIB(WGL_STENCIL_BITS_ARB),
288         ATTRIB(WGL_STEREO_ARB),
289         ATTRIB(WGL_SUPPORT_GDI_ARB),
290         ATTRIB(WGL_SUPPORT_OPENGL_ARB),
291         ATTRIB(WGL_SWAP_LAYER_BUFFERS_ARB),
292         ATTRIB(WGL_SWAP_METHOD_ARB),
293         ATTRIB(WGL_TRANSPARENT_ALPHA_VALUE_ARB),
294         ATTRIB(WGL_TRANSPARENT_ARB),
295         ATTRIB(WGL_TRANSPARENT_BLUE_VALUE_ARB),
296         ATTRIB(WGL_TRANSPARENT_GREEN_VALUE_ARB),
297         ATTRIB(WGL_TRANSPARENT_INDEX_VALUE_ARB),
298         ATTRIB(WGL_TRANSPARENT_RED_VALUE_ARB),
299 #undef ATTRIB
300     };
301     int i;
302     const char *attrib_name = NULL;
303     const char *value_name = NULL;
304
305     for (i = 0; i < sizeof(attrib_names) / sizeof(attrib_names[0]); i++)
306     {
307         if (attrib_names[i].attrib == attrib)
308         {
309             attrib_name = attrib_names[i].name;
310             break;
311         }
312     }
313
314     if (!attrib_name)
315         attrib_name = wine_dbg_sprintf("Attrib 0x%04x", attrib);
316
317     switch (attrib)
318     {
319         case WGL_ACCELERATION_ARB:
320             switch (value)
321             {
322                 case WGL_FULL_ACCELERATION_ARB:     value_name = "WGL_FULL_ACCELERATION_ARB"; break;
323                 case WGL_GENERIC_ACCELERATION_ARB:  value_name = "WGL_GENERIC_ACCELERATION_ARB"; break;
324                 case WGL_NO_ACCELERATION_ARB:       value_name = "WGL_NO_ACCELERATION_ARB"; break;
325             }
326             break;
327         case WGL_PIXEL_TYPE_ARB:
328             switch (value)
329             {
330                 case WGL_TYPE_COLORINDEX_ARB:           value_name = "WGL_TYPE_COLORINDEX_ARB"; break;
331                 case WGL_TYPE_RGBA_ARB:                 value_name = "WGL_TYPE_RGBA_ARB"; break;
332                 case WGL_TYPE_RGBA_FLOAT_ARB:           value_name = "WGL_TYPE_RGBA_FLOAT_ARB"; break;
333                 case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT:  value_name = "WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT"; break;
334             }
335             break;
336         case WGL_SWAP_METHOD_ARB:
337             switch (value)
338             {
339                 case WGL_SWAP_COPY_ARB:         value_name = "WGL_SWAP_COPY_ARB"; break;
340                 case WGL_SWAP_EXCHANGE_ARB:     value_name = "WGL_SWAP_EXCHANGE_ARB"; break;
341                 case WGL_SWAP_UNDEFINED_ARB:    value_name = "WGL_SWAP_UNDEFINED_ARB"; break;
342             }
343             break;
344     }
345
346     if (!value_name)
347         value_name = wine_dbg_sprintf("%d / 0x%04x", value, value);
348
349     return wine_dbg_sprintf("%40s: %s", attrib_name, value_name);
350 }
351
352
353 static BOOL get_renderer_property(CGLRendererInfoObj renderer_info, GLint renderer_index,
354                                   CGLRendererProperty property, GLint *value)
355 {
356     CGLError err = CGLDescribeRenderer(renderer_info, renderer_index, property, value);
357     if (err != kCGLNoError)
358         WARN("CGLDescribeRenderer failed for property %d: %d %s\n", property, err, CGLErrorString(err));
359     return (err == kCGLNoError);
360 }
361
362
363 static void get_renderer_properties(CGLRendererInfoObj renderer_info, int renderer_index, renderer_properties* properties)
364 {
365     GLint value;
366
367     memset(properties, 0, sizeof(*properties));
368
369     if (get_renderer_property(renderer_info, renderer_index, kCGLRPRendererID, &value))
370         properties->renderer_id = value & kCGLRendererIDMatchingMask;
371
372     if (get_renderer_property(renderer_info, renderer_index, kCGLRPBufferModes, &value))
373         properties->buffer_modes = value;
374
375     if (get_renderer_property(renderer_info, renderer_index, kCGLRPColorModes, &value))
376         properties->color_modes = value;
377
378     if (get_renderer_property(renderer_info, renderer_index, kCGLRPAccumModes, &value))
379         properties->accum_modes = value;
380
381     if (get_renderer_property(renderer_info, renderer_index, kCGLRPDepthModes, &value))
382         properties->depth_modes = value;
383
384     if (get_renderer_property(renderer_info, renderer_index, kCGLRPStencilModes, &value))
385         properties->stencil_modes = value;
386
387     if (get_renderer_property(renderer_info, renderer_index, kCGLRPMaxAuxBuffers, &value))
388         properties->max_aux_buffers = value;
389
390     if (get_renderer_property(renderer_info, renderer_index, kCGLRPMaxSampleBuffers, &value))
391         properties->max_sample_buffers = value;
392
393     if (get_renderer_property(renderer_info, renderer_index, kCGLRPMaxSamples, &value))
394         properties->max_samples = value;
395
396     if (get_renderer_property(renderer_info, renderer_index, kCGLRPOffScreen, &value))
397         properties->offscreen = (value != 0);
398
399     if (get_renderer_property(renderer_info, renderer_index, kCGLRPAccelerated, &value))
400         properties->accelerated = (value != 0);
401
402     if (get_renderer_property(renderer_info, renderer_index, kCGLRPBackingStore, &value))
403         properties->backing_store = (value != 0);
404
405     if (get_renderer_property(renderer_info, renderer_index, kCGLRPWindow, &value))
406         properties->window = (value != 0);
407
408     if (get_renderer_property(renderer_info, renderer_index, kCGLRPOnline, &value))
409         properties->online = (value != 0);
410 }
411
412
413 static void dump_renderer(const renderer_properties* renderer)
414 {
415     int i;
416
417     TRACE("Renderer ID: 0x%08x\n", renderer->renderer_id);
418     TRACE("Buffer modes:\n");
419     TRACE("    Monoscopic:    %s\n", (renderer->buffer_modes & kCGLMonoscopicBit) ? "YES" : "NO");
420     TRACE("    Stereoscopic:  %s\n", (renderer->buffer_modes & kCGLStereoscopicBit) ? "YES" : "NO");
421     TRACE("    Single buffer: %s\n", (renderer->buffer_modes & kCGLSingleBufferBit) ? "YES" : "NO");
422     TRACE("    Double buffer: %s\n", (renderer->buffer_modes & kCGLDoubleBufferBit) ? "YES" : "NO");
423
424     TRACE("Color buffer modes:\n");
425     for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
426     {
427         if (renderer->color_modes & color_modes[i].mode)
428         {
429             TRACE("    Color size %d, Alpha size %d", color_modes[i].color_bits, color_modes[i].alpha_bits);
430             if (color_modes[i].is_float)
431                 TRACE(", Float");
432             TRACE("\n");
433         }
434     }
435
436     TRACE("Accumulation buffer sizes: { ");
437     for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
438     {
439         if (renderer->accum_modes & color_modes[i].mode)
440             TRACE("%d, ", color_modes[i].color_bits);
441     }
442     TRACE("}\n");
443
444     TRACE("Depth buffer sizes: { ");
445     for (i = 0; i < sizeof(depth_stencil_modes)/sizeof(depth_stencil_modes[0]); i++)
446     {
447         if (renderer->depth_modes & depth_stencil_modes[i].mode)
448             TRACE("%d, ", depth_stencil_modes[i].bits);
449     }
450     TRACE("}\n");
451
452     TRACE("Stencil buffer sizes: { ");
453     for (i = 0; i < sizeof(depth_stencil_modes)/sizeof(depth_stencil_modes[0]); i++)
454     {
455         if (renderer->stencil_modes & depth_stencil_modes[i].mode)
456             TRACE("%d, ", depth_stencil_modes[i].bits);
457     }
458     TRACE("}\n");
459
460     TRACE("Max. Auxiliary Buffers: %d\n", renderer->max_aux_buffers);
461     TRACE("Max. Sample Buffers: %d\n", renderer->max_sample_buffers);
462     TRACE("Max. Samples: %d\n", renderer->max_samples);
463     TRACE("Offscreen: %s\n", renderer->offscreen ? "YES" : "NO");
464     TRACE("Accelerated: %s\n", renderer->accelerated ? "YES" : "NO");
465     TRACE("Backing store: %s\n", renderer->backing_store ? "YES" : "NO");
466     TRACE("Window: %s\n", renderer->window ? "YES" : "NO");
467     TRACE("Online: %s\n", renderer->online ? "YES" : "NO");
468 }
469
470
471 static inline UInt64 code_for_pixel_format(const pixel_format* format)
472 {
473     pixel_format_or_code pfc;
474
475     pfc.code = 0;
476     pfc.format = *format;
477     return pfc.code;
478 }
479
480
481 static inline pixel_format pixel_format_for_code(UInt64 code)
482 {
483     pixel_format_or_code pfc;
484
485     pfc.code = code;
486     return pfc.format;
487 }
488
489
490 static const char *debugstr_pf(const pixel_format *pf)
491 {
492     return wine_dbg_sprintf("w/p/a %u/%u/%u col %u%s/%u dp/stn/ac/ax/b/db/str %u/%u/%u/%u/%u/%u/%u samp %u/%u %017llx",
493                             pf->window,
494                             pf->pbuffer,
495                             pf->accelerated,
496                             color_modes[pf->color_mode].color_bits,
497                             (color_modes[pf->color_mode].is_float ? "f" : ""),
498                             color_modes[pf->color_mode].alpha_bits,
499                             pf->depth_bits,
500                             pf->stencil_bits,
501                             pf->accum_mode ? color_modes[pf->accum_mode - 1].color_bits : 0,
502                             pf->aux_buffers,
503                             pf->backing_store,
504                             pf->double_buffer,
505                             pf->stereo,
506                             pf->sample_buffers,
507                             pf->samples,
508                             code_for_pixel_format(pf));
509 }
510
511
512 static unsigned int best_color_mode(GLint modes, GLint color_size, GLint alpha_size, GLint color_float)
513 {
514     int best = -1;
515     int i;
516
517     for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
518     {
519         if ((modes & color_modes[i].mode) &&
520             color_modes[i].color_bits >= color_size &&
521             color_modes[i].alpha_bits >= alpha_size &&
522             !color_modes[i].is_float == !color_float)
523         {
524             if (best < 0) /* no existing best choice */
525                 best = i;
526             else if (color_modes[i].color_bits == color_size &&
527                      color_modes[i].alpha_bits == alpha_size) /* candidate is exact match */
528             {
529                 /* prefer it over a best which isn't exact or which has a higher bpp */
530                 if (color_modes[best].color_bits != color_size ||
531                     color_modes[best].alpha_bits != alpha_size ||
532                     color_modes[i].bits_per_pixel < color_modes[best].bits_per_pixel)
533                     best = i;
534             }
535             else if (color_modes[i].color_bits < color_modes[best].color_bits ||
536                      (color_modes[i].color_bits == color_modes[best].color_bits &&
537                       color_modes[i].alpha_bits < color_modes[best].alpha_bits)) /* prefer closer */
538                 best = i;
539         }
540     }
541
542     if (best < 0)
543     {
544         /* Couldn't find a match.  Return first one that renderer supports. */
545         for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
546         {
547             if (modes & color_modes[i].mode)
548                 return i;
549         }
550     }
551
552     return best;
553 }
554
555
556 static unsigned int best_accum_mode(GLint modes, GLint accum_size)
557 {
558     int best = -1;
559     int i;
560
561     for (i = 0; i < sizeof(color_modes)/sizeof(color_modes[0]); i++)
562     {
563         if ((modes & color_modes[i].mode) && color_modes[i].color_bits >= accum_size)
564         {
565             /* Prefer the fewest color bits, then prefer more alpha bits, then
566                prefer more bits per pixel. */
567             if (best < 0)
568                 best = i;
569             else if (color_modes[i].color_bits < color_modes[best].color_bits)
570                 best = i;
571             else if (color_modes[i].color_bits == color_modes[best].color_bits)
572             {
573                 if (color_modes[i].alpha_bits > color_modes[best].alpha_bits)
574                     best = i;
575                 else if (color_modes[i].alpha_bits == color_modes[best].alpha_bits &&
576                          color_modes[i].bits_per_pixel > color_modes[best].bits_per_pixel)
577                     best = i;
578             }
579         }
580     }
581
582     if (best < 0)
583     {
584         /* Couldn't find a match.  Return last one that renderer supports. */
585         for (i = sizeof(color_modes)/sizeof(color_modes[0]) - 1; i >= 0; i--)
586         {
587             if (modes & color_modes[i].mode)
588                 return i;
589         }
590     }
591
592     return best;
593 }
594
595
596 static void enum_renderer_pixel_formats(renderer_properties renderer, CFMutableArrayRef pixel_format_array,
597                                         CFMutableSetRef pixel_format_set)
598 {
599     CGLPixelFormatAttribute attribs[64] = {
600         kCGLPFAMinimumPolicy,
601         kCGLPFAClosestPolicy,
602         kCGLPFARendererID, renderer.renderer_id,
603         kCGLPFASingleRenderer,
604     };
605     int n = 5, n_stack[16], n_stack_idx = -1;
606     unsigned int tried_pixel_formats = 0, failed_pixel_formats = 0, dupe_pixel_formats = 0,
607                  new_pixel_formats = 0;
608     pixel_format request;
609     unsigned int double_buffer;
610     unsigned int accelerated = renderer.accelerated;
611
612     if (accelerated)
613     {
614         attribs[n++] = kCGLPFAAccelerated;
615         attribs[n++] = kCGLPFANoRecovery;
616     }
617
618     n_stack[++n_stack_idx] = n;
619     for (double_buffer = 0; double_buffer <= 1; double_buffer++)
620     {
621         unsigned int aux;
622
623         n = n_stack[n_stack_idx];
624
625         if ((!double_buffer && !(renderer.buffer_modes & kCGLSingleBufferBit)) ||
626             (double_buffer && !(renderer.buffer_modes & kCGLDoubleBufferBit)))
627             continue;
628
629         if (double_buffer)
630             attribs[n++] = kCGLPFADoubleBuffer;
631         memset(&request, 0, sizeof(request));
632         request.accelerated = accelerated;
633         request.double_buffer = double_buffer;
634
635         /* Don't bother with in-between aux buffers values: either 0 or max. */
636         n_stack[++n_stack_idx] = n;
637         for (aux = 0; aux <= renderer.max_aux_buffers; aux += renderer.max_aux_buffers)
638         {
639             unsigned int color_mode;
640
641             n = n_stack[n_stack_idx];
642
643             attribs[n++] = kCGLPFAAuxBuffers;
644             attribs[n++] = aux;
645             request.aux_buffers = aux;
646
647             n_stack[++n_stack_idx] = n;
648             for (color_mode = 0; color_mode < sizeof(color_modes)/sizeof(color_modes[0]); color_mode++)
649             {
650                 unsigned int depth_mode;
651
652                 n = n_stack[n_stack_idx];
653
654                 if (!(renderer.color_modes & color_modes[color_mode].mode))
655                     continue;
656
657                 attribs[n++] = kCGLPFAColorSize;
658                 attribs[n++] = color_modes[color_mode].color_bits;
659                 attribs[n++] = kCGLPFAAlphaSize;
660                 attribs[n++] = color_modes[color_mode].alpha_bits;
661                 if (color_modes[color_mode].is_float)
662                     attribs[n++] = kCGLPFAColorFloat;
663                 request.color_mode = color_mode;
664
665                 n_stack[++n_stack_idx] = n;
666                 for (depth_mode = 0; depth_mode < sizeof(depth_stencil_modes)/sizeof(depth_stencil_modes[0]); depth_mode++)
667                 {
668                     unsigned int stencil_mode;
669
670                     n = n_stack[n_stack_idx];
671
672                     if (!(renderer.depth_modes & depth_stencil_modes[depth_mode].mode))
673                         continue;
674
675                     attribs[n++] = kCGLPFADepthSize;
676                     attribs[n++] = depth_stencil_modes[depth_mode].bits;
677                     request.depth_bits = depth_stencil_modes[depth_mode].bits;
678
679                     n_stack[++n_stack_idx] = n;
680                     for (stencil_mode = 0; stencil_mode < sizeof(depth_stencil_modes)/sizeof(depth_stencil_modes[0]); stencil_mode++)
681                     {
682                         unsigned int stereo;
683
684                         n = n_stack[n_stack_idx];
685
686                         if (!(renderer.stencil_modes & depth_stencil_modes[stencil_mode].mode))
687                             continue;
688                         if (accelerated && depth_stencil_modes[depth_mode].bits != 24 && stencil_mode > 0)
689                             continue;
690
691                         attribs[n++] = kCGLPFAStencilSize;
692                         attribs[n++] = depth_stencil_modes[stencil_mode].bits;
693                         request.stencil_bits = depth_stencil_modes[stencil_mode].bits;
694
695                         /* FIXME: Could trim search space a bit here depending on GPU.
696                                   For ATI Radeon HD 4850, kCGLRGBA16161616Bit implies stereo-capable. */
697                         n_stack[++n_stack_idx] = n;
698                         for (stereo = 0; stereo <= 1; stereo++)
699                         {
700                             int accum_mode;
701
702                             n = n_stack[n_stack_idx];
703
704                             if ((!stereo && !(renderer.buffer_modes & kCGLMonoscopicBit)) ||
705                                 (stereo && !(renderer.buffer_modes & kCGLStereoscopicBit)))
706                                 continue;
707
708                             if (stereo)
709                                 attribs[n++] = kCGLPFAStereo;
710                             request.stereo = stereo;
711
712                             /* Starts at -1 for a 0 accum size */
713                             n_stack[++n_stack_idx] = n;
714                             for (accum_mode = -1; accum_mode < (int)(sizeof(color_modes)/sizeof(color_modes[0])); accum_mode++)
715                             {
716                                 unsigned int target_pass;
717
718                                 n = n_stack[n_stack_idx];
719
720                                 if (accum_mode >= 0)
721                                 {
722                                     if (!(renderer.accum_modes & color_modes[accum_mode].mode))
723                                         continue;
724
725                                     attribs[n++] = kCGLPFAAccumSize;
726                                     attribs[n++] = color_modes[accum_mode].color_bits;
727                                     request.accum_mode = accum_mode + 1;
728                                 }
729                                 else
730                                     request.accum_mode = 0;
731
732                                 /* Targets to request are:
733                                         accelerated: window OR window + pbuffer
734                                         software: window + pbuffer */
735                                 n_stack[++n_stack_idx] = n;
736                                 for (target_pass = 0; target_pass <= accelerated; target_pass++)
737                                 {
738                                     unsigned int samples, max_samples;
739
740                                     n = n_stack[n_stack_idx];
741
742                                     attribs[n++] = kCGLPFAWindow;
743                                     request.window = 1;
744
745                                     if (!accelerated || target_pass > 0)
746                                     {
747                                         attribs[n++] = kCGLPFAPBuffer;
748                                         request.pbuffer = 1;
749                                     }
750                                     else
751                                         request.pbuffer = 0;
752
753                                     /* FIXME: Could trim search space a bit here depending on GPU.
754                                               For Nvidia GeForce 8800 GT, limited to 4 samples for color_bits >= 128.
755                                               For ATI Radeon HD 4850, can't multi-sample for color_bits >= 64 or pbuffer. */
756                                     n_stack[++n_stack_idx] = n;
757                                     max_samples = renderer.max_sample_buffers ? max(1, renderer.max_samples) : 1;
758                                     for (samples = 1; samples <= max_samples; samples *= 2)
759                                     {
760                                         unsigned int backing_store, min_backing_store, max_backing_store;
761
762                                         n = n_stack[n_stack_idx];
763
764                                         if (samples > 1)
765                                         {
766                                             attribs[n++] = kCGLPFASampleBuffers;
767                                             attribs[n++] = renderer.max_sample_buffers;
768                                             attribs[n++] = kCGLPFASamples;
769                                             attribs[n++] = samples;
770                                             request.sample_buffers = renderer.max_sample_buffers;
771                                             request.samples = samples;
772                                         }
773                                         else
774                                             request.sample_buffers = request.samples = 0;
775
776                                         if (renderer.backing_store && double_buffer)
777                                         {
778                                             /* The software renderer seems to always preserve the backing store, whether
779                                                we ask for it or not.  So don't bother not asking for it. */
780                                             min_backing_store = accelerated ? 0 : 1;
781                                             max_backing_store = 1;
782                                         }
783                                         else
784                                             min_backing_store = max_backing_store = 0;
785                                         n_stack[++n_stack_idx] = n;
786                                         for (backing_store = min_backing_store; backing_store <= max_backing_store; backing_store++)
787                                         {
788                                             CGLPixelFormatObj pix;
789                                             GLint virtualScreens;
790                                             CGLError err;
791
792                                             n = n_stack[n_stack_idx];
793
794                                             if (backing_store)
795                                                 attribs[n++] = kCGLPFABackingStore;
796                                             request.backing_store = backing_store;
797
798                                             attribs[n] = 0;
799
800                                             err = CGLChoosePixelFormat(attribs, &pix, &virtualScreens);
801                                             if (err == kCGLNoError && pix)
802                                             {
803                                                 pixel_format pf;
804                                                 GLint value, color_size, alpha_size, color_float;
805                                                 UInt64 pf_code;
806                                                 CFNumberRef code_object;
807                                                 BOOL dupe;
808
809                                                 memset(&pf, 0, sizeof(pf));
810
811                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAAccelerated, &value) == kCGLNoError)
812                                                     pf.accelerated = value;
813                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAAuxBuffers, &value) == kCGLNoError)
814                                                     pf.aux_buffers = value;
815                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFADepthSize, &value) == kCGLNoError)
816                                                     pf.depth_bits = value;
817                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFADoubleBuffer, &value) == kCGLNoError)
818                                                     pf.double_buffer = value;
819                                                 if (pf.double_buffer &&
820                                                     CGLDescribePixelFormat(pix, 0, kCGLPFABackingStore, &value) == kCGLNoError)
821                                                     pf.backing_store = value;
822                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAPBuffer, &value) == kCGLNoError)
823                                                     pf.pbuffer = value;
824                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFASampleBuffers, &value) == kCGLNoError)
825                                                     pf.sample_buffers = value;
826                                                 if (pf.sample_buffers &&
827                                                     CGLDescribePixelFormat(pix, 0, kCGLPFASamples, &value) == kCGLNoError)
828                                                     pf.samples = value;
829                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAStencilSize, &value) == kCGLNoError)
830                                                     pf.stencil_bits = value;
831                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAStereo, &value) == kCGLNoError)
832                                                     pf.stereo = value;
833                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAWindow, &value) == kCGLNoError)
834                                                     pf.window = value;
835
836                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAColorSize, &color_size) != kCGLNoError)
837                                                     color_size = 0;
838                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAAlphaSize, &alpha_size) != kCGLNoError)
839                                                     alpha_size = 0;
840                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAColorFloat, &color_float) != kCGLNoError)
841                                                     color_float = 0;
842                                                 pf.color_mode = best_color_mode(renderer.color_modes, color_size, alpha_size, color_float);
843
844                                                 if (CGLDescribePixelFormat(pix, 0, kCGLPFAAccumSize, &value) == kCGLNoError && value)
845                                                     pf.accum_mode = best_accum_mode(renderer.accum_modes, value) + 1;
846
847                                                 CGLReleasePixelFormat(pix);
848
849                                                 pf_code = code_for_pixel_format(&pf);
850
851                                                 code_object = CFNumberCreate(NULL, kCFNumberSInt64Type, &pf_code);
852                                                 if ((dupe = CFSetContainsValue(pixel_format_set, code_object)))
853                                                     dupe_pixel_formats++;
854                                                 else
855                                                 {
856                                                     CFSetAddValue(pixel_format_set, code_object);
857                                                     CFArrayAppendValue(pixel_format_array, code_object);
858                                                     new_pixel_formats++;
859                                                 }
860                                                 CFRelease(code_object);
861
862                                                 if (pf_code == code_for_pixel_format(&request))
863                                                     TRACE("%s%s\n", debugstr_pf(&pf), dupe ? " (duplicate)" : "");
864                                                 else
865                                                 {
866                                                     TRACE("%s remapped from %s%s\n", debugstr_pf(&pf), debugstr_pf(&request),
867                                                           dupe ? " (duplicate)" : "");
868                                                 }
869                                             }
870                                             else
871                                             {
872                                                 failed_pixel_formats++;
873                                                 TRACE("%s failed request err %d %s\n", debugstr_pf(&request), err, err ? CGLErrorString(err) : "");
874                                             }
875
876                                             tried_pixel_formats++;
877                                         }
878
879                                         n_stack_idx--;
880                                     }
881
882                                     n_stack_idx--;
883                                 }
884
885                                 n_stack_idx--;
886                             }
887
888                             n_stack_idx--;
889                         }
890
891                         n_stack_idx--;
892                     }
893
894                     n_stack_idx--;
895                 }
896
897                 n_stack_idx--;
898             }
899
900             n_stack_idx--;
901         }
902
903         n_stack_idx--;
904     }
905
906     n_stack_idx--;
907
908     TRACE("Number of pixel format attribute combinations: %u\n", tried_pixel_formats);
909     TRACE(" Number which failed to choose a pixel format: %u\n", failed_pixel_formats);
910     TRACE("   Number which chose redundant pixel formats: %u\n", dupe_pixel_formats);
911     TRACE("Number of new pixel formats for this renderer: %u\n", new_pixel_formats);
912 }
913
914
915 /* The docs for WGL_ARB_pixel_format say:
916     Indices are assigned to pixel formats in the following order:
917     1. Accelerated pixel formats that are displayable
918     2. Accelerated pixel formats that are displayable and which have
919        extended attributes
920     3. Generic pixel formats
921     4. Accelerated pixel formats that are non displayable
922  */
923 static int pixel_format_category(pixel_format pf)
924 {
925     /* non-displayable */
926     if (!pf.window)
927         return 4;
928
929     /* non-accelerated a.k.a. software a.k.a. generic */
930     if (!pf.accelerated)
931         return 3;
932
933     /* extended attributes that can't be represented in PIXELFORMATDESCRIPTOR */
934     if (color_modes[pf.color_mode].is_float)
935         return 2;
936
937     /* accelerated, displayable, no extended attributes */
938     return 1;
939 }
940
941
942 static CFComparisonResult pixel_format_comparator(const void *val1, const void *val2, void *context)
943 {
944     CFNumberRef number1 = val1;
945     CFNumberRef number2 = val2;
946     UInt64 code1, code2;
947     pixel_format pf1, pf2;
948     int category1, category2;
949
950     CFNumberGetValue(number1, kCFNumberLongLongType, &code1);
951     CFNumberGetValue(number2, kCFNumberLongLongType, &code2);
952     pf1 = pixel_format_for_code(code1);
953     pf2 = pixel_format_for_code(code2);
954     category1 = pixel_format_category(pf1);
955     category2 = pixel_format_category(pf2);
956
957     if (category1 < category2)
958         return kCFCompareLessThan;
959     if (category1 > category2)
960         return kCFCompareGreaterThan;
961
962     /* Within a category, sort the "best" formats toward the front since that's
963        what wglChoosePixelFormatARB() has to do.  The ordering implemented here
964        matches at least one Windows 7 machine's behavior.
965      */
966     /* Accelerated before unaccelerated. */
967     if (pf1.accelerated && !pf2.accelerated)
968         return kCFCompareLessThan;
969     if (!pf1.accelerated && pf2.accelerated)
970         return kCFCompareGreaterThan;
971
972     /* Explicit color mode ordering. */
973     if (color_modes[pf1.color_mode].color_ordering < color_modes[pf2.color_mode].color_ordering)
974         return kCFCompareLessThan;
975     if (color_modes[pf1.color_mode].color_ordering > color_modes[pf2.color_mode].color_ordering)
976         return kCFCompareGreaterThan;
977
978     /* Non-pbuffer-capable before pbuffer-capable. */
979     if (!pf1.pbuffer && pf2.pbuffer)
980         return kCFCompareLessThan;
981     if (pf1.pbuffer && !pf2.pbuffer)
982         return kCFCompareGreaterThan;
983
984     /* Fewer samples before more samples. */
985     if (pf1.samples < pf2.samples)
986         return kCFCompareLessThan;
987     if (pf1.samples > pf2.samples)
988         return kCFCompareGreaterThan;
989
990     /* Monoscopic before stereoscopic.  (This is a guess.) */
991     if (!pf1.stereo && pf2.stereo)
992         return kCFCompareLessThan;
993     if (pf1.stereo && !pf2.stereo)
994         return kCFCompareGreaterThan;
995
996     /* Single buffered before double buffered. */
997     if (!pf1.double_buffer && pf2.double_buffer)
998         return kCFCompareLessThan;
999     if (pf1.double_buffer && !pf2.double_buffer)
1000         return kCFCompareGreaterThan;
1001
1002     /* Possibly-optimized double buffering before backing-store-preserving
1003        double buffering. */
1004     if (!pf1.backing_store && pf2.backing_store)
1005         return kCFCompareLessThan;
1006     if (pf1.backing_store && !pf2.backing_store)
1007         return kCFCompareGreaterThan;
1008
1009     /* Bigger depth buffer before smaller depth buffer. */
1010     if (pf1.depth_bits > pf2.depth_bits)
1011         return kCFCompareLessThan;
1012     if (pf1.depth_bits < pf2.depth_bits)
1013         return kCFCompareGreaterThan;
1014
1015     /* Smaller stencil buffer before bigger stencil buffer. */
1016     if (pf1.stencil_bits < pf2.stencil_bits)
1017         return kCFCompareLessThan;
1018     if (pf1.stencil_bits > pf2.stencil_bits)
1019         return kCFCompareGreaterThan;
1020
1021     /* Smaller alpha bits before larger alpha bits. */
1022     if (color_modes[pf1.color_mode].alpha_bits < color_modes[pf2.color_mode].alpha_bits)
1023         return kCFCompareLessThan;
1024     if (color_modes[pf1.color_mode].alpha_bits > color_modes[pf2.color_mode].alpha_bits)
1025         return kCFCompareGreaterThan;
1026
1027     /* Smaller accum buffer before larger accum buffer.  (This is a guess.) */
1028     if (pf1.accum_mode)
1029     {
1030         if (pf2.accum_mode)
1031         {
1032             if (color_modes[pf1.accum_mode - 1].color_bits - color_modes[pf1.accum_mode - 1].alpha_bits <
1033                 color_modes[pf2.accum_mode - 1].color_bits - color_modes[pf2.accum_mode - 1].alpha_bits)
1034                 return kCFCompareLessThan;
1035             if (color_modes[pf1.accum_mode - 1].color_bits - color_modes[pf1.accum_mode - 1].alpha_bits >
1036                 color_modes[pf2.accum_mode - 1].color_bits - color_modes[pf2.accum_mode - 1].alpha_bits)
1037                 return kCFCompareGreaterThan;
1038
1039             if (color_modes[pf1.accum_mode - 1].bits_per_pixel < color_modes[pf2.accum_mode - 1].bits_per_pixel)
1040                 return kCFCompareLessThan;
1041             if (color_modes[pf1.accum_mode - 1].bits_per_pixel > color_modes[pf2.accum_mode - 1].bits_per_pixel)
1042                 return kCFCompareGreaterThan;
1043
1044             if (color_modes[pf1.accum_mode - 1].alpha_bits < color_modes[pf2.accum_mode - 1].alpha_bits)
1045                 return kCFCompareLessThan;
1046             if (color_modes[pf1.accum_mode - 1].alpha_bits > color_modes[pf2.accum_mode - 1].alpha_bits)
1047                 return kCFCompareGreaterThan;
1048         }
1049         else
1050             return kCFCompareGreaterThan;
1051     }
1052     else if (pf2.accum_mode)
1053         return kCFCompareLessThan;
1054
1055     /* Fewer auxiliary buffers before more auxiliary buffers.  (This is a guess.) */
1056     if (pf1.aux_buffers < pf2.aux_buffers)
1057         return kCFCompareLessThan;
1058     if (pf1.aux_buffers > pf2.aux_buffers)
1059         return kCFCompareGreaterThan;
1060
1061     /* If we get here, arbitrarily sort based on code. */
1062     if (code1 < code2)
1063         return kCFCompareLessThan;
1064     if (code1 > code2)
1065         return kCFCompareGreaterThan;
1066     return kCFCompareEqualTo;
1067 }
1068
1069
1070 static BOOL init_pixel_formats(void)
1071 {
1072     BOOL ret = FALSE;
1073     CGLRendererInfoObj renderer_info;
1074     GLint rendererCount;
1075     CGLError err;
1076     CFMutableSetRef pixel_format_set;
1077     CFMutableArrayRef pixel_format_array;
1078     int i;
1079     CFRange range;
1080
1081     TRACE("()\n");
1082
1083     assert(sizeof(((pixel_format_or_code*)0)->format) <= sizeof(((pixel_format_or_code*)0)->code));
1084
1085     err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID()), &renderer_info, &rendererCount);
1086     if (err)
1087     {
1088         WARN("CGLQueryRendererInfo failed (%d) %s\n", err, CGLErrorString(err));
1089         return FALSE;
1090     }
1091
1092     pixel_format_set = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
1093     if (!pixel_format_set)
1094     {
1095         WARN("CFSetCreateMutable failed\n");
1096         CGLDestroyRendererInfo(renderer_info);
1097         return FALSE;
1098     }
1099
1100     pixel_format_array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1101     if (!pixel_format_array)
1102     {
1103         WARN("CFArrayCreateMutable failed\n");
1104         CFRelease(pixel_format_set);
1105         CGLDestroyRendererInfo(renderer_info);
1106         return FALSE;
1107     }
1108
1109     for (i = 0; i < rendererCount; i++)
1110     {
1111         renderer_properties renderer;
1112
1113         get_renderer_properties(renderer_info, i, &renderer);
1114         if (TRACE_ON(wgl))
1115         {
1116             TRACE("renderer_properties %d:\n", i);
1117             dump_renderer(&renderer);
1118         }
1119
1120         enum_renderer_pixel_formats(renderer, pixel_format_array, pixel_format_set);
1121     }
1122
1123     CFRelease(pixel_format_set);
1124     CGLDestroyRendererInfo(renderer_info);
1125
1126     range = CFRangeMake(0, CFArrayGetCount(pixel_format_array));
1127     if (range.length)
1128     {
1129         pixel_formats = HeapAlloc(GetProcessHeap(), 0, range.length * sizeof(*pixel_formats));
1130         if (pixel_formats)
1131         {
1132             CFArraySortValues(pixel_format_array, range, pixel_format_comparator, NULL);
1133             for (i = 0; i < range.length; i++)
1134             {
1135                 CFNumberRef number = CFArrayGetValueAtIndex(pixel_format_array, i);
1136                 UInt64 code;
1137
1138                 CFNumberGetValue(number, kCFNumberLongLongType, &code);
1139                 pixel_formats[i] = pixel_format_for_code(code);
1140                 if (pixel_formats[i].window)
1141                     nb_displayable_formats++;
1142             }
1143
1144             nb_formats = range.length;
1145             TRACE("Total number of unique pixel formats: %d\n", nb_formats);
1146             ret = TRUE;
1147         }
1148         else
1149             WARN("failed to allocate pixel format list\n");
1150     }
1151     else
1152         WARN("got no pixel formats\n");
1153
1154     CFRelease(pixel_format_array);
1155     return ret;
1156 }
1157
1158
1159 static inline BOOL is_valid_pixel_format(int format)
1160 {
1161     return format > 0 && format <= nb_formats;
1162 }
1163
1164
1165 static inline BOOL is_displayable_pixel_format(int format)
1166 {
1167     return format > 0 && format <= nb_displayable_formats;
1168 }
1169
1170
1171 static const pixel_format *get_pixel_format(int format, BOOL allow_nondisplayable)
1172 {
1173     /* Check if the pixel format is valid. Note that it is legal to pass an invalid
1174      * format in case of probing the number of pixel formats.
1175      */
1176     if (is_valid_pixel_format(format) && (is_displayable_pixel_format(format) || allow_nondisplayable))
1177     {
1178         TRACE("Returning format %d\n", format);
1179         return &pixel_formats[format - 1];
1180     }
1181     return NULL;
1182 }
1183
1184
1185 static BOOL init_gl_info(void)
1186 {
1187     CGDirectDisplayID display = CGMainDisplayID();
1188     CGOpenGLDisplayMask displayMask = CGDisplayIDToOpenGLDisplayMask(display);
1189     CGLPixelFormatAttribute attribs[] = {
1190         kCGLPFADisplayMask, displayMask,
1191         0
1192     };
1193     CGLPixelFormatObj pix;
1194     GLint virtualScreens;
1195     CGLError err;
1196     CGLContextObj context;
1197     CGLContextObj old_context = CGLGetCurrentContext();
1198     const char *str;
1199
1200     err = CGLChoosePixelFormat(attribs, &pix, &virtualScreens);
1201     if (err != kCGLNoError || !pix)
1202     {
1203         WARN("CGLChoosePixelFormat() failed with error %d %s\n", err, CGLErrorString(err));
1204         return FALSE;
1205     }
1206
1207     err = CGLCreateContext(pix, NULL, &context);
1208     CGLReleasePixelFormat(pix);
1209     if (err != kCGLNoError || !context)
1210     {
1211         WARN("CGLCreateContext() failed with error %d %s\n", err, CGLErrorString(err));
1212         return FALSE;
1213     }
1214
1215     err = CGLSetCurrentContext(context);
1216     if (err != kCGLNoError)
1217     {
1218         WARN("CGLSetCurrentContext() failed with error %d %s\n", err, CGLErrorString(err));
1219         CGLReleaseContext(context);
1220         return FALSE;
1221     }
1222
1223     str = (const char*)opengl_funcs.gl.p_glGetString(GL_VERSION);
1224     gl_info.glVersion = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
1225     strcpy(gl_info.glVersion, str);
1226     str = (const char*)opengl_funcs.gl.p_glGetString(GL_EXTENSIONS);
1227     gl_info.glExtensions = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1);
1228     strcpy(gl_info.glExtensions, str);
1229
1230     opengl_funcs.gl.p_glGetIntegerv(GL_MAX_VIEWPORT_DIMS, gl_info.max_viewport_dims);
1231
1232     TRACE("GL version   : %s\n", gl_info.glVersion);
1233     TRACE("GL renderer  : %s\n", opengl_funcs.gl.p_glGetString(GL_RENDERER));
1234
1235     CGLSetCurrentContext(old_context);
1236     CGLReleaseContext(context);
1237
1238     return TRUE;
1239 }
1240
1241
1242 static BOOL get_gl_view_window_rect(struct macdrv_win_data *data, macdrv_window *window, RECT *rect)
1243 {
1244     BOOL ret = TRUE;
1245     *rect = data->client_rect;
1246
1247     if (data->cocoa_window)
1248     {
1249         if (window)
1250             *window = data->cocoa_window;
1251         OffsetRect(rect, -data->whole_rect.left, -data->whole_rect.top);
1252     }
1253     else
1254     {
1255         HWND top = GetAncestor(data->hwnd, GA_ROOT);
1256         HWND parent = GetAncestor(data->hwnd, GA_PARENT);
1257         struct macdrv_win_data *top_data = get_win_data(top);
1258
1259         if (top_data && top_data->cocoa_window)
1260         {
1261             if (window)
1262                 *window = top_data->cocoa_window;
1263             MapWindowPoints(parent, 0, (POINT*)rect, 2);
1264             OffsetRect(rect, -top_data->whole_rect.left, -top_data->whole_rect.top);
1265         }
1266         else
1267             ret = FALSE;
1268
1269         release_win_data(top_data);
1270     }
1271
1272     return ret;
1273 }
1274
1275
1276 /***********************************************************************
1277  *              set_win_format
1278  */
1279 static BOOL set_win_format(struct macdrv_win_data *data, int format)
1280 {
1281     macdrv_window cocoa_window;
1282
1283     TRACE("hwnd %p format %d\n", data->hwnd, format);
1284
1285     if (!get_gl_view_window_rect(data, &cocoa_window, &data->gl_rect))
1286     {
1287         ERR("no top-level parent with Cocoa window in this process\n");
1288         return FALSE;
1289     }
1290
1291     if (data->gl_view) macdrv_dispose_view(data->gl_view);
1292     data->gl_view = macdrv_create_view(cocoa_window, cgrect_from_rect(data->gl_rect));
1293
1294     if (!data->gl_view)
1295     {
1296         WARN("failed to create GL view for window %p rect %s\n", cocoa_window, wine_dbgstr_rect(&data->gl_rect));
1297         return FALSE;
1298     }
1299
1300     TRACE("created GL view %p in window %p at %s\n", data->gl_view, cocoa_window,
1301           wine_dbgstr_rect(&data->gl_rect));
1302
1303     data->pixel_format = format;
1304
1305     return TRUE;
1306 }
1307
1308
1309 /**********************************************************************
1310  *              set_pixel_format
1311  *
1312  * Implementation of wglSetPixelFormat and wglSetPixelFormatWINE.
1313  */
1314 static BOOL set_pixel_format(HDC hdc, int fmt, BOOL allow_reset)
1315 {
1316     struct macdrv_win_data *data;
1317     const pixel_format *pf;
1318     HWND hwnd = WindowFromDC(hdc);
1319     BOOL ret = FALSE;
1320
1321     TRACE("hdc %p format %d\n", hdc, fmt);
1322
1323     if (!hwnd || hwnd == GetDesktopWindow())
1324     {
1325         WARN("not a proper window DC %p/%p\n", hdc, hwnd);
1326         return FALSE;
1327     }
1328
1329     if (!(data = get_win_data(hwnd)))
1330     {
1331         FIXME("DC for window %p of other process: not implemented\n", hwnd);
1332         return FALSE;
1333     }
1334
1335     if (!allow_reset && data->pixel_format)  /* cannot change it if already set */
1336     {
1337         ret = (data->pixel_format == fmt);
1338         goto done;
1339     }
1340
1341     /* Check if fmt is in our list of supported formats to see if it is supported. */
1342     pf = get_pixel_format(fmt, FALSE /* non-displayable */);
1343     if (!pf)
1344     {
1345         ERR("Invalid pixel format: %d\n", fmt);
1346         goto done;
1347     }
1348
1349     if (!pf->window)
1350     {
1351         WARN("Pixel format %d is not compatible for window rendering\n", fmt);
1352         goto done;
1353     }
1354
1355     if (!set_win_format(data, fmt))
1356     {
1357         WARN("Couldn't set format of the window, returning failure\n");
1358         goto done;
1359     }
1360
1361     TRACE("pixel format:\n");
1362     TRACE("           window: %u\n", (unsigned int)pf->window);
1363     TRACE("          pBuffer: %u\n", (unsigned int)pf->pbuffer);
1364     TRACE("      accelerated: %u\n", (unsigned int)pf->accelerated);
1365     TRACE("       color bits: %u%s\n", (unsigned int)color_modes[pf->color_mode].color_bits, (color_modes[pf->color_mode].is_float ? " float" : ""));
1366     TRACE("       alpha bits: %u\n", (unsigned int)color_modes[pf->color_mode].alpha_bits);
1367     TRACE("      aux buffers: %u\n", (unsigned int)pf->aux_buffers);
1368     TRACE("       depth bits: %u\n", (unsigned int)pf->depth_bits);
1369     TRACE("     stencil bits: %u\n", (unsigned int)pf->stencil_bits);
1370     TRACE("       accum bits: %u\n", (unsigned int)pf->accum_mode ? color_modes[pf->accum_mode - 1].color_bits : 0);
1371     TRACE("    double_buffer: %u\n", (unsigned int)pf->double_buffer);
1372     TRACE("           stereo: %u\n", (unsigned int)pf->stereo);
1373     TRACE("   sample_buffers: %u\n", (unsigned int)pf->sample_buffers);
1374     TRACE("          samples: %u\n", (unsigned int)pf->samples);
1375     TRACE("    backing_store: %u\n", (unsigned int)pf->backing_store);
1376     ret = TRUE;
1377
1378 done:
1379     release_win_data(data);
1380     if (ret) __wine_set_pixel_format(hwnd, fmt);
1381     return ret;
1382 }
1383
1384
1385 /**********************************************************************
1386  *              set_gl_view_parent
1387  */
1388 void set_gl_view_parent(HWND hwnd, HWND parent)
1389 {
1390     struct macdrv_win_data *data;
1391
1392     if (!(data = get_win_data(hwnd))) return;
1393
1394     if (data->gl_view)
1395     {
1396         macdrv_window cocoa_window;
1397
1398         TRACE("moving GL view %p to parent %p\n", data->gl_view, parent);
1399
1400         if (!get_gl_view_window_rect(data, &cocoa_window, &data->gl_rect))
1401         {
1402             ERR("no top-level parent with Cocoa window in this process\n");
1403             macdrv_dispose_view(data->gl_view);
1404             data->gl_view = NULL;
1405             release_win_data(data);
1406             __wine_set_pixel_format( hwnd, 0 );
1407             return;
1408         }
1409
1410         macdrv_set_view_window_and_frame(data->gl_view, cocoa_window, cgrect_from_rect(data->gl_rect));
1411     }
1412
1413     release_win_data(data);
1414 }
1415
1416
1417 /**********************************************************************
1418  *              make_context_current
1419  */
1420 static void make_context_current(struct wgl_context *context, BOOL read)
1421 {
1422     macdrv_view view;
1423     struct wgl_pbuffer *pbuffer;
1424
1425     if (read)
1426     {
1427         view = context->read_view;
1428         pbuffer = context->read_pbuffer;
1429     }
1430     else
1431     {
1432         view = context->draw_view;
1433         pbuffer = context->draw_pbuffer;
1434     }
1435
1436     if (view || !pbuffer)
1437         macdrv_make_context_current(context->context, view);
1438     else
1439     {
1440         CGLSetPBuffer(context->cglcontext, pbuffer->pbuffer, pbuffer->face,
1441                       pbuffer->level, 0);
1442         CGLSetCurrentContext(context->cglcontext);
1443     }
1444 }
1445
1446
1447 /**********************************************************************
1448  *              macdrv_glCopyColorTable
1449  *
1450  * Hook into glCopyColorTable as part of the implementation of
1451  * wglMakeContextCurrentARB.  If the context has a separate readable,
1452  * temporarily make that current, do glCopyColorTable, and then set it
1453  * back to the drawable.  This is modeled after what Mesa GLX's Apple
1454  * implementation does.
1455  */
1456 static void macdrv_glCopyColorTable(GLenum target, GLenum internalformat, GLint x, GLint y,
1457                                     GLsizei width)
1458 {
1459     struct wgl_context *context = NtCurrentTeb()->glContext;
1460
1461     if (context->read_view || context->read_pbuffer)
1462         make_context_current(context, TRUE);
1463
1464     pglCopyColorTable(target, internalformat, x, y, width);
1465
1466     if (context->read_view || context->read_pbuffer)
1467         make_context_current(context, FALSE);
1468 }
1469
1470
1471 /**********************************************************************
1472  *              macdrv_glCopyPixels
1473  *
1474  * Hook into glCopyPixels as part of the implementation of
1475  * wglMakeContextCurrentARB.  If the context has a separate readable,
1476  * temporarily make that current, do glCopyPixels, and then set it back
1477  * to the drawable.  This is modeled after what Mesa GLX's Apple
1478  * implementation does.
1479  */
1480 static void macdrv_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
1481 {
1482     struct wgl_context *context = NtCurrentTeb()->glContext;
1483
1484     if (context->read_view || context->read_pbuffer)
1485         make_context_current(context, TRUE);
1486
1487     pglCopyPixels(x, y, width, height, type);
1488
1489     if (context->read_view || context->read_pbuffer)
1490         make_context_current(context, FALSE);
1491 }
1492
1493
1494 /**********************************************************************
1495  *              macdrv_glReadPixels
1496  *
1497  * Hook into glReadPixels as part of the implementation of
1498  * wglMakeContextCurrentARB.  If the context has a separate readable,
1499  * temporarily make that current, do glReadPixels, and then set it back
1500  * to the drawable.  This is modeled after what Mesa GLX's Apple
1501  * implementation does.
1502  */
1503 static void macdrv_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1504                                 GLenum format, GLenum type, void *pixels)
1505 {
1506     struct wgl_context *context = NtCurrentTeb()->glContext;
1507
1508     if (context->read_view || context->read_pbuffer)
1509         make_context_current(context, TRUE);
1510
1511     pglReadPixels(x, y, width, height, format, type, pixels);
1512
1513     if (context->read_view || context->read_pbuffer)
1514         make_context_current(context, FALSE);
1515 }
1516
1517
1518 /**********************************************************************
1519  *              macdrv_glViewport
1520  *
1521  * Hook into glViewport as an opportunity to update the OpenGL context
1522  * if necessary.  This is modeled after what Mesa GLX's Apple
1523  * implementation does.
1524  */
1525 static void macdrv_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
1526 {
1527     struct wgl_context *context = NtCurrentTeb()->glContext;
1528
1529     macdrv_update_opengl_context(context->context);
1530     pglViewport(x, y, width, height);
1531 }
1532
1533
1534 /***********************************************************************
1535  *              macdrv_wglBindTexImageARB
1536  *
1537  * WGL_ARB_render_texture: wglBindTexImageARB
1538  */
1539 static BOOL macdrv_wglBindTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer)
1540 {
1541     struct wgl_context *context = NtCurrentTeb()->glContext;
1542     GLenum source;
1543     CGLError err;
1544
1545     TRACE("pbuffer %p iBuffer 0x%x\n", pbuffer, iBuffer);
1546
1547     if (pbuffer->no_texture)
1548     {
1549         SetLastError(ERROR_INVALID_OPERATION);
1550         return GL_FALSE;
1551     }
1552
1553     if (!context->draw_view && context->draw_pbuffer == pbuffer)
1554         opengl_funcs.gl.p_glFlush();
1555
1556     switch (iBuffer)
1557     {
1558         case WGL_FRONT_LEFT_ARB:
1559             if (pixel_formats[pbuffer->format].stereo)
1560                 source = GL_FRONT_LEFT;
1561             else
1562                 source = GL_FRONT;
1563             break;
1564         case WGL_FRONT_RIGHT_ARB:
1565             source = GL_FRONT_RIGHT;
1566             break;
1567         case WGL_BACK_LEFT_ARB:
1568             if (pixel_formats[pbuffer->format].stereo)
1569                 source = GL_BACK_LEFT;
1570             else
1571                 source = GL_BACK;
1572             break;
1573         case WGL_BACK_RIGHT_ARB:
1574             source = GL_BACK_RIGHT;
1575             break;
1576         case WGL_AUX0_ARB: source = GL_AUX0; break;
1577         case WGL_AUX1_ARB: source = GL_AUX1; break;
1578         case WGL_AUX2_ARB: source = GL_AUX2; break;
1579         case WGL_AUX3_ARB: source = GL_AUX3; break;
1580
1581         case WGL_AUX4_ARB:
1582         case WGL_AUX5_ARB:
1583         case WGL_AUX6_ARB:
1584         case WGL_AUX7_ARB:
1585         case WGL_AUX8_ARB:
1586         case WGL_AUX9_ARB:
1587             FIXME("unsupported source buffer 0x%x\n", iBuffer);
1588             SetLastError(ERROR_INVALID_DATA);
1589             return GL_FALSE;
1590
1591         default:
1592             WARN("unknown source buffer 0x%x\n", iBuffer);
1593             SetLastError(ERROR_INVALID_DATA);
1594             return GL_FALSE;
1595     }
1596
1597     err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, source);
1598     if (err != kCGLNoError)
1599     {
1600         WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err));
1601         SetLastError(ERROR_INVALID_OPERATION);
1602         return GL_FALSE;
1603     }
1604
1605     return GL_TRUE;
1606 }
1607
1608
1609 /***********************************************************************
1610  *              macdrv_wglChoosePixelFormatARB
1611  *
1612  * WGL_ARB_pixel_format: wglChoosePixelFormatARB
1613  */
1614 static BOOL macdrv_wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList,
1615                                            const FLOAT *pfAttribFList, UINT nMaxFormats,
1616                                            int *piFormats, UINT *nNumFormats)
1617 {
1618     pixel_format pf, valid;
1619     const int *iptr;
1620     int color_bits, red_bits, green_bits, blue_bits, alpha_bits;
1621     int accum_bits, accum_red_bits, accum_green_bits, accum_blue_bits, accum_alpha_bits;
1622     int float_color;
1623     BOOL srgb;
1624     int i, found = 0;
1625
1626     TRACE("hdc %p piAttribIList %p pfAttribFList %p nMaxFormats %u piFormats %p nNumFormats %p\n",
1627           hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
1628     if (pfAttribFList)
1629         FIXME("unused pfAttribFList\n");
1630
1631     memset(&pf, 0, sizeof(pf));
1632     memset(&valid, 0, sizeof(valid));
1633     color_bits = red_bits = green_bits = blue_bits = alpha_bits = 0;
1634     accum_bits = accum_red_bits = accum_green_bits = accum_blue_bits = accum_alpha_bits = 0;
1635     float_color = -1;
1636     srgb = FALSE;
1637
1638     for (iptr = piAttribIList; iptr && *iptr; iptr += 2)
1639     {
1640         int attr = iptr[0];
1641         int value = iptr[1];
1642
1643         TRACE("%s\n", debugstr_attrib(attr, value));
1644
1645         switch (attr)
1646         {
1647             case WGL_DRAW_TO_WINDOW_ARB:
1648                 if (valid.window && (!pf.window != !value)) goto cant_match;
1649                 pf.window = (value != 0);
1650                 valid.window = 1;
1651                 break;
1652
1653             case WGL_DRAW_TO_BITMAP_ARB:
1654                 goto cant_match;
1655
1656             case WGL_ACCELERATION_ARB:
1657                 if (value == WGL_FULL_ACCELERATION_ARB)
1658                     value = 1;
1659                 else if (value == WGL_NO_ACCELERATION_ARB)
1660                     value = 0;
1661                 else
1662                     goto cant_match;
1663                 if (valid.accelerated && pf.accelerated != value) goto cant_match;
1664                 pf.accelerated = value;
1665                 valid.accelerated = 1;
1666                 break;
1667
1668             case WGL_NEED_PALETTE_ARB:
1669             case WGL_NEED_SYSTEM_PALETTE_ARB:
1670             case WGL_SWAP_LAYER_BUFFERS_ARB:
1671                 if (value) goto cant_match;
1672                 break;
1673
1674             case WGL_SWAP_METHOD_ARB:
1675                 if (value == WGL_SWAP_COPY_ARB)
1676                     value = 1;
1677                 else if (value == WGL_SWAP_UNDEFINED_ARB)
1678                     value = 0;
1679                 else
1680                     goto cant_match;
1681                 if (valid.backing_store && pf.backing_store != value) goto cant_match;
1682                 if (valid.double_buffer && !pf.double_buffer && value) goto cant_match;
1683                 pf.backing_store = value;
1684                 valid.backing_store = 1;
1685                 break;
1686
1687             case WGL_NUMBER_OVERLAYS_ARB:
1688             case WGL_NUMBER_UNDERLAYS_ARB:
1689                 if (value) goto cant_match;
1690                 break;
1691
1692             case WGL_SHARE_DEPTH_ARB:
1693             case WGL_SHARE_STENCIL_ARB:
1694             case WGL_SHARE_ACCUM_ARB:
1695                 /* no effect */
1696                 break;
1697
1698             case WGL_SUPPORT_GDI_ARB:
1699                 if (value) goto cant_match;
1700                 break;
1701
1702             case WGL_SUPPORT_OPENGL_ARB:
1703                 if (!value) goto cant_match;
1704                 break;
1705
1706             case WGL_DOUBLE_BUFFER_ARB:
1707                 if (valid.double_buffer && (!pf.double_buffer != !value)) goto cant_match;
1708                 pf.double_buffer = (value != 0);
1709                 valid.double_buffer = 1;
1710                 if (valid.backing_store && pf.backing_store && !pf.double_buffer) goto cant_match;
1711                 break;
1712
1713             case WGL_STEREO_ARB:
1714                 if (valid.stereo && (!pf.stereo != !value)) goto cant_match;
1715                 pf.stereo = (value != 0);
1716                 valid.stereo = 1;
1717                 break;
1718
1719             case WGL_PIXEL_TYPE_ARB:
1720                 if (value == WGL_TYPE_RGBA_FLOAT_ARB)
1721                     value = 1;
1722                 else if (value == WGL_TYPE_RGBA_ARB)
1723                     value = 0;
1724                 else
1725                 {
1726                     /* Mac contexts don't support rendering to unsigned floating
1727                        point formats, even if GL_EXT_packed_float is supported.
1728                        So, WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT is not supported. */
1729                     goto cant_match;
1730                 }
1731                 if (float_color != -1 && float_color != value) goto cant_match;
1732                 if (srgb && value) goto cant_match;
1733                 float_color = value;
1734                 break;
1735
1736             case WGL_COLOR_BITS_ARB:
1737                 if (color_bits < value) color_bits = value;
1738                 break;
1739
1740             case WGL_RED_BITS_ARB:
1741                 if (srgb && value > 8) goto cant_match;
1742                 if (red_bits < value) red_bits = value;
1743                 break;
1744
1745             case WGL_GREEN_BITS_ARB:
1746                 if (srgb && value > 8) goto cant_match;
1747                 if (green_bits < value) green_bits = value;
1748                 break;
1749
1750             case WGL_BLUE_BITS_ARB:
1751                 if (srgb && value > 8) goto cant_match;
1752                 if (blue_bits < value) blue_bits = value;
1753                 break;
1754
1755             case WGL_ALPHA_BITS_ARB:
1756                 if (alpha_bits < value) alpha_bits = value;
1757                 break;
1758
1759             case WGL_ACCUM_BITS_ARB:
1760                 if (accum_bits < value) accum_bits = value;
1761                 break;
1762
1763             case WGL_ACCUM_RED_BITS_ARB:
1764                 if (accum_red_bits < value) accum_red_bits = value;
1765                 break;
1766
1767             case WGL_ACCUM_GREEN_BITS_ARB:
1768                 if (accum_green_bits < value) accum_green_bits = value;
1769                 break;
1770
1771             case WGL_ACCUM_BLUE_BITS_ARB:
1772                 if (accum_blue_bits < value) accum_blue_bits = value;
1773                 break;
1774
1775             case WGL_ACCUM_ALPHA_BITS_ARB:
1776                 if (accum_alpha_bits < value) accum_alpha_bits = value;
1777                 break;
1778
1779             case WGL_DEPTH_BITS_ARB:
1780                 if (value > 255) goto cant_match;
1781                 if (pf.depth_bits < value) pf.depth_bits = value;
1782                 break;
1783
1784             case WGL_STENCIL_BITS_ARB:
1785                 if (value > 255) goto cant_match;
1786                 if (pf.stencil_bits < value) pf.stencil_bits = value;
1787                 break;
1788
1789             case WGL_AUX_BUFFERS_ARB:
1790                 if (value > 7) goto cant_match;
1791                 if (pf.aux_buffers < value) pf.aux_buffers = value;
1792                 break;
1793
1794             case WGL_SAMPLE_BUFFERS_ARB:
1795                 if (value > 1) goto cant_match;
1796                 if (pf.sample_buffers < value) pf.sample_buffers = value;
1797                 break;
1798
1799             case WGL_SAMPLES_ARB:
1800                 if (value > 31) goto cant_match;
1801                 if (pf.samples < value) pf.samples = value;
1802                 break;
1803
1804             case WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB: /* a.k.a. WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT */
1805                 /* sRGB is only supported for 8-bit integer color components */
1806                 if (float_color >= 1 || red_bits > 8 || green_bits > 8 || blue_bits > 8)
1807                     goto cant_match;
1808                 srgb = TRUE;
1809                 break;
1810
1811             case WGL_NUMBER_PIXEL_FORMATS_ARB:
1812             case WGL_RED_SHIFT_ARB:
1813             case WGL_GREEN_SHIFT_ARB:
1814             case WGL_BLUE_SHIFT_ARB:
1815             case WGL_ALPHA_SHIFT_ARB:
1816             case WGL_TRANSPARENT_ARB:
1817             case WGL_TRANSPARENT_RED_VALUE_ARB:
1818             case WGL_TRANSPARENT_GREEN_VALUE_ARB:
1819             case WGL_TRANSPARENT_BLUE_VALUE_ARB:
1820             case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
1821             case WGL_TRANSPARENT_INDEX_VALUE_ARB:
1822                 /* ignored */
1823                 break;
1824
1825             case WGL_DRAW_TO_PBUFFER_ARB:
1826             case WGL_BIND_TO_TEXTURE_RGB_ARB:
1827             case WGL_BIND_TO_TEXTURE_RGBA_ARB:
1828             case WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV:
1829             case WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV:
1830                 if (valid.pbuffer && (!pf.pbuffer != !value)) goto cant_match;
1831                 pf.pbuffer = (value != 0);
1832                 valid.pbuffer = 1;
1833                 if ((attr == WGL_BIND_TO_TEXTURE_RGBA_ARB || attr == WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV) &&
1834                     !alpha_bits)
1835                     alpha_bits = 1;
1836                 break;
1837
1838             default:
1839                 WARN("invalid attribute %s\n", debugstr_attrib(attr, value));
1840                 return GL_FALSE;
1841         }
1842     }
1843
1844     TRACE("required: w/p/a %s/%s/%s col/r/g/b/a %d%s/%d/%d/%d/%d srgb %d ac %d/%d/%d/%d/%d dp/stn/ax/b/db/str %u/%u/%u/%s/%s/%s samp %u/%u\n",
1845           valid.window ? (pf.window ? "1" : "0") : "?",
1846           valid.pbuffer ? (pf.pbuffer ? "1" : "0") : "?",
1847           valid.accelerated ? (pf.accelerated ? "1" : "0") : "?",
1848           color_bits,
1849           float_color == -1 ? "?" : float_color ? "f" : "",
1850           red_bits,
1851           green_bits,
1852           blue_bits,
1853           alpha_bits,
1854           (int)srgb,
1855           accum_bits,
1856           accum_red_bits,
1857           accum_green_bits,
1858           accum_blue_bits,
1859           accum_alpha_bits,
1860           pf.depth_bits,
1861           pf.stencil_bits,
1862           pf.aux_buffers,
1863           valid.backing_store ? (pf.backing_store ? "1" : "0") : "?",
1864           valid.double_buffer ? (pf.double_buffer ? "1" : "0") : "?",
1865           valid.stereo ? (pf.stereo ? "1" : "0") : "?",
1866           pf.sample_buffers,
1867           pf.samples);
1868
1869     for (i = 0; i < nb_formats && found < nMaxFormats; i++)
1870     {
1871         const struct color_mode *mode;
1872
1873         if (valid.window && pixel_formats[i].window != pf.window) continue;
1874         if (valid.pbuffer && pixel_formats[i].pbuffer != pf.pbuffer) continue;
1875         if (valid.accelerated && pixel_formats[i].accelerated != pf.accelerated) continue;
1876         if (valid.double_buffer && pixel_formats[i].double_buffer != pf.double_buffer) continue;
1877         if (valid.stereo && pixel_formats[i].stereo != pf.stereo) continue;
1878         if (valid.backing_store && pixel_formats[i].backing_store != pf.backing_store) continue;
1879
1880         if (pixel_formats[i].aux_buffers < pf.aux_buffers) continue;
1881         if (pixel_formats[i].depth_bits < pf.depth_bits) continue;
1882         if (pixel_formats[i].stencil_bits < pf.stencil_bits) continue;
1883         if (pixel_formats[i].sample_buffers < pf.sample_buffers) continue;
1884         if (pixel_formats[i].samples < pf.samples) continue;
1885
1886         mode = &color_modes[pixel_formats[i].color_mode];
1887         /* If the mode doesn't have alpha, check requested color bits against
1888            bits per pixel instead of the mode's color bits.  On Windows, color
1889            bits sometimes exceeds r+g+b (e.g. it's 32 for an R8G8B8A0 pixel format).
1890            If an app depends on that and requests WGL_COLOR_BITS_ARB == 32 and
1891            expects that to match such a pixel format, we need to accommodate that. */
1892         if (mode->alpha_bits)
1893         {
1894             if (mode->color_bits < color_bits)
1895                 continue;
1896         }
1897         else
1898         {
1899             if (mode->bits_per_pixel < color_bits)
1900                 continue;
1901         }
1902         if (mode->red_bits < red_bits || mode->green_bits < green_bits ||
1903             mode->blue_bits < blue_bits || mode->alpha_bits < alpha_bits)
1904             continue;
1905         if (float_color != -1 && (!mode->is_float != !float_color)) continue;
1906         if (srgb && (mode->red_bits != 8 || mode->green_bits != 8 || mode->blue_bits != 8 || mode->is_float))
1907             continue;
1908
1909         if (pixel_formats[i].accum_mode)
1910         {
1911             mode = &color_modes[pixel_formats[i].accum_mode - 1];
1912             if (mode->color_bits < accum_bits || mode->red_bits < accum_red_bits ||
1913                 mode->green_bits < accum_green_bits || mode->blue_bits < accum_blue_bits ||
1914                 mode->alpha_bits < accum_alpha_bits)
1915                 continue;
1916         }
1917         else if (accum_bits || accum_red_bits || accum_green_bits || accum_blue_bits || accum_alpha_bits)
1918             continue;
1919
1920         piFormats[found++] = i;
1921         TRACE("match: pixel format %d %s\n", i, debugstr_pf(&pixel_formats[i]));
1922     }
1923
1924 cant_match:
1925     *nNumFormats = found;
1926
1927     return TRUE;
1928 }
1929
1930
1931 /**********************************************************************
1932  *              macdrv_wglCreatePbufferARB
1933  *
1934  * WGL_ARB_pbuffer: wglCreatePbufferARB
1935  */
1936 static struct wgl_pbuffer *macdrv_wglCreatePbufferARB(HDC hdc, int iPixelFormat, int iWidth, int iHeight,
1937                                                       const int *piAttribList)
1938 {
1939     struct wgl_pbuffer* pbuffer;
1940     GLenum target = 0;
1941     GLenum internalFormat = 0;
1942     CGLError err;
1943
1944     TRACE("hdc %p iPixelFormat %d iWidth %d iHeight %d piAttribList %p\n",
1945           hdc, iPixelFormat, iWidth, iHeight, piAttribList);
1946
1947     if (!is_valid_pixel_format(iPixelFormat) || !pixel_formats[iPixelFormat].pbuffer)
1948     {
1949         WARN("invalid pixel format %d\n", iPixelFormat);
1950         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
1951         return NULL;
1952     }
1953
1954     pbuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pbuffer));
1955     pbuffer->format = iPixelFormat;
1956
1957     for ( ; piAttribList && *piAttribList; piAttribList += 2)
1958     {
1959         int attr = piAttribList[0];
1960         int value = piAttribList[1];
1961
1962         switch (attr)
1963         {
1964             case WGL_PBUFFER_LARGEST_ARB:
1965                 FIXME("WGL_PBUFFER_LARGEST_ARB: %d; ignoring\n", value);
1966                 break;
1967
1968             case WGL_TEXTURE_FORMAT_ARB:
1969                 switch (value)
1970                 {
1971                     case WGL_TEXTURE_RGBA_ARB:
1972                         TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGBA_ARB\n");
1973                         internalFormat = GL_RGBA;
1974                         break;
1975                     case WGL_TEXTURE_RGB_ARB:
1976                         TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_TEXTURE_RGB_ARB\n");
1977                         internalFormat = GL_RGB;
1978                         break;
1979                     case WGL_NO_TEXTURE_ARB:
1980                         TRACE("WGL_TEXTURE_FORMAT_ARB: WGL_NO_TEXTURE_ARB\n");
1981                         internalFormat = 0;
1982                         break;
1983                     default:
1984                         WARN("unknown WGL_TEXTURE_FORMAT_ARB value 0x%x\n", value);
1985                         SetLastError(ERROR_INVALID_DATA);
1986                         goto done;
1987                 }
1988                 break;
1989
1990             case WGL_TEXTURE_TARGET_ARB:
1991                 pbuffer->face = 0;
1992                 switch (value)
1993                 {
1994                     case WGL_NO_TEXTURE_ARB:
1995                         TRACE("WGL_TEXTURE_TARGET_ARB: WGL_NO_TEXTURE_ARB\n");
1996                         target = 0;
1997                         break;
1998                     case WGL_TEXTURE_CUBE_MAP_ARB:
1999                         TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_CUBE_MAP_ARB\n");
2000                         target = GL_TEXTURE_CUBE_MAP;
2001                         pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
2002                         break;
2003                     case WGL_TEXTURE_1D_ARB:
2004                         FIXME("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_1D_ARB; not supported\n");
2005                         SetLastError(ERROR_NO_SYSTEM_RESOURCES);
2006                         goto done;
2007                     case WGL_TEXTURE_2D_ARB:
2008                         TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_2D_ARB\n");
2009                         target = GL_TEXTURE_2D;
2010                         break;
2011                     case WGL_TEXTURE_RECTANGLE_NV:
2012                         TRACE("WGL_TEXTURE_TARGET_ARB: WGL_TEXTURE_RECTANGLE_NV\n");
2013                         target = GL_TEXTURE_RECTANGLE;
2014                         break;
2015                     default:
2016                         WARN("unknown WGL_TEXTURE_TARGET_ARB value 0x%x\n", value);
2017                         SetLastError(ERROR_INVALID_DATA);
2018                         goto done;
2019                 }
2020                 break;
2021
2022             case WGL_MIPMAP_TEXTURE_ARB:
2023                 TRACE("WGL_MIPMAP_TEXTURE_ARB: %d\n", value);
2024                 pbuffer->max_level = 0;
2025                 if (value)
2026                 {
2027                     int size = min(iWidth, iHeight) / 2;
2028                     while (size)
2029                     {
2030                         pbuffer->max_level++;
2031                         size /= 2;
2032                     }
2033                 }
2034                 break;
2035
2036             default:
2037                 WARN("unknown attribute 0x%x\n", attr);
2038                 SetLastError(ERROR_INVALID_DATA);
2039                 goto done;
2040         }
2041     }
2042
2043     if (!target || !internalFormat)
2044     {
2045         pbuffer->no_texture = TRUE;
2046         /* no actual way to turn off ability to texture; use most permissive target */
2047         target = GL_TEXTURE_RECTANGLE;
2048         internalFormat = GL_RGB;
2049     }
2050
2051     err = CGLCreatePBuffer(iWidth, iHeight, target, internalFormat, pbuffer->max_level, &pbuffer->pbuffer);
2052     if (err != kCGLNoError)
2053     {
2054         WARN("CGLCreatePBuffer failed; err %d %s\n", err, CGLErrorString(err));
2055         pbuffer->pbuffer = NULL;
2056         if (err == kCGLBadAlloc)
2057             SetLastError(ERROR_NO_SYSTEM_RESOURCES);
2058         else
2059             SetLastError(ERROR_INVALID_DATA);
2060     }
2061
2062 done:
2063     if (!pbuffer->pbuffer)
2064     {
2065         HeapFree(GetProcessHeap(), 0, pbuffer);
2066         return NULL;
2067     }
2068
2069     TRACE(" -> %p\n", pbuffer);
2070     return pbuffer;
2071 }
2072
2073
2074 /**********************************************************************
2075  *              macdrv_wglDestroyPbufferARB
2076  *
2077  * WGL_ARB_pbuffer: wglDestroyPbufferARB
2078  */
2079 static BOOL macdrv_wglDestroyPbufferARB(struct wgl_pbuffer *pbuffer)
2080 {
2081     TRACE("pbuffer %p\n", pbuffer);
2082     if (pbuffer && pbuffer->pbuffer)
2083         CGLReleasePBuffer(pbuffer->pbuffer);
2084     HeapFree(GetProcessHeap(), 0, pbuffer);
2085     return GL_TRUE;
2086 }
2087
2088
2089 /**********************************************************************
2090  *              macdrv_wglGetExtensionsStringARB
2091  *
2092  * WGL_ARB_extensions_string: wglGetExtensionsStringARB
2093  */
2094 static const GLubyte *macdrv_wglGetExtensionsStringARB(HDC hdc)
2095 {
2096     /* FIXME: Since we're given an HDC, this should be device-specific.  I.e.
2097               this can be specific to the CGL renderer like we're supposed to do. */
2098     TRACE("returning \"%s\"\n", gl_info.wglExtensions);
2099     return (const GLubyte*)gl_info.wglExtensions;
2100 }
2101
2102
2103 /**********************************************************************
2104  *              macdrv_wglGetExtensionsStringEXT
2105  *
2106  * WGL_EXT_extensions_string: wglGetExtensionsStringEXT
2107  */
2108 static const GLubyte *macdrv_wglGetExtensionsStringEXT(void)
2109 {
2110     TRACE("returning \"%s\"\n", gl_info.wglExtensions);
2111     return (const GLubyte*)gl_info.wglExtensions;
2112 }
2113
2114
2115 /**********************************************************************
2116  *              macdrv_wglGetPbufferDCARB
2117  *
2118  * WGL_ARB_pbuffer: wglGetPbufferDCARB
2119  */
2120 static HDC macdrv_wglGetPbufferDCARB(struct wgl_pbuffer *pbuffer)
2121 {
2122     HDC hdc;
2123     struct wgl_pbuffer *prev;
2124
2125     hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
2126     if (!hdc) return 0;
2127
2128     EnterCriticalSection(&dc_pbuffers_section);
2129     prev = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc);
2130     if (prev)
2131     {
2132         CGLReleasePBuffer(prev->pbuffer);
2133         HeapFree(GetProcessHeap(), 0, prev);
2134     }
2135     CFDictionarySetValue(dc_pbuffers, hdc, pbuffer);
2136     LeaveCriticalSection(&dc_pbuffers_section);
2137
2138     TRACE("pbuffer %p -> hdc %p\n", pbuffer, hdc);
2139     return hdc;
2140 }
2141
2142
2143 /**********************************************************************
2144  *              macdrv_wglGetPixelFormatAttribivARB
2145  *
2146  * WGL_ARB_pixel_format: wglGetPixelFormatAttribivARB
2147  */
2148 static BOOL macdrv_wglGetPixelFormatAttribivARB(HDC hdc, int iPixelFormat, int iLayerPlane,
2149                                                 UINT nAttributes, const int *piAttributes, int *piValues)
2150 {
2151     const pixel_format *pf;
2152     UINT i;
2153
2154     TRACE("hdc %p iPixelFormat %d iLayerPlane %d nAttributes %u piAttributes %p piValues %p\n",
2155           hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues);
2156
2157     if (!nAttributes) return GL_TRUE;
2158
2159     if (nAttributes == 1 && piAttributes[0] == WGL_NUMBER_PIXEL_FORMATS_ARB)
2160     {
2161         piValues[0] = nb_formats;
2162         TRACE("%s\n", debugstr_attrib(piAttributes[0], piValues[0]));
2163         return GL_TRUE;
2164     }
2165
2166     pf = get_pixel_format(iPixelFormat, TRUE /* non-displayable */);
2167     if (!pf)
2168     {
2169         WARN("invalid pixel format %d\n", iPixelFormat);
2170         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2171         return GL_FALSE;
2172     }
2173
2174     for (i = 0; i < nAttributes; ++i)
2175     {
2176         switch (piAttributes[i])
2177         {
2178             case WGL_NUMBER_PIXEL_FORMATS_ARB:
2179                 piValues[i] = nb_formats;
2180                 break;
2181
2182             case WGL_DRAW_TO_WINDOW_ARB:
2183                 piValues[i] = pf->window ? GL_TRUE : GL_FALSE;
2184                 break;
2185
2186             case WGL_DRAW_TO_BITMAP_ARB:
2187                 piValues[i] = GL_FALSE;
2188                 break;
2189
2190             case WGL_ACCELERATION_ARB:
2191                 if (iLayerPlane) goto invalid_layer;
2192                 if (pf->accelerated)
2193                     piValues[i] = WGL_FULL_ACCELERATION_ARB;
2194                 else
2195                     piValues[i] = WGL_NO_ACCELERATION_ARB;
2196                 break;
2197
2198             case WGL_NEED_PALETTE_ARB:
2199             case WGL_NEED_SYSTEM_PALETTE_ARB:
2200             case WGL_SWAP_LAYER_BUFFERS_ARB:
2201                 piValues[i] = GL_FALSE;
2202                 break;
2203
2204             case WGL_SWAP_METHOD_ARB:
2205                 if (pf->double_buffer && pf->backing_store)
2206                     piValues[i] = WGL_SWAP_COPY_ARB;
2207                 else
2208                     piValues[i] = WGL_SWAP_UNDEFINED_ARB;
2209                 break;
2210
2211             case WGL_NUMBER_OVERLAYS_ARB:
2212             case WGL_NUMBER_UNDERLAYS_ARB:
2213                 piValues[i] = 0;
2214                 break;
2215
2216             case WGL_TRANSPARENT_ARB:
2217                 if (iLayerPlane) goto invalid_layer;
2218                 piValues[i] = GL_FALSE;
2219                 break;
2220
2221             case WGL_TRANSPARENT_RED_VALUE_ARB:
2222             case WGL_TRANSPARENT_GREEN_VALUE_ARB:
2223             case WGL_TRANSPARENT_BLUE_VALUE_ARB:
2224             case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
2225             case WGL_TRANSPARENT_INDEX_VALUE_ARB:
2226                 if (iLayerPlane) goto invalid_layer;
2227                 piValues[i] = 0;
2228                 break;
2229
2230             case WGL_SHARE_DEPTH_ARB:
2231             case WGL_SHARE_STENCIL_ARB:
2232             case WGL_SHARE_ACCUM_ARB:
2233                 if (iLayerPlane) goto invalid_layer;
2234                 piValues[i] = GL_TRUE;
2235                 break;
2236
2237             case WGL_SUPPORT_GDI_ARB:
2238                 if (iLayerPlane) goto invalid_layer;
2239                 piValues[i] = GL_FALSE;
2240                 break;
2241
2242             case WGL_SUPPORT_OPENGL_ARB:
2243                 if (iLayerPlane) goto invalid_layer;
2244                 piValues[i] = GL_TRUE;
2245                 break;
2246
2247             case WGL_DOUBLE_BUFFER_ARB:
2248                 if (iLayerPlane) goto invalid_layer;
2249                 piValues[i] = pf->double_buffer ? GL_TRUE : GL_FALSE;
2250                 break;
2251
2252             case WGL_STEREO_ARB:
2253                 if (iLayerPlane) goto invalid_layer;
2254                 piValues[i] = pf->stereo ? GL_TRUE : GL_FALSE;
2255                 break;
2256
2257             case WGL_PIXEL_TYPE_ARB:
2258                 if (iLayerPlane) goto invalid_layer;
2259                 if (color_modes[pf->color_mode].is_float)
2260                     piValues[i] = WGL_TYPE_RGBA_FLOAT_ARB;
2261                 else
2262                     piValues[i] = WGL_TYPE_RGBA_ARB;
2263                 /* WGL_EXT_pixel_format_packed_float may be supported, which should in theory
2264                    make another pixel type available: WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT.
2265                    However, Mac contexts don't support rendering to unsigned floating-point
2266                    formats, even when GL_EXT_packed_float is supported. */
2267                 break;
2268
2269             case WGL_COLOR_BITS_ARB:
2270                 if (iLayerPlane) goto invalid_layer;
2271                 /* If the mode doesn't have alpha, return bits per pixel instead
2272                    of color bits.  On Windows, color bits sometimes exceeds r+g+b
2273                    (e.g. it's 32 for an R8G8B8A0 pixel format).  If an app depends
2274                    on that and expects that WGL_COLOR_BITS_ARB >= 32 for such a
2275                    pixel format, we need to accommodate that. */
2276                 if (color_modes[pf->color_mode].alpha_bits)
2277                     piValues[i] = color_modes[pf->color_mode].color_bits;
2278                 else
2279                     piValues[i] = color_modes[pf->color_mode].bits_per_pixel;
2280                 break;
2281
2282             case WGL_RED_BITS_ARB:
2283                 if (iLayerPlane) goto invalid_layer;
2284                 piValues[i] = color_modes[pf->color_mode].red_bits;
2285                 break;
2286
2287             case WGL_RED_SHIFT_ARB:
2288                 if (iLayerPlane) goto invalid_layer;
2289                 piValues[i] = color_modes[pf->color_mode].red_shift;
2290                 break;
2291
2292             case WGL_GREEN_BITS_ARB:
2293                 if (iLayerPlane) goto invalid_layer;
2294                 piValues[i] = color_modes[pf->color_mode].green_bits;
2295                 break;
2296
2297             case WGL_GREEN_SHIFT_ARB:
2298                 if (iLayerPlane) goto invalid_layer;
2299                 piValues[i] = color_modes[pf->color_mode].green_shift;
2300                 break;
2301
2302             case WGL_BLUE_BITS_ARB:
2303                 if (iLayerPlane) goto invalid_layer;
2304                 piValues[i] = color_modes[pf->color_mode].blue_bits;
2305                 break;
2306
2307             case WGL_BLUE_SHIFT_ARB:
2308                 if (iLayerPlane) goto invalid_layer;
2309                 piValues[i] = color_modes[pf->color_mode].blue_shift;
2310                 break;
2311
2312             case WGL_ALPHA_BITS_ARB:
2313                 if (iLayerPlane) goto invalid_layer;
2314                 piValues[i] = color_modes[pf->color_mode].alpha_bits;
2315                 break;
2316
2317             case WGL_ALPHA_SHIFT_ARB:
2318                 if (iLayerPlane) goto invalid_layer;
2319                 piValues[i] = color_modes[pf->color_mode].alpha_shift;
2320                 break;
2321
2322             case WGL_ACCUM_BITS_ARB:
2323                 if (iLayerPlane) goto invalid_layer;
2324                 if (pf->accum_mode)
2325                     piValues[i] = color_modes[pf->accum_mode - 1].color_bits;
2326                 else
2327                     piValues[i] = 0;
2328                 break;
2329
2330             case WGL_ACCUM_RED_BITS_ARB:
2331                 if (iLayerPlane) goto invalid_layer;
2332                 if (pf->accum_mode)
2333                     piValues[i] = color_modes[pf->accum_mode - 1].red_bits;
2334                 else
2335                     piValues[i] = 0;
2336                 break;
2337
2338             case WGL_ACCUM_GREEN_BITS_ARB:
2339                 if (iLayerPlane) goto invalid_layer;
2340                 if (pf->accum_mode)
2341                     piValues[i] = color_modes[pf->accum_mode - 1].green_bits;
2342                 else
2343                     piValues[i] = 0;
2344                 break;
2345
2346             case WGL_ACCUM_BLUE_BITS_ARB:
2347                 if (iLayerPlane) goto invalid_layer;
2348                 if (pf->accum_mode)
2349                     piValues[i] = color_modes[pf->accum_mode - 1].blue_bits;
2350                 else
2351                     piValues[i] = 0;
2352                 break;
2353
2354             case WGL_ACCUM_ALPHA_BITS_ARB:
2355                 if (iLayerPlane) goto invalid_layer;
2356                 if (pf->accum_mode)
2357                     piValues[i] = color_modes[pf->accum_mode - 1].alpha_bits;
2358                 else
2359                     piValues[i] = 0;
2360                 break;
2361
2362             case WGL_DEPTH_BITS_ARB:
2363                 if (iLayerPlane) goto invalid_layer;
2364                 piValues[i] = pf->depth_bits;
2365                 break;
2366
2367             case WGL_STENCIL_BITS_ARB:
2368                 if (iLayerPlane) goto invalid_layer;
2369                 piValues[i] = pf->stencil_bits;
2370                 break;
2371
2372             case WGL_AUX_BUFFERS_ARB:
2373                 if (iLayerPlane) goto invalid_layer;
2374                 piValues[i] = pf->aux_buffers;
2375                 break;
2376
2377             case WGL_SAMPLE_BUFFERS_ARB:
2378                 if (iLayerPlane) goto invalid_layer;
2379                 piValues[i] = pf->sample_buffers;
2380                 break;
2381
2382             case WGL_SAMPLES_ARB:
2383                 if (iLayerPlane) goto invalid_layer;
2384                 piValues[i] = pf->samples;
2385                 break;
2386
2387             case WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB: /* a.k.a. WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT */
2388                 if (iLayerPlane) goto invalid_layer;
2389                 /* sRGB is only supported for 8-bit integer color components */
2390                 if (color_modes[pf->color_mode].red_bits == 8 &&
2391                     color_modes[pf->color_mode].green_bits == 8 &&
2392                     color_modes[pf->color_mode].blue_bits == 8 &&
2393                     !color_modes[pf->color_mode].is_float)
2394                     piValues[i] = GL_TRUE;
2395                 else
2396                     piValues[i] = GL_FALSE;
2397                 break;
2398
2399             case WGL_DRAW_TO_PBUFFER_ARB:
2400             case WGL_BIND_TO_TEXTURE_RGB_ARB:
2401             case WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV:
2402                 piValues[i] = pf->pbuffer ? GL_TRUE : GL_FALSE;
2403                 break;
2404
2405             case WGL_BIND_TO_TEXTURE_RGBA_ARB:
2406             case WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV:
2407                 piValues[i] = (pf->pbuffer && color_modes[pf->color_mode].alpha_bits) ? GL_TRUE : GL_FALSE;
2408                 break;
2409
2410             case WGL_MAX_PBUFFER_WIDTH_ARB:
2411                 piValues[i] = gl_info.max_viewport_dims[0];
2412                 break;
2413
2414             case WGL_MAX_PBUFFER_HEIGHT_ARB:
2415                 piValues[i] = gl_info.max_viewport_dims[1];
2416                 break;
2417
2418             case WGL_MAX_PBUFFER_PIXELS_ARB:
2419                 piValues[i] = gl_info.max_viewport_dims[0] * gl_info.max_viewport_dims[1];
2420                 break;
2421
2422             default:
2423                 WARN("invalid attribute %x\n", piAttributes[i]);
2424                 return GL_FALSE;
2425         }
2426
2427         TRACE("%s\n", debugstr_attrib(piAttributes[i], piValues[i]));
2428     }
2429
2430     return GL_TRUE;
2431
2432 invalid_layer:
2433     FIXME("unsupported iLayerPlane %d\n", iLayerPlane);
2434     return GL_FALSE;
2435 }
2436
2437
2438 /**********************************************************************
2439  *              macdrv_wglGetPixelFormatAttribfvARB
2440  *
2441  * WGL_ARB_pixel_format: wglGetPixelFormatAttribfvARB
2442  */
2443 static BOOL macdrv_wglGetPixelFormatAttribfvARB(HDC hdc, int iPixelFormat, int iLayerPlane,
2444                                                 UINT nAttributes, const int *piAttributes, FLOAT *pfValues)
2445 {
2446     int *attr;
2447     int ret;
2448
2449     TRACE("hdc %p iPixelFormat %d iLayerPlane %d nAttributes %u piAttributes %p pfValues %p\n",
2450           hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues);
2451
2452     /* Allocate a temporary array to store integer values */
2453     attr = HeapAlloc(GetProcessHeap(), 0, nAttributes * sizeof(int));
2454     if (!attr)
2455     {
2456         ERR("couldn't allocate %d array\n", nAttributes);
2457         return GL_FALSE;
2458     }
2459
2460     /* Piggy-back on wglGetPixelFormatAttribivARB */
2461     ret = macdrv_wglGetPixelFormatAttribivARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, attr);
2462     if (ret)
2463     {
2464         UINT i;
2465
2466         /* Convert integer values to float. Should also check for attributes
2467            that can give decimal values here */
2468         for (i = 0; i < nAttributes; i++)
2469             pfValues[i] = attr[i];
2470     }
2471
2472     HeapFree(GetProcessHeap(), 0, attr);
2473     return ret;
2474 }
2475
2476
2477 /**********************************************************************
2478  *              macdrv_wglGetSwapIntervalEXT
2479  *
2480  * WGL_EXT_swap_control: wglGetSwapIntervalEXT
2481  */
2482 static int macdrv_wglGetSwapIntervalEXT(void)
2483 {
2484     struct wgl_context *context = NtCurrentTeb()->glContext;
2485     long value;
2486     CGLError err;
2487
2488     TRACE("\n");
2489
2490     err = CGLGetParameter(context->cglcontext, kCGLCPSwapInterval, (GLint*)&value);
2491     if (err != kCGLNoError)
2492     {
2493         WARN("CGLGetParameter(kCGLCPSwapInterval) failed; error %d %s\n",
2494              err, CGLErrorString(err));
2495         value = 1;
2496     }
2497
2498     return value;
2499 }
2500
2501
2502 /***********************************************************************
2503  *              macdrv_wglMakeContextCurrentARB
2504  *
2505  * WGL_ARB_make_current_read: wglMakeContextCurrentARB
2506  *
2507  * This is not supported directly by OpenGL on the Mac.  We emulate it
2508  * by hooking into glReadPixels, glCopyPixels, and glCopyColorTable to
2509  * temporarily swap the drawable.  This follows the technique used in
2510  * the implementation of Mesa GLX for Apple.
2511  */
2512 static BOOL macdrv_wglMakeContextCurrentARB(HDC draw_hdc, HDC read_hdc, struct wgl_context *context)
2513 {
2514     struct macdrv_win_data *data;
2515     HWND hwnd;
2516
2517     TRACE("draw_hdc %p read_hdc %p context %p/%p/%p\n", draw_hdc, read_hdc, context,
2518           (context ? context->context : NULL), (context ? context->cglcontext : NULL));
2519
2520     if (!context)
2521     {
2522         macdrv_make_context_current(NULL, NULL);
2523         NtCurrentTeb()->glContext = NULL;
2524         return TRUE;
2525     }
2526
2527     if ((hwnd = WindowFromDC(draw_hdc)))
2528     {
2529         if (!(data = get_win_data(hwnd)))
2530         {
2531             FIXME("draw DC for window %p of other process: not implemented\n", hwnd);
2532             return FALSE;
2533         }
2534
2535         if (!data->pixel_format)
2536         {
2537             WARN("no pixel format set\n");
2538             release_win_data(data);
2539             SetLastError(ERROR_INVALID_HANDLE);
2540             return FALSE;
2541         }
2542         if (context->format != data->pixel_format)
2543         {
2544             WARN("mismatched pixel format draw_hdc %p %u context %p %u\n", draw_hdc, data->pixel_format, context, context->format);
2545             release_win_data(data);
2546             SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2547             return FALSE;
2548         }
2549
2550         context->draw_view = data->gl_view;
2551         context->draw_pbuffer = NULL;
2552         release_win_data(data);
2553     }
2554     else
2555     {
2556         struct wgl_pbuffer *pbuffer;
2557
2558         EnterCriticalSection(&dc_pbuffers_section);
2559         pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, draw_hdc);
2560         if (pbuffer)
2561         {
2562             if (context->format != pbuffer->format)
2563             {
2564                 WARN("mismatched pixel format draw_hdc %p %u context %p %u\n", draw_hdc, pbuffer->format, context, context->format);
2565                 LeaveCriticalSection(&dc_pbuffers_section);
2566                 SetLastError(ERROR_INVALID_PIXEL_FORMAT);
2567                 return FALSE;
2568             }
2569         }
2570         else
2571         {
2572             WARN("no window or pbuffer for DC\n");
2573             LeaveCriticalSection(&dc_pbuffers_section);
2574             SetLastError(ERROR_INVALID_HANDLE);
2575             return FALSE;
2576         }
2577
2578         context->draw_view = NULL;
2579         context->draw_pbuffer = pbuffer;
2580         LeaveCriticalSection(&dc_pbuffers_section);
2581     }
2582
2583     context->read_view = NULL;
2584     context->read_pbuffer = NULL;
2585     if (read_hdc && read_hdc != draw_hdc)
2586     {
2587         if ((hwnd = WindowFromDC(read_hdc)))
2588         {
2589             if ((data = get_win_data(hwnd)))
2590             {
2591                 if (data->gl_view != context->draw_view)
2592                     context->read_view = data->gl_view;
2593                 release_win_data(data);
2594             }
2595         }
2596         else
2597         {
2598             EnterCriticalSection(&dc_pbuffers_section);
2599             context->read_pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, read_hdc);
2600             LeaveCriticalSection(&dc_pbuffers_section);
2601         }
2602     }
2603
2604     TRACE("making context current with draw_view %p draw_pbuffer %p read_view %p read_pbuffer %p format %u\n",
2605           context->draw_view, context->draw_pbuffer, context->read_view, context->read_pbuffer, context->format);
2606
2607     make_context_current(context, FALSE);
2608     context->has_been_current = TRUE;
2609     NtCurrentTeb()->glContext = context;
2610
2611     return TRUE;
2612 }
2613
2614
2615 /**********************************************************************
2616  *              macdrv_wglQueryPbufferARB
2617  *
2618  * WGL_ARB_pbuffer: wglQueryPbufferARB
2619  */
2620 static BOOL macdrv_wglQueryPbufferARB(struct wgl_pbuffer *pbuffer, int iAttribute, int *piValue)
2621 {
2622     CGLError err;
2623     GLsizei width;
2624     GLsizei height;
2625     GLenum target;
2626     GLenum internalFormat;
2627     GLint mipmap;
2628
2629     TRACE("pbuffer %p iAttribute 0x%x piValue %p\n", pbuffer, iAttribute, piValue);
2630
2631     err = CGLDescribePBuffer(pbuffer->pbuffer, &width, &height, &target, &internalFormat, &mipmap);
2632     if (err != kCGLNoError)
2633     {
2634         WARN("CGLDescribePBuffer failed; error %d %s\n", err, CGLErrorString(err));
2635         SetLastError(ERROR_INVALID_HANDLE);
2636         return GL_FALSE;
2637     }
2638
2639     switch (iAttribute)
2640     {
2641         case WGL_PBUFFER_WIDTH_ARB:
2642             *piValue = width;
2643             break;
2644         case WGL_PBUFFER_HEIGHT_ARB:
2645             *piValue = height;
2646             break;
2647         case WGL_PBUFFER_LOST_ARB:
2648             /* Mac PBuffers can't be lost */
2649             *piValue = GL_FALSE;
2650             break;
2651         case WGL_TEXTURE_FORMAT_ARB:
2652             if (pbuffer->no_texture)
2653                 *piValue = WGL_NO_TEXTURE_ARB;
2654             else switch (internalFormat)
2655             {
2656                 case GL_RGBA:
2657                     *piValue = WGL_TEXTURE_RGBA_ARB;
2658                     break;
2659                 case GL_RGB:
2660                 default:
2661                     *piValue = WGL_TEXTURE_RGB_ARB;
2662                     break;
2663             }
2664             break;
2665         case WGL_TEXTURE_TARGET_ARB:
2666             if (pbuffer->no_texture)
2667                 *piValue = WGL_NO_TEXTURE_ARB;
2668             else switch (target)
2669             {
2670                 case GL_TEXTURE_CUBE_MAP:
2671                     *piValue = WGL_TEXTURE_CUBE_MAP_ARB;
2672                     break;
2673                 case GL_TEXTURE_2D:
2674                     *piValue = WGL_TEXTURE_2D_ARB;
2675                     break;
2676                 case GL_TEXTURE_RECTANGLE:
2677                 default:
2678                     *piValue = WGL_TEXTURE_RECTANGLE_NV;
2679                     break;
2680             }
2681             break;
2682         case WGL_MIPMAP_TEXTURE_ARB:
2683             *piValue = (pbuffer->max_level > 0);
2684             break;
2685         case WGL_MIPMAP_LEVEL_ARB:
2686             *piValue = pbuffer->level;
2687             break;
2688         case WGL_CUBE_MAP_FACE_ARB:
2689             switch (pbuffer->face)
2690             {
2691                 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2692                 default:
2693                     *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
2694                     break;
2695                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2696                     *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
2697                     break;
2698                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2699                     *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB;
2700                     break;
2701                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2702                     *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB;
2703                     break;
2704                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2705                     *piValue = WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB;
2706                     break;
2707                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2708                     *piValue = WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB;
2709                     break;
2710             }
2711             break;
2712         default:
2713             WARN("invalid attribute 0x%x\n", iAttribute);
2714             SetLastError(ERROR_INVALID_DATA);
2715             return GL_FALSE;
2716     }
2717
2718     return GL_TRUE;
2719 }
2720
2721
2722 /**********************************************************************
2723  *              macdrv_wglReleasePbufferDCARB
2724  *
2725  * WGL_ARB_pbuffer: wglReleasePbufferDCARB
2726  */
2727 static int macdrv_wglReleasePbufferDCARB(struct wgl_pbuffer *pbuffer, HDC hdc)
2728 {
2729     struct wgl_pbuffer *prev;
2730
2731     TRACE("pbuffer %p hdc %p\n", pbuffer, hdc);
2732
2733     EnterCriticalSection(&dc_pbuffers_section);
2734
2735     prev = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc);
2736     if (prev)
2737     {
2738         if (prev != pbuffer)
2739             FIXME("hdc %p isn't associated with pbuffer %p\n", hdc, pbuffer);
2740         CGLReleasePBuffer(prev->pbuffer);
2741         HeapFree(GetProcessHeap(), 0, prev);
2742         CFDictionaryRemoveValue(dc_pbuffers, hdc);
2743     }
2744     else hdc = 0;
2745
2746     LeaveCriticalSection(&dc_pbuffers_section);
2747
2748     return hdc && DeleteDC(hdc);
2749 }
2750
2751
2752 /**********************************************************************
2753  *              macdrv_wglReleaseTexImageARB
2754  *
2755  * WGL_ARB_render_texture: wglReleaseTexImageARB
2756  */
2757 static BOOL macdrv_wglReleaseTexImageARB(struct wgl_pbuffer *pbuffer, int iBuffer)
2758 {
2759     struct wgl_context *context = NtCurrentTeb()->glContext;
2760     CGLError err;
2761
2762     TRACE("pbuffer %p iBuffer 0x%x; stub!\n", pbuffer, iBuffer);
2763
2764     if (pbuffer->no_texture)
2765     {
2766         SetLastError(ERROR_INVALID_OPERATION);
2767         return GL_FALSE;
2768     }
2769
2770     err = CGLTexImagePBuffer(context->cglcontext, pbuffer->pbuffer, GL_NONE);
2771     if (err != kCGLNoError)
2772     {
2773         WARN("CGLTexImagePBuffer failed with err %d %s\n", err, CGLErrorString(err));
2774         SetLastError(ERROR_INVALID_OPERATION);
2775         return GL_FALSE;
2776     }
2777
2778     return GL_TRUE;
2779 }
2780
2781
2782 /**********************************************************************
2783  *              macdrv_wglSetPbufferAttribARB
2784  *
2785  * WGL_ARB_render_texture: wglSetPbufferAttribARB
2786  */
2787 static BOOL macdrv_wglSetPbufferAttribARB(struct wgl_pbuffer *pbuffer, const int *piAttribList)
2788 {
2789     struct wgl_context *context = NtCurrentTeb()->glContext;
2790
2791     TRACE("pbuffer %p piAttribList %p\n", pbuffer, piAttribList);
2792
2793     for ( ; piAttribList && *piAttribList; piAttribList += 2)
2794     {
2795         int attr = piAttribList[0];
2796         int value = piAttribList[1];
2797         switch (attr)
2798         {
2799             case WGL_MIPMAP_LEVEL_ARB:
2800                 TRACE("WGL_MIPMAP_LEVEL_ARB: %d\n", value);
2801                 pbuffer->level = value;
2802                 break;
2803             case WGL_CUBE_MAP_FACE_ARB:
2804                 switch (value)
2805                 {
2806                     case WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
2807                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB\n");
2808                         pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
2809                         break;
2810                     case WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
2811                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB\n");
2812                         pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
2813                         break;
2814                     case WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
2815                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB\n");
2816                         pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
2817                         break;
2818                     case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
2819                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB\n");
2820                         pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
2821                         break;
2822                     case WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
2823                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB\n");
2824                         pbuffer->face = GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
2825                         break;
2826                     case WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
2827                         TRACE("WGL_CUBE_MAP_FACE_ARB: WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB\n");
2828                         pbuffer->face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
2829                         break;
2830                     default:
2831                         WARN("unknown WGL_CUBE_MAP_FACE_ARB value 0x%x\n", value);
2832                         SetLastError(ERROR_INVALID_DATA);
2833                         return GL_FALSE;
2834                 }
2835                 break;
2836             default:
2837                 WARN("invalide attribute 0x%x\n", attr);
2838                 SetLastError(ERROR_INVALID_DATA);
2839                 return GL_FALSE;
2840         }
2841     }
2842
2843     if (context && context->draw_pbuffer == pbuffer)
2844         make_context_current(context, FALSE);
2845
2846     return GL_TRUE;
2847 }
2848
2849
2850 /**********************************************************************
2851  *              macdrv_wglSetPixelFormatWINE
2852  *
2853  * WGL_WINE_pixel_format_passthrough: wglSetPixelFormatWINE
2854  */
2855 static BOOL macdrv_wglSetPixelFormatWINE(HDC hdc, int fmt)
2856 {
2857     return set_pixel_format(hdc, fmt, TRUE);
2858 }
2859
2860
2861 /**********************************************************************
2862  *              macdrv_wglSwapIntervalEXT
2863  *
2864  * WGL_EXT_swap_control: wglSwapIntervalEXT
2865  */
2866 static BOOL macdrv_wglSwapIntervalEXT(int interval)
2867 {
2868     struct wgl_context *context = NtCurrentTeb()->glContext;
2869     long value;
2870     CGLError err;
2871
2872     TRACE("interval %d\n", interval);
2873
2874     if (interval < 0)
2875     {
2876         SetLastError(ERROR_INVALID_DATA);
2877         return FALSE;
2878     }
2879
2880     if (interval > 1)
2881         interval = 1;
2882
2883     value = interval;
2884     err = CGLSetParameter(context->cglcontext, kCGLCPSwapInterval, (GLint*)&value);
2885     if (err != kCGLNoError)
2886     {
2887         WARN("CGLSetParameter(kCGLCPSwapInterval) failed; error %d %s\n",
2888              err, CGLErrorString(err));
2889         SetLastError(ERROR_GEN_FAILURE);
2890         return FALSE;
2891     }
2892
2893     return TRUE;
2894 }
2895
2896
2897 static void register_extension(const char *ext)
2898 {
2899     if (gl_info.wglExtensions[0])
2900         strcat(gl_info.wglExtensions, " ");
2901     strcat(gl_info.wglExtensions, ext);
2902
2903     TRACE("'%s'\n", ext);
2904 }
2905
2906 static void load_extensions(void)
2907 {
2908     /*
2909      * ARB Extensions
2910      */
2911     register_extension("WGL_ARB_extensions_string");
2912     opengl_funcs.ext.p_wglGetExtensionsStringARB = macdrv_wglGetExtensionsStringARB;
2913
2914     register_extension("WGL_ARB_make_current_read");
2915     opengl_funcs.ext.p_wglGetCurrentReadDCARB   = (void *)1;  /* never called */
2916     opengl_funcs.ext.p_wglMakeContextCurrentARB = macdrv_wglMakeContextCurrentARB;
2917
2918     register_extension("WGL_ARB_pixel_format");
2919     opengl_funcs.ext.p_wglChoosePixelFormatARB      = macdrv_wglChoosePixelFormatARB;
2920     opengl_funcs.ext.p_wglGetPixelFormatAttribfvARB = macdrv_wglGetPixelFormatAttribfvARB;
2921     opengl_funcs.ext.p_wglGetPixelFormatAttribivARB = macdrv_wglGetPixelFormatAttribivARB;
2922
2923     if (gluCheckExtension((GLubyte*)"GL_ARB_color_buffer_float", (GLubyte*)gl_info.glExtensions))
2924     {
2925         register_extension("WGL_ARB_pixel_format_float");
2926         register_extension("WGL_ATI_pixel_format_float");
2927     }
2928
2929     if (gluCheckExtension((GLubyte*)"GL_ARB_multisample", (GLubyte*)gl_info.glExtensions))
2930         register_extension("WGL_ARB_multisample");
2931
2932     if (gluCheckExtension((GLubyte*)"GL_ARB_framebuffer_sRGB", (GLubyte*)gl_info.glExtensions))
2933         register_extension("WGL_ARB_framebuffer_sRGB");
2934
2935     if (gluCheckExtension((GLubyte*)"GL_APPLE_pixel_buffer", (GLubyte*)gl_info.glExtensions))
2936     {
2937         register_extension("WGL_ARB_pbuffer");
2938         opengl_funcs.ext.p_wglCreatePbufferARB    = macdrv_wglCreatePbufferARB;
2939         opengl_funcs.ext.p_wglDestroyPbufferARB   = macdrv_wglDestroyPbufferARB;
2940         opengl_funcs.ext.p_wglGetPbufferDCARB     = macdrv_wglGetPbufferDCARB;
2941         opengl_funcs.ext.p_wglQueryPbufferARB     = macdrv_wglQueryPbufferARB;
2942         opengl_funcs.ext.p_wglReleasePbufferDCARB = macdrv_wglReleasePbufferDCARB;
2943
2944         register_extension("WGL_ARB_render_texture");
2945         opengl_funcs.ext.p_wglBindTexImageARB       = macdrv_wglBindTexImageARB;
2946         opengl_funcs.ext.p_wglReleaseTexImageARB    = macdrv_wglReleaseTexImageARB;
2947         opengl_funcs.ext.p_wglSetPbufferAttribARB   = macdrv_wglSetPbufferAttribARB;
2948
2949         if (gluCheckExtension((GLubyte*)"GL_ARB_texture_rectangle", (GLubyte*)gl_info.glExtensions) ||
2950             gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle", (GLubyte*)gl_info.glExtensions))
2951             register_extension("WGL_NV_render_texture_rectangle");
2952     }
2953
2954     /* TODO:
2955         WGL_ARB_create_context: wglCreateContextAttribsARB
2956         WGL_ARB_create_context_profile
2957      */
2958
2959     /*
2960      * EXT Extensions
2961      */
2962     register_extension("WGL_EXT_extensions_string");
2963     opengl_funcs.ext.p_wglGetExtensionsStringEXT = macdrv_wglGetExtensionsStringEXT;
2964
2965     register_extension("WGL_EXT_swap_control");
2966     opengl_funcs.ext.p_wglSwapIntervalEXT = macdrv_wglSwapIntervalEXT;
2967     opengl_funcs.ext.p_wglGetSwapIntervalEXT = macdrv_wglGetSwapIntervalEXT;
2968
2969     /* Presumably identical to [W]GL_ARB_framebuffer_sRGB, above, but clients may
2970        check for either, so register them separately. */
2971     if (gluCheckExtension((GLubyte*)"GL_EXT_framebuffer_sRGB", (GLubyte*)gl_info.glExtensions))
2972         register_extension("WGL_EXT_framebuffer_sRGB");
2973
2974     if (gluCheckExtension((GLubyte*)"GL_EXT_packed_float", (GLubyte*)gl_info.glExtensions))
2975         register_extension("WGL_EXT_pixel_format_packed_float");
2976
2977     /*
2978      * WINE-specific WGL Extensions
2979      */
2980
2981     /* In WineD3D we need the ability to set the pixel format more than once (e.g. after a device reset).
2982      * The default wglSetPixelFormat doesn't allow this, so add our own which allows it.
2983      */
2984     register_extension("WGL_WINE_pixel_format_passthrough");
2985     opengl_funcs.ext.p_wglSetPixelFormatWINE = macdrv_wglSetPixelFormatWINE;
2986 }
2987
2988
2989 static BOOL init_opengl(void)
2990 {
2991     static int init_done;
2992     unsigned int i;
2993     char buffer[200];
2994
2995     if (init_done) return (opengl_handle != NULL);
2996     init_done = 1;
2997
2998     TRACE("()\n");
2999
3000     dc_pbuffers = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
3001     if (!dc_pbuffers)
3002     {
3003         WARN("CFDictionaryCreateMutable failed\n");
3004         return FALSE;
3005     }
3006
3007     opengl_handle = wine_dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY|RTLD_LOCAL|RTLD_NOLOAD, buffer, sizeof(buffer));
3008     if (!opengl_handle)
3009     {
3010         ERR("Failed to load OpenGL: %s\n", buffer);
3011         ERR("OpenGL support is disabled.\n");
3012         return FALSE;
3013     }
3014
3015     for (i = 0; i < sizeof(opengl_func_names)/sizeof(opengl_func_names[0]); i++)
3016     {
3017         if (!(((void **)&opengl_funcs.gl)[i] = wine_dlsym(opengl_handle, opengl_func_names[i], NULL, 0)))
3018         {
3019             ERR("%s not found in OpenGL, disabling.\n", opengl_func_names[i]);
3020             goto failed;
3021         }
3022     }
3023
3024     /* redirect some standard OpenGL functions */
3025 #define REDIRECT(func) \
3026     do { p##func = opengl_funcs.gl.p_##func; opengl_funcs.gl.p_##func = macdrv_##func; } while(0)
3027     REDIRECT(glCopyPixels);
3028     REDIRECT(glReadPixels);
3029     REDIRECT(glViewport);
3030 #undef REDIRECT
3031
3032     /* redirect some OpenGL extension functions */
3033 #define REDIRECT(func) \
3034     do { if (opengl_funcs.ext.p_##func) { p##func = opengl_funcs.ext.p_##func; opengl_funcs.ext.p_##func = macdrv_##func; } } while(0)
3035     REDIRECT(glCopyColorTable);
3036 #undef REDIRECT
3037
3038     if (!init_gl_info())
3039         goto failed;
3040
3041     load_extensions();
3042     if (!init_pixel_formats())
3043         goto failed;
3044
3045     return TRUE;
3046
3047 failed:
3048     wine_dlclose(opengl_handle, NULL, 0);
3049     opengl_handle = NULL;
3050     return FALSE;
3051 }
3052
3053
3054 /***********************************************************************
3055  *              sync_gl_view
3056  *
3057  * Synchronize the Mac GL view position with the Windows child window
3058  * position.
3059  */
3060 void sync_gl_view(struct macdrv_win_data *data)
3061 {
3062     RECT rect;
3063
3064     TRACE("hwnd %p gl_view %p\n", data->hwnd, data->gl_view);
3065
3066     if (!data->gl_view) return;
3067
3068     if (get_gl_view_window_rect(data, NULL, &rect) && memcmp(&data->gl_rect, &rect, sizeof(rect)))
3069     {
3070         TRACE("Setting GL view %p frame to %s\n", data->gl_view, wine_dbgstr_rect(&rect));
3071         macdrv_set_view_window_and_frame(data->gl_view, NULL, cgrect_from_rect(rect));
3072         data->gl_rect = rect;
3073     }
3074 }
3075
3076
3077 static int get_dc_pixel_format(HDC hdc)
3078 {
3079     int format;
3080     HWND hwnd;
3081
3082     if ((hwnd = WindowFromDC(hdc)))
3083     {
3084         struct macdrv_win_data *data;
3085
3086         if (!(data = get_win_data(hwnd)))
3087         {
3088             FIXME("DC for window %p of other process: not implemented\n", hwnd);
3089             return 0;
3090         }
3091
3092         format = data->pixel_format;
3093         release_win_data(data);
3094     }
3095     else
3096     {
3097         struct wgl_pbuffer *pbuffer;
3098
3099         EnterCriticalSection(&dc_pbuffers_section);
3100         pbuffer = (struct wgl_pbuffer*)CFDictionaryGetValue(dc_pbuffers, hdc);
3101         if (pbuffer)
3102             format = pbuffer->format;
3103         else
3104         {
3105             WARN("no window or pbuffer for DC %p\n", hdc);
3106             format = 0;
3107         }
3108         LeaveCriticalSection(&dc_pbuffers_section);
3109     }
3110
3111     return format;
3112 }
3113
3114
3115 /**********************************************************************
3116  *              create_context
3117  */
3118 static BOOL create_context(struct wgl_context *context, CGLContextObj share)
3119 {
3120     const pixel_format *pf;
3121     CGLPixelFormatAttribute attribs[64];
3122     int n = 0;
3123     CGLPixelFormatObj pix;
3124     GLint virtualScreens;
3125     CGLError err;
3126     long swap_interval;
3127
3128     pf = get_pixel_format(context->format, TRUE /* non-displayable */);
3129     if (!pf)
3130     {
3131         ERR("Invalid pixel format %d, expect problems!\n", context->format);
3132         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
3133         return FALSE;
3134     }
3135
3136     attribs[n++] = kCGLPFAMinimumPolicy;
3137     attribs[n++] = kCGLPFAClosestPolicy;
3138
3139     if (pf->accelerated)
3140     {
3141         attribs[n++] = kCGLPFAAccelerated;
3142         attribs[n++] = kCGLPFANoRecovery;
3143     }
3144     else
3145     {
3146         attribs[n++] = kCGLPFARendererID;
3147         attribs[n++] = kCGLRendererGenericFloatID;
3148     }
3149
3150     if (pf->double_buffer)
3151         attribs[n++] = kCGLPFADoubleBuffer;
3152
3153     attribs[n++] = kCGLPFAAuxBuffers;
3154     attribs[n++] = pf->aux_buffers;
3155
3156     attribs[n++] = kCGLPFAColorSize;
3157     attribs[n++] = color_modes[pf->color_mode].color_bits;
3158     attribs[n++] = kCGLPFAAlphaSize;
3159     attribs[n++] = color_modes[pf->color_mode].alpha_bits;
3160     if (color_modes[pf->color_mode].is_float)
3161         attribs[n++] = kCGLPFAColorFloat;
3162
3163     attribs[n++] = kCGLPFADepthSize;
3164     attribs[n++] = pf->depth_bits;
3165
3166     attribs[n++] = kCGLPFAStencilSize;
3167     attribs[n++] = pf->stencil_bits;
3168
3169     if (pf->stereo)
3170         attribs[n++] = kCGLPFAStereo;
3171
3172     if (pf->accum_mode)
3173     {
3174         attribs[n++] = kCGLPFAAccumSize;
3175         attribs[n++] = color_modes[pf->accum_mode - 1].color_bits;
3176     }
3177
3178     if (pf->window)
3179         attribs[n++] = kCGLPFAWindow;
3180     if (pf->pbuffer)
3181         attribs[n++] = kCGLPFAPBuffer;
3182
3183     if (pf->sample_buffers && pf->samples)
3184     {
3185         attribs[n++] = kCGLPFASampleBuffers;
3186         attribs[n++] = pf->sample_buffers;
3187         attribs[n++] = kCGLPFASamples;
3188         attribs[n++] = pf->samples;
3189     }
3190
3191     if (pf->backing_store)
3192         attribs[n++] = kCGLPFABackingStore;
3193
3194     attribs[n] = 0;
3195
3196     err = CGLChoosePixelFormat(attribs, &pix, &virtualScreens);
3197     if (err != kCGLNoError || !pix)
3198     {
3199         WARN("CGLChoosePixelFormat() failed with error %d %s\n", err, CGLErrorString(err));
3200         return FALSE;
3201     }
3202
3203     err = CGLCreateContext(pix, share, &context->cglcontext);
3204     CGLReleasePixelFormat(pix);
3205     if (err != kCGLNoError || !context->cglcontext)
3206     {
3207         context->cglcontext = NULL;
3208         WARN("CGLCreateContext() failed with error %d %s\n", err, CGLErrorString(err));
3209         return FALSE;
3210     }
3211
3212     /* According to the WGL_EXT_swap_control docs, the default swap interval for
3213        a context is 1.  CGL contexts default to 0, so we need to set it. */
3214     swap_interval = 1;
3215     err = CGLSetParameter(context->cglcontext, kCGLCPSwapInterval, (GLint*)&swap_interval);
3216     if (err != kCGLNoError)
3217         WARN("CGLSetParameter(kCGLCPSwapInterval) failed with error %d %s; leaving un-vsynced\n", err, CGLErrorString(err));
3218
3219     context->context = macdrv_create_opengl_context(context->cglcontext);
3220     CGLReleaseContext(context->cglcontext);
3221     if (!context->context)
3222     {
3223         WARN("macdrv_create_opengl_context() failed\n");
3224         return FALSE;
3225     }
3226
3227     TRACE("created context %p/%p/%p\n", context, context->context, context->cglcontext);
3228
3229     return TRUE;
3230 }
3231
3232
3233 /**********************************************************************
3234  *              macdrv_wglDescribePixelFormat
3235  */
3236 int macdrv_wglDescribePixelFormat(HDC hdc, int fmt, UINT size, PIXELFORMATDESCRIPTOR *descr)
3237 {
3238     int ret = nb_formats;
3239     const pixel_format *pf;
3240     const struct color_mode *mode;
3241
3242     TRACE("hdc %p fmt %d size %u descr %p\n", hdc, fmt, size, descr);
3243
3244     if (fmt <= 0 || fmt > ret) return ret;
3245     if (size < sizeof(*descr)) return 0;
3246
3247     pf = &pixel_formats[fmt - 1];
3248
3249     memset(descr, 0, sizeof(*descr));
3250     descr->nSize            = sizeof(*descr);
3251     descr->nVersion         = 1;
3252
3253     descr->dwFlags          = PFD_SUPPORT_OPENGL;
3254     if (pf->window)         descr->dwFlags |= PFD_DRAW_TO_WINDOW;
3255     if (!pf->accelerated)   descr->dwFlags |= PFD_GENERIC_FORMAT;
3256     if (pf->double_buffer)  descr->dwFlags |= PFD_DOUBLEBUFFER;
3257     if (pf->stereo)         descr->dwFlags |= PFD_STEREO;
3258     if (pf->backing_store)  descr->dwFlags |= PFD_SWAP_COPY;
3259
3260     descr->iPixelType       = PFD_TYPE_RGBA;
3261
3262     mode = &color_modes[pf->color_mode];
3263     /* If the mode doesn't have alpha, return bits per pixel instead of color bits.
3264        On Windows, color bits sometimes exceeds r+g+b (e.g. it's 32 for an
3265        R8G8B8A0 pixel format).  If an app depends on that and expects that
3266        cColorBits >= 32 for such a pixel format, we need to accommodate that. */
3267     if (mode->alpha_bits)
3268         descr->cColorBits   = mode->color_bits;
3269     else
3270         descr->cColorBits   = mode->bits_per_pixel;
3271     descr->cRedBits         = mode->red_bits;
3272     descr->cRedShift        = mode->red_shift;
3273     descr->cGreenBits       = mode->green_bits;
3274     descr->cGreenShift      = mode->green_shift;
3275     descr->cBlueBits        = mode->blue_bits;
3276     descr->cBlueShift       = mode->blue_shift;
3277     descr->cAlphaBits       = mode->alpha_bits;
3278     descr->cAlphaShift      = mode->alpha_shift;
3279
3280     if (pf->accum_mode)
3281     {
3282         mode = &color_modes[pf->accum_mode - 1];
3283         descr->cAccumBits       = mode->color_bits;
3284         descr->cAccumRedBits    = mode->red_bits;
3285         descr->cAccumGreenBits  = mode->green_bits;
3286         descr->cAccumBlueBits   = mode->blue_bits;
3287         descr->cAccumAlphaBits  = mode->alpha_bits;
3288     }
3289
3290     descr->cDepthBits       = pf->depth_bits;
3291     descr->cStencilBits     = pf->stencil_bits;
3292     descr->cAuxBuffers      = pf->aux_buffers;
3293     descr->iLayerType       = PFD_MAIN_PLANE;
3294     return ret;
3295 }
3296
3297 /***********************************************************************
3298  *              macdrv_wglCopyContext
3299  */
3300 static BOOL macdrv_wglCopyContext(struct wgl_context *src, struct wgl_context *dst, UINT mask)
3301 {
3302     CGLError err;
3303
3304     TRACE("src %p dst %p mask %x\n", src, dst, mask);
3305
3306     err = CGLCopyContext(src->cglcontext, dst->cglcontext, mask);
3307     if (err != kCGLNoError)
3308         WARN("CGLCopyContext() failed with err %d %s\n", err, CGLErrorString(err));
3309     return (err == kCGLNoError);
3310 }
3311
3312 /***********************************************************************
3313  *              macdrv_wglCreateContext
3314  */
3315 static struct wgl_context *macdrv_wglCreateContext(HDC hdc)
3316 {
3317     int format;
3318     struct wgl_context *context;
3319
3320     TRACE("hdc %p\n", hdc);
3321
3322     format = get_dc_pixel_format(hdc);
3323
3324     if (!is_valid_pixel_format(format))
3325     {
3326         ERR("Invalid pixel format %d, expect problems!\n", format);
3327         SetLastError(ERROR_INVALID_PIXEL_FORMAT);
3328         return NULL;
3329     }
3330
3331     if (!(context = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context)))) return NULL;
3332
3333     context->format = format;
3334     if (!create_context(context, NULL))
3335     {
3336         HeapFree(GetProcessHeap(), 0, context);
3337         return NULL;
3338     }
3339
3340     return context;
3341 }
3342
3343 /***********************************************************************
3344  *              macdrv_wglDeleteContext
3345  */
3346 static void macdrv_wglDeleteContext(struct wgl_context *context)
3347 {
3348     TRACE("deleting context %p/%p/%p\n", context, context->context, context->cglcontext);
3349     macdrv_dispose_opengl_context(context->context);
3350     HeapFree(GetProcessHeap(), 0, context);
3351 }
3352
3353 /***********************************************************************
3354  *              macdrv_wglGetPixelFormat
3355  */
3356 static int macdrv_wglGetPixelFormat(HDC hdc)
3357 {
3358     int format;
3359
3360     format = get_dc_pixel_format(hdc);
3361
3362     if (!is_valid_pixel_format(format))  /* not set yet */
3363         format = 0;
3364     else if (!is_displayable_pixel_format(format))
3365     {
3366         /* Non-displayable formats can't be used with traditional WGL calls.
3367          * As has been verified on Windows GetPixelFormat doesn't fail but returns pixel format 1. */
3368         format = 1;
3369     }
3370
3371     TRACE(" hdc %p -> %d\n", hdc, format);
3372     return format;
3373 }
3374
3375 /***********************************************************************
3376  *              macdrv_wglGetProcAddress
3377  */
3378 static PROC macdrv_wglGetProcAddress(const char *proc)
3379 {
3380     void *ret;
3381
3382     if (!strncmp(proc, "wgl", 3)) return NULL;
3383     ret = wine_dlsym(opengl_handle, proc, NULL, 0);
3384     if (ret)
3385     {
3386         if (TRACE_ON(wgl))
3387         {
3388             Dl_info info;
3389             if (dladdr(ret, &info))
3390                 TRACE("%s -> %s from %s\n", proc, info.dli_sname, info.dli_fname);
3391             else
3392                 TRACE("%s -> %p (no library info)\n", proc, ret);
3393         }
3394     }
3395     else
3396         WARN("failed to find proc %s\n", debugstr_a(proc));
3397     return ret;
3398 }
3399
3400 /***********************************************************************
3401  *              macdrv_wglMakeCurrent
3402  */
3403 static BOOL macdrv_wglMakeCurrent(HDC hdc, struct wgl_context *context)
3404 {
3405     TRACE("hdc %p context %p/%p/%p\n", hdc, context, (context ? context->context : NULL),
3406           (context ? context->cglcontext : NULL));
3407
3408     return macdrv_wglMakeContextCurrentARB(hdc, hdc, context);
3409 }
3410
3411 /**********************************************************************
3412  *              macdrv_wglSetPixelFormat
3413  */
3414 static BOOL macdrv_wglSetPixelFormat(HDC hdc, int fmt, const PIXELFORMATDESCRIPTOR *descr)
3415 {
3416     return set_pixel_format(hdc, fmt, FALSE);
3417 }
3418
3419 /***********************************************************************
3420  *              macdrv_wglShareLists
3421  */
3422 static BOOL macdrv_wglShareLists(struct wgl_context *org, struct wgl_context *dest)
3423 {
3424     macdrv_opengl_context saved_context;
3425     CGLContextObj saved_cglcontext;
3426
3427     TRACE("org %p dest %p\n", org, dest);
3428
3429     /* Sharing of display lists works differently in Mac OpenGL and WGL.  In Mac OpenGL it is done
3430      * at context creation time but in case of WGL it is done using wglShareLists.
3431      *
3432      * The approach is to create a Mac OpenGL context in wglCreateContext / wglCreateContextAttribsARB
3433      * and when a program requests sharing we recreate the destination context if it hasn't been made
3434      * current or when it hasn't shared display lists before.
3435      */
3436
3437     if (dest->has_been_current)
3438     {
3439         WARN("could not share display lists, the destination context has been current already\n");
3440         return FALSE;
3441     }
3442     else if (dest->sharing)
3443     {
3444         WARN("could not share display lists because dest has already shared lists before\n");
3445         return FALSE;
3446     }
3447
3448     /* Re-create the Mac context and share display lists */
3449     saved_context = dest->context;
3450     saved_cglcontext = dest->cglcontext;
3451     dest->context = NULL;
3452     dest->cglcontext = NULL;
3453     if (!create_context(dest, org->cglcontext))
3454     {
3455         dest->context = saved_context;
3456         dest->cglcontext = saved_cglcontext;
3457         return FALSE;
3458     }
3459
3460     /* Implicitly disposes of saved_cglcontext. */
3461     macdrv_dispose_opengl_context(saved_context);
3462
3463     TRACE("re-created OpenGL context %p/%p/%p sharing lists with context %p/%p/%p\n",
3464           dest, dest->context, dest->cglcontext, org, org->context, org->cglcontext);
3465
3466     org->sharing = TRUE;
3467     dest->sharing = TRUE;
3468
3469     return TRUE;
3470 }
3471
3472 /**********************************************************************
3473  *              macdrv_wglSwapBuffers
3474  */
3475 static BOOL macdrv_wglSwapBuffers(HDC hdc)
3476 {
3477     struct wgl_context *context = NtCurrentTeb()->glContext;
3478
3479     TRACE("hdc %p context %p/%p/%p\n", hdc, context, (context ? context->context : NULL),
3480           (context ? context->cglcontext : NULL));
3481
3482     if (!context)
3483     {
3484         SetLastError(ERROR_INVALID_HANDLE);
3485         return FALSE;
3486     }
3487
3488     macdrv_flush_opengl_context(context->context);
3489     return TRUE;
3490 }
3491
3492 static struct opengl_funcs opengl_funcs =
3493 {
3494     {
3495         macdrv_wglCopyContext,          /* p_wglCopyContext */
3496         macdrv_wglCreateContext,        /* p_wglCreateContext */
3497         macdrv_wglDeleteContext,        /* p_wglDeleteContext */
3498         macdrv_wglDescribePixelFormat,  /* p_wglDescribePixelFormat */
3499         macdrv_wglGetPixelFormat,       /* p_wglGetPixelFormat */
3500         macdrv_wglGetProcAddress,       /* p_wglGetProcAddress */
3501         macdrv_wglMakeCurrent,          /* p_wglMakeCurrent */
3502         macdrv_wglSetPixelFormat,       /* p_wglSetPixelFormat */
3503         macdrv_wglShareLists,           /* p_wglShareLists */
3504         macdrv_wglSwapBuffers,          /* p_wglSwapBuffers */
3505     }
3506 };
3507
3508 /**********************************************************************
3509  *              macdrv_wine_get_wgl_driver
3510  */
3511 struct opengl_funcs *macdrv_wine_get_wgl_driver(PHYSDEV dev, UINT version)
3512 {
3513     if (version != WINE_WGL_DRIVER_VERSION)
3514     {
3515         ERR("version mismatch, opengl32 wants %u but macdrv has %u\n", version, WINE_WGL_DRIVER_VERSION);
3516         return NULL;
3517     }
3518
3519     if (!init_opengl()) return (void *)-1;
3520
3521     return &opengl_funcs;
3522 }