dnsapi: Cast-qual warnings fix.
[wine] / dlls / ddraw / tests / ddrawmodes.c
1 /*
2  * Unit tests for ddraw functions
3  *
4  * Copyright (C) 2003 Sami Aario
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <assert.h>
22 #include "wine/test.h"
23 #include "ddraw.h"
24
25 static LPDIRECTDRAW lpDD = NULL;
26 static LPDIRECTDRAWSURFACE lpDDSPrimary = NULL;
27 static LPDIRECTDRAWSURFACE lpDDSBack = NULL;
28 static WNDCLASS wc;
29 static HWND hwnd;
30 static int modes_cnt;
31 static int modes_size;
32 static LPDDSURFACEDESC modes;
33
34 static void createwindow(void)
35 {
36     wc.style = CS_HREDRAW | CS_VREDRAW;
37     wc.lpfnWndProc = DefWindowProcA;
38     wc.cbClsExtra = 0;
39     wc.cbWndExtra = 0;
40     wc.hInstance = GetModuleHandleA(0);
41     wc.hIcon = LoadIconA(wc.hInstance, IDI_APPLICATION);
42     wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
43     wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
44     wc.lpszMenuName = NULL;
45     wc.lpszClassName = "TestWindowClass";
46     if(!RegisterClassA(&wc))
47         assert(0);
48     
49     hwnd = CreateWindowExA(0, "TestWindowClass", "TestWindowClass",
50         WS_POPUP, 0, 0,
51         GetSystemMetrics(SM_CXSCREEN),
52         GetSystemMetrics(SM_CYSCREEN),
53         NULL, NULL, GetModuleHandleA(0), NULL);
54     assert(hwnd != NULL);
55     
56     ShowWindow(hwnd, SW_HIDE);
57     UpdateWindow(hwnd);
58     SetFocus(hwnd);
59     
60 }
61
62 static BOOL createdirectdraw(void)
63 {
64     HRESULT rc;
65
66     rc = DirectDrawCreate(NULL, &lpDD, NULL);
67     ok(rc==DD_OK || rc==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreateEx returned: %lx\n", rc);
68     if (!lpDD) {
69         trace("DirectDrawCreateEx() failed with an error %lx\n", rc);
70         return FALSE;
71     }
72     return TRUE;
73 }
74
75
76 static void releasedirectdraw(void)
77 {
78         if( lpDD != NULL )
79         {
80                 IDirectDraw_Release(lpDD);
81                 lpDD = NULL;
82         }
83 }
84
85 static void adddisplaymode(LPDDSURFACEDESC lpddsd)
86 {
87     if (!modes) 
88         modes = malloc((modes_size = 2) * sizeof(DDSURFACEDESC));
89     if (modes_cnt == modes_size) 
90             modes = realloc(modes, (modes_size *= 2) * sizeof(DDSURFACEDESC));
91     assert(modes);
92     modes[modes_cnt++] = *lpddsd;
93 }
94
95 static void flushdisplaymodes(void)
96 {
97     free(modes);
98     modes = 0;
99     modes_cnt = modes_size = 0;
100 }
101
102 static HRESULT WINAPI enummodescallback(LPDDSURFACEDESC lpddsd, LPVOID lpContext)
103 {
104     trace("Width = %li, Height = %li, Refresh Rate = %li\r\n",
105         lpddsd->dwWidth, lpddsd->dwHeight,
106         U2(*lpddsd).dwRefreshRate);
107     adddisplaymode(lpddsd);
108
109     return DDENUMRET_OK;
110 }
111
112 static void enumdisplaymodes(void)
113 {
114     DDSURFACEDESC ddsd;
115     HRESULT rc;
116
117     ZeroMemory(&ddsd, sizeof(DDSURFACEDESC));
118     ddsd.dwSize = sizeof(DDSURFACEDESC);
119     ddsd.dwFlags = DDSD_CAPS;
120     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
121
122     rc = IDirectDraw_EnumDisplayModes(lpDD,
123         DDEDM_STANDARDVGAMODES, &ddsd, 0, enummodescallback);
124     ok(rc==DD_OK || rc==E_INVALIDARG,"EnumDisplayModes returned: %lx\n",rc);
125 }
126
127 static void setdisplaymode(int i)
128 {
129     HRESULT rc;
130
131     rc = IDirectDraw_SetCooperativeLevel(lpDD,
132         hwnd, DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
133     ok(rc==DD_OK,"SetCooperativeLevel returned: %lx\n",rc);
134     if (modes[i].dwFlags & DDSD_PIXELFORMAT)
135     {
136         if (modes[i].ddpfPixelFormat.dwFlags & DDPF_RGB)
137         {
138             rc = IDirectDraw_SetDisplayMode(lpDD,
139                 modes[i].dwWidth, modes[i].dwHeight,
140                 U1(modes[i].ddpfPixelFormat).dwRGBBitCount);
141             ok(DD_OK==rc || DDERR_UNSUPPORTED==rc,"SetDisplayMode returned: %lx\n",rc);
142             if (DD_OK==rc) {
143                 rc = IDirectDraw_RestoreDisplayMode(lpDD);
144                 ok(DD_OK==rc,"RestoreDisplayMode returned: %lx\n",rc);
145             }
146         }
147     }
148 }
149
150 static void createsurface(void)
151 {
152     DDSURFACEDESC ddsd;
153     DDSCAPS ddscaps;
154     HRESULT rc;
155     
156     ddsd.dwSize = sizeof(ddsd);
157     ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
158     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
159         DDSCAPS_FLIP |
160         DDSCAPS_COMPLEX;
161     ddsd.dwBackBufferCount = 1;
162     rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDDSPrimary, NULL );
163     ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
164     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
165     rc = IDirectDrawSurface_GetAttachedSurface(lpDDSPrimary, &ddscaps, &lpDDSBack);
166     ok(rc==DD_OK,"GetAttachedSurface returned: %lx\n",rc);
167 }
168
169 static void destroysurface(void)
170 {
171     if( lpDDSPrimary != NULL )
172     {
173         IDirectDrawSurface_Release(lpDDSPrimary);
174         lpDDSPrimary = NULL;
175     }
176 }
177
178 static void testsurface(void)
179 {
180     const char* testMsg = "ddraw device context test";
181     HDC hdc;
182     HRESULT rc;
183     
184     rc = IDirectDrawSurface_GetDC(lpDDSBack, &hdc);
185     ok(rc==DD_OK, "IDirectDrawSurface_GetDC returned: %lx\n",rc);
186     SetBkColor(hdc, RGB(0, 0, 255));
187     SetTextColor(hdc, RGB(255, 255, 0));
188     TextOut(hdc, 0, 0, testMsg, lstrlen(testMsg));
189     IDirectDrawSurface_ReleaseDC(lpDDSBack, hdc);
190     ok(rc==DD_OK, "IDirectDrawSurface_ReleaseDC returned: %lx\n",rc);
191     
192     while (1)
193     {
194         rc = IDirectDrawSurface_Flip(lpDDSPrimary, NULL, DDFLIP_WAIT);
195         ok(rc==DD_OK || rc==DDERR_SURFACELOST, "IDirectDrawSurface_BltFast returned: %lx\n",rc);
196
197         if (rc == DD_OK)
198         {
199             break;
200         }
201         else if (rc == DDERR_SURFACELOST)
202         {
203             rc = IDirectDrawSurface_Restore(lpDDSPrimary);
204             ok(rc==DD_OK, "IDirectDrawSurface_Restore returned: %lx\n",rc);
205         }
206     }
207 }
208
209 static void testdisplaymodes(void)
210 {
211     int i;
212
213     for (i = 0; i < modes_cnt; ++i)
214     {
215         setdisplaymode(i);
216         createsurface();
217         testsurface();
218         destroysurface();
219     }
220 }
221
222 static void testcooperativelevels_normal(void)
223 {
224     HRESULT rc;
225
226     /* Do some tests with DDSCL_NORMAL mode */
227
228     rc = IDirectDraw_SetCooperativeLevel(lpDD,
229         hwnd, DDSCL_NORMAL);
230     ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NORMAL) returned: %lx\n",rc);
231
232     /* Set the focus window */
233     rc = IDirectDraw_SetCooperativeLevel(lpDD,
234         hwnd, DDSCL_SETFOCUSWINDOW);
235     ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
236
237     /* Set the focus window a second time*/
238     rc = IDirectDraw_SetCooperativeLevel(lpDD,
239         hwnd, DDSCL_SETFOCUSWINDOW);
240     ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_SETFOCUSWINDOW) the second time returned: %lx\n",rc);
241
242     /* Test DDSCL_SETFOCUSWINDOW with the other flags. They should all fail, except of DDSCL_NOWINDOWCHANGES */
243     rc = IDirectDraw_SetCooperativeLevel(lpDD,
244         hwnd, DDSCL_NORMAL | DDSCL_SETFOCUSWINDOW);
245     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_NORMAL | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
246
247     rc = IDirectDraw_SetCooperativeLevel(lpDD,
248         hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_SETFOCUSWINDOW);
249     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
250
251     /* This one succeeds */
252     rc = IDirectDraw_SetCooperativeLevel(lpDD,
253         hwnd, DDSCL_NOWINDOWCHANGES | DDSCL_SETFOCUSWINDOW);
254     ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NOWINDOWCHANGES | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
255
256     rc = IDirectDraw_SetCooperativeLevel(lpDD,
257         hwnd, DDSCL_MULTITHREADED | DDSCL_SETFOCUSWINDOW);
258     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_MULTITHREADED | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
259
260     rc = IDirectDraw_SetCooperativeLevel(lpDD,
261         hwnd, DDSCL_FPUSETUP | DDSCL_SETFOCUSWINDOW);
262     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_FPUSETUP | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
263
264     rc = IDirectDraw_SetCooperativeLevel(lpDD,
265         hwnd, DDSCL_FPUPRESERVE | DDSCL_SETFOCUSWINDOW);
266     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_FPUPRESERVE | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
267
268     rc = IDirectDraw_SetCooperativeLevel(lpDD,
269         hwnd, DDSCL_ALLOWREBOOT | DDSCL_SETFOCUSWINDOW);
270     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_ALLOWREBOOT | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
271
272     rc = IDirectDraw_SetCooperativeLevel(lpDD,
273         hwnd, DDSCL_ALLOWMODEX | DDSCL_SETFOCUSWINDOW);
274     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_ALLOWMODEX | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
275
276     /* Set the device window without any other flags. Should give an error */
277     rc = IDirectDraw_SetCooperativeLevel(lpDD,
278         hwnd, DDSCL_SETDEVICEWINDOW);
279     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_SETDEVICEWINDOW) returned: %lx\n",rc);
280
281     /* Set device window with DDSCL_NORMAL */
282     rc = IDirectDraw_SetCooperativeLevel(lpDD,
283         hwnd, DDSCL_NORMAL | DDSCL_SETDEVICEWINDOW);
284     ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_NORMAL | DDSCL_SETDEVICEWINDOW) returned: %lx\n",rc);
285  
286     /* Also set the focus window. Should give an error */
287     rc = IDirectDraw_SetCooperativeLevel(lpDD,
288         hwnd, DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_SETDEVICEWINDOW | DDSCL_SETFOCUSWINDOW);
289     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_NORMAL | DDSCL_SETDEVICEWINDOW | DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
290
291     /* All done */
292 }
293
294 static void testcooperativelevels_exclusive(void)
295 {
296     HRESULT rc;
297
298     /* Do some tests with DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN mode */
299
300     /* Try to set exclusive mode only */
301     rc = IDirectDraw_SetCooperativeLevel(lpDD,
302         hwnd, DDSCL_EXCLUSIVE);
303     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_EXCLUSIVE) returned: %lx\n",rc);
304
305     /* Full screen mode only */
306     rc = IDirectDraw_SetCooperativeLevel(lpDD,
307         hwnd, DDSCL_FULLSCREEN);
308     ok(rc==DDERR_INVALIDPARAMS,"SetCooperativeLevel(DDSCL_FULLSCREEN) returned: %lx\n",rc);
309
310     /* Full screen mode + exclusive mode */
311     rc = IDirectDraw_SetCooperativeLevel(lpDD,
312         hwnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
313     ok(rc==DD_OK,"SetCooperativeLevel(DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) returned: %lx\n",rc);
314
315     /* Set the focus window. Should fail */
316     rc = IDirectDraw_SetCooperativeLevel(lpDD,
317         hwnd, DDSCL_SETFOCUSWINDOW);
318     ok(rc==DDERR_HWNDALREADYSET,"SetCooperativeLevel(DDSCL_SETFOCUSWINDOW) returned: %lx\n",rc);
319
320
321     /* All done */
322 }
323
324 START_TEST(ddrawmodes)
325 {
326     createwindow();
327     if (!createdirectdraw())
328         return;
329     enumdisplaymodes();
330     testdisplaymodes();
331     flushdisplaymodes();
332     releasedirectdraw();
333
334     createdirectdraw();
335     testcooperativelevels_normal();
336     releasedirectdraw();
337
338     createdirectdraw();
339     testcooperativelevels_exclusive();
340     releasedirectdraw();
341 }