0649be77876750fd5361de4ea2a93a74bd1fe7b2
[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: DirectDraw 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 if((ret = Hel_DirectDraw_SetCooperativeLevel (iface)) != DD_OK)
75 return ret;
76
77 if((ret = Hal_DirectDraw_SetCooperativeLevel (iface)) != DD_OK)
78 return ret;
79
80 return DD_OK;
81 }
82
83 HRESULT WINAPI Main_DirectDraw_SetDisplayMode (LPDIRECTDRAW7 iface, DWORD dwWidth, DWORD dwHeight,
84 DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags)
85 {
86 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
87
88 // this only for exclusive mode
89 if(!(This->cooperative_level & DDSCL_EXCLUSIVE))
90 return DDERR_NOEXCLUSIVEMODE;
91
92 // change the resolution using normal WinAPI function
93 DEVMODE mode;
94 mode.dmSize = sizeof(mode);
95 mode.dmPelsWidth = dwWidth;
96 mode.dmPelsHeight = dwHeight;
97 mode.dmBitsPerPel = dwBPP;
98 mode.dmDisplayFrequency = dwRefreshRate;
99 mode.dmFields = 0;
100
101 if(dwWidth)
102 mode.dmFields |= DM_PELSWIDTH;
103 if(dwHeight)
104 mode.dmFields |= DM_PELSHEIGHT;
105 if(dwBPP)
106 mode.dmFields |= DM_BITSPERPEL;
107 if(dwRefreshRate)
108 mode.dmFields |= DM_DISPLAYFREQUENCY;
109
110 if (ChangeDisplaySettings(&mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
111 return DDERR_UNSUPPORTEDMODE;
112
113 // TODO: reactivate ddraw object, maximize window, set it in foreground
114 // and set excluive mode (if implemented by the driver)
115
116 if(dwWidth)
117 This->Height = dwWidth;
118 if(dwHeight)
119 This->Width = dwHeight;
120 if(dwBPP)
121 This->Bpp = dwBPP;
122
123 return DD_OK;
124 }
125
126 HRESULT WINAPI Main_DirectDraw_CreateSurface (LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD,
127 LPDIRECTDRAWSURFACE7 *ppSurf, IUnknown *pUnkOuter)
128 {
129 if (pUnkOuter!=NULL)
130 return DDERR_INVALIDPARAMS;
131
132 if(sizeof(DDSURFACEDESC2)!=pDDSD->dwSize)
133 return DDERR_UNSUPPORTED;
134
135 // the nasty com stuff
136 IDirectDrawSurfaceImpl* That;
137
138 That = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
139
140 if (That == NULL)
141 return E_OUTOFMEMORY;
142
143 That->lpVtbl = &DDrawSurface_VTable;
144 That->ref = 1;
145 *ppSurf = (LPDIRECTDRAWSURFACE7)That;
146
147 // the real surface object creation
148 return That->lpVtbl->Initialize (*ppSurf, (LPDIRECTDRAW)iface, pDDSD);
149 }
150
151 ULONG WINAPI Main_DirectDraw_AddRef (LPDIRECTDRAW7 iface)
152 {
153 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
154 ULONG ref = InterlockedIncrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
155
156 return ref;
157 }
158
159 ULONG WINAPI Main_DirectDraw_Release (LPDIRECTDRAW7 iface)
160 {
161 IDirectDrawImpl* This = (IDirectDrawImpl*)iface;
162 ULONG ref = InterlockedDecrement((PLONG)&This->DirectDrawGlobal.dwRefCnt);
163
164 if (ref == 0)
165 {
166 // set resoltion back to the one in registry
167 if(This->cooperative_level & DDSCL_EXCLUSIVE)
168 ChangeDisplaySettings(NULL, 0);
169
170 HeapFree(GetProcessHeap(), 0, This);
171 }
172
173 return ref;
174 }
175
176 /**** Stubs ****/
177
178 HRESULT WINAPI Main_DirectDraw_QueryInterface (LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj)
179 {
180 DX_STUB;
181 }
182
183 HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface)
184 {
185 DX_STUB;
186 }
187
188 HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags,
189 LPDIRECTDRAWCLIPPER *ppClipper, IUnknown *pUnkOuter)
190 {
191 DX_STUB;
192 }
193 HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,
194 LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE* ppPalette,LPUNKNOWN pUnknown)
195 {
196 DX_STUB;
197 }
198
199 HRESULT WINAPI Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src,
200 LPDIRECTDRAWSURFACE7* dst)
201 {
202 DX_STUB;
203 }
204
205 HRESULT WINAPI Main_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags,
206 LPDDSURFACEDESC2 pDDSD, LPVOID context, LPDDENUMMODESCALLBACK2 callback)
207 {
208 DX_STUB;
209 }
210
211 HRESULT WINAPI Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags,
212 LPDDSURFACEDESC2 lpDDSD2, LPVOID context,
213 LPDDENUMSURFACESCALLBACK7 callback)
214 {
215 DX_STUB;
216 }
217
218 HRESULT WINAPI Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface)
219 {
220 DX_STUB;
221 }
222
223 HRESULT WINAPI Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps,
224 LPDDCAPS pHELCaps)
225 {
226 DWORD status = DD_FALSE;
227 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
228
229 if (pDriverCaps != NULL)
230 {
231 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
232 status = DD_OK;
233 }
234
235 if (pHELCaps != NULL)
236 {
237 RtlCopyMemory(pDriverCaps,&This->DirectDrawGlobal.ddHELCaps,sizeof(DDCORECAPS));
238 status = DD_OK;
239 }
240
241 /* Both caps mixed ?? */
242 /* DDCORECAPS ddBothCaps; */
243
244 return status;
245 }
246
247 HRESULT WINAPI Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD)
248 {
249 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
250
251 if (pDDSD == NULL)
252 {
253 return DD_FALSE;
254 }
255
256 pDDSD->dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_REFRESHRATE | DDSD_WIDTH;
257 pDDSD->dwHeight = This->DirectDrawGlobal.vmiData.dwDisplayHeight;
258 pDDSD->dwWidth = This->DirectDrawGlobal.vmiData.dwDisplayWidth;
259
260 /* FIXME Do not use DUMMYUNIONNAME1 some how union lPitch does not see by the compiler
261 but rest of the union are visable. more header problem ???
262 */
263 pDDSD->DUMMYUNIONNAME1.lPitch = This->DirectDrawGlobal.vmiData.lDisplayPitch;
264
265
266 /* have not check where I should get hold of this info yet
267 DWORD dwBackBufferCount;
268 */
269
270 pDDSD->dwRefreshRate = This->DirectDrawGlobal.dwMonitorFrequency;
271
272 /* have not check where I should get hold of this info yet
273 DWORD dwAlphaBitDepth;
274 DWORD dwReserved;
275 LPVOID lpSurface;
276 union
277 {
278 DDCOLORKEY ddckCKDestOverlay;
279 DWORD dwEmptyFaceColor;
280 }
281 DDCOLORKEY ddckCKDestBlt;
282 DDCOLORKEY ddckCKSrcOverlay;
283 DDCOLORKEY ddckCKSrcBlt;
284 */
285
286 RtlCopyMemory(&pDDSD->ddpfPixelFormat,&This->DirectDrawGlobal.vmiData.ddpfDisplay,sizeof(DDPIXELFORMAT));
287 RtlCopyMemory(&pDDSD->ddsCaps,&This->DirectDrawGlobal.ddCaps,sizeof(DDCORECAPS));
288
289 /* have not check where I should get hold of this info yet
290 DWORD dwTextureStage;
291 */
292
293 return DD_OK;
294 }
295
296
297 HRESULT WINAPI Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, LPDWORD pCodes)
298 {
299 DX_STUB;
300 }
301
302 HRESULT WINAPI Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface,
303 LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface)
304 {
305 DX_STUB;
306 }
307
308 HRESULT WINAPI Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq)
309 {
310 IDirectDrawImpl *This = (IDirectDrawImpl *)iface;
311
312 if (freq == NULL)
313 {
314 return DD_FALSE;
315 }
316
317 *freq = This->DirectDrawGlobal.dwMonitorFrequency;
318 return DD_OK;
319 }
320
321 HRESULT WINAPI Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine)
322 {
323 DX_STUB;
324 }
325
326 HRESULT WINAPI Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status)
327 {
328 DX_STUB;
329 }
330
331 HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface)
332 {
333 DX_STUB;
334 }
335
336 HRESULT WINAPI Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags,
337 HANDLE h)
338 {
339
340 DX_STUB;
341 }
342
343 HRESULT WINAPI Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps,
344 LPDWORD total, LPDWORD free)
345 {
346
347 DX_STUB;
348 }
349
350 HRESULT WINAPI Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc,
351 LPDIRECTDRAWSURFACE7 *lpDDS)
352 {
353 DX_STUB;
354 }
355
356 HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface)
357 {
358 DX_STUB;
359 }
360
361 HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface)
362 {
363 DX_STUB;
364 }
365
366 HRESULT WINAPI Main_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface,
367 LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags)
368 {
369 DX_STUB;
370 }
371
372 HRESULT WINAPI Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes,
373 DWORD dwNumModes, DWORD dwFlags)
374 {
375 DX_STUB;
376 }
377
378 HRESULT WINAPI Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b)
379 {
380 DX_STUB;
381 }
382
383 IDirectDraw7Vtbl DirectDraw_VTable =
384 {
385 Main_DirectDraw_QueryInterface,
386 Main_DirectDraw_AddRef,
387 Main_DirectDraw_Release,
388 Main_DirectDraw_Compact,
389 Main_DirectDraw_CreateClipper,
390 Main_DirectDraw_CreatePalette,
391 Main_DirectDraw_CreateSurface,
392 Main_DirectDraw_DuplicateSurface,
393 Main_DirectDraw_EnumDisplayModes,
394 Main_DirectDraw_EnumSurfaces,
395 Main_DirectDraw_FlipToGDISurface,
396 Main_DirectDraw_GetCaps,
397 Main_DirectDraw_GetDisplayMode,
398 Main_DirectDraw_GetFourCCCodes,
399 Main_DirectDraw_GetGDISurface,
400 Main_DirectDraw_GetMonitorFrequency,
401 Main_DirectDraw_GetScanLine,
402 Main_DirectDraw_GetVerticalBlankStatus,
403 Main_DirectDraw_Initialize,
404 Main_DirectDraw_RestoreDisplayMode,
405 Main_DirectDraw_SetCooperativeLevel,
406 Main_DirectDraw_SetDisplayMode,
407 Main_DirectDraw_WaitForVerticalBlank,
408 Main_DirectDraw_GetAvailableVidMem,
409 Main_DirectDraw_GetSurfaceFromDC,
410 Main_DirectDraw_RestoreAllSurfaces,
411 Main_DirectDraw_TestCooperativeLevel,
412 Main_DirectDraw_GetDeviceIdentifier,
413 Main_DirectDraw_StartModeTest,
414 Main_DirectDraw_EvaluateMode
415 };