|
|
#include <efi.h>
#include <efilib.h>
typedef CHAR16* PWSTR; typedef const PWSTR PCWSTR;
EFI_STATUS GetInputKey( EFI_INPUT_KEY* pKey); void DisplayKey(EFI_INPUT_KEY* pKey);
// This string is used to check when the user has pressed "q" followed
// by "u" followed by "i" followed by "t". This is the method to quit
// the application and return to the EFI prompt.
const PWSTR pszExitString = L"quit";
// Constants to use when displaying what key was pressed.
// Note that this array is indexed by EFI scan code, and includes
// all keystrokes enumerated in the EFI v1.02 specification document.
PCWSTR pszKeyStrings[] = { L"NULL scan code", // 0x00
L"Move cursor up 1 row", // 0x01
L"Move cursor down 1 row", // 0x02
L"Move cursor right 1 column", // 0x03
L"Move cursor left 1 column", // 0x04
L"Home", // 0x05
L"End", // 0x06
L"Insert", // 0x07
L"Delete", // 0x08
L"Page Up", // 0x09
L"Page Down", // 0x0a
L"Function 1", // 0x0b
L"Function 2", // 0x0c
L"Function 3", // 0x0d
L"Function 4", // 0x0e
L"Function 5", // 0x0f
L"Function 6", // 0x10
L"Function 7", // 0x11
L"Function 8", // 0x12
L"Function 9", // 0x13
L"Function 10", // 0x14
L"INVALID scan code", // 0x15
L"INVALID scan code", // 0x16
L"Escape", // 0x17
};
// This is the main routine. After initializing the SDX library, we will
// wait in a loop for keys to be pressed, and then we will display what
// those keys are. I have made an effort to make the output as useful as
// possible.
EFI_STATUS EfiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { EFI_INPUT_KEY Key; EFI_STATUS Status; PWSTR pszExitCounter = pszExitString;
// Initialize the EFI SDX libraries
InitializeLib( ImageHandle, SystemTable );
// Echo some message to the user, as the initialization takes
// some time. At least the user will know when he can start
// pressing keys.
Print(L"EFI Keystroke Echo Utility.\n"); Print(L"Type \"quit\" to quit.\n");
// We will continue until the user has pressed quit. Note that each
// successive correct key will cause pszExitCounter to be incremented,
// and this will cause it to eventually point at the NULL character that
// is terminating pszExitString.
while (*pszExitCounter!=L'\0') { // Get a keystroke
Status = GetInputKey( &Key);
if (EFI_ERROR(Status)) { Print(L"Error in ReadKeyStroke (0x%08x).\n", Status); break; }
// Display the keystroke
DisplayKey(&Key);
// Check if this is the next key in the quit sequence
if (Key.UnicodeChar==*pszExitCounter) { // If it is, then look for the next one.
pszExitCounter++; } else { // Else start at the beginning.
pszExitCounter = pszExitString; } }
// We are quitting, so tell the user.
Print(L"We are done.\n");
// If you return the status, EFI will kindly give the user an English
// error message.
return Status; }
EFI_STATUS GetInputKey( OUT EFI_INPUT_KEY* pKey) { EFI_STATUS Status; // Wait until a keystroke is available
WaitForSingleEvent( ST->ConIn->WaitForKey, 0);
// Read the key that has been pressed
Status = ST->ConIn->ReadKeyStroke( ST->ConIn, pKey);
// Return the status, whether success or failure
return Status; }
void DisplayKey(EFI_INPUT_KEY* pKey) { // Firstly, let's display the raw keystroke
Print(L"0x%04x 0x%04x - ", pKey->ScanCode, pKey->UnicodeChar);
// Let's check if this is a Unicode only key (some character)
if (pKey->ScanCode==0) { // Is this a printable character
if (pKey->UnicodeChar>=33 && pKey->UnicodeChar<=127) { // If so, print the character
Print(L"\"%c\"", pKey->UnicodeChar); } else { // Else print it's numerical value
Print(L"(CHAR16)0x%04x", pKey->UnicodeChar); } } // Check to ensure that this scancode is in the range that we have
// a string constant for ...
else if (pKey->ScanCode>=0 && pKey->ScanCode<=0x17) { // Display the string constant for our keystroke
Print(L"%s", pszKeyStrings[pKey->ScanCode]); } else { // We know nothing about this keystroke, so say so.
Print(L"INVALID scan code", pszKeyStrings[pKey->ScanCode]); }
Print(L"\n"); }
|