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