winemac: Consolidate mouse move handling into -[WineApplicationController handleMouse...
[wine.git] / dlls / ddraw / tests / ddraw7.c
blob3d8c70d2fce300b42e807cdebae7b208baed23ae
1 /*
2 * Copyright 2006, 2012-2013 Stefan Dösinger for CodeWeavers
3 * Copyright 2011 Henri Verbeet for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include "wine/test.h"
22 #include <limits.h>
23 #include "d3d.h"
25 static HRESULT (WINAPI *pDirectDrawCreateEx)(GUID *guid, void **ddraw, REFIID iid, IUnknown *outer_unknown);
27 struct vec2
29 float x, y;
32 struct vec3
34 float x, y, z;
37 struct vec4
39 float x, y, z, w;
42 struct create_window_thread_param
44 HWND window;
45 HANDLE window_created;
46 HANDLE destroy_window;
47 HANDLE thread;
50 static BOOL compare_float(float f, float g, unsigned int ulps)
52 int x = *(int *)&f;
53 int y = *(int *)&g;
55 if (x < 0)
56 x = INT_MIN - x;
57 if (y < 0)
58 y = INT_MIN - y;
60 if (abs(x - y) > ulps)
61 return FALSE;
63 return TRUE;
66 static BOOL compare_vec3(struct vec3 *vec, float x, float y, float z, unsigned int ulps)
68 return compare_float(vec->x, x, ulps)
69 && compare_float(vec->y, y, ulps)
70 && compare_float(vec->z, z, ulps);
73 static BOOL compare_vec4(struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
75 return compare_float(vec->x, x, ulps)
76 && compare_float(vec->y, y, ulps)
77 && compare_float(vec->z, z, ulps)
78 && compare_float(vec->w, w, ulps);
81 static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
83 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
84 c1 >>= 8; c2 >>= 8;
85 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
86 c1 >>= 8; c2 >>= 8;
87 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
88 c1 >>= 8; c2 >>= 8;
89 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
90 return TRUE;
93 static DWORD WINAPI create_window_thread_proc(void *param)
95 struct create_window_thread_param *p = param;
96 DWORD res;
97 BOOL ret;
99 p->window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
100 0, 0, 640, 480, 0, 0, 0, 0);
101 ret = SetEvent(p->window_created);
102 ok(ret, "SetEvent failed, last error %#x.\n", GetLastError());
104 for (;;)
106 MSG msg;
108 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
109 DispatchMessage(&msg);
110 res = WaitForSingleObject(p->destroy_window, 100);
111 if (res == WAIT_OBJECT_0)
112 break;
113 if (res != WAIT_TIMEOUT)
115 ok(0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
116 break;
120 DestroyWindow(p->window);
122 return 0;
125 static void create_window_thread(struct create_window_thread_param *p)
127 DWORD res, tid;
129 p->window_created = CreateEvent(NULL, FALSE, FALSE, NULL);
130 ok(!!p->window_created, "CreateEvent failed, last error %#x.\n", GetLastError());
131 p->destroy_window = CreateEvent(NULL, FALSE, FALSE, NULL);
132 ok(!!p->destroy_window, "CreateEvent failed, last error %#x.\n", GetLastError());
133 p->thread = CreateThread(NULL, 0, create_window_thread_proc, p, 0, &tid);
134 ok(!!p->thread, "Failed to create thread, last error %#x.\n", GetLastError());
135 res = WaitForSingleObject(p->window_created, INFINITE);
136 ok(res == WAIT_OBJECT_0, "Wait failed (%#x), last error %#x.\n", res, GetLastError());
139 static void destroy_window_thread(struct create_window_thread_param *p)
141 SetEvent(p->destroy_window);
142 WaitForSingleObject(p->thread, INFINITE);
143 CloseHandle(p->destroy_window);
144 CloseHandle(p->window_created);
145 CloseHandle(p->thread);
148 static IDirectDrawSurface7 *get_depth_stencil(IDirect3DDevice7 *device)
150 IDirectDrawSurface7 *rt, *ret;
151 DDSCAPS2 caps = {DDSCAPS_ZBUFFER, 0, 0, 0};
152 HRESULT hr;
154 hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
155 ok(SUCCEEDED(hr), "Failed to get the render target, hr %#x.\n", hr);
156 hr = IDirectDrawSurface7_GetAttachedSurface(rt, &caps, &ret);
157 ok(SUCCEEDED(hr) || hr == DDERR_NOTFOUND, "Failed to get the z buffer, hr %#x.\n", hr);
158 IDirectDrawSurface7_Release(rt);
159 return ret;
162 static D3DCOLOR get_surface_color(IDirectDrawSurface7 *surface, UINT x, UINT y)
164 RECT rect = {x, y, x + 1, y + 1};
165 DDSURFACEDESC2 surface_desc;
166 D3DCOLOR color;
167 HRESULT hr;
169 memset(&surface_desc, 0, sizeof(surface_desc));
170 surface_desc.dwSize = sizeof(surface_desc);
172 hr = IDirectDrawSurface7_Lock(surface, &rect, &surface_desc, DDLOCK_READONLY, NULL);
173 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
174 if (FAILED(hr))
175 return 0xdeadbeef;
177 color = *((DWORD *)surface_desc.lpSurface) & 0x00ffffff;
179 hr = IDirectDrawSurface7_Unlock(surface, &rect);
180 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
182 return color;
185 static HRESULT CALLBACK enum_z_fmt(DDPIXELFORMAT *format, void *ctx)
187 DDPIXELFORMAT *z_fmt = ctx;
189 if (U1(*format).dwZBufferBitDepth > U1(*z_fmt).dwZBufferBitDepth)
190 *z_fmt = *format;
192 return DDENUMRET_OK;
195 static IDirectDraw7 *create_ddraw(void)
197 IDirectDraw7 *ddraw;
199 if (FAILED(pDirectDrawCreateEx(NULL, (void **)&ddraw, &IID_IDirectDraw7, NULL)))
200 return NULL;
202 return ddraw;
205 static HRESULT WINAPI enum_devtype_cb(char *desc_str, char *name, D3DDEVICEDESC7 *desc, void *ctx)
207 BOOL *hal_ok = ctx;
208 if (IsEqualGUID(&desc->deviceGUID, &IID_IDirect3DTnLHalDevice))
210 *hal_ok = TRUE;
211 return DDENUMRET_CANCEL;
213 return DDENUMRET_OK;
216 static IDirect3DDevice7 *create_device(HWND window, DWORD coop_level)
218 IDirectDrawSurface7 *surface, *ds;
219 IDirect3DDevice7 *device = NULL;
220 DDSURFACEDESC2 surface_desc;
221 DDPIXELFORMAT z_fmt;
222 IDirectDraw7 *ddraw;
223 IDirect3D7 *d3d7;
224 HRESULT hr;
225 BOOL hal_ok = FALSE;
226 const GUID *devtype = &IID_IDirect3DHALDevice;
228 if (!(ddraw = create_ddraw()))
229 return NULL;
231 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, coop_level);
232 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
234 memset(&surface_desc, 0, sizeof(surface_desc));
235 surface_desc.dwSize = sizeof(surface_desc);
236 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
237 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
238 surface_desc.dwWidth = 640;
239 surface_desc.dwHeight = 480;
241 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
242 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
244 if (coop_level & DDSCL_NORMAL)
246 IDirectDrawClipper *clipper;
248 hr = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL);
249 ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
250 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
251 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
252 hr = IDirectDrawSurface7_SetClipper(surface, clipper);
253 ok(SUCCEEDED(hr), "Failed to set surface clipper, hr %#x.\n", hr);
254 IDirectDrawClipper_Release(clipper);
257 hr = IDirectDraw7_QueryInterface(ddraw, &IID_IDirect3D7, (void **)&d3d7);
258 IDirectDraw7_Release(ddraw);
259 if (FAILED(hr))
261 IDirectDrawSurface7_Release(surface);
262 return NULL;
265 hr = IDirect3D7_EnumDevices(d3d7, enum_devtype_cb, &hal_ok);
266 ok(SUCCEEDED(hr), "Failed to enumerate devices, hr %#x.\n", hr);
267 if (hal_ok) devtype = &IID_IDirect3DTnLHalDevice;
269 memset(&z_fmt, 0, sizeof(z_fmt));
270 hr = IDirect3D7_EnumZBufferFormats(d3d7, devtype, enum_z_fmt, &z_fmt);
271 if (FAILED(hr) || !z_fmt.dwSize)
273 IDirect3D7_Release(d3d7);
274 IDirectDrawSurface7_Release(surface);
275 return NULL;
278 memset(&surface_desc, 0, sizeof(surface_desc));
279 surface_desc.dwSize = sizeof(surface_desc);
280 surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
281 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
282 U4(surface_desc).ddpfPixelFormat = z_fmt;
283 surface_desc.dwWidth = 640;
284 surface_desc.dwHeight = 480;
285 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &ds, NULL);
286 ok(SUCCEEDED(hr), "Failed to create depth buffer, hr %#x.\n", hr);
287 if (FAILED(hr))
289 IDirect3D7_Release(d3d7);
290 IDirectDrawSurface7_Release(surface);
291 return NULL;
294 hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
295 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
296 IDirectDrawSurface7_Release(ds);
297 if (FAILED(hr))
299 IDirect3D7_Release(d3d7);
300 IDirectDrawSurface7_Release(surface);
301 return NULL;
304 hr = IDirect3D7_CreateDevice(d3d7, devtype, surface, &device);
305 IDirect3D7_Release(d3d7);
306 IDirectDrawSurface7_Release(surface);
307 if (FAILED(hr))
308 return NULL;
310 return device;
313 static const UINT *expect_messages;
315 static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
317 if (expect_messages && message == *expect_messages)
318 ++expect_messages;
320 return DefWindowProcA(hwnd, message, wparam, lparam);
323 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
324 * interface. This prevents subsequent SetCooperativeLevel() calls on a
325 * different window from failing with DDERR_HWNDALREADYSET. */
326 static void fix_wndproc(HWND window, LONG_PTR proc)
328 IDirectDraw7 *ddraw;
329 HRESULT hr;
331 if (!(ddraw = create_ddraw()))
332 return;
334 SetWindowLongPtrA(window, GWLP_WNDPROC, proc);
335 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
336 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
337 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
338 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
340 IDirectDraw7_Release(ddraw);
343 static void test_process_vertices(void)
345 IDirect3DVertexBuffer7 *src_vb, *dst_vb1, *dst_vb2;
346 D3DVERTEXBUFFERDESC vb_desc;
347 IDirect3DDevice7 *device;
348 struct vec4 *dst_data;
349 struct vec3 *dst_data2;
350 struct vec3 *src_data;
351 IDirect3D7 *d3d7;
352 D3DVIEWPORT7 vp;
353 HWND window;
354 HRESULT hr;
356 static D3DMATRIX world =
358 0.0f, 1.0f, 0.0f, 0.0f,
359 1.0f, 0.0f, 0.0f, 0.0f,
360 0.0f, 0.0f, 0.0f, 1.0f,
361 0.0f, 1.0f, 1.0f, 1.0f,
363 static D3DMATRIX view =
365 2.0f, 0.0f, 0.0f, 0.0f,
366 0.0f, -1.0f, 0.0f, 0.0f,
367 0.0f, 0.0f, 1.0f, 0.0f,
368 0.0f, 0.0f, 0.0f, 3.0f,
370 static D3DMATRIX proj =
372 1.0f, 0.0f, 0.0f, 1.0f,
373 0.0f, 1.0f, 1.0f, 0.0f,
374 0.0f, 1.0f, 1.0f, 0.0f,
375 1.0f, 0.0f, 0.0f, 1.0f,
378 window = CreateWindowA("static", "d3d7_test", WS_OVERLAPPEDWINDOW,
379 0, 0, 640, 480, 0, 0, 0, 0);
380 if (!(device = create_device(window, DDSCL_NORMAL)))
382 skip("Failed to create a ddraw object, skipping test.\n");
383 DestroyWindow(window);
384 return;
387 hr = IDirect3DDevice7_GetDirect3D(device, &d3d7);
388 ok(SUCCEEDED(hr), "Failed to get Direct3D7 interface, hr %#x.\n", hr);
390 memset(&vb_desc, 0, sizeof(vb_desc));
391 vb_desc.dwSize = sizeof(vb_desc);
392 vb_desc.dwFVF = D3DFVF_XYZ;
393 vb_desc.dwNumVertices = 4;
394 hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &src_vb, 0);
395 ok(SUCCEEDED(hr), "Failed to create source vertex buffer, hr %#x.\n", hr);
397 hr = IDirect3DVertexBuffer7_Lock(src_vb, 0, (void **)&src_data, NULL);
398 ok(SUCCEEDED(hr), "Failed to lock source vertex buffer, hr %#x.\n", hr);
399 src_data[0].x = 0.0f;
400 src_data[0].y = 0.0f;
401 src_data[0].z = 0.0f;
402 src_data[1].x = 1.0f;
403 src_data[1].y = 1.0f;
404 src_data[1].z = 1.0f;
405 src_data[2].x = -1.0f;
406 src_data[2].y = -1.0f;
407 src_data[2].z = 0.5f;
408 src_data[3].x = 0.5f;
409 src_data[3].y = -0.5f;
410 src_data[3].z = 0.25f;
411 hr = IDirect3DVertexBuffer7_Unlock(src_vb);
412 ok(SUCCEEDED(hr), "Failed to unlock source vertex buffer, hr %#x.\n", hr);
414 memset(&vb_desc, 0, sizeof(vb_desc));
415 vb_desc.dwSize = sizeof(vb_desc);
416 vb_desc.dwFVF = D3DFVF_XYZRHW;
417 vb_desc.dwNumVertices = 4;
418 /* MSDN says that the last parameter must be 0 - check that. */
419 hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &dst_vb1, 4);
420 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
422 memset(&vb_desc, 0, sizeof(vb_desc));
423 vb_desc.dwSize = sizeof(vb_desc);
424 vb_desc.dwFVF = D3DFVF_XYZ;
425 vb_desc.dwNumVertices = 5;
426 /* MSDN says that the last parameter must be 0 - check that. */
427 hr = IDirect3D7_CreateVertexBuffer(d3d7, &vb_desc, &dst_vb2, 12345678);
428 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
430 memset(&vp, 0, sizeof(vp));
431 vp.dwX = 64;
432 vp.dwY = 64;
433 vp.dwWidth = 128;
434 vp.dwHeight = 128;
435 vp.dvMinZ = 0.0f;
436 vp.dvMaxZ = 1.0f;
437 hr = IDirect3DDevice7_SetViewport(device, &vp);
438 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
440 hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
441 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
442 hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb2, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
443 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
445 hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
446 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
447 ok(compare_vec4(&dst_data[0], +1.280e+2f, +1.280e+2f, +0.000e+0f, +1.000e+0f, 4096),
448 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
449 dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
450 ok(compare_vec4(&dst_data[1], +1.920e+2f, +6.400e+1f, +1.000e+0f, +1.000e+0f, 4096),
451 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
452 dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
453 ok(compare_vec4(&dst_data[2], +6.400e+1f, +1.920e+2f, +5.000e-1f, +1.000e+0f, 4096),
454 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
455 dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
456 ok(compare_vec4(&dst_data[3], +1.600e+2f, +1.600e+2f, +2.500e-1f, +1.000e+0f, 4096),
457 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
458 dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
459 hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
460 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
462 hr = IDirect3DVertexBuffer7_Lock(dst_vb2, 0, (void **)&dst_data2, NULL);
463 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
464 /* Small thing without much practical meaning, but I stumbled upon it,
465 * so let's check for it: If the output vertex buffer has no RHW value,
466 * the RHW value of the last vertex is written into the next vertex. */
467 ok(compare_vec3(&dst_data2[4], +1.000e+0f, +0.000e+0f, +0.000e+0f, 4096),
468 "Got unexpected vertex 4 {%.8e, %.8e, %.8e}.\n",
469 dst_data2[4].x, dst_data2[4].y, dst_data2[4].z);
470 hr = IDirect3DVertexBuffer7_Unlock(dst_vb2);
471 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
473 /* Try a more complicated viewport, same vertices. */
474 memset(&vp, 0, sizeof(vp));
475 vp.dwX = 10;
476 vp.dwY = 5;
477 vp.dwWidth = 246;
478 vp.dwHeight = 130;
479 vp.dvMinZ = -2.0f;
480 vp.dvMaxZ = 4.0f;
481 hr = IDirect3DDevice7_SetViewport(device, &vp);
482 ok(SUCCEEDED(hr), "Failed to set viewport, hr %#x.\n", hr);
484 hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
485 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
487 hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
488 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
489 ok(compare_vec4(&dst_data[0], +1.330e+2f, +7.000e+1f, -2.000e+0f, +1.000e+0f, 4096),
490 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
491 dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
492 ok(compare_vec4(&dst_data[1], +2.560e+2f, +5.000e+0f, +4.000e+0f, +1.000e+0f, 4096),
493 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
494 dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
495 ok(compare_vec4(&dst_data[2], +1.000e+1f, +1.350e+2f, +1.000e+0f, +1.000e+0f, 4096),
496 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
497 dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
498 ok(compare_vec4(&dst_data[3], +1.945e+2f, +1.025e+2f, -5.000e-1f, +1.000e+0f, 4096),
499 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
500 dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
501 hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
502 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
504 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &world);
505 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
506 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &view);
507 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
508 hr = IDirect3DDevice7_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &proj);
509 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
511 hr = IDirect3DVertexBuffer7_ProcessVertices(dst_vb1, D3DVOP_TRANSFORM, 0, 4, src_vb, 0, device, 0);
512 ok(SUCCEEDED(hr), "Failed to process vertices, hr %#x.\n", hr);
514 hr = IDirect3DVertexBuffer7_Lock(dst_vb1, 0, (void **)&dst_data, NULL);
515 ok(SUCCEEDED(hr), "Failed to lock destination vertex buffer, hr %#x.\n", hr);
516 ok(compare_vec4(&dst_data[0], +2.560e+2f, +7.000e+1f, -2.000e+0f, +3.333e-1f, 4096),
517 "Got unexpected vertex 0 {%.8e, %.8e, %.8e, %.8e}.\n",
518 dst_data[0].x, dst_data[0].y, dst_data[0].z, dst_data[0].w);
519 ok(compare_vec4(&dst_data[1], +2.560e+2f, +7.813e+1f, -2.750e+0f, +1.250e-1f, 4096),
520 "Got unexpected vertex 1 {%.8e, %.8e, %.8e, %.8e}.\n",
521 dst_data[1].x, dst_data[1].y, dst_data[1].z, dst_data[1].w);
522 ok(compare_vec4(&dst_data[2], +2.560e+2f, +4.400e+1f, +4.000e-1f, +4.000e-1f, 4096),
523 "Got unexpected vertex 2 {%.8e, %.8e, %.8e, %.8e}.\n",
524 dst_data[2].x, dst_data[2].y, dst_data[2].z, dst_data[2].w);
525 ok(compare_vec4(&dst_data[3], +2.560e+2f, +8.182e+1f, -3.091e+0f, +3.636e-1f, 4096),
526 "Got unexpected vertex 3 {%.8e, %.8e, %.8e, %.8e}.\n",
527 dst_data[3].x, dst_data[3].y, dst_data[3].z, dst_data[3].w);
528 hr = IDirect3DVertexBuffer7_Unlock(dst_vb1);
529 ok(SUCCEEDED(hr), "Failed to unlock destination vertex buffer, hr %#x.\n", hr);
531 IDirect3DVertexBuffer7_Release(dst_vb2);
532 IDirect3DVertexBuffer7_Release(dst_vb1);
533 IDirect3DVertexBuffer7_Release(src_vb);
534 IDirect3D7_Release(d3d7);
535 IDirect3DDevice7_Release(device);
536 DestroyWindow(window);
539 static void test_coop_level_create_device_window(void)
541 HWND focus_window, device_window;
542 IDirectDraw7 *ddraw;
543 HRESULT hr;
545 focus_window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
546 0, 0, 640, 480, 0, 0, 0, 0);
547 if (!(ddraw = create_ddraw()))
549 skip("Failed to create a 3D device, skipping test.\n");
550 DestroyWindow(focus_window);
551 return;
554 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
555 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
556 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
557 ok(!device_window, "Unexpected device window found.\n");
558 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW);
559 ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
560 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
561 ok(!device_window, "Unexpected device window found.\n");
562 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_NORMAL);
563 ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
564 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
565 ok(!device_window, "Unexpected device window found.\n");
566 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_NORMAL | DDSCL_FULLSCREEN);
567 ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
568 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
569 ok(!device_window, "Unexpected device window found.\n");
570 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
571 ok(hr == DDERR_NOFOCUSWINDOW || broken(hr == DDERR_INVALIDPARAMS), "Got unexpected hr %#x.\n", hr);
572 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
573 ok(!device_window, "Unexpected device window found.\n");
575 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
576 if (broken(hr == DDERR_INVALIDPARAMS))
578 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
579 IDirectDraw7_Release(ddraw);
580 DestroyWindow(focus_window);
581 return;
584 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
585 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
586 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
587 ok(!device_window, "Unexpected device window found.\n");
588 hr = IDirectDraw7_SetCooperativeLevel(ddraw, focus_window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
589 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
590 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
591 ok(!device_window, "Unexpected device window found.\n");
593 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
594 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
595 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
596 ok(!device_window, "Unexpected device window found.\n");
597 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_SETFOCUSWINDOW
598 | DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
599 ok(hr == DDERR_NOHWND, "Got unexpected hr %#x.\n", hr);
600 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
601 ok(!!device_window, "Device window not found.\n");
603 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
604 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
605 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
606 ok(!device_window, "Unexpected device window found.\n");
607 hr = IDirectDraw7_SetCooperativeLevel(ddraw, focus_window, DDSCL_SETFOCUSWINDOW
608 | DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
609 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
610 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
611 ok(!!device_window, "Device window not found.\n");
613 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
614 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
615 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
616 ok(!device_window, "Unexpected device window found.\n");
617 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
618 ok(hr == DDERR_NOFOCUSWINDOW, "Got unexpected hr %#x.\n", hr);
619 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
620 ok(!device_window, "Unexpected device window found.\n");
621 hr = IDirectDraw7_SetCooperativeLevel(ddraw, focus_window, DDSCL_SETFOCUSWINDOW);
622 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
623 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
624 ok(!device_window, "Unexpected device window found.\n");
625 hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
626 ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
627 device_window = FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
628 ok(!!device_window, "Device window not found.\n");
630 IDirectDraw7_Release(ddraw);
631 DestroyWindow(focus_window);
634 static void test_clipper_blt(void)
636 IDirectDrawSurface7 *src_surface, *dst_surface;
637 RECT client_rect, src_rect;
638 IDirectDrawClipper *clipper;
639 DDSURFACEDESC2 surface_desc;
640 unsigned int i, j, x, y;
641 IDirectDraw7 *ddraw;
642 RGNDATA *rgn_data;
643 D3DCOLOR color;
644 HRGN r1, r2;
645 HWND window;
646 DDBLTFX fx;
647 HRESULT hr;
648 DWORD *ptr;
649 DWORD ret;
651 static const DWORD src_data[] =
653 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
654 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
655 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
657 static const D3DCOLOR expected1[] =
659 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
660 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
661 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
662 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
664 static const D3DCOLOR expected2[] =
666 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
667 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
668 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
669 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
672 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
673 10, 10, 640, 480, 0, 0, 0, 0);
674 ShowWindow(window, SW_SHOW);
675 if (!(ddraw = create_ddraw()))
677 skip("Failed to create a ddraw object, skipping test.\n");
678 DestroyWindow(window);
679 return;
682 ret = GetClientRect(window, &client_rect);
683 ok(ret, "Failed to get client rect.\n");
684 ret = MapWindowPoints(window, NULL, (POINT *)&client_rect, 2);
685 ok(ret, "Failed to map client rect.\n");
687 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
688 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
690 hr = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL);
691 ok(SUCCEEDED(hr), "Failed to create clipper, hr %#x.\n", hr);
692 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
693 ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
694 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
695 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
696 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
697 ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
698 rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
699 hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret);
700 ok(SUCCEEDED(hr), "Failed to get clip list, hr %#x.\n", hr);
701 ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#x.\n", rgn_data->rdh.dwSize);
702 ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#x.\n", rgn_data->rdh.iType);
703 ok(rgn_data->rdh.nCount >= 1, "Got unexpected count %u.\n", rgn_data->rdh.nCount);
704 ok(EqualRect(&rgn_data->rdh.rcBound, &client_rect),
705 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
706 rgn_data->rdh.rcBound.left, rgn_data->rdh.rcBound.top,
707 rgn_data->rdh.rcBound.right, rgn_data->rdh.rcBound.bottom,
708 client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
709 HeapFree(GetProcessHeap(), 0, rgn_data);
711 r1 = CreateRectRgn(0, 0, 320, 240);
712 ok(!!r1, "Failed to create region.\n");
713 r2 = CreateRectRgn(320, 240, 640, 480);
714 ok(!!r2, "Failed to create region.\n");
715 CombineRgn(r1, r1, r2, RGN_OR);
716 ret = GetRegionData(r1, 0, NULL);
717 rgn_data = HeapAlloc(GetProcessHeap(), 0, ret);
718 ret = GetRegionData(r1, ret, rgn_data);
719 ok(!!ret, "Failed to get region data.\n");
721 DeleteObject(r2);
722 DeleteObject(r1);
724 hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
725 ok(hr == DDERR_CLIPPERISUSINGHWND, "Got unexpected hr %#x.\n", hr);
726 hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
727 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
728 hr = IDirectDrawClipper_SetClipList(clipper, rgn_data, 0);
729 ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
731 HeapFree(GetProcessHeap(), 0, rgn_data);
733 memset(&surface_desc, 0, sizeof(surface_desc));
734 surface_desc.dwSize = sizeof(surface_desc);
735 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
736 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
737 surface_desc.dwWidth = 640;
738 surface_desc.dwHeight = 480;
739 U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
740 U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB;
741 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32;
742 U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
743 U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
744 U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff;
746 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &src_surface, NULL);
747 ok(SUCCEEDED(hr), "Failed to create source surface, hr %#x.\n", hr);
748 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &dst_surface, NULL);
749 ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
751 memset(&fx, 0, sizeof(fx));
752 fx.dwSize = sizeof(fx);
753 hr = IDirectDrawSurface7_Blt(src_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
754 ok(SUCCEEDED(hr), "Failed to clear source surface, hr %#x.\n", hr);
755 hr = IDirectDrawSurface7_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
756 ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
758 hr = IDirectDrawSurface7_Lock(src_surface, NULL, &surface_desc, 0, NULL);
759 ok(SUCCEEDED(hr), "Failed to lock source surface, hr %#x.\n", hr);
760 ok(U1(surface_desc).lPitch == 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc).lPitch);
761 ptr = surface_desc.lpSurface;
762 memcpy(&ptr[ 0], &src_data[ 0], 6 * sizeof(DWORD));
763 memcpy(&ptr[ 640], &src_data[ 6], 6 * sizeof(DWORD));
764 memcpy(&ptr[1280], &src_data[12], 6 * sizeof(DWORD));
765 hr = IDirectDrawSurface7_Unlock(src_surface, NULL);
766 ok(SUCCEEDED(hr), "Failed to unlock source surface, hr %#x.\n", hr);
768 hr = IDirectDrawSurface7_SetClipper(dst_surface, clipper);
769 ok(SUCCEEDED(hr), "Failed to set clipper, hr %#x.\n", hr);
771 SetRect(&src_rect, 1, 1, 5, 2);
772 hr = IDirectDrawSurface7_Blt(dst_surface, NULL, src_surface, &src_rect, DDBLT_WAIT, NULL);
773 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
774 for (i = 0; i < 4; ++i)
776 for (j = 0; j < 4; ++j)
778 x = 80 * ((2 * j) + 1);
779 y = 60 * ((2 * i) + 1);
780 color = get_surface_color(dst_surface, x, y);
781 ok(compare_color(color, expected1[i * 4 + j], 1),
782 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1[i * 4 + j], x, y, color);
786 U5(fx).dwFillColor = 0xff0000ff;
787 hr = IDirectDrawSurface7_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
788 ok(SUCCEEDED(hr), "Failed to clear destination surface, hr %#x.\n", hr);
789 for (i = 0; i < 4; ++i)
791 for (j = 0; j < 4; ++j)
793 x = 80 * ((2 * j) + 1);
794 y = 60 * ((2 * i) + 1);
795 color = get_surface_color(dst_surface, x, y);
796 ok(compare_color(color, expected2[i * 4 + j], 1),
797 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2[i * 4 + j], x, y, color);
801 hr = IDirectDrawSurface7_BltFast(dst_surface, 0, 0, src_surface, NULL, DDBLTFAST_WAIT);
802 ok(hr == DDERR_BLTFASTCANTCLIP, "Got unexpected hr %#x.\n", hr);
804 hr = IDirectDrawClipper_SetHWnd(clipper, 0, window);
805 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
806 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
807 ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
808 DestroyWindow(window);
809 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
810 ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
811 hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL);
812 ok(SUCCEEDED(hr), "Failed to set clipper window, hr %#x.\n", hr);
813 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
814 ok(SUCCEEDED(hr), "Failed to get clip list size, hr %#x.\n", hr);
815 hr = IDirectDrawClipper_SetClipList(clipper, NULL, 0);
816 ok(SUCCEEDED(hr), "Failed to set clip list, hr %#x.\n", hr);
817 hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret);
818 ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
819 hr = IDirectDrawSurface7_Blt(dst_surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
820 ok(hr == DDERR_NOCLIPLIST, "Got unexpected hr %#x.\n", hr);
822 IDirectDrawSurface7_Release(dst_surface);
823 IDirectDrawSurface7_Release(src_surface);
824 IDirectDrawClipper_Release(clipper);
825 IDirectDraw7_Release(ddraw);
828 static void test_coop_level_d3d_state(void)
830 IDirectDrawSurface7 *rt, *surface;
831 IDirect3DDevice7 *device;
832 IDirectDraw7 *ddraw;
833 IDirect3D7 *d3d;
834 D3DCOLOR color;
835 DWORD value;
836 HWND window;
837 HRESULT hr;
839 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
840 0, 0, 640, 480, 0, 0, 0, 0);
841 if (!(device = create_device(window, DDSCL_NORMAL)))
843 skip("Failed to create D3D device, skipping test.\n");
844 DestroyWindow(window);
845 return;
848 hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
849 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
850 hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_ZENABLE, &value);
851 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
852 ok(!!value, "Got unexpected z-enable state %#x.\n", value);
853 hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
854 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
855 ok(!value, "Got unexpected alpha blend enable state %#x.\n", value);
856 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
857 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
858 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
859 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
860 color = get_surface_color(rt, 320, 240);
861 ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
863 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
864 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
865 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
866 ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
867 IDirect3D7_Release(d3d);
868 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
869 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
870 hr = IDirectDrawSurface7_IsLost(rt);
871 ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr);
872 hr = IDirectDraw7_RestoreAllSurfaces(ddraw);
873 ok(SUCCEEDED(hr), "Failed to restore surfaces, hr %#x.\n", hr);
874 IDirectDraw7_Release(ddraw);
876 hr = IDirect3DDevice7_GetRenderTarget(device, &surface);
877 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
878 ok(surface == rt, "Got unexpected surface %p.\n", surface);
879 hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_ZENABLE, &value);
880 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
881 ok(!!value, "Got unexpected z-enable state %#x.\n", value);
882 hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
883 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
884 ok(!!value, "Got unexpected alpha blend enable state %#x.\n", value);
885 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
886 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
887 color = get_surface_color(rt, 320, 240);
888 ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
890 IDirectDrawSurface7_Release(surface);
891 IDirectDrawSurface7_Release(rt);
892 IDirect3DDevice7_Release(device);
893 DestroyWindow(window);
896 static void test_surface_interface_mismatch(void)
898 IDirectDraw7 *ddraw = NULL;
899 IDirect3D7 *d3d = NULL;
900 IDirectDrawSurface7 *surface = NULL, *ds;
901 IDirectDrawSurface3 *surface3 = NULL;
902 IDirect3DDevice7 *device = NULL;
903 DDSURFACEDESC2 surface_desc;
904 DDPIXELFORMAT z_fmt;
905 ULONG refcount;
906 HRESULT hr;
907 D3DCOLOR color;
908 HWND window;
910 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
911 0, 0, 640, 480, 0, 0, 0, 0);
913 if (!(ddraw = create_ddraw()))
915 skip("Failed to create a ddraw object, skipping test.\n");
916 goto cleanup;
919 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
920 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
922 memset(&surface_desc, 0, sizeof(surface_desc));
923 surface_desc.dwSize = sizeof(surface_desc);
924 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
925 surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
926 surface_desc.dwWidth = 640;
927 surface_desc.dwHeight = 480;
929 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
930 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
932 hr = IDirectDrawSurface7_QueryInterface(surface, &IID_IDirectDrawSurface3, (void **)&surface3);
933 ok(SUCCEEDED(hr), "Failed to QI IDirectDrawSurface3, hr %#x.\n", hr);
935 hr = IDirectDraw7_QueryInterface(ddraw, &IID_IDirect3D7, (void **)&d3d);
936 if (FAILED(hr))
938 skip("Failed to get the IDirect3D7 interface, skipping test.\n");
939 goto cleanup;
942 memset(&z_fmt, 0, sizeof(z_fmt));
943 hr = IDirect3D7_EnumZBufferFormats(d3d, &IID_IDirect3DHALDevice, enum_z_fmt, &z_fmt);
944 if (FAILED(hr) || !z_fmt.dwSize)
946 skip("No depth buffer formats available, skipping test.\n");
947 goto cleanup;
950 memset(&surface_desc, 0, sizeof(surface_desc));
951 surface_desc.dwSize = sizeof(surface_desc);
952 surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
953 surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
954 U4(surface_desc).ddpfPixelFormat = z_fmt;
955 surface_desc.dwWidth = 640;
956 surface_desc.dwHeight = 480;
957 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &ds, NULL);
958 ok(SUCCEEDED(hr), "Failed to create depth buffer, hr %#x.\n", hr);
959 if (FAILED(hr))
960 goto cleanup;
962 /* Using a different surface interface version still works */
963 hr = IDirectDrawSurface3_AddAttachedSurface(surface3, (IDirectDrawSurface3 *)ds);
964 ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x.\n", hr);
965 refcount = IDirectDrawSurface7_Release(ds);
966 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
967 if (FAILED(hr))
968 goto cleanup;
970 /* Here too */
971 hr = IDirect3D7_CreateDevice(d3d, &IID_IDirect3DHALDevice, (IDirectDrawSurface7 *)surface3, &device);
972 ok(SUCCEEDED(hr), "Failed to create d3d device.\n");
973 if (FAILED(hr))
974 goto cleanup;
976 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
977 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
978 color = get_surface_color(surface, 320, 240);
979 ok(compare_color(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
981 cleanup:
982 if (surface3) IDirectDrawSurface3_Release(surface3);
983 if (surface) IDirectDrawSurface7_Release(surface);
984 if (device) IDirect3DDevice7_Release(device);
985 if (d3d) IDirect3D7_Release(d3d);
986 if (ddraw) IDirectDraw7_Release(ddraw);
987 DestroyWindow(window);
990 static void test_coop_level_threaded(void)
992 struct create_window_thread_param p;
993 IDirectDraw7 *ddraw;
994 HRESULT hr;
996 if (!(ddraw = create_ddraw()))
998 skip("Failed to create a ddraw object, skipping test.\n");
999 return;
1001 create_window_thread(&p);
1003 hr = IDirectDraw7_SetCooperativeLevel(ddraw, p.window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1004 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
1006 IDirectDraw7_Release(ddraw);
1007 destroy_window_thread(&p);
1010 static void test_depth_blit(void)
1012 IDirect3DDevice7 *device;
1013 static struct
1015 float x, y, z;
1016 DWORD color;
1018 quad1[] =
1020 { -1.0, 1.0, 0.50f, 0xff00ff00},
1021 { 1.0, 1.0, 0.50f, 0xff00ff00},
1022 { -1.0, -1.0, 0.50f, 0xff00ff00},
1023 { 1.0, -1.0, 0.50f, 0xff00ff00},
1025 static const D3DCOLOR expected_colors[4][4] =
1027 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1028 {0x00ff0000, 0x00ff0000, 0x0000ff00, 0x0000ff00},
1029 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1030 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00},
1032 DDSURFACEDESC2 ddsd_new, ddsd_existing;
1034 IDirectDrawSurface7 *ds1, *ds2, *ds3, *rt;
1035 RECT src_rect, dst_rect;
1036 unsigned int i, j;
1037 D3DCOLOR color;
1038 HRESULT hr;
1039 IDirect3D7 *d3d;
1040 IDirectDraw7 *ddraw;
1041 DDBLTFX fx;
1042 HWND window;
1044 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1045 0, 0, 640, 480, 0, 0, 0, 0);
1046 if (!(device = create_device(window, DDSCL_NORMAL)))
1048 skip("Failed to create D3D device, skipping test.\n");
1049 DestroyWindow(window);
1050 return;
1053 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
1054 ok(SUCCEEDED(hr), "Failed to get Direct3D7 interface, hr %#x.\n", hr);
1055 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
1056 ok(SUCCEEDED(hr), "Failed to get DirectDraw7 interface, hr %#x.\n", hr);
1057 IDirect3D7_Release(d3d);
1059 ds1 = get_depth_stencil(device);
1061 memset(&ddsd_new, 0, sizeof(ddsd_new));
1062 ddsd_new.dwSize = sizeof(ddsd_new);
1063 memset(&ddsd_existing, 0, sizeof(ddsd_existing));
1064 ddsd_existing.dwSize = sizeof(ddsd_existing);
1065 hr = IDirectDrawSurface7_GetSurfaceDesc(ds1, &ddsd_existing);
1066 ddsd_new.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
1067 ddsd_new.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
1068 ddsd_new.dwWidth = ddsd_existing.dwWidth;
1069 ddsd_new.dwHeight = ddsd_existing.dwHeight;
1070 U4(ddsd_new).ddpfPixelFormat = U4(ddsd_existing).ddpfPixelFormat;
1071 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd_new, &ds2, NULL);
1072 ok(SUCCEEDED(hr), "Failed to create a z buffer, hr %#x.\n", hr);
1073 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd_new, &ds3, NULL);
1074 ok(SUCCEEDED(hr), "Failed to create a z buffer, hr %#x.\n", hr);
1075 IDirectDraw7_Release(ddraw);
1077 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
1078 ok(SUCCEEDED(hr), "Failed to enable z testing, hr %#x.\n", hr);
1079 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
1080 ok(SUCCEEDED(hr), "Failed to set the z function, hr %#x.\n", hr);
1081 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
1082 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1084 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
1085 ok(SUCCEEDED(hr), "Failed to clear the z buffer, hr %#x.\n", hr);
1087 /* Partial blit. */
1088 SetRect(&src_rect, 0, 0, 320, 240);
1089 SetRect(&dst_rect, 0, 0, 320, 240);
1090 hr = IDirectDrawSurface7_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1091 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1092 /* Different locations. */
1093 SetRect(&src_rect, 0, 0, 320, 240);
1094 SetRect(&dst_rect, 320, 240, 640, 480);
1095 hr = IDirectDrawSurface7_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1096 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1097 /* Streched. */
1098 SetRect(&src_rect, 0, 0, 320, 240);
1099 SetRect(&dst_rect, 0, 0, 640, 480);
1100 hr = IDirectDrawSurface7_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1101 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1102 /* Flipped. */
1103 SetRect(&src_rect, 0, 480, 640, 0);
1104 SetRect(&dst_rect, 0, 0, 640, 480);
1105 hr = IDirectDrawSurface7_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1106 ok(hr == DDERR_INVALIDRECT, "Got unexpected hr %#x.\n", hr);
1107 SetRect(&src_rect, 0, 0, 640, 480);
1108 SetRect(&dst_rect, 0, 480, 640, 0);
1109 hr = IDirectDrawSurface7_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1110 ok(hr == DDERR_INVALIDRECT, "Got unexpected hr %#x.\n", hr);
1111 /* Full, explicit. */
1112 SetRect(&src_rect, 0, 0, 640, 480);
1113 SetRect(&dst_rect, 0, 0, 640, 480);
1114 hr = IDirectDrawSurface7_Blt(ds2, &dst_rect, ds1, &src_rect, DDBLT_WAIT, NULL);
1115 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1116 /* Depth -> color blit: Succeeds on Win7 + Radeon HD 5700, fails on WinXP + Radeon X1600 */
1118 /* Depth blit inside a BeginScene / EndScene pair */
1119 hr = IDirect3DDevice7_BeginScene(device);
1120 ok(SUCCEEDED(hr), "Failed to start scene, hr %#x.\n", hr);
1121 /* From the current depth stencil */
1122 hr = IDirectDrawSurface7_Blt(ds2, NULL, ds1, NULL, DDBLT_WAIT, NULL);
1123 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1124 /* To the current depth stencil */
1125 hr = IDirectDrawSurface7_Blt(ds1, NULL, ds2, NULL, DDBLT_WAIT, NULL);
1126 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1127 /* Between unbound surfaces */
1128 hr = IDirectDrawSurface7_Blt(ds3, NULL, ds2, NULL, DDBLT_WAIT, NULL);
1129 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1130 hr = IDirect3DDevice7_EndScene(device);
1131 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1133 /* Avoid changing the depth stencil, it doesn't work properly on Windows.
1134 * Instead use DDBLT_DEPTHFILL to clear the depth stencil. Unfortunately
1135 * drivers disagree on the meaning of dwFillDepth. Only 0 seems to produce
1136 * a reliable result(z = 0.0) */
1137 memset(&fx, 0, sizeof(fx));
1138 fx.dwSize = sizeof(fx);
1139 hr = IDirectDrawSurface7_Blt(ds2, NULL, NULL, NULL, DDBLT_DEPTHFILL | DDBLT_WAIT, &fx);
1140 ok(SUCCEEDED(hr), "Failed to clear the source z buffer, hr %#x.\n", hr);
1142 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
1143 ok(SUCCEEDED(hr), "Failed to clear the color and z buffers, hr %#x.\n", hr);
1144 SetRect(&dst_rect, 0, 0, 320, 240);
1145 hr = IDirectDrawSurface7_Blt(ds1, &dst_rect, ds2, NULL, DDBLT_WAIT, NULL);
1146 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1147 IDirectDrawSurface7_Release(ds3);
1148 IDirectDrawSurface7_Release(ds2);
1149 IDirectDrawSurface7_Release(ds1);
1151 hr = IDirect3DDevice7_BeginScene(device);
1152 ok(SUCCEEDED(hr), "Failed to start scene, hr %#x.\n", hr);
1153 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZ | D3DFVF_DIFFUSE,
1154 quad1, 4, 0);
1155 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1156 hr = IDirect3DDevice7_EndScene(device);
1157 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1159 hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
1160 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
1161 for (i = 0; i < 4; ++i)
1163 for (j = 0; j < 4; ++j)
1165 unsigned int x = 80 * ((2 * j) + 1);
1166 unsigned int y = 60 * ((2 * i) + 1);
1167 color = get_surface_color(rt, x, y);
1168 ok(compare_color(color, expected_colors[i][j], 1),
1169 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
1173 IDirectDrawSurface7_Release(rt);
1174 IDirect3DDevice7_Release(device);
1175 DestroyWindow(window);
1178 static void test_texture_load_ckey(void)
1180 HWND window;
1181 IDirect3DDevice7 *device;
1182 IDirectDraw7 *ddraw;
1183 IDirectDrawSurface7 *src;
1184 IDirectDrawSurface7 *dst;
1185 DDSURFACEDESC2 ddsd;
1186 HRESULT hr;
1187 DDCOLORKEY ckey;
1188 IDirect3D7 *d3d;
1190 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1191 0, 0, 640, 480, 0, 0, 0, 0);
1192 if (!(device = create_device(window, DDSCL_NORMAL)))
1194 skip("Failed to create D3D device, skipping test.\n");
1195 DestroyWindow(window);
1196 return;
1199 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
1200 ok(SUCCEEDED(hr), "Failed to get Direct3D7 interface, hr %#x.\n", hr);
1201 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
1202 ok(SUCCEEDED(hr), "Failed to get DirectDraw7 interface, hr %#x.\n", hr);
1203 IDirect3D7_Release(d3d);
1205 memset(&ddsd, 0, sizeof(ddsd));
1206 ddsd.dwSize = sizeof(ddsd);
1207 ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
1208 ddsd.dwHeight = 128;
1209 ddsd.dwWidth = 128;
1210 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY;
1211 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &src, NULL);
1212 ok(SUCCEEDED(hr), "Failed to create source texture, hr %#x.\n", hr);
1213 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1214 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &dst, NULL);
1215 ok(SUCCEEDED(hr), "Failed to create destination texture, hr %#x.\n", hr);
1217 /* No surface has a color key */
1218 hr = IDirect3DDevice7_Load(device, dst, NULL, src, NULL, 0);
1219 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1220 ckey.dwColorSpaceLowValue = ckey.dwColorSpaceHighValue = 0xdeadbeef;
1221 hr = IDirectDrawSurface7_GetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1222 ok(hr == DDERR_NOCOLORKEY, "Got unexpected hr %#x.\n", hr);
1223 ok(ckey.dwColorSpaceLowValue == 0xdeadbeef, "dwColorSpaceLowValue is %#x.\n", ckey.dwColorSpaceLowValue);
1224 ok(ckey.dwColorSpaceHighValue == 0xdeadbeef, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue);
1226 /* Source surface has a color key */
1227 ckey.dwColorSpaceLowValue = ckey.dwColorSpaceHighValue = 0x0000ff00;
1228 hr = IDirectDrawSurface7_SetColorKey(src, DDCKEY_SRCBLT, &ckey);
1229 ok(SUCCEEDED(hr), "Failed to set color key, hr %#x.\n", hr);
1230 hr = IDirect3DDevice7_Load(device, dst, NULL, src, NULL, 0);
1231 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1232 hr = IDirectDrawSurface7_GetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1233 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1234 ok(ckey.dwColorSpaceLowValue == 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey.dwColorSpaceLowValue);
1235 ok(ckey.dwColorSpaceHighValue == 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue);
1237 /* Both surfaces have a color key: Dest ckey is overwritten */
1238 ckey.dwColorSpaceLowValue = ckey.dwColorSpaceHighValue = 0x000000ff;
1239 hr = IDirectDrawSurface7_SetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1240 ok(SUCCEEDED(hr), "Failed to set color key, hr %#x.\n", hr);
1241 hr = IDirect3DDevice7_Load(device, dst, NULL, src, NULL, 0);
1242 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1243 hr = IDirectDrawSurface7_GetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1244 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1245 ok(ckey.dwColorSpaceLowValue == 0x0000ff00, "dwColorSpaceLowValue is %#x.\n", ckey.dwColorSpaceLowValue);
1246 ok(ckey.dwColorSpaceHighValue == 0x0000ff00, "dwColorSpaceHighValue is %#x.\n", ckey.dwColorSpaceHighValue);
1248 /* Only the destination has a color key: It is deleted. This behavior differs from
1249 * IDirect3DTexture(2)::Load */
1250 hr = IDirectDrawSurface7_SetColorKey(src, DDCKEY_SRCBLT, NULL);
1251 ok(SUCCEEDED(hr), "Failed to set color key, hr %#x.\n", hr);
1252 hr = IDirectDrawSurface7_GetColorKey(src, DDCKEY_SRCBLT, &ckey);
1253 ok(hr == DDERR_NOCOLORKEY, "Got unexpected hr %#x.\n", hr);
1254 hr = IDirect3DDevice7_Load(device, dst, NULL, src, NULL, 0);
1255 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
1256 hr = IDirectDrawSurface7_GetColorKey(dst, DDCKEY_SRCBLT, &ckey);
1257 todo_wine ok(hr == DDERR_NOCOLORKEY, "Got unexpected hr %#x.\n", hr);
1259 IDirectDrawSurface7_Release(dst);
1260 IDirectDrawSurface7_Release(src);
1261 IDirectDraw7_Release(ddraw);
1262 IDirect3DDevice7_Release(device);
1265 static void test_zenable(void)
1267 static struct
1269 struct vec4 position;
1270 D3DCOLOR diffuse;
1272 tquad[] =
1274 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
1275 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
1276 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
1277 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
1279 IDirect3DDevice7 *device;
1280 IDirectDrawSurface7 *rt;
1281 D3DCOLOR color;
1282 HWND window;
1283 HRESULT hr;
1284 UINT x, y;
1285 UINT i, j;
1287 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1288 0, 0, 640, 480, 0, 0, 0, 0);
1289 if (!(device = create_device(window, DDSCL_NORMAL)))
1291 skip("Failed to create D3D device, skipping test.\n");
1292 DestroyWindow(window);
1293 return;
1296 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE);
1297 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
1299 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
1300 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
1301 hr = IDirect3DDevice7_BeginScene(device);
1302 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1303 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, tquad, 4, 0);
1304 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1305 hr = IDirect3DDevice7_EndScene(device);
1306 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1308 hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
1309 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
1310 for (i = 0; i < 4; ++i)
1312 for (j = 0; j < 4; ++j)
1314 x = 80 * ((2 * j) + 1);
1315 y = 60 * ((2 * i) + 1);
1316 color = get_surface_color(rt, x, y);
1317 ok(compare_color(color, 0x0000ff00, 1),
1318 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
1321 IDirectDrawSurface7_Release(rt);
1323 IDirect3DDevice7_Release(device);
1324 DestroyWindow(window);
1327 static void test_ck_rgba(void)
1329 static struct
1331 struct vec4 position;
1332 struct vec2 texcoord;
1334 tquad[] =
1336 {{ 0.0f, 480.0f, 0.25f, 1.0f}, {0.0f, 0.0f}},
1337 {{ 0.0f, 0.0f, 0.25f, 1.0f}, {0.0f, 1.0f}},
1338 {{640.0f, 480.0f, 0.25f, 1.0f}, {1.0f, 0.0f}},
1339 {{640.0f, 0.0f, 0.25f, 1.0f}, {1.0f, 1.0f}},
1340 {{ 0.0f, 480.0f, 0.75f, 1.0f}, {0.0f, 0.0f}},
1341 {{ 0.0f, 0.0f, 0.75f, 1.0f}, {0.0f, 1.0f}},
1342 {{640.0f, 480.0f, 0.75f, 1.0f}, {1.0f, 0.0f}},
1343 {{640.0f, 0.0f, 0.75f, 1.0f}, {1.0f, 1.0f}},
1345 static const struct
1347 D3DCOLOR fill_color;
1348 BOOL color_key;
1349 BOOL blend;
1350 D3DCOLOR result1;
1351 D3DCOLOR result2;
1353 tests[] =
1355 {0xff00ff00, TRUE, TRUE, 0x00ff0000, 0x000000ff},
1356 {0xff00ff00, TRUE, FALSE, 0x00ff0000, 0x000000ff},
1357 {0xff00ff00, FALSE, TRUE, 0x0000ff00, 0x0000ff00},
1358 {0xff00ff00, FALSE, FALSE, 0x0000ff00, 0x0000ff00},
1359 {0x7f00ff00, TRUE, TRUE, 0x00807f00, 0x00807f00},
1360 {0x7f00ff00, TRUE, FALSE, 0x0000ff00, 0x0000ff00},
1361 {0x7f00ff00, FALSE, TRUE, 0x00807f00, 0x00807f00},
1362 {0x7f00ff00, FALSE, FALSE, 0x0000ff00, 0x0000ff00},
1365 IDirectDrawSurface7 *texture;
1366 DDSURFACEDESC2 surface_desc;
1367 IDirect3DDevice7 *device;
1368 IDirectDrawSurface7 *rt;
1369 IDirectDraw7 *ddraw;
1370 IDirect3D7 *d3d;
1371 D3DCOLOR color;
1372 HWND window;
1373 DDBLTFX fx;
1374 HRESULT hr;
1375 UINT i;
1377 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1378 0, 0, 640, 480, 0, 0, 0, 0);
1379 if (!(device = create_device(window, DDSCL_NORMAL)))
1381 skip("Failed to create D3D device, skipping test.\n");
1382 DestroyWindow(window);
1383 return;
1386 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
1387 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
1388 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
1389 ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
1390 IDirect3D7_Release(d3d);
1392 memset(&surface_desc, 0, sizeof(surface_desc));
1393 surface_desc.dwSize = sizeof(surface_desc);
1394 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT;
1395 surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1396 surface_desc.dwWidth = 256;
1397 surface_desc.dwHeight = 256;
1398 U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
1399 U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
1400 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32;
1401 U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1402 U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1403 U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff;
1404 U5(U4(surface_desc).ddpfPixelFormat).dwRGBAlphaBitMask = 0xff000000;
1405 surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff00;
1406 surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff00;
1407 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &texture, NULL);
1408 ok(SUCCEEDED(hr), "Failed to create destination surface, hr %#x.\n", hr);
1410 hr = IDirect3DDevice7_SetTexture(device, 0, texture);
1411 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
1412 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
1413 ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
1414 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
1415 ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
1417 hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
1418 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
1420 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
1422 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, tests[i].color_key);
1423 ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr);
1424 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, tests[i].blend);
1425 ok(SUCCEEDED(hr), "Failed to enable alpha blending, hr %#x.\n", hr);
1427 memset(&fx, 0, sizeof(fx));
1428 fx.dwSize = sizeof(fx);
1429 U5(fx).dwFillColor = tests[i].fill_color;
1430 hr = IDirectDrawSurface7_Blt(texture, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
1431 ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
1433 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
1434 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
1435 hr = IDirect3DDevice7_BeginScene(device);
1436 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1437 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0);
1438 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1439 hr = IDirect3DDevice7_EndScene(device);
1440 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1442 color = get_surface_color(rt, 320, 240);
1443 if (i == 2)
1444 todo_wine ok(compare_color(color, tests[i].result1, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1445 tests[i].result1, i, color);
1446 else
1447 ok(compare_color(color, tests[i].result1, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1448 tests[i].result1, i, color);
1450 U5(fx).dwFillColor = 0xff0000ff;
1451 hr = IDirectDrawSurface7_Blt(texture, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
1452 ok(SUCCEEDED(hr), "Failed to fill texture, hr %#x.\n", hr);
1454 hr = IDirect3DDevice7_BeginScene(device);
1455 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1456 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[4], 4, 0);
1457 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1458 hr = IDirect3DDevice7_EndScene(device);
1459 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1461 /* This tests that fragments that are masked out by the color key are
1462 * discarded, instead of just fully transparent. */
1463 color = get_surface_color(rt, 320, 240);
1464 if (i == 2)
1465 todo_wine ok(compare_color(color, tests[i].result2, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1466 tests[i].result2, i, color);
1467 else
1468 ok(compare_color(color, tests[i].result2, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1469 tests[i].result2, i, color);
1472 IDirectDrawSurface7_Release(rt);
1473 IDirectDrawSurface7_Release(texture);
1474 IDirectDraw7_Release(ddraw);
1475 IDirect3DDevice7_Release(device);
1476 DestroyWindow(window);
1479 static void test_ck_default(void)
1481 static struct
1483 struct vec4 position;
1484 struct vec2 texcoord;
1486 tquad[] =
1488 {{ 0.0f, 480.0f, 0.0f, 1.0f}, {0.0f, 0.0f}},
1489 {{ 0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
1490 {{640.0f, 480.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
1491 {{640.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
1493 IDirectDrawSurface7 *surface, *rt;
1494 DDSURFACEDESC2 surface_desc;
1495 IDirect3DDevice7 *device;
1496 IDirectDraw7 *ddraw;
1497 IDirect3D7 *d3d;
1498 D3DCOLOR color;
1499 DWORD value;
1500 HWND window;
1501 DDBLTFX fx;
1502 HRESULT hr;
1504 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1505 0, 0, 640, 480, 0, 0, 0, 0);
1507 if (!(device = create_device(window, DDSCL_NORMAL)))
1509 skip("Failed to create D3D device, skipping test.\n");
1510 DestroyWindow(window);
1511 return;
1514 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
1515 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
1516 hr = IDirect3D7_QueryInterface(d3d, &IID_IDirectDraw7, (void **)&ddraw);
1517 ok(SUCCEEDED(hr), "Failed to get ddraw interface, hr %#x.\n", hr);
1518 IDirect3D7_Release(d3d);
1520 hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
1521 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
1523 memset(&surface_desc, 0, sizeof(surface_desc));
1524 surface_desc.dwSize = sizeof(surface_desc);
1525 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CKSRCBLT;
1526 surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1527 surface_desc.dwWidth = 256;
1528 surface_desc.dwHeight = 256;
1529 U4(surface_desc).ddpfPixelFormat.dwSize = sizeof(U4(surface_desc).ddpfPixelFormat);
1530 U4(surface_desc).ddpfPixelFormat.dwFlags = DDPF_RGB;
1531 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount = 32;
1532 U2(U4(surface_desc).ddpfPixelFormat).dwRBitMask = 0x00ff0000;
1533 U3(U4(surface_desc).ddpfPixelFormat).dwGBitMask = 0x0000ff00;
1534 U4(U4(surface_desc).ddpfPixelFormat).dwBBitMask = 0x000000ff;
1535 surface_desc.ddckCKSrcBlt.dwColorSpaceLowValue = 0x000000ff;
1536 surface_desc.ddckCKSrcBlt.dwColorSpaceHighValue = 0x000000ff;
1537 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
1538 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1539 hr = IDirect3DDevice7_SetTexture(device, 0, surface);
1540 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
1542 memset(&fx, 0, sizeof(fx));
1543 fx.dwSize = sizeof(fx);
1544 U5(fx).dwFillColor = 0x000000ff;
1545 hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx);
1546 ok(SUCCEEDED(hr), "Failed to fill surface, hr %#x.\n", hr);
1548 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 1.0f, 0);
1549 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
1550 hr = IDirect3DDevice7_BeginScene(device);
1551 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1552 hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, &value);
1553 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1554 ok(!value, "Got unexpected color keying state %#x.\n", value);
1555 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0);
1556 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1557 hr = IDirect3DDevice7_EndScene(device);
1558 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1559 color = get_surface_color(rt, 320, 240);
1560 ok(compare_color(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
1562 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 1.0f, 0);
1563 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
1564 hr = IDirect3DDevice7_BeginScene(device);
1565 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1566 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, TRUE);
1567 ok(SUCCEEDED(hr), "Failed to enable color keying, hr %#x.\n", hr);
1568 hr = IDirect3DDevice7_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DFVF_XYZRHW | D3DFVF_TEX1, &tquad[0], 4, 0);
1569 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1570 hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_COLORKEYENABLE, &value);
1571 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
1572 ok(!!value, "Got unexpected color keying state %#x.\n", value);
1573 hr = IDirect3DDevice7_EndScene(device);
1574 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1575 color = get_surface_color(rt, 320, 240);
1576 ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
1578 IDirectDrawSurface7_Release(surface);
1579 IDirectDrawSurface7_Release(rt);
1580 IDirect3DDevice7_Release(device);
1581 IDirectDraw7_Release(ddraw);
1582 DestroyWindow(window);
1585 struct qi_test
1587 REFIID iid;
1588 REFIID refcount_iid;
1589 HRESULT hr;
1592 static void test_qi(const char *test_name, IUnknown *base_iface,
1593 REFIID refcount_iid, const struct qi_test *tests, UINT entry_count)
1595 ULONG refcount, expected_refcount;
1596 IUnknown *iface1, *iface2;
1597 HRESULT hr;
1598 UINT i, j;
1600 for (i = 0; i < entry_count; ++i)
1602 hr = IUnknown_QueryInterface(base_iface, tests[i].iid, (void **)&iface1);
1603 ok(hr == tests[i].hr, "Got hr %#x for test \"%s\" %u.\n", hr, test_name, i);
1604 if (SUCCEEDED(hr))
1606 for (j = 0; j < entry_count; ++j)
1608 hr = IUnknown_QueryInterface(iface1, tests[j].iid, (void **)&iface2);
1609 ok(hr == tests[j].hr, "Got hr %#x for test \"%s\" %u, %u.\n", hr, test_name, i, j);
1610 if (SUCCEEDED(hr))
1612 expected_refcount = 0;
1613 if (IsEqualGUID(refcount_iid, tests[j].refcount_iid))
1614 ++expected_refcount;
1615 if (IsEqualGUID(tests[i].refcount_iid, tests[j].refcount_iid))
1616 ++expected_refcount;
1617 refcount = IUnknown_Release(iface2);
1618 ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1619 refcount, test_name, i, j, expected_refcount);
1623 expected_refcount = 0;
1624 if (IsEqualGUID(refcount_iid, tests[i].refcount_iid))
1625 ++expected_refcount;
1626 refcount = IUnknown_Release(iface1);
1627 ok(refcount == expected_refcount, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1628 refcount, test_name, i, expected_refcount);
1633 static void test_surface_qi(void)
1635 static const struct qi_test tests[] =
1637 {&IID_IDirect3DTexture2, NULL, E_NOINTERFACE},
1638 {&IID_IDirect3DTexture, NULL, E_NOINTERFACE},
1639 {&IID_IDirectDrawGammaControl, &IID_IDirectDrawGammaControl, S_OK },
1640 {&IID_IDirectDrawColorControl, NULL, E_NOINTERFACE},
1641 {&IID_IDirectDrawSurface7, &IID_IDirectDrawSurface7, S_OK },
1642 {&IID_IDirectDrawSurface4, &IID_IDirectDrawSurface4, S_OK },
1643 {&IID_IDirectDrawSurface3, &IID_IDirectDrawSurface3, S_OK },
1644 {&IID_IDirectDrawSurface2, &IID_IDirectDrawSurface2, S_OK },
1645 {&IID_IDirectDrawSurface, &IID_IDirectDrawSurface, S_OK },
1646 {&IID_IDirect3DDevice7, NULL, E_NOINTERFACE},
1647 {&IID_IDirect3DDevice3, NULL, E_NOINTERFACE},
1648 {&IID_IDirect3DDevice2, NULL, E_NOINTERFACE},
1649 {&IID_IDirect3DDevice, NULL, E_NOINTERFACE},
1650 {&IID_IDirect3DRampDevice, NULL, E_NOINTERFACE},
1651 {&IID_IDirect3DRGBDevice, NULL, E_NOINTERFACE},
1652 {&IID_IDirect3DHALDevice, NULL, E_NOINTERFACE},
1653 {&IID_IDirect3DMMXDevice, NULL, E_NOINTERFACE},
1654 {&IID_IDirect3DRefDevice, NULL, E_NOINTERFACE},
1655 {&IID_IDirect3DTnLHalDevice, NULL, E_NOINTERFACE},
1656 {&IID_IDirect3DNullDevice, NULL, E_NOINTERFACE},
1657 {&IID_IDirect3D7, NULL, E_NOINTERFACE},
1658 {&IID_IDirect3D3, NULL, E_NOINTERFACE},
1659 {&IID_IDirect3D2, NULL, E_NOINTERFACE},
1660 {&IID_IDirect3D, NULL, E_NOINTERFACE},
1661 {&IID_IDirectDraw7, NULL, E_NOINTERFACE},
1662 {&IID_IDirectDraw4, NULL, E_NOINTERFACE},
1663 {&IID_IDirectDraw3, NULL, E_NOINTERFACE},
1664 {&IID_IDirectDraw2, NULL, E_NOINTERFACE},
1665 {&IID_IDirectDraw, NULL, E_NOINTERFACE},
1666 {&IID_IDirect3DLight, NULL, E_NOINTERFACE},
1667 {&IID_IDirect3DMaterial, NULL, E_NOINTERFACE},
1668 {&IID_IDirect3DMaterial2, NULL, E_NOINTERFACE},
1669 {&IID_IDirect3DMaterial3, NULL, E_NOINTERFACE},
1670 {&IID_IDirect3DExecuteBuffer, NULL, E_NOINTERFACE},
1671 {&IID_IDirect3DViewport, NULL, E_NOINTERFACE},
1672 {&IID_IDirect3DViewport2, NULL, E_NOINTERFACE},
1673 {&IID_IDirect3DViewport3, NULL, E_NOINTERFACE},
1674 {&IID_IDirect3DVertexBuffer, NULL, E_NOINTERFACE},
1675 {&IID_IDirect3DVertexBuffer7, NULL, E_NOINTERFACE},
1676 {&IID_IDirectDrawPalette, NULL, E_NOINTERFACE},
1677 {&IID_IDirectDrawClipper, NULL, E_NOINTERFACE},
1678 {&IID_IUnknown, &IID_IDirectDrawSurface, S_OK },
1681 IDirectDrawSurface7 *surface;
1682 DDSURFACEDESC2 surface_desc;
1683 IDirect3DDevice7 *device;
1684 IDirectDraw7 *ddraw;
1685 HWND window;
1686 HRESULT hr;
1688 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1689 0, 0, 640, 480, 0, 0, 0, 0);
1690 /* Try to create a D3D device to see if the ddraw implementation supports
1691 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1692 * doesn't support e.g. the IDirect3DTexture interfaces. */
1693 if (!(device = create_device(window, DDSCL_NORMAL)))
1695 skip("Failed to create D3D device, skipping test.\n");
1696 DestroyWindow(window);
1697 return;
1699 IDirect3DDevice_Release(device);
1700 if (!(ddraw = create_ddraw()))
1702 skip("Failed to create a ddraw object, skipping test.\n");
1703 DestroyWindow(window);
1704 return;
1706 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
1707 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
1709 memset(&surface_desc, 0, sizeof(surface_desc));
1710 surface_desc.dwSize = sizeof(surface_desc);
1711 surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
1712 surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1713 surface_desc.dwWidth = 512;
1714 surface_desc.dwHeight = 512;
1715 hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
1716 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
1718 test_qi("surface_qi", (IUnknown *)surface, &IID_IDirectDrawSurface7, tests, sizeof(tests) / sizeof(*tests));
1720 IDirectDrawSurface7_Release(surface);
1721 IDirectDraw7_Release(ddraw);
1722 DestroyWindow(window);
1725 static void test_device_qi(void)
1727 static const struct qi_test tests[] =
1729 {&IID_IDirect3DTexture2, NULL, E_NOINTERFACE},
1730 {&IID_IDirect3DTexture, NULL, E_NOINTERFACE},
1731 {&IID_IDirectDrawGammaControl, NULL, E_NOINTERFACE},
1732 {&IID_IDirectDrawColorControl, NULL, E_NOINTERFACE},
1733 {&IID_IDirectDrawSurface7, NULL, E_NOINTERFACE},
1734 {&IID_IDirectDrawSurface4, NULL, E_NOINTERFACE},
1735 {&IID_IDirectDrawSurface3, NULL, E_NOINTERFACE},
1736 {&IID_IDirectDrawSurface2, NULL, E_NOINTERFACE},
1737 {&IID_IDirectDrawSurface, NULL, E_NOINTERFACE},
1738 {&IID_IDirect3DDevice7, &IID_IDirect3DDevice7, S_OK },
1739 {&IID_IDirect3DDevice3, NULL, E_NOINTERFACE},
1740 {&IID_IDirect3DDevice2, NULL, E_NOINTERFACE},
1741 {&IID_IDirect3DDevice, NULL, E_NOINTERFACE},
1742 {&IID_IDirect3DRampDevice, NULL, E_NOINTERFACE},
1743 {&IID_IDirect3DRGBDevice, NULL, E_NOINTERFACE},
1744 {&IID_IDirect3DHALDevice, NULL, E_NOINTERFACE},
1745 {&IID_IDirect3DMMXDevice, NULL, E_NOINTERFACE},
1746 {&IID_IDirect3DRefDevice, NULL, E_NOINTERFACE},
1747 {&IID_IDirect3DTnLHalDevice, NULL, E_NOINTERFACE},
1748 {&IID_IDirect3DNullDevice, NULL, E_NOINTERFACE},
1749 {&IID_IDirect3D7, NULL, E_NOINTERFACE},
1750 {&IID_IDirect3D3, NULL, E_NOINTERFACE},
1751 {&IID_IDirect3D2, NULL, E_NOINTERFACE},
1752 {&IID_IDirect3D, NULL, E_NOINTERFACE},
1753 {&IID_IDirectDraw7, NULL, E_NOINTERFACE},
1754 {&IID_IDirectDraw4, NULL, E_NOINTERFACE},
1755 {&IID_IDirectDraw3, NULL, E_NOINTERFACE},
1756 {&IID_IDirectDraw2, NULL, E_NOINTERFACE},
1757 {&IID_IDirectDraw, NULL, E_NOINTERFACE},
1758 {&IID_IDirect3DLight, NULL, E_NOINTERFACE},
1759 {&IID_IDirect3DMaterial, NULL, E_NOINTERFACE},
1760 {&IID_IDirect3DMaterial2, NULL, E_NOINTERFACE},
1761 {&IID_IDirect3DMaterial3, NULL, E_NOINTERFACE},
1762 {&IID_IDirect3DExecuteBuffer, NULL, E_NOINTERFACE},
1763 {&IID_IDirect3DViewport, NULL, E_NOINTERFACE},
1764 {&IID_IDirect3DViewport2, NULL, E_NOINTERFACE},
1765 {&IID_IDirect3DViewport3, NULL, E_NOINTERFACE},
1766 {&IID_IDirect3DVertexBuffer, NULL, E_NOINTERFACE},
1767 {&IID_IDirect3DVertexBuffer7, NULL, E_NOINTERFACE},
1768 {&IID_IDirectDrawPalette, NULL, E_NOINTERFACE},
1769 {&IID_IDirectDrawClipper, NULL, E_NOINTERFACE},
1770 {&IID_IUnknown, &IID_IDirect3DDevice7, S_OK },
1773 IDirect3DDevice7 *device;
1774 HWND window;
1776 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1777 0, 0, 640, 480, 0, 0, 0, 0);
1778 if (!(device = create_device(window, DDSCL_NORMAL)))
1780 skip("Failed to create D3D device, skipping test.\n");
1781 DestroyWindow(window);
1782 return;
1785 test_qi("device_qi", (IUnknown *)device, &IID_IDirect3DDevice7, tests, sizeof(tests) / sizeof(*tests));
1787 IDirect3DDevice7_Release(device);
1788 DestroyWindow(window);
1791 static void test_wndproc(void)
1793 LONG_PTR proc, ddraw_proc;
1794 IDirectDraw7 *ddraw;
1795 WNDCLASSA wc = {0};
1796 HWND window;
1797 HRESULT hr;
1798 ULONG ref;
1800 static const UINT messages[] =
1802 WM_WINDOWPOSCHANGING,
1803 WM_MOVE,
1804 WM_SIZE,
1805 WM_WINDOWPOSCHANGING,
1806 WM_ACTIVATE,
1807 WM_SETFOCUS,
1811 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
1812 if (!(ddraw = create_ddraw()))
1814 skip("Failed to create IDirectDraw7 object, skipping tests.\n");
1815 return;
1818 wc.lpfnWndProc = test_proc;
1819 wc.lpszClassName = "ddraw_test_wndproc_wc";
1820 ok(RegisterClassA(&wc), "Failed to register window class.\n");
1822 window = CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
1823 WS_MAXIMIZE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
1825 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1826 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1827 (LONG_PTR)test_proc, proc);
1828 expect_messages = messages;
1829 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1830 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1831 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
1832 expect_messages = NULL;
1833 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1834 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
1835 (LONG_PTR)test_proc, proc);
1836 ref = IDirectDraw7_Release(ddraw);
1837 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
1838 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1839 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1840 (LONG_PTR)test_proc, proc);
1842 /* DDSCL_NORMAL doesn't. */
1843 ddraw = create_ddraw();
1844 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1845 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1846 (LONG_PTR)test_proc, proc);
1847 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
1848 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1849 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1850 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1851 (LONG_PTR)test_proc, proc);
1852 ref = IDirectDraw7_Release(ddraw);
1853 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
1854 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1855 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1856 (LONG_PTR)test_proc, proc);
1858 /* The original window proc is only restored by ddraw if the current
1859 * window proc matches the one ddraw set. This also affects switching
1860 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
1861 ddraw = create_ddraw();
1862 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1863 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1864 (LONG_PTR)test_proc, proc);
1865 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1866 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1867 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1868 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
1869 (LONG_PTR)test_proc, proc);
1870 ddraw_proc = proc;
1871 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
1872 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1873 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1874 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1875 (LONG_PTR)test_proc, proc);
1876 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1877 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1878 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
1879 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
1880 (LONG_PTR)test_proc, proc);
1881 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
1882 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1883 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1884 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
1885 (LONG_PTR)DefWindowProcA, proc);
1886 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1887 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1888 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)ddraw_proc);
1889 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
1890 (LONG_PTR)DefWindowProcA, proc);
1891 ref = IDirectDraw7_Release(ddraw);
1892 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
1893 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1894 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1895 (LONG_PTR)test_proc, proc);
1897 ddraw = create_ddraw();
1898 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1899 ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx.\n",
1900 (LONG_PTR)test_proc, proc);
1901 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1902 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1903 proc = SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)DefWindowProcA);
1904 ok(proc != (LONG_PTR)test_proc, "Expected wndproc != %#lx, got %#lx.\n",
1905 (LONG_PTR)test_proc, proc);
1906 ref = IDirectDraw7_Release(ddraw);
1907 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
1908 proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
1909 ok(proc == (LONG_PTR)DefWindowProcA, "Expected wndproc %#lx, got %#lx.\n",
1910 (LONG_PTR)DefWindowProcA, proc);
1912 fix_wndproc(window, (LONG_PTR)test_proc);
1913 expect_messages = NULL;
1914 DestroyWindow(window);
1915 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL));
1918 static void test_window_style(void)
1920 LONG style, exstyle, tmp;
1921 RECT fullscreen_rect, r;
1922 IDirectDraw7 *ddraw;
1923 HWND window;
1924 HRESULT hr;
1925 ULONG ref;
1927 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1928 0, 0, 100, 100, 0, 0, 0, 0);
1929 if (!(ddraw = create_ddraw()))
1931 skip("Failed to create a ddraw object, skipping test.\n");
1932 DestroyWindow(window);
1933 return;
1936 style = GetWindowLongA(window, GWL_STYLE);
1937 exstyle = GetWindowLongA(window, GWL_EXSTYLE);
1938 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
1940 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1941 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1943 tmp = GetWindowLongA(window, GWL_STYLE);
1944 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
1945 tmp = GetWindowLongA(window, GWL_EXSTYLE);
1946 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
1948 GetWindowRect(window, &r);
1949 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
1950 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
1951 r.left, r.top, r.right, r.bottom);
1952 GetClientRect(window, &r);
1953 todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
1955 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
1956 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1958 tmp = GetWindowLongA(window, GWL_STYLE);
1959 todo_wine ok(tmp == style, "Expected window style %#x, got %#x.\n", style, tmp);
1960 tmp = GetWindowLongA(window, GWL_EXSTYLE);
1961 todo_wine ok(tmp == exstyle, "Expected window extended style %#x, got %#x.\n", exstyle, tmp);
1963 ref = IDirectDraw7_Release(ddraw);
1964 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
1966 DestroyWindow(window);
1969 static void test_redundant_mode_set(void)
1971 DDSURFACEDESC2 surface_desc = {0};
1972 IDirectDraw7 *ddraw;
1973 HWND window;
1974 HRESULT hr;
1975 RECT r, s;
1976 ULONG ref;
1978 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
1979 0, 0, 100, 100, 0, 0, 0, 0);
1980 if (!(ddraw = create_ddraw()))
1982 skip("Failed to create a ddraw object, skipping test.\n");
1983 DestroyWindow(window);
1984 return;
1987 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
1988 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
1990 surface_desc.dwSize = sizeof(surface_desc);
1991 hr = IDirectDraw7_GetDisplayMode(ddraw, &surface_desc);
1992 ok(SUCCEEDED(hr), "GetDipslayMode failed, hr %#x.\n", hr);
1994 hr = IDirectDraw7_SetDisplayMode(ddraw, surface_desc.dwWidth, surface_desc.dwHeight,
1995 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
1996 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
1998 GetWindowRect(window, &r);
1999 r.right /= 2;
2000 r.bottom /= 2;
2001 SetWindowPos(window, HWND_TOP, r.left, r.top, r.right, r.bottom, 0);
2002 GetWindowRect(window, &s);
2003 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2004 r.left, r.top, r.right, r.bottom,
2005 s.left, s.top, s.right, s.bottom);
2007 hr = IDirectDraw7_SetDisplayMode(ddraw, surface_desc.dwWidth, surface_desc.dwHeight,
2008 U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, 0, 0);
2009 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2011 GetWindowRect(window, &s);
2012 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2013 r.left, r.top, r.right, r.bottom,
2014 s.left, s.top, s.right, s.bottom);
2016 ref = IDirectDraw7_Release(ddraw);
2017 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2019 DestroyWindow(window);
2022 static SIZE screen_size;
2024 static LRESULT CALLBACK mode_set_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
2026 if (message == WM_SIZE)
2028 screen_size.cx = GetSystemMetrics(SM_CXSCREEN);
2029 screen_size.cy = GetSystemMetrics(SM_CYSCREEN);
2032 return test_proc(hwnd, message, wparam, lparam);
2035 static void test_coop_level_mode_set(void)
2037 IDirectDrawSurface7 *primary;
2038 RECT fullscreen_rect, r, s;
2039 IDirectDraw7 *ddraw;
2040 DDSURFACEDESC2 ddsd;
2041 WNDCLASSA wc = {0};
2042 HWND window;
2043 HRESULT hr;
2044 ULONG ref;
2046 static const UINT exclusive_messages[] =
2048 WM_WINDOWPOSCHANGING,
2049 WM_WINDOWPOSCHANGED,
2050 WM_SIZE,
2051 WM_DISPLAYCHANGE,
2055 static const UINT normal_messages[] =
2057 WM_DISPLAYCHANGE,
2061 if (!(ddraw = create_ddraw()))
2063 skip("Failed to create a ddraw object, skipping test.\n");
2064 return;
2067 wc.lpfnWndProc = mode_set_proc;
2068 wc.lpszClassName = "ddraw_test_wndproc_wc";
2069 ok(RegisterClassA(&wc), "Failed to register window class.\n");
2071 window = CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW,
2072 0, 0, 100, 100, 0, 0, 0, 0);
2074 SetRect(&fullscreen_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2075 SetRect(&s, 0, 0, 640, 480);
2077 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2078 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2080 GetWindowRect(window, &r);
2081 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2082 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2083 r.left, r.top, r.right, r.bottom);
2085 memset(&ddsd, 0, sizeof(ddsd));
2086 ddsd.dwSize = sizeof(ddsd);
2087 ddsd.dwFlags = DDSD_CAPS;
2088 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2090 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2091 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2092 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2093 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2094 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2095 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2096 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2097 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2099 GetWindowRect(window, &r);
2100 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2101 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2102 r.left, r.top, r.right, r.bottom);
2104 expect_messages = exclusive_messages;
2105 screen_size.cx = 0;
2106 screen_size.cy = 0;
2108 hr = IDirectDraw7_SetDisplayMode(ddraw, 640, 480, 32, 0, 0);
2109 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2111 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2112 expect_messages = NULL;
2113 ok(screen_size.cx == s.right && screen_size.cy == s.bottom,
2114 "Expected screen size %ux%u, got %ux%u.\n",
2115 s.right, s.bottom, screen_size.cx, screen_size.cy);
2117 GetWindowRect(window, &r);
2118 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2119 s.left, s.top, s.right, s.bottom,
2120 r.left, r.top, r.right, r.bottom);
2122 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2123 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2124 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2125 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2126 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2127 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2128 IDirectDrawSurface7_Release(primary);
2130 memset(&ddsd, 0, sizeof(ddsd));
2131 ddsd.dwSize = sizeof(ddsd);
2132 ddsd.dwFlags = DDSD_CAPS;
2133 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2135 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2136 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2137 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2138 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2139 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2140 s.right - s.left, ddsd.dwWidth);
2141 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2142 s.bottom - s.top, ddsd.dwHeight);
2144 GetWindowRect(window, &r);
2145 ok(EqualRect(&r, &s), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2146 s.left, s.top, s.right, s.bottom,
2147 r.left, r.top, r.right, r.bottom);
2149 expect_messages = exclusive_messages;
2150 screen_size.cx = 0;
2151 screen_size.cy = 0;
2153 hr = IDirectDraw_RestoreDisplayMode(ddraw);
2154 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
2156 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2157 expect_messages = NULL;
2158 ok(screen_size.cx == fullscreen_rect.right && screen_size.cy == fullscreen_rect.bottom,
2159 "Expected screen size %ux%u, got %ux%u.\n",
2160 fullscreen_rect.right, fullscreen_rect.bottom, screen_size.cx, screen_size.cy);
2162 GetWindowRect(window, &r);
2163 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2164 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2165 r.left, r.top, r.right, r.bottom);
2167 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2168 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2169 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2170 s.right - s.left, ddsd.dwWidth);
2171 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2172 s.bottom - s.top, ddsd.dwHeight);
2173 IDirectDrawSurface7_Release(primary);
2175 memset(&ddsd, 0, sizeof(ddsd));
2176 ddsd.dwSize = sizeof(ddsd);
2177 ddsd.dwFlags = DDSD_CAPS;
2178 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2180 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2181 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2182 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2183 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2184 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2185 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2186 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2187 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2189 GetWindowRect(window, &r);
2190 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2191 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2192 r.left, r.top, r.right, r.bottom);
2194 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
2195 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2197 GetWindowRect(window, &r);
2198 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2199 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2200 r.left, r.top, r.right, r.bottom);
2202 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2203 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2204 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2205 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2206 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2207 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2208 IDirectDrawSurface7_Release(primary);
2210 memset(&ddsd, 0, sizeof(ddsd));
2211 ddsd.dwSize = sizeof(ddsd);
2212 ddsd.dwFlags = DDSD_CAPS;
2213 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2215 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2216 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2217 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2218 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2219 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2220 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2221 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2222 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2224 GetWindowRect(window, &r);
2225 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2226 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2227 r.left, r.top, r.right, r.bottom);
2229 expect_messages = normal_messages;
2230 screen_size.cx = 0;
2231 screen_size.cy = 0;
2233 hr = IDirectDraw7_SetDisplayMode(ddraw, 640, 480, 32, 0, 0);
2234 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2236 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2237 expect_messages = NULL;
2238 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
2240 GetWindowRect(window, &r);
2241 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2242 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2243 r.left, r.top, r.right, r.bottom);
2245 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2246 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2247 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2248 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2249 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2250 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2251 IDirectDrawSurface7_Release(primary);
2253 memset(&ddsd, 0, sizeof(ddsd));
2254 ddsd.dwSize = sizeof(ddsd);
2255 ddsd.dwFlags = DDSD_CAPS;
2256 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2258 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2259 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2260 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2261 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2262 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2263 s.right - s.left, ddsd.dwWidth);
2264 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2265 s.bottom - s.top, ddsd.dwHeight);
2267 GetWindowRect(window, &r);
2268 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2269 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2270 r.left, r.top, r.right, r.bottom);
2272 expect_messages = normal_messages;
2273 screen_size.cx = 0;
2274 screen_size.cy = 0;
2276 hr = IDirectDraw_RestoreDisplayMode(ddraw);
2277 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
2279 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2280 expect_messages = NULL;
2281 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
2283 GetWindowRect(window, &r);
2284 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2285 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2286 r.left, r.top, r.right, r.bottom);
2288 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2289 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2290 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2291 s.right - s.left, ddsd.dwWidth);
2292 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2293 s.bottom - s.top, ddsd.dwHeight);
2294 IDirectDrawSurface7_Release(primary);
2296 memset(&ddsd, 0, sizeof(ddsd));
2297 ddsd.dwSize = sizeof(ddsd);
2298 ddsd.dwFlags = DDSD_CAPS;
2299 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2301 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2302 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2303 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2304 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2305 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2306 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2307 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2308 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2310 GetWindowRect(window, &r);
2311 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2312 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2313 r.left, r.top, r.right, r.bottom);
2315 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2316 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2317 * not DDSCL_FULLSCREEN. */
2318 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL | DDSCL_FULLSCREEN);
2319 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2321 GetWindowRect(window, &r);
2322 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2323 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2324 r.left, r.top, r.right, r.bottom);
2326 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2327 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2328 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2329 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2330 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2331 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2332 IDirectDrawSurface7_Release(primary);
2334 memset(&ddsd, 0, sizeof(ddsd));
2335 ddsd.dwSize = sizeof(ddsd);
2336 ddsd.dwFlags = DDSD_CAPS;
2337 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2339 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2340 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2341 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2342 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2343 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2344 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2345 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2346 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2348 GetWindowRect(window, &r);
2349 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2350 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2351 r.left, r.top, r.right, r.bottom);
2353 expect_messages = normal_messages;
2354 screen_size.cx = 0;
2355 screen_size.cy = 0;
2357 hr = IDirectDraw7_SetDisplayMode(ddraw, 640, 480, 32, 0, 0);
2358 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2360 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2361 expect_messages = NULL;
2362 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
2364 GetWindowRect(window, &r);
2365 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2366 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2367 r.left, r.top, r.right, r.bottom);
2369 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2370 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2371 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2372 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2373 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2374 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2375 IDirectDrawSurface7_Release(primary);
2377 memset(&ddsd, 0, sizeof(ddsd));
2378 ddsd.dwSize = sizeof(ddsd);
2379 ddsd.dwFlags = DDSD_CAPS;
2380 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2382 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2383 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2384 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2385 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2386 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2387 s.right - s.left, ddsd.dwWidth);
2388 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2389 s.bottom - s.top, ddsd.dwHeight);
2391 GetWindowRect(window, &r);
2392 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2393 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2394 r.left, r.top, r.right, r.bottom);
2396 expect_messages = normal_messages;
2397 screen_size.cx = 0;
2398 screen_size.cy = 0;
2400 hr = IDirectDraw_RestoreDisplayMode(ddraw);
2401 ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr);
2403 ok(!*expect_messages, "Expected message %#x, but didn't receive it.\n", *expect_messages);
2404 expect_messages = NULL;
2405 ok(!screen_size.cx && !screen_size.cy, "Got unxpected screen size %ux%u.\n", screen_size.cx, screen_size.cy);
2407 GetWindowRect(window, &r);
2408 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2409 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2410 r.left, r.top, r.right, r.bottom);
2412 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2413 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2414 ok(ddsd.dwWidth == s.right - s.left, "Expected surface width %u, got %u.\n",
2415 s.right - s.left, ddsd.dwWidth);
2416 ok(ddsd.dwHeight == s.bottom - s.top, "Expected surface height %u, got %u.\n",
2417 s.bottom - s.top, ddsd.dwHeight);
2418 IDirectDrawSurface7_Release(primary);
2420 memset(&ddsd, 0, sizeof(ddsd));
2421 ddsd.dwSize = sizeof(ddsd);
2422 ddsd.dwFlags = DDSD_CAPS;
2423 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2425 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &primary, NULL);
2426 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n",hr);
2427 hr = IDirectDrawSurface7_GetSurfaceDesc(primary, &ddsd);
2428 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
2429 ok(ddsd.dwWidth == fullscreen_rect.right - fullscreen_rect.left, "Expected surface width %u, got %u.\n",
2430 fullscreen_rect.right - fullscreen_rect.left, ddsd.dwWidth);
2431 ok(ddsd.dwHeight == fullscreen_rect.bottom - fullscreen_rect.top, "Expected surface height %u, got %u.\n",
2432 fullscreen_rect.bottom - fullscreen_rect.top, ddsd.dwHeight);
2433 IDirectDrawSurface7_Release(primary);
2435 GetWindowRect(window, &r);
2436 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2437 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2438 r.left, r.top, r.right, r.bottom);
2440 ref = IDirectDraw7_Release(ddraw);
2441 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2443 GetWindowRect(window, &r);
2444 ok(EqualRect(&r, &fullscreen_rect), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2445 fullscreen_rect.left, fullscreen_rect.top, fullscreen_rect.right, fullscreen_rect.bottom,
2446 r.left, r.top, r.right, r.bottom);
2448 expect_messages = NULL;
2449 DestroyWindow(window);
2450 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL));
2453 static void test_coop_level_mode_set_multi(void)
2455 IDirectDraw7 *ddraw1, *ddraw2;
2456 UINT orig_w, orig_h, w, h;
2457 HWND window;
2458 HRESULT hr;
2459 ULONG ref;
2461 if (!(ddraw1 = create_ddraw()))
2463 skip("Failed to create a ddraw object, skipping test.\n");
2464 return;
2467 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2468 0, 0, 100, 100, 0, 0, 0, 0);
2470 orig_w = GetSystemMetrics(SM_CXSCREEN);
2471 orig_h = GetSystemMetrics(SM_CYSCREEN);
2473 /* With just a single ddraw object, the display mode is restored on
2474 * release. */
2475 hr = IDirectDraw7_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2476 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2477 w = GetSystemMetrics(SM_CXSCREEN);
2478 ok(w == 800, "Got unexpected screen width %u.\n", w);
2479 h = GetSystemMetrics(SM_CYSCREEN);
2480 ok(h == 600, "Got unexpected screen height %u.\n", h);
2482 ref = IDirectDraw7_Release(ddraw1);
2483 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2484 w = GetSystemMetrics(SM_CXSCREEN);
2485 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2486 h = GetSystemMetrics(SM_CYSCREEN);
2487 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2489 /* When there are multiple ddraw objects, the display mode is restored to
2490 * the initial mode, before the first SetDisplayMode() call. */
2491 ddraw1 = create_ddraw();
2492 hr = IDirectDraw7_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2493 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2494 w = GetSystemMetrics(SM_CXSCREEN);
2495 ok(w == 800, "Got unexpected screen width %u.\n", w);
2496 h = GetSystemMetrics(SM_CYSCREEN);
2497 ok(h == 600, "Got unexpected screen height %u.\n", h);
2499 ddraw2 = create_ddraw();
2500 hr = IDirectDraw7_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2501 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2502 w = GetSystemMetrics(SM_CXSCREEN);
2503 ok(w == 640, "Got unexpected screen width %u.\n", w);
2504 h = GetSystemMetrics(SM_CYSCREEN);
2505 ok(h == 480, "Got unexpected screen height %u.\n", h);
2507 ref = IDirectDraw7_Release(ddraw2);
2508 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2509 w = GetSystemMetrics(SM_CXSCREEN);
2510 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2511 h = GetSystemMetrics(SM_CYSCREEN);
2512 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2514 ref = IDirectDraw7_Release(ddraw1);
2515 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2516 w = GetSystemMetrics(SM_CXSCREEN);
2517 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2518 h = GetSystemMetrics(SM_CYSCREEN);
2519 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2521 /* Regardless of release ordering. */
2522 ddraw1 = create_ddraw();
2523 hr = IDirectDraw7_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2524 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2525 w = GetSystemMetrics(SM_CXSCREEN);
2526 ok(w == 800, "Got unexpected screen width %u.\n", w);
2527 h = GetSystemMetrics(SM_CYSCREEN);
2528 ok(h == 600, "Got unexpected screen height %u.\n", h);
2530 ddraw2 = create_ddraw();
2531 hr = IDirectDraw7_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2532 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2533 w = GetSystemMetrics(SM_CXSCREEN);
2534 ok(w == 640, "Got unexpected screen width %u.\n", w);
2535 h = GetSystemMetrics(SM_CYSCREEN);
2536 ok(h == 480, "Got unexpected screen height %u.\n", h);
2538 ref = IDirectDraw7_Release(ddraw1);
2539 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2540 w = GetSystemMetrics(SM_CXSCREEN);
2541 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2542 h = GetSystemMetrics(SM_CYSCREEN);
2543 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2545 ref = IDirectDraw7_Release(ddraw2);
2546 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2547 w = GetSystemMetrics(SM_CXSCREEN);
2548 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2549 h = GetSystemMetrics(SM_CYSCREEN);
2550 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2552 /* But only for ddraw objects that called SetDisplayMode(). */
2553 ddraw1 = create_ddraw();
2554 ddraw2 = create_ddraw();
2555 hr = IDirectDraw7_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2556 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2557 w = GetSystemMetrics(SM_CXSCREEN);
2558 ok(w == 640, "Got unexpected screen width %u.\n", w);
2559 h = GetSystemMetrics(SM_CYSCREEN);
2560 ok(h == 480, "Got unexpected screen height %u.\n", h);
2562 ref = IDirectDraw7_Release(ddraw1);
2563 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2564 w = GetSystemMetrics(SM_CXSCREEN);
2565 ok(w == 640, "Got unexpected screen width %u.\n", w);
2566 h = GetSystemMetrics(SM_CYSCREEN);
2567 ok(h == 480, "Got unexpected screen height %u.\n", h);
2569 ref = IDirectDraw7_Release(ddraw2);
2570 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2571 w = GetSystemMetrics(SM_CXSCREEN);
2572 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2573 h = GetSystemMetrics(SM_CYSCREEN);
2574 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2576 /* If there's a ddraw object that's currently in exclusive mode, it blocks
2577 * restoring the display mode. */
2578 ddraw1 = create_ddraw();
2579 hr = IDirectDraw7_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2580 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2581 w = GetSystemMetrics(SM_CXSCREEN);
2582 ok(w == 800, "Got unexpected screen width %u.\n", w);
2583 h = GetSystemMetrics(SM_CYSCREEN);
2584 ok(h == 600, "Got unexpected screen height %u.\n", h);
2586 ddraw2 = create_ddraw();
2587 hr = IDirectDraw7_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2588 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2589 w = GetSystemMetrics(SM_CXSCREEN);
2590 ok(w == 640, "Got unexpected screen width %u.\n", w);
2591 h = GetSystemMetrics(SM_CYSCREEN);
2592 ok(h == 480, "Got unexpected screen height %u.\n", h);
2594 hr = IDirectDraw7_SetCooperativeLevel(ddraw2, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2595 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2597 ref = IDirectDraw7_Release(ddraw1);
2598 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2599 w = GetSystemMetrics(SM_CXSCREEN);
2600 ok(w == 640, "Got unexpected screen width %u.\n", w);
2601 h = GetSystemMetrics(SM_CYSCREEN);
2602 ok(h == 480, "Got unexpected screen height %u.\n", h);
2604 ref = IDirectDraw7_Release(ddraw2);
2605 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2606 w = GetSystemMetrics(SM_CXSCREEN);
2607 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2608 h = GetSystemMetrics(SM_CYSCREEN);
2609 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2611 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
2612 ddraw1 = create_ddraw();
2613 hr = IDirectDraw7_SetDisplayMode(ddraw1, 800, 600, 32, 0, 0);
2614 ok(SUCCEEDED(hr), "SetDipslayMode failed, hr %#x.\n", hr);
2615 w = GetSystemMetrics(SM_CXSCREEN);
2616 ok(w == 800, "Got unexpected screen width %u.\n", w);
2617 h = GetSystemMetrics(SM_CYSCREEN);
2618 ok(h == 600, "Got unexpected screen height %u.\n", h);
2620 hr = IDirectDraw7_SetCooperativeLevel(ddraw1, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
2621 ok(SUCCEEDED(hr), "SetCooperativeLevel failed, hr %#x.\n", hr);
2623 ddraw2 = create_ddraw();
2624 hr = IDirectDraw7_SetDisplayMode(ddraw2, 640, 480, 32, 0, 0);
2625 ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr);
2627 ref = IDirectDraw7_Release(ddraw1);
2628 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2629 w = GetSystemMetrics(SM_CXSCREEN);
2630 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2631 h = GetSystemMetrics(SM_CYSCREEN);
2632 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2634 ref = IDirectDraw7_Release(ddraw2);
2635 ok(ref == 0, "The ddraw object was not properly freed: refcount %u.\n", ref);
2636 w = GetSystemMetrics(SM_CXSCREEN);
2637 ok(w == orig_w, "Got unexpected screen width %u.\n", w);
2638 h = GetSystemMetrics(SM_CYSCREEN);
2639 ok(h == orig_h, "Got unexpected screen height %u.\n", h);
2641 DestroyWindow(window);
2644 static void test_initialize(void)
2646 IDirectDraw7 *ddraw;
2647 HRESULT hr;
2649 if (!(ddraw = create_ddraw()))
2651 skip("Failed to create a ddraw object, skipping test.\n");
2652 return;
2655 hr = IDirectDraw7_Initialize(ddraw, NULL);
2656 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x.\n", hr);
2657 IDirectDraw7_Release(ddraw);
2659 CoInitialize(NULL);
2660 hr = CoCreateInstance(&CLSID_DirectDraw, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectDraw7, (void **)&ddraw);
2661 ok(SUCCEEDED(hr), "Failed to create IDirectDraw7 instance, hr %#x.\n", hr);
2662 hr = IDirectDraw7_Initialize(ddraw, NULL);
2663 ok(hr == DD_OK, "Initialize returned hr %#x, expected DD_OK.\n", hr);
2664 hr = IDirectDraw7_Initialize(ddraw, NULL);
2665 ok(hr == DDERR_ALREADYINITIALIZED, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr);
2666 IDirectDraw7_Release(ddraw);
2667 CoUninitialize();
2670 static void test_coop_level_surf_create(void)
2672 IDirectDrawSurface7 *surface;
2673 IDirectDraw7 *ddraw;
2674 DDSURFACEDESC2 ddsd;
2675 HRESULT hr;
2677 if (!(ddraw = create_ddraw()))
2679 skip("Failed to create a ddraw object, skipping test.\n");
2680 return;
2683 memset(&ddsd, 0, sizeof(ddsd));
2684 ddsd.dwSize = sizeof(ddsd);
2685 ddsd.dwFlags = DDSD_CAPS;
2686 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
2687 hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &surface, NULL);
2688 ok(hr == DDERR_NOCOOPERATIVELEVELSET, "Surface creation returned hr %#x.\n", hr);
2690 IDirectDraw7_Release(ddraw);
2693 static void test_vb_discard(void)
2695 static const struct vec4 quad[] =
2697 { 0.0f, 480.0f, 0.0f, 1.0f},
2698 { 0.0f, 0.0f, 0.0f, 1.0f},
2699 {640.0f, 480.0f, 0.0f, 1.0f},
2700 {640.0f, 0.0f, 0.0f, 1.0f},
2703 IDirect3DDevice7 *device;
2704 IDirect3D7 *d3d;
2705 IDirect3DVertexBuffer7 *buffer;
2706 HWND window;
2707 HRESULT hr;
2708 D3DVERTEXBUFFERDESC desc;
2709 BYTE *data;
2710 static const unsigned int vbsize = 16;
2711 unsigned int i;
2713 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2714 0, 0, 640, 480, 0, 0, 0, 0);
2716 if (!(device = create_device(window, DDSCL_NORMAL)))
2718 skip("Failed to create D3D device, skipping test.\n");
2719 DestroyWindow(window);
2720 return;
2723 hr = IDirect3DDevice7_GetDirect3D(device, &d3d);
2724 ok(SUCCEEDED(hr), "Failed to get d3d interface, hr %#x.\n", hr);
2726 memset(&desc, 0, sizeof(desc));
2727 desc.dwSize = sizeof(desc);
2728 desc.dwCaps = D3DVBCAPS_WRITEONLY;
2729 desc.dwFVF = D3DFVF_XYZRHW;
2730 desc.dwNumVertices = vbsize;
2731 hr = IDirect3D7_CreateVertexBuffer(d3d, &desc, &buffer, 0);
2732 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
2734 hr = IDirect3DVertexBuffer7_Lock(buffer, DDLOCK_DISCARDCONTENTS, (void **)&data, NULL);
2735 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
2736 memcpy(data, quad, sizeof(quad));
2737 hr = IDirect3DVertexBuffer7_Unlock(buffer);
2738 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
2740 hr = IDirect3DDevice7_BeginScene(device);
2741 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2742 hr = IDirect3DDevice7_DrawPrimitiveVB(device, D3DPT_TRIANGLESTRIP, buffer, 0, 4, 0);
2743 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2744 hr = IDirect3DDevice7_EndScene(device);
2745 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2747 hr = IDirect3DVertexBuffer7_Lock(buffer, DDLOCK_DISCARDCONTENTS, (void **)&data, NULL);
2748 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
2749 memset(data, 0xaa, sizeof(struct vec4) * vbsize);
2750 hr = IDirect3DVertexBuffer7_Unlock(buffer);
2751 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
2753 hr = IDirect3DVertexBuffer7_Lock(buffer, DDLOCK_DISCARDCONTENTS, (void **)&data, NULL);
2754 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
2755 for (i = 0; i < sizeof(struct vec4) * vbsize; i++)
2757 if (data[i] != 0xaa)
2759 ok(FALSE, "Vertex buffer data byte %u is 0x%02x, expected 0xaa\n", i, data[i]);
2760 break;
2763 hr = IDirect3DVertexBuffer7_Unlock(buffer);
2764 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
2766 IDirect3DVertexBuffer7_Release(buffer);
2767 IDirect3D7_Release(d3d);
2768 IDirect3DDevice7_Release(device);
2769 DestroyWindow(window);
2772 static void test_coop_level_multi_window(void)
2774 HWND window1, window2;
2775 IDirectDraw7 *ddraw;
2776 HRESULT hr;
2778 window1 = CreateWindowA("static", "ddraw_test1", WS_OVERLAPPEDWINDOW,
2779 0, 0, 640, 480, 0, 0, 0, 0);
2780 window2 = CreateWindowA("static", "ddraw_test2", WS_OVERLAPPEDWINDOW,
2781 0, 0, 640, 480, 0, 0, 0, 0);
2782 if (!(ddraw = create_ddraw()))
2784 skip("Failed to create a ddraw object, skipping test.\n");
2785 DestroyWindow(window2);
2786 DestroyWindow(window1);
2787 return;
2790 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL);
2791 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
2792 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL);
2793 ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
2794 ok(IsWindow(window1), "Window 1 was destroyed.\n");
2795 ok(IsWindow(window2), "Window 2 was destroyed.\n");
2797 IDirectDraw7_Release(ddraw);
2798 DestroyWindow(window2);
2799 DestroyWindow(window1);
2802 static void test_draw_strided(void)
2804 static struct vec3 position[] =
2806 {-1.0, -1.0, 0.0},
2807 {-1.0, 1.0, 0.0},
2808 { 1.0, 1.0, 0.0},
2809 { 1.0, -1.0, 0.0},
2811 static DWORD diffuse[] =
2813 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2815 static WORD indices[] =
2817 0, 1, 2, 2, 3, 0
2820 IDirectDrawSurface7 *rt;
2821 IDirect3DDevice7 *device;
2822 D3DCOLOR color;
2823 HWND window;
2824 HRESULT hr;
2825 D3DDRAWPRIMITIVESTRIDEDDATA strided;
2827 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2828 0, 0, 640, 480, 0, 0, 0, 0);
2830 if (!(device = create_device(window, DDSCL_NORMAL)))
2832 skip("Failed to create D3D device, skipping test.\n");
2833 DestroyWindow(window);
2834 return;
2837 hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
2838 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2840 hr = IDirect3DDevice7_SetRenderState(device, D3DRENDERSTATE_LIGHTING, FALSE);
2841 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
2842 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
2843 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2844 hr = IDirect3DDevice7_BeginScene(device);
2845 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2847 memset(&strided, 0x55, sizeof(strided));
2848 strided.position.lpvData = position;
2849 strided.position.dwStride = sizeof(*position);
2850 strided.diffuse.lpvData = diffuse;
2851 strided.diffuse.dwStride = sizeof(*diffuse);
2852 hr = IDirect3DDevice7_DrawIndexedPrimitiveStrided(device, D3DPT_TRIANGLELIST, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2853 &strided, 4, indices, 6, 0);
2854 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2856 hr = IDirect3DDevice7_EndScene(device);
2857 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2859 color = get_surface_color(rt, 320, 240);
2860 ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
2862 IDirectDrawSurface7_Release(rt);
2863 IDirect3DDevice7_Release(device);
2864 DestroyWindow(window);
2867 static void test_clear_rect_count(void)
2869 IDirectDrawSurface7 *rt;
2870 IDirect3DDevice7 *device;
2871 D3DCOLOR color;
2872 HWND window;
2873 HRESULT hr;
2874 D3DRECT rect = {{0}, {0}, {640}, {480}};
2876 window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
2877 0, 0, 640, 480, 0, 0, 0, 0);
2878 if (!(device = create_device(window, DDSCL_NORMAL)))
2880 skip("Failed to create D3D device, skipping test.\n");
2881 DestroyWindow(window);
2882 return;
2885 hr = IDirect3DDevice7_GetRenderTarget(device, &rt);
2886 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
2888 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
2889 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2890 hr = IDirect3DDevice7_Clear(device, 0, &rect, D3DCLEAR_TARGET, 0x00ff0000, 1.0f, 0);
2891 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2893 color = get_surface_color(rt, 320, 240);
2894 ok(compare_color(color, 0x00ffffff, 1),
2895 "Clear with count = 0, rect != NULL has color %#08x.\n", color);
2897 hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
2898 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2899 hr = IDirect3DDevice7_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0x0000ff00, 1.0f, 0);
2900 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
2902 color = get_surface_color(rt, 320, 240);
2903 ok(compare_color(color, 0x0000ff00, 1),
2904 "Clear with count = 1, rect = NULL has color %#08x.\n", color);
2906 IDirectDrawSurface7_Release(rt);
2907 IDirect3DDevice7_Release(device);
2908 DestroyWindow(window);
2911 START_TEST(ddraw7)
2913 HMODULE module = GetModuleHandleA("ddraw.dll");
2915 if (!(pDirectDrawCreateEx = (void *)GetProcAddress(module, "DirectDrawCreateEx")))
2917 win_skip("DirectDrawCreateEx not available, skipping tests.\n");
2918 return;
2921 test_process_vertices();
2922 test_coop_level_create_device_window();
2923 test_clipper_blt();
2924 test_coop_level_d3d_state();
2925 test_surface_interface_mismatch();
2926 test_coop_level_threaded();
2927 test_depth_blit();
2928 test_texture_load_ckey();
2929 test_zenable();
2930 test_ck_rgba();
2931 test_ck_default();
2932 test_surface_qi();
2933 test_device_qi();
2934 test_wndproc();
2935 test_window_style();
2936 test_redundant_mode_set();
2937 test_coop_level_mode_set();
2938 test_coop_level_mode_set_multi();
2939 test_initialize();
2940 test_coop_level_surf_create();
2941 test_vb_discard();
2942 test_coop_level_multi_window();
2943 test_draw_strided();
2944 test_clear_rect_count();