Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chen A Chen <chen.a.chen@intel.com> Reviewed-by: Jaben Carsey <jaben.carsey@intel.com> Reviewed-by: Ruiyu Ni <Ruiyu.ni@intel.com>
		
			
				
	
	
		
			317 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			317 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Implements inputbar interface functions.
 | |
| 
 | |
|   Copyright (c) 2005 - 2014, 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
 | |
|   http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
|   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
|   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "EditInputBar.h"
 | |
| #include "UefiShellDebug1CommandsLib.h"
 | |
| 
 | |
| CHAR16  *mPrompt;        // Input bar mPrompt string.
 | |
| CHAR16  *mReturnString;  // The returned string.
 | |
| UINTN   StringSize;      // Size of mReturnString space size.
 | |
| 
 | |
| /**
 | |
|   Initialize the input bar.
 | |
| **/
 | |
| VOID
 | |
| InputBarInit (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   mPrompt       = NULL;
 | |
|   mReturnString = NULL;
 | |
|   StringSize    = 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Cleanup function for input bar.
 | |
| **/
 | |
| VOID
 | |
| InputBarCleanup (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // free input bar's prompt and input string
 | |
|   //
 | |
|   SHELL_FREE_NON_NULL (mPrompt);
 | |
|   SHELL_FREE_NON_NULL (mReturnString);
 | |
|   mPrompt       = NULL;
 | |
|   mReturnString = NULL;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Display the prompt.
 | |
|   Do the requesting of input.
 | |
| 
 | |
|   @param[in]  LastColumn   The last printable column.
 | |
|   @param[in]  LastRow      The last printable row.
 | |
| **/
 | |
| VOID
 | |
| InputBarPrintInput (
 | |
|   IN UINTN LastColumn,
 | |
|   IN UINTN LastRow
 | |
|   )
 | |
| {
 | |
|   UINTN   Limit;
 | |
|   UINTN   Size;
 | |
|   CHAR16  *Buffer;
 | |
|   UINTN   Index;
 | |
|   UINTN   mPromptLen;
 | |
| 
 | |
|   mPromptLen = StrLen (mPrompt);
 | |
|   Limit     = LastColumn - mPromptLen - 1;
 | |
|   Size      = StrLen (mReturnString);
 | |
| 
 | |
|   //
 | |
|   // check whether the mPrompt length and input length will
 | |
|   // exceed limit
 | |
|   //
 | |
|   if (Size <= Limit) {
 | |
|     Buffer = mReturnString;
 | |
|   } else {
 | |
|     Buffer = mReturnString + Size - Limit;
 | |
|   }
 | |
| 
 | |
|   gST->ConOut->EnableCursor (gST->ConOut, FALSE);
 | |
| 
 | |
|   ShellPrintEx (((INT32)mPromptLen), ((INT32)LastRow) - 1, L"%s", Buffer);
 | |
|   Size = StrLen (Buffer);
 | |
| 
 | |
|   //
 | |
|   // print " " after mPrompt
 | |
|   //
 | |
|   for (Index = Size; Index < Limit; Index++) {
 | |
|     ShellPrintEx ((INT32)(mPromptLen + Size), ((INT32)LastRow) - 1, L" ");
 | |
|   }
 | |
| 
 | |
|   gST->ConOut->EnableCursor (gST->ConOut, TRUE);
 | |
|   gST->ConOut->SetCursorPosition (gST->ConOut, Size + mPromptLen, LastRow - 1);
 | |
| }
 | |
| 
 | |
| typedef struct {
 | |
|   UINT32  Foreground : 4;
 | |
|   UINT32  Background : 3;
 | |
| } INPUT_BAR_COLOR_ATTRIBUTES;
 | |
| 
 | |
| typedef union {
 | |
|   INPUT_BAR_COLOR_ATTRIBUTES  Colors;
 | |
|   UINTN                       Data;
 | |
| } INPUT_BAR_COLOR_UNION;
 | |
| 
 | |
| 
 | |
| /**
 | |
|   The refresh function for InputBar, it will wait for user input
 | |
| 
 | |
|   @param[in] LastRow            The last printable row.
 | |
|   @param[in] LastColumn         The last printable column.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The operation was successful.
 | |
| **/
 | |
| EFI_STATUS
 | |
| InputBarRefresh (
 | |
|   UINTN LastRow,
 | |
|   UINTN LastColumn
 | |
|   )
 | |
| {
 | |
|   INPUT_BAR_COLOR_UNION   Orig;
 | |
|   INPUT_BAR_COLOR_UNION   New;
 | |
|   EFI_INPUT_KEY           Key;
 | |
|   UINTN                   Size;
 | |
|   EFI_STATUS              Status;
 | |
|   BOOLEAN                 NoDisplay;
 | |
|   UINTN                   EventIndex;
 | |
|   UINTN                   CursorRow;
 | |
|   UINTN                   CursorCol;
 | |
| 
 | |
|   //
 | |
|   // variable initialization
 | |
|   //
 | |
|   Size    = 0;
 | |
|   Status  = EFI_SUCCESS;
 | |
| 
 | |
|   //
 | |
|   // back up the old screen attributes
 | |
|   //
 | |
|   CursorCol             = gST->ConOut->Mode->CursorColumn;
 | |
|   CursorRow             = gST->ConOut->Mode->CursorRow;
 | |
|   Orig.Data             = gST->ConOut->Mode->Attribute;
 | |
|   New.Data              = 0;
 | |
|   New.Colors.Foreground = Orig.Colors.Background & 0xF;
 | |
|   New.Colors.Background = Orig.Colors.Foreground & 0x7;
 | |
| 
 | |
|   gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
 | |
| 
 | |
|   //
 | |
|   // clear input bar
 | |
|   //
 | |
|   EditorClearLine (LastRow , LastColumn, LastRow);
 | |
| 
 | |
|   gST->ConOut->SetCursorPosition (gST->ConOut, 0, LastRow - 1);
 | |
|   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBINPUTBAR_MAININPUTBAR), gShellDebug1HiiHandle, mPrompt);
 | |
| 
 | |
|   //
 | |
|   // this is a selection mPrompt, cursor will stay in edit area
 | |
|   // actually this is for search , search/replace
 | |
|   //
 | |
|   if (StrStr (mPrompt, L"Yes/No")) {
 | |
|     NoDisplay = TRUE;
 | |
|     gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow);
 | |
|     gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
 | |
|   } else {
 | |
|     NoDisplay = FALSE;
 | |
|   }
 | |
|   //
 | |
|   // wait for user input
 | |
|   //
 | |
|   for (;;) {
 | |
|     gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
 | |
|     Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       continue;
 | |
|     }
 | |
|     //
 | |
|     // pressed ESC
 | |
|     //
 | |
|     if (Key.ScanCode == SCAN_ESC) {
 | |
|       Size    = 0;
 | |
|       Status  = EFI_NOT_READY;
 | |
|       break;
 | |
|     }
 | |
|     //
 | |
|     // return pressed
 | |
|     //
 | |
|     if (Key.UnicodeChar == CHAR_LINEFEED || Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
 | |
|       break;
 | |
|     } else if (Key.UnicodeChar == CHAR_BACKSPACE) {
 | |
|       //
 | |
|       // backspace
 | |
|       //
 | |
|       if (Size > 0) {
 | |
|         Size--;
 | |
|         mReturnString[Size] = CHAR_NULL;
 | |
|         if (!NoDisplay) {
 | |
| 
 | |
|           InputBarPrintInput (LastColumn, LastRow);
 | |
| 
 | |
|         }
 | |
|       }
 | |
|     } else if (Key.UnicodeChar <= 127 && Key.UnicodeChar >= 32) {
 | |
|       //
 | |
|       // VALID ASCII char pressed
 | |
|       //
 | |
|       mReturnString[Size] = Key.UnicodeChar;
 | |
| 
 | |
|       //
 | |
|       // should be less than specified length
 | |
|       //
 | |
|       if (Size >= StringSize) {
 | |
|         continue;
 | |
|       }
 | |
| 
 | |
|       Size++;
 | |
| 
 | |
|       mReturnString[Size] = CHAR_NULL;
 | |
| 
 | |
|       if (!NoDisplay) {
 | |
| 
 | |
|         InputBarPrintInput (LastColumn, LastRow);
 | |
| 
 | |
|       } else {
 | |
|         //
 | |
|         // if just choose yes/no
 | |
|         //
 | |
|         break;
 | |
|       }
 | |
| 
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   mReturnString[Size] = CHAR_NULL;
 | |
|   
 | |
| 
 | |
|   //
 | |
|   // restore screen attributes
 | |
|   //
 | |
|   gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow);
 | |
|   gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   SetPrompt and wait for input.
 | |
| 
 | |
|   @param[in] Str                The prompt string.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The operation was successful.
 | |
|   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
 | |
| **/
 | |
| EFI_STATUS
 | |
| InputBarSetPrompt (
 | |
|   IN CONST CHAR16 *Str
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // FREE the old mPrompt string
 | |
|   //
 | |
|   SHELL_FREE_NON_NULL (mPrompt);
 | |
| 
 | |
|   mPrompt = CatSPrint (NULL, L"%s ", Str);
 | |
|   if (mPrompt == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Set the size of the string in characters.
 | |
| 
 | |
|   @param[in] Size               The max number of characters to accept.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The operation was successful.
 | |
|   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
 | |
| **/
 | |
| EFI_STATUS
 | |
| InputBarSetStringSize (
 | |
|   UINTN   Size
 | |
|   )
 | |
| {
 | |
|   //
 | |
|   // free the old ReturnStirng
 | |
|   //
 | |
|   SHELL_FREE_NON_NULL (mReturnString);
 | |
| 
 | |
|   StringSize = Size;
 | |
|   mReturnString = AllocateZeroPool ((StringSize + 1) * sizeof(mReturnString[0]));
 | |
|   if (mReturnString == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Function to retrieve the input from the user.
 | |
| 
 | |
|   @retval NULL                  No input has been received.
 | |
|   @return The string that was input.
 | |
| **/
 | |
| CONST CHAR16*
 | |
| InputBarGetString (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   return (mReturnString);
 | |
| }
 |