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

📄 keypadist.cpp

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

    @doc	EXTERNAL DRIVERS

    @module	keypadist.cpp |

This file implements the interrupt service thread part of the platform
independent code of the keyboard driver.  This is provided as a sample to
platform driver writers and is expected to be able to be used without
major modification on most hardware platforms.

*/

#include <windows.h>
#include <nkintr.h>
#include "keypad.hpp"
#include <winuserm.h>

//	Auto repeat #defines and state variables.
#define AR_WAIT_FOR_ANY		0
#define AR_INITIAL_DELAY	1
#define AR_AUTOREPEATING	2
#define AR_AUTO_PARTIAL     3   // Auto repeat was interrupted by real PDD event.

#define AUTO_REPEAT_INITIAL_DELAY_MIN		500
#define AUTO_REPEAT_INITIAL_DELAY_MAX		250
#define AUTO_REPEAT_INITIAL_DELAY_DEFAULT	500

#define AUTO_REPEAT_KEYS_PER_SEC_MIN		2
#define AUTO_REPEAT_KEYS_PER_SEC_MAX		4
#define AUTO_REPEAT_KEYS_PER_SEC_DEFAULT	2




static int              v_AutoRepeatState = AR_WAIT_FOR_ANY;
static DWORD            v_AutoRepeatInitialDelay = AUTO_REPEAT_INITIAL_DELAY_DEFAULT;
static DWORD            v_AutoRepeatKeysPerSec = AUTO_REPEAT_KEYS_PER_SEC_DEFAULT;
static UINT32           v_AutoRepeatVKey;
static UINT32           v_AutoRepeatScanCode;
static KEY_STATE_FLAGS  v_AutoRepeatKeyStateFlags;



static VOID KeybdEvent(DWORD dwVk, DWORD dwSc, KEY_STATE_FLAGS flags)
{
    DWORD dwFlags = KeyStateIsDown(flags) ? 0 : KEYEVENTF_KEYUP;
    keybd_event((BYTE) dwVk, (BYTE) dwFlags, dwFlags, 0);
}


/*++

KeybdDriverThread:

Keyboard driver interrupt service thread.


Return Value:

Never returns.

--*/
BOOL
KeyPadIstLoop(
            HANDLE  hevInterrupt
            )
{
    UINT32          VKeyBuf[16];            //	hardcoded w/ PDD.
    UINT32          ScanCodeBuf[16];        //	hardcoded w/ PDD.
    KEY_STATE_FLAGS KeyStateFlagsBuf[16];   //  hardcoded w/ PDD.

    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;    //Get rid of compiler uninitialized variable warning.

    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

    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 = KeypdPdd_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++ )
                    {
//						RETAILMSG(1,
//							(TEXT("D %d %x %x\r\n"),
//								iRemapIdx, RemapVKeyBuf[iRemapIdx], RemapKeyStateFlagsBuf[iRemapIdx]));

/*						NKDbgPrintfW(TEXT("D %d %x %x\r\n"),iRemapIdx, 
                                                            RemapVKeyBuf[iRemapIdx], 
                                                            RemapKeyStateFlagsBuf[iRemapIdx]);*/
                        KeybdEvent(
                            RemapVKeyBuf[iRemapIdx],
                            RemapScanCodeBuf[iRemapIdx],
                            RemapKeyStateFlagsBuf[iRemapIdx]);

                        if ((RemapVKeyBuf[iRemapIdx] == VK_TVOLUMEUP) || (RemapVKeyBuf[iRemapIdx] == VK_TVOLUMEDOWN) ||
                            (RemapVKeyBuf[iRemapIdx] == VK_UP) || (RemapVKeyBuf[iRemapIdx] == VK_DOWN))
                        {
                            KeybdEvent(
                                RemapVKeyBuf[iRemapIdx],
                                RemapScanCodeBuf[iRemapIdx],
                                0);
                            v_AutoRepeatState = AR_WAIT_FOR_ANY;
                        }
                    }
                }
                else
                {
//					RETAILMSG(1,(TEXT("reset keystate to up\r\n")));
//					NKDbgPrintfW(TEXT("reset keystate to up\r\n"));

                    v_AutoRepeatState = AR_WAIT_FOR_ANY;

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

                    for ( iRemapIdx = 0; iRemapIdx < cRemapEvents; iRemapIdx++ )
                    {
//					RETAILMSG(1, (TEXT("U %d %x %x\r\n"), j, RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]));
//					NKDbgPrintfW(TEXT("U %d %x %x\r\n"), iRemapIdx, RemapVKeyBuf[iRemapIdx], RemapKeyStateFlagsBuf[iRemapIdx]);
                        KeybdEvent(
                            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(SYSINTR_KEYPAD);
    }

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

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

            KeybdEvent(
                RemapVKeyBuf[iRemapIdx],
                RemapScanCodeBuf[iRemapIdx],
                RemapKeyStateFlagsBuf[iRemapIdx]);
        }
    }

    goto wait_for_keybd_interrupt;

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



/*++

@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    bOff    // @parm TRUE, the system is powering off; FALSE, the system is powering up.
                            )
{
    v_AutoRepeatState = AR_WAIT_FOR_ANY;
    KeypdPdd_PowerHandler(bOff);
    return;
}

⌨️ 快捷键说明

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