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