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

📄 ps2keybd.cpp

📁 三星2410的BSP开发包
💻 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.

*/

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

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

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

#include "keybddbg.h"


// 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;

extern void Read_SysIntr( LPCWSTR szKeyName, LPDWORD pdwSysIntr );

void
WINAPI
KeybdPdd_PowerHandler(
	BOOL	bOff
	)
{
	extern DWORD gdwIoBase;
	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.
			if(gdwIoBase != 0) {
				do
				{
					ucKbdData = READ_PORT_UCHAR((PUCHAR)(gdwIoBase + 0x00));
				} while ( !(ucKbdData & scKeyUpMask) );
			}

			KeyStateFlags = 0;
			
			if(gdwIoBase != 0) {
				ucKbdStatus = READ_PORT_UCHAR((PUCHAR)(gdwIoBase + 0x04));
				while ( (ucKbdStatus & 0x21) == 0x01 )
				{
					ucKbdData = READ_PORT_UCHAR((PUCHAR)(gdwIoBase + 0x00));
					ucKbdStatus = READ_PORT_UCHAR((PUCHAR)(gdwIoBase + 0x04));
				}
			}
		}
	}
	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);

	DEBUGMSG(ZONE_SCANCODES, 
	    (_T("%s: scan code 0x%08x, code in progress 0x%08x, previous 0x%08x\r\n"),
	    _T(__FILE__), ui8ScanCode, scInProgress, scPrevious));

	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
	)
{
	DWORD dwTransferred = 0;
       HKEY hk;
       DWORD dwStatus, dwSize, dwValue, dwType;
       int iPriority = 145;
       
       // look for our priority in the registry
       dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\KEYBD"), 0, 0, &hk);
       if(dwStatus == ERROR_SUCCESS) {
           // get interrupt thread priority
           dwSize = sizeof(dwValue);
           dwStatus = RegQueryValueEx(hk, _T("Priority256"), NULL, &dwType, (LPBYTE) &dwValue, &dwSize);
           if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) {
               iPriority = (int) dwValue;
           }

           // read our sysintr
           dwSize = sizeof(dwValue);
           dwStatus = RegQueryValueEx(hk, _T("SysIntr"), NULL, &dwType, (LPBYTE) &dwValue, &dwSize);
           if(dwStatus == ERROR_SUCCESS) {
            if(dwType == REG_DWORD) {
                dwSysIntr_Keybd = dwValue;
            } else {
            dwStatus = ERROR_INVALID_PARAMETER;
            }
           }
           RegCloseKey(hk);
       }

       if(dwStatus != ERROR_SUCCESS) {
        goto leave;
       }

	// set the thread priority
	CeSetThreadPriority(GetCurrentThread(), iPriority);

	m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
	if ( m_hevInterrupt == NULL)
		{
		goto leave;
		}

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

	// Ask the OAL to enable our interrupt to wake the system from suspend.
	KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &dwSysIntr_Keybd, sizeof(dwSysIntr_Keybd), NULL, 0, &dwTransferred);

	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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -