UEFI开发学习5 – 获取键盘输入

简述

UEFI中提供了两个Protocol可用于获取键盘输入,分别是EFI_SIMPLE_TEXT_INPUT_PROTOCOLEFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL,后者功能更加强大,但使用方法都差不多,这里说的是后者。

定义

typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL{
EFI_INPUT_RESET_EX Reset;
EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx;
EFI_EVENT WaitForKeyEx;
EFI_SET_STATE SetState;
EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify;
EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify;
} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;

参数:

Reset 用于复位输入设备
ReadKeyStrokeEx 读取输入的字符,每次只能读取一个
WaitForKeyEx 需要配合WaitForEvent() 函数使用,用于等待字符的输入
SetState 设置按键的切换状态,如是否启用NumLock、CapsLock等
RegisterKeyNotify 注册按键通知事件
UnregisterKeyNotify 取消注册按键通知事件

实例

1.获取从键盘输入的字符串

#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>

#define UNICODE_CHAR_ENTER 0x0D

int main(
IN int Argc,
IN char **Argv
)
{
EFI_STATUS Status;
UINTN EventIndex;
EFI_KEY_DATA Key;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *InputEx;
CHAR16 StrBuf[100] = {0};
UINTN StrLen = 0;

Status = gBS->LocateProtocol(&gEfiSimpleTextInputExProtocolGuid , NULL, (VOID **) &InputEx);

if (EFI_ERROR(Status))
{
Print(L"Unsupported.\n\r");
return EFI_UNSUPPORTED;
}

while(1)
{
/* Wait for enter a char */
Status = gBS->WaitForEvent(1, &InputEx->WaitForKeyEx, &EventIndex);
if (EFI_ERROR(Status)){
Print(L"Unsupported.\n\r");
return EFI_UNSUPPORTED;
}
/* Read a char */
Status = InputEx->ReadKeyStrokeEx(InputEx, &Key);
if (EFI_ERROR(Status))
{
Print(L"Unsupported.\n\r");
return EFI_UNSUPPORTED;
}
/* End loop when read a 'enter' */
if(Key.Key.UnicodeChar == UNICODE_CHAR_ENTER)
{
Print(L"\n\r");
break;
}
/* Store char */
StrBuf[StrLen++] = Key.Key.UnicodeChar;
/* Show input */
Print(L"%c", Key.Key.UnicodeChar);
}
/* Print the string input */
Print(L"Input string: %s\n\r", StrBuf);
}

运行结果:

NOTE:这段程序会获取所有的键盘输入,包括方向键等,实际应用还需要做一些判断,排除些字符。

2.注册一个按键输入

#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>

#define SCANCODE_DELETE 0x08

BOOLEAN IsEnterNotify = FALSE;

EFI_STATUS
EFIAPI
KeyNotifyFunction(IN EFI_KEY_DATA *KeyData)
{
Print(L"Welcome to come to key notify function.\n\r");
IsEnterNotify = TRUE;

return EFI_SUCCESS;
}

int main(
IN int Argc,
IN char **Argv
)
{
EFI_STATUS Status;
EFI_KEY_DATA Key;
EFI_HANDLE NotifyHandle;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *InputEx;
UINTN s;

Status = gBS->LocateProtocol(&gEfiSimpleTextInputExProtocolGuid , NULL, (VOID **) &InputEx);

if (EFI_ERROR(Status))
{
Print(L"Unsupported.\n\r");
return EFI_UNSUPPORTED;
}

Key.KeyState.KeyToggleState = 0;
Key.Key.ScanCode = 0;
Key.KeyState.KeyShiftState = 0;
Key.Key.ScanCode = SCANCODE_DELETE;

Status = InputEx->RegisterKeyNotify(InputEx, &Key, KeyNotifyFunction, &NotifyHandle);

for (s = 0; s < 5; s++)
{
gBS->Stall(1000 * 1000);
if (IsEnterNotify) break;
Print(L"Press [Delete] to enter notify function %d\n\r", 5 - s);
}
Status = InputEx->UnregisterKeyNotify(InputEx, NotifyHandle);
Print(L"Program Exit\n\r");
}

运行结果:

 

版权声明:
作者:bin
链接:https://ay123.net/mystudy/uefi/792/
来源:爱影博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
海报
UEFI开发学习5 – 获取键盘输入
简述 UEFI中提供了两个Protocol可用于获取键盘输入,分别是EFI_SIMPLE_TEXT_INPUT_PROTOCOL和EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL,后者功能更加强大,但使用方……
<<上一篇
下一篇>>