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

📄 jsthid.cpp

📁 ce5下测试游戏手柄/摇杆的驱动程序和测试代码以及一个笔记. 硬件是S3C2440. 对写CE的USB HID驱动的同志有帮助.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        CloseHandle(pHidKbd->hThread);
    }

    if (pHidKbd->hevClosing != NULL) CloseHandle(pHidKbd->hevClosing);
    if (pHidKbd->puapPrevUsages != NULL) LocalFree(pHidKbd->puapPrevUsages);
    if (pHidKbd->pbOutputBuffer != NULL) LocalFree(pHidKbd->pbOutputBuffer);
    LocalFree(pHidKbd);    
}


// Determine what usages have been set/unset and send the key events off to
// the system.
//
// On entry, pHidKbd->puapPrevUsages contains the previous usage list and
// pHidKbd->puapMakeUsages contains the most recent set of usages that
// went down (usually a single usage).
static
void
ProcessKeyboardReport(
    PHID_KBD pHidKbd,
    PCHAR pbHidPacket,
    DWORD cbHidPacket
    )
{
//    RETAILMSG( 1, (TEXT(">ProcessKeyboardReport--joystick\r\n")));

    BOOL fRollover = FALSE;
    ULONG uCurrUsages;
    DWORD dwUsageIdx;
    DWORD cbUsageList;
    DWORD cKeysSent;
    NTSTATUS status;

	static bool state=false;
    PREFAST_DEBUGCHK(pHidKbd != NULL);
    DEBUGCHK(pbHidPacket != NULL);

    uCurrUsages = pHidKbd->dwMaxUsages;
    cbUsageList = uCurrUsages * sizeof(USAGE_AND_PAGE);

    status = HidP_GetUsagesEx(
        HidP_Input,
        0,
        pHidKbd->puapCurrUsages,
        &uCurrUsages, // IN OUT parameter
        pHidKbd->phidpPreparsedData,
        pbHidPacket,
        cbHidPacket
        );
    DEBUGCHK(NT_SUCCESS(status));
    DEBUGCHK(uCurrUsages <= pHidKbd->dwMaxUsages);

    // Check usages returned for keyboard rollover.
    for (dwUsageIdx = 0; dwUsageIdx < uCurrUsages; ++dwUsageIdx) 
    {
        PUSAGE_AND_PAGE puapCurr = &pHidKbd->puapCurrUsages[dwUsageIdx];

        if (puapCurr->UsagePage == HID_USAGE_PAGE_KEYBOARD) 
        {
            if (puapCurr->Usage == HID_USAGE_KEYBOARD_ROLLOVER) {
                //RETAILMSG(1, (_T("%s: HID keyboard rollover\r\n"), pszFname));
				RETAILMSG(1, (_T("HID keyboard rollover\r\n")));
                fRollover = TRUE;
            }

            // At this point either we got the rollover usage or there will
            // not be one. Break either way.
            break;
        }
    }

    if (fRollover == FALSE) 
    {
        // Save our most recent down list.
        memcpy(pHidKbd->puapOldMakeUsages, pHidKbd->puapMakeUsages, cbUsageList);

        // Determine what keys went down and up.
        status = HidP_UsageAndPageListDifference(
            pHidKbd->puapPrevUsages,
            pHidKbd->puapCurrUsages,
            pHidKbd->puapBreakUsages,
            pHidKbd->puapMakeUsages,
            pHidKbd->dwMaxUsages
            );
        DEBUGCHK(NT_SUCCESS(status));

        if (HidP_IsSameUsageAndPage(pHidKbd->puapMakeUsages[0], g_uapZero) &&
            HidP_IsSameUsageAndPage(pHidKbd->puapBreakUsages[0], g_uapZero))
        {
            // No new keys
//			if(state==false)
//			{
//				state=true;
//				RETAILMSG(1, (_T("No new keys. Hardware autorepeat?--jsthid\r\n")));
//			}
            // Replace the list of recent downs.
            memcpy(pHidKbd->puapMakeUsages, pHidKbd->puapOldMakeUsages, cbUsageList);
        }
        else
        {
//			if(state==true){
//				state = false;
//				RETAILMSG(1, (_T("New keys appear-------------------------------jsthid\r\n")));
//			}

            // Move the current usages to the previous usage list.
            memcpy(pHidKbd->puapPrevUsages, pHidKbd->puapCurrUsages, cbUsageList);

            // Convert the key ups into scan codes and send them
            cKeysSent = SendKeyboardUsages(pHidKbd->puapBreakUsages, pHidKbd->dwMaxUsages,
                HidP_Keyboard_Break, &pHidKbd->KeyStateFlags);

            // If there were ups, then turn off repeat.
            if (cKeysSent > 0) {
                pHidKbd->ARState = AR_WAIT_FOR_ANY;
            }

            if (HidP_IsSameUsageAndPage(pHidKbd->puapCurrUsages[0], g_uapZero) == FALSE &&
                HidP_IsSameUsageAndPage(pHidKbd->puapMakeUsages[0], g_uapZero) == TRUE)
            {
                // There are not any new downs, but there may be some old ones
                // that are repeating in hardware. We'll update our make usages
                // to include any keys that have not come up.
                status = HidP_UsageAndPageListDifference(
                    pHidKbd->puapBreakUsages,
                    pHidKbd->puapOldMakeUsages,
                    pHidKbd->puapCurrUsages, // We can scrap the current usages now
                    pHidKbd->puapMakeUsages,
                    pHidKbd->dwMaxUsages
                    );
                DEBUGCHK(NT_SUCCESS(status));
            }
            else {
                // Convert the key downs to scan codes and send them
               cKeysSent = SendKeyboardUsages(pHidKbd->puapMakeUsages, pHidKbd->dwMaxUsages,
                   HidP_Keyboard_Make, &pHidKbd->KeyStateFlags);

                // If there were downs, then set for repeat.
               if (cKeysSent > 0) {
                    pHidKbd->ARState = AR_INITIAL_DELAY;
                }
            }
        }
    }
}


// Expands a usage, scan code, and flags to a full scan code and virtual key.
static
void
GenerateKeyInfo(
    const USAGE_TO_SCANCODE *pUsageToSc,
    PUINT puiVk,
    PUINT puiSc,
    PDWORD pdwFlags,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent
    )
{
	RETAILMSG( 1, (TEXT(">GenerateKeyInfo--joystick\r\n")));
	
    PREFAST_DEBUGCHK(pUsageToSc);
    PREFAST_DEBUGCHK(puiVk);
    PREFAST_DEBUGCHK(puiSc);
    PREFAST_DEBUGCHK(pdwFlags);
    
    *puiSc = pUsageToSc->uiSc;
    *pdwFlags = 0;

    if (hidpKeyEvent == HidP_Keyboard_Break) {
        *pdwFlags |= KEYEVENTF_KEYUP;
    }

    // Prepend extended bits
    switch (GET_EB(pUsageToSc->uiFlags)) {
        case EB_E0:
            *puiSc |= SC_EXTENDED_BITS;
            *pdwFlags |= KEYEVENTF_EXTENDEDKEY;
            break;

        case EB_E114:
            *puiSc |= SC_E1_BITS;
            break;

        case EB_NONE:
            break;

        default:
            // Why are you here?
            DEBUGCHK(FALSE);
    };

    // Convert scan code to virtual key
    *puiVk = MapVirtualKey(*puiSc, MAP_SC_TO_VK);
}


// Converts the usages to virtual keys and sends them off.
// Returns the number of usages converted.
//static
DWORD
SendKeyboardUsages(
    PUSAGE_AND_PAGE puapUsages,
    DWORD dwMaxUsages,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{    
//    RETAILMSG( 1, (TEXT(">SendKeyboardUsages--joystick\r\n")));
    
    PREFAST_DEBUGCHK(puapUsages != NULL);
    DEBUGCHK(pKeyStateFlags != NULL);

    for (DWORD dwIdx = 0; dwIdx < dwMaxUsages; ++dwIdx) {
        // Determine virtual key mapping
        PUSAGE_AND_PAGE puapCurr = &puapUsages[dwIdx];
        const USAGE_TO_SCANCODE *pUsageToSc = NULL;
        USAGE_TO_SCANCODE usageToSc; // For Consumer page

        if (puapCurr->Usage == 0) {
            // No more usages
            break;
        }

        // Convert the usage to a scan code with flags.
        switch (puapCurr->UsagePage) {                
            case HID_USAGE_PAGE_KEYBOARD:
                pUsageToSc = FindUsageToSc(puapCurr->Usage);
                break;
        			
            case HID_USAGE_PAGE_CONSUMER:
            {
                // Note that most consumer keys will be handled in the 0xC 0x1 
                // HID client.
                DWORD dwAssn;
                
                for (dwAssn = 0; dwAssn < dim(g_rgConsumerToScAssn); ++dwAssn) {
                    const USAGE_TO_SC_ASSOCIATION *pUsageAssn = 
                        &g_rgConsumerToScAssn[dwAssn];

                    // Later, we assume that this scan code is extended. If
                    // it is not, we need to dynamically assign the EB_E0 enum.
                    DEBUGCHK( (pUsageAssn->uiSc & SC_EXTENDED_BITS) == SC_EXTENDED_BITS );
                    
                    if (pUsageAssn->usage == puapCurr->Usage) {
                        // Fill in the local USAGE_TO_SCANCODE
                        usageToSc.uiSc = (UINT8) pUsageAssn->uiSc;
                        usageToSc.uiFlags = MAKE_FLAGS(EB_E0, PT_STANDARD);
                        pUsageToSc = &usageToSc;
                        break;
                    }
                }
                
                break;
            }
        };

        // Was there a conversion? If so, send the event.
        if (pUsageToSc != NULL) {
            DWORD dwFlags;
            UINT uiSc;
            UINT uiVk;
            PFN_PROCESSING_TYPE pfnProcessingType;
            ProcessingType PT;
            
            GenerateKeyInfo(pUsageToSc, &uiVk, &uiSc, &dwFlags, hidpKeyEvent);

            DEBUGMSG(ZONE_USAGES, (_T("%s: Usage Page: 0x%04x Usage: 0x%04x -> SC: 0x%06x\r\n"),
                pszFname, puapCurr->UsagePage, puapCurr->Usage, uiSc));

            // Determine which processing function to call
            PT = GET_PT(pUsageToSc->uiFlags);
            DEBUGCHK(dim(g_rgpfnProcessingType) == PT_COUNT);
            DEBUGCHK(PT < PT_COUNT);
            pfnProcessingType = g_rgpfnProcessingType[PT];
            PREFAST_DEBUGCHK(pfnProcessingType != NULL);

            // Call the processing function to send off the event
            (*pfnProcessingType)(uiVk, uiSc, dwFlags, hidpKeyEvent, pKeyStateFlags);
        }
        else {
            DEBUGMSG(ZONE_WARNING, (_T("%s: No scan code for Usage Page: 0x%04x Usage: 0x%04x\r\n"),
                pszFname, puapCurr->UsagePage, puapCurr->Usage));
        }
    }

    return dwIdx;
}


// Send the keyboard event to GWES.
static
void
KeyboardEvent(
    UINT vk,
    UINT sc,
    DWORD dwFlags
    )
{
    RETAILMSG( 1, (TEXT(">KeyboardEvent--joystick\r\n")));

    UINT8 uiVk = (UINT8) vk;
    UINT8 uiSc = (UINT8) sc;

    DEBUGCHK((uiVk != 0) || (uiSc != 0));

    DEBUGMSG(ZONE_USAGES, (_T("%s: Keybd event: vk: 0x%02x sc: 0x%02x flags: 0x%08x\r\n"),
        pszFname, uiVk, uiSc, dwFlags));
    keybd_event(uiVk, uiSc, dwFlags, 0);
}


// Search for usage in the g_rgUsageToScInfo tables.
static
const USAGE_TO_SCANCODE *
FindUsageToSc(
    USAGE usage
    )
{
    const USAGE_TO_SC_INFO *pUsageToScInfo;
    const USAGE_TO_SCANCODE *pUsageToSc = NULL;
    DWORD cUsageToScInfo = dim(g_rgUsageToScInfo);
    DWORD dwNormalizedUsage;
    DWORD dwIdx;

    ValidateAllUsageToSc();

    for (dwIdx = 0; dwIdx < cUsageToScInfo; ++dwIdx) 
    {
        pUsageToScInfo = &g_rgUsageToScInfo[dwIdx];

        ValidateUsageToSc(pUsageToScInfo);

        if ( (usage >= pUsageToScInfo->uFirstUsage) &&
             (usage <= pUsageToScInfo->uLastUsage) ) 
        {
            dwNormalizedUsage = usage - pUsageToScInfo->uFirstUsage;
            DEBUGCHK(dwNormalizedUsage <= pUsageToScInfo->uLastUsage);
            pUsageToSc = &pUsageToScInfo->pUsageToSc[dwNormalizedUsage];
            break;
        }
    }

    return pUsageToSc;
}


// Standard key processing.
static
void
ProcessStandard(
    UINT uiVk,
    UINT uiSc,
    DWORD dwFlags,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{
    KeyboardEvent(uiVk, uiSc, dwFlags);
}


// Updates the given key state with the given virtual key modifier.
// Only processes L/R Ctrl, Shift and Alt. The toggled key state is
// set through IOCTL calls from the Layout Manager.
static
void
UpdateKeyState(
    KEY_STATE_FLAGS *pKeyStateFlags,
    UINT8 vk,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent
    )
{
	struct VKeyToShiftState {
		UINT8           vk; // Virtual key
		KEY_STATE_FLAGS ksf;   // Corresponding shift state flag
	}; 
    
    static const VKeyToShiftState rgVKeyDownToShiftState[] = {
        { VK_LSHIFT,    KeyShiftLeftShiftFlag },
        { VK_RSHIFT,    KeyShiftRightShiftFlag },
        { VK_LCONTROL,  KeyShiftLeftCtrlFlag },
        { VK_RCONTROL,  KeyShiftRightCtrlFlag },
        { VK_LMENU,     KeyShiftLeftAltFlag },
        { VK_RMENU,     KeyShiftRightAltFlag },
    };

    DWORD dwIdx;
    const VKeyToShiftState *pvkshiftCurr;

    PREFAST_DEBUGCHK(pKeyStateFlags != NULL);
    DEBUGCHK(vk != 0);

    for (dwIdx = 0; dwIdx < dim(rgVKeyDownToShiftState); ++dwIdx) {

⌨️ 快捷键说明

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