mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/ConSplitter: ReadKeyStrokeEx always return key state
Today's implementation only return key state when there is key. But when user doesn't press any key, the key state cannot be returned. The patch changes the ReadKeyStrokeEx() to always return the key state even there is no key pressed. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
parent
2de87e461d
commit
20ddbc133f
|
@ -16,7 +16,7 @@
|
||||||
never removed. Such design ensures sytem function well during none console
|
never removed. Such design ensures sytem function well during none console
|
||||||
device situation.
|
device situation.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
|
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -67,6 +67,8 @@ GLOBAL_REMOVE_IF_UNREFERENCED TEXT_IN_SPLITTER_PRIVATE_DATA mConIn = {
|
||||||
(LIST_ENTRY *) NULL,
|
(LIST_ENTRY *) NULL,
|
||||||
(LIST_ENTRY *) NULL
|
(LIST_ENTRY *) NULL
|
||||||
},
|
},
|
||||||
|
(EFI_KEY_DATA *) NULL,
|
||||||
|
0,
|
||||||
0,
|
0,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
|
||||||
|
@ -606,6 +608,7 @@ ConSplitterTextInConstructor (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
UINTN TextInExListCount;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate buffer for Simple Text Input device
|
// Allocate buffer for Simple Text Input device
|
||||||
|
@ -631,6 +634,19 @@ ConSplitterTextInConstructor (
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate buffer for KeyQueue
|
||||||
|
//
|
||||||
|
TextInExListCount = ConInPrivate->TextInExListCount;
|
||||||
|
Status = ConSplitterGrowBuffer (
|
||||||
|
sizeof (EFI_KEY_DATA),
|
||||||
|
&TextInExListCount,
|
||||||
|
(VOID **) &ConInPrivate->KeyQueue
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate buffer for Simple Text Input Ex device
|
// Allocate buffer for Simple Text Input Ex device
|
||||||
//
|
//
|
||||||
|
@ -1968,6 +1984,17 @@ ConSplitterTextInExAddDevice (
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextInExListCount = Private->TextInExListCount;
|
||||||
|
Status = ConSplitterGrowBuffer (
|
||||||
|
sizeof (EFI_KEY_DATA),
|
||||||
|
&TextInExListCount,
|
||||||
|
(VOID **) &Private->KeyQueue
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
Status = ConSplitterGrowBuffer (
|
Status = ConSplitterGrowBuffer (
|
||||||
sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),
|
sizeof (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *),
|
||||||
&Private->TextInExListCount,
|
&Private->TextInExListCount,
|
||||||
|
@ -3445,11 +3472,46 @@ ConSplitterTextInReset (
|
||||||
|
|
||||||
if (!EFI_ERROR (ReturnStatus)) {
|
if (!EFI_ERROR (ReturnStatus)) {
|
||||||
ToggleStateSyncReInitialization (Private);
|
ToggleStateSyncReInitialization (Private);
|
||||||
|
//
|
||||||
|
// Empty the key queue.
|
||||||
|
//
|
||||||
|
Private->CurrentNumberOfKeys = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReturnStatus;
|
return ReturnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Dequeue the saved key from internal key queue.
|
||||||
|
|
||||||
|
@param Private Protocol instance pointer.
|
||||||
|
@param KeyData A pointer to a buffer that is filled in with the
|
||||||
|
keystroke state data for the key that was
|
||||||
|
pressed.
|
||||||
|
@retval EFI_NOT_FOUND Queue is empty.
|
||||||
|
@retval EFI_SUCCESS First key is dequeued and returned.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
ConSplitterTextInExDequeueKey (
|
||||||
|
IN TEXT_IN_SPLITTER_PRIVATE_DATA *Private,
|
||||||
|
OUT EFI_KEY_DATA *KeyData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Private->CurrentNumberOfKeys == 0) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Return the first saved key.
|
||||||
|
//
|
||||||
|
CopyMem (KeyData, &Private->KeyQueue[0], sizeof (EFI_KEY_DATA));
|
||||||
|
Private->CurrentNumberOfKeys--;
|
||||||
|
CopyMem (
|
||||||
|
&Private->KeyQueue[0],
|
||||||
|
&Private->KeyQueue[1],
|
||||||
|
Private->CurrentNumberOfKeys * sizeof (EFI_KEY_DATA)
|
||||||
|
);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reads the next keystroke from the input device. The WaitForKey Event can
|
Reads the next keystroke from the input device. The WaitForKey Event can
|
||||||
|
@ -3473,7 +3535,21 @@ ConSplitterTextInPrivateReadKeyStroke (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
EFI_INPUT_KEY CurrentKey;
|
EFI_KEY_DATA KeyData;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the first saved non-NULL key.
|
||||||
|
//
|
||||||
|
while (TRUE) {
|
||||||
|
Status = ConSplitterTextInExDequeueKey (Private, &KeyData);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((KeyData.Key.ScanCode != CHAR_NULL) || (KeyData.Key.UnicodeChar != SCAN_NULL)) {
|
||||||
|
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Key->UnicodeChar = 0;
|
Key->UnicodeChar = 0;
|
||||||
Key->ScanCode = SCAN_NULL;
|
Key->ScanCode = SCAN_NULL;
|
||||||
|
@ -3486,15 +3562,15 @@ ConSplitterTextInPrivateReadKeyStroke (
|
||||||
for (Index = 0; Index < Private->CurrentNumberOfConsoles;) {
|
for (Index = 0; Index < Private->CurrentNumberOfConsoles;) {
|
||||||
Status = Private->TextInList[Index]->ReadKeyStroke (
|
Status = Private->TextInList[Index]->ReadKeyStroke (
|
||||||
Private->TextInList[Index],
|
Private->TextInList[Index],
|
||||||
&CurrentKey
|
&KeyData.Key
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// If it is not partial keystorke, return the key. Otherwise, continue
|
// If it is not partial keystorke, return the key. Otherwise, continue
|
||||||
// to read key from THIS physical console input device.
|
// to read key from THIS physical console input device.
|
||||||
//
|
//
|
||||||
if ((CurrentKey.ScanCode != CHAR_NULL) || (CurrentKey.UnicodeChar != SCAN_NULL)) {
|
if ((KeyData.Key.ScanCode != CHAR_NULL) || (KeyData.Key.UnicodeChar != SCAN_NULL)) {
|
||||||
*Key = CurrentKey;
|
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -3681,6 +3757,10 @@ ConSplitterTextInResetEx (
|
||||||
|
|
||||||
if (!EFI_ERROR (ReturnStatus)) {
|
if (!EFI_ERROR (ReturnStatus)) {
|
||||||
ToggleStateSyncReInitialization (Private);
|
ToggleStateSyncReInitialization (Private);
|
||||||
|
//
|
||||||
|
// Empty the key queue.
|
||||||
|
//
|
||||||
|
Private->CurrentNumberOfKeys = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReturnStatus;
|
return ReturnStatus;
|
||||||
|
@ -3714,6 +3794,7 @@ ConSplitterTextInReadKeyStrokeEx (
|
||||||
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
|
TEXT_IN_SPLITTER_PRIVATE_DATA *Private;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
|
EFI_KEY_STATE KeyState;
|
||||||
EFI_KEY_DATA CurrentKeyData;
|
EFI_KEY_DATA CurrentKeyData;
|
||||||
|
|
||||||
|
|
||||||
|
@ -3725,9 +3806,6 @@ ConSplitterTextInReadKeyStrokeEx (
|
||||||
|
|
||||||
Private->KeyEventSignalState = FALSE;
|
Private->KeyEventSignalState = FALSE;
|
||||||
|
|
||||||
KeyData->Key.UnicodeChar = 0;
|
|
||||||
KeyData->Key.ScanCode = SCAN_NULL;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Signal ConnectConIn event on first call in Lazy ConIn mode
|
// Signal ConnectConIn event on first call in Lazy ConIn mode
|
||||||
//
|
//
|
||||||
|
@ -3738,35 +3816,81 @@ ConSplitterTextInReadKeyStrokeEx (
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// if no physical console input device exists, return EFI_NOT_READY;
|
// Return the first saved key.
|
||||||
// if any physical console input device has key input,
|
|
||||||
// return the key and EFI_SUCCESS.
|
|
||||||
//
|
//
|
||||||
for (Index = 0; Index < Private->CurrentNumberOfExConsoles;) {
|
Status = ConSplitterTextInExDequeueKey (Private, KeyData);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
ASSERT (Private->CurrentNumberOfKeys == 0);
|
||||||
|
|
||||||
|
ZeroMem (&KeyState, sizeof (KeyState));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Iterate through all physical consoles to get key state.
|
||||||
|
// Some physical consoles may return valid key.
|
||||||
|
// Queue the valid keys.
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < Private->CurrentNumberOfExConsoles; Index++) {
|
||||||
|
ZeroMem (&CurrentKeyData, sizeof (EFI_KEY_DATA));
|
||||||
Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
|
Status = Private->TextInExList[Index]->ReadKeyStrokeEx (
|
||||||
Private->TextInExList[Index],
|
Private->TextInExList[Index],
|
||||||
&CurrentKeyData
|
&CurrentKeyData
|
||||||
);
|
);
|
||||||
|
if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Consolidate the key state from all physical consoles.
|
||||||
|
//
|
||||||
|
if ((CurrentKeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) {
|
||||||
|
KeyState.KeyShiftState |= CurrentKeyData.KeyState.KeyShiftState;
|
||||||
|
}
|
||||||
|
if ((CurrentKeyData.KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != 0) {
|
||||||
|
KeyState.KeyToggleState |= CurrentKeyData.KeyState.KeyToggleState;
|
||||||
|
}
|
||||||
|
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
//
|
//
|
||||||
// If virtual KeyState has been required to be exposed, or it is not
|
// If virtual KeyState has been required to be exposed, or it is not
|
||||||
// partial keystorke, return the key. Otherwise, continue to read key
|
// partial keystorke, queue the key.
|
||||||
// from THIS physical console input device.
|
// It's possible that user presses at multiple keyboards at the same moment,
|
||||||
|
// Private->KeyQueue[] are the storage to save all the keys.
|
||||||
//
|
//
|
||||||
if ((Private->VirtualKeyStateExported) ||
|
if ((Private->VirtualKeyStateExported) ||
|
||||||
(CurrentKeyData.Key.ScanCode != CHAR_NULL) ||
|
(CurrentKeyData.Key.ScanCode != CHAR_NULL) ||
|
||||||
(CurrentKeyData.Key.UnicodeChar != SCAN_NULL)) {
|
(CurrentKeyData.Key.UnicodeChar != SCAN_NULL)) {
|
||||||
CopyMem (KeyData, &CurrentKeyData, sizeof (CurrentKeyData));
|
CopyMem (
|
||||||
return Status;
|
&Private->KeyQueue[Private->CurrentNumberOfKeys],
|
||||||
|
&CurrentKeyData,
|
||||||
|
sizeof (EFI_KEY_DATA)
|
||||||
|
);
|
||||||
|
Private->CurrentNumberOfKeys++;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// Continue to read key from NEXT physical console input device.
|
|
||||||
//
|
|
||||||
Index++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Consolidate the key state for all keys in Private->KeyQueue[]
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < Private->CurrentNumberOfKeys; Index++) {
|
||||||
|
CopyMem (&Private->KeyQueue[Index].KeyState, &KeyState, sizeof (EFI_KEY_STATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the first saved key.
|
||||||
|
//
|
||||||
|
Status = ConSplitterTextInExDequeueKey (Private, KeyData);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Always return the key state even there is no key pressed.
|
||||||
|
//
|
||||||
|
ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
|
||||||
|
CopyMem (&KeyData->KeyState, &KeyState, sizeof (KeyData->KeyState));
|
||||||
return EFI_NOT_READY;
|
return EFI_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
Private data structures for the Console Splitter driver
|
Private data structures for the Console Splitter driver
|
||||||
|
|
||||||
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -129,6 +129,8 @@ typedef struct {
|
||||||
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **TextInExList;
|
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL **TextInExList;
|
||||||
UINTN TextInExListCount;
|
UINTN TextInExListCount;
|
||||||
LIST_ENTRY NotifyList;
|
LIST_ENTRY NotifyList;
|
||||||
|
EFI_KEY_DATA *KeyQueue;
|
||||||
|
UINTN CurrentNumberOfKeys;
|
||||||
//
|
//
|
||||||
// It will be initialized and synced between console input devices
|
// It will be initialized and synced between console input devices
|
||||||
// for toggle state sync.
|
// for toggle state sync.
|
||||||
|
|
Loading…
Reference in New Issue