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