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

📄 laymgr.cpp

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
--*/
BOOL KeybdDriverSetMode(
    INT        iPddId,    // @parm Id of the keyboard to set the information.
    INT        iIndex,        // @parm Id of info to set.
    LPVOID    lpInput     // @parm Input buffer.
    )
{
    BOOL fRet = FALSE;

    LockConfig();

    if ( lpInput == NULL ) {
        SetLastError(ERROR_INVALID_PARAMETER);
        goto leave;
    }

    switch ( iIndex )
    {
    case KBDI_AUTOREPEAT_INFO_ID:
        {
            struct KBDI_AUTOREPEAT_INFO    *pInfo =
                (struct KBDI_AUTOREPEAT_INFO*) lpInput;

            if ( pInfo -> CurrentInitialDelay > KBD_AUTO_REPEAT_INITIAL_DELAY_MAX ) {
                //                RETAILMSG(1,
                //                    (TEXT("Initial delay too large, using %d\r\n"),
                //                        KBD_AUTO_REPEAT_INITIAL_DELAY_MAX));
                v_AutoRepeatInitialDelay = KBD_AUTO_REPEAT_INITIAL_DELAY_MAX;
            }
            else if ( pInfo -> CurrentInitialDelay < KBD_AUTO_REPEAT_INITIAL_DELAY_MIN ) {
                //                RETAILMSG(1,
                //                    (TEXT("Initial delay too small, using %d\r\n"),
                //                        KBD_AUTO_REPEAT_INITIAL_DELAY_MIN));
                v_AutoRepeatInitialDelay = KBD_AUTO_REPEAT_INITIAL_DELAY_MIN;
            }
            else {
                v_AutoRepeatInitialDelay = pInfo -> CurrentInitialDelay;
            }


            if ( pInfo -> CurrentRepeatRate > KBD_AUTO_REPEAT_KEYS_PER_SEC_MAX ) {
                //                RETAILMSG(1,
                //                    (TEXT("Initial repeat rate too large, using %d\r\n"),
                //                        KBD_AUTO_REPEAT_KEYS_PER_SEC_MAX));
                v_AutoRepeatKeysPerSec = KBD_AUTO_REPEAT_KEYS_PER_SEC_MAX;
            }
            else if ( ( pInfo -> CurrentRepeatRate < KBD_AUTO_REPEAT_KEYS_PER_SEC_MIN ) &&
                ( pInfo -> CurrentRepeatRate != 0 ) ) {
                //                RETAILMSG(1,
                //                    (TEXT("Initial repeat rate too small, using %d\r\n"),
                //                        KBD_AUTO_REPEAT_KEYS_PER_SEC_MIN));
                v_AutoRepeatKeysPerSec = KBD_AUTO_REPEAT_KEYS_PER_SEC_MIN;
            }
            else {
                v_AutoRepeatKeysPerSec = pInfo -> CurrentRepeatRate;
            }

            // Now send the new repeat rate off to any external keyboards
            struct KBDI_AUTOREPEAT_INFO AutoRepeatInfo = { 
                v_AutoRepeatInitialDelay, v_AutoRepeatKeysPerSec 
            };
            BroadcastToKeyboards(IOCTL_KBD_SET_AUTOREPEAT, &AutoRepeatInfo,
                sizeof(AutoRepeatInfo));
        }
        break;

    default:
        SetLastError(ERROR_INVALID_PARAMETER);
        goto leave;
    }

    fRet = TRUE;

leave:
    UnlockConfig();
    return fRet;
}
#ifdef DEBUG
// Verify function declaration against the typedef.
static PFN_KEYBD_DRIVER_SET_MODE  v_pfnSetModeTest = KeybdDriverSetMode;
#endif



extern "C"
/*++

@doc EXTERNAL DRIVERS

@func

System power state change notification.

@comm This routine is called in a kernel context and may not make any
system calls whatsoever.  It may read and write its own memory and that's
about it.

@comm Resets the auto-repeat state and calls the <f KeybdPdd_PowerHandler> routine.

--*/
void KeybdDriverPowerHandler(
    BOOL    fOff    // @parm TRUE, the system is powering off; FALSE, the system is powering up.
    )
{
    v_AutoRepeatState = AR_WAIT_FOR_ANY;

    for (UINT uiCurrPdd = 0; uiCurrPdd < g_cPdds; ++uiCurrPdd) 
    {
        PKEYBD_PDD_INFO pKeybdPddInfo = pKeybdPddInfoFromId(uiCurrPdd);
        if (pKeybdPddInfo->fValid == TRUE) 
        {
            PKEYBD_PDD pKeybdPdd = pKeybdPddInfo->pKeybdPdd;
            PREFAST_DEBUGCHK(pKeybdPdd != NULL);
            if (pKeybdPdd->pfnPowerHandler != NULL) {
                (*pKeybdPdd->pfnPowerHandler)(uiCurrPdd, fOff);
            }
        }
    }

    return;
}
#ifdef DEBUG
// Verify function declaration against the typedef.
static PFN_KEYBD_DRIVER_POWER_HANDLER v_pfnPowerHandler = 
    KeybdDriverPowerHandler;
#endif

//----------------------------------------------------------------------------
//
// Keybd_EventFlags
//
// Create the flags parameter for keybd_event.
//
//----------------------------------------------------------------------------
static
DWORD
Keybd_EventFlags(
    UINT32 uiVKey,
    UINT32 uiScanCode,
    KEY_STATE_FLAGS KeyStateFlags,
    BOOL fRepeat
    )
{
    DWORD dwFlags = 0;

    // The key is extended if it matches 0x0000e0xx (not 0xe1xxxx)
    if ((uiScanCode & 0xFFFFFF00) == 0xE000) {
        dwFlags |= KEYEVENTF_EXTENDEDKEY;
    }

    if ( (fRepeat == TRUE) &&
         ((uiVKey & KEYBD_DEVICE_SILENT_REPEAT) != 0) ) 
    {
        dwFlags |= KEYEVENTF_SILENT;
    }

    if ((KeyStateFlags & KeyStateDownFlag) == 0) {
        dwFlags |= KEYEVENTF_KEYUP;
    }

    return dwFlags;
}


//----------------------------------------------------------------------------
//
// CallDLRemapFn
//
// Call external remap function. 
//
// Returns 0 if there are no remapped events or if there is an error.
//
//----------------------------------------------------------------------------
static
UINT
CallDLRemapFn(
    PFN_KEYBD_REMAP    pfnRemapKey,
    const KEYBD_EVENT *pKbdEvents,
    UINT               cKbdEvents,
    KEYBD_EVENT       *pRmpKbdEvents,
    UINT               cMaxRmpKbdEvents
    )
{
    UINT cEvents;
    
    DEBUGCHK(pfnRemapKey != NULL);
    DEBUGCHK( (pKbdEvents != NULL) || (pRmpKbdEvents == NULL) );

    __try {
        cEvents = (*pfnRemapKey)(pKbdEvents, cKbdEvents, 
            pRmpKbdEvents, cMaxRmpKbdEvents);
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        RETAILMSG(1, (_T("Keyboard: Exception in device layout remapping function\r\n")));
        cEvents = 0;
    }

    return cEvents;
}


//----------------------------------------------------------------------------
//
// SendRemappedEvent
//
// Remap the key and send it to GWE.
//
//----------------------------------------------------------------------------
static
VOID
SendRemappedEvent(
    UINT32 uiVKey,
    UINT32 uiScanCode,
    KEY_STATE_FLAGS KeyStateFlags,
    BOOL fRepeat,
    DEVICE_LAYOUT_INFO *pdli
    )
{
    SETFNAME(_T("SendRemappedEvent"));

    PREFAST_DEBUGCHK(pdli != NULL);

    const DEVICE_LAYOUT *pdl = &pdli->dl;
    KEYBD_EVENT rgKbdEvent[ALTGR_MAPPING] = { uiVKey, uiScanCode, KeyStateFlags };
    KEYBD_EVENT *pKbdEvent = NULL; // Final list to use
    UINT cEvents = 1;

    DEBUGCHK(IsLocked() == TRUE);

    if ( (uiVKey == VK_RMENU) && (g_ili.il.fLocaleFlags & KLLF_ALTGR) ) {
        // Add in the control key for AltGr
        const KEYBD_EVENT c_KbdEventLControl = { VK_LCONTROL, uiScanCode, KeyStateFlags };
        
        rgKbdEvent[cEvents] = rgKbdEvent[0];
        rgKbdEvent[0] = c_KbdEventLControl;
        
        ++cEvents;
    }

    // Verify that our pdli->cMaxRmpKbdEvents was calculated properly.
    DEBUGCHK(cEvents <= ALTGR_MAPPING); 
    
    if (pdl->pfnRemapKey) {
        // Which remapping buffer do we use?
        if (pdli->pKbdEvents) {
            pKbdEvent = pdli->pKbdEvents;
        }
        else {
            pKbdEvent = pdli->rgKbdEvent;
        }

        cEvents = CallDLRemapFn(pdl->pfnRemapKey, rgKbdEvent, cEvents,
            pKbdEvent, pdli->cMaxRmpKbdEvents);

        if (cEvents > pdli->cMaxRmpKbdEvents) {
            ERRORMSG(1, (_T("Keyboard: Remapping function returned too many events\r\n")));
            cEvents = 0;
        }
    }
    else {
        pKbdEvent = rgKbdEvent;
    }

    PREFAST_DEBUGCHK(pKbdEvent != NULL);

    for (UINT uiIdx = 0; uiIdx < cEvents; ++uiIdx) 
    {
        UINT32 uiCurrVk = pKbdEvent[uiIdx].uiVk; 
        UINT32 uiCurrSc = pKbdEvent[uiIdx].uiSc;

        DEBUGMSG(ZONE_DEVICELAYOUT, (_T("%s: VK: 0x%08x SC: 0x%08x Shift Flags: 0x%08x\r\n"),
            pszFname, uiCurrVk, uiCurrSc, pKbdEvent[uiIdx].KeyStateFlags));

        DWORD dwFlags = Keybd_EventFlags(uiCurrVk, uiCurrSc,
            pKbdEvent[uiIdx].KeyStateFlags, fRepeat);
        keybd_event((BYTE) uiCurrVk, (BYTE) uiCurrSc, dwFlags, 0);
    }
}

#define LAYOUT_HAS_KOREAN_KEYS(hkl) ( ( (hkl) == 0x0412 ) || ( (hkl) == 0x0409 ) )

//----------------------------------------------------------------------------
//
// WillKeyUp
//
// Returns FALSE if the key will not send a keyup. Currently, this is
// only known to occur for two Korean keys.
//
//----------------------------------------------------------------------------
static
BOOL
WillKeyUp(
    UINT32 uiVKey,
    const DEVICE_LAYOUT_INFO *pdli
    )
{
    PREFAST_DEBUGCHK(pdli != NULL);
    DEBUGCHK(IsLocked() == TRUE);

    BOOL fRet = TRUE;

    //    Some Korean specific keys only generate a key
    //    down when pressed.
    if ( LAYOUT_HAS_KOREAN_KEYS((UINT) pdli->hkl) &&
        (uiVKey == VK_HANJA || uiVKey == VK_HANGUL))
    {
        fRet = FALSE;
    }

    return fRet;
}

//----------------------------------------------------------------------------
//
// KeybdEventThreadProc
//
// Receives the keyboard event sent from PDDs to KeybdEventCallback. Will 
// handle auto repeat.
//
//----------------------------------------------------------------------------
DWORD
WINAPI
KeybdEventThreadProc(
    LPVOID
    )
{
    SETFNAME(_T("KeybdEventThreadProc"));

    static const BOOL bRepeatForever = TRUE;

    static UINT32            v_AutoRepeatVKey;
    static UINT32            v_AutoRepeatScanCode;
    static KEY_STATE_FLAGS    v_AutoRepeatKeyStateFlags;
    static UINT             v_AutoRepeatPddId;

    UINT uiPddId;
    UINT32 uiScanCode;
    BOOL fKeyUp;

    DEVICE_LAYOUT_INFO *pdli = NULL;
    const DEVICE_LAYOUT *pdl = NULL;

    UINT32 uiVKey;
    KEY_STATE_FLAGS KeyStateFlags;

    DWORD            AutoRepeatKeysPerSec;
    long            AutoRepeatTimeout;
    BOOL            fSendAutoRepeatKey;
    DWORD            MRKeyTimeForPolling = 0;    //Get rid of compiler uninitialized variable warning.
    DWORD            dwWait;           


    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

    AutoRepeatTimeout = INFINITE;

    while (bRepeatForever)
    {
        fSendAutoRepeatKey = FALSE;

        AutoRepeatKeysPerSec = v_AutoRepeatKeysPerSec;

        //    0 keys per second => auto repeat disabled.
        if ( AutoRepeatKeysPerSec == 0 )
            v_AutoRepeatState = AR_WAIT_FOR_ANY;

        if ( v_AutoRepeatState == AR_WAIT_FOR_ANY )
        {
            AutoRepeatTimeout = INFINITE;
        }
        else if ( v_AutoRepeatState == AR_INITIAL_DELAY )
        {
            AutoRepeatTimeout = v_AutoRepeatInitialDelay;
        }
        else if ( v_AutoRepeatState == AR_AUTO_PARTIAL )
        {
            long lTemp = AutoRepeatTimeout - (GetTickCount() - MRKeyTimeForPolling);
            AutoRepeatTimeout = (lTemp > 0) ? lTemp : 0;
        }
        else
        {
            AutoRepeatTimeout = 1000/AutoRepeatKeysPerSec;
        }

        MRKeyTimeForPolling = GetTickCount();
        
        dwWait = WaitForSingleObject(g_hevBeginEvent, AutoRepeatTimeout);

        LockConfig();
        
        if (  dwWait == WAIT_TIMEOUT )
        {
            /*    On power off, the v_AutoRepeatState is set to AR_WAIT_FOR_ANY, but we
            cannot reset the WaitForSingleObject timeout value.  This means that when
            we power on, we could (and probably will) come back from the wait with a
            wait timeout status.  In this case, we do nothing and come back around to
            wait again with the proper timeout.  */           

            if ( v_AutoRepeatState == AR_WAIT_FOR_ANY )
                ;    //    do nothing
            else if ( v_AutoRepeatState == AR_INITIAL_DELAY )
            {
                fSendAutoRepeatKey = TRUE;
                v_AutoRepeatState = AR_AUTOREPEATING;
            }
            else if ( v_AutoRepeatState == AR_AUTO_PARTIAL )
            {
                fSendAutoRepeatKey = TRUE;
                v_AutoRepeatState = AR_AUTOREPEATING;
            }
            else
            {
                fSendAutoRepeatKey = TRUE;
            }
            
            if ( fSendAutoRepeatKey ) 
            {
                pdli = pDLIFromPDDIndex(v_AutoRepeatPddId);
                pdl = &pdli->dl;
                DEBUGCHK(ValidateDeviceLayout(pdl));
                SendRemappedEvent(v_AutoRepeatVKey, v_AutoRepeatScanCode,
                    v_AutoRepeatKeyStateFlags, TRUE, pdli);
            }            
        }
        else
        {
            //    We got a keyboard interrupt but there may or may not be key events.
            DEBUGCHK(g_PrivateKeybdEvent.fValid == TRUE);
            uiPddId = g_PrivateKeybdEvent.uiPddId;
            uiScanCode = g_PrivateKeybdEvent.uiScanCode;
            fKeyUp = g_PrivateKeybdEvent.fKeyUp;
            
#ifdef DEBUG
            memset(&g_PrivateKeybdEvent, 0xcd, sizeof(g_PrivateKeybdEvent));
            g_PrivateKeybdEvent.fValid = FALSE;
#endif

            // Release KeybdEventCallback()
            SetEvent(g_hevEndEvent);

            pdli = pDLIFromPDDIndex(uiPddId);
            DEBUGCHK(pKeybdPddInfoFromId(uiPddId)->fValid);

            if (pdli->hkl == INVALID_HKL) {
                ERRORMSG(1, (_T("Keyboard: Keypress ignored since Device Layout is not set\r\n")));
            }
            else {
                pdl = &pdli->dl;
                DEBUGCHK(Valida

⌨️ 快捷键说明

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