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

📄 laymgr.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

//------------------------------------------------------------------------------
//
//  Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <keybd.h>
#include <keybddr.h>
#include <laymgr.h>
#include <keybdpdd.h>
#include <pnp.h>
#include <msgqueue.h>
#include "devicelayout.h"
#include "InputLang.h"
#include <winuserm.h>

const char pszFname[]="LayMgr.cpp";

struct PRIVATE_KEYBD_EVENT {
    UINT    uiPddId;
    UINT32  uiScanCode;
    BOOL    fKeyUp;
#ifdef DEBUG
    BOOL    fValid;
#endif
};
// Used to send a keyboard event to the keyboard thread
static PRIVATE_KEYBD_EVENT g_PrivateKeybdEvent;
static HANDLE g_hEventThread;
static HANDLE g_hevBeginEvent;
static HANDLE g_hevEndEvent;

CRITICAL_SECTION g_csEventCallback;

struct MODIFIER_TO_SHIFT {
    BYTE             bModifier;
    KEY_STATE_FLAGS  ShiftFlag;
};

#define MAX_MODIFIERS 6

// Input language wrapper
typedef struct tagINPUT_LANGUAGE_INFO {
    HKL                    hkl;
    WCHAR                  szName[KL_NAMELENGTH];
    WCHAR                  szDll[MAX_PATH];
    INPUT_LANGUAGE         il;
    BOOL                   fGenerateNumPadChars;
    WCHAR                  wchDeadChar;
    const VK_TO_SHIFT      *pVkToShiftState;
    const VK_TO_SHIFT      *pVkToToggledState;
    MODIFIER_TO_SHIFT      rgModToShift[MAX_MODIFIERS+1]; // +1 FOR {0, 0}
    HINSTANCE              hDll;
    HKL                    hklFull;
    WCHAR                  szFullName[KL_NAMELENGTH];
} INPUT_LANGUAGE_INFO, *PINPUT_LANGUAGE_INFO;
#define INVALID_HKL ((HKL)0x00000000)
static INPUT_LANGUAGE_INFO g_ili = { INVALID_HKL };

#define DL_PROC_PREFIXLENGTH 30
#define DL_PROC_NAMELENGTH (DL_PROC_PREFIXLENGTH + KL_NAMELENGTH + 1)

#ifdef DEBUG
#define DEFAULT_REMAP_BUFFER_SIZE 1 // Exercise dynamic code
#else
#define DEFAULT_REMAP_BUFFER_SIZE 8
#endif

// Device layout wrapper
typedef struct tagDEVICE_LAYOUT_INFO {
    HKL             hkl;
    WCHAR           szProcName[DL_PROC_NAMELENGTH];
    WCHAR           szDll[MAX_PATH];
    DEVICE_LAYOUT   dl;
    HINSTANCE       hDll;
    KEYBD_EVENT     rgKbdEvent[DEFAULT_REMAP_BUFFER_SIZE];
    UINT            cMaxRmpKbdEvents;
    KEYBD_EVENT    *pKbdEvents; // Buffer in case rgKbdEvent is too small
} DEVICE_LAYOUT_INFO, *PDEVICE_LAYOUT_INFO;

// PDD wrapper
typedef struct tagKEYBD_PDD_INFO {
    BOOL                fValid;
    PKEYBD_PDD          pKeybdPdd;
    DEVICE_LAYOUT_INFO  dli;
} KEYBD_PDD_INFO, *PKEYBD_PDD_INFO;

static KEYBD_PDD_INFO *g_pPdds;
static UINT            g_cPdds;

// Event used to terminate the notifications thread.
static HANDLE g_hevExitNotficationThread;

// Array holding open file handles to keyboard devices.
static HANDLE g_rghKbd[10];

// Critical section to guard access to all global data structures
static CRITICAL_SECTION g_csAccessInputLocaleInfo;
#ifdef DEBUG
static UINT g_cInAccessCS = 0;
#endif

// Keeps track of the most recent KeyStateFlags
static KEY_STATE_FLAGS g_KeyStateFlags;

// Size of buffer used in KeybdDriverVKeyToUnicode
#define MAX_TO_UNICODE_CHARACTERS   16

// AltGr can turn one scan code/vkey into two
#define ALTGR_MAPPING                2


#define VK_A    'A'
#define VK_F    'F'
#define VK_X    'X'

static const VK_TO_SHIFT g_rgVkToShiftState[] = {
    { VK_CONTROL,   KeyShiftAnyCtrlFlag },
    { VK_LCONTROL,  KeyShiftLeftCtrlFlag },
    { VK_RCONTROL,  KeyShiftRightCtrlFlag },
    { VK_SHIFT,     KeyShiftAnyShiftFlag },
    { VK_LSHIFT,    KeyShiftLeftShiftFlag },
    { VK_RSHIFT,    KeyShiftRightShiftFlag },
    { VK_MENU,      KeyShiftAnyAltFlag },
    { VK_LMENU,     KeyShiftLeftAltFlag },
    { VK_RMENU,     KeyShiftRightAltFlag },
    //    VK_LWIN and VK_RWIN do not have a merged key.
    { VK_LWIN,      KeyShiftLeftWinFlag },
    { VK_RWIN,      KeyShiftRightWinFlag },
    { VK_SYMBOL,    KeyShiftReserved100 },
    { 0,            0 }
};

static const VK_TO_SHIFT g_rgVkToToggledState[] = {
    { VK_CAPITAL,   KeyShiftCapitalFlag },
    { VK_NUMLOCK,   KeyShiftNumLockFlag },
    { VK_SCROLL,    KeyShiftScrollLockFlag },
    { 0,            0 }
};

static const TCHAR g_szRegLayouts[] =
    _T("System\\CurrentControlSet\\Control\\Layouts");
static const TCHAR g_szProcPrefix[] = _T("IL_");
static const TCHAR g_szLayoutTextValue[] = _T("Layout Text");
static const TCHAR g_szLayoutFileValue[] = _T("Layout File");
static const TCHAR g_szImeFileValue[] = _T("Ime File");

// List of PDD entry points.
extern PFN_KEYBD_PDD_ENTRY g_rgpfnPddEntries[];


void
ToggleLights(
    KEY_STATE_FLAGS KeyStateFlags
    );


#ifdef DEBUG
// Checks to see if the global access cs is currently entered
static
inline
BOOL
IsLocked(
    void
    )
{
    return g_cInAccessCS > 0;
}
#endif


// Enters the global access cs
static
inline
void
LockConfig(
    void
    )
{
    DEBUGCHK(g_cInAccessCS < 10); // Check for cycle
    EnterCriticalSection(&g_csAccessInputLocaleInfo);
#ifdef DEBUG
    ++g_cInAccessCS;
#endif
}


// Leaves the global access cs
static
inline
void
UnlockConfig(
    void
    )
{
    DEBUGCHK(IsLocked() == TRUE);
    LeaveCriticalSection(&g_csAccessInputLocaleInfo);
#ifdef DEBUG
    --g_cInAccessCS;
#endif    
}


// Gets the PDD info structure from an index. Checks bounds.
static
inline
PKEYBD_PDD_INFO
pKeybdPddInfoFromId(
    UINT uiPddId
    )
{
    PREFAST_DEBUGCHK(g_pPdds != NULL);
    DEBUGCHK(uiPddId < g_cPdds);

    PKEYBD_PDD_INFO pKeybdPddInfo = &(g_pPdds[uiPddId]);

    DEBUGCHK(pKeybdPddInfo != NULL);
    return pKeybdPddInfo;
}


// Gets the PDD structure from an index.
// Return value is a reference so that the caller can take the address of it.
static
inline
PKEYBD_PDD
pKeybdPddFromId(
    UINT uiPddId
    )
{
    PKEYBD_PDD pKeybdPdd = pKeybdPddInfoFromId(uiPddId)->pKeybdPdd;

    DEBUGCHK(pKeybdPdd != NULL);
    return pKeybdPdd;
}

// Gets the device layout info structure from a PDD index.
static
inline
PDEVICE_LAYOUT_INFO
pDLIFromPDDIndex(
    UINT uiPddId
    )
{
    PDEVICE_LAYOUT_INFO pdli = &(pKeybdPddInfoFromId(uiPddId)->dli);

    DEBUGCHK(pdli != NULL);
    return pdli;
}


static
BOOL
ValidateKeybdPdd(
    const KEYBD_PDD *pKeybdPdd
    )
{    
    return TRUE;
}


//----------------------------------------------------------------------------
//
// ValidateInputLanguage
//
// Validates all data in an input language.
//
// Return value:
//
// TRUE if it is valid.
//
//----------------------------------------------------------------------------
static
BOOL
ValidateInputLanguage(
    const INPUT_LANGUAGE *pil
    )
{
    BOOL fRet = FALSE;

    PREFAST_DEBUGCHK(pil);

    if (pil->dwSize != sizeof(INPUT_LANGUAGE)) {
        goto leave;
    }

    if ( (pil->pCharModifiers == NULL) ||
         (pil->pCharModifiers->pVkToBit == NULL) || 
         (pil->pVkToWcharTable == NULL) ||
         (pil->pVkToScanCodeTable == NULL) ) {
         goto leave;
    }

    const VK_TO_WCHAR_TABLE *pVkToWcharTable = pil->pVkToWcharTable;
    while (pVkToWcharTable->pVkToWchars) {
        const VK_TO_WCHARS1 *pVkToWchars = pVkToWcharTable->pVkToWchars;
        DWORD cbSize = pVkToWcharTable->cbSize;
        if (cbSize == 0) {
            goto leave;
        }

        ++pVkToWcharTable;
    }

    if (pil->pLigature) {
        if ( (pil->nLgMax == 0) || (pil->cbLgEntry == 0) ) {
            goto leave;
        }
        else if (pil->nLgMax > MAX_TO_UNICODE_CHARACTERS) {
            goto leave;
        }
    }

    fRet = TRUE;

leave:
    if (fRet == FALSE) {
        ERRORMSG(1, (_T("ValidateInputLanguage: Invalid input language\r\n")));
    }
    
    return fRet;
}


//----------------------------------------------------------------------------
//
// ValidateDeviceLayout
//
// Validates all data in a device layout.
//
// Return value:
//
// TRUE if it is valid.
//
//----------------------------------------------------------------------------
static
BOOL
ValidateDeviceLayout(
    const DEVICE_LAYOUT *pdl
    )
{
    BOOL fRet = FALSE;
    DWORD dwIdx;

    PREFAST_DEBUGCHK(pdl);

    if (pdl->dwSize != sizeof(DEVICE_LAYOUT)) {
        goto leave;
    }
    else if (pdl->pfnRemapKey && IsBadCodePtr((FARPROC)pdl->pfnRemapKey)) {
        goto leave;
    }
    else if (pdl->rgpscvk == NULL) {
        goto leave;
    }

    for (dwIdx = 0; dwIdx < pdl->cpscvk; ++dwIdx) {
        const ScanCodeToVKeyData *pScToVkData = pdl->rgpscvk[dwIdx];

        if (pScToVkData->uMax < pScToVkData->uMin) {
            goto leave;
        }
    }

    fRet = TRUE;

leave:
    return fRet;
}


//----------------------------------------------------------------------------
//
// ScanCodeToVKey
//
// Map a scan code to virtual key(s).
//
// Return value:
//
// Whether the is a key mapping. If there is not key mapping, *puiVKey will
// be 0, as well.
//
//----------------------------------------------------------------------------
static
BOOL
ScanCodeToVKey(
    UINT32                uiScanCode,
    ScanCodeToVKeyData  **rgpscvk,
    UINT                cpscvk,
    UINT32                *puiVKey
    )
{
    SETFNAME(_T("ScanCodeToVKey"));

    PREFAST_DEBUGCHK(rgpscvk != NULL);
    PREFAST_DEBUGCHK(puiVKey != NULL);
    DEBUGCHK(IsLocked());

    BOOL fRet = FALSE;

    *puiVKey = 0;
    ScanCodeToVKeyData *pscvk = NULL;

    // Determine which table to look in
    for (UINT uiTable = 0; uiTable < cpscvk; ++uiTable) 
    {
        ScanCodeToVKeyData *pscvkCurr = rgpscvk[uiTable];

        PREFAST_DEBUGCHK(pscvkCurr != NULL);
        DEBUGCHK(pscvkCurr->uMin <= pscvkCurr->uMax);
        DEBUGCHK(pscvkCurr->puScanCodeToVKey != NULL);

        UINT32 uPrefixMask = pscvkCurr->uPrefixMask;
        if (((uiScanCode & uPrefixMask) == uPrefixMask) &&
            (uiScanCode >= pscvkCurr->uMin) && (uiScanCode <= pscvkCurr->uMax)) 
        {
            pscvk = pscvkCurr;
            break;
        }
    }

    // If this scan code falls in a table range, determine its virtual key
    if (pscvk != NULL) 
    {
        DEBUGCHK(uiScanCode >= pscvk->uMin);
        DEBUGCHK(uiScanCode <= pscvk->uMax);

        // Get the normalized index
        UINT idxScan = uiScanCode - pscvk->uMin;

        *puiVKey = pscvk->puScanCodeToVKey[idxScan];

        if (*puiVKey != 0) { // 0 is an invalid virtual key
            fRet = TRUE;
        }
    }

    return fRet;

⌨️ 快捷键说明

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