ShellPkg/[hex]edit: use SimpleTextInEx to read console
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=682 Edit and HexEdit commands assume that SimpleTxtIn translates Ctrl+<Alpha-Key> key combinations into Unicode control characters (0x1-0x1A). Such translation does not seem to be required by the UEFI spec. Shell should not rely on implementation specific behavior. It should instead use SimpleTextInEx to read Ctrl+<Alpha-Key> key combinations. The patch changes edit and hexedit to only consumes SimpleTextInEx so that the implementation specific behavior dependency is removed. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reported-by: Felix <felixp@mail.ru> Cc: Felix <felixp@mail.ru> Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
Implements editor interface functions.
|
||||
|
||||
Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved. <BR>
|
||||
Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
|
||||
This program and the accompanying materials
|
||||
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
|
||||
@ -1362,7 +1362,9 @@ MainCommandDisplayHelp (
|
||||
{
|
||||
INT32 CurrentLine;
|
||||
CHAR16 *InfoString;
|
||||
EFI_INPUT_KEY Key;
|
||||
EFI_KEY_DATA KeyData;
|
||||
EFI_STATUS Status;
|
||||
UINTN EventIndex;
|
||||
|
||||
//
|
||||
// print helpInfo
|
||||
@ -1371,14 +1373,39 @@ MainCommandDisplayHelp (
|
||||
InfoString = HiiGetString(gShellDebug1HiiHandle, MainMenuHelpInfo[CurrentLine], NULL);
|
||||
ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// scan for ctrl+w
|
||||
//
|
||||
do {
|
||||
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
||||
} while(SCAN_CONTROL_W != Key.UnicodeChar);
|
||||
while (TRUE) {
|
||||
Status = gBS->WaitForEvent (1, &MainEditor.TextInputEx->WaitForKeyEx, &EventIndex);
|
||||
if (EFI_ERROR (Status) || (EventIndex != 0)) {
|
||||
continue;
|
||||
}
|
||||
Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) {
|
||||
//
|
||||
// For consoles that don't support shift state reporting,
|
||||
// CTRL+W is translated to L'W' - L'A' + 1.
|
||||
//
|
||||
if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) {
|
||||
break;
|
||||
}
|
||||
} else if (((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) &&
|
||||
((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0)) {
|
||||
//
|
||||
// For consoles that supports shift state reporting,
|
||||
// make sure that only CONTROL shift key is pressed.
|
||||
//
|
||||
if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// update screen with file buffer's info
|
||||
//
|
||||
@ -1407,6 +1434,7 @@ EFI_EDITOR_GLOBAL_EDITOR MainEditorConst = {
|
||||
0
|
||||
},
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
NULL
|
||||
};
|
||||
@ -1452,6 +1480,19 @@ MainEditorInit (
|
||||
&(MainEditor.ScreenSize.Row)
|
||||
);
|
||||
|
||||
//
|
||||
// Find TextInEx in System Table ConsoleInHandle
|
||||
// Per UEFI Spec, TextInEx is required for a console capable platform.
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
gST->ConsoleInHandle,
|
||||
&gEfiSimpleTextInputExProtocolGuid,
|
||||
(VOID**)&MainEditor.TextInputEx
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Find mouse in System Table ConsoleInHandle
|
||||
//
|
||||
@ -1521,7 +1562,7 @@ MainEditorInit (
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
|
||||
InputBarInit ();
|
||||
InputBarInit (MainEditor.TextInputEx);
|
||||
|
||||
Status = FileBufferInit ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -1794,9 +1835,11 @@ MainEditorKeyInput (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_INPUT_KEY Key;
|
||||
EFI_KEY_DATA KeyData;
|
||||
EFI_STATUS Status;
|
||||
EFI_SIMPLE_POINTER_STATE MouseState;
|
||||
UINTN EventIndex;
|
||||
BOOLEAN NoShiftState;
|
||||
|
||||
do {
|
||||
|
||||
@ -1831,46 +1874,52 @@ MainEditorKeyInput (
|
||||
}
|
||||
}
|
||||
|
||||
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// dispatch to different components' key handling function
|
||||
// so not everywhere has to set this variable
|
||||
//
|
||||
FileBufferMouseNeedRefresh = TRUE;
|
||||
//
|
||||
// clear previous status string
|
||||
//
|
||||
StatusBarSetRefresh();
|
||||
|
||||
//
|
||||
// dispatch to different components' key handling function
|
||||
//
|
||||
if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey(&Key)) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else if ((Key.ScanCode == SCAN_NULL) || ((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {
|
||||
Status = FileBufferHandleInput (&Key);
|
||||
} else if ((Key.ScanCode >= SCAN_F1) && (Key.ScanCode <= SCAN_F12)) {
|
||||
Status = MenuBarDispatchFunctionKey (&Key);
|
||||
} else {
|
||||
StatusBarSetStatusString (L"Unknown Command");
|
||||
FileBufferMouseNeedRefresh = FALSE;
|
||||
}
|
||||
|
||||
if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
|
||||
Status = gBS->WaitForEvent (1, &MainEditor.TextInputEx->WaitForKeyEx, &EventIndex);
|
||||
if (!EFI_ERROR (Status) && EventIndex == 0) {
|
||||
Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// not already has some error status
|
||||
// dispatch to different components' key handling function
|
||||
// so not everywhere has to set this variable
|
||||
//
|
||||
if (StatusBarGetString() != NULL && StrCmp (L"", StatusBarGetString()) == 0) {
|
||||
StatusBarSetStatusString (L"Disk Error. Try Again");
|
||||
FileBufferMouseNeedRefresh = TRUE;
|
||||
//
|
||||
// clear previous status string
|
||||
//
|
||||
StatusBarSetRefresh();
|
||||
//
|
||||
// NoShiftState: TRUE when no shift key is pressed.
|
||||
//
|
||||
NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID);
|
||||
//
|
||||
// dispatch to different components' key handling function
|
||||
//
|
||||
if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey(&KeyData)) {
|
||||
Status = EFI_SUCCESS;
|
||||
} else if (NoShiftState && ((KeyData.Key.ScanCode == SCAN_NULL) || ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN)))) {
|
||||
Status = FileBufferHandleInput (&KeyData.Key);
|
||||
} else if (NoShiftState && (KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12)) {
|
||||
Status = MenuBarDispatchFunctionKey (&KeyData.Key);
|
||||
} else {
|
||||
StatusBarSetStatusString (L"Unknown Command");
|
||||
FileBufferMouseNeedRefresh = FALSE;
|
||||
}
|
||||
|
||||
if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
|
||||
//
|
||||
// not already has some error status
|
||||
//
|
||||
if (StatusBarGetString() != NULL && StrCmp (L"", StatusBarGetString()) == 0) {
|
||||
StatusBarSetStatusString (L"Disk Error. Try Again");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//
|
||||
// after handling, refresh editor
|
||||
//
|
||||
MainEditorRefresh ();
|
||||
}
|
||||
//
|
||||
// after handling, refresh editor
|
||||
//
|
||||
MainEditorRefresh ();
|
||||
|
||||
} while (Status != EFI_OUT_OF_RESOURCES && !EditorExit);
|
||||
|
||||
|
Reference in New Issue
Block a user