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