kbdist.cpp

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

CPP
522
字号
    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 = FALSE;
    DWORD MRKeyTimeForPolling = 0;

    AutoRepeatTimeout = INFINITE;

    if (timedout)
    {
#if 0
        DEBUGMSG(1, (TEXT("KbdIstUpcall: timed out, repeatstate = %d\r\n"),
                     v_AutoRepeatState));
#endif /* 0/1 */

        /*
         * 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
    {
        /*
         * no timeout, so we got a keyboard interrupt; however there
         * may or may not be key events
         */
        cKeyEvents = pl050KeybdPdd_GetEventEx(VKeyBuf, ScanCodeBuf,
                                              KeyStateFlagsBuf,
                                              (UINT8)scancode);

#if 0
        DEBUGMSG(1, (TEXT("KbdIstUpcall: event was %d\r\n"), cKeyEvents));
#endif /* 0/1 */

        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("D1 %d %x %x\r\n"),
                                      iRemapIdx, RemapVKeyBuf[iRemapIdx],
                                      RemapKeyStateFlagsBuf[iRemapIdx]));
#endif /* 0/1 */

                        /*
                         * XXX
                         *
                         * we don't need to test v_pfnKeybdEventCallbackEx
                         * against NULL, 'cause if it's NULL then we'll
                         * never get into this Upcall in the first place
                         * (see code in KeybdDriverInitializeEx())
                         */
                        (*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"),
                                     iRemapIdx, RemapVKeyBuf[iRemapIdx],
                                     RemapKeyStateFlagsBuf[iRemapIdx]));
#endif /* 0/1 */

                        /*
                         * XXX
                         *
                         * we don't need to test v_pfnKeybdEventCallbackEx
                         * against NULL, 'cause if it's NULL then we'll
                         * never get into this Upcall in the first place
                         * (see code in KeybdDriverInitializeEx())
                         */
                        (*v_pfnKeybdEventCallbackEx)(RemapVKeyBuf[iRemapIdx],
                                                     RemapScanCodeBuf[iRemapIdx],
                                                     RemapKeyStateFlagsBuf[iRemapIdx]);
                    }
                }
            }
        }

        /*
         * 20000714 KWelton
         *
         * This is arse - we are >not< periodically polling. We have
         * cKeyEvents as zero because we've just been given the first
         * part of a multi-byte scan code (e.g. a cursor key); don't
         * execute this code, otherwise we get erroneous autorepeats.
         */
#ifdef OldCode
        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_AUTOREPEATING))
            {
                v_AutoRepeatState = AR_AUTO_PARTIAL;
            }
        }
#endif /* OldCode */
    }

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

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

            /*
             * XXX
             *
             * we don't need to test v_pfnKeybdEventCallbackEx
             * against NULL, 'cause if it's NULL then we'll
             * never get into this Upcall in the first place
             * (see code in KeybdDriverInitializeEx())
             */
            (*v_pfnKeybdEventCallbackEx)(RemapVKeyBuf[iRemapIdx],
                                         RemapScanCodeBuf[iRemapIdx],
                                         RemapKeyStateFlagsBuf[iRemapIdx]);
        }
    }

    /*
     * now calculate and return timeout value
     */

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

    return AutoRepeatTimeout;
}

/*
 *
 * @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()
 */
extern "C" 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

/* EOF kbdist.cpp */

⌨️ 快捷键说明

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