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