Update to support EFI_SIMPLE_INPUT_EX protocol

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4178 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qhuang8
2007-10-19 02:35:29 +00:00
parent 1b249b5744
commit 66aa04e4e3
11 changed files with 2386 additions and 92 deletions

View File

@@ -43,6 +43,21 @@ STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = {
0,
(EFI_SIMPLE_TEXT_INPUT_PROTOCOL **) NULL,
0,
{
ConSplitterTextInResetEx,
ConSplitterTextInReadKeyStrokeEx,
(EFI_EVENT) NULL,
ConSplitterTextInSetState,
ConSplitterTextInRegisterKeyNotify,
ConSplitterTextInUnregisterKeyNotify
},
0,
(EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **) NULL,
0,
{
(struct _LIST_ENTRY *) NULL,
(struct _LIST_ENTRY *) NULL
},
{
ConSplitterSimplePointerReset,
@@ -367,6 +382,8 @@ Returns:
&mConIn.VirtualHandle,
&gEfiSimpleTextInProtocolGuid,
&mConIn.TextIn,
&gEfiSimpleTextInputExProtocolGuid,
&mConIn.TextInEx,
&gEfiSimplePointerProtocolGuid,
&mConIn.SimplePointer,
&gEfiPrimaryConsoleInDeviceGuid,
@@ -514,6 +531,30 @@ Returns:
);
ASSERT_EFI_ERROR (Status);
//
// Buffer for Simple Text Input Ex Protocol
//
Status = ConSplitterGrowBuffer (
sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),
&ConInPrivate->TextInExListCount,
(VOID **) &ConInPrivate->TextInExList
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
Status = gBS->CreateEvent (
EVT_NOTIFY_WAIT,
TPL_NOTIFY,
ConSplitterTextInWaitForKey,
ConInPrivate,
&ConInPrivate->TextInEx.WaitForKeyEx
);
ASSERT_EFI_ERROR (Status);
InitializeListHead (&ConInPrivate->NotifyList);
ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;
Status = ConSplitterGrowBuffer (
@@ -898,6 +939,7 @@ Returns:
{
EFI_STATUS Status;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;
//
// Start ConSplitter on ControllerHandle, and create the virtual
@@ -915,6 +957,23 @@ Returns:
return Status;
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimpleTextInputExProtocolGuid,
(VOID **) &TextInEx,
This->DriverBindingHandle,
mConIn.VirtualHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = ConSplitterTextInExAddDevice (&mConIn, TextInEx);
if (EFI_ERROR (Status)) {
return Status;
}
return ConSplitterTextInAddDevice (&mConIn, TextIn);
}
@@ -1195,10 +1254,29 @@ Returns:
EFI_STATUS Status;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;
if (NumberOfChildren == 0) {
return EFI_SUCCESS;
}
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimpleTextInputExProtocolGuid,
(VOID **) &TextInEx,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = ConSplitterTextInExDeleteDevice (&mConIn, TextInEx);
if (EFI_ERROR (Status)) {
return Status;
}
Status = ConSplitterStop (
This,
ControllerHandle,
@@ -1512,6 +1590,66 @@ Returns:
return EFI_NOT_FOUND;
}
EFI_STATUS
ConSplitterTextInExAddDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx
)
{
EFI_STATUS Status;
//
// If the TextInEx List is full, enlarge it by calling growbuffer().
//
if (Private->CurrentNumberOfExConsoles >= Private->TextInExListCount) {
Status = ConSplitterGrowBuffer (
sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),
&Private->TextInExListCount,
(VOID **) &Private->TextInExList
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
}
//
// Add the new text-in device data structure into the Text In List.
//
Private->TextInExList[Private->CurrentNumberOfExConsoles] = TextInEx;
Private->CurrentNumberOfExConsoles++;
//
// Extra CheckEvent added to reduce the double CheckEvent() in UI.c
//
gBS->CheckEvent (TextInEx->WaitForKeyEx);
return EFI_SUCCESS;
}
EFI_STATUS
ConSplitterTextInExDeleteDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx
)
{
UINTN Index;
//
// Remove the specified text-in device data structure from the Text In List,
// and rearrange the remaining data structures in the Text In List.
//
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
if (Private->TextInExList[Index] == TextInEx) {
for (Index = Index; Index < Private->CurrentNumberOfExConsoles - 1; Index++) {
Private->TextInExList[Index] = Private->TextInExList[Index + 1];
}
Private->CurrentNumberOfExConsoles--;
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
ConSplitterSimplePointerAddDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
@@ -2760,6 +2898,433 @@ Returns:
}
}
STATIC
BOOLEAN
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
)
/*++
Routine Description:
Arguments:
RegsiteredData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was registered.
InputData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
Returns:
TRUE - Key be pressed matches a registered key.
FLASE - Match failed.
--*/
{
ASSERT (RegsiteredData != NULL && InputData != NULL);
if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
(RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
return FALSE;
}
//
// Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
//
if (RegsiteredData->KeyState.KeyShiftState != 0 &&
RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
return FALSE;
}
if (RegsiteredData->KeyState.KeyToggleState != 0 &&
RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
return FALSE;
}
return TRUE;
}
//
// Simple Text Input Ex protocol functions
//
EFI_STATUS
EFIAPI
ConSplitterTextInResetEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Reset the input device and optionaly run diagnostics
Arguments:
This - Protocol instance pointer.
ExtendedVerification - Driver may perform diagnostics on reset.
Returns:
EFI_SUCCESS - The device was reset.
EFI_DEVICE_ERROR - The device is not functioning properly and could
not be reset.
--*/
{
EFI_STATUS Status;
EFI_STATUS ReturnStatus;
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
UINTN Index;
Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
Private->KeyEventSignalState = FALSE;
//
// return the worst status met
//
for (Index = 0, ReturnStatus = EFI_SUCCESS; Index < Private->CurrentNumberOfExConsoles; Index++) {
Status = Private->TextInExList[Index]->Reset (
Private->TextInExList[Index],
ExtendedVerification
);
if (EFI_ERROR (Status)) {
ReturnStatus = Status;
}
}
return ReturnStatus;
}
EFI_STATUS
EFIAPI
ConSplitterTextInReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
)
/*++
Routine Description:
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
Arguments:
This - Protocol instance pointer.
KeyData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
Returns:
EFI_SUCCESS - The keystroke information was returned.
EFI_NOT_READY - There was no keystroke data availiable.
EFI_DEVICE_ERROR - The keystroke information was not returned due to
hardware errors.
EFI_INVALID_PARAMETER - KeyData is NULL.
--*/
{
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
EFI_STATUS Status;
UINTN Index;
EFI_KEY_DATA CurrentKeyData;
if (KeyData == NULL) {
return EFI_INVALID_PARAMETER;
}
Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
if (Private->PasswordEnabled) {
//
// If StdIn Locked return not ready
//
return EFI_NOT_READY;
}
Private->KeyEventSignalState = FALSE;
KeyData->Key.UnicodeChar = 0;
KeyData->Key.ScanCode = SCAN_NULL;
//
// if no physical console input device exists, return EFI_NOT_READY;
// if any physical console input device has key input,
// return the key and EFI_SUCCESS.
//
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
Private->TextInExList[Index],
&CurrentKeyData
);
if (!EFI_ERROR (Status)) {
CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));
return Status;
}
}
return EFI_NOT_READY;
}
EFI_STATUS
EFIAPI
ConSplitterTextInSetState (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
)
/*++
Routine Description:
Set certain state for the input device.
Arguments:
This - Protocol instance pointer.
KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
state for the input device.
Returns:
EFI_SUCCESS - The device state was set successfully.
EFI_DEVICE_ERROR - The device is not functioning correctly and could
not have the setting adjusted.
EFI_UNSUPPORTED - The device does not have the ability to set its state.
EFI_INVALID_PARAMETER - KeyToggleState is NULL.
--*/
{
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
EFI_STATUS Status;
UINTN Index;
if (KeyToggleState == NULL) {
return EFI_INVALID_PARAMETER;
}
Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
//
// if no physical console input device exists, return EFI_SUCCESS;
// otherwise return the status of setting state of physical console input device
//
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
Status = Private->TextInExList[Index]->SetState (
Private->TextInExList[Index],
KeyToggleState
);
if (EFI_ERROR (Status)) {
return Status;
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ConSplitterTextInRegisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT EFI_HANDLE *NotifyHandle
)
/*++
Routine Description:
Register a notification function for a particular keystroke for the input device.
Arguments:
This - Protocol instance pointer.
KeyData - A pointer to a buffer that is filled in with the keystroke
information data for the key that was pressed.
KeyNotificationFunction - Points to the function to be called when the key
sequence is typed specified by KeyData.
NotifyHandle - Points to the unique handle assigned to the registered notification.
Returns:
EFI_SUCCESS - The notification function was registered successfully.
EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
--*/
{
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
EFI_STATUS Status;
UINTN Index;
TEXT_IN_EX_SPLITTER_NOTIFY *NewNotify;
LIST_ENTRY *Link;
TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;
if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
return EFI_INVALID_PARAMETER;
}
Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
//
// if no physical console input device exists,
// return EFI_SUCCESS directly.
//
if (Private->CurrentNumberOfExConsoles <= 0) {
return EFI_SUCCESS;
}
//
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
//
for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (
Link,
TEXT_IN_EX_SPLITTER_NOTIFY,
NotifyEntry,
TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
*NotifyHandle = CurrentNotify->NotifyHandle;
return EFI_SUCCESS;
}
}
}
//
// Allocate resource to save the notification function
//
NewNotify = (TEXT_IN_EX_SPLITTER_NOTIFY *) AllocateZeroPool (sizeof (TEXT_IN_EX_SPLITTER_NOTIFY));
if (NewNotify == NULL) {
return EFI_OUT_OF_RESOURCES;
}
NewNotify->NotifyHandleList = (EFI_HANDLE *) AllocateZeroPool (sizeof (EFI_HANDLE) * Private->CurrentNumberOfExConsoles);
if (NewNotify->NotifyHandleList == NULL) {
gBS->FreePool (NewNotify);
return EFI_OUT_OF_RESOURCES;
}
NewNotify->Signature = TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE;
NewNotify->KeyNotificationFn = KeyNotificationFunction;
CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
//
// Return the wrong status of registering key notify of
// physical console input device if meet problems
//
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
Status = Private->TextInExList[Index]->RegisterKeyNotify (
Private->TextInExList[Index],
KeyData,
KeyNotificationFunction,
&NewNotify->NotifyHandleList[Index]
);
if (EFI_ERROR (Status)) {
gBS->FreePool (NewNotify->NotifyHandleList);
gBS->FreePool (NewNotify);
return Status;
}
}
//
// Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
//
Status = gBS->InstallMultipleProtocolInterfaces (
&NewNotify->NotifyHandle,
&gSimpleTextInExNotifyGuid,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
InsertTailList (&mConIn.NotifyList, &NewNotify->NotifyEntry);
*NotifyHandle = NewNotify->NotifyHandle;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ConSplitterTextInUnregisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_HANDLE NotificationHandle
)
/*++
Routine Description:
Remove a registered notification function from a particular keystroke.
Arguments:
This - Protocol instance pointer.
NotificationHandle - The handle of the notification function being unregistered.
Returns:
EFI_SUCCESS - The notification function was unregistered successfully.
EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
EFI_NOT_FOUND - Can not find the matching entry in database.
--*/
{
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
EFI_STATUS Status;
UINTN Index;
TEXT_IN_EX_SPLITTER_NOTIFY *CurrentNotify;
LIST_ENTRY *Link;
if (NotificationHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = gBS->OpenProtocol (
NotificationHandle,
&gSimpleTextInExNotifyGuid,
NULL,
NULL,
NULL,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_INVALID_PARAMETER;
}
Private = TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
//
// if no physical console input device exists,
// return EFI_SUCCESS directly.
//
if (Private->CurrentNumberOfExConsoles <= 0) {
return EFI_SUCCESS;
}
for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (Link, TEXT_IN_EX_SPLITTER_NOTIFY, NotifyEntry, TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE);
if (CurrentNotify->NotifyHandle == NotificationHandle) {
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
Status = Private->TextInExList[Index]->UnregisterKeyNotify (
Private->TextInExList[Index],
CurrentNotify->NotifyHandleList[Index]
);
if (EFI_ERROR (Status)) {
return Status;
}
}
RemoveEntryList (&CurrentNotify->NotifyEntry);
Status = gBS->UninstallMultipleProtocolInterfaces (
CurrentNotify->NotifyHandle,
&gSimpleTextInExNotifyGuid,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
gBS->FreePool (CurrentNotify->NotifyHandleList);
gBS->FreePool (CurrentNotify);
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
EFI_STATUS
EFIAPI
ConSplitterSimplePointerReset (

View File

@@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SimpleTextOut.h>
#include <Guid/ConsoleInDevice.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/SimpleTextInEx.h>
#include <Protocol/ConsoleControl.h>
#include <Guid/StandardErrorDevice.h>
#include <Guid/ConsoleOutDevice.h>
@@ -53,6 +54,8 @@ extern EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gConSplitterStdErrComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gConSplitterStdErrComponentName2;
extern EFI_GUID gSimpleTextInExNotifyGuid;
// These definitions were in the old Hii protocol, but are not in the new UEFI
// version. So they are defined locally.
#define UNICODE_NARROW_CHAR 0xFFF0
@@ -76,6 +79,16 @@ typedef struct {
//
#define TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('T', 'i', 'S', 'p')
#define TEXT_IN_EX_SPLITTER_NOTIFY_SIGNATURE EFI_SIGNATURE_32 ('T', 'i', 'S', 'n')
typedef struct _TEXT_IN_EX_SPLITTER_NOTIFY {
UINTN Signature;
EFI_HANDLE *NotifyHandleList;
EFI_HANDLE NotifyHandle;
EFI_KEY_DATA KeyData;
EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
LIST_ENTRY NotifyEntry;
} TEXT_IN_EX_SPLITTER_NOTIFY;
typedef struct {
UINT64 Signature;
EFI_HANDLE VirtualHandle;
@@ -85,6 +98,13 @@ typedef struct {
EFI_SIMPLE_TEXT_INPUT_PROTOCOL **TextInList;
UINTN TextInListCount;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL TextInEx;
UINTN CurrentNumberOfExConsoles;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **TextInExList;
UINTN TextInExListCount;
LIST_ENTRY NotifyList;
EFI_SIMPLE_POINTER_PROTOCOL SimplePointer;
EFI_SIMPLE_POINTER_MODE SimplePointerMode;
UINTN CurrentNumberOfPointers;
@@ -114,6 +134,19 @@ typedef struct {
SimplePointer, \
TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE \
)
#define TEXT_IN_EX_SPLITTER_PRIVATE_DATA_FROM_THIS(a) \
CR (a, \
TEXT_IN_SPLITTER_PRIVATE_DATA, \
TextInEx, \
TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE \
)
#define TEXT_IN_SPLITTER_PRIVATE_DATA_FROM_ABSOLUTE_POINTER_THIS(a) \
CR (a, \
TEXT_IN_SPLITTER_PRIVATE_DATA, \
AbsolutePointer, \
TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE \
)
//
// Private data for the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL splitter
@@ -770,7 +803,151 @@ ConSplitterTextInReadKeyStroke (
OUT EFI_INPUT_KEY *Key
)
;
EFI_STATUS
ConSplitterTextInExAddDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx
)
;
EFI_STATUS
ConSplitterTextInExDeleteDevice (
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx
)
;
//
// Simple Text Input Ex protocol function prototypes
//
EFI_STATUS
EFIAPI
ConSplitterTextInResetEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Reset the input device and optionaly run diagnostics
Arguments:
This - Protocol instance pointer.
ExtendedVerification - Driver may perform diagnostics on reset.
Returns:
EFI_SUCCESS - The device was reset.
EFI_DEVICE_ERROR - The device is not functioning properly and could
not be reset.
--*/
;
EFI_STATUS
EFIAPI
ConSplitterTextInReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
)
/*++
Routine Description:
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
Arguments:
This - Protocol instance pointer.
KeyData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
Returns:
EFI_SUCCESS - The keystroke information was returned.
EFI_NOT_READY - There was no keystroke data availiable.
EFI_DEVICE_ERROR - The keystroke information was not returned due to
hardware errors.
EFI_INVALID_PARAMETER - KeyData is NULL.
--*/
;
EFI_STATUS
EFIAPI
ConSplitterTextInSetState (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
)
/*++
Routine Description:
Set certain state for the input device.
Arguments:
This - Protocol instance pointer.
KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
state for the input device.
Returns:
EFI_SUCCESS - The device state was set successfully.
EFI_DEVICE_ERROR - The device is not functioning correctly and could
not have the setting adjusted.
EFI_UNSUPPORTED - The device does not have the ability to set its state.
EFI_INVALID_PARAMETER - KeyToggleState is NULL.
--*/
;
EFI_STATUS
EFIAPI
ConSplitterTextInRegisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT EFI_HANDLE *NotifyHandle
)
/*++
Routine Description:
Register a notification function for a particular keystroke for the input device.
Arguments:
This - Protocol instance pointer.
KeyData - A pointer to a buffer that is filled in with the keystroke
information data for the key that was pressed.
KeyNotificationFunction - Points to the function to be called when the key
sequence is typed specified by KeyData.
NotifyHandle - Points to the unique handle assigned to the registered notification.
Returns:
EFI_SUCCESS - The notification function was registered successfully.
EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
--*/
;
EFI_STATUS
EFIAPI
ConSplitterTextInUnregisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_HANDLE NotificationHandle
)
/*++
Routine Description:
Remove a registered notification function from a particular keystroke.
Arguments:
This - Protocol instance pointer.
NotificationHandle - The handle of the notification function being unregistered.
Returns:
EFI_SUCCESS - The notification function was unregistered successfully.
EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
EFI_NOT_FOUND - Can not find the matching entry in database.
--*/
;
VOID
EFIAPI
ConSplitterTextInWaitForKey (
@@ -945,10 +1122,10 @@ ConSpliterConsoleControlSetMode (
EFI_STATUS
EFIAPI
ConSpliterGraphicsOutputQueryMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
)
;

View File

@@ -67,11 +67,13 @@
gEfiPrimaryConsoleOutDeviceGuid # ALWAYS_PRODUCED
gEfiPrimaryConsoleInDeviceGuid # ALWAYS_PRODUCED
gEfiPrimaryStandardErrorDeviceGuid # ALWAYS_PRODUCED
gSimpleTextInExNotifyGuid # ALWAYS_PRODUCED
[Protocols]
gEfiConsoleControlProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiSimplePointerProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiSimpleTextInProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiSimpleTextInputExProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiSimpleTextOutProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiGraphicsOutputProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiUgaDrawProtocolGuid # PROTOCOL ALWAYS_PRODUCED

View File

@@ -22,6 +22,12 @@ Revision History:
#include "Terminal.h"
STATIC
EFI_STATUS
TerminalFreeNotifyList (
IN OUT LIST_ENTRY *ListHead
);
//
// Globals
//
@@ -94,7 +100,19 @@ TERMINAL_DEV gTerminalDevTemplate = {
NULL,
INPUT_STATE_DEFAULT,
RESET_STATE_DEFAULT,
FALSE
FALSE,
{ // SimpleTextInputEx
TerminalConInResetEx,
TerminalConInReadKeyStrokeEx,
NULL,
TerminalConInSetState,
TerminalConInRegisterKeyNotify,
TerminalConInUnregisterKeyNotify,
},
{
NULL,
NULL,
}
};
@@ -381,6 +399,19 @@ TerminalDriverBindingStart (
TerminalDevice->TerminalType = TerminalType;
TerminalDevice->SerialIo = SerialIo;
InitializeListHead (&TerminalDevice->NotifyList);
Status = gBS->CreateEvent (
EVT_NOTIFY_WAIT,
TPL_NOTIFY,
TerminalConInWaitForKeyEx,
&TerminalDevice->SimpleInputEx,
&TerminalDevice->SimpleInputEx.WaitForKeyEx
);
if (EFI_ERROR (Status)) {
goto Error;
}
Status = gBS->CreateEvent (
EVT_NOTIFY_WAIT,
TPL_NOTIFY,
@@ -391,7 +422,6 @@ TerminalDriverBindingStart (
if (EFI_ERROR (Status)) {
goto Error;
}
//
// initialize the FIFO buffer used for accommodating
// the pre-read pending characters
@@ -405,6 +435,7 @@ TerminalDriverBindingStart (
// keystroke response performance issue
//
Mode = TerminalDevice->SerialIo->Mode;
SerialInTimeOut = 0;
if (Mode->BaudRate != 0) {
SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;
@@ -578,6 +609,8 @@ TerminalDriverBindingStart (
TerminalDevice->DevicePath,
&gEfiSimpleTextInProtocolGuid,
&TerminalDevice->SimpleInput,
&gEfiSimpleTextInputExProtocolGuid,
&TerminalDevice->SimpleInputEx,
&gEfiSimpleTextOutProtocolGuid,
&TerminalDevice->SimpleTextOutput,
NULL
@@ -655,6 +688,12 @@ Error:
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
}
if (TerminalDevice->SimpleInputEx.WaitForKeyEx != NULL) {
gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);
}
TerminalFreeNotifyList (&TerminalDevice->NotifyList);
if (TerminalDevice->ControllerNameTable != NULL) {
FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
}
@@ -809,6 +848,8 @@ TerminalDriverBindingStop (
ChildHandleBuffer[Index],
&gEfiSimpleTextInProtocolGuid,
&TerminalDevice->SimpleInput,
&gEfiSimpleTextInputExProtocolGuid,
&TerminalDevice->SimpleInputEx,
&gEfiSimpleTextOutProtocolGuid,
&TerminalDevice->SimpleTextOutput,
&gEfiDevicePathProtocolGuid,
@@ -851,6 +892,8 @@ TerminalDriverBindingStop (
gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);
TerminalFreeNotifyList (&TerminalDevice->NotifyList);
FreePool (TerminalDevice->DevicePath);
FreePool (TerminalDevice);
}
@@ -868,6 +911,47 @@ TerminalDriverBindingStop (
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
TerminalFreeNotifyList (
IN OUT LIST_ENTRY *ListHead
)
/*++
Routine Description:
Arguments:
ListHead - The list head
Returns:
EFI_SUCCESS - Free the notify list successfully
EFI_INVALID_PARAMETER - ListHead is invalid.
--*/
{
TERMINAL_CONSOLE_IN_EX_NOTIFY *NotifyNode;
if (ListHead == NULL) {
return EFI_INVALID_PARAMETER;
}
while (!IsListEmpty (ListHead)) {
NotifyNode = CR (
ListHead->ForwardLink,
TERMINAL_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
RemoveEntryList (ListHead->ForwardLink);
gBS->FreePool (NotifyNode);
}
return EFI_SUCCESS;
}
VOID
TerminalUpdateConsoleDevVariable (
IN CHAR16 *VariableName,

View File

@@ -30,6 +30,7 @@ Revision History
#include <Guid/GlobalVariable.h>
#include <Protocol/DevicePath.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/SimpleTextInEx.h>
#include <Guid/HotPlugDevice.h>
#include <Guid/PcAnsi.h>
#include <Library/DebugLib.h>
@@ -42,7 +43,7 @@ Revision History
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseLib.h>
#define RAW_FIFO_MAX_NUMBER 256
@@ -68,6 +69,15 @@ typedef struct {
#define TERMINAL_DEV_SIGNATURE EFI_SIGNATURE_32 ('t', 'm', 'n', 'l')
#define TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE EFI_SIGNATURE_32 ('t', 'm', 'e', 'n')
typedef struct _TERMINAL_CONSOLE_IN_EX_NOTIFY {
UINTN Signature;
EFI_HANDLE NotifyHandle;
EFI_KEY_DATA KeyData;
EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
LIST_ENTRY NotifyEntry;
} TERMINAL_CONSOLE_IN_EX_NOTIFY;
typedef struct {
UINTN Signature;
EFI_HANDLE Handle;
@@ -94,6 +104,8 @@ typedef struct {
// to indicate whether the Esc could be sent or not.
//
BOOLEAN OutputEscChar;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleInputEx;
LIST_ENTRY NotifyList;
} TERMINAL_DEV;
#define INPUT_STATE_DEFAULT 0x00
@@ -109,6 +121,7 @@ typedef struct {
#define TERMINAL_CON_IN_DEV_FROM_THIS(a) CR (a, TERMINAL_DEV, SimpleInput, TERMINAL_DEV_SIGNATURE)
#define TERMINAL_CON_OUT_DEV_FROM_THIS(a) CR (a, TERMINAL_DEV, SimpleTextOutput, TERMINAL_DEV_SIGNATURE)
#define TERMINAL_CON_IN_EX_DEV_FROM_THIS(a) CR (a, TERMINAL_DEV, SimpleInputEx, TERMINAL_DEV_SIGNATURE)
typedef union {
UINT8 Utf8_1;
@@ -153,6 +166,7 @@ extern EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL gTerminalComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gTerminalComponentName2;
extern EFI_GUID gSimpleTextInExNotifyGuid;
//
// Prototypes
//
@@ -180,6 +194,169 @@ TerminalConInReadKeyStroke (
)
;
BOOLEAN
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
)
/*++
Routine Description:
Arguments:
RegsiteredData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was registered.
InputData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
Returns:
TRUE - Key be pressed matches a registered key.
FLASE - Match failed.
--*/
;
VOID
EFIAPI
TerminalConInWaitForKeyEx (
IN EFI_EVENT Event,
IN VOID *Context
)
;
//
// Simple Text Input Ex protocol prototypes
//
EFI_STATUS
EFIAPI
TerminalConInResetEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Reset the input device and optionaly run diagnostics
Arguments:
This - Protocol instance pointer.
ExtendedVerification - Driver may perform diagnostics on reset.
Returns:
EFI_SUCCESS - The device was reset.
EFI_DEVICE_ERROR - The device is not functioning properly and could
not be reset.
--*/
;
EFI_STATUS
EFIAPI
TerminalConInReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
)
/*++
Routine Description:
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
Arguments:
This - Protocol instance pointer.
KeyData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
Returns:
EFI_SUCCESS - The keystroke information was returned.
EFI_NOT_READY - There was no keystroke data availiable.
EFI_DEVICE_ERROR - The keystroke information was not returned due to
hardware errors.
EFI_INVALID_PARAMETER - KeyData is NULL.
--*/
;
EFI_STATUS
EFIAPI
TerminalConInSetState (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
)
/*++
Routine Description:
Set certain state for the input device.
Arguments:
This - Protocol instance pointer.
KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
state for the input device.
Returns:
EFI_SUCCESS - The device state was set successfully.
EFI_DEVICE_ERROR - The device is not functioning correctly and could
not have the setting adjusted.
EFI_UNSUPPORTED - The device does not have the ability to set its state.
EFI_INVALID_PARAMETER - KeyToggleState is NULL.
--*/
;
EFI_STATUS
EFIAPI
TerminalConInRegisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT EFI_HANDLE *NotifyHandle
)
/*++
Routine Description:
Register a notification function for a particular keystroke for the input device.
Arguments:
This - Protocol instance pointer.
KeyData - A pointer to a buffer that is filled in with the keystroke
information data for the key that was pressed.
KeyNotificationFunction - Points to the function to be called when the key
sequence is typed specified by KeyData.
NotifyHandle - Points to the unique handle assigned to the registered notification.
Returns:
EFI_SUCCESS - The notification function was registered successfully.
EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
--*/
;
EFI_STATUS
EFIAPI
TerminalConInUnregisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_HANDLE NotificationHandle
)
/*++
Routine Description:
Remove a registered notification function from a particular keystroke.
Arguments:
This - Protocol instance pointer.
NotificationHandle - The handle of the notification function being unregistered.
Returns:
EFI_SUCCESS - The notification function was unregistered successfully.
EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
EFI_NOT_FOUND - Can not find the matching entry in database.
--*/
;
VOID
EFIAPI
TerminalConInWaitForKey (

View File

@@ -1,6 +1,6 @@
/**@file
Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.
Implementation for EFI_SIMPLE_TEXT_INPUT_PROTOCOL protocol.
Copyright (c) 2006 - 2007 Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -15,6 +15,78 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Terminal.h"
STATIC
EFI_STATUS
ReadKeyStrokeWorker (
IN TERMINAL_DEV *TerminalDevice,
OUT EFI_KEY_DATA *KeyData
)
/*++
Routine Description:
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
Arguments:
TerminalDevice - Terminal driver private structure
KeyData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
Returns:
EFI_SUCCESS - The keystroke information was returned.
EFI_NOT_READY - There was no keystroke data availiable.
EFI_DEVICE_ERROR - The keystroke information was not returned due to
hardware errors.
EFI_INVALID_PARAMETER - KeyData is NULL.
--*/
{
EFI_STATUS Status;
LIST_ENTRY *Link;
TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
if (KeyData == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Initialize *Key to nonsense value.
//
KeyData->Key.ScanCode = SCAN_NULL;
KeyData->Key.UnicodeChar = 0;
Status = TerminalConInCheckForKey (&TerminalDevice->SimpleInput);
if (EFI_ERROR (Status)) {
return EFI_NOT_READY;
}
if (!EfiKeyFiFoRemoveOneKey (TerminalDevice, &KeyData->Key)) {
return EFI_NOT_READY;
}
KeyData->KeyState.KeyShiftState = 0;
KeyData->KeyState.KeyToggleState = 0;
//
// Invoke notification functions if exist
//
for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (
Link,
TERMINAL_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
CurrentNotify->KeyNotificationFn (KeyData);
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
TerminalConInReset (
@@ -111,28 +183,358 @@ TerminalConInReadKeyStroke (
{
TERMINAL_DEV *TerminalDevice;
EFI_STATUS Status;
EFI_KEY_DATA KeyData;
//
// Initialize *Key to nonsense value.
//
Key->ScanCode = SCAN_NULL;
Key->UnicodeChar = 0;
//
// get TERMINAL_DEV from "This" parameter.
//
TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);
Status = TerminalConInCheckForKey (This);
Status = ReadKeyStrokeWorker (TerminalDevice, &KeyData);
if (EFI_ERROR (Status)) {
return EFI_NOT_READY;
return Status;
}
EfiKeyFiFoRemoveOneKey (TerminalDevice, Key);
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
return EFI_SUCCESS;
}
BOOLEAN
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
)
/*++
Routine Description:
Arguments:
RegsiteredData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was registered.
InputData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
Returns:
TRUE - Key be pressed matches a registered key.
FLASE - Match failed.
--*/
{
ASSERT (RegsiteredData != NULL && InputData != NULL);
if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
(RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
return FALSE;
}
return TRUE;
}
VOID
EFIAPI
TerminalConInWaitForKeyEx (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
Event notification function for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
Signal the event if there is key available
Arguments:
Event - Indicates the event that invoke this function.
Context - Indicates the calling context.
Returns:
N/A
--*/
{
TERMINAL_DEV *TerminalDevice;
TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (Context);
TerminalConInWaitForKey (Event, &TerminalDevice->SimpleInput);
}
//
// Simple Text Input Ex protocol functions
//
EFI_STATUS
EFIAPI
TerminalConInResetEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
Reset the input device and optionaly run diagnostics
Arguments:
This - Protocol instance pointer.
ExtendedVerification - Driver may perform diagnostics on reset.
Returns:
EFI_SUCCESS - The device was reset.
EFI_DEVICE_ERROR - The device is not functioning properly and could
not be reset.
--*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
Status = TerminalDevice->SimpleInput.Reset (&TerminalDevice->SimpleInput, ExtendedVerification);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
TerminalConInReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
)
/*++
Routine Description:
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
Arguments:
This - Protocol instance pointer.
KeyData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
Returns:
EFI_SUCCESS - The keystroke information was returned.
EFI_NOT_READY - There was no keystroke data availiable.
EFI_DEVICE_ERROR - The keystroke information was not returned due to
hardware errors.
EFI_INVALID_PARAMETER - KeyData is NULL.
--*/
{
TERMINAL_DEV *TerminalDevice;
if (KeyData == NULL) {
return EFI_INVALID_PARAMETER;
}
TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
return ReadKeyStrokeWorker (TerminalDevice, KeyData);
}
EFI_STATUS
EFIAPI
TerminalConInSetState (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
)
/*++
Routine Description:
Set certain state for the input device.
Arguments:
This - Protocol instance pointer.
KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
state for the input device.
Returns:
EFI_SUCCESS - The device state was set successfully.
EFI_DEVICE_ERROR - The device is not functioning correctly and could
not have the setting adjusted.
EFI_UNSUPPORTED - The device does not have the ability to set its state.
EFI_INVALID_PARAMETER - KeyToggleState is NULL.
--*/
{
if (KeyToggleState == NULL) {
return EFI_INVALID_PARAMETER;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
TerminalConInRegisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT EFI_HANDLE *NotifyHandle
)
/*++
Routine Description:
Register a notification function for a particular keystroke for the input device.
Arguments:
This - Protocol instance pointer.
KeyData - A pointer to a buffer that is filled in with the keystroke
information data for the key that was pressed.
KeyNotificationFunction - Points to the function to be called when the key
sequence is typed specified by KeyData.
NotifyHandle - Points to the unique handle assigned to the registered notification.
Returns:
EFI_SUCCESS - The notification function was registered successfully.
EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
--*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
TERMINAL_CONSOLE_IN_EX_NOTIFY *NewNotify;
LIST_ENTRY *Link;
TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
return EFI_INVALID_PARAMETER;
}
TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
//
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
//
for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (
Link,
TERMINAL_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
*NotifyHandle = CurrentNotify->NotifyHandle;
return EFI_SUCCESS;
}
}
}
//
// Allocate resource to save the notification function
//
NewNotify = (TERMINAL_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (TERMINAL_CONSOLE_IN_EX_NOTIFY));
if (NewNotify == NULL) {
return EFI_OUT_OF_RESOURCES;
}
NewNotify->Signature = TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
NewNotify->KeyNotificationFn = KeyNotificationFunction;
CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
InsertTailList (&TerminalDevice->NotifyList, &NewNotify->NotifyEntry);
//
// Use gSimpleTextInExNotifyGuid to get a valid EFI_HANDLE
//
Status = gBS->InstallMultipleProtocolInterfaces (
&NewNotify->NotifyHandle,
&gSimpleTextInExNotifyGuid,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
*NotifyHandle = NewNotify->NotifyHandle;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
TerminalConInUnregisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_HANDLE NotificationHandle
)
/*++
Routine Description:
Remove a registered notification function from a particular keystroke.
Arguments:
This - Protocol instance pointer.
NotificationHandle - The handle of the notification function being unregistered.
Returns:
EFI_SUCCESS - The notification function was unregistered successfully.
EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
EFI_NOT_FOUND - Can not find the matching entry in database.
--*/
{
EFI_STATUS Status;
TERMINAL_DEV *TerminalDevice;
LIST_ENTRY *Link;
TERMINAL_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
if (NotificationHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
Status = gBS->OpenProtocol (
NotificationHandle,
&gSimpleTextInExNotifyGuid,
NULL,
NULL,
NULL,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_INVALID_PARAMETER;
}
TerminalDevice = TERMINAL_CON_IN_EX_DEV_FROM_THIS (This);
for (Link = TerminalDevice->NotifyList.ForwardLink; Link != &TerminalDevice->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (
Link,
TERMINAL_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (CurrentNotify->NotifyHandle == NotificationHandle) {
//
// Remove the notification function from NotifyList and free resources
//
RemoveEntryList (&CurrentNotify->NotifyEntry);
Status = gBS->UninstallMultipleProtocolInterfaces (
CurrentNotify->NotifyHandle,
&gSimpleTextInExNotifyGuid,
NULL,
NULL
);
ASSERT_EFI_ERROR (Status);
gBS->FreePool (CurrentNotify);
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
VOID
TranslateRawDataToEfiKey (
IN TERMINAL_DEV *TerminalDevice
@@ -787,7 +1189,9 @@ Symbols used in table below
| F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |
| F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |
| Escape | 0x17 | ESC | ESC | ESC |
+=========+======+===========+==========+=========+
| F11 | 0x15 | | ESC ! | |
| F12 | 0x16 | | ESC @ | |
+=========+======+===========+==========+==========+
Special Mappings
================
@@ -882,6 +1286,12 @@ ESC R ESC r ESC R = Reset System
case '0':
Key.ScanCode = SCAN_F10;
break;
case '!':
Key.ScanCode = SCAN_F11;
break;
case '@':
Key.ScanCode = SCAN_F12;
break;
case 'h':
Key.ScanCode = SCAN_HOME;
break;
@@ -1150,6 +1560,10 @@ ESC R ESC r ESC R = Reset System
if (UnicodeChar == ESC) {
TerminalDevice->InputState = INPUT_STATE_ESC;
}
if (UnicodeChar == CSI) {
TerminalDevice->InputState = INPUT_STATE_CSI;
}
if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {
Status = gBS->SetTimer(

View File

@@ -58,6 +58,7 @@
UefiDriverEntryPoint
DebugLib
PcdLib
BaseLib
[Guids]
gEfiGlobalVariableGuid # SOMETIMES_CONSUMED L"ErrOutDev"
@@ -65,13 +66,14 @@
gEfiVT100Guid # SOMETIMES_CONSUMED
gEfiVT100PlusGuid # SOMETIMES_CONSUMED
gEfiPcAnsiGuid # SOMETIMES_CONSUMED
gSimpleTextInExNotifyGuid # SOMETIMES_CONSUMED
[Protocols]
gEfiHotPlugDeviceGuid # PROTOCOL SOMETIMES_CONSUMED
gEfiSerialIoProtocolGuid # PROTOCOL TO_START
gEfiDevicePathProtocolGuid # PROTOCOL TO_START
gEfiSimpleTextInProtocolGuid # PROTOCOL BY_START
gEfiSimpleTextInputExProtocolGuid # PROTOCOL BY_START
gEfiSimpleTextOutProtocolGuid # PROTOCOL BY_START
[Pcd]