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