adding more stuff for create surface right
[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
20
21 // this if it is not called by DirectDrawCreate
22 if(FALSE)
23 return DDERR_ALREADYINITIALIZED;
24
25 // save the parameter
26 This->lpGUID = lpGUID;
27
28 // get the HDC
29 This->hdc = GetWindowDC(GetDesktopWindow());
30 This->Height = GetDeviceCaps(This->hdc, VERTRES);
31 This->Width = GetDeviceCaps(This->hdc, HORZRES);
32 This->Bpp = GetDeviceCaps(This->hdc, BITSPIXEL);
33
34 // call software first
35 if((ret = Hal_DirectDraw_Initialize (iface)) != DD_OK)
36 return ret;
37
38 // ... then overwrite with hal
39 if((ret = Hel_DirectDraw_Initialize (iface)) != DD_OK)
40 return ret;
41
42 return DD_OK;
43 }
44
45 HRESULT WINAPI Main_DirectDraw_SetCooperativeLevel (LPDIRECTDRAW7 iface, HWND hwnd, DWORD cooplevel)
46 {
47 // TODO:
48 // - create a scaner that check which driver we should get the HDC from
49 // for now we always asume it is the active dirver that should be use.
50 // - allow more Flags
51
52 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
53
54 // check the parameters
55 if (This->cooperative_level == cooplevel && This->window == hwnd)
56 return DD_OK;
57
58 if (This->window)
59 return DDERR_HWNDALREADYSET;
60
61 if (This->cooperative_level)
62 return DDERR_EXCLUSIVEMODEALREADYSET;
63
64 if ((cooplevel&DDSCL_EXCLUSIVE) && !(cooplevel&DDSCL_FULLSCREEN))
65 return DDERR_INVALIDPARAMS;
66
67 if (cooplevel&DDSCL_NORMAL && cooplevel&DDSCL_FULLSCREEN)
68 return DDERR_INVALIDPARAMS;
69
70 // set the data
71 This->window = hwnd;
72 This->hdc = GetDC(hwnd);
73 This->cooperative_level = cooplevel;
74
75
76 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_SETEXCLUSIVEMODE)
77 {
78 return Hal_DirectDraw_SetCooperativeLevel (iface);
79 }
80
81 return Hel_DirectDraw_SetCooperativeLevel(iface);
82
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
90 /* FIXME implement hal setMode */
91 if((ret = Hal_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight,
92 dwBPP, dwRefreshRate, dwFlags)) == DD_OK)
93 {
94 return ret;
95 }
96
97 ret = Hel_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags);
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)
165 return DDERR_UNSUPPORTED;
166
167 // the nasty com stuff
168 IDirectDrawSurfaceImpl* That;
169
170 That = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawSurfaceImpl));
171
172 if (That == NULL)
173 return E_OUTOFMEMORY;
174
175 ZeroMemory(That, sizeof(IDirectDrawSurfaceImpl));
176
177 That->lpVtbl = &DirectDrawSurface7_Vtable;
178 That->lpVtbl_v3 = &DDRAW_IDDS3_Thunk_VTable;
179
180 That->owner->DirectDrawGlobal.dsList->dwIntRefCnt =1;
181
182 /* we alwasy set to use the DirectDrawSurface7_Vtable as internel */
183 That->owner->DirectDrawGlobal.dsList->lpVtbl = (PVOID) &DirectDrawSurface7_Vtable;
184
185 *ppSurf = (LPDIRECTDRAWSURFACE7)That;
186
187 // the real surface object creation
188 return That->lpVtbl->Initialize (*ppSurf, (LPDIRECTDRAW)iface, pDDSD);
189 }
190
191 HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
192 LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)
193 {
194 if (pUnkOuter!=NULL)
195 return DDERR_INVALIDPARAMS;
196
197 IDirectDrawClipperImpl* That;
198 That = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawClipperImpl));
199
200 if (That == NULL)
201 return E_OUTOFMEMORY;
202
203 ZeroMemory(That, sizeof(IDirectDrawClipperImpl));
204
205 That->lpVtbl = &DirectDrawClipper_Vtable;
206 That->ref = 1;
207 *ppClipper = (LPDIRECTDRAWCLIPPER)That;
208
209 return That->lpVtbl->Initialize (*ppClipper, (LPDIRECTDRAW)iface, dwFlags);
210 }
211
212 // This function is exported by the dll
213 HRESULT WINAPI DirectDrawCreateClipper (DWORD dwFlags,
214 LPDIRECTDRAWCLIPPER* lplpDDClipper, LPUNKNOWN pUnkOuter)
215 {
216 return Main_DirectDraw_CreateClipper(NULL, dwFlags, lplpDDClipper, pUnkOuter);
217 }
218
219 HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
220 LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter)
221 {
222 if (pUnkOuter!=NULL)
223 return DDERR_INVALIDPARAMS;
224
225 IDirectDrawPaletteImpl* That;
226 That = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawPaletteImpl));
227
228 if (That == NULL)
229 return E_OUTOFMEMORY;
230
231 ZeroMemory(That, sizeof(IDirectDrawPaletteImpl));
232
233 That->lpVtbl = &DirectDrawPalette_Vtable;
234 That->ref = 1;
235 *ppPalette = (LPDIRECTDRAWPALETTE)That;
236
237 return That->lpVtbl->Initialize (*ppPalette, (LPDIRECTDRAW)iface, dwFlags, palent);
238 }
239
240 /**** Stubs ****/
241
242 HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
243 {
244 DX_STUB;
245 }
246
247 HRESULT WINAPI Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
248 LPDIRECTDRAWSURFACE7* dst)
249 {
250 DX_STUB;
251 }
252
253 HRESULT WINAPI Main_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
254 LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback)
255 {
256 DX_STUB;
257 }
258
259 HRESULT WINAPI Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
260 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
261 LPDDENUMSURFACESCALLBACK7 callback)
262 {
263 DX_STUB;
264 }
265
266 HRESULT WINAPI Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
267 {
268 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
269
270 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_FLIPTOGDISURFACE)
271 {
272 return Hal_DirectDraw_FlipToGDISurface( iface);
273 }
274
275 return Hel_DirectDraw_FlipToGDISurface( iface);
276 }
277
278 HRESULT WINAPI Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
279 LPDDCAPS pHELCaps)
280 {
281 DWORD status = DD_FALSE;
282 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
283
284 if (pDriverCaps != NULL)
285 {
286 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
287 status = DD_OK;
288 }
289
290 if (pHELCaps != NULL)
291 {
292 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddHELCaps,sizeof(DDCORECAPS));
293 status = DD_OK;
294 }
295
296 /* Both caps mixed ?? */
297 /* DDCORECAPS ddBothCaps; */
298
299 return status;
300 }
301
302 HRESULT WINAPI Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
303 {
304 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
305
306 if (pDDSD == NULL)
307 {
308 return DD_FALSE;
309 }
310
311 pDDSD->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_REFRESHRATE | DDSD_WIDTH;
312 pDDSD->dwHeight = This->DirectDrawGlobal.vmiData.dwDisplayHeight;
313 pDDSD->dwWidth = This->DirectDrawGlobal.vmiData.dwDisplayWidth;
314
315 /* FIXME Do not use DUMMYUNIONNAME1 some how union lPitch does not see by the compiler
316 but rest of the union are visable. more header problem ???
317 */
318 pDDSD->DUMMYUNIONNAME1.lPitch = This->DirectDrawGlobal.vmiData.lDisplayPitch;
319
320
321 /* have not check where I should get hold of this info yet
322 DWORD dwBackBufferCount;
323 */
324
325 pDDSD->dwRefreshRate = This->DirectDrawGlobal.dwMonitorFrequency;
326
327 /* have not check where I should get hold of this info yet
328 DWORD dwAlphaBitDepth;
329 DWORD dwReserved;
330 LPVOID lpSurface;
331 union
332 {
333 DDCOLORKEY ddckCKDestOverlay;
334 DWORD dwEmptyFaceColor;
335 }
336 DDCOLORKEY ddckCKDestBlt;
337 DDCOLORKEY ddckCKSrcOverlay;
338 DDCOLORKEY ddckCKSrcBlt;
339 */
340
341
342 RtlCopyMemory(&pDDSD->ddpfPixelFormat,&This->DirectDrawGlobal.vmiData.ddpfDisplay,sizeof(DDPIXELFORMAT));
343 RtlCopyMemory(&pDDSD->ddsCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
344
345 /* have not check where I should get hold of this info yet
346 DWORD dwTextureStage;
347 */
348
349 return DD_OK;
350 }
351
352
353 HRESULT WINAPI Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)
354 {
355 DX_STUB;
356 }
357
358 HRESULT WINAPI Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
359 LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
360 {
361 DX_STUB;
362 }
363
364 HRESULT WINAPI Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
365 {
366 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
367
368 if (freq == NULL)
369 {
370 return DD_FALSE;
371 }
372
373 *freq = This->DirectDrawGlobal.dwMonitorFrequency;
374 return DD_OK;
375 }
376
377 HRESULT WINAPI Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
378 {
379 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
380
381 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_GETSCANLINE)
382 {
383 return Hal_DirectDraw_GetScanLine( iface, lpdwScanLine);
384 }
385
386 return Hel_DirectDraw_GetScanLine( iface, lpdwScanLine);
387 }
388
389 HRESULT WINAPI Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
390 {
391 DX_STUB;
392 }
393
394 HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
395 {
396 DX_STUB;
397 }
398
399 HRESULT WINAPI Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
400 HANDLE h)
401 {
402 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
403
404 if (This->DirectDrawGlobal.lpDDCBtmp->HALDD.dwFlags & DDHAL_CB32_WAITFORVERTICALBLANK)
405 {
406 return Hal_DirectDraw_WaitForVerticalBlank( iface, dwFlags, h);
407 }
408
409 return Hel_DirectDraw_WaitForVerticalBlank( iface, dwFlags, h);
410 }
411
412 HRESULT WINAPI Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
413 LPDWORD total, LPDWORD free)
414 {
415 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
416
417 if (This->DirectDrawGlobal.lpDDCBtmp->HALDDMiscellaneous.dwFlags & DDHAL_MISCCB32_GETAVAILDRIVERMEMORY)
418 {
419 return Hal_DirectDraw_GetAvailableVidMem (iface,ddscaps,total,free);
420 }
421
422 return Hel_DirectDraw_GetAvailableVidMem (iface,ddscaps,total,free);
423 }
424
425 HRESULT WINAPI Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
426 LPDIRECTDRAWSURFACE7 *lpDDS)
427 {
428 DX_STUB;
429 }
430
431 HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
432 {
433 DX_STUB;
434 }
435
436 HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
437 {
438 DX_STUB;
439 }
440
441 HRESULT WINAPI Main_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
442 LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
443 {
444 DX_STUB;
445 }
446
447 HRESULT WINAPI Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
448 DWORD dwNumModes, DWORD dwFlags)
449 {
450 DX_STUB;
451 }
452
453 HRESULT WINAPI Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
454 {
455 DX_STUB;
456 }
457
458 IDirectDraw7Vtbl DirectDraw7_Vtable =
459 {
460 Main_DirectDraw_QueryInterface,
461 Main_DirectDraw_AddRef,
462 Main_DirectDraw_Release,
463 Main_DirectDraw_Compact,
464 Main_DirectDraw_CreateClipper,
465 Main_DirectDraw_CreatePalette,
466 Main_DirectDraw_CreateSurface,
467 Main_DirectDraw_DuplicateSurface,
468 Main_DirectDraw_EnumDisplayModes,
469 Main_DirectDraw_EnumSurfaces,
470 Main_DirectDraw_FlipToGDISurface,
471 Main_DirectDraw_GetCaps,
472 Main_DirectDraw_GetDisplayMode,
473 Main_DirectDraw_GetFourCCCodes,
474 Main_DirectDraw_GetGDISurface,
475 Main_DirectDraw_GetMonitorFrequency,
476 Main_DirectDraw_GetScanLine,
477 Main_DirectDraw_GetVerticalBlankStatus,
478 Main_DirectDraw_Initialize,
479 Main_DirectDraw_RestoreDisplayMode,
480 Main_DirectDraw_SetCooperativeLevel,
481 Main_DirectDraw_SetDisplayMode,
482 Main_DirectDraw_WaitForVerticalBlank,
483 Main_DirectDraw_GetAvailableVidMem,
484 Main_DirectDraw_GetSurfaceFromDC,
485 Main_DirectDraw_RestoreAllSurfaces,
486 Main_DirectDraw_TestCooperativeLevel,
487 Main_DirectDraw_GetDeviceIdentifier,
488 Main_DirectDraw_StartModeTest,
489 Main_DirectDraw_EvaluateMode
490 };