msxml3: Fix attributes formatting.
[wine/multimedia.git] / dlls / ddrawex / tests / surface.c
blob099c6d2c27b18d8442453cdc80245edc7eca5d4f
1 /*
2 * Unit tests for ddrawex surfaces
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 #define COBJMACROS
19 /* For IID_IDirectDraw3 - it is not in dxguid.dll */
20 #define INITGUID
22 #include <assert.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "ddraw.h"
27 #include "ddrawex.h"
28 #include "unknwn.h"
30 static IDirectDrawFactory *factory;
31 static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
33 static IDirectDraw *createDD(void)
35 HRESULT hr;
36 IDirectDraw *dd;
38 hr = IDirectDrawFactory_CreateDirectDraw(factory, NULL, NULL, DDSCL_NORMAL, 0,
39 0, &dd);
40 ok(hr == DD_OK, "Failed to create an IDirectDraw interface, hr = 0x%08x\n", hr);
41 return SUCCEEDED(hr) ? dd : NULL;
44 static void dctest_surf(IDirectDrawSurface *surf, int ddsdver) {
45 HRESULT hr;
46 HDC dc, dc2 = (HDC) 0x1234;
47 DDSURFACEDESC ddsd;
48 DDSURFACEDESC2 ddsd2;
50 memset(&ddsd, 0, sizeof(ddsd));
51 ddsd.dwSize = sizeof(ddsd);
52 memset(&ddsd2, 0, sizeof(ddsd2));
53 ddsd2.dwSize = sizeof(ddsd2);
55 hr = IDirectDrawSurface_GetDC(surf, &dc);
56 ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
58 hr = IDirectDrawSurface_GetDC(surf, &dc);
59 ok(hr == DDERR_DCALREADYCREATED, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
60 ok(dc2 == (HDC) 0x1234, "The failed GetDC call changed the dc: %p\n", dc2);
62 hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
63 ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_SURFACEBUSY\n", hr);
65 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
66 ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
67 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
68 ok(hr == DDERR_NODC, "IDirectDrawSurface_ReleaseDC returned 0x%08x, expected DDERR_NODC\n", hr);
71 static void GetDCTest_main(DDSURFACEDESC *ddsd, DDSURFACEDESC2 *ddsd2, void (*testfunc)(IDirectDrawSurface *surf, int ddsdver))
73 IDirectDrawSurface *surf;
74 IDirectDrawSurface2 *surf2;
75 IDirectDrawSurface2 *surf3;
76 IDirectDrawSurface4 *surf4;
77 HRESULT hr;
78 IDirectDraw *dd1 = createDD();
79 IDirectDraw2 *dd2;
80 IDirectDraw3 *dd3;
81 IDirectDraw4 *dd4;
83 hr = IDirectDraw_CreateSurface(dd1, ddsd, &surf, NULL);
84 if (hr == DDERR_UNSUPPORTEDMODE) {
85 win_skip("Unsupported mode\n");
86 return;
88 ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr);
89 testfunc(surf, 1);
90 IDirectDrawSurface_Release(surf);
92 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw2, (void **) &dd2);
93 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
95 hr = IDirectDraw2_CreateSurface(dd2, ddsd, &surf, NULL);
96 ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr);
97 testfunc(surf, 1);
99 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2);
100 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
101 testfunc((IDirectDrawSurface *) surf2, 1);
103 IDirectDrawSurface2_Release(surf2);
104 IDirectDrawSurface_Release(surf);
105 IDirectDraw2_Release(dd2);
107 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw3, (void **) &dd3);
108 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
110 hr = IDirectDraw3_CreateSurface(dd3, ddsd, &surf, NULL);
111 ok(hr == DD_OK, "IDirectDraw3_CreateSurface failed: 0x%08x\n", hr);
112 testfunc(surf, 1);
114 hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface3, (void **) &surf3);
115 ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr);
116 testfunc((IDirectDrawSurface *) surf3, 1);
118 IDirectDrawSurface3_Release(surf3);
119 IDirectDrawSurface_Release(surf);
120 IDirectDraw3_Release(dd3);
122 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw4, (void **) &dd4);
123 ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr);
125 surf = NULL;
126 hr = IDirectDraw4_CreateSurface(dd4, ddsd2, &surf4, NULL);
127 ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr);
128 testfunc((IDirectDrawSurface *) surf4, 2);
130 IDirectDrawSurface4_Release(surf4);
131 IDirectDraw4_Release(dd4);
133 IDirectDraw_Release(dd1);
136 static void GetDCTest(void)
138 DDSURFACEDESC ddsd;
139 DDSURFACEDESC2 ddsd2;
141 memset(&ddsd, 0, sizeof(ddsd));
142 ddsd.dwSize = sizeof(ddsd);
143 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
144 ddsd.dwWidth = 64;
145 ddsd.dwHeight = 64;
146 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
147 memset(&ddsd2, 0, sizeof(ddsd2));
148 ddsd2.dwSize = sizeof(ddsd2);
149 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
150 ddsd2.dwWidth = 64;
151 ddsd2.dwHeight = 64;
152 ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
154 GetDCTest_main(&ddsd, &ddsd2, dctest_surf);
157 static void CapsTest(void)
159 DDSURFACEDESC ddsd;
160 IDirectDraw *dd1 = createDD();
161 IDirectDrawSurface *surf;
162 HRESULT hr;
164 memset(&ddsd, 0, sizeof(ddsd));
165 ddsd.dwSize = sizeof(ddsd);
166 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
167 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
168 ddsd.dwWidth = 64;
169 ddsd.dwHeight = 64;
170 hr = IDirectDraw_CreateSurface(dd1, &ddsd, &surf, NULL);
171 if (hr == DDERR_UNSUPPORTEDMODE) {
172 win_skip("Unsupported mode\n");
173 return;
175 ok(hr == DD_OK, "Creating a SYSMEM | VIDMEM surface returned 0x%08x, expected DD_OK\n", hr);
176 if(surf) IDirectDrawSurface_Release(surf);
178 IDirectDraw_Release(dd1);
181 static void dctest_sysvidmem(IDirectDrawSurface *surf, int ddsdver) {
182 HRESULT hr;
183 HDC dc, dc2 = (HDC) 0x1234;
184 DDSURFACEDESC ddsd;
185 DDSURFACEDESC2 ddsd2;
187 memset(&ddsd, 0, sizeof(ddsd));
188 ddsd.dwSize = sizeof(ddsd);
189 memset(&ddsd2, 0, sizeof(ddsd2));
190 ddsd2.dwSize = sizeof(ddsd2);
192 hr = IDirectDrawSurface_GetDC(surf, &dc);
193 ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
195 hr = IDirectDrawSurface_GetDC(surf, &dc2);
196 ok(hr == DD_OK, "IDirectDrawSurface_GetDC failed: 0x%08x\n", hr);
197 ok(dc == dc2, "Got two different DCs\n");
199 hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
200 ok(hr == DD_OK, "IDirectDrawSurface_Lock returned 0x%08x, expected DD_OK\n", hr);
202 hr = IDirectDrawSurface_Lock(surf, NULL, ddsdver == 1 ? &ddsd : ((DDSURFACEDESC *) &ddsd2), 0, NULL);
203 ok(hr == DDERR_SURFACEBUSY, "IDirectDrawSurface_Lock returned 0x%08x, expected DDERR_SURFACEBUSY\n", hr);
205 hr = IDirectDrawSurface_Unlock(surf, NULL);
206 ok(hr == DD_OK, "IDirectDrawSurface_Unlock returned 0x%08x, expected DD_OK\n", hr);
207 hr = IDirectDrawSurface_Unlock(surf, NULL);
208 ok(hr == DDERR_NOTLOCKED, "IDirectDrawSurface_Unlock returned 0x%08x, expected DDERR_NOTLOCKED\n", hr);
210 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
211 ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
212 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
213 ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
214 /* That works any number of times... */
215 hr = IDirectDrawSurface_ReleaseDC(surf, dc);
216 ok(hr == DD_OK, "IDirectDrawSurface_ReleaseDC failed: 0x%08x\n", hr);
219 static void SysVidMemTest(void)
221 DDSURFACEDESC ddsd;
222 DDSURFACEDESC2 ddsd2;
224 memset(&ddsd, 0, sizeof(ddsd));
225 ddsd.dwSize = sizeof(ddsd);
226 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
227 ddsd.dwWidth = 64;
228 ddsd.dwHeight = 64;
229 ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
230 memset(&ddsd2, 0, sizeof(ddsd2));
231 ddsd2.dwSize = sizeof(ddsd2);
232 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
233 ddsd2.dwWidth = 64;
234 ddsd2.dwHeight = 64;
235 ddsd2.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_VIDEOMEMORY;
237 GetDCTest_main(&ddsd, &ddsd2, dctest_sysvidmem);
240 static void test_surface_from_dc3(void)
242 IDirectDrawSurface3 *surf3;
243 IDirectDrawSurface *surf1;
244 IDirectDrawSurface *tmp;
245 DDSURFACEDESC ddsd;
246 IDirectDraw3 *dd3;
247 IDirectDraw *dd1;
248 HRESULT hr;
249 HDC dc;
251 dd1 = createDD();
252 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw3, (void **)&dd3);
253 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed, hr %#x.\n", hr);
254 IDirectDraw_Release(dd1);
256 memset(&ddsd, 0, sizeof(ddsd));
257 ddsd.dwSize = sizeof(ddsd);
258 ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
259 ddsd.dwWidth = 64;
260 ddsd.dwHeight = 64;
261 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
263 hr = IDirectDraw3_CreateSurface(dd3, &ddsd, &surf1, NULL);
264 if (hr == DDERR_UNSUPPORTEDMODE) {
265 win_skip("Unsupported mode\n");
266 IDirectDraw3_Release(dd3);
267 return;
269 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x.\n", hr);
271 hr = IDirectDrawSurface3_QueryInterface(surf1, &IID_IDirectDrawSurface, (void **)&surf3);
272 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
273 IDirectDrawSurface_Release(surf1);
275 hr = IDirectDrawSurface3_GetDC(surf3, &dc);
276 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
278 hr = IDirectDraw3_GetSurfaceFromDC(dd3, dc, NULL);
279 ok(hr == E_POINTER, "Expected E_POINTER, got %#x.\n", hr);
281 hr = IDirectDraw3_GetSurfaceFromDC(dd3, dc, &tmp);
282 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
283 ok((IDirectDrawSurface3 *)tmp == surf3, "Expected surface != %p.\n", surf3);
285 IUnknown_Release(tmp);
287 hr = IDirectDrawSurface3_ReleaseDC(surf3, dc);
288 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
290 dc = CreateCompatibleDC(NULL);
291 ok(!!dc, "CreateCompatibleDC failed.\n");
293 tmp = (IDirectDrawSurface *)0xdeadbeef;
294 hr = IDirectDraw3_GetSurfaceFromDC(dd3, dc, &tmp);
295 ok(hr == DDERR_NOTFOUND, "Expected DDERR_NOTFOUND, got %#x.\n", hr);
296 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
298 ok(DeleteDC(dc), "DeleteDC failed.\n");
300 IDirectDrawSurface3_Release(surf3);
301 IDirectDraw3_Release(dd3);
304 DEFINE_GUID(guid, 0x38594b23, 0x2311, 0x4332, 0x95, 0xde, 0x2b, 0x0c, 0x61, 0xbf, 0x7b, 0x84);
306 static void test_surface_from_dc4(void)
308 IDirectDrawSurface4 *surf4;
309 IDirectDrawSurface *surf1;
310 DDSURFACEDESC2 ddsd2;
311 IUnknown *tmp, *tmp2;
312 IDirectDraw4 *dd4;
313 IDirectDraw *dd1;
314 DWORD priv, size;
315 HRESULT hr;
316 HDC dc;
318 dd1 = createDD();
319 hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw4, (void **)&dd4);
320 if (hr == E_NOINTERFACE) {
321 win_skip("DirectDraw4 is not supported\n");
322 IDirectDraw_Release(dd1);
323 return;
325 ok(SUCCEEDED(hr), "IDirectDraw_QueryInterface failed, hr %#x.\n", hr);
326 IDirectDraw_Release(dd1);
328 memset(&ddsd2, 0, sizeof(ddsd2));
329 ddsd2.dwSize = sizeof(ddsd2);
330 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
331 ddsd2.dwWidth = 64;
332 ddsd2.dwHeight = 64;
333 ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
335 hr = IDirectDraw4_CreateSurface(dd4, &ddsd2, &surf4, NULL);
336 if (hr == DDERR_UNSUPPORTEDMODE) {
337 win_skip("Unsupported mode\n");
338 IDirectDraw3_Release(dd4);
339 return;
341 ok(SUCCEEDED(hr), "CreateSurface failed, hr %#x.\n", hr);
343 hr = IDirectDrawSurface4_QueryInterface(surf4, &IID_IDirectDrawSurface, (void **)&surf1);
344 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
346 priv = 0xdeadbeef;
347 size = sizeof(priv);
348 hr = IDirectDrawSurface4_SetPrivateData(surf4, &guid, &priv, size, 0);
349 ok(SUCCEEDED(hr), "SetPrivateData failed, hr %#x.\n", hr);
351 priv = 0;
352 hr = IDirectDrawSurface4_GetPrivateData(surf4, &guid, &priv, &size);
353 ok(SUCCEEDED(hr), "GetPrivateData failed, hr %#x.\n", hr);
354 ok(priv == 0xdeadbeef, "Expected private data 0xdeadbeef, got %#x.\n", priv);
356 hr = IDirectDrawSurface4_GetDC(surf4, &dc);
357 ok(SUCCEEDED(hr), "GetDC failed, hr %#x.\n", hr);
359 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, NULL);
360 ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %#x.\n", hr);
362 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
363 ok(SUCCEEDED(hr), "GetSurfaceFromDC failed, hr %#x.\n", hr);
364 ok((IDirectDrawSurface4 *)tmp != surf4, "Expected surface != %p.\n", surf4);
366 hr = IUnknown_QueryInterface(tmp, &IID_IDirectDrawSurface, (void **)&tmp2);
367 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
368 ok(tmp2 == tmp, "Expected %p, got %p.\n", tmp, tmp2);
369 ok((IDirectDrawSurface *)tmp2 != surf1, "Expected surface != %p.\n", surf1);
370 IUnknown_Release(tmp2);
372 hr = IUnknown_QueryInterface(tmp, &IID_IDirectDrawSurface4, (void **)&tmp2);
373 ok(SUCCEEDED(hr), "QueryInterface failed, hr %#x.\n", hr);
374 ok((IDirectDrawSurface4 *)tmp2 != surf4, "Expected surface != %p.\n", surf4);
376 priv = 0;
377 hr = IDirectDrawSurface4_GetPrivateData((IDirectDrawSurface4 *)tmp2, &guid, &priv, &size);
378 ok(SUCCEEDED(hr), "GetPrivateData failed, hr %#x.\n", hr);
379 ok(priv == 0xdeadbeef, "Expected private data 0xdeadbeef, got %#x.\n", priv);
380 IUnknown_Release(tmp2);
382 IUnknown_Release(tmp);
384 hr = IDirectDrawSurface4_ReleaseDC(surf4, dc);
385 ok(SUCCEEDED(hr), "ReleaseDC failed, hr %#x.\n", hr);
387 dc = CreateCompatibleDC(NULL);
388 ok(!!dc, "CreateCompatibleDC failed.\n");
390 tmp = (IUnknown *)0xdeadbeef;
391 hr = IDirectDraw4_GetSurfaceFromDC(dd4, dc, (IDirectDrawSurface4 **)&tmp);
392 ok(hr == DDERR_NOTFOUND, "Expected DDERR_NOTFOUND, got %#x.\n", hr);
393 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
395 ok(DeleteDC(dc), "DeleteDC failed.\n");
397 tmp = (IUnknown *)0xdeadbeef;
398 hr = IDirectDraw4_GetSurfaceFromDC(dd4, NULL, (IDirectDrawSurface4 **)&tmp);
399 ok(hr == DDERR_NOTFOUND, "Expected DDERR_NOTFOUND, got %#x.\n", hr);
400 ok(!tmp, "Expected surface NULL, got %p.\n", tmp);
402 IDirectDrawSurface_Release(surf1);
403 IDirectDrawSurface4_Release(surf4);
404 IDirectDraw4_Release(dd4);
407 START_TEST(surface)
409 IClassFactory *classfactory = NULL;
410 ULONG ref;
411 HRESULT hr;
412 HMODULE hmod = LoadLibrary("ddrawex.dll");
413 if(hmod == NULL) {
414 skip("Failed to load ddrawex.dll\n");
415 return;
417 pDllGetClassObject = (void*)GetProcAddress(hmod, "DllGetClassObject");
418 if(pDllGetClassObject == NULL) {
419 skip("Failed to get DllGetClassObject\n");
420 return;
423 hr = pDllGetClassObject(&CLSID_DirectDrawFactory, &IID_IClassFactory, (void **) &classfactory);
424 ok(hr == S_OK, "Failed to create a IClassFactory\n");
425 if (FAILED(hr)) {
426 skip("Failed to get DirectDrawFactory\n");
427 return;
429 hr = IClassFactory_CreateInstance(classfactory, NULL, &IID_IDirectDrawFactory, (void **) &factory);
430 ok(hr == S_OK, "Failed to create a IDirectDrawFactory\n");
431 if (FAILED(hr)) {
432 IClassFactory_Release(classfactory);
433 skip("Failed to get a DirectDrawFactory\n");
434 return;
437 GetDCTest();
438 CapsTest();
439 SysVidMemTest();
440 test_surface_from_dc3();
441 test_surface_from_dc4();
443 ref = IDirectDrawFactory_Release(factory);
444 ok(ref == 0, "IDirectDrawFactory not cleanly released\n");
445 ref = IClassFactory_Release(classfactory);
446 todo_wine ok(ref == 1, "IClassFactory refcount wrong, ref = %u\n", ref);