|
|
/***************************************************************************
* * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved. * * File: dihid.h * Content: DirectInput internal include file for HID * ***************************************************************************/
#ifndef _DIHID_H
#define _DIHID_H
/*
* Defines that should be in hidusage.h but are not yet */
#ifndef HID_USAGE_PAGE_PID
#define HID_USAGE_PAGE_PID ( (USAGE) 0x0000f )
#endif
#ifndef HID_USAGE_PAGE_VENDOR
#define HID_USAGE_PAGE_VENDOR ( (USAGE) 0xff00 )
#endif
#ifndef HID_USAGE_SIMULATION_RUDDER
#define HID_USAGE_SIMULATION_RUDDER ((USAGE) 0xBA)
#endif
#ifndef HID_USAGE_SIMULATION_THROTTLE
#define HID_USAGE_SIMULATION_THROTTLE ((USAGE) 0xBB)
#endif
#ifndef HID_USAGE_SIMULATION_ACCELERATOR
#define HID_USAGE_SIMULATION_ACCELERATOR ((USAGE) 0xC4)
#endif
#ifndef HID_USAGE_SIMULATION_BRAKE
#define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xC5)
#endif
#ifndef HID_USAGE_SIMULATION_CLUTCH
#define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xC6)
#endif
#ifndef HID_USAGE_SIMULATION_SHIFTER
#define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xC7)
#endif
#ifndef HID_USAGE_SIMULATION_STEERING
#define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xC8)
#endif
#ifndef HID_USAGE_GAME_POV
#define HID_USAGE_GAME_POV ((USAGE) 0x20)
#endif
/*****************************************************************************
* * @doc INTERNAL * * @struct HIDDEVICEINFO | * * Records information about a single hid device. * * @field DIOBJECTSTATICDATA | osd | * * Standard information that identifies the device crudely. * * The <e DIOBJECTSTATICDATA.dwDevType> field contains the * device type code, used by * <f CDIDEnum_Next>. * * If the device is a HID mouse, then the remaining fields * are commandeered as follows: * * The <e DIOBJECTSTATICDATA.pcguid> field is the number * of buttons on the mouse. * * The <e DIOBJECTSTATICDATA.CreateDcb> field is the number * of axes on the mouse. * * See <f DIHid_ProbeMouse> for an explanation of why we * need to do this. * * @field PSP_DEVICE_INTERFACE_DETAIL_DATA | pdidd | * * Pointer to name for device to be used in <f CreateFile>. * * @field HKEY | hk | * * Registry key that contains configuration information. * Sadly, we must keep it open because there is no way to * obtain the name of the key, and the only way to open the * key is inside an enumeration. * * @field HKEY | hkOld | * * Registry key that contains configuration information. * This key originally pointed to the registry used in Win2k Gold. * It is to maintain compatibiltiy with Win2k Gold. * * @field LPTSTR | ptszId | * * Cached device ID that allows us to access other information * about the device. * * @field GUID | guid | * * The instance GUID for the device. * * @field GUID | guidProduct | * * The product GUID for the device. * * @field WORD | ProductID | * * The PID for the device * * @field WORD | VendorID | * * The VID for the device * * *****************************************************************************/
typedef struct HIDDEVICEINFO { DIOBJECTSTATICDATA osd; PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd; HKEY hk; HKEY hkOld; LPTSTR ptszId; GUID guid; GUID guidProduct; int idJoy; WORD ProductID; WORD VendorID; BOOL fAttached; } HIDDEVICEINFO, *PHIDDEVICEINFO;
/*****************************************************************************
* * @doc INTERNAL * * @struct HIDDEVICELIST | * * Records information about all the HID devices. * * @field int | chdi | * * Number of items in the list that are in use. * * @field int | chdiAlloc | * * Number of items allocated in the list. * * @field HIDDEVICEINFO | rghdi[0] | * * Variable-size array of device information structures. * *****************************************************************************/
typedef struct HIDDEVICELIST {
int chdi; int chdiAlloc; int idMaxJoy; HIDDEVICEINFO rghdi[0];
} HIDDEVICELIST, *PHIDDEVICELIST;
extern PHIDDEVICELIST g_phdl;
#define cbHdlChdi(chdi) FIELD_OFFSET(HIDDEVICELIST, rghdi[chdi])
/*
* We choose our starting point at 64 devices, since * that's the maximum number of USB devices supported. This * avoids needless reallocs. */
#define chdiMax 64
#define chdiInit 16
/*
* Tag for unused translation of object instance */ #define NOREGTRANSLATION (0x80000000)
/*
* VID/PID definitions used to handle analog devices */ #define MSFT_SYSTEM_VID (0x45E)
#define MSFT_SYSTEM_PID (0x100)
#define ANALOG_ID_ROOT TEXT("VID_045E&PID_01")
/*
* VID/PID template so that upper case hex is always used */ #define VID_PID_TEMPLATE TEXT("VID_%04X&PID_%04X")
/*
* Size of string in characters generated using VID_PID_TEMPLATE */ #define cbszVIDPID cA( VID_PID_TEMPLATE )
/*****************************************************************************
* * dihidenm.c - HID enumeration functions. * *****************************************************************************/
extern TCHAR g_tszIdLastRemoved[MAX_PATH]; //in dihidenm.c
extern DWORD g_tmLastRemoved; //in dihinenm.c
STDMETHODIMP hresFindHIDInstanceGUID(PCGUID pguid, CREATEDCB *pcdcb); STDMETHODIMP hresFindHIDDeviceInterface(LPCTSTR ptszPath, LPGUID pguidOut);
PHIDDEVICEINFO EXTERNAL phdiFindHIDInstanceGUID(PCGUID pguid); PHIDDEVICEINFO EXTERNAL phdiFindHIDDeviceInterface(LPCTSTR ptszPath);
void EXTERNAL DIHid_BuildHidList(BOOL fForce); void EXTERNAL DIHid_EmptyHidList(void);
BOOL EXTERNAL DIHid_GetDevicePath(HDEVINFO hdev, PSP_DEVICE_INTERFACE_DATA pdid, PSP_DEVICE_INTERFACE_DETAIL_DATA *ppdidd, PSP_DEVINFO_DATA pdinf);
BOOL EXTERNAL DIHid_GetDeviceInstanceId(HDEVINFO hdev, PSP_DEVINFO_DATA pdinf, LPTSTR *pptszId);
BOOL EXTERNAL DIHid_GetInstanceGUID(HKEY hk, LPGUID pguid);
/*****************************************************************************
* * diguid.c - GUID generation * *****************************************************************************/
void EXTERNAL DICreateGuid(LPGUID pguid); void EXTERNAL DICreateStaticGuid(LPGUID pguid, WORD pid, WORD vid);
/*****************************************************************************
* * dihid.c * *****************************************************************************/
/*****************************************************************************
* * We will just use the HID item index as our DirectInput * internal ID number, which is in turn an index into the * <t DIOBJECTDATAFORMAT> array. * * Keyboard support requires a translation table. * Other devices also a translation table so that the external * instance numbers can be made compatible with legacy ones and * so that secondary aliases can be separated from primary ones. * * Since HID restarts the item index counter at zero for * each of input, feature, and output, we need to do some * adjustment so there aren't any collisions. So we * shift the features to start after the inputs, and the * outputs to start after the features. * * The <e CHid.rgdwBase> array contains the amount by which * each group of HID item indexes has been shifted. * *****************************************************************************/
/*****************************************************************************
* * @doc INTERNAL * * @func BOOL | HidP_IsValidReportType | * * For debugging only. Check if a value is a valid * <t HIDP_REPORT_TYPE>. * * Note that we also create a "fake" report type in which * to record our collections. * * @field HIDP_REPORT_TYPE | type | * * One of the values * <c HidP_Input>, * <c HidP_Output>, * or * <c HidP_Feature>. Hopefully. * *****************************************************************************/
#define HidP_Max (HidP_Feature + 1)
#define HidP_Coll HidP_Max
#define HidP_MaxColl (HidP_Coll + 1)
BOOL INLINE HidP_IsValidReportType(HIDP_REPORT_TYPE type) { CAssertF(HidP_Input == 0); CAssertF(HidP_Output == 1); CAssertF(HidP_Feature == 2); return type < HidP_Max; }
/*****************************************************************************
* * There are three (overlapping) classes of HID reports. * * InputLike - HidP_Input and HidP_Feature * OutputLike - HidP_Output and HidP_Feature * NothingLike - HidP_Coll * *****************************************************************************/
BOOL INLINE HidP_IsInputLike(HIDP_REPORT_TYPE type) { return type == HidP_Input || type == HidP_Feature; }
BOOL INLINE HidP_IsOutputLike(HIDP_REPORT_TYPE type) { return type == HidP_Output || type == HidP_Feature; }
/*****************************************************************************
* * @doc INTERNAL * * @struct LMINMAX | * * Min and max, that's all. These are kept in structures * to make logical-to-physical and physical-to-logical * translations less gross. * * @field LONG | Min | * * The minimum value. * * @field LONG | Max | * * The maximum value. * *****************************************************************************/
typedef struct LMINMAX { LONG Min; LONG Max; } LMINMAX, *PLMINMAX;
typedef const LMINMAX *PCLMINMAX;
/*****************************************************************************
* * @doc INTERNAL * * @struct HIDGROUPCAPS | * * This structure unifies the various HID caps structures * <t HIDP_BUTTON_CAPS> and * <t HIDP_VALUE_CAPS>. * * @field HIDP_REPORT_TYPE | type | * * One of the values * <c HidP_Input>, * <c HidP_Output>, * or * <c HidP_Feature>. * * @field UINT | cObj | * * Number of objects in this group. * * @field USAGE | UsagePage | * * Usage page for all usages in the group. * * @field USAGE | UsageMin | * * First usage described by this group. The remaining * items are numbered consecutively starting from * this value. * * @field USHORT | StringMin | * * String for first usage described by this group. * The remaining strings are numbered consecutively * starting from this value, unless the string maximum * is reached, in which case all subsequent objects * share that last string. * * @field USHORT | StringMax | * * Last string. * * @field USHORT | DesignatorMin | * * Designator for first usage described by this group. * The remaining designators are numbered consecutively * starting from this value, unless the designator maximum * is reached, in which case all subsequent objects * share that last designator. * * @field USHORT | DesignatorMax | * * Last designator. * * @field USHORT | DataIndexMin | * * Data index for the first usage described by this group. * The remaining data index values are numbered consecutively * starting from this value. * * @field USHORT | usGranularity | * * If object is a POV or wheel, then contains device granularity. * * @field LONG | lMask | * * Mask bits used for sign extension. For example, if the * value is 8-bits, the mask will be 0xFFFFFF80, indicating * that bit 7 (0x00000080) is extended to fill the remainder * of the value. * * This field is used only by values. * * @field USHORT | BitSize | * * Number of bits devoted to this value, including the sign bit. * * ISSUE-2001/03/29-timgill structure field probably not used anywhere. * * @field USHORT | LinkCollection | * * HID link collection number. * * @field LMINMAX | Logical | * * Logical minimum and maximum values. * These are the extremes of raw values * that can validly be received from the device. * * This field is used only by values. * * @field LMINMAX | Physical | * * Physical minimum and maximum values. * This is the "actual" value * that the logical minimum and maximum value corresponds to. * * This field is used only by values, and is consulted * only when converting between DirectInput calibration * (which uses logical values) and VJOYD calibration * (which uses physical values). * * @field LONG | Null | * * The null value to be used for output. * * This field is used only by values. * * @field ULONG | Units | * * The HID units descriptor, if any. * * @field WORD | Exponent | * * The HID unit exponent, if any. * * @field WORD | wReportId | * * HID report Id * * @field BOOL | IsAbsolute | * * Nonzero if the group describes absolute axes. * * This field is used only by values. * * @field BOOL | IsValue | * * Nonzero if the group describes a HID value. * * Note that an analog pushbutton is reported by * DirectInput as a <c DIDFT_BUTTON>, but is * handled internally as a HID value. * * @field BOOL | IsAlias | * * Nonzero if the group describes an alias. * * @field BOOL | IsSigned | * * The return data is signed. * * @field BOOL | IsPolledPOV | * * TRUE if axis is a polled POV. * * @devnote New for DX6.1a * *****************************************************************************/
#define HIDGROUPCAPS_SIGNATURE 0x47444948 /* HIDG */
typedef struct HIDGROUPCAPS {
D(DWORD dwSignature;) HIDP_REPORT_TYPE type; UINT cObj;
USAGE UsagePage; USAGE UsageMin;
USHORT StringMin, StringMax; USHORT DesignatorMin, DesignatorMax; USHORT DataIndexMin;
USHORT usGranularity;
LONG lMask;
USHORT BitSize;
USHORT LinkCollection;
LMINMAX Logical; LMINMAX Physical;
LONG Null;
ULONG Units; WORD Exponent;
WORD wReportId; BOOL fReportDisabled; BOOL Reserved;
BOOL IsAbsolute; BOOL IsValue; BOOL IsAlias; BOOL IsSigned; #ifdef WINNT
BOOL IsPolledPOV; #endif
} HIDGROUPCAPS, *PHIDGROUPCAPS;
/*****************************************************************************
* * @doc INTERNAL * * @struct HIDOBJCAPS | * * This structure contains various cached pointers for each * object on the device, allowing us to get at things like * the group caps and the calibration information. * * @field PHIDGROUPCAPS | pcaps | * * The <t PHIDGROUPCAPS> for the group the object belongs to. * * @field PJOYRANGECONVERT | pjrc | * * If non-NULL, then points to the range conversion information * for the object. * * @field int | idata | * * Index into the <t HIDP_DATA> array for the corresponding * output/feature report, * or <c -1> if the item is not in the output/feature report. * *****************************************************************************/
typedef struct HIDOBJCAPS { PHIDGROUPCAPS pcaps; PJOYRANGECONVERT pjrc; int idata; } HIDOBJCAPS, *PHIDOBJCAPS;
/*****************************************************************************
* * @doc INTERNAL * * @struct HIDREPORTINFO | * * This structure contains information that is used for * parsing HID reports. * * @field PHIDP_DATA | rgdata | * * Array used when parsing reports via * <f HidP_GetData> or <f HidP_SetData>. This MUST be aligned * correctly on some architechtures. * * @field PV | pvReport | * * The report itself. * * @field int | cdataMax | * * Number of elements in the <e HIDREPORTINFO.rgdata> array. * * @field int | cdataUsed | * * Number of elements in the <e HIDREPORTINFO.rgdata> array * that are actually in use. * * @field ULONG | cbReport | * * Number of bytes in the report. * * @field BOOL | fNeedClear | * * Nonzero if the report needs to be zero'd out because we * deleted something (most likely a button) from it. * The only way to delete an item from a report is to zero * out the entire report and then re-add everything back in. * * @field BOOL | fChanged | * * Nonzero if an element in the report has changed. * *****************************************************************************/
typedef struct HIDREPORTINFO { PHIDP_DATA rgdata; PV pvReport; int cdataMax; int cdataUsed; ULONG cbReport; BOOL fNeedClear; BOOL fChanged; } HIDREPORTINFO, *PHIDREPORTINFO;
/*****************************************************************************
* * @doc INTERNAL * * @struct CHid | * * The <i IDirectInputDeviceCallback> object for HID devices. * * @field IDirectInputDeviceCalllback | didc | * * The object (containing vtbl). * * @field PV | pvGroup2 | * * Pointer to group 2 memory. This field is a union with the * pointer to the first chunk of memory in the second memory group. * * @field HIDREPORTINFO | hriIn | * * HID input report parsing and state. * * This memory is the first chunk of group 2. * * @field HIDREPORTINFO | hriOut | * * HID output report parsing and state. * * @field HIDREPORTINFO | hriFea | * * HID feature report parsing and state. * * @field PV | pvPhys | * * Pointer to physical device status information updated * asynchronously by the data collection thread. * * @field PV | pvStage | * * Staging area used when the HID report is parsed. * * This memory is the last chunk of group 2. * * @field DWORD | cbPhys | * * Size of the physical device state. * * @field VXDINSTANCE * | pvi | * * The DirectInput instance handle. * * HID devices always run through ring 3, which is misleadingly * called "emulation". * * @field DWORD | dwDevType | * * Device type code. * * @field LPTSTR | ptszId | * * Setupapi device instance ID. Used to obtain things * like manufacturer name. * * @field LPTSTR | ptszPath | * * Path to the device, for <f CreateFile>. * * @field UINT | dwAxes | * * Number of axes on the device. * * @field UINT | dwButtons | * * Number of buttons on the device. * * @field UINT | dwPOVs | * * Number of POV controllers on the device. * * @field HANDLE | hdev | * * Handle to the device itself. This field is valid only * while the device is acquired. * * @field HANDLE | hdevEm | * * <f DuplicateHandle> of the <e CHid.hdev> which is used * by the worker thread. We need to keep this separate from * the main copy to avoid race conditions between the main * thread and the worker thread. * * @field HKEY | hkInstType | * * Per-instance registry key that contains additional configuration * information, equivalent to the joystick Type key. * * @field DWORD | rgdwBase[HidP_MaxColl] | * * Array of base indices for the three HID usage classes: * <c HidP_Input>, <c HidP_Output>, and <c HidP_Feature>. * We hide the <c HidP_Collection> base index here, too. * * @field PHIDOBJCAPS | rghoc | * * Pointer to array of * <t PHIDOBJCAPS>, one for each object on the device, * each of which in turn contains info about a single object. * * This memory is allocated as part of the * df.rgodf in the <t DIDATAFORMAT> structure * hence should not be freed separately. * * @field DIDATAFORMAT | df | * * The dynamically-generated data format based on the * usages on the HID device. * * @field DWORD | ibButtonData | * * The location of the button data inside the data format. * * @field DWORD | cbButtonData | * * The number of bytes of button data inside the data format. * * @field PBYTE * | rgpbButtonMasks | * * Pointer to a an array of pointers to byte strings to mask * the buttons relevant to a report. * * @field PHIDP_PREPARSED_DATA | ppd | * * Preparsed data generated by the HID subsystem. * * @field PHIDGROUPCAPS | rgcaps | * * Array of <t HIDGROUPCAPS> structures used to keep * track of the various buttons, groups, and collections. * * @field UINT | ccaps | * * Number of caps structures in the <e CHid.rgcaps> array. * * @field HIDP_CAPS | caps | * * Cached HID caps. * * @field OVERLAPPED | o | * * Overlapped I/O structure used by worker thread * for reading. * * * @field PJOYRANGECONVERT | pjrcNext | * * Pointer to the first <t JOYRANGECONVERT> structure * (in a preallocated array) which has * yet to be used. * This structure is used for logical-to-physical * range conversion (a.k.a. calibration). * * This memory is allocated as part of the * df.rgodf in the <t DIDATAFORMAT> structure * hence should not be freed separately. * * This field is used during device initialization to * parcel out the <t JOYRANGECONVERT>s. Afterwards, * the field is <c NULL> if we did not create any * conversion structures (hence do not need to subclass * the cooperative window to catch recalibrations). * * @field PBYTE | rgbaxissemflags | * * This points to an array which maps DirectInput axis * instance values to default semantic map flags. * * @field PINT | rgiobj | * * This points to an array which maps DirectInput instance * values (DIDFT_GETINSTANCE) into object indices. * * @field PINT | rgipov | * * If we are not a keyboard, then this is the first element in * the above array which maps povs. * * @field PINT | rgiaxis | * * If we are not a keyboard, then this is the first element in * the above array which maps axes. * * @field PINT | rgicoll | * * If we are not a keyboard, then this is the first element in * the above array which maps collections. * //ISSUE-2001/03/29-timgill need to document keyboard case behaviour
* * @field UINT | uiInstanceMax | * * The number of elements in the above * <f rgiobj> array. * * @field int | idJoy | * * Joystick identifier for <f joyGetPosEx> and friends for * legacy access. * * This value starts out as -1, to meant that * the corresponding legacy joystick is unknown. * If we do something that requires the matched legacy * joystick to be found, we check if the current value * is still valid. If not (either it is -1 or the cached * value is stale), then we go hunt for the correct value. * * @field HKEY | hkType | * * The joystick type key opened with <c MAXIMUM_ALLOWED> access. * This is not per-instance; multiple instances of the same * hardware share this key. * * @field USHORT | VendorID | * * HID vendor ID for this device. * * @field USHORT | ProductID | * * HID product ID for this device. * * @field HWND | hwnd | * * The window which we have subclassed in order to watch * for recalibration messages. * * @field BOOL | IsPolledInput | * * Nonzero if the device has to be polled for Input data. * * @field BOOL | fPIDdevice | * * Set to true if the device is found to support PID. * * @field WORD | wMaxReportId | * * The maximum (number) of ReportId used by the HID device. * * @field PUCHAR | pEnableReportId | * * Pointer to (wMaxReportId) bytes. If a reportID needs to be * polled in order to get features / set Output, then that element * of this array is set to 0x1. * * @field HKEY | hkProp | * * Extended properties for device type. Currently we keep dwFlags2 and * OEMMapFile under this key. * * @field BOOL | fEnableInputReport | * * True if Input report should be enabled for this device. * * @field BOOL | fFlags2Checked | * * True after we check the registry for Flags2 for disabling * input reports. * * @comm * * It is the caller's responsibility to serialize access as * necessary. * *****************************************************************************/
typedef struct CHid {
/* Supported interfaces */ IDirectInputDeviceCallback dcb;
union { PV pvGroup2; HIDREPORTINFO hriIn; };
HIDREPORTINFO hriOut; HIDREPORTINFO hriFea;
PV pvPhys; PV pvStage; DWORD cbPhys;
VXDINSTANCE *pvi;
DWORD dwDevType;
UINT dwAxes; UINT dwButtons; UINT dwPOVs; UINT dwCollections;
HANDLE hdev; HANDLE hdevEm;
DWORD rgdwBase[HidP_MaxColl]; PHIDOBJCAPS rghoc; DIDATAFORMAT df;
DWORD ibButtonData; DWORD cbButtonData; PBYTE *rgpbButtonMasks;
PHIDP_PREPARSED_DATA ppd; PHIDGROUPCAPS rgcaps;
PJOYRANGECONVERT pjrcNext;
HIDP_CAPS caps;
ED ed; OVERLAPPED o; DWORD dwStartRead; DWORD dwStopRead;
PBYTE rgbaxissemflags; PINT rgiobj; PINT rgipov; PINT rgiaxis; PINT rgicoll; UINT uiInstanceMax;
LPTSTR ptszId; LPTSTR ptszPath; HKEY hkInstType; UINT ccaps; int idJoy;
HKEY hkType; USHORT VendorID; USHORT ProductID; #define FAILED_POLL_THRESHOLD (0x4)
HWND hwnd; BOOL IsPolledInput; BOOL fPIDdevice; WORD wMaxReportId[HidP_Max]; PUCHAR pEnableReportId[HidP_Max];
DWORD dwVersion;
DIAPPHACKS diHacks;
HKEY hkProp;
BOOL fEnableInputReport; BOOL fFlags2Checked;
} CHid, CHID, *PCHID;
/*****************************************************************************
* * @doc INTERNAL * * @func PCHID | pchidFromPo | * * Given an interior pointer to an <t OVERLAPPED>, retrieve * a pointer to the parent <t CHid>. * * @parm LPOVERLAPPED | po | * * The pointer to convert. * *****************************************************************************/
PCHID INLINE pchidFromPo(LPOVERLAPPED po) { return pvSubPvCb(po, FIELD_OFFSET(CHid, o)); }
/*****************************************************************************
* * @doc INTERNAL * * @func PCHID | pchidFromPed | * * Given an interior pointer to a <t CEd>, retrieve * a pointer to the parent <t CHid>. * * @parm PED | ped | * * The pointer to convert. * *****************************************************************************/
PCHID INLINE pchidFromPed(PED ped) { return pvSubPvCb(ped, FIELD_OFFSET(CHid, ed)); }
/*****************************************************************************
* * @doc INTERNAL * * @func PCHID | pchidFromPem | * * Given a <t CEm>, wander back to the * <t CHid> that spawned it. * * @parm PEM | pem | * * The pointer at which to start. * *****************************************************************************/
PCHID INLINE pchidFromPem(PEM pem) { PCHID pchid = pchidFromPed(pem->ped); AssertF(pemFromPvi(pchid->pvi) == pem); return pchid; }
/*****************************************************************************
* * @doc INTERNAL * * @method UINT | CHid | ObjFromType | * * Given a <p dwType>, extract the instance number * and (if necessary) convert it to an object index. * Note, the instance number will always be of the primary instance * not an alias. * * @parm PCHID | this | * * HID device object. * * @parm DWORD | dwType | * * The type code to convert. * * @returns * * The object index, or an out-of-range value. * *****************************************************************************/
UINT INLINE CHid_ObjFromType(PCHID this, DWORD dwType) { UINT uiObj = DIDFT_GETINSTANCE(dwType);
// ISSUE-2001/03/29-timgill Range checks may be unnecessary
// MarcAnd can we ever get the out of range value?
// if so, can we really run with it?
// if not, can these range checks be converted into Asserts?
/*
* The range checking makes use of the fact that the translation * tables are taken from a contiguous memory allocation and that * aliased collections are not distinguished. */ if(this->rgiobj) { switch( DIDFT_GETTYPE(dwType) ) { case DIDFT_RELAXIS: case DIDFT_ABSAXIS: if( &this->rgiaxis[uiObj] < this->rgicoll ) { uiObj = this->rgiaxis[uiObj]; } else { uiObj = 0xFFFFFFFF; } break;
case DIDFT_PSHBUTTON: case DIDFT_TGLBUTTON: /*
* If it is keyboard, this->rgiobj == this->rgipov (see CHid_MungeKeyboard). * So, we can't test &this->rgiobj[uiObj] < this->rgipov. */ if( (GET_DIDEVICE_TYPE(this->dwDevType) == DI8DEVTYPE_KEYBOARD && uiObj < this->uiInstanceMax ) || &this->rgiobj[uiObj] < this->rgipov ) { uiObj = this->rgiobj[uiObj]; } else { uiObj = 0xFFFFFFFF; } break;
case DIDFT_POV: if( &this->rgipov[uiObj] < this->rgiaxis ) { uiObj = this->rgipov[uiObj]; } else { uiObj = 0xFFFFFFFF; } break; case (DIDFT_COLLECTION | DIDFT_NODATA): if( &this->rgicoll[uiObj] <= &this->rgiobj[this->uiInstanceMax] ) { uiObj = this->rgicoll[uiObj]; } else { uiObj = 0xFFFFFFFF; } break; case DIDFT_NODATA: /*
* So far, this TYPE only shows up on Keyboard (HID_USAGE_PAGE_LED). */ if( GET_DIDEVICE_TYPE(this->dwDevType) == DI8DEVTYPE_KEYBOARD && uiObj < this->uiInstanceMax ) { uiObj = this->rgiobj[uiObj]; } break; default: /*
* Hopefully this is just a vendor defined object but squirt * in debug as these may cause problems. */ SquirtSqflPtszV(sqflHidParse | sqflVerbose, TEXT("CHid_ObjFromType: dwType 0x%08x not converted"), dwType ); break; } } else { SquirtSqflPtszV(sqflHidParse | sqflError, TEXT("CHid_ObjFromType: Translation array missing") ); }
return uiObj; }
LONG EXTERNAL CHid_CoordinateTransform(PLMINMAX Dst, PLMINMAX Src, LONG lVal);
#ifndef WINNT
void EXTERNAL CHid_UpdateVjoydCalibration(PCHID this, UINT iobj);
void EXTERNAL CHid_UpdateCalibrationFromVjoyd(PCHID this, UINT iobj, LPDIOBJECTCALIBRATION pCal); #endif
/*****************************************************************************
* * dihidini.c - Device callback initialization stuff * *****************************************************************************/
#define INITBUTTONFLAG 0x10000000
HRESULT EXTERNAL CHid_InitParseData(PCHID this);
HRESULT EXTERNAL CHid_Init(PCHID this, REFGUID rguid);
HANDLE EXTERNAL CHid_OpenDevicePath(PCHID this, DWORD dwAttributes );
UINT EXTERNAL CHid_LoadCalibrations(PCHID this);
BOOL EXTERNAL CHid_IsPolledDevice( HANDLE hdev );
/*****************************************************************************
* * dihiddat.c - HID data parsing/management * *****************************************************************************/
typedef HRESULT (FAR PASCAL * SENDHIDREPORT)(PCHID this, PHIDREPORTINFO phri);
void EXTERNAL CHid_ResetDeviceData(PCHID this, PHIDREPORTINFO phri, HIDP_REPORT_TYPE type); HRESULT EXTERNAL CHid_AddDeviceData(PCHID this, UINT uiObj, DWORD dwData); STDMETHODIMP CHid_PrepareDeviceData(PCHID this, PHIDREPORTINFO phri); STDMETHODIMP CHid_SendHIDReport(PCHID this, PHIDREPORTINFO phri, HIDP_REPORT_TYPE type, SENDHIDREPORT SendHIDReport);
NTSTATUS EXTERNAL CHid_ParseData(PCHID this, HIDP_REPORT_TYPE type, PHIDREPORTINFO phri);
HRESULT EXTERNAL DIHid_GetRegistryProperty(LPTSTR ptszId, DWORD dwProperty, LPDIPROPHEADER pdiph);
DWORD EXTERNAL DIHid_DetectHideAndRevealFlags( PCHID this );
/*****************************************************************************
* * diemh.c - HID "emulation" * *****************************************************************************/
void EXTERNAL CEm_HID_Sync(PLLTHREADSTATE plts, PEM pem);
BOOL EXTERNAL CEm_HID_IssueRead( PCHID pchid );
#endif /* _DIHID_H */
|