2 * Copyright 2011-2012 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/test.h"
23 struct create_window_thread_param
26 HANDLE window_created
;
27 HANDLE destroy_window
;
31 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
33 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
35 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
37 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
39 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
43 static DWORD WINAPI
create_window_thread_proc(void *param
)
45 struct create_window_thread_param
*p
= param
;
49 p
->window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
50 0, 0, 640, 480, 0, 0, 0, 0);
51 ret
= SetEvent(p
->window_created
);
52 ok(ret
, "SetEvent failed, last error %#x.\n", GetLastError());
58 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
59 DispatchMessage(&msg
);
60 res
= WaitForSingleObject(p
->destroy_window
, 100);
61 if (res
== WAIT_OBJECT_0
)
63 if (res
!= WAIT_TIMEOUT
)
65 ok(0, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
70 DestroyWindow(p
->window
);
75 static void create_window_thread(struct create_window_thread_param
*p
)
79 p
->window_created
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
80 ok(!!p
->window_created
, "CreateEvent failed, last error %#x.\n", GetLastError());
81 p
->destroy_window
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
82 ok(!!p
->destroy_window
, "CreateEvent failed, last error %#x.\n", GetLastError());
83 p
->thread
= CreateThread(NULL
, 0, create_window_thread_proc
, p
, 0, &tid
);
84 ok(!!p
->thread
, "Failed to create thread, last error %#x.\n", GetLastError());
85 res
= WaitForSingleObject(p
->window_created
, INFINITE
);
86 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#x), last error %#x.\n", res
, GetLastError());
89 static void destroy_window_thread(struct create_window_thread_param
*p
)
91 SetEvent(p
->destroy_window
);
92 WaitForSingleObject(p
->thread
, INFINITE
);
93 CloseHandle(p
->destroy_window
);
94 CloseHandle(p
->window_created
);
95 CloseHandle(p
->thread
);
98 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
100 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
101 DDSURFACEDESC surface_desc
;
105 memset(&surface_desc
, 0, sizeof(surface_desc
));
106 surface_desc
.dwSize
= sizeof(surface_desc
);
108 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
109 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
113 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
115 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
116 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
121 static void emit_process_vertices(void **ptr
, WORD base_idx
, DWORD vertex_count
)
123 D3DINSTRUCTION
*inst
= *ptr
;
124 D3DPROCESSVERTICES
*pv
= (D3DPROCESSVERTICES
*)(inst
+ 1);
126 inst
->bOpcode
= D3DOP_PROCESSVERTICES
;
127 inst
->bSize
= sizeof(*pv
);
130 pv
->dwFlags
= D3DPROCESSVERTICES_COPY
;
131 pv
->wStart
= base_idx
;
133 pv
->dwCount
= vertex_count
;
139 static void emit_set_rs(void **ptr
, D3DRENDERSTATETYPE state
, DWORD value
)
141 D3DINSTRUCTION
*inst
= *ptr
;
142 D3DSTATE
*rs
= (D3DSTATE
*)(inst
+ 1);
144 inst
->bOpcode
= D3DOP_STATERENDER
;
145 inst
->bSize
= sizeof(*rs
);
148 U1(*rs
).drstRenderStateType
= state
;
149 U2(*rs
).dwArg
[0] = value
;
154 static void emit_tquad(void **ptr
, WORD base_idx
)
156 D3DINSTRUCTION
*inst
= *ptr
;
157 D3DTRIANGLE
*tri
= (D3DTRIANGLE
*)(inst
+ 1);
159 inst
->bOpcode
= D3DOP_TRIANGLE
;
160 inst
->bSize
= sizeof(*tri
);
163 U1(*tri
).v1
= base_idx
;
164 U2(*tri
).v2
= base_idx
+ 1;
165 U3(*tri
).v3
= base_idx
+ 2;
166 tri
->wFlags
= D3DTRIFLAG_START
;
169 U1(*tri
).v1
= base_idx
+ 2;
170 U2(*tri
).v2
= base_idx
+ 1;
171 U3(*tri
).v3
= base_idx
+ 3;
172 tri
->wFlags
= D3DTRIFLAG_ODD
;
178 static void emit_end(void **ptr
)
180 D3DINSTRUCTION
*inst
= *ptr
;
182 inst
->bOpcode
= D3DOP_EXIT
;
189 static void set_execute_data(IDirect3DExecuteBuffer
*execute_buffer
, UINT vertex_count
, UINT offset
, UINT len
)
191 D3DEXECUTEDATA exec_data
;
194 memset(&exec_data
, 0, sizeof(exec_data
));
195 exec_data
.dwSize
= sizeof(exec_data
);
196 exec_data
.dwVertexCount
= vertex_count
;
197 exec_data
.dwInstructionOffset
= offset
;
198 exec_data
.dwInstructionLength
= len
;
199 hr
= IDirect3DExecuteBuffer_SetExecuteData(execute_buffer
, &exec_data
);
200 ok(SUCCEEDED(hr
), "Failed to set execute data, hr %#x.\n", hr
);
203 static HRESULT CALLBACK
enum_z_fmt(GUID
*guid
, char *description
, char *name
,
204 D3DDEVICEDESC
*hal_desc
, D3DDEVICEDESC
*hel_desc
, void *ctx
)
206 DWORD
*z_depth
= ctx
;
208 if (!IsEqualGUID(&IID_IDirect3DHALDevice
, guid
))
209 return D3DENUMRET_OK
;
211 if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_32
)
213 else if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_24
)
215 else if (hal_desc
->dwDeviceZBufferBitDepth
& DDBD_16
)
221 static IDirectDraw
*create_ddraw(void)
225 if (FAILED(DirectDrawCreate(NULL
, &ddraw
, NULL
)))
231 static IDirect3DDevice
*create_device(IDirectDraw
*ddraw
, HWND window
, DWORD coop_level
)
233 IDirectDrawSurface
*surface
, *ds
;
234 IDirect3DDevice
*device
= NULL
;
235 DDSURFACEDESC surface_desc
;
240 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, coop_level
);
241 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
243 memset(&surface_desc
, 0, sizeof(surface_desc
));
244 surface_desc
.dwSize
= sizeof(surface_desc
);
245 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
246 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
247 surface_desc
.dwWidth
= 640;
248 surface_desc
.dwHeight
= 480;
250 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
251 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
253 if (coop_level
& DDSCL_NORMAL
)
255 IDirectDrawClipper
*clipper
;
257 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
258 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
259 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
260 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
261 hr
= IDirectDrawSurface_SetClipper(surface
, clipper
);
262 ok(SUCCEEDED(hr
), "Failed to set surface clipper, hr %#x.\n", hr
);
263 IDirectDrawClipper_Release(clipper
);
266 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
269 IDirectDrawSurface_Release(surface
);
273 hr
= IDirect3D_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
274 ok(SUCCEEDED(hr
), "Failed to enumerate z-formats, hr %#x.\n", hr
);
275 IDirect3D_Release(d3d
);
276 if (FAILED(hr
) || !z_depth
)
278 IDirectDrawSurface_Release(surface
);
282 memset(&surface_desc
, 0, sizeof(surface_desc
));
283 surface_desc
.dwSize
= sizeof(surface_desc
);
284 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
285 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
286 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
287 surface_desc
.dwWidth
= 640;
288 surface_desc
.dwHeight
= 480;
289 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
290 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
293 IDirectDrawSurface_Release(surface
);
297 hr
= IDirectDrawSurface_AddAttachedSurface(surface
, ds
);
298 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
299 IDirectDrawSurface_Release(ds
);
302 IDirectDrawSurface_Release(surface
);
306 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DHALDevice
, (void **)&device
);
307 IDirectDrawSurface_Release(surface
);
314 static IDirect3DViewport
*create_viewport(IDirect3DDevice
*device
, UINT x
, UINT y
, UINT w
, UINT h
)
316 IDirect3DViewport
*viewport
;
321 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
322 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
323 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
324 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
325 hr
= IDirect3DDevice_AddViewport(device
, viewport
);
326 ok(SUCCEEDED(hr
), "Failed to add viewport, hr %#x.\n", hr
);
327 memset(&vp
, 0, sizeof(vp
));
328 vp
.dwSize
= sizeof(vp
);
333 vp
.dvScaleX
= (float)w
/ 2.0f
;
334 vp
.dvScaleY
= (float)h
/ 2.0f
;
339 hr
= IDirect3DViewport_SetViewport(viewport
, &vp
);
340 ok(SUCCEEDED(hr
), "Failed to set viewport data, hr %#x.\n", hr
);
341 IDirect3D_Release(d3d
);
346 static void viewport_set_background(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
,
347 IDirect3DMaterial
*material
)
349 D3DMATERIALHANDLE material_handle
;
352 hr
= IDirect3DMaterial2_GetHandle(material
, device
, &material_handle
);
353 ok(SUCCEEDED(hr
), "Failed to get material handle, hr %#x.\n", hr
);
354 hr
= IDirect3DViewport2_SetBackground(viewport
, material_handle
);
355 ok(SUCCEEDED(hr
), "Failed to set viewport background, hr %#x.\n", hr
);
358 static void destroy_viewport(IDirect3DDevice
*device
, IDirect3DViewport
*viewport
)
362 hr
= IDirect3DDevice_DeleteViewport(device
, viewport
);
363 ok(SUCCEEDED(hr
), "Failed to delete viewport, hr %#x.\n", hr
);
364 IDirect3DViewport_Release(viewport
);
367 static IDirect3DMaterial
*create_diffuse_material(IDirect3DDevice
*device
, float r
, float g
, float b
, float a
)
369 IDirect3DMaterial
*material
;
374 hr
= IDirect3DDevice_GetDirect3D(device
, &d3d
);
375 ok(SUCCEEDED(hr
), "Failed to get d3d interface, hr %#x.\n", hr
);
376 hr
= IDirect3D_CreateMaterial(d3d
, &material
, NULL
);
377 ok(SUCCEEDED(hr
), "Failed to create material, hr %#x.\n", hr
);
378 memset(&mat
, 0, sizeof(mat
));
379 mat
.dwSize
= sizeof(mat
);
380 U1(U(mat
).diffuse
).r
= r
;
381 U2(U(mat
).diffuse
).g
= g
;
382 U3(U(mat
).diffuse
).b
= b
;
383 U4(U(mat
).diffuse
).a
= a
;
384 hr
= IDirect3DMaterial_SetMaterial(material
, &mat
);
385 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
386 IDirect3D_Release(d3d
);
391 static void destroy_material(IDirect3DMaterial
*material
)
393 IDirect3DMaterial_Release(material
);
396 static const UINT
*expect_messages
;
398 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
400 if (expect_messages
&& message
== *expect_messages
)
403 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
406 /* Set the wndproc back to what ddraw expects it to be, and release the ddraw
407 * interface. This prevents subsequent SetCooperativeLevel() calls on a
408 * different window from failing with DDERR_HWNDALREADYSET. */
409 static void fix_wndproc(HWND window
, LONG_PTR proc
)
414 if (!(ddraw
= create_ddraw()))
417 SetWindowLongPtrA(window
, GWLP_WNDPROC
, proc
);
418 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
419 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
420 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
421 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
423 IDirectDraw_Release(ddraw
);
426 static HRESULT CALLBACK
restore_callback(IDirectDrawSurface
*surface
, DDSURFACEDESC
*desc
, void *context
)
428 HRESULT hr
= IDirectDrawSurface_Restore(surface
);
429 ok(SUCCEEDED(hr
), "Failed to restore surface, hr %#x.\n", hr
);
430 IDirectDrawSurface_Release(surface
);
435 static HRESULT
restore_surfaces(IDirectDraw
*ddraw
)
437 return IDirectDraw_EnumSurfaces(ddraw
, DDENUMSURFACES_ALL
| DDENUMSURFACES_DOESEXIST
,
438 NULL
, NULL
, restore_callback
);
441 static void test_coop_level_create_device_window(void)
443 HWND focus_window
, device_window
;
447 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
448 0, 0, 640, 480, 0, 0, 0, 0);
449 if (!(ddraw
= create_ddraw()))
451 skip("Failed to create a ddraw object, skipping test.\n");
452 DestroyWindow(focus_window
);
456 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
457 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
458 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
459 ok(!device_window
, "Unexpected device window found.\n");
460 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
461 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
462 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
463 ok(!device_window
, "Unexpected device window found.\n");
464 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
465 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
466 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
467 ok(!device_window
, "Unexpected device window found.\n");
468 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
469 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
470 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
471 ok(!device_window
, "Unexpected device window found.\n");
472 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
473 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
474 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
475 ok(!device_window
, "Unexpected device window found.\n");
477 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
478 if (broken(hr
== DDERR_INVALIDPARAMS
))
480 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
481 IDirectDraw_Release(ddraw
);
482 DestroyWindow(focus_window
);
486 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
487 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
488 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
489 ok(!device_window
, "Unexpected device window found.\n");
490 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
491 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
492 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
493 ok(!device_window
, "Unexpected device window found.\n");
495 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
496 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
497 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
498 ok(!device_window
, "Unexpected device window found.\n");
499 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
500 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
501 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
502 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
503 ok(!!device_window
, "Device window not found.\n");
505 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
506 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
507 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
508 ok(!device_window
, "Unexpected device window found.\n");
509 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
510 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
511 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
512 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
513 ok(!!device_window
, "Device window not found.\n");
515 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
516 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
517 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
518 ok(!device_window
, "Unexpected device window found.\n");
519 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
520 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
521 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
522 ok(!device_window
, "Unexpected device window found.\n");
523 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
524 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
525 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
526 ok(!device_window
, "Unexpected device window found.\n");
527 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
528 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
529 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
530 ok(!!device_window
, "Device window not found.\n");
532 IDirectDraw_Release(ddraw
);
533 DestroyWindow(focus_window
);
536 static void test_clipper_blt(void)
538 IDirectDrawSurface
*src_surface
, *dst_surface
;
539 RECT client_rect
, src_rect
;
540 IDirectDrawClipper
*clipper
;
541 DDSURFACEDESC surface_desc
;
542 unsigned int i
, j
, x
, y
;
553 static const DWORD src_data
[] =
555 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
556 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
557 0xff0000ff, 0xff0000ff, 0xff00ff00, 0xffff0000, 0xffffffff, 0xffffffff,
559 static const D3DCOLOR expected1
[] =
561 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
562 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
563 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
564 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
566 static const D3DCOLOR expected2
[] =
568 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
569 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
570 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
571 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
574 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
575 10, 10, 640, 480, 0, 0, 0, 0);
576 ShowWindow(window
, SW_SHOW
);
577 if (!(ddraw
= create_ddraw()))
579 skip("Failed to create a ddraw object, skipping test.\n");
580 DestroyWindow(window
);
584 ret
= GetClientRect(window
, &client_rect
);
585 ok(ret
, "Failed to get client rect.\n");
586 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
587 ok(ret
, "Failed to map client rect.\n");
589 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
590 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
592 hr
= IDirectDraw_CreateClipper(ddraw
, 0, &clipper
, NULL
);
593 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
594 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
595 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
596 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
597 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
598 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
599 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
600 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
601 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
602 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
603 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
604 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
605 ok(rgn_data
->rdh
.nCount
>= 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
606 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
607 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
608 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
609 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
610 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
611 HeapFree(GetProcessHeap(), 0, rgn_data
);
613 r1
= CreateRectRgn(0, 0, 320, 240);
614 ok(!!r1
, "Failed to create region.\n");
615 r2
= CreateRectRgn(320, 240, 640, 480);
616 ok(!!r2
, "Failed to create region.\n");
617 CombineRgn(r1
, r1
, r2
, RGN_OR
);
618 ret
= GetRegionData(r1
, 0, NULL
);
619 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
620 ret
= GetRegionData(r1
, ret
, rgn_data
);
621 ok(!!ret
, "Failed to get region data.\n");
626 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
627 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
628 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
629 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
630 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
631 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
633 HeapFree(GetProcessHeap(), 0, rgn_data
);
635 memset(&surface_desc
, 0, sizeof(surface_desc
));
636 surface_desc
.dwSize
= sizeof(surface_desc
);
637 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
638 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
639 surface_desc
.dwWidth
= 640;
640 surface_desc
.dwHeight
= 480;
641 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
642 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
643 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
644 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
645 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
646 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
648 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
649 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
650 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
651 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
653 memset(&fx
, 0, sizeof(fx
));
654 fx
.dwSize
= sizeof(fx
);
655 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
656 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
657 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
658 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
660 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, DDLOCK_WAIT
, NULL
);
661 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
662 ok(U1(surface_desc
).lPitch
== 2560, "Got unexpected surface pitch %u.\n", U1(surface_desc
).lPitch
);
663 ptr
= surface_desc
.lpSurface
;
664 memcpy(&ptr
[ 0], &src_data
[ 0], 6 * sizeof(DWORD
));
665 memcpy(&ptr
[ 640], &src_data
[ 6], 6 * sizeof(DWORD
));
666 memcpy(&ptr
[1280], &src_data
[12], 6 * sizeof(DWORD
));
667 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
668 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
670 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
671 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
673 SetRect(&src_rect
, 1, 1, 5, 2);
674 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
675 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
676 for (i
= 0; i
< 4; ++i
)
678 for (j
= 0; j
< 4; ++j
)
680 x
= 80 * ((2 * j
) + 1);
681 y
= 60 * ((2 * i
) + 1);
682 color
= get_surface_color(dst_surface
, x
, y
);
683 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
684 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
688 U5(fx
).dwFillColor
= 0xff0000ff;
689 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
690 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
691 for (i
= 0; i
< 4; ++i
)
693 for (j
= 0; j
< 4; ++j
)
695 x
= 80 * ((2 * j
) + 1);
696 y
= 60 * ((2 * i
) + 1);
697 color
= get_surface_color(dst_surface
, x
, y
);
698 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
699 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
703 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
704 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
706 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
707 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
708 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
709 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
710 DestroyWindow(window
);
711 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
712 ok(hr
== E_FAIL
, "Got unexpected hr %#x.\n", hr
);
713 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
714 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
715 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
716 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
717 hr
= IDirectDrawClipper_SetClipList(clipper
, NULL
, 0);
718 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
719 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
720 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
721 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
722 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
724 IDirectDrawSurface_Release(dst_surface
);
725 IDirectDrawSurface_Release(src_surface
);
726 IDirectDrawClipper_Release(clipper
);
727 IDirectDraw_Release(ddraw
);
730 static void test_coop_level_d3d_state(void)
732 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
733 IDirectDrawSurface
*rt
, *surface
;
734 IDirect3DMaterial
*background
;
735 IDirect3DViewport
*viewport
;
736 IDirect3DDevice
*device
;
737 D3DMATERIAL material
;
743 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
744 0, 0, 640, 480, 0, 0, 0, 0);
745 if (!(ddraw
= create_ddraw()))
747 skip("Failed to create ddraw object, skipping test.\n");
748 DestroyWindow(window
);
751 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
753 skip("Failed to create D3D device, skipping test.\n");
754 IDirectDraw_Release(ddraw
);
755 DestroyWindow(window
);
759 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
760 viewport
= create_viewport(device
, 0, 0, 640, 480);
761 viewport_set_background(device
, viewport
, background
);
763 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
764 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
765 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
766 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
767 color
= get_surface_color(rt
, 320, 240);
768 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
770 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
771 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
772 hr
= IDirectDrawSurface_IsLost(rt
);
773 ok(hr
== DDERR_SURFACELOST
, "Got unexpected hr %#x.\n", hr
);
774 hr
= restore_surfaces(ddraw
);
775 ok(SUCCEEDED(hr
), "Failed to restore surfaces, hr %#x.\n", hr
);
777 memset(&material
, 0, sizeof(material
));
778 material
.dwSize
= sizeof(material
);
779 U1(U(material
).diffuse
).r
= 0.0f
;
780 U2(U(material
).diffuse
).g
= 1.0f
;
781 U3(U(material
).diffuse
).b
= 0.0f
;
782 U4(U(material
).diffuse
).a
= 1.0f
;
783 hr
= IDirect3DMaterial_SetMaterial(background
, &material
);
784 ok(SUCCEEDED(hr
), "Failed to set material data, hr %#x.\n", hr
);
786 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&surface
);
787 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
788 ok(surface
== rt
, "Got unexpected surface %p.\n", surface
);
789 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
790 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
791 color
= get_surface_color(rt
, 320, 240);
792 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
794 destroy_viewport(device
, viewport
);
795 destroy_material(background
);
796 IDirectDrawSurface_Release(surface
);
797 IDirectDrawSurface_Release(rt
);
798 IDirect3DDevice_Release(device
);
799 IDirectDraw_Release(ddraw
);
800 DestroyWindow(window
);
803 static void test_surface_interface_mismatch(void)
805 IDirectDraw
*ddraw
= NULL
;
806 IDirect3D
*d3d
= NULL
;
807 IDirectDrawSurface
*surface
= NULL
, *ds
;
808 IDirectDrawSurface3
*surface3
= NULL
;
809 IDirect3DDevice
*device
= NULL
;
810 IDirect3DViewport
*viewport
= NULL
;
811 IDirect3DMaterial
*background
= NULL
;
812 DDSURFACEDESC surface_desc
;
818 D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
820 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
821 0, 0, 640, 480, 0, 0, 0, 0);
823 if (!(ddraw
= create_ddraw()))
825 skip("Failed to create a ddraw object, skipping test.\n");
829 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
830 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
832 memset(&surface_desc
, 0, sizeof(surface_desc
));
833 surface_desc
.dwSize
= sizeof(surface_desc
);
834 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
835 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_3DDEVICE
;
836 surface_desc
.dwWidth
= 640;
837 surface_desc
.dwHeight
= 480;
839 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
840 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
842 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirectDrawSurface3
, (void **)&surface3
);
845 skip("Failed to get the IDirectDrawSurface3 interface, skipping test.\n");
849 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
852 skip("Failed to get the IDirect3D interface, skipping test.\n");
856 hr
= IDirect3D_EnumDevices(d3d
, enum_z_fmt
, &z_depth
);
857 if (FAILED(hr
) || !z_depth
)
859 skip("No depth buffer formats available, skipping test.\n");
863 memset(&surface_desc
, 0, sizeof(surface_desc
));
864 surface_desc
.dwSize
= sizeof(surface_desc
);
865 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_ZBUFFERBITDEPTH
| DDSD_WIDTH
| DDSD_HEIGHT
;
866 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_ZBUFFER
;
867 U2(surface_desc
).dwZBufferBitDepth
= z_depth
;
868 surface_desc
.dwWidth
= 640;
869 surface_desc
.dwHeight
= 480;
870 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &ds
, NULL
);
871 ok(SUCCEEDED(hr
), "Failed to create depth buffer, hr %#x.\n", hr
);
875 /* Using a different surface interface version still works */
876 hr
= IDirectDrawSurface3_AddAttachedSurface(surface3
, (IDirectDrawSurface3
*)ds
);
877 ok(SUCCEEDED(hr
), "Failed to attach depth buffer, hr %#x.\n", hr
);
878 refcount
= IDirectDrawSurface_Release(ds
);
879 ok(refcount
== 1, "Got unexpected refcount %u.\n", refcount
);
884 hr
= IDirectDrawSurface3_QueryInterface(surface3
, &IID_IDirect3DHALDevice
, (void **)&device
);
885 ok(SUCCEEDED(hr
), "Failed to create d3d device.\n");
889 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
890 viewport
= create_viewport(device
, 0, 0, 640, 480);
891 viewport_set_background(device
, viewport
, background
);
893 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
894 ok(SUCCEEDED(hr
), "Failed to clear render target, hr %#x.\n", hr
);
895 color
= get_surface_color(surface
, 320, 240);
896 ok(compare_color(color
, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color
);
900 destroy_viewport(device
, viewport
);
902 destroy_material(background
);
903 if (surface3
) IDirectDrawSurface3_Release(surface3
);
904 if (surface
) IDirectDrawSurface_Release(surface
);
905 if (device
) IDirect3DDevice_Release(device
);
906 if (d3d
) IDirect3D_Release(d3d
);
907 if (ddraw
) IDirectDraw_Release(ddraw
);
908 DestroyWindow(window
);
911 static void test_coop_level_threaded(void)
913 struct create_window_thread_param p
;
917 if (!(ddraw
= create_ddraw()))
919 skip("Failed to create a ddraw object, skipping test.\n");
922 create_window_thread(&p
);
924 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, p
.window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
925 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
927 IDirectDraw_Release(ddraw
);
928 destroy_window_thread(&p
);
931 static ULONG
get_refcount(IUnknown
*test_iface
)
933 IUnknown_AddRef(test_iface
);
934 return IUnknown_Release(test_iface
);
937 static void test_viewport_interfaces(void)
943 IDirect3DViewport
*viewport
;
944 IDirect3DViewport2
*viewport2
;
945 IDirect3DViewport3
*viewport3
;
946 IDirectDrawGammaControl
*gamma
;
949 if (!(ddraw
= create_ddraw()))
951 skip("Failed to create ddraw object, skipping test.\n");
954 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
955 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
, "Failed to get d3d interface, hr %#x.\n", hr
);
958 skip("Direct3D not available, skipping tests\n");
959 IDirectDraw_Release(ddraw
);
962 ref
= get_refcount((IUnknown
*)d3d
);
963 ok(ref
== 2, "IDirect3D refcount is %d\n", ref
);
965 hr
= IDirect3D_CreateViewport(d3d
, &viewport
, NULL
);
966 ok(SUCCEEDED(hr
), "Failed to create viewport, hr %#x.\n", hr
);
967 ref
= get_refcount((IUnknown
*)viewport
);
968 ok(ref
== 1, "Initial IDirect3DViewport refcount is %u\n", ref
);
969 ref
= get_refcount((IUnknown
*)d3d
);
970 ok(ref
== 2, "IDirect3D refcount is %u\n", ref
);
972 /* E_FAIL return values are returned by Winetestbot Windows NT machines. While not supporting
973 * newer interfaces is legitimate for old ddraw versions, E_FAIL violates Microsoft's rules
974 * for QueryInterface, hence the broken() */
975 gamma
= (IDirectDrawGammaControl
*)0xdeadbeef;
976 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirectDrawGammaControl
, (void **)&gamma
);
977 ok(hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
), "Got unexpected hr %#x.\n", hr
);
978 ok(gamma
== NULL
, "Interface not set to NULL by failed QI call: %p\n", gamma
);
979 if (SUCCEEDED(hr
)) IDirectDrawGammaControl_Release(gamma
);
980 /* NULL iid: Segfaults */
982 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport2
, (void **)&viewport2
);
983 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
),
984 "Failed to QI IDirect3DViewport2, hr %#x.\n", hr
);
987 ref
= get_refcount((IUnknown
*)viewport
);
988 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
989 ref
= get_refcount((IUnknown
*)viewport2
);
990 ok(ref
== 2, "IDirect3DViewport2 refcount is %u\n", ref
);
991 IDirect3DViewport2_Release(viewport2
);
995 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IDirect3DViewport3
, (void **)&viewport3
);
996 ok(SUCCEEDED(hr
) || hr
== E_NOINTERFACE
|| broken(hr
== E_FAIL
),
997 "Failed to QI IDirect3DViewport3, hr %#x.\n", hr
);
1000 ref
= get_refcount((IUnknown
*)viewport
);
1001 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1002 ref
= get_refcount((IUnknown
*)viewport3
);
1003 ok(ref
== 2, "IDirect3DViewport3 refcount is %u\n", ref
);
1004 IDirect3DViewport3_Release(viewport3
);
1007 hr
= IDirect3DViewport_QueryInterface(viewport
, &IID_IUnknown
, (void **)&unknown
);
1008 ok(SUCCEEDED(hr
), "Failed to QI IUnknown, hr %#x.\n", hr
);
1011 ref
= get_refcount((IUnknown
*)viewport
);
1012 ok(ref
== 2, "IDirect3DViewport refcount is %u\n", ref
);
1013 ref
= get_refcount(unknown
);
1014 ok(ref
== 2, "IUnknown refcount is %u\n", ref
);
1015 IUnknown_Release(unknown
);
1018 IDirect3DViewport_Release(viewport
);
1019 IDirect3D_Release(d3d
);
1020 IDirectDraw_Release(ddraw
);
1023 static void test_zenable(void)
1025 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1026 static D3DTLVERTEX tquad
[] =
1028 {{ 0.0f
}, {480.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1029 {{ 0.0f
}, { 0.0f
}, {-0.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1030 {{640.0f
}, {480.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1031 {{640.0f
}, { 0.0f
}, { 1.5f
}, {1.0f
}, {0xff00ff00}, {0x00000000}, {0.0f
}, {0.0f
}},
1033 IDirect3DExecuteBuffer
*execute_buffer
;
1034 D3DEXECUTEBUFFERDESC exec_desc
;
1035 IDirect3DMaterial
*background
;
1036 IDirect3DViewport
*viewport
;
1037 IDirect3DDevice
*device
;
1038 IDirectDrawSurface
*rt
;
1048 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1049 0, 0, 640, 480, 0, 0, 0, 0);
1050 if (!(ddraw
= create_ddraw()))
1052 skip("Failed to create ddraw object, skipping test.\n");
1053 DestroyWindow(window
);
1056 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1058 skip("Failed to create D3D device, skipping test.\n");
1059 IDirectDraw_Release(ddraw
);
1060 DestroyWindow(window
);
1064 background
= create_diffuse_material(device
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
1065 viewport
= create_viewport(device
, 0, 0, 640, 480);
1066 viewport_set_background(device
, viewport
, background
);
1068 memset(&exec_desc
, 0, sizeof(exec_desc
));
1069 exec_desc
.dwSize
= sizeof(exec_desc
);
1070 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1071 exec_desc
.dwBufferSize
= 1024;
1072 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1074 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1075 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1076 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1077 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1078 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1079 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1080 emit_process_vertices(&ptr
, 0, 4);
1081 emit_set_rs(&ptr
, D3DRENDERSTATE_ZENABLE
, D3DZB_FALSE
);
1082 emit_tquad(&ptr
, 0);
1084 inst_length
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
;
1085 inst_length
-= sizeof(tquad
);
1086 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1087 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1089 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1090 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1091 hr
= IDirect3DDevice_BeginScene(device
);
1092 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1093 set_execute_data(execute_buffer
, 4, sizeof(tquad
), inst_length
);
1094 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1095 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1096 hr
= IDirect3DDevice_EndScene(device
);
1097 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1099 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1100 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1101 for (i
= 0; i
< 4; ++i
)
1103 for (j
= 0; j
< 4; ++j
)
1105 x
= 80 * ((2 * j
) + 1);
1106 y
= 60 * ((2 * i
) + 1);
1107 color
= get_surface_color(rt
, x
, y
);
1108 ok(compare_color(color
, 0x0000ff00, 1),
1109 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x
, y
, color
);
1112 IDirectDrawSurface_Release(rt
);
1114 destroy_viewport(device
, viewport
);
1115 IDirect3DExecuteBuffer_Release(execute_buffer
);
1116 destroy_material(background
);
1117 IDirect3DDevice_Release(device
);
1118 IDirectDraw_Release(ddraw
);
1119 DestroyWindow(window
);
1122 static void test_ck_rgba(void)
1124 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1125 static D3DTLVERTEX tquad
[] =
1127 {{ 0.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1128 {{ 0.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1129 {{640.0f
}, {480.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1130 {{640.0f
}, { 0.0f
}, {0.25f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1131 {{ 0.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1132 {{ 0.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1133 {{640.0f
}, {480.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1134 {{640.0f
}, { 0.0f
}, {0.75f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1138 D3DCOLOR fill_color
;
1146 {0xff00ff00, TRUE
, TRUE
, 0x00ff0000, 0x000000ff},
1147 {0xff00ff00, TRUE
, FALSE
, 0x00ff0000, 0x000000ff},
1148 {0xff00ff00, FALSE
, TRUE
, 0x0000ff00, 0x0000ff00},
1149 {0xff00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1150 {0x7f00ff00, TRUE
, TRUE
, 0x00807f00, 0x00807f00},
1151 {0x7f00ff00, TRUE
, FALSE
, 0x0000ff00, 0x0000ff00},
1152 {0x7f00ff00, FALSE
, TRUE
, 0x00807f00, 0x00807f00},
1153 {0x7f00ff00, FALSE
, FALSE
, 0x0000ff00, 0x0000ff00},
1156 IDirect3DExecuteBuffer
*execute_buffer
;
1157 D3DTEXTUREHANDLE texture_handle
;
1158 D3DEXECUTEBUFFERDESC exec_desc
;
1159 IDirect3DMaterial
*background
;
1160 IDirectDrawSurface
*surface
;
1161 IDirect3DViewport
*viewport
;
1162 DDSURFACEDESC surface_desc
;
1163 IDirect3DTexture
*texture
;
1164 IDirect3DDevice
*device
;
1165 IDirectDrawSurface
*rt
;
1173 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1174 0, 0, 640, 480, 0, 0, 0, 0);
1175 if (!(ddraw
= create_ddraw()))
1177 skip("Failed to create ddraw object, skipping test.\n");
1178 DestroyWindow(window
);
1181 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1183 skip("Failed to create D3D device, skipping test.\n");
1184 IDirectDraw_Release(ddraw
);
1185 DestroyWindow(window
);
1189 background
= create_diffuse_material(device
, 1.0, 0.0f
, 0.0f
, 1.0f
);
1190 viewport
= create_viewport(device
, 0, 0, 640, 480);
1191 viewport_set_background(device
, viewport
, background
);
1193 memset(&surface_desc
, 0, sizeof(surface_desc
));
1194 surface_desc
.dwSize
= sizeof(surface_desc
);
1195 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1196 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1197 surface_desc
.dwWidth
= 256;
1198 surface_desc
.dwHeight
= 256;
1199 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1200 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
1201 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1202 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1203 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1204 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1205 U5(surface_desc
.ddpfPixelFormat
).dwRGBAlphaBitMask
= 0xff000000;
1206 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff00;
1207 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff00;
1208 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1209 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
1210 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
1211 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1212 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
1213 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1214 IDirect3DTexture_Release(texture
);
1216 memset(&exec_desc
, 0, sizeof(exec_desc
));
1217 exec_desc
.dwSize
= sizeof(exec_desc
);
1218 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1219 exec_desc
.dwBufferSize
= 1024;
1220 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1221 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1222 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1224 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1225 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1227 for (i
= 0; i
< sizeof(tests
) / sizeof(*tests
); ++i
)
1229 UINT draw1_len
, draw2_len
;
1232 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1233 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1234 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1235 ptr
= ((BYTE
*)exec_desc
.lpData
) + sizeof(tquad
);
1236 emit_process_vertices(&ptr
, 0, 4);
1237 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1238 emit_set_rs(&ptr
, D3DRENDERSTATE_SRCBLEND
, D3DBLEND_SRCALPHA
);
1239 emit_set_rs(&ptr
, D3DRENDERSTATE_DESTBLEND
, D3DBLEND_INVSRCALPHA
);
1240 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, tests
[i
].color_key
);
1241 emit_set_rs(&ptr
, D3DRENDERSTATE_ALPHABLENDENABLE
, tests
[i
].blend
);
1242 emit_tquad(&ptr
, 0);
1244 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- sizeof(tquad
);
1245 emit_process_vertices(&ptr
, 4, 4);
1246 emit_tquad(&ptr
, 0);
1247 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1249 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_len
;
1250 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1251 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1253 memset(&fx
, 0, sizeof(fx
));
1254 fx
.dwSize
= sizeof(fx
);
1255 U5(fx
).dwFillColor
= tests
[i
].fill_color
;
1256 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1257 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1259 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
);
1260 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1261 hr
= IDirect3DDevice_BeginScene(device
);
1262 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1263 set_execute_data(execute_buffer
, 8, sizeof(tquad
), draw1_len
);
1264 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1265 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1266 hr
= IDirect3DDevice_EndScene(device
);
1267 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1269 color
= get_surface_color(rt
, 320, 240);
1271 todo_wine
ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1272 tests
[i
].result1
, i
, color
);
1274 ok(compare_color(color
, tests
[i
].result1
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1275 tests
[i
].result1
, i
, color
);
1277 U5(fx
).dwFillColor
= 0xff0000ff;
1278 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1279 ok(SUCCEEDED(hr
), "Failed to fill texture, hr %#x.\n", hr
);
1281 hr
= IDirect3DDevice_BeginScene(device
);
1282 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1283 set_execute_data(execute_buffer
, 8, sizeof(tquad
) + draw1_len
, draw2_len
);
1284 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1285 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1286 hr
= IDirect3DDevice_EndScene(device
);
1287 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1289 /* This tests that fragments that are masked out by the color key are
1290 * discarded, instead of just fully transparent. */
1291 color
= get_surface_color(rt
, 320, 240);
1293 todo_wine
ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1294 tests
[i
].result2
, i
, color
);
1296 ok(compare_color(color
, tests
[i
].result2
, 1), "Expected color 0x%08x for test %u, got 0x%08x.\n",
1297 tests
[i
].result2
, i
, color
);
1300 IDirectDrawSurface_Release(rt
);
1301 IDirect3DExecuteBuffer_Release(execute_buffer
);
1302 IDirectDrawSurface_Release(surface
);
1303 destroy_viewport(device
, viewport
);
1304 destroy_material(background
);
1305 IDirect3DDevice_Release(device
);
1306 IDirectDraw_Release(ddraw
);
1307 DestroyWindow(window
);
1310 static void test_ck_default(void)
1312 static D3DRECT clear_rect
= {{0}, {0}, {640}, {480}};
1313 static D3DTLVERTEX tquad
[] =
1315 {{ 0.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {0.0f
}},
1316 {{ 0.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {0.0f
}, {1.0f
}},
1317 {{640.0f
}, {480.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {0.0f
}},
1318 {{640.0f
}, { 0.0f
}, {0.0f
}, {1.0f
}, {0xffffffff}, {0x00000000}, {1.0f
}, {1.0f
}},
1320 IDirect3DExecuteBuffer
*execute_buffer
;
1321 IDirectDrawSurface
*surface
, *rt
;
1322 D3DTEXTUREHANDLE texture_handle
;
1323 D3DEXECUTEBUFFERDESC exec_desc
;
1324 IDirect3DMaterial
*background
;
1325 UINT draw1_offset
, draw1_len
;
1326 UINT draw2_offset
, draw2_len
;
1327 UINT draw3_offset
, draw3_len
;
1328 UINT draw4_offset
, draw4_len
;
1329 IDirect3DViewport
*viewport
;
1330 DDSURFACEDESC surface_desc
;
1331 IDirect3DTexture
*texture
;
1332 IDirect3DDevice
*device
;
1340 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1341 0, 0, 640, 480, 0, 0, 0, 0);
1343 if (!(ddraw
= create_ddraw()))
1345 skip("Failed to create ddraw object, skipping test.\n");
1346 DestroyWindow(window
);
1349 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1351 skip("Failed to create D3D device, skipping test.\n");
1352 IDirectDraw_Release(ddraw
);
1353 DestroyWindow(window
);
1357 hr
= IDirect3DDevice_QueryInterface(device
, &IID_IDirectDrawSurface
, (void **)&rt
);
1358 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#x.\n", hr
);
1360 background
= create_diffuse_material(device
, 0.0, 1.0f
, 0.0f
, 1.0f
);
1361 viewport
= create_viewport(device
, 0, 0, 640, 480);
1362 viewport_set_background(device
, viewport
, background
);
1364 memset(&surface_desc
, 0, sizeof(surface_desc
));
1365 surface_desc
.dwSize
= sizeof(surface_desc
);
1366 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CKSRCBLT
;
1367 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1368 surface_desc
.dwWidth
= 256;
1369 surface_desc
.dwHeight
= 256;
1370 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
1371 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
1372 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
1373 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
1374 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
1375 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
1376 surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0x000000ff;
1377 surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0x000000ff;
1378 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1379 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1380 hr
= IDirectDrawSurface_QueryInterface(surface
, &IID_IDirect3DTexture
, (void **)&texture
);
1381 ok(SUCCEEDED(hr
), "Failed to get texture interface, hr %#x.\n", hr
);
1382 hr
= IDirect3DTexture_GetHandle(texture
, device
, &texture_handle
);
1383 ok(SUCCEEDED(hr
), "Failed to get texture handle, hr %#x.\n", hr
);
1384 IDirect3DTexture_Release(texture
);
1386 memset(&fx
, 0, sizeof(fx
));
1387 fx
.dwSize
= sizeof(fx
);
1388 U5(fx
).dwFillColor
= 0x000000ff;
1389 hr
= IDirectDrawSurface_Blt(surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
1390 ok(SUCCEEDED(hr
), "Failed to fill surface, hr %#x.\n", hr
);
1392 memset(&exec_desc
, 0, sizeof(exec_desc
));
1393 exec_desc
.dwSize
= sizeof(exec_desc
);
1394 exec_desc
.dwFlags
= D3DDEB_BUFSIZE
| D3DDEB_CAPS
;
1395 exec_desc
.dwBufferSize
= 1024;
1396 exec_desc
.dwCaps
= D3DDEBCAPS_SYSTEMMEMORY
;
1397 hr
= IDirect3DDevice_CreateExecuteBuffer(device
, &exec_desc
, &execute_buffer
, NULL
);
1398 ok(SUCCEEDED(hr
), "Failed to create execute buffer, hr %#x.\n", hr
);
1400 hr
= IDirect3DExecuteBuffer_Lock(execute_buffer
, &exec_desc
);
1401 ok(SUCCEEDED(hr
), "Failed to lock execute buffer, hr %#x.\n", hr
);
1402 memcpy(exec_desc
.lpData
, tquad
, sizeof(tquad
));
1403 ptr
= (BYTE
*)exec_desc
.lpData
+ sizeof(tquad
);
1404 emit_process_vertices(&ptr
, 0, 4);
1405 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, texture_handle
);
1406 emit_tquad(&ptr
, 0);
1408 draw1_offset
= sizeof(tquad
);
1409 draw1_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw1_offset
;
1410 emit_process_vertices(&ptr
, 0, 4);
1411 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, FALSE
);
1412 emit_tquad(&ptr
, 0);
1414 draw2_offset
= draw1_offset
+ draw1_len
;
1415 draw2_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw2_offset
;
1416 emit_process_vertices(&ptr
, 0, 4);
1417 emit_tquad(&ptr
, 0);
1419 draw3_offset
= draw2_offset
+ draw2_len
;
1420 draw3_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw3_offset
;
1421 emit_process_vertices(&ptr
, 0, 4);
1422 emit_set_rs(&ptr
, D3DRENDERSTATE_COLORKEYENABLE
, TRUE
);
1423 emit_tquad(&ptr
, 0);
1424 emit_set_rs(&ptr
, D3DRENDERSTATE_TEXTUREHANDLE
, 0);
1426 draw4_offset
= draw3_offset
+ draw3_len
;
1427 draw4_len
= (BYTE
*)ptr
- (BYTE
*)exec_desc
.lpData
- draw4_offset
;
1428 hr
= IDirect3DExecuteBuffer_Unlock(execute_buffer
);
1429 ok(SUCCEEDED(hr
), "Failed to unlock execute buffer, hr %#x.\n", hr
);
1431 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1432 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1433 hr
= IDirect3DDevice_BeginScene(device
);
1434 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1435 set_execute_data(execute_buffer
, 4, draw1_offset
, draw1_len
);
1436 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1437 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1438 hr
= IDirect3DDevice_EndScene(device
);
1439 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1440 color
= get_surface_color(rt
, 320, 240);
1441 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1443 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1444 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1445 hr
= IDirect3DDevice_BeginScene(device
);
1446 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1447 set_execute_data(execute_buffer
, 4, draw2_offset
, draw2_len
);
1448 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1449 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1450 hr
= IDirect3DDevice_EndScene(device
);
1451 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1452 color
= get_surface_color(rt
, 320, 240);
1453 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1455 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1456 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1457 hr
= IDirect3DDevice_BeginScene(device
);
1458 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1459 set_execute_data(execute_buffer
, 4, draw3_offset
, draw3_len
);
1460 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1461 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1462 hr
= IDirect3DDevice_EndScene(device
);
1463 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1464 color
= get_surface_color(rt
, 320, 240);
1465 ok(compare_color(color
, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color
);
1467 hr
= IDirect3DViewport_Clear(viewport
, 1, &clear_rect
, D3DCLEAR_TARGET
);
1468 ok(SUCCEEDED(hr
), "Failed to clear viewport, hr %#x.\n", hr
);
1469 hr
= IDirect3DDevice_BeginScene(device
);
1470 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#x.\n", hr
);
1471 set_execute_data(execute_buffer
, 4, draw4_offset
, draw4_len
);
1472 hr
= IDirect3DDevice_Execute(device
, execute_buffer
, viewport
, D3DEXECUTE_CLIPPED
);
1473 ok(SUCCEEDED(hr
), "Failed to execute exec buffer, hr %#x.\n", hr
);
1474 hr
= IDirect3DDevice_EndScene(device
);
1475 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#x.\n", hr
);
1476 color
= get_surface_color(rt
, 320, 240);
1477 ok(compare_color(color
, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color
);
1479 IDirect3DExecuteBuffer_Release(execute_buffer
);
1480 IDirectDrawSurface_Release(surface
);
1481 destroy_viewport(device
, viewport
);
1482 destroy_material(background
);
1483 IDirectDrawSurface_Release(rt
);
1484 IDirect3DDevice_Release(device
);
1485 IDirectDraw_Release(ddraw
);
1486 DestroyWindow(window
);
1492 REFIID refcount_iid
;
1496 static void test_qi(const char *test_name
, IUnknown
*base_iface
,
1497 REFIID refcount_iid
, const struct qi_test
*tests
, UINT entry_count
)
1499 ULONG refcount
, expected_refcount
;
1500 IUnknown
*iface1
, *iface2
;
1504 for (i
= 0; i
< entry_count
; ++i
)
1506 hr
= IUnknown_QueryInterface(base_iface
, tests
[i
].iid
, (void **)&iface1
);
1507 ok(hr
== tests
[i
].hr
, "Got hr %#x for test \"%s\" %u.\n", hr
, test_name
, i
);
1510 for (j
= 0; j
< entry_count
; ++j
)
1512 hr
= IUnknown_QueryInterface(iface1
, tests
[j
].iid
, (void **)&iface2
);
1513 ok(hr
== tests
[j
].hr
, "Got hr %#x for test \"%s\" %u, %u.\n", hr
, test_name
, i
, j
);
1516 expected_refcount
= 0;
1517 if (IsEqualGUID(refcount_iid
, tests
[j
].refcount_iid
))
1518 ++expected_refcount
;
1519 if (IsEqualGUID(tests
[i
].refcount_iid
, tests
[j
].refcount_iid
))
1520 ++expected_refcount
;
1521 refcount
= IUnknown_Release(iface2
);
1522 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, %u, expected %u.\n",
1523 refcount
, test_name
, i
, j
, expected_refcount
);
1527 expected_refcount
= 0;
1528 if (IsEqualGUID(refcount_iid
, tests
[i
].refcount_iid
))
1529 ++expected_refcount
;
1530 refcount
= IUnknown_Release(iface1
);
1531 ok(refcount
== expected_refcount
, "Got refcount %u for test \"%s\" %u, expected %u.\n",
1532 refcount
, test_name
, i
, expected_refcount
);
1537 static void test_surface_qi(void)
1539 static const struct qi_test tests
[] =
1541 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
1542 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
1543 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1544 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1545 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1546 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1547 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1548 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1549 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1550 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
1551 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
1552 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
1553 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
1554 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
1555 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
1556 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
1557 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
1558 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
1559 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
1560 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
1561 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
1562 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
1563 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
1564 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
1565 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
1566 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
1567 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
1568 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
1569 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
1570 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
1571 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
1572 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
1573 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
1574 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
1575 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1578 IDirectDrawSurface
*surface
;
1579 DDSURFACEDESC surface_desc
;
1580 IDirect3DDevice
*device
;
1585 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
1587 win_skip("DirectDrawCreateEx not available, skipping test.\n");
1591 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1592 0, 0, 640, 480, 0, 0, 0, 0);
1593 if (!(ddraw
= create_ddraw()))
1595 skip("Failed to create a ddraw object, skipping test.\n");
1596 DestroyWindow(window
);
1599 /* Try to create a D3D device to see if the ddraw implementation supports
1600 * D3D. 64-bit ddraw in particular doesn't seem to support D3D, and
1601 * doesn't support e.g. the IDirect3DTexture interfaces. */
1602 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1604 skip("Failed to create D3D device, skipping test.\n");
1605 IDirectDraw_Release(ddraw
);
1606 DestroyWindow(window
);
1609 IDirect3DDevice_Release(device
);
1611 memset(&surface_desc
, 0, sizeof(surface_desc
));
1612 surface_desc
.dwSize
= sizeof(surface_desc
);
1613 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
;
1614 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1615 surface_desc
.dwWidth
= 512;
1616 surface_desc
.dwHeight
= 512;
1617 hr
= IDirectDraw_CreateSurface(ddraw
, &surface_desc
, &surface
, NULL
);
1618 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n", hr
);
1620 test_qi("surface_qi", (IUnknown
*)surface
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
1622 IDirectDrawSurface_Release(surface
);
1623 IDirectDraw_Release(ddraw
);
1624 DestroyWindow(window
);
1627 static void test_device_qi(void)
1629 static const struct qi_test tests
[] =
1631 {&IID_IDirect3DTexture2
, &IID_IDirectDrawSurface
, S_OK
},
1632 {&IID_IDirect3DTexture
, &IID_IDirectDrawSurface
, S_OK
},
1633 {&IID_IDirectDrawGammaControl
, &IID_IDirectDrawGammaControl
, S_OK
},
1634 {&IID_IDirectDrawColorControl
, NULL
, E_NOINTERFACE
},
1635 {&IID_IDirectDrawSurface7
, &IID_IDirectDrawSurface7
, S_OK
},
1636 {&IID_IDirectDrawSurface4
, &IID_IDirectDrawSurface4
, S_OK
},
1637 {&IID_IDirectDrawSurface3
, &IID_IDirectDrawSurface3
, S_OK
},
1638 {&IID_IDirectDrawSurface2
, &IID_IDirectDrawSurface2
, S_OK
},
1639 {&IID_IDirectDrawSurface
, &IID_IDirectDrawSurface
, S_OK
},
1640 {&IID_IDirect3DDevice7
, NULL
, E_INVALIDARG
},
1641 {&IID_IDirect3DDevice3
, NULL
, E_INVALIDARG
},
1642 {&IID_IDirect3DDevice2
, NULL
, E_INVALIDARG
},
1643 {&IID_IDirect3DDevice
, NULL
, E_INVALIDARG
},
1644 {&IID_IDirect3DHALDevice
, &IID_IDirectDrawSurface
, S_OK
},
1645 {&IID_IDirect3D7
, NULL
, E_INVALIDARG
},
1646 {&IID_IDirect3D3
, NULL
, E_INVALIDARG
},
1647 {&IID_IDirect3D2
, NULL
, E_INVALIDARG
},
1648 {&IID_IDirect3D
, NULL
, E_INVALIDARG
},
1649 {&IID_IDirectDraw7
, NULL
, E_INVALIDARG
},
1650 {&IID_IDirectDraw4
, NULL
, E_INVALIDARG
},
1651 {&IID_IDirectDraw3
, NULL
, E_INVALIDARG
},
1652 {&IID_IDirectDraw2
, NULL
, E_INVALIDARG
},
1653 {&IID_IDirectDraw
, NULL
, E_INVALIDARG
},
1654 {&IID_IDirect3DLight
, NULL
, E_INVALIDARG
},
1655 {&IID_IDirect3DMaterial
, NULL
, E_INVALIDARG
},
1656 {&IID_IDirect3DMaterial2
, NULL
, E_INVALIDARG
},
1657 {&IID_IDirect3DMaterial3
, NULL
, E_INVALIDARG
},
1658 {&IID_IDirect3DExecuteBuffer
, NULL
, E_INVALIDARG
},
1659 {&IID_IDirect3DViewport
, NULL
, E_INVALIDARG
},
1660 {&IID_IDirect3DViewport2
, NULL
, E_INVALIDARG
},
1661 {&IID_IDirect3DViewport3
, NULL
, E_INVALIDARG
},
1662 {&IID_IDirect3DVertexBuffer
, NULL
, E_INVALIDARG
},
1663 {&IID_IDirect3DVertexBuffer7
, NULL
, E_INVALIDARG
},
1664 {&IID_IDirectDrawPalette
, NULL
, E_INVALIDARG
},
1665 {&IID_IDirectDrawClipper
, NULL
, E_INVALIDARG
},
1666 {&IID_IUnknown
, &IID_IDirectDrawSurface
, S_OK
},
1670 IDirect3DDevice
*device
;
1674 if (!GetProcAddress(GetModuleHandleA("ddraw.dll"), "DirectDrawCreateEx"))
1676 win_skip("DirectDrawCreateEx not available, skipping test.\n");
1680 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1681 0, 0, 640, 480, 0, 0, 0, 0);
1682 if (!(ddraw
= create_ddraw()))
1684 skip("Failed to create ddraw object, skipping test.\n");
1685 DestroyWindow(window
);
1688 if (!(device
= create_device(ddraw
, window
, DDSCL_NORMAL
)))
1690 skip("Failed to create D3D device, skipping test.\n");
1691 IDirectDraw_Release(ddraw
);
1692 DestroyWindow(window
);
1696 test_qi("device_qi", (IUnknown
*)device
, &IID_IDirectDrawSurface
, tests
, sizeof(tests
) / sizeof(*tests
));
1698 IDirect3DDevice_Release(device
);
1699 IDirectDraw_Release(ddraw
);
1700 DestroyWindow(window
);
1703 static void test_wndproc(void)
1705 LONG_PTR proc
, ddraw_proc
;
1712 static const UINT messages
[] =
1714 WM_WINDOWPOSCHANGING
,
1717 WM_WINDOWPOSCHANGING
,
1723 /* DDSCL_EXCLUSIVE replaces the window's window proc. */
1724 if (!(ddraw
= create_ddraw()))
1726 skip("Failed to create IDirectDraw object, skipping tests.\n");
1730 wc
.lpfnWndProc
= test_proc
;
1731 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
1732 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
1734 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test",
1735 WS_MAXIMIZE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
1737 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1738 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1739 (LONG_PTR
)test_proc
, proc
);
1740 expect_messages
= messages
;
1741 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1742 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1743 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
1744 expect_messages
= NULL
;
1745 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1746 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1747 (LONG_PTR
)test_proc
, proc
);
1748 ref
= IDirectDraw_Release(ddraw
);
1749 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1750 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1751 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1752 (LONG_PTR
)test_proc
, proc
);
1754 /* DDSCL_NORMAL doesn't. */
1755 ddraw
= create_ddraw();
1756 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1757 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1758 (LONG_PTR
)test_proc
, proc
);
1759 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
1760 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1761 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1762 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1763 (LONG_PTR
)test_proc
, proc
);
1764 ref
= IDirectDraw_Release(ddraw
);
1765 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1766 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1767 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1768 (LONG_PTR
)test_proc
, proc
);
1770 /* The original window proc is only restored by ddraw if the current
1771 * window proc matches the one ddraw set. This also affects switching
1772 * from DDSCL_NORMAL to DDSCL_EXCLUSIVE. */
1773 ddraw
= create_ddraw();
1774 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1775 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1776 (LONG_PTR
)test_proc
, proc
);
1777 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1778 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1779 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1780 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1781 (LONG_PTR
)test_proc
, proc
);
1783 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1784 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1785 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1786 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1787 (LONG_PTR
)test_proc
, proc
);
1788 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1789 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1790 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1791 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1792 (LONG_PTR
)test_proc
, proc
);
1793 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
1794 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1795 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1796 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1797 (LONG_PTR
)DefWindowProcA
, proc
);
1798 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1799 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1800 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)ddraw_proc
);
1801 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1802 (LONG_PTR
)DefWindowProcA
, proc
);
1803 ref
= IDirectDraw_Release(ddraw
);
1804 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1805 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1806 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1807 (LONG_PTR
)test_proc
, proc
);
1809 ddraw
= create_ddraw();
1810 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1811 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#lx, got %#lx.\n",
1812 (LONG_PTR
)test_proc
, proc
);
1813 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1814 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1815 proc
= SetWindowLongPtrA(window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
1816 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#lx, got %#lx.\n",
1817 (LONG_PTR
)test_proc
, proc
);
1818 ref
= IDirectDraw_Release(ddraw
);
1819 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1820 proc
= GetWindowLongPtrA(window
, GWLP_WNDPROC
);
1821 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#lx, got %#lx.\n",
1822 (LONG_PTR
)DefWindowProcA
, proc
);
1824 fix_wndproc(window
, (LONG_PTR
)test_proc
);
1825 expect_messages
= NULL
;
1826 DestroyWindow(window
);
1827 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
1830 static void test_window_style(void)
1832 LONG style
, exstyle
, tmp
;
1833 RECT fullscreen_rect
, r
;
1839 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1840 0, 0, 100, 100, 0, 0, 0, 0);
1841 if (!(ddraw
= create_ddraw()))
1843 skip("Failed to create a ddraw object, skipping test.\n");
1844 DestroyWindow(window
);
1848 style
= GetWindowLongA(window
, GWL_STYLE
);
1849 exstyle
= GetWindowLongA(window
, GWL_EXSTYLE
);
1850 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
1852 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1853 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1855 tmp
= GetWindowLongA(window
, GWL_STYLE
);
1856 todo_wine
ok(tmp
== style
, "Expected window style %#x, got %#x.\n", style
, tmp
);
1857 tmp
= GetWindowLongA(window
, GWL_EXSTYLE
);
1858 todo_wine
ok(tmp
== exstyle
, "Expected window extended style %#x, got %#x.\n", exstyle
, tmp
);
1860 GetWindowRect(window
, &r
);
1861 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
1862 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
1863 r
.left
, r
.top
, r
.right
, r
.bottom
);
1864 GetClientRect(window
, &r
);
1865 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
), "Client rect and window rect are equal.\n");
1867 ref
= IDirectDraw_Release(ddraw
);
1868 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1870 DestroyWindow(window
);
1873 static void test_redundant_mode_set(void)
1875 DDSURFACEDESC surface_desc
= {0};
1882 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1883 0, 0, 100, 100, 0, 0, 0, 0);
1884 if (!(ddraw
= create_ddraw()))
1886 skip("Failed to create a ddraw object, skipping test.\n");
1887 DestroyWindow(window
);
1891 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1892 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1894 surface_desc
.dwSize
= sizeof(surface_desc
);
1895 hr
= IDirectDraw_GetDisplayMode(ddraw
, &surface_desc
);
1896 ok(SUCCEEDED(hr
), "GetDipslayMode failed, hr %#x.\n", hr
);
1898 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
1899 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
1900 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
1902 GetWindowRect(window
, &r
);
1905 SetWindowPos(window
, HWND_TOP
, r
.left
, r
.top
, r
.right
, r
.bottom
, 0);
1906 GetWindowRect(window
, &s
);
1907 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
1908 r
.left
, r
.top
, r
.right
, r
.bottom
,
1909 s
.left
, s
.top
, s
.right
, s
.bottom
);
1911 hr
= IDirectDraw_SetDisplayMode(ddraw
, surface_desc
.dwWidth
, surface_desc
.dwHeight
,
1912 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
);
1913 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
1915 GetWindowRect(window
, &s
);
1916 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
1917 r
.left
, r
.top
, r
.right
, r
.bottom
,
1918 s
.left
, s
.top
, s
.right
, s
.bottom
);
1920 ref
= IDirectDraw_Release(ddraw
);
1921 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
1923 DestroyWindow(window
);
1926 static SIZE screen_size
;
1928 static LRESULT CALLBACK
mode_set_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
1930 if (message
== WM_SIZE
)
1932 screen_size
.cx
= GetSystemMetrics(SM_CXSCREEN
);
1933 screen_size
.cy
= GetSystemMetrics(SM_CYSCREEN
);
1936 return test_proc(hwnd
, message
, wparam
, lparam
);
1939 static void test_coop_level_mode_set(void)
1941 IDirectDrawSurface
*primary
;
1942 RECT fullscreen_rect
, r
, s
;
1950 static const UINT exclusive_messages
[] =
1952 WM_WINDOWPOSCHANGING
,
1953 WM_WINDOWPOSCHANGED
,
1959 static const UINT normal_messages
[] =
1965 if (!(ddraw
= create_ddraw()))
1967 skip("Failed to create a ddraw object, skipping test.\n");
1971 wc
.lpfnWndProc
= mode_set_proc
;
1972 wc
.lpszClassName
= "ddraw_test_wndproc_wc";
1973 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
1975 window
= CreateWindowA("ddraw_test_wndproc_wc", "ddraw_test", WS_OVERLAPPEDWINDOW
,
1976 0, 0, 100, 100, 0, 0, 0, 0);
1978 SetRect(&fullscreen_rect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
1979 SetRect(&s
, 0, 0, 640, 480);
1981 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
1982 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
1984 GetWindowRect(window
, &r
);
1985 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
1986 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
1987 r
.left
, r
.top
, r
.right
, r
.bottom
);
1989 memset(&ddsd
, 0, sizeof(ddsd
));
1990 ddsd
.dwSize
= sizeof(ddsd
);
1991 ddsd
.dwFlags
= DDSD_CAPS
;
1992 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
1994 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
1995 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
1996 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
1997 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
1998 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
1999 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2000 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2001 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2003 GetWindowRect(window
, &r
);
2004 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2005 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2006 r
.left
, r
.top
, r
.right
, r
.bottom
);
2008 expect_messages
= exclusive_messages
;
2012 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 32);
2013 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2015 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2016 expect_messages
= NULL
;
2017 ok(screen_size
.cx
== s
.right
&& screen_size
.cy
== s
.bottom
,
2018 "Expected screen size %ux%u, got %ux%u.\n",
2019 s
.right
, s
.bottom
, screen_size
.cx
, screen_size
.cy
);
2021 GetWindowRect(window
, &r
);
2022 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2023 s
.left
, s
.top
, s
.right
, s
.bottom
,
2024 r
.left
, r
.top
, r
.right
, r
.bottom
);
2026 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2027 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2028 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2029 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2030 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2031 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2032 IDirectDrawSurface_Release(primary
);
2034 memset(&ddsd
, 0, sizeof(ddsd
));
2035 ddsd
.dwSize
= sizeof(ddsd
);
2036 ddsd
.dwFlags
= DDSD_CAPS
;
2037 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2039 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2040 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2041 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2042 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2043 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2044 s
.right
- s
.left
, ddsd
.dwWidth
);
2045 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2046 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2048 GetWindowRect(window
, &r
);
2049 ok(EqualRect(&r
, &s
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2050 s
.left
, s
.top
, s
.right
, s
.bottom
,
2051 r
.left
, r
.top
, r
.right
, r
.bottom
);
2053 expect_messages
= exclusive_messages
;
2057 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2058 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2060 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2061 expect_messages
= NULL
;
2062 ok(screen_size
.cx
== fullscreen_rect
.right
&& screen_size
.cy
== fullscreen_rect
.bottom
,
2063 "Expected screen size %ux%u, got %ux%u.\n",
2064 fullscreen_rect
.right
, fullscreen_rect
.bottom
, screen_size
.cx
, screen_size
.cy
);
2066 GetWindowRect(window
, &r
);
2067 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2068 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2069 r
.left
, r
.top
, r
.right
, r
.bottom
);
2071 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2072 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2073 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2074 s
.right
- s
.left
, ddsd
.dwWidth
);
2075 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2076 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2077 IDirectDrawSurface_Release(primary
);
2079 memset(&ddsd
, 0, sizeof(ddsd
));
2080 ddsd
.dwSize
= sizeof(ddsd
);
2081 ddsd
.dwFlags
= DDSD_CAPS
;
2082 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2084 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2085 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2086 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2087 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2088 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2089 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2090 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2091 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2093 GetWindowRect(window
, &r
);
2094 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2095 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2096 r
.left
, r
.top
, r
.right
, r
.bottom
);
2098 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
2099 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2101 GetWindowRect(window
, &r
);
2102 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2103 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2104 r
.left
, r
.top
, r
.right
, r
.bottom
);
2106 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2107 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2108 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2109 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2110 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2111 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2112 IDirectDrawSurface_Release(primary
);
2114 memset(&ddsd
, 0, sizeof(ddsd
));
2115 ddsd
.dwSize
= sizeof(ddsd
);
2116 ddsd
.dwFlags
= DDSD_CAPS
;
2117 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2119 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2120 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2121 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2122 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2123 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2124 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2125 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2126 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2128 GetWindowRect(window
, &r
);
2129 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2130 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2131 r
.left
, r
.top
, r
.right
, r
.bottom
);
2133 expect_messages
= normal_messages
;
2137 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 32);
2138 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_NOEXCLUSIVEMODE
) /* NT4 testbot */,
2139 "SetDipslayMode failed, hr %#x.\n", hr
);
2140 if (hr
== DDERR_NOEXCLUSIVEMODE
)
2142 win_skip("Broken SetDisplayMode(), skipping remaining tests.\n");
2143 IDirectDrawSurface_Release(primary
);
2144 IDirectDraw_Release(ddraw
);
2148 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2149 expect_messages
= NULL
;
2150 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2152 GetWindowRect(window
, &r
);
2153 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2154 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2155 r
.left
, r
.top
, r
.right
, r
.bottom
);
2157 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2158 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2159 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2160 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2161 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2162 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2163 IDirectDrawSurface_Release(primary
);
2165 memset(&ddsd
, 0, sizeof(ddsd
));
2166 ddsd
.dwSize
= sizeof(ddsd
);
2167 ddsd
.dwFlags
= DDSD_CAPS
;
2168 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2170 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2171 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2172 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2173 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2174 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2175 s
.right
- s
.left
, ddsd
.dwWidth
);
2176 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2177 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2179 GetWindowRect(window
, &r
);
2180 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2181 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2182 r
.left
, r
.top
, r
.right
, r
.bottom
);
2184 expect_messages
= normal_messages
;
2188 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2189 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2191 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2192 expect_messages
= NULL
;
2193 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2195 GetWindowRect(window
, &r
);
2196 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2197 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2198 r
.left
, r
.top
, r
.right
, r
.bottom
);
2200 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2201 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2202 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2203 s
.right
- s
.left
, ddsd
.dwWidth
);
2204 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2205 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2206 IDirectDrawSurface_Release(primary
);
2208 memset(&ddsd
, 0, sizeof(ddsd
));
2209 ddsd
.dwSize
= sizeof(ddsd
);
2210 ddsd
.dwFlags
= DDSD_CAPS
;
2211 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2213 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2214 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2215 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2216 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2217 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2218 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2219 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2220 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2222 GetWindowRect(window
, &r
);
2223 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2224 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2225 r
.left
, r
.top
, r
.right
, r
.bottom
);
2227 /* DDSCL_NORMAL | DDSCL_FULLSCREEN behaves the same as just DDSCL_NORMAL.
2228 * Resizing the window on mode changes is a property of DDSCL_EXCLUSIVE,
2229 * not DDSCL_FULLSCREEN. */
2230 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
2231 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2233 GetWindowRect(window
, &r
);
2234 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2235 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2236 r
.left
, r
.top
, r
.right
, r
.bottom
);
2238 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2239 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2240 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2241 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2242 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2243 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2244 IDirectDrawSurface_Release(primary
);
2246 memset(&ddsd
, 0, sizeof(ddsd
));
2247 ddsd
.dwSize
= sizeof(ddsd
);
2248 ddsd
.dwFlags
= DDSD_CAPS
;
2249 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2251 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2252 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2253 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2254 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2255 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2256 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2257 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2258 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2260 GetWindowRect(window
, &r
);
2261 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2262 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2263 r
.left
, r
.top
, r
.right
, r
.bottom
);
2265 expect_messages
= normal_messages
;
2269 hr
= IDirectDraw_SetDisplayMode(ddraw
, 640, 480, 32);
2270 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2272 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2273 expect_messages
= NULL
;
2274 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2276 GetWindowRect(window
, &r
);
2277 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2278 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2279 r
.left
, r
.top
, r
.right
, r
.bottom
);
2281 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2282 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2283 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2284 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2285 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2286 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2287 IDirectDrawSurface_Release(primary
);
2289 memset(&ddsd
, 0, sizeof(ddsd
));
2290 ddsd
.dwSize
= sizeof(ddsd
);
2291 ddsd
.dwFlags
= DDSD_CAPS
;
2292 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2294 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2295 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2296 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2297 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2298 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2299 s
.right
- s
.left
, ddsd
.dwWidth
);
2300 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2301 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2303 GetWindowRect(window
, &r
);
2304 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2305 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2306 r
.left
, r
.top
, r
.right
, r
.bottom
);
2308 expect_messages
= normal_messages
;
2312 hr
= IDirectDraw_RestoreDisplayMode(ddraw
);
2313 ok(SUCCEEDED(hr
), "RestoreDisplayMode failed, hr %#x.\n", hr
);
2315 ok(!*expect_messages
, "Expected message %#x, but didn't receive it.\n", *expect_messages
);
2316 expect_messages
= NULL
;
2317 ok(!screen_size
.cx
&& !screen_size
.cy
, "Got unxpected screen size %ux%u.\n", screen_size
.cx
, screen_size
.cy
);
2319 GetWindowRect(window
, &r
);
2320 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2321 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2322 r
.left
, r
.top
, r
.right
, r
.bottom
);
2324 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2325 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2326 ok(ddsd
.dwWidth
== s
.right
- s
.left
, "Expected surface width %u, got %u.\n",
2327 s
.right
- s
.left
, ddsd
.dwWidth
);
2328 ok(ddsd
.dwHeight
== s
.bottom
- s
.top
, "Expected surface height %u, got %u.\n",
2329 s
.bottom
- s
.top
, ddsd
.dwHeight
);
2330 IDirectDrawSurface_Release(primary
);
2332 memset(&ddsd
, 0, sizeof(ddsd
));
2333 ddsd
.dwSize
= sizeof(ddsd
);
2334 ddsd
.dwFlags
= DDSD_CAPS
;
2335 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2337 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &primary
, NULL
);
2338 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#x.\n",hr
);
2339 hr
= IDirectDrawSurface_GetSurfaceDesc(primary
, &ddsd
);
2340 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
2341 ok(ddsd
.dwWidth
== fullscreen_rect
.right
- fullscreen_rect
.left
, "Expected surface width %u, got %u.\n",
2342 fullscreen_rect
.right
- fullscreen_rect
.left
, ddsd
.dwWidth
);
2343 ok(ddsd
.dwHeight
== fullscreen_rect
.bottom
- fullscreen_rect
.top
, "Expected surface height %u, got %u.\n",
2344 fullscreen_rect
.bottom
- fullscreen_rect
.top
, ddsd
.dwHeight
);
2345 IDirectDrawSurface_Release(primary
);
2347 GetWindowRect(window
, &r
);
2348 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2349 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2350 r
.left
, r
.top
, r
.right
, r
.bottom
);
2352 ref
= IDirectDraw_Release(ddraw
);
2353 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2355 GetWindowRect(window
, &r
);
2356 ok(EqualRect(&r
, &fullscreen_rect
), "Expected {%d, %d, %d, %d}, got {%d, %d, %d, %d}.\n",
2357 fullscreen_rect
.left
, fullscreen_rect
.top
, fullscreen_rect
.right
, fullscreen_rect
.bottom
,
2358 r
.left
, r
.top
, r
.right
, r
.bottom
);
2361 expect_messages
= NULL
;
2362 DestroyWindow(window
);
2363 UnregisterClassA("ddraw_test_wndproc_wc", GetModuleHandleA(NULL
));
2366 static void test_coop_level_mode_set_multi(void)
2368 IDirectDraw
*ddraw1
, *ddraw2
;
2369 UINT orig_w
, orig_h
, w
, h
;
2374 if (!(ddraw1
= create_ddraw()))
2376 skip("Failed to create a ddraw object, skipping test.\n");
2380 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
2381 0, 0, 100, 100, 0, 0, 0, 0);
2383 orig_w
= GetSystemMetrics(SM_CXSCREEN
);
2384 orig_h
= GetSystemMetrics(SM_CYSCREEN
);
2386 /* With just a single ddraw object, the display mode is restored on
2388 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2389 ok(SUCCEEDED(hr
) || broken(hr
== DDERR_NOEXCLUSIVEMODE
) /* NT4 testbot */,
2390 "SetDipslayMode failed, hr %#x.\n", hr
);
2391 if (hr
== DDERR_NOEXCLUSIVEMODE
)
2393 win_skip("Broken SetDisplayMode(), skipping test.\n");
2394 IDirectDraw_Release(ddraw1
);
2395 DestroyWindow(window
);
2398 w
= GetSystemMetrics(SM_CXSCREEN
);
2399 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2400 h
= GetSystemMetrics(SM_CYSCREEN
);
2401 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2403 ref
= IDirectDraw_Release(ddraw1
);
2404 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2405 w
= GetSystemMetrics(SM_CXSCREEN
);
2406 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2407 h
= GetSystemMetrics(SM_CYSCREEN
);
2408 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2410 /* When there are multiple ddraw objects, the display mode is restored to
2411 * the initial mode, before the first SetDisplayMode() call. */
2412 ddraw1
= create_ddraw();
2413 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2414 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2415 w
= GetSystemMetrics(SM_CXSCREEN
);
2416 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2417 h
= GetSystemMetrics(SM_CYSCREEN
);
2418 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2420 ddraw2
= create_ddraw();
2421 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2422 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2423 w
= GetSystemMetrics(SM_CXSCREEN
);
2424 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2425 h
= GetSystemMetrics(SM_CYSCREEN
);
2426 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2428 ref
= IDirectDraw_Release(ddraw2
);
2429 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2430 w
= GetSystemMetrics(SM_CXSCREEN
);
2431 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2432 h
= GetSystemMetrics(SM_CYSCREEN
);
2433 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2435 ref
= IDirectDraw_Release(ddraw1
);
2436 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2437 w
= GetSystemMetrics(SM_CXSCREEN
);
2438 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2439 h
= GetSystemMetrics(SM_CYSCREEN
);
2440 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2442 /* Regardless of release ordering. */
2443 ddraw1
= create_ddraw();
2444 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2445 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2446 w
= GetSystemMetrics(SM_CXSCREEN
);
2447 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2448 h
= GetSystemMetrics(SM_CYSCREEN
);
2449 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2451 ddraw2
= create_ddraw();
2452 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2453 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2454 w
= GetSystemMetrics(SM_CXSCREEN
);
2455 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2456 h
= GetSystemMetrics(SM_CYSCREEN
);
2457 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2459 ref
= IDirectDraw_Release(ddraw1
);
2460 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2461 w
= GetSystemMetrics(SM_CXSCREEN
);
2462 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2463 h
= GetSystemMetrics(SM_CYSCREEN
);
2464 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2466 ref
= IDirectDraw_Release(ddraw2
);
2467 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2468 w
= GetSystemMetrics(SM_CXSCREEN
);
2469 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2470 h
= GetSystemMetrics(SM_CYSCREEN
);
2471 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2473 /* But only for ddraw objects that called SetDisplayMode(). */
2474 ddraw1
= create_ddraw();
2475 ddraw2
= create_ddraw();
2476 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2477 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2478 w
= GetSystemMetrics(SM_CXSCREEN
);
2479 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2480 h
= GetSystemMetrics(SM_CYSCREEN
);
2481 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2483 ref
= IDirectDraw_Release(ddraw1
);
2484 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2485 w
= GetSystemMetrics(SM_CXSCREEN
);
2486 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2487 h
= GetSystemMetrics(SM_CYSCREEN
);
2488 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2490 ref
= IDirectDraw_Release(ddraw2
);
2491 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2492 w
= GetSystemMetrics(SM_CXSCREEN
);
2493 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2494 h
= GetSystemMetrics(SM_CYSCREEN
);
2495 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2497 /* If there's a ddraw object that's currently in exclusive mode, it blocks
2498 * restoring the display mode. */
2499 ddraw1
= create_ddraw();
2500 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2501 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2502 w
= GetSystemMetrics(SM_CXSCREEN
);
2503 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2504 h
= GetSystemMetrics(SM_CYSCREEN
);
2505 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2507 ddraw2
= create_ddraw();
2508 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2509 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2510 w
= GetSystemMetrics(SM_CXSCREEN
);
2511 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2512 h
= GetSystemMetrics(SM_CYSCREEN
);
2513 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2515 hr
= IDirectDraw_SetCooperativeLevel(ddraw2
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2516 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2518 ref
= IDirectDraw_Release(ddraw1
);
2519 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2520 w
= GetSystemMetrics(SM_CXSCREEN
);
2521 ok(w
== 640, "Got unexpected screen width %u.\n", w
);
2522 h
= GetSystemMetrics(SM_CYSCREEN
);
2523 ok(h
== 480, "Got unexpected screen height %u.\n", h
);
2525 ref
= IDirectDraw_Release(ddraw2
);
2526 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2527 w
= GetSystemMetrics(SM_CXSCREEN
);
2528 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2529 h
= GetSystemMetrics(SM_CYSCREEN
);
2530 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2532 /* Exclusive mode blocks mode setting on other ddraw objects in general. */
2533 ddraw1
= create_ddraw();
2534 hr
= IDirectDraw_SetDisplayMode(ddraw1
, 800, 600, 32);
2535 ok(SUCCEEDED(hr
), "SetDipslayMode failed, hr %#x.\n", hr
);
2536 w
= GetSystemMetrics(SM_CXSCREEN
);
2537 ok(w
== 800, "Got unexpected screen width %u.\n", w
);
2538 h
= GetSystemMetrics(SM_CYSCREEN
);
2539 ok(h
== 600, "Got unexpected screen height %u.\n", h
);
2541 hr
= IDirectDraw_SetCooperativeLevel(ddraw1
, window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
2542 ok(SUCCEEDED(hr
), "SetCooperativeLevel failed, hr %#x.\n", hr
);
2544 ddraw2
= create_ddraw();
2545 hr
= IDirectDraw_SetDisplayMode(ddraw2
, 640, 480, 32);
2546 ok(hr
== DDERR_NOEXCLUSIVEMODE
, "Got unexpected hr %#x.\n", hr
);
2548 ref
= IDirectDraw_Release(ddraw1
);
2549 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2550 w
= GetSystemMetrics(SM_CXSCREEN
);
2551 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2552 h
= GetSystemMetrics(SM_CYSCREEN
);
2553 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2555 ref
= IDirectDraw_Release(ddraw2
);
2556 ok(ref
== 0, "The ddraw object was not properly freed: refcount %u.\n", ref
);
2557 w
= GetSystemMetrics(SM_CXSCREEN
);
2558 ok(w
== orig_w
, "Got unexpected screen width %u.\n", w
);
2559 h
= GetSystemMetrics(SM_CYSCREEN
);
2560 ok(h
== orig_h
, "Got unexpected screen height %u.\n", h
);
2562 DestroyWindow(window
);
2565 static void test_initialize(void)
2571 if (!(ddraw
= create_ddraw()))
2573 skip("Failed to create a ddraw object, skipping test.\n");
2577 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
2578 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x.\n", hr
);
2579 IDirectDraw_Release(ddraw
);
2582 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectDraw
, (void **)&ddraw
);
2583 ok(SUCCEEDED(hr
), "Failed to create IDirectDraw instance, hr %#x.\n", hr
);
2584 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirect3D
, (void **)&d3d
);
2587 /* IDirect3D_Initialize() just returns DDERR_ALREADYINITIALIZED. */
2588 hr
= IDirect3D_Initialize(d3d
, NULL
);
2589 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
2590 IDirect3D_Release(d3d
);
2592 else skip("Failed to query IDirect3D interface, skipping tests.\n");
2593 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
2594 ok(hr
== DD_OK
, "Initialize returned hr %#x, expected DD_OK.\n", hr
);
2595 hr
= IDirectDraw_Initialize(ddraw
, NULL
);
2596 ok(hr
== DDERR_ALREADYINITIALIZED
, "Initialize returned hr %#x, expected DDERR_ALREADYINITIALIZED.\n", hr
);
2597 IDirectDraw_Release(ddraw
);
2600 if (0) /* This crashes on the W2KPROSP4 testbot. */
2603 hr
= CoCreateInstance(&CLSID_DirectDraw
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirect3D
, (void **)&d3d
);
2604 ok(hr
== E_NOINTERFACE
, "CoCreateInstance returned hr %#x, expected E_NOINTERFACE.\n", hr
);
2609 static void test_coop_level_surf_create(void)
2611 IDirectDrawSurface
*surface
;
2616 if (!(ddraw
= create_ddraw()))
2618 skip("Failed to create a ddraw object, skipping test.\n");
2622 memset(&ddsd
, 0, sizeof(ddsd
));
2623 ddsd
.dwSize
= sizeof(ddsd
);
2624 ddsd
.dwFlags
= DDSD_CAPS
;
2625 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
2626 hr
= IDirectDraw_CreateSurface(ddraw
, &ddsd
, &surface
, NULL
);
2627 ok(hr
== DDERR_NOCOOPERATIVELEVELSET
, "Surface creation returned hr %#x.\n", hr
);
2629 IDirectDraw_Release(ddraw
);
2634 test_coop_level_create_device_window();
2636 test_coop_level_d3d_state();
2637 test_surface_interface_mismatch();
2638 test_coop_level_threaded();
2639 test_viewport_interfaces();
2646 test_window_style();
2647 test_redundant_mode_set();
2648 test_coop_level_mode_set();
2649 test_coop_level_mode_set_multi();
2651 test_coop_level_surf_create();