⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hid.hpp

📁 Intel PXA270 Wince5.0 BSP
💻 HPP
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.

Module Name:  

hid.hpp

Abstract:  
    USB Human Interface Device (HID) class driver sample.

Functions:

Notes: 

--*/
#ifndef _HID_HPP_
#define _HID_HPP_

// Make sure we know about DirectInput
#include <hiddi.hpp>

// Debug zone defs
#ifdef DEBUG
#define ZONE_INIT               DEBUGZONE(0)
#define ZONE_ATTACH             DEBUGZONE(1)
#define ZONE_CONFIG             DEBUGZONE(2)
#define ZONE_REPORT             DEBUGZONE(3)
#define ZONE_MOUSE              DEBUGZONE(4)
#define ZONE_KEYBD              DEBUGZONE(5)
#define ZONE_JOYSTICK           DEBUGZONE(6)
#define ZONE_EVENTS             DEBUGZONE(7)
#define ZONE_FUNCTION           DEBUGZONE(13)
#define ZONE_WARNING    	DEBUGZONE(14)
#define ZONE_ERROR              DEBUGZONE(15)
#endif

#define UnusedParameter(x) x = x

// There is a bug in the version of OHCI.DLL shipped in CE 2.1 where the HID class
// descriptor is not returned if it appears after the endpoint descriptors.  Include
// code to work around this in case we distribute a HID driver as an add on for 2.1.
#define OHCI_DESC_BUG_WORKAROUND 1


const DWORD gcBitsPerByte = 8;
const DWORD gcBitsPerInt32 = 32;

const DWORD gcJoyRepeatTimeMS = 6;
const DWORD gcKeyFirstRepeatTimeMS = 400;
const DWORD gcKeyRepeatTimeMS = 50;

const UINT gcInitialMaxNumDevices = 4;

const BYTE gcInvalidOffset = 0xFF;
											 
const UINT gcConfigStatusNewDevice         = 0;
const UINT gcConfigStatusGettingConfigDesc = 1;
const UINT gcConfigStatusGettingReport     = 2;
const UINT gcConfigStatusConfigured        = 3;

const UINT gcSignalStatusNone         = 0x00;
const UINT gcSignalStatusCtrlPending  = 0x01;
const UINT gcSignalStatusIntrPending  = 0x02;
const UINT gcSignalStatusCtrlSignaled = 0x04;
const UINT gcSignalStatusIntrSignaled = 0x08;

const UINT gcSignalStatusIntr = gcSignalStatusIntrPending | gcSignalStatusIntrSignaled;
const UINT gcSignalStatusCtrl = gcSignalStatusCtrlPending | gcSignalStatusCtrlSignaled;


// Class-specific definitions (from the HID specification).

// Must use IssueVendorTransfer to make these requests.
#define USB_REQUEST_HID_GET_REPORT      0x01
#define USB_REQUEST_HID_GET_IDLE        0x02
#define USB_REQUEST_HID_GET_PROTOCOL    0x03
#define USB_REQUEST_HID_SET_REPORT      0x09
#define USB_REQUEST_HID_SET_IDLE        0x0A
#define USB_REQUEST_HID_SET_PROTOCOL    0x0B

#define HID_DESCRIPTOR_TYPE 0x21
#define HID_REPORT_DESCRIPTOR_TYPE 0x22

#pragma pack (1)
typedef struct _HID_DESCRIPTOR
{
	UCHAR	bLength;
	UCHAR	bDescriptorType;
	USHORT	bcdHID;
	UCHAR	bCountryCode;
	UCHAR	bNumDescriptors;
	UCHAR	bClassDescriptorType;
	USHORT	wDescriptorLength;	
} HID_DESCRIPTOR, *PHID_DESCRIPTOR;
#pragma pack ()


struct SParseState;
struct SDataDescription;
//struct SDiData;

struct SHidDevice
{
    USB_HANDLE hDevice;
    USB_PIPE   hIntrPipe;
    USB_TRANSFER hIntrTransfer;

    USB_TRANSFER hCtrlTransfer;

        DWORD dwId;  // despite that this is a dword, DirectInput expects it to fit in 16 bits.

	UINT configStatus;
	UINT signalStatus;

	PBYTE pDataBuffer;
	UINT dataBufferSize;	

	BOOL bValid;

	UINT intrBufferSize;

	UCHAR bConfigurationValue;
	UCHAR bMaxPacketSize;
	USHORT wReportDescriptorLength;

	BOOL bSendToInterface;
	UCHAR endptOrIntrNum;

	BOOL bRepeating;
	DWORD dwRepeatDeadline;

	WORD wDeviceUsagePage;
	WORD wDeviceUsage;
	DWORD dwDeviceType;
	int attachCount;
	BOOL bAcquired;
        BOOL bHaveFormat;
	DWORD dwBufCount;

	HANDLE hDIWakeup;
	CRITICAL_SECTION csLock; 

	PBYTE pUserData;
	DWORD userDataSize;
    
    SDataDescription *pstDataDescriptionHead;

    ULONG LedState;
};



class CHid
{
public:
	CHid();
	~CHid();
		
	BOOL Initialize(LPCUSB_FUNCS  lpUsbFuncs);

	static ULONG CALLBACK
	HidThreadStub(
		PVOID   context);

	static DWORD CALLBACK
	ControlCompletionStub(
                          LPVOID lpvNotifyParameter);
	static DWORD CALLBACK
	InterruptCompletionStub(
                          LPVOID lpvNotifyParameter);

	SHidDevice *
	HidNewDevice(
		USB_HANDLE hDevice,
        LPCUSB_INTERFACE lpInterface,
        UCHAR bMaxPacketSize0);

        BOOL
        IOControl(
                DWORD dwCode,
                PBYTE pInpBuf, DWORD dwInpLen,
                PBYTE pOutBuf, DWORD dwOutLen, PDWORD pdwActualOutLen);

	BOOL
	HidCloseDevice(
		SHidDevice *pHidDevice);	

    UINT m_curDevices;

private:


	BOOL
	ParseReportDescriptor(
		SHidDevice *pstHidDevice);

	BOOL
	ParseMouse(
		SParseState *pstState,
		UINT8 type,
		UINT32 data);

	BOOL
	ParseKeyboard(
		SParseState *pstState,
		UINT8 type,
		UINT32 data);

	BOOL
	ParseJoystick(
		SParseState *pstState,
		UINT8 type,
		UINT32 data);


	SDataDescription*
	AllocateDescriptionStruct(
		SDataDescription **ppstDataDescriptionHead);

	SDataDescription*
	DeallocateDescriptionStruct(
		SDataDescription *pstDataDescription);
	
#ifdef OHCI_DESC_BUG_WORKAROUND
	BOOL
	GetConfigDesc(
		SHidDevice *pstHidDevice,
		UINT size);

	BOOL
	ParseConfigDesc(
		SHidDevice *pstHidDevice);
#endif
	
        BOOL
	SetReport(
		SHidDevice *pstHidDevice,
                DWORD reportId,
                PVOID pData,
                WORD lenData);
	
        BOOL
	SetIdle(
		SHidDevice *pstHidDevice,
                DWORD reportId,
                DWORD idleRateMS);
	
        // A misnomer. This really gets the Report Descriptor.
        BOOL
	GetReport(
		SHidDevice *pstHidDevice);

	BOOL
	SubmitInterrupt(
		SHidDevice *pstHidDevice);

	BOOL
	InterpretData(
		SHidDevice *pstHidDevice);

	DWORD
	ConvertDataToDword(
		UINT startBit,
		UINT length,
		BOOL bSigned,
		BYTE *pBuffer);

	BOOL
	InterpretDataAsJoystick(
		SHidDevice *pstHidDevice,
		PBYTE pDataBuffer,
		SDataDescription *pstData);

	BOOL
	InterpretDataAsMouse(
		SHidDevice *pstHidDevice,
		PBYTE pDataBuffer,
		SDataDescription *pstData);

	BOOL
	InterpretDataAsKeyboard(
		SHidDevice *pstHidDevice,
		PBYTE pDataBuffer,
		SDataDescription *pstData);

	BOOL
	HandleRepeat(
		SHidDevice *pstHidDevice);

	BOOL
	KeyboardRepeat(
		SHidDevice *pstHidDevice,
		SDataDescription *pstData);
        BOOL
        HandleUnplug(
                SHidDevice *pstHidDevice);

        BOOL
        KeyboardUnplug(
                SHidDevice *pstHidDevice,
                SDataDescription *pstData);

	void
	HandleChordKeys(
		SHidDevice *pstHidDevice,
		UINT8 data,
		SDataDescription *pstData);

	void
	HandleArrayKeys(
		SHidDevice *pstHidDevice,
		PUCHAR data,
		SDataDescription *pstData);

	void
	KeyboardEvent(
	    UINT8 vkCode,
	    BOOL bDown);

        // Helper methods to implement ioctls for DirectInput
        BOOL EnumerateDevices (PBYTE inbuf, DWORD inlen, PBYTE buf, DWORD len, PDWORD retlen);
        BOOL EnumerateObjects (PBYTE inbuf, DWORD inlen, PBYTE buf, DWORD len, PDWORD retlen);
        BOOL SetFormat (PBYTE inbuf, DWORD inlen, PBYTE buf, DWORD len, PDWORD retlen);
        BOOL TransferEvent (PBYTE inbuf, DWORD inlen, PBYTE buf, DWORD len, PDWORD retlen);
        BOOL UserAttach (PBYTE inbuf, DWORD inlen, PBYTE buf, DWORD len, PDWORD retlen);
        BOOL GetUserData (PBYTE inbuf, DWORD inlen, PBYTE buf, DWORD len, PDWORD retlen);
        BOOL Acquire (PBYTE inbuf, DWORD inlen, PBYTE buf, DWORD len, PDWORD retlen);
//        BOOL Poll (PBYTE inbuf, DWORD inlen, PBYTE buf, DWORD len, PDWORD retlen);

	void DumpDataDescription(SDataDescription *pstData);
	void ClearMouseAxes(SHidDevice *pstHidDevice);

	DWORD SetTimeout();
	DWORD HidThread(void);


    LPCUSB_FUNCS  m_lpUsbFuncs;
	BOOL m_bClosing;
	CRITICAL_SECTION m_csDeviceLock;
	SHidDevice **m_ppDevices;
    UINT m_curMaxNumDevices;
    
	HANDLE m_hEvent;
	HANDLE m_hThread;
        HANDLE m_hOSDevice;      // opaque: returned by ActivateDevice, passed to DeactivateDevice

};	

const UINT gcMaxJoyAxes = 7;
const UINT gcMaxMouseAxes = 3;
const UINT gcXAxis = 0;
const UINT gcYAxis = 1;
const UINT gcZAxis = 2;
const UINT gcRxAxis = 3;
const UINT gcRyAxis = 4;
const UINT gcRzAxis = 5;
const UINT gcThrottleAxis = 6;

const UINT gcAxisToDITypeTable[] = 
{
	gcHiddiObjectTypeXAxis,
	gcHiddiObjectTypeYAxis,
	gcHiddiObjectTypeZAxis,
	gcHiddiObjectTypeRxAxis,	
	gcHiddiObjectTypeRyAxis,	
	gcHiddiObjectTypeRzAxis,
	gcHiddiObjectTypeSlider	
};

const UINT gcJoyFirstAxisId = 0;
const UINT gcJoyPovId = gcMaxJoyAxes;
const UINT gcJoyFirstButtonId = gcJoyPovId + 1;
const UINT gcMouseFirstAxisId = 0;
const UINT gcMouseFirstButtonId = gcMaxMouseAxes;


// We want to report data as going from 0 to range.  So we've set the 
// offset to logicalMin, the min to 0 and the max to logicalMax - offset.
struct SAxisInfo
{
	INT32	min;
	INT32	max;
	UINT16	wUsagePage;
	UINT16	wUsage;
	UINT8	startBit;
	UINT8	length;
	UINT8	offset;
};	

//struct SDiData
//{
//	DWORD dwTimestamp;
//	PBYTE buffer;
//	SDiData *pNext;
//};

const UINT gcHatIncrements = 36000;

struct SJoystickInfo
{
	SAxisInfo *pAxes[gcMaxJoyAxes];
	UINT8 buttonsStartBit;
	UINT8 buttonsLength;
	UINT8 altButtonsStartBit;
	UINT8 altButtonsLength;
	PBYTE pButtonOffsets;
	UINT8 hatStartBit;
	UINT8 hatLength;
	UINT8 hatMin;
	UINT8 hatMax;
	UINT8 hatOffset;
};	


struct SMouseInfo
{
	SAxisInfo *pAxes[gcMaxMouseAxes];
	PBYTE pButtonOffsets;
	DWORD prevButtons;
	UINT8 buttonsStartBit;
	UINT8 buttonsLength;
};	


const UINT gcMaxKeybdChordLength = 1;	// byte
const UINT gcMaxKeybdChordEntries = gcMaxKeybdChordLength * 8; //8 bits per byte
// Assume a max of 8 simultaneous non-chord keys.
const BYTE gcKeyUserBufferSize = gcMaxKeybdChordEntries + 8; 

struct SKeyboardInfo
{
    UINT8 chordStartByte;
    UINT8 chordLength;
    UINT8 pressedChords;
    UINT8 arrayStartByte;
    UINT8 arrayLength;
    UINT8 *pressedKeys;
    UINT8 LastRepeated;
    UINT8 numPressedKeys;
};


typedef BOOL
(CHid::*PFN_PARSE_HANDLER)(
	SParseState *pstState,
	UINT8 type,
	UINT32 data);

const UINT gcDeviceTypeUndefined	= 0;
const UINT gcDeviceTypeKeyboard		= 1;
const UINT gcDeviceTypeMouse		= 2;
const UINT gcDeviceTypeJoystick		= 3;

struct SDataDescription
{
	PFN_PARSE_HANDLER pfnParseHandler;
	UINT deviceType;
	UINT reportId;
	SDataDescription *pNext;
	union
	{
		SMouseInfo mouse;
		SKeyboardInfo keybd;
		SJoystickInfo joy;
	};
};

const UINT gcMaxUsagesPerMain = 16;

struct SParseState
{
	// Global items
	UINT32 usagePage;
	UINT32 reportSize;
	UINT32 reportCount;
	UINT32 reportId;
	INT32 logicalMin;
	INT32 logicalMax;
	INT32 physicalMin;
	INT32 physicalMax;
	// Local items 
	UINT32 usage[gcMaxUsagesPerMain];
	INT32 usageMin;
	INT32 usageMax;
	// Other
	UINT32 curBit;
	UINT32 nextFreeUsage;
	SDataDescription *pstData;
	SParseState *pNext;
};

inline void
CopyStateGlobals(
	SParseState *to,
	SParseState *from)
{
	to->usagePage = from->usagePage;
	to->reportSize = from->reportSize;
	to->reportCount = from->reportCount;
	to->reportId = from->reportId;
	to->logicalMin = from->logicalMin;
	to->logicalMax = from->logicalMax;
	to->physicalMin = from->physicalMin;
	to->physicalMax = from->physicalMax;
}	




#endif // _HID_HPP_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -