Home | History | Annotate | Download | only in UefiShellDebug1CommandsLib
      1 /** @file
      2   Implements inputbar interface functions.
      3 
      4   Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved. <BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "EditInputBar.h"
     16 #include "UefiShellDebug1CommandsLib.h"
     17 
     18 CHAR16  *mPrompt;        // Input bar mPrompt string.
     19 CHAR16  *mReturnString;  // The returned string.
     20 UINTN   StringSize;      // Size of mReturnString space size.
     21 
     22 /**
     23   Initialize the input bar.
     24 **/
     25 VOID
     26 InputBarInit (
     27   VOID
     28   )
     29 {
     30   mPrompt       = NULL;
     31   mReturnString = NULL;
     32   StringSize    = 0;
     33 }
     34 
     35 /**
     36   Cleanup function for input bar.
     37 **/
     38 VOID
     39 InputBarCleanup (
     40   VOID
     41   )
     42 {
     43   //
     44   // free input bar's prompt and input string
     45   //
     46   SHELL_FREE_NON_NULL (mPrompt);
     47   SHELL_FREE_NON_NULL (mReturnString);
     48   mPrompt       = NULL;
     49   mReturnString = NULL;
     50 }
     51 
     52 /**
     53   Display the prompt.
     54   Do the requesting of input.
     55 
     56   @param[in]  LastColumn   The last printable column.
     57   @param[in]  LastRow      The last printable row.
     58 **/
     59 VOID
     60 InputBarPrintInput (
     61   IN UINTN LastColumn,
     62   IN UINTN LastRow
     63   )
     64 {
     65   UINTN   Limit;
     66   UINTN   Size;
     67   CHAR16  *Buffer;
     68   UINTN   Index;
     69   UINTN   mPromptLen;
     70 
     71   mPromptLen = StrLen (mPrompt);
     72   Limit     = LastColumn - mPromptLen - 1;
     73   Size      = StrLen (mReturnString);
     74 
     75   //
     76   // check whether the mPrompt length and input length will
     77   // exceed limit
     78   //
     79   if (Size <= Limit) {
     80     Buffer = mReturnString;
     81   } else {
     82     Buffer = mReturnString + Size - Limit;
     83   }
     84 
     85   gST->ConOut->EnableCursor (gST->ConOut, FALSE);
     86 
     87   ShellPrintEx (((INT32)mPromptLen), ((INT32)LastRow) - 1, L"%s", Buffer);
     88   Size = StrLen (Buffer);
     89 
     90   //
     91   // print " " after mPrompt
     92   //
     93   for (Index = Size; Index < Limit; Index++) {
     94     ShellPrintEx ((INT32)(mPromptLen + Size), ((INT32)LastRow) - 1, L" ");
     95   }
     96 
     97   gST->ConOut->EnableCursor (gST->ConOut, TRUE);
     98   gST->ConOut->SetCursorPosition (gST->ConOut, Size + mPromptLen, LastRow - 1);
     99 }
    100 
    101 typedef struct {
    102   UINT32  Foreground : 4;
    103   UINT32  Background : 3;
    104 } INPUT_BAR_COLOR_ATTRIBUTES;
    105 
    106 typedef union {
    107   INPUT_BAR_COLOR_ATTRIBUTES  Colors;
    108   UINTN                       Data;
    109 } INPUT_BAR_COLOR_UNION;
    110 
    111 
    112 /**
    113   The refresh function for InputBar, it will wait for user input
    114 
    115   @param[in] LastRow            The last printable row.
    116   @param[in] LastColumn         The last printable column.
    117 
    118   @retval EFI_SUCCESS           The operation was successful.
    119 **/
    120 EFI_STATUS
    121 InputBarRefresh (
    122   UINTN LastRow,
    123   UINTN LastColumn
    124   )
    125 {
    126   INPUT_BAR_COLOR_UNION   Orig;
    127   INPUT_BAR_COLOR_UNION   New;
    128   EFI_INPUT_KEY           Key;
    129   UINTN                   Size;
    130   EFI_STATUS              Status;
    131   BOOLEAN                 NoDisplay;
    132   UINTN                   EventIndex;
    133   UINTN                   CursorRow;
    134   UINTN                   CursorCol;
    135 
    136   //
    137   // variable initialization
    138   //
    139   Size    = 0;
    140   Status  = EFI_SUCCESS;
    141 
    142   //
    143   // back up the old screen attributes
    144   //
    145   CursorCol             = gST->ConOut->Mode->CursorColumn;
    146   CursorRow             = gST->ConOut->Mode->CursorRow;
    147   Orig.Data             = gST->ConOut->Mode->Attribute;
    148   New.Data              = 0;
    149   New.Colors.Foreground = Orig.Colors.Background & 0xF;
    150   New.Colors.Background = Orig.Colors.Foreground & 0x7;
    151 
    152   gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
    153 
    154   //
    155   // clear input bar
    156   //
    157   EditorClearLine (LastRow , LastColumn, LastRow);
    158 
    159   gST->ConOut->SetCursorPosition (gST->ConOut, 0, LastRow - 1);
    160   ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBINPUTBAR_MAININPUTBAR), gShellDebug1HiiHandle, mPrompt);
    161 
    162   //
    163   // this is a selection mPrompt, cursor will stay in edit area
    164   // actually this is for search , search/replace
    165   //
    166   if (StrStr (mPrompt, L"Yes/No")) {
    167     NoDisplay = TRUE;
    168     gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow);
    169     gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
    170   } else {
    171     NoDisplay = FALSE;
    172   }
    173   //
    174   // wait for user input
    175   //
    176   for (;;) {
    177     gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
    178     Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    179     if (EFI_ERROR (Status)) {
    180       continue;
    181     }
    182     //
    183     // pressed ESC
    184     //
    185     if (Key.ScanCode == SCAN_ESC) {
    186       Size    = 0;
    187       Status  = EFI_NOT_READY;
    188       break;
    189     }
    190     //
    191     // return pressed
    192     //
    193     if (Key.UnicodeChar == CHAR_LINEFEED || Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
    194       break;
    195     } else if (Key.UnicodeChar == CHAR_BACKSPACE) {
    196       //
    197       // backspace
    198       //
    199       if (Size > 0) {
    200         Size--;
    201         mReturnString[Size] = CHAR_NULL;
    202         if (!NoDisplay) {
    203 
    204           InputBarPrintInput (LastColumn, LastRow);
    205 
    206         }
    207       }
    208     } else if (Key.UnicodeChar <= 127 && Key.UnicodeChar >= 32) {
    209       //
    210       // VALID ASCII char pressed
    211       //
    212       mReturnString[Size] = Key.UnicodeChar;
    213 
    214       //
    215       // should be less than specified length
    216       //
    217       if (Size >= StringSize) {
    218         continue;
    219       }
    220 
    221       Size++;
    222 
    223       mReturnString[Size] = CHAR_NULL;
    224 
    225       if (!NoDisplay) {
    226 
    227         InputBarPrintInput (LastColumn, LastRow);
    228 
    229       } else {
    230         //
    231         // if just choose yes/no
    232         //
    233         break;
    234       }
    235 
    236     }
    237   }
    238 
    239   mReturnString[Size] = CHAR_NULL;
    240 
    241 
    242   //
    243   // restore screen attributes
    244   //
    245   gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow);
    246   gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
    247 
    248   return Status;
    249 }
    250 
    251 /**
    252   SetPrompt and wait for input.
    253 
    254   @param[in] Str                The prompt string.
    255 
    256   @retval EFI_SUCCESS           The operation was successful.
    257   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
    258 **/
    259 EFI_STATUS
    260 InputBarSetPrompt (
    261   IN CONST CHAR16 *Str
    262   )
    263 {
    264   //
    265   // FREE the old mPrompt string
    266   //
    267   SHELL_FREE_NON_NULL (mPrompt);
    268 
    269   mPrompt = CatSPrint (NULL, L"%s ", Str);
    270   if (mPrompt == NULL) {
    271     return EFI_OUT_OF_RESOURCES;
    272   }
    273 
    274   return EFI_SUCCESS;
    275 }
    276 
    277 /**
    278   Set the size of the string in characters.
    279 
    280   @param[in] Size               The max number of characters to accept.
    281 
    282   @retval EFI_SUCCESS           The operation was successful.
    283   @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
    284 **/
    285 EFI_STATUS
    286 InputBarSetStringSize (
    287   UINTN   Size
    288   )
    289 {
    290   //
    291   // free the old ReturnStirng
    292   //
    293   SHELL_FREE_NON_NULL (mReturnString);
    294 
    295   StringSize = Size;
    296   mReturnString = AllocateZeroPool ((StringSize + 1) * sizeof(mReturnString[0]));
    297   if (mReturnString == NULL) {
    298     return EFI_OUT_OF_RESOURCES;
    299   }
    300 
    301   return EFI_SUCCESS;
    302 }
    303 
    304 /**
    305   Function to retrieve the input from the user.
    306 
    307   @retval NULL                  No input has been received.
    308   @return The string that was input.
    309 **/
    310 CONST CHAR16*
    311 InputBarGetString (
    312   VOID
    313   )
    314 {
    315   return (mReturnString);
    316 }
    317