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         {
209             /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
210             pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
211             res = GetPixelFormat(pbuffer_hdc);
212 
213             ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat);
214             trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
215             trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
216             pwglReleasePbufferDCARB(pbuffer, hdc);
217         }
218         else skip("Pbuffer creation failed!\n");
219     }
220     else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n");
221 }
222 
223 static int test_pfd(const PIXELFORMATDESCRIPTOR *pfd, PIXELFORMATDESCRIPTOR *fmt)
224 {
225     int pf;
226     HDC hdc;
227     HWND hwnd;
228 
229     hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
230             NULL, NULL);
231     if (!hwnd)
232         return 0;
233 
234     hdc = GetDC( hwnd );
235     pf = ChoosePixelFormat( hdc, pfd );
236     if (pf && fmt)
237     {
238         memset(fmt, 0, sizeof(*fmt));
239         ok(DescribePixelFormat( hdc, pf, sizeof(*fmt), fmt ),
240            "DescribePixelFormat failed with error: %u\n", GetLastError());
241     }
242     ReleaseDC( hwnd, hdc );
243     DestroyWindow( hwnd );
244 
245     return pf;
246 }
247 
248 static void test_choosepixelformat(void)
249 {
250     PIXELFORMATDESCRIPTOR pfd = {
251         sizeof(PIXELFORMATDESCRIPTOR),
252         1,                     /* version */
253         PFD_DRAW_TO_WINDOW | 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[ARRAY_SIZE(iAttribList)];
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, ARRAY_SIZE(iAttribList), iAttribList,
609             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[ARRAY_SIZE(iAttribList)];
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, ARRAY_SIZE(iAttribList),
638                 iAttribList, iAttribRet);
639         ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
640         if(res == FALSE)
641             continue;
642 
643         ok(!(iAttribRet[0] && iAttribRet[1]), "GDI support and double buffering on pixel format %d\n", iPixelFormat);
644     }
645 }
646 
647 static void test_acceleration(HDC hdc)
648 {
649     const int iAttribList[] = { WGL_ACCELERATION_ARB };
650     int iAttribRet[ARRAY_SIZE(iAttribList)];
651     unsigned int nFormats;
652     int iPixelFormat;
653     int res;
654     PIXELFORMATDESCRIPTOR pfd;
655 
656     if (!pwglGetPixelFormatAttribivARB)
657     {
658         win_skip("wglGetPixelFormatAttribivARB is not available\n");
659         return;
660     }
661 
662     nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
663     for(iPixelFormat = 1; iPixelFormat <= nFormats; iPixelFormat++)
664     {
665         res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, ARRAY_SIZE(iAttribList),
666                 iAttribList, iAttribRet);
667         ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
668         if(res == FALSE)
669             continue;
670 
671         memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
672         DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
673 
674         switch(iAttribRet[0])
675         {
676             case WGL_NO_ACCELERATION_ARB:
677                 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);
678                 break;
679             case WGL_GENERIC_ACCELERATION_ARB:
680                 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);
681                 break;
682             case WGL_FULL_ACCELERATION_ARB:
683                 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);
684                 break;
685         }
686     }
687 }
688 
689 static void test_bitmap_rendering( BOOL use_dib )
690 {
691     PIXELFORMATDESCRIPTOR pfd;
692     int i, ret, bpp, iPixelFormat=0;
693     unsigned int nFormats;
694     HGLRC hglrc, hglrc2;
695     BITMAPINFO biDst;
696     HBITMAP bmpDst, oldDst, bmp2;
697     HDC hdcDst, hdcScreen;
698     UINT *dstBuffer = NULL;
699 
700     hdcScreen = CreateCompatibleDC(0);
701     hdcDst = CreateCompatibleDC(0);
702 
703     if (use_dib)
704     {
705         bpp = 32;
706         memset(&biDst, 0, sizeof(BITMAPINFO));
707         biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
708         biDst.bmiHeader.biWidth = 4;
709         biDst.bmiHeader.biHeight = -4;
710         biDst.bmiHeader.biPlanes = 1;
711         biDst.bmiHeader.biBitCount = 32;
712         biDst.bmiHeader.biCompression = BI_RGB;
713 
714         bmpDst = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
715 
716         biDst.bmiHeader.biWidth = 12;
717         biDst.bmiHeader.biHeight = -12;
718         biDst.bmiHeader.biBitCount = 16;
719         bmp2 = CreateDIBSection(0, &biDst, DIB_RGB_COLORS, NULL, NULL, 0);
720     }
721     else
722     {
723         bpp = GetDeviceCaps( hdcScreen, BITSPIXEL );
724         bmpDst = CreateBitmap( 4, 4, 1, bpp, NULL );
725         bmp2 = CreateBitmap( 12, 12, 1, bpp, NULL );
726     }
727 
728     oldDst = SelectObject(hdcDst, bmpDst);
729 
730     trace( "testing on %s\n", use_dib ? "DIB" : "DDB" );
731 
732     /* Pick a pixel format by hand because ChoosePixelFormat is unreliable */
733     nFormats = DescribePixelFormat(hdcDst, 0, 0, NULL);
734     for(i=1; i<=nFormats; i++)
735     {
736         memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
737         DescribePixelFormat(hdcDst, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
738 
739         if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) &&
740            (pfd.dwFlags & PFD_SUPPORT_OPENGL) &&
741            (pfd.cColorBits == bpp) &&
742            (pfd.cAlphaBits == 8) )
743         {
744             iPixelFormat = i;
745             break;
746         }
747     }
748 
749     if(!iPixelFormat)
750     {
751         skip("Unable to find a suitable pixel format\n");
752     }
753     else
754     {
755         ret = SetPixelFormat(hdcDst, iPixelFormat, &pfd);
756         ok( ret, "SetPixelFormat failed\n" );
757         ret = GetPixelFormat( hdcDst );
758         ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
759         ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
760         ok( !ret, "SetPixelFormat succeeded\n" );
761         hglrc = wglCreateContext(hdcDst);
762         ok(hglrc != NULL, "Unable to create a context\n");
763 
764         if(hglrc)
765         {
766             GLint viewport[4];
767             wglMakeCurrent(hdcDst, hglrc);
768             hglrc2 = wglCreateContext(hdcDst);
769             ok(hglrc2 != NULL, "Unable to create a context\n");
770 
771             /* Note this is RGBA but we read ARGB back */
772             glClearColor((float)0x22/0xff, (float)0x33/0xff, (float)0x44/0xff, (float)0x11/0xff);
773             glClear(GL_COLOR_BUFFER_BIT);
774             glGetIntegerv( GL_VIEWPORT, viewport );
775             glFinish();
776 
777             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
778                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
779             /* Note apparently the alpha channel is not supported by the software renderer (bitmap only works using software) */
780             if (dstBuffer)
781                 for (i = 0; i < 16; i++)
782                     ok(dstBuffer[i] == 0x223344 || dstBuffer[i] == 0x11223344, "Received color=%x at %u\n",
783                        dstBuffer[i], i);
784 
785             SelectObject(hdcDst, bmp2);
786             ret = GetPixelFormat( hdcDst );
787             ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
788             ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
789             ok( !ret, "SetPixelFormat succeeded\n" );
790 
791             /* context still uses the old pixel format and viewport */
792             glClearColor((float)0x44/0xff, (float)0x33/0xff, (float)0x22/0xff, (float)0x11/0xff);
793             glClear(GL_COLOR_BUFFER_BIT);
794             glFinish();
795             glGetIntegerv( GL_VIEWPORT, viewport );
796             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
797                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
798 
799             wglMakeCurrent(NULL, NULL);
800             wglMakeCurrent(hdcDst, hglrc);
801             glClearColor((float)0x44/0xff, (float)0x55/0xff, (float)0x66/0xff, (float)0x11/0xff);
802             glClear(GL_COLOR_BUFFER_BIT);
803             glFinish();
804             glGetIntegerv( GL_VIEWPORT, viewport );
805             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
806                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
807 
808             wglMakeCurrent(hdcDst, hglrc2);
809             glGetIntegerv( GL_VIEWPORT, viewport );
810             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
811                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
812 
813             wglMakeCurrent(hdcDst, hglrc);
814             glGetIntegerv( GL_VIEWPORT, viewport );
815             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 4 && viewport[3] == 4,
816                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
817 
818             SelectObject(hdcDst, bmpDst);
819             ret = GetPixelFormat( hdcDst );
820             ok( ret == iPixelFormat, "GetPixelFormat returned %d/%d\n", ret, iPixelFormat );
821             ret = SetPixelFormat(hdcDst, iPixelFormat + 1, &pfd);
822             ok( !ret, "SetPixelFormat succeeded\n" );
823             wglMakeCurrent(hdcDst, hglrc2);
824             glGetIntegerv( GL_VIEWPORT, viewport );
825             ok( viewport[0] == 0 && viewport[1] == 0 && viewport[2] == 12 && viewport[3] == 12,
826                 "wrong viewport %d,%d,%d,%d\n", viewport[0], viewport[1], viewport[2], viewport[3] );
827 
828             wglDeleteContext(hglrc2);
829             wglDeleteContext(hglrc);
830         }
831     }
832 
833     SelectObject(hdcDst, oldDst);
834     DeleteObject(bmp2);
835     DeleteObject(bmpDst);
836     DeleteDC(hdcDst);
837     DeleteDC(hdcScreen);
838 }
839 
840 struct wgl_thread_param
841 {
842     HANDLE test_finished;
843     HWND hwnd;
844     HGLRC hglrc;
845     BOOL make_current;
846     BOOL make_current_error;
847     BOOL deleted;
848     DWORD deleted_error;
849 };
850 
851 static DWORD WINAPI wgl_thread(void *param)
852 {
853     struct wgl_thread_param *p = param;
854     HDC hdc = GetDC( p->hwnd );
855 
856     ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
857        "Expected NULL string when no active context is set\n");
858 
859     SetLastError(0xdeadbeef);
860     p->make_current = wglMakeCurrent(hdc, p->hglrc);
861     p->make_current_error = GetLastError();
862     p->deleted = wglDeleteContext(p->hglrc);
863     p->deleted_error = GetLastError();
864     ReleaseDC( p->hwnd, hdc );
865     SetEvent(p->test_finished);
866     return 0;
867 }
868 
869 static void test_deletecontext(HWND hwnd, HDC hdc)
870 {
871     struct wgl_thread_param thread_params;
872     HGLRC hglrc = wglCreateContext(hdc);
873     HANDLE thread_handle;
874     BOOL res;
875     DWORD tid;
876 
877     SetLastError(0xdeadbeef);
878     res = wglDeleteContext(NULL);
879     ok(res == FALSE, "wglDeleteContext succeeded\n");
880     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
881 
882     if(!hglrc)
883     {
884         skip("wglCreateContext failed!\n");
885         return;
886     }
887 
888     res = wglMakeCurrent(hdc, hglrc);
889     if(!res)
890     {
891         skip("wglMakeCurrent failed!\n");
892         return;
893     }
894 
895     /* WGL doesn't allow you to delete a context from a different thread than the one in which it is current.
896      * This differs from GLX which does allow it but it delays actual deletion until the context becomes not current.
897      */
898     thread_params.hglrc = hglrc;
899     thread_params.hwnd  = hwnd;
900     thread_params.test_finished = CreateEventW(NULL, FALSE, FALSE, NULL);
901     thread_handle = CreateThread(NULL, 0, wgl_thread, &thread_params, 0, &tid);
902     ok(!!thread_handle, "Failed to create thread, last error %#x.\n", GetLastError());
903     if(thread_handle)
904     {
905         WaitForSingleObject(thread_handle, INFINITE);
906         ok(!thread_params.make_current, "Attempt to make WGL context from another thread passed\n");
907         ok(thread_params.make_current_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.make_current_error);
908         ok(!thread_params.deleted, "Attempt to delete WGL context from another thread passed\n");
909         ok(thread_params.deleted_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.deleted_error);
910     }
911     CloseHandle(thread_params.test_finished);
912 
913     res = wglDeleteContext(hglrc);
914     ok(res == TRUE, "wglDeleteContext failed\n");
915 
916     /* Attempting to delete the same context twice should fail. */
917     SetLastError(0xdeadbeef);
918     res = wglDeleteContext(hglrc);
919     ok(res == FALSE, "wglDeleteContext succeeded\n");
920     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
921 
922     /* WGL makes a context not current when deleting it. This differs from GLX behavior where
923      * deletion takes place when the thread becomes not current. */
924     hglrc = wglGetCurrentContext();
925     ok(hglrc == NULL, "A WGL context is active while none was expected\n");
926 }
927 
928 
929 static void test_getprocaddress(HDC hdc)
930 {
931     const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
932     PROC func = NULL;
933     HGLRC ctx = wglGetCurrentContext();
934 
935     if (!extensions)
936     {
937         skip("skipping wglGetProcAddress tests because no GL extensions supported\n");
938         return;
939     }
940 
941     /* Core GL 1.0/1.1 functions should not be loadable through wglGetProcAddress.
942      * Try to load the function with and without a context.
943      */
944     func = wglGetProcAddress("glEnable");
945     ok(func == NULL, "Lookup of function glEnable with a context passed, expected a failure\n");
946     wglMakeCurrent(hdc, NULL);
947     func = wglGetProcAddress("glEnable");
948     ok(func == NULL, "Lookup of function glEnable without a context passed, expected a failure\n");
949     wglMakeCurrent(hdc, ctx);
950 
951     /* The goal of the test will be to test behavior of wglGetProcAddress when
952      * no WGL context is active. Before the test we pick an extension (GL_ARB_multitexture)
953      * which any GL >=1.2.1 implementation supports. Unfortunately the GDI renderer doesn't
954      * support it. There aren't any extensions we can use for this test which are supported by
955      * both GDI and real drivers.
956      * Note GDI only has GL_EXT_bgra, GL_EXT_paletted_texture and GL_WIN_swap_hint.
957      */
958     if (!gl_extension_supported(extensions, "GL_ARB_multitexture"))
959     {
960         skip("skipping test because lack of GL_ARB_multitexture support\n");
961         return;
962     }
963 
964     func = wglGetProcAddress("glActiveTextureARB");
965     ok(func != NULL, "Unable to lookup glActiveTextureARB, last error %#x\n", GetLastError());
966 
967     /* Temporarily disable the context, so we can see that we can't retrieve functions now. */
968     wglMakeCurrent(hdc, NULL);
969     func = wglGetProcAddress("glActiveTextureARB");
970     ok(func == NULL, "Function lookup without a context passed, expected a failure; last error %#x\n", GetLastError());
971     wglMakeCurrent(hdc, ctx);
972 }
973 
974 static void test_make_current_read(HDC hdc)
975 {
976     int res;
977     HDC hread;
978     HGLRC hglrc = wglCreateContext(hdc);
979 
980     if(!hglrc)
981     {
982         skip("wglCreateContext failed!\n");
983         return;
984     }
985 
986     res = wglMakeCurrent(hdc, hglrc);
987     if(!res)
988     {
989         skip("wglMakeCurrent failed!\n");
990         return;
991     }
992 
993     /* Test what wglGetCurrentReadDCARB does for wglMakeCurrent as the spec doesn't mention it */
994     hread = pwglGetCurrentReadDCARB();
995     trace("hread %p, hdc %p\n", hread, hdc);
996     ok(hread == hdc, "wglGetCurrentReadDCARB failed for standard wglMakeCurrent\n");
997 
998     pwglMakeContextCurrentARB(hdc, hdc, hglrc);
999     hread = pwglGetCurrentReadDCARB();
1000     ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n");
1001 }
1002 
1003 static void test_dc(HWND hwnd, HDC hdc)
1004 {
1005     int pf1, pf2;
1006     HDC hdc2;
1007 
1008     /* Get another DC and make sure it has the same pixel format */
1009     hdc2 = GetDC(hwnd);
1010     if(hdc != hdc2)
1011     {
1012         pf1 = GetPixelFormat(hdc);
1013         pf2 = GetPixelFormat(hdc2);
1014         ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2);
1015     }
1016     else
1017         skip("Could not get a different DC for the window\n");
1018 
1019     if(hdc2)
1020     {
1021         ReleaseDC(hwnd, hdc2);
1022         hdc2 = NULL;
1023     }
1024 }
1025 
1026 /* Nvidia converts win32 error codes to (0xc007 << 16) | win32_error_code */
1027 #define NVIDIA_HRESULT_FROM_WIN32(x) (HRESULT_FROM_WIN32(x) | 0x40000000)
1028 static void test_opengl3(HDC hdc)
1029 {
1030     /* Try to create a context compatible with OpenGL 1.x; 1.0-2.1 is allowed */
1031     {
1032         HGLRC gl3Ctx;
1033         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 1, 0};
1034 
1035         gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1036         ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 1.x context failed!\n");
1037         wglDeleteContext(gl3Ctx);
1038     }
1039 
1040     /* Try to pass an invalid HDC */
1041     {
1042         HGLRC gl3Ctx;
1043         DWORD error;
1044         SetLastError(0xdeadbeef);
1045         gl3Ctx = pwglCreateContextAttribsARB((HDC)0xdeadbeef, 0, 0);
1046         ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid HDC passed\n");
1047         error = GetLastError();
1048         ok(error == ERROR_DC_NOT_FOUND || error == ERROR_INVALID_HANDLE ||
1049            broken(error == ERROR_DS_GENERIC_ERROR) ||
1050            broken(error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_DATA)), /* Nvidia Vista + Win7 */
1051            "Expected ERROR_DC_NOT_FOUND, got error=%x\n", error);
1052         wglDeleteContext(gl3Ctx);
1053     }
1054 
1055     /* Try to pass an invalid shareList */
1056     {
1057         HGLRC gl3Ctx;
1058         DWORD error;
1059         SetLastError(0xdeadbeef);
1060         gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0);
1061         ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
1062         error = GetLastError();
1063         /* The Nvidia implementation seems to return hresults instead of win32 error codes */
1064         ok(error == ERROR_INVALID_OPERATION || error == ERROR_INVALID_DATA ||
1065            error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION), "Expected ERROR_INVALID_OPERATION, got error=%x\n", error);
1066         wglDeleteContext(gl3Ctx);
1067     }
1068 
1069     /* Try to create an OpenGL 3.0 context */
1070     {
1071         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1072         HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1073 
1074         if(gl3Ctx == NULL)
1075         {
1076             skip("Skipping the rest of the WGL_ARB_create_context test due to lack of OpenGL 3.0\n");
1077             return;
1078         }
1079 
1080         wglDeleteContext(gl3Ctx);
1081     }
1082 
1083     /* 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 */
1084     {
1085         HGLRC glCtx = wglCreateContext(hdc);
1086 
1087         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1088         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};
1089 
1090         HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs);
1091         ok(gl3Ctx != NULL, "Sharing of a display list between OpenGL 3.0 and OpenGL 1.x/2.x failed!\n");
1092         if(gl3Ctx)
1093             wglDeleteContext(gl3Ctx);
1094 
1095         gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs_future);
1096         ok(gl3Ctx != NULL, "Sharing of a display list between a forward compatible OpenGL 3.0 context and OpenGL 1.x/2.x failed!\n");
1097         if(gl3Ctx)
1098             wglDeleteContext(gl3Ctx);
1099 
1100         if(glCtx)
1101             wglDeleteContext(glCtx);
1102     }
1103 
1104     /* Try to create an OpenGL 3.0 context and test windowless rendering */
1105     {
1106         HGLRC gl3Ctx;
1107         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
1108         BOOL res;
1109 
1110         gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
1111         ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 3.0 context failed!\n");
1112 
1113         /* OpenGL 3.0 allows offscreen rendering WITHOUT a drawable
1114          * Neither AMD or Nvidia support it at this point. The WGL_ARB_create_context specs also say that
1115          * it is hard because drivers use the HDC to enter the display driver and it sounds like they don't
1116          * expect drivers to ever offer it.
1117          */
1118         res = wglMakeCurrent(0, gl3Ctx);
1119         ok(res == FALSE, "Wow, OpenGL 3.0 windowless rendering passed while it was expected not to!\n");
1120         if(res)
1121             wglMakeCurrent(0, 0);
1122 
1123         if(gl3Ctx)
1124             wglDeleteContext(gl3Ctx);
1125     }
1126 }
1127 
1128 static void test_minimized(void)
1129 {
1130     PIXELFORMATDESCRIPTOR pf_desc =
1131     {
1132         sizeof(PIXELFORMATDESCRIPTOR),
1133         1,                     /* version */
1134         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1135         PFD_TYPE_RGBA,
1136         24,                    /* 24-bit color depth */
1137         0, 0, 0, 0, 0, 0,      /* color bits */
1138         0,                     /* alpha buffer */
1139         0,                     /* shift bit */
1140         0,                     /* accumulation buffer */
1141         0, 0, 0, 0,            /* accum bits */
1142         32,                    /* z-buffer */
1143         0,                     /* stencil buffer */
1144         0,                     /* auxiliary buffer */
1145         PFD_MAIN_PLANE,        /* main layer */
1146         0,                     /* reserved */
1147         0, 0, 0                /* layer masks */
1148     };
1149     int pixel_format;
1150     HWND window;
1151     LONG style;
1152     HGLRC ctx;
1153     BOOL ret;
1154     HDC dc;
1155 
1156     window = CreateWindowA("static", "opengl32_test",
1157             WS_POPUP | WS_MINIMIZE, 0, 0, 640, 480, 0, 0, 0, 0);
1158     ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1159 
1160     dc = GetDC(window);
1161     ok(!!dc, "Failed to get DC.\n");
1162 
1163     pixel_format = ChoosePixelFormat(dc, &pf_desc);
1164     if (!pixel_format)
1165     {
1166         win_skip("Failed to find pixel format.\n");
1167         ReleaseDC(window, dc);
1168         DestroyWindow(window);
1169         return;
1170     }
1171 
1172     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1173     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1174 
1175     style = GetWindowLongA(window, GWL_STYLE);
1176     ok(style & WS_MINIMIZE, "Window should be minimized, got style %#x.\n", style);
1177 
1178     ctx = wglCreateContext(dc);
1179     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1180 
1181     ret = wglMakeCurrent(dc, ctx);
1182     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1183 
1184     style = GetWindowLongA(window, GWL_STYLE);
1185     ok(style & WS_MINIMIZE, "window should be minimized, got style %#x.\n", style);
1186 
1187     ret = wglMakeCurrent(NULL, NULL);
1188     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1189 
1190     ret = wglDeleteContext(ctx);
1191     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1192 
1193     ReleaseDC(window, dc);
1194     DestroyWindow(window);
1195 }
1196 
1197 static void test_window_dc(void)
1198 {
1199     PIXELFORMATDESCRIPTOR pf_desc =
1200     {
1201         sizeof(PIXELFORMATDESCRIPTOR),
1202         1,                     /* version */
1203         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1204         PFD_TYPE_RGBA,
1205         24,                    /* 24-bit color depth */
1206         0, 0, 0, 0, 0, 0,      /* color bits */
1207         0,                     /* alpha buffer */
1208         0,                     /* shift bit */
1209         0,                     /* accumulation buffer */
1210         0, 0, 0, 0,            /* accum bits */
1211         32,                    /* z-buffer */
1212         0,                     /* stencil buffer */
1213         0,                     /* auxiliary buffer */
1214         PFD_MAIN_PLANE,        /* main layer */
1215         0,                     /* reserved */
1216         0, 0, 0                /* layer masks */
1217     };
1218     int pixel_format;
1219     HWND window;
1220     RECT vp, r;
1221     HGLRC ctx;
1222     BOOL ret;
1223     HDC dc;
1224 
1225     window = CreateWindowA("static", "opengl32_test",
1226             WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
1227     ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1228 
1229     ShowWindow(window, SW_SHOW);
1230 
1231     dc = GetWindowDC(window);
1232     ok(!!dc, "Failed to get DC.\n");
1233 
1234     pixel_format = ChoosePixelFormat(dc, &pf_desc);
1235     if (!pixel_format)
1236     {
1237         win_skip("Failed to find pixel format.\n");
1238         ReleaseDC(window, dc);
1239         DestroyWindow(window);
1240         return;
1241     }
1242 
1243     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1244     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1245 
1246     ctx = wglCreateContext(dc);
1247     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1248 
1249     ret = wglMakeCurrent(dc, ctx);
1250     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1251 
1252     GetClientRect(window, &r);
1253     glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1254     ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1255 
1256     ret = wglMakeCurrent(NULL, NULL);
1257     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1258 
1259     ret = wglDeleteContext(ctx);
1260     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1261 
1262     ReleaseDC(window, dc);
1263     DestroyWindow(window);
1264 }
1265 
1266 static void test_message_window(void)
1267 {
1268     PIXELFORMATDESCRIPTOR pf_desc =
1269     {
1270         sizeof(PIXELFORMATDESCRIPTOR),
1271         1,                     /* version */
1272         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1273         PFD_TYPE_RGBA,
1274         24,                    /* 24-bit color depth */
1275         0, 0, 0, 0, 0, 0,      /* color bits */
1276         0,                     /* alpha buffer */
1277         0,                     /* shift bit */
1278         0,                     /* accumulation buffer */
1279         0, 0, 0, 0,            /* accum bits */
1280         32,                    /* z-buffer */
1281         0,                     /* stencil buffer */
1282         0,                     /* auxiliary buffer */
1283         PFD_MAIN_PLANE,        /* main layer */
1284         0,                     /* reserved */
1285         0, 0, 0                /* layer masks */
1286     };
1287     int pixel_format;
1288     HWND window;
1289     RECT vp, r;
1290     HGLRC ctx;
1291     BOOL ret;
1292     HDC dc;
1293     GLenum glerr;
1294 
1295     window = CreateWindowA("static", "opengl32_test",
1296                            WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, HWND_MESSAGE, 0, 0, 0);
1297     if (!window)
1298     {
1299         win_skip( "HWND_MESSAGE not supported\n" );
1300         return;
1301     }
1302     dc = GetDC(window);
1303     ok(!!dc, "Failed to get DC.\n");
1304 
1305     pixel_format = ChoosePixelFormat(dc, &pf_desc);
1306     if (!pixel_format)
1307     {
1308         win_skip("Failed to find pixel format.\n");
1309         ReleaseDC(window, dc);
1310         DestroyWindow(window);
1311         return;
1312     }
1313 
1314     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1315     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1316 
1317     ctx = wglCreateContext(dc);
1318     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1319 
1320     ret = wglMakeCurrent(dc, ctx);
1321     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1322 
1323     GetClientRect(window, &r);
1324     glGetIntegerv(GL_VIEWPORT, (GLint *)&vp);
1325     ok(EqualRect(&r, &vp), "Viewport not equal to client rect.\n");
1326 
1327     glClear(GL_COLOR_BUFFER_BIT);
1328     glFinish();
1329     glerr = glGetError();
1330     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1331     ret = SwapBuffers(dc);
1332     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1333 
1334     ret = wglMakeCurrent(NULL, NULL);
1335     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1336 
1337     ret = wglDeleteContext(ctx);
1338     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1339 
1340     ReleaseDC(window, dc);
1341     DestroyWindow(window);
1342 }
1343 
1344 static void test_destroy(HDC oldhdc)
1345 {
1346     PIXELFORMATDESCRIPTOR pf_desc =
1347     {
1348         sizeof(PIXELFORMATDESCRIPTOR),
1349         1,                     /* version */
1350         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1351         PFD_TYPE_RGBA,
1352         24,                    /* 24-bit color depth */
1353         0, 0, 0, 0, 0, 0,      /* color bits */
1354         0,                     /* alpha buffer */
1355         0,                     /* shift bit */
1356         0,                     /* accumulation buffer */
1357         0, 0, 0, 0,            /* accum bits */
1358         32,                    /* z-buffer */
1359         0,                     /* stencil buffer */
1360         0,                     /* auxiliary buffer */
1361         PFD_MAIN_PLANE,        /* main layer */
1362         0,                     /* reserved */
1363         0, 0, 0                /* layer masks */
1364     };
1365     int pixel_format;
1366     HWND window;
1367     HGLRC ctx;
1368     BOOL ret;
1369     HDC dc;
1370     GLenum glerr;
1371     DWORD err;
1372     HGLRC oldctx = wglGetCurrentContext();
1373 
1374     ok(!!oldctx, "Expected to find a valid current context.\n");
1375 
1376     window = CreateWindowA("static", "opengl32_test",
1377             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1378     ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
1379 
1380     dc = GetDC(window);
1381     ok(!!dc, "Failed to get DC.\n");
1382 
1383     pixel_format = ChoosePixelFormat(dc, &pf_desc);
1384     if (!pixel_format)
1385     {
1386         win_skip("Failed to find pixel format.\n");
1387         ReleaseDC(window, dc);
1388         DestroyWindow(window);
1389         return;
1390     }
1391 
1392     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
1393     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1394 
1395     ctx = wglCreateContext(dc);
1396     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1397 
1398     ret = wglMakeCurrent(dc, ctx);
1399     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1400 
1401     glClear(GL_COLOR_BUFFER_BIT);
1402     glFinish();
1403     glerr = glGetError();
1404     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1405     ret = SwapBuffers(dc);
1406     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1407 
1408     ret = DestroyWindow(window);
1409     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1410 
1411     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1412 
1413     SetLastError(0xdeadbeef);
1414     ret = wglMakeCurrent(dc, ctx);
1415     err = GetLastError();
1416     ok(!ret && err == ERROR_INVALID_HANDLE,
1417             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1418     SetLastError(0xdeadbeef);
1419     ret = SwapBuffers(dc);
1420     err = GetLastError();
1421     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1422 
1423     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1424 
1425     glClear(GL_COLOR_BUFFER_BIT);
1426     glFinish();
1427     glerr = glGetError();
1428     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1429     SetLastError(0xdeadbeef);
1430     ret = SwapBuffers(dc);
1431     err = GetLastError();
1432     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1433 
1434     ret = wglMakeCurrent(NULL, NULL);
1435     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1436 
1437     glClear(GL_COLOR_BUFFER_BIT);
1438     glFinish();
1439     glerr = glGetError();
1440     ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1441     SetLastError(0xdeadbeef);
1442     ret = SwapBuffers(dc);
1443     err = GetLastError();
1444     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1445 
1446     SetLastError(0xdeadbeef);
1447     ret = wglMakeCurrent(dc, ctx);
1448     err = GetLastError();
1449     ok(!ret && err == ERROR_INVALID_HANDLE,
1450             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1451 
1452     ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1453 
1454     ret = wglMakeCurrent(oldhdc, oldctx);
1455     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1456     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1457 
1458     SetLastError(0xdeadbeef);
1459     ret = wglMakeCurrent(dc, ctx);
1460     err = GetLastError();
1461     ok(!ret && err == ERROR_INVALID_HANDLE,
1462             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1463 
1464     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1465 
1466     ret = wglDeleteContext(ctx);
1467     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1468 
1469     ReleaseDC(window, dc);
1470 
1471     ret = wglMakeCurrent(oldhdc, oldctx);
1472     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1473 }
1474 
1475 static void test_destroy_read(HDC oldhdc)
1476 {
1477     PIXELFORMATDESCRIPTOR pf_desc =
1478     {
1479         sizeof(PIXELFORMATDESCRIPTOR),
1480         1,                     /* version */
1481         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1482         PFD_TYPE_RGBA,
1483         24,                    /* 24-bit color depth */
1484         0, 0, 0, 0, 0, 0,      /* color bits */
1485         0,                     /* alpha buffer */
1486         0,                     /* shift bit */
1487         0,                     /* accumulation buffer */
1488         0, 0, 0, 0,            /* accum bits */
1489         32,                    /* z-buffer */
1490         0,                     /* stencil buffer */
1491         0,                     /* auxiliary buffer */
1492         PFD_MAIN_PLANE,        /* main layer */
1493         0,                     /* reserved */
1494         0, 0, 0                /* layer masks */
1495     };
1496     int pixel_format;
1497     HWND draw_window, read_window;
1498     HGLRC ctx;
1499     BOOL ret;
1500     HDC read_dc, draw_dc;
1501     GLenum glerr;
1502     DWORD err;
1503     HGLRC oldctx = wglGetCurrentContext();
1504 
1505     ok(!!oldctx, "Expected to find a valid current context\n");
1506 
1507     draw_window = CreateWindowA("static", "opengl32_test",
1508             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1509     ok(!!draw_window, "Failed to create window, last error %#x.\n", GetLastError());
1510 
1511     draw_dc = GetDC(draw_window);
1512     ok(!!draw_dc, "Failed to get DC.\n");
1513 
1514     pixel_format = ChoosePixelFormat(draw_dc, &pf_desc);
1515     if (!pixel_format)
1516     {
1517         win_skip("Failed to find pixel format.\n");
1518         ReleaseDC(draw_window, draw_dc);
1519         DestroyWindow(draw_window);
1520         return;
1521     }
1522 
1523     ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc);
1524     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1525 
1526     read_window = CreateWindowA("static", "opengl32_test",
1527             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1528     ok(!!read_window, "Failed to create window, last error %#x.\n", GetLastError());
1529 
1530     read_dc = GetDC(read_window);
1531     ok(!!draw_dc, "Failed to get DC.\n");
1532 
1533     pixel_format = ChoosePixelFormat(read_dc, &pf_desc);
1534     if (!pixel_format)
1535     {
1536         win_skip("Failed to find pixel format.\n");
1537         ReleaseDC(read_window, read_dc);
1538         DestroyWindow(read_window);
1539         ReleaseDC(draw_window, draw_dc);
1540         DestroyWindow(draw_window);
1541         return;
1542     }
1543 
1544     ret = SetPixelFormat(read_dc, pixel_format, &pf_desc);
1545     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1546 
1547     ctx = wglCreateContext(draw_dc);
1548     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1549 
1550     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1551     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1552 
1553     glCopyPixels(0, 0, 640, 480, GL_COLOR);
1554     glFinish();
1555     glerr = glGetError();
1556     ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1557     ret = SwapBuffers(draw_dc);
1558     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1559 
1560     ret = DestroyWindow(read_window);
1561     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1562 
1563     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1564 
1565     if (0) /* Crashes on AMD on Windows */
1566     {
1567         glCopyPixels(0, 0, 640, 480, GL_COLOR);
1568         glFinish();
1569         glerr = glGetError();
1570         ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1571     }
1572 
1573     glClear(GL_COLOR_BUFFER_BIT);
1574     glFinish();
1575     glerr = glGetError();
1576     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1577     ret = SwapBuffers(draw_dc);
1578     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1579 
1580     ret = wglMakeCurrent(NULL, NULL);
1581     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1582 
1583     if (0) /* This crashes with Nvidia drivers on Windows. */
1584     {
1585         SetLastError(0xdeadbeef);
1586         ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1587         err = GetLastError();
1588         ok(!ret && err == ERROR_INVALID_HANDLE,
1589                 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1590     }
1591 
1592     ret = DestroyWindow(draw_window);
1593     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1594 
1595     glClear(GL_COLOR_BUFFER_BIT);
1596     glFinish();
1597     glerr = glGetError();
1598     ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1599     SetLastError(0xdeadbeef);
1600     ret = SwapBuffers(draw_dc);
1601     err = GetLastError();
1602     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1603 
1604     SetLastError(0xdeadbeef);
1605     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1606     err = GetLastError();
1607     ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1608             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1609 
1610     ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1611 
1612     wglMakeCurrent(NULL, NULL);
1613 
1614     wglMakeCurrent(oldhdc, oldctx);
1615     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1616 
1617     SetLastError(0xdeadbeef);
1618     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1619     err = GetLastError();
1620     ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1621             "Unexpected behavior when making context current, last error %#x.\n", err);
1622 
1623     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1624 
1625     ret = wglDeleteContext(ctx);
1626     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1627 
1628     ReleaseDC(read_window, read_dc);
1629     ReleaseDC(draw_window, draw_dc);
1630 
1631     wglMakeCurrent(oldhdc, oldctx);
1632 }
1633 
1634 static void test_swap_control(HDC oldhdc)
1635 {
1636     PIXELFORMATDESCRIPTOR pf_desc =
1637     {
1638         sizeof(PIXELFORMATDESCRIPTOR),
1639         1,                     /* version */
1640         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1641         PFD_TYPE_RGBA,
1642         24,                    /* 24-bit color depth */
1643         0, 0, 0, 0, 0, 0,      /* color bits */
1644         0,                     /* alpha buffer */
1645         0,                     /* shift bit */
1646         0,                     /* accumulation buffer */
1647         0, 0, 0, 0,            /* accum bits */
1648         32,                    /* z-buffer */
1649         0,                     /* stencil buffer */
1650         0,                     /* auxiliary buffer */
1651         PFD_MAIN_PLANE,        /* main layer */
1652         0,                     /* reserved */
1653         0, 0, 0                /* layer masks */
1654     };
1655     int pixel_format;
1656     HWND window1, window2, old_parent;
1657     HGLRC ctx1, ctx2, oldctx;
1658     BOOL ret;
1659     HDC dc1, dc2;
1660     int interval;
1661 
1662     oldctx = wglGetCurrentContext();
1663     ok(!!oldctx, "Expected to find a valid current context.\n");
1664 
1665     window1 = CreateWindowA("static", "opengl32_test",
1666             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1667     ok(!!window1, "Failed to create window1, last error %#x.\n", GetLastError());
1668 
1669     dc1 = GetDC(window1);
1670     ok(!!dc1, "Failed to get DC.\n");
1671 
1672     pixel_format = ChoosePixelFormat(dc1, &pf_desc);
1673     if (!pixel_format)
1674     {
1675         win_skip("Failed to find pixel format.\n");
1676         ReleaseDC(window1, dc1);
1677         DestroyWindow(window1);
1678         return;
1679     }
1680 
1681     ret = SetPixelFormat(dc1, pixel_format, &pf_desc);
1682     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1683 
1684     ctx1 = wglCreateContext(dc1);
1685     ok(!!ctx1, "Failed to create GL context, last error %#x.\n", GetLastError());
1686 
1687     ret = wglMakeCurrent(dc1, ctx1);
1688     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1689 
1690     interval = pwglGetSwapIntervalEXT();
1691     ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1692 
1693     ret = pwglSwapIntervalEXT(0);
1694     ok(ret, "Failed to set swap interval to 0, last error %#x.\n", GetLastError());
1695 
1696     interval = pwglGetSwapIntervalEXT();
1697     ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1698 
1699     /* Check what interval we get on a second context on the same drawable.*/
1700     ctx2 = wglCreateContext(dc1);
1701     ok(!!ctx2, "Failed to create GL context, last error %#x.\n", GetLastError());
1702 
1703     ret = wglMakeCurrent(dc1, ctx2);
1704     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1705 
1706     interval = pwglGetSwapIntervalEXT();
1707     ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1708 
1709     /* A second window is created to see whether its swap interval was affected
1710      * by previous calls.
1711      */
1712     window2 = CreateWindowA("static", "opengl32_test",
1713             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1714     ok(!!window2, "Failed to create window2, last error %#x.\n", GetLastError());
1715 
1716     dc2 = GetDC(window2);
1717     ok(!!dc2, "Failed to get DC.\n");
1718 
1719     ret = SetPixelFormat(dc2, pixel_format, &pf_desc);
1720     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1721 
1722     ret = wglMakeCurrent(dc2, ctx1);
1723     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1724 
1725     /* Since the second window lacks the swap interval, this proves that the interval
1726      * is not global or shared among contexts.
1727      */
1728     interval = pwglGetSwapIntervalEXT();
1729     ok(interval == 1, "Expected default swap interval 1, got %d\n", interval);
1730 
1731     /* Test if setting the parent of a window resets the swap interval. */
1732     ret = wglMakeCurrent(dc1, ctx1);
1733     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1734 
1735     old_parent = SetParent(window1, window2);
1736     ok(!!old_parent, "Failed to make window1 a child of window2, last error %#x.\n", GetLastError());
1737 
1738     interval = pwglGetSwapIntervalEXT();
1739     ok(interval == 0, "Expected swap interval 0, got %d\n", interval);
1740 
1741     ret = wglDeleteContext(ctx1);
1742     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1743     ret = wglDeleteContext(ctx2);
1744     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1745 
1746     ReleaseDC(window1, dc1);
1747     DestroyWindow(window1);
1748     ReleaseDC(window2, dc2);
1749     DestroyWindow(window2);
1750 
1751     wglMakeCurrent(oldhdc, oldctx);
1752 }
1753 
1754 START_TEST(opengl)
1755 {
1756     HWND hwnd;
1757     PIXELFORMATDESCRIPTOR pfd = {
1758         sizeof(PIXELFORMATDESCRIPTOR),
1759         1,                     /* version */
1760         PFD_DRAW_TO_WINDOW |
1761         PFD_SUPPORT_OPENGL |
1762         PFD_DOUBLEBUFFER,
1763         PFD_TYPE_RGBA,
1764         24,                    /* 24-bit color depth */
1765         0, 0, 0, 0, 0, 0,      /* color bits */
1766         0,                     /* alpha buffer */
1767         0,                     /* shift bit */
1768         0,                     /* accumulation buffer */
1769         0, 0, 0, 0,            /* accum bits */
1770         32,                    /* z-buffer */
1771         0,                     /* stencil buffer */
1772         0,                     /* auxiliary buffer */
1773         PFD_MAIN_PLANE,        /* main layer */
1774         0,                     /* reserved */
1775         0, 0, 0                /* layer masks */
1776     };
1777 
1778     hwnd = CreateWindowA("static", "Title", WS_OVERLAPPEDWINDOW, 10, 10, 200, 200, NULL, NULL,
1779             NULL, NULL);
1780     ok(hwnd != NULL, "err: %d\n", GetLastError());
1781     if (hwnd)
1782     {
1783         HDC hdc;
1784         int iPixelFormat, res;
1785         HGLRC hglrc;
1786         DWORD error;
1787         ShowWindow(hwnd, SW_SHOW);
1788 
1789         hdc = GetDC(hwnd);
1790 
1791         iPixelFormat = ChoosePixelFormat(hdc, &pfd);
1792         if(iPixelFormat == 0)
1793         {
1794             /* This should never happen as ChoosePixelFormat always returns a closest match, but currently this fails in Wine if we don't have glX */
1795             win_skip("Unable to find pixel format.\n");
1796             goto cleanup;
1797         }
1798 
1799         /* We shouldn't be able to create a context from a hdc which doesn't have a pixel format set */
1800         hglrc = wglCreateContext(hdc);
1801         ok(hglrc == NULL, "wglCreateContext should fail when no pixel format has been set, but it passed\n");
1802         error = GetLastError();
1803         ok(error == ERROR_INVALID_PIXEL_FORMAT, "expected ERROR_INVALID_PIXEL_FORMAT for wglCreateContext without a pixelformat set, but received %#x\n", error);
1804 
1805         res = SetPixelFormat(hdc, iPixelFormat, &pfd);
1806         ok(res, "SetPixelformat failed: %x\n", GetLastError());
1807 
1808         test_bitmap_rendering( TRUE );
1809         test_bitmap_rendering( FALSE );
1810         test_minimized();
1811         test_window_dc();
1812         test_message_window();
1813         test_dc(hwnd, hdc);
1814 
1815         ok(!glGetString(GL_RENDERER) && !glGetString(GL_VERSION) && !glGetString(GL_VENDOR),
1816            "Expected NULL string when no active context is set\n");
1817         hglrc = wglCreateContext(hdc);
1818         res = wglMakeCurrent(hdc, hglrc);
1819         ok(res, "wglMakeCurrent failed!\n");
1820         if(res)
1821         {
1822             trace("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
1823             trace("OpenGL driver version: %s\n", glGetString(GL_VERSION));
1824             trace("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
1825         }
1826         else
1827         {
1828             skip("Skipping OpenGL tests without a current context\n");
1829             return;
1830         }
1831 
1832         /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making
1833          * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD).
1834          */
1835         init_functions();
1836         test_getprocaddress(hdc);
1837         test_deletecontext(hwnd, hdc);
1838         test_makecurrent(hdc);
1839 
1840         /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */
1841         if (!pwglGetExtensionsStringARB)
1842         {
1843             win_skip("wglGetExtensionsStringARB is not available\n");
1844             return;
1845         }
1846 
1847         test_choosepixelformat();
1848         test_debug_message_callback();
1849         test_setpixelformat(hdc);
1850         test_destroy(hdc);
1851         test_sharelists(hdc);
1852         test_colorbits(hdc);
1853         test_gdi_dbuf(hdc);
1854         test_acceleration(hdc);
1855 
1856         wgl_extensions = pwglGetExtensionsStringARB(hdc);
1857         if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n");
1858 
1859         if(strstr(wgl_extensions, "WGL_ARB_create_context"))
1860             test_opengl3(hdc);
1861 
1862         if(strstr(wgl_extensions, "WGL_ARB_make_current_read"))
1863         {
1864             test_make_current_read(hdc);
1865             test_destroy_read(hdc);
1866         }
1867         else
1868             skip("WGL_ARB_make_current_read not supported, skipping test\n");
1869 
1870         if(strstr(wgl_extensions, "WGL_ARB_pbuffer"))
1871             test_pbuffers(hdc);
1872         else
1873             skip("WGL_ARB_pbuffer not supported, skipping pbuffer test\n");
1874 
1875         if(strstr(wgl_extensions, "WGL_EXT_swap_control"))
1876             test_swap_control(hdc);
1877         else
1878             skip("WGL_EXT_swap_control not supported, skipping test\n");
1879 
1880 cleanup:
1881         ReleaseDC(hwnd, hdc);
1882         DestroyWindow(hwnd);
1883     }
1884 }
1885