1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * PURPOSE: Native DirectDraw implementation 5 * FILE: win32ss/reactx/ntddraw/ddraw.c 6 * PROGRAMER: Magnus olsen (magnus@greatlord.com) 7 * REVISION HISTORY: 8 * 19/1-2006 Magnus Olsen 9 */ 10 11 #include <win32k.h> 12 #include <debug.h> 13 14 PGD_DXDDSTARTUPDXGRAPHICS gpfnStartupDxGraphics = NULL; 15 PGD_DXDDCLEANUPDXGRAPHICS gpfnCleanupDxGraphics = NULL; 16 17 /* export from dxeng.c */ 18 extern DRVFN gaEngFuncs[]; 19 extern ULONG gcEngFuncs; 20 extern EDD_DIRECTDRAW_GLOBAL edd_DdirectDraw_Global; 21 22 23 DRVFN gpDxFuncs[DXG_INDEX_DxDdIoctl + 1]; 24 HANDLE ghDxGraphics = NULL; 25 ULONG gdwDirectDrawContext = 0; 26 27 #define DXDBG 1 28 29 /************************************************************************/ 30 /* DirectX graphic/video driver loading and cleanup starts here */ 31 /************************************************************************/ 32 NTSTATUS 33 APIENTRY 34 DxDdStartupDxGraphics( ULONG ulc1, 35 PDRVENABLEDATA DxEngDrvOld, 36 ULONG ulc2, 37 PDRVENABLEDATA DxgDrvOld, 38 PULONG DirectDrawContext, 39 PEPROCESS Proc) 40 { 41 DRVENABLEDATA DxEngDrv; 42 DRVENABLEDATA DxgDrv; 43 44 NTSTATUS Status = STATUS_PROCEDURE_NOT_FOUND; 45 46 /* FIXME: Setup of gaEngFuncs driver export list 47 * but not in this api, we can add it here tempary until we figout where 48 * no code have been writen for it yet 49 */ 50 51 52 /* FIXME: ReactOS does not loading the dxapi.sys or import functions from it yet */ 53 // DxApiGetVersion() 54 55 /* Loading the kernel interface of DirectX for win32k */ 56 57 DPRINT1("Warning: trying loading xp/2003/windows7/reactos dxg.sys\n"); 58 ghDxGraphics = EngLoadImage(L"\\SystemRoot\\System32\\drivers\\dxg.sys"); 59 if ( ghDxGraphics == NULL) 60 { 61 Status = STATUS_DLL_NOT_FOUND; 62 DPRINT1("Warning: no ReactX or DirectX kernel driver found\n"); 63 } 64 else 65 { 66 /* Import DxDdStartupDxGraphics and DxDdCleanupDxGraphics */ 67 gpfnStartupDxGraphics = EngFindImageProcAddress(ghDxGraphics,"DxDdStartupDxGraphics"); 68 gpfnCleanupDxGraphics = EngFindImageProcAddress(ghDxGraphics,"DxDdCleanupDxGraphics"); 69 70 if ((gpfnStartupDxGraphics) && 71 (gpfnCleanupDxGraphics)) 72 { 73 /* Setup driver data for activate the dx interface */ 74 DxEngDrv.iDriverVersion = DDI_DRIVER_VERSION_NT5_01; 75 DxEngDrv.pdrvfn = gaEngFuncs; 76 DxEngDrv.c = gcEngFuncs; 77 78 Status = gpfnStartupDxGraphics ( sizeof(DRVENABLEDATA), 79 &DxEngDrv, 80 sizeof(DRVENABLEDATA), 81 &DxgDrv, 82 &gdwDirectDrawContext, 83 Proc ); 84 } 85 86 /* Check if we manage loading the data and execute the dxStartupDxGraphics if it is successful */ 87 if (!NT_SUCCESS(Status)) 88 { 89 gpfnStartupDxGraphics = NULL; 90 gpfnCleanupDxGraphics = NULL; 91 if (ghDxGraphics != NULL) 92 { 93 EngUnloadImage( ghDxGraphics); 94 ghDxGraphics = NULL; 95 } 96 DPRINT1("Warning: DirectX graphics interface can not be initialized\n"); 97 } 98 else 99 { 100 /* Sort the drv functions list in index order, this allows us doing, smaller optimize 101 * in API that are redirect to dx.sys 102 */ 103 104 PDRVFN lstDrvFN = DxgDrv.pdrvfn; 105 INT t; 106 for (t=0;t<=DXG_INDEX_DxDdIoctl;t++) 107 { 108 gpDxFuncs[lstDrvFN[t].iFunc].iFunc =lstDrvFN[t].iFunc; 109 gpDxFuncs[lstDrvFN[t].iFunc].pfn =lstDrvFN[t].pfn; 110 } 111 112 DPRINT1("DirectX interface is activated\n"); 113 114 } 115 /* Return the status */ 116 } 117 118 return Status; 119 } 120 121 /************************************************************************/ 122 /* DirectX graphic/video driver loading cleanup ends here */ 123 /************************************************************************/ 124 125 /************************************************************************/ 126 /* NtGdiDdCreateDirectDrawObject */ 127 /************************************************************************/ 128 HANDLE 129 APIENTRY 130 NtGdiDdCreateDirectDrawObject(HDC hdc) 131 { 132 PGD_DDCREATEDIRECTDRAWOBJECT pfnDdCreateDirectDrawObject; 133 134 if (hdc == NULL) 135 { 136 DPRINT1("Warning: hdc is NULL\n"); 137 return 0; 138 } 139 140 /* Get the pfnDdCreateDirectDrawObject after we load the drv */ 141 pfnDdCreateDirectDrawObject = (PGD_DDCREATEDIRECTDRAWOBJECT)gpDxFuncs[DXG_INDEX_DxDdCreateDirectDrawObject].pfn; 142 143 if (pfnDdCreateDirectDrawObject == NULL) 144 { 145 DPRINT1("Warning: no pfnDdCreateDirectDrawObject\n"); 146 return DDHAL_DRIVER_NOTHANDLED; 147 } 148 149 DPRINT1("Calling dxg.sys DdCreateDirectDrawObject\n"); 150 151 return pfnDdCreateDirectDrawObject(hdc); 152 } 153 154 /*++ 155 * @name NtGdiDxgGenericThunk 156 * @implemented 157 * 158 * The function NtGdiDxgGenericThunk redirects DirectX calls to another function. 159 * It redirects to dxg.sys in Windows XP/2003, dxkrnl.sys in Vista and is fully implemented in win32k.sys in Windows 2000 and below 160 * 161 * @param ULONG_PTR ulIndex 162 * The functions we want to redirect 163 * 164 * @param ULONG_PTR ulHandle 165 * Unknown 166 * 167 * @param SIZE_T *pdwSizeOfPtr1 168 * Unknown 169 * 170 * @param PVOID pvPtr1 171 * Unknown 172 * 173 * @param SIZE_T *pdwSizeOfPtr2 174 * Unknown 175 * 176 * @param PVOID pvPtr2 177 * Unknown 178 * 179 * @return 180 * Always returns DDHAL_DRIVER_NOTHANDLED 181 * 182 * @remarks. 183 * dxg.sys NtGdiDxgGenericThunk calls are redirected to dxg.sys 184 * This function is no longer used but is still present in Windows NT 2000/XP/2003. 185 * 186 *--*/ 187 DWORD 188 APIENTRY 189 NtGdiDxgGenericThunk(ULONG_PTR ulIndex, 190 ULONG_PTR ulHandle, 191 SIZE_T *pdwSizeOfPtr1, 192 PVOID pvPtr1, 193 SIZE_T *pdwSizeOfPtr2, 194 PVOID pvPtr2) 195 { 196 PGD_DXGENERICTRUNK pfnDxgGenericThunk = (PGD_DXGENERICTRUNK)gpDxFuncs[DXG_INDEX_DxDxgGenericThunk].pfn; 197 198 if (pfnDxgGenericThunk == NULL) 199 { 200 DPRINT1("Warning: no pfnDxgGenericThunk\n"); 201 return DDHAL_DRIVER_NOTHANDLED; 202 } 203 204 DPRINT1("Calling dxg.sys pfnDxgGenericThunk\n"); 205 return pfnDxgGenericThunk(ulIndex, ulHandle, pdwSizeOfPtr1, pvPtr1, pdwSizeOfPtr2, pvPtr2); 206 } 207 208 /************************************************************************/ 209 /* NtGdiDdGetDriverState */ 210 /************************************************************************/ 211 DWORD 212 APIENTRY 213 NtGdiDdGetDriverState(PDD_GETDRIVERSTATEDATA pdata) 214 { 215 PGD_DDGETDRIVERSTATE pfnDdGetDriverState = (PGD_DDGETDRIVERSTATE)gpDxFuncs[DXG_INDEX_DxDdGetDriverState].pfn; 216 217 if (pfnDdGetDriverState == NULL) 218 { 219 DPRINT1("Warning: no pfnDdGetDriverState\n"); 220 return DDHAL_DRIVER_NOTHANDLED; 221 } 222 223 DPRINT1("Calling dxg.sys DdGetDriverState\n"); 224 return pfnDdGetDriverState(pdata); 225 } 226 227 /************************************************************************/ 228 /* NtGdiDdColorControl */ 229 /************************************************************************/ 230 DWORD 231 APIENTRY 232 NtGdiDdColorControl(HANDLE hSurface, 233 PDD_COLORCONTROLDATA puColorControlData) 234 { 235 PGD_DDCOLORCONTROL pfnDdColorControl = (PGD_DDCOLORCONTROL)gpDxFuncs[DXG_INDEX_DxDdColorControl].pfn; 236 237 if (pfnDdColorControl == NULL) 238 { 239 DPRINT1("Warning: no pfnDdColorControl\n"); 240 return DDHAL_DRIVER_NOTHANDLED; 241 } 242 243 DPRINT1("Calling dxg.sys DdColorControl\n"); 244 return pfnDdColorControl(hSurface,puColorControlData); 245 } 246 247 /************************************************************************/ 248 /* NtGdiDdCreateSurfaceObject */ 249 /************************************************************************/ 250 HANDLE 251 APIENTRY 252 NtGdiDdCreateSurfaceObject(HANDLE hDirectDrawLocal, 253 HANDLE hSurface, 254 PDD_SURFACE_LOCAL puSurfaceLocal, 255 PDD_SURFACE_MORE puSurfaceMore, 256 PDD_SURFACE_GLOBAL puSurfaceGlobal, 257 BOOL bComplete 258 ) 259 { 260 PGD_DXDDCREATESURFACEOBJECT pfnDdCreateSurfaceObject = (PGD_DXDDCREATESURFACEOBJECT)gpDxFuncs[DXG_INDEX_DxDdCreateSurfaceObject].pfn; 261 262 if (pfnDdCreateSurfaceObject == NULL) 263 { 264 DPRINT1("Warning: no pfnDdCreateSurfaceObject\n"); 265 return DDHAL_DRIVER_NOTHANDLED; 266 } 267 268 DPRINT1("Calling dxg.sys pfnDdCreateSurfaceObject\n"); 269 return pfnDdCreateSurfaceObject(hDirectDrawLocal, hSurface, puSurfaceLocal, puSurfaceMore, puSurfaceGlobal, bComplete); 270 } 271 272 /************************************************************************/ 273 /* NtGdiDdDeleteDirectDrawObject */ 274 /************************************************************************/ 275 BOOL 276 APIENTRY 277 NtGdiDdDeleteDirectDrawObject(HANDLE hDirectDrawLocal) 278 { 279 PGD_DXDDDELETEDIRECTDRAWOBJECT pfnDdDeleteDirectDrawObject = (PGD_DXDDDELETEDIRECTDRAWOBJECT)gpDxFuncs[DXG_INDEX_DxDdDeleteDirectDrawObject].pfn; 280 281 if (pfnDdDeleteDirectDrawObject == NULL) 282 { 283 DPRINT1("Warning: no pfnDdDeleteDirectDrawObject\n"); 284 return FALSE; 285 } 286 287 if (hDirectDrawLocal == NULL) 288 { 289 DPRINT1("Warning: hDirectDrawLocal is NULL\n"); 290 return FALSE; 291 } 292 293 DPRINT1("hDirectDrawLocal = %p \n", hDirectDrawLocal); 294 DPRINT1("Calling dxg.sys pfnDdDeleteDirectDrawObject\n"); 295 296 return pfnDdDeleteDirectDrawObject(hDirectDrawLocal); 297 } 298 299 /************************************************************************/ 300 /* NtGdiDdDeleteSurfaceObject */ 301 /************************************************************************/ 302 BOOL 303 APIENTRY 304 NtGdiDdDeleteSurfaceObject(HANDLE hSurface) 305 { 306 PGD_DXDDDELETESURFACEOBJECT pfnDdDeleteSurfaceObject = (PGD_DXDDDELETESURFACEOBJECT)gpDxFuncs[DXG_INDEX_DxDdDeleteSurfaceObject].pfn; 307 308 if (pfnDdDeleteSurfaceObject == NULL) 309 { 310 DPRINT1("Warning: no pfnDdDeleteSurfaceObject\n"); 311 return DDHAL_DRIVER_NOTHANDLED; 312 } 313 /* Try and see if the handle is valid */ 314 315 DPRINT1("Calling dxg.sys DdDeleteSurfaceObject\n"); 316 return pfnDdDeleteSurfaceObject(hSurface); 317 } 318 319 /************************************************************************/ 320 /* NtGdiDdQueryDirectDrawObject */ 321 /************************************************************************/ 322 BOOL 323 APIENTRY 324 NtGdiDdQueryDirectDrawObject(HANDLE hDirectDrawLocal, 325 DD_HALINFO *pHalInfo, 326 DWORD *pCallBackFlags, 327 LPD3DNTHAL_CALLBACKS puD3dCallbacks, 328 LPD3DNTHAL_GLOBALDRIVERDATA puD3dDriverData, 329 PDD_D3DBUFCALLBACKS puD3dBufferCallbacks, 330 LPDDSURFACEDESC puD3dTextureFormats, 331 DWORD *puNumHeaps, 332 VIDEOMEMORY *puvmList, 333 DWORD *puNumFourCC, 334 DWORD *puFourCC) 335 { 336 PGD_DXDDQUERYDIRECTDRAWOBJECT pfnDdQueryDirectDrawObject = (PGD_DXDDQUERYDIRECTDRAWOBJECT)gpDxFuncs[DXG_INDEX_DxDdQueryDirectDrawObject].pfn; 337 338 if (pfnDdQueryDirectDrawObject == NULL) 339 { 340 DPRINT1("Warning: no pfnDdQueryDirectDrawObject\n"); 341 return DDHAL_DRIVER_NOTHANDLED; 342 } 343 344 DPRINT1("Calling dxg.sys pfnDdQueryDirectDrawObject\n"); 345 346 347 return pfnDdQueryDirectDrawObject(hDirectDrawLocal, pHalInfo, pCallBackFlags, puD3dCallbacks, puD3dDriverData, 348 puD3dBufferCallbacks, puD3dTextureFormats, puNumHeaps, puvmList, puNumFourCC, puFourCC); 349 350 } 351 352 353 /************************************************************************/ 354 /* NtGdiDdReenableDirectDrawObject */ 355 /************************************************************************/ 356 BOOL 357 APIENTRY 358 NtGdiDdReenableDirectDrawObject(HANDLE hDirectDrawLocal, 359 BOOL *pubNewMode) 360 { 361 #if DXDBG 362 BOOL status = FALSE; 363 #endif 364 PGD_DXDDREENABLEDIRECTDRAWOBJECT pfnDdReenableDirectDrawObject = (PGD_DXDDREENABLEDIRECTDRAWOBJECT)gpDxFuncs[DXG_INDEX_DxDdReenableDirectDrawObject].pfn; 365 366 if (pfnDdReenableDirectDrawObject == NULL) 367 { 368 DPRINT1("Warning: no pfnDdReenableDirectDrawObject\n"); 369 return DDHAL_DRIVER_NOTHANDLED; 370 } 371 372 DPRINT1("Calling dxg.sys pfnDdReenableDirectDrawObject\n"); 373 374 #if DXDBG 375 status = pfnDdReenableDirectDrawObject(hDirectDrawLocal, pubNewMode); 376 DPRINT1("end Calling dxg.sys pfnDdReenableDirectDrawObject\n"); 377 DPRINT1("return value : 0x%08x\n", status); 378 return status; 379 #else 380 return pfnDdReenableDirectDrawObject(hDirectDrawLocal, pubNewMode); 381 #endif 382 } 383 384 385 /************************************************************************/ 386 /* NtGdiDdGetDriverInfo */ 387 /************************************************************************/ 388 DWORD 389 APIENTRY 390 NtGdiDdGetDriverInfo(HANDLE hDirectDrawLocal, 391 PDD_GETDRIVERINFODATA puGetDriverInfoData) 392 393 { 394 PGD_DXDDGETDRIVERINFO pfnDdGetDriverInfo = (PGD_DXDDGETDRIVERINFO)gpDxFuncs[DXG_INDEX_DxDdGetDriverInfo].pfn; 395 396 if (pfnDdGetDriverInfo == NULL) 397 { 398 DPRINT1("Warning: no pfnDdGetDriverInfo\n"); 399 return DDHAL_DRIVER_NOTHANDLED; 400 } 401 402 DPRINT1("Calling dxg.sys pfnDdGetDriverInfo\n"); 403 return pfnDdGetDriverInfo(hDirectDrawLocal, puGetDriverInfoData); 404 } 405 406 407 /************************************************************************/ 408 /* NtGdiDdGetAvailDriverMemory */ 409 /************************************************************************/ 410 DWORD 411 APIENTRY 412 NtGdiDdGetAvailDriverMemory(HANDLE hDirectDrawLocal, 413 PDD_GETAVAILDRIVERMEMORYDATA puGetAvailDriverMemoryData) 414 { 415 PGD_DXDDGETAVAILDRIVERMEMORY pfnDdGetAvailDriverMemory = (PGD_DXDDGETAVAILDRIVERMEMORY)gpDxFuncs[DXG_INDEX_DxDdGetAvailDriverMemory].pfn; 416 417 if (pfnDdGetAvailDriverMemory == NULL) 418 { 419 DPRINT1("Warning: no pfnDdGetAvailDriverMemory\n"); 420 return DDHAL_DRIVER_NOTHANDLED; 421 } 422 423 DPRINT1("Calling dxg.sys pfnDdGetAvailDriverMemory\n"); 424 return pfnDdGetAvailDriverMemory(hDirectDrawLocal, puGetAvailDriverMemoryData); 425 } 426 427 428 /************************************************************************/ 429 /* NtGdiDdSetExclusiveMode */ 430 /************************************************************************/ 431 432 DWORD 433 APIENTRY 434 NtGdiDdSetExclusiveMode(HANDLE hDirectDraw, 435 PDD_SETEXCLUSIVEMODEDATA puSetExclusiveModeData) 436 { 437 PGD_DXDDSETEXCLUSIVEMODE pfnDdSetExclusiveMode = (PGD_DXDDSETEXCLUSIVEMODE)gpDxFuncs[DXG_INDEX_DxDdSetExclusiveMode].pfn; 438 439 if (pfnDdSetExclusiveMode == NULL) 440 { 441 DPRINT1("Warning: no pfnDdSetExclusiveMode\n"); 442 return DDHAL_DRIVER_NOTHANDLED; 443 } 444 445 DPRINT1("Calling dxg.sys pfnDdSetExclusiveMode\n"); 446 return pfnDdSetExclusiveMode(hDirectDraw, puSetExclusiveModeData); 447 448 } 449 450 451 /************************************************************************/ 452 /* NtGdiDdFlipToGDISurface */ 453 /************************************************************************/ 454 DWORD 455 APIENTRY 456 NtGdiDdFlipToGDISurface(HANDLE hDirectDraw, 457 PDD_FLIPTOGDISURFACEDATA puFlipToGDISurfaceData) 458 { 459 PGD_DXDDFLIPTOGDISURFACE pfnDdFlipToGDISurface = (PGD_DXDDFLIPTOGDISURFACE)gpDxFuncs[DXG_INDEX_DxDdFlipToGDISurface].pfn; 460 461 if (pfnDdFlipToGDISurface == NULL) 462 { 463 DPRINT1("Warning: no pfnDdFlipToGDISurface\n"); 464 return DDHAL_DRIVER_NOTHANDLED; 465 } 466 467 DPRINT1("Calling dxg.sys pfnDdFlipToGDISurface\n"); 468 return pfnDdFlipToGDISurface(hDirectDraw, puFlipToGDISurfaceData); 469 470 } 471 472 /************************************************************************/ 473 /* NtGdiDdGetDC */ 474 /************************************************************************/ 475 HDC 476 APIENTRY 477 NtGdiDdGetDC(HANDLE hSurface, 478 PALETTEENTRY *puColorTable) 479 { 480 PGD_DDGETDC pfnDdGetDC = (PGD_DDGETDC)gpDxFuncs[DXG_INDEX_DxDdGetDC].pfn; 481 482 if (pfnDdGetDC == NULL) 483 { 484 DPRINT1("Warning: no pfnDdGetDC\n"); 485 return DDHAL_DRIVER_NOTHANDLED; 486 } 487 488 DPRINT1("Calling dxg.sys pfnDdGetDC\n"); 489 return pfnDdGetDC(hSurface, puColorTable); 490 } 491 492 /************************************************************************/ 493 /* NtGdiDdGetDxHandle */ 494 /************************************************************************/ 495 HANDLE 496 APIENTRY 497 NtGdiDdGetDxHandle(HANDLE hDirectDraw, 498 HANDLE hSurface, 499 BOOL bRelease) 500 { 501 PGD_DDGETDXHANDLE pfnDdGetDxHandle = (PGD_DDGETDXHANDLE)gpDxFuncs[DXG_INDEX_DxDdGetDxHandle].pfn; 502 503 if (pfnDdGetDxHandle == NULL) 504 { 505 DPRINT1("Warning: no pfnDdGetDxHandle\n"); 506 return DDHAL_DRIVER_NOTHANDLED; 507 } 508 509 DPRINT1("Calling dxg.sys pfnDdGetDxHandle\n"); 510 return pfnDdGetDxHandle(hDirectDraw, hSurface, bRelease); 511 } 512 513 514 /************************************************************************/ 515 /* NtGdiDdReleaseDC */ 516 /************************************************************************/ 517 BOOL 518 APIENTRY 519 NtGdiDdReleaseDC(HANDLE hSurface) 520 { 521 PGD_DDRELEASEDC pfnDdReleaseDC = (PGD_DDRELEASEDC)gpDxFuncs[DXG_INDEX_DxDdReleaseDC].pfn; 522 523 if (pfnDdReleaseDC == NULL) 524 { 525 DPRINT1("Warning: no pfnDdReleaseDC\n"); 526 return DDHAL_DRIVER_NOTHANDLED; 527 } 528 529 DPRINT1("Calling dxg.sys pfnDdReleaseDC\n"); 530 return pfnDdReleaseDC(hSurface); 531 } 532 533 /************************************************************************/ 534 /* NtGdiDdResetVisrgn */ 535 /************************************************************************/ 536 BOOL 537 APIENTRY 538 NtGdiDdResetVisrgn(HANDLE hSurface, 539 HWND hwnd) 540 { 541 542 PGD_DDRESTVISRGN pfnDdResetVisrgn = (PGD_DDRESTVISRGN)gpDxFuncs[DXG_INDEX_DxDdResetVisrgn].pfn; 543 544 if (pfnDdResetVisrgn == NULL) 545 { 546 DPRINT1("Warning: no pfnDdResetVisrgn\n"); 547 return DDHAL_DRIVER_NOTHANDLED; 548 } 549 550 DPRINT1("Calling dxg.sys pfnDdResetVisrgn\n"); 551 return pfnDdResetVisrgn(hSurface, hwnd); 552 } 553 554 /************************************************************************/ 555 /* NtGdiDdSetGammaRamp */ 556 /************************************************************************/ 557 BOOL 558 APIENTRY 559 NtGdiDdSetGammaRamp(HANDLE hDirectDraw, 560 HDC hdc, 561 LPVOID lpGammaRamp) 562 { 563 PGD_DDSETGAMMARAMP pfnDdSetGammaRamp = (PGD_DDSETGAMMARAMP)gpDxFuncs[DXG_INDEX_DxDdSetGammaRamp].pfn; 564 565 if (pfnDdSetGammaRamp == NULL) 566 { 567 DPRINT1("Warning: no pfnDdSetGammaRamp\n"); 568 return DDHAL_DRIVER_NOTHANDLED; 569 } 570 571 DPRINT1("Calling dxg.sys pfnDdSetGammaRamp\n"); 572 return pfnDdSetGammaRamp(hDirectDraw, hdc, lpGammaRamp); 573 } 574