implment Hal FlipToGDISurface
[reactos.git] / reactos / lib / ddraw / main / ddraw.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 HRESULT ret;
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
75
76 if((ret = Hal_DirectDraw_SetCooperativeLevel (iface)) != DD_OK)
77 return ret;
78
79 if((ret = Hel_DirectDraw_SetCooperativeLevel (iface)) != DD_OK)
80 return ret;
81
82 return DD_OK;
83 }
84
85 HRESULT WINAPI Main_DirectDraw_SetDisplayMode (LPDIRECTDRAW7 iface, DWORD dwWidth, DWORD dwHeight,
86 DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags)
87 {
88 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
89
90 // this only for exclusive mode
91 if(!(This->cooperative_level & DDSCL_EXCLUSIVE))
92 return DDERR_NOEXCLUSIVEMODE;
93
94 // change the resolution using normal WinAPI function
95 DEVMODE mode;
96 mode.dmSize = sizeof(mode);
97 mode.dmPelsWidth = dwWidth;
98 mode.dmPelsHeight = dwHeight;
99 mode.dmBitsPerPel = dwBPP;
100 mode.dmDisplayFrequency = dwRefreshRate;
101 mode.dmFields = 0;
102
103 if(dwWidth)
104 mode.dmFields |= DM_PELSWIDTH;
105 if(dwHeight)
106 mode.dmFields |= DM_PELSHEIGHT;
107 if(dwBPP)
108 mode.dmFields |= DM_BITSPERPEL;
109 if(dwRefreshRate)
110 mode.dmFields |= DM_DISPLAYFREQUENCY;
111
112 if (ChangeDisplaySettings(&mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
113 return DDERR_UNSUPPORTEDMODE;
114
115 // TODO: reactivate ddraw object, maximize window, set it in foreground
116 // and set excluive mode (if implemented by the driver)
117
118 if(dwWidth)
119 This->Height = dwWidth;
120 if(dwHeight)
121 This->Width = dwHeight;
122 if(dwBPP)
123 This->Bpp = dwBPP;
124
125 return DD_OK;
126 }
127
128 ULONG WINAPI Main_DirectDraw_AddRef (LPDIRECTDRAW7 iface)
129 {
130 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
131 ULONG ref = InterlockedIncrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
132
133 return ref;
134 }
135
136 ULONG WINAPI Main_DirectDraw_Release (LPDIRECTDRAW7 iface)
137 {
138 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
139 ULONG ref = InterlockedDecrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
140
141 if (ref == 0)
142 {
143 // set resoltion back to the one in registry
144 if(This->cooperative_level & DDSCL_EXCLUSIVE)
145 ChangeDisplaySettings(NULL, 0);
146
147 HeapFree(GetProcessHeap(), 0, This);
148 }
149
150 return ref;
151 }
152
153 HRESULT WINAPI Main_DirectDraw_QueryInterface (
154 LPDIRECTDRAW7 iface, REFIID id, LPVOID *obj )
155 {
156 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
157
158 if (IsEqualGUID(&IID_IDirectDraw7, id))
159 {
160 *obj = &This->lpVtbl;
161 }
162 else if (IsEqualGUID(&IID_IDirectDraw, id))
163 {
164 *obj = &This->lpVtbl_v1;
165 }
166 else if (IsEqualGUID(&IID_IDirectDraw2, id))
167 {
168 *obj = &This->lpVtbl_v2;
169 }
170 else if (IsEqualGUID(&IID_IDirectDraw4, id))
171 {
172 *obj = &This->lpVtbl_v4;
173 }
174 else
175 {
176 *obj = NULL;
177 return E_NOINTERFACE;
178 }
179
180 Main_DirectDraw_AddRef(iface);
181 return S_OK;
182 }
183
184 HRESULT WINAPI Main_DirectDraw_CreateSurface (LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
185 LPDIRECTDRAWSURFACE7 *ppSurf, IUnknown *pUnkOuter)
186 {
187 if (pUnkOuter!=NULL)
188 return DDERR_INVALIDPARAMS;
189
190 if(sizeof(DDSURFACEDESC2)!=pDDSD->dwSize)
191 return DDERR_UNSUPPORTED;
192
193 // the nasty com stuff
194 IDirectDrawSurfaceImpl* That;
195
196 That = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawSurfaceImpl));
197
198 if (That == NULL)
199 return E_OUTOFMEMORY;
200
201 ZeroMemory(That, sizeof(IDirectDrawSurfaceImpl));
202
203 That->lpVtbl = &DirectDrawSurface7_Vtable;
204 That->lpVtbl_v3 = &DDRAW_IDDS3_Thunk_VTable;
205 That->ref = 1;
206
207 *ppSurf = (LPDIRECTDRAWSURFACE7)That;
208
209 // the real surface object creation
210 return That->lpVtbl->Initialize (*ppSurf, (LPDIRECTDRAW)iface, pDDSD);
211 }
212
213 HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
214 LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)
215 {
216 if (pUnkOuter!=NULL)
217 return DDERR_INVALIDPARAMS;
218
219 IDirectDrawClipperImpl* That;
220 That = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawClipperImpl));
221
222 if (That == NULL)
223 return E_OUTOFMEMORY;
224
225 ZeroMemory(That, sizeof(IDirectDrawClipperImpl));
226
227 That->lpVtbl = &DirectDrawClipper_Vtable;
228 That->ref = 1;
229 *ppClipper = (LPDIRECTDRAWCLIPPER)That;
230
231 return That->lpVtbl->Initialize (*ppClipper, (LPDIRECTDRAW)iface, dwFlags);
232 }
233
234 // This function is exported by the dll
235 HRESULT WINAPI DirectDrawCreateClipper (DWORD dwFlags,
236 LPDIRECTDRAWCLIPPER* lplpDDClipper, LPUNKNOWN pUnkOuter)
237 {
238 return Main_DirectDraw_CreateClipper(NULL, dwFlags, lplpDDClipper, pUnkOuter);
239 }
240
241 HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
242 LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter)
243 {
244 if (pUnkOuter!=NULL)
245 return DDERR_INVALIDPARAMS;
246
247 IDirectDrawPaletteImpl* That;
248 That = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawPaletteImpl));
249
250 if (That == NULL)
251 return E_OUTOFMEMORY;
252
253 ZeroMemory(That, sizeof(IDirectDrawPaletteImpl));
254
255 That->lpVtbl = &DirectDrawPalette_Vtable;
256 That->ref = 1;
257 *ppPalette = (LPDIRECTDRAWPALETTE)That;
258
259 return That->lpVtbl->Initialize (*ppPalette, (LPDIRECTDRAW)iface, dwFlags, palent);
260 }
261
262 /**** Stubs ****/
263
264 HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
265 {
266 DX_STUB;
267 }
268
269 HRESULT WINAPI Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
270 LPDIRECTDRAWSURFACE7* dst)
271 {
272 DX_STUB;
273 }
274
275 HRESULT WINAPI Main_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
276 LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback)
277 {
278 DX_STUB;
279 }
280
281 HRESULT WINAPI Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
282 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
283 LPDDENUMSURFACESCALLBACK7 callback)
284 {
285 DX_STUB;
286 }
287
288 HRESULT WINAPI Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
289 {
290 DWORD ret;
291
292 if((ret = Hal_DirectDraw_FlipToGDISurface( iface)) == DD_OK)
293 return ret;
294
295 if((ret = Hel_DirectDraw_FlipToGDISurface( iface)) == DD_OK)
296 return ret;
297
298 return DDERR_NOTINITIALIZED;
299 }
300
301 HRESULT WINAPI Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
302 LPDDCAPS pHELCaps)
303 {
304 DWORD status = DD_FALSE;
305 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
306
307 if (pDriverCaps != NULL)
308 {
309 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
310 status = DD_OK;
311 }
312
313 if (pHELCaps != NULL)
314 {
315 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddHELCaps,sizeof(DDCORECAPS));
316 status = DD_OK;
317 }
318
319 /* Both caps mixed ?? */
320 /* DDCORECAPS ddBothCaps; */
321
322 return status;
323 }
324
325 HRESULT WINAPI Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
326 {
327 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
328
329 if (pDDSD == NULL)
330 {
331 return DD_FALSE;
332 }
333
334 pDDSD->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_REFRESHRATE | DDSD_WIDTH;
335 pDDSD->dwHeight = This->DirectDrawGlobal.vmiData.dwDisplayHeight;
336 pDDSD->dwWidth = This->DirectDrawGlobal.vmiData.dwDisplayWidth;
337
338 /* FIXME Do not use DUMMYUNIONNAME1 some how union lPitch does not see by the compiler
339 but rest of the union are visable. more header problem ???
340 */
341 pDDSD->DUMMYUNIONNAME1.lPitch = This->DirectDrawGlobal.vmiData.lDisplayPitch;
342
343
344 /* have not check where I should get hold of this info yet
345 DWORD dwBackBufferCount;
346 */
347
348 pDDSD->dwRefreshRate = This->DirectDrawGlobal.dwMonitorFrequency;
349
350 /* have not check where I should get hold of this info yet
351 DWORD dwAlphaBitDepth;
352 DWORD dwReserved;
353 LPVOID lpSurface;
354 union
355 {
356 DDCOLORKEY ddckCKDestOverlay;
357 DWORD dwEmptyFaceColor;
358 }
359 DDCOLORKEY ddckCKDestBlt;
360 DDCOLORKEY ddckCKSrcOverlay;
361 DDCOLORKEY ddckCKSrcBlt;
362 */
363
364
365 RtlCopyMemory(&pDDSD->ddpfPixelFormat,&This->DirectDrawGlobal.vmiData.ddpfDisplay,sizeof(DDPIXELFORMAT));
366 RtlCopyMemory(&pDDSD->ddsCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
367
368 /* have not check where I should get hold of this info yet
369 DWORD dwTextureStage;
370 */
371
372 return DD_OK;
373 }
374
375
376 HRESULT WINAPI Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)
377 {
378 DX_STUB;
379 }
380
381 HRESULT WINAPI Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
382 LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
383 {
384 DX_STUB;
385 }
386
387 HRESULT WINAPI Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
388 {
389 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
390
391 if (freq == NULL)
392 {
393 return DD_FALSE;
394 }
395
396 *freq = This->DirectDrawGlobal.dwMonitorFrequency;
397 return DD_OK;
398 }
399
400 HRESULT WINAPI Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
401 {
402 DWORD ret;
403
404 if((ret = Hal_DirectDraw_GetScanLine( iface, lpdwScanLine)) == DD_OK)
405 return ret;
406
407 if((ret = Hel_DirectDraw_GetScanLine( iface, lpdwScanLine)) == DD_OK)
408 return ret;
409
410 return DDERR_NOTINITIALIZED;
411 }
412
413 HRESULT WINAPI Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
414 {
415 DX_STUB;
416 }
417
418 HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
419 {
420 DX_STUB;
421 }
422
423 HRESULT WINAPI Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
424 HANDLE h)
425 {
426 DWORD ret;
427
428 if((ret = Hal_DirectDraw_WaitForVerticalBlank( iface, dwFlags, h)) == DD_OK)
429 return ret;
430
431 if((ret = Hel_DirectDraw_WaitForVerticalBlank( iface, dwFlags, h)) == DD_OK)
432 return ret;
433
434 return DDERR_NOTINITIALIZED;
435 }
436
437 HRESULT WINAPI Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
438 LPDWORD total, LPDWORD free)
439 {
440 DWORD ret;
441
442 if((ret = Hal_DirectDraw_GetAvailableVidMem (iface,ddscaps,total,free)) == DD_OK)
443 return ret;
444
445 if((ret = Hel_DirectDraw_GetAvailableVidMem (iface,ddscaps,total,free)) == DD_OK)
446 return ret;
447
448
449 return DDERR_NOTINITIALIZED;
450
451 }
452
453 HRESULT WINAPI Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
454 LPDIRECTDRAWSURFACE7 *lpDDS)
455 {
456 DX_STUB;
457 }
458
459 HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
460 {
461 DX_STUB;
462 }
463
464 HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
465 {
466 DX_STUB;
467 }
468
469 HRESULT WINAPI Main_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
470 LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
471 {
472 DX_STUB;
473 }
474
475 HRESULT WINAPI Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
476 DWORD dwNumModes, DWORD dwFlags)
477 {
478 DX_STUB;
479 }
480
481 HRESULT WINAPI Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
482 {
483 DX_STUB;
484 }
485
486 IDirectDraw7Vtbl DirectDraw7_Vtable =
487 {
488 Main_DirectDraw_QueryInterface,
489 Main_DirectDraw_AddRef,
490 Main_DirectDraw_Release,
491 Main_DirectDraw_Compact,
492 Main_DirectDraw_CreateClipper,
493 Main_DirectDraw_CreatePalette,
494 Main_DirectDraw_CreateSurface,
495 Main_DirectDraw_DuplicateSurface,
496 Main_DirectDraw_EnumDisplayModes,
497 Main_DirectDraw_EnumSurfaces,
498 Main_DirectDraw_FlipToGDISurface,
499 Main_DirectDraw_GetCaps,
500 Main_DirectDraw_GetDisplayMode,
501 Main_DirectDraw_GetFourCCCodes,
502 Main_DirectDraw_GetGDISurface,
503 Main_DirectDraw_GetMonitorFrequency,
504 Main_DirectDraw_GetScanLine,
505 Main_DirectDraw_GetVerticalBlankStatus,
506 Main_DirectDraw_Initialize,
507 Main_DirectDraw_RestoreDisplayMode,
508 Main_DirectDraw_SetCooperativeLevel,
509 Main_DirectDraw_SetDisplayMode,
510 Main_DirectDraw_WaitForVerticalBlank,
511 Main_DirectDraw_GetAvailableVidMem,
512 Main_DirectDraw_GetSurfaceFromDC,
513 Main_DirectDraw_RestoreAllSurfaces,
514 Main_DirectDraw_TestCooperativeLevel,
515 Main_DirectDraw_GetDeviceIdentifier,
516 Main_DirectDraw_StartModeTest,
517 Main_DirectDraw_EvaluateMode
518 };