Reviewed-by: Jaben Carsey <[email protected]> > -----Original Message----- > From: Ni, Ruiyu > Sent: Monday, February 12, 2018 7:34 AM > To: [email protected] > Cc: Felix <[email protected]>; Carsey, Jaben <[email protected]> > Subject: [PATCH] ShellPkg/[hex]edit: use SimpleTextInEx to read console > Importance: High > > 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. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ruiyu Ni <[email protected]> > Reported-by: Felix <[email protected]> > Cc: Felix <[email protected]> > Cc: Jaben Carsey <[email protected]> > --- > .../Edit/MainTextEditor.c | 135 +++++++++----- > .../Edit/TextEditorTypes.h | 21 ++- > .../UefiShellDebug1CommandsLib/EditInputBar.c | 34 +++- > .../UefiShellDebug1CommandsLib/EditInputBar.h | 6 +- > .../UefiShellDebug1CommandsLib/EditMenuBar.c | 38 +++- > .../UefiShellDebug1CommandsLib/EditMenuBar.h | 6 +- > .../HexEdit/HexEditorTypes.h | 25 +-- > .../HexEdit/MainHexEditor.c | 205 > +++++++++++++-------- > 8 files changed, 309 insertions(+), 161 deletions(-) > > diff --git > a/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c > b/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c > index 14f51dff19..a197f80a40 100644 > --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c > +++ > b/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/MainTextEditor.c > @@ -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)) { > + // > + // dispatch to different components' key handling function > + // so not everywhere has to set this variable > + // > + FileBufferMouseNeedRefresh = TRUE; > // > - // not already has some error status > + // clear previous status string > // > - if (StatusBarGetString() != NULL && StrCmp (L"", > StatusBarGetString()) > == 0) { > - StatusBarSetStatusString (L"Disk Error. Try Again"); > + 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); > > diff --git > a/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditorTypes.h > b/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditorTypes.h > index dfd56dd9a6..4cabba7b13 100644 > --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditorTypes.h > +++ > b/ShellPkg/Library/UefiShellDebug1CommandsLib/Edit/TextEditorTypes.h > @@ -1,7 +1,7 @@ > /** @file > Declares editor types. > > - Copyright (c) 2005 - 2011, 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 > @@ -87,15 +87,16 @@ typedef struct { > } EFI_EDITOR_FILE_BUFFER; > > typedef struct { > - EFI_EDITOR_FILE_BUFFER *FileBuffer; > - > - EFI_EDITOR_COLOR_UNION ColorAttributes; > - EFI_EDITOR_POSITION ScreenSize; // row number and column number > - EFI_EDITOR_LINE *CutLine; // clip board > - BOOLEAN MouseSupported; > - EFI_SIMPLE_POINTER_PROTOCOL *MouseInterface; > - INT32 MouseAccumulatorX; > - INT32 MouseAccumulatorY; > + EFI_EDITOR_FILE_BUFFER *FileBuffer; > + > + EFI_EDITOR_COLOR_UNION ColorAttributes; > + EFI_EDITOR_POSITION ScreenSize; // row number and column > number > + EFI_EDITOR_LINE *CutLine; // clip board > + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; > + BOOLEAN MouseSupported; > + EFI_SIMPLE_POINTER_PROTOCOL *MouseInterface; > + INT32 MouseAccumulatorX; > + INT32 MouseAccumulatorY; > > } EFI_EDITOR_GLOBAL_EDITOR; > > diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c > b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c > index 26f70d719a..6c6fc70bab 100644 > --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c > +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c > @@ -1,7 +1,7 @@ > /** @file > Implements inputbar interface functions. > > - Copyright (c) 2005 - 2014, 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 > @@ -18,18 +18,22 @@ > CHAR16 *mPrompt; // Input bar mPrompt string. > CHAR16 *mReturnString; // The returned string. > UINTN StringSize; // Size of mReturnString space size. > +EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *mTextInEx; > > /** > Initialize the input bar. > + > + @param[in] TextInEx Pointer to SimpleTextInEx instance in System Table. > **/ > VOID > InputBarInit ( > - VOID > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx > ) > { > mPrompt = NULL; > mReturnString = NULL; > StringSize = 0; > + mTextInEx = TextInEx; > } > > /** > @@ -125,7 +129,7 @@ InputBarRefresh ( > { > INPUT_BAR_COLOR_UNION Orig; > INPUT_BAR_COLOR_UNION New; > - EFI_INPUT_KEY Key; > + EFI_KEY_DATA KeyData; > UINTN Size; > EFI_STATUS Status; > BOOLEAN NoDisplay; > @@ -174,15 +178,25 @@ InputBarRefresh ( > // wait for user input > // > for (;;) { > - gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex); > - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); > + Status = gBS->WaitForEvent (1, &mTextInEx->WaitForKeyEx, > &EventIndex); > + if (EFI_ERROR (Status) || (EventIndex != 0)) { > + continue; > + } > + Status = mTextInEx->ReadKeyStrokeEx (mTextInEx, &KeyData); > if (EFI_ERROR (Status)) { > continue; > } > + if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && > + (KeyData.KeyState.KeyShiftState != EFI_SHIFT_STATE_VALID)) { > + // > + // Shift key pressed. > + // > + continue; > + } > // > // pressed ESC > // > - if (Key.ScanCode == SCAN_ESC) { > + if (KeyData.Key.ScanCode == SCAN_ESC) { > Size = 0; > Status = EFI_NOT_READY; > break; > @@ -190,9 +204,9 @@ InputBarRefresh ( > // > // return pressed > // > - if (Key.UnicodeChar == CHAR_LINEFEED || Key.UnicodeChar == > CHAR_CARRIAGE_RETURN) { > + if (KeyData.Key.UnicodeChar == CHAR_LINEFEED || > KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { > break; > - } else if (Key.UnicodeChar == CHAR_BACKSPACE) { > + } else if (KeyData.Key.UnicodeChar == CHAR_BACKSPACE) { > // > // backspace > // > @@ -205,11 +219,11 @@ InputBarRefresh ( > > } > } > - } else if (Key.UnicodeChar <= 127 && Key.UnicodeChar >= 32) { > + } else if (KeyData.Key.UnicodeChar <= 127 && KeyData.Key.UnicodeChar > >= 32) { > // > // VALID ASCII char pressed > // > - mReturnString[Size] = Key.UnicodeChar; > + mReturnString[Size] = KeyData.Key.UnicodeChar; > > // > // should be less than specified length > diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.h > b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.h > index f4aaee9ac5..e7e6c78680 100644 > --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.h > +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.h > @@ -1,7 +1,7 @@ > /** @file > Declares imputbar interface functions. > > - Copyright (c) 2005 - 2011, 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 > @@ -17,10 +17,12 @@ > > /** > Initialize the input bar. > + > + @param[in] TextInEx Pointer to SimpleTextInEx instance in System Table. > **/ > VOID > InputBarInit ( > - VOID > + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx > ); > > /** > diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c > b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c > index 2e00b90c6b..b86594bb28 100644 > --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c > +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.c > @@ -1,7 +1,7 @@ > /** @file > implements menubar interface functions. > > - Copyright (c) 2005 - 2011, 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 > @@ -165,7 +165,7 @@ MenuBarDispatchFunctionKey ( > /** > Function to dispatch the correct function based on a control-based key > (ctrl+o...) > > - @param[in] Key The pressed key. > + @param[in] KeyData The pressed key. > > @retval EFI_NOT_FOUND The key was not a valid control-based key > (an error was sent to the status bar). > @@ -173,17 +173,41 @@ MenuBarDispatchFunctionKey ( > **/ > EFI_STATUS > MenuBarDispatchControlHotKey ( > - IN CONST EFI_INPUT_KEY *Key > + IN CONST EFI_KEY_DATA *KeyData > ) > { > - > - if ((SCAN_CONTROL_Z < Key->UnicodeChar) > - ||(NULL == ControlBasedMenuFunctions[Key->UnicodeChar])) > + UINT16 ControlIndex; > + > + // > + // Set to invalid value first. > + // > + ControlIndex = MAX_UINT16; > + > + if ((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) { > + // > + // For those console devices that cannot report the CONTROL state, > + // Ctrl+A is translated to 1 (UnicodeChar). > + // > + ControlIndex = KeyData->Key.UnicodeChar; > + } else if (((KeyData->KeyState.KeyShiftState & > (EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED)) != 0) && > + ((KeyData->KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | > EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED)) == 0)) { > + // > + // For those console devices that can report the CONTROL state, > + // make sure only CONTROL is pressed. > + // > + if ((KeyData->Key.UnicodeChar >= L'A') && (KeyData->Key.UnicodeChar > <= L'Z')) { > + ControlIndex = KeyData->Key.UnicodeChar - L'A' + 1; > + } else if ((KeyData->Key.UnicodeChar >= L'a') && (KeyData- > >Key.UnicodeChar <= L'z')) { > + ControlIndex = KeyData->Key.UnicodeChar - L'a' + 1; > + } > + } > + if ((SCAN_CONTROL_Z < ControlIndex) > + ||(NULL == ControlBasedMenuFunctions[ControlIndex])) > { > return EFI_NOT_FOUND; > } > > - ControlBasedMenuFunctions[Key->UnicodeChar](); > + ControlBasedMenuFunctions[ControlIndex](); > return EFI_SUCCESS; > } > > diff --git a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.h > b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.h > index d545db9346..a15617edf6 100644 > --- a/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.h > +++ b/ShellPkg/Library/UefiShellDebug1CommandsLib/EditMenuBar.h > @@ -1,7 +1,7 @@ > /** @file > Declares menubar interface functions. > > - Copyright (c) 2005 - 2011, 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 > @@ -105,7 +105,7 @@ MenuBarDispatchFunctionKey ( > /** > Function to dispatch the correct function based on a control-based key > (ctrl+o...) > > - @param[in] Key The pressed key. > + @param[in] KeyData The pressed key. > > @retval EFI_NOT_FOUND The key was not a valid control-based key > (an error was sent to the status bar). > @@ -113,7 +113,7 @@ MenuBarDispatchFunctionKey ( > **/ > EFI_STATUS > MenuBarDispatchControlHotKey ( > - IN CONST EFI_INPUT_KEY *Key > + IN CONST EFI_KEY_DATA *KeyData > ); > > #endif > diff --git > a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes. > h > b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes. > h > index 8f0da3b667..2a0429a4a1 100644 > --- > a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes. > h > +++ > b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/HexEditorTypes. > h > @@ -1,7 +1,7 @@ > /** @file > data types that are used by editor > > - Copyright (c) 2005 - 2017, 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 > @@ -109,17 +109,18 @@ typedef struct { > } HEFI_EDITOR_BUFFER_IMAGE; > > typedef struct { > - HEFI_EDITOR_BUFFER_IMAGE *BufferImage; > - > - HEFI_EDITOR_COLOR_UNION ColorAttributes; > - HEFI_EDITOR_POSITION ScreenSize; // row number and column > number > - BOOLEAN MouseSupported; > - EFI_SIMPLE_POINTER_PROTOCOL *MouseInterface; > - INT32 MouseAccumulatorX; > - INT32 MouseAccumulatorY; > - > - UINTN SelectStart; // starting from 1 > - UINTN SelectEnd; // starting from 1 > + HEFI_EDITOR_BUFFER_IMAGE *BufferImage; > + > + HEFI_EDITOR_COLOR_UNION ColorAttributes; > + HEFI_EDITOR_POSITION ScreenSize; // row number and > column number > + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx; > + BOOLEAN MouseSupported; > + EFI_SIMPLE_POINTER_PROTOCOL *MouseInterface; > + INT32 MouseAccumulatorX; > + INT32 MouseAccumulatorY; > + > + UINTN SelectStart; // starting from 1 > + UINTN SelectEnd; // starting from 1 > } HEFI_EDITOR_GLOBAL_EDITOR; > > #endif > diff --git > a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c > b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c > index 491acb131e..065f8e95a7 100644 > --- > a/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c > +++ > b/ShellPkg/Library/UefiShellDebug1CommandsLib/HexEdit/MainHexEditor.c > @@ -4,7 +4,7 @@ > - Instances of the other objects of the editor > - Main Interfaces > > - Copyright (c) 2005 - 2012, 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 > @@ -56,6 +56,7 @@ HEFI_EDITOR_GLOBAL_EDITOR HMainEditorConst = { > 0, > 0 > }, > + NULL, > FALSE, > NULL, > 0, > @@ -105,22 +106,53 @@ HMainCommandDisplayHelp ( > VOID > ) > { > - INT32 CurrentLine; > - CHAR16 * InfoString; > - EFI_INPUT_KEY Key; > - > - CurrentLine = 0; > + INT32 CurrentLine; > + CHAR16 *InfoString; > + EFI_KEY_DATA KeyData; > + EFI_STATUS Status; > + UINTN EventIndex; > + > + // > // print helpInfo > + // > for (CurrentLine = 0; 0 != HexMainMenuHelpInfo[CurrentLine]; > CurrentLine++) { > InfoString = HiiGetString(gShellDebug1HiiHandle, > HexMainMenuHelpInfo[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, &HMainEditor.TextInputEx- > >WaitForKeyEx, &EventIndex); > + if (EFI_ERROR (Status) || (EventIndex != 0)) { > + continue; > + } > + Status = HMainEditor.TextInputEx->ReadKeyStrokeEx > (HMainEditor.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 buffer's info > HBufferImageNeedRefresh = TRUE; > @@ -1633,6 +1665,19 @@ HMainEditorInit ( > &(HMainEditor.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**)&HMainEditor.TextInputEx > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > // > // Find mouse in System Table ConsoleInHandle > // > @@ -1706,7 +1751,7 @@ HMainEditorInit ( > return EFI_LOAD_ERROR; > } > > - InputBarInit (); > + InputBarInit (HMainEditor.TextInputEx); > > Status = HBufferImageInit (); > if (EFI_ERROR (Status)) { > @@ -2058,9 +2103,11 @@ HMainEditorKeyInput ( > VOID > ) > { > - EFI_INPUT_KEY Key; > + EFI_KEY_DATA KeyData; > EFI_STATUS Status; > EFI_SIMPLE_POINTER_STATE MouseState; > + UINTN EventIndex; > + BOOLEAN NoShiftState; > BOOLEAN LengthChange; > UINTN Size; > UINTN OldSize; > @@ -2219,84 +2266,94 @@ HMainEditorKeyInput ( > } > } > > - 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 > - // > - HBufferImageMouseNeedRefresh = TRUE; > - > - // > - // clear previous status string > - // > - StatusBarSetRefresh(); > - if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&Key)) { > - Status = EFI_SUCCESS; > - } else if (Key.ScanCode == SCAN_NULL) { > - Status = HBufferImageHandleInput (&Key); > - } else if (((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= > SCAN_PAGE_DOWN))) { > - Status = HBufferImageHandleInput (&Key); > - } else if (((Key.ScanCode >= SCAN_F1) && Key.ScanCode <= > (SCAN_F12))) { > - Status = MenuBarDispatchFunctionKey (&Key); > - } else { > - StatusBarSetStatusString (L"Unknown Command"); > - > - HBufferImageMouseNeedRefresh = FALSE; > - } > + Status = gBS->WaitForEvent (1, &HMainEditor.TextInputEx- > >WaitForKeyEx, &EventIndex); > + if (!EFI_ERROR (Status) && EventIndex == 0) { > + Status = HMainEditor.TextInputEx->ReadKeyStrokeEx > (HMainEditor.TextInputEx, &KeyData); > + if (!EFI_ERROR (Status)) { > + // > + // dispatch to different components' key handling function > + // so not everywhere has to set this variable > + // > + HBufferImageMouseNeedRefresh = TRUE; > > - if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) { > // > - // not already has some error status > + // clear previous status string > // > - if (StrCmp (L"", StatusBarGetString()) == 0) { > - StatusBarSetStatusString (L"Disk Error. Try Again"); > + 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_SUCCESS == MenuBarDispatchControlHotKey(&KeyData)) { > + Status = EFI_SUCCESS; > + } else if (NoShiftState && KeyData.Key.ScanCode == SCAN_NULL) { > + Status = HBufferImageHandleInput (&KeyData.Key); > + } else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_UP) && > (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN))) { > + Status = HBufferImageHandleInput (&KeyData.Key); > + } else if (NoShiftState && ((KeyData.Key.ScanCode >= SCAN_F1) && > KeyData.Key.ScanCode <= SCAN_F12)) { > + Status = MenuBarDispatchFunctionKey (&KeyData.Key); > + } else { > + StatusBarSetStatusString (L"Unknown Command"); > + > + HBufferImageMouseNeedRefresh = FALSE; > + } > + > + if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) { > + // > + // not already has some error status > + // > + if (StrCmp (L"", StatusBarGetString()) == 0) { > + StatusBarSetStatusString (L"Disk Error. Try Again"); > + } > } > } > - } > - // > - // decide if has to set length warning > - // > - if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) { > - LengthChange = FALSE; > - } else { > // > - // still the old buffer > + // decide if has to set length warning > // > - if (HBufferImage.BufferType != FileTypeFileBuffer) { > - Size = HBufferImageGetTotalSize (); > + if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) { > + LengthChange = FALSE; > + } else { > + // > + // still the old buffer > + // > + if (HBufferImage.BufferType != FileTypeFileBuffer) { > + Size = HBufferImageGetTotalSize (); > > - switch (HBufferImage.BufferType) { > - case FileTypeDiskBuffer: > - OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage- > >BlockSize; > - break; > + switch (HBufferImage.BufferType) { > + case FileTypeDiskBuffer: > + OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage- > >BlockSize; > + break; > > - case FileTypeMemBuffer: > - OldSize = HBufferImage.MemImage->Size; > - break; > + case FileTypeMemBuffer: > + OldSize = HBufferImage.MemImage->Size; > + break; > > - default: > - OldSize = 0; > - break; > - } > + default: > + OldSize = 0; > + break; > + } > > - if (!LengthChange) { > - if (OldSize != Size) { > - StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be > changed"); > + if (!LengthChange) { > + if (OldSize != Size) { > + StatusBarSetStatusString (L"Disk/Mem Buffer Length should not > be > changed"); > + } > } > - } > > - if (OldSize != Size) { > - LengthChange = TRUE; > - } else { > - LengthChange = FALSE; > + if (OldSize != Size) { > + LengthChange = TRUE; > + } else { > + LengthChange = FALSE; > + } > } > } > + // > + // after handling, refresh editor > + // > + HMainEditorRefresh (); > } > - // > - // after handling, refresh editor > - // > - HMainEditorRefresh (); > > } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit); > > -- > 2.16.1.windows.1
_______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

