]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c
ShellPkg: Replace BSD License with BSD+Patent License
[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 /**
111 The refresh function for InputBar, it will wait for user input
112
113 @param[in] LastRow The last printable row.
114 @param[in] LastColumn The last printable column.
115
116 @retval EFI_SUCCESS The operation was successful.
117 **/
118 EFI_STATUS
119 InputBarRefresh (
120 UINTN LastRow,
121 UINTN LastColumn
122 )
123 {
124 INPUT_BAR_COLOR_UNION Orig;
125 INPUT_BAR_COLOR_UNION New;
126 EFI_KEY_DATA KeyData;
127 UINTN Size;
128 EFI_STATUS Status;
129 BOOLEAN NoDisplay;
130 UINTN EventIndex;
131 UINTN CursorRow;
132 UINTN CursorCol;
133
134 //
135 // variable initialization
136 //
137 Size = 0;
138 Status = EFI_SUCCESS;
139
140 //
141 // back up the old screen attributes
142 //
143 CursorCol = gST->ConOut->Mode->CursorColumn;
144 CursorRow = gST->ConOut->Mode->CursorRow;
145 Orig.Data = gST->ConOut->Mode->Attribute;
146 New.Data = 0;
147 New.Colors.Foreground = Orig.Colors.Background & 0xF;
148 New.Colors.Background = Orig.Colors.Foreground & 0x7;
149
150 gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
151
152 //
153 // clear input bar
154 //
155 EditorClearLine (LastRow , LastColumn, LastRow);
156
157 gST->ConOut->SetCursorPosition (gST->ConOut, 0, LastRow - 1);
158 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBINPUTBAR_MAININPUTBAR), gShellDebug1HiiHandle, mPrompt);
159
160 //
161 // this is a selection mPrompt, cursor will stay in edit area
162 // actually this is for search , search/replace
163 //
164 if (StrStr (mPrompt, L"Yes/No")) {
165 NoDisplay = TRUE;
166 gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow);
167 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
168 } else {
169 NoDisplay = FALSE;
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 Status = mTextInEx->ReadKeyStrokeEx (mTextInEx, &KeyData);
180 if (EFI_ERROR (Status)) {
181 continue;
182 }
183 if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) &&
184 (KeyData.KeyState.KeyShiftState != EFI_SHIFT_STATE_VALID)) {
185 //
186 // Shift key pressed.
187 //
188 continue;
189 }
190 //
191 // pressed ESC
192 //
193 if (KeyData.Key.ScanCode == SCAN_ESC) {
194 Size = 0;
195 Status = EFI_NOT_READY;
196 break;
197 }
198 //
199 // return pressed
200 //
201 if (KeyData.Key.UnicodeChar == CHAR_LINEFEED || KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
202 break;
203 } else if (KeyData.Key.UnicodeChar == CHAR_BACKSPACE) {
204 //
205 // backspace
206 //
207 if (Size > 0) {
208 Size--;
209 mReturnString[Size] = CHAR_NULL;
210 if (!NoDisplay) {
211
212 InputBarPrintInput (LastColumn, LastRow);
213
214 }
215 }
216 } else if (KeyData.Key.UnicodeChar <= 127 && KeyData.Key.UnicodeChar >= 32) {
217 //
218 // VALID ASCII char pressed
219 //
220 mReturnString[Size] = KeyData.Key.UnicodeChar;
221
222 //
223 // should be less than specified length
224 //
225 if (Size >= StringSize) {
226 continue;
227 }
228
229 Size++;
230
231 mReturnString[Size] = CHAR_NULL;
232
233 if (!NoDisplay) {
234
235 InputBarPrintInput (LastColumn, LastRow);
236
237 } else {
238 //
239 // if just choose yes/no
240 //
241 break;
242 }
243
244 }
245 }
246
247 mReturnString[Size] = CHAR_NULL;
248
249
250 //
251 // restore screen attributes
252 //
253 gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow);
254 gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
255
256 return Status;
257 }
258
259 /**
260 SetPrompt and wait for input.
261
262 @param[in] Str The prompt string.
263
264 @retval EFI_SUCCESS The operation was successful.
265 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
266 **/
267 EFI_STATUS
268 InputBarSetPrompt (
269 IN CONST CHAR16 *Str
270 )
271 {
272 //
273 // FREE the old mPrompt string
274 //
275 SHELL_FREE_NON_NULL (mPrompt);
276
277 mPrompt = CatSPrint (NULL, L"%s ", Str);
278 if (mPrompt == NULL) {
279 return EFI_OUT_OF_RESOURCES;
280 }
281
282 return EFI_SUCCESS;
283 }
284
285 /**
286 Set the size of the string in characters.
287
288 @param[in] Size The max number of characters to accept.
289
290 @retval EFI_SUCCESS The operation was successful.
291 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
292 **/
293 EFI_STATUS
294 InputBarSetStringSize (
295 UINTN Size
296 )
297 {
298 //
299 // free the old ReturnStirng
300 //
301 SHELL_FREE_NON_NULL (mReturnString);
302
303 StringSize = Size;
304 mReturnString = AllocateZeroPool ((StringSize + 1) * sizeof(mReturnString[0]));
305 if (mReturnString == NULL) {
306 return EFI_OUT_OF_RESOURCES;
307 }
308
309 return EFI_SUCCESS;
310 }
311
312 /**
313 Function to retrieve the input from the user.
314
315 @retval NULL No input has been received.
316 @return The string that was input.
317 **/
318 CONST CHAR16*
319 InputBarGetString (
320 VOID
321 )
322 {
323 return (mReturnString);
324 }