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