Bind the Hal and Hel right in main call only to hal if the api are implement in the...
[reactos.git] / reactos / lib / ddraw / main / ddraw_main.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
75
76 if((ret = Hal_DirectDraw_SetCooperativeLevel (iface)) != DD_OK)
77 return ret;
78
79 if((ret = Hel_DirectDraw_SetCooperativeLevel (iface)) != DD_OK)
80 return ret;
81
82 return DD_OK;
83 }
84
85 HRESULT WINAPI Main_DirectDraw_SetDisplayMode (LPDIRECTDRAW7 iface, DWORD dwWidth, DWORD dwHeight,
86 DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags)
87 {
88 DWORD ret;
89 if((ret = Hal_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight,
90 dwBPP, dwRefreshRate, dwFlags)) == DD_OK)
91 {
92 return ret;
93 }
94
95 ret = Hel_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags);
96
97 return ret;
98 }
99
100 ULONG WINAPI Main_DirectDraw_AddRef (LPDIRECTDRAW7 iface)
101 {
102 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
103 ULONG ref = InterlockedIncrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
104
105 return ref;
106 }
107
108 ULONG WINAPI Main_DirectDraw_Release (LPDIRECTDRAW7 iface)
109 {
110 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
111 ULONG ref = InterlockedDecrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
112
113 if (ref == 0)
114 {
115 // set resoltion back to the one in registry
116 if(This->cooperative_level & DDSCL_EXCLUSIVE)
117 ChangeDisplaySettings(NULL, 0);
118
119 HeapFree(GetProcessHeap(), 0, This);
120 }
121
122 return ref;
123 }
124
125 HRESULT WINAPI Main_DirectDraw_QueryInterface (
126 LPDIRECTDRAW7 iface, REFIID id, LPVOID *obj )
127 {
128 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
129
130 if (IsEqualGUID(&IID_IDirectDraw7, id))
131 {
132 *obj = &This->lpVtbl;
133 }
134 else if (IsEqualGUID(&IID_IDirectDraw, id))
135 {
136 *obj = &This->lpVtbl_v1;
137 }
138 else if (IsEqualGUID(&IID_IDirectDraw2, id))
139 {
140 *obj = &This->lpVtbl_v2;
141 }
142 else if (IsEqualGUID(&IID_IDirectDraw4, id))
143 {
144 *obj = &This->lpVtbl_v4;
145 }
146 else
147 {
148 *obj = NULL;
149 return E_NOINTERFACE;
150 }
151
152 Main_DirectDraw_AddRef(iface);
153 return S_OK;
154 }
155
156 HRESULT WINAPI Main_DirectDraw_CreateSurface (LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
157 LPDIRECTDRAWSURFACE7 *ppSurf, IUnknown *pUnkOuter)
158 {
159 if (pUnkOuter!=NULL)
160 return DDERR_INVALIDPARAMS;
161
162 if(sizeof(DDSURFACEDESC2)!=pDDSD->dwSize)
163 return DDERR_UNSUPPORTED;
164
165 // the nasty com stuff
166 IDirectDrawSurfaceImpl* That;
167
168 That = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawSurfaceImpl));
169
170 if (That == NULL)
171 return E_OUTOFMEMORY;
172
173 ZeroMemory(That, sizeof(IDirectDrawSurfaceImpl));
174
175 That->lpVtbl = &DirectDrawSurface7_Vtable;
176 That->lpVtbl_v3 = &DDRAW_IDDS3_Thunk_VTable;
177 That->ref = 1;
178
179 *ppSurf = (LPDIRECTDRAWSURFACE7)That;
180
181 // the real surface object creation
182 return That->lpVtbl->Initialize (*ppSurf, (LPDIRECTDRAW)iface, pDDSD);
183 }
184
185 HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
186 LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)
187 {
188 if (pUnkOuter!=NULL)
189 return DDERR_INVALIDPARAMS;
190
191 IDirectDrawClipperImpl* That;
192 That = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawClipperImpl));
193
194 if (That == NULL)
195 return E_OUTOFMEMORY;
196
197 ZeroMemory(That, sizeof(IDirectDrawClipperImpl));
198
199 That->lpVtbl = &DirectDrawClipper_Vtable;
200 That->ref = 1;
201 *ppClipper = (LPDIRECTDRAWCLIPPER)That;
202
203 return That->lpVtbl->Initialize (*ppClipper, (LPDIRECTDRAW)iface, dwFlags);
204 }
205
206 // This function is exported by the dll
207 HRESULT WINAPI DirectDrawCreateClipper (DWORD dwFlags,
208 LPDIRECTDRAWCLIPPER* lplpDDClipper, LPUNKNOWN pUnkOuter)
209 {
210 return Main_DirectDraw_CreateClipper(NULL, dwFlags, lplpDDClipper, pUnkOuter);
211 }
212
213 HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
214 LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter)
215 {
216 if (pUnkOuter!=NULL)
217 return DDERR_INVALIDPARAMS;
218
219 IDirectDrawPaletteImpl* That;
220 That = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawPaletteImpl));
221
222 if (That == NULL)
223 return E_OUTOFMEMORY;
224
225 ZeroMemory(That, sizeof(IDirectDrawPaletteImpl));
226
227 That->lpVtbl = &DirectDrawPalette_Vtable;
228 That->ref = 1;
229 *ppPalette = (LPDIRECTDRAWPALETTE)That;
230
231 return That->lpVtbl->Initialize (*ppPalette, (LPDIRECTDRAW)iface, dwFlags, palent);
232 }
233
234 /**** Stubs ****/
235
236 HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
237 {
238 DX_STUB;
239 }
240
241 HRESULT WINAPI Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
242 LPDIRECTDRAWSURFACE7* dst)
243 {
244 DX_STUB;
245 }
246
247 HRESULT WINAPI Main_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
248 LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback)
249 {
250 DX_STUB;
251 }
252
253 HRESULT WINAPI Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
254 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
255 LPDDENUMSURFACESCALLBACK7 callback)
256 {
257 DX_STUB;
258 }
259
260 HRESULT WINAPI Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
261 {
262 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
263
264 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_FLIPTOGDISURFACE)
265 {
266 return Hal_DirectDraw_FlipToGDISurface( iface);
267 }
268
269 return Hel_DirectDraw_FlipToGDISurface( iface);
270 }
271
272 HRESULT WINAPI Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
273 LPDDCAPS pHELCaps)
274 {
275 DWORD status = DD_FALSE;
276 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
277
278 if (pDriverCaps != NULL)
279 {
280 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
281 status = DD_OK;
282 }
283
284 if (pHELCaps != NULL)
285 {
286 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddHELCaps,sizeof(DDCORECAPS));
287 status = DD_OK;
288 }
289
290 /* Both caps mixed ?? */
291 /* DDCORECAPS ddBothCaps; */
292
293 return status;
294 }
295
296 HRESULT WINAPI Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
297 {
298 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
299
300 if (pDDSD == NULL)
301 {
302 return DD_FALSE;
303 }
304
305 pDDSD->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_REFRESHRATE | DDSD_WIDTH;
306 pDDSD->dwHeight = This->DirectDrawGlobal.vmiData.dwDisplayHeight;
307 pDDSD->dwWidth = This->DirectDrawGlobal.vmiData.dwDisplayWidth;
308
309 /* FIXME Do not use DUMMYUNIONNAME1 some how union lPitch does not see by the compiler
310 but rest of the union are visable. more header problem ???
311 */
312 pDDSD->DUMMYUNIONNAME1.lPitch = This->DirectDrawGlobal.vmiData.lDisplayPitch;
313
314
315 /* have not check where I should get hold of this info yet
316 DWORD dwBackBufferCount;
317 */
318
319 pDDSD->dwRefreshRate = This->DirectDrawGlobal.dwMonitorFrequency;
320
321 /* have not check where I should get hold of this info yet
322 DWORD dwAlphaBitDepth;
323 DWORD dwReserved;
324 LPVOID lpSurface;
325 union
326 {
327 DDCOLORKEY ddckCKDestOverlay;
328 DWORD dwEmptyFaceColor;
329 }
330 DDCOLORKEY ddckCKDestBlt;
331 DDCOLORKEY ddckCKSrcOverlay;
332 DDCOLORKEY ddckCKSrcBlt;
333 */
334
335
336 RtlCopyMemory(&pDDSD->ddpfPixelFormat,&This->DirectDrawGlobal.vmiData.ddpfDisplay,sizeof(DDPIXELFORMAT));
337 RtlCopyMemory(&pDDSD->ddsCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
338
339 /* have not check where I should get hold of this info yet
340 DWORD dwTextureStage;
341 */
342
343 return DD_OK;
344 }
345
346
347 HRESULT WINAPI Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)
348 {
349 DX_STUB;
350 }
351
352 HRESULT WINAPI Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
353 LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
354 {
355 DX_STUB;
356 }
357
358 HRESULT WINAPI Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
359 {
360 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
361
362 if (freq == NULL)
363 {
364 return DD_FALSE;
365 }
366
367 *freq = This->DirectDrawGlobal.dwMonitorFrequency;
368 return DD_OK;
369 }
370
371 HRESULT WINAPI Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
372 {
373 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
374
375 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_GETSCANLINE)
376 {
377 return Hal_DirectDraw_GetScanLine( iface, lpdwScanLine);
378 }
379
380 return Hel_DirectDraw_GetScanLine( iface, lpdwScanLine);
381 }
382
383 HRESULT WINAPI Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
384 {
385 DX_STUB;
386 }
387
388 HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
389 {
390 DX_STUB;
391 }
392
393 HRESULT WINAPI Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
394 HANDLE h)
395 {
396 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
397
398 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_WAITFORVERTICALBLANK)
399 {
400 return Hal_DirectDraw_WaitForVerticalBlank( iface, dwFlags, h);
401 }
402
403 return Hel_DirectDraw_WaitForVerticalBlank( iface, dwFlags, h);
404 }
405
406 HRESULT WINAPI Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
407 LPDWORD total, LPDWORD free)
408 {
409 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
410
411 if (This->DirectDrawGlobal.lpDDCBtmp->HALDDMiscellaneous.dwFlags & DDHAL_MISCCB32_GETAVAILDRIVERMEMORY)
412 {
413 return Hal_DirectDraw_GetAvailableVidMem (iface,ddscaps,total,free);
414 }
415
416 return Hel_DirectDraw_GetAvailableVidMem (iface,ddscaps,total,free);
417 }
418
419 HRESULT WINAPI Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
420 LPDIRECTDRAWSURFACE7 *lpDDS)
421 {
422 DX_STUB;
423 }
424
425 HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
426 {
427 DX_STUB;
428 }
429
430 HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
431 {
432 DX_STUB;
433 }
434
435 HRESULT WINAPI Main_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
436 LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
437 {
438 DX_STUB;
439 }
440
441 HRESULT WINAPI Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
442 DWORD dwNumModes, DWORD dwFlags)
443 {
444 DX_STUB;
445 }
446
447 HRESULT WINAPI Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
448 {
449 DX_STUB;
450 }
451
452 IDirectDraw7Vtbl DirectDraw7_Vtable =
453 {
454 Main_DirectDraw_QueryInterface,
455 Main_DirectDraw_AddRef,
456 Main_DirectDraw_Release,
457 Main_DirectDraw_Compact,
458 Main_DirectDraw_CreateClipper,
459 Main_DirectDraw_CreatePalette,
460 Main_DirectDraw_CreateSurface,
461 Main_DirectDraw_DuplicateSurface,
462 Main_DirectDraw_EnumDisplayModes,
463 Main_DirectDraw_EnumSurfaces,
464 Main_DirectDraw_FlipToGDISurface,
465 Main_DirectDraw_GetCaps,
466 Main_DirectDraw_GetDisplayMode,
467 Main_DirectDraw_GetFourCCCodes,
468 Main_DirectDraw_GetGDISurface,
469 Main_DirectDraw_GetMonitorFrequency,
470 Main_DirectDraw_GetScanLine,
471 Main_DirectDraw_GetVerticalBlankStatus,
472 Main_DirectDraw_Initialize,
473 Main_DirectDraw_RestoreDisplayMode,
474 Main_DirectDraw_SetCooperativeLevel,
475 Main_DirectDraw_SetDisplayMode,
476 Main_DirectDraw_WaitForVerticalBlank,
477 Main_DirectDraw_GetAvailableVidMem,
478 Main_DirectDraw_GetSurfaceFromDC,
479 Main_DirectDraw_RestoreAllSurfaces,
480 Main_DirectDraw_TestCooperativeLevel,
481 Main_DirectDraw_GetDeviceIdentifier,
482 Main_DirectDraw_StartModeTest,
483 Main_DirectDraw_EvaluateMode
484 };