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