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