ps2keybd.cpp

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C++ 代码 · 共 351 行

CPP
351
字号
/*

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.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.

*/

#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>

#include <keybddr.h>
#include <keybdpdd.h>

#include "ps2port.hpp"
#include "ps2mouse.hpp"
#include "ps2keybd.hpp"


// Scan code consts
static const UINT8 scE0Extended	= 0xe0;
static const UINT8 scE1Extended	= 0xe1;
static const UINT8 scKeyUpMask	= 0x80;

DWORD dwSysIntr_Keybd;

//	There is really only one physical keyboard supported by the system.
Ps2Keybd	*v_pp2k;


static KEY_STATE_FLAGS	v_KeyStateToggled;
static KEY_STATE_FLAGS	KeyStateFlags;


// We read our SysIntr Value from the registry
void
Read_SysIntr(
	LPCWSTR	 szKeyName,
    LPDWORD pdwSysIntr
    )
{
    HKEY hKeybd;
    DWORD ValType;
    DWORD ValLen;
    DWORD status;

    //
    // Get the device key from the active device registry key
    //
    status = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                szKeyName,
                0,
                0,
                &hKeybd);
    if (status) {
        DEBUGMSG(1, (TEXT("OpenDeviceKey: RegOpenKeyEx(HLM\\%s) returned %d!!!\r\n"),
                  szKeyName, status));
		pdwSysIntr = 0;   // Fail
        return;
    }

    ValLen = sizeof(DWORD);
    status = RegQueryValueEx(       // Retrieve the SysIntr value
                hKeybd,
                TEXT("SysIntr"),
                NULL,
                &ValType,
                (PUCHAR)pdwSysIntr,
                &ValLen);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(1, (TEXT("OpenDeviceKey: RegQueryValueEx(SYSINTR) returned %d\r\n"),
                  status));
		pdwSysIntr = 0;   // Fail
    }

    RegCloseKey(hKeybd);
}   // OpenDeviceKey



void
WINAPI
KeybdPdd_PowerHandler(
	BOOL	bOff
	)
{
	if ( bOff )
	{
		if ( KeyStateFlags == KeyStateDownFlag )
		{
			UCHAR ucKbdStatus, ucKbdData;

			// Since this function is invoked right after a key is pressed, the output buffer of
			// the keyboard must be cleaned until the corresponding key is released. Otherwise the
			// data in that buffer will prevent subsequent key stroke from generating interrupts,
			// which may cause the keyboard be hang up.
			do
			{
				ucKbdData = READ_PORT_UCHAR((PUCHAR)0x60);
			} while ( !(ucKbdData & scKeyUpMask) );
			KeyStateFlags = 0;
			
			ucKbdStatus = READ_PORT_UCHAR((PUCHAR)0x64);
			while ( (ucKbdStatus & 0x21) == 0x01 )
			{
				ucKbdData = READ_PORT_UCHAR((PUCHAR)0x60);
				ucKbdStatus = READ_PORT_UCHAR((PUCHAR)0x64);
			}
		}
	}
	return;
}

BOOL
WINAPI
KeybdPdd_InitializeDriverEx(
	PFN_KEYBD_EVENT_CALLBACK_EX	pfnKeybdEventCallbackEx
	)
{
	return TRUE;
}




int
WINAPI
KeybdPdd_GetEventEx(
	UINT32			VKeyBuf[16],
	UINT32			ScanCodeBuf[16],
	KEY_STATE_FLAGS	KeyStateFlagsBuf[16]
	)
{
	UINT8			ui8ScanCode;
	INT				cEvents = 0;

	static	UINT32	scInProgress;
	static	UINT32	scPrevious;

	v_pp2k -> m_pp2p -> KeybdDataRead(&ui8ScanCode);

//	RETAILMSG(1,(TEXT("scInProgress: %08x  ui8ScanCode: %08x\r\n"), scInProgress, ui8ScanCode));

	if ( ui8ScanCode == scE0Extended )
		{
		scInProgress = 0xe000;
		}
	else if ( ui8ScanCode == scE1Extended )
		{
		scInProgress = 0xe10000;
		}
	else if ( scInProgress == 0xe10000 )
		{
		ui8ScanCode &= ~scKeyUpMask;
		scInProgress |= ui8ScanCode << 8;
		}
	else
		{
		scInProgress |= ui8ScanCode;
		if ( scInProgress == scPrevious )
			{
			//	mdd handles auto-repeat so ignore auto-repeats from keybd
			}
		else	// Not a repeated key.  This is the real thing.
			{
			//	The Korean keyboard has two keys which generate a single
			//	scan code when pressed.  The keys don't auto-repeat or
			//	generate a scan code on release.  The scan codes are 0xf1
			//	and 0xf2.  It doesn't look like any other driver uses
			//	the 0x71 or 0x72 scan code so it should be safe.

			//	If it is one of the Korean keys, drop the previous scan code.
			//	If we didn't, the earlier check to ignore auto-repeating keys
			//	would prevent this key from working twice in a row.  (Since the
			//	key does not generate a scan code on release.)
			if ( ( scInProgress == 0xf1 ) ||
				 ( scInProgress == 0xf2 ) )
				{
				scPrevious = 0;
				}
			else
				{
				scPrevious = scInProgress;
				}
			
			//	Note that the special Korean scan scan codes look like key up
			//	events so this changes them to 0x71 and 0x72.
			if ( ui8ScanCode & scKeyUpMask )
				{
				KeyStateFlags = 0;
				scInProgress &= ~scKeyUpMask;
				}
			else
				{
				KeyStateFlags = KeyStateDownFlag;
				}
			cEvents = ScanCodeToVKeyEx(scInProgress, KeyStateFlags, VKeyBuf, ScanCodeBuf, KeyStateFlagsBuf);
			}
		scInProgress = 0;
		}

	return(cEvents);

}



void
WINAPI
KeybdPdd_ToggleKeyNotification(
	KEY_STATE_FLAGS	KeyStateFlags
	)
{
	unsigned int	fLights;

	v_KeyStateToggled = KeyStateFlags;

	fLights = 0;

	if ( KeyStateFlags & KeyShiftCapitalFlag )
		{
		fLights |= 0x04;
		}

	if ( KeyStateFlags & KeyShiftNumLockFlag )
		{
		fLights |= 0x2;
		}

	v_pp2k -> m_pp2p -> KeyboardLights(fLights);

	return;
}


KEY_STATE_FLAGS
WINAPI
KeybdPdd_KeyStateToggled(
	void
	)
{
	return v_KeyStateToggled;
}



BOOL
KeybdIstLoop(
	HANDLE	hevIntrKeybd
	);


BOOL
Ps2Keybd::
IsrThreadProc(
	void
	)
{
	m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
	if ( m_hevInterrupt == NULL)
		{
		goto leave;
		}

	Read_SysIntr( TEXT("HARDWARE\\DEVICEMAP\\KEYBD"),
					&dwSysIntr_Keybd );
					
	if( !dwSysIntr_Keybd ) {
		goto leave;
	}

	if ( !InterruptInitialize(dwSysIntr_Keybd, m_hevInterrupt, NULL, 0) )
		{
		goto leave;
		}


	m_pp2p -> KeybdInterruptEnable();

	KeybdIstLoop(m_hevInterrupt);


leave:
	return 0;
}



DWORD
Ps2KeybdIsrThread(
	Ps2Keybd	*pp2k
	)
{

	pp2k -> IsrThreadProc();

	return 0;
}




BOOL
Ps2Keybd::
IsrThreadStart(
	void
	)
{
	HANDLE	hthrd;

	hthrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Ps2KeybdIsrThread, this, 0, NULL);

	//	Since we don't need the handle, close it now.
	CloseHandle(hthrd);
	return TRUE;
}






BOOL
Ps2Keybd::
Initialize(
	Ps2Port	*pp2p
	)
{
	BOOL	bRet = FALSE;

	m_pp2p = pp2p;
	if ( !m_pp2p -> KeyboardInterfaceTest() )
		{
		ASSERT(0);
		goto leave;
		}

	v_pp2k -> m_pp2p -> KeyboardLights(0);

	return bRet = TRUE;

leave:
	return bRet;
}


⌨️ 快捷键说明

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