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

📄 kbdhid.cpp

📁 Xcale270Bsp包,wince平台
💻 CPP
📖 第 1 页 / 共 4 页
字号:

    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));

    RETAILMSG(1, (TEXT("KeyboardEvent: vk: 0x%08x sc: 0x%08x flags: 0x%08x\r\n\r\n"), 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;

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

    for (dwIdx = 0; dwIdx < dim(rgVKeyDownToShiftState); ++dwIdx) {
        pvkshiftCurr = &rgVKeyDownToShiftState[dwIdx];
        if (pvkshiftCurr->vk == vk) {
            if (hidpKeyEvent == HidP_Keyboard_Make) {
                *pKeyStateFlags |= pvkshiftCurr->ksf;
            }
            else {
                *pKeyStateFlags &= ~pvkshiftCurr->ksf;
            }
            break;
        }
    }
}


// Modifier key processing.
static
void
ProcessModifier(
    UINT uiVk,
    UINT uiSc,
    DWORD dwFlags,
    HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
    KEY_STATE_FLAGS *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;
    
    DEBUGCHK(pKeyStateFlags != NULL);
    DEBUGCHK(uiVk >= VK_NUMPAD0);
    DEBUGCHK(uiVk < VK_NUMPAD0 + dim(rgVkNumLockOff));

	RETAILMSG(1,(TEXT("ProcNumPad: KeyStateFlags: %08x, uiSc: %08x, uiVk: %08x.\r\n"), *pKeyStateFlags, uiSc, uiVk ));

    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;
    
    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 & 0xFFFF00) == 0xE000) {
            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 ( v_vkFullHalfSent )
        {
            vkDown = v_vkFullHalfSent;
        }
        else if ( ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() )
        {
            vkDown = v_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 = v_vkFullHalfSent = VK_DBE_SBCSCHAR;
                }
                else
                {
                    vkDown = v_vkFullHalfSent = VK_DBE_DBCSCHAR;
                }
            }
            else
            {
                vkDown = v_vkFullHalfSent = VK_DBE_SBCSCHAR;
            }
        }
    }
    else if ( vkOnly == VK_DBE_ALPHANUMERIC )
    {
        if ( v_vkAlphaNumSent )
        {
            vkDown = v_vkAlphaNumSent;
        }
        else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() )
        {
            vkDown = v_vkAlphaNumSent = VK_DBE_ALPHANUMERIC;
        }
        else
        {
            vkDown = v_vkAlphaNumSent = VK_CAPITAL;
        }
    }
    else if ( vkOnly == VK_DBE_HIRAGANA )
    {
        if ( v_vkHiraKataSent )
        {
            vkDown = v_vkHiraKataSent;
        }
        else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() )
        {
            vkDown = v_vkHiraKataSent = VK_DBE_KATAKANA;
        }
        else if ( !ANY_ALT_DOWN() && ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() )
        {
            vkDown = v_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 = v_vkHiraKataSent = VK_DBE_NOROMAN;
                }
                else
                {
                    vkDown = v_vkHiraKataSent = VK_DBE_ROMAN;
                }
            }
            else
            {
                vkDown = v_vkHiraKataSent = VK_DBE_NOROMAN;
            }
        }
		else {
			v_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 = v_vkFullHalfSent;
        v_vkFullHalfSent = 0;
    }
    else if ( vkOnly == VK_DBE_ALPHANUMERIC )
    {
        vkUp = v_vkAlphaNumSent;
        v_vkAlphaNumSent = 0;
    }
    else if ( vkOnly == VK_DBE_HIRAGANA )
    {
        vkUp = v_vkHiraKataSent;
        v_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;
    
    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 + -