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:
@@ -55,16 +55,17 @@
|
|||||||
DebugLib
|
DebugLib
|
||||||
PcdLib
|
PcdLib
|
||||||
UsbLib
|
UsbLib
|
||||||
|
BaseLib
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiHotPlugDeviceGuid # ALWAYS_CONSUMED
|
gEfiHotPlugDeviceGuid # ALWAYS_CONSUMED
|
||||||
|
gSimpleTextInExNotifyGuid # ALWAYS_CONSUMED
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiUsbIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiUsbIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
gEfiSimpleTextInProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiSimpleTextInProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
|
gEfiSimpleTextInputExProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
|
|
||||||
[FixedPcd]
|
[FixedPcd]
|
||||||
gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueKeyboardEnable
|
gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueKeyboardEnable
|
||||||
|
@@ -100,6 +100,18 @@ USBKeyboardCheckForKey (
|
|||||||
EFI_GUID gEfiUsbKeyboardDriverGuid = {
|
EFI_GUID gEfiUsbKeyboardDriverGuid = {
|
||||||
0xa05f5f78, 0xfb3, 0x4d10, {0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c}
|
0xa05f5f78, 0xfb3, 0x4d10, {0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c}
|
||||||
};
|
};
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
KbdFreeNotifyList (
|
||||||
|
IN OUT LIST_ENTRY *ListHead
|
||||||
|
);
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
IsKeyRegistered (
|
||||||
|
IN EFI_KEY_DATA *RegsiteredData,
|
||||||
|
IN EFI_KEY_DATA *InputData
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// USB Keyboard Driver Global Variables
|
// USB Keyboard Driver Global Variables
|
||||||
@@ -349,6 +361,27 @@ USBKeyboardDriverBindingStart (
|
|||||||
UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE;
|
UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE;
|
||||||
UsbKeyboardDevice->SimpleInput.Reset = USBKeyboardReset;
|
UsbKeyboardDevice->SimpleInput.Reset = USBKeyboardReset;
|
||||||
UsbKeyboardDevice->SimpleInput.ReadKeyStroke = USBKeyboardReadKeyStroke;
|
UsbKeyboardDevice->SimpleInput.ReadKeyStroke = USBKeyboardReadKeyStroke;
|
||||||
|
|
||||||
|
UsbKeyboardDevice->SimpleInputEx.Reset = USBKeyboardResetEx;
|
||||||
|
UsbKeyboardDevice->SimpleInputEx.ReadKeyStrokeEx = USBKeyboardReadKeyStrokeEx;
|
||||||
|
UsbKeyboardDevice->SimpleInputEx.SetState = USBKeyboardSetState;
|
||||||
|
UsbKeyboardDevice->SimpleInputEx.RegisterKeyNotify = USBKeyboardRegisterKeyNotify;
|
||||||
|
UsbKeyboardDevice->SimpleInputEx.UnregisterKeyNotify = USBKeyboardUnregisterKeyNotify;
|
||||||
|
|
||||||
|
InitializeListHead (&UsbKeyboardDevice->NotifyList);
|
||||||
|
|
||||||
|
Status = gBS->CreateEvent (
|
||||||
|
EVT_NOTIFY_WAIT,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
USBKeyboardWaitForKey,
|
||||||
|
UsbKeyboardDevice,
|
||||||
|
&(UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto ErrorExit;
|
||||||
|
}
|
||||||
|
|
||||||
Status = gBS->CreateEvent (
|
Status = gBS->CreateEvent (
|
||||||
EVT_NOTIFY_WAIT,
|
EVT_NOTIFY_WAIT,
|
||||||
TPL_NOTIFY,
|
TPL_NOTIFY,
|
||||||
@@ -380,6 +413,8 @@ USBKeyboardDriverBindingStart (
|
|||||||
&Controller,
|
&Controller,
|
||||||
&gEfiSimpleTextInProtocolGuid,
|
&gEfiSimpleTextInProtocolGuid,
|
||||||
&UsbKeyboardDevice->SimpleInput,
|
&UsbKeyboardDevice->SimpleInput,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
&UsbKeyboardDevice->SimpleInputEx,
|
||||||
&gEfiHotPlugDeviceGuid,
|
&gEfiHotPlugDeviceGuid,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
@@ -408,6 +443,8 @@ USBKeyboardDriverBindingStart (
|
|||||||
Controller,
|
Controller,
|
||||||
&gEfiSimpleTextInProtocolGuid,
|
&gEfiSimpleTextInProtocolGuid,
|
||||||
&UsbKeyboardDevice->SimpleInput,
|
&UsbKeyboardDevice->SimpleInput,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
&UsbKeyboardDevice->SimpleInputEx,
|
||||||
&gEfiHotPlugDeviceGuid,
|
&gEfiHotPlugDeviceGuid,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
@@ -445,6 +482,8 @@ USBKeyboardDriverBindingStart (
|
|||||||
Controller,
|
Controller,
|
||||||
&gEfiSimpleTextInProtocolGuid,
|
&gEfiSimpleTextInProtocolGuid,
|
||||||
&UsbKeyboardDevice->SimpleInput,
|
&UsbKeyboardDevice->SimpleInput,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
&UsbKeyboardDevice->SimpleInputEx,
|
||||||
&gEfiHotPlugDeviceGuid,
|
&gEfiHotPlugDeviceGuid,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
@@ -478,6 +517,27 @@ USBKeyboardDriverBindingStart (
|
|||||||
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
ErrorExit:
|
||||||
|
if (UsbKeyboardDevice != NULL) {
|
||||||
|
if (UsbKeyboardDevice->SimpleInput.WaitForKey != NULL) {
|
||||||
|
gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx != NULL) {
|
||||||
|
gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx);
|
||||||
|
}
|
||||||
|
KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList);
|
||||||
|
gBS->FreePool (UsbKeyboardDevice);
|
||||||
|
UsbKeyboardDevice = NULL;
|
||||||
|
}
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
return Status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -518,7 +578,17 @@ USBKeyboardDriverBindingStop (
|
|||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
This->DriverBindingHandle,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Get USB_KB_DEV instance.
|
// Get USB_KB_DEV instance.
|
||||||
//
|
//
|
||||||
@@ -565,6 +635,8 @@ USBKeyboardDriverBindingStop (
|
|||||||
Controller,
|
Controller,
|
||||||
&gEfiSimpleTextInProtocolGuid,
|
&gEfiSimpleTextInProtocolGuid,
|
||||||
&UsbKeyboardDevice->SimpleInput,
|
&UsbKeyboardDevice->SimpleInput,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
&UsbKeyboardDevice->SimpleInputEx,
|
||||||
&gEfiHotPlugDeviceGuid,
|
&gEfiHotPlugDeviceGuid,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
@@ -575,6 +647,8 @@ USBKeyboardDriverBindingStop (
|
|||||||
gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
|
gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);
|
||||||
gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
|
gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);
|
||||||
gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey);
|
gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey);
|
||||||
|
gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx);
|
||||||
|
KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList);
|
||||||
|
|
||||||
if (UsbKeyboardDevice->ControllerNameTable != NULL) {
|
if (UsbKeyboardDevice->ControllerNameTable != NULL) {
|
||||||
FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable);
|
FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable);
|
||||||
@@ -586,20 +660,107 @@ USBKeyboardDriverBindingStop (
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
USBKeyboardReadKeyStrokeWorker (
|
||||||
|
IN USB_KB_DEV *UsbKeyboardDevice,
|
||||||
|
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:
|
||||||
Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset() function.
|
UsbKeyboardDevice - Usb keyboard private structure.
|
||||||
|
KeyData - A pointer to a buffer that is filled in with the keystroke
|
||||||
|
state data for the key that was pressed.
|
||||||
|
|
||||||
This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
|
Returns:
|
||||||
ExtendedVerification
|
EFI_SUCCESS - The keystroke information was returned.
|
||||||
Indicates that the driver may perform a more exhaustive
|
EFI_NOT_READY - There was no keystroke data availiable.
|
||||||
verification operation of the device during reset.
|
EFI_DEVICE_ERROR - The keystroke information was not returned due to
|
||||||
|
hardware errors.
|
||||||
|
EFI_INVALID_PARAMETER - KeyData is NULL.
|
||||||
|
|
||||||
@retval EFI_SUCCESS Success
|
--*/
|
||||||
@retval EFI_DEVICE_ERROR Hardware Error
|
{
|
||||||
|
|
||||||
**/
|
EFI_STATUS Status;
|
||||||
|
UINT8 KeyChar;
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
|
||||||
|
EFI_KEY_DATA OriginalKeyData;
|
||||||
|
|
||||||
|
if (KeyData == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// if there is no saved ASCII byte, fetch it
|
||||||
|
// by calling USBKeyboardCheckForKey().
|
||||||
|
//
|
||||||
|
if (UsbKeyboardDevice->CurKeyChar == 0) {
|
||||||
|
Status = USBKeyboardCheckForKey (UsbKeyboardDevice);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyData->Key.UnicodeChar = 0;
|
||||||
|
KeyData->Key.ScanCode = SCAN_NULL;
|
||||||
|
|
||||||
|
KeyChar = UsbKeyboardDevice->CurKeyChar;
|
||||||
|
|
||||||
|
UsbKeyboardDevice->CurKeyChar = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Translate saved ASCII byte into EFI_INPUT_KEY
|
||||||
|
//
|
||||||
|
Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, &KeyData->Key);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMem (&KeyData->KeyState, &UsbKeyboardDevice->KeyState, sizeof (KeyData->KeyState));
|
||||||
|
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
|
||||||
|
UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Switch the control value to their original characters. In USBKeyCodeToEFIScanCode() the CTRL-Alpha characters have been switched to
|
||||||
|
// their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A), here switch them back for notification function.
|
||||||
|
//
|
||||||
|
CopyMem (&OriginalKeyData, KeyData, sizeof (EFI_KEY_DATA));
|
||||||
|
if (UsbKeyboardDevice->CtrlOn) {
|
||||||
|
if (OriginalKeyData.Key.UnicodeChar >= 0x01 && OriginalKeyData.Key.UnicodeChar <= 0x1A) {
|
||||||
|
if (UsbKeyboardDevice->CapsOn) {
|
||||||
|
OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + 'A' - 1);
|
||||||
|
} else {
|
||||||
|
OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + 'a' - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Invoke notification functions if exist
|
||||||
|
//
|
||||||
|
for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) {
|
||||||
|
CurrentNotify = CR (
|
||||||
|
Link,
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY,
|
||||||
|
NotifyEntry,
|
||||||
|
USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
|
||||||
|
);
|
||||||
|
if (IsKeyRegistered (&CurrentNotify->KeyData, &OriginalKeyData)) {
|
||||||
|
CurrentNotify->KeyNotificationFn (&OriginalKeyData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
USBKeyboardReset (
|
USBKeyboardReset (
|
||||||
@@ -670,34 +831,18 @@ USBKeyboardReadKeyStroke (
|
|||||||
{
|
{
|
||||||
USB_KB_DEV *UsbKeyboardDevice;
|
USB_KB_DEV *UsbKeyboardDevice;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT8 KeyChar;
|
EFI_KEY_DATA KeyData;
|
||||||
|
|
||||||
UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
|
UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
//
|
Status = USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, &KeyData);
|
||||||
// if there is no saved ASCII byte, fetch it
|
|
||||||
// by calling USBKeyboardCheckForKey().
|
|
||||||
//
|
|
||||||
if (UsbKeyboardDevice->CurKeyChar == 0) {
|
|
||||||
Status = USBKeyboardCheckForKey (UsbKeyboardDevice);
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Key->UnicodeChar = 0;
|
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
|
||||||
Key->ScanCode = SCAN_NULL;
|
|
||||||
|
|
||||||
KeyChar = UsbKeyboardDevice->CurKeyChar;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
UsbKeyboardDevice->CurKeyChar = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Translate saved ASCII byte into EFI_INPUT_KEY
|
|
||||||
//
|
|
||||||
Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, Key);
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,3 +937,396 @@ KbdReportStatusCode (
|
|||||||
DevicePath
|
DevicePath
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
KbdFreeNotifyList (
|
||||||
|
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.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
|
||||||
|
|
||||||
|
if (ListHead == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
while (!IsListEmpty (ListHead)) {
|
||||||
|
NotifyNode = CR (
|
||||||
|
ListHead->ForwardLink,
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY,
|
||||||
|
NotifyEntry,
|
||||||
|
USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE
|
||||||
|
);
|
||||||
|
RemoveEntryList (ListHead->ForwardLink);
|
||||||
|
gBS->FreePool (NotifyNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
USBKeyboardResetEx (
|
||||||
|
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;
|
||||||
|
USB_KB_DEV *UsbKeyboardDevice;
|
||||||
|
EFI_TPL OldTpl;
|
||||||
|
|
||||||
|
|
||||||
|
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
|
Status = UsbKeyboardDevice->SimpleInput.Reset (&UsbKeyboardDevice->SimpleInput, ExtendedVerification);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
|
||||||
|
UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
|
||||||
|
gBS->RestoreTPL (OldTpl);
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
USBKeyboardReadKeyStrokeEx (
|
||||||
|
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.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
USB_KB_DEV *UsbKeyboardDevice;
|
||||||
|
|
||||||
|
if (KeyData == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
|
return USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, KeyData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
USBKeyboardSetState (
|
||||||
|
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.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
USB_KB_DEV *UsbKeyboardDevice;
|
||||||
|
|
||||||
|
if (KeyToggleState == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
|
if (((UsbKeyboardDevice->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
|
||||||
|
((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update the status light
|
||||||
|
//
|
||||||
|
|
||||||
|
UsbKeyboardDevice->ScrollOn = 0;
|
||||||
|
UsbKeyboardDevice->NumLockOn = 0;
|
||||||
|
UsbKeyboardDevice->CapsOn = 0;
|
||||||
|
|
||||||
|
if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
|
||||||
|
UsbKeyboardDevice->ScrollOn = 1;
|
||||||
|
}
|
||||||
|
if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
|
||||||
|
UsbKeyboardDevice->NumLockOn = 1;
|
||||||
|
}
|
||||||
|
if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
|
||||||
|
UsbKeyboardDevice->CapsOn = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetKeyLED (UsbKeyboardDevice);
|
||||||
|
|
||||||
|
UsbKeyboardDevice->KeyState.KeyToggleState = *KeyToggleState;
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
USBKeyboardRegisterKeyNotify (
|
||||||
|
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.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
USB_KB_DEV *UsbKeyboardDevice;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
|
||||||
|
|
||||||
|
if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
|
||||||
|
//
|
||||||
|
for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) {
|
||||||
|
CurrentNotify = CR (
|
||||||
|
Link,
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY,
|
||||||
|
NotifyEntry,
|
||||||
|
USB_KB_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 = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));
|
||||||
|
if (NewNotify == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewNotify->Signature = USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
|
||||||
|
NewNotify->KeyNotificationFn = KeyNotificationFunction;
|
||||||
|
CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
|
||||||
|
InsertTailList (&UsbKeyboardDevice->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
|
||||||
|
USBKeyboardUnregisterKeyNotify (
|
||||||
|
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.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
USB_KB_DEV *UsbKeyboardDevice;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
|
||||||
|
LIST_ENTRY *Link;
|
||||||
|
|
||||||
|
if (NotificationHandle == NULL) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
NotificationHandle,
|
||||||
|
&gSimpleTextInExNotifyGuid,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Link = UsbKeyboardDevice->NotifyList.ForwardLink; Link != &UsbKeyboardDevice->NotifyList; Link = Link->ForwardLink) {
|
||||||
|
CurrentNotify = CR (
|
||||||
|
Link,
|
||||||
|
KEYBOARD_CONSOLE_IN_EX_NOTIFY,
|
||||||
|
NotifyEntry,
|
||||||
|
USB_KB_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@ Revision History
|
|||||||
#include <PiDxe.h>
|
#include <PiDxe.h>
|
||||||
|
|
||||||
#include <Protocol/SimpleTextIn.h>
|
#include <Protocol/SimpleTextIn.h>
|
||||||
|
#include <Protocol/SimpleTextInEx.h>
|
||||||
#include <Guid/HotPlugDevice.h>
|
#include <Guid/HotPlugDevice.h>
|
||||||
#include <Protocol/UsbIo.h>
|
#include <Protocol/UsbIo.h>
|
||||||
#include <Protocol/DevicePath.h>
|
#include <Protocol/DevicePath.h>
|
||||||
@@ -40,7 +41,7 @@ Revision History
|
|||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
#include <Library/UsbLib.h>
|
#include <Library/UsbLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
|
||||||
#include <IndustryStandard/Usb.h>
|
#include <IndustryStandard/Usb.h>
|
||||||
|
|
||||||
@@ -69,11 +70,21 @@ typedef struct {
|
|||||||
} USB_KB_BUFFER;
|
} USB_KB_BUFFER;
|
||||||
|
|
||||||
#define USB_KB_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'k', 'b', 'd')
|
#define USB_KB_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'k', 'b', 'd')
|
||||||
|
#define USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE EFI_SIGNATURE_32 ('u', 'k', 'b', 'x')
|
||||||
|
|
||||||
|
typedef struct _KEYBOARD_CONSOLE_IN_EX_NOTIFY {
|
||||||
|
UINTN Signature;
|
||||||
|
EFI_HANDLE NotifyHandle;
|
||||||
|
EFI_KEY_DATA KeyData;
|
||||||
|
EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
|
||||||
|
LIST_ENTRY NotifyEntry;
|
||||||
|
} KEYBOARD_CONSOLE_IN_EX_NOTIFY;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINTN Signature;
|
UINTN Signature;
|
||||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||||
EFI_EVENT DelayedRecoveryEvent;
|
EFI_EVENT DelayedRecoveryEvent;
|
||||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleInput;
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleInput;
|
||||||
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleInputEx;
|
||||||
EFI_USB_IO_PROTOCOL *UsbIo;
|
EFI_USB_IO_PROTOCOL *UsbIo;
|
||||||
|
|
||||||
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
|
||||||
@@ -94,6 +105,22 @@ typedef struct {
|
|||||||
|
|
||||||
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
|
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
|
||||||
|
|
||||||
|
UINT8 LeftCtrlOn;
|
||||||
|
UINT8 LeftAltOn;
|
||||||
|
UINT8 LeftShiftOn;
|
||||||
|
UINT8 LeftLogoOn;
|
||||||
|
UINT8 RightCtrlOn;
|
||||||
|
UINT8 RightAltOn;
|
||||||
|
UINT8 RightShiftOn;
|
||||||
|
UINT8 RightLogoOn;
|
||||||
|
UINT8 MenuKeyOn;
|
||||||
|
UINT8 SysReqOn;
|
||||||
|
|
||||||
|
EFI_KEY_STATE KeyState;
|
||||||
|
//
|
||||||
|
// Notification function list
|
||||||
|
//
|
||||||
|
LIST_ENTRY NotifyList;
|
||||||
} USB_KB_DEV;
|
} USB_KB_DEV;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -103,6 +130,7 @@ extern EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding;
|
|||||||
extern EFI_COMPONENT_NAME_PROTOCOL gUsbKeyboardComponentName;
|
extern EFI_COMPONENT_NAME_PROTOCOL gUsbKeyboardComponentName;
|
||||||
extern EFI_COMPONENT_NAME2_PROTOCOL gUsbKeyboardComponentName2;
|
extern EFI_COMPONENT_NAME2_PROTOCOL gUsbKeyboardComponentName2;
|
||||||
extern EFI_GUID gEfiUsbKeyboardDriverGuid;
|
extern EFI_GUID gEfiUsbKeyboardDriverGuid;
|
||||||
|
extern EFI_GUID gSimpleTextInExNotifyGuid;
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KbdReportStatusCode (
|
KbdReportStatusCode (
|
||||||
@@ -113,6 +141,9 @@ KbdReportStatusCode (
|
|||||||
|
|
||||||
#define USB_KB_DEV_FROM_THIS(a) \
|
#define USB_KB_DEV_FROM_THIS(a) \
|
||||||
CR(a, USB_KB_DEV, SimpleInput, USB_KB_DEV_SIGNATURE)
|
CR(a, USB_KB_DEV, SimpleInput, USB_KB_DEV_SIGNATURE)
|
||||||
|
#define TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS(a) \
|
||||||
|
CR(a, USB_KB_DEV, SimpleInputEx, USB_KB_DEV_SIGNATURE)
|
||||||
|
|
||||||
|
|
||||||
#define MOD_CONTROL_L 0x01
|
#define MOD_CONTROL_L 0x01
|
||||||
#define MOD_CONTROL_R 0x10
|
#define MOD_CONTROL_R 0x10
|
||||||
@@ -128,7 +159,7 @@ typedef struct {
|
|||||||
UINT8 Key;
|
UINT8 Key;
|
||||||
} KB_MODIFIER;
|
} KB_MODIFIER;
|
||||||
|
|
||||||
#define USB_KEYCODE_MAX_MAKE 0x64
|
#define USB_KEYCODE_MAX_MAKE 0x7E
|
||||||
|
|
||||||
#define USBKBD_VALID_KEYCODE(key) ((UINT8) (key) > 3)
|
#define USBKBD_VALID_KEYCODE(key) ((UINT8) (key) > 3)
|
||||||
|
|
||||||
@@ -138,4 +169,137 @@ typedef struct {
|
|||||||
UINT8 ScrollLock : 1;
|
UINT8 ScrollLock : 1;
|
||||||
UINT8 Resrvd : 5;
|
UINT8 Resrvd : 5;
|
||||||
} LED_MAP;
|
} LED_MAP;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Simple Text Input Ex protocol functions
|
||||||
|
//
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
USBKeyboardResetEx (
|
||||||
|
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
|
||||||
|
USBKeyboardReadKeyStrokeEx (
|
||||||
|
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
|
||||||
|
USBKeyboardSetState (
|
||||||
|
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
|
||||||
|
USBKeyboardRegisterKeyNotify (
|
||||||
|
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
|
||||||
|
USBKeyboardUnregisterKeyNotify (
|
||||||
|
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.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -129,7 +129,22 @@ UINT8 KeyConvertionTable[USB_KEYCODE_MAX_MAKE][3] = {
|
|||||||
{ SCAN_NULL, '\\', '|' }, // 0x64 Keyboard Non-US \ and |
|
{ SCAN_NULL, '\\', '|' }, // 0x64 Keyboard Non-US \ and |
|
||||||
{ SCAN_NULL, 0x00, 0x00 }, // 0x65 Keyboard Application
|
{ SCAN_NULL, 0x00, 0x00 }, // 0x65 Keyboard Application
|
||||||
{ SCAN_NULL, 0x00, 0x00 }, // 0x66 Keyboard Power
|
{ SCAN_NULL, 0x00, 0x00 }, // 0x66 Keyboard Power
|
||||||
{ SCAN_NULL, '=' , '=' } // 0x67 Keypad =
|
{ SCAN_NULL, '=' , '=' }, // 0x67 Keypad =
|
||||||
|
{ SCAN_F13, 0x00, 0x00 }, // 0x68
|
||||||
|
{ SCAN_F14, 0x00, 0x00 }, // 0x69
|
||||||
|
{ SCAN_F15, 0x00, 0x00 }, // 0x6A
|
||||||
|
{ SCAN_F16, 0x00, 0x00 }, // 0x6B
|
||||||
|
{ SCAN_F17, 0x00, 0x00 }, // 0x6C
|
||||||
|
{ SCAN_F18, 0x00, 0x00 }, // 0x6D
|
||||||
|
{ SCAN_F19, 0x00, 0x00 }, // 0x6E
|
||||||
|
{ SCAN_F20, 0x00, 0x00 }, // 0x6F
|
||||||
|
{ SCAN_F21, 0x00, 0x00 }, // 0x70
|
||||||
|
{ SCAN_F22, 0x00, 0x00 }, // 0x71
|
||||||
|
{ SCAN_F23, 0x00, 0x00 }, // 0x72
|
||||||
|
{ SCAN_F24, 0x00, 0x00 }, // 0x73
|
||||||
|
{ SCAN_MUTE, 0x00, 0x00 }, // 0x7F
|
||||||
|
{ SCAN_VOLUME_UP, 0x00, 0x00 }, // 0x80
|
||||||
|
{ SCAN_VOLUME_DOWN, 0x00, 0x00 }, // 0x81
|
||||||
};
|
};
|
||||||
|
|
||||||
STATIC KB_MODIFIER KB_Mod[8] = {
|
STATIC KB_MODIFIER KB_Mod[8] = {
|
||||||
@@ -140,7 +155,7 @@ STATIC KB_MODIFIER KB_Mod[8] = {
|
|||||||
{ MOD_ALT_L, 0xe2 }, // 11100010
|
{ MOD_ALT_L, 0xe2 }, // 11100010
|
||||||
{ MOD_ALT_R, 0xe6 }, // 11100110
|
{ MOD_ALT_R, 0xe6 }, // 11100110
|
||||||
{ MOD_WIN_L, 0xe3 }, // 11100011
|
{ MOD_WIN_L, 0xe3 }, // 11100011
|
||||||
{ MOD_WIN_R, 0xe7 } // 11100111
|
{ MOD_WIN_R, 0xe7 }, // 11100111
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -287,6 +302,17 @@ InitUSBKeyboard (
|
|||||||
UsbKeyboardDevice->CapsOn = 0;
|
UsbKeyboardDevice->CapsOn = 0;
|
||||||
UsbKeyboardDevice->ScrollOn = 0;
|
UsbKeyboardDevice->ScrollOn = 0;
|
||||||
|
|
||||||
|
UsbKeyboardDevice->LeftCtrlOn = 0;
|
||||||
|
UsbKeyboardDevice->LeftAltOn = 0;
|
||||||
|
UsbKeyboardDevice->LeftShiftOn = 0;
|
||||||
|
UsbKeyboardDevice->LeftLogoOn = 0;
|
||||||
|
UsbKeyboardDevice->RightCtrlOn = 0;
|
||||||
|
UsbKeyboardDevice->RightAltOn = 0;
|
||||||
|
UsbKeyboardDevice->RightShiftOn = 0;
|
||||||
|
UsbKeyboardDevice->RightLogoOn = 0;
|
||||||
|
UsbKeyboardDevice->MenuKeyOn = 0;
|
||||||
|
UsbKeyboardDevice->SysReqOn = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sync the initial state of lights
|
// Sync the initial state of lights
|
||||||
//
|
//
|
||||||
@@ -675,21 +701,65 @@ USBParseKey (
|
|||||||
if (!UsbKey.Down) {
|
if (!UsbKey.Down) {
|
||||||
switch (UsbKey.KeyCode) {
|
switch (UsbKey.KeyCode) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// CTRL release
|
||||||
|
//
|
||||||
case 0xe0:
|
case 0xe0:
|
||||||
|
UsbKeyboardDevice->LeftCtrlOn = 0;
|
||||||
|
UsbKeyboardDevice->CtrlOn = 0;
|
||||||
|
break;
|
||||||
case 0xe4:
|
case 0xe4:
|
||||||
|
UsbKeyboardDevice->RightCtrlOn = 0;
|
||||||
UsbKeyboardDevice->CtrlOn = 0;
|
UsbKeyboardDevice->CtrlOn = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Shift release
|
||||||
|
//
|
||||||
case 0xe1:
|
case 0xe1:
|
||||||
|
UsbKeyboardDevice->LeftShiftOn = 0;
|
||||||
|
UsbKeyboardDevice->ShiftOn = 0;
|
||||||
|
break;
|
||||||
case 0xe5:
|
case 0xe5:
|
||||||
|
UsbKeyboardDevice->RightShiftOn = 0;
|
||||||
UsbKeyboardDevice->ShiftOn = 0;
|
UsbKeyboardDevice->ShiftOn = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alt release
|
||||||
|
//
|
||||||
case 0xe2:
|
case 0xe2:
|
||||||
|
UsbKeyboardDevice->LeftAltOn = 0;
|
||||||
|
UsbKeyboardDevice->AltOn = 0;
|
||||||
|
break;
|
||||||
case 0xe6:
|
case 0xe6:
|
||||||
|
UsbKeyboardDevice->RightAltOn = 0;
|
||||||
UsbKeyboardDevice->AltOn = 0;
|
UsbKeyboardDevice->AltOn = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Logo release
|
||||||
|
//
|
||||||
|
case 0xe3:
|
||||||
|
UsbKeyboardDevice->LeftLogoOn = 0;
|
||||||
|
break;
|
||||||
|
case 0xe7:
|
||||||
|
UsbKeyboardDevice->RightLogoOn = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Menu key (App/Apps) release
|
||||||
|
//
|
||||||
|
case 0x65:
|
||||||
|
UsbKeyboardDevice->MenuKeyOn = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SysReq release
|
||||||
|
//
|
||||||
|
case 0x46:
|
||||||
|
UsbKeyboardDevice->SysReqOn = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -703,25 +773,69 @@ USBParseKey (
|
|||||||
switch (UsbKey.KeyCode) {
|
switch (UsbKey.KeyCode) {
|
||||||
|
|
||||||
case 0xe0:
|
case 0xe0:
|
||||||
|
UsbKeyboardDevice->LeftCtrlOn = 1;
|
||||||
|
UsbKeyboardDevice->CtrlOn = 1;
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
case 0xe4:
|
case 0xe4:
|
||||||
|
UsbKeyboardDevice->RightCtrlOn = 1;
|
||||||
UsbKeyboardDevice->CtrlOn = 1;
|
UsbKeyboardDevice->CtrlOn = 1;
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Shift press
|
||||||
|
//
|
||||||
case 0xe1:
|
case 0xe1:
|
||||||
|
UsbKeyboardDevice->LeftShiftOn = 1;
|
||||||
|
UsbKeyboardDevice->ShiftOn = 1;
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
case 0xe5:
|
case 0xe5:
|
||||||
|
UsbKeyboardDevice->RightShiftOn = 1;
|
||||||
UsbKeyboardDevice->ShiftOn = 1;
|
UsbKeyboardDevice->ShiftOn = 1;
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alt press
|
||||||
|
//
|
||||||
case 0xe2:
|
case 0xe2:
|
||||||
|
UsbKeyboardDevice->LeftAltOn = 1;
|
||||||
|
UsbKeyboardDevice->AltOn = 1;
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
case 0xe6:
|
case 0xe6:
|
||||||
|
UsbKeyboardDevice->RightAltOn = 1;
|
||||||
UsbKeyboardDevice->AltOn = 1;
|
UsbKeyboardDevice->AltOn = 1;
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Logo press
|
||||||
|
//
|
||||||
case 0xe3:
|
case 0xe3:
|
||||||
|
UsbKeyboardDevice->LeftLogoOn = 1;
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
case 0xe7:
|
case 0xe7:
|
||||||
|
UsbKeyboardDevice->RightLogoOn = 1;
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Menu key (App/Apps) press
|
||||||
|
//
|
||||||
|
case 0x65:
|
||||||
|
UsbKeyboardDevice->MenuKeyOn = 1;
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SysReq press
|
||||||
|
//
|
||||||
|
case 0x46:
|
||||||
|
UsbKeyboardDevice->SysReqOn = 1;
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -757,18 +871,14 @@ USBParseKey (
|
|||||||
// keys are not valid EFI key
|
// keys are not valid EFI key
|
||||||
//
|
//
|
||||||
|
|
||||||
case 0x46:
|
|
||||||
//
|
|
||||||
// fall through
|
|
||||||
//
|
//
|
||||||
|
// PrintScreen/SysRq key and Application key
|
||||||
|
// Should be handled by UEFI2.1 compliant code
|
||||||
|
|
||||||
case 0x48:
|
case 0x48:
|
||||||
//
|
//
|
||||||
// fall through
|
// fall through
|
||||||
//
|
//
|
||||||
case 0x65:
|
|
||||||
//
|
|
||||||
// fall through
|
|
||||||
//
|
|
||||||
case 0x66:
|
case 0x66:
|
||||||
//
|
//
|
||||||
// fall through
|
// fall through
|
||||||
@@ -834,11 +944,26 @@ USBKeyCodeToEFIScanCode (
|
|||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Undefined entries from 0x74 to 0x7E
|
||||||
|
//
|
||||||
|
if (KeyChar > USB_KEYCODE_MAX_MAKE) {
|
||||||
|
Index = (UINT8) (Index - 11);
|
||||||
|
}
|
||||||
|
|
||||||
Key->ScanCode = KeyConvertionTable[Index][0];
|
Key->ScanCode = KeyConvertionTable[Index][0];
|
||||||
|
|
||||||
if (UsbKeyboardDevice->ShiftOn) {
|
if (UsbKeyboardDevice->ShiftOn) {
|
||||||
|
|
||||||
Key->UnicodeChar = KeyConvertionTable[Index][2];
|
Key->UnicodeChar = KeyConvertionTable[Index][2];
|
||||||
|
//
|
||||||
|
// Need not return associated shift state if a class of printable characters that
|
||||||
|
// are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
|
||||||
|
//
|
||||||
|
if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {
|
||||||
|
UsbKeyboardDevice->LeftShiftOn = 0;
|
||||||
|
UsbKeyboardDevice->RightShiftOn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -885,6 +1010,51 @@ USBKeyCodeToEFIScanCode (
|
|||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Save Shift/Toggle state
|
||||||
|
//
|
||||||
|
if (UsbKeyboardDevice->LeftCtrlOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->RightCtrlOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->LeftAltOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->RightAltOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_ALT_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->LeftShiftOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->RightShiftOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->LeftLogoOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->RightLogoOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->MenuKeyOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->SysReqOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UsbKeyboardDevice->ScrollOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->NumLockOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
|
||||||
|
}
|
||||||
|
if (UsbKeyboardDevice->CapsOn == 1) {
|
||||||
|
UsbKeyboardDevice->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,21 @@ STATIC TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = {
|
|||||||
0,
|
0,
|
||||||
(EFI_SIMPLE_TEXT_INPUT_PROTOCOL **) NULL,
|
(EFI_SIMPLE_TEXT_INPUT_PROTOCOL **) NULL,
|
||||||
0,
|
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,
|
ConSplitterSimplePointerReset,
|
||||||
@@ -367,6 +382,8 @@ Returns:
|
|||||||
&mConIn.VirtualHandle,
|
&mConIn.VirtualHandle,
|
||||||
&gEfiSimpleTextInProtocolGuid,
|
&gEfiSimpleTextInProtocolGuid,
|
||||||
&mConIn.TextIn,
|
&mConIn.TextIn,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
&mConIn.TextInEx,
|
||||||
&gEfiSimplePointerProtocolGuid,
|
&gEfiSimplePointerProtocolGuid,
|
||||||
&mConIn.SimplePointer,
|
&mConIn.SimplePointer,
|
||||||
&gEfiPrimaryConsoleInDeviceGuid,
|
&gEfiPrimaryConsoleInDeviceGuid,
|
||||||
@@ -514,6 +531,30 @@ Returns:
|
|||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
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;
|
ConInPrivate->SimplePointer.Mode = &ConInPrivate->SimplePointerMode;
|
||||||
|
|
||||||
Status = ConSplitterGrowBuffer (
|
Status = ConSplitterGrowBuffer (
|
||||||
@@ -898,6 +939,7 @@ Returns:
|
|||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
|
||||||
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Start ConSplitter on ControllerHandle, and create the virtual
|
// Start ConSplitter on ControllerHandle, and create the virtual
|
||||||
@@ -915,6 +957,23 @@ Returns:
|
|||||||
return Status;
|
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);
|
return ConSplitterTextInAddDevice (&mConIn, TextIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1195,10 +1254,29 @@ Returns:
|
|||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *TextIn;
|
||||||
|
|
||||||
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx;
|
||||||
if (NumberOfChildren == 0) {
|
if (NumberOfChildren == 0) {
|
||||||
return EFI_SUCCESS;
|
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 (
|
Status = ConSplitterStop (
|
||||||
This,
|
This,
|
||||||
ControllerHandle,
|
ControllerHandle,
|
||||||
@@ -1512,6 +1590,66 @@ Returns:
|
|||||||
return EFI_NOT_FOUND;
|
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
|
EFI_STATUS
|
||||||
ConSplitterSimplePointerAddDevice (
|
ConSplitterSimplePointerAddDevice (
|
||||||
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
|
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
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ConSplitterSimplePointerReset (
|
ConSplitterSimplePointerReset (
|
||||||
|
@@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include <Protocol/SimpleTextOut.h>
|
#include <Protocol/SimpleTextOut.h>
|
||||||
#include <Guid/ConsoleInDevice.h>
|
#include <Guid/ConsoleInDevice.h>
|
||||||
#include <Protocol/SimpleTextIn.h>
|
#include <Protocol/SimpleTextIn.h>
|
||||||
|
#include <Protocol/SimpleTextInEx.h>
|
||||||
#include <Protocol/ConsoleControl.h>
|
#include <Protocol/ConsoleControl.h>
|
||||||
#include <Guid/StandardErrorDevice.h>
|
#include <Guid/StandardErrorDevice.h>
|
||||||
#include <Guid/ConsoleOutDevice.h>
|
#include <Guid/ConsoleOutDevice.h>
|
||||||
@@ -53,6 +54,8 @@ extern EFI_DRIVER_BINDING_PROTOCOL gConSplitterStdErrDriverBinding;
|
|||||||
extern EFI_COMPONENT_NAME_PROTOCOL gConSplitterStdErrComponentName;
|
extern EFI_COMPONENT_NAME_PROTOCOL gConSplitterStdErrComponentName;
|
||||||
extern EFI_COMPONENT_NAME2_PROTOCOL gConSplitterStdErrComponentName2;
|
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
|
// These definitions were in the old Hii protocol, but are not in the new UEFI
|
||||||
// version. So they are defined locally.
|
// version. So they are defined locally.
|
||||||
#define UNICODE_NARROW_CHAR 0xFFF0
|
#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_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 {
|
typedef struct {
|
||||||
UINT64 Signature;
|
UINT64 Signature;
|
||||||
EFI_HANDLE VirtualHandle;
|
EFI_HANDLE VirtualHandle;
|
||||||
@@ -85,6 +98,13 @@ typedef struct {
|
|||||||
EFI_SIMPLE_TEXT_INPUT_PROTOCOL **TextInList;
|
EFI_SIMPLE_TEXT_INPUT_PROTOCOL **TextInList;
|
||||||
UINTN TextInListCount;
|
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_PROTOCOL SimplePointer;
|
||||||
EFI_SIMPLE_POINTER_MODE SimplePointerMode;
|
EFI_SIMPLE_POINTER_MODE SimplePointerMode;
|
||||||
UINTN CurrentNumberOfPointers;
|
UINTN CurrentNumberOfPointers;
|
||||||
@@ -114,6 +134,19 @@ typedef struct {
|
|||||||
SimplePointer, \
|
SimplePointer, \
|
||||||
TEXT_IN_SPLITTER_PRIVATE_DATA_SIGNATURE \
|
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
|
// Private data for the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL splitter
|
||||||
@@ -770,7 +803,151 @@ ConSplitterTextInReadKeyStroke (
|
|||||||
OUT EFI_INPUT_KEY *Key
|
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
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ConSplitterTextInWaitForKey (
|
ConSplitterTextInWaitForKey (
|
||||||
|
@@ -67,11 +67,13 @@
|
|||||||
gEfiPrimaryConsoleOutDeviceGuid # ALWAYS_PRODUCED
|
gEfiPrimaryConsoleOutDeviceGuid # ALWAYS_PRODUCED
|
||||||
gEfiPrimaryConsoleInDeviceGuid # ALWAYS_PRODUCED
|
gEfiPrimaryConsoleInDeviceGuid # ALWAYS_PRODUCED
|
||||||
gEfiPrimaryStandardErrorDeviceGuid # ALWAYS_PRODUCED
|
gEfiPrimaryStandardErrorDeviceGuid # ALWAYS_PRODUCED
|
||||||
|
gSimpleTextInExNotifyGuid # ALWAYS_PRODUCED
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiConsoleControlProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
gEfiConsoleControlProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||||
gEfiSimplePointerProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
gEfiSimplePointerProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||||
gEfiSimpleTextInProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
gEfiSimpleTextInProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||||
|
gEfiSimpleTextInputExProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||||
gEfiSimpleTextOutProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
gEfiSimpleTextOutProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||||
gEfiGraphicsOutputProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
gEfiGraphicsOutputProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||||
gEfiUgaDrawProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
gEfiUgaDrawProtocolGuid # PROTOCOL ALWAYS_PRODUCED
|
||||||
|
@@ -22,6 +22,12 @@ Revision History:
|
|||||||
|
|
||||||
#include "Terminal.h"
|
#include "Terminal.h"
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
TerminalFreeNotifyList (
|
||||||
|
IN OUT LIST_ENTRY *ListHead
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Globals
|
// Globals
|
||||||
//
|
//
|
||||||
@@ -94,7 +100,19 @@ TERMINAL_DEV gTerminalDevTemplate = {
|
|||||||
NULL,
|
NULL,
|
||||||
INPUT_STATE_DEFAULT,
|
INPUT_STATE_DEFAULT,
|
||||||
RESET_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->TerminalType = TerminalType;
|
||||||
TerminalDevice->SerialIo = SerialIo;
|
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 (
|
Status = gBS->CreateEvent (
|
||||||
EVT_NOTIFY_WAIT,
|
EVT_NOTIFY_WAIT,
|
||||||
TPL_NOTIFY,
|
TPL_NOTIFY,
|
||||||
@@ -391,7 +422,6 @@ TerminalDriverBindingStart (
|
|||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// initialize the FIFO buffer used for accommodating
|
// initialize the FIFO buffer used for accommodating
|
||||||
// the pre-read pending characters
|
// the pre-read pending characters
|
||||||
@@ -405,6 +435,7 @@ TerminalDriverBindingStart (
|
|||||||
// keystroke response performance issue
|
// keystroke response performance issue
|
||||||
//
|
//
|
||||||
Mode = TerminalDevice->SerialIo->Mode;
|
Mode = TerminalDevice->SerialIo->Mode;
|
||||||
|
|
||||||
SerialInTimeOut = 0;
|
SerialInTimeOut = 0;
|
||||||
if (Mode->BaudRate != 0) {
|
if (Mode->BaudRate != 0) {
|
||||||
SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;
|
SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;
|
||||||
@@ -578,6 +609,8 @@ TerminalDriverBindingStart (
|
|||||||
TerminalDevice->DevicePath,
|
TerminalDevice->DevicePath,
|
||||||
&gEfiSimpleTextInProtocolGuid,
|
&gEfiSimpleTextInProtocolGuid,
|
||||||
&TerminalDevice->SimpleInput,
|
&TerminalDevice->SimpleInput,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
&TerminalDevice->SimpleInputEx,
|
||||||
&gEfiSimpleTextOutProtocolGuid,
|
&gEfiSimpleTextOutProtocolGuid,
|
||||||
&TerminalDevice->SimpleTextOutput,
|
&TerminalDevice->SimpleTextOutput,
|
||||||
NULL
|
NULL
|
||||||
@@ -655,6 +688,12 @@ Error:
|
|||||||
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
|
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TerminalDevice->SimpleInputEx.WaitForKeyEx != NULL) {
|
||||||
|
gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalFreeNotifyList (&TerminalDevice->NotifyList);
|
||||||
|
|
||||||
if (TerminalDevice->ControllerNameTable != NULL) {
|
if (TerminalDevice->ControllerNameTable != NULL) {
|
||||||
FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
|
FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
|
||||||
}
|
}
|
||||||
@@ -809,6 +848,8 @@ TerminalDriverBindingStop (
|
|||||||
ChildHandleBuffer[Index],
|
ChildHandleBuffer[Index],
|
||||||
&gEfiSimpleTextInProtocolGuid,
|
&gEfiSimpleTextInProtocolGuid,
|
||||||
&TerminalDevice->SimpleInput,
|
&TerminalDevice->SimpleInput,
|
||||||
|
&gEfiSimpleTextInputExProtocolGuid,
|
||||||
|
&TerminalDevice->SimpleInputEx,
|
||||||
&gEfiSimpleTextOutProtocolGuid,
|
&gEfiSimpleTextOutProtocolGuid,
|
||||||
&TerminalDevice->SimpleTextOutput,
|
&TerminalDevice->SimpleTextOutput,
|
||||||
&gEfiDevicePathProtocolGuid,
|
&gEfiDevicePathProtocolGuid,
|
||||||
@@ -851,6 +892,8 @@ TerminalDriverBindingStop (
|
|||||||
|
|
||||||
gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
|
gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
|
||||||
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
|
gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
|
||||||
|
gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);
|
||||||
|
TerminalFreeNotifyList (&TerminalDevice->NotifyList);
|
||||||
FreePool (TerminalDevice->DevicePath);
|
FreePool (TerminalDevice->DevicePath);
|
||||||
FreePool (TerminalDevice);
|
FreePool (TerminalDevice);
|
||||||
}
|
}
|
||||||
@@ -868,6 +911,47 @@ TerminalDriverBindingStop (
|
|||||||
return EFI_SUCCESS;
|
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
|
VOID
|
||||||
TerminalUpdateConsoleDevVariable (
|
TerminalUpdateConsoleDevVariable (
|
||||||
IN CHAR16 *VariableName,
|
IN CHAR16 *VariableName,
|
||||||
|
@@ -30,6 +30,7 @@ Revision History
|
|||||||
#include <Guid/GlobalVariable.h>
|
#include <Guid/GlobalVariable.h>
|
||||||
#include <Protocol/DevicePath.h>
|
#include <Protocol/DevicePath.h>
|
||||||
#include <Protocol/SimpleTextIn.h>
|
#include <Protocol/SimpleTextIn.h>
|
||||||
|
#include <Protocol/SimpleTextInEx.h>
|
||||||
#include <Guid/HotPlugDevice.h>
|
#include <Guid/HotPlugDevice.h>
|
||||||
#include <Guid/PcAnsi.h>
|
#include <Guid/PcAnsi.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
@@ -42,7 +43,7 @@ Revision History
|
|||||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||||
#include <Library/DevicePathLib.h>
|
#include <Library/DevicePathLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
|
#include <Library/BaseLib.h>
|
||||||
|
|
||||||
|
|
||||||
#define RAW_FIFO_MAX_NUMBER 256
|
#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_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 {
|
typedef struct {
|
||||||
UINTN Signature;
|
UINTN Signature;
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
@@ -94,6 +104,8 @@ typedef struct {
|
|||||||
// to indicate whether the Esc could be sent or not.
|
// to indicate whether the Esc could be sent or not.
|
||||||
//
|
//
|
||||||
BOOLEAN OutputEscChar;
|
BOOLEAN OutputEscChar;
|
||||||
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleInputEx;
|
||||||
|
LIST_ENTRY NotifyList;
|
||||||
} TERMINAL_DEV;
|
} TERMINAL_DEV;
|
||||||
|
|
||||||
#define INPUT_STATE_DEFAULT 0x00
|
#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_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_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 {
|
typedef union {
|
||||||
UINT8 Utf8_1;
|
UINT8 Utf8_1;
|
||||||
@@ -153,6 +166,7 @@ extern EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding;
|
|||||||
extern EFI_COMPONENT_NAME_PROTOCOL gTerminalComponentName;
|
extern EFI_COMPONENT_NAME_PROTOCOL gTerminalComponentName;
|
||||||
extern EFI_COMPONENT_NAME2_PROTOCOL gTerminalComponentName2;
|
extern EFI_COMPONENT_NAME2_PROTOCOL gTerminalComponentName2;
|
||||||
|
|
||||||
|
extern EFI_GUID gSimpleTextInExNotifyGuid;
|
||||||
//
|
//
|
||||||
// Prototypes
|
// 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
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
TerminalConInWaitForKey (
|
TerminalConInWaitForKey (
|
||||||
|
@@ -15,6 +15,78 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "Terminal.h"
|
#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
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
TerminalConInReset (
|
TerminalConInReset (
|
||||||
@@ -111,28 +183,358 @@ TerminalConInReadKeyStroke (
|
|||||||
{
|
{
|
||||||
TERMINAL_DEV *TerminalDevice;
|
TERMINAL_DEV *TerminalDevice;
|
||||||
EFI_STATUS Status;
|
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.
|
// get TERMINAL_DEV from "This" parameter.
|
||||||
//
|
//
|
||||||
TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);
|
TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (This);
|
||||||
|
|
||||||
Status = TerminalConInCheckForKey (This);
|
Status = ReadKeyStrokeWorker (TerminalDevice, &KeyData);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return EFI_NOT_READY;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
EfiKeyFiFoRemoveOneKey (TerminalDevice, Key);
|
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
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
|
VOID
|
||||||
TranslateRawDataToEfiKey (
|
TranslateRawDataToEfiKey (
|
||||||
IN TERMINAL_DEV *TerminalDevice
|
IN TERMINAL_DEV *TerminalDevice
|
||||||
@@ -787,7 +1189,9 @@ Symbols used in table below
|
|||||||
| F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |
|
| F9 | 0x13 | ESC [ U | ESC 9 | ESC O p |
|
||||||
| F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |
|
| F10 | 0x14 | ESC [ V | ESC 0 | ESC O M |
|
||||||
| Escape | 0x17 | ESC | ESC | ESC |
|
| Escape | 0x17 | ESC | ESC | ESC |
|
||||||
+=========+======+===========+==========+=========+
|
| F11 | 0x15 | | ESC ! | |
|
||||||
|
| F12 | 0x16 | | ESC @ | |
|
||||||
|
+=========+======+===========+==========+==========+
|
||||||
|
|
||||||
Special Mappings
|
Special Mappings
|
||||||
================
|
================
|
||||||
@@ -882,6 +1286,12 @@ ESC R ESC r ESC R = Reset System
|
|||||||
case '0':
|
case '0':
|
||||||
Key.ScanCode = SCAN_F10;
|
Key.ScanCode = SCAN_F10;
|
||||||
break;
|
break;
|
||||||
|
case '!':
|
||||||
|
Key.ScanCode = SCAN_F11;
|
||||||
|
break;
|
||||||
|
case '@':
|
||||||
|
Key.ScanCode = SCAN_F12;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
Key.ScanCode = SCAN_HOME;
|
Key.ScanCode = SCAN_HOME;
|
||||||
break;
|
break;
|
||||||
@@ -1151,6 +1561,10 @@ ESC R ESC r ESC R = Reset System
|
|||||||
TerminalDevice->InputState = INPUT_STATE_ESC;
|
TerminalDevice->InputState = INPUT_STATE_ESC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UnicodeChar == CSI) {
|
||||||
|
TerminalDevice->InputState = INPUT_STATE_CSI;
|
||||||
|
}
|
||||||
|
|
||||||
if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {
|
if (TerminalDevice->InputState != INPUT_STATE_DEFAULT) {
|
||||||
Status = gBS->SetTimer(
|
Status = gBS->SetTimer(
|
||||||
TerminalDevice->TwoSecondTimeOut,
|
TerminalDevice->TwoSecondTimeOut,
|
||||||
|
@@ -58,6 +58,7 @@
|
|||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
DebugLib
|
DebugLib
|
||||||
PcdLib
|
PcdLib
|
||||||
|
BaseLib
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiGlobalVariableGuid # SOMETIMES_CONSUMED L"ErrOutDev"
|
gEfiGlobalVariableGuid # SOMETIMES_CONSUMED L"ErrOutDev"
|
||||||
@@ -65,13 +66,14 @@
|
|||||||
gEfiVT100Guid # SOMETIMES_CONSUMED
|
gEfiVT100Guid # SOMETIMES_CONSUMED
|
||||||
gEfiVT100PlusGuid # SOMETIMES_CONSUMED
|
gEfiVT100PlusGuid # SOMETIMES_CONSUMED
|
||||||
gEfiPcAnsiGuid # SOMETIMES_CONSUMED
|
gEfiPcAnsiGuid # SOMETIMES_CONSUMED
|
||||||
|
gSimpleTextInExNotifyGuid # SOMETIMES_CONSUMED
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiHotPlugDeviceGuid # PROTOCOL SOMETIMES_CONSUMED
|
gEfiHotPlugDeviceGuid # PROTOCOL SOMETIMES_CONSUMED
|
||||||
gEfiSerialIoProtocolGuid # PROTOCOL TO_START
|
gEfiSerialIoProtocolGuid # PROTOCOL TO_START
|
||||||
gEfiDevicePathProtocolGuid # PROTOCOL TO_START
|
gEfiDevicePathProtocolGuid # PROTOCOL TO_START
|
||||||
gEfiSimpleTextInProtocolGuid # PROTOCOL BY_START
|
gEfiSimpleTextInProtocolGuid # PROTOCOL BY_START
|
||||||
|
gEfiSimpleTextInputExProtocolGuid # PROTOCOL BY_START
|
||||||
gEfiSimpleTextOutProtocolGuid # PROTOCOL BY_START
|
gEfiSimpleTextOutProtocolGuid # PROTOCOL BY_START
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
|
Reference in New Issue
Block a user