2 * Copyright 2011 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
19 #include "wine/test.h"
22 static BOOL
compare_color(D3DCOLOR c1
, D3DCOLOR c2
, BYTE max_diff
)
24 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
26 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
28 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
30 if (abs((c1
& 0xff) - (c2
& 0xff)) > max_diff
) return FALSE
;
34 static D3DCOLOR
get_surface_color(IDirectDrawSurface
*surface
, UINT x
, UINT y
)
36 RECT rect
= {x
, y
, x
+ 1, y
+ 1};
37 DDSURFACEDESC surface_desc
;
41 memset(&surface_desc
, 0, sizeof(surface_desc
));
42 surface_desc
.dwSize
= sizeof(surface_desc
);
44 hr
= IDirectDrawSurface_Lock(surface
, &rect
, &surface_desc
, DDLOCK_READONLY
| DDLOCK_WAIT
, NULL
);
45 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#x.\n", hr
);
49 color
= *((DWORD
*)surface_desc
.lpSurface
) & 0x00ffffff;
51 hr
= IDirectDrawSurface_Unlock(surface
, NULL
);
52 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#x.\n", hr
);
57 static IDirectDraw2
*create_ddraw(void)
63 if (FAILED(DirectDrawCreate(NULL
, &ddraw1
, NULL
)))
66 hr
= IDirectDraw_QueryInterface(ddraw1
, &IID_IDirectDraw2
, (void **)&ddraw2
);
67 IDirectDraw_Release(ddraw1
);
74 static void test_coop_level_create_device_window(void)
76 HWND focus_window
, device_window
;
80 focus_window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
81 0, 0, 640, 480, 0, 0, 0, 0);
82 if (!(ddraw
= create_ddraw()))
84 skip("Failed to create a ddraw object, skipping test.\n");
85 DestroyWindow(focus_window
);
89 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
90 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
91 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
92 ok(!device_window
, "Unexpected device window found.\n");
93 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
);
94 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
95 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
96 ok(!device_window
, "Unexpected device window found.\n");
97 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
);
98 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
99 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
100 ok(!device_window
, "Unexpected device window found.\n");
101 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_NORMAL
| DDSCL_FULLSCREEN
);
102 ok(hr
== DDERR_INVALIDPARAMS
, "Got unexpected hr %#x.\n", hr
);
103 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
104 ok(!device_window
, "Unexpected device window found.\n");
105 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
106 ok(hr
== DDERR_NOFOCUSWINDOW
|| broken(hr
== DDERR_INVALIDPARAMS
), "Got unexpected hr %#x.\n", hr
);
107 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
108 ok(!device_window
, "Unexpected device window found.\n");
110 /* Windows versions before 98 / NT5 don't support DDSCL_CREATEDEVICEWINDOW. */
111 if (broken(hr
== DDERR_INVALIDPARAMS
))
113 win_skip("DDSCL_CREATEDEVICEWINDOW not supported, skipping test.\n");
114 IDirectDraw2_Release(ddraw
);
115 DestroyWindow(focus_window
);
119 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
120 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
121 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
122 ok(!device_window
, "Unexpected device window found.\n");
123 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
124 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
125 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
126 ok(!device_window
, "Unexpected device window found.\n");
128 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
129 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
130 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
131 ok(!device_window
, "Unexpected device window found.\n");
132 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_SETFOCUSWINDOW
133 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
134 ok(hr
== DDERR_NOHWND
, "Got unexpected hr %#x.\n", hr
);
135 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
136 ok(!!device_window
, "Device window not found.\n");
138 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
139 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
140 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
141 ok(!device_window
, "Unexpected device window found.\n");
142 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
143 | DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
144 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
145 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
146 ok(!!device_window
, "Device window not found.\n");
148 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
149 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
150 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
151 ok(!device_window
, "Unexpected device window found.\n");
152 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
153 ok(hr
== DDERR_NOFOCUSWINDOW
, "Got unexpected hr %#x.\n", hr
);
154 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
155 ok(!device_window
, "Unexpected device window found.\n");
156 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, focus_window
, DDSCL_SETFOCUSWINDOW
);
157 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
158 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
159 ok(!device_window
, "Unexpected device window found.\n");
160 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, NULL
, DDSCL_CREATEDEVICEWINDOW
| DDSCL_EXCLUSIVE
| DDSCL_FULLSCREEN
);
161 ok(hr
== DD_OK
, "Got unexpected hr %#x.\n", hr
);
162 device_window
= FindWindowA("DirectDrawDeviceWnd", "DirectDrawDeviceWnd");
163 ok(!!device_window
, "Device window not found.\n");
165 IDirectDraw2_Release(ddraw
);
166 DestroyWindow(focus_window
);
169 static void test_clipper_blt(void)
171 IDirectDrawSurface
*src_surface
, *dst_surface
;
172 RECT client_rect
, src_rect
, *rect
;
173 IDirectDrawClipper
*clipper
;
174 DDSURFACEDESC surface_desc
;
175 unsigned int i
, j
, x
, y
;
185 static const D3DCOLOR expected1
[] =
187 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
188 0x000000ff, 0x0000ff00, 0x00000000, 0x00000000,
189 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
190 0x00000000, 0x00000000, 0x00ff0000, 0x00ffffff,
192 static const D3DCOLOR expected2
[] =
194 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
195 0x000000ff, 0x000000ff, 0x00000000, 0x00000000,
196 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
197 0x00000000, 0x00000000, 0x000000ff, 0x000000ff,
200 window
= CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW
,
201 10, 10, 640, 480, 0, 0, 0, 0);
202 ShowWindow(window
, SW_SHOW
);
203 if (!(ddraw
= create_ddraw()))
205 skip("Failed to create a ddraw object, skipping test.\n");
206 DestroyWindow(window
);
210 ret
= GetClientRect(window
, &client_rect
);
211 ok(ret
, "Failed to get client rect.\n");
212 ret
= MapWindowPoints(window
, NULL
, (POINT
*)&client_rect
, 2);
213 ok(ret
, "Failed to map client rect.\n");
215 hr
= IDirectDraw2_SetCooperativeLevel(ddraw
, window
, DDSCL_NORMAL
);
216 ok(SUCCEEDED(hr
), "Failed to set cooperative level, hr %#x.\n", hr
);
218 hr
= IDirectDraw2_CreateClipper(ddraw
, 0, &clipper
, NULL
);
219 ok(SUCCEEDED(hr
), "Failed to create clipper, hr %#x.\n", hr
);
220 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
221 ok(hr
== DDERR_NOCLIPLIST
, "Got unexpected hr %#x.\n", hr
);
222 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, window
);
223 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
224 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, NULL
, &ret
);
225 ok(SUCCEEDED(hr
), "Failed to get clip list size, hr %#x.\n", hr
);
226 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
227 hr
= IDirectDrawClipper_GetClipList(clipper
, NULL
, rgn_data
, &ret
);
228 ok(SUCCEEDED(hr
), "Failed to get clip list, hr %#x.\n", hr
);
229 ok(rgn_data
->rdh
.dwSize
== sizeof(rgn_data
->rdh
), "Got unexpected structure size %#x.\n", rgn_data
->rdh
.dwSize
);
230 ok(rgn_data
->rdh
.iType
== RDH_RECTANGLES
, "Got unexpected type %#x.\n", rgn_data
->rdh
.iType
);
231 ok(rgn_data
->rdh
.nCount
== 1, "Got unexpected count %u.\n", rgn_data
->rdh
.nCount
);
232 ok(rgn_data
->rdh
.nRgnSize
== 16 || broken(rgn_data
->rdh
.nRgnSize
== 168 /* NT4 */),
233 "Got unexpected region size %u.\n", rgn_data
->rdh
.nRgnSize
);
234 ok(EqualRect(&rgn_data
->rdh
.rcBound
, &client_rect
),
235 "Got unexpected bounding rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
236 rgn_data
->rdh
.rcBound
.left
, rgn_data
->rdh
.rcBound
.top
,
237 rgn_data
->rdh
.rcBound
.right
, rgn_data
->rdh
.rcBound
.bottom
,
238 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
239 rect
= (RECT
*)&rgn_data
->Buffer
[0];
240 ok(EqualRect(rect
, &client_rect
),
241 "Got unexpected clip rect {%d, %d, %d, %d}, expected {%d, %d, %d, %d}.\n",
242 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
243 client_rect
.left
, client_rect
.top
, client_rect
.right
, client_rect
.bottom
);
244 HeapFree(GetProcessHeap(), 0, rgn_data
);
246 r1
= CreateRectRgn(0, 0, 320, 240);
247 ok(!!r1
, "Failed to create region.\n");
248 r2
= CreateRectRgn(320, 240, 640, 480);
249 ok(!!r2
, "Failed to create region.\n");
250 CombineRgn(r1
, r1
, r2
, RGN_OR
);
251 ret
= GetRegionData(r1
, 0, NULL
);
252 rgn_data
= HeapAlloc(GetProcessHeap(), 0, ret
);
253 ret
= GetRegionData(r1
, ret
, rgn_data
);
254 ok(!!ret
, "Failed to get region data.\n");
259 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
260 ok(hr
== DDERR_CLIPPERISUSINGHWND
, "Got unexpected hr %#x.\n", hr
);
261 hr
= IDirectDrawClipper_SetHWnd(clipper
, 0, NULL
);
262 ok(SUCCEEDED(hr
), "Failed to set clipper window, hr %#x.\n", hr
);
263 hr
= IDirectDrawClipper_SetClipList(clipper
, rgn_data
, 0);
264 ok(SUCCEEDED(hr
), "Failed to set clip list, hr %#x.\n", hr
);
266 HeapFree(GetProcessHeap(), 0, rgn_data
);
268 memset(&surface_desc
, 0, sizeof(surface_desc
));
269 surface_desc
.dwSize
= sizeof(surface_desc
);
270 surface_desc
.dwFlags
= DDSD_CAPS
| DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
;
271 surface_desc
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
;
272 surface_desc
.dwWidth
= 640;
273 surface_desc
.dwHeight
= 480;
274 surface_desc
.ddpfPixelFormat
.dwSize
= sizeof(surface_desc
.ddpfPixelFormat
);
275 surface_desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
276 U1(surface_desc
.ddpfPixelFormat
).dwRGBBitCount
= 32;
277 U2(surface_desc
.ddpfPixelFormat
).dwRBitMask
= 0x00ff0000;
278 U3(surface_desc
.ddpfPixelFormat
).dwGBitMask
= 0x0000ff00;
279 U4(surface_desc
.ddpfPixelFormat
).dwBBitMask
= 0x000000ff;
281 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &src_surface
, NULL
);
282 ok(SUCCEEDED(hr
), "Failed to create source surface, hr %#x.\n", hr
);
283 hr
= IDirectDraw2_CreateSurface(ddraw
, &surface_desc
, &dst_surface
, NULL
);
284 ok(SUCCEEDED(hr
), "Failed to create destination surface, hr %#x.\n", hr
);
286 memset(&fx
, 0, sizeof(fx
));
287 fx
.dwSize
= sizeof(fx
);
288 hr
= IDirectDrawSurface_Blt(src_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
289 ok(SUCCEEDED(hr
), "Failed to clear source surface, hr %#x.\n", hr
);
290 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
291 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
293 hr
= IDirectDrawSurface_Lock(src_surface
, NULL
, &surface_desc
, 0, NULL
);
294 ok(SUCCEEDED(hr
), "Failed to lock source surface, hr %#x.\n", hr
);
295 ((DWORD
*)surface_desc
.lpSurface
)[0] = 0xff0000ff;
296 ((DWORD
*)surface_desc
.lpSurface
)[1] = 0xff00ff00;
297 ((DWORD
*)surface_desc
.lpSurface
)[2] = 0xffff0000;
298 ((DWORD
*)surface_desc
.lpSurface
)[3] = 0xffffffff;
299 hr
= IDirectDrawSurface_Unlock(src_surface
, NULL
);
300 ok(SUCCEEDED(hr
), "Failed to unlock source surface, hr %#x.\n", hr
);
302 hr
= IDirectDrawSurface_SetClipper(dst_surface
, clipper
);
303 ok(SUCCEEDED(hr
), "Failed to set clipper, hr %#x.\n", hr
);
305 SetRect(&src_rect
, 0, 0, 4, 1);
306 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, src_surface
, &src_rect
, DDBLT_WAIT
, NULL
);
307 ok(SUCCEEDED(hr
), "Failed to blit, hr %#x.\n", hr
);
308 for (i
= 0; i
< 4; ++i
)
310 for (j
= 0; j
< 4; ++j
)
312 x
= 80 * ((2 * j
) + 1);
313 y
= 60 * ((2 * i
) + 1);
314 color
= get_surface_color(dst_surface
, x
, y
);
315 ok(compare_color(color
, expected1
[i
* 4 + j
], 1),
316 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected1
[i
* 4 + j
], x
, y
, color
);
320 U5(fx
).dwFillColor
= 0xff0000ff;
321 hr
= IDirectDrawSurface_Blt(dst_surface
, NULL
, NULL
, NULL
, DDBLT_COLORFILL
| DDBLT_WAIT
, &fx
);
322 ok(SUCCEEDED(hr
), "Failed to clear destination surface, hr %#x.\n", hr
);
323 for (i
= 0; i
< 4; ++i
)
325 for (j
= 0; j
< 4; ++j
)
327 x
= 80 * ((2 * j
) + 1);
328 y
= 60 * ((2 * i
) + 1);
329 color
= get_surface_color(dst_surface
, x
, y
);
330 ok(compare_color(color
, expected2
[i
* 4 + j
], 1),
331 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected2
[i
* 4 + j
], x
, y
, color
);
335 hr
= IDirectDrawSurface_BltFast(dst_surface
, 0, 0, src_surface
, NULL
, DDBLTFAST_WAIT
);
336 ok(hr
== DDERR_BLTFASTCANTCLIP
|| broken(hr
== E_NOTIMPL
/* NT4 */), "Got unexpected hr %#x.\n", hr
);
338 IDirectDrawSurface_Release(dst_surface
);
339 IDirectDrawSurface_Release(src_surface
);
340 IDirectDrawClipper_Release(clipper
);
341 IDirectDraw2_Release(ddraw
);
346 test_coop_level_create_device_window();