shell32/tests: Add some tests related to the shellview created by ExplorerBrowser.
[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  * Copyright (C) 2007 Stefan Dösinger
8  * Copyright (C) 2008 Alexander Dorofeyev
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 #define COBJMACROS
25
26 #include <assert.h>
27 #include "wine/test.h"
28 #include "wine/exception.h"
29 #include "ddraw.h"
30 #include "d3d.h"
31 #include "unknwn.h"
32
33 static LPDIRECTDRAW lpDD = NULL;
34 static DDCAPS ddcaps;
35
36 static BOOL CreateDirectDraw(void)
37 {
38     HRESULT rc;
39
40     rc = DirectDrawCreate(NULL, &lpDD, NULL);
41     ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
42     if (!lpDD) {
43         trace("DirectDrawCreateEx() failed with an error %x\n", rc);
44         return FALSE;
45     }
46
47     rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
48     ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
49
50     return TRUE;
51 }
52
53
54 static void ReleaseDirectDraw(void)
55 {
56     if( lpDD != NULL )
57     {
58         IDirectDraw_Release(lpDD);
59         lpDD = NULL;
60     }
61 }
62
63 static void MipMapCreationTest(void)
64 {
65     LPDIRECTDRAWSURFACE lpDDSMipMapTest;
66     DDSURFACEDESC ddsd;
67     HRESULT rc;
68
69     /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
70        DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
71         requested mipmap levels. */
72     ddsd.dwSize = sizeof(ddsd);
73     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
74     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
75     U2(ddsd).dwMipMapCount = 3;
76     ddsd.dwWidth = 128;
77     ddsd.dwHeight = 32;
78     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
79     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
80     if (FAILED(rc)) {
81         skip("failed to create surface\n");
82         return;
83     }
84
85     /* Check the number of created mipmaps */
86     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
87     ddsd.dwSize = sizeof(ddsd);
88     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
89     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
90     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
91         "GetSurfaceDesc returned no mipmapcount.\n");
92     ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
93         U2(ddsd).dwMipMapCount);
94
95     /* Destroy the surface. */
96     IDirectDrawSurface_Release(lpDDSMipMapTest);
97
98
99     /* Second mipmap creation test: create a surface without a mipmap
100        count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
101        This creates a single mipmap level. */
102     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
103     ddsd.dwSize = sizeof(ddsd);
104     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
105     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
106     ddsd.dwWidth = 128;
107     ddsd.dwHeight = 32;
108     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
109     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
110     if (FAILED(rc)) {
111         skip("failed to create surface\n");
112         return;
113     }
114     /* Check the number of created mipmaps */
115     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
116     ddsd.dwSize = sizeof(ddsd);
117     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
118     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
119     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
120         "GetSurfaceDesc returned no mipmapcount.\n");
121     ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
122         U2(ddsd).dwMipMapCount);
123
124     /* Destroy the surface. */
125     IDirectDrawSurface_Release(lpDDSMipMapTest);
126
127
128     /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
129         DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
130        It's an undocumented features where a chain of mipmaps, starting from
131        he specified size and down to the smallest size, is automatically
132        created.
133        Anarchy Online needs this feature to work. */
134     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
135     ddsd.dwSize = sizeof(ddsd);
136     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
137     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
138     ddsd.dwWidth = 128;
139     ddsd.dwHeight = 32;
140     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
141     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
142     if (FAILED(rc)) {
143         skip("failed to create surface\n");
144         return;
145     }
146
147     /* Check the number of created mipmaps */
148     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
149     ddsd.dwSize = sizeof(ddsd);
150     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
151     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
152     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
153         "GetSurfaceDesc returned no mipmapcount.\n");
154     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
155         U2(ddsd).dwMipMapCount);
156
157     /* Destroy the surface. */
158     IDirectDrawSurface_Release(lpDDSMipMapTest);
159
160
161     /* Fourth mipmap creation test: same as above with a different texture
162        size.
163        The purpose is to verify that the number of generated mipmaps is
164        dependent on the smallest dimension. */
165     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
166     ddsd.dwSize = sizeof(ddsd);
167     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
168     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
169     ddsd.dwWidth = 32;
170     ddsd.dwHeight = 64;
171     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
172     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
173     if (FAILED(rc)) {
174         skip("failed to create surface\n");
175         return;
176     }
177
178     /* Check the number of created mipmaps */
179     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
180     ddsd.dwSize = sizeof(ddsd);
181     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
182     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
183     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
184         "GetSurfaceDesc returned no mipmapcount.\n");
185     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
186         U2(ddsd).dwMipMapCount);
187
188     /* Destroy the surface. */
189     IDirectDrawSurface_Release(lpDDSMipMapTest);
190
191
192     /* Fifth mipmap creation test: try to create a surface with
193        DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT,
194        where dwMipMapCount = 0. This should fail. */
195
196     ddsd.dwSize = sizeof(ddsd);
197     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
198     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
199     U2(ddsd).dwMipMapCount = 0;
200     ddsd.dwWidth = 128;
201     ddsd.dwHeight = 32;
202     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
203     ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc);
204
205     /* Destroy the surface. */
206     if( rc == DD_OK )
207         IDirectDrawSurface_Release(lpDDSMipMapTest);
208
209 }
210
211 static void SrcColorKey32BlitTest(void)
212 {
213     LPDIRECTDRAWSURFACE lpSrc;
214     LPDIRECTDRAWSURFACE lpDst;
215     DDSURFACEDESC ddsd, ddsd2, ddsd3;
216     DDCOLORKEY DDColorKey;
217     LPDWORD lpData;
218     HRESULT rc;
219     DDBLTFX fx;
220
221     ddsd2.dwSize = sizeof(ddsd2);
222     ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
223
224     ddsd.dwSize = sizeof(ddsd);
225     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
226     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
227     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
228     ddsd.dwWidth = 800;
229     ddsd.dwHeight = 600;
230     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
231     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
232     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
233     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
234     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
235     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
236     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
237     if (FAILED(rc)) {
238         skip("failed to create surface\n");
239         return;
240     }
241
242     ddsd.dwFlags |= DDSD_CKSRCBLT;
243     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
244     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
245     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
246     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
247     if (FAILED(rc)) {
248         skip("failed to create surface\n");
249         return;
250     }
251
252     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
253     ok(rc==DD_OK,"Lock returned: %x\n",rc);
254     lpData = ddsd2.lpSurface;
255     lpData[0] = 0xCCCCCCCC;
256     lpData[1] = 0xCCCCCCCC;
257     lpData[2] = 0xCCCCCCCC;
258     lpData[3] = 0xCCCCCCCC;
259
260     memset(&ddsd3, 0, sizeof(ddsd3));
261     ddsd3.dwSize = sizeof(ddsd3);
262     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
263     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
264     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
265     ok(ddsd3.lpSurface == ddsd3.lpSurface, "lpSurface from GetSurfaceDesc(%p) differs from the one returned by Lock(%p)\n", ddsd3.lpSurface, ddsd2.lpSurface);
266
267     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
268     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
269
270     memset(&ddsd3, 0, sizeof(ddsd3));
271     ddsd3.dwSize = sizeof(ddsd3);
272     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
273     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
274     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
275     ok(ddsd3.lpSurface == NULL, "lpSurface from GetSurfaceDesc(%p) is not NULL after unlock\n", ddsd3.lpSurface);
276
277     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
278     ok(rc==DD_OK,"Lock returned: %x\n",rc);
279     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
280     lpData = ddsd2.lpSurface;
281     lpData[0] = 0x77010203;
282     lpData[1] = 0x00010203;
283     lpData[2] = 0x77FF00FF;
284     lpData[3] = 0x00FF00FF;
285     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
286     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
287
288     IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
289
290     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
291     ok(rc==DD_OK,"Lock returned: %x\n",rc);
292     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
293     lpData = ddsd2.lpSurface;
294     /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
295      * color keying, but copy it to the destination surface. Others apply it for color keying, but
296      * do not copy it into the destination surface.
297      */
298     if(lpData[0]==0x00010203) {
299         trace("X channel was not copied into the destination surface\n");
300         ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
301            "Destination data after blitting is not correct\n");
302     } else {
303         ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
304            "Destination data after blitting is not correct\n");
305     }
306     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
307     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
308
309     /* Below we repeat the same test as above but now using BltFast instead of Blt. Before
310      * we can carry out the test we need to restore the color of the destination surface.
311      */
312     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
313     ok(rc==DD_OK,"Lock returned: %x\n",rc);
314     lpData = ddsd2.lpSurface;
315     lpData[0] = 0xCCCCCCCC;
316     lpData[1] = 0xCCCCCCCC;
317     lpData[2] = 0xCCCCCCCC;
318     lpData[3] = 0xCCCCCCCC;
319     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
320     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
321
322     IDirectDrawSurface_BltFast(lpDst, 0, 0, lpSrc, NULL, DDBLTFAST_SRCCOLORKEY);
323
324     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
325     ok(rc==DD_OK,"Lock returned: %x\n",rc);
326     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
327     lpData = ddsd2.lpSurface;
328     /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
329      * color keying, but copy it to the destination surface. Others apply it for color keying, but
330      * do not copy it into the destination surface.
331      */
332     if(lpData[0]==0x00010203) {
333         trace("X channel was not copied into the destination surface\n");
334         ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
335            "Destination data after blitting is not correct\n");
336     } else {
337         ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
338            "Destination data after blitting is not correct\n");
339     }
340     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
341     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
342
343     /* Also test SetColorKey */
344     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
345     ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
346        "GetColorKey does not return the colorkey used at surface creation\n");
347
348     DDColorKey.dwColorSpaceLowValue = 0x00FF00;
349     DDColorKey.dwColorSpaceHighValue = 0x00FF00;
350     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
351
352     DDColorKey.dwColorSpaceLowValue = 0;
353     DDColorKey.dwColorSpaceHighValue = 0;
354     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
355     ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
356        "GetColorKey does not return the colorkey set with SetColorKey\n");
357
358     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
359     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
360     IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
361     ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
362        "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
363
364     /* Test SetColorKey with dwColorSpaceHighValue < dwColorSpaceLowValue */
365     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
366     DDColorKey.dwColorSpaceHighValue = 0x000000;
367     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
368
369     DDColorKey.dwColorSpaceLowValue = 0;
370     DDColorKey.dwColorSpaceHighValue = 0;
371     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
372     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
373        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
374
375     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
376     DDColorKey.dwColorSpaceHighValue = 0x000001;
377     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
378
379     DDColorKey.dwColorSpaceLowValue = 0;
380     DDColorKey.dwColorSpaceHighValue = 0;
381     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
382     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
383        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
384
385     DDColorKey.dwColorSpaceLowValue = 0x0000FF;
386     DDColorKey.dwColorSpaceHighValue = 0x0000FE;
387     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
388
389     DDColorKey.dwColorSpaceLowValue = 0;
390     DDColorKey.dwColorSpaceHighValue = 0;
391     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
392     ok(DDColorKey.dwColorSpaceLowValue == 0x0000FF && DDColorKey.dwColorSpaceHighValue == 0x0000FF,
393        "GetColorKey does not return the colorkey set with SetColorKey (%x %x)\n", DDColorKey.dwColorSpaceLowValue, DDColorKey.dwColorSpaceHighValue);
394
395     IDirectDrawSurface_Release(lpSrc);
396     IDirectDrawSurface_Release(lpDst);
397
398     /* start with a new set of surfaces to test the color keying parameters to blit */
399     memset(&ddsd, 0, sizeof(ddsd));
400     ddsd.dwSize = sizeof(ddsd);
401     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
402     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
403     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
404     ddsd.dwWidth = 800;
405     ddsd.dwHeight = 600;
406     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
407     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
408     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
409     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
410     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
411     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
412     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
413     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
414     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
415     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
416     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
417     if(FAILED(rc))
418     {
419         skip("Failed to create surface\n");
420         return;
421     }
422
423     /* start with a new set of surfaces to test the color keying parameters to blit */
424     memset(&ddsd, 0, sizeof(ddsd));
425     ddsd.dwSize = sizeof(ddsd);
426     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
427     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
428     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
429     ddsd.dwWidth = 800;
430     ddsd.dwHeight = 600;
431     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
432     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
433     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
434     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
435     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
436     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
437     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
438     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
439     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
440     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
441     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
442     if(FAILED(rc))
443     {
444         skip("Failed to create surface\n");
445         IDirectDrawSurface_Release(lpDst);
446         return;
447     }
448
449     memset(&fx, 0, sizeof(fx));
450     fx.dwSize = sizeof(fx);
451     fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
452     fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
453     fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
454     fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
455
456     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
457     ok(rc==DD_OK,"Lock returned: %x\n",rc);
458     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
459     lpData = ddsd2.lpSurface;
460     lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
461     lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
462     lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
463     lpData[3] = 0x0000FF00; /* Src color key in dst surface */
464     lpData[4] = 0x00001100; /* Src color key in ddbltfx */
465     lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
466     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
467     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
468
469     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
470     ok(rc==DD_OK,"Lock returned: %x\n",rc);
471     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
472     lpData = ddsd2.lpSurface;
473     lpData[0] = 0x55555555;
474     lpData[1] = 0x55555555;
475     lpData[2] = 0x55555555;
476     lpData[3] = 0x55555555;
477     lpData[4] = 0x55555555;
478     lpData[5] = 0x55555555;
479     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
480     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
481
482     /* Test a blit without keying */
483     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
484     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
485
486     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
487     ok(rc==DD_OK,"Lock returned: %x\n",rc);
488     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
489     lpData = ddsd2.lpSurface;
490     /* Should have copied src data unmodified to dst */
491     ok(lpData[0] == 0x000000FF &&
492        lpData[1] == 0x00000000 &&
493        lpData[2] == 0x00FF0000 &&
494        lpData[3] == 0x0000FF00 &&
495        lpData[4] == 0x00001100 &&
496        lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
497
498     lpData[0] = 0x55555555;
499     lpData[1] = 0x55555555;
500     lpData[2] = 0x55555555;
501     lpData[3] = 0x55555555;
502     lpData[4] = 0x55555555;
503     lpData[5] = 0x55555555;
504     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
505     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
506
507     /* Src key */
508     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
509     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
510
511     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
512     ok(rc==DD_OK,"Lock returned: %x\n",rc);
513     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
514     lpData = ddsd2.lpSurface;
515
516     ok(lpData[0] == 0x55555555 && /* Here the src key applied */
517        lpData[1] == 0x00000000 &&
518        lpData[2] == 0x00FF0000 &&
519        lpData[3] == 0x0000FF00 &&
520        lpData[4] == 0x00001100 &&
521        lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
522
523     lpData[0] = 0x55555555;
524     lpData[1] = 0x55555555;
525     lpData[2] = 0x55555555;
526     lpData[3] = 0x55555555;
527     lpData[4] = 0x55555555;
528     lpData[5] = 0x55555555;
529     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
530     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
531
532     /* Src override */
533     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
534     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
535
536     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
537     ok(rc==DD_OK,"Lock returned: %x\n",rc);
538     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
539     lpData = ddsd2.lpSurface;
540
541     ok(lpData[0] == 0x000000FF &&
542        lpData[1] == 0x00000000 &&
543        lpData[2] == 0x00FF0000 &&
544        lpData[3] == 0x0000FF00 &&
545        lpData[4] == 0x00001100 &&
546        lpData[5] == 0x55555555, /* Override key applies here */
547        "Surface data after src override key blit does not match\n");
548
549     lpData[0] = 0x55555555;
550     lpData[1] = 0x55555555;
551     lpData[2] = 0x55555555;
552     lpData[3] = 0x55555555;
553     lpData[4] = 0x55555555;
554     lpData[5] = 0x55555555;
555     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
556     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
557
558     /* Src override AND src key. That is not supposed to work */
559     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
560     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
561
562     /* Verify that the destination is unchanged */
563     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
564     ok(rc==DD_OK,"Lock returned: %x\n",rc);
565     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
566     lpData = ddsd2.lpSurface;
567
568     ok(lpData[0] == 0x55555555 &&
569        lpData[1] == 0x55555555 &&
570        lpData[2] == 0x55555555 &&
571        lpData[3] == 0x55555555 &&
572        lpData[4] == 0x55555555 &&
573        lpData[5] == 0x55555555, /* Override key applies here */
574        "Surface data after src key blit with override does not match\n");
575
576     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
577     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
578     lpData[2] = 0x00001100; /* Dest key in override */
579     lpData[3] = 0x00001100; /* Dest key in override */
580     lpData[4] = 0x00000000; /* Dest key in src surface */
581     lpData[5] = 0x00000000; /* Dest key in src surface */
582     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
583     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
584
585     /* Dest key blit */
586     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
587     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
588
589     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
590     ok(rc==DD_OK,"Lock returned: %x\n",rc);
591     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
592     lpData = ddsd2.lpSurface;
593
594     /* DirectDraw uses the dest blit key from the SOURCE surface ! */
595     ok(lpData[0] == 0x00ff0000 &&
596        lpData[1] == 0x00ff0000 &&
597        lpData[2] == 0x00001100 &&
598        lpData[3] == 0x00001100 &&
599        lpData[4] == 0x00001100 && /* Key applies here */
600        lpData[5] == 0x00110000,   /* Key applies here */
601        "Surface data after dest key blit does not match\n");
602
603     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
604     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
605     lpData[2] = 0x00001100; /* Dest key in override */
606     lpData[3] = 0x00001100; /* Dest key in override */
607     lpData[4] = 0x00000000; /* Dest key in src surface */
608     lpData[5] = 0x00000000; /* Dest key in src surface */
609     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
610     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
611
612     /* Dest override key blit */
613     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
614     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
615
616     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
617     ok(rc==DD_OK,"Lock returned: %x\n",rc);
618     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
619     lpData = ddsd2.lpSurface;
620
621     ok(lpData[0] == 0x00FF0000 &&
622        lpData[1] == 0x00FF0000 &&
623        lpData[2] == 0x00FF0000 && /* Key applies here */
624        lpData[3] == 0x0000FF00 && /* Key applies here */
625        lpData[4] == 0x00000000 &&
626        lpData[5] == 0x00000000,
627        "Surface data after dest key override blit does not match\n");
628
629     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
630     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
631     lpData[2] = 0x00001100; /* Dest key in override */
632     lpData[3] = 0x00001100; /* Dest key in override */
633     lpData[4] = 0x00000000; /* Dest key in src surface */
634     lpData[5] = 0x00000000; /* Dest key in src surface */
635     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
636     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
637
638     /* Dest override key blit. Supposed to fail too */
639     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
640     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
641
642     /* Check for unchanged data */
643     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
644     ok(rc==DD_OK,"Lock returned: %x\n",rc);
645     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
646     lpData = ddsd2.lpSurface;
647
648     ok(lpData[0] == 0x00FF0000 &&
649        lpData[1] == 0x00FF0000 &&
650        lpData[2] == 0x00001100 && /* Key applies here */
651        lpData[3] == 0x00001100 && /* Key applies here */
652        lpData[4] == 0x00000000 &&
653        lpData[5] == 0x00000000,
654        "Surface data with dest key and dest override does not match\n");
655
656     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
657     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
658     lpData[2] = 0x00001100; /* Dest key in override */
659     lpData[3] = 0x00001100; /* Dest key in override */
660     lpData[4] = 0x00000000; /* Dest key in src surface */
661     lpData[5] = 0x00000000; /* Dest key in src surface */
662     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
663     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
664
665     /* Modify the source data a bit to give some more conclusive results */
666     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
667     ok(rc==DD_OK,"Lock returned: %x\n",rc);
668     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
669     lpData = ddsd2.lpSurface;
670     lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
671     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
672     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
673
674     /* Source and destination key */
675     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
676     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
677
678     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
679     ok(rc==DD_OK,"Lock returned: %x\n",rc);
680     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
681     lpData = ddsd2.lpSurface;
682
683     ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
684        lpData[1] == 0x00FF0000 && /* Masked by Destination key */
685        lpData[2] == 0x00001100 && /* Masked by Destination key */
686        lpData[3] == 0x00001100 && /* Masked by Destination key */
687        lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
688        lpData[5] == 0x00000000,   /* Allowed by dst key, but masked by source key */
689        "Surface data with src key and dest key blit does not match\n");
690
691     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
692     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
693     lpData[2] = 0x00001100; /* Dest key in override */
694     lpData[3] = 0x00001100; /* Dest key in override */
695     lpData[4] = 0x00000000; /* Dest key in src surface */
696     lpData[5] = 0x00000000; /* Dest key in src surface */
697     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
698     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
699
700     /* Override keys without ddbltfx parameter fail */
701     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
702     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
703     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
704     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
705
706     /* Try blitting without keys in the source surface*/
707     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
708     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
709     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
710     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
711
712     /* That fails now. Do not bother to check that the data is unmodified */
713     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
714     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
715
716     /* Dest key blit still works. Which key is used this time??? */
717     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
718     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
719
720     /* With correctly passed override keys no key in the surface is needed.
721      * Again, the result was checked before, no need to do that again
722      */
723     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
724     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
725     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
726     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
727
728     IDirectDrawSurface_Release(lpSrc);
729     IDirectDrawSurface_Release(lpDst);
730 }
731
732 static void QueryInterface(void)
733 {
734     LPDIRECTDRAWSURFACE dsurface;
735     DDSURFACEDESC surface;
736     LPVOID object;
737     HRESULT ret;
738
739     /* Create a surface */
740     ZeroMemory(&surface, sizeof(surface));
741     surface.dwSize = sizeof(surface);
742     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
743     surface.dwHeight = 10;
744     surface.dwWidth = 10;
745     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
746     if(ret != DD_OK)
747     {
748         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
749         return;
750     }
751
752     /* Call IUnknown::QueryInterface */
753     ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
754     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
755
756     IDirectDrawSurface_Release(dsurface);
757 }
758
759 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
760  * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
761  * partially in the refcount test
762  */
763
764 static ULONG getref(IUnknown *iface)
765 {
766     IUnknown_AddRef(iface);
767     return IUnknown_Release(iface);
768 }
769
770 static void GetDDInterface_1(void)
771 {
772     LPDIRECTDRAWSURFACE dsurface;
773     LPDIRECTDRAWSURFACE2 dsurface2;
774     DDSURFACEDESC surface;
775     HRESULT ret;
776     IDirectDraw2 *dd2;
777     IDirectDraw4 *dd4;
778     IDirectDraw7 *dd7;
779     ULONG ref1, ref2, ref4, ref7;
780     void *dd;
781
782     /* Create a surface */
783     ZeroMemory(&surface, sizeof(surface));
784     surface.dwSize = sizeof(surface);
785     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
786     surface.dwHeight = 10;
787     surface.dwWidth = 10;
788     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
789     if(ret != DD_OK)
790     {
791         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
792         return;
793     }
794     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
795     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
796     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
797     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
798     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
799     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
800     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
801     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
802
803     ref1 = getref((IUnknown *) lpDD);
804     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
805     ref2 = getref((IUnknown *) dd2);
806     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
807     ref4 = getref((IUnknown *) dd4);
808     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
809     ref7 = getref((IUnknown *) dd7);
810     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
811
812
813     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
814     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
815     ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
816     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
817     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
818     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
819
820     ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
821     IUnknown_Release((IUnknown *) dd);
822
823     /* try a NULL pointer */
824     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
825     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
826
827     IDirectDraw_Release(dd2);
828     IDirectDraw_Release(dd4);
829     IDirectDraw_Release(dd7);
830     IDirectDrawSurface2_Release(dsurface2);
831     IDirectDrawSurface_Release(dsurface);
832 }
833
834 static void GetDDInterface_2(void)
835 {
836     LPDIRECTDRAWSURFACE dsurface;
837     LPDIRECTDRAWSURFACE2 dsurface2;
838     DDSURFACEDESC surface;
839     HRESULT ret;
840     IDirectDraw2 *dd2;
841     IDirectDraw4 *dd4;
842     IDirectDraw7 *dd7;
843     ULONG ref1, ref2, ref4, ref7;
844     void *dd;
845
846     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
847     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
848     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
849     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
850     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
851     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
852
853     /* Create a surface */
854     ZeroMemory(&surface, sizeof(surface));
855     surface.dwSize = sizeof(surface);
856     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
857     surface.dwHeight = 10;
858     surface.dwWidth = 10;
859     ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
860     if(ret != DD_OK)
861     {
862         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
863         return;
864     }
865     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
866     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
867
868     ref1 = getref((IUnknown *) lpDD);
869     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
870     ref2 = getref((IUnknown *) dd2);
871     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
872     ref4 = getref((IUnknown *) dd4);
873     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
874     ref7 = getref((IUnknown *) dd7);
875     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
876
877
878     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
879     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
880     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
881     ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
882     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
883     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
884
885     ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
886     IUnknown_Release((IUnknown *) dd);
887
888     IDirectDraw_Release(dd2);
889     IDirectDraw_Release(dd4);
890     IDirectDraw_Release(dd7);
891     IDirectDrawSurface2_Release(dsurface2);
892     IDirectDrawSurface_Release(dsurface);
893 }
894
895 static void GetDDInterface_4(void)
896 {
897     LPDIRECTDRAWSURFACE2 dsurface2;
898     LPDIRECTDRAWSURFACE4 dsurface4;
899     DDSURFACEDESC2 surface;
900     HRESULT ret;
901     IDirectDraw2 *dd2;
902     IDirectDraw4 *dd4;
903     IDirectDraw7 *dd7;
904     ULONG ref1, ref2, ref4, ref7;
905     void *dd;
906
907     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
908     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
909     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
910     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
911     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
912     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
913
914     /* Create a surface */
915     ZeroMemory(&surface, sizeof(surface));
916     surface.dwSize = sizeof(surface);
917     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
918     surface.dwHeight = 10;
919     surface.dwWidth = 10;
920     ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
921     if(ret != DD_OK)
922     {
923         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
924         return;
925     }
926     ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
927     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
928
929     ref1 = getref((IUnknown *) lpDD);
930     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
931     ref2 = getref((IUnknown *) dd2);
932     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
933     ref4 = getref((IUnknown *) dd4);
934     ok(ref4 == 2, "IDirectDraw4 refcount is %d\n", ref4);
935     ref7 = getref((IUnknown *) dd7);
936     ok(ref7 == 1, "IDirectDraw7 refcount is %d\n", ref7);
937
938     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
939     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
940     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
941     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
942     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
943     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
944
945     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
946     IUnknown_Release((IUnknown *) dd);
947
948     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
949     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
950     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
951     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
952     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
953     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
954     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
955
956     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
957     IUnknown_Release((IUnknown *) dd);
958
959     IDirectDraw_Release(dd2);
960     IDirectDraw_Release(dd4);
961     IDirectDraw_Release(dd7);
962     IDirectDrawSurface4_Release(dsurface4);
963     IDirectDrawSurface2_Release(dsurface2);
964 }
965
966 static void GetDDInterface_7(void)
967 {
968     LPDIRECTDRAWSURFACE4 dsurface4;
969     LPDIRECTDRAWSURFACE7 dsurface7;
970     DDSURFACEDESC2 surface;
971     HRESULT ret;
972     IDirectDraw2 *dd2;
973     IDirectDraw4 *dd4;
974     IDirectDraw7 *dd7;
975     ULONG ref1, ref2, ref4, ref7;
976     void *dd;
977
978     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
979     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
980     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
981     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
982     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
983     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
984
985     /* Create a surface */
986     ZeroMemory(&surface, sizeof(surface));
987     surface.dwSize = sizeof(surface);
988     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
989     surface.dwHeight = 10;
990     surface.dwWidth = 10;
991     ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
992     if(ret != DD_OK)
993     {
994         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
995         return;
996     }
997     ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
998     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
999
1000     ref1 = getref((IUnknown *) lpDD);
1001     ok(ref1 == 1, "IDirectDraw refcount is %d\n", ref1);
1002     ref2 = getref((IUnknown *) dd2);
1003     ok(ref2 == 1, "IDirectDraw2 refcount is %d\n", ref2);
1004     ref4 = getref((IUnknown *) dd4);
1005     ok(ref4 == 1, "IDirectDraw4 refcount is %d\n", ref4);
1006     ref7 = getref((IUnknown *) dd7);
1007     ok(ref7 == 2, "IDirectDraw7 refcount is %d\n", ref7);
1008
1009     ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
1010     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1011     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1012     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1013     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1014     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1015
1016     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1017     IUnknown_Release((IUnknown *) dd);
1018
1019     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
1020     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
1021     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
1022     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %d\n", getref((IUnknown *) lpDD) - ref1);
1023     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %d\n", getref((IUnknown *) dd2) - ref2);
1024     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %d\n", getref((IUnknown *) dd4) - ref4);
1025     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %d\n", getref((IUnknown *) dd7) - ref7);
1026
1027     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
1028     IUnknown_Release((IUnknown *) dd);
1029
1030     IDirectDraw_Release(dd2);
1031     IDirectDraw_Release(dd4);
1032     IDirectDraw_Release(dd7);
1033     IDirectDrawSurface4_Release(dsurface4);
1034     IDirectDrawSurface7_Release(dsurface7);
1035 }
1036
1037 static ULONG getRefcount(IUnknown *iface)
1038 {
1039     IUnknown_AddRef(iface);
1040     return IUnknown_Release(iface);
1041 }
1042
1043 static void IFaceRefCount(void)
1044 {
1045     LPDIRECTDRAWSURFACE surf;
1046     DDSURFACEDESC surface;
1047     HRESULT ret;
1048     IDirectDrawSurface2 *surf2;
1049     IDirectDrawSurface2 *surf2a;
1050     IDirectDrawSurface4 *surf4;
1051     IDirectDrawSurface7 *surf7a;
1052     IDirectDrawSurface7 *surf7b;
1053     IDirect3DTexture* tex;
1054     IDirect3DTexture2* tex2;
1055     IDirectDrawGammaControl* gamma;
1056     ULONG ref;
1057
1058     /* Create a surface */
1059     ZeroMemory(&surface, sizeof(surface));
1060     surface.dwSize = sizeof(surface);
1061     surface.dwFlags = DDSD_CAPS;
1062     surface.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1063     ret = IDirectDraw_CreateSurface(lpDD, &surface, &surf, NULL);
1064
1065     if (ret != DD_OK)
1066     {
1067         ok(FALSE, "Could not create surface, skipping test\n");
1068         return;
1069     }
1070
1071     ref = getRefcount((IUnknown *) surf);
1072     ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1073
1074     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
1075     ref = getRefcount((IUnknown *) surf);
1076     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* Check the ref count is one */
1077     ref = getRefcount((IUnknown *) surf2);
1078     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref); /* This should also be one */
1079
1080     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2a);
1081     ref = getRefcount((IUnknown *) surf2);
1082     todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);   /* Surf2's refcount should be 2 now, but surf should be 1 */
1083     ref = getRefcount((IUnknown *) surf);
1084     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1085
1086     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface4, (void **) &surf4);
1087     ref = getRefcount((IUnknown *) surf4);
1088     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1089
1090     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7a);
1091     ref = getRefcount((IUnknown *) surf7a);
1092     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1093
1094     IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface7, (void **) &surf7b);
1095     ref = getRefcount((IUnknown *) surf7b);
1096     todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1097
1098     /* IDirect3DTexture interface (unlike the others) alters the original IDirectDrawSurface ref count */
1099     ret = IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture, (void **) &tex);
1100     if (SUCCEEDED(ret))
1101     {
1102         ref = getRefcount((IUnknown *) tex);
1103         todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1104         ref = getRefcount((IUnknown *) surf);
1105         todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1106
1107         IDirectDrawSurface_QueryInterface(surf, &IID_IDirect3DTexture2, (void **) &tex2);
1108         ref = getRefcount((IUnknown *) tex);
1109         todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1110         ref = getRefcount((IUnknown *) tex2);
1111         todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1112         ref = getRefcount((IUnknown *) surf);
1113         todo_wine ok(ref == 3, "Refcount is %u, expected 3\n", ref);
1114
1115         IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawGammaControl, (void **) &gamma);
1116         ref = getRefcount((IUnknown *) gamma);
1117         todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1118
1119         ref = IDirect3DTexture2_Release(tex2); /* Release the texture */
1120         todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1121         ref = getRefcount((IUnknown *) surf);
1122         todo_wine ok(ref == 2, "Refcount is %u, expected 2\n", ref);
1123
1124         ref = IDirect3DTexture_Release(tex); /* Release the texture */
1125         todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1126         ref = getRefcount((IUnknown *) surf);
1127         todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1128
1129         ref = IDirectDrawGammaControl_Release(gamma); /* Release the gamma control */
1130         todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1131     }
1132
1133     ref = IDirectDrawSurface2_Release(surf2); /* Release one of the 2 surf2 interfaces */
1134     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1135
1136     ref = IDirectDrawSurface2_Release(surf2a); /* Release the other */
1137     todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1138
1139     ref = IDirectDrawSurface4_Release(surf4);
1140     todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1141
1142     ref = IDirectDrawSurface7_Release(surf7a);
1143     todo_wine ok(ref == 1, "Refcount is %u, expected 1\n", ref);
1144
1145     ref = IDirectDrawSurface7_Release(surf7b);
1146     todo_wine ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1147
1148     ref = IDirectDrawSurface_Release(surf);
1149     ok(ref == 0, "Refcount is %u, expected 0\n", ref);
1150 }
1151
1152 #define MAXEXPECTED 8  /* Can match up to 8 expected surfaces */
1153 struct enumstruct
1154 {
1155     IDirectDrawSurface *expected[MAXEXPECTED];
1156     UINT count;
1157 };
1158
1159 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
1160 {
1161     int i;
1162     BOOL found = FALSE;
1163
1164     for(i = 0; i < MAXEXPECTED; i++)
1165     {
1166         if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
1167     }
1168
1169     ok(found, "Unexpected surface %p enumerated\n", surf);
1170     ((struct enumstruct *)ctx)->count++;
1171     IDirectDrawSurface_Release(surf);
1172     return DDENUMRET_OK;
1173 }
1174
1175 static void EnumTest(void)
1176 {
1177     HRESULT rc;
1178     DDSURFACEDESC ddsd;
1179     IDirectDrawSurface *surface;
1180     struct enumstruct ctx;
1181
1182     ddsd.dwSize = sizeof(ddsd);
1183     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1184     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1185     U2(ddsd).dwMipMapCount = 3;
1186     ddsd.dwWidth = 32;
1187     ddsd.dwHeight = 32;
1188     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
1189     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
1190
1191     memset(&ctx, 0, sizeof(ctx));
1192     ctx.expected[0] = surface;
1193     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1194     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1195     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1196     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1197     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1198     ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1199     ok(!ctx.expected[3], "expected NULL pointer\n");
1200     ctx.count = 0;
1201
1202     rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, &ctx, enumCB);
1203     ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1204     ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1205
1206     IDirectDrawSurface_Release(ctx.expected[2]);
1207     IDirectDrawSurface_Release(ctx.expected[1]);
1208     IDirectDrawSurface_Release(surface);
1209 }
1210
1211 static HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1212 {
1213     UINT *num = context;
1214     (*num)++;
1215     IDirectDrawSurface_Release(surface);
1216     return DDENUMRET_OK;
1217 }
1218
1219 static void AttachmentTest7(void)
1220 {
1221     HRESULT hr;
1222     IDirectDraw7 *dd7;
1223     IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1224     DDSURFACEDESC2 ddsd, ddsd2;
1225     UINT num;
1226     DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0}, caps2 = {DDSCAPS_BACKBUFFER,0,0,0};
1227     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1228
1229     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1230     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1231
1232     memset(&ddsd, 0, sizeof(ddsd));
1233     ddsd.dwSize = sizeof(ddsd);
1234     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1235     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1236     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1237     ddsd.dwWidth = 128;
1238     ddsd.dwHeight = 128;
1239     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1240     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1241
1242     /* ROOT */
1243     num = 0;
1244     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1245     ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1246     /* DONE ROOT */
1247
1248     /* LEVEL 1 */
1249     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1250     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1251     num = 0;
1252     IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1253     ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1254     /* DONE LEVEL 1 */
1255
1256     /* LEVEL 2 */
1257     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1258     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1259     IDirectDrawSurface7_Release(surface2);
1260     num = 0;
1261     IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1262     ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1263     /* Done level 2 */
1264     /* Mip level 3 is still needed */
1265     hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
1266     ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
1267     ok(!surface4, "expected NULL pointer\n");
1268
1269     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1270     memset(&ddsd, 0, sizeof(ddsd));
1271     ddsd.dwSize = sizeof(ddsd);
1272     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1273     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1274     ddsd.dwWidth = 16;
1275     ddsd.dwHeight = 16;
1276     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1277     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1278
1279     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1280     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1281     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1282     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1283     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1284     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1285     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1286     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1287
1288     IDirectDrawSurface7_Release(surface2);
1289
1290     memset(&ddsd, 0, sizeof(ddsd));
1291     ddsd.dwSize = sizeof(ddsd);
1292     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1293     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1294     ddsd.dwWidth = 16;
1295     ddsd.dwHeight = 16;
1296     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1297     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1298
1299     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1300     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1301     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1302     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1303     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1304     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1305     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1306     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1307
1308     IDirectDrawSurface7_Release(surface3);
1309     IDirectDrawSurface7_Release(surface2);
1310     IDirectDrawSurface7_Release(surface1);
1311
1312     hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1313     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1314
1315     memset(&ddsd, 0, sizeof(ddsd));
1316     ddsd.dwSize = sizeof(ddsd);
1317     ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1318     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1319     ddsd.dwBackBufferCount = 2;
1320     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1321     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1322
1323     /* backbuffer surfaces must not have dwBackBufferCount set */
1324     ddsd2.dwSize = sizeof(ddsd2);
1325     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps2, &surface2);
1326     ok(hr==DD_OK,"GetAttachedSurface returned: %x\n", hr);
1327     hr = IDirectDrawSurface7_GetSurfaceDesc(surface2, &ddsd2);
1328     ok(hr==DD_OK,"GetSurfaceDesc returned: %x\n", hr);
1329     ok(ddsd2.dwBackBufferCount==0,"backbuffer surface has dwBackBufferCount==%u\n", ddsd2.dwBackBufferCount);
1330
1331     num = 0;
1332     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1333     ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1334     IDirectDrawSurface7_Release(surface1);
1335
1336     /* Those are some invalid descriptions, no need to test attachments with them */
1337     memset(&ddsd, 0, sizeof(ddsd));
1338     ddsd.dwSize = sizeof(ddsd);
1339     ddsd.dwFlags = DDSD_CAPS;
1340     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1341     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1342     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1343     memset(&ddsd, 0, sizeof(ddsd));
1344     ddsd.dwSize = sizeof(ddsd);
1345     ddsd.dwFlags = DDSD_CAPS;
1346     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1347     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1348     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1349
1350     /* Try a single primary and two offscreen plain surfaces */
1351     memset(&ddsd, 0, sizeof(ddsd));
1352     ddsd.dwSize = sizeof(ddsd);
1353     ddsd.dwFlags = DDSD_CAPS;
1354     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1355     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1356     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1357
1358     memset(&ddsd, 0, sizeof(ddsd));
1359     ddsd.dwSize = sizeof(ddsd);
1360     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1361     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1362     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1363     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1364     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1365     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1366
1367     memset(&ddsd, 0, sizeof(ddsd));
1368     ddsd.dwSize = sizeof(ddsd);
1369     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1370     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1371     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1372     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1373     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1374     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1375
1376     /* This one has a different size */
1377     memset(&ddsd, 0, sizeof(ddsd));
1378     ddsd.dwSize = sizeof(ddsd);
1379     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1380     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1381     ddsd.dwWidth = 128;
1382     ddsd.dwHeight = 128;
1383     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1384     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1385
1386     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1387     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1388     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1389     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1390     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1391     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1392     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1393     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1394     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1395     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1396
1397     IDirectDrawSurface7_Release(surface4);
1398     IDirectDrawSurface7_Release(surface3);
1399     IDirectDrawSurface7_Release(surface2);
1400     IDirectDrawSurface7_Release(surface1);
1401
1402     hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1403     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1404     IDirectDraw7_Release(dd7);
1405 }
1406
1407 static void AttachmentTest(void)
1408 {
1409     HRESULT hr;
1410     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1411     DDSURFACEDESC ddsd;
1412     DDSCAPS caps = {DDSCAPS_TEXTURE};
1413     BOOL refrast = FALSE;
1414     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1415
1416     memset(&ddsd, 0, sizeof(ddsd));
1417     ddsd.dwSize = sizeof(ddsd);
1418     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1419     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1420     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1421     ddsd.dwWidth = 128;
1422     ddsd.dwHeight = 128;
1423     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1424     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1425
1426     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1427     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1428     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1429     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1430
1431     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1432     memset(&ddsd, 0, sizeof(ddsd));
1433     ddsd.dwSize = sizeof(ddsd);
1434     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1435     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1436     ddsd.dwWidth = 16;
1437     ddsd.dwHeight = 16;
1438     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1439     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1440
1441     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1442     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1443     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1444     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1445     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1446     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1447     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1448     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1449     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1450     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1451     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1452     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1453
1454     IDirectDrawSurface7_Release(surface4);
1455
1456     memset(&ddsd, 0, sizeof(ddsd));
1457     ddsd.dwSize = sizeof(ddsd);
1458     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1459     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1460     ddsd.dwWidth = 16;
1461     ddsd.dwHeight = 16;
1462     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1463     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1464
1465     if (SUCCEEDED(IDirectDrawSurface7_AddAttachedSurface(surface1, surface4)))
1466     {
1467         IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1468         refrast = TRUE;
1469     }
1470
1471     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1472     if (refrast)
1473         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1474     else
1475         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1476     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1477
1478     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);  /* Succeeds on refrast */
1479     if (refrast)
1480         ok(hr == S_OK, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1481     else
1482         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1483     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1484
1485     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);  /* Succeeds on refrast */
1486     if (refrast)
1487         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1488     else
1489         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1490     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1491
1492     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1493     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1494     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1495
1496     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);  /* Succeeds on refrast */
1497     if (refrast)
1498         ok(hr == S_OK, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1499     else
1500         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1501     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1502
1503     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1504     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1505     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1506
1507     IDirectDrawSurface7_Release(surface4);
1508     IDirectDrawSurface7_Release(surface3);
1509     IDirectDrawSurface7_Release(surface2);
1510     IDirectDrawSurface7_Release(surface1);
1511
1512     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1513     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1514
1515     /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1516     memset(&ddsd, 0, sizeof(ddsd));
1517     ddsd.dwSize = sizeof(ddsd);
1518     ddsd.dwFlags = DDSD_CAPS;
1519     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1520     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1521     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1522     /* This old ddraw version happily creates explicit front buffers */
1523     memset(&ddsd, 0, sizeof(ddsd));
1524     ddsd.dwSize = sizeof(ddsd);
1525     ddsd.dwFlags = DDSD_CAPS;
1526     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1527     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1528     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1529     IDirectDrawSurface_Release(surface1);
1530
1531     /* Try a single primary and two offscreen plain surfaces */
1532     memset(&ddsd, 0, sizeof(ddsd));
1533     ddsd.dwSize = sizeof(ddsd);
1534     ddsd.dwFlags = DDSD_CAPS;
1535     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1536     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1537     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1538
1539     memset(&ddsd, 0, sizeof(ddsd));
1540     ddsd.dwSize = sizeof(ddsd);
1541     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1542     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1543     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1544     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1545     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1546     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1547
1548     memset(&ddsd, 0, sizeof(ddsd));
1549     ddsd.dwSize = sizeof(ddsd);
1550     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1551     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1552     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1553     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1554     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1555     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1556
1557     /* This one has a different size */
1558     memset(&ddsd, 0, sizeof(ddsd));
1559     ddsd.dwSize = sizeof(ddsd);
1560     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1561     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1562     ddsd.dwWidth = 128;
1563     ddsd.dwHeight = 128;
1564     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1565     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1566
1567     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1568     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1569        "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1570     if(SUCCEEDED(hr))
1571     {
1572         /* Try the reverse without detaching first */
1573         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1574         ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1575         hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1576         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1577     }
1578     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1579     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1580        "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1581     if(SUCCEEDED(hr))
1582     {
1583         /* Try to detach reversed */
1584         hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1585         ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1586         /* Now the proper detach */
1587         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1588         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1589     }
1590     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1591     ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
1592        "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1593     if(SUCCEEDED(hr))
1594     {
1595         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1596         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1597     }
1598     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1599     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1600     hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1601     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1602
1603     IDirectDrawSurface_Release(surface4);
1604     IDirectDrawSurface_Release(surface3);
1605     IDirectDrawSurface_Release(surface2);
1606     IDirectDrawSurface_Release(surface1);
1607
1608     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1609     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1610
1611     DestroyWindow(window);
1612 }
1613
1614 struct compare
1615 {
1616     DWORD width, height;
1617     DWORD caps, caps2;
1618     UINT mips;
1619 };
1620
1621 static HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1622 {
1623     UINT *mips = context;
1624
1625     (*mips)++;
1626     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1627                                              context,
1628                                              CubeTestLvl2Enum);
1629
1630     return DDENUMRET_OK;
1631 }
1632
1633 static HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1634 {
1635     UINT mips = 0;
1636     UINT *num = context;
1637     static const struct compare expected[] =
1638     {
1639         {
1640             128, 128,
1641             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1642             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1643             7
1644         },
1645         {
1646             128, 128,
1647             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1648             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1649             7
1650         },
1651         {
1652             128, 128,
1653             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1654             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1655             7
1656         },
1657         {
1658             128, 128,
1659             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1660             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1661             7
1662         },
1663         {
1664             128, 128,
1665             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1666             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1667             7
1668         },
1669         {
1670             64, 64, /* This is the first mipmap */
1671             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1672             DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1673             6
1674         },
1675     };
1676
1677     mips = 0;
1678     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1679                                              &mips,
1680                                              CubeTestLvl2Enum);
1681
1682     ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1683     ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1684     ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1685     ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1686     ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1687
1688     (*num)++;
1689
1690     IDirectDrawSurface7_Release(surface);
1691
1692     return DDENUMRET_OK;
1693 }
1694
1695 static void CubeMapTest(void)
1696 {
1697     IDirectDraw7 *dd7 = NULL;
1698     IDirectDrawSurface7 *cubemap = NULL;
1699     DDSURFACEDESC2 ddsd;
1700     HRESULT hr;
1701     UINT num = 0;
1702     struct enumstruct ctx;
1703
1704     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1705     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1706     if (FAILED(hr)) goto err;
1707
1708     memset(&ddsd, 0, sizeof(ddsd));
1709     ddsd.dwSize = sizeof(ddsd);
1710     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1711     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1712     ddsd.dwWidth = 128;
1713     ddsd.dwHeight = 128;
1714     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1715     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1716
1717     /* D3DFMT_R5G6B5 */
1718     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1719     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1720     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1721     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1722     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1723
1724     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1725     if (FAILED(hr))
1726     {
1727         skip("Can't create cubemap surface\n");
1728         goto err;
1729     }
1730
1731     hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1732     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1733     ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1734        "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1735     ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1736        "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1737
1738     IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1739                                              &num,
1740                                              CubeTestLvl1Enum);
1741     ok(num == 6, "Surface has %d attachments\n", num);
1742     IDirectDrawSurface7_Release(cubemap);
1743
1744     /* What happens if I do not specify any faces? */
1745     memset(&ddsd, 0, sizeof(ddsd));
1746     ddsd.dwSize = sizeof(ddsd);
1747     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1748     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1749     ddsd.dwWidth = 128;
1750     ddsd.dwHeight = 128;
1751     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1752     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1753
1754     /* D3DFMT_R5G6B5 */
1755     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1756     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1757     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1758     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1759     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1760
1761     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1762     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1763
1764     /* Cube map faces without a cube map? */
1765     memset(&ddsd, 0, sizeof(ddsd));
1766     ddsd.dwSize = sizeof(ddsd);
1767     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1768     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1769     ddsd.dwWidth = 128;
1770     ddsd.dwHeight = 128;
1771     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1772     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1773
1774     /* D3DFMT_R5G6B5 */
1775     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1776     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1777     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1778     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1779     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1780
1781     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1782     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1783
1784     memset(&ddsd, 0, sizeof(ddsd));
1785     ddsd.dwSize = sizeof(ddsd);
1786     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1787     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1788     ddsd.dwWidth = 128;
1789     ddsd.dwHeight = 128;
1790     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1791     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1792
1793     /* D3DFMT_R5G6B5 */
1794     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1795     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1796     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1797     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1798     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1799
1800     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1801     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1802
1803     /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1804     memset(&ctx, 0, sizeof(ctx));
1805     memset(&ddsd, 0, sizeof(ddsd));
1806     ddsd.dwSize = sizeof(DDSURFACEDESC);
1807     hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1808     ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1809     ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1810
1811     err:
1812     if (dd7) IDirectDraw7_Release(dd7);
1813 }
1814
1815 static void test_lockrect_invalid(void)
1816 {
1817     unsigned int i, j;
1818
1819     RECT valid[] = {
1820         {60, 60, 68, 68},
1821         {60, 60, 60, 68},
1822         {60, 60, 68, 60},
1823         {120, 60, 128, 68},
1824         {60, 120, 68, 128},
1825     };
1826
1827     RECT invalid[] = {
1828         {68, 60, 60, 68},       /* left > right */
1829         {60, 68, 68, 60},       /* top > bottom */
1830         {-8, 60,  0, 68},       /* left < surface */
1831         {60, -8, 68,  0},       /* top < surface */
1832         {-16, 60, -8, 68},      /* right < surface */
1833         {60, -16, 68, -8},      /* bottom < surface */
1834         {60, 60, 136, 68},      /* right > surface */
1835         {60, 60, 68, 136},      /* bottom > surface */
1836         {136, 60, 144, 68},     /* left > surface */
1837         {60, 136, 68, 144},     /* top > surface */
1838     };
1839
1840     const DWORD dds_caps[] = {
1841         DDSCAPS_OFFSCREENPLAIN
1842     };
1843
1844     for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1845     {
1846         IDirectDrawSurface *surface = 0;
1847         DDSURFACEDESC surface_desc = {0};
1848         DDSURFACEDESC locked_desc = {0};
1849         HRESULT hr;
1850
1851         surface_desc.dwSize = sizeof(surface_desc);
1852         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1853         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1854         surface_desc.ddsCaps.dwCaps = dds_caps[j];
1855         surface_desc.dwWidth = 128;
1856         surface_desc.dwHeight = 128;
1857         surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1858         U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1859         U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1860         U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1861         U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1862
1863         hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1864         ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1865         if (FAILED(hr)) {
1866             skip("failed to create surface\n");
1867             continue;
1868         }
1869
1870         for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1871         {
1872             RECT *rect = &valid[i];
1873
1874             memset(&locked_desc, 0, sizeof(locked_desc));
1875             locked_desc.dwSize = sizeof(locked_desc);
1876
1877             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1878             ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1879                     hr, rect->left, rect->top, rect->right, rect->bottom);
1880
1881             hr = IDirectDrawSurface_Unlock(surface, NULL);
1882             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1883         }
1884
1885         for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1886         {
1887             RECT *rect = &invalid[i];
1888
1889             memset(&locked_desc, 1, sizeof(locked_desc));
1890             locked_desc.dwSize = sizeof(locked_desc);
1891
1892             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1893             ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1894                     ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1895                     rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1896             ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1897         }
1898
1899         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1900         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1901         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1902         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1903         if(SUCCEEDED(hr)) {
1904             hr = IDirectDrawSurface_Unlock(surface, NULL);
1905             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1906         }
1907         hr = IDirectDrawSurface_Unlock(surface, NULL);
1908         ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1909
1910         memset(&locked_desc, 0, sizeof(locked_desc));
1911         locked_desc.dwSize = sizeof(locked_desc);
1912         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1913         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1914            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1915         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1916         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1917            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1918
1919         /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1920          * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1921          */
1922
1923         hr = IDirectDrawSurface_Unlock(surface, NULL);
1924         ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1925
1926         IDirectDrawSurface_Release(surface);
1927     }
1928 }
1929
1930 static void CompressedTest(void)
1931 {
1932     HRESULT hr;
1933     IDirectDrawSurface7 *surface;
1934     DDSURFACEDESC2 ddsd, ddsd2;
1935     IDirectDraw7 *dd7 = NULL;
1936     RECT r = { 0, 0, 128, 128 };
1937     RECT r2 = { 32, 32, 64, 64 };
1938
1939     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1940     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1941
1942     memset(&ddsd, 0, sizeof(ddsd));
1943     ddsd.dwSize = sizeof(ddsd);
1944     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1945     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1946     ddsd.dwWidth = 128;
1947     ddsd.dwHeight = 128;
1948     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1949     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1950     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1951
1952     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1953     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1954     if (FAILED(hr)) {
1955         skip("failed to create surface\n");
1956         return;
1957     }
1958
1959     memset(&ddsd2, 0, sizeof(ddsd2));
1960     ddsd2.dwSize = sizeof(ddsd2);
1961     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1962     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1963     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1964
1965     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1966        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1967     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1968     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1969     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1970        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1971     ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1972     ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1973     IDirectDrawSurface7_Release(surface);
1974
1975     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1976     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1977     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1978     if (FAILED(hr)) {
1979         skip("failed to create surface\n");
1980         return;
1981     }
1982
1983     memset(&ddsd2, 0, sizeof(ddsd2));
1984     ddsd2.dwSize = sizeof(ddsd2);
1985     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1986     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1987     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1988
1989     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1990        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1991     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1992     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1993     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1994        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1995     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1996     IDirectDrawSurface7_Release(surface);
1997
1998     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1999     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2000     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2001     if (FAILED(hr)) {
2002         skip("failed to create surface\n");
2003         return;
2004     }
2005
2006     memset(&ddsd2, 0, sizeof(ddsd2));
2007     ddsd2.dwSize = sizeof(ddsd2);
2008     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2009     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2010     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2011
2012     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2013        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2014     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2015     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2016     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2017        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2018     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2019     ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2020
2021     memset(&ddsd2, 0, sizeof(ddsd2));
2022     ddsd2.dwSize = sizeof(ddsd2);
2023     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2024
2025     /* Show that the description is not changed when locking the surface. What is really interesting
2026      * about this is that DDSD_LPSURFACE isn't set.
2027      */
2028     hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2029     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2030
2031     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2032        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2033     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2034     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2035     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2036        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2037     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2038     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2039
2040     hr = IDirectDrawSurface7_Unlock(surface, NULL);
2041     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2042
2043     /* Now what about a locking rect?  */
2044     hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2045     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2046
2047     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2048        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2049     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2050     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2051     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2052        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2053     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2054     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2055
2056     hr = IDirectDrawSurface7_Unlock(surface, &r);
2057     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2058
2059     /* Now what about a different locking offset? */
2060     hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2061     ok(hr == DD_OK, "Lock returned %08x\n", hr);
2062
2063     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2064        "Surface desc flags: %08x\n", ddsd2.dwFlags);
2065     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2066     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2067     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2068        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2069     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2070     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2071
2072     hr = IDirectDrawSurface7_Unlock(surface, &r2);
2073     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2074     IDirectDrawSurface7_Release(surface);
2075
2076     /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
2077      * but seems to have a pitch instead.
2078      */
2079     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
2080     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2081
2082     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2083     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS ||
2084        broken(hr == DDERR_NODIRECTDRAWHW), "CreateSurface returned %08x\n", hr);
2085
2086     /* Not supported everywhere */
2087     if(SUCCEEDED(hr))
2088     {
2089         memset(&ddsd2, 0, sizeof(ddsd2));
2090         ddsd2.dwSize = sizeof(ddsd2);
2091         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2092         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2093         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2094
2095         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2096         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2097         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2098         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2099         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2100         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2101         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2102         ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2103         IDirectDrawSurface7_Release(surface);
2104
2105         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2106         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2107         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2108
2109         memset(&ddsd2, 0, sizeof(ddsd2));
2110         ddsd2.dwSize = sizeof(ddsd2);
2111         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2112         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2113         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2114
2115         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2116         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2117         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2118         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2119         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2120         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2121         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2122         IDirectDrawSurface7_Release(surface);
2123
2124         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2125         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2126         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2127
2128         memset(&ddsd2, 0, sizeof(ddsd2));
2129         ddsd2.dwSize = sizeof(ddsd2);
2130         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2131         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2132         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2133
2134         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2135         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2136         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2137         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2138         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2139         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2140         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2141         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2142
2143         memset(&ddsd2, 0, sizeof(ddsd2));
2144         ddsd2.dwSize = sizeof(ddsd2);
2145         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2146
2147         /* Show that the description is not changed when locking the surface. What is really interesting
2148         * about this is that DDSD_LPSURFACE isn't set.
2149         */
2150         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2151         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2152
2153         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2154         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2155         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2156         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2157         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2158         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2159         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2160         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2161
2162         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2163         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2164
2165         /* Now what about a locking rect?  */
2166         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2167         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2168
2169         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2170         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2171         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2172         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2173         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2174         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2175         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2176         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2177
2178         hr = IDirectDrawSurface7_Unlock(surface, &r);
2179         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2180
2181         /* Now what about a different locking offset? */
2182         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2183         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2184
2185         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2186         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2187         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2188         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2189         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
2190         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2191         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
2192         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2193
2194         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2195         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2196
2197         IDirectDrawSurface7_Release(surface);
2198     }
2199     else
2200     {
2201         skip("Hardware DXTN textures not supported\n");
2202     }
2203
2204     /* What happens to managed textures? Interestingly, Windows reports them as being in system
2205      * memory. The linear size fits again.
2206      */
2207     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
2208     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
2209     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
2210
2211     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2212     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
2213
2214     /* Not supported everywhere */
2215     if(SUCCEEDED(hr))
2216     {
2217         memset(&ddsd2, 0, sizeof(ddsd2));
2218         ddsd2.dwSize = sizeof(ddsd2);
2219         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2220         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2221         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2222
2223         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2224         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2225         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2226         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2227         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2228         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2229         ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2230         ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2231         IDirectDrawSurface7_Release(surface);
2232
2233         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2234         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2235         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2236
2237         memset(&ddsd2, 0, sizeof(ddsd2));
2238         ddsd2.dwSize = sizeof(ddsd2);
2239         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2240         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2241         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2242
2243         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2244         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2245         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2246         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2247         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2248         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2249         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2250         IDirectDrawSurface7_Release(surface);
2251
2252         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2253         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2254         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2255
2256         memset(&ddsd2, 0, sizeof(ddsd2));
2257         ddsd2.dwSize = sizeof(ddsd2);
2258         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2259         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2260         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
2261
2262         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2263         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2264         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2265         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2266         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2267         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2268         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2269         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
2270
2271         memset(&ddsd2, 0, sizeof(ddsd2));
2272         ddsd2.dwSize = sizeof(ddsd2);
2273         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2274
2275         /* Show that the description is not changed when locking the surface. What is really interesting
2276         * about this is that DDSD_LPSURFACE isn't set.
2277         */
2278         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2279         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2280
2281         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2282         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2283         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2284         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2285         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2286         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2287         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2288         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2289
2290         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2291         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2292
2293         /* Now what about a locking rect?  */
2294         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2295         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2296
2297         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2298         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2299         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2300         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2301         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2302         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2303         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2304         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2305
2306         hr = IDirectDrawSurface7_Unlock(surface, &r);
2307         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2308
2309         /* Now what about a different locking offset? */
2310         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2311         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2312
2313         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2314         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2315         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2316         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2317         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2318         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2319         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2320         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2321
2322         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2323         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2324
2325         IDirectDrawSurface7_Release(surface);
2326     }
2327     else
2328     {
2329         skip("Hardware DXTN textures not supported\n");
2330     }
2331
2332     IDirectDraw7_Release(dd7);
2333 }
2334
2335 static void SizeTest(void)
2336 {
2337     LPDIRECTDRAWSURFACE dsurface = NULL;
2338     DDSURFACEDESC desc;
2339     HRESULT ret;
2340     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2341
2342     /* Create an offscreen surface surface without a size */
2343     ZeroMemory(&desc, sizeof(desc));
2344     desc.dwSize = sizeof(desc);
2345     desc.dwFlags = DDSD_CAPS;
2346     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2347     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2348     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2349     if(dsurface)
2350     {
2351         trace("Surface at %p\n", dsurface);
2352         IDirectDrawSurface_Release(dsurface);
2353         dsurface = NULL;
2354     }
2355
2356     /* Create an offscreen surface surface with only a width parameter */
2357     ZeroMemory(&desc, sizeof(desc));
2358     desc.dwSize = sizeof(desc);
2359     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2360     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2361     desc.dwWidth = 128;
2362     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2363     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without hight info returned %08x\n", ret);
2364     if(dsurface)
2365     {
2366         IDirectDrawSurface_Release(dsurface);
2367         dsurface = NULL;
2368     }
2369
2370     /* Create an offscreen surface surface with only a height parameter */
2371     ZeroMemory(&desc, sizeof(desc));
2372     desc.dwSize = sizeof(desc);
2373     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2374     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2375     desc.dwHeight = 128;
2376     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2377     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2378     if(dsurface)
2379     {
2380         IDirectDrawSurface_Release(dsurface);
2381         dsurface = NULL;
2382     }
2383
2384     /* Sanity check */
2385     ZeroMemory(&desc, sizeof(desc));
2386     desc.dwSize = sizeof(desc);
2387     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2388     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2389     desc.dwHeight = 128;
2390     desc.dwWidth = 128;
2391     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2392     ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2393     if(dsurface)
2394     {
2395         IDirectDrawSurface_Release(dsurface);
2396         dsurface = NULL;
2397     }
2398
2399     /* Test a primary surface size */
2400     ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2401     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2402
2403     ZeroMemory(&desc, sizeof(desc));
2404     desc.dwSize = sizeof(desc);
2405     desc.dwFlags = DDSD_CAPS;
2406     desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2407     desc.dwHeight = 128; /* Keep them set to  check what happens */
2408     desc.dwWidth = 128; /* Keep them set to  check what happens */
2409     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2410     ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2411     if(dsurface)
2412     {
2413         ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2414         ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2415
2416         IDirectDrawSurface_Release(dsurface);
2417         dsurface = NULL;
2418
2419         ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2420         ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2421         ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2422         ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2423     }
2424     ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2425     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2426 }
2427
2428 static void PrivateDataTest(void)
2429 {
2430     HRESULT hr;
2431     IDirectDrawSurface7 *surface7 = NULL;
2432     IDirectDrawSurface *surface = NULL;
2433     DDSURFACEDESC desc;
2434     ULONG ref, ref2;
2435     IUnknown *ptr;
2436     DWORD size = sizeof(IUnknown *);
2437
2438     ZeroMemory(&desc, sizeof(desc));
2439     desc.dwSize = sizeof(desc);
2440     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2441     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2442     desc.dwHeight = 128;
2443     desc.dwWidth = 128;
2444     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2445     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2446     if(!surface)
2447     {
2448         return;
2449     }
2450     hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2451     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2452     if(!surface7)
2453     {
2454         IDirectDrawSurface_Release(surface);
2455         return;
2456     }
2457
2458     /* This fails */
2459     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2460     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2461     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2462     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2463     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2464     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2465
2466     ref = getref((IUnknown *) lpDD);
2467     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2468     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2469     ref2 = getref((IUnknown *) lpDD);
2470     ok(ref2 == ref + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2471     hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2472     ok(SUCCEEDED(hr), "IDirectDrawSurface7_FreePrivateData returned %#x.\n", hr);
2473     ref2 = getref((IUnknown *) lpDD);
2474     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2475
2476     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2477     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2478     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2479     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2480     ref2 = getref((IUnknown *) lpDD);
2481     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2482
2483     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2484     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2485     hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2486     ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2487     ref2 = getref((IUnknown *) lpDD);
2488     /* Object is NOT being addrefed */
2489     ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2490     ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2491
2492     IDirectDrawSurface_Release(surface);
2493     IDirectDrawSurface7_Release(surface7);
2494
2495     /* Destroying the surface frees the held reference */
2496     ref2 = getref((IUnknown *) lpDD);
2497     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2498 }
2499
2500 static void BltParamTest(void)
2501 {
2502     IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2503     DDSURFACEDESC desc;
2504     HRESULT hr;
2505     DDBLTFX BltFx;
2506     RECT valid = {10, 10, 20, 20};
2507     RECT invalid1 = {20, 10, 10, 20};
2508     RECT invalid2 = {20, 20, 20, 20};
2509     RECT invalid3 = {-1, -1, 20, 20};
2510     RECT invalid4 = {60, 60, 70, 70};
2511
2512     memset(&desc, 0, sizeof(desc));
2513     desc.dwSize = sizeof(desc);
2514     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2515     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2516     desc.dwHeight = 128;
2517     desc.dwWidth = 128;
2518     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2519     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2520
2521     desc.dwHeight = 64;
2522     desc.dwWidth = 64;
2523     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2524     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2525
2526     if(0)
2527     {
2528         /* This crashes */
2529         hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2530         ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2531     }
2532     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2533     ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2534     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2535     ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2536     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2537     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2538     hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2539     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2540     hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2541     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2542
2543     hr = IDirectDrawSurface_BltFast(surface1, -10, 0, surface2, NULL, 0);
2544     ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2545     hr = IDirectDrawSurface_BltFast(surface1, 0, -10, surface2, NULL, 0);
2546     ok(hr == DDERR_INVALIDRECT, "BltFast with an offset resulting in an off-surface write returned %08x\n", hr);
2547     hr = IDirectDrawSurface_BltFast(surface2, 20, 20, surface1, &valid, 0);
2548     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle and offset returned %08x\n", hr);
2549
2550     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2551     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2552     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2553     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2554     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2555     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2556     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2557     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2558     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2559     ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2560
2561     /* Blt(non-fast) tests */
2562     memset(&BltFx, 0, sizeof(BltFx));
2563     BltFx.dwSize = sizeof(BltFx);
2564     U5(BltFx).dwFillColor = 0xaabbccdd;
2565
2566     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2567     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2568     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2569     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2570     hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2571     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2572     hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2573     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2574     hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2575     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2576     hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2577     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2578
2579     /* Valid on surface 1 */
2580     hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2581     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2582
2583     /* Works - stretched blit */
2584     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2585     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2586     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2587     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2588
2589     /* Invalid dest rects in sourced blits */
2590     hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2591     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2592     hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2593     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2594     hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2595     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2596     hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2597     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2598
2599     /* Invalid src rects */
2600     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2601     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2602     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2603     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2604     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2605     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2606     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2607     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2608
2609     IDirectDrawSurface_Release(surface1);
2610     IDirectDrawSurface_Release(surface2);
2611 }
2612
2613 static void PaletteTest(void)
2614 {
2615     HRESULT hr;
2616     LPDIRECTDRAWSURFACE lpSurf = NULL;
2617     DDSURFACEDESC ddsd;
2618     IDirectDrawPalette *palette = NULL;
2619     PALETTEENTRY Table[256];
2620     PALETTEENTRY palEntries[256];
2621     int i;
2622
2623     for(i=0; i<256; i++)
2624     {
2625         Table[i].peRed   = 0xff;
2626         Table[i].peGreen = 0;
2627         Table[i].peBlue  = 0;
2628         Table[i].peFlags = 0;
2629     }
2630
2631     /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2632     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2633     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2634     if (FAILED(hr)) goto err;
2635     /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2636     /  entry 0 and 255 should have been overwritten with black and white */
2637     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2638     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2639     if(hr == DD_OK)
2640     {
2641         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2642            "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2643            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2644         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2645            "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2646            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2647
2648         /* Entry 1-254 should contain red */
2649         for(i=1; i<255; i++)
2650             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2651                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2652                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2653     }
2654
2655     /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2656     /  now check we are able to update the entries afterwards. */
2657     IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2658     ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2659     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2660     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2661     if(hr == DD_OK)
2662     {
2663         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2664            "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2665            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2666         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2667            "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2668            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2669     }
2670     IDirectDrawPalette_Release(palette);
2671
2672     /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2673     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2674     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2675     if (FAILED(hr)) goto err;
2676
2677     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2678     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2679     if(hr == DD_OK)
2680     {
2681         /* All entries should contain red */
2682         for(i=0; i<256; i++)
2683             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2684                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2685                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2686     }
2687
2688     /* Try to set palette to a non-palettized surface */
2689     ddsd.dwSize = sizeof(ddsd);
2690     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2691     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2692     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2693     ddsd.dwWidth = 800;
2694     ddsd.dwHeight = 600;
2695     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2696     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2697     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2698     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2699     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2700     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2701     ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2702     if (FAILED(hr)) {
2703         skip("failed to create surface\n");
2704         goto err;
2705     }
2706
2707     hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2708     ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2709
2710     IDirectDrawPalette_Release(palette);
2711     palette = NULL;
2712
2713     hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2714     ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2715
2716     err:
2717
2718     if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2719     if (palette) IDirectDrawPalette_Release(palette);
2720 }
2721
2722 static void StructSizeTest(void)
2723 {
2724     IDirectDrawSurface *surface1;
2725     IDirectDrawSurface7 *surface7;
2726     union {
2727         DDSURFACEDESC desc1;
2728         DDSURFACEDESC2 desc2;
2729         char blob[1024]; /* To get a bunch of writable memory */
2730     } desc;
2731     DDSURFACEDESC create;
2732     HRESULT hr;
2733
2734     memset(&desc, 0, sizeof(desc));
2735     memset(&create, 0, sizeof(create));
2736
2737     memset(&create, 0, sizeof(create));
2738     create.dwSize = sizeof(create);
2739     create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2740     create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2741     create.dwHeight = 128;
2742     create.dwWidth = 128;
2743     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2744     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2745     hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2746     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2747
2748     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2749     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2750     ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2751     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2752     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2753
2754     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2755     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2756     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2757     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2758     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2759
2760     desc.desc2.dwSize = 0;
2761     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2762     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2763     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2764     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2765
2766     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2767     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2768     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2769     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2770     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2771
2772     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2773     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2774     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2775     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2776     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2777
2778     /* Tests for Lock() */
2779
2780     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2781     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2782     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2783     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2784     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2785     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2786     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2787     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2788     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2789
2790     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2791     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2792     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2793     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2794     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2795     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2796     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2797     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2798     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2799
2800     desc.desc2.dwSize = 0;
2801     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2802     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2803     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2804     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2805     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2806     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2807
2808     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2809     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2810     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2811     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2812     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2813     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2814     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2815
2816     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2817     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2818     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2819     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2820     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2821     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2822     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2823
2824     IDirectDrawSurface7_Release(surface7);
2825     IDirectDrawSurface_Release(surface1);
2826 }
2827
2828 static void SurfaceCapsTest(void)
2829 {
2830     DDSURFACEDESC create;
2831     DDSURFACEDESC desc;
2832     HRESULT hr;
2833     IDirectDrawSurface *surface1 = NULL;
2834     DDSURFACEDESC2 create2, desc2;
2835     IDirectDrawSurface7 *surface7 = NULL;
2836     IDirectDraw7 *dd7 = NULL;
2837     DWORD create_caps[] = {
2838         DDSCAPS_OFFSCREENPLAIN,
2839         DDSCAPS_TEXTURE,
2840         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD,
2841         0,
2842         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2843         DDSCAPS_PRIMARYSURFACE,
2844         DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY
2845     };
2846     DWORD expected_caps[] = {
2847         DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2848         DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2849         DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_ALLOCONLOAD,
2850         DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM,
2851         DDSCAPS_TEXTURE | DDSCAPS_ALLOCONLOAD | DDSCAPS_SYSTEMMEMORY,
2852         DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_VISIBLE,
2853         DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_VISIBLE
2854     };
2855     UINT i;
2856
2857     /* Tests various surface flags, what changes do they undergo during surface creation. Forsaken
2858      * engine expects texture surfaces without memory flag to get a video memory flag right after
2859      * creation. Currently, Wine adds DDSCAPS_FRONTBUFFER to primary surface, but native doesn't do this
2860      * for single buffered primaries. Because of this primary surface creation tests are todo_wine. No real
2861      * app is known so far to care about this. */
2862
2863     if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
2864     {
2865         skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
2866         return ;
2867     }
2868
2869     for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2870     {
2871         memset(&create, 0, sizeof(create));
2872         create.dwSize = sizeof(create);
2873         create.ddsCaps.dwCaps = create_caps[i];
2874         create.dwFlags = DDSD_CAPS;
2875
2876         if (!(create.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2877         {
2878             create.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2879             create.dwHeight = 128;
2880             create.dwWidth = 128;
2881         }
2882
2883         hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2884         ok(hr == DD_OK, "IDirectDraw_CreateSurface failed with %08x\n", hr);
2885
2886         if (SUCCEEDED(hr))
2887         {
2888             memset(&desc, 0, sizeof(desc));
2889             desc.dwSize = sizeof(DDSURFACEDESC);
2890             hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc);
2891             ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2892
2893             if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2894                 ok(desc.ddsCaps.dwCaps == expected_caps[i],
2895                     "GetSurfaceDesc returned caps %x, expected %x\n", desc.ddsCaps.dwCaps,
2896                     expected_caps[i]);
2897             else
2898                 todo_wine ok(desc.ddsCaps.dwCaps == expected_caps[i],
2899                                 "GetSurfaceDesc returned caps %x, expected %x\n", desc.ddsCaps.dwCaps,
2900                                 expected_caps[i]);
2901
2902             IDirectDrawSurface_Release(surface1);
2903         }
2904     }
2905
2906     /* Test for differences in ddraw 7 */
2907     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
2908     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
2909     if (FAILED(hr))
2910     {
2911         skip("Failed to get IDirectDraw7 interface, skipping tests\n");
2912     }
2913     else
2914     {
2915         for (i = 0; i < sizeof(create_caps) / sizeof(DWORD); i++)
2916         {
2917             memset(&create2, 0, sizeof(create2));
2918             create2.dwSize = sizeof(create2);
2919             create2.ddsCaps.dwCaps = create_caps[i];
2920             create2.dwFlags = DDSD_CAPS;
2921
2922             if (!(create2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE))
2923             {
2924                 create2.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH;
2925                 create2.dwHeight = 128;
2926                 create2.dwWidth = 128;
2927             }
2928
2929             hr = IDirectDraw7_CreateSurface(dd7, &create2, &surface7, NULL);
2930             ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
2931
2932             if (SUCCEEDED(hr))
2933             {
2934                 memset(&desc2, 0, sizeof(desc2));
2935                 desc2.dwSize = sizeof(DDSURFACEDESC2);
2936                 hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc2);
2937                 ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc failed with %08x\n", hr);
2938
2939                 if (!(create_caps[i] & DDSCAPS_PRIMARYSURFACE))
2940                     ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2941                         "GetSurfaceDesc returned caps %x, expected %x\n", desc2.ddsCaps.dwCaps,
2942                         expected_caps[i]);
2943                 else
2944                     todo_wine ok(desc2.ddsCaps.dwCaps == expected_caps[i],
2945                                     "GetSurfaceDesc returned caps %x, expected %x\n", desc2.ddsCaps.dwCaps,
2946                                     expected_caps[i]);
2947
2948                 IDirectDrawSurface7_Release(surface7);
2949             }
2950         }
2951
2952         IDirectDraw7_Release(dd7);
2953     }
2954
2955     memset(&create, 0, sizeof(create));
2956     create.dwSize = sizeof(create);
2957     create.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
2958     create.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
2959     create.dwWidth = 64;
2960     create.dwHeight = 64;
2961     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2962     ok(hr == DDERR_INVALIDCAPS, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DDERR_INVALIDCAPS\n", hr);
2963     if(surface1) IDirectDrawSurface_Release(surface1);
2964 }
2965
2966 static BOOL can_create_primary_surface(void)
2967 {
2968     DDSURFACEDESC ddsd;
2969     IDirectDrawSurface *surface;
2970     HRESULT hr;
2971
2972     memset(&ddsd, 0, sizeof(ddsd));
2973     ddsd.dwSize = sizeof(ddsd);
2974     ddsd.dwFlags = DDSD_CAPS;
2975     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2976     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
2977     if(FAILED(hr)) return FALSE;
2978     IDirectDrawSurface_Release(surface);
2979     return TRUE;
2980 }
2981
2982 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
2983     HRESULT hr;
2984     HDC dc, dc2 = (HDC) 0x1234;
2985     DDSURFACEDESC ddsd;
2986     DDSURFACEDESC2 ddsd2;
2987
2988     memset(&ddsd, 0, sizeof(ddsd));
2989     ddsd.dwSize = sizeof(ddsd);
2990     memset(&ddsd2, 0, sizeof(ddsd2));
2991     ddsd2.dwSize = sizeof(ddsd2);
2992
2993     hr = IDirectDrawSurface_GetDC(surf, &dc);
2994     ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2995
2996     hr = IDirectDrawSurface_GetDC(surf, &dc2);
2997     ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
2998     ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
2999
3000     hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
3001     ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_ALREADYLOCKED\n", hr);
3002
3003     hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3004     ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
3005     hr = IDirectDrawSurface_ReleaseDC(surf, dc);
3006     ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
3007 }
3008
3009 static void GetDCTest(void)
3010 {
3011     DDSURFACEDESC ddsd;
3012     DDSURFACEDESC2 ddsd2;
3013     IDirectDrawSurface *surf;
3014     IDirectDrawSurface2 *surf2;
3015     IDirectDrawSurface4 *surf4;
3016     IDirectDrawSurface7 *surf7;
3017     IDirectDrawSurface *tmp;
3018     IDirectDrawSurface7 *tmp7;
3019     HRESULT hr;
3020     IDirectDraw2 *dd2;
3021     IDirectDraw4 *dd4;
3022     IDirectDraw7 *dd7;
3023     HDC dc;
3024
3025     memset(&ddsd, 0, sizeof(ddsd));
3026     ddsd.dwSize = sizeof(ddsd);
3027     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3028     ddsd.dwWidth = 64;
3029     ddsd.dwHeight = 64;
3030     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3031     memset(&ddsd2, 0, sizeof(ddsd2));
3032     ddsd2.dwSize = sizeof(ddsd2);
3033     ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3034     ddsd2.dwWidth = 64;
3035     ddsd2.dwHeight = 64;
3036     ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3037
3038     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3039     ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3040     dctest_surf(surf, 1);
3041     IDirectDrawSurface_Release(surf);
3042
3043     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3044     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3045
3046     hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3047     ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3048     dctest_surf(surf, 1);
3049
3050     hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
3051     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
3052     dctest_surf((IDirectDrawSurface *) surf2, 1);
3053
3054     IDirectDrawSurface2_Release(surf2);
3055     IDirectDrawSurface_Release(surf);
3056     IDirectDraw2_Release(dd2);
3057
3058     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3059     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3060
3061     surf = NULL;
3062     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3063     ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3064     dctest_surf((IDirectDrawSurface *) surf4, 2);
3065
3066     hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf);
3067     ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
3068
3069     hr = IDirectDrawSurface4_GetDC(surf4, &dc);
3070     ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3071
3072     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
3073     ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3074
3075     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3076     ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3077     ok(tmp == surf, "Expected surface %p, got %p.\n\n", surf, tmp);
3078
3079     hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
3080     ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3081
3082     dc = CreateCompatibleDC(NULL);
3083     ok(!!dc, "CreateCompatibleDC failed.\n");
3084
3085     tmp = (IDirectDrawSurface *)0xdeadbeef;
3086     hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
3087     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3088     ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3089
3090     ok(DeleteDC(dc), "DeleteDC failed.\n");
3091
3092     tmp = (IDirectDrawSurface *)0xdeadbeef;
3093     hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
3094     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3095     ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
3096
3097     IDirectDrawSurface4_Release(surf4);
3098     IDirectDraw4_Release(dd4);
3099
3100     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3101     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3102     surf = NULL;
3103     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3104     ok(hr == DD_OK, "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3105     dctest_surf((IDirectDrawSurface *) surf7, 2);
3106
3107     hr = IDirectDrawSurface7_GetDC(surf7, &dc);
3108     ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
3109
3110     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, NULL);
3111     ok(hr == E_INVALIDARG, "Expected hr E_INVALIDARG, got %#x.\n", hr);
3112
3113     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3114     ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
3115     ok(tmp7 == surf7, "Expected surface %p, got %p.\n\n", surf7, tmp7);
3116     IDirectDrawSurface7_Release(tmp7);
3117
3118     hr = IDirectDrawSurface7_ReleaseDC(surf7, dc);
3119     ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
3120
3121     dc = CreateCompatibleDC(NULL);
3122     ok(!!dc, "CreateCompatibleDC failed.\n");
3123
3124     tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3125     hr = IDirectDraw7_GetSurfaceFromDC(dd7, dc, &tmp7);
3126     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3127     ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3128
3129     ok(DeleteDC(dc), "DeleteDC failed.\n");
3130
3131     tmp7 = (IDirectDrawSurface7 *)0xdeadbeef;
3132     hr = IDirectDraw7_GetSurfaceFromDC(dd7, NULL, (IDirectDrawSurface7 **)&tmp7);
3133     ok(hr == DDERR_NOTFOUND, "GetSurfaceFromDC failed, hr %#x.\n", hr);
3134     ok(!tmp7, "Expected surface NULL, got %p.\n", tmp7);
3135
3136     IDirectDrawSurface7_Release(surf7);
3137     IDirectDraw7_Release(dd7);
3138 }
3139
3140 static void GetDCFormatTest(void)
3141 {
3142     DDSURFACEDESC2 ddsd;
3143     unsigned int i;
3144     IDirectDrawSurface7 *surface;
3145     IDirectDraw7 *dd7;
3146     HRESULT hr;
3147     HDC dc;
3148
3149     struct
3150     {
3151         const char *name;
3152         DDPIXELFORMAT fmt;
3153         BOOL getdc_capable;
3154         HRESULT alt_result;
3155     } testdata[] = {
3156         {
3157             "D3DFMT_A8R8G8B8",
3158             {
3159                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3160                 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0xff000000}
3161             },
3162             TRUE
3163         },
3164         {
3165             "D3DFMT_X8R8G8B8",
3166             {
3167                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3168                 {32}, {0x00ff0000}, {0x0000ff00}, {0x000000ff}, {0x00000000}
3169             },
3170             TRUE
3171         },
3172         {
3173             "D3DFMT_X8B8G8R8",
3174             {
3175                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3176                 {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0x00000000}
3177             },
3178             TRUE,
3179             DDERR_CANTCREATEDC /* Vista+ */
3180         },
3181         {
3182             "D3DFMT_X8B8G8R8",
3183             {
3184                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3185                        {32}, {0x000000ff}, {0x0000ff00}, {0x00ff0000}, {0xff000000}
3186             },
3187             TRUE,
3188             DDERR_CANTCREATEDC /* Vista+ */
3189         },
3190         {
3191             "D3DFMT_A4R4G4B4",
3192             {
3193                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3194                        {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x0000f000}
3195             },
3196             TRUE,
3197             DDERR_CANTCREATEDC /* Vista+ */
3198         },
3199         {
3200             "D3DFMT_X4R4G4B4",
3201             {
3202                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3203                        {16}, {0x00000f00}, {0x000000f0}, {0x0000000f}, {0x00000000}
3204             },
3205             TRUE,
3206             DDERR_CANTCREATEDC /* Vista+ */
3207         },
3208         {
3209             "D3DFMT_R5G6B5",
3210             {
3211                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3212                        {16}, {0x0000F800}, {0x000007E0}, {0x0000001F}, {0x00000000}
3213             },
3214             TRUE
3215         },
3216         {
3217             "D3DFMT_A1R5G5B5",
3218             {
3219                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3220                        {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00008000}
3221             },
3222             TRUE
3223         },
3224         {
3225             "D3DFMT_X1R5G5B5",
3226             {
3227                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3228                        {16}, {0x00007C00}, {0x000003E0}, {0x0000001F}, {0x00000000}
3229             },
3230             TRUE
3231         },
3232         {
3233             "D3DFMT_R3G3B2",
3234             {
3235                 sizeof(DDPIXELFORMAT), DDPF_RGB, 0,
3236                        { 8}, {0x000000E0}, {0x0000001C}, {0x00000003}, {0x00000000}
3237             },
3238             FALSE
3239         },
3240         {
3241             /* Untested, windows test machine didn't support this format */
3242             "D3DFMT_A2R10G10B10",
3243             {
3244                 sizeof(DDPIXELFORMAT), DDPF_RGB | DDPF_ALPHAPIXELS, 0,
3245                        {32}, {0xC0000000}, {0x3FF00000}, {0x000FFC00}, {0x000003FF}
3246             },
3247             TRUE
3248         },
3249         /*
3250          * GetDC on a P8 surface fails unless the display mode is 8 bpp. This is not
3251          * implemented in wine yet, so disable the test for now. Succeeding P8 getDC
3252          * calls are tested in the ddraw.visual test.
3253          *
3254         {
3255             "D3DFMT_P8",
3256             {
3257                 sizeof(DDPIXELFORMAT), DDPF_PALETTEINDEXED8 | DDPF_RGB, 0,
3258                 {8 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3259             },
3260             FALSE
3261         },
3262          */
3263         {
3264             "D3DFMT_L8",
3265             {
3266                 sizeof(DDPIXELFORMAT), DDPF_LUMINANCE, 0,
3267                 {8 }, {0x000000ff}, {0x00000000}, {0x00000000}, {0x00000000}
3268             },
3269             FALSE
3270         },
3271         {
3272             "D3DFMT_A8L8",
3273             {
3274                 sizeof(DDPIXELFORMAT), DDPF_ALPHAPIXELS | DDPF_LUMINANCE, 0,
3275                 {16}, {0x000000ff}, {0x00000000}, {0x00000000}, {0x0000ff00}
3276             },
3277             FALSE
3278         },
3279         {
3280             "D3DFMT_DXT1",
3281             {
3282                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','1'),
3283                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3284             },
3285             FALSE
3286         },
3287         {
3288             "D3DFMT_DXT2",
3289             {
3290                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','2'),
3291                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3292             },
3293             FALSE
3294         },
3295         {
3296             "D3DFMT_DXT3",
3297             {
3298                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','3'),
3299                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3300             },
3301             FALSE
3302         },
3303         {
3304             "D3DFMT_DXT4",
3305             {
3306                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','4'),
3307                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3308             },
3309             FALSE
3310         },
3311         {
3312             "D3DFMT_DXT5",
3313             {
3314                 sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('D','X','T','5'),
3315                 {0 }, {0x00000000}, {0x00000000}, {0x00000000}, {0x00000000}
3316             },
3317             FALSE
3318         },
3319     };
3320
3321     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3322     ok(hr == DD_OK, "IDirectDraw_QueryInterface failed, hr = 0x%08x\n", hr);
3323
3324     for(i = 0; i < (sizeof(testdata) / sizeof(testdata[0])); i++)
3325     {
3326         memset(&ddsd, 0, sizeof(ddsd));
3327         ddsd.dwSize = sizeof(ddsd);
3328         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
3329         ddsd.dwWidth = 64;
3330         ddsd.dwHeight = 64;
3331         U4(ddsd).ddpfPixelFormat = testdata[i].fmt;
3332         ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3333
3334         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3335         if(FAILED(hr))
3336         {
3337             ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
3338             ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
3339             hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
3340             if(FAILED(hr))
3341             {
3342                 skip("IDirectDraw7_CreateSurface failed, hr = 0x%08x, format %s\n", hr, testdata[i].name);
3343                 continue;
3344             }
3345         }
3346
3347         dc = (void *) 0x1234;
3348         hr = IDirectDrawSurface7_GetDC(surface, &dc);
3349         if(testdata[i].getdc_capable)
3350         {
3351             ok(SUCCEEDED(hr) ||
3352                (testdata[i].alt_result && hr == testdata[i].alt_result),
3353                "GetDC on a %s surface failed(0x%08x), expected it to work\n",
3354                testdata[i].name, hr);
3355         }
3356         else
3357         {
3358             ok(FAILED(hr), "GetDC on a %s surface succeeded(0x%08x), expected it to fail\n",
3359                testdata[i].name, hr);
3360         }
3361
3362         if(SUCCEEDED(hr))
3363         {
3364             IDirectDrawSurface7_ReleaseDC(surface, dc);
3365             ok(hr == DD_OK, "IDirectDrawSurface7_ReleaseDC failed, hr = 0x%08x\n", hr);
3366             dc = 0;
3367         }
3368         else
3369         {
3370             ok(dc == NULL, "After failed GetDC dc is %p\n", dc);
3371         }
3372
3373         IDirectDrawSurface7_Release(surface);
3374     }
3375
3376     IDirectDraw7_Release(dd7);
3377 }
3378
3379 static void BackBufferCreateSurfaceTest(void)
3380 {
3381     DDSURFACEDESC ddsd;
3382     DDSURFACEDESC created_ddsd;
3383     DDSURFACEDESC2 ddsd2;
3384     IDirectDrawSurface *surf;
3385     IDirectDrawSurface4 *surf4;
3386     IDirectDrawSurface7 *surf7;
3387     HRESULT hr;
3388     IDirectDraw2 *dd2;
3389     IDirectDraw4 *dd4;
3390     IDirectDraw7 *dd7;
3391
3392     const DWORD caps = DDSCAPS_BACKBUFFER;
3393     const DWORD expected_caps = DDSCAPS_BACKBUFFER | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
3394
3395     if (!(ddcaps.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
3396     {
3397         skip("DDraw reported no VIDEOMEMORY cap. Broken video driver? Skipping surface caps tests.\n");
3398         return ;
3399     }
3400
3401     memset(&ddsd, 0, sizeof(ddsd));
3402     ddsd.dwSize = sizeof(ddsd);
3403     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3404     ddsd.dwWidth = 64;
3405     ddsd.dwHeight = 64;
3406     ddsd.ddsCaps.dwCaps = caps;
3407     memset(&ddsd2, 0, sizeof(ddsd2));
3408     ddsd2.dwSize = sizeof(ddsd2);
3409     ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3410     ddsd2.dwWidth = 64;
3411     ddsd2.dwHeight = 64;
3412     ddsd2.ddsCaps.dwCaps = caps;
3413     memset(&created_ddsd, 0, sizeof(created_ddsd));
3414     created_ddsd.dwSize = sizeof(DDSURFACEDESC);
3415
3416     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surf, NULL);
3417     todo_wine ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3418     if (surf != NULL)
3419     {
3420         hr = IDirectDrawSurface_GetSurfaceDesc(surf, &created_ddsd);
3421         ok(SUCCEEDED(hr), "IDirectDraw_GetSurfaceDesc failed: 0x%08x\n", hr);
3422         ok(created_ddsd.ddsCaps.dwCaps == expected_caps,
3423            "GetSurfaceDesc returned caps %x, expected %x\n", created_ddsd.ddsCaps.dwCaps,
3424            expected_caps);
3425         IDirectDrawSurface_Release(surf);
3426     }
3427
3428     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3429     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3430
3431     hr = IDirectDraw2_CreateSurface(dd2, &ddsd, &surf, NULL);
3432     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw2_CreateSurface didn't return %x08x, but %x08x\n",
3433        DDERR_INVALIDCAPS, hr);
3434
3435     IDirectDraw2_Release(dd2);
3436
3437     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3438     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3439
3440     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
3441     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw4_CreateSurface didn't return %x08x, but %x08x\n",
3442        DDERR_INVALIDCAPS, hr);
3443
3444     IDirectDraw4_Release(dd4);
3445
3446     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3447     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3448
3449     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2, &surf7, NULL);
3450     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7_CreateSurface didn't return %x08x, but %x08x\n",
3451        DDERR_INVALIDCAPS, hr);
3452
3453     IDirectDraw7_Release(dd7);
3454 }
3455
3456 static void BackBufferAttachmentFlipTest(void)
3457 {
3458     HRESULT hr;
3459     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
3460     DDSURFACEDESC ddsd;
3461     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
3462
3463     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
3464     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3465
3466     /* Perform attachment tests on a back-buffer */
3467     memset(&ddsd, 0, sizeof(ddsd));
3468     ddsd.dwSize = sizeof(ddsd);
3469     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3470     ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3471     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3472     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3473     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
3474     todo_wine ok(SUCCEEDED(hr), "CreateSurface returned: %x\n",hr);
3475
3476     if (surface2 != NULL)
3477     {
3478         /* Try a single primary and a two back buffers */
3479         memset(&ddsd, 0, sizeof(ddsd));
3480         ddsd.dwSize = sizeof(ddsd);
3481         ddsd.dwFlags = DDSD_CAPS;
3482         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
3483         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
3484         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3485
3486         memset(&ddsd, 0, sizeof(ddsd));
3487         ddsd.dwSize = sizeof(ddsd);
3488         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3489         ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3490         ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
3491         ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
3492         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
3493         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3494
3495         /* This one has a different size */
3496         memset(&ddsd, 0, sizeof(ddsd));
3497         ddsd.dwSize = sizeof(ddsd);
3498         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3499         ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
3500         ddsd.dwWidth = 128;
3501         ddsd.dwHeight = 128;
3502         hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
3503         ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
3504
3505         hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
3506         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3507            "Attaching a back buffer to a front buffer returned %08x\n", hr);
3508         if(SUCCEEDED(hr))
3509         {
3510             /* Try flipping the surfaces */
3511             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3512             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3513             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3514             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3515
3516             /* Try the reverse without detaching first */
3517             hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3518             ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
3519             hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3520             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3521         }
3522         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
3523         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3524            "Attaching a front buffer to a back buffer returned %08x\n", hr);
3525         if(SUCCEEDED(hr))
3526         {
3527             /* Try flipping the surfaces */
3528             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3529             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3530             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3531             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3532
3533             /* Try to detach reversed */
3534             hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
3535             ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
3536             /* Now the proper detach */
3537             hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
3538             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3539         }
3540         hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3);
3541         todo_wine ok(hr == DD_OK || broken(hr == DDERR_CANNOTATTACHSURFACE),
3542            "Attaching a back buffer to another back buffer returned %08x\n", hr);
3543         if(SUCCEEDED(hr))
3544         {
3545             /* Try flipping the surfaces */
3546             hr = IDirectDrawSurface_Flip(surface3, NULL, DDFLIP_WAIT);
3547             todo_wine ok(hr == DD_OK, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3548             hr = IDirectDrawSurface_Flip(surface2, NULL, DDFLIP_WAIT);
3549             todo_wine ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3550             hr = IDirectDrawSurface_Flip(surface1, NULL, DDFLIP_WAIT);
3551             ok(hr == DDERR_NOTFLIPPABLE, "IDirectDrawSurface_Flip returned 0x%08x\n", hr);
3552
3553             hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
3554             ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
3555         }
3556         hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
3557         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a back buffer to a front buffer of different size returned %08x\n", hr);
3558         hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
3559         ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to a back buffer of different size returned %08x\n", hr);
3560
3561         IDirectDrawSurface_Release(surface4);
3562         IDirectDrawSurface_Release(surface3);
3563         IDirectDrawSurface_Release(surface2);
3564         IDirectDrawSurface_Release(surface1);
3565     }
3566
3567     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
3568     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
3569
3570     DestroyWindow(window);
3571 }
3572
3573 static void CreateSurfaceBadCapsSizeTest(void)
3574 {
3575     DDSURFACEDESC ddsd_ok;
3576     DDSURFACEDESC ddsd_bad1;
3577     DDSURFACEDESC ddsd_bad2;
3578     DDSURFACEDESC ddsd_bad3;
3579     DDSURFACEDESC ddsd_bad4;
3580     DDSURFACEDESC2 ddsd2_ok;
3581     DDSURFACEDESC2 ddsd2_bad1;
3582     DDSURFACEDESC2 ddsd2_bad2;
3583     DDSURFACEDESC2 ddsd2_bad3;
3584     DDSURFACEDESC2 ddsd2_bad4;
3585     IDirectDrawSurface *surf;
3586     IDirectDrawSurface4 *surf4;
3587     IDirectDrawSurface7 *surf7;
3588     HRESULT hr;
3589     IDirectDraw2 *dd2;
3590     IDirectDraw4 *dd4;
3591     IDirectDraw7 *dd7;
3592
3593     const DWORD caps = DDSCAPS_OFFSCREENPLAIN;
3594
3595     memset(&ddsd_ok, 0, sizeof(ddsd_ok));
3596     ddsd_ok.dwSize = sizeof(ddsd_ok);
3597     ddsd_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3598     ddsd_ok.dwWidth = 64;
3599     ddsd_ok.dwHeight = 64;
3600     ddsd_ok.ddsCaps.dwCaps = caps;
3601     memcpy(&ddsd_bad1, &ddsd_ok, sizeof(ddsd_bad1));
3602     ddsd_bad1.dwSize--;
3603     memcpy(&ddsd_bad2, &ddsd_ok, sizeof(ddsd_bad2));
3604     ddsd_bad2.dwSize++;
3605     memcpy(&ddsd_bad3, &ddsd_ok, sizeof(ddsd_bad3));
3606     ddsd_bad3.dwSize = 0;
3607     memcpy(&ddsd_bad4, &ddsd_ok, sizeof(ddsd_bad4));
3608     ddsd_bad4.dwSize = sizeof(DDSURFACEDESC2);
3609
3610     memset(&ddsd2_ok, 0, sizeof(ddsd2_ok));
3611     ddsd2_ok.dwSize = sizeof(ddsd2_ok);
3612     ddsd2_ok.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
3613     ddsd2_ok.dwWidth = 64;
3614     ddsd2_ok.dwHeight = 64;
3615     ddsd2_ok.ddsCaps.dwCaps = caps;
3616     memcpy(&ddsd2_bad1, &ddsd2_ok, sizeof(ddsd2_bad1));
3617     ddsd2_bad1.dwSize--;
3618     memcpy(&ddsd2_bad2, &ddsd2_ok, sizeof(ddsd2_bad2));
3619     ddsd2_bad2.dwSize++;
3620     memcpy(&ddsd2_bad3, &ddsd2_ok, sizeof(ddsd2_bad3));
3621     ddsd2_bad3.dwSize = 0;
3622     memcpy(&ddsd2_bad4, &ddsd2_ok, sizeof(ddsd2_bad4));
3623     ddsd2_bad4.dwSize = sizeof(DDSURFACEDESC);
3624
3625     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_ok, &surf, NULL);
3626     ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
3627     IDirectDrawSurface_Release(surf);
3628
3629     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad1, &surf, NULL);
3630     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3631        DDERR_INVALIDPARAMS, hr);
3632     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad2, &surf, NULL);
3633     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3634        DDERR_INVALIDPARAMS, hr);
3635     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad3, &surf, NULL);
3636     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3637        DDERR_INVALIDPARAMS, hr);
3638     hr = IDirectDraw_CreateSurface(lpDD, &ddsd_bad4, &surf, NULL);
3639     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3640        DDERR_INVALIDPARAMS, hr);
3641
3642     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
3643     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3644
3645     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_ok, &surf, NULL);
3646     ok(SUCCEEDED(hr), "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
3647     IDirectDrawSurface_Release(surf);
3648
3649     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad1, &surf, NULL);
3650     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3651        DDERR_INVALIDPARAMS, hr);
3652     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad2, &surf, NULL);
3653     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3654        DDERR_INVALIDPARAMS, hr);
3655     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad3, &surf, NULL);
3656     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3657        DDERR_INVALIDPARAMS, hr);
3658     hr = IDirectDraw2_CreateSurface(dd2, &ddsd_bad4, &surf, NULL);
3659     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw2_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3660        DDERR_INVALIDPARAMS, hr);
3661
3662     IDirectDraw2_Release(dd2);
3663
3664     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3665     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3666
3667     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_ok, &surf4, NULL);
3668     ok(SUCCEEDED(hr), "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
3669     IDirectDrawSurface4_Release(surf4);
3670
3671     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad1, &surf4, NULL);
3672     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3673        DDERR_INVALIDPARAMS, hr);
3674     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad2, &surf4, NULL);
3675     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3676        DDERR_INVALIDPARAMS, hr);
3677     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad3, &surf4, NULL);
3678     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3679        DDERR_INVALIDPARAMS, hr);
3680     hr = IDirectDraw4_CreateSurface(dd4, &ddsd2_bad4, &surf4, NULL);
3681     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw4_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3682        DDERR_INVALIDPARAMS, hr);
3683
3684     IDirectDraw4_Release(dd4);
3685
3686     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
3687     ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
3688
3689     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_ok, &surf7, NULL);
3690     ok(SUCCEEDED(hr), "IDirectDraw7_CreateSurface failed: 0x%08x\n", hr);
3691     IDirectDrawSurface7_Release(surf7);
3692
3693     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad1, &surf7, NULL);
3694     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3695        DDERR_INVALIDPARAMS, hr);
3696     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad2, &surf7, NULL);
3697     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3698        DDERR_INVALIDPARAMS, hr);
3699     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad3, &surf7, NULL);
3700     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3701        DDERR_INVALIDPARAMS, hr);
3702     hr = IDirectDraw7_CreateSurface(dd7, &ddsd2_bad4, &surf7, NULL);
3703     todo_wine ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7_CreateSurface didn't return 0x%08x, but 0x%08x\n",
3704        DDERR_INVALIDPARAMS, hr);
3705
3706     IDirectDraw7_Release(dd7);
3707 }
3708
3709 START_TEST(dsurface)
3710 {
3711     HRESULT ret;
3712     IDirectDraw4 *dd4;
3713
3714     if (!CreateDirectDraw())
3715         return;
3716
3717     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
3718     if (ret == E_NOINTERFACE)
3719     {
3720         win_skip("DirectDraw4 and higher are not supported\n");
3721         ReleaseDirectDraw();
3722         return;
3723     }
3724     IDirectDraw_Release(dd4);
3725
3726     if(!can_create_primary_surface())
3727     {
3728         skip("Unable to create primary surface\n");
3729         return;
3730     }
3731
3732     ddcaps.dwSize = sizeof(DDCAPS);
3733     ret = IDirectDraw_GetCaps(lpDD, &ddcaps, NULL);
3734     if (ret != DD_OK)
3735     {
3736         skip("IDirectDraw_GetCaps failed with %08x\n", ret);
3737         return;
3738     }
3739
3740     MipMapCreationTest();
3741     SrcColorKey32BlitTest();
3742     QueryInterface();
3743     GetDDInterface_1();
3744     GetDDInterface_2();
3745     GetDDInterface_4();
3746     GetDDInterface_7();
3747     IFaceRefCount();
3748     EnumTest();
3749     AttachmentTest();
3750     AttachmentTest7();
3751     CubeMapTest();
3752     test_lockrect_invalid();
3753     CompressedTest();
3754     SizeTest();
3755     PrivateDataTest();
3756     BltParamTest();
3757     StructSizeTest();
3758     PaletteTest();
3759     SurfaceCapsTest();
3760     GetDCTest();
3761     GetDCFormatTest();
3762     BackBufferCreateSurfaceTest();
3763     BackBufferAttachmentFlipTest();
3764     CreateSurfaceBadCapsSizeTest();
3765     ReleaseDirectDraw();
3766 }