filling in bit more info to DDRAW_GLOBAL struct in halinistate.
[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 HRESULT WINAPI Main_DirectDraw_CreateSurface (LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
129 LPDIRECTDRAWSURFACE7 *ppSurf, IUnknown *pUnkOuter)
130 {
131 if (pUnkOuter!=NULL)
132 return DDERR_INVALIDPARAMS;
133
134 if(sizeof(DDSURFACEDESC2)!=pDDSD->dwSize)
135 return DDERR_UNSUPPORTED;
136
137 // the nasty com stuff
138 IDirectDrawSurfaceImpl* That;
139
140 That = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
141
142 if (That == NULL)
143 return E_OUTOFMEMORY;
144
145 That->lpVtbl = &DirectDrawSurface7_Vtable;
146 That->lpVtbl_v3 = &DDRAW_IDDS3_Thunk_VTable;
147
148 That->ref = 1;
149 *ppSurf = (LPDIRECTDRAWSURFACE7)That;
150
151 // the real surface object creation
152 return That->lpVtbl->Initialize (*ppSurf, (LPDIRECTDRAW)iface, pDDSD);
153 }
154
155 ULONG WINAPI Main_DirectDraw_AddRef (LPDIRECTDRAW7 iface)
156 {
157 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
158 ULONG ref = InterlockedIncrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
159
160 return ref;
161 }
162
163 ULONG WINAPI Main_DirectDraw_Release (LPDIRECTDRAW7 iface)
164 {
165 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
166 ULONG ref = InterlockedDecrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
167
168 if (ref == 0)
169 {
170 // set resoltion back to the one in registry
171 if(This->cooperative_level & DDSCL_EXCLUSIVE)
172 ChangeDisplaySettings(NULL, 0);
173
174 HeapFree(GetProcessHeap(), 0, This);
175 }
176
177 return ref;
178 }
179
180 HRESULT WINAPI Main_DirectDraw_QueryInterface (
181 LPDIRECTDRAW7 iface, REFIID id, LPVOID *obj )
182 {
183 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
184
185 if (IsEqualGUID(&IID_IDirectDraw7, id))
186 {
187 *obj = &This->lpVtbl;
188 }
189 else if (IsEqualGUID(&IID_IDirectDraw, id))
190 {
191 *obj = &This->lpVtbl_v1;
192 }
193 else if (IsEqualGUID(&IID_IDirectDraw2, id))
194 {
195 *obj = &This->lpVtbl_v2;
196 }
197 else if (IsEqualGUID(&IID_IDirectDraw4, id))
198 {
199 *obj = &This->lpVtbl_v4;
200 }
201 else
202 {
203 *obj = NULL;
204 return E_NOINTERFACE;
205 }
206
207 Main_DirectDraw_AddRef(iface);
208 return S_OK;
209 }
210
211 /**** Stubs ****/
212
213 HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
214 {
215 DX_STUB;
216 }
217
218 HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
219 LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)
220 {
221 DX_STUB;
222 }
223 HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
224 LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE* ppPalette,LPUNKNOWN pUnknown)
225 {
226 DX_STUB;
227 }
228
229 HRESULT WINAPI Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
230 LPDIRECTDRAWSURFACE7* dst)
231 {
232 DX_STUB;
233 }
234
235 HRESULT WINAPI Main_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
236 LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback)
237 {
238 DX_STUB;
239 }
240
241 HRESULT WINAPI Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
242 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
243 LPDDENUMSURFACESCALLBACK7 callback)
244 {
245 DX_STUB;
246 }
247
248 HRESULT WINAPI Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
249 {
250 DX_STUB;
251 }
252
253 HRESULT WINAPI Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
254 LPDDCAPS pHELCaps)
255 {
256 DWORD status = DD_FALSE;
257 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
258
259 if (pDriverCaps != NULL)
260 {
261 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
262 status = DD_OK;
263 }
264
265 if (pHELCaps != NULL)
266 {
267 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddHELCaps,sizeof(DDCORECAPS));
268 status = DD_OK;
269 }
270
271 /* Both caps mixed ?? */
272 /* DDCORECAPS ddBothCaps; */
273
274 return status;
275 }
276
277 HRESULT WINAPI Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
278 {
279 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
280
281 if (pDDSD == NULL)
282 {
283 return DD_FALSE;
284 }
285
286 pDDSD->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_REFRESHRATE | DDSD_WIDTH;
287 pDDSD->dwHeight = This->DirectDrawGlobal.vmiData.dwDisplayHeight;
288 pDDSD->dwWidth = This->DirectDrawGlobal.vmiData.dwDisplayWidth;
289
290 /* FIXME Do not use DUMMYUNIONNAME1 some how union lPitch does not see by the compiler
291 but rest of the union are visable. more header problem ???
292 */
293 pDDSD->DUMMYUNIONNAME1.lPitch = This->DirectDrawGlobal.vmiData.lDisplayPitch;
294
295
296 /* have not check where I should get hold of this info yet
297 DWORD dwBackBufferCount;
298 */
299
300 pDDSD->dwRefreshRate = This->DirectDrawGlobal.dwMonitorFrequency;
301
302 /* have not check where I should get hold of this info yet
303 DWORD dwAlphaBitDepth;
304 DWORD dwReserved;
305 LPVOID lpSurface;
306 union
307 {
308 DDCOLORKEY ddckCKDestOverlay;
309 DWORD dwEmptyFaceColor;
310 }
311 DDCOLORKEY ddckCKDestBlt;
312 DDCOLORKEY ddckCKSrcOverlay;
313 DDCOLORKEY ddckCKSrcBlt;
314 */
315
316 RtlCopyMemory(&pDDSD->ddpfPixelFormat,&This->DirectDrawGlobal.vmiData.ddpfDisplay,sizeof(DDPIXELFORMAT));
317 RtlCopyMemory(&pDDSD->ddsCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
318
319 /* have not check where I should get hold of this info yet
320 DWORD dwTextureStage;
321 */
322
323 return DD_OK;
324 }
325
326
327 HRESULT WINAPI Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)
328 {
329 DX_STUB;
330 }
331
332 HRESULT WINAPI Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
333 LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
334 {
335 DX_STUB;
336 }
337
338 HRESULT WINAPI Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
339 {
340 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
341
342 if (freq == NULL)
343 {
344 return DD_FALSE;
345 }
346
347 *freq = This->DirectDrawGlobal.dwMonitorFrequency;
348 return DD_OK;
349 }
350
351 HRESULT WINAPI Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
352 {
353 DX_STUB;
354 }
355
356 HRESULT WINAPI Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
357 {
358 DX_STUB;
359 }
360
361 HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
362 {
363 DX_STUB;
364 }
365
366 HRESULT WINAPI Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
367 HANDLE h)
368 {
369
370 DX_STUB;
371 }
372
373 HRESULT WINAPI Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
374 LPDWORD total, LPDWORD free)
375 {
376
377 DX_STUB;
378 }
379
380 HRESULT WINAPI Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
381 LPDIRECTDRAWSURFACE7 *lpDDS)
382 {
383 DX_STUB;
384 }
385
386 HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
387 {
388 DX_STUB;
389 }
390
391 HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
392 {
393 DX_STUB;
394 }
395
396 HRESULT WINAPI Main_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
397 LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
398 {
399 DX_STUB;
400 }
401
402 HRESULT WINAPI Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
403 DWORD dwNumModes, DWORD dwFlags)
404 {
405 DX_STUB;
406 }
407
408 HRESULT WINAPI Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
409 {
410 DX_STUB;
411 }
412
413 IDirectDraw7Vtbl DirectDraw7_Vtable =
414 {
415 Main_DirectDraw_QueryInterface,
416 Main_DirectDraw_AddRef,
417 Main_DirectDraw_Release,
418 Main_DirectDraw_Compact,
419 Main_DirectDraw_CreateClipper,
420 Main_DirectDraw_CreatePalette,
421 Main_DirectDraw_CreateSurface,
422 Main_DirectDraw_DuplicateSurface,
423 Main_DirectDraw_EnumDisplayModes,
424 Main_DirectDraw_EnumSurfaces,
425 Main_DirectDraw_FlipToGDISurface,
426 Main_DirectDraw_GetCaps,
427 Main_DirectDraw_GetDisplayMode,
428 Main_DirectDraw_GetFourCCCodes,
429 Main_DirectDraw_GetGDISurface,
430 Main_DirectDraw_GetMonitorFrequency,
431 Main_DirectDraw_GetScanLine,
432 Main_DirectDraw_GetVerticalBlankStatus,
433 Main_DirectDraw_Initialize,
434 Main_DirectDraw_RestoreDisplayMode,
435 Main_DirectDraw_SetCooperativeLevel,
436 Main_DirectDraw_SetDisplayMode,
437 Main_DirectDraw_WaitForVerticalBlank,
438 Main_DirectDraw_GetAvailableVidMem,
439 Main_DirectDraw_GetSurfaceFromDC,
440 Main_DirectDraw_RestoreAllSurfaces,
441 Main_DirectDraw_TestCooperativeLevel,
442 Main_DirectDraw_GetDeviceIdentifier,
443 Main_DirectDraw_StartModeTest,
444 Main_DirectDraw_EvaluateMode
445 };