📄 keybdist.cpp
字号:
return TRUE;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_SET_MODE v_pfnSetModeTest = KeybdDriverSetMode;
#endif
/*++
KeybdDriverThread:
Keyboard driver interrupt service thread.
Return Value:
Never returns.
--*/
DWORD
KeybdDriverThread(
PVOID pArg
)
{
HANDLE hKeyIntr;
UINT32 VirtualKey[16]; // hardcoded w/ PDD
KEY_STATE_FLAGS KeyStateFlags[16]; // hardcoded w/ PDD
UINT32 RemapVKeyBuf[16];
KEY_STATE_FLAGS RemapKeyStateFlagsBuf[16];
INT nKeys;
int i, j;
INT nRemapKeys;
DWORD AutoRepeatKeysPerSec;
long AutoRepeatTimeout;
BOOL fSendAutoRepeatKey;
DWORD MRKeyTimeForPolling = 0; // Get rid of compiler uninitialized variable warning.
//SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
hKeyIntr = CreateEvent(
NULL, // No Security
FALSE, // Not manual reset
FALSE, // Not initially signalled
NULL // No name
);
if ( !hKeyIntr )
{
ERRORMSG(1,
(TEXT("Could not create event handle for keyboard interrupt!!!\r\n")));
goto exit;
}
// Turn on the interrupt.
if ( !InterruptInitialize(gIntrKeyboard, hKeyIntr, 0, 0) )
{
ERRORMSG(1,
(TEXT("InterruptInitialize(gIntrKeyboard %d) failed!!!\r\n"),
gIntrKeyboard));
goto exit;
}
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 0
if ( AutoRepeatKeysPerSec == 0 )
v_AutoRepeatState = AR_WAIT_FOR_ANY;
if ( v_AutoRepeatState == AR_WAIT_FOR_ANY )
{
#endif // 0
AutoRepeatTimeout = INFINITE;
#if 0
}
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;
}
#endif // 0
MRKeyTimeForPolling = GetTickCount();
if ( WaitForSingleObject(hKeyIntr, 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 keys.
if ( nKeys = KeybdPdd_GetEvent(VirtualKey, KeyStateFlags) ) // Assignment in if
{
for ( i = 0; i < nKeys; i++ )
{
if ( KeyStateIsDown(KeyStateFlags[i]) )
{
MRKeyTimeForPolling = GetTickCount();
v_AutoRepeatState = AR_INITIAL_DELAY;
v_AutoRepeatVKey = VirtualKey[i];
v_AutoRepeatFlags = KeyStateFlags[i];
nRemapKeys = KeybdDriverRemapVKeyDown(VirtualKey[i], RemapVKeyBuf, RemapKeyStateFlagsBuf);
for ( j = 0; j < nRemapKeys; j++ )
{
// RETAILMSG(1, (TEXT("D %d %x %x\r\n"), j, RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]));
(*v_pfnKeybdEventCallback)(RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]);
}
}
else
{
v_AutoRepeatState = AR_WAIT_FOR_ANY;
nRemapKeys = KeybdDriverRemapVKeyUp(VirtualKey[i], RemapVKeyBuf, RemapKeyStateFlagsBuf);
for ( j = 0; j < nRemapKeys; j++ )
{
// RETAILMSG(1, (TEXT("U %d %x %x\r\n"), j, RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]));
(*v_pfnKeybdEventCallback)(RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]);
}
}
}
}
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(gIntrKeyboard);
}
if ( fSendAutoRepeatKey )
{
nRemapKeys = KeybdDriverRemapVKeyDown(v_AutoRepeatVKey, RemapVKeyBuf, RemapKeyStateFlagsBuf);
for ( j = 0; j < nRemapKeys; j++ )
{
// RETAILMSG(1, (TEXT("R %d %x %x\r\n"), j, RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]));
(*v_pfnKeybdEventCallback)(RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]);
}
}
// Always acknowledge the interrupt.
// Ack the interrupt.
InterruptDone(gIntrKeyboard);
goto wait_for_keybd_interrupt;
exit:
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 KeybdDriverInitialize(
PFN_KEYBD_EVENT_CALLBACK pfnKeybdEventCallback // @parm The callback into the input system.
)
{
HANDLE hNewThread;
DWORD IDThread;
v_pfnKeybdEventCallback = pfnKeybdEventCallback;
KeybdPdd_InitializeDriver(pfnKeybdEventCallback);
hNewThread = CreateThread(
0, // Security Attributes
0, // Stack Size
(LPTHREAD_START_ROUTINE)KeybdDriverThread,
0, // Thread Param
0, // Creation Flags
&IDThread
);
if ( hNewThread == NULL )
{
ERRORMSG(1, (TEXT("Could not start keybd driver thread.\r\n")));
return;
}
// Get thread priority from registry and set
CeSetThreadPriority(hNewThread, KeybdDriverpGetPriority( ));
return;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_INITIALIZE v_pfnDriverInitializeTest = KeybdDriverInitialize;
#endif
BOOL
WINAPI
DllEntry(
HANDLE hinstDLL,
DWORD Op,
LPVOID lpvReserved
)
{
if ( !KeybdPdd_DllEntry(hinstDLL, Op, lpvReserved) )
return FALSE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -