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

📄 jsthid.cpp

📁 ce5下测试游戏手柄/摇杆的驱动程序和测试代码以及一个笔记. 硬件是S3C2440. 对写CE的USB HID驱动的同志有帮助.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        pvkshiftCurr = &rgVKeyDownToShiftState[dwIdx];
        if (pvkshiftCurr->vk == vk) {
            if (hidpKeyEvent == HidP_Keyboard_Make) {
                *pKeyStateFlags |= pvkshiftCurr->ksf;
            }
            else {
                *pKeyStateFlags &= ~pvkshiftCurr->ksf;
            }
            break;
        }
    }
}


// Send an LControl keyboard event
static
void
GenerateLControl(
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{
    DEBUGCHK(pKeyStateFlags);


    const USAGE_TO_SCANCODE *pUsageToSc = FindUsageToSc(HID_USAGE_KEYBOARD_LCTRL);
    DEBUGCHK(pUsageToSc);
    UINT uiVk;
    UINT uiSc;
    DWORD dwFlags;
    GenerateKeyInfo(pUsageToSc, &uiVk, &uiSc, &dwFlags, hidpKeyEvent);

    if (uiVk == VK_LCONTROL) {
        UpdateKeyState(pKeyStateFlags, (UINT8) uiVk, hidpKeyEvent);
        KeyboardEvent(uiVk, uiSc, dwFlags);
    }
    else {
        RETAILMSG(1, (_T("Keyboard: AltGr processing failed. Returned vkey 0x%02X\r\n"),
            uiVk));
    }
}


// Modifier key processing.
static
void
ProcessModifier(
    UINT uiVk,
    UINT uiSc,
    DWORD dwFlags,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{    
    // Handle AltGr
    if ( (uiVk == VK_RMENU) && (g_dwLocaleFlags & KLLF_ALTGR) ) {
        // Also send a Left Control
        GenerateLControl(hidpKeyEvent, pKeyStateFlags);
    }

    UpdateKeyState(pKeyStateFlags, (UINT8) uiVk, hidpKeyEvent);
    KeyboardEvent(uiVk, uiSc, dwFlags);
}


// NumPad key processing.
static
void
ProcessNumPad(
    UINT uiVk,
    UINT uiSc,
    DWORD dwFlags,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{
    static const UINT8 rgVkNumLockOff[] = {
        VK_INSERT,      //   VK_NUMPAD0        0x60
        VK_END,         //   VK_NUMPAD1        0x61
        VK_DOWN,        //   VK_NUMPAD2        0x62
        VK_NEXT,        //   VK_NUMPAD3        0x63
        VK_LEFT,        //   VK_NUMPAD4        0x64
        VK_CLEAR,       //   VK_NUMPAD5        0x65
        VK_RIGHT,       //   VK_NUMPAD6        0x66
        VK_HOME,        //   VK_NUMPAD7        0x67
        VK_UP,          //   VK_NUMPAD8        0x68
        VK_PRIOR,       //   VK_NUMPAD9        0x69
        VK_MULTIPLY,    //   VK_MULTIPLY       0x6A
        VK_ADD,         //   VK_ADD            0x6B
        VK_SEPARATOR,   //   VK_SEPARATOR      0x6C
        VK_SUBTRACT,    //   VK_SUBTRACT       0x6D
        VK_DELETE       //   VK_DECIMAL        0x6E
    };
    
    DWORD dwNormalizedIdx;
    
    PREFAST_DEBUGCHK(pKeyStateFlags != NULL);
    DEBUGCHK(uiVk >= VK_NUMPAD0);
    DEBUGCHK(uiVk < VK_NUMPAD0 + dim(rgVkNumLockOff));

    if (IS_NUMLOCK_ENABLED() == FALSE) {
        dwNormalizedIdx = uiVk - VK_NUMPAD0;
        DEBUGCHK(dwNormalizedIdx < dim(rgVkNumLockOff));
        uiVk = rgVkNumLockOff[dwNormalizedIdx];
    }

    KeyboardEvent(uiVk, uiSc, dwFlags);
}


// Special key processing that does not fit into any other category.
static
void
ProcessSpecial(
    UINT uiVk,
    UINT uiSc,
    DWORD dwFlags,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{
    UINT uiScOld = uiSc;
    
    PREFAST_DEBUGCHK(pKeyStateFlags != NULL);

    if (uiSc == SC_PRTSCRN) {
        if (ANY_ALT_DOWN()) {
            uiSc = 0x84;
        }
    }
    else if (uiSc == SC_PAUSE) {
        if (ANY_CTRL_DOWN()) {
            uiSc = 0xE07E;
        }
    }

    // If the scan code changed, update the virtual key and extended flag.
    if (uiSc != uiScOld) 
    {
        uiVk = MapVirtualKey(uiSc, MAP_SC_TO_VK);

        if ((uiSc & SC_EXTENDED_MASK) == SC_EXTENDED_BITS) {
            dwFlags |= KEYEVENTF_EXTENDEDKEY;
        }
        else {
            dwFlags &= ~KEYEVENTF_EXTENDEDKEY;
        }
    }

    KeyboardEvent(uiVk, uiSc, dwFlags);
}


// Remap the Japanese keydowns.
static
UINT8
RemapJpnKeyDown(
    UINT8 vkOnly,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{
    UINT8 vkDown = vkOnly;

    if ( vkOnly == VK_DBE_SBCSCHAR ) {
        if ( g_vkFullHalfSent ) {
            vkDown = g_vkFullHalfSent;
        }
        else if ( ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() ) {
            vkDown = g_vkFullHalfSent = VK_KANJI;
        }
        else {
            //	Don't use imm function if not configured.
            //	The remapping won't work correctly but at least there won't be link errors.
            DWORD fdwConversion;
            DWORD fdwSentence;
            if ( ImmGetConversionStatus(NULL, &fdwConversion, &fdwSentence) ) {
                if ( fdwConversion & IME_CMODE_FULLSHAPE ) {
                    vkDown = g_vkFullHalfSent = VK_DBE_SBCSCHAR;
                }
                else {
                    vkDown = g_vkFullHalfSent = VK_DBE_DBCSCHAR;
                }
            }
            else {
                vkDown = g_vkFullHalfSent = VK_DBE_SBCSCHAR;
            }
        }
    }
    else if ( vkOnly == VK_DBE_ALPHANUMERIC ) {
        if ( g_vkAlphaNumSent ) {
            vkDown = g_vkAlphaNumSent;
        }
        else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() ) {
            vkDown = g_vkAlphaNumSent = VK_DBE_ALPHANUMERIC;
        }
        else {
            vkDown = g_vkAlphaNumSent = VK_CAPITAL;
        }
    }
    else if ( vkOnly == VK_DBE_HIRAGANA ) {
        if ( g_vkHiraKataSent ) {
            vkDown = g_vkHiraKataSent;
        }
        else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() ) {
            vkDown = g_vkHiraKataSent = VK_DBE_KATAKANA;
        }
        else if ( !ANY_ALT_DOWN() && ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() ) {
            vkDown = g_vkHiraKataSent = VK_KANA;
        }
        else if ( ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() ) {
            DWORD fdwConversion;
            DWORD fdwSentence;
            if ( ImmGetConversionStatus(NULL, &fdwConversion, &fdwSentence) ) {
                if ( fdwConversion & IME_CMODE_ROMAN ) {
                    vkDown = g_vkHiraKataSent = VK_DBE_NOROMAN;
                }
                else {
                    vkDown = g_vkHiraKataSent = VK_DBE_ROMAN;
                }
            }
            else {
                vkDown = g_vkHiraKataSent = VK_DBE_NOROMAN;
            }
        }
        else {
            g_vkHiraKataSent = vkOnly;
        }
    }

    return vkDown;
}


// Remap the Japanese keyup.
static
UINT8
RemapJpnKeyUp(
    UINT8 vkOnly,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{    
    UINT8 vkUp = vkOnly;
    
    if ( vkOnly == VK_DBE_SBCSCHAR ) {
        vkUp = g_vkFullHalfSent;
        g_vkFullHalfSent = 0;
    }
    else if ( vkOnly == VK_DBE_ALPHANUMERIC ) {
        vkUp = g_vkAlphaNumSent;
        g_vkAlphaNumSent = 0;
    }
    else if ( vkOnly == VK_DBE_HIRAGANA ) {
        vkUp = g_vkHiraKataSent;
        g_vkHiraKataSent = 0;
    }

    return vkUp;
}


// Japanese key processing.
static
void
ProcessJpn(
    UINT uiVk,
    UINT uiSc,
    DWORD dwFlags,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{
    DEBUGCHK(pKeyStateFlags != NULL);
    
    if (hidpKeyEvent == HidP_Keyboard_Make) {
        uiVk = RemapJpnKeyDown(uiVk, pKeyStateFlags);
    }
    else {
        uiVk = RemapJpnKeyUp(uiVk, pKeyStateFlags);
    }

    KeyboardEvent(uiVk, uiSc, dwFlags);
}


// Do not send a key up for this key.
static
void
ProcessNoBreak(
    UINT uiVk,
    UINT uiSc,
    DWORD dwFlags,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *pKeyStateFlags
    )
{
    DEBUGCHK(pKeyStateFlags != NULL);

    if (hidpKeyEvent == HidP_Keyboard_Make) {
        KeyboardEvent(uiVk, uiSc, dwFlags);
    }
}


#ifdef DEBUG


// Validate a PHID_KBD structure
void
ValidateHidKbd(
    PHID_KBD pHidKbd
    )
{
    DWORD cbUsageList;
    
    PREFAST_DEBUGCHK(pHidKbd != NULL);
    DEBUGCHK(pHidKbd->dwSig == HID_KBD_SIG);
    DEBUGCHK(pHidKbd->hDevice != NULL);
    DEBUGCHK(pHidKbd->pHidFuncs != NULL);
    DEBUGCHK(pHidKbd->phidpPreparsedData != NULL);
    DEBUGCHK(pHidKbd->hidpCaps.UsagePage == HID_USAGE_PAGE_GENERIC);
    DEBUGCHK(pHidKbd->hidpCaps.Usage == HID_USAGE_GENERIC_KEYBOARD);
    DEBUGCHK(pHidKbd->pbOutputBuffer != NULL);
    if (pHidKbd->fhThreadInited == TRUE) {
        DEBUGCHK(pHidKbd->hThread != NULL);
    }
    DEBUGCHK(pHidKbd->ARState <= AR_AUTOREPEATING);
    if (pHidKbd->fhOSDeviceInited == TRUE) {
        DEBUGCHK(pHidKbd->hOSDevice != NULL);
    }
    DEBUGCHK(pHidKbd->hevClosing != NULL);

    cbUsageList = pHidKbd->dwMaxUsages * sizeof(USAGE_AND_PAGE);
    DEBUGCHK(pHidKbd->puapPrevUsages != NULL);
    DEBUGCHK(LocalSize(pHidKbd->puapPrevUsages) >= cbUsageList * 5);
    DEBUGCHK((DWORD) pHidKbd->puapCurrUsages == ((DWORD) pHidKbd->puapPrevUsages) + cbUsageList);
    DEBUGCHK((DWORD) pHidKbd->puapBreakUsages == ((DWORD) pHidKbd->puapCurrUsages) + cbUsageList);
    DEBUGCHK((DWORD) pHidKbd->puapMakeUsages == ((DWORD) pHidKbd->puapBreakUsages) + cbUsageList);
    DEBUGCHK((DWORD) pHidKbd->puapOldMakeUsages == ((DWORD) pHidKbd->puapMakeUsages) + cbUsageList);
}


// Validate the given USAGE_TO_SC_INFO structure.
static 
void
ValidateUsageToSc(
    const USAGE_TO_SC_INFO *pUsageToScInfo
    )
{
    DEBUGCHK(pUsageToScInfo->pUsageToSc != NULL);
    DEBUGCHK(pUsageToScInfo->uFirstUsage <= pUsageToScInfo->uLastUsage);
}


// Validate the list of USAGE_TO_SC_INFO structures.
static
void
ValidateAllUsageToSc(
    )
{
    const USAGE_TO_SC_INFO *pUsageToScInfo;
    DWORD cUsageToScInfo = dim(g_rgUsageToScInfo);
    DWORD dwOuter, dwInner;

    // Check the definitions of EB and EP
    DEBUGCHK(SET_EB(EB_COUNT) <= SET_PT(1));

    for (dwOuter = 0; dwOuter < cUsageToScInfo; ++dwOuter) 
    {
        pUsageToScInfo = &g_rgUsageToScInfo[dwOuter];
        ValidateUsageToSc(pUsageToScInfo);
    
        // Verify that this range does not overlap with any of the later ones
        USHORT uFirstUsage = pUsageToScInfo->uFirstUsage;
        USHORT uLastUsage = pUsageToScInfo->uLastUsage;
        for (dwInner = dwOuter + 1; dwInner < cUsageToScInfo; ++dwInner) {
            DEBUGCHK( (uFirstUsage < g_rgUsageToScInfo[dwInner].uFirstUsage) ||
                      (uLastUsage  > g_rgUsageToScInfo[dwInner].uLastUsage) );
        }

        // Now make sure that each USAGE_TO_SCANCODE is valid
        for (dwInner = 0; dwInner < (USHORT)(uLastUsage - uFirstUsage + 1); ++dwInner)
        {
            const USAGE_TO_SCANCODE *pUsageToSc = pUsageToScInfo->pUsageToSc;
            DEBUGCHK(GET_EB(pUsageToSc->uiFlags) < EB_COUNT);
            DEBUGCHK(GET_PT(pUsageToSc->uiFlags) < PT_COUNT);
        }
    }
}

#endif // DEBUG


⌨️ 快捷键说明

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