📄 keybdist.cpp
字号:
//
// 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 keybdist.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 <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
// 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 = 0;
static KEY_STATE_FLAGS v_AutoRepeatFlags = 0;
// Routine to call back in to user when there is a keyboard event.
static PFN_KEYBD_EVENT_CALLBACK v_pfnKeybdEventCallback = NULL;
#define DEFAULT_THREAD_PRIORITY 145
#define KEYNAME_KEYBD_DRIVER TEXT("\\Drivers\\BuiltIn\\KeyBd")
#define VALNAME_THREAD_PRIO TEXT("Priority256")
/*++
Autodoc Information:
@func DWORD | KeybdDriverpGetPriority |
This routine reads the KeybdDriverThread thread priority from the registry.
@rdesc
Returns thread priority read from registry or the default priority if not
in the registry.
--*/
static DWORD KeybdDriverpGetPriority(void)
{
HKEY hKey;
DWORD dwType;
DWORD dwVal;
DWORD dwSize;
DWORD dwStatus;
dwStatus = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
KEYNAME_KEYBD_DRIVER,
0,
0,
&hKey
);
if (dwStatus)
{
DEBUGMSG(ZONE_INIT | ZONE_WARN,
(TEXT("KEYBDDR:KeybdDriverpGetPriority - RegOpenKeyEx(%s) failed %d, using default thread priority\n"),
KEYNAME_KEYBD_DRIVER, dwStatus));
return DEFAULT_THREAD_PRIORITY;
}
dwSize = sizeof(DWORD);
dwStatus = RegQueryValueEx(
hKey,
VALNAME_THREAD_PRIO,
0,
&dwType,
(PUCHAR)&dwVal,
&dwSize
);
if (dwStatus)
{
DEBUGMSG(ZONE_INIT | ZONE_WARN,
(TEXT("KEYBDDR:KeybdDriverpGetPriority - Failed to get %s value, defaulting to %d\r\n"),
VALNAME_THREAD_PRIO, DEFAULT_THREAD_PRIORITY));
dwVal = DEFAULT_THREAD_PRIORITY;
}
RegCloseKey(hKey);
return dwVal;
} // KeybdDriverpGetPriority
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 )
{
// RETAILMSG(1,
// (TEXT("Initial delay too large, using %d\r\n"),
// AUTO_REPEAT_INITIAL_DELAY_MAX));
v_AutoRepeatInitialDelay = AUTO_REPEAT_INITIAL_DELAY_MAX;
}
else if ( pInfo -> CurrentInitialDelay < AUTO_REPEAT_INITIAL_DELAY_MIN )
{
// RETAILMSG(1,
// (TEXT("Initial delay too small, using %d\r\n"),
// 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 )
{
// RETAILMSG(1,
// (TEXT("Initial repeat rate too large, using %d\r\n"),
// 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 ) )
{
// RETAILMSG(1,
// (TEXT("Initial repeat rate too small, using %d\r\n"),
// AUTO_REPEAT_KEYS_PER_SEC_MIN));
v_AutoRepeatKeysPerSec = AUTO_REPEAT_KEYS_PER_SEC_MIN;
}
else
{
v_AutoRepeatKeysPerSec = pInfo -> CurrentRepeatRate;
}
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -