d3dc8492a10b32a7daa5d6edc786d638b7a391d4
[reactos.git] / reactos / lib / ddraw / main / ddraw.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS
5 * FILE: lib/ddraw/main/ddraw.c
6 * PURPOSE: IDirectDraw7 Implementation
7 * PROGRAMMER: Magnus Olsen, Maarten Bosma
8 *
9 */
10
11 #include "rosdraw.h"
12
13
14 HRESULT WINAPI Main_DirectDraw_Initialize (LPDIRECTDRAW7 iface, LPGUID lpGUID)
15 {
16 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
17 HRESULT ret;
18
19 // this if it is not called by DirectDrawCreate
20 if(FALSE)
21 return DDERR_ALREADYINITIALIZED;
22
23 // save the parameter
24 This->lpGUID = lpGUID;
25
26 // get the HDC
27 This->hdc = GetWindowDC(GetDesktopWindow());
28 This->Height = GetDeviceCaps(This->hdc, VERTRES);
29 This->Width = GetDeviceCaps(This->hdc, HORZRES);
30 This->Bpp = GetDeviceCaps(This->hdc, BITSPIXEL);
31
32 // call software first
33 if((ret = Hal_DirectDraw_Initialize (iface)) != DD_OK)
34 return ret;
35
36 // ... then overwrite with hal
37 if((ret = Hel_DirectDraw_Initialize (iface)) != DD_OK)
38 return ret;
39
40 return DD_OK;
41 }
42
43 HRESULT WINAPI Main_DirectDraw_SetCooperativeLevel (LPDIRECTDRAW7 iface, HWND hwnd, DWORD cooplevel)
44 {
45 // TODO:
46 // - create a scaner that check which driver we should get the HDC from
47 // for now we always asume it is the active dirver that should be use.
48 // - allow more Flags
49
50 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
51 HRESULT ret;
52
53 // check the parameters
54 if (This->cooperative_level == cooplevel && This->window == hwnd)
55 return DD_OK;
56
57 if (This->window)
58 return DDERR_HWNDALREADYSET;
59
60 if (This->cooperative_level)
61 return DDERR_EXCLUSIVEMODEALREADYSET;
62
63 if ((cooplevel&DDSCL_EXCLUSIVE) && !(cooplevel&DDSCL_FULLSCREEN))
64 return DDERR_INVALIDPARAMS;
65
66 if (cooplevel&DDSCL_NORMAL && cooplevel&DDSCL_FULLSCREEN)
67 return DDERR_INVALIDPARAMS;
68
69 // set the data
70 This->window = hwnd;
71 This->hdc = GetDC(hwnd);
72 This->cooperative_level = cooplevel;
73
74 if((ret = Hel_DirectDraw_SetCooperativeLevel (iface)) != DD_OK)
75 return ret;
76
77 if((ret = Hal_DirectDraw_SetCooperativeLevel (iface)) != DD_OK)
78 return ret;
79
80 return DD_OK;
81 }
82
83 HRESULT WINAPI Main_DirectDraw_SetDisplayMode (LPDIRECTDRAW7 iface, DWORD dwWidth, DWORD dwHeight,
84 DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags)
85 {
86 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
87
88 // this only for exclusive mode
89 if(!(This->cooperative_level & DDSCL_EXCLUSIVE))
90 return DDERR_NOEXCLUSIVEMODE;
91
92 // change the resolution using normal WinAPI function
93 DEVMODE mode;
94 mode.dmSize = sizeof(mode);
95 mode.dmPelsWidth = dwWidth;
96 mode.dmPelsHeight = dwHeight;
97 mode.dmBitsPerPel = dwBPP;
98 mode.dmDisplayFrequency = dwRefreshRate;
99 mode.dmFields = 0;
100
101 if(dwWidth)
102 mode.dmFields |= DM_PELSWIDTH;
103 if(dwHeight)
104 mode.dmFields |= DM_PELSHEIGHT;
105 if(dwBPP)
106 mode.dmFields |= DM_BITSPERPEL;
107 if(dwRefreshRate)
108 mode.dmFields |= DM_DISPLAYFREQUENCY;
109
110 if (ChangeDisplaySettings(&mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
111 return DDERR_UNSUPPORTEDMODE;
112
113 // TODO: reactivate ddraw object, maximize window, set it in foreground
114 // and set excluive mode (if implemented by the driver)
115
116 if(dwWidth)
117 This->Height = dwWidth;
118 if(dwHeight)
119 This->Width = dwHeight;
120 if(dwBPP)
121 This->Bpp = dwBPP;
122
123 return DD_OK;
124 }
125
126 HRESULT WINAPI Main_DirectDraw_CreateSurface (LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
127 LPDIRECTDRAWSURFACE7 *ppSurf, IUnknown *pUnkOuter)
128 {
129 if (pUnkOuter!=NULL)
130 return DDERR_INVALIDPARAMS;
131
132 if(sizeof(DDSURFACEDESC2)!=pDDSD->dwSize)
133 return DDERR_UNSUPPORTED;
134
135 // the nasty com stuff
136 IDirectDrawSurfaceImpl* That;
137
138 That = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
139
140 if (That == NULL)
141 return E_OUTOFMEMORY;
142
143 That->lpVtbl = &DirectDrawSurface7_Vtable;
144 That->lpVtbl_v3 = &DDRAW_IDDS3_Thunk_VTable;
145
146 That->ref = 1;
147 *ppSurf = (LPDIRECTDRAWSURFACE7)That;
148
149 // the real surface object creation
150 return That->lpVtbl->Initialize (*ppSurf, (LPDIRECTDRAW)iface, pDDSD);
151 }
152
153 ULONG WINAPI Main_DirectDraw_AddRef (LPDIRECTDRAW7 iface)
154 {
155 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
156 ULONG ref = InterlockedIncrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
157
158 return ref;
159 }
160
161 ULONG WINAPI Main_DirectDraw_Release (LPDIRECTDRAW7 iface)
162 {
163 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
164 ULONG ref = InterlockedDecrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
165
166 if (ref == 0)
167 {
168 // set resoltion back to the one in registry
169 if(This->cooperative_level & DDSCL_EXCLUSIVE)
170 ChangeDisplaySettings(NULL, 0);
171
172 HeapFree(GetProcessHeap(), 0, This);
173 }
174
175 return ref;
176 }
177
178 HRESULT WINAPI Main_DirectDraw_QueryInterface (
179 LPDIRECTDRAW7 iface, REFIID id, LPVOID *obj )
180 {
181 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
182
183 if (IsEqualGUID(&IID_IDirectDraw7, id))
184 {
185 *obj = &This->lpVtbl;
186 }
187 else if (IsEqualGUID(&IID_IDirectDraw, id))
188 {
189 *obj = &This->lpVtbl_v1;
190 }
191 else if (IsEqualGUID(&IID_IDirectDraw2, id))
192 {
193 *obj = &This->lpVtbl_v2;
194 }
195 else if (IsEqualGUID(&IID_IDirectDraw4, id))
196 {
197 *obj = &This->lpVtbl_v4;
198 }
199 else
200 {
201 *obj = NULL;
202 return E_NOINTERFACE;
203 }
204
205 Main_DirectDraw_AddRef(iface);
206 return S_OK;
207 }
208
209 /**** Stubs ****/
210
211 HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
212 {
213 DX_STUB;
214 }
215
216 HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
217 LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)
218 {
219 DX_STUB;
220 }
221 HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
222 LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE* ppPalette,LPUNKNOWN pUnknown)
223 {
224 DX_STUB;
225 }
226
227 HRESULT WINAPI Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
228 LPDIRECTDRAWSURFACE7* dst)
229 {
230 DX_STUB;
231 }
232
233 HRESULT WINAPI Main_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
234 LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback)
235 {
236 DX_STUB;
237 }
238
239 HRESULT WINAPI Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
240 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
241 LPDDENUMSURFACESCALLBACK7 callback)
242 {
243 DX_STUB;
244 }
245
246 HRESULT WINAPI Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
247 {
248 DX_STUB;
249 }
250
251 HRESULT WINAPI Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
252 LPDDCAPS pHELCaps)
253 {
254 DWORD status = DD_FALSE;
255 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
256
257 if (pDriverCaps != NULL)
258 {
259 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
260 status = DD_OK;
261 }
262
263 if (pHELCaps != NULL)
264 {
265 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddHELCaps,sizeof(DDCORECAPS));
266 status = DD_OK;
267 }
268
269 /* Both caps mixed ?? */
270 /* DDCORECAPS ddBothCaps; */
271
272 return status;
273 }
274
275 HRESULT WINAPI Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
276 {
277 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
278
279 if (pDDSD == NULL)
280 {
281 return DD_FALSE;
282 }
283
284 pDDSD->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_REFRESHRATE | DDSD_WIDTH;
285 pDDSD->dwHeight = This->DirectDrawGlobal.vmiData.dwDisplayHeight;
286 pDDSD->dwWidth = This->DirectDrawGlobal.vmiData.dwDisplayWidth;
287
288 /* FIXME Do not use DUMMYUNIONNAME1 some how union lPitch does not see by the compiler
289 but rest of the union are visable. more header problem ???
290 */
291 pDDSD->DUMMYUNIONNAME1.lPitch = This->DirectDrawGlobal.vmiData.lDisplayPitch;
292
293
294 /* have not check where I should get hold of this info yet
295 DWORD dwBackBufferCount;
296 */
297
298 pDDSD->dwRefreshRate = This->DirectDrawGlobal.dwMonitorFrequency;
299
300 /* have not check where I should get hold of this info yet
301 DWORD dwAlphaBitDepth;
302 DWORD dwReserved;
303 LPVOID lpSurface;
304 union
305 {
306 DDCOLORKEY ddckCKDestOverlay;
307 DWORD dwEmptyFaceColor;
308 }
309 DDCOLORKEY ddckCKDestBlt;
310 DDCOLORKEY ddckCKSrcOverlay;
311 DDCOLORKEY ddckCKSrcBlt;
312 */
313
314 RtlCopyMemory(&pDDSD->ddpfPixelFormat,&This->DirectDrawGlobal.vmiData.ddpfDisplay,sizeof(DDPIXELFORMAT));
315 RtlCopyMemory(&pDDSD->ddsCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
316
317 /* have not check where I should get hold of this info yet
318 DWORD dwTextureStage;
319 */
320
321 return DD_OK;
322 }
323
324
325 HRESULT WINAPI Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)
326 {
327 DX_STUB;
328 }
329
330 HRESULT WINAPI Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
331 LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
332 {
333 DX_STUB;
334 }
335
336 HRESULT WINAPI Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
337 {
338 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
339
340 if (freq == NULL)
341 {
342 return DD_FALSE;
343 }
344
345 *freq = This->DirectDrawGlobal.dwMonitorFrequency;
346 return DD_OK;
347 }
348
349 HRESULT WINAPI Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
350 {
351 DX_STUB;
352 }
353
354 HRESULT WINAPI Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
355 {
356 DX_STUB;
357 }
358
359 HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
360 {
361 DX_STUB;
362 }
363
364 HRESULT WINAPI Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
365 HANDLE h)
366 {
367
368 DX_STUB;
369 }
370
371 HRESULT WINAPI Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
372 LPDWORD total, LPDWORD free)
373 {
374
375 DX_STUB;
376 }
377
378 HRESULT WINAPI Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
379 LPDIRECTDRAWSURFACE7 *lpDDS)
380 {
381 DX_STUB;
382 }
383
384 HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
385 {
386 DX_STUB;
387 }
388
389 HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
390 {
391 DX_STUB;
392 }
393
394 HRESULT WINAPI Main_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
395 LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
396 {
397 DX_STUB;
398 }
399
400 HRESULT WINAPI Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
401 DWORD dwNumModes, DWORD dwFlags)
402 {
403 DX_STUB;
404 }
405
406 HRESULT WINAPI Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
407 {
408 DX_STUB;
409 }
410
411 IDirectDraw7Vtbl DirectDraw7_Vtable =
412 {
413 Main_DirectDraw_QueryInterface,
414 Main_DirectDraw_AddRef,
415 Main_DirectDraw_Release,
416 Main_DirectDraw_Compact,
417 Main_DirectDraw_CreateClipper,
418 Main_DirectDraw_CreatePalette,
419 Main_DirectDraw_CreateSurface,
420 Main_DirectDraw_DuplicateSurface,
421 Main_DirectDraw_EnumDisplayModes,
422 Main_DirectDraw_EnumSurfaces,
423 Main_DirectDraw_FlipToGDISurface,
424 Main_DirectDraw_GetCaps,
425 Main_DirectDraw_GetDisplayMode,
426 Main_DirectDraw_GetFourCCCodes,
427 Main_DirectDraw_GetGDISurface,
428 Main_DirectDraw_GetMonitorFrequency,
429 Main_DirectDraw_GetScanLine,
430 Main_DirectDraw_GetVerticalBlankStatus,
431 Main_DirectDraw_Initialize,
432 Main_DirectDraw_RestoreDisplayMode,
433 Main_DirectDraw_SetCooperativeLevel,
434 Main_DirectDraw_SetDisplayMode,
435 Main_DirectDraw_WaitForVerticalBlank,
436 Main_DirectDraw_GetAvailableVidMem,
437 Main_DirectDraw_GetSurfaceFromDC,
438 Main_DirectDraw_RestoreAllSurfaces,
439 Main_DirectDraw_TestCooperativeLevel,
440 Main_DirectDraw_GetDeviceIdentifier,
441 Main_DirectDraw_StartModeTest,
442 Main_DirectDraw_EvaluateMode
443 };