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