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

📄 keybdmdd.cpp

📁 三星2410的BSP开发包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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	keybdmdd.cpp |

This file implements 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 <memory.h>
#include <nkintr.h>
#include <keybddr.h>
#include <keybdpdd.h>

#ifdef DEBUG
DBGPARAM dpCurSettings = { TEXT("Keybd"), {
  TEXT("Init"),  TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),
  TEXT("Undefined"),  TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),
  TEXT("Undefined"),  TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),
  TEXT("Undefined"),  TEXT("Undefined"), TEXT("Warning"), TEXT("Error") },
			   0x00000000 };

#define ZONE_INIT       DEBUGZONE(0)
#define ZONE_WARN       DEBUGZONE(14)
#define ZONE_ERROR      DEBUGZONE(15)

#endif


#define C_VIRTUAL_KEYS     			256
#define MAX_TO_UNICODE_CHARACTERS	1

#define VK_0	0x30
#define VK_9	0x39


//	Auto repeat #defines and state variables.
#define AR_WAIT_FOR_ANY		0
#define AR_INITIAL_DELAY	1
#define AR_AUTOREPEATING	2

#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 KEY_STATE_FLAGS	v_AutoRepeatFlags;



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


//	The real state of the certain keys.
static BOOL		v_fLShiftDown;
static BOOL		v_fRShiftDown;
static BOOL		v_fLAltDown;
static BOOL		v_fRAltDown;
static BOOL		v_fLCtrlDown;
static BOOL		v_fRCtrlDown;


//	Use a pseudo Alt key since we simulate that the Alt key goes up and down.
static BOOL		v_fLPseudoAltDown;
static BOOL		v_fRPseudoAltDown;
static BOOL		v_fLastKeyDownWasPseudoAlt;


//	Keep track of the last vkey actually sent for keys which have multiple 
//	virtual keys.  
static UINT32	v_LShiftVKeySent;
static UINT32	v_RShiftVKeySent;
static UINT32	v_PeriodVKeySent;
static UINT32	v_CommaVKeySent;
static UINT32	v_BackVKeySent;
static UINT32	v_RightVKeySent;
static UINT32	v_LeftVKeySent;
static UINT32	v_UpVKeySent;
static UINT32	v_DownVKeySent;


#define ANY_ALT_DOWN()		(v_fLAltDown || v_fRAltDown)
#define ANY_CTRL_DOWN()		(v_fLCtrlDown || v_fRCtrlDown)
#define ANY_SHIFT_DOWN()	(v_fLShiftDown || v_fRShiftDown)


//      @doc    EXTERNAL DRIVERS
/*      @struct TO_UNICODE_STATE |

State info needed by the driver to convert virtual keys to Unicode.

@xref
	<tab><f KeybdDriverGetDeviceInfo><nl>
	<tab><f KeybdDriverInitStates><nl>
	<tab><f KeybdDriverVKeyToUnicode><nl>


@comm This struct would be used by the driver to maintain any state 
information needed between key events in order to generate Unicode 
characters from virtual keys.  

@comm This structure is not visible outside of the driver.  The driver 
provides information on its size via the <f KeybdDriverGetDeviceInfo> 
function.  The input system allocates a buffer for the structure and 
passes it in when it calls <f KeybdDriverVKeyToUnicode>.  

@comm In the sample driver code, it appears for demo purposes only.  

*/
struct TO_UNICODE_STATE
	{
	int     KeybdSpecificVKeyToUnicodeStateHere;    //      @field  Whatever is needed by a specific keyboard driver
	};


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:
			{
			struct KBDI_VKEY_TO_UNICODE_INFO	*pInfo =
					(struct KBDI_VKEY_TO_UNICODE_INFO*)lpOutput;
			pInfo -> cbToUnicodeState = sizeof(TO_UNICODE_STATE); //for demo purposes only
			pInfo -> cMaxToUnicodeCharacters = MAX_TO_UNICODE_CHARACTERS;
			}
			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

Initializes the virtual key state and driver specific state.

@xref

	<tab><t KEY_STATE><nl>
	<tab><t TO_UNICODE_STATE><nl>
	<tab><f KeybdDriverGetInfo><nl>
	<tab><c KBDI_VKEY_TO_UNICODE_INFO_ID><nl>
	<tab><t KBDI_VKEY_TO_UNICODE_INFO><nl>

@comm After calling <f KeybdDriverGetInfo> and allocating its required 
memory, the input system calls this function to allow the driver to 
initialize the memory.

@comm The pKeybdDriverToUnicodeState is a pointer to a piece of memory of 
at least cbToUnicodeState bytes as reported by the <f KeybdDriverGetInfo> 
function in the <t KBDI_VKEY_TO_UNICODE_INFO> structure.  If 
cbToUnicodeState was reported as 0, this parameter may be NULL.  

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

*/
BOOL KeybdDriverInitStates(
	INT			iKeybdId,						// @parm Id of the keyboard to initialize keystate data for.
	KEY_STATE   KeyState,                       // @parm Key state to initialize.
	void        *pKeybdDeviceToUnicodeState     // @parm Keyboard specific state to initialize.
	)
{
	TO_UNICODE_STATE	*pDemoState = (TO_UNICODE_STATE*)pKeybdDeviceToUnicodeState;
	int	i;

// We have some demo state, so check for it.  If we had no state,
// this parameter could be NULL with no error.
	if ( pDemoState == NULL )
		{
		SetLastError(ERROR_INVALID_PARAMETER);
		return FALSE;
		}
 
	for ( i = 0; i < COUNT_VKEYS; i++ )
		{
		KeyState[i] = 0;
		}

	return TRUE;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_INIT_STATES v_pfnInitStatesTest = KeybdDriverInitStates;
#endif




/*++

MapLRVKeys:

Map left and right virtual keys to their common vkey.  


Return Value:

The common vkey.  

--*/
UINT32
MapLRVKeys(
	UINT32	vkey
	)
{
	if ( ( vkey == VK_LCONTROL ) ||
		 ( vkey == VK_RCONTROL ) )
		return VK_CONTROL;

	if ( ( vkey == VK_LMENU ) ||
		 ( vkey == VK_RMENU ) )
		return VK_MENU;

	if ( ( vkey == VK_LSHIFT ) ||
		 ( vkey == VK_RSHIFT ) )
		return VK_SHIFT;

//	VK_LWIN and VK_RWIN do not have a merged key.

	return vkey;
}





/*++

NewKeyStateFlags:

Figure out the new key state flags based on the current state and the 
event.  


Return Value:

The new flag settings.  

--*/
UINT32
NewKeyStateFlags(
	KEY_STATE_FLAGS CurrentState,
	KEY_STATE_FLAGS KeyEventFlags
	)
{
//	Just interested in down/up flag.
	KeyEventFlags &= KeyStateDownFlag;

//	First update the key state for the specific key.
//	Remember the previous state.
	if ( KeyStateIsDown(CurrentState) )
		CurrentState |= KeyStatePrevDownFlag;
	else
		CurrentState &= ~KeyStatePrevDownFlag;

//	Set the new state.
	if ( KeyEventFlags )
		CurrentState |= KeyStateDownFlag | KeyStateGetAsyncDownFlag;
	else
		CurrentState &= ~KeyStateDownFlag;

//	Toggle flag only changes on down transition, not auto repeat.
	if ( KeyStateIsDownTransition(CurrentState) )
		CurrentState ^= KeyStateToggledFlag;

	return CurrentState;
}


/*++

KeybdDriverKeyStateToShiftFlags:

Collapse the shift state from a given key state array into a single 
element.  


Notes:

For the given virtual key, the current flags from the key state array are 
put into the low bits of the output flags.  


--*/
void KeybdDriverKeyStateToShiftFlags(
	KEY_STATE       KeyState,           // Key state array.
	UINT32          VKey,               // Virtual key.
	KEY_STATE_FLAGS *pShiftStateFlags   // Location to put collapsed shift state.
	)
{
	KEY_STATE_FLAGS ShiftFlags = 0;

//  Add the standard keys.
	if ( KeyStateIsDown(KeyState[VK_CONTROL]) )
		{
		ShiftFlags |= KeyShiftAnyCtrlFlag;
		}

	if ( KeyStateIsDown(KeyState[VK_LCONTROL]) )
		{
		ShiftFlags |= KeyShiftLeftCtrlFlag;
		}

	if ( KeyStateIsDown(KeyState[VK_RCONTROL]) )
		{
		ShiftFlags |= KeyShiftRightCtrlFlag;
		}


	if ( KeyStateIsDown(KeyState[VK_SHIFT]) )
		{
		ShiftFlags |= KeyShiftAnyShiftFlag;
		}

	if ( KeyStateIsDown(KeyState[VK_LSHIFT]) )
		{
		ShiftFlags |= KeyShiftLeftShiftFlag;
		}

	if ( KeyStateIsDown(KeyState[VK_RSHIFT]) )
		{
		ShiftFlags |= KeyShiftRightShiftFlag;
		}


	if ( KeyStateIsDown(KeyState[VK_MENU]) )
		{
		ShiftFlags |= KeyShiftAnyAltFlag;
		}

	if ( KeyStateIsDown(KeyState[VK_LMENU]) )
		{
		ShiftFlags |= KeyShiftLeftAltFlag;
		}

	if ( KeyStateIsDown(KeyState[VK_RMENU]) )
		{
		ShiftFlags |= KeyShiftRightAltFlag;
		}

	if ( KeyStateIsDown(KeyState[VK_LWIN]) )
		{
		ShiftFlags |= KeyShiftLeftWinFlag;
		}

	if ( KeyStateIsDown(KeyState[VK_RWIN]) )
		{
		ShiftFlags |= KeyShiftRightWinFlag;
		}

	if ( KeyStateIsToggled(KeyState[VK_CAPITAL]) )
		ShiftFlags |= KeyShiftCapitalFlag;

//  Set the low order bits to reflect the current key.
	*pShiftStateFlags = ShiftFlags | KeyState[VKey];
	return;
}




/*
   The following defines will be used for converting the key pressed
   into a Unicode character using the context information (the state
   of other keys). We are assuming here that the count of bytes required
   for state info for Unicode character generation (cbToUnicodeState
   field in KEYBD_DRIVER_INFO structure) is zero, ie the driver does
   not maintain any state information (besides CAPS, SHIFT, ALT and
   CONTROL state) for Unicode character generation.
   The Unicode character generated depends on the key pressed and
   the state of the following keys: CAPS, SHIFT, ALT and CONTROL. Hence
   for every Virtual key generated by  the PDD, there can be a total of
   16 different Unicode Characters  in the worst case. Since there are
   a total of 256 different virtual keys  possible, storing all possible
   states would require a lot of memory. Hence rows which are together
   have been grouped and columns which have the same corresponding values

⌨️ 快捷键说明

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