663 lines
20 KiB
C
663 lines
20 KiB
C
|
//==========================================================================;
|
||
|
//
|
||
|
// 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|