mirror of https://github.com/tongzx/nt5src
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.
2171 lines
63 KiB
2171 lines
63 KiB
//****************************************************************************
|
|
//
|
|
// File: joycpl.c
|
|
// Content: Joystick configuration and testing
|
|
// History:
|
|
// Date By Reason
|
|
// ==== == ======
|
|
// 03-oct-94 craige initial implementation
|
|
// 05-nov-94 craige generalized 4 axis joysticks and other improvements
|
|
// 11-nov-94 craige allow multiple copies of tab to run
|
|
// 22-nov-94 craige tweaks to calibration code
|
|
// 29-nov-94 craige small bugs
|
|
// 08-dec-94 craige generalized second joystick
|
|
// 11-dec-94 craige split into component parts
|
|
// 15-dec-94 craige allow N joysticks
|
|
// 18-dec-94 craige process UV
|
|
// 05-jan-95 craige external rudder bug
|
|
// 05-mar-95 craige Bug 9998: pass id -1 to get base dev caps
|
|
// Bug 15334: allow reset of user values for compatiblity
|
|
// 06-mar-95 craige Bug 7608: deleting VxD name if joystick not present
|
|
// caused unplugged joystick to never come back
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1994
|
|
//
|
|
//****************************************************************************
|
|
|
|
#pragma pack (8)
|
|
|
|
#include "stdafx.h"
|
|
#include "assert.h"
|
|
|
|
#include "joycpl.h"
|
|
#include "resource.h"
|
|
|
|
#include "baseids.h"
|
|
#include "pov.h"
|
|
|
|
#include "pinfo.h"
|
|
#include "comstr.h"
|
|
|
|
#include "joyarray.h" // Help array
|
|
|
|
extern USHORT gnID; // ID as sent from Client via SetID
|
|
extern BOOL fIsSideWinder;
|
|
static BOOL fIsLoaded = 0;
|
|
|
|
// Context sensitive help stuff!
|
|
static void OnContextMenu(WPARAM wParam);
|
|
extern const DWORD gaHelpIDs[];
|
|
|
|
#ifdef DEBUG
|
|
void cdecl MBOX(LPSTR szFormat, ...)
|
|
{
|
|
char ach[256];
|
|
|
|
wvsprintf( ach,szFormat,(LPSTR)(&szFormat+1));
|
|
MessageBox( NULL, ach, "JOYCPL", MB_OK | MB_SYSTEMMODAL );
|
|
|
|
}
|
|
#endif
|
|
|
|
extern "C" WINMMAPI MMRESULT WINAPI joyConfigChanged(DWORD);
|
|
|
|
/***************************************************************************
|
|
|
|
|
|
MEMORY MANAGEMENT ROUTINES FOLLOW
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
#ifdef DEBUG
|
|
DWORD allocCount;
|
|
#endif
|
|
|
|
// DoAlloc - allocate memory
|
|
LPVOID DoAlloc( DWORD size )
|
|
{
|
|
LPVOID res;
|
|
|
|
res = LocalAlloc( LPTR, size );
|
|
#ifdef DEBUG
|
|
allocCount++;
|
|
#endif
|
|
return(res);
|
|
|
|
} /* DoAlloc */
|
|
|
|
/*
|
|
* DoFree - free allocated memory
|
|
*/
|
|
void DoFree( LPVOID ptr )
|
|
{
|
|
if( ptr != NULL )
|
|
{
|
|
LocalFree( ptr );
|
|
#ifdef DEBUG
|
|
allocCount--;
|
|
if( allocCount < 0 )
|
|
{
|
|
DPF( "JOYCPL: Too many frees, allocCount=%d\r\n", allocCount );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
} /* DoFree */
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
|
|
REGISTRY RELATED ROUTINES FOLLOW
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
// getDevCaps - get the joystick device caps
|
|
static void getDevCaps( LPGLOBALVARS pgv )
|
|
{
|
|
JOYCAPS jc;
|
|
|
|
if( joyGetDevCaps( pgv->iJoyId, &jc, sizeof( jc ) ) == JOYERR_NOERROR )
|
|
{
|
|
pgv->joyRange.jpMin.dwX = jc.wXmin;
|
|
pgv->joyRange.jpMax.dwX = jc.wXmax;
|
|
pgv->joyRange.jpMin.dwY = jc.wYmin;
|
|
pgv->joyRange.jpMax.dwY = jc.wYmax;
|
|
pgv->joyRange.jpMin.dwZ = jc.wZmin;
|
|
pgv->joyRange.jpMax.dwZ = jc.wZmax;
|
|
pgv->joyRange.jpMin.dwR = jc.wRmin;
|
|
pgv->joyRange.jpMax.dwR = jc.wRmax;
|
|
pgv->joyRange.jpMin.dwU = jc.wUmin;
|
|
pgv->joyRange.jpMax.dwU = jc.wUmax;
|
|
pgv->joyRange.jpMin.dwV = jc.wVmin;
|
|
pgv->joyRange.jpMax.dwV = jc.wVmax;
|
|
pgv->dwMaxAxes = (DWORD) jc.wMaxAxes;
|
|
}
|
|
|
|
} /* getDevCaps */
|
|
|
|
/*
|
|
* RegistryUpdated - notify the driver that the registry is updated
|
|
*/
|
|
void RegistryUpdated( LPGLOBALVARS pgv )
|
|
{
|
|
// joyConfigChanged( 0 );
|
|
if( pgv != NULL )
|
|
getDevCaps( pgv ); // devcaps could change
|
|
|
|
} /* RegistryUpdated */
|
|
|
|
/*
|
|
* createSettingsKeyFromCurr - create a settings key for a specific joystick
|
|
*/
|
|
static void createSettingsKeyFromCurr( LPGLOBALVARS pgv, LPSTR str )
|
|
{
|
|
assert(pgv);
|
|
|
|
char tmp[MAX_STR];
|
|
int type;
|
|
LPJOYDATA pjd;
|
|
|
|
pjd = pgv->pjd;
|
|
assert(pjd);
|
|
|
|
if( pgv->joyHWCurr.dwUsageSettings & JOY_US_ISOEM )
|
|
{
|
|
type = pgv->joyHWCurr.dwType - JOY_HW_LASTENTRY;
|
|
|
|
if( type < 0 || type >= pjd->oemCount )
|
|
tmp[0] = 0;
|
|
else
|
|
lstrcpy( tmp, pjd->oemList[type].keyname );
|
|
} else wsprintf( tmp, "predef%d", pgv->joyHWCurr.dwType );
|
|
|
|
wsprintf( str, "%s\\%s", pjd->regSettingsCfgKey, tmp );
|
|
|
|
} /* createSettingsKeyFromCurr */
|
|
|
|
static CListBox ChangeListCtrl;
|
|
|
|
// regSaveSpecificJoyHW - save specific joystick hardware config. to the registry
|
|
static void regSaveSpecificJoyHW( LPGLOBALVARS pgv )
|
|
{
|
|
assert(pgv);
|
|
|
|
char str[MAX_STR];
|
|
HKEY hkey;
|
|
char jcfg[MAX_STR];
|
|
|
|
if( pgv->joyHWCurr.dwType == JOY_HW_NONE ) return;
|
|
|
|
createSettingsKeyFromCurr( pgv, str );
|
|
|
|
if( !RegCreateKey( HKEY_LOCAL_MACHINE, str, &hkey ) )
|
|
{
|
|
GETKEYNAME( pgv, jcfg, REGSTR_VAL_JOYNCONFIG );
|
|
RegSetValueEx( hkey, jcfg, 0, REG_BINARY, (CONST LPBYTE)&pgv->joyHWCurr, sizeof( pgv->joyHWCurr ));
|
|
RegCloseKey( hkey );
|
|
}
|
|
|
|
} /* regSaveSpecificJoyHW */
|
|
|
|
/*
|
|
* regCreateCurrKey - create the current joystick settings key
|
|
*/
|
|
static HKEY regCreateCurrKey( LPGLOBALVARS pgv )
|
|
{
|
|
assert(pgv);
|
|
|
|
HKEY hkey;
|
|
|
|
if( !RegCreateKey( HKEY_LOCAL_MACHINE, pgv->pjd->regCurrCfgKey, &hkey ) )
|
|
return(hkey);
|
|
else
|
|
return(NULL);
|
|
|
|
} /* regCreateCurrKey */
|
|
|
|
// RegSaveCurrentJoyHW - save the joystick info to the current entry in the registry
|
|
void RegSaveCurrentJoyHW( LPGLOBALVARS pgv )
|
|
{
|
|
HKEY hkey;
|
|
LPSTR sptr;
|
|
char vname[MAX_STR];
|
|
char oname[MAX_STR];
|
|
char coname[MAX_STR];
|
|
int type;
|
|
LPJOYDATA pjd;
|
|
|
|
assert(pgv);
|
|
|
|
hkey = regCreateCurrKey( pgv );
|
|
assert(hkey);
|
|
|
|
if( hkey == NULL )
|
|
{
|
|
DPF( "Could not save current joystick settings!\r\n" );
|
|
return;
|
|
}
|
|
|
|
pjd = pgv->pjd;
|
|
assert(pjd);
|
|
|
|
if( pgv->joyHWCurr.dwUsageSettings & JOY_US_ISOEM )
|
|
sptr = pjd->oemList[ pgv->joyHWCurr.dwType - JOY_HW_LASTENTRY ].keyname;
|
|
|
|
GETKEYNAME( pgv, vname, REGSTR_VAL_JOYNCONFIG );
|
|
GETKEYNAME( pgv, oname, REGSTR_VAL_JOYNOEMNAME );
|
|
GETKEYNAME( pgv, coname, REGSTR_VAL_JOYNOEMCALLOUT );
|
|
|
|
RegSetValueEx( hkey, vname, 0, REG_BINARY, (CONST LPBYTE)&pgv->joyHWCurr, sizeof( pgv->joyHWCurr ) );
|
|
if( pgv->joyHWCurr.dwUsageSettings & JOY_US_ISOEM )
|
|
{
|
|
RegSetValueEx( hkey, oname, 0, REG_SZ,(const unsigned char *) sptr, strlen( sptr ) + 1 );
|
|
|
|
// set up VxD name for this joystick
|
|
type = pgv->joyHWCurr.dwType - JOY_HW_LASTENTRY;
|
|
if( (pjd->oemList[type].vxd_name[0] != 0) )
|
|
{
|
|
RegSetValueEx( hkey, coname, 0, REG_SZ, (const unsigned char *) pjd->oemList[type].vxd_name,
|
|
lstrlen( pjd->oemList[type].vxd_name )+1 );
|
|
} else RegDeleteValue( hkey, coname );
|
|
} else
|
|
{
|
|
RegDeleteValue( hkey, oname );
|
|
RegDeleteValue( hkey, coname );
|
|
}
|
|
|
|
RegCloseKey( hkey );
|
|
|
|
} /* RegSaveCurrentJoyHW */
|
|
|
|
// regPermSaveAllInfo - save joystick data to the registry for good
|
|
static void regPermSaveAllInfo( LPGLOBALVARS pgv )
|
|
{
|
|
|
|
assert(pgv);
|
|
|
|
// save specific hardware settings to the registry
|
|
regSaveSpecificJoyHW( pgv );
|
|
|
|
// save current current hardware to the registry
|
|
RegSaveCurrentJoyHW( pgv );
|
|
|
|
RegistryUpdated( pgv );
|
|
|
|
} /* regPermSaveAllInfo */
|
|
|
|
// setHWCurrType - set the current hardware type (check for OEM type)
|
|
static BOOL setHWCurrType( LPGLOBALVARS pgv, HKEY hkey, LPJOYREGHWCONFIG pcfg )
|
|
{
|
|
assert(pgv);
|
|
assert(hkey);
|
|
assert(pcfg);
|
|
|
|
char str[MAX_STR];
|
|
char pname[MAX_STR];
|
|
int i;
|
|
DWORD regtype;
|
|
DWORD cb;
|
|
LPJOYDATA pjd;
|
|
|
|
if( !(pcfg->dwUsageSettings & JOY_US_ISOEM) )
|
|
return(TRUE);
|
|
|
|
GETKEYNAME( pgv, pname, REGSTR_VAL_JOYNOEMNAME );
|
|
cb = sizeof( str );
|
|
if( RegQueryValueEx( hkey, pname, NULL, ®type, (CONST LPBYTE)str, &cb) )
|
|
return(FALSE);
|
|
|
|
if( regtype != REG_SZ )
|
|
return(FALSE);
|
|
|
|
pjd = pgv->pjd;
|
|
assert(pjd);
|
|
|
|
for( i=0;i<pjd->oemCount;i++ )
|
|
{
|
|
if( !lstrcmpi( str, pjd->oemList[i].keyname ) )
|
|
{
|
|
pcfg->dwType = i + JOY_HW_LASTENTRY;
|
|
return(TRUE);
|
|
}
|
|
}
|
|
return(FALSE);
|
|
|
|
} /* setHWCurrType */
|
|
|
|
// regGetCurrHW - get the information about the current configuration from the registry
|
|
static void regGetCurrHW( LPGLOBALVARS pgv )
|
|
{
|
|
assert(pgv);
|
|
|
|
DWORD regtype;
|
|
DWORD cb;
|
|
JOYREGHWCONFIG config;
|
|
HKEY hkey;
|
|
char str[MAX_STR];
|
|
|
|
if( hkey = regCreateCurrKey( pgv ) )
|
|
{
|
|
cb = sizeof( config );
|
|
GETKEYNAME( pgv, str, REGSTR_VAL_JOYNCONFIG );
|
|
|
|
if( !RegQueryValueEx( hkey, str, NULL, ®type, (CONST LPBYTE)&config, &cb) )
|
|
{
|
|
if( regtype == REG_BINARY && cb == sizeof( config ) )
|
|
{
|
|
if( setHWCurrType( pgv, hkey, &config ) )
|
|
pgv->joyHWCurr = config;
|
|
}
|
|
}
|
|
}
|
|
|
|
cb = sizeof( config );
|
|
RegCloseKey( hkey );
|
|
|
|
} /* regGetCurrHW */
|
|
|
|
// regGetOEMStr - get an OEM string
|
|
static BOOL regGetOEMStr( HKEY hkey, LPSTR keyname, LPSTR buff, int size, LPSTR *res )
|
|
{
|
|
assert(hkey);
|
|
assert(keyname);
|
|
|
|
DWORD cb;
|
|
DWORD type;
|
|
LPSTR str;
|
|
int slen;
|
|
|
|
cb = size;
|
|
slen = 1;
|
|
if( !RegQueryValueEx( hkey, keyname, NULL, &type, (CONST LPBYTE)buff, &cb ) )
|
|
{
|
|
if( type == REG_SZ )
|
|
slen = strlen( buff ) + 1;
|
|
}
|
|
|
|
str = (char *) DoAlloc( slen );
|
|
assert(str);
|
|
if( str != NULL )
|
|
{
|
|
if( slen == 1 )
|
|
str[0] = 0;
|
|
else
|
|
lstrcpy( str, buff );
|
|
}
|
|
|
|
*res = str;
|
|
|
|
if( str == NULL )
|
|
return(TRUE);
|
|
|
|
return(FALSE);
|
|
|
|
} /* regGetOEMStr */
|
|
|
|
#define RANGE_MIN 0
|
|
#define RANGE_MAX 65535
|
|
|
|
/*
|
|
* checkNonStandardUserVals
|
|
*/
|
|
static BOOL checkNonStandardUserVals( LPJOYREGUSERVALUES puv )
|
|
{
|
|
assert(puv);
|
|
|
|
if( (puv->jrvRanges.jpMin.dwX != RANGE_MIN) ||
|
|
(puv->jrvRanges.jpMin.dwY != RANGE_MIN) ||
|
|
(puv->jrvRanges.jpMin.dwZ != RANGE_MIN) ||
|
|
(puv->jrvRanges.jpMin.dwR != RANGE_MIN) ||
|
|
(puv->jrvRanges.jpMin.dwU != RANGE_MIN) ||
|
|
(puv->jrvRanges.jpMin.dwV != RANGE_MIN) ||
|
|
(puv->jrvRanges.jpMax.dwX != RANGE_MAX) ||
|
|
(puv->jrvRanges.jpMax.dwY != RANGE_MAX) ||
|
|
(puv->jrvRanges.jpMax.dwZ != RANGE_MAX) ||
|
|
(puv->jrvRanges.jpMax.dwR != RANGE_MAX) ||
|
|
(puv->jrvRanges.jpMax.dwU != RANGE_MAX) ||
|
|
(puv->jrvRanges.jpMax.dwV != RANGE_MAX) ||
|
|
(puv->dwTimeOut != 0x1000) ||
|
|
(puv->jpDeadZone.dwX != 0) ||
|
|
(puv->jpDeadZone.dwY != 0) )
|
|
{
|
|
return(TRUE);
|
|
}
|
|
return(FALSE);
|
|
|
|
} /* checkNonStandardUserVals */
|
|
|
|
// regSetUserVals - set user values to our defaults
|
|
static void regSetUserVals( LPJOYDATA pjd, BOOL retest )
|
|
{
|
|
assert(pjd);
|
|
|
|
JOYREGUSERVALUES uv;
|
|
JOYREGUSERVALUES ouv;
|
|
HKEY hkey;
|
|
DWORD regtype;
|
|
DWORD cb;
|
|
|
|
if( !RegOpenKey( HKEY_LOCAL_MACHINE, pjd->regCfgKey, &hkey ) )
|
|
{
|
|
/*
|
|
* build the default settings
|
|
*/
|
|
memset( &uv, 0, sizeof( uv ) );
|
|
|
|
// fix #2245, take the Greater of the two timeout values.
|
|
uv.dwTimeOut = (pjd->userVals.dwTimeOut > 0x1000) ? pjd->userVals.dwTimeOut : 0x1000;
|
|
|
|
uv.jpDeadZone.dwX = 0;
|
|
uv.jpDeadZone.dwY = 0;
|
|
uv.jrvRanges.jpMin.dwX = RANGE_MIN;
|
|
uv.jrvRanges.jpMin.dwY = RANGE_MIN;
|
|
uv.jrvRanges.jpMin.dwZ = RANGE_MIN;
|
|
uv.jrvRanges.jpMin.dwR = RANGE_MIN;
|
|
uv.jrvRanges.jpMin.dwU = RANGE_MIN;
|
|
uv.jrvRanges.jpMin.dwV = RANGE_MIN;
|
|
uv.jrvRanges.jpMax.dwX = RANGE_MAX;
|
|
uv.jrvRanges.jpMax.dwY = RANGE_MAX;
|
|
uv.jrvRanges.jpMax.dwZ = RANGE_MAX;
|
|
uv.jrvRanges.jpMax.dwR = RANGE_MAX;
|
|
uv.jrvRanges.jpMax.dwU = RANGE_MAX;
|
|
uv.jrvRanges.jpMax.dwV = RANGE_MAX;
|
|
|
|
if( retest )
|
|
{
|
|
/*
|
|
* see if the values have changed since we last set them:
|
|
* if yes, then we need to reset our remembered values
|
|
*/
|
|
DPF( "Looking for USER entries\r\n" );
|
|
cb = sizeof( ouv );
|
|
if( !RegQueryValueEx( hkey, REGSTR_VAL_JOYUSERVALUES, NULL,
|
|
®type, (CONST LPBYTE)&ouv, &cb) )
|
|
{
|
|
DPF( "found REGSTR_VAL_JOYUSERVALUES\r\n" );
|
|
if( regtype == REG_BINARY && cb == sizeof( ouv ) )
|
|
{
|
|
if( memcmp( &uv, &ouv, sizeof( uv ) ) )
|
|
{
|
|
DPF( "USER entries changed!\r\n" );
|
|
pjd->bHasUserVals = TRUE;
|
|
pjd->bDeleteUserVals = FALSE;
|
|
pjd->userVals = ouv;
|
|
}
|
|
}
|
|
} else
|
|
{
|
|
if( pjd->bHasUserVals )
|
|
{
|
|
DPF( "USER entries changed, no longer exist!\r\n" );
|
|
pjd->bHasUserVals = FALSE;
|
|
pjd->bDeleteUserVals = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* set our new values
|
|
*/
|
|
RegSetValueEx( hkey, REGSTR_VAL_JOYUSERVALUES, 0, REG_BINARY,
|
|
(CONST LPBYTE)&uv, sizeof( uv ) );
|
|
RegCloseKey( hkey );
|
|
}
|
|
|
|
} /* regSetUserVals */
|
|
|
|
// regUserValsInit - save old user values, and init to ones we like
|
|
static void regUserValsInit( LPJOYDATA pjd )
|
|
{
|
|
assert(pjd);
|
|
|
|
HKEY hkey;
|
|
DWORD regtype;
|
|
DWORD cb;
|
|
|
|
pjd->bHasUserVals = FALSE;
|
|
pjd->bDeleteUserVals = FALSE;
|
|
|
|
if( !RegOpenKey( HKEY_LOCAL_MACHINE, pjd->regCfgKey, &hkey ) )
|
|
{
|
|
cb = sizeof( pjd->userVals );
|
|
|
|
if( !RegQueryValueEx( hkey, REGSTR_VAL_JOYUSERVALUES, NULL,
|
|
®type, (CONST LPBYTE)&pjd->userVals, &cb) )
|
|
{
|
|
if( regtype == REG_BINARY && cb == sizeof( pjd->userVals ) )
|
|
{
|
|
pjd->bHasUserVals = TRUE;
|
|
DPF( "USER entries exist!\r\n" );
|
|
}
|
|
|
|
pjd->bHasNonStandardUserVals = checkNonStandardUserVals( &pjd->userVals );
|
|
} else
|
|
{
|
|
pjd->bDeleteUserVals = TRUE;
|
|
pjd->bHasNonStandardUserVals = FALSE;
|
|
DPF( "USER entries don't exist!\r\n" );
|
|
}
|
|
|
|
RegCloseKey( hkey );
|
|
}
|
|
|
|
regSetUserVals( pjd, FALSE );
|
|
|
|
} /* regUserValsInit */
|
|
|
|
// regUserValsFini - restore old user values
|
|
static void regUserValsFini( LPJOYDATA pjd )
|
|
{
|
|
assert(pjd);
|
|
|
|
HKEY hkey = 0;
|
|
|
|
if( pjd->bHasUserVals || pjd->bDeleteUserVals )
|
|
{
|
|
if( !RegOpenKey( HKEY_LOCAL_MACHINE, pjd->regCfgKey, &hkey ) )
|
|
{
|
|
if( pjd->bHasUserVals )
|
|
{
|
|
DPF( "resetting USER entries!\r\n" );
|
|
RegSetValueEx( hkey, REGSTR_VAL_JOYUSERVALUES, 0, REG_BINARY,
|
|
(CONST LPBYTE)&pjd->userVals, sizeof( pjd->userVals ) );
|
|
} else
|
|
{
|
|
DPF( "deleting USER entries!\r\n" );
|
|
RegDeleteValue( hkey, REGSTR_VAL_JOYUSERVALUES );
|
|
}
|
|
RegistryUpdated( NULL );
|
|
}
|
|
pjd->bHasUserVals = FALSE;
|
|
pjd->bDeleteUserVals = FALSE;
|
|
}
|
|
|
|
} /* regUserValsFini */
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
|
|
CUSTOM JOYSTICK SELECTION FUNCTIONS FOLLOW
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
/*
|
|
* custom joystick variables
|
|
*/
|
|
typedef struct
|
|
{
|
|
LPGLOBALVARS pgv;
|
|
BOOL bHasZ;
|
|
BOOL bHasR;
|
|
BOOL bHasPOV;
|
|
BOOL bIsYoke;
|
|
BOOL bIsGamePad;
|
|
BOOL bIsCarCtrl;
|
|
BOOL bHas2Buttons;
|
|
} cust_vars, *LPCUSTVARS;
|
|
|
|
|
|
// enableCustomSpecial - enable the special section of the custom dialog box
|
|
static void enableCustomSpecial( HWND hwnd, BOOL on )
|
|
{
|
|
ASSERT (::IsWindow(hwnd));
|
|
|
|
HWND hCtrl = GetDlgItem( hwnd, IDC_JOYISYOKE );
|
|
ASSERT (::IsWindow(hCtrl));
|
|
EnableWindow( hCtrl, on );
|
|
|
|
hCtrl = GetDlgItem( hwnd, IDC_JOYISGAMEPAD );
|
|
ASSERT (::IsWindow(hCtrl));
|
|
EnableWindow( hCtrl, on );
|
|
|
|
hCtrl = GetDlgItem( hwnd, IDC_JOYISCARCTRL );
|
|
ASSERT (::IsWindow(hCtrl));
|
|
EnableWindow( hCtrl, on );
|
|
|
|
CheckDlgButton( hwnd, IDC_JOYUSESPECIAL, on );
|
|
|
|
if( !on )
|
|
{
|
|
CheckDlgButton( hwnd, IDC_JOYISYOKE, FALSE );
|
|
CheckDlgButton( hwnd, IDC_JOYISGAMEPAD, FALSE );
|
|
CheckDlgButton( hwnd, IDC_JOYISCARCTRL, FALSE );
|
|
}
|
|
|
|
} /* enableCustomSpecial */
|
|
|
|
|
|
// CustomProc - callback procedure for custom joystick setup
|
|
BOOL CALLBACK CustomProc( HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int id;
|
|
LPGLOBALVARS pgv;
|
|
LPCUSTVARS pcv;
|
|
|
|
switch( umsg )
|
|
{
|
|
case WM_DESTROY:
|
|
/*
|
|
* don't free the dialog's variables here, they are returned to the
|
|
* creator; the creator will free them
|
|
*/
|
|
break;
|
|
case WM_INITDIALOG:
|
|
// create variables for the custom dialog
|
|
pcv = (cust_vars *) DoAlloc( sizeof( cust_vars ) );
|
|
assert(pcv);
|
|
SetWindowLong( hwnd, DWL_USER, (LONG) pcv );
|
|
if( pcv == NULL )
|
|
{
|
|
EndDialog( hwnd, 0 );
|
|
return(FALSE);
|
|
}
|
|
pgv = (LPGLOBALVARS) lParam;
|
|
|
|
assert(pgv);
|
|
pcv->pgv = pgv;
|
|
|
|
// set up initial dialog state
|
|
pcv->bHasZ = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_HASZ);
|
|
pcv->bHasR = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_HASR);
|
|
pcv->bHas2Buttons = (pgv->joyHWCurr.hws.dwNumButtons == 2);
|
|
pcv->bHasPOV = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_HASPOV);
|
|
pcv->bIsYoke = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_ISYOKE);
|
|
pcv->bIsGamePad = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_ISGAMEPAD);
|
|
pcv->bIsCarCtrl = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_ISCARCTRL);
|
|
|
|
if( pcv->bHasZ && pcv->bHasR )
|
|
{
|
|
CheckRadioButton( hwnd, IDC_JOY2AXIS, IDC_JOY4AXIS, IDC_JOY4AXIS );
|
|
} else if( pcv->bHasZ )
|
|
{
|
|
CheckRadioButton( hwnd, IDC_JOY2AXIS, IDC_JOY4AXIS, IDC_JOY3AXIS );
|
|
} else
|
|
{
|
|
CheckRadioButton( hwnd, IDC_JOY2AXIS, IDC_JOY4AXIS, IDC_JOY2AXIS );
|
|
}
|
|
|
|
if( pcv->bHas2Buttons )
|
|
{
|
|
CheckRadioButton( hwnd, IDC_JOY2BUTTON, IDC_JOY4BUTTON, IDC_JOY2BUTTON );
|
|
} else
|
|
{
|
|
CheckRadioButton( hwnd, IDC_JOY2BUTTON, IDC_JOY4BUTTON, IDC_JOY4BUTTON );
|
|
}
|
|
|
|
CheckDlgButton( hwnd, IDC_JOYHASPOV, pcv->bHasPOV );
|
|
id = -1;
|
|
if( pcv->bIsYoke )
|
|
{
|
|
id = IDC_JOYISYOKE;
|
|
} else if( pcv->bIsGamePad )
|
|
{
|
|
id = IDC_JOYISGAMEPAD;
|
|
} else if( pcv->bIsCarCtrl )
|
|
{
|
|
id = IDC_JOYISCARCTRL;
|
|
}
|
|
if( id != -1 )
|
|
{
|
|
enableCustomSpecial( hwnd, TRUE );
|
|
CheckRadioButton( hwnd, IDC_JOYISYOKE, IDC_JOYISCARCTRL, id );
|
|
} else
|
|
{
|
|
enableCustomSpecial( hwnd, FALSE );
|
|
}
|
|
return(FALSE);
|
|
|
|
case WM_COMMAND:
|
|
pcv = (LPCUSTVARS) GetWindowLong( hwnd, DWL_USER );
|
|
id = GET_WM_COMMAND_ID(wParam, lParam);
|
|
switch( id )
|
|
{
|
|
case IDC_JOY2AXIS:
|
|
case IDC_JOY3AXIS:
|
|
case IDC_JOY4AXIS:
|
|
CheckRadioButton( hwnd, IDC_JOY2AXIS, IDC_JOY4AXIS, id );
|
|
pcv->bHasZ = FALSE;
|
|
pcv->bHasR = FALSE;
|
|
if( id == IDC_JOY3AXIS )
|
|
{
|
|
pcv->bHasZ = TRUE;
|
|
} else if( id == IDC_JOY4AXIS )
|
|
{
|
|
pcv->bHasZ = TRUE;
|
|
pcv->bHasR = TRUE;
|
|
}
|
|
break;
|
|
case IDC_JOY2BUTTON:
|
|
case IDC_JOY4BUTTON:
|
|
CheckRadioButton( hwnd, IDC_JOY2BUTTON, IDC_JOY4BUTTON, id );
|
|
pcv->bHas2Buttons = (id == IDC_JOY2BUTTON);
|
|
break;
|
|
case IDC_JOYUSESPECIAL:
|
|
enableCustomSpecial( hwnd, IsDlgButtonChecked( hwnd, IDC_JOYUSESPECIAL ) );
|
|
pcv->bIsYoke = FALSE;
|
|
pcv->bIsGamePad = FALSE;
|
|
pcv->bIsCarCtrl = FALSE;
|
|
break;
|
|
case IDC_JOYHASPOV:
|
|
pcv->bHasPOV = !pcv->bHasPOV;
|
|
break;
|
|
case IDC_JOYISYOKE:
|
|
case IDC_JOYISGAMEPAD:
|
|
case IDC_JOYISCARCTRL:
|
|
pcv->bIsYoke = (id == IDC_JOYISYOKE);
|
|
pcv->bIsGamePad = (id == IDC_JOYISGAMEPAD);
|
|
pcv->bIsCarCtrl = (id == IDC_JOYISCARCTRL);
|
|
CheckRadioButton( hwnd, IDC_JOYISYOKE, IDC_JOYISCARCTRL, id );
|
|
break;
|
|
case IDCANCEL:
|
|
EndDialog( hwnd, 0 );
|
|
break;
|
|
case IDOK:
|
|
pcv = (LPCUSTVARS) GetWindowLong( hwnd, DWL_USER );
|
|
EndDialog(hwnd, (int) pcv );
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return(FALSE);
|
|
|
|
} /* CustomProc */
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
|
|
MAIN DIALOG FUNCTIONS FOLLOW
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
// variables used by joystick tab dialog
|
|
typedef struct
|
|
{
|
|
LPGLOBALVARS pgv;
|
|
} JTVARS, *LPJTVARS;
|
|
|
|
// numJoyAxes - get number of axes on a joystick
|
|
static int numJoyAxes( LPGLOBALVARS pgv )
|
|
{
|
|
assert(pgv);
|
|
|
|
DWORD flags;
|
|
int axis_count;
|
|
|
|
flags = pgv->joyHWCurr.hws.dwFlags;
|
|
axis_count = 2;
|
|
if( flags & JOY_HWS_HASZ )
|
|
{
|
|
axis_count++;
|
|
}
|
|
if( flags & JOY_HWS_HASR )
|
|
{
|
|
axis_count++;
|
|
}
|
|
if( (flags & JOY_HWS_HASPOV) && (flags & JOY_HWS_POVISPOLL) )
|
|
{
|
|
axis_count++;
|
|
}
|
|
return(axis_count);
|
|
|
|
} /* numJoyAxes */
|
|
|
|
// saveHWSettings - save the current hardware settings
|
|
static void saveHWSettings( LPGLOBALVARS pgv )
|
|
{
|
|
assert(pgv);
|
|
|
|
pgv->joyHWOrig = pgv->joyHWCurr;
|
|
|
|
} /* saveHWSettings */
|
|
|
|
// restoreHWSettings - restore current hw settings to saved values
|
|
static void restoreHWSettings( LPGLOBALVARS pgv )
|
|
{
|
|
assert(pgv);
|
|
|
|
pgv->joyHWCurr = pgv->joyHWOrig;
|
|
RegSaveCurrentJoyHW( pgv );
|
|
|
|
} /* restoreHWSettings */
|
|
|
|
// getActiveFlags - poll and test which joysticks are currently plugged in
|
|
static unsigned getActiveFlags( LPGLOBALVARS pgv )
|
|
{
|
|
JOYINFOEX ji;
|
|
MMRESULT rc;
|
|
unsigned val;
|
|
|
|
assert(pgv);
|
|
|
|
// check for presense of joystick 1 and joystick 2
|
|
val = 0;
|
|
ji.dwSize = sizeof( ji );
|
|
ji.dwFlags = JOY_RETURNX|JOY_RETURNY|JOY_CAL_READXYONLY|JOY_CAL_READALWAYS;
|
|
rc = joyGetPosEx( pgv->iJoyId, &ji );
|
|
DPF( "joyGetPosEx = %d\r\n", rc );
|
|
if( rc == JOYERR_NOERROR )
|
|
{
|
|
val = HASJOY;
|
|
}
|
|
|
|
// check if either could have a rudder attached.
|
|
ji.dwFlags = JOY_RETURNR | JOY_CAL_READRONLY;
|
|
if( (numJoyAxes( pgv ) < 4) &&
|
|
!(pgv->joyHWCurr.hws.dwFlags & JOY_HWS_HASR ) )
|
|
{
|
|
rc = joyGetPosEx( pgv->iJoyId, &ji );
|
|
if( rc ==JOYERR_NOERROR )
|
|
{
|
|
val |= HASRUDDERMAYBE;
|
|
}
|
|
}
|
|
return(val);
|
|
|
|
} /* getActiveFlags */
|
|
|
|
// enableTestCal - enable/disable test and calibrate buttons
|
|
static void enableTestCal( HWND hwnd, int hw_type )
|
|
{
|
|
ASSERT(::IsWindow(hwnd));
|
|
|
|
BOOL enable = (hw_type != JOY_HW_NONE);
|
|
|
|
HWND hCtrl = GetDlgItem( hwnd, IDC_JOYCALIBRATE );
|
|
ASSERT (::IsWindow(hCtrl));
|
|
EnableWindow( hCtrl, enable );
|
|
} /* enableTestCal */
|
|
|
|
// cleanUpJoyDlg - clean up allocated stuff
|
|
static void cleanUpJoyDlg( HWND hwnd )
|
|
{
|
|
assert(hwnd);
|
|
|
|
LPGLOBALVARS pgv;
|
|
|
|
pgv = (LPGLOBALVARS) GetWindowLong( hwnd, DWL_USER );
|
|
if( pgv == NULL )
|
|
return;
|
|
|
|
// ditch timer
|
|
if( pgv->pjd->bHasTimer )
|
|
{
|
|
KillTimer( hwnd, TIMER_ID );
|
|
pgv->pjd->bHasTimer = FALSE;
|
|
}
|
|
|
|
// done with our variables
|
|
#if defined( WANT_SHEETS )
|
|
DoFree( pgv );
|
|
#endif
|
|
|
|
} /* cleanUpJoyDlg */
|
|
|
|
// enableJoyWindows - enable controls for a joystick
|
|
static void enableJoyWindows( LPGLOBALVARS pgv, HWND hwnd, BOOL enable )
|
|
{
|
|
HWND hCtrl = GetDlgItem(hwnd,IDC_JOYCALIBRATE);
|
|
ASSERT (::IsWindow(hCtrl));
|
|
EnableWindow( hCtrl, enable );
|
|
} /* enableJoyWindows */
|
|
|
|
// enableActiveJoystick - enable dialog controls based on presence of joysticks
|
|
static void enableActiveJoystick( LPGLOBALVARS pgv, HWND hwnd )
|
|
{
|
|
assert(pgv);
|
|
assert(hwnd);
|
|
|
|
BOOL allowj;
|
|
char str[MAX_STR];
|
|
unsigned joys;
|
|
LPSTR text;
|
|
|
|
// check what joysticks are active; if it hasn't changed, just return
|
|
joys = getActiveFlags( pgv );
|
|
if( pgv->joyActiveFlags == joys )
|
|
return;
|
|
|
|
pgv->joyActiveFlags = joys;
|
|
|
|
// turn off the rudder if it is gone
|
|
if( !(joys & HASRUDDERMAYBE) )
|
|
{
|
|
pgv->joyHWCurr.dwUsageSettings &= ~JOY_US_HASRUDDER;
|
|
CheckDlgButton( hwnd, IDC_JOY1HASRUDDER, FALSE );
|
|
}
|
|
|
|
// enable the appropriate windows
|
|
allowj = ((joys & HASJOY) != 0);
|
|
enableJoyWindows( pgv, hwnd, allowj );
|
|
|
|
HWND hCtrl = GetDlgItem( hwnd, IDC_JOY1HASRUDDER );
|
|
ASSERT (::IsWindow(hCtrl));
|
|
EnableWindow( hCtrl, allowj && (joys & HASRUDDERMAYBE) );
|
|
|
|
// set message for the user if there is no joystick plugged in, or if there is no joystick driver present
|
|
if( allowj )
|
|
{
|
|
text = "";
|
|
} else
|
|
{
|
|
text = str;
|
|
|
|
LoadString( GetResourceInstance(), (joyGetNumDevs()) ? IDS_JOYUNPLUGGED : IDS_JOYNOTPRESENT, str, sizeof( str ) );
|
|
}
|
|
|
|
if( allowj )
|
|
enableTestCal( hwnd, pgv->joyHWCurr.dwType );
|
|
|
|
if( allowj )
|
|
pgv->joyHWCurr.dwUsageSettings |= JOY_US_PRESENT;
|
|
else
|
|
pgv->joyHWCurr.dwUsageSettings &= ~JOY_US_PRESENT;
|
|
|
|
RegSaveCurrentJoyHW( pgv );
|
|
RegistryUpdated( pgv );
|
|
|
|
} /* enableActiveJoystick */
|
|
|
|
|
|
#ifdef DEAD_CODE
|
|
/*
|
|
* getNewJoyInfo - get information from the registry about a new joystick.
|
|
* If no info, default to joyHWDefault settings
|
|
*/
|
|
static void getNewJoyInfo( LPGLOBALVARS pgv, HWND hwnd )
|
|
{
|
|
assert(pgv);
|
|
assert(hwnd);
|
|
|
|
|
|
DWORD hw_type;
|
|
HKEY hkey;
|
|
char str[MAX_STR];
|
|
char jcfg[MAX_STR];
|
|
DWORD regtype;
|
|
JOYREGHWCONFIG config;
|
|
DWORD cb;
|
|
BOOL same;
|
|
int rc;
|
|
|
|
GETKEYNAME( pgv, jcfg, REGSTR_VAL_JOYNCONFIG );
|
|
|
|
// get the hardware type
|
|
hw_type = SendDlgItemMessage( hwnd, IDC_JOYSELECT, CB_GETCURSEL, 0, 0L );
|
|
same = (hw_type == pgv->joyHWCurr.dwType);
|
|
|
|
// read the info from the registry if a new hardware type selected
|
|
if( !same )
|
|
{
|
|
pgv->joyHWCurr = pgv->pjd->joyHWDefaults[ hw_type ];
|
|
createSettingsKeyFromCurr( pgv, str );
|
|
if( !RegOpenKey( HKEY_LOCAL_MACHINE, str, &hkey ) )
|
|
{
|
|
cb = sizeof( pgv->joyHWCurr );
|
|
if( !RegQueryValueEx( hkey, jcfg, NULL, ®type,
|
|
(CONST LPBYTE)&config, &cb) )
|
|
{
|
|
if( regtype == REG_BINARY && cb == sizeof( config ) )
|
|
{
|
|
pgv->joyHWCurr.hws = config.hws;
|
|
pgv->joyHWCurr.hwv = config.hwv;
|
|
pgv->joyHWCurr.dwUsageSettings = config.dwUsageSettings;
|
|
}
|
|
}
|
|
RegCloseKey( hkey );
|
|
}
|
|
|
|
// set up the rudder bit
|
|
if( pgv->joyHWCurr.dwUsageSettings & JOY_US_HASRUDDER )
|
|
{
|
|
CheckDlgButton( hwnd, IDC_JOY1HASRUDDER, TRUE );
|
|
} else
|
|
{
|
|
if( IsDlgButtonChecked( hwnd, IDC_JOY1HASRUDDER ) )
|
|
{
|
|
pgv->joyHWCurr.dwUsageSettings |= JOY_US_HASRUDDER;
|
|
} else
|
|
{
|
|
pgv->joyHWCurr.dwUsageSettings &= ~JOY_US_HASRUDDER;
|
|
}
|
|
}
|
|
}
|
|
|
|
// disable test/calibrate buttons based on hardware picked
|
|
enableTestCal( hwnd, hw_type );
|
|
|
|
// if custom selected, go get the data from the user
|
|
if( hw_type == JOY_HW_CUSTOM )
|
|
{
|
|
//ISSUE-2001/03/29-timgill Old code issue
|
|
//HINSTANCE hInst = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE);
|
|
HINSTANCE hInst = (HINSTANCE)GetResourceInstance();
|
|
assert(hInst);
|
|
rc = DialogBoxParam(hInst,
|
|
MAKEINTRESOURCE(IDD_JOYCUSTOM), hwnd,
|
|
(int (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))CustomProc, (LONG) pgv );
|
|
if( rc )
|
|
{
|
|
LPCUSTVARS pcv;
|
|
|
|
pcv = (LPCUSTVARS) rc;
|
|
pgv->joyHWCurr.dwUsageSettings |= JOY_US_PRESENT;
|
|
pgv->joyHWCurr.hws.dwFlags &= ~(JOY_HWS_HASR|JOY_HWS_HASZ|
|
|
JOY_HWS_HASPOV|JOY_HWS_ISYOKE| JOY_HWS_ISGAMEPAD|
|
|
JOY_HWS_ISCARCTRL| JOY_HWS_POVISPOLL|
|
|
JOY_HWS_POVISBUTTONCOMBOS );
|
|
/*
|
|
* NOTE: for a custom joystick, we always assume that Z is
|
|
* implemented on J2 Y.
|
|
*/
|
|
if( pcv->bHasZ )
|
|
pgv->joyHWCurr.hws.dwFlags |= JOY_HWS_HASZ;
|
|
/*
|
|
* NOTE: for a custom joystick, we always assume that R is
|
|
* implemented on J2 X.
|
|
*/
|
|
if( pcv->bHasR )
|
|
pgv->joyHWCurr.hws.dwFlags |= JOY_HWS_HASR;
|
|
|
|
if( pcv->bHasPOV )
|
|
pgv->joyHWCurr.hws.dwFlags |= JOY_HWS_HASPOV;
|
|
|
|
if( pcv->bIsYoke )
|
|
pgv->joyHWCurr.hws.dwFlags |= JOY_HWS_ISYOKE;
|
|
|
|
if( pcv->bIsGamePad )
|
|
{
|
|
pgv->joyHWCurr.hws.dwFlags |= JOY_HWS_ISGAMEPAD;
|
|
}
|
|
if( pcv->bIsCarCtrl )
|
|
{
|
|
pgv->joyHWCurr.hws.dwFlags |= JOY_HWS_ISCARCTRL;
|
|
}
|
|
if( pcv->bHas2Buttons )
|
|
{
|
|
pgv->joyHWCurr.hws.dwNumButtons = 2;
|
|
} else
|
|
{
|
|
pgv->joyHWCurr.hws.dwNumButtons = 4;
|
|
}
|
|
DoFree( pcv );
|
|
same = FALSE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* update the registry with the new current joystick
|
|
*/
|
|
if( !same )
|
|
{
|
|
RegSaveCurrentJoyHW( pgv );
|
|
RegistryUpdated( pgv );
|
|
PropSheet_Changed( GetParent(hwnd), hwnd );
|
|
pgv->joyActiveFlags = (unsigned) -1;
|
|
enableActiveJoystick( pgv, hwnd );
|
|
}
|
|
|
|
} /* getNewJoyInfo */
|
|
#endif //DEAD_CODE
|
|
|
|
// initCurrentHW - set up the current hardware for the first time
|
|
static void initCurrentHW( LPGLOBALVARS pgv )
|
|
{
|
|
assert(pgv);
|
|
|
|
|
|
regGetCurrHW( pgv );
|
|
pgv->joyActiveFlags = (unsigned) -1;
|
|
saveHWSettings( pgv );
|
|
|
|
} /* initCurrentHW */
|
|
|
|
// newJoyId - set up for a new joystick id
|
|
static LPGLOBALVARS newJoyId( LPGLOBALVARS pgv, HWND hwnd, int joyid )
|
|
{
|
|
|
|
assert(pgv);
|
|
assert(hwnd);
|
|
|
|
// if( joyid == pgv->iJoyId )
|
|
// return pgv;
|
|
|
|
#if !defined( WANT_SHEETS )
|
|
pgv = &pgv->pjd->pgvlist[ joyid ];
|
|
#endif
|
|
pgv->iJoyId = joyid;
|
|
|
|
/*
|
|
* save the pointer to the variables
|
|
*/
|
|
SetWindowLong( hwnd, DWL_USER, (LONG) pgv );
|
|
|
|
#if defined( WANT_SHEETS )
|
|
/*
|
|
* set up current joystick hardware
|
|
*/
|
|
initCurrentHW( pgv );
|
|
#endif
|
|
|
|
// set up windows
|
|
pgv->joyActiveFlags = (unsigned) -1;
|
|
enableActiveJoystick( pgv, hwnd );
|
|
|
|
CheckDlgButton( hwnd, IDC_JOY1HASRUDDER, ( pgv->joyHWCurr.dwUsageSettings & JOY_US_HASRUDDER ) ? TRUE : FALSE);
|
|
|
|
// select the current info
|
|
// SendDlgItemMessage( hwnd, IDC_JOYSELECT, CB_SETCURSEL, pgv->joyHWCurr.dwType, 0L );
|
|
|
|
#if !defined( WANT_SHEETS )
|
|
// SendDlgItemMessage( hwnd, IDC_JOYCURRENTID, CB_SETCURSEL, pgv->iJoyId, 0L );
|
|
#endif
|
|
return(pgv);
|
|
|
|
|
|
} /* newJoyId */
|
|
|
|
/*
|
|
* showResetInfo
|
|
*
|
|
static void showResetInfo( HWND hwnd, BOOL show )
|
|
{
|
|
ASSERT (::IsWindow(hwnd));
|
|
|
|
// HWND hCtrl = GetDlgItem( hwnd, IDC_JOYTROUBLESHOOT_FRAME );
|
|
// ASSERT (::IsWindow(hCtrl));
|
|
// EnableWindow( hCtrl, show );
|
|
|
|
// hCtrl = GetDlgItem( hwnd, IDC_JOYTROUBLESHOOT_TEXT );
|
|
// ASSERT (::IsWindow(hCtrl));
|
|
// EnableWindow( hCtrl, show );
|
|
|
|
// hCtrl = GetDlgItem( hwnd, IDC_JOYRESET );
|
|
// ASSERT (::IsWindow(hCtrl));
|
|
// EnableWindow( hCtrl, show );
|
|
|
|
} * showResetInfo */
|
|
|
|
// doJoyDlgInitDialog - process initialization for joystick tabbed dialog
|
|
static BOOL doJoyDlgInitDialog( HWND hwnd, LPARAM lParam )
|
|
{
|
|
assert(IsWindow(hwnd));
|
|
|
|
HINSTANCE hinst = GetWindowInstance( hwnd );
|
|
HINSTANCE hResInst = GetResourceInstance();
|
|
LPPROPSHEETPAGE ppsp;
|
|
// int i;
|
|
// char str[MAX_STR];
|
|
LPGLOBALVARS pgv;
|
|
LPJOYDATA pjd;
|
|
LPJOYDATAPTR pjdp;
|
|
|
|
/*
|
|
LRESULT lr;
|
|
HKEY hKey;
|
|
ULONG cb;
|
|
PACKETINFO PacketInfo;
|
|
//
|
|
// set labels
|
|
//
|
|
|
|
// load icon
|
|
if (fIsSideWinder)
|
|
{
|
|
HANDLE hDevice;
|
|
DWORD dwVerSize;
|
|
char sz[256];
|
|
char sz2[256];
|
|
JOYCAPS jc;
|
|
|
|
// set icon
|
|
HICON hIcon =(struct HICON__ *) LoadImage(hResInst,(PSTR)IDI_SIDEWINDER, IMAGE_ICON, 64, 64, 0);
|
|
ASSERT(hIcon);
|
|
|
|
HWND hCtrl = GetDlgItem(hwnd, IDC_SIDEWINDERICON);
|
|
ASSERT (::IsWindow(hCtrl));
|
|
ShowWindow(hCtrl, SW_SHOW);
|
|
|
|
hCtrl = GetDlgItem(hwnd, IDC_SIDEWINDERICON);
|
|
ASSERT (::IsWindow(hCtrl));
|
|
Static_SetIcon(hCtrl, hIcon);
|
|
|
|
// set title
|
|
pszCommonString->LoadString(IDS_PROP_TBAR);
|
|
lstrcpy(sz, (LPCTSTR)*pszCommonString);
|
|
|
|
SetWindowText(GetParent(hwnd), sz);
|
|
|
|
// product name
|
|
SetDialogItemText(hwnd, IDC_TEXT_PRODUCTNAME, IDS_SETTING_PRODUCT_NAME+1);
|
|
|
|
// version
|
|
GetSystemDirectory(sz, sizeof(sz));
|
|
lstrcat(sz, "\\MSGAME.VXD");
|
|
dwVerSize = GetFileVersionInfoSize(sz, &cb);
|
|
if (dwVerSize)
|
|
{
|
|
VS_FIXEDFILEINFO* pVer;
|
|
UINT cbVer;
|
|
char* p = (char*)malloc(dwVerSize);
|
|
GetFileVersionInfo(sz, 0, dwVerSize, (void*)p);
|
|
VerQueryValue((void*)p, "\\", (void**)&pVer, &cbVer);
|
|
wsprintf(
|
|
sz, "%d.%02d.%02d",
|
|
HIWORD(pVer->dwFileVersionMS),
|
|
LOWORD(pVer->dwFileVersionMS),
|
|
LOWORD(pVer->dwFileVersionLS));
|
|
SetDlgItemText(hwnd, IDC_TEXT_VERSION, sz);
|
|
free(p);
|
|
}
|
|
|
|
// copyright
|
|
SetDialogItemText(hwnd, IDC_TEXT_COPYRIGHT, IDS_COPYRIGHT+1);
|
|
|
|
// PID
|
|
pszCommonString->LoadString(IDS_SETTING_PRODUCT_NAME+2);
|
|
lstrcpy(sz2, (LPCTSTR)*pszCommonString);
|
|
|
|
wsprintf(sz, "Software\\Microsoft\\%s\\1.0\\registration", sz2);
|
|
lr = RegOpenKey(HKEY_LOCAL_MACHINE, sz, &hKey);
|
|
*sz = 0;
|
|
cb = sizeof(sz);
|
|
lr = RegQueryValueEx(hKey, "ProductID", 0, 0, (BYTE*)sz, &cb);
|
|
RegCloseKey(hKey);
|
|
SetDlgItemText(hwnd, IDC_TEXT_PID, sz);
|
|
|
|
// diagnostics
|
|
joyGetDevCaps(0, &jc, sizeof(jc));
|
|
if (!strcmp(jc.szOEMVxD, "MSGAME.VXD"))
|
|
{
|
|
hDevice = CreateFile(
|
|
"\\\\.\\MSGAME.VXD",
|
|
0, 0, 0, 0,
|
|
FILE_FLAG_DELETE_ON_CLOSE, 0);
|
|
if (hDevice!=INVALID_HANDLE_VALUE)
|
|
{
|
|
lr = DeviceIoControl(
|
|
hDevice, 6,
|
|
&PacketInfo, sizeof(PACKETINFO),
|
|
0, 0, &cb, 0);
|
|
CloseHandle(hDevice);
|
|
}
|
|
wsprintf(
|
|
sz, "%08x-%08x-%02x",
|
|
PacketInfo.nFailures, PacketInfo.nAttempts, PacketInfo.iMode);
|
|
SetDlgItemText(hwnd, IDC_TEXT_DIAGNOSTIC, sz);
|
|
}
|
|
|
|
SetDlgItemText(hwnd, IDC_TEXT_DIAGNOSTIC, sz);
|
|
|
|
// hide calibration button and rudder options
|
|
hCtrl = GetDlgItem(hwnd, IDC_JOYCALIBRATE);
|
|
ASSERT (::IsWindow(hCtrl));
|
|
ShowWindow(hCtrl, 0);
|
|
|
|
hCtrl = GetDlgItem(hwnd, IDC_GROUP_RUDDER);
|
|
ASSERT (::IsWindow(hCtrl));
|
|
ShowWindow(hCtrl, 0);
|
|
|
|
hCtrl = GetDlgItem(hwnd, IDC_TEXT_RUDDERHELP);
|
|
ASSERT (::IsWindow(hCtrl));
|
|
ShowWindow(hCtrl, 0);
|
|
|
|
hCtrl = GetDlgItem(hwnd, IDC_JOY1HASRUDDER);
|
|
ASSERT (::IsWindow(hCtrl));
|
|
ShowWindow(hCtrl, 0);
|
|
}
|
|
*/
|
|
|
|
// pointer to data
|
|
ppsp = (LPPROPSHEETPAGE) lParam;
|
|
pjdp = (LPJOYDATAPTR) ppsp->lParam;
|
|
pjd = pjdp->pjd;
|
|
|
|
// blj: Fix #8049, Assign the proper ID for the joysick assigned to this property sheet.
|
|
pjdp->iJoyId = gnID;
|
|
|
|
// create global variables. These will be used by all dialogs
|
|
#if defined( WANT_SHEETS )
|
|
pgv = DoAlloc( sizeof( GLOBALVARS ) );
|
|
assert(pgv);
|
|
if( pgv == NULL )
|
|
return(FALSE);
|
|
|
|
// get joystick id that this sheet is for
|
|
pgv->iJoyId = pjdp->iJoyId;
|
|
pgv->pjd = pjd;
|
|
DPF( "Tab for joystick %d started\r\n", pgv->iJoyId );
|
|
#else
|
|
pgv = &pjd->pgvlist[ pjdp->iJoyId ];
|
|
#endif
|
|
|
|
// get device caps
|
|
getDevCaps( pgv );
|
|
|
|
/* these are for the old combo boxes that used to display the controllers... this is no longer needed
|
|
// set up pre-defined joystick list
|
|
for( i=IDS_JOYHW0; i<IDS_JOYHWLAST; i++ )
|
|
{
|
|
if (LoadString( hResInst , i, str, sizeof( str )))
|
|
SendDlgItemMessage( hwnd, IDC_JOYSELECT, CB_ADDSTRING, 0, (LPARAM)(LPSTR) str );
|
|
}
|
|
|
|
// set up OEM joystick list
|
|
for( i=0;i<pjd->oemCount;i++ )
|
|
SendDlgItemMessage( hwnd, IDC_JOYSELECT, CB_ADDSTRING, 0, (LPARAM)(LPSTR) pjd->oemList[i].ident_string );
|
|
|
|
// this can all go away!!!
|
|
// set up joystick choices list
|
|
#if !defined(WANT_SHEETS)
|
|
{
|
|
int numdevs;
|
|
char strid[MAX_STR];
|
|
if( LoadString( hResInst, IDS_JOY, str, sizeof( str ) ) )
|
|
{
|
|
numdevs = joyGetNumDevs();
|
|
|
|
for( i=0;i<numdevs;i++ )
|
|
{
|
|
wsprintf( strid, "%s %d", str, i+1 );
|
|
SendDlgItemMessage( hwnd, IDC_JOYCURRENTID, CB_ADDSTRING, 0, (LPARAM)(LPSTR) strid );
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
*/
|
|
|
|
// pgv->iJoyId = -1;
|
|
newJoyId( pgv, hwnd, pjdp->iJoyId);
|
|
|
|
// enable/disable our Reset button
|
|
// showResetInfo( hwnd, pjd->bHasNonStandardUserVals );
|
|
|
|
return(TRUE);
|
|
|
|
} /* doJoyDlgInitDialog */
|
|
|
|
/*
|
|
* doJoyDlgCommand - process WM_COMMAND message for main joystick tabbed dialog
|
|
*/
|
|
static void doJoyDlgCommand( HWND hwnd, int id, HWND hctl, UINT code )
|
|
{
|
|
assert(hwnd);
|
|
|
|
LPGLOBALVARS pgv;
|
|
|
|
pgv = (LPGLOBALVARS) GetWindowLong( hwnd, DWL_USER );
|
|
assert(pgv);
|
|
|
|
switch( id )
|
|
{
|
|
#ifdef DEAD_CODE
|
|
// new joystick has been picked
|
|
case IDC_JOYSELECT:
|
|
if( code == CBN_SELCHANGE )
|
|
getNewJoyInfo( pgv, hwnd );
|
|
break;
|
|
#endif // DEAD_CODE
|
|
|
|
#if !defined( WANT_SHEET )
|
|
// new joystick id has been picked
|
|
case IDC_JOYCURRENTID:
|
|
if( code == CBN_SELCHANGE )
|
|
{
|
|
int joyid;
|
|
joyid = SendDlgItemMessage( hwnd, IDC_JOYCURRENTID, CB_GETCURSEL, 0, 0L );
|
|
pgv = newJoyId( pgv, hwnd, joyid );
|
|
regSetUserVals( pgv->pjd, TRUE );
|
|
RegSaveCurrentJoyHW( pgv );
|
|
RegistryUpdated( pgv );
|
|
}
|
|
break;
|
|
#endif
|
|
|
|
// calibrate current joystick
|
|
case IDC_JOYCALIBRATE:
|
|
pgv->pjd->bUseTimer = FALSE;
|
|
DoCalibrate( pgv, hwnd );
|
|
pgv->pjd->bUseTimer = TRUE;
|
|
break;
|
|
|
|
#ifdef DEAD_CODE
|
|
// test either joystick 1 or joystick 2
|
|
case IDC_JOYTEST:
|
|
pgv->pjd->bUseTimer = FALSE;
|
|
DoTest( pgv, hwnd, NULL, pgv );
|
|
pgv->pjd->bUseTimer = TRUE;
|
|
break;
|
|
#endif
|
|
|
|
// reset to user values
|
|
case IDC_JOYRESET:
|
|
pgv->pjd->bResetUserVals = TRUE;
|
|
PropSheet_Changed( GetParent(hwnd), hwnd );
|
|
break;
|
|
|
|
// rudder selected/unselected
|
|
case IDC_JOY1HASRUDDER:
|
|
{
|
|
LPJOYREGHWCONFIG pcfg;
|
|
// rudder status changed, force recalibration (leave POV alone if it was button based)
|
|
pcfg = &pgv->joyHWCurr;
|
|
assert(pcfg);
|
|
|
|
if( (pcfg->hws.dwFlags & JOY_HWS_HASPOV) && (pcfg->hws.dwFlags & JOY_HWS_POVISBUTTONCOMBOS) )
|
|
pcfg->hwv.dwCalFlags &= JOY_ISCAL_POV;
|
|
else
|
|
pcfg->hwv.dwCalFlags = 0;
|
|
|
|
if( IsDlgButtonChecked( hwnd, id ) )
|
|
pcfg->dwUsageSettings |= JOY_US_HASRUDDER;
|
|
else
|
|
pcfg->dwUsageSettings &= ~JOY_US_HASRUDDER;
|
|
|
|
pgv->joyActiveFlags = (unsigned) -1;
|
|
enableActiveJoystick( pgv, hwnd );
|
|
|
|
// tell vjoyd that the device has changed!
|
|
joyConfigChanged(0);
|
|
|
|
PropSheet_Changed( GetParent(hwnd), hwnd );
|
|
break;
|
|
}
|
|
|
|
case ID_APPLY:
|
|
{
|
|
DPF( "ID_APPLY\r\n" );
|
|
|
|
#if !defined( WANT_SHEETS )
|
|
{
|
|
// int i;
|
|
// int numjoys;
|
|
|
|
// numjoys = joyGetNumDevs();
|
|
// for( i=0;i<numjoys;i++ )
|
|
{
|
|
regPermSaveAllInfo( &pgv->pjd->pgvlist[gnID] );
|
|
saveHWSettings( &pgv->pjd->pgvlist[gnID] );
|
|
}
|
|
}
|
|
#else
|
|
regPermSaveAllInfo( pgv );
|
|
saveHWSettings( pgv );
|
|
#endif
|
|
if( pgv->pjd->bResetUserVals )
|
|
{
|
|
regUserValsFini( pgv->pjd );
|
|
regUserValsInit( pgv->pjd );
|
|
pgv->pjd->bResetUserVals = FALSE;
|
|
}
|
|
// showResetInfo( hwnd, pgv->pjd->bHasNonStandardUserVals );
|
|
// BUG 419 FIX: brute force method
|
|
InvalidateRect(GetParent(hwnd), 0, 0);
|
|
break;
|
|
}
|
|
|
|
|
|
case ID_INIT:
|
|
DPF( "ID_INIT\r\n" );
|
|
joyConfigChanged(0);
|
|
|
|
pgv->iJoyId = gnID;
|
|
|
|
// we've been re-activated, reset the current joystick settings
|
|
regSetUserVals( pgv->pjd, TRUE );
|
|
RegSaveCurrentJoyHW( pgv );
|
|
RegistryUpdated( pgv );
|
|
break;
|
|
|
|
case IDOK:
|
|
DPF( "IDOK\r\n" );
|
|
|
|
joyConfigChanged(0);
|
|
|
|
EndDialog(hwnd, TRUE );
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
DPF( "IDCANCEL\r\n" );
|
|
pgv->pjd->bResetUserVals = FALSE;
|
|
#if !defined( WANT_SHEETS )
|
|
{
|
|
// int i;
|
|
// int numjoys;
|
|
|
|
// numjoys = joyGetNumDevs();
|
|
// for( i=0;i<numjoys;i++ ) {
|
|
restoreHWSettings( &pgv->pjd->pgvlist[gnID] );
|
|
// }
|
|
}
|
|
#else
|
|
restoreHWSettings( pgv );
|
|
#endif
|
|
RegistryUpdated( pgv );
|
|
EndDialog(hwnd, FALSE );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
} /* doJoyDlgCommand */
|
|
|
|
|
|
/*
|
|
* JoystickDlg - dialog procedure for joystick tabbed dialog
|
|
*/
|
|
BOOL CALLBACK JoystickDlg( HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
BOOL rc;
|
|
|
|
switch( umsg )
|
|
{
|
|
case WM_HELP:
|
|
OnHelp(lParam);
|
|
return(1);
|
|
|
|
case WM_CONTEXTMENU:
|
|
OnContextMenu(wParam);
|
|
return(1);
|
|
|
|
case WM_INITDIALOG:
|
|
rc = doJoyDlgInitDialog( hwnd, lParam );
|
|
|
|
if( !rc )
|
|
EndDialog( hwnd, 0 );
|
|
return(FALSE);
|
|
|
|
case WM_COMMAND:
|
|
HANDLE_WM_COMMAND( hwnd, wParam, lParam, doJoyDlgCommand );
|
|
break;
|
|
|
|
case WM_ACTIVATE:
|
|
// we've been activated, pretend we were re-selected
|
|
if( LOWORD( wParam ) != WA_INACTIVE )
|
|
FORWARD_WM_COMMAND( hwnd, ID_INIT, 0, 0, SendMessage );
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
cleanUpJoyDlg( hwnd );
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
NMHDR FAR * lpnm = (NMHDR FAR *)lParam;
|
|
switch( lpnm->code )
|
|
{
|
|
case PSN_KILLACTIVE:
|
|
FORWARD_WM_COMMAND( hwnd, IDOK, 0, 0, SendMessage );
|
|
FORWARD_WM_COMMAND( hwnd, ID_INIT, 0, 0, SendMessage );
|
|
// ADDED CML 7/03/96
|
|
KillTimer(hwnd, TIMER_ID);
|
|
return(TRUE);
|
|
|
|
case PSN_APPLY:
|
|
FORWARD_WM_COMMAND( hwnd, ID_APPLY, 0, 0, SendMessage );
|
|
return(TRUE);
|
|
|
|
case PSN_SETACTIVE:
|
|
FORWARD_WM_COMMAND( hwnd, ID_INIT, 0, 0, SendMessage );
|
|
// ADDED CML 7/03/96
|
|
// PSN_SETACTIVE gets sent for the first page on loading of the sheet,
|
|
// even if that page is not displayed
|
|
// check to see if we have been loaded
|
|
if( !fIsLoaded )
|
|
{
|
|
fIsLoaded=1; break;
|
|
}
|
|
|
|
return(TRUE);
|
|
|
|
case PSN_RESET:
|
|
FORWARD_WM_COMMAND( hwnd, IDCANCEL, 0, 0, SendMessage );
|
|
return(TRUE);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return(FALSE);
|
|
|
|
} /* JoystickDlg */
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
|
|
GLOBAL JOYSTICK DATA FUNCTIONS FOLLOW
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
// default joysticks
|
|
#define TYPE00 0
|
|
#define TYPE01 0
|
|
#define TYPE02 0
|
|
#define TYPE03 0
|
|
#define TYPE04 JOY_HWS_ISGAMEPAD
|
|
#define TYPE05 JOY_HWS_ISYOKE
|
|
#define TYPE06 JOY_HWS_HASZ | JOY_HWS_ISYOKE
|
|
#define TYPE07 JOY_HWS_HASZ
|
|
#define TYPE08 JOY_HWS_HASZ
|
|
#define TYPE09 JOY_HWS_ISGAMEPAD
|
|
#define TYPE10 JOY_HWS_ISYOKE
|
|
#define TYPE11 JOY_HWS_HASZ | JOY_HWS_ISYOKE
|
|
|
|
static JOYREGHWCONFIG _joyHWDefaults[] =
|
|
{
|
|
{ {TYPE00,0},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_NONE},
|
|
{ {TYPE01,2},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_CUSTOM},
|
|
{ {TYPE02,2},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_2A_2B_GENERIC},
|
|
{ {TYPE03,4},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_2A_4B_GENERIC},
|
|
{ {TYPE04,2},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_2B_GAMEPAD},
|
|
{ {TYPE05,2},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_2B_FLIGHTYOKE},
|
|
{ {TYPE06,2},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_2B_FLIGHTYOKETHROTTLE},
|
|
{ {TYPE07,2},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_3A_2B_GENERIC},
|
|
{ {TYPE08,4},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_3A_4B_GENERIC},
|
|
{ {TYPE09,4},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_4B_GAMEPAD},
|
|
{ {TYPE10,4},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_4B_FLIGHTYOKE},
|
|
{ {TYPE11,4},JOY_US_PRESENT,{{0,0,0,0,0,0,0,0,0},{0,0,0,0}},JOY_HW_4B_FLIGHTYOKETHROTTLE},
|
|
};
|
|
|
|
// registry strings for calibration messages
|
|
static LPSTR _oemCalRegStrs[] =
|
|
{
|
|
REGSTR_VAL_JOYOEMCAL1,
|
|
REGSTR_VAL_JOYOEMCAL2,
|
|
REGSTR_VAL_JOYOEMCAL3,
|
|
REGSTR_VAL_JOYOEMCAL4,
|
|
REGSTR_VAL_JOYOEMCAL5,
|
|
REGSTR_VAL_JOYOEMCAL6,
|
|
REGSTR_VAL_JOYOEMCAL7,
|
|
REGSTR_VAL_JOYOEMCAL8,
|
|
REGSTR_VAL_JOYOEMCAL9,
|
|
REGSTR_VAL_JOYOEMCAL10,
|
|
REGSTR_VAL_JOYOEMCAL11,
|
|
REGSTR_VAL_JOYOEMCAL12,
|
|
};
|
|
|
|
/*
|
|
* base registry keys
|
|
*/
|
|
static char szCfgKey[] = REGSTR_PATH_JOYCONFIG "\\";
|
|
static char szCurrCfgKey[] = "\\" REGSTR_KEY_JOYCURR;
|
|
static char szSettingsCfgKey[] = "\\" REGSTR_KEY_JOYSETTINGS;
|
|
|
|
// freeOEMListItem - free a list of oem data
|
|
static void freeOEMListItem( LPJOYDATA pjd, int i )
|
|
{
|
|
int j;
|
|
|
|
DoFree( pjd->oemList[i].keyname );
|
|
DoFree( pjd->oemList[i].ident_string );
|
|
DoFree( pjd->oemList[i].vxd_name );
|
|
DoFree( pjd->oemList[i].xy_label );
|
|
DoFree( pjd->oemList[i].z_label );
|
|
DoFree( pjd->oemList[i].r_label );
|
|
DoFree( pjd->oemList[i].u_label );
|
|
DoFree( pjd->oemList[i].v_label );
|
|
DoFree( pjd->oemList[i].pov_label );
|
|
DoFree( pjd->oemList[i].testmove_desc );
|
|
DoFree( pjd->oemList[i].testbutton_desc );
|
|
DoFree( pjd->oemList[i].testmove_cap );
|
|
DoFree( pjd->oemList[i].testbutton_cap );
|
|
DoFree( pjd->oemList[i].testwin_cap );
|
|
DoFree( pjd->oemList[i].cal_cap );
|
|
DoFree( pjd->oemList[i].calwin_cap );
|
|
for( j=0;j<NUM_CAL_STRS;j++ )
|
|
{
|
|
DoFree( pjd->oemList[i].cal_strs[j] );
|
|
}
|
|
|
|
} /* freeOEMListItem */
|
|
|
|
/*
|
|
* initHWDefaults - initialize the hardware list: use defaults + OEM types
|
|
* defined in the registry
|
|
*/
|
|
static void initHWDefaults( LPJOYDATA pjd )
|
|
{
|
|
assert(pjd);
|
|
|
|
int list_size;
|
|
int def_size;
|
|
DWORD isubkey;
|
|
DWORD keyidx;
|
|
HKEY hkey;
|
|
HKEY hsubkey;
|
|
char str[MAX_STR];
|
|
DWORD clsize;
|
|
DWORD num_subkeys;
|
|
DWORD dont_care;
|
|
DWORD longest_key;
|
|
FILETIME ftime;
|
|
LPSTR keyname;
|
|
JOYREGHWSETTINGS hws;
|
|
DWORD longest_val;
|
|
DWORD type;
|
|
DWORD cb;
|
|
int i;
|
|
int j;
|
|
int ctype;
|
|
LPSTR tmpstr;
|
|
int fail;
|
|
|
|
def_size = sizeof( _joyHWDefaults )/sizeof( _joyHWDefaults[0] );
|
|
list_size = def_size;
|
|
pjd->oemCount = 0;
|
|
if( !RegOpenKey( HKEY_LOCAL_MACHINE, REGSTR_PATH_JOYOEM, &hkey ) )
|
|
{
|
|
clsize = sizeof( str );
|
|
if( !RegQueryInfoKey ( hkey, str, &clsize, NULL, &num_subkeys,
|
|
&longest_key, &dont_care, &dont_care, &dont_care,
|
|
&dont_care, // address of buffer for longest value data length
|
|
&dont_care, &ftime ) )
|
|
{
|
|
pjd->oemList = (OEMLIST *)DoAlloc( num_subkeys * sizeof( OEMLIST ));
|
|
if( pjd->oemList != NULL )
|
|
{
|
|
pjd->oemCount = num_subkeys;
|
|
list_size += num_subkeys;
|
|
}
|
|
longest_key++;
|
|
}
|
|
}
|
|
|
|
pjd->joyHWDefaults = (struct joyreghwconfig_tag *) DoAlloc( list_size * sizeof( JOYREGHWCONFIG ) );
|
|
if( pjd->joyHWDefaults == NULL )
|
|
{
|
|
pjd->joyHWDefaults = _joyHWDefaults;
|
|
} else
|
|
{
|
|
memcpy( pjd->joyHWDefaults, _joyHWDefaults, def_size * sizeof( JOYREGHWCONFIG ) );
|
|
/*
|
|
* if we have keys in the registry, go fetch them
|
|
*/
|
|
if( list_size > def_size )
|
|
{
|
|
isubkey = 0;
|
|
keyidx = 0;
|
|
keyname = (char *) DoAlloc( longest_key );
|
|
if( keyname == NULL )
|
|
{
|
|
keyname = str;
|
|
longest_key = sizeof( str );
|
|
}
|
|
/*
|
|
* run through all keys, getting the info on them
|
|
*/
|
|
while( !RegEnumKey( hkey, keyidx, keyname, longest_key ) )
|
|
{
|
|
if( !RegOpenKey( hkey, keyname, &hsubkey ) )
|
|
{
|
|
if( !RegQueryInfoKey ( hsubkey, str, &clsize, NULL,
|
|
&dont_care, &dont_care, &dont_care, &dont_care,
|
|
&dont_care, &longest_val, &dont_care, &ftime ) )
|
|
{
|
|
pjd->oemList[isubkey].keyname = (char *)DoAlloc( strlen( keyname ) +1 );
|
|
tmpstr = (char *) DoAlloc( longest_val+1 );
|
|
if( pjd->oemList[isubkey].keyname != NULL && tmpstr != NULL )
|
|
{
|
|
lstrcpy( pjd->oemList[isubkey].keyname, keyname );
|
|
cb = sizeof( hws );
|
|
if( !RegQueryValueEx( hsubkey, REGSTR_VAL_JOYOEMDATA, NULL,
|
|
&type, (CONST LPBYTE)&hws, &cb) )
|
|
{
|
|
if( type == REG_BINARY && cb == sizeof( hws ) )
|
|
{
|
|
pjd->oemList[isubkey].hws = hws;
|
|
}
|
|
}
|
|
fail = 0;
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMCALLOUT,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].vxd_name );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMNAME,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].ident_string );
|
|
for( j=0;j<NUM_CAL_STRS;j++ )
|
|
{
|
|
fail |= regGetOEMStr( hsubkey, _oemCalRegStrs[j],
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].cal_strs[j] );
|
|
}
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMXYLABEL,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].xy_label );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMZLABEL,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].z_label );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMRLABEL,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].r_label );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMULABEL,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].u_label );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMVLABEL,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].v_label );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMPOVLABEL,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].pov_label );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMTESTMOVEDESC,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].testmove_desc );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMTESTBUTTONDESC,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].testbutton_desc );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMTESTMOVECAP,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].testmove_cap );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMTESTBUTTONCAP,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].testbutton_cap );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMTESTWINCAP,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].testwin_cap );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMCALCAP,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].cal_cap );
|
|
fail |= regGetOEMStr( hsubkey, REGSTR_VAL_JOYOEMCALWINCAP,
|
|
tmpstr, longest_val,
|
|
&pjd->oemList[isubkey].calwin_cap );
|
|
if( fail )
|
|
{
|
|
freeOEMListItem( pjd, isubkey );
|
|
} else
|
|
{
|
|
isubkey++;
|
|
}
|
|
} else
|
|
{
|
|
DoFree( pjd->oemList[isubkey].keyname );
|
|
}
|
|
DoFree( tmpstr );
|
|
RegCloseKey( hsubkey );
|
|
}
|
|
}
|
|
keyidx++;
|
|
}
|
|
pjd->oemCount = isubkey;
|
|
|
|
/*
|
|
* sort the list, and then fill in the joyHWDefault array
|
|
*/
|
|
if( pjd->oemCount > 0 )
|
|
{
|
|
for( i=0;i<pjd->oemCount;i++ )
|
|
{
|
|
for( j=i;j<pjd->oemCount;j++ )
|
|
{
|
|
OEMLIST ol;
|
|
if( lstrcmp( pjd->oemList[i].ident_string,
|
|
pjd->oemList[j].ident_string ) > 0 )
|
|
{
|
|
ol = pjd->oemList[i];
|
|
pjd->oemList[i] = pjd->oemList[j];
|
|
pjd->oemList[j] = ol;
|
|
}
|
|
}
|
|
}
|
|
for( i=0;i<pjd->oemCount;i++ )
|
|
{
|
|
ctype = i+JOY_HW_LASTENTRY;
|
|
memset( &pjd->joyHWDefaults[ctype], 0,
|
|
sizeof( pjd->joyHWDefaults[ctype] ) );
|
|
pjd->joyHWDefaults[ctype].hws = pjd->oemList[i].hws;
|
|
pjd->joyHWDefaults[ctype].dwUsageSettings = JOY_US_ISOEM|JOY_US_PRESENT;
|
|
pjd->joyHWDefaults[ctype].dwType = ctype;
|
|
}
|
|
}
|
|
if( keyname != str )
|
|
{
|
|
DoFree( keyname );
|
|
}
|
|
}
|
|
}
|
|
|
|
} /* initHWDefaults */
|
|
|
|
/*
|
|
* finiHWList - finished with the hardware list, free it
|
|
*/
|
|
static void finiHWList( LPJOYDATA pjd )
|
|
{
|
|
int i;
|
|
|
|
assert(pjd);
|
|
|
|
if( pjd->joyHWDefaults != NULL )
|
|
{
|
|
if( pjd->joyHWDefaults != _joyHWDefaults )
|
|
{
|
|
DoFree( pjd->joyHWDefaults );
|
|
}
|
|
pjd->joyHWDefaults = NULL;
|
|
}
|
|
if( pjd->oemList != NULL )
|
|
{
|
|
for( i=0;i<pjd->oemCount;i++ )
|
|
{
|
|
freeOEMListItem( pjd, i );
|
|
}
|
|
DoFree( pjd->oemList );
|
|
pjd->oemList = NULL;
|
|
pjd->oemCount = 0;
|
|
}
|
|
|
|
} /* finiHWList */
|
|
|
|
/*
|
|
* getRegKeys - get the registry keys we need
|
|
*/
|
|
static void getRegKeys( LPJOYDATA pjd )
|
|
{
|
|
JOYCAPS jc;
|
|
int len;
|
|
|
|
assert(pjd);
|
|
|
|
/*
|
|
* call with magic ID of -1, which retrieves base info without
|
|
* checking for anything joystick specific
|
|
*/
|
|
joyGetDevCaps( (UINT) -1, &jc, sizeof( jc ) );
|
|
|
|
// set up registry keys
|
|
pjd->regCfgKey = NULL;
|
|
pjd->regCurrCfgKey = NULL;
|
|
pjd->regSettingsCfgKey = NULL;
|
|
|
|
len = sizeof( szCfgKey ) + strlen( jc.szRegKey );
|
|
pjd->regCfgKey = (char *) DoAlloc( len );
|
|
if( pjd->regCfgKey != NULL )
|
|
{
|
|
lstrcpy( pjd->regCfgKey, szCfgKey );
|
|
lstrcpy( &pjd->regCfgKey[ sizeof( szCfgKey ) - 1], jc.szRegKey );
|
|
pjd->regCurrCfgKey = (char *)DoAlloc( len + sizeof( szCurrCfgKey ) - 1 );
|
|
if( pjd->regCurrCfgKey != NULL )
|
|
{
|
|
lstrcpy( pjd->regCurrCfgKey, pjd->regCfgKey );
|
|
lstrcpy( &pjd->regCurrCfgKey[ len-1 ], szCurrCfgKey );
|
|
}
|
|
pjd->regSettingsCfgKey = (char *)DoAlloc( len + sizeof( szSettingsCfgKey ) - 1 );
|
|
if( pjd->regSettingsCfgKey != NULL )
|
|
{
|
|
lstrcpy( pjd->regSettingsCfgKey, pjd->regCfgKey );
|
|
lstrcpy( &pjd->regSettingsCfgKey[ len-1 ], szSettingsCfgKey );
|
|
}
|
|
}
|
|
|
|
} /* getRegKeys */
|
|
|
|
/*
|
|
* JoystickDataInit
|
|
*/
|
|
LPJOYDATA JoystickDataInit( void )
|
|
{
|
|
LPJOYDATA pjd;
|
|
|
|
pjd = (JOYDATA *) DoAlloc( sizeof( JOYDATA ) );
|
|
assert(pjd);
|
|
if( pjd == NULL )
|
|
return(NULL);
|
|
|
|
// go set up all our defaults + oem lists
|
|
initHWDefaults( pjd );
|
|
|
|
// get registry keys used by everyone
|
|
getRegKeys( pjd );
|
|
|
|
// brushes for use by button display and bar display (z & r info)
|
|
pjd->hbUp = CreateSolidBrush( ACTIVE_COLOR );
|
|
pjd->hbDown = CreateSolidBrush( INACTIVE_COLOR );
|
|
|
|
// set up user values we like
|
|
regUserValsInit( pjd );
|
|
|
|
#if !defined( WANT_SHEETS )
|
|
{
|
|
// set up array of "global" vars (global to a joystick id)
|
|
int numjoys;
|
|
int i;
|
|
|
|
numjoys = joyGetNumDevs();
|
|
if( numjoys == 0 )
|
|
{
|
|
// blj: I'd love to have called JoyError Here, but we don't have a
|
|
// valid window handle to pass it!
|
|
char szTitle[STR_LEN_32];
|
|
char szMessage[STR_LEN_128];
|
|
|
|
if( LoadString(GetResourceInstance(), IDS_JOYREADERROR, szTitle, sizeof(szTitle)) == 0 )
|
|
{
|
|
OutputDebugString (TEXT("GCDEF.DLL: Unable to load string IDS_JOYREADERROR!\n"));
|
|
return(NULL);
|
|
}
|
|
|
|
if( LoadString(GetResourceInstance(), IDS_JOYUNPLUGGED, szMessage, sizeof(szMessage)) == 0 )
|
|
{
|
|
OutputDebugString (TEXT("GCDEF.DLL: Unable to load string IDS_JOYUNPLUGGED!\n"));
|
|
return(NULL);
|
|
}
|
|
|
|
MessageBox( NULL, szMessage, szTitle, MB_OK | MB_ICONERROR | MB_TASKMODAL );
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
pjd->pgvlist = (_GLOBALVARS *)DoAlloc( sizeof( GLOBALVARS ) * numjoys );
|
|
if( pjd->pgvlist == NULL )
|
|
return(NULL);
|
|
|
|
for( i=0;i<numjoys;i++ )
|
|
{
|
|
pjd->pgvlist[i].iJoyId = i;
|
|
pjd->pgvlist[i].pjd = pjd;
|
|
initCurrentHW( &pjd->pgvlist[i] );
|
|
}
|
|
|
|
}
|
|
#endif
|
|
return(pjd);
|
|
|
|
} /* JoystickDataInit */
|
|
|
|
/*
|
|
* JoystickDataFini - finished with DLL wide joystick data data
|
|
*/
|
|
void JoystickDataFini( LPJOYDATA pjd )
|
|
{
|
|
assert(pjd);
|
|
|
|
// ditch brushes
|
|
if( pjd->hbUp != NULL )
|
|
DeleteObject( pjd->hbUp );
|
|
|
|
if( pjd->hbDown != NULL )
|
|
DeleteObject( pjd->hbDown );
|
|
|
|
// done with hardware list
|
|
finiHWList( pjd );
|
|
|
|
// restore user values in registry
|
|
regUserValsFini( pjd );
|
|
|
|
// done with registry keys
|
|
DoFree( pjd->regCfgKey );
|
|
DoFree( pjd->regCurrCfgKey );
|
|
DoFree( pjd->regSettingsCfgKey );
|
|
|
|
#if !defined( WANT_SHEETS )
|
|
DoFree( pjd->pgvlist );
|
|
#endif
|
|
|
|
// free up the joystick data
|
|
DoFree( pjd );
|
|
#ifdef DEBUG
|
|
if( allocCount != 0 )
|
|
MBOX( "Memory left unfreed: %d allocations", allocCount );
|
|
#endif
|
|
|
|
} /* JoystickDataFini */
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
// OnContextMenu(WPARAM wParam)
|
|
////////////////////////////////////////////////////////////////////////////////////////
|
|
void OnContextMenu(WPARAM wParam)
|
|
{
|
|
short nSize = STR_LEN_32;
|
|
|
|
// point to help file
|
|
char *pszHelpFileName = new char[nSize];
|
|
ASSERT (pszHelpFileName);
|
|
|
|
// returns help file name and size of string
|
|
GetHelpFileName(pszHelpFileName, &nSize);
|
|
|
|
WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (DWORD)gaHelpIDs);
|
|
|
|
if( pszHelpFileName ) delete[] (pszHelpFileName);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// FUNCTION: GetHelpFileName(LPSTR lpszHelpFileName)
|
|
//
|
|
// PURPOSE: Populates lpszHelpFileName with the Help File Name from the registry
|
|
//
|
|
// RETURN: ERROR_SUCCESS if successfull, -1 otherwise
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
LRESULT GetHelpFileName(LPSTR lpszHelpFileName, short* nSize)
|
|
{
|
|
if( LoadString(GetResourceInstance(), IDS_HELPFILENAME, lpszHelpFileName, *nSize) )
|
|
return(S_OK);
|
|
else
|
|
return(E_FAIL);
|
|
}
|
|
|
|
void OnHelp(LPARAM lParam)
|
|
{
|
|
ASSERT ( lParam );
|
|
|
|
short nSize = STR_LEN_32;
|
|
|
|
// point to help file
|
|
char *pszHelpFileName = new char[nSize];
|
|
ASSERT (pszHelpFileName);
|
|
|
|
// returns help file name and size of string
|
|
GetHelpFileName(pszHelpFileName, &nSize);
|
|
|
|
LPHELPINFO lphi = (LPHELPINFO)lParam;
|
|
if( lphi->iContextType==HELPINFO_WINDOW )
|
|
WinHelp((HWND)lphi->hItemHandle, pszHelpFileName, HELP_WM_HELP, (DWORD)gaHelpIDs);
|
|
|
|
if( pszHelpFileName ) delete[] (pszHelpFileName);
|
|
}
|
|
|