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

📄 laymgr.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}


//----------------------------------------------------------------------------
//
// VKeyToScanCode
//
// Maps a virtual key to an XT scan code.  The LR specific virtual keys are
// mapped to LR specific scan codes.
//
//----------------------------------------------------------------------------
static
UINT32
VKeyToScanCode(
    UINT32    vkey,
    const VKEY_TO_SCANCODE *pVkToScanCodeTable
    )
{
    PREFAST_DEBUGCHK(pVkToScanCodeTable != NULL);
    DEBUGCHK(IsLocked());

    UINT8 uiVKey = (UINT8) vkey;

    VKEY_TO_SCANCODE VkToScanCodeEntry = pVkToScanCodeTable[uiVKey];
    UINT32 uiScanCode = VkToScanCodeEntry.uiVkToSc;

    if (VkToScanCodeEntry.uiType == SC_E0) {
        uiScanCode |= 0xe000;
    }
    else if (VkToScanCodeEntry.uiType == SC_E11D) {
        uiScanCode |= 0xe11d00;
    }

    return uiScanCode;
}


//----------------------------------------------------------------------------
//
// VKeyToUnicodeInfo
//
// Set up the descriptive VKey to Unicode structure.
//
//----------------------------------------------------------------------------
static
void
VKeyToUnicodeInfo(
    KBDI_VKEY_TO_UNICODE_INFO *pInfo
    )
{
    pInfo->cbToUnicodeState = 0;

    // Since we do not know which layouts will be used, we must return the
    // maximum.
    pInfo->cMaxToUnicodeCharacters = MAX_TO_UNICODE_CHARACTERS; 
}


//----------------------------------------------------------------------------
//
// GetModifierBits
//
// Converts KeyStateFlags to the modifier bit value
//
//----------------------------------------------------------------------------
static 
WORD
GetModifierBits(
    const MODIFIERS *pModifiers,
    const MODIFIER_TO_SHIFT *pModToShift,
    KEY_STATE_FLAGS KeyStateFlags
    )
{
    WORD wBits = 0;

    PREFAST_DEBUGCHK(pModifiers != NULL);
    PREFAST_DEBUGCHK(pModToShift != NULL);

    while (pModToShift->bModifier != 0)
    {
        VK_TO_BIT const *pVkToBit = pModifiers->pVkToBit;
        DEBUGCHK(pVkToBit != NULL);

        while (pVkToBit->Vk != 0) {
            if ( ((pModToShift->bModifier & pVkToBit->ModBits) != 0) &&
                 ((pModToShift->ShiftFlag & KeyStateFlags) != 0) )
            {
                wBits |= pModToShift->bModifier;
            }

            ++pVkToBit;
        }

        ++pModToShift;
    }

    return wBits;
}

//----------------------------------------------------------------------------
//
// GetModificationNumber
//
// Converts a modifier bit number to a table index
//
//----------------------------------------------------------------------------
static 
WORD 
GetModificationNumber(
    const MODIFIERS *pModifiers,
    WORD wModBits
    )
{
    PREFAST_DEBUGCHK(pModifiers != NULL);

    WORD wModNum = SHFT_INVALID;

    if (wModBits <= pModifiers->wMaxModBits) {
        DEBUGCHK(pModifiers->ModNumber != NULL);
        wModNum = pModifiers->ModNumber[wModBits];
    }

    return wModNum;
}


//----------------------------------------------------------------------------
//
// SearchVkToWCharTables
//
// Returns the table containing VirtualKey, or NULL if not in any.
//
//----------------------------------------------------------------------------
static
const VK_TO_WCHARS1*
SearchVkToWCharTables(
    UINT32 VirtualKey,
    const VK_TO_WCHAR_TABLE **ppVkToWCharTable
    )
{
    PREFAST_DEBUGCHK(ppVkToWCharTable != NULL);
    PREFAST_DEBUGCHK(*ppVkToWCharTable != NULL);
    DEBUGCHK(IsLocked());

    const VK_TO_WCHARS1 *pActualVkToWChars = NULL;
    const VK_TO_WCHARS1 *pCurrVkToWChars;
    const VK_TO_WCHAR_TABLE *pVkToWCharTable = *ppVkToWCharTable;

    if (VirtualKey) {
        while ( (pActualVkToWChars == NULL) && 
                (pVkToWCharTable->pVkToWchars != NULL) ) {
            DEBUGCHK(pVkToWCharTable->pVkToWchars != NULL);

            pCurrVkToWChars = pVkToWCharTable->pVkToWchars;
            PREFAST_DEBUGCHK(pCurrVkToWChars != NULL);

            DWORD cbCurrEntry = pVkToWCharTable->cbSize;

            // Linear search for entry
            while (pCurrVkToWChars->VirtualKey != 0) {
                if (pCurrVkToWChars->VirtualKey == VirtualKey) {
                    *ppVkToWCharTable = pVkToWCharTable;
                    pActualVkToWChars = pCurrVkToWChars;
                    break;
                }
                
                pCurrVkToWChars = (PVK_TO_WCHARS1) 
                    (((const BYTE*) pCurrVkToWChars) + cbCurrEntry);
            }

            ++pVkToWCharTable;
        }
    }

    DEBUGCHK((pActualVkToWChars == NULL) ||
             (pActualVkToWChars->VirtualKey == VirtualKey));
    
    return pActualVkToWChars;
}


//----------------------------------------------------------------------------
//
// GetControlledChar
//
// Ctrl-[Shift]-A through Ctrl-[Shift]-Z return chars of 1 through 26.
// Returns 0 if Alt is down.
//
//----------------------------------------------------------------------------
static
WCHAR
GetControlledChar(
    UINT32 uiVKey,
    KEY_STATE_FLAGS ksf
    )
{
    static const UINT32 uiMask = KeyShiftAnyCtrlFlag | KeyShiftAnyAltFlag;
    static const UINT32 uiMaskMatch = KeyShiftAnyCtrlFlag;

    WCHAR wch = '\0';
    
    if ((ksf & uiMask) == uiMaskMatch) {
        if (uiVKey >= 'A' && uiVKey <= 'Z') {
            wch = uiVKey - 'A' + 1;
        }
    }

    return wch;
}


// Update the pwModBits based on row properties. Perhaps even change
// row pointer (ppVkToWChars).
static
VOID
ProcessModBitsForAttributes(
    DWORD cbVkToWChars,
    KEY_STATE_FLAGS ShiftFlags,
    IN OUT PWORD pwModBits,
    IN OUT const VK_TO_WCHARS1 **ppVkToWChars
    )
{
    DEBUGCHK(cbVkToWChars);
    PREFAST_DEBUGCHK(pwModBits);
    PREFAST_DEBUGCHK(ppVkToWChars);
    PREFAST_DEBUGCHK(*ppVkToWChars);
    
    const WORD wCtrlAltMask = (KBDALT | KBDCTRL);
    WORD wModBits = *pwModBits;
    const VK_TO_WCHARS1 *pVkToWChars = *ppVkToWChars;
    
    if ((wModBits & wCtrlAltMask) == KBDALT) {
        // The KBDALT modifier in the Input Language tells the Layout
        // Manager to perform Alt+NumPad character generation, so
        // we mask it off here. However, we only do this when the
        // KBDCTRL modifier is not set since Ctrl+Alt is a valid
        // modifier combination.
        wModBits &= ~KBDALT;
    }

    // If Kana is on and affects this character, then none of the other 
    // Attributes should affect the modification bits.
    if ( (pVkToWChars->Attributes & KANALOK) && 
         (ShiftFlags & KeyShiftKanaFlag) ) {
        DEBUGCHK(wModBits & KBDKANA);
    }
    else {
        if ( (pVkToWChars->Attributes & CAPLOK) &&
             ((wModBits & wCtrlAltMask) == 0) &&
             (ShiftFlags & KeyShiftCapitalFlag) ) {
            // Flip the shift bit if CAPLOK is set for this key,
            // neither control nor alt are down, and CapsLock is on.
            wModBits ^= KBDSHIFT;
        }
        else if ( (pVkToWChars->Attributes & CAPLOKALTGR) && 
                  ((wModBits & wCtrlAltMask) == wCtrlAltMask) &&
                  (ShiftFlags & KeyShiftCapitalFlag) ) {
            // Flip the shift bit if CAPLOKALTGR is set for this key,
            // both alt and control are down, and CapsLock is on.
            wModBits ^= KBDSHIFT;
        }

        if ( (pVkToWChars->Attributes & SGCAPS) &&
             ((wModBits & wCtrlAltMask) == 0) &&
             (ShiftFlags & KeyShiftCapitalFlag) ) {
            // Use the next VkToWChars entry if SGCAPS is set for this key,
            // neither control nor alt are down, and CapsLock is on.
            BYTE bCurrVk = pVkToWChars->VirtualKey;
            pVkToWChars = (const VK_TO_WCHARS1*) 
                (((const BYTE*) pVkToWChars) + cbVkToWChars);
            DEBUGCHK(pVkToWChars->VirtualKey == bCurrVk);
        }
    }

    *pwModBits = wModBits;
    *ppVkToWChars = pVkToWChars;
}


// Safely write to the pChar buffer. Increments *pcChars if there is space 
// for this character.
static
inline
VOID
WriteToCharBuffer(
    WCHAR   wch,
    UINT32  cChars, // Total count of elements in pcChars
    UINT32 *pChars, // Index of next empty slot in pcChars
    UINT32 *pcChars
    )
{
    PREFAST_DEBUGCHK(pChars);
    PREFAST_DEBUGCHK(pcChars);
    
    if (*pcChars < cChars) {
        pChars[(*pcChars)++] = wch;
    }
    else {
        ERRORMSG(1, 
            (_T("WriteToCharBuffer: Character buffer is not large enough to hold '%c' (0x%04x)\r\n"),
            wch, wch));
    }
}


//----------------------------------------------------------------------------
//
// ProcessDeadKeys
//
// Called when a key is pressed after a dead key. Fills pChars with either
// the generated character or both individual characters if this was not a
// valid dead key combination.
//
// Returns number of characters placed in pChars.
//
//----------------------------------------------------------------------------
static
UINT32
ProcessDeadKeys(
    WCHAR           *pwchDeadKey,
    const DEADKEY   *pDeadKey,
    WCHAR            wch,
    UINT32          *pChars,
    UINT32           cChars,
    KEY_STATE_FLAGS  ShiftFlags
    )
{
    SETFNAME(_T("ProcessDeadKeys"));
    
    PREFAST_DEBUGCHK(pwchDeadKey != NULL);
    DEBUGCHK(*pwchDeadKey != 0);
    PREFAST_DEBUGCHK(pDeadKey != NULL);
    DEBUGCHK(wch != 0);
    DEBUGCHK(pChars != NULL);
    DEBUGCHK(cChars != 0);

    UINT32 cchValid = 0;
    WCHAR wchOriginalDeadKey = *pwchDeadKey;
    DWORD dwBoth = MAKELONG(wch, *pwchDeadKey);
    BOOL fKeyDown = (ShiftFlags & KeyStateDownFlag);
    BOOL fFound = FALSE;

    // First search the dead key table for a match of the combination
    // of dead key char + new key char
    if (fKeyDown) {
        // Dead keys only apply to the next key pressed.
        // Reset the dead key variable.
        *pwchDeadKey = 0;
    }

    while (pDeadKey->dwBoth != 0) 
    {
        if (pDeadKey->dwBoth == dwBoth) {
            // Found the match.
            
            if (pDeadKey->uFlags & DKF_DEAD) {
                DEBUGMSG(ZONE_ERROR, (_T("%s: No support for DKF_DEAD flag\r\n"),
                    pszFname));
            }
            else {
                WriteToCharBuffer(pDeadKey->wchComposed, cChars, pChars, &cchValid);
            }
            
            fFound = TRUE;
            break;
        }                

        ++pDeadKey;
    }

    if (fFound == FALSE) {
        // There was not dead key match for this combination.
        // Both the dead key char and the new key char should 
        // be sent as individual characters.
        WriteToCharBuffer(wchOriginalDeadKey, cChars, pChars, &cchValid);

        if (cChars >= 2) {
            WriteToCharBuffer(wch, cChars, pChars, &cchValid);
        }
    }

    return cchValid;    
}


// Process the WCH_LGTR match.
// Returns number of characters placed in pChars.
static
UINT32
ProcessLigature(
    PINPUT_LANGUAGE_INFO    pili,
    UINT32                  uiVk,
    KEY_STATE_FLAGS         ShiftFlags,
    WORD                    wModNum,
    UINT32                 *pChars,
    UINT32                  cChars
    )
{
    SETFNAME(_T("ProcessLigature"));

    PREFAST_DEBUGCHK(pili);
    DEBUGCHK(pChars);
    DEBUGCHK(cChars);
    DEBUGCHK(IsLocked());
    
    UINT32 cchValid = 0;

    const LIGATURE1 *pLigature = pili->il.pLigature;
    if (pLigature == NULL) {
        ERRORMSG(1, (_T("ProcessLigature: WCH_LGTR but no ligature table\r\n")));
        WriteToCharBuffer(0, cChars, pChars, &cchValid);
    }
    else {
        const DWORD cbLigatureRow = pili->il.cbLgEntry;
        
        while (pLigature->VirtualKey) {
            if ( (pLigature->VirtualKey == uiVk) &&
                 (pLigature->ModificationNumber == wModNum) ) {
                // Found match
                DWORD dwChar = 0;
                const DWORD cwchLig = pili->il.nLgMax;
                
                while (dwChar < cwchLig) {
                    WCHAR wch = pLigature->wch[dwChar];
                    
                    if (cchValid > cwchLig) {
                        ERRORMSG(1, (_T("ProcessLigature: Too many characters for buffer\r\n")));
                        break;
                    }
                    else if (wch == WCH_NONE) {
                        // No more characters for this row
                        break;
                    }
                    else {
                        if (pili->wchDeadChar) {
                            DWORD dwNewChars = 
                                ProcessDeadKeys(&pili->wchDeadChar, 
                                    pili->il.pDeadKey, wch, pChars + cchValid,
                                    cChars - cchValid, ShiftFlags);

                            if (dwNewChars) {
                                cchValid += dwNewChars;
                            }
                            else {
                                // This is very unexpected and should probably be avoided.
                                DEBUGMSG(ZONE_ERROR, 
                                    (_T("%s: Dead key + ligature 0x%04x produced a dead key 0x%04x"),
                                    pszFname, wch, pili->wchDeadChar));
                            }
                        }
                        else {            

⌨️ 快捷键说明

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