[DIRECTX] Improve the FILE header section. Brought to you by Adam Stachowicz. CORE...
[reactos.git] / reactos / dll / directx / ddraw / Ddraw / ddraw_main.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS DirectX
4 * FILE: dll/directx/ddraw/Ddraw/ddraw_main.c
5 * PURPOSE: IDirectDraw7 Implementation
6 * PROGRAMMER: Magnus Olsen, Maarten Bosma
7 *
8 */
9
10 /* TODO
11 * add warper functions for dx 1 - 6
12 * map the DirectDraw4_Vtable, DirectDraw2_Vtable, DirectDraw_Vtable
13 * table to right version of the functions
14 */
15
16
17
18 #include "rosdraw.h"
19
20 #include <string.h>
21
22 LPDDRAWI_DIRECTDRAW_INT
23 internal_directdraw_int_alloc(LPDDRAWI_DIRECTDRAW_INT This)
24 {
25 LPDDRAWI_DIRECTDRAW_INT newThis;
26 DxHeapMemAlloc(newThis, sizeof(DDRAWI_DIRECTDRAW_INT));
27 if (newThis)
28 {
29 newThis->lpLcl = This->lpLcl;
30 newThis->lpLink = This;
31 }
32
33 return newThis;
34 }
35
36 HRESULT WINAPI
37 Main_DirectDraw_QueryInterface (LPDDRAWI_DIRECTDRAW_INT This,
38 REFIID id,
39 LPVOID *obj)
40 {
41 HRESULT retVal = DD_OK;
42
43 DX_WINDBG_trace();
44
45 _SEH2_TRY
46 {
47 /* FIXME
48 the D3D object can be optained from here
49 Direct3D7
50 */
51 if (IsEqualGUID(&IID_IDirectDraw7, id))
52 {
53 if (This->lpVtbl != &DirectDraw7_Vtable)
54 {
55 This = internal_directdraw_int_alloc(This);
56 if (!This)
57 {
58 retVal = DDERR_OUTOFVIDEOMEMORY;
59 _SEH2_LEAVE;
60 }
61 }
62
63 This->lpVtbl = &DirectDraw7_Vtable;
64 *obj = This;
65 Main_DirectDraw_AddRef(This);
66 }
67 else if (IsEqualGUID(&IID_IDirectDraw4, id))
68 {
69 if (This->lpVtbl != &DirectDraw4_Vtable)
70 {
71 This = internal_directdraw_int_alloc(This);
72 if (!This)
73 {
74 retVal = DDERR_OUTOFVIDEOMEMORY;
75 _SEH2_LEAVE;
76 }
77 }
78
79 This->lpVtbl = &DirectDraw4_Vtable;
80 *obj = This;
81 Main_DirectDraw_AddRef(This);
82 }
83
84 else if (IsEqualGUID(&IID_IDirectDraw2, id))
85 {
86 if (This->lpVtbl != &DirectDraw2_Vtable)
87 {
88 This = internal_directdraw_int_alloc(This);
89 if (!This)
90 {
91 retVal = DDERR_OUTOFVIDEOMEMORY;
92 _SEH2_LEAVE;
93 }
94 }
95
96 This->lpVtbl = &DirectDraw2_Vtable;
97 *obj = This;
98 Main_DirectDraw_AddRef(This);
99 }
100 else if (IsEqualGUID(&IID_IDirectDraw, id))
101 {
102 if (This->lpVtbl != &DirectDraw_Vtable)
103 {
104 This = internal_directdraw_int_alloc(This);
105 if (!This)
106 {
107 retVal = DDERR_OUTOFVIDEOMEMORY;
108 _SEH2_LEAVE;
109 }
110 }
111
112 This->lpVtbl = &DirectDraw_Vtable;
113 *obj = This;
114 Main_DirectDraw_AddRef(This);
115 }
116 else
117 {
118 *obj = NULL;
119 DX_STUB_str("E_NOINTERFACE");
120 retVal = E_NOINTERFACE;
121 }
122 }
123 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
124 {
125 }
126 _SEH2_END;
127
128 return retVal;
129 }
130
131 /*++
132 * @name DDraw->AddRef
133 * @implemented
134 *
135 * The function DDraw->AddRef manages all ref counters in the COM object DDraw->
136
137 * @return
138 * Returns the local Ref counter value for the COM object
139 *
140 * @remarks.
141 * none
142 *
143 *--*/
144 ULONG WINAPI
145 Main_DirectDraw_AddRef (LPDDRAWI_DIRECTDRAW_INT This)
146 {
147 ULONG retValue = 0;
148
149 DX_WINDBG_trace();
150
151 /* Lock the thread */
152 AcquireDDThreadLock();
153
154 _SEH2_TRY
155 {
156 /* Increment the internal ref counter */
157 This->dwIntRefCnt++;
158
159 /* Increment the local internal ref counter */
160 This->lpLcl->dwLocalRefCnt++;
161
162 if (This->lpLcl->lpGbl != NULL)
163 {
164 /* Increment the gobal internal ref counter */
165 This->lpLcl->lpGbl->dwRefCnt++;
166 }
167 }
168 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
169 {
170 }
171 _SEH2_END;
172
173 _SEH2_TRY
174 {
175 retValue = This->dwIntRefCnt;
176 }
177 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
178 {
179 retValue = 0;
180 }
181 _SEH2_END;
182
183 /* Release the thread lock */
184 ReleaseDDThreadLock();
185
186 /* Return the local Ref counter */
187 return retValue;
188 }
189
190
191
192
193 ULONG WINAPI
194 Main_DirectDraw_Release (LPDDRAWI_DIRECTDRAW_INT This)
195 {
196 ULONG Counter = 0;
197
198 DX_WINDBG_trace();
199
200 /* Lock the thread */
201 AcquireDDThreadLock();
202
203 _SEH2_TRY
204 {
205 if (This!=NULL)
206 {
207 This->lpLcl->dwLocalRefCnt--;
208 This->dwIntRefCnt--;
209
210 if (This->lpLcl->lpGbl != NULL)
211 {
212 This->lpLcl->lpGbl->dwRefCnt--;
213 }
214
215 if ( This->lpLcl->lpGbl->dwRefCnt == 0)
216 {
217 // set resoltion back to the one in registry
218 /*if(This->cooperative_level & DDSCL_EXCLUSIVE)
219 {
220 ChangeDisplaySettings(NULL, 0);
221 }*/
222
223 Cleanup(This);
224 }
225
226 /* FIXME cleanup being not call why ?? */
227 Counter = This->dwIntRefCnt;
228 }
229 else
230 {
231 Counter = This->dwIntRefCnt;
232 }
233 }
234 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
235 {
236 }
237 _SEH2_END;
238
239 /* Release the thread lock */
240 ReleaseDDThreadLock();
241
242 return Counter;
243 }
244
245
246 HRESULT WINAPI
247 Main_DirectDraw_Initialize (LPDDRAWI_DIRECTDRAW_INT This, LPGUID lpGUID)
248 {
249 return DDERR_ALREADYINITIALIZED;
250 }
251
252
253 /*++
254 * @name DDraw->Compact
255 * @implemented
256 *
257 * In exlusive mode the function DDraw->Compact returns DERR_NOEXCLUSIVEMODE, otherwise it returns DD_OK
258 *
259 * @return
260 * Returns only error code DD_OK or DERR_NOEXCLUSIVEMODE
261 *
262 * @remarks.
263 * Microsoft says Compact is not implemented in ddraw.dll, but it returns DDERR_NOEXCLUSIVEMODE or DD_OK
264 *
265 *--*/
266 HRESULT WINAPI
267 Main_DirectDraw_Compact(LPDDRAWI_DIRECTDRAW_INT This)
268 {
269 HRESULT retVal = DD_OK;
270
271 DX_WINDBG_trace();
272
273 /* Lock the thread */
274 AcquireDDThreadLock();
275
276 _SEH2_TRY
277 {
278 /* Check if Exclusive mode has been activated */
279 if (This->lpLcl->lpGbl->lpExclusiveOwner != This->lpLcl)
280 {
281 retVal = DDERR_NOEXCLUSIVEMODE;
282 }
283 }
284 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
285 {
286 }
287 _SEH2_END;
288
289 /* Release the thread lock */
290 ReleaseDDThreadLock();
291
292 return retVal;
293 }
294
295 HRESULT WINAPI
296 Main_DirectDraw_GetAvailableVidMem(LPDDRAWI_DIRECTDRAW_INT This, LPDDSCAPS ddscaps, LPDWORD dwTotal, LPDWORD dwFree)
297 {
298 DDSCAPS2 myddscaps;
299 HRESULT retValue = DD_OK;
300
301 ZeroMemory(&myddscaps, sizeof(DDSCAPS2));
302
303 _SEH2_TRY
304 {
305 myddscaps.dwCaps = ddscaps->dwCaps;
306 retValue = Main_DirectDraw_GetAvailableVidMem4(This, &myddscaps, dwTotal, dwFree);
307 }
308 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
309 {
310 retValue = DDERR_INVALIDPARAMS;
311 }
312 _SEH2_END;
313
314 return retValue;
315 }
316
317 HRESULT WINAPI
318 Main_DirectDraw_GetAvailableVidMem4(LPDDRAWI_DIRECTDRAW_INT This, LPDDSCAPS2 ddscaps,
319 LPDWORD dwTotal, LPDWORD dwFree)
320 {
321 HRESULT retVal = DD_OK;
322 DDHAL_GETAVAILDRIVERMEMORYDATA memdata;
323
324 DX_WINDBG_trace();
325
326 _SEH2_TRY
327 {
328 // There is no HEL implentation of this api
329 if (!(This->lpLcl->lpDDCB->HALDDMiscellaneous.dwFlags & DDHAL_MISCCB32_GETAVAILDRIVERMEMORY) ||
330 (This->lpLcl->lpGbl->dwFlags & DDRAWI_NOHARDWARE) )
331 {
332 retVal = DDERR_NODIRECTDRAWHW;
333 }
334 else
335 {
336 if ((!dwTotal && !dwFree) || !ddscaps)
337 {
338 retVal = DDERR_INVALIDPARAMS;
339 _SEH2_LEAVE;
340 }
341
342 if ( ddscaps->dwCaps & (DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
343 DDSCAPS_FRONTBUFFER | DDSCAPS_PALETTE | DDSCAPS_SYSTEMMEMORY |
344 DDSCAPS_VISIBLE | DDSCAPS_WRITEONLY | DDSCAPS_OWNDC))
345 {
346 retVal = DDERR_INVALIDPARAMS;
347 _SEH2_LEAVE;
348 }
349
350
351 /* ddscaps->dwCaps2 & 0x01
352 this flag is outdate and are
353 set to 0 in ms dxsdk the name of
354 this flag is DDSCAPS2_HARDWAREDEINTERLACE
355 */
356
357 if ( ddscaps->dwCaps2 & 0x01)
358 {
359 retVal = DDERR_INVALIDCAPS;
360 _SEH2_LEAVE;
361 }
362
363 if ( ddscaps->dwCaps3 & ~( DDSCAPS3_MULTISAMPLE_QUALITY_MASK | DDSCAPS3_MULTISAMPLE_MASK |
364 DDSCAPS3_RESERVED1 | DDSCAPS3_RESERVED2 |
365 DDSCAPS3_LIGHTWEIGHTMIPMAP | DDSCAPS3_AUTOGENMIPMAP |
366 DDSCAPS3_DMAP))
367 {
368 retVal = DDERR_INVALIDCAPS;
369 _SEH2_LEAVE;
370 }
371
372 if ( ddscaps->dwCaps4)
373 {
374 retVal = DDERR_INVALIDCAPS;
375 _SEH2_LEAVE;
376 }
377
378 ZeroMemory(&memdata, sizeof(DDHAL_GETAVAILDRIVERMEMORYDATA));
379 memdata.lpDD = This->lpLcl->lpGbl;
380 memdata.ddRVal = DDERR_INVALIDPARAMS;
381
382 memdata.ddsCapsEx.dwCaps2 = ddscaps->dwCaps2;
383 memdata.ddsCapsEx.dwCaps3 = ddscaps->dwCaps3;
384
385 This->lpLcl->lpGbl->hDD = This->lpLcl->hDD;
386
387 if (This->lpLcl->lpDDCB->HALDDMiscellaneous.GetAvailDriverMemory(&memdata) == DDHAL_DRIVER_NOTHANDLED)
388 {
389 retVal = DDERR_NODIRECTDRAWHW;
390
391 if (dwTotal)
392 *dwTotal = 0;
393
394 if (dwFree)
395 *dwFree = 0;
396 }
397 else
398 {
399 if (dwTotal)
400 *dwTotal = memdata.dwTotal;
401
402 if (dwFree)
403 *dwFree = memdata.dwFree;
404
405 retVal = memdata.ddRVal;
406 }
407 }
408 }
409 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
410 {
411 }
412 _SEH2_END;
413
414 return retVal;
415 }
416
417 HRESULT WINAPI
418 Main_DirectDraw_GetFourCCCodes(LPDDRAWI_DIRECTDRAW_INT This, LPDWORD lpNumCodes, LPDWORD lpCodes)
419 {
420 HRESULT retVal = DD_OK;
421
422 DX_WINDBG_trace();
423
424
425 // EnterCriticalSection(&ddcs);
426
427 _SEH2_TRY
428 {
429 if(IsBadWritePtr(lpNumCodes,sizeof(LPDWORD)))
430 {
431 retVal = DDERR_INVALIDPARAMS;
432 }
433 else
434 {
435 if(!(IsBadWritePtr(lpNumCodes,sizeof(LPDWORD))))
436 {
437 DWORD size;
438
439 if (*lpNumCodes > This->lpLcl->lpGbl->dwNumFourCC)
440 {
441 *lpNumCodes = This->lpLcl->lpGbl->dwNumFourCC;
442 }
443
444 size = *lpNumCodes * sizeof(DWORD);
445
446 if(!IsBadWritePtr(lpCodes, size ))
447 {
448 memcpy(lpCodes, This->lpLcl->lpGbl->lpdwFourCC, size );
449 }
450 else
451 {
452 *lpNumCodes = This->lpLcl->lpGbl->dwNumFourCC;
453 }
454 }
455 }
456 }
457 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
458 {
459 }
460 _SEH2_END;
461
462 //LeaveCriticalSection(&ddcs);
463 return retVal;
464 }
465
466
467 /*
468 * We can optain the version of the directdraw object by compare the
469 * vtl table pointer from iface we do not need pass which version
470 * we whant to use
471 *
472 * Main_DirectDraw_CreateSurface is dead at moment we do only support
473 * directdraw 7 at moment
474 */
475
476 /* For DirectDraw 1 - 3 */
477 HRESULT WINAPI
478 Main_DirectDraw_CreateSurface (LPDDRAWI_DIRECTDRAW_INT This, LPDDSURFACEDESC pDDSD,
479 LPDDRAWI_DDRAWSURFACE_INT *ppSurf, IUnknown *pUnkOuter)
480 {
481 HRESULT ret = DDERR_GENERIC;
482 DDSURFACEDESC2 dd_desc_v2;
483
484 DX_WINDBG_trace();
485
486 EnterCriticalSection(&ddcs);
487 *ppSurf = NULL;
488
489 _SEH2_TRY
490 {
491 if (pDDSD->dwSize == sizeof(DDSURFACEDESC))
492 {
493 CopyDDSurfDescToDDSurfDesc2(&dd_desc_v2, (LPDDSURFACEDESC)pDDSD);
494 ret = Internal_CreateSurface(This,
495 &dd_desc_v2,
496 ppSurf,
497 pUnkOuter);
498 }
499 else
500 {
501 ret = DDERR_INVALIDPARAMS;
502 }
503 }
504 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
505 {
506 ret = DDERR_INVALIDPARAMS;
507 }
508 _SEH2_END;
509 LeaveCriticalSection(&ddcs);
510 return ret;
511 }
512
513
514 /* For DirectDraw 4 - 7 */
515 HRESULT WINAPI
516 Main_DirectDraw_CreateSurface4(LPDDRAWI_DIRECTDRAW_INT This, LPDDSURFACEDESC2 pDDSD,
517 LPDDRAWI_DDRAWSURFACE_INT *ppSurf, IUnknown *pUnkOuter)
518 {
519 HRESULT ret = DD_OK;
520 DX_WINDBG_trace();
521
522 EnterCriticalSection(&ddcs);
523 *ppSurf = NULL;
524
525 _SEH2_TRY
526 {
527 ret = Internal_CreateSurface(This, pDDSD, ppSurf, pUnkOuter);
528 }
529 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
530 {
531 ret = DDERR_INVALIDPARAMS;
532 }
533 _SEH2_END;
534
535 if(*ppSurf != NULL)
536 Main_DirectDraw_AddRef(This);
537
538 LeaveCriticalSection(&ddcs);
539 return ret;
540 }
541
542 /* 5 of 31 DirectDraw7_Vtable api are working simluare to windows */
543 /* 8 of 31 DirectDraw7_Vtable api are under devloping / testing */
544
545 HRESULT WINAPI Main_DirectDraw_CreatePalette(LPDDRAWI_DIRECTDRAW_INT This, DWORD dwFlags,
546 LPPALETTEENTRY palent, LPDIRECTDRAWPALETTE* ppPalette, LPUNKNOWN pUnkOuter)
547 {
548 HRESULT ret = DD_OK;
549 DX_WINDBG_trace();
550
551 EnterCriticalSection(&ddcs);
552 *ppPalette = NULL;
553
554 _SEH2_TRY
555 {
556 ret = Internal_CreatePalette(This, dwFlags, palent, ppPalette, pUnkOuter);
557 }
558 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
559 {
560 ret = DDERR_INVALIDPARAMS;
561 }
562 _SEH2_END;
563
564 //Versions 7 and 4 are addref'ed
565 if((This->lpVtbl == &DirectDraw7_Vtable || This->lpVtbl == &DirectDraw4_Vtable) && *ppPalette != NULL)
566 Main_DirectDraw_AddRef(This) ;
567
568 LeaveCriticalSection(&ddcs);
569 return ret;
570 }
571
572
573
574
575
576
577