kbdist.cpp
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C++ 代码 · 共 532 行 · 第 1/2 页
CPP
532 行
{
/*
* these three variables are all hardcoded with the PDD
*/
UINT32 VKeyBuf[16];
UINT32 ScanCodeBuf[16];
KEY_STATE_FLAGS KeyStateFlagsBuf[16];
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;
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 0
RETAILMSG(1, (TEXT("D %d %x %x\r\n"),
j, RemapVKeyBuf[j],
RemapKeyStateFlagsBuf[j]));
#endif /* 0/1 */
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 0
RETAILMSG(1, (TEXT("U %d %x %x\r\n"),
j, RemapVKeyBuf[j],
RemapKeyStateFlagsBuf[j]));
#endif /* 0/1 */
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(bSYSINTR);
}
if (fSendAutoRepeatKey)
{
cRemapEvents =
KeybdDriverRemapVKeyDownEx(v_AutoRepeatVKey,
v_AutoRepeatScanCode,
v_AutoRepeatKeyStateFlags,
RemapVKeyBuf,
RemapScanCodeBuf,
RemapKeyStateFlagsBuf);
for (iRemapIdx = 0; iRemapIdx < cRemapEvents; iRemapIdx++)
{
#if 0
RETAILMSG(1, (TEXT("D %d %x %x\r\n"),
j, RemapVKeyBuf[j], RemapKeyStateFlagsBuf[j]));
#endif /* 0/1 */
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"
/*
*
* @func
*
* System power state change notification.
*
* @parm
*
* bOff TRUE, the system is powering off; FALSE, the system is
* powering up.
*
* @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.
*
* Resets the auto-repeat state and calls KeybdPdd_PowerHandler()
*/
void KeybdDriverPowerHandler(BOOL bOff)
{
v_AutoRepeatState = AR_WAIT_FOR_ANY;
KeybdPdd_PowerHandler(bOff);
return;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_POWER_HANDLER v_pfnPowerHandler = KeybdDriverPowerHandler;
#endif
extern "C"
/*
* @func KeybdDriverInitializeEx
*
* Do one time only keyboard driver initialization.
*
* @parm
*
* pfnKeybdEventCallbackEx The callback into the input system.
*
* @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 KeybdPdd_InitializeDriver() then starts driver interrupt
* service thread.
*/
void KeybdDriverInitializeEx(PFN_KEYBD_EVENT_CALLBACK_EX pfnKeybdEventCallbackEx)
{
v_pfnKeybdEventCallbackEx = pfnKeybdEventCallbackEx;
KeybdPdd_InitializeDriverEx(pfnKeybdEventCallbackEx);
(*pfnKeybdEventCallbackEx)(KEYBD_DEVICE_CONNECT, 0, 0);
return;
}
#ifdef DEBUG
PFN_KEYBD_DRIVER_INITIALIZE_EX v_pfnDriverInitializeTestEx = KeybdDriverInitializeEx;
#endif
/* EOF kbdist.cpp */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?