kbdist.cpp

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C++ 代码 · 共 532 行 · 第 1/2 页

CPP
532
字号
{
    /*
     * these three variables are all hardcoded with the PDD
     */
    UINT32 VKeyBuf[16];
    UINT32 ScanCodeBuf[16];
    KEY_STATE_FLAGS KeyStateFlagsBuf[16];

    UINT32 RemapVKeyBuf[16];
    UINT32 RemapScanCodeBuf[16];
    KEY_STATE_FLAGS RemapKeyStateFlagsBuf[16];

    int cKeyEvents;
    int iKeyEventIdx;
    int cRemapEvents;
    int iRemapIdx;

    DWORD AutoRepeatKeysPerSec;
    long AutoRepeatTimeout;
    BOOL fSendAutoRepeatKey;
    DWORD MRKeyTimeForPolling = 0;
    AutoRepeatTimeout = INFINITE;

  wait_for_keybd_interrupt:
    fSendAutoRepeatKey = FALSE;

    // Grab a copy once w/o critical section.
    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();

    if (WaitForSingleObject(hevInterrupt, AutoRepeatTimeout) == 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;
    }
    else
    {
        // We got a keyboard interrupt but there may or may not be key events.
        cKeyEvents = KeybdPdd_GetEventEx(VKeyBuf, ScanCodeBuf,
                                         KeyStateFlagsBuf);

        if (cKeyEvents)
        {
            for (iKeyEventIdx = 0; iKeyEventIdx < cKeyEvents; iKeyEventIdx++)
            {
                if (KeyStateIsDown(KeyStateFlagsBuf[iKeyEventIdx]))
                {
                    MRKeyTimeForPolling = GetTickCount();

                    v_AutoRepeatState = AR_INITIAL_DELAY;
                    v_AutoRepeatVKey = VKeyBuf[iKeyEventIdx];
                    v_AutoRepeatScanCode = ScanCodeBuf[iKeyEventIdx];
                    v_AutoRepeatKeyStateFlags = KeyStateFlagsBuf[iKeyEventIdx];

                    cRemapEvents =
                        KeybdDriverRemapVKeyDownEx(VKeyBuf[iKeyEventIdx],
                                                   ScanCodeBuf[iKeyEventIdx],
                                                   KeyStateFlagsBuf[iKeyEventIdx],
                                                   RemapVKeyBuf,
                                                   RemapScanCodeBuf,
                                                   RemapKeyStateFlagsBuf);

                    for (iRemapIdx = 0; iRemapIdx < cRemapEvents; iRemapIdx++)
                    {
#if 0
                        RETAILMSG(1, (TEXT("D %d %x %x\r\n"),
                                      j, RemapVKeyBuf[j],
                                      RemapKeyStateFlagsBuf[j]));
#endif /* 0/1 */
                        if (v_pfnKeybdEventCallbackEx)
                        {
                            (*v_pfnKeybdEventCallbackEx)(RemapVKeyBuf[iRemapIdx],
                                                         RemapScanCodeBuf[iRemapIdx],
                                                         RemapKeyStateFlagsBuf[iRemapIdx]);
                        }
                    }
                }
                else
                {
                    v_AutoRepeatState = AR_WAIT_FOR_ANY;

                    cRemapEvents =
                        KeybdDriverRemapVKeyUpEx(VKeyBuf[iKeyEventIdx],
                                                 ScanCodeBuf[iKeyEventIdx],
                                                 KeyStateFlagsBuf[iKeyEventIdx],
                                                 RemapVKeyBuf,
                                                 RemapScanCodeBuf,
                                                 RemapKeyStateFlagsBuf);

                    for (iRemapIdx = 0; iRemapIdx < cRemapEvents; iRemapIdx++)
                    {
#if 0
                        RETAILMSG(1, (TEXT("U %d %x %x\r\n"),
                                      j, RemapVKeyBuf[j],
                                      RemapKeyStateFlagsBuf[j]));
#endif /* 0/1 */

                        if (v_pfnKeybdEventCallbackEx)
                        {
                            (*v_pfnKeybdEventCallbackEx)(RemapVKeyBuf[iRemapIdx],
                                                         RemapScanCodeBuf[iRemapIdx],
                                                         RemapKeyStateFlagsBuf[iRemapIdx]);
                        }
                    }
                }
            }
        }
        else
        {
            /*
             * We did not get a timeout from the wait or key events. We
             * must be periodically polling. This means that we will need
             * to do the timing here.
             */
            if ( (v_AutoRepeatState == AR_INITIAL_DELAY) ||
                 (v_AutoRepeatState == AR_AUTO_PARTIAL) ||
                 (v_AutoRepeatState == AR_AUTOREPEATING))
            {
                v_AutoRepeatState = AR_AUTO_PARTIAL;
            }
        }

        //  Ack the interrupt.
        InterruptDone(bSYSINTR);
    }

    if (fSendAutoRepeatKey)
    {
        cRemapEvents =
            KeybdDriverRemapVKeyDownEx(v_AutoRepeatVKey,
                                       v_AutoRepeatScanCode,
                                       v_AutoRepeatKeyStateFlags,
                                       RemapVKeyBuf,
                                       RemapScanCodeBuf,
                                       RemapKeyStateFlagsBuf);

        for (iRemapIdx = 0; iRemapIdx < cRemapEvents; iRemapIdx++)
        {
#if 0
            RETAILMSG(1, (TEXT("D %d %x %x\r\n"),
                          j, RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]));
#endif /* 0/1 */

            if (v_pfnKeybdEventCallbackEx)
            {
                (*v_pfnKeybdEventCallbackEx)(RemapVKeyBuf[iRemapIdx],
                                             RemapScanCodeBuf[iRemapIdx],
                                             RemapKeyStateFlagsBuf[iRemapIdx]);
            }
        }
    }

    goto wait_for_keybd_interrupt;

    ERRORMSG(1, (TEXT("Keyboard driver thread terminating.\r\n")));
    return 0;
}

extern "C"
/*
 *
 * @func
 *
 * System power state change notification.
 *
 * @parm
 *
 *    bOff    TRUE, the system is powering off; FALSE, the system is
 *            powering up.
 *
 * @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.
 *
 *    Resets the auto-repeat state and calls KeybdPdd_PowerHandler()
 */
void KeybdDriverPowerHandler(BOOL bOff)
{
    v_AutoRepeatState = AR_WAIT_FOR_ANY;
    KeybdPdd_PowerHandler(bOff);
    return;
}

#ifdef DEBUG
PFN_KEYBD_DRIVER_POWER_HANDLER v_pfnPowerHandler = KeybdDriverPowerHandler;
#endif

extern "C"
/*
 * @func KeybdDriverInitializeEx
 *
 *    Do one time only keyboard driver initialization.
 *
 * @parm
 *
 *    pfnKeybdEventCallbackEx    The callback into the input system.
 *
 * @rdesc
 *
 *    If the function succeeds the return value is TRUE, otherwise, it is
 *    FALSE.  Extended error information is available via the GetLastError
 *    function.
 *
 * @comm
 *
 *    Calls KeybdPdd_InitializeDriver() then starts driver interrupt
 *    service thread.
 */
void KeybdDriverInitializeEx(PFN_KEYBD_EVENT_CALLBACK_EX pfnKeybdEventCallbackEx)
{
    v_pfnKeybdEventCallbackEx = pfnKeybdEventCallbackEx;

    KeybdPdd_InitializeDriverEx(pfnKeybdEventCallbackEx);

    (*pfnKeybdEventCallbackEx)(KEYBD_DEVICE_CONNECT, 0, 0);

    return;
}

#ifdef DEBUG
PFN_KEYBD_DRIVER_INITIALIZE_EX v_pfnDriverInitializeTestEx = KeybdDriverInitializeEx;
#endif

/* EOF kbdist.cpp */

⌨️ 快捷键说明

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