|
|
//==========================================================================;
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1992 - 1996 Microsoft Corporation. All Rights Reserved.
//
//==========================================================================;
#include "strmini.h"
#include "ksmedia.h"
#include "ddkmapi.h"
#include "capmain.h"
#include "capdebug.h"
#define _NO_COM
#include "ddkernel.h"
#define DD_OK 0
// The following should be defined in ddkmapi.h, but for some reason are not!
#ifndef booboo // DDKERNELCAPS_SKIPFIELDS
/*
* Indicates that the device supports field skipping. */ #define DDKERNELCAPS_SKIPFIELDS 0x00000001l
/*
* Indicates that the device can support software autoflipping. */ #define DDKERNELCAPS_AUTOFLIP 0x00000002l
/*
* Indicates that the device can switch between bob and weave. */ #define DDKERNELCAPS_SETSTATE 0x00000004l
/*
* Indicates that a client can gain direct access to the frame buffer. */ #define DDKERNELCAPS_LOCK 0x00000008l
/*
* Indicates that a client can manually flip the video port. */ #define DDKERNELCAPS_FLIPVIDEOPORT 0x00000010l
/*
* Indicates that a client can manually flip the overlay. */ #define DDKERNELCAPS_FLIPOVERLAY 0x00000020l
/*
* Indicates that the device supports a fast, asynchronous transfer * mechanism to system memory. */ #define DDKERNELCAPS_TRANSFER_SYSMEM 0x00000040l
/*
* Indicates that the device supports a fast, asynchronous transfer * mechanism via AGP. */ #define DDKERNELCAPS_TRANSFER_AGP 0x00000080l
/*
* Indicates that the device can report the polarity (even/odd) of * the curent video field. */ #define DDKERNELCAPS_FIELDPOLARITY 0x00000100l
/****************************************************************************
* * DDKERNELCAPS IRQ CAPS * ****************************************************************************/
/*
* The device can generate display VSYNC IRQs */ #define DDIRQ_DISPLAY_VSYNC 0x00000001l
/*
* Reserved */ #define DDIRQ_RESERVED1 0x00000002l
/*
* The device can generate video ports VSYNC IRQs using video port 0 */ #define DDIRQ_VPORT0_VSYNC 0x00000004l
/*
* The device can generate video ports line IRQs using video port 0 */ #define DDIRQ_VPORT0_LINE 0x00000008l
/*
* The device can generate video ports VSYNC IRQs using video port 1 */ #define DDIRQ_VPORT1_VSYNC 0x00000010l
/*
* The device can generate video ports line IRQs using video port 1 */ #define DDIRQ_VPORT1_LINE 0x00000020l
/*
* The device can generate video ports VSYNC IRQs using video port 2 */ #define DDIRQ_VPORT2_VSYNC 0x00000040l
/*
* The device can generate video ports line IRQs using video port 2 */ #define DDIRQ_VPORT2_LINE 0x00000080l
/*
* The device can generate video ports VSYNC IRQs using video port 3 */ #define DDIRQ_VPORT3_VSYNC 0x00000100l
/*
* The device can generate video ports line IRQs using video port 3 */ #define DDIRQ_VPORT3_LINE 0x00000200l
/*
* The device can generate video ports VSYNC IRQs using video port 4 */ #define DDIRQ_VPORT4_VSYNC 0x00000400l
/*
* The device can generate video ports line IRQs using video port 4 */ #define DDIRQ_VPORT4_LINE 0x00000800l
/*
* The device can generate video ports VSYNC IRQs using video port 5 */ #define DDIRQ_VPORT5_VSYNC 0x00001000l
/*
* The device can generate video ports line IRQs using video port 5 */ #define DDIRQ_VPORT5_LINE 0x00002000l
/*
* The device can generate video ports VSYNC IRQs using video port 6 */ #define DDIRQ_VPORT6_VSYNC 0x00004000l
/*
* The device can generate video ports line IRQs using video port 6 */ #define DDIRQ_VPORT6_LINE 0x00008000l
/*
* The device can generate video ports VSYNC IRQs using video port 7 */ #define DDIRQ_VPORT7_VSYNC 0x00010000l
/*
* The device can generate video ports line IRQs using video port 7 */ #define DDIRQ_VPORT7_LINE 0x00020000l
/*
* The device can generate video ports VSYNC IRQs using video port 8 */ #define DDIRQ_VPORT8_VSYNC 0x00040000l
/*
* The device can generate video ports line IRQs using video port 8 */ #define DDIRQ_VPORT8_LINE 0x00080000l
/*
* The device can generate video ports VSYNC IRQs using video port 9 */ #define DDIRQ_VPORT9_VSYNC 0x00010000l
/*
* The device can generate video ports line IRQs using video port 9 */ #define DDIRQ_VPORT9_LINE 0x00020000l
#endif
DWORD FAR PASCAL DirectDrawEventCallback ( DWORD dwEvent, PVOID pContext, DWORD dwParam1, DWORD dwParam2 ) { switch (dwEvent) { case DDNOTIFY_PRERESCHANGE: { PSTREAMEX pStrmEx = (PSTREAMEX)pContext; PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
DbgLogInfo(("Testcap: DDNOTIFY_PRERESCHANGE; stream = %d\n", StreamNumber));
pStrmEx->PreEventOccurred = TRUE; }
break;
case DDNOTIFY_POSTRESCHANGE: { PSTREAMEX pStrmEx = (PSTREAMEX)pContext; PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
DbgLogInfo(("Testcap: DDNOTIFY_POSTRESCHANGE; stream = %d\n", StreamNumber));
pStrmEx->PostEventOccurred = TRUE; DbgLogInfo(("Testcap: Before Attempted Renegotiation due to DDNOTIFY_POSTRESCHANGE\n")); // AttemptRenegotiation(pStrmEx);
DbgLogInfo(("Testcap: Afer Attempted Renegotiation due to DDNOTIFY_POSTRESCHANGE\n")); }
break;
case DDNOTIFY_PREDOSBOX: { PSTREAMEX pStrmEx = (PSTREAMEX)pContext; PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
DbgLogInfo(("Testcap: DDNOTIFY_PREDOSBOX; stream = %d\n", StreamNumber));
pStrmEx->PreEventOccurred = TRUE; }
break;
case DDNOTIFY_POSTDOSBOX: { PSTREAMEX pStrmEx = (PSTREAMEX)pContext; PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
DbgLogInfo(("Testcap: DDNOTIFY_POSTDOSBOX; stream = %d\n", StreamNumber));
pStrmEx->PostEventOccurred = TRUE; DbgLogInfo(("Testcap: Before Attempted Renegotiation due to DDNOTIFY_POSTDOSBOX\n")); // AttemptRenegotiation(pStrmEx);
DbgLogInfo(("Testcap: After Attempted Renegotiation due to DDNOTIFY_POSTDOSBOX\n")); }
break;
case DDNOTIFY_CLOSEDIRECTDRAW: { PSTREAMEX pStrmEx = (PSTREAMEX)pContext; PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pContext;
DbgLogInfo(("Testcap: DDNOTIFY_CLOSEDIRECTDRAW\n"));
pStrmEx->KernelDirectDrawHandle = 0; pStrmEx->UserDirectDrawHandle = 0; }
break;
case DDNOTIFY_CLOSESURFACE: { PHW_STREAM_REQUEST_BLOCK pSrb = (PHW_STREAM_REQUEST_BLOCK)pContext; PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;
DbgLogInfo(("Testcap: DDNOTIFY_CLOSESURFACE\n"));
pSrbExt->KernelSurfaceHandle = 0; }
break;
default: TRAP; break; } return 0; }
BOOL RegisterForDirectDrawEvents ( PSTREAMEX pStrmEx ) { PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber; DDREGISTERCALLBACK ddRegisterCallback; DWORD ddOut;
DbgLogInfo(("Testcap: Stream %d registering for DirectDraw events\n", StreamNumber));
// =============== DDEVENT_PRERESCHANGE ===============
RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback)); RtlZeroMemory(&ddOut, sizeof(ddOut));
ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle; ddRegisterCallback.dwEvents = DDEVENT_PRERESCHANGE; ddRegisterCallback.pfnCallback = DirectDrawEventCallback; ddRegisterCallback.pContext = pStrmEx;
DxApi(DD_DXAPI_REGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_REGISTER_CALLBACK failed.\n")); TRAP; return FALSE; }
// =============== DDEVENT_POSTRESCHANGE ==============
RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback)); RtlZeroMemory(&ddOut, sizeof(ddOut));
ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle; ddRegisterCallback.dwEvents = DDEVENT_POSTRESCHANGE; ddRegisterCallback.pfnCallback = DirectDrawEventCallback; ddRegisterCallback.pContext = pStrmEx;
DxApi(DD_DXAPI_REGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_REGISTER_CALLBACK failed.\n")); TRAP; return FALSE; }
// =============== DDEVENT_PREDOSBOX =================
RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback)); RtlZeroMemory(&ddOut, sizeof(ddOut));
ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle; ddRegisterCallback.dwEvents = DDEVENT_PREDOSBOX; ddRegisterCallback.pfnCallback = DirectDrawEventCallback; ddRegisterCallback.pContext = pStrmEx;
DxApi(DD_DXAPI_REGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_REGISTER_CALLBACK failed.\n")); TRAP; return FALSE; }
// =============== DDEVENT_POSTDOSBOX ================
RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback)); RtlZeroMemory(&ddOut, sizeof(ddOut));
ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle; ddRegisterCallback.dwEvents = DDEVENT_POSTDOSBOX; ddRegisterCallback.pfnCallback = DirectDrawEventCallback; ddRegisterCallback.pContext = pStrmEx;
DxApi(DD_DXAPI_REGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_REGISTER_CALLBACK failed.\n")); TRAP; return FALSE; } pStrmEx->KernelDirectDrawRegistered = TRUE;
return TRUE; }
BOOL UnregisterForDirectDrawEvents ( PSTREAMEX pStrmEx ) { PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber; DDREGISTERCALLBACK ddRegisterCallback; DWORD ddOut;
DbgLogInfo(("Testcap: Stream %d UNregistering for DirectDraw events\n", StreamNumber));
// =============== DDEVENT_PRERESCHANGE ===============
RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback)); RtlZeroMemory(&ddOut, sizeof(ddOut));
ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle; ddRegisterCallback.dwEvents = DDEVENT_PRERESCHANGE ; ddRegisterCallback.pfnCallback = DirectDrawEventCallback; ddRegisterCallback.pContext = pStrmEx;
DxApi(DD_DXAPI_UNREGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_UNREGISTER_CALLBACK failed.\n")); TRAP; return FALSE; }
// =============== DDEVENT_POSTRESCHANGE ==============
RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback)); RtlZeroMemory(&ddOut, sizeof(ddOut));
ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle; ddRegisterCallback.dwEvents = DDEVENT_POSTRESCHANGE; ddRegisterCallback.pfnCallback = DirectDrawEventCallback; ddRegisterCallback.pContext = pStrmEx;
DxApi(DD_DXAPI_UNREGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_UNREGISTER_CALLBACK failed.\n")); TRAP; return FALSE; }
// =============== DDEVENT_PREDOSBOX ==================
RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback)); RtlZeroMemory(&ddOut, sizeof(ddOut));
ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle; ddRegisterCallback.dwEvents = DDEVENT_PREDOSBOX; ddRegisterCallback.pfnCallback = DirectDrawEventCallback; ddRegisterCallback.pContext = pStrmEx;
DxApi(DD_DXAPI_UNREGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_UNREGISTER_CALLBACK failed.\n")); TRAP; return FALSE; }
// =============== DDEVENT_POSTDOSBOX =================
RtlZeroMemory(&ddRegisterCallback, sizeof(ddRegisterCallback)); RtlZeroMemory(&ddOut, sizeof(ddOut));
ddRegisterCallback.hDirectDraw = pStrmEx->KernelDirectDrawHandle; ddRegisterCallback.dwEvents = DDEVENT_POSTDOSBOX; ddRegisterCallback.pfnCallback = DirectDrawEventCallback; ddRegisterCallback.pContext = pStrmEx;
DxApi(DD_DXAPI_UNREGISTER_CALLBACK, &ddRegisterCallback, sizeof(ddRegisterCallback), &ddOut, sizeof(ddOut));
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_UNREGISTER_CALLBACK failed.\n")); TRAP; return FALSE; } pStrmEx->KernelDirectDrawRegistered = FALSE;
return TRUE; }
BOOL OpenKernelDirectDraw ( PSTREAMEX pStrmEx ) { PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
if (pStrmEx->UserDirectDrawHandle != 0) { DDOPENDIRECTDRAWIN ddOpenIn; DDOPENDIRECTDRAWOUT ddOpenOut;
ASSERT (pStrmEx->KernelDirectDrawHandle == 0);
DbgLogInfo(("Testcap: Stream %d getting Kernel ddraw handle\n", StreamNumber));
RtlZeroMemory(&ddOpenIn, sizeof(ddOpenIn)); RtlZeroMemory(&ddOpenOut, sizeof(ddOpenOut));
ddOpenIn.dwDirectDrawHandle = (DWORD_PTR) pStrmEx->UserDirectDrawHandle; ddOpenIn.pfnDirectDrawClose = DirectDrawEventCallback; ddOpenIn.pContext = pStrmEx;
DxApi(DD_DXAPI_OPENDIRECTDRAW, &ddOpenIn, sizeof(ddOpenIn), &ddOpenOut, sizeof(ddOpenOut));
if (ddOpenOut.ddRVal != DD_OK) { DbgLogInfo(("Testcap: DD_DXAPI_OPENDIRECTDRAW failed.\n")); } else { pStrmEx->KernelDirectDrawHandle = ddOpenOut.hDirectDraw; return TRUE; } }
return FALSE; }
BOOL CloseKernelDirectDraw ( PSTREAMEX pStrmEx ) { PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
if (pStrmEx->KernelDirectDrawHandle != 0) { DWORD ddOut; DDCLOSEHANDLE ddClose;
DbgLogInfo(("Testcap: Stream %d CloseKernelDirectDraw\n", StreamNumber));
ddClose.hHandle = pStrmEx->KernelDirectDrawHandle;
DxApi(DD_DXAPI_CLOSEHANDLE, &ddClose, sizeof(ddClose), &ddOut, sizeof(ddOut));
pStrmEx->KernelDirectDrawHandle = 0;
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: CloseKernelDirectDraw FAILED.\n")); TRAP; return FALSE; } } return TRUE; }
BOOL IsKernelLockAndFlipAvailable ( PSTREAMEX pStrmEx ) { PHW_DEVICE_EXTENSION pHwDevExt = pStrmEx->pHwDevExt; int StreamNumber = pStrmEx->pStreamObject->StreamNumber;
if (pStrmEx->KernelDirectDrawHandle != 0) { DDGETKERNELCAPSOUT ddGetKernelCapsOut;
DbgLogInfo(("Testcap: Stream %d getting Kernel Caps\n", StreamNumber));
RtlZeroMemory(&ddGetKernelCapsOut, sizeof(ddGetKernelCapsOut));
DxApi(DD_DXAPI_GETKERNELCAPS, &pStrmEx->KernelDirectDrawHandle, sizeof(pStrmEx->KernelDirectDrawHandle), &ddGetKernelCapsOut, sizeof(ddGetKernelCapsOut));
if (ddGetKernelCapsOut.ddRVal != DD_OK) { DbgLogInfo(("Testcap: DDGETKERNELCAPSOUT failed.\n")); } else { DbgLogInfo(("Testcap: Stream %d KernelCaps = %x\n", StreamNumber, ddGetKernelCapsOut.dwCaps));
if ((ddGetKernelCapsOut.dwCaps & (DDKERNELCAPS_LOCK | DDKERNELCAPS_FLIPOVERLAY)) == (DDKERNELCAPS_LOCK | DDKERNELCAPS_FLIPOVERLAY)) { // TODO: Check where we may need to set up for kernel flipping
} return TRUE; } } return FALSE; }
BOOL OpenKernelDDrawSurfaceHandle( IN PHW_STREAM_REQUEST_BLOCK pSrb ) { PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension); PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension; int StreamNumber = pStrmEx->pStreamObject->StreamNumber; PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;
ASSERT (pStrmEx->KernelDirectDrawHandle != 0); ASSERT (pSrbExt->UserSurfaceHandle != 0);
if (pSrbExt->UserSurfaceHandle == 0) { DDOPENSURFACEIN ddOpenSurfaceIn; DDOPENSURFACEOUT ddOpenSurfaceOut;
DbgLogInfo(("Testcap: Stream %d getting Kernel surface handle\n", StreamNumber));
RtlZeroMemory(&ddOpenSurfaceIn, sizeof(ddOpenSurfaceIn)); RtlZeroMemory(&ddOpenSurfaceOut, sizeof(ddOpenSurfaceOut));
ddOpenSurfaceIn.hDirectDraw = pStrmEx->UserDirectDrawHandle; ddOpenSurfaceIn.pfnSurfaceClose = DirectDrawEventCallback; ddOpenSurfaceIn.pContext = pSrb;
ddOpenSurfaceIn.dwSurfaceHandle = (DWORD_PTR) pSrbExt->UserSurfaceHandle;
DxApi(DD_DXAPI_OPENSURFACE, &ddOpenSurfaceIn, sizeof(ddOpenSurfaceIn), &ddOpenSurfaceOut, sizeof(ddOpenSurfaceOut));
if (ddOpenSurfaceOut.ddRVal != DD_OK) { pSrbExt->KernelSurfaceHandle = 0; DbgLogInfo(("Testcap: DD_DXAPI_OPENSURFACE failed.\n")); TRAP; } else { pSrbExt->KernelSurfaceHandle = ddOpenSurfaceOut.hSurface; return TRUE; } } return FALSE; }
BOOL CloseKernelDDrawSurfaceHandle ( IN PHW_STREAM_REQUEST_BLOCK pSrb ) { PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension); PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension; int StreamNumber = pStrmEx->pStreamObject->StreamNumber; PSRB_EXTENSION pSrbExt = (PSRB_EXTENSION)pSrb->SRBExtension;
ASSERT (pStrmEx->KernelDirectDrawHandle != 0); ASSERT (pSrbExt->UserSurfaceHandle != 0); ASSERT (pSrbExt->KernelSurfaceHandle != 0);
if (pSrbExt->KernelSurfaceHandle != 0) { DWORD ddOut; DDCLOSEHANDLE ddClose;
DbgLogInfo(("Testcap: Stream %d ReleaseKernelDDrawSurfaceHandle\n", StreamNumber));
ddClose.hHandle = pSrbExt->KernelSurfaceHandle;
DxApi(DD_DXAPI_CLOSEHANDLE, &ddClose, sizeof(ddClose), &ddOut, sizeof(ddOut));
pSrbExt->KernelSurfaceHandle = 0; // what else can we do?
if (ddOut != DD_OK) { DbgLogInfo(("Testcap: ReleaseKernelDDrawSurfaceHandle FAILED.\n")); TRAP; return FALSE; } else { return TRUE; } }
return FALSE; }
|