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