1 /*
2  * Some tests for OpenGL functions
3  *
4  * Copyright (C) 2007-2008 Roderick Colenbrander
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <windows.h>
22 #include <wingdi.h>
23 #include "wine/test.h"
24 #include "wine/wgl.h"
25 
26 #define MAX_FORMATS 256
27 
28 /* WGL_ARB_create_context */
29 static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList);
30 
31 /* WGL_ARB_extensions_string */
32 static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC);
33 static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC);
34 
35 /* WGL_ARB_make_current_read */
36 static BOOL (WINAPI *pwglMakeContextCurrentARB)(HDC hdraw, HDC hread, HGLRC hglrc);
37 static HDC (WINAPI *pwglGetCurrentReadDCARB)(void);
38 
39 /* WGL_ARB_pixel_format */
40 static BOOL (WINAPI *pwglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *);
41 static BOOL (WINAPI *pwglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int *, int *);
42 
43 /* WGL_ARB_pbuffer */
44 static HPBUFFERARB (WINAPI *pwglCreatePbufferARB)(HDC, int, int, int, const int *);
45 static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB);
46 
47 /* WGL_EXT_swap_control */
48 static BOOL (WINAPI *pwglSwapIntervalEXT)(int interval);
49 static int (WINAPI *pwglGetSwapIntervalEXT)(void);
50 
51 /* GL_ARB_debug_output */
52 static void (WINAPI *pglDebugMessageCallbackARB)(void *, void *);
53 static void (WINAPI *pglDebugMessageControlARB)(GLenum, GLenum, GLenum, GLsizei, const GLuint *, GLboolean);
54 static void (WINAPI *pglDebugMessageInsertARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const char *);
55 
56 static const char* wgl_extensions = NULL;
57 
58 static void init_functions(void)
59 {
60 #define GET_PROC(func) \
61     p ## func = (void*)wglGetProcAddress(#func); \
62     if(!p ## func) \
63       trace("wglGetProcAddress(%s) failed\n", #func);
64 
65     /* WGL_ARB_create_context */
66     GET_PROC(wglCreateContextAttribsARB);
67 
68     /* WGL_ARB_extensions_string */
69     GET_PROC(wglGetExtensionsStringARB)
70 
71     /* WGL_ARB_make_current_read */
72     GET_PROC(wglMakeContextCurrentARB);
73     GET_PROC(wglGetCurrentReadDCARB);
74 
75     /* WGL_ARB_pixel_format */
76     GET_PROC(wglChoosePixelFormatARB)
77     GET_PROC(wglGetPixelFormatAttribivARB)
78 
79     /* WGL_ARB_pbuffer */
80     GET_PROC(wglCreatePbufferARB)
81     GET_PROC(wglGetPbufferDCARB)
82     GET_PROC(wglReleasePbufferDCARB)
83 
84     /* WGL_EXT_swap_control */
85     GET_PROC(wglSwapIntervalEXT)
86     GET_PROC(wglGetSwapIntervalEXT)
87 
88     /* GL_ARB_debug_output */
89     GET_PROC(glDebugMessageCallbackARB)
90     GET_PROC(glDebugMessageControlARB)
91     GET_PROC(glDebugMessageInsertARB)
92 
93 #undef GET_PROC
94 }
95 
96 static BOOL gl_extension_supported(const char *extensions, const char *extension_string)
97 {
98     size_t ext_str_len = strlen(extension_string);
99 
100     while (*extensions)
101     {
102         const char *start;
103         size_t len;
104 
105         while (isspace(*extensions))
106             ++extensions;
107         start = extensions;
108         while (!isspace(*extensions) && *extensions)
109             ++extensions;
110 
111         len = extensions - start;
112         if (!len)
113             continue;
114 
115         if (len == ext_str_len && !memcmp(start, extension_string, ext_str_len))
116         {
117             return TRUE;
118         }
119     }
120     return FALSE;
121 }
122 
123 static void test_pbuffers(HDC hdc)
124 {
125     const int iAttribList[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, /* Request pbuffer support */
126                                 0 };
127     int iFormats[MAX_FORMATS];
128     unsigned int nOnscreenFormats;
129     unsigned int nFormats;
130     int i, res;
131     int iPixelFormat = 0;
132 
133     nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL);
134 
135     /* When you want to render to a pbuffer you need to call wglGetPbufferDCARB which
136      * returns a 'magic' HDC which you can then pass to wglMakeCurrent to switch rendering
137      * to the pbuffer. Below some tests are performed on what happens if you use standard WGL calls
138      * on this 'magic' HDC for both a pixelformat that support onscreen and offscreen rendering
139      * and a pixelformat that's only available for offscreen rendering (this means that only
140      * wglChoosePixelFormatARB and friends know about the format.
141      *
142      * The first thing we need are pixelformats with pbuffer capabilities.
143      */
144     res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats);
145     if(res <= 0)
146     {
147         skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n");
148         return;
149     }
150     trace("nOnscreenFormats: %d\n", nOnscreenFormats);
151     trace("Total number of pbuffer capable pixelformats: %d\n", nFormats);
152 
153     /* Try to select an onscreen pixelformat out of the list */
154     for(i=0; i < nFormats; i++)
155     {
156         /* Check if the format is onscreen, if it is choose it */
157         if(iFormats[i] <= nOnscreenFormats)
158         {
159             iPixelFormat = iFormats[i];
160             trace("Selected iPixelFormat=%d\n", iPixelFormat);
161             break;
162         }
163     }
164 
165     /* A video driver supports a large number of onscreen and offscreen pixelformats.
166      * The traditional WGL calls only see a subset of the whole pixelformat list. First
167      * of all they only see the onscreen formats (the offscreen formats are at the end of the
168      * pixelformat list) and second extended pixelformat capabilities are hidden from the
169      * standard WGL calls. Only functions that depend on WGL_ARB_pixel_format can see them.
170      *
171      * Below we check if the pixelformat is also supported onscreen.
172      */
173     if(iPixelFormat != 0)
174     {
175         HDC pbuffer_hdc;
176         int attrib = 0;
177         HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, &attrib);
178         if(!pbuffer)
179             skip("Pbuffer creation failed!\n");
180 
181         /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
182         pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
183         res = GetPixelFormat(pbuffer_hdc);
184         ok(res == iPixelFormat, "Unexpected iPixelFormat=%d returned by GetPixelFormat for format %d\n", res, iPixelFormat);
185         trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
186         trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
187 
188         pwglReleasePbufferDCARB(pbuffer, pbuffer_hdc);
189     }
190     else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n");
191 
192     /* Search for a real offscreen format */
193     for(i=0, iPixelFormat=0; i<nFormats; i++)
194     {
195         if(iFormats[i] > nOnscreenFormats)
196         {
197             iPixelFormat = iFormats[i];
198             trace("Selected iPixelFormat: %d\n", iPixelFormat);
199             break;
200         }
201     }
202 
203     if(iPixelFormat != 0)
204     {
205         HDC pbuffer_hdc;
206         HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL);
207         if(!pbuffer)
208             skip("Pbuffer creation failed!\n");
209 
210         /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
211         pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
212         res = GetPixelFormat(pbuffer_hdc);
213 
214         ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat);
215         trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
216         trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
217         pwglReleasePbufferDCARB(pbuffer, hdc);
218     }
219     else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n");
220 }
221 
222 static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd, PIXELFORMATDESCRIPTOR *fmt)
223 {
224     int pf;
225     HDC hdc;
226     HWND hwnd;
227 
228     hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
229             NULL, NULL);
230     if (!hwnd)
231         return 0;
232 
233     hdc = GetDC( hwnd );
234     pf = ChoosePixelFormat( hdc, pfd );
235     if (pf && fmt)
236     {
237         memset(fmt, 0, sizeof(*fmt));
238         ok(DescribePixelFormat( hdc, pf, sizeof(*fmt), fmt ),
239            "DescribePixelFormat failed with error: %u\n", GetLastError());
240     }
241     ReleaseDC( hwnd, hdc );
242     DestroyWindow( hwnd );
243 
244     return pf;
245 }
246 
247 static void test_choosepixelformat(void)
248 {
249     PIXELFORMATDESCRIPTOR pfd = {
250         sizeof(PIXELFORMATDESCRIPTOR),
251         1,                     /* version */
252         PFD_DRAW_TO_WINDOW |
253         PFD_SUPPORT_OPENGL |
254         PFD_TYPE_RGBA,
255         0,                     /* color depth */
256         0, 0, 0, 0, 0, 0,      /* color bits */
257         0,                     /* alpha buffer */
258         0,                     /* shift bit */
259         0,                     /* accumulation buffer */
260         0, 0, 0, 0,            /* accum bits */
261         0,                     /* z-buffer */
262         0,                     /* stencil buffer */
263         0,                     /* auxiliary buffer */
264         PFD_MAIN_PLANE,        /* main layer */
265         0,                     /* reserved */
266         0, 0, 0                /* layer masks */
267     };
268     PIXELFORMATDESCRIPTOR ret_fmt;
269 
270     ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
271     pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
272     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
273     pfd.dwFlags |= PFD_STEREO_DONTCARE;
274     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
275     pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
276     ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
277     pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
278     pfd.iPixelType = 32;
279     ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 32 failed\n" );
280     ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
281     pfd.iPixelType = 33;
282     ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 33 failed\n" );
283     ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
284     pfd.iPixelType = 15;
285     ok( test_pfd(&pfd, &ret_fmt), "Invalid pixel format 15 failed\n" );
286     ok( ret_fmt.iPixelType == PFD_TYPE_RGBA, "Expected pixel type PFD_TYPE_RGBA, got %d\n", ret_fmt.iPixelType );
287     pfd.iPixelType = PFD_TYPE_RGBA;
288 
289     pfd.cColorBits = 32;
290     ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
291     pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
292     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
293     pfd.dwFlags |= PFD_STEREO_DONTCARE;
294     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
295     pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
296     ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
297     pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
298     pfd.cColorBits = 0;
299 
300     pfd.cAlphaBits = 8;
301     ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
302     pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
303     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
304     pfd.dwFlags |= PFD_STEREO_DONTCARE;
305     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
306     pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
307     ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
308     pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
309     pfd.cAlphaBits = 0;
310 
311     pfd.cStencilBits = 8;
312     ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
313     pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
314     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
315     pfd.dwFlags |= PFD_STEREO_DONTCARE;
316     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
317     pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
318     ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
319     pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
320     pfd.cStencilBits = 0;
321 
322     pfd.cAuxBuffers = 1;
323     ok( test_pfd(&pfd, NULL), "Simple pfd failed\n" );
324     pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE;
325     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE failed\n" );
326     pfd.dwFlags |= PFD_STEREO_DONTCARE;
327     ok( test_pfd(&pfd, NULL), "PFD_DOUBLEBUFFER_DONTCARE|PFD_STEREO_DONTCARE failed\n" );
328     pfd.dwFlags &= ~PFD_DOUBLEBUFFER_DONTCARE;
329     ok( test_pfd(&pfd, NULL), "PFD_STEREO_DONTCARE failed\n" );
330     pfd.dwFlags &= ~PFD_STEREO_DONTCARE;
331     pfd.cAuxBuffers = 0;
332 }
333 
334 static void WINAPI gl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity,
335                                              GLsizei length, const GLchar *message, const void *userParam)
336 {
337     DWORD *count = (DWORD *)userParam;
338     (*count)++;
339 }
340 
341 static void test_debug_message_callback(void)
342 {
343     static const char testmsg[] = "Hello World";
344     DWORD count;
345 
346     if (!pglDebugMessageCallbackARB)
347     {
348         skip("glDebugMessageCallbackARB not supported\n");
349         return;
350     }
351 
352     glEnable(GL_DEBUG_OUTPUT);
353     glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
354 
355     pglDebugMessageCallbackARB(gl_debug_message_callback, &count);
356     pglDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE);
357 
358     count = 0;
359     pglDebugMessageInsertARB(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0x42424242,
360                              GL_DEBUG_SEVERITY_LOW, sizeof(testmsg), testmsg);
361     ok(count == 1, "expected count == 1, got %u\n", count);
362 
363     glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
364     glDisable(GL_DEBUG_OUTPUT);
365 }
366 
367 static void test_setpixelformat(HDC winhdc)
368 {
369     int res = 0;
370     int nCfgs;
371     int pf;
372     int i;
373     HWND hwnd;
374     PIXELFORMATDESCRIPTOR pfd = {
375         sizeof(PIXELFORMATDESCRIPTOR),
376         1,                     /* version */
377         PFD_DRAW_TO_WINDOW |
378         PFD_SUPPORT_OPENGL |
379         PFD_DOUBLEBUFFER,
380         PFD_TYPE_RGBA,
381         24,                    /* 24-bit color depth */
382         0, 0, 0, 0, 0, 0,      /* color bits */
383         0,                     /* alpha buffer */
384         0,                     /* shift bit */
385         0,                     /* accumulation buffer */
386         0, 0, 0, 0,            /* accum bits */
387         32,                    /* z-buffer */
388         0,                     /* stencil buffer */
389         0,                     /* auxiliary buffer */
390         PFD_MAIN_PLANE,        /* main layer */
391         0,                     /* reserved */
392         0, 0, 0                /* layer masks */
393     };
394 
395     HDC hdc = GetDC(0);
396     ok(hdc != 0, "GetDC(0) failed!\n");
397 
398     /* This should pass even on the main device context */
399     pf = ChoosePixelFormat(hdc, &pfd);
400     ok(pf != 0, "ChoosePixelFormat failed on main device context\n");
401 
402     /* SetPixelFormat on the main device context 'X root window' should fail,
403      * but some broken drivers allow it
404      */
405     res = SetPixelFormat(hdc, pf, &pfd);
406     trace("SetPixelFormat on main device context %s\n", res ? "succeeded" : "failed");
407 
408     /* Setting the same format that was set on the HDC is allowed; other
409        formats fail */
410     nCfgs = DescribePixelFormat(winhdc, 0, 0, NULL);
411     pf = GetPixelFormat(winhdc);
412     for(i = 1;i <= nCfgs;i++)
413     {
414         int res = SetPixelFormat(winhdc, i, NULL);
415         if(i == pf) ok(res, "Failed to set the same pixel format\n");
416         else ok(!res, "Unexpectedly set an alternate pixel format\n");
417     }
418 
419     hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
420             NULL, NULL);
421     ok(hwnd != NULL, "err: %d\n", GetLastError());
422     if (hwnd)
423     {
424         HDC hdc = GetDC( hwnd );
425         pf = ChoosePixelFormat( hdc, &pfd );
426         ok( pf != 0, "ChoosePixelFormat failed\n" );
427         res = SetPixelFormat( hdc, pf, &pfd );
428         ok( res != 0, "SetPixelFormat failed\n" );
429         i = GetPixelFormat( hdc );
430         ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
431         ReleaseDC( hwnd, hdc );
432         hdc = GetWindowDC( hwnd );
433         i = GetPixelFormat( hdc );
434         ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
435         ReleaseDC( hwnd, hdc );
436         DestroyWindow( hwnd );
437         /* check various calls with invalid hdc */
438         SetLastError( 0xdeadbeef );
439         i = GetPixelFormat( hdc );
440         ok( i == 0, "GetPixelFormat succeeded\n" );
441         ok( GetLastError() == ERROR_INVALID_PIXEL_FORMAT, "wrong error %u\n", GetLastError() );
442         SetLastError( 0xdeadbeef );
443         res = SetPixelFormat( hdc, pf, &pfd );
444         ok( !res, "SetPixelFormat succeeded\n" );
445         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
446         SetLastError( 0xdeadbeef );
447         res = DescribePixelFormat( hdc, 0, 0, NULL );
448         ok( !res, "DescribePixelFormat succeeded\n" );
449         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
450         SetLastError( 0xdeadbeef );
451         pf = ChoosePixelFormat( hdc, &pfd );
452         ok( !pf, "ChoosePixelFormat succeeded\n" );
453         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
454         SetLastError( 0xdeadbeef );
455         res = SwapBuffers( hdc );
456         ok( !res, "SwapBuffers succeeded\n" );
457         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
458         SetLastError( 0xdeadbeef );
459         ok( !wglCreateContext( hdc ), "CreateContext succeeded\n" );
460         ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
461     }
462 
463     hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
464             NULL, NULL);
465     ok(hwnd != NULL, "err: %d\n", GetLastError());
466     if (hwnd)
467     {
468         HDC hdc = GetWindowDC( hwnd );
469         pf = ChoosePixelFormat( hdc, &pfd );
470         ok( pf != 0, "ChoosePixelFormat failed\n" );
471         res = SetPixelFormat( hdc, pf, &pfd );
472         ok( res != 0, "SetPixelFormat failed\n" );
473         i = GetPixelFormat( hdc );
474         ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
475         ReleaseDC( hwnd, hdc );
476         DestroyWindow( hwnd );
477     }
478 }
479 
480 static void test_sharelists(HDC winhdc)
481 {
482     HGLRC hglrc1, hglrc2, hglrc3;
483     BOOL res;
484 
485     hglrc1 = wglCreateContext(winhdc);
486     res = wglShareLists(0, 0);
487     ok(res == FALSE, "Sharing display lists for no contexts passed!\n");
488 
489     /* Test 1: Create a context and just share lists without doing anything special */
490     hglrc2 = wglCreateContext(winhdc);
491     if(hglrc2)
492     {
493         res = wglShareLists(hglrc1, hglrc2);
494         ok(res, "Sharing of display lists failed\n");
495         wglDeleteContext(hglrc2);
496     }
497 
498     /* Test 2: Share display lists with a 'destination' context which has been made current */
499     hglrc2 = wglCreateContext(winhdc);
500     if(hglrc2)
501     {
502         res = wglMakeCurrent(winhdc, hglrc2);
503         ok(res, "Make current failed\n");
504         res = wglShareLists(hglrc1, hglrc2);
505         ok(res, "Sharing display lists with a destination context which has been made current failed\n");
506         wglMakeCurrent(0, 0);
507         wglDeleteContext(hglrc2);
508     }
509 
510     /* Test 3: Share display lists with a context which already shares display lists with another context.
511      * According to MSDN the second parameter cannot share any display lists but some buggy drivers might allow it */
512     hglrc3 = wglCreateContext(winhdc);
513     if(hglrc3)
514     {
515         res = wglShareLists(hglrc3, hglrc1);
516         ok(res == FALSE, "Sharing of display lists passed for a context which already shared lists before\n");
517         wglDeleteContext(hglrc3);
518     }
519 
520     /* Test 4: Share display lists with a 'source' context which has been made current */
521     hglrc2 = wglCreateContext(winhdc);
522     if(hglrc2)
523     {
524         res = wglMakeCurrent(winhdc, hglrc1);
525         ok(res, "Make current failed\n");
526         res = wglShareLists(hglrc1, hglrc2);
527         ok(res, "Sharing display lists with a source context which has been made current failed\n");
528         wglMakeCurrent(0, 0);
529         wglDeleteContext(hglrc2);
530     }
531 }
532 
533 static void test_makecurrent(HDC winhdc)
534 {
535     BOOL ret;
536     HGLRC hglrc;
537 
538     hglrc = wglCreateContext(winhdc);
539     ok( hglrc != 0, "wglCreateContext failed\n" );
540 
541     ret = wglMakeCurrent( winhdc, hglrc );
542     ok( ret, "wglMakeCurrent failed\n" );
543 
544     ok( wglGetCurrentContext() == hglrc, "wrong context\n" );
545 
546     /* set the same context again */
547     ret = wglMakeCurrent( winhdc, hglrc );
548     ok( ret, "wglMakeCurrent failed\n" );
549 
550     /* check wglMakeCurrent(x, y) after another call to wglMakeCurrent(x, y) */
551     ret = wglMakeCurrent( winhdc, NULL );
552     ok( ret, "wglMakeCurrent failed\n" );
553 
554     ret = wglMakeCurrent( winhdc, NULL );
555     ok( ret, "wglMakeCurrent failed\n" );
556 
557     SetLastError( 0xdeadbeef );
558     ret = wglMakeCurrent( NULL, NULL );
559     ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" );
560     if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE,
561                   "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
562 
563     ret = wglMakeCurrent( winhdc, NULL );
564     ok( ret, "wglMakeCurrent failed\n" );
565 
566     ret = wglMakeCurrent( winhdc, hglrc );
567     ok( ret, "wglMakeCurrent failed\n" );
568 
569     ret = wglMakeCurrent( NULL, NULL );
570     ok( ret, "wglMakeCurrent failed\n" );
571 
572     ok( wglGetCurrentContext() == NULL, "wrong context\n" );
573 
574     SetLastError( 0xdeadbeef );
575     ret = wglMakeCurrent( NULL, NULL );
576     ok( !ret || broken(ret) /* nt4 */, "wglMakeCurrent succeeded\n" );
577     if (!ret) ok( GetLastError() == ERROR_INVALID_HANDLE,
578                   "Expected ERROR_INVALID_HANDLE, got error=%x\n", GetLastError() );
579 
580     ret = wglMakeCurrent( winhdc, hglrc );
581     ok( ret, "wglMakeCurrent failed\n" );
582 }
583 
584 static void test_colorbits(HDC hdc)
585 {
586     const int iAttribList[] = { WGL_COLOR_BITS_ARB, WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB,
587                                 WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB };
588     int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
589     const int iAttribs[] = { WGL_ALPHA_BITS_ARB, 1, 0 };
590     unsigned int nFormats;
591     BOOL res;
592     int iPixelFormat = 0;
593 
594     if (!pwglChoosePixelFormatARB)
595     {
596         win_skip("wglChoosePixelFormatARB is not available\n");
597         return;
598     }
599 
600     /* We need a pixel format with at least one bit of alpha */
601     res = pwglChoosePixelFormatARB(hdc, iAttribs, NULL, 1, &iPixelFormat, &nFormats);
602     if(res == FALSE || nFormats == 0)
603     {
604         skip("No suitable pixel formats found\n");
605         return;
606     }
607 
608     res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
609               sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList, iAttribRet);
610     if(res == FALSE)
611     {
612         skip("wglGetPixelFormatAttribivARB failed\n");
613         return;
614     }
615     iAttribRet[1] += iAttribRet[2]+iAttribRet[3]+iAttribRet[4];
616     ok(iAttribRet[0] == iAttribRet[1], "WGL_COLOR_BITS_ARB (%d) does not equal R+G+B+A (%d)!\n",
617                                        iAttribRet[0], iAttribRet[1]);
618 }
619 
620 static void test_gdi_dbuf(HDC hdc)
621 {
622     const int iAttribList[] = { WGL_SUPPORT_GDI_ARB, WGL_DOUBLE_BUFFER_ARB };
623     int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
624     unsigned int nFormats;
625     int iPixelFormat;
626     BOOL res;
627 
628     if (!pwglGetPixelFormatAttribivARB)
629     {
630         win_skip("wglGetPixelFormatAttribivARB is not available\n");
631         return;
632     }
633 
634     nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
635     for(iPixelFormat = 1;iPixelFormat <= nFormats;iPixelFormat++)
636     {
637         res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
638                   sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList,
639                   iAttribRet);
640         ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
641         if(res == FALSE)
642             continue;
643 
644         ok(!(iAttribRet[0] && iAttribRet[1]), "GDI support and double buffering on pixel format %d\n", iPixelFormat);
645     }
646 }
647 
648 static void test_acceleration(HDC hdc)
649 {
650     const int iAttribList[] = { WGL_ACCELERATION_ARB };
651     int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
652     unsigned int nFormats;
653     int iPixelFormat;
654     int res;
655     PIXELFORMATDESCRIPTOR pfd;
656 
657     if (!pwglGetPixelFormatAttribivARB)
658     {
659         win_skip("wglGetPixelFormatAttribivARB is not available\n");
660         return;
661     }
662 
663     nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
664     for(iPixelFormat = 1; iPixelFormat <= nFormats; iPixelFormat++)
665     {
666         res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
667                   sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList,
668                   iAttribRet);
669         ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
670         if(res == FALSE)
671             continue;
672 
673         memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
674         DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
675 
676         switch(iAttribRet[0])
677         {
678             case WGL_NO_ACCELERATION_ARB:
679                 ok( (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) == PFD_GENERIC_FORMAT , "Expected only PFD_GENERIC_FORMAT to be set for WGL_NO_ACCELERATION_ARB!: iPixelFormat=%d, dwFlags=%x!\n", iPixelFormat, pfd.dwFlags);
680                 break;
681             case WGL_GENERIC_ACCELERATION_ARB:
682                 ok( (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) == (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED), "Expected both PFD_GENERIC_FORMAT and PFD_GENERIC_ACCELERATION to be set for WGL_GENERIC_ACCELERATION_ARB: iPixelFormat=%d, dwFlags=%x!\n", iPixelFormat, pfd.dwFlags);
683                 break;
684             case WGL_FULL_ACCELERATION_ARB:
685                 ok( (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) == 0, "Expected no PFD_GENERIC_FORMAT/_ACCELERATION to be set for WGL_FULL_ACCELERATION_ARB: iPixelFormat=%d, dwFlags=%x!\n", iPixelFormat, pfd.dwFlags);
686                 break;
687         }
688     }
689 }
690 
691 static void test_bitmap_rendering( BOOL use_dib )
692 {
693     PIXELFORMATDESCRIPTOR pfd;
694     int i, ret, bpp, iPixelFormat=0;
695     unsigned int nFormats;
696     HGLRC hglrc, hglrc2;
697     BITMAPINFO biDst;
698     HBITMAP bmpDst, oldDst, bmp2;
699     HDC hdcDst, hdcScreen;
700     UINT *dstBuffer = NULL;
701 
702     hdcScreen = CreateCompatibleDC(0);
703     hdcDst = CreateCompatibleDC(0);
704 
705     if (use_dib)
706     {
707         bpp = 32;
708         memset(&biDst, 0, sizeof(BITMAPINFO));
709         biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
710         biDst.bmiHeader.biWidth = 4;
711         biDst.bmiHeader.biHeight = -4;
712         biDst.bmiHeader.biPlanes = 1;
713         biDst.bmiHeader.biBitCount = 32;
714         biDst.bmiHeader.biCompression = BI_RGB;
715 
716         bmpDst = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
717 
718         biDst.bmiHeader.biWidth = 12;
719         biDst.bmiHeader.biHeight = -12;
720         biDst.bmiHeader.biBitCount = 16;
721         bmp2 = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, NULL, NULL, 0);
722     }
723     else
724     {
725         bpp = GetDeviceCaps( hdcScreen, BITSPIXEL );
726         bmpDst = CreateBitmap( 4, 4, 1, bpp, NULL );
727         bmp2 = CreateBitmap( 12, 12, 1, bpp, NULL );
728     }
729 
730     oldDst = SelectObject(hdcDst, bmpDst);
731 
732     trace( "testing on %s\n", use_dib ? "DIB" : "DDB" );
733 
734     /* Pick a pixel format by hand because ChoosePixelFormat is unreliable */
735     nFormats = DescribePixelFormat(hdcDst, 0, 0, NULL);
736     for(i=1; i<=nFormats; i++)
737     {
738         memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
739         DescribePixelFormat(hdcDst, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
740 
741         if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) &&
742            (pfd.dwFlags & PFD_SUPPORT_OPENGL) &&
743            (pfd.cColorBits == bpp) &&
744            (pfd.cAlphaBits == 8) )
745         {
746             iPixelFormat = i;
747             break;
748         }
749     }
750 
751     if(!iPixelFormat)
752     {
753         skip("Unable to find a suitable pixel format\n");
754     }
755     else
756     {
757         ret = SetPixelFormat(hdcDst, iPixelFormat, &pfd);
758         ok( ret, "SetPixelFormat failed\n" );
759         ret = GetPixelFormat( hdcDst );
760         ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
761         ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
762         ok( !ret, "SetPixelFormat succeeded\n" );
763         hglrc = wglCreateContext(hdcDst);
764         ok(hglrc != NULL, "Unable to create a context\n");
765 
766         if(hglrc)
767         {
768             GLint viewport[4];
769             wglMakeCurrent(hdcDst, hglrc);
770             hglrc2 = wglCreateContext(hdcDst);
771             ok(hglrc2 != NULL, "Unable to create a context\n");
772 
773             /* Note this is RGBA but we read ARGB back */
774             glClearColor((float)0x22/0xff, (float)0x33/0xff, (float)0x44/0xff, (float)0x11/0xff);
775             glClear(GL_COLOR_BUFFER_BIT);
776             glGetIntegerv( GL_VIEWPORT, viewport );
777             glFinish();
778 
779             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
780                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
781             /* Note apparently the alpha channel is not supported by the software renderer (bitmap only works using software) */
782             if (dstBuffer)
783                 for (i = 0; i < 16; i++)
784                     ok(dstBuffer[i] == 0x223344 || dstBuffer[i] == 0x11223344, "Received color=%x at %u\n",
785                        dstBuffer[i], i);
786 
787             SelectObject(hdcDst, bmp2);
788             ret = GetPixelFormat( hdcDst );
789             ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
790             ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
791             ok( !ret, "SetPixelFormat succeeded\n" );
792 
793             /* context still uses the old pixel format and viewport */
794             glClearColor((float)0x44/0xff, (float)0x33/0xff, (float)0x22/0xff, (float)0x11/0xff);
795             glClear(GL_COLOR_BUFFER_BIT);
796             glFinish();
797             glGetIntegerv( GL_VIEWPORT, viewport );
798             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
799                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
800 
801             wglMakeCurrent(NULL, NULL);
802             wglMakeCurrent(hdcDst, hglrc);
803             glClearColor((float)0x44/0xff, (float)0x55/0xff, (float)0x66/0xff, (float)0x11/0xff);
804             glClear(GL_COLOR_BUFFER_BIT);
805             glFinish();
806             glGetIntegerv( GL_VIEWPORT, viewport );
807             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
808                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
809 
810             wglMakeCurrent(hdcDst, hglrc2);
811             glGetIntegerv( GL_VIEWPORT, viewport );
812             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
813                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
814 
815             wglMakeCurrent(hdcDst, hglrc);
816             glGetIntegerv( GL_VIEWPORT, viewport );
817             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
818                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
819 
820             SelectObject(hdcDst, bmpDst);
821             ret = GetPixelFormat( hdcDst );
822             ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
823             ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
824             ok( !ret, "SetPixelFormat succeeded\n" );
825             wglMakeCurrent(hdcDst, hglrc2);
826             glGetIntegerv( GL_VIEWPORT, viewport );
827             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
828                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
829 
830             wglDeleteContext(hglrc2);
831             wglDeleteContext(hglrc);
832         }
833     }
834 
835     SelectObject(hdcDst, oldDst);
836     DeleteObject(bmp2);
837     DeleteObject(bmpDst);
838     DeleteDC(hdcDst);
839     DeleteDC(hdcScreen);
840 }
841 
842 struct wgl_thread_param
843 {
844     HANDLE test_finished;
845     HWND hwnd;
846     HGLRC hglrc;
847     BOOL make_current;
848     BOOL make_current_error;
849     BOOL deleted;
850     DWORD deleted_error;
851 };
852 
853 static DWORD WINAPI wgl_thread(void *param)
854 {
855     struct wgl_thread_param *p = param;
856     HDC hdc = GetDC( p->hwnd );
857 
858     ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
859        "Expected NULL string when no active context is set\n");
860 
861     SetLastError(0xdeadbeef);
862     p->make_current = wglMakeCurrent(hdc, p->hglrc);
863     p->make_current_error = GetLastError();
864     p->deleted = wglDeleteContext(p->hglrc);
865     p->deleted_error = GetLastError();
866     ReleaseDC( p->hwnd, hdc );
867     SetEvent(p->test_finished);
868     return 0;
869 }
870 
871 static void test_deletecontext(HWND hwnd, HDC hdc)
872 {
873     struct wgl_thread_param thread_params;
874     HGLRC hglrc = wglCreateContext(hdc);
875     HANDLE thread_handle;
876     BOOL res;
877     DWORD tid;
878 
879     SetLastError(0xdeadbeef);
880     res = wglDeleteContext(NULL);
881     ok(res == FALSE, "wglDeleteContext succeeded\n");
882     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
883 
884     if(!hglrc)
885     {
886         skip("wglCreateContext failed!\n");
887         return;
888     }
889 
890     res = wglMakeCurrent(hdc, hglrc);
891     if(!res)
892     {
893         skip("wglMakeCurrent failed!\n");
894         return;
895     }
896 
897     /* WGL doesn't allow you to delete a context from a different thread than the one in which it is current.
898      * This differs from GLX which does allow it but it delays actual deletion until the context becomes not current.
899      */
900     thread_params.hglrc = hglrc;
901     thread_params.hwnd  = hwnd;
902     thread_params.test_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
903     thread_handle = CreateThread(NULL, 0, wgl_thread, &thread_params, 0, &tid);
904     ok(!!thread_handle, "Failed to create thread, last error %#x.\n", GetLastError());
905     if(thread_handle)
906     {
907         WaitForSingleObject(thread_handle, INFINITE);
908         ok(!thread_params.make_current, "Attempt to make WGL context from another thread passed\n");
909         ok(thread_params.make_current_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.make_current_error);
910         ok(!thread_params.deleted, "Attempt to delete WGL context from another thread passed\n");
911         ok(thread_params.deleted_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.deleted_error);
912     }
913     CloseHandle(thread_params.test_finished);
914 
915     res = wglDeleteContext(hglrc);
916     ok(res == TRUE, "wglDeleteContext failed\n");
917 
918     /* Attempting to delete the same context twice should fail. */
919     SetLastError(0xdeadbeef);
920     res = wglDeleteContext(hglrc);
921     ok(res == FALSE, "wglDeleteContext succeeded\n");
922     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
923 
924     /* WGL makes a context not current when deleting it. This differs from GLX behavior where
925      * deletion takes place when the thread becomes not current. */
926     hglrc = wglGetCurrentContext();
927     ok(hglrc == NULL, "A WGL context is active while none was expected\n");
928 }
929 
930 
931 static void test_getprocaddress(HDC hdc)
932 {
933     const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
934     PROC func = NULL;
935     HGLRC ctx = wglGetCurrentContext();
936 
937     if (!extensions)
938     {
939         skip("skipping wglGetProcAddress tests because no GL extensions supported\n");
940         return;
941     }
942 
943     /* Core GL 1.0/1.1 functions should not be loadable through wglGetProcAddress.
944      * Try to load the function with and without a context.
945      */
946     func = wglGetProcAddress("glEnable");
947     ok(func == NULL, "Lookup of function glEnable with a context passed, expected a failure\n");
948     wglMakeCurrent(hdc, NULL);
949     func = wglGetProcAddress("glEnable");
950     ok(func == NULL, "Lookup of function glEnable without a context passed, expected a failure\n");
951     wglMakeCurrent(hdc, ctx);
952 
953     /* The goal of the test will be to test behavior of wglGetProcAddress when
954      * no WGL context is active. Before the test we pick an extension (GL_ARB_multitexture)
955      * which any GL >=1.2.1 implementation supports. Unfortunately the GDI renderer doesn't
956      * support it. There aren't any extensions we can use for this test which are supported by
957      * both GDI and real drivers.
958      * Note GDI only has GL_EXT_bgra, GL_EXT_paletted_texture and GL_WIN_swap_hint.
959      */
960     if (!gl_extension_supported(extensions, "GL_ARB_multitexture"))
961     {
962         skip("skipping test because lack of GL_ARB_multitexture support\n");
963         return;
964     }
965 
966     func = wglGetProcAddress("glActiveTextureARB");
967     ok(func != NULL, "Unable to lookup glActiveTextureARB, last error %#x\n", GetLastError());
968 
969     /* Temporarily disable the context, so we can see that we can't retrieve functions now. */
970     wglMakeCurrent(hdc, NULL);
971     func = wglGetProcAddress("glActiveTextureARB");
972     ok(func == NULL, "Function lookup without a context passed, expected a failure; last error %#x\n", GetLastError());
973     wglMakeCurrent(hdc, ctx);
974 }
975 
976 static void test_make_current_read(HDC hdc)
977 {
978     int res;
979     HDC hread;
980     HGLRC hglrc = wglCreateContext(hdc);
981 
982     if(!hglrc)
983     {
984         skip("wglCreateContext failed!\n");
985         return;
986     }
987 
988     res = wglMakeCurrent(hdc, hglrc);
989     if(!res)
990     {
991         skip("wglMakeCurrent failed!\n");
992         return;
993     }
994 
995     /* Test what wglGetCurrentReadDCARB does for wglMakeCurrent as the spec doesn't mention it */
996     hread = pwglGetCurrentReadDCARB();
997     trace("hread %p, hdc %p\n", hread, hdc);
998     ok(hread == hdc, "wglGetCurrentReadDCARB failed for standard wglMakeCurrent\n");
999 
1000     pwglMakeContextCurrentARB(hdc, hdc, hglrc);
1001     hread = pwglGetCurrentReadDCARB();
1002     ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n");
1003 }
1004 
1005 static void test_dc(HWND hwnd, HDC hdc)
1006 {
1007     int pf1, pf2;
1008     HDC hdc2;
1009 
1010     /* Get another DC and make sure it has the same pixel format */
1011     hdc2 = GetDC(hwnd);
1012     if(hdc != hdc2)
1013     {
1014         pf1 = GetPixelFormat(hdc);
1015         pf2 = GetPixelFormat(hdc2);
1016         ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2);
1017     }
1018     else
1019         skip("Could not get a different DC for the window\n");
1020 
1021     if(hdc2)
1022     {
1023         ReleaseDC(hwnd, hdc2);
1024         hdc2 = NULL;
1025     }
1026 }
1027 
1028 /* Nvidia converts win32 error codes to (0xc007 << 16) | win32_error_code */
1029 #define NVIDIA_HRESULT_FROM_WIN32(x) (HRESULT_FROM_WIN32(x) | 0x40000000)
1030 static void test_opengl3(HDC hdc)
1031 {
1032     /* Try to create a context compatible with OpenGL 1.x; 1.0-2.1 is allowed */
1033     {
1034         HGLRC gl3Ctx;
1035         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 1, 0};
1036 
1037         gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1038         ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 1.x context failed!\n");
1039         wglDeleteContext(gl3Ctx);
1040     }
1041 
1042     /* Try to pass an invalid HDC */
1043     {
1044         HGLRC gl3Ctx;
1045         DWORD error;
1046         SetLastError(0xdeadbeef);
1047         gl3Ctx = pwglCreateContextAttribsARB((HDC)0xdeadbeef, 0, 0);
1048         ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid HDC passed\n");
1049         error = GetLastError();
1050         ok(error == ERROR_DC_NOT_FOUND || error == ERROR_INVALID_HANDLE ||
1051            broken(error == ERROR_DS_GENERIC_ERROR) ||
1052            broken(error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_DATA)), /* Nvidia Vista + Win7 */
1053            "Expected ERROR_DC_NOT_FOUND, got error=%x\n", error);
1054         wglDeleteContext(gl3Ctx);
1055     }
1056 
1057     /* Try to pass an invalid shareList */
1058     {
1059         HGLRC gl3Ctx;
1060         DWORD error;
1061         SetLastError(0xdeadbeef);
1062         gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0);
1063         ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
1064         error = GetLastError();
1065         /* The Nvidia implementation seems to return hresults instead of win32 error codes */
1066         ok(error == ERROR_INVALID_OPERATION || error == ERROR_INVALID_DATA ||
1067            error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION), "Expected ERROR_INVALID_OPERATION, got error=%x\n", error);
1068         wglDeleteContext(gl3Ctx);
1069     }
1070 
1071     /* Try to create an OpenGL 3.0 context */
1072     {
1073         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1074         HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1075 
1076         if(gl3Ctx == NULL)
1077         {
1078             skip("Skipping the rest of the WGL_ARB_create_context test due to lack of OpenGL 3.0\n");
1079             return;
1080         }
1081 
1082         wglDeleteContext(gl3Ctx);
1083     }
1084 
1085     /* Test matching an OpenGL 3.0 context with an older one, OpenGL 3.0 should allow it until the new object model is introduced in a future revision */
1086     {
1087         HGLRC glCtx = wglCreateContext(hdc);
1088 
1089         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1090         int attribs_future[] = {WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1091 
1092         HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs);
1093         ok(gl3Ctx != NULL, "Sharing of a display list between OpenGL 3.0 and OpenGL 1.x/2.x failed!\n");
1094         if(gl3Ctx)
1095             wglDeleteContext(gl3Ctx);
1096 
1097         gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs_future);
1098         ok(gl3Ctx != NULL, "Sharing of a display list between a forward compatible OpenGL 3.0 context and OpenGL 1.x/2.x failed!\n");
1099         if(gl3Ctx)
1100             wglDeleteContext(gl3Ctx);
1101 
1102         if(glCtx)
1103             wglDeleteContext(glCtx);
1104     }
1105 
1106     /* Try to create an OpenGL 3.0 context and test windowless rendering */
1107     {
1108         HGLRC gl3Ctx;
1109         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1110         BOOL res;
1111 
1112         gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1113         ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 3.0 context failed!\n");
1114 
1115         /* OpenGL 3.0 allows offscreen rendering WITHOUT a drawable
1116          * Neither AMD or Nvidia support it at this point. The WGL_ARB_create_context specs also say that
1117          * it is hard because drivers use the HDC to enter the display driver and it sounds like they don't
1118          * expect drivers to ever offer it.
1119          */
1120         res = wglMakeCurrent(0, gl3Ctx);
1121         ok(res == FALSE, "Wow, OpenGL 3.0 windowless rendering passed while it was expected not to!\n");
1122         if(res)
1123             wglMakeCurrent(0, 0);
1124 
1125         if(gl3Ctx)
1126             wglDeleteContext(gl3Ctx);
1127     }
1128 }
1129 
1130 static void test_minimized(void)
1131 {
1132     PIXELFORMATDESCRIPTOR pf_desc =
1133     {
1134         sizeof(PIXELFORMATDESCRIPTOR),
1135         1,                     /* version */
1136         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1137         PFD_TYPE_RGBA,
1138         24,                    /* 24-bit color depth */
1139         0, 0, 0, 0, 0, 0,      /* color bits */
1140         0,                     /* alpha buffer */
1141         0,                     /* shift bit */
1142         0,                     /* accumulation buffer */
1143         0, 0, 0, 0,            /* accum bits */
1144         32,                    /* z-buffer */
1145         0,                     /* stencil buffer */
1146         0,                     /* auxiliary buffer */
1147         PFD_MAIN_PLANE,        /* main layer */
1148         0,                     /* reserved */
1149         0, 0, 0                /* layer masks */
1150     };
1151     int pixel_format;
1152     HWND window;
1153     LONG style;
1154     HGLRC ctx;
1155     BOOL ret;
1156     HDC dc;
1157 
1158     window = CreateWindowA("static", "opengl32_test",
1159             WS_POPUP | WS_MINIMIZE, 0, 0, 640, 480, 0, 0, 0, 0);
1160     ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1161 
1162     dc = GetDC(window);
1163     ok(!!dc, "Failed to get DC.\n");
1164 
1165     pixel_format = ChoosePixelFormat(dc, &pf_desc);
1166     if (!pixel_format)
1167     {
1168         win_skip("Failed to find pixel format.\n");
1169         ReleaseDC(window, dc);
1170         DestroyWindow(window);
1171         return;
1172     }
1173 
1174     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1175     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1176 
1177     style = GetWindowLongA(window, GWL_STYLE);
1178     ok(style & WS_MINIMIZE, "Window should be minimized, got style %#x.\n", style);
1179 
1180     ctx = wglCreateContext(dc);
1181     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1182 
1183     ret = wglMakeCurrent(dc, ctx);
1184     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1185 
1186     style = GetWindowLongA(window, GWL_STYLE);
1187     ok(style & WS_MINIMIZE, "window should be minimized, got style %#x.\n", style);
1188 
1189     ret = wglMakeCurrent(NULL, NULL);
1190     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1191 
1192     ret = wglDeleteContext(ctx);
1193     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1194 
1195     ReleaseDC(window, dc);
1196     DestroyWindow(window);
1197 }
1198 
1199 static void test_window_dc(void)
1200 {
1201     PIXELFORMATDESCRIPTOR pf_desc =
1202     {
1203         sizeof(PIXELFORMATDESCRIPTOR),
1204         1,                     /* version */
1205         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1206         PFD_TYPE_RGBA,
1207         24,                    /* 24-bit color depth */
1208         0, 0, 0, 0, 0, 0,      /* color bits */
1209         0,                     /* alpha buffer */
1210         0,                     /* shift bit */
1211         0,                     /* accumulation buffer */
1212         0, 0, 0, 0,            /* accum bits */
1213         32,                    /* z-buffer */
1214         0,                     /* stencil buffer */
1215         0,                     /* auxiliary buffer */
1216         PFD_MAIN_PLANE,        /* main layer */
1217         0,                     /* reserved */
1218         0, 0, 0                /* layer masks */
1219     };
1220     int pixel_format;
1221     HWND window;
1222     RECT vp, r;
1223     HGLRC ctx;
1224     BOOL ret;
1225     HDC dc;
1226 
1227     window = CreateWindowA("static", "opengl32_test",
1228             WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
1229     ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1230 
1231     ShowWindow(window, SW_SHOW);
1232 
1233     dc = GetWindowDC(window);
1234     ok(!!dc, "Failed to get DC.\n");
1235 
1236     pixel_format = ChoosePixelFormat(dc, &pf_desc);
1237     if (!pixel_format)
1238     {
1239         win_skip("Failed to find pixel format.\n");
1240         ReleaseDC(window, dc);
1241         DestroyWindow(window);
1242         return;
1243     }
1244 
1245     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1246     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1247 
1248     ctx = wglCreateContext(dc);
1249     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1250 
1251     ret = wglMakeCurrent(dc, ctx);
1252     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1253 
1254     GetClientRect(window, &r);
1255     glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1256     ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1257 
1258     ret = wglMakeCurrent(NULL, NULL);
1259     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1260 
1261     ret = wglDeleteContext(ctx);
1262     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1263 
1264     ReleaseDC(window, dc);
1265     DestroyWindow(window);
1266 }
1267 
1268 static void test_message_window(void)
1269 {
1270     PIXELFORMATDESCRIPTOR pf_desc =
1271     {
1272         sizeof(PIXELFORMATDESCRIPTOR),
1273         1,                     /* version */
1274         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1275         PFD_TYPE_RGBA,
1276         24,                    /* 24-bit color depth */
1277         0, 0, 0, 0, 0, 0,      /* color bits */
1278         0,                     /* alpha buffer */
1279         0,                     /* shift bit */
1280         0,                     /* accumulation buffer */
1281         0, 0, 0, 0,            /* accum bits */
1282         32,                    /* z-buffer */
1283         0,                     /* stencil buffer */
1284         0,                     /* auxiliary buffer */
1285         PFD_MAIN_PLANE,        /* main layer */
1286         0,                     /* reserved */
1287         0, 0, 0                /* layer masks */
1288     };
1289     int pixel_format;
1290     HWND window;
1291     RECT vp, r;
1292     HGLRC ctx;
1293     BOOL ret;
1294     HDC dc;
1295     GLenum glerr;
1296 
1297     window = CreateWindowA("static", "opengl32_test",
1298                            WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, HWND_MESSAGE, 0, 0, 0);
1299     if (!window)
1300     {
1301         win_skip( "HWND_MESSAGE not supported\n" );
1302         return;
1303     }
1304     dc = GetDC(window);
1305     ok(!!dc, "Failed to get DC.\n");
1306 
1307     pixel_format = ChoosePixelFormat(dc, &pf_desc);
1308     if (!pixel_format)
1309     {
1310         win_skip("Failed to find pixel format.\n");
1311         ReleaseDC(window, dc);
1312         DestroyWindow(window);
1313         return;
1314     }
1315 
1316     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1317     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1318 
1319     ctx = wglCreateContext(dc);
1320     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1321 
1322     ret = wglMakeCurrent(dc, ctx);
1323     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1324 
1325     GetClientRect(window, &r);
1326     glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1327     ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1328 
1329     glClear(GL_COLOR_BUFFER_BIT);
1330     glFinish();
1331     glerr = glGetError();
1332     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1333     ret = SwapBuffers(dc);
1334     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1335 
1336     ret = wglMakeCurrent(NULL, NULL);
1337     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1338 
1339     ret = wglDeleteContext(ctx);
1340     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1341 
1342     ReleaseDC(window, dc);
1343     DestroyWindow(window);
1344 }
1345 
1346 static void test_destroy(HDC oldhdc)
1347 {
1348     PIXELFORMATDESCRIPTOR pf_desc =
1349     {
1350         sizeof(PIXELFORMATDESCRIPTOR),
1351         1,                     /* version */
1352         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1353         PFD_TYPE_RGBA,
1354         24,                    /* 24-bit color depth */
1355         0, 0, 0, 0, 0, 0,      /* color bits */
1356         0,                     /* alpha buffer */
1357         0,                     /* shift bit */
1358         0,                     /* accumulation buffer */
1359         0, 0, 0, 0,            /* accum bits */
1360         32,                    /* z-buffer */
1361         0,                     /* stencil buffer */
1362         0,                     /* auxiliary buffer */
1363         PFD_MAIN_PLANE,        /* main layer */
1364         0,                     /* reserved */
1365         0, 0, 0                /* layer masks */
1366     };
1367     int pixel_format;
1368     HWND window;
1369     HGLRC ctx;
1370     BOOL ret;
1371     HDC dc;
1372     GLenum glerr;
1373     DWORD err;
1374     HGLRC oldctx = wglGetCurrentContext();
1375 
1376     ok(!!oldctx, "Expected to find a valid current context.\n");
1377 
1378     window = CreateWindowA("static", "opengl32_test",
1379             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1380     ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1381 
1382     dc = GetDC(window);
1383     ok(!!dc, "Failed to get DC.\n");
1384 
1385     pixel_format = ChoosePixelFormat(dc, &pf_desc);
1386     if (!pixel_format)
1387     {
1388         win_skip("Failed to find pixel format.\n");
1389         ReleaseDC(window, dc);
1390         DestroyWindow(window);
1391         return;
1392     }
1393 
1394     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1395     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1396 
1397     ctx = wglCreateContext(dc);
1398     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1399 
1400     ret = wglMakeCurrent(dc, ctx);
1401     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1402 
1403     glClear(GL_COLOR_BUFFER_BIT);
1404     glFinish();
1405     glerr = glGetError();
1406     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1407     ret = SwapBuffers(dc);
1408     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1409 
1410     ret = DestroyWindow(window);
1411     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1412 
1413     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1414 
1415     SetLastError(0xdeadbeef);
1416     ret = wglMakeCurrent(dc, ctx);
1417     err = GetLastError();
1418     ok(!ret && err == ERROR_INVALID_HANDLE,
1419             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1420     SetLastError(0xdeadbeef);
1421     ret = SwapBuffers(dc);
1422     err = GetLastError();
1423     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1424 
1425     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1426 
1427     glClear(GL_COLOR_BUFFER_BIT);
1428     glFinish();
1429     glerr = glGetError();
1430     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1431     SetLastError(0xdeadbeef);
1432     ret = SwapBuffers(dc);
1433     err = GetLastError();
1434     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1435 
1436     ret = wglMakeCurrent(NULL, NULL);
1437     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1438 
1439     glClear(GL_COLOR_BUFFER_BIT);
1440     glFinish();
1441     glerr = glGetError();
1442     ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1443     SetLastError(0xdeadbeef);
1444     ret = SwapBuffers(dc);
1445     err = GetLastError();
1446     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1447 
1448     SetLastError(0xdeadbeef);
1449     ret = wglMakeCurrent(dc, ctx);
1450     err = GetLastError();
1451     ok(!ret && err == ERROR_INVALID_HANDLE,
1452             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1453 
1454     ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1455 
1456     ret = wglMakeCurrent(oldhdc, oldctx);
1457     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1458     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1459 
1460     SetLastError(0xdeadbeef);
1461     ret = wglMakeCurrent(dc, ctx);
1462     err = GetLastError();
1463     ok(!ret && err == ERROR_INVALID_HANDLE,
1464             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1465 
1466     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1467 
1468     ret = wglDeleteContext(ctx);
1469     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1470 
1471     ReleaseDC(window, dc);
1472 
1473     ret = wglMakeCurrent(oldhdc, oldctx);
1474     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1475 }
1476 
1477 static void test_destroy_read(HDC oldhdc)
1478 {
1479     PIXELFORMATDESCRIPTOR pf_desc =
1480     {
1481         sizeof(PIXELFORMATDESCRIPTOR),
1482         1,                     /* version */
1483         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1484         PFD_TYPE_RGBA,
1485         24,                    /* 24-bit color depth */
1486         0, 0, 0, 0, 0, 0,      /* color bits */
1487         0,                     /* alpha buffer */
1488         0,                     /* shift bit */
1489         0,                     /* accumulation buffer */
1490         0, 0, 0, 0,            /* accum bits */
1491         32,                    /* z-buffer */
1492         0,                     /* stencil buffer */
1493         0,                     /* auxiliary buffer */
1494         PFD_MAIN_PLANE,        /* main layer */
1495         0,                     /* reserved */
1496         0, 0, 0                /* layer masks */
1497     };
1498     int pixel_format;
1499     HWND draw_window, read_window;
1500     HGLRC ctx;
1501     BOOL ret;
1502     HDC read_dc, draw_dc;
1503     GLenum glerr;
1504     DWORD err;
1505     HGLRC oldctx = wglGetCurrentContext();
1506 
1507     ok(!!oldctx, "Expected to find a valid current context\n");
1508 
1509     draw_window = CreateWindowA("static", "opengl32_test",
1510             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1511     ok(!!draw_window, "Failed to create window, last error %#x.\n", GetLastError());
1512 
1513     draw_dc = GetDC(draw_window);
1514     ok(!!draw_dc, "Failed to get DC.\n");
1515 
1516     pixel_format = ChoosePixelFormat(draw_dc, &pf_desc);
1517     if (!pixel_format)
1518     {
1519         win_skip("Failed to find pixel format.\n");
1520         ReleaseDC(draw_window, draw_dc);
1521         DestroyWindow(draw_window);
1522         return;
1523     }
1524 
1525     ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc);
1526     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1527 
1528     read_window = CreateWindowA("static", "opengl32_test",
1529             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1530     ok(!!read_window, "Failed to create window, last error %#x.\n", GetLastError());
1531 
1532     read_dc = GetDC(read_window);
1533     ok(!!draw_dc, "Failed to get DC.\n");
1534 
1535     pixel_format = ChoosePixelFormat(read_dc, &pf_desc);
1536     if (!pixel_format)
1537     {
1538         win_skip("Failed to find pixel format.\n");
1539         ReleaseDC(read_window, read_dc);
1540         DestroyWindow(read_window);
1541         ReleaseDC(draw_window, draw_dc);
1542         DestroyWindow(draw_window);
1543         return;
1544     }
1545 
1546     ret = SetPixelFormat(read_dc, pixel_format, &pf_desc);
1547     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1548 
1549     ctx = wglCreateContext(draw_dc);
1550     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1551 
1552     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1553     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1554 
1555     glCopyPixels(0, 0, 640, 480, GL_COLOR);
1556     glFinish();
1557     glerr = glGetError();
1558     ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1559     ret = SwapBuffers(draw_dc);
1560     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1561 
1562     ret = DestroyWindow(read_window);
1563     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1564 
1565     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1566 
1567     if (0) /* Crashes on AMD on Windows */
1568     {
1569         glCopyPixels(0, 0, 640, 480, GL_COLOR);
1570         glFinish();
1571         glerr = glGetError();
1572         ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1573     }
1574 
1575     glClear(GL_COLOR_BUFFER_BIT);
1576     glFinish();
1577     glerr = glGetError();
1578     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1579     ret = SwapBuffers(draw_dc);
1580     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1581 
1582     ret = wglMakeCurrent(NULL, NULL);
1583     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1584 
1585     if (0) /* This crashes with Nvidia drivers on Windows. */
1586     {
1587         SetLastError(0xdeadbeef);
1588         ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1589         err = GetLastError();
1590         ok(!ret && err == ERROR_INVALID_HANDLE,
1591                 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1592     }
1593 
1594     ret = DestroyWindow(draw_window);
1595     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1596 
1597     glClear(GL_COLOR_BUFFER_BIT);
1598     glFinish();
1599     glerr = glGetError();
1600     ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1601     SetLastError(0xdeadbeef);
1602     ret = SwapBuffers(draw_dc);
1603     err = GetLastError();
1604     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1605 
1606     SetLastError(0xdeadbeef);
1607     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1608     err = GetLastError();
1609     ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1610             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1611 
1612     ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1613 
1614     wglMakeCurrent(NULL, NULL);
1615 
1616     wglMakeCurrent(oldhdc, oldctx);
1617     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1618 
1619     SetLastError(0xdeadbeef);
1620     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1621     err = GetLastError();
1622     ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1623             "Unexpected behavior when making context current, last error %#x.\n", err);
1624 
1625     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1626 
1627     ret = wglDeleteContext(ctx);
1628     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1629 
1630     ReleaseDC(read_window, read_dc);
1631     ReleaseDC(draw_window, draw_dc);
1632 
1633     wglMakeCurrent(oldhdc, oldctx);
1634 }
1635 
1636 static void test_swap_control(HDC oldhdc)
1637 {
1638     PIXELFORMATDESCRIPTOR pf_desc =
1639     {
1640         sizeof(PIXELFORMATDESCRIPTOR),
1641         1,                     /* version */
1642         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1643         PFD_TYPE_RGBA,
1644         24,                    /* 24-bit color depth */
1645         0, 0, 0, 0, 0, 0,      /* color bits */
1646         0,                     /* alpha buffer */
1647         0,                     /* shift bit */
1648         0,                     /* accumulation buffer */
1649         0, 0, 0, 0,            /* accum bits */
1650         32,                    /* z-buffer */
1651         0,                     /* stencil buffer */
1652         0,                     /* auxiliary buffer */
1653         PFD_MAIN_PLANE,        /* main layer */
1654         0,                     /* reserved */
1655         0, 0, 0                /* layer masks */
1656     };
1657     int pixel_format;
1658     HWND window1, window2, old_parent;
1659     HGLRC ctx1, ctx2, oldctx;
1660     BOOL ret;
1661     HDC dc1, dc2;
1662     int interval;
1663 
1664     oldctx = wglGetCurrentContext();
1665     ok(!!oldctx, "Expected to find a valid current context.\n");
1666 
1667     window1 = CreateWindowA("static", "opengl32_test",
1668             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1669     ok(!!window1, "Failed to create window1, last error %#x.\n", GetLastError());
1670 
1671     dc1 = GetDC(window1);
1672     ok(!!dc1, "Failed to get DC.\n");
1673 
1674     pixel_format = ChoosePixelFormat(dc1, &pf_desc);
1675     if (!pixel_format)
1676     {
1677         win_skip("Failed to find pixel format.\n");
1678         ReleaseDC(window1, dc1);
1679         DestroyWindow(window1);
1680         return;
1681     }
1682 
1683     ret = SetPixelFormat(dc1, pixel_format, &pf_desc);
1684     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1685 
1686     ctx1 = wglCreateContext(dc1);
1687     ok(!!ctx1, "Failed to create GL context, last error %#x.\n", GetLastError());
1688 
1689     ret = wglMakeCurrent(dc1, ctx1);
1690     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1691 
1692     interval = pwglGetSwapIntervalEXT();
1693     ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1694 
1695     ret = pwglSwapIntervalEXT(0);
1696     ok(ret, "Failed to set swap interval to 0, last error %#x.\n", GetLastError());
1697 
1698     interval = pwglGetSwapIntervalEXT();
1699     ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1700 
1701     /* Check what interval we get on a second context on the same drawable.*/
1702     ctx2 = wglCreateContext(dc1);
1703     ok(!!ctx2, "Failed to create GL context, last error %#x.\n", GetLastError());
1704 
1705     ret = wglMakeCurrent(dc1, ctx2);
1706     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1707 
1708     interval = pwglGetSwapIntervalEXT();
1709     ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1710 
1711     /* A second window is created to see whether its swap interval was affected
1712      * by previous calls.
1713      */
1714     window2 = CreateWindowA("static", "opengl32_test",
1715             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1716     ok(!!window2, "Failed to create window2, last error %#x.\n", GetLastError());
1717 
1718     dc2 = GetDC(window2);
1719     ok(!!dc2, "Failed to get DC.\n");
1720 
1721     ret = SetPixelFormat(dc2, pixel_format, &pf_desc);
1722     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1723 
1724     ret = wglMakeCurrent(dc2, ctx1);
1725     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1726 
1727     /* Since the second window lacks the swap interval, this proves that the interval
1728      * is not global or shared among contexts.
1729      */
1730     interval = pwglGetSwapIntervalEXT();
1731     ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1732 
1733     /* Test if setting the parent of a window resets the swap interval. */
1734     ret = wglMakeCurrent(dc1, ctx1);
1735     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1736 
1737     old_parent = SetParent(window1, window2);
1738     ok(!!old_parent, "Failed to make window1 a child of window2, last error %#x.\n", GetLastError());
1739 
1740     interval = pwglGetSwapIntervalEXT();
1741     ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1742 
1743     ret = wglDeleteContext(ctx1);
1744     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1745     ret = wglDeleteContext(ctx2);
1746     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1747 
1748     ReleaseDC(window1, dc1);
1749     DestroyWindow(window1);
1750     ReleaseDC(window2, dc2);
1751     DestroyWindow(window2);
1752 
1753     wglMakeCurrent(oldhdc, oldctx);
1754 }
1755 
1756 START_TEST(opengl)
1757 {
1758     HWND hwnd;
1759     PIXELFORMATDESCRIPTOR pfd = {
1760         sizeof(PIXELFORMATDESCRIPTOR),
1761         1,                     /* version */
1762         PFD_DRAW_TO_WINDOW |
1763         PFD_SUPPORT_OPENGL |
1764         PFD_DOUBLEBUFFER,
1765         PFD_TYPE_RGBA,
1766         24,                    /* 24-bit color depth */
1767         0, 0, 0, 0, 0, 0,      /* color bits */
1768         0,                     /* alpha buffer */
1769         0,                     /* shift bit */
1770         0,                     /* accumulation buffer */
1771         0, 0, 0, 0,            /* accum bits */
1772         32,                    /* z-buffer */
1773         0,                     /* stencil buffer */
1774         0,                     /* auxiliary buffer */
1775         PFD_MAIN_PLANE,        /* main layer */
1776         0,                     /* reserved */
1777         0, 0, 0                /* layer masks */
1778     };
1779 
1780     hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
1781             NULL, NULL);
1782     ok(hwnd != NULL, "err: %d\n", GetLastError());
1783     if (hwnd)
1784     {
1785         HDC hdc;
1786         int iPixelFormat, res;
1787         HGLRC hglrc;
1788         DWORD error;
1789         ShowWindow(hwnd, SW_SHOW);
1790 
1791         hdc = GetDC(hwnd);
1792 
1793         iPixelFormat = ChoosePixelFormat(hdc, &pfd);
1794         if(iPixelFormat == 0)
1795         {
1796             /* This should never happen as ChoosePixelFormat always returns a closest match, but currently this fails in Wine if we don't have glX */
1797             win_skip("Unable to find pixel format.\n");
1798             goto cleanup;
1799         }
1800 
1801         /* We shouldn't be able to create a context from a hdc which doesn't have a pixel format set */
1802         hglrc = wglCreateContext(hdc);
1803         ok(hglrc == NULL, "wglCreateContext should fail when no pixel format has been set, but it passed\n");
1804         error = GetLastError();
1805         ok(error == ERROR_INVALID_PIXEL_FORMAT, "expected ERROR_INVALID_PIXEL_FORMAT for wglCreateContext without a pixelformat set, but received %#x\n", error);
1806 
1807         res = SetPixelFormat(hdc, iPixelFormat, &pfd);
1808         ok(res, "SetPixelformat failed: %x\n", GetLastError());
1809 
1810         test_bitmap_rendering( TRUE );
1811         test_bitmap_rendering( FALSE );
1812         test_minimized();
1813         test_window_dc();
1814         test_message_window();
1815         test_dc(hwnd, hdc);
1816 
1817         ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
1818            "Expected NULL string when no active context is set\n");
1819         hglrc = wglCreateContext(hdc);
1820         res = wglMakeCurrent(hdc, hglrc);
1821         ok(res, "wglMakeCurrent failed!\n");
1822         if(res)
1823         {
1824             trace("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
1825             trace("OpenGL driver version: %s\n", glGetString(GL_VERSION));
1826             trace("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
1827         }
1828         else
1829         {
1830             skip("Skipping OpenGL tests without a current context\n");
1831             return;
1832         }
1833 
1834         /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making
1835          * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD).
1836          */
1837         init_functions();
1838         test_getprocaddress(hdc);
1839         test_deletecontext(hwnd, hdc);
1840         test_makecurrent(hdc);
1841 
1842         /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */
1843         if (!pwglGetExtensionsStringARB)
1844         {
1845             win_skip("wglGetExtensionsStringARB is not available\n");
1846             return;
1847         }
1848 
1849         test_choosepixelformat();
1850         test_debug_message_callback();
1851         test_setpixelformat(hdc);
1852         test_destroy(hdc);
1853         test_sharelists(hdc);
1854         test_colorbits(hdc);
1855         test_gdi_dbuf(hdc);
1856         test_acceleration(hdc);
1857 
1858         wgl_extensions = pwglGetExtensionsStringARB(hdc);
1859         if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n");
1860 
1861         if(strstr(wgl_extensions, "WGL_ARB_create_context"))
1862             test_opengl3(hdc);
1863 
1864         if(strstr(wgl_extensions, "WGL_ARB_make_current_read"))
1865         {
1866             test_make_current_read(hdc);
1867             test_destroy_read(hdc);
1868         }
1869         else
1870             skip("WGL_ARB_make_current_read not supported, skipping test\n");
1871 
1872         if(strstr(wgl_extensions, "WGL_ARB_pbuffer"))
1873             test_pbuffers(hdc);
1874         else
1875             skip("WGL_ARB_pbuffer not supported, skipping pbuffer test\n");
1876 
1877         if(strstr(wgl_extensions, "WGL_EXT_swap_control"))
1878             test_swap_control(hdc);
1879         else
1880             skip("WGL_EXT_swap_control not supported, skipping test\n");
1881 
1882 cleanup:
1883         ReleaseDC(hwnd, hdc);
1884         DestroyWindow(hwnd);
1885     }
1886 }
1887