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