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

📄 hid.cpp

📁 Intel PXA270 Wince5.0 BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}   


DWORD CALLBACK 
CHid::ControlCompletionStub(LPVOID lpvNotifyParameter)
{
    SHidDevice *pstHidDevice = (SHidDevice *)lpvNotifyParameter;
    DEBUGCHK(pstHidDevice->signalStatus & gcSignalStatusCtrlPending);
    pstHidDevice->signalStatus |= gcSignalStatusCtrlSignaled;
    SetEvent(gpobHid->m_hEvent);
    return 0;
}

DWORD CALLBACK 
CHid::InterruptCompletionStub(LPVOID lpvNotifyParameter)
{
    SHidDevice *pstHidDevice = (SHidDevice *)lpvNotifyParameter;
    DEBUGCHK(pstHidDevice->signalStatus & gcSignalStatusIntrPending);
    pstHidDevice->signalStatus |= gcSignalStatusIntrSignaled;
	RETAILMSG(RETAIL_ZONE_HID,(TEXT("Hid::InterruptCompletionStub: device %08x, signalling event %08x.\r\n"), pstHidDevice, gpobHid->m_hEvent ));
    SetEvent(gpobHid->m_hEvent);
    return 0;
}

#ifdef DEBUG
static TCHAR *TagDesc[] =
{
    L"!RSVD!",
    L"Usage Page", //x01
    L"Usage", //x02
    L"!RSVD!",
    L"!RSVD!",
    L"Logical Min", //x05
    L"Usage Min", //x06
    L"!RSVD!",
    L"!RSVD!",
    L"Logical Max", //x09
    L"Usage Max", //x0a
    L"!RSVD!",
    L"!RSVD!",
    L"Physical Min", //x0d
    L"Designator Index", //x0e
    L"!RSVD!",
    L"!RSVD!",
    L"Physical Max", //x11
    L"Designator Min", //x12
    L"!RSVD!",
    L"!RSVD!",
    L"Unit Exponent", //x15
    L"Designator Max", //x16
    L"!RSVD!",
    L"!RSVD!",
    L"Unit", //x19
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"Report Size", //x1d
    L"String Index", //x1e
    L"!RSVD!",
    L"Input", //x20
    L"Report ID", //x21
    L"String Min", //x22
    L"!RSVD!",
    L"Output", //x24
    L"Report Count", //x25
    L"String Max", //x26
    L"!RSVD!",
    L"Collection", //x28
    L"Push", //x29
    L"Delimiter", //x2a
    L"!RSVD!",
    L"Feature", //x2c
    L"Pop", //x2d
    L"!RSVD!",
    L"!RSVD!",
    L"End Collection", //x30
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
    L"!RSVD!",
};
#endif

BOOL
CHid::ParseReportDescriptor(
                           SHidDevice *pstHidDevice)
{
    PUCHAR pBuffer = pstHidDevice->pDataBuffer;
    UINT descriptorLength  = pstHidDevice->wReportDescriptorLength;
    UINT byte;
    UINT8 infoByte;
    int dataLength;
    int collectionDepth = 0;
    PFN_PARSE_HANDLER pfnHandler;
    BOOL fRet;

    BOOL bDidSomething = FALSE;

    UINT32 dwData;
    INT32 sigData;

    SParseState *pstState = new SParseState;
    SParseState *pstStateTemp;
    memset(pstState, 0, sizeof(SParseState));

    DEBUGMSG(ZONE_FUNCTION,(TEXT("+CHid::ParseReportDescriptor\r\n")));
// Gotta go through all this because each debug message may be prefixed by the thread ID...
#ifdef DEBUGNEVER   // ever try to read the raw dump? yech. i have a better dump below.
    if (ZONE_REPORT) {
        WCHAR szFmtBuf[2000];
        int   iLen;
        iLen = wsprintf(szFmtBuf,TEXT("%d byte Report Descriptor:"), descriptorLength);
        for (byte = 0; (byte < descriptorLength) && 
            (iLen < (sizeof(szFmtBuf)/sizeof(szFmtBuf[0]) - 10)); byte++) {
            if (byte % 8 == 0)
                iLen += wsprintf(szFmtBuf+iLen,TEXT("\r\n    "));

            iLen += wsprintf(szFmtBuf+iLen,TEXT(" %02X"), pBuffer[byte]);
        }
        wcscpy(szFmtBuf+iLen,TEXT("\r\n"));
        DEBUGMSG(ZONE_REPORT, (TEXT("%s"), szFmtBuf));
    }
#endif //DEBUG

    for (byte = 0; byte < descriptorLength; byte++) {
        infoByte = pBuffer[byte];

        dataLength = GetDataSize(infoByte);
        if (dataLength < 0) {
            // It's a long data item.
            DEBUGMSG(ZONE_ERROR,
                     (TEXT("HID: Parse error, long data items not supported.\r\n")));
            dataLength = 1 + pBuffer[byte + 1];
            continue;
        }

        ConvertData(&pBuffer[byte + 1], dataLength, &dwData, &sigData);

#ifdef DEBUG
        DEBUGMSG(ZONE_REPORT, (TEXT("RDesc idx %3d (%02X) len=%d tag=%02X (%s) data=%04X or %04X\r\n"),
                               byte, infoByte, dataLength, infoByte>>2, TagDesc[infoByte>>2], dwData, sigData));
#endif

        byte += dataLength;

        // We've already got the length info.  Mask off those bits now.
        infoByte &= ~gcParseShortItemLengthMask;

        switch (infoByte) {
            case gcParseGlobalUsagePage:
                pstState->usagePage = dwData;
                if (pstState->usagePage != gcParseUsagePageGenericDesktop &&
                    pstState->usagePage != gcParseUsagePageKeyboard &&
                    pstState->usagePage != gcParseUsagePageLEDs &&
                    pstState->usagePage != gcParseUsagePageButtons) {
                    DEBUGMSG(ZONE_ERROR,
                             (TEXT("HID: Parse error, %02X is an unsupported usage page\r\n"),
                              pstState->usagePage));
                }
                break;

            case gcParseLocalUsage:
                pstState->usage[pstState->nextFreeUsage] = dwData;
                pstState->nextFreeUsage++;
                if (pstState->usagePage == gcParseUsagePageGenericDesktop) {
                    if (dwData == gcParseDesktopUsageMouse ||
                        dwData == gcParseDesktopUsageKeyboard ||
                        dwData == gcParseDesktopUsageJoystick ||
                        dwData == gcParseDesktopUsageGamePad) {
                        pstState->nextFreeUsage--;
                        pstState->pstData =
                        AllocateDescriptionStruct(
                                                 &pstHidDevice->pstDataDescriptionHead);
                        if (pstState->pstData == NULL) {
                            return (FALSE);
                        }

                        bDidSomething = TRUE;

                        pstHidDevice->wDeviceUsagePage = pstState->usagePage;
                        pstHidDevice->wDeviceUsage = dwData;

                        if (pstState->reportId == 0) {
                            pstState->curBit = 0;
                        }
                        else {
                            pstState->curBit = 8;
                        }

                        if (dwData == gcParseDesktopUsageMouse) {
                            pstState->pstData->deviceType = gcDeviceTypeMouse;
                            pstState->pstData->pfnParseHandler = ParseMouse;
                            pstState->pstData->mouse.pButtonOffsets = NULL;
                            pstHidDevice->dwDeviceType = DIDEVTYPE_MOUSE;
                        }
                        else if (dwData == gcParseDesktopUsageKeyboard) {
                            pstState->pstData->deviceType = gcDeviceTypeKeyboard;
                            pstState->pstData->pfnParseHandler = ParseKeyboard;
                            pstHidDevice->dwDeviceType = DIDEVTYPE_KEYBOARD;
                        }
                        else { // Joystick or Gamepad
                            pstState->pstData->deviceType = gcDeviceTypeJoystick;
                            pstState->pstData->pfnParseHandler = ParseJoystick;
                            pstState->pstData->joy.pButtonOffsets = NULL;
                            pstHidDevice->dwDeviceType = DIDEVTYPE_JOYSTICK;
                        }                   
                    }

                }
                break;

            case gcParseGlobalReportId:
                pstState->reportId = dwData;
                if (pstState->curBit == 0) {
                    pstState->curBit = 8;
                }
                break;

            case gcParseMainCollection:
                collectionDepth++;
                break;

            case gcParseMainEndCollection:
                collectionDepth--;
                break;

            case gcParseGlobalReportSize:
                pstState->reportSize = dwData;
                break;

            case gcParseGlobalReportCount:
                pstState->reportCount = dwData;
                break;

            case gcParseGlobalLogicalMinimum:
                pstState->logicalMin = sigData;
                break;

            case gcParseGlobalLogicalMaximum:
#ifdef DONT_USE_MIN_MAX_WORKAROUND
                pstState->logicalMax = sigData;
#else
                if (sigData < pstState->logicalMin) {
                    // If max < min, they forgot this was a signed value
                    // and said something like min = 0 max = 0xFF
                    pstState->logicalMax = dwData;              
                }
                else {
                    pstState->logicalMax = sigData;             
                }
#endif //DONT_USE_MIN_MAX_WORKAROUND
                break;

            case gcParseGlobalPhysicalMinimum:
                pstState->physicalMin = sigData;
                break;

            case gcParseGlobalPhysicalMaximum:
#ifdef DONT_USE_MIN_MAX_WORKAROUND
                pstState->physicalMax = sigData;
#else
                if (sigData < pstState->physicalMin) {
                    // If max < min, they forgot this was a signed value
                    // and said something like min = 0 max = 0xFF
                    pstState->physicalMax = dwData;             
                }
                else {
                    pstState->physicalMax = sigData;                
                }
#endif //DONT_USE_MIN_MAX_WORKAROUND
                break;

            case gcParseLocalUsageMinimum:
                pstState->usageMin = sigData;
                break;

            case gcParseLocalUsageMaximum:
                pstState->usageMax = sigData;
                break;

            case gcParseMainOutput:
            case gcParseMainInput:
            case gcParseMainFeature:
                if (pstState->pstData == NULL ||
                    pstState->pstData->pfnParseHandler == NULL) {
                    DEBUGMSG(ZONE_ERROR,
                             (TEXT("Parse error. Main before Usage\r\n")));
                    return (FALSE);
                }

                // pfnHandler points to one of the Parse handler functions
                // (ie, ParseKeyboard or ParseJoystick).  This value was set
                // in the gcParseLocalUsage case above.
                pfnHandler = pstState->pstData->pfnParseHandler;
                fRet = (this->*pfnHandler)(pstState, infoByte, dwData);
                if (!fRet)
                    return (FALSE);
                break;

            case gcParseGlobalPush:
                pstStateTemp = new SParseState;
                memcpy(pstStateTemp, pstState, sizeof(SParseState));
                pstState->pNext = pstStateTemp;
                break;

            case gcParseGlobalPop:
                CopyStateGlobals(pstState, pstStateTemp);
                pstState->pNext = pstStateTemp->pNext;
                delete pstStateTemp;
                break;

        }
    }

    pstHidDevice->intrBufferSize = pstState->curBit / 8;
    if (pstState->curBit % 8 != 0) {
        pstHidDevice->intrBufferSize++;
    }

#ifdef DEBUG
    if (ZONE_REPORT) {
        DumpDataDescription(pstState->pstData);
    }
#endif

    // Deallocate the state info structures.  There SHOULD only be one, but
    // it's always possible that an IHV did a push without a pop.
    while (pstState != NULL) {
        pstStateTemp = pstState;
        pstState = pstState->pNext;
        delete pstStateTemp;
    }

    DEBUGMSG(ZONE_FUNCTION,(TEXT("-CHid::ParseReportDescriptor\r\n")));

    if (!bDidSomething) {
        return (FALSE);
    }

    return (TRUE);   
}


BOOL
CHid::ParseMouse(
                SParseState *pstState,
                UINT8 type,
                UINT32 data)
{
    UINT curUsage;
    UINT offset;
    BOOL bFoundAxis;
    UINT axisNum;
    SDataDescription *pstData = pstState->pstData;
    DEBUGMSG(ZONE_FUNCTION,(TEXT("+CHid::ParseMouse\r\n")));

    if (type != gcParseMainInput) {
        // We don't do anything with anything but inputs, so ignore these.
        return (TRUE);
    }

⌨️ 快捷键说明

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