winex11: add owned windows to taskbar if owner is not mapped
[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  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 #define COBJMACROS
24
25 #include <assert.h>
26 #include "wine/test.h"
27 #include "ddraw.h"
28 #include "unknwn.h"
29
30 static LPDIRECTDRAW lpDD = NULL;
31
32 static BOOL CreateDirectDraw(void)
33 {
34     HRESULT rc;
35
36     rc = DirectDrawCreate(NULL, &lpDD, NULL);
37     ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %x\n", rc);
38     if (!lpDD) {
39         trace("DirectDrawCreateEx() failed with an error %x\n", rc);
40         return FALSE;
41     }
42
43     rc = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
44     ok(rc==DD_OK,"SetCooperativeLevel returned: %x\n",rc);
45
46     return TRUE;
47 }
48
49
50 static void ReleaseDirectDraw(void)
51 {
52     if( lpDD != NULL )
53     {
54         IDirectDraw_Release(lpDD);
55         lpDD = NULL;
56     }
57 }
58
59 static void MipMapCreationTest(void)
60 {
61     LPDIRECTDRAWSURFACE lpDDSMipMapTest;
62     DDSURFACEDESC ddsd;
63     HRESULT rc;
64
65     /* First mipmap creation test: create a surface with DDSCAPS_COMPLEX,
66        DDSCAPS_MIPMAP, and DDSD_MIPMAPCOUNT. This create the number of
67         requested mipmap levels. */
68     ddsd.dwSize = sizeof(ddsd);
69     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
70     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
71     U2(ddsd).dwMipMapCount = 3;
72     ddsd.dwWidth = 128;
73     ddsd.dwHeight = 32;
74     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
75     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
76     if (FAILED(rc)) {
77         skip("failed to create surface\n");
78         return;
79     }
80
81     /* Check the number of created mipmaps */
82     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
83     ddsd.dwSize = sizeof(ddsd);
84     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
85     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
86     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
87         "GetSurfaceDesc returned no mipmapcount.\n");
88     ok(U2(ddsd).dwMipMapCount == 3, "Incorrect mipmap count: %d.\n",
89         U2(ddsd).dwMipMapCount);
90
91     /* Destroy the surface. */
92     IDirectDrawSurface_Release(lpDDSMipMapTest);
93
94
95     /* Second mipmap creation test: create a surface without a mipmap
96        count, with DDSCAPS_MIPMAP and without DDSCAPS_COMPLEX.
97        This creates a single mipmap level. */
98     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
99     ddsd.dwSize = sizeof(ddsd);
100     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
101     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
102     ddsd.dwWidth = 128;
103     ddsd.dwHeight = 32;
104     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
105     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
106     if (FAILED(rc)) {
107         skip("failed to create surface\n");
108         return;
109     }
110     /* Check the number of created mipmaps */
111     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
112     ddsd.dwSize = sizeof(ddsd);
113     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
114     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
115     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
116         "GetSurfaceDesc returned no mipmapcount.\n");
117     ok(U2(ddsd).dwMipMapCount == 1, "Incorrect mipmap count: %d.\n",
118         U2(ddsd).dwMipMapCount);
119
120     /* Destroy the surface. */
121     IDirectDrawSurface_Release(lpDDSMipMapTest);
122
123
124     /* Third mipmap creation test: create a surface with DDSCAPS_MIPMAP,
125         DDSCAPS_COMPLEX and without DDSD_MIPMAPCOUNT.
126        It's an undocumented features where a chain of mipmaps, starting from
127        he specified size and down to the smallest size, is automatically
128        created.
129        Anarchy Online needs this feature to work. */
130     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
131     ddsd.dwSize = sizeof(ddsd);
132     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
133     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
134     ddsd.dwWidth = 128;
135     ddsd.dwHeight = 32;
136     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
137     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
138     if (FAILED(rc)) {
139         skip("failed to create surface\n");
140         return;
141     }
142
143     /* Check the number of created mipmaps */
144     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
145     ddsd.dwSize = sizeof(ddsd);
146     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
147     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
148     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
149         "GetSurfaceDesc returned no mipmapcount.\n");
150     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
151         U2(ddsd).dwMipMapCount);
152
153     /* Destroy the surface. */
154     IDirectDrawSurface_Release(lpDDSMipMapTest);
155
156
157     /* Fourth mipmap creation test: same as above with a different texture
158        size.
159        The purpose is to verify that the number of generated mipmaps is
160        dependent on the smallest dimension. */
161     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
162     ddsd.dwSize = sizeof(ddsd);
163     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
164     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
165     ddsd.dwWidth = 32;
166     ddsd.dwHeight = 64;
167     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
168     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
169     if (FAILED(rc)) {
170         skip("failed to create surface\n");
171         return;
172     }
173
174     /* Check the number of created mipmaps */
175     memset(&ddsd, 0, sizeof(DDSURFACEDESC));
176     ddsd.dwSize = sizeof(ddsd);
177     rc = IDirectDrawSurface_GetSurfaceDesc(lpDDSMipMapTest, &ddsd);
178     ok(rc==DD_OK,"GetSurfaceDesc returned: %x\n",rc);
179     ok(ddsd.dwFlags & DDSD_MIPMAPCOUNT,
180         "GetSurfaceDesc returned no mipmapcount.\n");
181     ok(U2(ddsd).dwMipMapCount == 6, "Incorrect mipmap count: %d.\n",
182         U2(ddsd).dwMipMapCount);
183
184     /* Destroy the surface. */
185     IDirectDrawSurface_Release(lpDDSMipMapTest);
186
187
188     /* Fifth mipmap creation test: try to create a surface with
189        DDSCAPS_COMPLEX, DDSCAPS_MIPMAP, DDSD_MIPMAPCOUNT,
190        where dwMipMapCount = 0. This should fail. */
191
192     ddsd.dwSize = sizeof(ddsd);
193     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
194     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
195     U2(ddsd).dwMipMapCount = 0;
196     ddsd.dwWidth = 128;
197     ddsd.dwHeight = 32;
198     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSMipMapTest, NULL);
199     ok(rc==DDERR_INVALIDPARAMS,"CreateSurface returned: %x\n",rc);
200
201     /* Destroy the surface. */
202     if( rc == DD_OK )
203         IDirectDrawSurface_Release(lpDDSMipMapTest);
204
205 }
206
207 static void SrcColorKey32BlitTest(void)
208 {
209     LPDIRECTDRAWSURFACE lpSrc;
210     LPDIRECTDRAWSURFACE lpDst;
211     DDSURFACEDESC ddsd, ddsd2, ddsd3;
212     DDCOLORKEY DDColorKey;
213     LPDWORD lpData;
214     HRESULT rc;
215     DDBLTFX fx;
216
217     ddsd2.dwSize = sizeof(ddsd2);
218     ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
219
220     ddsd.dwSize = sizeof(ddsd);
221     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
222     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
223     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
224     ddsd.dwWidth = 800;
225     ddsd.dwHeight = 600;
226     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
227     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
228     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
229     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
230     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
231     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
232     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
233     if (FAILED(rc)) {
234         skip("failed to create surface\n");
235         return;
236     }
237
238     ddsd.dwFlags |= DDSD_CKSRCBLT;
239     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
240     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
241     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
242     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
243     if (FAILED(rc)) {
244         skip("failed to create surface\n");
245         return;
246     }
247
248     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
249     ok(rc==DD_OK,"Lock returned: %x\n",rc);
250     lpData = (LPDWORD)ddsd2.lpSurface;
251     lpData[0] = 0xCCCCCCCC;
252     lpData[1] = 0xCCCCCCCC;
253     lpData[2] = 0xCCCCCCCC;
254     lpData[3] = 0xCCCCCCCC;
255
256     memset(&ddsd3, 0, sizeof(ddsd3));
257     ddsd3.dwSize = sizeof(ddsd3);
258     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
259     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
260     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
261     ok(ddsd3.lpSurface == ddsd3.lpSurface, "lpSurface from GetSurfaceDesc(%p) differs from the one returned by Lock(%p)\n", ddsd3.lpSurface, ddsd2.lpSurface);
262
263     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
264     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
265
266     memset(&ddsd3, 0, sizeof(ddsd3));
267     ddsd3.dwSize = sizeof(ddsd3);
268     ddsd3.ddpfPixelFormat.dwSize = sizeof(ddsd3.ddpfPixelFormat);
269     rc = IDirectDrawSurface_GetSurfaceDesc(lpDst, &ddsd3);
270     ok(rc == DD_OK, "IDirectDrawSurface_GetSurfaceDesc between a lock/unlock pair returned %08x\n", rc);
271     ok(ddsd3.lpSurface == NULL, "lpSurface from GetSurfaceDesc(%p) is not NULL after unlock\n", ddsd3.lpSurface);
272
273     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
274     ok(rc==DD_OK,"Lock returned: %x\n",rc);
275     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
276     lpData = (LPDWORD)ddsd2.lpSurface;
277     lpData[0] = 0x77010203;
278     lpData[1] = 0x00010203;
279     lpData[2] = 0x77FF00FF;
280     lpData[3] = 0x00FF00FF;
281     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
282     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
283
284     IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
285
286     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
287     ok(rc==DD_OK,"Lock returned: %x\n",rc);
288     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
289     lpData = (LPDWORD)ddsd2.lpSurface;
290     /* Different behavior on some drivers / windows versions. Some versions ignore the X channel when
291      * color keying, but copy it to the destination surface. Others apply it for color keying, but
292      * do not copy it into the destination surface.
293      */
294     if(lpData[0]==0x00010203) {
295         trace("X channel was not copied into the destination surface\n");
296         ok((lpData[0]==0x00010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0x00FF00FF)&&(lpData[3]==0xCCCCCCCC),
297            "Destination data after blitting is not correct\n");
298     } else {
299         ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
300            "Destination data after blitting is not correct\n");
301     }
302     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
303     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
304
305     /* Also test SetColorKey */
306     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
307     ok(DDColorKey.dwColorSpaceLowValue == 0xFF00FF && DDColorKey.dwColorSpaceHighValue == 0xFF00FF,
308        "GetColorKey does not return the colorkey used at surface creation\n");
309
310     DDColorKey.dwColorSpaceLowValue = 0x00FF00;
311     DDColorKey.dwColorSpaceHighValue = 0x00FF00;
312     IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
313
314     DDColorKey.dwColorSpaceLowValue = 0;
315     DDColorKey.dwColorSpaceHighValue = 0;
316     IDirectDrawSurface_GetColorKey(lpSrc, DDCKEY_SRCBLT, &DDColorKey);
317     ok(DDColorKey.dwColorSpaceLowValue == 0x00FF00 && DDColorKey.dwColorSpaceHighValue == 0x00FF00,
318        "GetColorKey does not return the colorkey set with SetColorKey\n");
319
320     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0;
321     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0;
322     IDirectDrawSurface_GetSurfaceDesc(lpSrc, &ddsd);
323     ok(ddsd.ddckCKSrcBlt.dwColorSpaceLowValue == 0x00FF00 && ddsd.ddckCKSrcBlt.dwColorSpaceHighValue == 0x00FF00,
324        "GetSurfaceDesc does not return the colorkey set with SetColorKey\n");
325
326     IDirectDrawSurface_Release(lpSrc);
327     IDirectDrawSurface_Release(lpDst);
328
329     /* start with a new set of surfaces to test the color keying parameters to blit */
330     memset(&ddsd, 0, sizeof(ddsd));
331     ddsd.dwSize = sizeof(ddsd);
332     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
333     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
334     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
335     ddsd.dwWidth = 800;
336     ddsd.dwHeight = 600;
337     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
338     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
339     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
340     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
341     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
342     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0xFF0000;
343     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0xFF0000;
344     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x00FF00;
345     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x00FF00;
346     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
347     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
348     if(FAILED(rc))
349     {
350         skip("Failed to create surface\n");
351         return;
352     }
353
354     /* start with a new set of surfaces to test the color keying parameters to blit */
355     memset(&ddsd, 0, sizeof(ddsd));
356     ddsd.dwSize = sizeof(ddsd);
357     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
358     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT | DDSD_CKDESTBLT;
359     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
360     ddsd.dwWidth = 800;
361     ddsd.dwHeight = 600;
362     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
363     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
364     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
365     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
366     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
367     ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0x0000FF;
368     ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0x0000FF;
369     ddsd.ddckCKDestBlt.dwColorSpaceLowValue = 0x000000;
370     ddsd.ddckCKDestBlt.dwColorSpaceHighValue = 0x000000;
371     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
372     ok(rc==DD_OK || rc == DDERR_NOCOLORKEYHW,"CreateSurface returned: %x\n",rc);
373     if(FAILED(rc))
374     {
375         skip("Failed to create surface\n");
376         IDirectDrawSurface_Release(lpDst);
377         return;
378     }
379
380     memset(&fx, 0, sizeof(fx));
381     fx.dwSize = sizeof(fx);
382     fx.ddckSrcColorkey.dwColorSpaceHighValue = 0x110000;
383     fx.ddckSrcColorkey.dwColorSpaceLowValue = 0x110000;
384     fx.ddckDestColorkey.dwColorSpaceHighValue = 0x001100;
385     fx.ddckDestColorkey.dwColorSpaceLowValue = 0x001100;
386
387     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
388     ok(rc==DD_OK,"Lock returned: %x\n",rc);
389     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
390     lpData = (LPDWORD)ddsd2.lpSurface;
391     lpData[0] = 0x000000FF; /* Applies to src blt key in src surface */
392     lpData[1] = 0x00000000; /* Applies to dst blt key in src surface */
393     lpData[2] = 0x00FF0000; /* Dst color key in dst surface */
394     lpData[3] = 0x0000FF00; /* Src color key in dst surface */
395     lpData[4] = 0x00001100; /* Src color key in ddbltfx */
396     lpData[5] = 0x00110000; /* Dst color key in ddbltfx */
397     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
398     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
399
400     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
401     ok(rc==DD_OK,"Lock returned: %x\n",rc);
402     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
403     lpData = (LPDWORD)ddsd2.lpSurface;
404     lpData[0] = 0x55555555;
405     lpData[1] = 0x55555555;
406     lpData[2] = 0x55555555;
407     lpData[3] = 0x55555555;
408     lpData[4] = 0x55555555;
409     lpData[5] = 0x55555555;
410     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
411     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
412
413     /* Test a blit without keying */
414     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, 0, &fx);
415     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
416
417     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
418     ok(rc==DD_OK,"Lock returned: %x\n",rc);
419     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
420     lpData = (LPDWORD)ddsd2.lpSurface;
421     /* Should have copied src data unmodified to dst */
422     ok(lpData[0] == 0x000000FF &&
423        lpData[1] == 0x00000000 &&
424        lpData[2] == 0x00FF0000 &&
425        lpData[3] == 0x0000FF00 &&
426        lpData[4] == 0x00001100 &&
427        lpData[5] == 0x00110000, "Surface data after unkeyed blit does not match\n");
428
429     lpData[0] = 0x55555555;
430     lpData[1] = 0x55555555;
431     lpData[2] = 0x55555555;
432     lpData[3] = 0x55555555;
433     lpData[4] = 0x55555555;
434     lpData[5] = 0x55555555;
435     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
436     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
437
438     /* Src key */
439     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
440     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
441
442     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
443     ok(rc==DD_OK,"Lock returned: %x\n",rc);
444     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
445     lpData = (LPDWORD)ddsd2.lpSurface;
446
447     ok(lpData[0] == 0x55555555 && /* Here the src key applied */
448        lpData[1] == 0x00000000 &&
449        lpData[2] == 0x00FF0000 &&
450        lpData[3] == 0x0000FF00 &&
451        lpData[4] == 0x00001100 &&
452        lpData[5] == 0x00110000, "Surface data after srckey blit does not match\n");
453
454     lpData[0] = 0x55555555;
455     lpData[1] = 0x55555555;
456     lpData[2] = 0x55555555;
457     lpData[3] = 0x55555555;
458     lpData[4] = 0x55555555;
459     lpData[5] = 0x55555555;
460     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
461     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
462
463     /* Src override */
464     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
465     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
466
467     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
468     ok(rc==DD_OK,"Lock returned: %x\n",rc);
469     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
470     lpData = (LPDWORD)ddsd2.lpSurface;
471
472     ok(lpData[0] == 0x000000FF &&
473        lpData[1] == 0x00000000 &&
474        lpData[2] == 0x00FF0000 &&
475        lpData[3] == 0x0000FF00 &&
476        lpData[4] == 0x00001100 &&
477        lpData[5] == 0x55555555, /* Override key applies here */
478        "Surface data after src override key blit does not match\n");
479
480     lpData[0] = 0x55555555;
481     lpData[1] = 0x55555555;
482     lpData[2] = 0x55555555;
483     lpData[3] = 0x55555555;
484     lpData[4] = 0x55555555;
485     lpData[5] = 0x55555555;
486     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
487     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
488
489     /* Src override AND src key. That is not supposed to work */
490     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE, &fx);
491     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
492
493     /* Verify that the destination is unchanged */
494     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
495     ok(rc==DD_OK,"Lock returned: %x\n",rc);
496     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
497     lpData = (LPDWORD)ddsd2.lpSurface;
498
499     ok(lpData[0] == 0x55555555 &&
500        lpData[1] == 0x55555555 &&
501        lpData[2] == 0x55555555 &&
502        lpData[3] == 0x55555555 &&
503        lpData[4] == 0x55555555 &&
504        lpData[5] == 0x55555555, /* Override key applies here */
505        "Surface data after src key blit with override does not match\n");
506
507     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
508     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
509     lpData[2] = 0x00001100; /* Dest key in override */
510     lpData[3] = 0x00001100; /* Dest key in override */
511     lpData[4] = 0x00000000; /* Dest key in src surface */
512     lpData[5] = 0x00000000; /* Dest key in src surface */
513     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
514     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
515
516     /* Dest key blit */
517     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
518     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
519
520     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
521     ok(rc==DD_OK,"Lock returned: %x\n",rc);
522     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
523     lpData = (LPDWORD)ddsd2.lpSurface;
524
525     /* DirectDraw uses the dest blit key from the SOURCE surface ! */
526     ok(lpData[0] == 0x00ff0000 &&
527        lpData[1] == 0x00ff0000 &&
528        lpData[2] == 0x00001100 &&
529        lpData[3] == 0x00001100 &&
530        lpData[4] == 0x00001100 && /* Key applies here */
531        lpData[5] == 0x00110000,   /* Key applies here */
532        "Surface data after dest key blit does not match\n");
533
534     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
535     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
536     lpData[2] = 0x00001100; /* Dest key in override */
537     lpData[3] = 0x00001100; /* Dest key in override */
538     lpData[4] = 0x00000000; /* Dest key in src surface */
539     lpData[5] = 0x00000000; /* Dest key in src surface */
540     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
541     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
542
543     /* Dest override key blit */
544     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
545     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
546
547     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
548     ok(rc==DD_OK,"Lock returned: %x\n",rc);
549     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
550     lpData = (LPDWORD)ddsd2.lpSurface;
551
552     ok(lpData[0] == 0x00FF0000 &&
553        lpData[1] == 0x00FF0000 &&
554        lpData[2] == 0x00FF0000 && /* Key applies here */
555        lpData[3] == 0x0000FF00 && /* Key applies here */
556        lpData[4] == 0x00000000 &&
557        lpData[5] == 0x00000000,
558        "Surface data after dest key override blit does not match\n");
559
560     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
561     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
562     lpData[2] = 0x00001100; /* Dest key in override */
563     lpData[3] = 0x00001100; /* Dest key in override */
564     lpData[4] = 0x00000000; /* Dest key in src surface */
565     lpData[5] = 0x00000000; /* Dest key in src surface */
566     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
567     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
568
569     /* Dest override key blit. Supposed to fail too */
570     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE, &fx);
571     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
572
573     /* Check for unchanged data */
574     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
575     ok(rc==DD_OK,"Lock returned: %x\n",rc);
576     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
577     lpData = (LPDWORD)ddsd2.lpSurface;
578
579     ok(lpData[0] == 0x00FF0000 &&
580        lpData[1] == 0x00FF0000 &&
581        lpData[2] == 0x00001100 && /* Key applies here */
582        lpData[3] == 0x00001100 && /* Key applies here */
583        lpData[4] == 0x00000000 &&
584        lpData[5] == 0x00000000,
585        "Surface data with dest key and dest override does not match\n");
586
587     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
588     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
589     lpData[2] = 0x00001100; /* Dest key in override */
590     lpData[3] = 0x00001100; /* Dest key in override */
591     lpData[4] = 0x00000000; /* Dest key in src surface */
592     lpData[5] = 0x00000000; /* Dest key in src surface */
593     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
594     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
595
596     /* Modify the source data a bit to give some more conclusive results */
597     rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
598     ok(rc==DD_OK,"Lock returned: %x\n",rc);
599     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
600     lpData = (LPDWORD)ddsd2.lpSurface;
601     lpData[5] = 0x000000FF; /* Applies to src blt key in src surface */
602     rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
603     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
604
605     /* Source and destination key */
606     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST | DDBLT_KEYSRC, &fx);
607     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
608
609     rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
610     ok(rc==DD_OK,"Lock returned: %x\n",rc);
611     ok((ddsd2.dwFlags & DDSD_LPSURFACE) == 0, "Surface desc has LPSURFACE Flags set\n");
612     lpData = (LPDWORD)ddsd2.lpSurface;
613
614     ok(lpData[0] == 0x00FF0000 && /* Masked by Destination key */
615        lpData[1] == 0x00FF0000 && /* Masked by Destination key */
616        lpData[2] == 0x00001100 && /* Masked by Destination key */
617        lpData[3] == 0x00001100 && /* Masked by Destination key */
618        lpData[4] == 0x00001100 && /* Allowed by destination key, not masked by source key */
619        lpData[5] == 0x00000000,   /* Allowed by dst key, but masked by source key */
620        "Surface data with src key and dest key blit does not match\n");
621
622     lpData[0] = 0x00FF0000; /* Dest key in dst surface */
623     lpData[1] = 0x00FF0000; /* Dest key in dst surface */
624     lpData[2] = 0x00001100; /* Dest key in override */
625     lpData[3] = 0x00001100; /* Dest key in override */
626     lpData[4] = 0x00000000; /* Dest key in src surface */
627     lpData[5] = 0x00000000; /* Dest key in src surface */
628     rc = IDirectDrawSurface_Unlock(lpDst, NULL);
629     ok(rc==DD_OK,"Unlock returned: %x\n",rc);
630
631     /* Override keys without ddbltfx parameter fail */
632     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, NULL);
633     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
634     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, NULL);
635     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
636
637     /* Try blitting without keys in the source surface*/
638     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_SRCBLT, NULL);
639     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
640     rc = IDirectDrawSurface_SetColorKey(lpSrc, DDCKEY_DESTBLT, NULL);
641     ok(rc == DD_OK, "SetColorKey returned %x\n", rc);
642
643     /* That fails now. Do not bother to check that the data is unmodified */
644     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, &fx);
645     ok(rc == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Blt returned %08x\n", rc);
646
647     /* Dest key blit still works. Which key is used this time??? */
648     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDEST, &fx);
649     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
650
651     /* With correctly passed override keys no key in the surface is needed.
652      * Again, the result was checked before, no need to do that again
653      */
654     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYDESTOVERRIDE, &fx);
655     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
656     rc = IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRCOVERRIDE, &fx);
657     ok(rc == DD_OK, "IDirectDrawSurface_Blt returned %08x\n", rc);
658
659     IDirectDrawSurface_Release(lpSrc);
660     IDirectDrawSurface_Release(lpDst);
661 }
662
663 static void QueryInterface(void)
664 {
665     LPDIRECTDRAWSURFACE dsurface;
666     DDSURFACEDESC surface;
667     LPVOID object;
668     HRESULT ret;
669
670     /* Create a surface */
671     ZeroMemory(&surface, sizeof(surface));
672     surface.dwSize = sizeof(surface);
673     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
674     surface.dwHeight = 10;
675     surface.dwWidth = 10;
676     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
677     if(ret != DD_OK)
678     {
679         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
680         return;
681     }
682
683     /* Call IUnknown::QueryInterface */
684     ret = IDirectDrawSurface_QueryInterface(dsurface, 0, &object);
685     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface::QueryInterface returned %x\n", ret);
686
687     IDirectDrawSurface_Release(dsurface);
688 }
689
690 /* The following tests test which interface is returned by IDirectDrawSurfaceX::GetDDInterface.
691  * It uses refcounts to test that and compares the interface addresses. Partially fits here, and
692  * partially in the refcount test
693  */
694
695 static unsigned long getref(IUnknown *iface)
696 {
697     IUnknown_AddRef(iface);
698     return IUnknown_Release(iface);
699 }
700
701 static void GetDDInterface_1(void)
702 {
703     LPDIRECTDRAWSURFACE dsurface;
704     LPDIRECTDRAWSURFACE2 dsurface2;
705     DDSURFACEDESC surface;
706     HRESULT ret;
707     IDirectDraw2 *dd2;
708     IDirectDraw4 *dd4;
709     IDirectDraw7 *dd7;
710     unsigned long ref1, ref2, ref4, ref7;
711     void *dd;
712
713     /* Create a surface */
714     ZeroMemory(&surface, sizeof(surface));
715     surface.dwSize = sizeof(surface);
716     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
717     surface.dwHeight = 10;
718     surface.dwWidth = 10;
719     ret = IDirectDraw_CreateSurface(lpDD, &surface, &dsurface, NULL);
720     if(ret != DD_OK)
721     {
722         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
723         return;
724     }
725     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
726     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
727     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
728     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
729     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
730     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
731     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
732     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
733
734     ref1 = getref((IUnknown *) lpDD);
735     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
736     ref2 = getref((IUnknown *) dd2);
737     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
738     ref4 = getref((IUnknown *) dd4);
739     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
740     ref7 = getref((IUnknown *) dd7);
741     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
742
743
744     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
745     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
746     ok(getref((IUnknown *) lpDD) == ref1 + 1, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
747     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
748     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
749     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
750
751     ok(dd == lpDD, "Returned interface pointer is not equal to the creation interface\n");
752     IUnknown_Release((IUnknown *) dd);
753
754     /* try a NULL pointer */
755     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, NULL);
756     ok(ret == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
757
758     IDirectDraw_Release(dd2);
759     IDirectDraw_Release(dd4);
760     IDirectDraw_Release(dd7);
761     IDirectDrawSurface2_Release(dsurface2);
762     IDirectDrawSurface_Release(dsurface);
763 }
764
765 static void GetDDInterface_2(void)
766 {
767     LPDIRECTDRAWSURFACE dsurface;
768     LPDIRECTDRAWSURFACE2 dsurface2;
769     DDSURFACEDESC surface;
770     HRESULT ret;
771     IDirectDraw2 *dd2;
772     IDirectDraw4 *dd4;
773     IDirectDraw7 *dd7;
774     unsigned long ref1, ref2, ref4, ref7;
775     void *dd;
776
777     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
778     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
779     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
780     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
781     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
782     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
783
784     /* Create a surface */
785     ZeroMemory(&surface, sizeof(surface));
786     surface.dwSize = sizeof(surface);
787     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
788     surface.dwHeight = 10;
789     surface.dwWidth = 10;
790     ret = IDirectDraw2_CreateSurface(dd2, &surface, &dsurface, NULL);
791     if(ret != DD_OK)
792     {
793         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
794         return;
795     }
796     ret = IDirectDrawSurface_QueryInterface(dsurface, &IID_IDirectDrawSurface2, (void **) &dsurface2);
797     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
798
799     ref1 = getref((IUnknown *) lpDD);
800     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
801     ref2 = getref((IUnknown *) dd2);
802     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
803     ref4 = getref((IUnknown *) dd4);
804     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
805     ref7 = getref((IUnknown *) dd7);
806     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
807
808
809     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
810     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
811     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
812     ok(getref((IUnknown *) dd2) == ref2 + 1, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
813     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
814     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
815
816     ok(dd == dd2, "Returned interface pointer is not equal to the creation interface\n");
817     IUnknown_Release((IUnknown *) dd);
818
819     IDirectDraw_Release(dd2);
820     IDirectDraw_Release(dd4);
821     IDirectDraw_Release(dd7);
822     IDirectDrawSurface2_Release(dsurface2);
823     IDirectDrawSurface_Release(dsurface);
824 }
825
826 static void GetDDInterface_4(void)
827 {
828     LPDIRECTDRAWSURFACE2 dsurface2;
829     LPDIRECTDRAWSURFACE4 dsurface4;
830     DDSURFACEDESC2 surface;
831     HRESULT ret;
832     IDirectDraw2 *dd2;
833     IDirectDraw4 *dd4;
834     IDirectDraw7 *dd7;
835     unsigned long ref1, ref2, ref4, ref7;
836     void *dd;
837
838     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
839     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
840     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
841     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
842     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
843     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
844
845     /* Create a surface */
846     ZeroMemory(&surface, sizeof(surface));
847     surface.dwSize = sizeof(surface);
848     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
849     surface.dwHeight = 10;
850     surface.dwWidth = 10;
851     ret = IDirectDraw4_CreateSurface(dd4, &surface, &dsurface4, NULL);
852     if(ret != DD_OK)
853     {
854         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
855         return;
856     }
857     ret = IDirectDrawSurface4_QueryInterface(dsurface4, &IID_IDirectDrawSurface2, (void **) &dsurface2);
858     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
859
860     ref1 = getref((IUnknown *) lpDD);
861     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
862     ref2 = getref((IUnknown *) dd2);
863     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
864     ref4 = getref((IUnknown *) dd4);
865     ok(ref4 == 2, "IDirectDraw4 refcount is %ld\n", ref4);
866     ref7 = getref((IUnknown *) dd7);
867     ok(ref7 == 1, "IDirectDraw7 refcount is %ld\n", ref7);
868
869     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
870     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
871     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
872     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
873     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
874     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
875
876     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
877     IUnknown_Release((IUnknown *) dd);
878
879     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
880     ret = IDirectDrawSurface2_GetDDInterface(dsurface2, &dd);
881     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
882     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
883     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
884     ok(getref((IUnknown *) dd4) == ref4 + 1, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
885     ok(getref((IUnknown *) dd7) == ref7 + 0, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
886
887     ok(dd == dd4, "Returned interface pointer is not equal to the creation interface\n");
888     IUnknown_Release((IUnknown *) dd);
889
890     IDirectDraw_Release(dd2);
891     IDirectDraw_Release(dd4);
892     IDirectDraw_Release(dd7);
893     IDirectDrawSurface4_Release(dsurface4);
894     IDirectDrawSurface2_Release(dsurface2);
895 }
896
897 static void GetDDInterface_7(void)
898 {
899     LPDIRECTDRAWSURFACE4 dsurface4;
900     LPDIRECTDRAWSURFACE7 dsurface7;
901     DDSURFACEDESC2 surface;
902     HRESULT ret;
903     IDirectDraw2 *dd2;
904     IDirectDraw4 *dd4;
905     IDirectDraw7 *dd7;
906     unsigned long ref1, ref2, ref4, ref7;
907     void *dd;
908
909     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw2, (void **) &dd2);
910     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
911     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw4, (void **) &dd4);
912     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
913     ret = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
914     ok(ret == DD_OK, "IDirectDraw7_QueryInterface returned %08x\n", ret);
915
916     /* Create a surface */
917     ZeroMemory(&surface, sizeof(surface));
918     surface.dwSize = sizeof(surface);
919     surface.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
920     surface.dwHeight = 10;
921     surface.dwWidth = 10;
922     ret = IDirectDraw7_CreateSurface(dd7, &surface, &dsurface7, NULL);
923     if(ret != DD_OK)
924     {
925         ok(FALSE, "IDirectDraw::CreateSurface failed with error %x\n", ret);
926         return;
927     }
928     ret = IDirectDrawSurface7_QueryInterface(dsurface7, &IID_IDirectDrawSurface4, (void **) &dsurface4);
929     ok(ret == DD_OK, "IDirectDrawSurface_QueryInterface returned %08x\n", ret);
930
931     ref1 = getref((IUnknown *) lpDD);
932     ok(ref1 == 1, "IDirectDraw refcount is %ld\n", ref1);
933     ref2 = getref((IUnknown *) dd2);
934     ok(ref2 == 1, "IDirectDraw2 refcount is %ld\n", ref2);
935     ref4 = getref((IUnknown *) dd4);
936     ok(ref4 == 1, "IDirectDraw4 refcount is %ld\n", ref4);
937     ref7 = getref((IUnknown *) dd7);
938     ok(ref7 == 2, "IDirectDraw7 refcount is %ld\n", ref7);
939
940     ret = IDirectDrawSurface7_GetDDInterface(dsurface7, &dd);
941     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
942     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
943     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
944     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
945     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
946
947     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
948     IUnknown_Release((IUnknown *) dd);
949
950     /* Now test what happens if we QI the surface for some other version - It should still return the creation interface */
951     ret = IDirectDrawSurface4_GetDDInterface(dsurface4, &dd);
952     ok(ret == DD_OK, "IDirectDrawSurface7_GetDDInterface returned %08x\n", ret);
953     ok(getref((IUnknown *) lpDD) == ref1 + 0, "IDirectDraw refcount was increased by %ld\n", getref((IUnknown *) lpDD) - ref1);
954     ok(getref((IUnknown *) dd2) == ref2 + 0, "IDirectDraw2 refcount was increased by %ld\n", getref((IUnknown *) dd2) - ref2);
955     ok(getref((IUnknown *) dd4) == ref4 + 0, "IDirectDraw4 refcount was increased by %ld\n", getref((IUnknown *) dd4) - ref4);
956     ok(getref((IUnknown *) dd7) == ref7 + 1, "IDirectDraw7 refcount was increased by %ld\n", getref((IUnknown *) dd7) - ref7);
957
958     ok(dd == dd7, "Returned interface pointer is not equal to the creation interface\n");
959     IUnknown_Release((IUnknown *) dd);
960
961     IDirectDraw_Release(dd2);
962     IDirectDraw_Release(dd4);
963     IDirectDraw_Release(dd7);
964     IDirectDrawSurface4_Release(dsurface4);
965     IDirectDrawSurface7_Release(dsurface7);
966 }
967
968 #define MAXEXPECTED 8  /* Can match up to 8 expected surfaces */
969 struct enumstruct
970 {
971     IDirectDrawSurface *expected[MAXEXPECTED];
972     UINT count;
973 };
974
975 static HRESULT WINAPI enumCB(IDirectDrawSurface *surf, DDSURFACEDESC *desc, void *ctx)
976 {
977     int i;
978     BOOL found = FALSE;
979
980     for(i = 0; i < MAXEXPECTED; i++)
981     {
982         if(((struct enumstruct *)ctx)->expected[i] == surf) found = TRUE;
983     }
984
985     ok(found, "Unexpected surface %p enumerated\n", surf);
986     ((struct enumstruct *)ctx)->count++;
987     IDirectDrawSurface_Release(surf);
988     return DDENUMRET_OK;
989 }
990
991 static void EnumTest(void)
992 {
993     HRESULT rc;
994     DDSURFACEDESC ddsd;
995     IDirectDrawSurface *surface;
996     struct enumstruct ctx;
997
998     ddsd.dwSize = sizeof(ddsd);
999     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1000     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1001     U2(ddsd).dwMipMapCount = 3;
1002     ddsd.dwWidth = 32;
1003     ddsd.dwHeight = 32;
1004     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
1005     ok(rc==DD_OK,"CreateSurface returned: %x\n",rc);
1006
1007     memset(&ctx, 0, sizeof(ctx));
1008     ctx.expected[0] = surface;
1009     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[0], &ddsd.ddsCaps, &ctx.expected[1]);
1010     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1011     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[1], &ddsd.ddsCaps, &ctx.expected[2]);
1012     ok(rc == DD_OK, "GetAttachedSurface returned %08x\n", rc);
1013     rc = IDirectDrawSurface_GetAttachedSurface(ctx.expected[2], &ddsd.ddsCaps, &ctx.expected[3]);
1014     ok(rc == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", rc);
1015     ok(!ctx.expected[3], "expected NULL pointer\n");
1016     ctx.count = 0;
1017
1018     rc = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, &ddsd, (void *) &ctx, enumCB);
1019     ok(rc == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", rc);
1020     ok(ctx.count == 3, "%d surfaces enumerated, expected 3\n", ctx.count);
1021
1022     IDirectDrawSurface_Release(ctx.expected[2]);
1023     IDirectDrawSurface_Release(ctx.expected[1]);
1024     IDirectDrawSurface_Release(surface);
1025 }
1026
1027 HRESULT WINAPI SurfaceCounter(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1028 {
1029     UINT *num = context;
1030     (*num)++;
1031     IDirectDrawSurface_Release(surface);
1032     return DDENUMRET_OK;
1033 }
1034
1035 static void AttachmentTest7(void)
1036 {
1037     HRESULT hr;
1038     IDirectDraw7 *dd7;
1039     IDirectDrawSurface7 *surface1, *surface2, *surface3, *surface4;
1040     DDSURFACEDESC2 ddsd;
1041     UINT num;
1042     DDSCAPS2 caps = {DDSCAPS_TEXTURE, 0, 0, 0};
1043     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1044
1045     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1046     ok(hr == DD_OK, "IDirectDraw_QueryInterface returned %08x\n", hr);
1047
1048     memset(&ddsd, 0, sizeof(ddsd));
1049     ddsd.dwSize = sizeof(ddsd);
1050     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1051     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1052     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1053     ddsd.dwWidth = 128;
1054     ddsd.dwHeight = 128;
1055     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1056     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1057
1058     /* ROOT */
1059     num = 0;
1060     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1061     ok(num == 1, "Mipmap root has %d surfaces attached, expected 1\n", num);
1062     /* DONE ROOT */
1063
1064     /* LEVEL 1 */
1065     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1066     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1067     num = 0;
1068     IDirectDrawSurface7_EnumAttachedSurfaces(surface2, &num, SurfaceCounter);
1069     ok(num == 1, "First mip level has %d surfaces attached, expected 1\n", num);
1070     /* DONE LEVEL 1 */
1071
1072     /* LEVEL 2 */
1073     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1074     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1075     IDirectDrawSurface7_Release(surface2);
1076     num = 0;
1077     IDirectDrawSurface7_EnumAttachedSurfaces(surface3, &num, SurfaceCounter);
1078     ok(num == 0, "Second mip level has %d surfaces attached, expected 1\n", num);
1079     /* Done level 2 */
1080     /* Mip level 3 is still needed */
1081     hr = IDirectDrawSurface7_GetAttachedSurface(surface3, &caps, &surface4);
1082     ok(hr == DDERR_NOTFOUND, "GetAttachedSurface returned %08x\n", hr);
1083     ok(!surface4, "expected NULL pointer\n");
1084
1085     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1086     memset(&ddsd, 0, sizeof(ddsd));
1087     ddsd.dwSize = sizeof(ddsd);
1088     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1089     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1090     ddsd.dwWidth = 16;
1091     ddsd.dwHeight = 16;
1092     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1093     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1094
1095     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1096     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1097     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1098     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1099     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1100     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1101     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1102     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1103
1104     IDirectDrawSurface7_Release(surface2);
1105
1106     memset(&ddsd, 0, sizeof(ddsd));
1107     ddsd.dwSize = sizeof(ddsd);
1108     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1109     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1110     ddsd.dwWidth = 16;
1111     ddsd.dwHeight = 16;
1112     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1113     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1114
1115     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1116     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1117     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1118     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1119     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface2);
1120     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1121     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1122     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1123
1124     IDirectDrawSurface7_Release(surface3);
1125     IDirectDrawSurface7_Release(surface2);
1126     IDirectDrawSurface7_Release(surface1);
1127
1128     hr = IDirectDraw7_SetCooperativeLevel(dd7, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1129     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1130
1131     memset(&ddsd, 0, sizeof(ddsd));
1132     ddsd.dwSize = sizeof(ddsd);
1133     ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
1134     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
1135     ddsd.dwBackBufferCount = 2;
1136     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1137     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1138
1139     num = 0;
1140     IDirectDrawSurface7_EnumAttachedSurfaces(surface1, &num, SurfaceCounter);
1141     ok(num == 1, "Primary surface has %d surfaces attached, expected 1\n", num);
1142     IDirectDrawSurface7_Release(surface1);
1143
1144     /* Those are some invalid descriptions, no need to test attachments with them */
1145     memset(&ddsd, 0, sizeof(ddsd));
1146     ddsd.dwSize = sizeof(ddsd);
1147     ddsd.dwFlags = DDSD_CAPS;
1148     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1149     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1150     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1151     memset(&ddsd, 0, sizeof(ddsd));
1152     ddsd.dwSize = sizeof(ddsd);
1153     ddsd.dwFlags = DDSD_CAPS;
1154     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1155     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1156     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1157
1158     /* Try a single primary and two offscreen plain surfaces */
1159     memset(&ddsd, 0, sizeof(ddsd));
1160     ddsd.dwSize = sizeof(ddsd);
1161     ddsd.dwFlags = DDSD_CAPS;
1162     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1163     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface1, NULL);
1164     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1165
1166     memset(&ddsd, 0, sizeof(ddsd));
1167     ddsd.dwSize = sizeof(ddsd);
1168     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1169     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1170     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1171     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1172     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface2, NULL);
1173     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1174
1175     memset(&ddsd, 0, sizeof(ddsd));
1176     ddsd.dwSize = sizeof(ddsd);
1177     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1178     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1179     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1180     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1181     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface3, NULL);
1182     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1183
1184     /* This one has a different size */
1185     memset(&ddsd, 0, sizeof(ddsd));
1186     ddsd.dwSize = sizeof(ddsd);
1187     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1188     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1189     ddsd.dwWidth = 128;
1190     ddsd.dwHeight = 128;
1191     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface4, NULL);
1192     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1193
1194     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface2);
1195     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1196     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface1);
1197     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1198     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface3);
1199     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1200     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1201     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1202     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1203     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1204
1205     IDirectDrawSurface7_Release(surface4);
1206     IDirectDrawSurface7_Release(surface3);
1207     IDirectDrawSurface7_Release(surface2);
1208     IDirectDrawSurface7_Release(surface1);
1209
1210     hr =IDirectDraw7_SetCooperativeLevel(dd7, NULL, DDSCL_NORMAL);
1211     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1212     IDirectDraw7_Release(dd7);
1213 }
1214
1215 static void AttachmentTest(void)
1216 {
1217     HRESULT hr;
1218     IDirectDrawSurface *surface1, *surface2, *surface3, *surface4;
1219     DDSURFACEDESC ddsd;
1220     DDSCAPS caps = {DDSCAPS_TEXTURE};
1221     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
1222
1223     memset(&ddsd, 0, sizeof(ddsd));
1224     ddsd.dwSize = sizeof(ddsd);
1225     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_MIPMAPCOUNT;
1226     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
1227     U2(ddsd).dwMipMapCount = 3; /* Will create 128x128, 64x64, 32x32 */
1228     ddsd.dwWidth = 128;
1229     ddsd.dwHeight = 128;
1230     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1231     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1232
1233     hr = IDirectDrawSurface7_GetAttachedSurface(surface1, &caps, &surface2);
1234     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1235     hr = IDirectDrawSurface7_GetAttachedSurface(surface2, &caps, &surface3);
1236     ok(hr == DD_OK, "GetAttachedSurface returned %08x\n", hr);
1237
1238     /* Try to attach a 16x16 miplevel - Should not work as far I can see */
1239     memset(&ddsd, 0, sizeof(ddsd));
1240     ddsd.dwSize = sizeof(ddsd);
1241     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1242     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1243     ddsd.dwWidth = 16;
1244     ddsd.dwHeight = 16;
1245     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1246     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1247
1248     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4);
1249     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 128x128 texture root returned %08x\n", hr);
1250     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);
1251     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 texture returned %08x\n", hr);
1252     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);
1253     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 32x32 texture mip level returned %08x\n", hr);
1254     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1255     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 surface returned %08x\n", hr);
1256     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);
1257     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 surface to a 64x64 texture sublevel returned %08x\n", hr);
1258     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1259     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 texture returned %08x\n", hr);
1260
1261     IDirectDrawSurface7_Release(surface4);
1262
1263     memset(&ddsd, 0, sizeof(ddsd));
1264     ddsd.dwSize = sizeof(ddsd);
1265     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1266     ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
1267     ddsd.dwWidth = 16;
1268     ddsd.dwHeight = 16;
1269     hr = IDirectDraw7_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1270     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1271
1272     hr = IDirectDrawSurface7_AddAttachedSurface(surface1, surface4); /* Succeeds on refrast */
1273     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 128x128 texture root returned %08x\n", hr);
1274     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface4);
1275     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface1);  /* Succeeds on refrast */
1276     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 128x128 texture root to a 16x16 offscreen plain surface returned %08x\n", hr);
1277     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface1, 0, surface1);
1278     hr = IDirectDrawSurface7_AddAttachedSurface(surface3, surface4);  /* Succeeds on refrast */
1279     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 32x32 texture mip level returned %08x\n", hr);
1280     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface3, 0, surface4);
1281     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface3);
1282     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 32x32 texture mip level to a 16x16 offscreen plain surface returned %08x\n", hr);
1283     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface3);
1284     hr = IDirectDrawSurface7_AddAttachedSurface(surface2, surface4);  /* Succeeds on refrast */
1285     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 16x16 offscreen plain surface to a 64x64 texture sublevel returned %08x\n", hr);
1286     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface2, 0, surface4);
1287     hr = IDirectDrawSurface7_AddAttachedSurface(surface4, surface2);
1288     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a 64x64 texture sublevel to a 16x16 offscreen plain surface returned %08x\n", hr);
1289     if(SUCCEEDED(hr)) IDirectDrawSurface7_DeleteAttachedSurface(surface4, 0, surface2);
1290
1291     IDirectDrawSurface7_Release(surface4);
1292     IDirectDrawSurface7_Release(surface3);
1293     IDirectDrawSurface7_Release(surface2);
1294     IDirectDrawSurface7_Release(surface1);
1295
1296     hr = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1297     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1298
1299     /* Creating a back buffer as-is, is not allowed. No need to perform attachment tests */
1300     memset(&ddsd, 0, sizeof(ddsd));
1301     ddsd.dwSize = sizeof(ddsd);
1302     ddsd.dwFlags = DDSD_CAPS;
1303     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER;
1304     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1305     ok(hr==DDERR_INVALIDCAPS,"CreateSurface returned: %x\n",hr);
1306     /* This old ddraw version happily creates explicit front buffers */
1307     memset(&ddsd, 0, sizeof(ddsd));
1308     ddsd.dwSize = sizeof(ddsd);
1309     ddsd.dwFlags = DDSD_CAPS;
1310     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER;
1311     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1312     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1313     IDirectDrawSurface_Release(surface1);
1314
1315     /* Try a single primary and two offscreen plain surfaces */
1316     memset(&ddsd, 0, sizeof(ddsd));
1317     ddsd.dwSize = sizeof(ddsd);
1318     ddsd.dwFlags = DDSD_CAPS;
1319     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
1320     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface1, NULL);
1321     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1322
1323     memset(&ddsd, 0, sizeof(ddsd));
1324     ddsd.dwSize = sizeof(ddsd);
1325     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1326     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1327     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1328     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1329     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface2, NULL);
1330     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1331
1332     memset(&ddsd, 0, sizeof(ddsd));
1333     ddsd.dwSize = sizeof(ddsd);
1334     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1335     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1336     ddsd.dwWidth = GetSystemMetrics(SM_CXSCREEN);
1337     ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
1338     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface3, NULL);
1339     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1340
1341     /* This one has a different size */
1342     memset(&ddsd, 0, sizeof(ddsd));
1343     ddsd.dwSize = sizeof(ddsd);
1344     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1345     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
1346     ddsd.dwWidth = 128;
1347     ddsd.dwHeight = 128;
1348     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface4, NULL);
1349     ok(hr==DD_OK,"CreateSurface returned: %x\n",hr);
1350
1351     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface2);
1352     ok(hr == DD_OK, "Attaching an offscreen plain surface to a front buffer returned %08x\n", hr);
1353     /* Try the reverse without detaching first */
1354     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1355     ok(hr == DDERR_SURFACEALREADYATTACHED, "Attaching an attached surface to its attachee returned %08x\n", hr);
1356     hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1357     ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1358     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface1);
1359     ok(hr == DD_OK, "Attaching a front buffer to an offscreen plain surface returned %08x\n", hr);
1360     /* Try to detach reversed */
1361     hr = IDirectDrawSurface_DeleteAttachedSurface(surface1, 0, surface2);
1362     ok(hr == DDERR_CANNOTDETACHSURFACE, "DeleteAttachedSurface returned %08x\n", hr);
1363     /* Now the proper detach */
1364     hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface1);
1365     ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1366     hr = IDirectDrawSurface_AddAttachedSurface(surface2, surface3); /* Fails on refrast */
1367     ok(hr == DD_OK, "Attaching an offscreen plain surface to another offscreen plain surface returned %08x\n", hr);
1368     if(SUCCEEDED(hr))
1369     {
1370         hr = IDirectDrawSurface_DeleteAttachedSurface(surface2, 0, surface3);
1371         ok(hr == DD_OK, "DeleteAttachedSurface failed with %08x\n", hr);
1372     }
1373     hr = IDirectDrawSurface_AddAttachedSurface(surface1, surface4);
1374     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching an offscreen plain surface to a front buffer of different size returned %08x\n", hr);
1375     hr = IDirectDrawSurface_AddAttachedSurface(surface4, surface1);
1376     ok(hr == DDERR_CANNOTATTACHSURFACE, "Attaching a front buffer to an offscreen plain surface of different size returned %08x\n", hr);
1377
1378     IDirectDrawSurface_Release(surface4);
1379     IDirectDrawSurface_Release(surface3);
1380     IDirectDrawSurface_Release(surface2);
1381     IDirectDrawSurface_Release(surface1);
1382
1383     hr =IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
1384     ok(hr == DD_OK, "SetCooperativeLevel returned %08x\n", hr);
1385
1386     DestroyWindow(window);
1387 }
1388
1389 struct compare
1390 {
1391     DWORD width, height;
1392     DWORD caps, caps2;
1393     UINT mips;
1394 };
1395
1396 HRESULT WINAPI CubeTestLvl2Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1397 {
1398     UINT *mips = context;
1399
1400     (*mips)++;
1401     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1402                                              context,
1403                                              CubeTestLvl2Enum);
1404
1405     return DDENUMRET_OK;
1406 }
1407
1408 HRESULT WINAPI CubeTestLvl1Enum(IDirectDrawSurface7 *surface, DDSURFACEDESC2 *desc, void *context)
1409 {
1410     UINT mips = 0;
1411     UINT *num = (UINT *) context;
1412     static const struct compare expected[] =
1413     {
1414         {
1415             128, 128,
1416             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1417             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ,
1418             7
1419         },
1420         {
1421             128, 128,
1422             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1423             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ,
1424             7
1425         },
1426         {
1427             128, 128,
1428             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1429             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY,
1430             7
1431         },
1432         {
1433             128, 128,
1434             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1435             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY,
1436             7
1437         },
1438         {
1439             128, 128,
1440             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1441             DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX,
1442             7
1443         },
1444         {
1445             64, 64, /* This is the first mipmap */
1446             DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX,
1447             DDSCAPS2_MIPMAPSUBLEVEL | DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX,
1448             6
1449         },
1450     };
1451
1452     mips = 0;
1453     IDirectDrawSurface7_EnumAttachedSurfaces(surface,
1454                                              &mips,
1455                                              CubeTestLvl2Enum);
1456
1457     ok(desc->dwWidth == expected[*num].width, "Surface width is %d expected %d\n", desc->dwWidth, expected[*num].width);
1458     ok(desc->dwHeight == expected[*num].height, "Surface height is %d expected %d\n", desc->dwHeight, expected[*num].height);
1459     ok(desc->ddsCaps.dwCaps == expected[*num].caps, "Surface caps are %08x expected %08x\n", desc->ddsCaps.dwCaps, expected[*num].caps);
1460     ok(desc->ddsCaps.dwCaps2 == expected[*num].caps2, "Surface caps2 are %08x expected %08x\n", desc->ddsCaps.dwCaps2, expected[*num].caps2);
1461     ok(mips == expected[*num].mips, "Surface has %d mipmaps, expected %d\n", mips, expected[*num].mips);
1462
1463     (*num)++;
1464
1465     IDirectDrawSurface7_Release(surface);
1466
1467     return DDENUMRET_OK;
1468 }
1469
1470 static void CubeMapTest(void)
1471 {
1472     IDirectDraw7 *dd7 = NULL;
1473     IDirectDrawSurface7 *cubemap;
1474     DDSURFACEDESC2 ddsd;
1475     HRESULT hr;
1476     UINT num = 0;
1477     struct enumstruct ctx;
1478
1479     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1480     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1481
1482     memset(&ddsd, 0, sizeof(ddsd));
1483     ddsd.dwSize = sizeof(ddsd);
1484     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1485     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1486     ddsd.dwWidth = 128;
1487     ddsd.dwHeight = 128;
1488     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1489     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
1490
1491     /* D3DFMT_R5G6B5 */
1492     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1493     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1494     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1495     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1496     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1497
1498     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1499     ok(hr == DD_OK, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1500
1501     hr = IDirectDrawSurface7_GetSurfaceDesc(cubemap, &ddsd);
1502     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc returned %08x\n", hr);
1503     ok(ddsd.ddsCaps.dwCaps == (DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY | DDSCAPS_COMPLEX),
1504        "Root Caps are %08x\n", ddsd.ddsCaps.dwCaps);
1505     ok(ddsd.ddsCaps.dwCaps2 == (DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP),
1506        "Root Caps2 are %08x\n", ddsd.ddsCaps.dwCaps2);
1507
1508     IDirectDrawSurface7_EnumAttachedSurfaces(cubemap,
1509                                              &num,
1510                                              CubeTestLvl1Enum);
1511     ok(num == 6, "Surface has %d attachments\n", num);
1512     IDirectDrawSurface7_Release(cubemap);
1513
1514     /* What happens if I do not specify any faces? */
1515     memset(&ddsd, 0, sizeof(ddsd));
1516     ddsd.dwSize = sizeof(ddsd);
1517     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1518     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1519     ddsd.dwWidth = 128;
1520     ddsd.dwHeight = 128;
1521     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1522     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP;
1523
1524     /* D3DFMT_R5G6B5 */
1525     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1526     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1527     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1528     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1529     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1530
1531     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1532     ok(hr == DDERR_INVALIDPARAMS, "IDirectDraw7::CreateSurface asking for a cube map without faces returned %08x\n", hr);
1533
1534     /* Cube map faces without a cube map? */
1535     memset(&ddsd, 0, sizeof(ddsd));
1536     ddsd.dwSize = sizeof(ddsd);
1537     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1538     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1539     ddsd.dwWidth = 128;
1540     ddsd.dwHeight = 128;
1541     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1542     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_ALLFACES;
1543
1544     /* D3DFMT_R5G6B5 */
1545     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1546     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1547     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1548     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1549     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1550
1551     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1552     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1553
1554     memset(&ddsd, 0, sizeof(ddsd));
1555     ddsd.dwSize = sizeof(ddsd);
1556     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1557     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1558     ddsd.dwWidth = 128;
1559     ddsd.dwHeight = 128;
1560     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_SYSTEMMEMORY;
1561     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP_POSITIVEX;
1562
1563     /* D3DFMT_R5G6B5 */
1564     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_RGB;
1565     U1(U4(ddsd).ddpfPixelFormat).dwRGBBitCount = 16;
1566     U2(U4(ddsd).ddpfPixelFormat).dwRBitMask = 0xF800;
1567     U3(U4(ddsd).ddpfPixelFormat).dwGBitMask = 0x07E0;
1568     U4(U4(ddsd).ddpfPixelFormat).dwBBitMask = 0x001F;
1569
1570     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &cubemap, NULL);
1571     ok(hr == DDERR_INVALIDCAPS, "IDirectDraw7::CreateSurface returned %08x\n", hr);
1572
1573     /* Make sure everything is cleaned up properly. Use the enumSurfaces test infrastructure */
1574     memset(&ctx, 0, sizeof(ctx));
1575     memset(&ddsd, 0, sizeof(ddsd));
1576     ddsd.dwSize = sizeof(DDSURFACEDESC);
1577     hr = IDirectDraw_EnumSurfaces(lpDD, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, (DDSURFACEDESC *) &ddsd, (void *) &ctx, enumCB);
1578     ok(hr == DD_OK, "IDirectDraw_EnumSurfaces returned %08x\n", hr);
1579     ok(ctx.count == 0, "%d surfaces enumerated, expected 0\n", ctx.count);
1580
1581     IDirectDraw7_Release(dd7);
1582 }
1583
1584 static void test_lockrect_invalid(void)
1585 {
1586     unsigned int i, j;
1587
1588     RECT valid[] = {
1589         {60, 60, 68, 68},
1590         {60, 60, 60, 68},
1591         {60, 60, 68, 60},
1592         {120, 60, 128, 68},
1593         {60, 120, 68, 128},
1594     };
1595
1596     RECT invalid[] = {
1597         {68, 60, 60, 68},       /* left > right */
1598         {60, 68, 68, 60},       /* top > bottom */
1599         {-8, 60,  0, 68},       /* left < surface */
1600         {60, -8, 68,  0},       /* top < surface */
1601         {-16, 60, -8, 68},      /* right < surface */
1602         {60, -16, 68, -8},      /* bottom < surface */
1603         {60, 60, 136, 68},      /* right > surface */
1604         {60, 60, 68, 136},      /* bottom > surface */
1605         {136, 60, 144, 68},     /* left > surface */
1606         {60, 136, 68, 144},     /* top > surface */
1607     };
1608
1609     const DWORD dds_caps[] = {
1610         DDSCAPS_OFFSCREENPLAIN
1611     };
1612
1613     for (j = 0; j < (sizeof(dds_caps) / sizeof(*dds_caps)); ++j)
1614     {
1615         IDirectDrawSurface *surface = 0;
1616         DDSURFACEDESC surface_desc = {0};
1617         DDSURFACEDESC locked_desc = {0};
1618         HRESULT hr;
1619
1620         surface_desc.dwSize = sizeof(surface_desc);
1621         surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
1622         surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1623         surface_desc.ddsCaps.dwCaps = dds_caps[j];
1624         surface_desc.dwWidth = 128;
1625         surface_desc.dwHeight = 128;
1626         surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1627         U1(surface_desc.ddpfPixelFormat).dwRGBBitCount = 32;
1628         U2(surface_desc.ddpfPixelFormat).dwRBitMask = 0xFF0000;
1629         U3(surface_desc.ddpfPixelFormat).dwGBitMask = 0x00FF00;
1630         U4(surface_desc.ddpfPixelFormat).dwBBitMask = 0x0000FF;
1631
1632         hr = IDirectDraw_CreateSurface(lpDD, &surface_desc, &surface, NULL);
1633         ok(SUCCEEDED(hr), "CreateSurface failed (0x%08x)\n", hr);
1634         if (FAILED(hr)) {
1635             skip("failed to create surface\n");
1636             continue;
1637         }
1638
1639         for (i = 0; i < (sizeof(valid) / sizeof(*valid)); ++i)
1640         {
1641             RECT *rect = &valid[i];
1642
1643             memset(&locked_desc, 0, sizeof(locked_desc));
1644             locked_desc.dwSize = sizeof(locked_desc);
1645
1646             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1647             ok(SUCCEEDED(hr), "Lock failed (0x%08x) for rect [%d, %d]->[%d, %d]\n",
1648                     hr, rect->left, rect->top, rect->right, rect->bottom);
1649
1650             hr = IDirectDrawSurface_Unlock(surface, NULL);
1651             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1652         }
1653
1654         for (i = 0; i < (sizeof(invalid) / sizeof(*invalid)); ++i)
1655         {
1656             RECT *rect = &invalid[i];
1657
1658             memset(&locked_desc, 1, sizeof(locked_desc));
1659             locked_desc.dwSize = sizeof(locked_desc);
1660
1661             hr = IDirectDrawSurface_Lock(surface, rect, &locked_desc, DDLOCK_WAIT, NULL);
1662             ok(hr == DDERR_INVALIDPARAMS, "Lock returned 0x%08x for rect [%d, %d]->[%d, %d]"
1663                     ", expected DDERR_INVALIDPARAMS (0x%08x)\n", hr, rect->left, rect->top,
1664                     rect->right, rect->bottom, DDERR_INVALIDPARAMS);
1665             ok(!locked_desc.lpSurface, "IDirectDrawSurface_Lock did not set lpSurface in the surface desc to zero.\n");
1666         }
1667
1668         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1669         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = NULL) failed (0x%08x)\n", hr);
1670         hr = IDirectDrawSurface_Lock(surface, NULL, &locked_desc, DDLOCK_WAIT, NULL);
1671         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = NULL) returned 0x%08x\n", hr);
1672         if(SUCCEEDED(hr)) {
1673             hr = IDirectDrawSurface_Unlock(surface, NULL);
1674             ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1675         }
1676         hr = IDirectDrawSurface_Unlock(surface, NULL);
1677         ok(SUCCEEDED(hr), "Unlock failed (0x%08x)\n", hr);
1678
1679         memset(&locked_desc, 0, sizeof(locked_desc));
1680         locked_desc.dwSize = sizeof(locked_desc);
1681         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1682         ok(hr == DD_OK, "IDirectDrawSurface_Lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1683            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1684         hr = IDirectDrawSurface_Lock(surface, &valid[0], &locked_desc, DDLOCK_WAIT, NULL);
1685         ok(hr == DDERR_SURFACEBUSY, "Double lock(rect = [%d, %d]->[%d, %d]) failed (0x%08x)\n",
1686            valid[0].left, valid[0].top, valid[0].right, valid[0].bottom, hr);
1687
1688         /* Locking a different rectangle returns DD_OK, but it seems to break the surface.
1689          * Afterwards unlocking the surface fails(NULL rectangle, and both locked rectangles
1690          */
1691
1692         hr = IDirectDrawSurface_Unlock(surface, NULL);
1693         ok(hr == DD_OK, "Unlock returned (0x%08x)\n", hr);
1694
1695         IDirectDrawSurface_Release(surface);
1696     }
1697 }
1698
1699 static void CompressedTest(void)
1700 {
1701     HRESULT hr;
1702     IDirectDrawSurface7 *surface;
1703     DDSURFACEDESC2 ddsd, ddsd2;
1704     IDirectDraw7 *dd7 = NULL;
1705     RECT r = { 0, 0, 128, 128 };
1706     RECT r2 = { 32, 32, 64, 64 };
1707
1708     hr = IDirectDraw_QueryInterface(lpDD, &IID_IDirectDraw7, (void **) &dd7);
1709     ok(hr == DD_OK, "IDirectDraw::QueryInterface returned %08x\n", hr);
1710
1711     memset(&ddsd, 0, sizeof(ddsd));
1712     ddsd.dwSize = sizeof(ddsd);
1713     U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
1714     ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
1715     ddsd.dwWidth = 128;
1716     ddsd.dwHeight = 128;
1717     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1718     U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
1719     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1720
1721     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1722     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1723     if (FAILED(hr)) {
1724         skip("failed to create surface\n");
1725         return;
1726     }
1727
1728     memset(&ddsd2, 0, sizeof(ddsd2));
1729     ddsd2.dwSize = sizeof(ddsd2);
1730     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1731     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1732     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1733
1734     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1735        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1736     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1737     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1738     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1739        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1740     ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1741     ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1742     IDirectDrawSurface7_Release(surface);
1743
1744     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1745     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1746     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1747     if (FAILED(hr)) {
1748         skip("failed to create surface\n");
1749         return;
1750     }
1751
1752     memset(&ddsd2, 0, sizeof(ddsd2));
1753     ddsd2.dwSize = sizeof(ddsd2);
1754     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1755     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1756     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1757
1758     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1759        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1760     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1761     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1762     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1763        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1764     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1765     IDirectDrawSurface7_Release(surface);
1766
1767     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1768     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1769     ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1770     if (FAILED(hr)) {
1771         skip("failed to create surface\n");
1772         return;
1773     }
1774
1775     memset(&ddsd2, 0, sizeof(ddsd2));
1776     ddsd2.dwSize = sizeof(ddsd2);
1777     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1778     hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1779     ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1780
1781     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1782        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1783     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1784     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1785     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1786        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1787     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1788     ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1789
1790     memset(&ddsd2, 0, sizeof(ddsd2));
1791     ddsd2.dwSize = sizeof(ddsd2);
1792     U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1793
1794     /* Show that the description is not changed when locking the surface. What is really interesting
1795      * about this is that DDSD_LPSURFACE isn't set.
1796      */
1797     hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1798     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1799
1800     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1801        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1802     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1803     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1804     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1805        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1806     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1807     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1808
1809     hr = IDirectDrawSurface7_Unlock(surface, NULL);
1810     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1811
1812     /* Now what about a locking rect?  */
1813     hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1814     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1815
1816     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1817        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1818     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1819     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1820     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1821        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1822     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1823     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1824
1825     hr = IDirectDrawSurface7_Unlock(surface, &r);
1826     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1827
1828     /* Now what about a different locking offset? */
1829     hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1830     ok(hr == DD_OK, "Lock returned %08x\n", hr);
1831
1832     ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1833        "Surface desc flags: %08x\n", ddsd2.dwFlags);
1834     ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1835     ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1836     ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1837        "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1838     ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1839     ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1840
1841     hr = IDirectDrawSurface7_Unlock(surface, &r2);
1842     ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1843     IDirectDrawSurface7_Release(surface);
1844
1845     /* Try this with video memory. A kind of surprise. It still has the LINEARSIZE flag set,
1846      * but seems to have a pitch instead.
1847      */
1848     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
1849     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1850
1851     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1852     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW || hr == DDERR_INVALIDPARAMS,
1853        "CreateSurface returned %08x\n", hr);
1854
1855     /* Not supported everywhere */
1856     if(SUCCEEDED(hr))
1857     {
1858         memset(&ddsd2, 0, sizeof(ddsd2));
1859         ddsd2.dwSize = sizeof(ddsd2);
1860         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1861         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1862         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1863
1864         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1865         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1866         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1867         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1868         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1869         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1870         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1871         ok(ddsd2.ddsCaps.dwCaps2 == 0, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
1872         IDirectDrawSurface7_Release(surface);
1873
1874         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
1875         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1876         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1877
1878         memset(&ddsd2, 0, sizeof(ddsd2));
1879         ddsd2.dwSize = sizeof(ddsd2);
1880         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1881         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1882         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1883
1884         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1885         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1886         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1887         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1888         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1889         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1890         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1891         IDirectDrawSurface7_Release(surface);
1892
1893         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
1894         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1895         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
1896
1897         memset(&ddsd2, 0, sizeof(ddsd2));
1898         ddsd2.dwSize = sizeof(ddsd2);
1899         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1900         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1901         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1902
1903         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1904         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1905         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1906         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1907         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1908         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1909         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1910         ok(ddsd2.lpSurface == 0, "Surface memory is at %p, expected NULL\n", ddsd2.lpSurface);
1911
1912         memset(&ddsd2, 0, sizeof(ddsd2));
1913         ddsd2.dwSize = sizeof(ddsd2);
1914         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1915
1916         /* Show that the description is not changed when locking the surface. What is really interesting
1917         * about this is that DDSD_LPSURFACE isn't set.
1918         */
1919         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
1920         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1921
1922         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1923         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1924         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1925         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1926         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1927         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1928         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1929         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1930
1931         hr = IDirectDrawSurface7_Unlock(surface, NULL);
1932         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1933
1934         /* Now what about a locking rect?  */
1935         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
1936         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1937
1938         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1939         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1940         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1941         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1942         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1943         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1944         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1945         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1946
1947         hr = IDirectDrawSurface7_Unlock(surface, &r);
1948         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1949
1950         /* Now what about a different locking offset? */
1951         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
1952         ok(hr == DD_OK, "Lock returned %08x\n", hr);
1953
1954         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1955         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1956         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1957         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1958         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM),
1959         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1960         /* ATI drivers report a broken linear size, thus no need to clone the exact behaviour. nvidia reports the correct size */
1961         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
1962
1963         hr = IDirectDrawSurface7_Unlock(surface, &r2);
1964         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
1965
1966         IDirectDrawSurface7_Release(surface);
1967     }
1968     else
1969     {
1970         skip("Hardware DXTN textures not supported\n");
1971     }
1972
1973     /* What happens to managed textures? Interestingly, Windows reports them as being in system
1974      * memory. The linear size fits again.
1975      */
1976     ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1977     ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
1978     U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','1');
1979
1980     hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
1981     ok(hr == DD_OK || hr == DDERR_NOTEXTUREHW, "CreateSurface returned %08x\n", hr);
1982
1983     /* Not supported everywhere */
1984     if(SUCCEEDED(hr))
1985     {
1986         memset(&ddsd2, 0, sizeof(ddsd2));
1987         ddsd2.dwSize = sizeof(ddsd2);
1988         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
1989         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
1990         ok(hr == DD_OK, "GetSurfaceDesc returned %08x\n", hr);
1991
1992         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
1993         "Surface desc flags: %08x\n", ddsd2.dwFlags);
1994         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
1995         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
1996         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
1997         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
1998         ok(U1(ddsd2).dwLinearSize == 8192, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
1999         ok(ddsd2.ddsCaps.dwCaps2 == DDSCAPS2_TEXTUREMANAGE, "Caps2: %08x\n", ddsd2.ddsCaps.dwCaps2);
2000         IDirectDrawSurface7_Release(surface);
2001
2002         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','3');
2003         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2004         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
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         IDirectDrawSurface7_Release(surface);
2020
2021         U4(ddsd).ddpfPixelFormat.dwFourCC = MAKEFOURCC('D','X','T','5');
2022         hr = IDirectDraw7_CreateSurface(dd7, &ddsd, &surface, NULL);
2023         ok(hr == DD_OK, "CreateSurface returned %08x\n", hr);
2024
2025         memset(&ddsd2, 0, sizeof(ddsd2));
2026         ddsd2.dwSize = sizeof(ddsd2);
2027         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2028         hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd2);
2029         ok(hr == DD_OK, "GetSurfaceDesc 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 %p, expected NULL\n", ddsd2.lpSurface);
2039
2040         memset(&ddsd2, 0, sizeof(ddsd2));
2041         ddsd2.dwSize = sizeof(ddsd2);
2042         U4(ddsd2).ddpfPixelFormat.dwSize = sizeof(U4(ddsd2).ddpfPixelFormat);
2043
2044         /* Show that the description is not changed when locking the surface. What is really interesting
2045         * about this is that DDSD_LPSURFACE isn't set.
2046         */
2047         hr = IDirectDrawSurface7_Lock(surface, NULL, &ddsd2, DDLOCK_READONLY, 0);
2048         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2049
2050         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2051         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2052         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2053         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2054         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2055         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2056         ok(U1(ddsd2).dwLinearSize == 16384, "Linear size is %d\n", U1(ddsd2).dwLinearSize);
2057         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2058
2059         hr = IDirectDrawSurface7_Unlock(surface, NULL);
2060         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2061
2062         /* Now what about a locking rect?  */
2063         hr = IDirectDrawSurface7_Lock(surface, &r, &ddsd2, DDLOCK_READONLY, 0);
2064         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2065
2066         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2067         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2068         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2069         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2070         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2071         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2072         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2073         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2074
2075         hr = IDirectDrawSurface7_Unlock(surface, &r);
2076         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2077
2078         /* Now what about a different locking offset? */
2079         hr = IDirectDrawSurface7_Lock(surface, &r2, &ddsd2, DDLOCK_READONLY, 0);
2080         ok(hr == DD_OK, "Lock returned %08x\n", hr);
2081
2082         ok(ddsd2.dwFlags == (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LINEARSIZE),
2083         "Surface desc flags: %08x\n", ddsd2.dwFlags);
2084         ok(U4(ddsd2).ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Pixel format flags: %08x\n", U4(ddsd2).ddpfPixelFormat.dwFlags);
2085         ok(U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount == 0, "RGB bitcount: %08x\n", U1(U4(ddsd2).ddpfPixelFormat).dwRGBBitCount);
2086         ok(ddsd2.ddsCaps.dwCaps == (DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY),
2087         "Surface caps flags: %08x\n", ddsd2.ddsCaps.dwCaps);
2088         ok(U1(ddsd2).dwLinearSize == 16384, "\"Linear\" size is %d\n", U1(ddsd2).dwLinearSize);
2089         ok(ddsd2.lpSurface != 0, "Surface memory is at NULL\n");
2090
2091         hr = IDirectDrawSurface7_Unlock(surface, &r2);
2092         ok(hr == DD_OK, "Unlock returned %08x\n", hr);
2093
2094         IDirectDrawSurface7_Release(surface);
2095     }
2096     else
2097     {
2098         skip("Hardware DXTN textures not supported\n");
2099     }
2100
2101     IDirectDraw7_Release(dd7);
2102 }
2103
2104 static void SizeTest(void)
2105 {
2106     LPDIRECTDRAWSURFACE dsurface = NULL;
2107     DDSURFACEDESC desc;
2108     HRESULT ret;
2109     HWND window = CreateWindow( "static", "ddraw_test", WS_OVERLAPPEDWINDOW, 100, 100, 160, 160, NULL, NULL, NULL, NULL );
2110
2111     /* Create an offscreen surface surface without a size */
2112     ZeroMemory(&desc, sizeof(desc));
2113     desc.dwSize = sizeof(desc);
2114     desc.dwFlags = DDSD_CAPS;
2115     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2116     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2117     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without a size info returned %08x (dsurface=%p)\n", ret, dsurface);
2118     if(dsurface)
2119     {
2120         trace("Surface at %p\n", dsurface);
2121         IDirectDrawSurface_Release(dsurface);
2122         dsurface = NULL;
2123     }
2124
2125     /* Create an offscreen surface surface with only a width parameter */
2126     ZeroMemory(&desc, sizeof(desc));
2127     desc.dwSize = sizeof(desc);
2128     desc.dwFlags = DDSD_CAPS | DDSD_WIDTH;
2129     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2130     desc.dwWidth = 128;
2131     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2132     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without hight info returned %08x\n", ret);
2133     if(dsurface)
2134     {
2135         IDirectDrawSurface_Release(dsurface);
2136         dsurface = NULL;
2137     }
2138
2139     /* Create an offscreen surface surface with only a height parameter */
2140     ZeroMemory(&desc, sizeof(desc));
2141     desc.dwSize = sizeof(desc);
2142     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT;
2143     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2144     desc.dwHeight = 128;
2145     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2146     ok(ret == DDERR_INVALIDPARAMS, "Creating an offscreen plain surface without width info returned %08x\n", ret);
2147     if(dsurface)
2148     {
2149         IDirectDrawSurface_Release(dsurface);
2150         dsurface = NULL;
2151     }
2152
2153     /* Sanity check */
2154     ZeroMemory(&desc, sizeof(desc));
2155     desc.dwSize = sizeof(desc);
2156     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2157     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2158     desc.dwHeight = 128;
2159     desc.dwWidth = 128;
2160     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2161     ok(ret == DD_OK, "Creating an offscreen plain surface with width and height info returned %08x\n", ret);
2162     if(dsurface)
2163     {
2164         IDirectDrawSurface_Release(dsurface);
2165         dsurface = NULL;
2166     }
2167
2168     /* Test a primary surface size */
2169     ret = IDirectDraw_SetCooperativeLevel(lpDD, window, DDSCL_NORMAL);
2170     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2171
2172     ZeroMemory(&desc, sizeof(desc));
2173     desc.dwSize = sizeof(desc);
2174     desc.dwFlags = DDSD_CAPS;
2175     desc.ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE;
2176     desc.dwHeight = 128; /* Keep them set to  check what happens */
2177     desc.dwWidth = 128; /* Keep them set to  check what happens */
2178     ret = IDirectDraw_CreateSurface(lpDD, &desc, &dsurface, NULL);
2179     ok(ret == DD_OK, "Creating a primary surface without width and height info returned %08x\n", ret);
2180     if(dsurface)
2181     {
2182         ret = IDirectDrawSurface_GetSurfaceDesc(dsurface, &desc);
2183         ok(ret == DD_OK, "GetSurfaceDesc returned %x\n", ret);
2184
2185         IDirectDrawSurface_Release(dsurface);
2186         dsurface = NULL;
2187
2188         ok(desc.dwFlags & DDSD_WIDTH, "Primary surface doesn't have width set\n");
2189         ok(desc.dwFlags & DDSD_HEIGHT, "Primary surface doesn't have height set\n");
2190         ok(desc.dwWidth == GetSystemMetrics(SM_CXSCREEN), "Surface width differs from screen width\n");
2191         ok(desc.dwHeight == GetSystemMetrics(SM_CYSCREEN), "Surface height differs from screen height\n");
2192     }
2193     ret = IDirectDraw_SetCooperativeLevel(lpDD, NULL, DDSCL_NORMAL);
2194     ok(ret == DD_OK, "SetCooperativeLevel failed with %08x\n", ret);
2195 }
2196
2197 static void PrivateDataTest(void)
2198 {
2199     HRESULT hr;
2200     IDirectDrawSurface7 *surface7 = NULL;
2201     IDirectDrawSurface *surface = NULL;
2202     DDSURFACEDESC desc;
2203     ULONG ref, ref2;
2204     IUnknown *ptr;
2205     DWORD size = sizeof(IUnknown *);
2206
2207     ZeroMemory(&desc, sizeof(desc));
2208     desc.dwSize = sizeof(desc);
2209     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2210     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2211     desc.dwHeight = 128;
2212     desc.dwWidth = 128;
2213     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface, NULL);
2214     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2215     if(!surface)
2216     {
2217         return;
2218     }
2219     hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **) &surface7);
2220     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2221     if(!surface)
2222     {
2223         IDirectDrawSurface_Release(surface);
2224         return;
2225     }
2226
2227     /* This fails */
2228     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 0, DDSPD_IUNKNOWNPOINTER);
2229     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2230     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, 5, DDSPD_IUNKNOWNPOINTER);
2231     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2232     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *) * 2, DDSPD_IUNKNOWNPOINTER);
2233     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2234
2235     ref = getref((IUnknown *) lpDD);
2236     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7 /* Abuse this tag */, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2237     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2238     ref2 = getref((IUnknown *) lpDD);
2239     ok(ref2 == ref + 1, "Object reference is %d, expected %d\n", ref2, ref + 1);
2240     hr = IDirectDrawSurface7_FreePrivateData(surface7, &IID_IDirectDrawSurface7);
2241     ref2 = getref((IUnknown *) lpDD);
2242     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2243
2244     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2245     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2246     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, surface7, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2247     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2248     ref2 = getref((IUnknown *) lpDD);
2249     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2250
2251     hr = IDirectDrawSurface7_SetPrivateData(surface7, &IID_IDirectDrawSurface7, lpDD, sizeof(IUnknown *), DDSPD_IUNKNOWNPOINTER);
2252     ok(hr == DD_OK, "IDirectDrawSurface7_SetPrivateData failed with %08x\n", hr);
2253     hr = IDirectDrawSurface7_GetPrivateData(surface7, &IID_IDirectDrawSurface7, &ptr, &size);
2254     ok(hr == DD_OK, "IDirectDrawSurface7_GetPrivateData failed with %08x\n", hr);
2255     ref2 = getref((IUnknown *) lpDD);
2256     /* Object is NOT being addrefed */
2257     ok(ptr == (IUnknown *) lpDD, "Returned interface pointer is %p, expected %p\n", ptr, lpDD);
2258     ok(ref2 == ref + 1, "Object reference is %d, expected %d. ptr at %p, orig at %p\n", ref2, ref + 1, ptr, lpDD);
2259
2260     IDirectDrawSurface_Release(surface);
2261     IDirectDrawSurface7_Release(surface7);
2262
2263     /* Destroying the surface frees the held reference */
2264     ref2 = getref((IUnknown *) lpDD);
2265     ok(ref2 == ref, "Object reference is %d, expected %d\n", ref2, ref);
2266 }
2267
2268 static void BltParamTest(void)
2269 {
2270     IDirectDrawSurface *surface1 = NULL, *surface2 = NULL;
2271     DDSURFACEDESC desc;
2272     HRESULT hr;
2273     DDBLTFX BltFx;
2274     RECT valid = {10, 10, 20, 20};
2275     RECT invalid1 = {20, 10, 10, 20};
2276     RECT invalid2 = {20, 20, 20, 20};
2277     RECT invalid3 = {-1, -1, 20, 20};
2278     RECT invalid4 = {60, 60, 70, 70};
2279
2280     memset(&desc, 0, sizeof(desc));
2281     desc.dwSize = sizeof(desc);
2282     desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2283     desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2284     desc.dwHeight = 128;
2285     desc.dwWidth = 128;
2286     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface1, NULL);
2287     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2288
2289     desc.dwHeight = 64;
2290     desc.dwWidth = 64;
2291     hr = IDirectDraw_CreateSurface(lpDD, &desc, &surface2, NULL);
2292     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2293
2294     if(0)
2295     {
2296         /* This crashes */
2297         hr = IDirectDrawSurface_BltFast(surface1, 0, 0, NULL, NULL, 0);
2298         ok(hr == DD_OK, "BltFast from NULL surface returned %08x\n", hr);
2299     }
2300     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, NULL, 0);
2301     ok(hr == DD_OK, "BltFast from smaller to bigger surface returned %08x\n", hr);
2302     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, NULL, 0);
2303     ok(hr == DDERR_INVALIDRECT, "BltFast from bigger to smaller surface returned %08x\n", hr);
2304     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &valid, 0);
2305     ok(hr == DD_OK, "BltFast from bigger to smaller surface using a valid rectangle returned %08x\n", hr);
2306     hr = IDirectDrawSurface_BltFast(surface2, 60, 60, surface1, &valid, 0);
2307     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2308     hr = IDirectDrawSurface_BltFast(surface1, 90, 90, surface2, NULL, 0);
2309     ok(hr == DDERR_INVALIDRECT, "BltFast with a rectangle resulting in an off-surface write returned %08x\n", hr);
2310     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid1, 0);
2311     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 1 returned %08x\n", hr);
2312     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid2, 0);
2313     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 2 returned %08x\n", hr);
2314     hr = IDirectDrawSurface_BltFast(surface2, 0, 0, surface1, &invalid3, 0);
2315     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2316     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface2, &invalid4, 0);
2317     ok(hr == DDERR_INVALIDRECT, "BltFast with invalid rectangle 3 returned %08x\n", hr);
2318     hr = IDirectDrawSurface_BltFast(surface1, 0, 0, surface1, NULL, 0);
2319     ok(hr == DD_OK, "BltFast blitting a surface onto itself returned %08x\n", hr);
2320
2321     /* Blt(non-fast) tests */
2322     memset(&BltFx, 0, sizeof(BltFx));
2323     BltFx.dwSize = sizeof(BltFx);
2324     U5(BltFx).dwFillColor = 0xaabbccdd;
2325
2326     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2327     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a valid rectangle for color fill returned %08x\n", hr);
2328     hr = IDirectDrawSurface_Blt(surface1, &valid, NULL, &invalid3, DDBLT_COLORFILL, &BltFx);
2329     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a invalid, unused rectangle returned %08x\n", hr);
2330     hr = IDirectDrawSurface_Blt(surface2, &invalid1, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2331     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2332     hr = IDirectDrawSurface_Blt(surface2, &invalid2, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2333     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2334     hr = IDirectDrawSurface_Blt(surface2, &invalid3, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2335     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2336     hr = IDirectDrawSurface_Blt(surface2, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2337     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2338
2339     /* Valid on surface 1 */
2340     hr = IDirectDrawSurface_Blt(surface1, &invalid4, NULL, NULL, DDBLT_COLORFILL, &BltFx);
2341     ok(hr == DD_OK, "IDirectDrawSurface_Blt with a subrectangle fill returned %08x\n", hr);
2342
2343     /* Works - stretched blit */
2344     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, NULL, 0, NULL);
2345     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a smaller to a bigger surface returned %08x\n", hr);
2346     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, NULL, 0, NULL);
2347     ok(hr == DD_OK, "IDirectDrawSurface_Blt from a bigger to a smaller surface %08x\n", hr);
2348
2349     /* Invalid dest rects in sourced blits */
2350     hr = IDirectDrawSurface_Blt(surface2, &invalid1, surface1, NULL, 0, NULL);
2351     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2352     hr = IDirectDrawSurface_Blt(surface2, &invalid2, surface1, NULL, 0, NULL);
2353     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2354     hr = IDirectDrawSurface_Blt(surface2, &invalid3, surface1, NULL, 0, NULL);
2355     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2356     hr = IDirectDrawSurface_Blt(surface2, &invalid4, surface1, NULL, 0, NULL);
2357     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2358
2359     /* Invalid src rects */
2360     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid1, 0, NULL);
2361     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 1 returned %08x\n", hr);
2362     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid2, 0, NULL);
2363     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 2 returned %08x\n", hr);
2364     hr = IDirectDrawSurface_Blt(surface2, NULL, surface1, &invalid3, 0, NULL);
2365     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 3 returned %08x\n", hr);
2366     hr = IDirectDrawSurface_Blt(surface1, NULL, surface2, &invalid4, 0, NULL);
2367     ok(hr == DDERR_INVALIDRECT, "IDirectDrawSurface_Blt with a with invalid rectangle 4 returned %08x\n", hr);
2368
2369     IDirectDrawSurface_Release(surface1);
2370     IDirectDrawSurface_Release(surface2);
2371 }
2372
2373 static void PaletteTest(void)
2374 {
2375     HRESULT hr;
2376     LPDIRECTDRAWSURFACE lpSurf = NULL;
2377     DDSURFACEDESC ddsd;
2378     IDirectDrawPalette *palette = NULL;
2379     PALETTEENTRY Table[256];
2380     PALETTEENTRY palEntries[256];
2381     int i;
2382
2383     for(i=0; i<256; i++)
2384     {
2385         Table[i].peRed   = 0xff;
2386         Table[i].peGreen = 0;
2387         Table[i].peBlue  = 0;
2388         Table[i].peFlags = 0;
2389     }
2390
2391     /* Create a 8bit palette without DDPCAPS_ALLOW256 set */
2392     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_8BIT, Table, &palette, NULL);
2393     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2394     if (FAILED(hr)) goto err;
2395     /* Read back the palette and verify the entries. Without DDPCAPS_ALLOW256 set
2396     /  entry 0 and 255 should have been overwritten with black and white */
2397     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2398     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2399     if(hr == DD_OK)
2400     {
2401         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2402            "Palette entry 0 of a palette without DDPCAPS_ALLOW256 set should be (0,0,0) but it is (%d,%d,%d)\n",
2403            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2404         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2405            "Palette entry 255 of a palette without DDPCAPS_ALLOW256 set should be (255,255,255) but it is (%d,%d,%d)\n",
2406            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2407
2408         /* Entry 1-254 should contain red */
2409         for(i=1; i<255; i++)
2410             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2411                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2412                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2413     }
2414
2415     /* CreatePalette without DDPCAPS_ALLOW256 ignores entry 0 and 255,
2416     /  now check we are able to update the entries afterwards. */
2417     IDirectDrawPalette_SetEntries(palette , 0, 0, 256, &Table[0]);
2418     ok(hr == DD_OK, "SetEntries failed with %08x\n", hr);
2419     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2420     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2421     if(hr == DD_OK)
2422     {
2423         ok((palEntries[0].peRed == 0) && (palEntries[0].peGreen == 0) && (palEntries[0].peBlue == 0),
2424            "Palette entry 0 should have been set to (0,0,0) but it contains (%d,%d,%d)\n",
2425            palEntries[0].peRed, palEntries[0].peGreen, palEntries[0].peBlue);
2426         ok((palEntries[255].peRed == 255) && (palEntries[255].peGreen == 255) && (palEntries[255].peBlue == 255),
2427            "Palette entry 255 should have been set to (255,255,255) but it contains (%d,%d,%d)\n",
2428            palEntries[255].peRed, palEntries[255].peGreen, palEntries[255].peBlue);
2429     }
2430     IDirectDrawPalette_Release(palette);
2431
2432     /* Create a 8bit palette with DDPCAPS_ALLOW256 set */
2433     hr = IDirectDraw_CreatePalette(lpDD, DDPCAPS_ALLOW256 | DDPCAPS_8BIT, Table, &palette, NULL);
2434     ok(hr == DD_OK, "CreatePalette failed with %08x\n", hr);
2435     if (FAILED(hr)) goto err;
2436
2437     IDirectDrawPalette_GetEntries(palette , 0, 0, 256, &palEntries[0]);
2438     ok(hr == DD_OK, "GetEntries failed with %08x\n", hr);
2439     if(hr == DD_OK)
2440     {
2441         /* All entries should contain red */
2442         for(i=0; i<256; i++)
2443             ok((palEntries[i].peRed == 255) && (palEntries[i].peGreen == 0) && (palEntries[i].peBlue == 0),
2444                "Palette entry %d should have contained (255,0,0) but was set to %d,%d,%d)\n",
2445                i, palEntries[i].peRed, palEntries[i].peGreen, palEntries[i].peBlue);
2446     }
2447
2448     /* Try to set palette to a non-palettized surface */
2449     ddsd.dwSize = sizeof(ddsd);
2450     ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
2451     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
2452     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
2453     ddsd.dwWidth = 800;
2454     ddsd.dwHeight = 600;
2455     ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
2456     U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
2457     U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
2458     U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
2459     U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
2460     hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSurf, NULL);
2461     ok(hr==DD_OK, "CreateSurface returned: %x\n",hr);
2462     if (FAILED(hr)) {
2463         skip("failed to create surface\n");
2464         goto err;
2465     }
2466
2467     hr = IDirectDrawSurface_SetPalette(lpSurf, palette);
2468     ok(hr == DDERR_INVALIDPIXELFORMAT, "CreateSurface returned: %x\n",hr);
2469
2470     IDirectDrawPalette_Release(palette);
2471     palette = NULL;
2472
2473     hr = IDirectDrawSurface_GetPalette(lpSurf, &palette);
2474     ok(hr == DDERR_NOPALETTEATTACHED, "CreateSurface returned: %x\n",hr);
2475
2476     err:
2477
2478     if (lpSurf) IDirectDrawSurface_Release(lpSurf);
2479     if (palette) IDirectDrawPalette_Release(palette);
2480 }
2481
2482 static void StructSizeTest(void)
2483 {
2484     IDirectDrawSurface *surface1;
2485     IDirectDrawSurface7 *surface7;
2486     union {
2487         DDSURFACEDESC desc1;
2488         DDSURFACEDESC2 desc2;
2489         char blob[1024]; /* To get a bunch of writable memory */
2490     } desc;
2491     DDSURFACEDESC create;
2492     HRESULT hr;
2493
2494     memset(&desc, 0, sizeof(desc));
2495     memset(&create, 0, sizeof(create));
2496
2497     memset(&create, 0, sizeof(create));
2498     create.dwSize = sizeof(create);
2499     create.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
2500     create.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
2501     create.dwHeight = 128;
2502     create.dwWidth = 128;
2503     hr = IDirectDraw_CreateSurface(lpDD, &create, &surface1, NULL);
2504     ok(hr == DD_OK, "Creating an offscreen plain surface failed with %08x\n", hr);
2505     hr = IDirectDrawSurface_QueryInterface(surface1, &IID_IDirectDrawSurface7, (void **) &surface7);
2506     ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed with %08x\n", hr);
2507
2508     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2509     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2510     ok(hr == DD_OK, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2511     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2512     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2513
2514     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2515     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2516     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2517     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2518     ok(hr == DD_OK, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2519
2520     desc.desc2.dwSize = 0;
2521     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2522     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2523     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2524     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size 0 returned %08x\n", hr);
2525
2526     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2527     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2528     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2529     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2530     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2531
2532     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2533     hr = IDirectDrawSurface_GetSurfaceDesc(surface1, &desc.desc1);
2534     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2535     hr = IDirectDrawSurface7_GetSurfaceDesc(surface7, &desc.desc2);
2536     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_GetSurfaceDesc with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2537
2538     /* Tests for Lock() */
2539
2540     desc.desc1.dwSize = sizeof(DDSURFACEDESC);
2541     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2542     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2543     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2544     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2545     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2546     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) returned %08x\n", hr);
2547     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2548     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC), "Destination size was changed to %d\n", desc.desc1.dwSize);
2549
2550     desc.desc2.dwSize = sizeof(DDSURFACEDESC2);
2551     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2552     ok(hr == DD_OK, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2553     ok(desc.desc1.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2554     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2555     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2556     ok(hr == DD_OK, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) returned %08x\n", hr);
2557     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2558     ok(desc.desc2.dwSize == sizeof(DDSURFACEDESC2), "Destination size was changed to %d\n", desc.desc1.dwSize);
2559
2560     desc.desc2.dwSize = 0;
2561     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2562     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size 0 returned %08x\n", hr);
2563     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2564     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2565     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size 0 returned %08x\n", hr);
2566     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2567
2568     desc.desc1.dwSize = sizeof(DDSURFACEDESC) + 1;
2569     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2570     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2571     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2572     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2573     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC) + 1 returned %08x\n", hr);
2574     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2575
2576     desc.desc2.dwSize = sizeof(DDSURFACEDESC2) + 1;
2577     hr = IDirectDrawSurface_Lock(surface1, NULL, &desc.desc1, 0, 0);
2578     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2579     if(SUCCEEDED(hr)) IDirectDrawSurface_Unlock(surface1, NULL);
2580     hr = IDirectDrawSurface7_Lock(surface7, NULL, &desc.desc2, 0, 0);
2581     ok(hr == DDERR_INVALIDPARAMS, "IDirectDrawSurface7_Lock with desc size sizeof(DDSURFACEDESC2) + 1returned %08x\n", hr);
2582     if(SUCCEEDED(hr)) IDirectDrawSurface7_Unlock(surface7, NULL);
2583
2584     IDirectDrawSurface7_Release(surface7);
2585     IDirectDrawSurface_Release(surface1);
2586 }
2587
2588 START_TEST(dsurface)
2589 {
2590     if (!CreateDirectDraw())
2591         return;
2592     MipMapCreationTest();
2593     SrcColorKey32BlitTest();
2594     QueryInterface();
2595     GetDDInterface_1();
2596     GetDDInterface_2();
2597     GetDDInterface_4();
2598     GetDDInterface_7();
2599     EnumTest();
2600     AttachmentTest();
2601     AttachmentTest7();
2602     CubeMapTest();
2603     test_lockrect_invalid();
2604     CompressedTest();
2605     SizeTest();
2606     PrivateDataTest();
2607     BltParamTest();
2608     StructSizeTest();
2609     PaletteTest();
2610     ReleaseDirectDraw();
2611 }