quartz: Use proper alloc/free functions for COM objects.
[wine] / dlls / ddraw / tests / dsurface.c
1 /*
2  * Unit tests for (a few) ddraw surface functions
3  *
4  * Copyright (C) 2005 Antoine Chavasse (a.chavasse@gmail.com)
5  * Copyright (C) 2005 Christian Costa
6  * Copyright 2005 Ivan Leo Puoti
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 #define COBJMACROS
23
24 #include <assert.h>
25 #include "wine/test.h"
26 #include "ddraw.h"
27 #include "unknwn.h"
28
29 static LPDIRECTDRAW lpDD = NULL;
30
31 static BOOL CreateDirectDraw(void)
32 {
33     HRESULT rc;
34
35     rc = DirectDrawCreate(NULL, &lpDD, NULL);
36     ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
37     if (!lpDD) {
38         trace("DirectDrawCreateEx() failed with an error %x\n", rc);
39         return FALSE;
40     }
41
42     rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
43     ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
44
45     return TRUE;
46 }
47
48
49 static void ReleaseDirectDraw(void)
50 {
51     if( lpDD != NULL )
52     {
53         IDirectDraw_Release(lpDD);
54         lpDD = NULL;
55     }
56 }
57
58 static void MipMapCreationTest(void)
59 {
60     LPDIRECTDRAWSURFACE lpDDSMipMapTest;
61     DDSURFACEDESC ddsd;
62     HRESULT rc;
63
64     /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
65        DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
66         requested mipmap levels. */
67     ddsd.dwSize = sizeof(ddsd);
68     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
69     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
70     U2(ddsd).dwMipMapCount = 3;
71     ddsd.dwWidth = 128;
72     ddsd.dwHeight = 32;
73     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
74     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
75
76     /* Check the number of created mipmaps */
77     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
78     ddsd.dwSize = sizeof(ddsd);
79     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
80     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
81     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
82         "GetSurfaceDesc returned no mipmapcount.\n");
83     ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
84         U2(ddsd).dwMipMapCount);
85
86     /* Destroy the surface. */
87     IDirectDrawSurface_Release(lpDDSMipMapTest);
88
89
90     /* Second mipmap creation test: create a surface without a mipmap
91        count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
92        This creates a single mipmap level. */
93     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
94     ddsd.dwSize = sizeof(ddsd);
95     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
96     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
97     ddsd.dwWidth = 128;
98     ddsd.dwHeight = 32;
99     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
100     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
101
102     /* Check the number of created mipmaps */
103     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
104     ddsd.dwSize = sizeof(ddsd);
105     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
106     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
107     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
108         "GetSurfaceDesc returned no mipmapcount.\n");
109     ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
110         U2(ddsd).dwMipMapCount);
111
112     /* Destroy the surface. */
113     IDirectDrawSurface_Release(lpDDSMipMapTest);
114
115
116     /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
117         DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
118        It's an undocumented features where a chain of mipmaps, starting from
119        he specified size and down to the smallest size, is automatically
120        created.
121        Anarchy Online needs this feature to work. */
122     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
123     ddsd.dwSize = sizeof(ddsd);
124     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
125     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
126     ddsd.dwWidth = 128;
127     ddsd.dwHeight = 32;
128     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
129     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
130
131     /* Check the number of created mipmaps */
132     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
133     ddsd.dwSize = sizeof(ddsd);
134     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
135     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
136     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
137         "GetSurfaceDesc returned no mipmapcount.\n");
138     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
139         U2(ddsd).dwMipMapCount);
140
141     /* Destroy the surface. */
142     IDirectDrawSurface_Release(lpDDSMipMapTest);
143
144
145     /* Fourth mipmap creation test: same as above with a different texture
146        size.
147        The purpose is to verify that the number of generated mipmaps is
148        dependent on the smallest dimension. */
149     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
150     ddsd.dwSize = sizeof(ddsd);
151     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
152     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
153     ddsd.dwWidth = 32;
154     ddsd.dwHeight = 64;
155     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
156     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
157
158     /* Check the number of created mipmaps */
159     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
160     ddsd.dwSize = sizeof(ddsd);
161     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
162     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
163     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
164         "GetSurfaceDesc returned no mipmapcount.\n");
165     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
166         U2(ddsd).dwMipMapCount);
167
168     /* Destroy the surface. */
169     IDirectDrawSurface_Release(lpDDSMipMapTest);
170 }
171
172 static void SrcColorKey32BlitTest(void)
173 {
174     LPDIRECTDRAWSURFACE lpSrc;
175     LPDIRECTDRAWSURFACE lpDst;
176     DDSURFACEDESC ddsd;
177     DDSURFACEDESC ddsd2;
178     DDCOLORKEY DDColorKey;
179     LPDWORD lpData;
180     HRESULT rc;
181     DDBLTFX fx;
182
183     ddsd2.dwSize = sizeof(ddsd2);
184     ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
185
186     ddsd.dwSize = sizeof(ddsd);
187     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
188     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
189     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
190     ddsd.dwWidth = 800;
191     ddsd.dwHeight = 600;
192     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
193     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
194     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
195     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
196     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
197     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
198     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
199
200     ddsd.dwFlags |= DDSD_CKSRCBLT;
201     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
202     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
203     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
204     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
205     
206     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
207     ok(rc==DD_OK,"Lock returned: %x\n",rc);
208     lpData = (LPDWORD)ddsd2.lpSurface;
209     lpData[0] = 0xCCCCCCCC;
210     lpData[1] = 0xCCCCCCCC;
211     lpData[2] = 0xCCCCCCCC;
212     lpData[3] = 0xCCCCCCCC;
213     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
214     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
215
216     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
217     ok(rc==DD_OK,"Lock returned: %x\n",rc);
218     lpData = (LPDWORD)ddsd2.lpSurface;
219     lpData[0] = 0x77010203;
220     lpData[1] = 0x00010203;
221     lpData[2] = 0x77FF00FF;
222     lpData[3] = 0x00FF00FF;
223     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
224     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
225
226     IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
227
228     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
229     ok(rc==DD_OK,"Lock returned: %x\n",rc);
230     lpData = (LPDWORD)ddsd2.lpSurface;
231     ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
232        "Destination data after blitting is not correct\n");
233     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
234     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
235
236     /* Also test SetColorKey */
237     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
238     ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
239        "GetColorKey does not return the colorkey used at surface creation\n");
240
241     DDColorKey.dwColorSpaceLowValue = 0x00FF00;
242     DDColorKey.dwColorSpaceHighValue = 0x00FF00;
243     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
244
245     DDColorKey.dwColorSpaceLowValue = 0;
246     DDColorKey.dwColorSpaceHighValue = 0;
247     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
248     ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
249        "GetColorKey does not return the colorkey set with SetColorKey\n");
250
251     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
252     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
253     IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
254     ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
255        "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
256
257     IDirectDrawSurface_Release(lpSrc);
258     IDirectDrawSurface_Release(lpDst);
259
260     /* start with a new set of surfaces to test the color keying parameters to blit */
261     memset(&ddsd, 0, sizeof(ddsd));
262     ddsd.dwSize = sizeof(ddsd);
263     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
264     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
265     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
266     ddsd.dwWidth = 800;
267     ddsd.dwHeight = 600;
268     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
269     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
270     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
271     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
272     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
273     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
274     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
275     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
276     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
277     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
278     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
279     if(FAILED(rc))
280     {
281         skip("Failed to create surface\n");
282         return;
283     }
284
285     /* start with a new set of surfaces to test the color keying parameters to blit */
286     memset(&ddsd, 0, sizeof(ddsd));
287     ddsd.dwSize = sizeof(ddsd);
288     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
289     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
290     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
291     ddsd.dwWidth = 800;
292     ddsd.dwHeight = 600;
293     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
294     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
295     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
296     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
297     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
298     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
299     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
300     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
301     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
302     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
303     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
304     if(FAILED(rc))
305     {
306         skip("Failed to create surface\n");
307         IDirectDrawSurface_Release(lpDst);
308         return;
309     }
310
311     memset(&fx, 0, sizeof(fx));
312     fx.dwSize = sizeof(fx);
313     fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
314     fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
315     fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
316     fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
317
318     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
319     ok(rc==DD_OK,"Lock returned: %x\n",rc);
320     lpData = (LPDWORD)ddsd2.lpSurface;
321     lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
322     lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
323     lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
324     lpData[3] = 0x0000FF00; /* Src color key in dst surface */
325     lpData[4] = 0x00001100; /* Src color key in ddbltfx */
326     lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
327     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
328     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
329
330     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
331     ok(rc==DD_OK,"Lock returned: %x\n",rc);
332     lpData = (LPDWORD)ddsd2.lpSurface;
333     lpData[0] = 0x55555555;
334     lpData[1] = 0x55555555;
335     lpData[2] = 0x55555555;
336     lpData[3] = 0x55555555;
337     lpData[4] = 0x55555555;
338     lpData[5] = 0x55555555;
339     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
340     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
341
342     /* Test a blit without keying */
343     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
344     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
345
346     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
347     ok(rc==DD_OK,"Lock returned: %x\n",rc);
348     lpData = (LPDWORD)ddsd2.lpSurface;
349     /* Should have copied src data unmodified to dst */
350     ok(lpData[0] == 0x000000FF &&
351        lpData[1] == 0x00000000 &&
352        lpData[2] == 0x00FF0000 &&
353        lpData[3] == 0x0000FF00 &&
354        lpData[4] == 0x00001100 &&
355        lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
356
357     lpData[0] = 0x55555555;
358     lpData[1] = 0x55555555;
359     lpData[2] = 0x55555555;
360     lpData[3] = 0x55555555;
361     lpData[4] = 0x55555555;
362     lpData[5] = 0x55555555;
363     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
364     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
365
366     /* Src key */
367     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
368     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
369
370     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
371     ok(rc==DD_OK,"Lock returned: %x\n",rc);
372     lpData = (LPDWORD)ddsd2.lpSurface;
373
374     ok(lpData[0] == 0x55555555 && /* Here the src key applied */
375        lpData[1] == 0x00000000 &&
376        lpData[2] == 0x00FF0000 &&
377        lpData[3] == 0x0000FF00 &&
378        lpData[4] == 0x00001100 &&
379        lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
380
381     lpData[0] = 0x55555555;
382     lpData[1] = 0x55555555;
383     lpData[2] = 0x55555555;
384     lpData[3] = 0x55555555;
385     lpData[4] = 0x55555555;
386     lpData[5] = 0x55555555;
387     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
388     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
389
390     /* Src override */
391     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
392     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
393
394     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
395     ok(rc==DD_OK,"Lock returned: %x\n",rc);
396     lpData = (LPDWORD)ddsd2.lpSurface;
397
398     ok(lpData[0] == 0x000000FF &&
399        lpData[1] == 0x00000000 &&
400        lpData[2] == 0x00FF0000 &&
401        lpData[3] == 0x0000FF00 &&
402        lpData[4] == 0x00001100 &&
403        lpData[5] == 0x55555555, /* Override key applies here */
404        "Surface data after src override key blit does not match\n");
405
406     lpData[0] = 0x55555555;
407     lpData[1] = 0x55555555;
408     lpData[2] = 0x55555555;
409     lpData[3] = 0x55555555;
410     lpData[4] = 0x55555555;
411     lpData[5] = 0x55555555;
412     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
413     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
414
415     /* Src override AND src key. That is not supposed to work */
416     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
417     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
418
419     /* Verify that the destination is unchanged */
420     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
421     ok(rc==DD_OK,"Lock returned: %x\n",rc);
422     lpData = (LPDWORD)ddsd2.lpSurface;
423
424     ok(lpData[0] == 0x55555555 &&
425        lpData[1] == 0x55555555 &&
426        lpData[2] == 0x55555555 &&
427        lpData[3] == 0x55555555 &&
428        lpData[4] == 0x55555555 &&
429        lpData[5] == 0x55555555, /* Override key applies here */
430        "Surface data after src key blit with override does not match\n");
431
432     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
433     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
434     lpData[2] = 0x00001100; /* Dest key in override */
435     lpData[3] = 0x00001100; /* Dest key in override */
436     lpData[4] = 0x00000000; /* Dest key in src surface */
437     lpData[5] = 0x00000000; /* Dest key in src surface */
438     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
439     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
440
441     /* Dest key blit */
442     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
443     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
444
445     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
446     ok(rc==DD_OK,"Lock returned: %x\n",rc);
447     lpData = (LPDWORD)ddsd2.lpSurface;
448
449     /* DirectDraw uses the dest blit key from the SOURCE surface ! */
450     ok(lpData[0] == 0x00ff0000 &&
451        lpData[1] == 0x00ff0000 &&
452        lpData[2] == 0x00001100 &&
453        lpData[3] == 0x00001100 &&
454        lpData[4] == 0x00001100 && /* Key applies here */
455        lpData[5] == 0x00110000,   /* Key applies here */
456        "Surface data after dest key blit does not match\n");
457
458     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
459     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
460     lpData[2] = 0x00001100; /* Dest key in override */
461     lpData[3] = 0x00001100; /* Dest key in override */
462     lpData[4] = 0x00000000; /* Dest key in src surface */
463     lpData[5] = 0x00000000; /* Dest key in src surface */
464     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
465     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
466
467     /* Dest override key blit */
468     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
469     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
470
471     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
472     ok(rc==DD_OK,"Lock returned: %x\n",rc);
473     lpData = (LPDWORD)ddsd2.lpSurface;
474
475     ok(lpData[0] == 0x00FF0000 &&
476        lpData[1] == 0x00FF0000 &&
477        lpData[2] == 0x00FF0000 && /* Key applies here */
478        lpData[3] == 0x0000FF00 && /* Key applies here */
479        lpData[4] == 0x00000000 &&
480        lpData[5] == 0x00000000,
481        "Surface data after dest key override blit does not match\n");
482
483     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
484     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
485     lpData[2] = 0x00001100; /* Dest key in override */
486     lpData[3] = 0x00001100; /* Dest key in override */
487     lpData[4] = 0x00000000; /* Dest key in src surface */
488     lpData[5] = 0x00000000; /* Dest key in src surface */
489     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
490     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
491
492     /* Dest override key blit. Supposed to fail too */
493     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
494     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
495
496     /* Check for unchanged data */
497     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
498     ok(rc==DD_OK,"Lock returned: %x\n",rc);
499     lpData = (LPDWORD)ddsd2.lpSurface;
500
501     ok(lpData[0] == 0x00FF0000 &&
502        lpData[1] == 0x00FF0000 &&
503        lpData[2] == 0x00001100 && /* Key applies here */
504        lpData[3] == 0x00001100 && /* Key applies here */
505        lpData[4] == 0x00000000 &&
506        lpData[5] == 0x00000000,
507        "Surface data with dest key and dest override does not match\n");
508
509     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
510     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
511     lpData[2] = 0x00001100; /* Dest key in override */
512     lpData[3] = 0x00001100; /* Dest key in override */
513     lpData[4] = 0x00000000; /* Dest key in src surface */
514     lpData[5] = 0x00000000; /* Dest key in src surface */
515     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
516     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
517
518     /* Modify the source data a bit to give some more conclusive results */
519     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
520     ok(rc==DD_OK,"Lock returned: %x\n",rc);
521     lpData = (LPDWORD)ddsd2.lpSurface;
522     lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
523     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
524     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
525
526     /* Source and destination key */
527     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
528     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
529
530     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
531     ok(rc==DD_OK,"Lock returned: %x\n",rc);
532     lpData = (LPDWORD)ddsd2.lpSurface;
533
534     ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
535        lpData[1] == 0x00FF0000 && /* Masked by Destination key */
536        lpData[2] == 0x00001100 && /* Masked by Destination key */
537        lpData[3] == 0x00001100 && /* Masked by Destination key */
538        lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
539        lpData[5] == 0x00000000,   /* Allowed by dst key, but masked by source key */
540        "Surface data with src key and dest key blit does not match\n");
541
542     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
543     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
544     lpData[2] = 0x00001100; /* Dest key in override */
545     lpData[3] = 0x00001100; /* Dest key in override */
546     lpData[4] = 0x00000000; /* Dest key in src surface */
547     lpData[5] = 0x00000000; /* Dest key in src surface */
548     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
549     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
550
551     /* Override keys without ddbltfx parameter fail */
552     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
553     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
554     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
555     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
556
557     /* Try blitting without keys in the source surface*/
558     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
559     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
560     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
561     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
562
563     /* That fails now. Do not bother to check that the data is unmodified */
564     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
565     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
566
567     /* Dest key blit still works. Which key is used this time??? */
568     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
569     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
570
571     /* With korrectly passed override keys no key in the surface is needed.
572      * Again, the result was checked before, no need to do that again
573      */
574     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
575     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
576     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
577     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
578
579     IDirectDrawSurface_Release(lpSrc);
580     IDirectDrawSurface_Release(lpDst);
581 }
582
583 static void QueryInterface(void)
584 {
585     LPDIRECTDRAWSURFACE dsurface;
586     DDSURFACEDESC surface;
587     LPVOID object;
588     HRESULT ret;
589
590     /* Create a surface */
591     ZeroMemory(&surface, sizeof(surface));
592     surface.dwSize = sizeof(surface);
593     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
594     surface.dwHeight = 10;
595     surface.dwWidth = 10;
596     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
597     if(ret != DD_OK)
598     {
599         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
600         return;
601     }
602
603     /* Call IUnknown::QueryInterface */
604     ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
605     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
606
607     IDirectDrawSurface_Release(dsurface);
608 }
609
610 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
611  * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
612  * partially in the refcount test
613  */
614
615 static unsigned long getref(IUnknown *iface)
616 {
617     IUnknown_AddRef(iface);
618     return IUnknown_Release(iface);
619 }
620
621 static void GetDDInterface_1(void)
622 {
623     LPDIRECTDRAWSURFACE dsurface;
624     LPDIRECTDRAWSURFACE2 dsurface2;
625     DDSURFACEDESC surface;
626     HRESULT ret;
627     IDirectDraw2 *dd2;
628     IDirectDraw4 *dd4;
629     IDirectDraw7 *dd7;
630     unsigned long ref1, ref2, ref4, ref7;
631     void *dd;
632
633     /* Create a surface */
634     ZeroMemory(&surface, sizeof(surface));
635     surface.dwSize = sizeof(surface);
636     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
637     surface.dwHeight = 10;
638     surface.dwWidth = 10;
639     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
640     if(ret != DD_OK)
641     {
642         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
643         return;
644     }
645     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
646     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
647     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
648     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
649     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
650     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
651     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
652     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
653
654     ref1 = getref((IUnknown *) lpDD);
655     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
656     ref2 = getref((IUnknown *) dd2);
657     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
658     ref4 = getref((IUnknown *) dd4);
659     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
660     ref7 = getref((IUnknown *) dd7);
661     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
662
663
664     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
665     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
666     ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
667     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
668     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
669     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
670
671     ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
672     IUnknown_Release((IUnknown *) dd);
673
674     /* try a NULL pointer */
675     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
676     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
677
678     IDirectDraw_Release(dd2);
679     IDirectDraw_Release(dd4);
680     IDirectDraw_Release(dd7);
681     IDirectDrawSurface2_Release(dsurface2);
682     IDirectDrawSurface_Release(dsurface);
683 }
684
685 static void GetDDInterface_2(void)
686 {
687     LPDIRECTDRAWSURFACE dsurface;
688     LPDIRECTDRAWSURFACE2 dsurface2;
689     DDSURFACEDESC surface;
690     HRESULT ret;
691     IDirectDraw2 *dd2;
692     IDirectDraw4 *dd4;
693     IDirectDraw7 *dd7;
694     unsigned long ref1, ref2, ref4, ref7;
695     void *dd;
696
697     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
698     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
699     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
700     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
701     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
702     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
703
704     /* Create a surface */
705     ZeroMemory(&surface, sizeof(surface));
706     surface.dwSize = sizeof(surface);
707     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
708     surface.dwHeight = 10;
709     surface.dwWidth = 10;
710     ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
711     if(ret != DD_OK)
712     {
713         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
714         return;
715     }
716     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
717     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
718
719     ref1 = getref((IUnknown *) lpDD);
720     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
721     ref2 = getref((IUnknown *) dd2);
722     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
723     ref4 = getref((IUnknown *) dd4);
724     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
725     ref7 = getref((IUnknown *) dd7);
726     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
727
728
729     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
730     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
731     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
732     ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
733     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
734     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
735
736     ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
737     IUnknown_Release((IUnknown *) dd);
738
739     IDirectDraw_Release(dd2);
740     IDirectDraw_Release(dd4);
741     IDirectDraw_Release(dd7);
742     IDirectDrawSurface2_Release(dsurface2);
743     IDirectDrawSurface_Release(dsurface);
744 }
745
746 static void GetDDInterface_4(void)
747 {
748     LPDIRECTDRAWSURFACE2 dsurface2;
749     LPDIRECTDRAWSURFACE4 dsurface4;
750     DDSURFACEDESC2 surface;
751     HRESULT ret;
752     IDirectDraw2 *dd2;
753     IDirectDraw4 *dd4;
754     IDirectDraw7 *dd7;
755     unsigned long ref1, ref2, ref4, ref7;
756     void *dd;
757
758     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
759     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
760     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
761     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
762     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
763     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
764
765     /* Create a surface */
766     ZeroMemory(&surface, sizeof(surface));
767     surface.dwSize = sizeof(surface);
768     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
769     surface.dwHeight = 10;
770     surface.dwWidth = 10;
771     ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
772     if(ret != DD_OK)
773     {
774         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
775         return;
776     }
777     ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
778     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
779
780     ref1 = getref((IUnknown *) lpDD);
781     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
782     ref2 = getref((IUnknown *) dd2);
783     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
784     ref4 = getref((IUnknown *) dd4);
785     ok(ref4 == 2, "IDirectDraw4 refcount is %ld\n", ref4);
786     ref7 = getref((IUnknown *) dd7);
787     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
788
789     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
790     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
791     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
792     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
793     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
794     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
795
796     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
797     IUnknown_Release((IUnknown *) dd);
798
799     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
800     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
801     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
802     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
803     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
804     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
805     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
806
807     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
808     IUnknown_Release((IUnknown *) dd);
809
810     IDirectDraw_Release(dd2);
811     IDirectDraw_Release(dd4);
812     IDirectDraw_Release(dd7);
813     IDirectDrawSurface4_Release(dsurface4);
814     IDirectDrawSurface2_Release(dsurface2);
815 }
816
817 static void GetDDInterface_7(void)
818 {
819     LPDIRECTDRAWSURFACE4 dsurface4;
820     LPDIRECTDRAWSURFACE7 dsurface7;
821     DDSURFACEDESC2 surface;
822     HRESULT ret;
823     IDirectDraw2 *dd2;
824     IDirectDraw4 *dd4;
825     IDirectDraw7 *dd7;
826     unsigned long ref1, ref2, ref4, ref7;
827     void *dd;
828
829     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
830     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
831     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
832     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
833     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
834     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
835
836     /* Create a surface */
837     ZeroMemory(&surface, sizeof(surface));
838     surface.dwSize = sizeof(surface);
839     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
840     surface.dwHeight = 10;
841     surface.dwWidth = 10;
842     ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
843     if(ret != DD_OK)
844     {
845         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
846         return;
847     }
848     ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
849     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
850
851     ref1 = getref((IUnknown *) lpDD);
852     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
853     ref2 = getref((IUnknown *) dd2);
854     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
855     ref4 = getref((IUnknown *) dd4);
856     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
857     ref7 = getref((IUnknown *) dd7);
858     ok(ref7 == 2, "IDirectDraw7 refcount is %ld\n", ref7);
859
860     ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
861     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
862     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
863     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
864     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
865     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
866
867     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
868     IUnknown_Release((IUnknown *) dd);
869
870     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
871     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
872     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
873     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
874     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
875     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
876     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
877
878     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
879     IUnknown_Release((IUnknown *) dd);
880
881     IDirectDraw_Release(dd2);
882     IDirectDraw_Release(dd4);
883     IDirectDraw_Release(dd7);
884     IDirectDrawSurface4_Release(dsurface4);
885     IDirectDrawSurface7_Release(dsurface7);
886 }
887
888 START_TEST(dsurface)
889 {
890     if (!CreateDirectDraw())
891         return;
892     MipMapCreationTest();
893     SrcColorKey32BlitTest();
894     QueryInterface();
895     GetDDInterface_1();
896     GetDDInterface_2();
897     GetDDInterface_4();
898     GetDDInterface_7();
899     ReleaseDirectDraw();
900 }