321 lines
9.2 KiB
C
321 lines
9.2 KiB
C
/****************************************************************************
|
||
*
|
||
* capinit.c
|
||
*
|
||
* Initialization code.
|
||
*
|
||
* Microsoft Video for Windows Sample Capture Class
|
||
*
|
||
* Copyright (c) 1992, 1993 Microsoft Corporation. All Rights Reserved.
|
||
*
|
||
* You have a royalty-free right to use, modify, reproduce and
|
||
* distribute the Sample Files (and/or any modified version) in
|
||
* any way you find useful, provided that you agree that
|
||
* Microsoft has no warranty obligations or liability for any
|
||
* Sample Application Files which are modified.
|
||
*
|
||
***************************************************************************/
|
||
|
||
#include <windows.h>
|
||
#include <windowsx.h>
|
||
#include <ver.h>
|
||
#include <mmsystem.h>
|
||
|
||
//
|
||
// define these before any msvideo.h, so our functions get declared right.
|
||
//
|
||
#ifndef WIN32
|
||
#define VFWAPI FAR PASCAL _loadds
|
||
#define VFWAPIV FAR CDECL _loadds
|
||
#endif
|
||
|
||
#include "msvideo.h"
|
||
#include <drawdib.h>
|
||
#include "avicap.h"
|
||
#include "avicapi.h"
|
||
|
||
// for correct handling of capGetDriverDescription on NT and Chicago
|
||
// this is used by the NT version of avicap.dll (16bit) but not intended for
|
||
// public use, hence not in msvideo.h
|
||
DWORD WINAPI videoCapDriverDescAndVer (
|
||
DWORD wDriverIndex,
|
||
LPSTR lpszName, UINT cbName,
|
||
LPSTR lpszVer, UINT cbVer);
|
||
|
||
HINSTANCE ghInst;
|
||
BOOL gfIsRTL;
|
||
char szCaptureWindowClass[] = "ClsCapWin";
|
||
|
||
typedef struct tagVS_VERSION
|
||
{
|
||
WORD wTotLen;
|
||
WORD wValLen;
|
||
char szSig[16];
|
||
VS_FIXEDFILEINFO vffInfo;
|
||
} VS_VERSION;
|
||
|
||
typedef struct tagLANGANDCP
|
||
{
|
||
WORD wLanguage;
|
||
WORD wCodePage;
|
||
} LANGANDCP;
|
||
|
||
|
||
BOOL FAR PASCAL RegisterCaptureClass (HINSTANCE hInst)
|
||
{
|
||
WNDCLASS cls;
|
||
|
||
// If we're already registered, we're OK
|
||
if (GetClassInfo(hInst, szCaptureWindowClass, &cls))
|
||
return TRUE;
|
||
|
||
cls.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||
cls.hIcon = NULL;
|
||
cls.lpszMenuName = NULL;
|
||
cls.lpszClassName = szCaptureWindowClass;
|
||
cls.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
|
||
cls.hInstance = hInst;
|
||
cls.style = CS_HREDRAW|CS_VREDRAW | CS_BYTEALIGNCLIENT |
|
||
CS_GLOBALCLASS;
|
||
cls.lpfnWndProc = (WNDPROC) CapWndProc;
|
||
cls.cbClsExtra = 0;
|
||
// Kludge, VB Status and Error GlobalAlloc'd ptrs + room to grow...
|
||
cls.cbWndExtra = sizeof (LPCAPSTREAM) + sizeof (DWORD) * 4;
|
||
|
||
RegisterClass(&cls);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// Internal version
|
||
// Get the name and version of the video device
|
||
//
|
||
BOOL capInternalGetDriverDesc (WORD wDriverIndex,
|
||
LPSTR lpszName, int cbName,
|
||
LPSTR lpszVer, int cbVer)
|
||
{
|
||
return (BOOL) videoCapDriverDescAndVer(
|
||
wDriverIndex,
|
||
lpszName, cbName,
|
||
lpszVer, cbVer);
|
||
|
||
}
|
||
|
||
//
|
||
// Exported version
|
||
// Get the name and version of the video device
|
||
//
|
||
BOOL VFWAPI capGetDriverDescription (WORD wDriverIndex,
|
||
LPSTR lpszName, int cbName,
|
||
LPSTR lpszVer, int cbVer)
|
||
{
|
||
return (capInternalGetDriverDesc (wDriverIndex,
|
||
lpszName, cbName,
|
||
lpszVer, cbVer));
|
||
}
|
||
|
||
//
|
||
// Disconnect from hardware resources
|
||
//
|
||
BOOL CapWinDisconnectHardware(LPCAPSTREAM lpcs)
|
||
{
|
||
if( lpcs->hVideoCapture ) {
|
||
videoStreamFini (lpcs->hVideoCapture);
|
||
videoClose( lpcs->hVideoCapture );
|
||
}
|
||
if( lpcs->hVideoDisplay ) {
|
||
videoStreamFini (lpcs->hVideoDisplay);
|
||
videoClose( lpcs->hVideoDisplay );
|
||
}
|
||
if( lpcs->hVideoIn ) {
|
||
videoClose( lpcs->hVideoIn );
|
||
}
|
||
|
||
lpcs->fHardwareConnected = FALSE;
|
||
|
||
lpcs->hVideoCapture = NULL;
|
||
lpcs->hVideoDisplay = NULL;
|
||
lpcs->hVideoIn = NULL;
|
||
|
||
lpcs->sCapDrvCaps.fHasDlgVideoSource = FALSE;
|
||
lpcs->sCapDrvCaps.fHasDlgVideoFormat = FALSE;
|
||
lpcs->sCapDrvCaps.fHasDlgVideoDisplay = FALSE;
|
||
lpcs->sCapDrvCaps.fHasDlgVideoDisplay = FALSE;
|
||
|
||
lpcs->sCapDrvCaps.hVideoIn = NULL;
|
||
lpcs->sCapDrvCaps.hVideoOut = NULL;
|
||
lpcs->sCapDrvCaps.hVideoExtIn = NULL;
|
||
lpcs->sCapDrvCaps.hVideoExtOut = NULL;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//
|
||
// Connect to hardware resources
|
||
// Return: TRUE if hardware connected to the stream
|
||
//
|
||
BOOL CapWinConnectHardware (LPCAPSTREAM lpcs, WORD wDeviceIndex)
|
||
{
|
||
DWORD dwError;
|
||
CHANNEL_CAPS VideoCapsExternalOut;
|
||
char ach1[_MAX_CAP_PATH];
|
||
char ach2[_MAX_CAP_PATH * 3];
|
||
CAPINFOCHUNK cic;
|
||
HINSTANCE hInstT;
|
||
|
||
lpcs->hVideoCapture = NULL;
|
||
lpcs->hVideoDisplay = NULL;
|
||
lpcs->hVideoIn = NULL;
|
||
lpcs->fHardwareConnected = FALSE;
|
||
lpcs->fUsingDefaultPalette = TRUE;
|
||
lpcs->sCapDrvCaps.fHasDlgVideoSource = FALSE;
|
||
lpcs->sCapDrvCaps.fHasDlgVideoFormat = FALSE;
|
||
lpcs->sCapDrvCaps.fHasDlgVideoDisplay = FALSE;
|
||
lpcs->sCapDrvCaps.wDeviceIndex = wDeviceIndex;
|
||
|
||
// Clear any existing capture device name chunk
|
||
cic.fccInfoID = mmioFOURCC ('I','S','F','T');
|
||
cic.lpData = NULL;
|
||
cic.cbData = 0;
|
||
SetInfoChunk (lpcs, &cic);
|
||
|
||
// try and open the video hardware!!!
|
||
if( !(dwError = videoOpen( &lpcs->hVideoIn, wDeviceIndex, VIDEO_IN ) ) ) {
|
||
if( !(dwError = videoOpen( &lpcs->hVideoCapture, wDeviceIndex, VIDEO_EXTERNALIN ) ) ) {
|
||
// We don't require the EXTERNALOUT channel,
|
||
// but do require EXTERNALIN and IN
|
||
videoOpen( &lpcs->hVideoDisplay, wDeviceIndex, VIDEO_EXTERNALOUT );
|
||
if( (!dwError) && lpcs->hVideoCapture && lpcs->hVideoIn ) {
|
||
|
||
lpcs->fHardwareConnected = TRUE;
|
||
capInternalGetDriverDesc (wDeviceIndex,
|
||
ach1, sizeof (ach1),
|
||
ach2, sizeof (ach2));
|
||
lstrcat (ach1, ", ");
|
||
lstrcat (ach1, ach2);
|
||
|
||
statusUpdateStatus (lpcs, IDS_CAP_INFO, (LPSTR) ach1);
|
||
|
||
// Make a string of the current task and capture driver
|
||
ach2[0] = '\0';
|
||
if (hInstT = GetWindowWord (GetParent (lpcs->hwnd), GWW_HINSTANCE))
|
||
GetModuleFileName (hInstT, ach2, sizeof (ach2));
|
||
lstrcat (ach2, " -AVICAP- ");
|
||
lstrcat (ach2, ach1);
|
||
|
||
// Set software chunk with name of capture device
|
||
if (*ach2) {
|
||
cic.lpData = ach2;
|
||
cic.cbData = lstrlen(ach2) + 1;
|
||
SetInfoChunk (lpcs, &cic);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (dwError)
|
||
errorDriverID (lpcs, dwError);
|
||
|
||
if(!lpcs->fHardwareConnected) {
|
||
CapWinDisconnectHardware(lpcs);
|
||
}
|
||
else {
|
||
if (lpcs->hVideoDisplay && videoGetChannelCaps (lpcs->hVideoDisplay,
|
||
&VideoCapsExternalOut,
|
||
sizeof (CHANNEL_CAPS)) == DV_ERR_OK) {
|
||
lpcs->sCapDrvCaps.fHasOverlay = (BOOL)(VideoCapsExternalOut.dwFlags &
|
||
(DWORD)VCAPS_OVERLAY);
|
||
}
|
||
else
|
||
lpcs->sCapDrvCaps.fHasOverlay = FALSE;
|
||
// if the hardware doesn't support it, make sure we don't enable
|
||
if (!lpcs->sCapDrvCaps.fHasOverlay)
|
||
lpcs->fOverlayWindow = FALSE;
|
||
|
||
// Start the external in channel streaming continuously
|
||
videoStreamInit (lpcs->hVideoCapture, 0L, 0L, 0L, 0L);
|
||
} // end if hardware is available
|
||
|
||
#if 0
|
||
// if we don't have a powerful machine, disable capture
|
||
if (GetWinFlags() & (DWORD) WF_CPU286)
|
||
CapWinDisconnectHardware(lpcs);
|
||
#endif
|
||
|
||
if (!lpcs->fHardwareConnected){
|
||
lpcs->fLiveWindow = FALSE;
|
||
lpcs->fOverlayWindow = FALSE;
|
||
}
|
||
|
||
if (lpcs->hVideoIn)
|
||
lpcs->sCapDrvCaps.fHasDlgVideoFormat = !videoDialog (lpcs-> hVideoIn,
|
||
lpcs-> hwnd, VIDEO_DLG_QUERY);
|
||
|
||
if (lpcs->hVideoCapture)
|
||
lpcs->sCapDrvCaps.fHasDlgVideoSource = !videoDialog (lpcs-> hVideoCapture,
|
||
lpcs-> hwnd, VIDEO_DLG_QUERY);
|
||
|
||
if (lpcs->hVideoDisplay)
|
||
lpcs->sCapDrvCaps.fHasDlgVideoDisplay = !videoDialog (lpcs-> hVideoDisplay,
|
||
lpcs-> hwnd, VIDEO_DLG_QUERY);
|
||
|
||
lpcs->sCapDrvCaps.hVideoIn = lpcs->hVideoIn;
|
||
lpcs->sCapDrvCaps.hVideoOut = NULL;
|
||
lpcs->sCapDrvCaps.hVideoExtIn = lpcs->hVideoCapture;
|
||
lpcs->sCapDrvCaps.hVideoExtOut = lpcs->hVideoDisplay;
|
||
|
||
return lpcs->fHardwareConnected;
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Creates a child window of the capture class
|
||
// Normally:
|
||
// Set lpszWindowName to NULL
|
||
// Set dwStyle to WS_CHILD | WS_VISIBLE
|
||
// Set hmenu to a unique child id
|
||
|
||
HWND VFWAPI capCreateCaptureWindow (
|
||
LPCSTR lpszWindowName,
|
||
DWORD dwStyle,
|
||
int x, int y, int nWidth, int nHeight,
|
||
HWND hwndParent, int nID)
|
||
{
|
||
DWORD fdwFlags;
|
||
|
||
#ifndef WS_EX_LEFTSCROLLBAR
|
||
#define WS_EX_LEFTSCROLLBAR 0
|
||
#define WS_EX_RIGHT 0
|
||
#define WS_EX_RTLREADING 0
|
||
#endif
|
||
|
||
RegisterCaptureClass(ghInst);
|
||
fdwFlags = gfIsRTL ? WS_EX_LEFTSCROLLBAR | WS_EX_RIGHT | WS_EX_RTLREADING : 0;
|
||
return CreateWindowEx(fdwFlags,
|
||
szCaptureWindowClass,
|
||
lpszWindowName,
|
||
dwStyle,
|
||
x, y, nWidth, nHeight,
|
||
hwndParent, (HMENU) nID,
|
||
ghInst,
|
||
NULL);
|
||
}
|
||
|
||
|
||
int CALLBACK LibMain(HINSTANCE hinst, WORD wDataSeg, WORD cbHeap,
|
||
LPSTR lpszCmdLine )
|
||
{
|
||
char ach[2];
|
||
|
||
ghInst = hinst;
|
||
LoadString(ghInst, IDS_CAP_RTL, ach, sizeof(ach));
|
||
gfIsRTL = ach[0] == '1';
|
||
return TRUE;
|
||
}
|
||
|
||
int FAR PASCAL WEP(int i)
|
||
{
|
||
return 1;
|
||
}
|
||
|