298 lines
8.6 KiB
C
298 lines
8.6 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* DIHidUsg.c
|
||
|
*
|
||
|
* Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* Abstract:
|
||
|
*
|
||
|
* Mapping between GUIDs and HID usages.
|
||
|
*
|
||
|
* Contents:
|
||
|
*
|
||
|
* UsageToGuid
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "dinputpr.h"
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* The sqiffle for this file.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#define sqfl sqflHidUsage
|
||
|
|
||
|
#pragma BEGIN_CONST_DATA
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @doc INTERNAL
|
||
|
*
|
||
|
* @global HIDUSAGEMAP | c_rghum[] |
|
||
|
*
|
||
|
* Mapping between GUIDs and HID usages for one-to-one mappings.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#ifndef DISEM_FLAGS_0
|
||
|
#define DISEM_FLAGS_0 0
|
||
|
#endif
|
||
|
|
||
|
#define MAKEHUM(Page, Usage, PosAxis, SemFlag, Guid) \
|
||
|
{ DIMAKEUSAGEDWORD(HID_USAGE_PAGE_##Page, \
|
||
|
HID_USAGE_##Page##_##Usage), \
|
||
|
PosAxis, \
|
||
|
DISEM_FLAGS_GET(DISEM_FLAGS_##SemFlag), \
|
||
|
0,0, \
|
||
|
DISEM_HINT_##Usage, \
|
||
|
&Guid, \
|
||
|
} \
|
||
|
|
||
|
|
||
|
HIDUSAGEMAP c_rghum[] = {
|
||
|
MAKEHUM(GENERIC, X, 0, X, GUID_XAxis),
|
||
|
MAKEHUM(GENERIC, Y, 1, Y, GUID_YAxis),
|
||
|
MAKEHUM(GENERIC, Z, 2, Z, GUID_ZAxis),
|
||
|
MAKEHUM(GENERIC, WHEEL, 2, Z, GUID_ZAxis),
|
||
|
MAKEHUM(GENERIC, RX, 3, V, GUID_RxAxis),
|
||
|
MAKEHUM(GENERIC, RY, 4, U, GUID_RyAxis),
|
||
|
MAKEHUM(GENERIC, RZ, 5, R, GUID_RzAxis),
|
||
|
MAKEHUM(GENERIC, HATSWITCH, 7, 0, GUID_POV),
|
||
|
|
||
|
MAKEHUM(GENERIC, SLIDER, 6, S, GUID_Slider),
|
||
|
MAKEHUM(GENERIC, DIAL, 6, S, GUID_Slider),
|
||
|
|
||
|
MAKEHUM(SIMULATION, STEERING, 0, X, GUID_XAxis),
|
||
|
MAKEHUM(SIMULATION, ACCELERATOR,1, A, GUID_YAxis),
|
||
|
MAKEHUM(SIMULATION, BRAKE, 5, B, GUID_RzAxis),
|
||
|
MAKEHUM(SIMULATION, RUDDER, 5, R, GUID_RzAxis),
|
||
|
MAKEHUM(SIMULATION, THROTTLE, 6, A, GUID_Slider),
|
||
|
MAKEHUM(GAME, POV, 7, 0, GUID_POV),
|
||
|
};
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @doc EXTERNAL
|
||
|
*
|
||
|
* @func PCGUID | UsageToUsageMap |
|
||
|
*
|
||
|
* Takes some HID usage and usage page information and
|
||
|
* returns a pointer to a <t HIDUSAGEMAP> that describes
|
||
|
* how we should treat it.
|
||
|
*
|
||
|
* If the type is not recognized, then <c NULL> is returned.
|
||
|
*
|
||
|
* @parm DWORD | dwUsage |
|
||
|
*
|
||
|
* Usage page and usage to convert. This should be a <t DWORD>
|
||
|
* formed using DIMAKEUSAGEDWORD on the component <t USAGE> values.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
PHIDUSAGEMAP EXTERNAL
|
||
|
UsageToUsageMap(DWORD dwUsage)
|
||
|
{
|
||
|
PHIDUSAGEMAP phum;
|
||
|
int ihum;
|
||
|
|
||
|
for (ihum = 0; ihum < cA(c_rghum); ihum++) {
|
||
|
if (c_rghum[ihum].dwUsage == dwUsage) {
|
||
|
phum = &c_rghum[ihum];
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
phum = 0;
|
||
|
|
||
|
done:;
|
||
|
if( phum )
|
||
|
{
|
||
|
SquirtSqflPtszV(sqflHidUsage | sqflVerbose,
|
||
|
TEXT("UsageToUsageMap: mapped 0x%04x:0x%04x to index %d"),
|
||
|
HIWORD( dwUsage ), LOWORD( dwUsage ), ihum );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SquirtSqflPtszV(sqflHidUsage | sqflVerbose,
|
||
|
TEXT("UsageToUsageMap: failed to map 0x%04x:0x%04x"),
|
||
|
HIWORD( dwUsage ), LOWORD( dwUsage ) );
|
||
|
}
|
||
|
|
||
|
return phum;
|
||
|
}
|
||
|
|
||
|
|
||
|
#if 0
|
||
|
// After we fixed Windows bug 357943, this function is no longer needed.
|
||
|
// But keep here for sometime just in case...
|
||
|
//
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @doc EXTERNAL
|
||
|
*
|
||
|
* @func DWORD | GuidToUsage |
|
||
|
*
|
||
|
* Map Guid to Usage
|
||
|
*
|
||
|
* If the guid is not recognized, then 0 is returned.
|
||
|
*
|
||
|
* @parm PCGUID | pguid |
|
||
|
*
|
||
|
* guid to map
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
DWORD EXTERNAL
|
||
|
GuidToUsage(PCGUID pguid)
|
||
|
{
|
||
|
DWORD dwUsage;
|
||
|
int ihum;
|
||
|
|
||
|
for (ihum = 0; ihum < cA(c_rghum); ihum++) {
|
||
|
if ( IsEqualGUID( c_rghum[ihum].pguid, pguid ) ) {
|
||
|
dwUsage = c_rghum[ihum].dwUsage;
|
||
|
goto done;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dwUsage = 0;
|
||
|
|
||
|
done:;
|
||
|
return dwUsage;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @doc INTERNAL
|
||
|
*
|
||
|
* @func UINT | GetHIDString |
|
||
|
*
|
||
|
* Given a HID usage page and usage, obtain a generic string
|
||
|
* that describes it if we recognize it.
|
||
|
*
|
||
|
* @parm DWORD | Usage |
|
||
|
*
|
||
|
* Usage number to convert. This is a <t DWORD> instead of
|
||
|
* a <t USAGE> because you aren't supposed to pass short types
|
||
|
* as parameters to functions.
|
||
|
*
|
||
|
* @parm DWORD | UsagePage |
|
||
|
*
|
||
|
* Usage page to convert.
|
||
|
*
|
||
|
* @parm LPWSTR | pwszBuf |
|
||
|
*
|
||
|
* Buffer to receive string.
|
||
|
*
|
||
|
* @parm UINT | cwch |
|
||
|
*
|
||
|
* Size of buffer.
|
||
|
*
|
||
|
* @returns
|
||
|
*
|
||
|
* Returns the number of characters retrieved, or zero
|
||
|
* if no string was obtained.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
/*
|
||
|
* Maps usage pages to string groups. Each string group is 512 strings long.
|
||
|
* Zero means "No string group".
|
||
|
*/
|
||
|
UINT c_mpuiusagePage[] = {
|
||
|
0, /* Invalid */
|
||
|
IDS_PAGE_GENERIC, /* HID_USAGE_PAGE_GENERIC */
|
||
|
IDS_PAGE_VEHICLE, /* HID_USAGE_PAGE_SIMULATION */
|
||
|
IDS_PAGE_VR, /* HID_USAGE_PAGE_VR */
|
||
|
IDS_PAGE_SPORT, /* HID_USAGE_PAGE_SPORT */
|
||
|
IDS_PAGE_GAME, /* HID_USAGE_PAGE_GAME */
|
||
|
0, /* ??????????????????????? */
|
||
|
IDS_PAGE_KEYBOARD, /* HID_USAGE_PAGE_KEYBOARD */
|
||
|
IDS_PAGE_LED, /* HID_USAGE_PAGE_LED */
|
||
|
0, /* HID_USAGE_PAGE_BUTTON */
|
||
|
0, /* HID_USAGE_PAGE_ORDINAL */
|
||
|
IDS_PAGE_TELEPHONY, /* HID_USAGE_PAGE_TELEPHONY */
|
||
|
IDS_PAGE_CONSUMER, /* HID_USAGE_PAGE_CONSUMER */
|
||
|
IDS_PAGE_DIGITIZER, /* HID_USAGE_PAGE_DIGITIZER */
|
||
|
0, /* ??????????????????????? */
|
||
|
IDS_PAGE_PID, /* HID_USAGE_PAGE_PID */
|
||
|
};
|
||
|
|
||
|
UINT EXTERNAL
|
||
|
GetHIDString(DWORD Usage, DWORD UsagePage, LPWSTR pwszBuf, UINT cwch)
|
||
|
{
|
||
|
UINT uiRc;
|
||
|
|
||
|
if (UsagePage < cA(c_mpuiusagePage) &&
|
||
|
c_mpuiusagePage[UsagePage] &&
|
||
|
Usage < 512) {
|
||
|
uiRc = LoadStringW(g_hinst, c_mpuiusagePage[UsagePage] + Usage,
|
||
|
pwszBuf, cwch);
|
||
|
|
||
|
SquirtSqflPtszV(sqflHidUsage | sqflBenign,
|
||
|
TEXT("[%s]\nName=%s\n Usage=%d \n UsagePage=%d"),
|
||
|
pwszBuf, pwszBuf, Usage, UsagePage );
|
||
|
|
||
|
} else {
|
||
|
uiRc = 0;
|
||
|
}
|
||
|
return uiRc;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* @doc INTERNAL
|
||
|
*
|
||
|
* @func void | InsertCollectionNumber |
|
||
|
*
|
||
|
* Prefix the collection number on the existing string.
|
||
|
*
|
||
|
* @parm UINT | icoll |
|
||
|
*
|
||
|
* Collection number to be prefixed.
|
||
|
*
|
||
|
* (Actually, it's placed wherever the string resource
|
||
|
* tells us, to allow for localization.)
|
||
|
*
|
||
|
* @parm LPWSTR | pwsz |
|
||
|
*
|
||
|
* Output buffer assumed to be of size MAX_PATH.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
void EXTERNAL
|
||
|
InsertCollectionNumber(UINT icoll, LPWSTR pwszBuf)
|
||
|
{
|
||
|
TCHAR tsz[MAX_PATH];
|
||
|
TCHAR tszFormat[64];
|
||
|
#ifndef UNICODE
|
||
|
TCHAR tszOut[MAX_PATH];
|
||
|
#endif
|
||
|
int ctch;
|
||
|
|
||
|
ctch = LoadString(g_hinst, IDS_COLLECTIONTEMPLATEFORMAT,
|
||
|
tszFormat, cA(tszFormat));
|
||
|
|
||
|
/*
|
||
|
* Make sure the combined format and collection name
|
||
|
* don't overflow the buffer. The maximum length of
|
||
|
* the stringification of icoll is 65534 because we
|
||
|
* allow only 16 bits worth of DIDFT_INSTANCEMASK.
|
||
|
*
|
||
|
* We also have to put it into a holding buffer because
|
||
|
* pwszBuf is about to be smashed by the upcoming wsprintf.
|
||
|
*/
|
||
|
UToT(tsz, cA(tsz) - ctch, pwszBuf);
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
wsprintfW(pwszBuf, tszFormat, icoll, tsz);
|
||
|
#else
|
||
|
wsprintfA(tszOut, tszFormat, icoll, tsz);
|
||
|
TToU(pwszBuf, MAX_PATH, tszOut);
|
||
|
#endif
|
||
|
}
|