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