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