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