88401bddc855b9e242bd2a6b0c486164ec603371
[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
52 // check the parameters
53 if (This->cooperative_level == cooplevel && This->window == hwnd)
54 return DD_OK;
55
56 if (This->window)
57 return DDERR_HWNDALREADYSET;
58
59 if (This->cooperative_level)
60 return DDERR_EXCLUSIVEMODEALREADYSET;
61
62 if ((cooplevel&DDSCL_EXCLUSIVE) && !(cooplevel&DDSCL_FULLSCREEN))
63 return DDERR_INVALIDPARAMS;
64
65 if (cooplevel&DDSCL_NORMAL && cooplevel&DDSCL_FULLSCREEN)
66 return DDERR_INVALIDPARAMS;
67
68 // set the data
69 This->window = hwnd;
70 This->hdc = GetDC(hwnd);
71 This->cooperative_level = cooplevel;
72
73 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_SETEXCLUSIVEMODE)
74 {
75 return Hal_DirectDraw_SetCooperativeLevel (iface);
76 }
77
78 return Hel_DirectDraw_SetCooperativeLevel(iface);
79
80 }
81
82 HRESULT WINAPI Main_DirectDraw_SetDisplayMode (LPDIRECTDRAW7 iface, DWORD dwWidth, DWORD dwHeight,
83 DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags)
84 {
85 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
86 BOOL dummy = TRUE;
87 DWORD ret;
88
89 /* FIXME check the refresrate if it same if it not same do the mode switch */
90 if ((This->DirectDrawGlobal.vmiData.dwDisplayHeight == dwHeight) &&
91 (This->DirectDrawGlobal.vmiData.dwDisplayWidth == dwWidth) &&
92 (This->DirectDrawGlobal.vmiData.ddpfDisplay.dwRGBBitCount == dwBPP))
93 {
94
95 return DD_OK;
96 }
97
98 /* Check use the Hal or Hel for SetMode */
99 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_SETMODE)
100 {
101 ret = Hal_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags);
102 }
103 else
104 {
105 ret = Hel_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags);
106 }
107
108 if (ret == DD_OK)
109 {
110 DdReenableDirectDrawObject(&This->DirectDrawGlobal, &dummy);
111 /* FIXME fill the This->DirectDrawGlobal.vmiData right */
112 }
113
114 return ret;
115 }
116
117 ULONG WINAPI Main_DirectDraw_AddRef (LPDIRECTDRAW7 iface)
118 {
119 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
120 ULONG ref = InterlockedIncrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
121
122 return ref;
123 }
124
125 ULONG WINAPI Main_DirectDraw_Release (LPDIRECTDRAW7 iface)
126 {
127 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
128 ULONG ref = InterlockedDecrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
129
130 if (ref == 0)
131 {
132 // set resoltion back to the one in registry
133 if(This->cooperative_level & DDSCL_EXCLUSIVE)
134 ChangeDisplaySettings(NULL, 0);
135
136 HeapFree(GetProcessHeap(), 0, This);
137 }
138
139 return ref;
140 }
141
142 HRESULT WINAPI Main_DirectDraw_QueryInterface (
143 LPDIRECTDRAW7 iface, REFIID id, LPVOID *obj )
144 {
145 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
146
147 if (IsEqualGUID(&IID_IDirectDraw7, id))
148 {
149 *obj = &This->lpVtbl;
150 }
151 else if (IsEqualGUID(&IID_IDirectDraw, id))
152 {
153 *obj = &This->lpVtbl_v1;
154 }
155 else if (IsEqualGUID(&IID_IDirectDraw2, id))
156 {
157 *obj = &This->lpVtbl_v2;
158 }
159 else if (IsEqualGUID(&IID_IDirectDraw4, id))
160 {
161 *obj = &This->lpVtbl_v4;
162 }
163 else
164 {
165 *obj = NULL;
166 return E_NOINTERFACE;
167 }
168
169 Main_DirectDraw_AddRef(iface);
170 return S_OK;
171 }
172
173 HRESULT WINAPI Main_DirectDraw_CreateSurface (LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
174 LPDIRECTDRAWSURFACE7 *ppSurf, IUnknown *pUnkOuter)
175 {
176 if (pUnkOuter!=NULL)
177 return DDERR_INVALIDPARAMS;
178
179 if(sizeof(DDSURFACEDESC2)!=pDDSD->dwSize && sizeof(DDSURFACEDESC)!=pDDSD->dwSize)
180 return DDERR_UNSUPPORTED;
181
182 // the nasty com stuff
183 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
184
185 IDirectDrawSurfaceImpl* That;
186
187 That = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawSurfaceImpl));
188
189 if (That == NULL)
190 return E_OUTOFMEMORY;
191
192 ZeroMemory(That, sizeof(IDirectDrawSurfaceImpl));
193
194 That->lpVtbl = &DirectDrawSurface7_Vtable;
195 That->lpVtbl_v3 = &DDRAW_IDDS3_Thunk_VTable;
196
197 This->DirectDrawGlobal.dsList = (LPDDRAWI_DDRAWSURFACE_INT)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
198 sizeof(DDRAWI_DDRAWSURFACE_INT));
199 That->owner = (IDirectDrawImpl *)This;
200 That->owner->DirectDrawGlobal.dsList->dwIntRefCnt =1;
201
202 /* we alwasy set to use the DirectDrawSurface7_Vtable as internel */
203 That->owner->DirectDrawGlobal.dsList->lpVtbl = (PVOID) &DirectDrawSurface7_Vtable;
204
205 *ppSurf = (LPDIRECTDRAWSURFACE7)That;
206
207 // the real surface object creation
208 return That->lpVtbl->Initialize (*ppSurf, (LPDIRECTDRAW)iface, pDDSD);
209 }
210
211 HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
212 LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)
213 {
214 if (pUnkOuter!=NULL)
215 return DDERR_INVALIDPARAMS;
216
217 IDirectDrawClipperImpl* That;
218 That = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawClipperImpl));
219
220 if (That == NULL)
221 return E_OUTOFMEMORY;
222
223 ZeroMemory(That, sizeof(IDirectDrawClipperImpl));
224
225 That->lpVtbl = &DirectDrawClipper_Vtable;
226 That->ref = 1;
227 *ppClipper = (LPDIRECTDRAWCLIPPER)That;
228
229 return That->lpVtbl->Initialize (*ppClipper, (LPDIRECTDRAW)iface, dwFlags);
230 }
231
232 // This function is exported by the dll
233 HRESULT WINAPI DirectDrawCreateClipper (DWORD dwFlags,
234 LPDIRECTDRAWCLIPPER* lplpDDClipper, LPUNKNOWN pUnkOuter)
235 {
236 return Main_DirectDraw_CreateClipper(NULL, dwFlags, lplpDDClipper, pUnkOuter);
237 }
238
239 HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
240 LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter)
241 {
242 if (pUnkOuter!=NULL)
243 return DDERR_INVALIDPARAMS;
244
245 IDirectDrawPaletteImpl* That;
246 That = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawPaletteImpl));
247
248 if (That == NULL)
249 return E_OUTOFMEMORY;
250
251 ZeroMemory(That, sizeof(IDirectDrawPaletteImpl));
252
253 That->lpVtbl = &DirectDrawPalette_Vtable;
254 That->ref = 1;
255 *ppPalette = (LPDIRECTDRAWPALETTE)That;
256
257 return That->lpVtbl->Initialize (*ppPalette, (LPDIRECTDRAW)iface, dwFlags, palent);
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 pDDSD->lPitch = This->DirectDrawGlobal.vmiData.lDisplayPitch;
309 pDDSD->dwRefreshRate = This->DirectDrawGlobal.dwMonitorFrequency;
310
311 RtlCopyMemory(&pDDSD->ddpfPixelFormat,&This->DirectDrawGlobal.vmiData.ddpfDisplay,sizeof(DDPIXELFORMAT));
312 RtlCopyMemory(&pDDSD->ddsCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
313
314 /* have not check where I should get hold of this info yet
315 DWORD dwBackBufferCount;
316 DWORD dwAlphaBitDepth;
317 DWORD dwReserved;
318 LPVOID lpSurface;
319 union
320 {
321 DDCOLORKEY ddckCKDestOverlay;
322 DWORD dwEmptyFaceColor;
323 }
324 DDCOLORKEY ddckCKDestBlt;
325 DDCOLORKEY ddckCKSrcOverlay;
326 DDCOLORKEY ddckCKSrcBlt;
327 DWORD dwTextureStage;
328 */
329
330 return DD_OK;
331 }
332
333 HRESULT WINAPI Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
334 HANDLE h)
335 {
336 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
337
338 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_WAITFORVERTICALBLANK)
339 {
340 return Hal_DirectDraw_WaitForVerticalBlank( iface, dwFlags, h);
341 }
342
343 return Hel_DirectDraw_WaitForVerticalBlank( iface, dwFlags, h);
344 }
345
346 HRESULT WINAPI Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
347 LPDWORD total, LPDWORD free)
348 {
349 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
350
351 if (This->DirectDrawGlobal.lpDDCBtmp->HALDDMiscellaneous.dwFlags & DDHAL_MISCCB32_GETAVAILDRIVERMEMORY)
352 {
353 return Hal_DirectDraw_GetAvailableVidMem (iface,ddscaps,total,free);
354 }
355
356 return Hel_DirectDraw_GetAvailableVidMem (iface,ddscaps,total,free);
357 }
358
359 HRESULT WINAPI Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
360 {
361 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
362
363 if (freq == NULL)
364 {
365 return DD_FALSE;
366 }
367
368 *freq = This->DirectDrawGlobal.dwMonitorFrequency;
369 return DD_OK;
370 }
371
372 HRESULT WINAPI Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
373 {
374 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
375
376 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_GETSCANLINE)
377 {
378 return Hal_DirectDraw_GetScanLine( iface, lpdwScanLine);
379 }
380
381 return Hel_DirectDraw_GetScanLine( iface, lpdwScanLine);
382 }
383
384 /********************************** Stubs **********************************/
385
386 HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
387 {
388 DX_STUB;
389 }
390
391 HRESULT WINAPI Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
392 LPDIRECTDRAWSURFACE7* dst)
393 {
394 DX_STUB;
395 }
396
397 HRESULT WINAPI Main_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
398 LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback)
399 {
400 DX_STUB;
401 }
402
403 HRESULT WINAPI Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
404 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
405 LPDDENUMSURFACESCALLBACK7 callback)
406 {
407 DX_STUB;
408 }
409
410
411 HRESULT WINAPI Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)
412 {
413 DX_STUB;
414 }
415
416 HRESULT WINAPI Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
417 LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
418 {
419 DX_STUB;
420 }
421
422 HRESULT WINAPI Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
423 {
424 DX_STUB;
425 }
426
427 HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
428 {
429 DX_STUB;
430 }
431
432 HRESULT WINAPI Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
433 LPDIRECTDRAWSURFACE7 *lpDDS)
434 {
435 DX_STUB;
436 }
437
438 HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
439 {
440 DX_STUB;
441 }
442
443 HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
444 {
445 DX_STUB;
446 }
447
448 HRESULT WINAPI Main_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
449 LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
450 {
451 DX_STUB;
452 }
453
454 HRESULT WINAPI Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
455 DWORD dwNumModes, DWORD dwFlags)
456 {
457 DX_STUB;
458 }
459
460 HRESULT WINAPI Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
461 {
462 DX_STUB;
463 }
464
465 IDirectDraw7Vtbl DirectDraw7_Vtable =
466 {
467 Main_DirectDraw_QueryInterface,
468 Main_DirectDraw_AddRef,
469 Main_DirectDraw_Release,
470 Main_DirectDraw_Compact,
471 Main_DirectDraw_CreateClipper,
472 Main_DirectDraw_CreatePalette,
473 Main_DirectDraw_CreateSurface,
474 Main_DirectDraw_DuplicateSurface,
475 Main_DirectDraw_EnumDisplayModes,
476 Main_DirectDraw_EnumSurfaces,
477 Main_DirectDraw_FlipToGDISurface,
478 Main_DirectDraw_GetCaps,
479 Main_DirectDraw_GetDisplayMode,
480 Main_DirectDraw_GetFourCCCodes,
481 Main_DirectDraw_GetGDISurface,
482 Main_DirectDraw_GetMonitorFrequency,
483 Main_DirectDraw_GetScanLine,
484 Main_DirectDraw_GetVerticalBlankStatus,
485 Main_DirectDraw_Initialize,
486 Main_DirectDraw_RestoreDisplayMode,
487 Main_DirectDraw_SetCooperativeLevel,
488 Main_DirectDraw_SetDisplayMode,
489 Main_DirectDraw_WaitForVerticalBlank,
490 Main_DirectDraw_GetAvailableVidMem,
491 Main_DirectDraw_GetSurfaceFromDC,
492 Main_DirectDraw_RestoreAllSurfaces,
493 Main_DirectDraw_TestCooperativeLevel,
494 Main_DirectDraw_GetDeviceIdentifier,
495 Main_DirectDraw_StartModeTest,
496 Main_DirectDraw_EvaluateMode
497 };