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