opengl32/tests: Improve window destroy tests.
[wine] / dlls / opengl32 / tests / 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
25 void WINAPI glClearColor(float red, float green, float blue, float alpha);
26 void WINAPI glClear(unsigned int mask);
27 #define GL_COLOR 0x1800
28 typedef unsigned int GLenum;
29 void WINAPI glCopyPixels(int x, int y, int width, int height, GLenum type);
30 void WINAPI glFinish(void);
31 #define GL_NO_ERROR 0x0
32 #define GL_INVALID_OPERATION 0x502
33 GLenum WINAPI glGetError(void);
34 #define GL_COLOR_BUFFER_BIT 0x00004000
35 const unsigned char * WINAPI glGetString(unsigned int);
36 #define GL_VENDOR 0x1F00
37 #define GL_RENDERER 0x1F01
38 #define GL_VERSION 0x1F02
39
40 #define MAX_FORMATS 256
41 typedef void* HPBUFFERARB;
42
43 /* WGL_ARB_create_context */
44 static HGLRC (WINAPI *pwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList);
45 /* GetLastError */
46 #define ERROR_INVALID_VERSION_ARB 0x2095
47 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
48 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
49 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
50 #define WGL_CONTEXT_FLAGS_ARB 0x2094
51 /* Flags for WGL_CONTEXT_FLAGS_ARB */
52 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
53 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB  0x0002
54
55 /* WGL_ARB_extensions_string */
56 static const char* (WINAPI *pwglGetExtensionsStringARB)(HDC);
57 static int (WINAPI *pwglReleasePbufferDCARB)(HPBUFFERARB, HDC);
58
59 /* WGL_ARB_make_current_read */
60 static BOOL (WINAPI *pwglMakeContextCurrentARB)(HDC hdraw, HDC hread, HGLRC hglrc);
61 static HDC (WINAPI *pwglGetCurrentReadDCARB)(void);
62
63 /* WGL_ARB_pixel_format */
64 #define WGL_ACCELERATION_ARB 0x2003
65 #define WGL_COLOR_BITS_ARB 0x2014
66 #define WGL_RED_BITS_ARB   0x2015
67 #define WGL_GREEN_BITS_ARB 0x2017
68 #define WGL_BLUE_BITS_ARB  0x2019
69 #define WGL_ALPHA_BITS_ARB 0x201B
70 #define WGL_SUPPORT_GDI_ARB   0x200F
71 #define WGL_DOUBLE_BUFFER_ARB 0x2011
72 #define WGL_NO_ACCELERATION_ARB        0x2025
73 #define WGL_GENERIC_ACCELERATION_ARB   0x2026
74 #define WGL_FULL_ACCELERATION_ARB      0x2027
75
76 static BOOL (WINAPI *pwglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *);
77 static BOOL (WINAPI *pwglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int *, int *);
78
79 /* WGL_ARB_pbuffer */
80 #define WGL_DRAW_TO_PBUFFER_ARB 0x202D
81 static HPBUFFERARB* (WINAPI *pwglCreatePbufferARB)(HDC, int, int, int, const int *);
82 static HDC (WINAPI *pwglGetPbufferDCARB)(HPBUFFERARB);
83
84 static const char* wgl_extensions = NULL;
85
86 static void init_functions(void)
87 {
88 #define GET_PROC(func) \
89     p ## func = (void*)wglGetProcAddress(#func); \
90     if(!p ## func) \
91       trace("wglGetProcAddress(%s) failed\n", #func);
92
93     /* WGL_ARB_create_context */
94     GET_PROC(wglCreateContextAttribsARB);
95
96     /* WGL_ARB_extensions_string */
97     GET_PROC(wglGetExtensionsStringARB)
98
99     /* WGL_ARB_make_current_read */
100     GET_PROC(wglMakeContextCurrentARB);
101     GET_PROC(wglGetCurrentReadDCARB);
102
103     /* WGL_ARB_pixel_format */
104     GET_PROC(wglChoosePixelFormatARB)
105     GET_PROC(wglGetPixelFormatAttribivARB)
106
107     /* WGL_ARB_pbuffer */
108     GET_PROC(wglCreatePbufferARB)
109     GET_PROC(wglGetPbufferDCARB)
110     GET_PROC(wglReleasePbufferDCARB)
111
112 #undef GET_PROC
113 }
114
115 static void test_pbuffers(HDC hdc)
116 {
117     const int iAttribList[] = { WGL_DRAW_TO_PBUFFER_ARB, 1, /* Request pbuffer support */
118                                 0 };
119     int iFormats[MAX_FORMATS];
120     unsigned int nOnscreenFormats;
121     unsigned int nFormats;
122     int i, res;
123     int iPixelFormat = 0;
124
125     nOnscreenFormats = DescribePixelFormat(hdc, 0, 0, NULL);
126
127     /* When you want to render to a pbuffer you need to call wglGetPbufferDCARB which
128      * returns a 'magic' HDC which you can then pass to wglMakeCurrent to switch rendering
129      * to the pbuffer. Below some tests are performed on what happens if you use standard WGL calls
130      * on this 'magic' HDC for both a pixelformat that support onscreen and offscreen rendering
131      * and a pixelformat that's only available for offscreen rendering (this means that only
132      * wglChoosePixelFormatARB and friends know about the format.
133      *
134      * The first thing we need are pixelformats with pbuffer capabilities.
135      */
136     res = pwglChoosePixelFormatARB(hdc, iAttribList, NULL, MAX_FORMATS, iFormats, &nFormats);
137     if(res <= 0)
138     {
139         skip("No pbuffer compatible formats found while WGL_ARB_pbuffer is supported\n");
140         return;
141     }
142     trace("nOnscreenFormats: %d\n", nOnscreenFormats);
143     trace("Total number of pbuffer capable pixelformats: %d\n", nFormats);
144
145     /* Try to select an onscreen pixelformat out of the list */
146     for(i=0; i < nFormats; i++)
147     {
148         /* Check if the format is onscreen, if it is choose it */
149         if(iFormats[i] <= nOnscreenFormats)
150         {
151             iPixelFormat = iFormats[i];
152             trace("Selected iPixelFormat=%d\n", iPixelFormat);
153             break;
154         }
155     }
156
157     /* A video driver supports a large number of onscreen and offscreen pixelformats.
158      * The traditional WGL calls only see a subset of the whole pixelformat list. First
159      * of all they only see the onscreen formats (the offscreen formats are at the end of the
160      * pixelformat list) and second extended pixelformat capabilities are hidden from the
161      * standard WGL calls. Only functions that depend on WGL_ARB_pixel_format can see them.
162      *
163      * Below we check if the pixelformat is also supported onscreen.
164      */
165     if(iPixelFormat != 0)
166     {
167         HDC pbuffer_hdc;
168         HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL);
169         if(!pbuffer)
170             skip("Pbuffer creation failed!\n");
171
172         /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
173         pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
174         res = GetPixelFormat(pbuffer_hdc);
175         ok(res == iPixelFormat, "Unexpected iPixelFormat=%d returned by GetPixelFormat for format %d\n", res, iPixelFormat);
176         trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
177         trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
178
179         pwglReleasePbufferDCARB(pbuffer, hdc);
180     }
181     else skip("Pbuffer test for onscreen pixelformat skipped as no onscreen format with pbuffer capabilities have been found\n");
182
183     /* Search for a real offscreen format */
184     for(i=0, iPixelFormat=0; i<nFormats; i++)
185     {
186         if(iFormats[i] > nOnscreenFormats)
187         {
188             iPixelFormat = iFormats[i];
189             trace("Selected iPixelFormat: %d\n", iPixelFormat);
190             break;
191         }
192     }
193
194     if(iPixelFormat != 0)
195     {
196         HDC pbuffer_hdc;
197         HPBUFFERARB pbuffer = pwglCreatePbufferARB(hdc, iPixelFormat, 640 /* width */, 480 /* height */, NULL);
198         if(!pbuffer)
199             skip("Pbuffer creation failed!\n");
200
201         /* Test the pixelformat returned by GetPixelFormat on a pbuffer as the behavior is not clear */
202         pbuffer_hdc = pwglGetPbufferDCARB(pbuffer);
203         res = GetPixelFormat(pbuffer_hdc);
204
205         ok(res == 1, "Unexpected iPixelFormat=%d (1 expected) returned by GetPixelFormat for offscreen format %d\n", res, iPixelFormat);
206         trace("iPixelFormat returned by GetPixelFormat: %d\n", res);
207         trace("PixelFormat from wglChoosePixelFormatARB: %d\n", iPixelFormat);
208         pwglReleasePbufferDCARB(pbuffer, hdc);
209     }
210     else skip("Pbuffer test for offscreen pixelformat skipped as no offscreen-only format with pbuffer capabilities has been found\n");
211 }
212
213 static void test_setpixelformat(HDC winhdc)
214 {
215     int res = 0;
216     int nCfgs;
217     int pf;
218     int i;
219     HWND hwnd;
220     PIXELFORMATDESCRIPTOR pfd = {
221         sizeof(PIXELFORMATDESCRIPTOR),
222         1,                     /* version */
223         PFD_DRAW_TO_WINDOW |
224         PFD_SUPPORT_OPENGL |
225         PFD_DOUBLEBUFFER,
226         PFD_TYPE_RGBA,
227         24,                    /* 24-bit color depth */
228         0, 0, 0, 0, 0, 0,      /* color bits */
229         0,                     /* alpha buffer */
230         0,                     /* shift bit */
231         0,                     /* accumulation buffer */
232         0, 0, 0, 0,            /* accum bits */
233         32,                    /* z-buffer */
234         0,                     /* stencil buffer */
235         0,                     /* auxiliary buffer */
236         PFD_MAIN_PLANE,        /* main layer */
237         0,                     /* reserved */
238         0, 0, 0                /* layer masks */
239     };
240
241     HDC hdc = GetDC(0);
242     ok(hdc != 0, "GetDC(0) failed!\n");
243
244     /* This should pass even on the main device context */
245     pf = ChoosePixelFormat(hdc, &pfd);
246     ok(pf != 0, "ChoosePixelFormat failed on main device context\n");
247
248     /* SetPixelFormat on the main device context 'X root window' should fail,
249      * but some broken drivers allow it
250      */
251     res = SetPixelFormat(hdc, pf, &pfd);
252     trace("SetPixelFormat on main device context %s\n", res ? "succeeded" : "failed");
253
254     /* Setting the same format that was set on the HDC is allowed; other
255        formats fail */
256     nCfgs = DescribePixelFormat(winhdc, 0, 0, NULL);
257     pf = GetPixelFormat(winhdc);
258     for(i = 1;i <= nCfgs;i++)
259     {
260         int res = SetPixelFormat(winhdc, i, NULL);
261         if(i == pf) ok(res, "Failed to set the same pixel format\n");
262         else ok(!res, "Unexpectedly set an alternate pixel format\n");
263     }
264
265     hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW,
266                         10, 10, 200, 200, NULL, NULL, NULL, NULL);
267     ok(hwnd != NULL, "err: %d\n", GetLastError());
268     if (hwnd)
269     {
270         HDC hdc = GetDC( hwnd );
271         pf = ChoosePixelFormat( hdc, &pfd );
272         ok( pf != 0, "ChoosePixelFormat failed\n" );
273         res = SetPixelFormat( hdc, pf, &pfd );
274         ok( res != 0, "SetPixelFormat failed\n" );
275         i = GetPixelFormat( hdc );
276         ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
277         ReleaseDC( hwnd, hdc );
278         hdc = GetWindowDC( hwnd );
279         i = GetPixelFormat( hdc );
280         ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
281         ReleaseDC( hwnd, hdc );
282         DestroyWindow( hwnd );
283     }
284
285     hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW,
286                         10, 10, 200, 200, NULL, NULL, NULL, NULL);
287     ok(hwnd != NULL, "err: %d\n", GetLastError());
288     if (hwnd)
289     {
290         HDC hdc = GetWindowDC( hwnd );
291         pf = ChoosePixelFormat( hdc, &pfd );
292         ok( pf != 0, "ChoosePixelFormat failed\n" );
293         res = SetPixelFormat( hdc, pf, &pfd );
294         ok( res != 0, "SetPixelFormat failed\n" );
295         i = GetPixelFormat( hdc );
296         ok( i == pf, "GetPixelFormat returned wrong format %d/%d\n", i, pf );
297         ReleaseDC( hwnd, hdc );
298         DestroyWindow( hwnd );
299     }
300 }
301
302 static void test_sharelists(HDC winhdc)
303 {
304     HGLRC hglrc1, hglrc2, hglrc3;
305     int res;
306
307     hglrc1 = wglCreateContext(winhdc);
308     res = wglShareLists(0, 0);
309     ok(res == FALSE, "Sharing display lists for no contexts passed!\n");
310
311     /* Test 1: Create a context and just share lists without doing anything special */
312     hglrc2 = wglCreateContext(winhdc);
313     if(hglrc2)
314     {
315         res = wglShareLists(hglrc1, hglrc2);
316         ok(res, "Sharing of display lists failed\n");
317         wglDeleteContext(hglrc2);
318     }
319
320     /* Test 2: Share display lists with a 'destination' context which has been made current */
321     hglrc2 = wglCreateContext(winhdc);
322     if(hglrc2)
323     {
324         res = wglMakeCurrent(winhdc, hglrc2);
325         ok(res, "Make current failed\n");
326         res = wglShareLists(hglrc1, hglrc2);
327         todo_wine ok(res, "Sharing display lists with a destination context which has been made current failed\n");
328         wglMakeCurrent(0, 0);
329         wglDeleteContext(hglrc2);
330     }
331
332     /* Test 3: Share display lists with a context which already shares display lists with another context.
333      * According to MSDN the second parameter cannot share any display lists but some buggy drivers might allow it */
334     hglrc3 = wglCreateContext(winhdc);
335     if(hglrc3)
336     {
337         res = wglShareLists(hglrc3, hglrc1);
338         ok(res == FALSE, "Sharing of display lists passed for a context which already shared lists before\n");
339         wglDeleteContext(hglrc3);
340     }
341
342     /* Test 4: Share display lists with a 'source' context which has been made current */
343     hglrc2 = wglCreateContext(winhdc);
344     if(hglrc2)
345     {
346         res = wglMakeCurrent(winhdc, hglrc1);
347         ok(res, "Make current failed\n");
348         res = wglShareLists(hglrc1, hglrc2);
349         ok(res, "Sharing display lists with a source context which has been made current failed\n");
350         wglMakeCurrent(0, 0);
351         wglDeleteContext(hglrc2);
352     }
353 }
354
355 static void test_makecurrent(HDC winhdc)
356 {
357     BOOL ret;
358     HGLRC hglrc;
359     DWORD error;
360
361     hglrc = wglCreateContext(winhdc);
362     ok( hglrc != 0, "wglCreateContext failed\n" );
363
364     ret = wglMakeCurrent( winhdc, hglrc );
365     ok( ret, "wglMakeCurrent failed\n" );
366
367     ok( wglGetCurrentContext() == hglrc, "wrong context\n" );
368
369     /* set the same context again */
370     ret = wglMakeCurrent( winhdc, hglrc );
371     ok( ret, "wglMakeCurrent failed\n" );
372
373     /* check wglMakeCurrent(x, y) after another call to wglMakeCurrent(x, y) */
374     ret = wglMakeCurrent( winhdc, NULL );
375     ok( ret, "wglMakeCurrent failed\n" );
376
377     ret = wglMakeCurrent( winhdc, NULL );
378     ok( ret, "wglMakeCurrent failed\n" );
379
380     SetLastError( 0xdeadbeef );
381     ret = wglMakeCurrent( NULL, NULL );
382     ok( !ret, "wglMakeCurrent succeeded\n" );
383     error = GetLastError();
384     ok( error == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got error=%x\n", error);
385
386     ret = wglMakeCurrent( winhdc, NULL );
387     ok( ret, "wglMakeCurrent failed\n" );
388
389     ret = wglMakeCurrent( winhdc, hglrc );
390     ok( ret, "wglMakeCurrent failed\n" );
391
392     ret = wglMakeCurrent( NULL, NULL );
393     ok( ret, "wglMakeCurrent failed\n" );
394
395     ok( wglGetCurrentContext() == NULL, "wrong context\n" );
396
397     SetLastError( 0xdeadbeef );
398     ret = wglMakeCurrent( NULL, NULL );
399     ok( !ret, "wglMakeCurrent succeeded\n" );
400     error = GetLastError();
401     ok( error == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got error=%x\n", error);
402
403     ret = wglMakeCurrent( winhdc, hglrc );
404     ok( ret, "wglMakeCurrent failed\n" );
405 }
406
407 static void test_colorbits(HDC hdc)
408 {
409     const int iAttribList[] = { WGL_COLOR_BITS_ARB, WGL_RED_BITS_ARB, WGL_GREEN_BITS_ARB,
410                                 WGL_BLUE_BITS_ARB, WGL_ALPHA_BITS_ARB };
411     int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
412     const int iAttribs[] = { WGL_ALPHA_BITS_ARB, 1, 0 };
413     unsigned int nFormats;
414     int res;
415     int iPixelFormat = 0;
416
417     if (!pwglChoosePixelFormatARB)
418     {
419         win_skip("wglChoosePixelFormatARB is not available\n");
420         return;
421     }
422
423     /* We need a pixel format with at least one bit of alpha */
424     res = pwglChoosePixelFormatARB(hdc, iAttribs, NULL, 1, &iPixelFormat, &nFormats);
425     if(res == FALSE || nFormats == 0)
426     {
427         skip("No suitable pixel formats found\n");
428         return;
429     }
430
431     res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
432               sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList, iAttribRet);
433     if(res == FALSE)
434     {
435         skip("wglGetPixelFormatAttribivARB failed\n");
436         return;
437     }
438     iAttribRet[1] += iAttribRet[2]+iAttribRet[3]+iAttribRet[4];
439     ok(iAttribRet[0] == iAttribRet[1], "WGL_COLOR_BITS_ARB (%d) does not equal R+G+B+A (%d)!\n",
440                                        iAttribRet[0], iAttribRet[1]);
441 }
442
443 static void test_gdi_dbuf(HDC hdc)
444 {
445     const int iAttribList[] = { WGL_SUPPORT_GDI_ARB, WGL_DOUBLE_BUFFER_ARB };
446     int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
447     unsigned int nFormats;
448     int iPixelFormat;
449     int res;
450
451     if (!pwglGetPixelFormatAttribivARB)
452     {
453         win_skip("wglGetPixelFormatAttribivARB is not available\n");
454         return;
455     }
456
457     nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
458     for(iPixelFormat = 1;iPixelFormat <= nFormats;iPixelFormat++)
459     {
460         res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
461                   sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList,
462                   iAttribRet);
463         ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
464         if(res == FALSE)
465             continue;
466
467         ok(!(iAttribRet[0] && iAttribRet[1]), "GDI support and double buffering on pixel format %d\n", iPixelFormat);
468     }
469 }
470
471 static void test_acceleration(HDC hdc)
472 {
473     const int iAttribList[] = { WGL_ACCELERATION_ARB };
474     int iAttribRet[sizeof(iAttribList)/sizeof(iAttribList[0])];
475     unsigned int nFormats;
476     int iPixelFormat;
477     int res;
478     PIXELFORMATDESCRIPTOR pfd;
479
480     if (!pwglGetPixelFormatAttribivARB)
481     {
482         win_skip("wglGetPixelFormatAttribivARB is not available\n");
483         return;
484     }
485
486     nFormats = DescribePixelFormat(hdc, 0, 0, NULL);
487     for(iPixelFormat = 1; iPixelFormat <= nFormats; iPixelFormat++)
488     {
489         res = pwglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0,
490                   sizeof(iAttribList)/sizeof(iAttribList[0]), iAttribList,
491                   iAttribRet);
492         ok(res!=FALSE, "wglGetPixelFormatAttribivARB failed for pixel format %d\n", iPixelFormat);
493         if(res == FALSE)
494             continue;
495
496         memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
497         DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
498
499         switch(iAttribRet[0])
500         {
501             case WGL_NO_ACCELERATION_ARB:
502                 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);
503                 break;
504             case WGL_GENERIC_ACCELERATION_ARB:
505                 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);
506                 break;
507             case WGL_FULL_ACCELERATION_ARB:
508                 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);
509                 break;
510         }
511     }
512 }
513
514 static void test_bitmap_rendering(void)
515 {
516     PIXELFORMATDESCRIPTOR pfd;
517     int i, iPixelFormat=0;
518     unsigned int nFormats;
519     HGLRC hglrc;
520     BITMAPINFO biDst;
521     HBITMAP bmpDst, oldDst;
522     HDC hdcDst, hdcScreen;
523     UINT32 *dstBuffer;
524
525     memset(&biDst, 0, sizeof(BITMAPINFO));
526     biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
527     biDst.bmiHeader.biWidth = 2;
528     biDst.bmiHeader.biHeight = -2;
529     biDst.bmiHeader.biPlanes = 1;
530     biDst.bmiHeader.biBitCount = 32;
531     biDst.bmiHeader.biCompression = BI_RGB;
532
533     hdcScreen = CreateCompatibleDC(0);
534     if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
535     {
536         DeleteDC(hdcScreen);
537         trace("Skipping bitmap rendering test\n");
538         return;
539     }
540
541     hdcDst = CreateCompatibleDC(hdcScreen);
542     bmpDst = CreateDIBSection(hdcDst, &biDst, DIB_RGB_COLORS, (void**)&dstBuffer, NULL, 0);
543     oldDst = SelectObject(hdcDst, bmpDst);
544
545     /* Pick a pixel format by hand because ChoosePixelFormat is unreliable */
546     nFormats = DescribePixelFormat(hdcDst, 0, 0, NULL);
547     for(i=1; i<=nFormats; i++)
548     {
549         memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
550         DescribePixelFormat(hdcDst, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
551
552         if((pfd.dwFlags & PFD_DRAW_TO_BITMAP) &&
553            (pfd.dwFlags & PFD_SUPPORT_OPENGL) &&
554            (pfd.cColorBits == 32) &&
555            (pfd.cAlphaBits == 8) )
556         {
557             iPixelFormat = i;
558             break;
559         }
560     }
561
562     if(!iPixelFormat)
563     {
564         skip("Unable to find a suitable pixel format\n");
565     }
566     else
567     {
568         SetPixelFormat(hdcDst, iPixelFormat, &pfd);
569         hglrc = wglCreateContext(hdcDst);
570         todo_wine ok(hglrc != NULL, "Unable to create a context\n");
571
572         if(hglrc)
573         {
574             wglMakeCurrent(hdcDst, hglrc);
575
576             /* Note this is RGBA but we read ARGB back */
577             glClearColor((float)0x22/0xff, (float)0x33/0xff, (float)0x44/0xff, (float)0x11/0xff);
578             glClear(GL_COLOR_BUFFER_BIT);
579             glFinish();
580
581             /* Note apparently the alpha channel is not supported by the software renderer (bitmap only works using software) */
582             ok(dstBuffer[0] == 0x223344, "Expected color=0x223344, received color=%x\n", dstBuffer[0]);
583
584             wglMakeCurrent(NULL, NULL);
585             wglDeleteContext(hglrc);
586         }
587     }
588
589     SelectObject(hdcDst, oldDst);
590     DeleteObject(bmpDst);
591     DeleteDC(hdcDst);
592
593     DeleteDC(hdcScreen);
594 }
595
596 struct wgl_thread_param
597 {
598     HANDLE test_finished;
599     HGLRC hglrc;
600     BOOL hglrc_deleted;
601     DWORD last_error;
602 };
603
604 static DWORD WINAPI wgl_thread(void *param)
605 {
606     struct wgl_thread_param *p = param;
607
608     SetLastError(0xdeadbeef);
609     p->hglrc_deleted = wglDeleteContext(p->hglrc);
610     p->last_error = GetLastError();
611     SetEvent(p->test_finished);
612
613     return 0;
614 }
615
616 static void test_deletecontext(HDC hdc)
617 {
618     struct wgl_thread_param thread_params;
619     HGLRC hglrc = wglCreateContext(hdc);
620     HANDLE thread_handle;
621     DWORD res, tid;
622
623     SetLastError(0xdeadbeef);
624     res = wglDeleteContext(NULL);
625     ok(res == FALSE, "wglDeleteContext succeeded\n");
626     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
627
628     if(!hglrc)
629     {
630         skip("wglCreateContext failed!\n");
631         return;
632     }
633
634     res = wglMakeCurrent(hdc, hglrc);
635     if(!res)
636     {
637         skip("wglMakeCurrent failed!\n");
638         return;
639     }
640
641     /* WGL doesn't allow you to delete a context from a different thread than the one in which it is current.
642      * This differs from GLX which does allow it but it delays actual deletion until the context becomes not current.
643      */
644     thread_params.hglrc = hglrc;
645     thread_params.test_finished = CreateEvent(NULL, FALSE, FALSE, NULL);
646     thread_handle = CreateThread(NULL, 0, wgl_thread, &thread_params, 0, &tid);
647     ok(!!thread_handle, "Failed to create thread, last error %#x.\n", GetLastError());
648     if(thread_handle)
649     {
650         WaitForSingleObject(thread_handle, INFINITE);
651         ok(thread_params.hglrc_deleted == FALSE, "Attempt to delete WGL context from another thread passed but should fail!\n");
652         ok(thread_params.last_error == ERROR_BUSY, "Expected last error to be ERROR_BUSY, got %u\n", thread_params.last_error);
653     }
654     CloseHandle(thread_params.test_finished);
655
656     res = wglDeleteContext(hglrc);
657     ok(res == TRUE, "wglDeleteContext failed\n");
658
659     /* Attempting to delete the same context twice should fail. */
660     SetLastError(0xdeadbeef);
661     res = wglDeleteContext(hglrc);
662     ok(res == FALSE, "wglDeleteContext succeeded\n");
663     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected last error to be ERROR_INVALID_HANDLE, got %u\n", GetLastError());
664
665     /* WGL makes a context not current when deleting it. This differs from GLX behavior where
666      * deletion takes place when the thread becomes not current. */
667     hglrc = wglGetCurrentContext();
668     ok(hglrc == NULL, "A WGL context is active while none was expected\n");
669 }
670
671 static void test_make_current_read(HDC hdc)
672 {
673     int res;
674     HDC hread;
675     HGLRC hglrc = wglCreateContext(hdc);
676
677     if(!hglrc)
678     {
679         skip("wglCreateContext failed!\n");
680         return;
681     }
682
683     res = wglMakeCurrent(hdc, hglrc);
684     if(!res)
685     {
686         skip("wglMakeCurrent failed!\n");
687         return;
688     }
689
690     /* Test what wglGetCurrentReadDCARB does for wglMakeCurrent as the spec doesn't mention it */
691     hread = pwglGetCurrentReadDCARB();
692     trace("hread %p, hdc %p\n", hread, hdc);
693     ok(hread == hdc, "wglGetCurrentReadDCARB failed for standard wglMakeCurrent\n");
694
695     pwglMakeContextCurrentARB(hdc, hdc, hglrc);
696     hread = pwglGetCurrentReadDCARB();
697     ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n");
698 }
699
700 static void test_dc(HWND hwnd, HDC hdc)
701 {
702     int pf1, pf2;
703     HDC hdc2;
704
705     /* Get another DC and make sure it has the same pixel format */
706     hdc2 = GetDC(hwnd);
707     if(hdc != hdc2)
708     {
709         pf1 = GetPixelFormat(hdc);
710         pf2 = GetPixelFormat(hdc2);
711         ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2);
712     }
713     else
714         skip("Could not get a different DC for the window\n");
715
716     if(hdc2)
717     {
718         ReleaseDC(hwnd, hdc2);
719         hdc2 = NULL;
720     }
721 }
722
723 /* Nvidia converts win32 error codes to (0xc007 << 16) | win32_error_code */
724 #define NVIDIA_HRESULT_FROM_WIN32(x) (HRESULT_FROM_WIN32(x) | 0x40000000)
725 static void test_opengl3(HDC hdc)
726 {
727     /* Try to create a context compatible with OpenGL 1.x; 1.0-2.1 is allowed */
728     {
729         HGLRC gl3Ctx;
730         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 1, 0};
731
732         gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
733         ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 1.x context failed!\n");
734         wglDeleteContext(gl3Ctx);
735     }
736
737     /* Try to pass an invalid HDC */
738     {
739         HGLRC gl3Ctx;
740         DWORD error;
741         gl3Ctx = pwglCreateContextAttribsARB((HDC)0xdeadbeef, 0, 0);
742         ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid HDC passed\n");
743         error = GetLastError();
744         todo_wine ok(error == ERROR_DC_NOT_FOUND ||
745                      broken(error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_DATA)), /* Nvidia Vista + Win7 */
746                      "Expected ERROR_DC_NOT_FOUND, got error=%x\n", error);
747         wglDeleteContext(gl3Ctx);
748     }
749
750     /* Try to pass an invalid shareList */
751     {
752         HGLRC gl3Ctx;
753         DWORD error;
754         gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0);
755         todo_wine ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
756         error = GetLastError();
757         /* The Nvidia implementation seems to return hresults instead of win32 error codes */
758         todo_wine ok(error == ERROR_INVALID_OPERATION ||
759                      error == NVIDIA_HRESULT_FROM_WIN32(ERROR_INVALID_OPERATION), "Expected ERROR_INVALID_OPERATION, got error=%x\n", error);
760         wglDeleteContext(gl3Ctx);
761     }
762
763     /* Try to create an OpenGL 3.0 context */
764     {
765         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
766         HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
767
768         if(gl3Ctx == NULL)
769         {
770             skip("Skipping the rest of the WGL_ARB_create_context test due to lack of OpenGL 3.0\n");
771             return;
772         }
773
774         wglDeleteContext(gl3Ctx);
775     }
776
777     /* 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 */
778     {
779         HGLRC glCtx = wglCreateContext(hdc);
780
781         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
782         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};
783
784         HGLRC gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs);
785         ok(gl3Ctx != NULL, "Sharing of a display list between OpenGL 3.0 and OpenGL 1.x/2.x failed!\n");
786         if(gl3Ctx)
787             wglDeleteContext(gl3Ctx);
788
789         gl3Ctx = pwglCreateContextAttribsARB(hdc, glCtx, attribs_future);
790         ok(gl3Ctx != NULL, "Sharing of a display list between a forward compatible OpenGL 3.0 context and OpenGL 1.x/2.x failed!\n");
791         if(gl3Ctx)
792             wglDeleteContext(gl3Ctx);
793
794         if(glCtx)
795             wglDeleteContext(glCtx);
796     }
797
798     /* Try to create an OpenGL 3.0 context and test windowless rendering */
799     {
800         HGLRC gl3Ctx;
801         int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, 0};
802         BOOL res;
803
804         gl3Ctx = pwglCreateContextAttribsARB(hdc, 0, attribs);
805         ok(gl3Ctx != 0, "pwglCreateContextAttribsARB for a 3.0 context failed!\n");
806
807         /* OpenGL 3.0 allows offscreen rendering WITHOUT a drawable
808          * Neither AMD or Nvidia support it at this point. The WGL_ARB_create_context specs also say that
809          * it is hard because drivers use the HDC to enter the display driver and it sounds like they don't
810          * expect drivers to ever offer it.
811          */
812         res = wglMakeCurrent(0, gl3Ctx);
813         ok(res == FALSE, "Wow, OpenGL 3.0 windowless rendering passed while it was expected not to!\n");
814         if(res)
815             wglMakeCurrent(0, 0);
816
817         if(gl3Ctx)
818             wglDeleteContext(gl3Ctx);
819     }
820 }
821
822 static void test_minimized(void)
823 {
824     PIXELFORMATDESCRIPTOR pf_desc =
825     {
826         sizeof(PIXELFORMATDESCRIPTOR),
827         1,                     /* version */
828         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
829         PFD_TYPE_RGBA,
830         24,                    /* 24-bit color depth */
831         0, 0, 0, 0, 0, 0,      /* color bits */
832         0,                     /* alpha buffer */
833         0,                     /* shift bit */
834         0,                     /* accumulation buffer */
835         0, 0, 0, 0,            /* accum bits */
836         32,                    /* z-buffer */
837         0,                     /* stencil buffer */
838         0,                     /* auxiliary buffer */
839         PFD_MAIN_PLANE,        /* main layer */
840         0,                     /* reserved */
841         0, 0, 0                /* layer masks */
842     };
843     int pixel_format;
844     HWND window;
845     LONG style;
846     HGLRC ctx;
847     BOOL ret;
848     HDC dc;
849
850     window = CreateWindowA("static", "opengl32_test",
851             WS_POPUP | WS_MINIMIZE, 0, 0, 640, 480, 0, 0, 0, 0);
852     ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
853
854     dc = GetDC(window);
855     ok(!!dc, "Failed to get DC.\n");
856
857     pixel_format = ChoosePixelFormat(dc, &pf_desc);
858     if (!pixel_format)
859     {
860         win_skip("Failed to find pixel format.\n");
861         ReleaseDC(window, dc);
862         DestroyWindow(window);
863         return;
864     }
865
866     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
867     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
868
869     style = GetWindowLongA(window, GWL_STYLE);
870     ok(style & WS_MINIMIZE, "Window should be minimized, got style %#x.\n", style);
871
872     ctx = wglCreateContext(dc);
873     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
874
875     ret = wglMakeCurrent(dc, ctx);
876     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
877
878     style = GetWindowLongA(window, GWL_STYLE);
879     ok(style & WS_MINIMIZE, "window should be minimized, got style %#x.\n", style);
880
881     ret = wglMakeCurrent(NULL, NULL);
882     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
883
884     ret = wglDeleteContext(ctx);
885     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
886
887     ReleaseDC(window, dc);
888     DestroyWindow(window);
889 }
890
891 static void test_destroy(HDC oldhdc)
892 {
893     PIXELFORMATDESCRIPTOR pf_desc =
894     {
895         sizeof(PIXELFORMATDESCRIPTOR),
896         1,                     /* version */
897         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
898         PFD_TYPE_RGBA,
899         24,                    /* 24-bit color depth */
900         0, 0, 0, 0, 0, 0,      /* color bits */
901         0,                     /* alpha buffer */
902         0,                     /* shift bit */
903         0,                     /* accumulation buffer */
904         0, 0, 0, 0,            /* accum bits */
905         32,                    /* z-buffer */
906         0,                     /* stencil buffer */
907         0,                     /* auxiliary buffer */
908         PFD_MAIN_PLANE,        /* main layer */
909         0,                     /* reserved */
910         0, 0, 0                /* layer masks */
911     };
912     int pixel_format;
913     HWND window;
914     HGLRC ctx;
915     BOOL ret;
916     HDC dc;
917     GLenum glerr;
918     DWORD err;
919     HGLRC oldctx = wglGetCurrentContext();
920
921     ok(!!oldctx, "Expected to find a valid current context.\n");
922
923     window = CreateWindowA("static", "opengl32_test",
924             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
925     ok(!!window, "Failed to create window, last error %#x.\n", GetLastError());
926
927     dc = GetDC(window);
928     ok(!!dc, "Failed to get DC.\n");
929
930     pixel_format = ChoosePixelFormat(dc, &pf_desc);
931     if (!pixel_format)
932     {
933         win_skip("Failed to find pixel format.\n");
934         ReleaseDC(window, dc);
935         DestroyWindow(window);
936         return;
937     }
938
939     ret = SetPixelFormat(dc, pixel_format, &pf_desc);
940     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
941
942     ctx = wglCreateContext(dc);
943     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
944
945     ret = wglMakeCurrent(dc, ctx);
946     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
947
948     glClear(GL_COLOR_BUFFER_BIT);
949     glFinish();
950     glerr = glGetError();
951     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
952     ret = SwapBuffers(dc);
953     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
954
955     ret = DestroyWindow(window);
956     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
957
958     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
959
960     SetLastError(0xdeadbeef);
961     ret = wglMakeCurrent(dc, ctx);
962     err = GetLastError();
963     ok(!ret && err == ERROR_INVALID_HANDLE,
964             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
965     SetLastError(0xdeadbeef);
966     ret = SwapBuffers(dc);
967     err = GetLastError();
968     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
969
970     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
971
972     glClear(GL_COLOR_BUFFER_BIT);
973     glFinish();
974     glerr = glGetError();
975     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
976     SetLastError(0xdeadbeef);
977     ret = SwapBuffers(dc);
978     err = GetLastError();
979     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
980
981     ret = wglMakeCurrent(NULL, NULL);
982     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
983
984     glClear(GL_COLOR_BUFFER_BIT);
985     glFinish();
986     glerr = glGetError();
987     todo_wine ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
988     SetLastError(0xdeadbeef);
989     ret = SwapBuffers(dc);
990     err = GetLastError();
991     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
992
993     SetLastError(0xdeadbeef);
994     ret = wglMakeCurrent(dc, ctx);
995     err = GetLastError();
996     ok(!ret && err == ERROR_INVALID_HANDLE,
997             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
998
999     ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1000
1001     ret = wglMakeCurrent(oldhdc, oldctx);
1002     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1003     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1004
1005     SetLastError(0xdeadbeef);
1006     ret = wglMakeCurrent(dc, ctx);
1007     err = GetLastError();
1008     ok(!ret && err == ERROR_INVALID_HANDLE,
1009             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1010
1011     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1012
1013     ret = wglDeleteContext(ctx);
1014     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1015
1016     ReleaseDC(window, dc);
1017
1018     ret = wglMakeCurrent(oldhdc, oldctx);
1019     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1020 }
1021
1022 static void test_destroy_read(HDC oldhdc)
1023 {
1024     PIXELFORMATDESCRIPTOR pf_desc =
1025     {
1026         sizeof(PIXELFORMATDESCRIPTOR),
1027         1,                     /* version */
1028         PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
1029         PFD_TYPE_RGBA,
1030         24,                    /* 24-bit color depth */
1031         0, 0, 0, 0, 0, 0,      /* color bits */
1032         0,                     /* alpha buffer */
1033         0,                     /* shift bit */
1034         0,                     /* accumulation buffer */
1035         0, 0, 0, 0,            /* accum bits */
1036         32,                    /* z-buffer */
1037         0,                     /* stencil buffer */
1038         0,                     /* auxiliary buffer */
1039         PFD_MAIN_PLANE,        /* main layer */
1040         0,                     /* reserved */
1041         0, 0, 0                /* layer masks */
1042     };
1043     int pixel_format;
1044     HWND draw_window, read_window;
1045     HGLRC ctx;
1046     BOOL ret;
1047     HDC read_dc, draw_dc;
1048     GLenum glerr;
1049     DWORD err;
1050     HGLRC oldctx = wglGetCurrentContext();
1051
1052     ok(!!oldctx, "Expected to find a valid current context\n");
1053
1054     draw_window = CreateWindowA("static", "opengl32_test",
1055             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1056     ok(!!draw_window, "Failed to create window, last error %#x.\n", GetLastError());
1057
1058     draw_dc = GetDC(draw_window);
1059     ok(!!draw_dc, "Failed to get DC.\n");
1060
1061     pixel_format = ChoosePixelFormat(draw_dc, &pf_desc);
1062     if (!pixel_format)
1063     {
1064         win_skip("Failed to find pixel format.\n");
1065         ReleaseDC(draw_window, draw_dc);
1066         DestroyWindow(draw_window);
1067         return;
1068     }
1069
1070     ret = SetPixelFormat(draw_dc, pixel_format, &pf_desc);
1071     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1072
1073     read_window = CreateWindowA("static", "opengl32_test",
1074             WS_POPUP, 0, 0, 640, 480, 0, 0, 0, 0);
1075     ok(!!read_window, "Failed to create window, last error %#x.\n", GetLastError());
1076
1077     read_dc = GetDC(read_window);
1078     ok(!!draw_dc, "Failed to get DC.\n");
1079
1080     pixel_format = ChoosePixelFormat(read_dc, &pf_desc);
1081     if (!pixel_format)
1082     {
1083         win_skip("Failed to find pixel format.\n");
1084         ReleaseDC(read_window, read_dc);
1085         DestroyWindow(read_window);
1086         ReleaseDC(draw_window, draw_dc);
1087         DestroyWindow(draw_window);
1088         return;
1089     }
1090
1091     ret = SetPixelFormat(read_dc, pixel_format, &pf_desc);
1092     ok(ret, "Failed to set pixel format, last error %#x.\n", GetLastError());
1093
1094     ctx = wglCreateContext(draw_dc);
1095     ok(!!ctx, "Failed to create GL context, last error %#x.\n", GetLastError());
1096
1097     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1098     ok(ret, "Failed to make context current, last error %#x.\n", GetLastError());
1099
1100     glCopyPixels(0, 0, 640, 480, GL_COLOR);
1101     glFinish();
1102     glerr = glGetError();
1103     ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1104     ret = SwapBuffers(draw_dc);
1105     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1106
1107     ret = DestroyWindow(read_window);
1108     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1109
1110     ok(wglGetCurrentContext() == ctx, "Wrong current context.\n");
1111
1112     if (0) /* Crashes on AMD on Windows */
1113     {
1114         glCopyPixels(0, 0, 640, 480, GL_COLOR);
1115         glFinish();
1116         glerr = glGetError();
1117         ok(glerr == GL_NO_ERROR, "Failed glCopyPixel, error %#x.\n", glerr);
1118     }
1119
1120     glClear(GL_COLOR_BUFFER_BIT);
1121     glFinish();
1122     glerr = glGetError();
1123     ok(glerr == GL_NO_ERROR, "Failed glClear, error %#x.\n", glerr);
1124     ret = SwapBuffers(draw_dc);
1125     ok(ret, "Failed SwapBuffers, error %#x.\n", GetLastError());
1126
1127     ret = wglMakeCurrent(NULL, NULL);
1128     ok(ret, "Failed to clear current context, last error %#x.\n", GetLastError());
1129
1130     if (0) /* This crashes with Nvidia drivers on Windows. */
1131     {
1132         SetLastError(0xdeadbeef);
1133         ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1134         err = GetLastError();
1135         ok(!ret && err == ERROR_INVALID_HANDLE,
1136                 "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1137     }
1138
1139     ret = DestroyWindow(draw_window);
1140     ok(ret, "Failed to destroy window, last error %#x.\n", GetLastError());
1141
1142     glClear(GL_COLOR_BUFFER_BIT);
1143     glFinish();
1144     glerr = glGetError();
1145     todo_wine ok(glerr == GL_INVALID_OPERATION, "Failed glClear, error %#x.\n", glerr);
1146     SetLastError(0xdeadbeef);
1147     ret = SwapBuffers(draw_dc);
1148     err = GetLastError();
1149     ok(!ret && err == ERROR_INVALID_HANDLE, "Unexpected behavior with SwapBuffer, last error %#x.\n", err);
1150
1151     SetLastError(0xdeadbeef);
1152     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1153     err = GetLastError();
1154     ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1155             "Unexpected behavior when making context current, ret %d, last error %#x.\n", ret, err);
1156
1157     ok(wglGetCurrentContext() == NULL, "Wrong current context.\n");
1158
1159     wglMakeCurrent(NULL, NULL);
1160
1161     wglMakeCurrent(oldhdc, oldctx);
1162     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1163
1164     SetLastError(0xdeadbeef);
1165     ret = pwglMakeContextCurrentARB(draw_dc, read_dc, ctx);
1166     err = GetLastError();
1167     ok(!ret && (err == ERROR_INVALID_HANDLE || err == 0xc0070006),
1168             "Unexpected behavior when making context current, last error %#x.\n", err);
1169
1170     ok(wglGetCurrentContext() == oldctx, "Wrong current context.\n");
1171
1172     ret = wglDeleteContext(ctx);
1173     ok(ret, "Failed to delete GL context, last error %#x.\n", GetLastError());
1174
1175     ReleaseDC(read_window, read_dc);
1176     ReleaseDC(draw_window, draw_dc);
1177
1178     wglMakeCurrent(oldhdc, oldctx);
1179 }
1180
1181 START_TEST(opengl)
1182 {
1183     HWND hwnd;
1184     PIXELFORMATDESCRIPTOR pfd = {
1185         sizeof(PIXELFORMATDESCRIPTOR),
1186         1,                     /* version */
1187         PFD_DRAW_TO_WINDOW |
1188         PFD_SUPPORT_OPENGL |
1189         PFD_DOUBLEBUFFER,
1190         PFD_TYPE_RGBA,
1191         24,                    /* 24-bit color depth */
1192         0, 0, 0, 0, 0, 0,      /* color bits */
1193         0,                     /* alpha buffer */
1194         0,                     /* shift bit */
1195         0,                     /* accumulation buffer */
1196         0, 0, 0, 0,            /* accum bits */
1197         32,                    /* z-buffer */
1198         0,                     /* stencil buffer */
1199         0,                     /* auxiliary buffer */
1200         PFD_MAIN_PLANE,        /* main layer */
1201         0,                     /* reserved */
1202         0, 0, 0                /* layer masks */
1203     };
1204
1205     hwnd = CreateWindow("static", "Title", WS_OVERLAPPEDWINDOW,
1206                         10, 10, 200, 200, NULL, NULL, NULL, NULL);
1207     ok(hwnd != NULL, "err: %d\n", GetLastError());
1208     if (hwnd)
1209     {
1210         HDC hdc;
1211         int iPixelFormat, res;
1212         HGLRC hglrc;
1213         DWORD error;
1214         ShowWindow(hwnd, SW_SHOW);
1215
1216         hdc = GetDC(hwnd);
1217
1218         iPixelFormat = ChoosePixelFormat(hdc, &pfd);
1219         if(iPixelFormat == 0)
1220         {
1221             /* This should never happen as ChoosePixelFormat always returns a closest match, but currently this fails in Wine if we don't have glX */
1222             win_skip("Unable to find pixel format.\n");
1223             goto cleanup;
1224         }
1225
1226         /* We shouldn't be able to create a context from a hdc which doesn't have a pixel format set */
1227         hglrc = wglCreateContext(hdc);
1228         ok(hglrc == NULL, "wglCreateContext should fail when no pixel format has been set, but it passed\n");
1229         error = GetLastError();
1230         ok(error == ERROR_INVALID_PIXEL_FORMAT, "expected ERROR_INVALID_PIXEL_FORMAT for wglCreateContext without a pixelformat set, but received %#x\n", error);
1231
1232         res = SetPixelFormat(hdc, iPixelFormat, &pfd);
1233         ok(res, "SetPixelformat failed: %x\n", GetLastError());
1234
1235         test_bitmap_rendering();
1236         test_minimized();
1237         test_dc(hwnd, hdc);
1238
1239         hglrc = wglCreateContext(hdc);
1240         res = wglMakeCurrent(hdc, hglrc);
1241         ok(res, "wglMakeCurrent failed!\n");
1242         if(res)
1243         {
1244             trace("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
1245             trace("OpenGL driver version: %s\n", glGetString(GL_VERSION));
1246             trace("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
1247         }
1248         else
1249         {
1250             skip("Skipping OpenGL tests without a current context\n");
1251             return;
1252         }
1253
1254         /* Initialisation of WGL functions depends on an implicit WGL context. For this reason we can't load them before making
1255          * any WGL call :( On Wine this would work but not on real Windows because there can be different implementations (software, ICD, MCD).
1256          */
1257         init_functions();
1258         /* The lack of wglGetExtensionsStringARB in general means broken software rendering or the lack of decent OpenGL support, skip tests in such cases */
1259         if (!pwglGetExtensionsStringARB)
1260         {
1261             win_skip("wglGetExtensionsStringARB is not available\n");
1262             return;
1263         }
1264
1265         test_deletecontext(hdc);
1266         test_makecurrent(hdc);
1267         test_setpixelformat(hdc);
1268         test_destroy(hdc);
1269         test_sharelists(hdc);
1270         test_colorbits(hdc);
1271         test_gdi_dbuf(hdc);
1272         test_acceleration(hdc);
1273
1274         wgl_extensions = pwglGetExtensionsStringARB(hdc);
1275         if(wgl_extensions == NULL) skip("Skipping opengl32 tests because this OpenGL implementation doesn't support WGL extensions!\n");
1276
1277         if(strstr(wgl_extensions, "WGL_ARB_create_context"))
1278             test_opengl3(hdc);
1279
1280         if(strstr(wgl_extensions, "WGL_ARB_make_current_read"))
1281         {
1282             test_make_current_read(hdc);
1283             test_destroy_read(hdc);
1284         }
1285         else
1286             skip("WGL_ARB_make_current_read not supported, skipping test\n");
1287
1288         if(strstr(wgl_extensions, "WGL_ARB_pbuffer"))
1289             test_pbuffers(hdc);
1290         else
1291             skip("WGL_ARB_pbuffer not supported, skipping pbuffer test\n");
1292
1293 cleanup:
1294         ReleaseDC(hwnd, hdc);
1295         DestroyWindow(hwnd);
1296     }
1297 }