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 obtained 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 global 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 resolution 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 exclusive 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 implementation 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 obtain 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 similar 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 578