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