Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1284 lines
30 KiB

/*
* dialog.c
*
* 32-bit Video Capture driver
* configuration dialog processing
*
* Geraint Davies, March 1993
*/
#include <windows.h>
#include <mmsystem.h>
#include <msvideo.h>
#include <msviddrv.h>
#include <ntavi.h> //16/32 porting macros
#include "spigotu.h"
#include "dialog.h"
/*
* sent to dialog to update all fields
* so user can see effect of changes dynamically
*/
#define WM_UPDATEDIALOG (WM_USER+200)
/* convert a width in bits to a ULONG aligned width in bytes */
#define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8)
/* force val to be within low and hi */
#define LIMIT_RANGE(val, low, hi) (max(low, (min(val, hi))))
/*
* we use these to contain a list of possible valid choices
* for configuration items.
*/
typedef struct tag_combobox_entry {
DWORD wValue;
LPTSTR szText;
} COMBOBOX_ENTRY;
/*
* copies of the configuration information used by the
* the dialogs - process-wide. Thus we can only have a dialog from
* one driver at once in this process (assuming we ever work out how
* to support multiple drivers!)
*/
CONFIG_FORMAT Dlg_Format;
CONFIG_SOURCE Dlg_Source;
COMBOBOX_ENTRY gwInterruptOptions [] =
{
10, TEXT("10"),
11, TEXT("11"),
15, TEXT("15")
};
#define N_INTERRUPTOPTIONS (sizeof (gwInterruptOptions) / sizeof (COMBOBOX_ENTRY))
/*
* possible choices for format field
*/
static COMBOBOX_ENTRY gwFormatOptions [] =
{
FmtPal8, TEXT("8 bit Palettized"),
FmtRGB555, TEXT("16 bit RGB 5:5:5"),
FmtRGB24, TEXT("24 bit RGB"),
FmtYUV422, TEXT("YUV 4:2:2")
};
#define N_FORMATOPTIONS (sizeof (gwFormatOptions) / sizeof (COMBOBOX_ENTRY))
VOID cfg_InitLocation(PVC_PROFILE_INFO pProf, PCONFIG_LOCATION pLoc);
VOID cfg_SetDialogVersionText(HWND hDlg);
VOID cfg_SetDefaultFormat(PCONFIG_FORMAT pFormat, PVC_PROFILE_INFO pProf);
VOID cfg_SetDefaultSource(PCONFIG_SOURCE pSource, PVC_PROFILE_INFO pProf);
VOID cfg_SaveFormat(PBU_INFO);
VOID cfg_SaveSource(PBU_INFO);
/*
* convert the given notional width into the correct width and height
* for a given video standard.
*/
VOID
GetWidthHeight(
DWORD dwWidth,
LPDWORD lpdwWidth,
LPDWORD lpdwHeight,
VIDSTD VideoStd,
BOOL bReturnTheoreticalMax
)
{
switch (VideoStd) {
case NTSC: {
switch (dwWidth) {
case 80:
case 96: {
*lpdwWidth = 80;
*lpdwHeight = 60;
break;
}
default:
case 160:
case 192: {
*lpdwWidth = 160;
*lpdwHeight = 120;
break;
}
case 240:
case 288: {
*lpdwWidth = 240;
*lpdwHeight = 180;
break;
}
case 640:
case 768: {
*lpdwWidth = 640;
*lpdwHeight = 480;
break;
}
case 320:
case 384: {
*lpdwWidth = 320;
*lpdwHeight = 240;
break;
}
}
break;
}
case PAL:
case SECAM: {
switch (dwWidth) {
case 80:
case 96: {
*lpdwWidth = 96;
*lpdwHeight = 72;
break;
}
default:
case 160:
case 192: {
*lpdwWidth = 192;
*lpdwHeight = 144;
break;
}
case 240:
case 288: {
*lpdwWidth = 288;
*lpdwHeight = 216;
break;
}
#ifndef PAL_FULLFRAME
case 640:
case 768: {
if (bReturnTheoreticalMax) {
*lpdwWidth = 768;
*lpdwHeight = 576;
break;
}
} // NOTE: NO BREAK -- we don't support fullfield PAL,SECAM
#else
case 640:
case 768:
*lpdwWidth = 768;
*lpdwHeight = 576;
break;
#endif
case 320:
case 384: {
*lpdwWidth = 384;
*lpdwHeight = 288;
break;
}
}
break;
}
}
}
/*
* set the destination DIB format to match the chosen format
* and dimensions.
*/
VOID
InitDestBIHeader(
LPBITMAPINFOHEADER lpbi,
CAPTUREFORMAT wEnumFormat,
DWORD dwWidth,
VIDSTD VideoStd
)
{
lpbi->biSize = sizeof (BITMAPINFOHEADER);
GetWidthHeight(dwWidth, &lpbi->biWidth, &lpbi->biHeight, VideoStd, FALSE);
lpbi->biPlanes = 1;
lpbi->biXPelsPerMeter = 0L;
lpbi->biYPelsPerMeter = 0L;
lpbi->biClrUsed = 0L;
lpbi->biClrImportant = 0L;
switch (wEnumFormat) {
case FmtPal8:
lpbi->biBitCount = 8;
lpbi->biCompression = BI_RGB;
break;
case FmtRGB555:
lpbi->biBitCount = 16;
lpbi->biCompression = BI_RGB;
break;
case FmtRGB24:
lpbi->biBitCount = 24;
lpbi->biCompression = BI_RGB;
break;
case FmtYUV422:
lpbi->biBitCount = 16;
lpbi->biCompression = FOURCC_YUV;
}
if (lpbi->biCompression == BI_RGB) {
lpbi->biSizeImage = (DWORD)lpbi->biHeight *
(DWORD)WIDTHBYTES(lpbi->biWidth * lpbi->biBitCount);
} else {
lpbi->biSizeImage = (DWORD)lpbi->biHeight *
(DWORD)WIDTHBYTES(lpbi->biWidth * lpbi->biBitCount);
if (lpbi->biHeight >= 480) {
lpbi->biSizeImage /= 2;
}
}
}
//
// Loads entries into a combobox, and selects the current index
// Parmameters:
// hWnd of the parent dialog box
// ID of the combobox
// array of text and values
// Count of entries in the COMBOBOX_ENTRY array
// Initial value which should match the wValue field of the
// COMBOBOX_ENTRY. If no values match, the selection
// defaults to the first entry in the combobox.
// Returns:
// Returns the index of the selected item in the combobox.
//
int
ConfigLoadComboBox(
HWND hDlg,
int wID,
COMBOBOX_ENTRY * pCBE,
int nEntries,
DWORD wInitialValue
)
{
int j;
int nIndex = 0; // Zeroeth entry should be blank, None, etc.
HWND hWndCB = GetDlgItem (hDlg, wID);
for (j = 0; j < nEntries; j++) {
SendMessage (hWndCB, CB_ADDSTRING, 0, (LONG) (LPTSTR) ((pCBE+j)->szText));
if (pCBE[j].wValue == wInitialValue) {
nIndex = j;
}
}
SendMessage (hWndCB, CB_SETCURSEL, nIndex, 0L);
return nIndex;
}
//
// Returns the value associated with the selected ComboBox text string.
// Parameters:
// hWnd of the parent dialog box
// ID of the ComboBox
// array of text and values
// Returns:
// Returns the value of the selected item in list.
//
DWORD
ConfigGetComboBoxValue(
HWND hDlg,
int wID,
COMBOBOX_ENTRY * pCBE
)
{
int nIndex;
HWND hWndCB = GetDlgItem (hDlg, wID);
nIndex = (int) SendMessage (hWndCB, CB_GETCURSEL, 0, 0L);
nIndex = max (0, nIndex); // LB_ERR is negative
return pCBE[nIndex].wValue;
}
//
// sets the current selection of a combo box to the entry
// whose data is represented by dwSelectValue
// - also returns its index
//
int
ConfigSetComboBoxSelection(
HWND hDlg,
int wID,
COMBOBOX_ENTRY * pCBE,
int nEntries,
DWORD dwSelectValue
)
{
int j;
int nIndex = 0; // Zeroeth entry should be blank, None, etc.
for (j = 0; j < nEntries; j++) {
if (pCBE[j].wValue == dwSelectValue) {
nIndex = j;
break;
}
}
SendDlgItemMessage (hDlg, wID, CB_SETCURSEL, nIndex, 0L);
return nIndex;
}
//
// Checks that a value passed matches an entry in a COMBOBOX_ENTRY list.
// Parameters:
// array of text and values
// Count of entries in the COMBOBOX_ENTRY array
// Value to confirm matches an entry in the
// value field of the COMBOBOX_ENTRY.
// Returns:
// Returns wValueToTest if a match is found, otherwise -1.
//
DWORD
ConfigConfirmLegalValue(
COMBOBOX_ENTRY * pCBE,
int nEntries,
DWORD wValueToTest
)
{
int j;
for (j = 0; j < nEntries; j++) {
if (wValueToTest == pCBE[j].wValue) {
return wValueToTest;
}
}
return (DWORD) -1;
}
VOID ConfigErrorMsgBox(HWND hDlg, DWORD wStringId)
{
TCHAR szPname[MAXPNAMELEN];
TCHAR szErrorBuffer[MAX_ERR_STRING]; // buffer for error messages
LoadString(ghModule, IDS_VCAPPRODUCT, szPname, sizeof(szPname));
LoadString(ghModule, wStringId, szErrorBuffer, sizeof(szErrorBuffer));
MessageBox(hDlg, szErrorBuffer, szPname, MB_OK|MB_ICONEXCLAMATION);
}
// Load up memory base page combo box (we have options of every 8KB page in
// either the 0th megabyte of memory or the 16th megabyte of memory). For
// practical purposes on the AT bus we will only allow 8KB pages above A000
// in the 0th megabyte (since program space occupies the 1st 640kb).
VOID
LoadMemoryBaseComboBox(
HWND hDlg,
DWORD dwCurrentBase
)
{
DWORD dwMemoryBase;
TCHAR szMemoryBase[32];
LRESULT lIndex;
WORD wCurSel;
// remember current selection if should preserve current selection
if (!dwCurrentBase) {
wCurSel = (WORD) SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_GETCURSEL,
0,
0L
);
}
// clear the combobox of any current data
SendDlgItemMessage(hDlg,ID_LBMEMORYBASEADDRESS,CB_RESETCONTENT,0,0L);
// add the possible address strings to the combobox...
for (dwMemoryBase = 0xa0000L;
dwMemoryBase <= 0xfe000L;
dwMemoryBase += 0x002000L
) {
wsprintf(szMemoryBase, TEXT("%.6lX"), dwMemoryBase);
lIndex = SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_ADDSTRING,
0,
(LONG)(LPSTR) szMemoryBase
);
SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_SETITEMDATA,
(UINT)lIndex,
dwMemoryBase
);
}
for (
dwMemoryBase = 0xf20000;
dwMemoryBase <= 0xffe000;
dwMemoryBase += 0x002000
) {
wsprintf(szMemoryBase, TEXT("%.6lX"), dwMemoryBase);
lIndex = SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_ADDSTRING,
0,
(LONG)(LPSTR) szMemoryBase
);
SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_SETITEMDATA,
(UINT)lIndex,
dwMemoryBase
);
}
if (dwCurrentBase) { // should update current selection...
wsprintf(szMemoryBase, TEXT("%.6lX"), dwCurrentBase);
if ((lIndex = SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_FINDSTRING,
(WPARAM) -1,
(LPARAM)(LPSTR) szMemoryBase
)
) != CB_ERR
) {
SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_SETCURSEL,
(WPARAM) lIndex,
MAKELPARAM(0,0)
);
}
}
else { // set current selection from base gotten at head of function...
SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_SETCURSEL,
(WPARAM) wCurSel,
0L
);
}
}
/*
* dialog proc to allow selection of the interrupt and frame-buffer
* address.
*
*
* on OK, we attempt to load the kernel driver with these values. Note that
* the kernel driver may possibly be loaded already, in which case we need to
* unload it before setting the parameters and loading it.
*
* we return DRV_CANCEL if the attempt failed or was aborted, DRV_RESTART
* if the system needs to be restarted before the changes take effect (eg
* because the current driver could not be unloaded) or DRV_OK if all went ok.
*/
int
ConfigDlgProc(HWND hDlg, UINT msg, UINT wParam, LONG lParam)
{
CONFIG_LOCATION Loc;
int iResult;
DWORD dwError;
PVC_PROFILE_INFO pProfile;
LONG lIndex;
/*
* the board structure is passed in the lParam of the WM_INITDIALOG,
* and stored in the spare window long .
*/
if (msg != WM_INITDIALOG) {
pProfile = (PVC_PROFILE_INFO) GetWindowLong(hDlg, DWL_USER);
}
switch (msg)
{
case WM_INITDIALOG:
{
/*
* store the profile info pointer in the spare window long
*/
pProfile = (PVC_PROFILE_INFO) lParam;
SetWindowLong(hDlg, DWL_USER, (LONG) pProfile);
/*
* set the version info from the version resource
* if present
*/
cfg_SetDialogVersionText(hDlg);
/*
* initialise config settings to previously set values
* or hardware defaults.
*/
cfg_InitLocation(pProfile, &Loc);
ConfigLoadComboBox (hDlg, ID_LBINTERRUPTNUMBER,
gwInterruptOptions, N_INTERRUPTOPTIONS,
Loc.Interrupt);
LoadMemoryBaseComboBox(hDlg, Loc.FifoWindow);
}
break;
// User will unload this module at exit time, so make
// sure that the dialog is gone if the user just quits
// Windows with the dialog box up.
case WM_ENDSESSION:
if (wParam)
EndDialog (hDlg, DRV_CANCEL);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
Loc.Interrupt = ConfigGetComboBoxValue (hDlg, ID_LBINTERRUPTNUMBER,
gwInterruptOptions);
lIndex = SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_GETCURSEL,
0,
0);
Loc.FifoWindow = SendDlgItemMessage(
hDlg,
ID_LBMEMORYBASEADDRESS,
CB_GETITEMDATA,
(UINT)lIndex,
0);
iResult = vidInstall(hDlg, &Loc, pProfile);
/* check the driver's own error code
* which should have been written to the profile.
* If this is VC_ERR_OK, the driver loaded ok
*/
dwError = VC_ReadProfile(
pProfile,
PARAM_ERROR,
IDS_ERR_UNKNOWN);
if((iResult != DRVCNF_CANCEL) && (dwError == VC_ERR_OK)) {
/*
* the return value from vidInstall indicates
* whether or not we need to reboot.
*/
if (iResult == DRVCNF_OK) {
dprintf2(("returning DRVCNF_OK"));
} else {
dprintf2(("returning %d", iResult));
}
EndDialog(hDlg, iResult);
} else {
ConfigErrorMsgBox(hDlg, dwError);
}
break;
case IDCANCEL:
EndDialog(hDlg, DRV_CANCEL);
break;
default:
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
/*
* put up the configure dialog to allow selection of the
* port, interrupt and frame buffer address for the card, then attempt to
* start the kernel driver.
*
* returns (from the dialog) DRV_CANCEL if the dialog was aborted or the install
* failed, DRV_RESTART if the install was ok but a system-restart is needed
* for the changes to take effect, or DRV_OK if all was completed ok.
*/
int
Config(HWND hWnd, HANDLE hModule, PVC_PROFILE_INFO pProfile)
{
return DialogBoxParam(
hModule,
MAKEINTATOM(DLG_VIDEOCONFIG),
hWnd,
ConfigDlgProc,
(LONG) pProfile
);
}
/*
* update the image size selection based on the current dest format and video
* standard
*/
VOID UpdateSizeDisplay (HWND hDlg, VIDSTD VideoStd)
{
DWORD dwWidth, dwHeight;
GetWidthHeight(
Dlg_Format.ulWidth,
&dwWidth,
&dwHeight,
VideoStd,
FALSE);
SetDlgItemInt(hDlg, ID_SIZEX, (WORD) dwWidth, FALSE);
SetDlgItemInt(hDlg, ID_SIZEY, (WORD) dwHeight, FALSE);
}
//
// Dialog proc for the video format dialog box (VIDEO_IN channel)
//
int
VideoFormatDlgProc(HWND hDlg, UINT msg, UINT wParam, LONG lParam)
{
int j;
BITMAPINFOHEADER bi;
PBU_INFO pBoard;
if (msg != WM_INITDIALOG) {
pBoard = (PBU_INFO) GetWindowLong(hDlg, DWL_USER);
}
switch (msg)
{
case WM_INITDIALOG:
/*
* pointer to board structure is passed as dialog param.
* save in spare window long
*/
pBoard = (PBU_INFO) lParam;
SetWindowLong(hDlg, DWL_USER, (LONG) pBoard);
/*
* make a copy of the current format information
*/
Dlg_Format = pBoard->CfgFormat;
ConfigLoadComboBox( hDlg, ID_LBIMAGEFORMAT,
gwFormatOptions, N_FORMATOPTIONS,
Dlg_Format.Format);
UpdateSizeDisplay (hDlg, pBoard->CfgSource.VideoStd);
#ifndef PAL_FULLFRAME
if (pBoard->CfgSource.VideoStd != NTSC) {
EnableWindow(GetDlgItem(hDlg, ID_PBSIZEFULL), FALSE);
}
#endif
break;
// User will unload this module at exit time, so make
// sure that the dialog is gone if the user just quits
// Windows with the dialog box up.
case WM_ENDSESSION:
if (wParam)
EndDialog (hDlg, IDCANCEL);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
j = ConfigGetComboBoxValue(hDlg,
ID_LBIMAGEFORMAT,
gwFormatOptions);
InitDestBIHeader (&bi, j, Dlg_Format.ulWidth,
pBoard->CfgSource.VideoStd);
SetDestFormat (&bi, sizeof (bi));
/*
* write settings to profile
*/
cfg_SaveFormat(pBoard);
EndDialog(hDlg, IDOK);
break;
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
break;
case ID_PBSIZEFULL:
Dlg_Format.ulWidth = 640;
UpdateSizeDisplay (hDlg, pBoard->CfgSource.VideoStd);
break;
case ID_PBSIZEHALF:
Dlg_Format.ulWidth = (640 / 2);
UpdateSizeDisplay (hDlg, pBoard->CfgSource.VideoStd);
break;
case ID_PBSIZETHREEEIGTHS:
Dlg_Format.ulWidth = ((640 * 3) / 8);
UpdateSizeDisplay (hDlg, pBoard->CfgSource.VideoStd);
break;
case ID_PBSIZEQUARTER:
Dlg_Format.ulWidth = (640 / 4);
UpdateSizeDisplay (hDlg, pBoard->CfgSource.VideoStd);
break;
case ID_PBSIZEEIGHTH:
Dlg_Format.ulWidth = (640 / 8);
UpdateSizeDisplay (hDlg, pBoard->CfgSource.VideoStd);
break;
case ID_DEFAULT:
cfg_SetDefaultFormat(&Dlg_Format, NULL);
UpdateSizeDisplay(hDlg, pBoard->CfgSource.VideoStd);
ConfigSetComboBoxSelection(
hDlg,
ID_LBIMAGEFORMAT,
gwFormatOptions,
N_FORMATOPTIONS,
Dlg_Format.Format);
break;
default:
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
/*
* process a scroll message for one of the colour adjustment fields
*/
int
ColorProcessScroll(
HWND hDlg,
HWND hCtl,
UINT Code,
UINT Pos,
int iVal,
DWORD wIDEditBox,
int iMaxValue
)
{
switch (Code) {
case SB_LINEDOWN:
iVal++;
break;
case SB_LINEUP:
iVal--;
break;
case SB_PAGEDOWN:
iVal += iMaxValue / 8;
break;
case SB_PAGEUP:
iVal -= iMaxValue / 8;
break;
case SB_THUMBTRACK:
iVal = Pos;
break;
default:
break;
}
iVal = LIMIT_RANGE(iVal, 0, iMaxValue);
SetScrollRange(hCtl, SB_CTL, 0, iMaxValue, FALSE);
SetScrollPos( hCtl, SB_CTL, iVal, TRUE);
SetDlgItemInt(hDlg, wIDEditBox, iVal, TRUE);
return (iVal);
}
//
// Dialog proc for the video source dialog box (VIDEO_EXTERNALIN channel)
//
int
VideoSourceDlgProc(HWND hDlg, UINT msg, UINT wParam, LONG lParam)
{
HWND hCtl;
UINT wID;
PBU_INFO pBoard;
BITMAPINFOHEADER bi;
if (msg != WM_INITDIALOG) {
pBoard = (PBU_INFO) GetWindowLong(hDlg, DWL_USER);
}
switch (msg)
{
case WM_INITDIALOG:
/*
* pointer to board structure is passed
* as dialog param- save in spare window long
*/
pBoard = (PBU_INFO) lParam;
SetWindowLong(hDlg, DWL_USER, (LONG) pBoard);
/*
* make a copy of the current config settings
*/
Dlg_Source = pBoard->CfgSource;
// Hue
hCtl = GetDlgItem (hDlg, ID_SBHUE);
SetScrollRange ( hCtl, SB_CTL, 0, MAX_HUE, FALSE);
// Intentional fall through
case WM_UPDATEDIALOG:
/*
* write current values to the driver so that user can
* get some feedback
*/
VC_ConfigSource(pBoard->vh, (PCONFIG_INFO) &Dlg_Source);
/*
* update radio button settings to current values
*/
CheckRadioButton(
hDlg,
ID_PBNTSC,
ID_PBSECAM,
ID_PBNTSC + Dlg_Source.VideoStd);
CheckRadioButton(
hDlg,
ID_PBCOMPOSITE,
ID_AUTODETECT,
ID_PBCOMPOSITE + Dlg_Source.VideoSrc);
// Hue
hCtl = GetDlgItem (hDlg, ID_SBHUE);
SetScrollPos(hCtl, SB_CTL, Dlg_Source.ulHue, TRUE);
SetDlgItemInt(hDlg, ID_EBHUE, Dlg_Source.ulHue, FALSE);
//VCR source flag
CheckDlgButton(hDlg, ID_VCRSOURCE, Dlg_Source.bVCR);
break;
// User will unload this module at exit time, so make
// sure that the dialog is gone if the user just quits
// Windows with the dialog box up.
case WM_ENDSESSION:
if (wParam)
EndDialog (hDlg, IDCANCEL);
break;
case WM_HSCROLL:
hCtl = GET_WM_HSCROLL_HWND(wParam, lParam);
wID = GetWindowLong(hCtl, GWL_ID);
switch (wID) {
case ID_SBHUE:
Dlg_Source.ulHue = ColorProcessScroll(
hDlg,
hCtl,
GET_WM_HSCROLL_CODE(wParam, lParam),
GET_WM_HSCROLL_POS(wParam, lParam),
Dlg_Source.ulHue,
ID_EBHUE,
MAX_HUE);
VC_ConfigSource(pBoard->vh, (PCONFIG_INFO) &Dlg_Source);
break;
default:
break;
}
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
/*
* pick up hue in case we never saw a focus-loss msg
*/
Dlg_Source.ulHue = GetDlgItemInt (hDlg, ID_EBHUE, NULL, FALSE);
Dlg_Source.ulHue = LIMIT_RANGE(Dlg_Source.ulHue, 0, MAX_HUE);
VC_ConfigSource(pBoard->vh, (PCONFIG_INFO) &Dlg_Source);
/* we also need to change the size of the video if
* the video standard has changed.
*/
if (Dlg_Source.VideoStd != pBoard->CfgSource.VideoStd) {
InitDestBIHeader (
&bi,
pBoard->CfgFormat.Format,
pBoard->CfgFormat.ulWidth,
Dlg_Source.VideoStd);
SetDestFormat (&bi, sizeof (bi));
}
/*
* copy the temporary settings (already written to
* the driver) back to the main table.
*/
pBoard->CfgSource = Dlg_Source;
/*
* write settings to profile
*/
cfg_SaveSource(pBoard);
EndDialog(hDlg, IDOK);
break;
case IDCANCEL:
// Fix, restore all values
VC_ConfigSource(pBoard->vh,
(PCONFIG_INFO) &pBoard->CfgSource);
EndDialog(hDlg, IDCANCEL);
break;
case ID_PBDEFAULT:
cfg_SetDefaultSource(&Dlg_Source, NULL);
VC_ConfigSource(pBoard->vh, (PCONFIG_INFO) &Dlg_Source);
SendMessage (hDlg, WM_UPDATEDIALOG, 0, 0L);
break;
case ID_AUTODETECT:
case ID_PBCOMPOSITE:
case ID_PBSVIDEO:
Dlg_Source.VideoSrc =
GET_WM_COMMAND_ID(wParam,lParam) - ID_PBCOMPOSITE;
SendMessage (hDlg, WM_UPDATEDIALOG, 0, 0L);
break;
case ID_PBNTSC:
Dlg_Source.VideoStd = NTSC;
SendMessage (hDlg, WM_UPDATEDIALOG, 0, 0L);
break;
case ID_PBPAL:
Dlg_Source.VideoStd = PAL;
SendMessage (hDlg, WM_UPDATEDIALOG, 0, 0L);
break;
case ID_PBSECAM:
Dlg_Source.VideoStd = SECAM;
SendMessage (hDlg, WM_UPDATEDIALOG, 0, 0L);
break;
case ID_EBHUE:
if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_KILLFOCUS) {
Dlg_Source.ulHue = GetDlgItemInt (hDlg, ID_EBHUE, NULL, FALSE);
Dlg_Source.ulHue = LIMIT_RANGE(Dlg_Source.ulHue, 0, MAX_HUE);
SendMessage (hDlg, WM_UPDATEDIALOG, 0, 0L);
}
break;
case ID_VCRSOURCE:
Dlg_Source.bVCR = IsDlgButtonChecked(hDlg, ID_VCRSOURCE);
SendMessage(hDlg, WM_UPDATEDIALOG, 0, 0L);
break;
default:
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
/*
* initialise board and structure to saved/default settings of config variables
*
* Reads all config settings from the profile / registry entry, or sets
* to default if can't be read.
*/
VOID
cfg_InitDefaults(PBU_INFO pBoard)
{
/*
* read default or saved source setup
*/
cfg_SetDefaultSource(&pBoard->CfgSource, pBoard->pProfile);
/*
* write to device
*/
VC_ConfigSource(pBoard->vh, (PCONFIG_INFO)&pBoard->CfgSource);
/*
* read default or saved format settings
*/
cfg_SetDefaultFormat(&pBoard->CfgFormat, pBoard->pProfile);
/*
* set BitmapInfoHeader from format and height x width
*/
InitDestBIHeader(
&pBoard->biDest,
pBoard->CfgFormat.Format,
pBoard->CfgFormat.ulWidth,
pBoard->CfgSource.VideoStd
);
/*
* write format info to device
*/
VC_ConfigFormat(pBoard->vh, (PCONFIG_INFO)&pBoard->CfgFormat);
}
/*
* initialise structure to default values. Then read in any saved settings
* from profile if pProf is non-null, otherwise leave as default.
*/
VOID
cfg_SetDefaultFormat(PCONFIG_FORMAT pFormat, PVC_PROFILE_INFO pProf)
{
pFormat->Format = FmtPal8;
pFormat->ulWidth = 160;
pFormat->ulHeight = 120;
if (pProf) {
pFormat->Format = VC_ReadProfileUser(pProf, PARAM_FORMAT, pFormat->Format);
pFormat->ulWidth = VC_ReadProfileUser(pProf, PARAM_WIDTH, pFormat->ulWidth);
pFormat->ulHeight = VC_ReadProfileUser(pProf, PARAM_HEIGHT, pFormat->ulHeight);
}
}
/*
* write new format info to the profile from the pBoardInfo structure
*/
VOID
cfg_SaveFormat(PBU_INFO pBoard)
{
PCONFIG_FORMAT pFormat = &pBoard->CfgFormat;
VC_WriteProfileUser(pBoard->pProfile, PARAM_FORMAT, pFormat->Format);
VC_WriteProfileUser(pBoard->pProfile, PARAM_WIDTH, pFormat->ulWidth);
VC_WriteProfileUser(pBoard->pProfile, PARAM_HEIGHT, pFormat->ulHeight);
}
/*
* init source config data to default values, then overwrite with
* saved values from profile if pProf given and the values can be
* read
*/
VOID
cfg_SetDefaultSource(PCONFIG_SOURCE pSource, PVC_PROFILE_INFO pProf)
{
pSource->ulHue = DEFAULT_HUE;
pSource->VideoStd = NTSC;
pSource->VideoSrc = SourceAuto; // default for User level driver
pSource->bVCR = FALSE;
if (pProf) {
pSource->ulHue = VC_ReadProfileUser(pProf, PARAM_HUE, pSource->ulHue);
pSource->VideoStd = VC_ReadProfileUser(pProf, PARAM_VIDEOSTD, pSource->VideoStd);
pSource->VideoSrc = VC_ReadProfileUser(pProf, PARAM_CONNECTOR, pSource->VideoSrc);
pSource->bVCR = VC_ReadProfileUser(pProf, PARAM_VCR, pSource->bVCR);
#if DBG
// Assertions:
// VideoSrc is SVideo, Composite or SourceAuto
// ulHue is in range 0-0xFF
// VideoStd is NTSC, Pal or Secam (0 -> MAXVIDEOSTD-1)
// bVCR is a boolean value
#endif
}
}
VOID
cfg_SaveSource(PBU_INFO pBoard)
{
PCONFIG_SOURCE pSource = &pBoard->CfgSource;
VC_WriteProfileUser(pBoard->pProfile, PARAM_HUE, pSource->ulHue);
VC_WriteProfileUser(pBoard->pProfile, PARAM_VIDEOSTD, pSource->VideoStd);
VC_WriteProfileUser(pBoard->pProfile, PARAM_CONNECTOR, pSource->VideoSrc);
VC_WriteProfileUser(pBoard->pProfile, PARAM_VCR, pSource->bVCR);
}
VOID
cfg_InitLocation(PVC_PROFILE_INFO pProf, PCONFIG_LOCATION pLoc)
{
pLoc->Interrupt = VC_ReadProfile(
pProf, // registry handles etc
PARAM_INTERRUPT, // value name
DEF_INTERRUPT); // default value if not in registry
pLoc->FifoWindow = VC_ReadProfile(
pProf, // registry handles etc
PARAM_FIFO, // value name
DEF_FIFO); // default value if not in registry
}
/*
* read the version info for this driver and display in the dialog box
*/
VOID
cfg_SetDialogVersionText(HWND hDlg)
{
LPTSTR lpVersion;
DWORD dwVersionLen;
BOOL bRetCode;
TCHAR szGetName[MAX_PATH];
DWORD dwVerInfoSize;
DWORD dwVerHnd;
TCHAR szBuf[MAX_PATH];
// All this junk just to get the version???
GetModuleFileName (ghModule, szBuf, sizeof (szBuf));
// You must find the file info size first before getting any file info
dwVerInfoSize =
GetFileVersionInfoSize(szBuf, &dwVerHnd);
if (dwVerInfoSize) {
LPBYTE lpstrVffInfo; // Pointer to block to hold info
HANDLE hMem; // handle to mem alloc'ed
// Get a block big enough to hold version info
hMem = GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
lpstrVffInfo = GlobalLock(hMem);
// Get the File Version first
if(GetFileVersionInfo(szBuf, 0L, dwVerInfoSize, lpstrVffInfo)) {
VS_FIXEDFILEINFO * pVerInfo;
/*
* get the VS_FIXEDFILEINFO in the root block
*/
bRetCode = VerQueryValue(
lpstrVffInfo, // version resource
TEXT("\\"), // fetch root VS_FIXEDFILEINFO
(PVOID *) &pVerInfo, // pointer to it goes here
&dwVersionLen); // length of it goes here
if (bRetCode && (dwVersionLen > 0) && (pVerInfo != NULL)) {
// fill in the file version
wsprintf(szBuf,
TEXT("Version: %d.%d.%d.%d"),
HIWORD(pVerInfo->dwFileVersionMS),
LOWORD(pVerInfo->dwFileVersionMS),
HIWORD(pVerInfo->dwFileVersionLS),
LOWORD(pVerInfo->dwFileVersionLS));
SetDlgItemText(hDlg, ID_DRIVERVERSION, szBuf);
}
}
// Now try to get the FileDescription
// Do this for the American english translation by default.
// Keep track of the string length for easy updating.
// 040904B0 - US, Unicode.
lstrcpy(szGetName, TEXT("\\StringFileInfo\\040904B0\\FileDescription"));
dwVersionLen = 0;
lpVersion = NULL;
// Look for the corresponding string.
bRetCode = VerQueryValue((LPVOID)lpstrVffInfo,
(LPTSTR)szGetName,
(void FAR* FAR*)&lpVersion,
&dwVersionLen);
if ( bRetCode && dwVersionLen && lpVersion) {
SetDlgItemText(hDlg, ID_FILEDESCRIPTION, lpVersion);
} else {
dprintf(("bRetCode %d, VerLen %d, lpversion 0x%d",
bRetCode, dwVersionLen, lpVersion));
}
// Let go of the memory
GlobalUnlock(hMem);
GlobalFree(hMem);
}
}