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

📄 kbdist.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
字号:
/*

  Copyright(c) 1998,1999 SIC/Hitachi,Ltd.
  Copyright(c) 1998,1999 3RD Rail Engineering.

	Module Name:

		keybdist.cpp

	Revision History:

		26th April 1999		Released
		16th June  1999		Revised
*/

#include <windows.h>
#include <nkintr.h>
#include <pkfuncs.h>
//#include <oalintr.h>
#include <keybddr.h>
#include <keybdpdd.h>

#ifdef DEBUG

DBGPARAM dpCurSettings = {
    TEXT("Keybddr"), {
        TEXT("0"),TEXT("1"),TEXT("2"),TEXT("3"),
        TEXT("4"),TEXT("5"),TEXT("6"),TEXT("7"),
        TEXT("8"),TEXT("9"),TEXT("Mouse Data"),TEXT("Scan Codes"),
        TEXT("Init"),TEXT("Function"),TEXT("Warning"),TEXT("Error")},
    0x0000
}; 


#endif

/* Note: The specific defines for the
 * debug zone flags are in: dbgzones.hpp
 */
#include "dbgzones.hpp"


//	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		250
#define AUTO_REPEAT_INITIAL_DELAY_MAX		1000
#define AUTO_REPEAT_INITIAL_DELAY_DEFAULT	500

#define AUTO_REPEAT_KEYS_PER_SEC_MIN		2
#define AUTO_REPEAT_KEYS_PER_SEC_MAX		30
#define AUTO_REPEAT_KEYS_PER_SEC_DEFAULT	20

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;

extern DWORD dwSysIntrKeyboard;


//	Routine to call back in to user when there is a keyboard event.
static PFN_KEYBD_EVENT_CALLBACK_EX	v_pfnKeybdEventCallbackEx;



extern "C"
//      @doc EXTERNAL DRIVERS
/*      @func

Gives information about the keyboard and driver.


@rdesc If the function succeeds the return value is TRUE, otherwise, it is
FALSE.  Extended error information is available via the GetLastError
function.

@xref
	<tab><c KBDI_VKEY_TO_UNICODE_INFO_ID><nl>
	<tab><c KBDI_AUTOREPEAT_INFO_ID><nl>
	<tab><c KBDI_AUTOREPEAT_SELECTIONS_INFO_ID>

@comm This function must be re-entrant since it is exposed by the input
system via the <f KeybdGetDeviceInfo> function and may be called by
multiple threads.

*/
BOOL KeybdDriverGetInfo(
	INT		iKeybdId,	// @parm Id of the keyboard to get the information from.
	INT		iIndex,		// @parm Id of info to retrieve.
	LPVOID  lpOutput	// @parm Output buffer.
	)
{
	if ( lpOutput == NULL )
		{
		SetLastError(ERROR_INVALID_PARAMETER);
		return FALSE;
		}

	switch ( iIndex )
		{
		case KBDI_VKEY_TO_UNICODE_INFO_ID:
			VKeyToUnicodeInfo((struct KBDI_VKEY_TO_UNICODE_INFO*)lpOutput);
			break;

		case KBDI_AUTOREPEAT_INFO_ID:
			{
			struct KBDI_AUTOREPEAT_INFO	*pInfo =
					(struct KBDI_AUTOREPEAT_INFO*)lpOutput;
			pInfo -> CurrentInitialDelay = v_AutoRepeatInitialDelay;
			pInfo -> CurrentRepeatRate = v_AutoRepeatKeysPerSec;
			pInfo -> cInitialDelaysSelectable = -1;
			pInfo -> cRepeatRatesSelectable = -1;
			}
			break;

		case KBDI_AUTOREPEAT_SELECTIONS_INFO_ID:
			{
			INT32	*pInfo = (INT32*)lpOutput;
			*(pInfo)	= AUTO_REPEAT_INITIAL_DELAY_MIN;		//	Min initial delay
			*(pInfo+1)	= AUTO_REPEAT_INITIAL_DELAY_MAX;		//	Max initial delay
			*(pInfo+2)	= AUTO_REPEAT_KEYS_PER_SEC_MIN;		//	Min repeat rate
			*(pInfo+3)	= AUTO_REPEAT_KEYS_PER_SEC_MAX;		//	Max repeat rate
			}
			break;

		default:
			SetLastError(ERROR_INVALID_PARAMETER);
			return FALSE;
		}
  return TRUE;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_GET_INFO v_pfnGetInfoTest = KeybdDriverGetInfo;
#endif








extern "C"
//      @doc EXTERNAL DRIVERS
/*		@func

Sets information about the keyboard device.

@rdesc If the function succeeds the return value is TRUE, otherwise, it is
FALSE.  Extended error information is available via the GetLastError
function.

@xref
	<tab><f KeybdDriverGetIno><nl>
	<tab><c KBDI_AUTOREPEAT_INFO_ID><nl>

--*/
BOOL KeybdDriverSetMode(
	INT		iKeybdId,	// @parm Id of the keyboard to set the information.
	INT		iIndex,		// @parm Id of info to set.
	LPVOID	lpInput 	// @parm Input buffer.
    )
{
	if ( lpInput == NULL )
		{
		SetLastError(ERROR_INVALID_PARAMETER);
		return FALSE;
		}

	switch ( iIndex )
		{
		case KBDI_AUTOREPEAT_INFO_ID:
			{
			struct KBDI_AUTOREPEAT_INFO	*pInfo =
					(struct KBDI_AUTOREPEAT_INFO*)lpInput;
			if ( pInfo -> CurrentInitialDelay > AUTO_REPEAT_INITIAL_DELAY_MAX )
				{
				v_AutoRepeatInitialDelay = AUTO_REPEAT_INITIAL_DELAY_MAX;
				}
			else if ( pInfo -> CurrentInitialDelay < AUTO_REPEAT_INITIAL_DELAY_MIN )
				{
				v_AutoRepeatInitialDelay = AUTO_REPEAT_INITIAL_DELAY_MIN;
				}
			else
				{
				v_AutoRepeatInitialDelay = pInfo -> CurrentInitialDelay;
				}


			if ( pInfo -> CurrentRepeatRate > AUTO_REPEAT_KEYS_PER_SEC_MAX )
				{
				v_AutoRepeatKeysPerSec = AUTO_REPEAT_KEYS_PER_SEC_MAX;
				}
			else if ( ( pInfo -> CurrentRepeatRate < AUTO_REPEAT_KEYS_PER_SEC_MIN ) &&
					  ( pInfo -> CurrentRepeatRate != 0 ) )
				{
				v_AutoRepeatKeysPerSec = AUTO_REPEAT_KEYS_PER_SEC_MIN;
				}
			else
				{
				v_AutoRepeatKeysPerSec = pInfo -> CurrentRepeatRate;
				}

			}
			break;

		default:
			SetLastError(ERROR_INVALID_PARAMETER);
			return FALSE;
		}

	return TRUE;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_SET_MODE  v_pfnSetModeTest = KeybdDriverSetMode;
#endif







/*++

KeybdDriverThread:

Keyboard driver interrupt service thread.


Return Value:

Never returns.

--*/
BOOL
KeybdIstLoop(
	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 = 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 ( 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 ( 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(dwSysIntrKeyboard);

		}

	if ( fSendAutoRepeatKey )
		{

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

		for ( iRemapIdx = 0; iRemapIdx < cRemapEvents; iRemapIdx++ )
			{
			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"
/*++

@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;
	KeybdPdd_PowerHandler(bOff);
	return;
}

#ifdef DEBUG
PFN_KEYBD_DRIVER_POWER_HANDLER v_pfnPowerHandler = KeybdDriverPowerHandler;
#endif



extern "C"
//	@doc EXTERNAL DRIVERS
/*	@func Do one time only keyboard driver initialization.

@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 <f KeybdPdd_InitializeDriver> then starts driver interrupt
service thread.

--*/
void KeybdDriverInitializeEx(
	PFN_KEYBD_EVENT_CALLBACK_EX	pfnKeybdEventCallbackEx	// @parm The callback into the input system.
	)
{
	v_pfnKeybdEventCallbackEx = pfnKeybdEventCallbackEx;

	KeybdPdd_InitializeDriverEx(pfnKeybdEventCallbackEx);

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

	return;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_INITIALIZE_EX v_pfnDriverInitializeTestEx = KeybdDriverInitializeEx;
#endif

⌨️ 快捷键说明

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