/** @file implements menubar interface functions. Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "EditMenuBar.h" #include "UefiShellDebug1CommandsLib.h" #include "EditStatusBar.h" EDITOR_MENU_ITEM *MenuItems; MENU_ITEM_FUNCTION *ControlBasedMenuFunctions; UINTN NumItems; /** Cleanup function for a menu bar. frees all allocated memory. **/ VOID MenuBarCleanup ( VOID ) { SHELL_FREE_NON_NULL(MenuItems); } /** Initialize the menu bar with the specified items. @param[in] Items The items to display and their functions. @retval EFI_SUCCESS The initialization was correct. @retval EFI_OUT_OF_RESOURCES A memory allocation failed. **/ EFI_STATUS MenuBarInit ( IN CONST EDITOR_MENU_ITEM *Items ) { CONST EDITOR_MENU_ITEM *ItemsWalker; for (NumItems = 0, ItemsWalker = Items ; ItemsWalker != NULL && ItemsWalker->Function != NULL ; ItemsWalker++,NumItems++); MenuItems = AllocateZeroPool((NumItems+1) * sizeof(EDITOR_MENU_ITEM)); if (MenuItems == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem(MenuItems, Items, (NumItems+1) * sizeof(EDITOR_MENU_ITEM)); return EFI_SUCCESS; } /** Initialize the control hot-key with the specified items. @param[in] Items The hot-key functions. @retval EFI_SUCCESS The initialization was correct. **/ EFI_STATUS ControlHotKeyInit ( IN MENU_ITEM_FUNCTION *Items ) { ControlBasedMenuFunctions = Items; return EFI_SUCCESS; } /** Refresh function for the menu bar. @param[in] LastRow The last printable row. @param[in] LastCol The last printable column. @retval EFI_SUCCESS The refresh was successful. **/ EFI_STATUS MenuBarRefresh ( IN CONST UINTN LastRow, IN CONST UINTN LastCol ) { EDITOR_MENU_ITEM *Item; UINTN Col; UINTN Row; UINTN Width; CHAR16 *NameString; CHAR16 *FunctionKeyString; // // variable initialization // Col = 1; Row = (LastRow - 2); // // clear menu bar rows // EditorClearLine (LastRow - 2, LastCol, LastRow); EditorClearLine (LastRow - 1, LastCol, LastRow); EditorClearLine (LastRow , LastCol, LastRow); // // print out the menu items // for (Item = MenuItems; Item != NULL && Item->Function != NULL; Item++) { NameString = HiiGetString(gShellDebug1HiiHandle, Item->NameToken, NULL); Width = MAX ((StrLen (NameString) + 6), 20); if (((Col + Width) > LastCol)) { Row++; Col = 1; } FunctionKeyString = HiiGetString(gShellDebug1HiiHandle, Item->FunctionKeyToken, NULL); ShellPrintEx ((INT32)(Col) - 1, (INT32)(Row) - 1, L"%E%s%N %H%s%N ", FunctionKeyString, NameString); FreePool (NameString); FreePool (FunctionKeyString); Col += Width; } return EFI_SUCCESS; } /** Function to dispatch the correct function based on a function key (F1...) @param[in] Key The pressed key. @retval EFI_NOT_FOUND The key was not a valid function key (an error was sent to the status bar). @return The return value from the called dispatch function. **/ EFI_STATUS MenuBarDispatchFunctionKey ( IN CONST EFI_INPUT_KEY *Key ) { UINTN Index; Index = Key->ScanCode - SCAN_F1; // // check whether in range // if (Index > (NumItems - 1)) { StatusBarSetStatusString (L"Unknown Command"); return EFI_SUCCESS; } return (MenuItems[Index].Function ()); } /** Function to dispatch the correct function based on a control-based key (ctrl+o...) @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). @return EFI_SUCCESS. **/ EFI_STATUS MenuBarDispatchControlHotKey ( IN CONST EFI_KEY_DATA *KeyData ) { UINT16 ControlIndex; // // Set to invalid value first. // ControlIndex = MAX_UINT16; if (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData->KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) { // // For consoles that don't support/report shift state, // Ctrl+A is translated to 1 (UnicodeChar). // ControlIndex = KeyData->Key.UnicodeChar; } else if (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && ((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 consoles that supports/reports shift 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[ControlIndex](); return EFI_SUCCESS; }