]>
Commit | Line | Data |
---|---|---|
93e3992d | 1 | /** @file |
2 | Copyright (c) 2004 - 2007, Intel Corporation | |
3 | All rights reserved. This program and the accompanying materials | |
4 | are licensed and made available under the terms and conditions of the BSD License | |
5 | which accompanies this distribution. The full text of the license may be found at | |
6 | http://opensource.org/licenses/bsd-license.php | |
7 | ||
8 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
9 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
10 | ||
11 | Module Name: | |
12 | Presentation.c | |
13 | ||
14 | Abstract: | |
15 | ||
16 | Some presentation routines. | |
17 | ||
18 | ||
19 | **/ | |
20 | ||
21 | #include "Setup.h" | |
22 | #include "Ui.h" | |
23 | ||
24 | BOOLEAN mHiiPackageListUpdated; | |
25 | UI_MENU_SELECTION *gCurrentSelection; | |
26 | ||
27 | ||
28 | /** | |
29 | Clear retangle with specified text attribute. | |
30 | ||
31 | @param LeftColumn Left column of retangle. | |
32 | @param RightColumn Right column of retangle. | |
33 | @param TopRow Start row of retangle. | |
34 | @param BottomRow End row of retangle. | |
35 | @param TextAttribute The character foreground and background. | |
36 | ||
37 | @return None. | |
38 | ||
39 | **/ | |
40 | VOID | |
41 | ClearLines ( | |
42 | UINTN LeftColumn, | |
43 | UINTN RightColumn, | |
44 | UINTN TopRow, | |
45 | UINTN BottomRow, | |
46 | UINTN TextAttribute | |
47 | ) | |
48 | { | |
49 | CHAR16 *Buffer; | |
50 | UINTN Row; | |
51 | ||
52 | // | |
53 | // For now, allocate an arbitrarily long buffer | |
54 | // | |
55 | Buffer = AllocateZeroPool (0x10000); | |
56 | ASSERT (Buffer != NULL); | |
57 | ||
58 | // | |
59 | // Set foreground and background as defined | |
60 | // | |
61 | gST->ConOut->SetAttribute (gST->ConOut, TextAttribute); | |
62 | ||
63 | // | |
64 | // Much faster to buffer the long string instead of print it a character at a time | |
65 | // | |
66 | SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' '); | |
67 | ||
68 | // | |
69 | // Clear the desired area with the appropriate foreground/background | |
70 | // | |
71 | for (Row = TopRow; Row <= BottomRow; Row++) { | |
72 | PrintStringAt (LeftColumn, Row, Buffer); | |
73 | } | |
74 | ||
75 | gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow); | |
76 | ||
77 | gBS->FreePool (Buffer); | |
78 | return ; | |
79 | } | |
80 | ||
81 | VOID | |
82 | NewStrCat ( | |
83 | CHAR16 *Destination, | |
84 | CHAR16 *Source | |
85 | ) | |
86 | { | |
87 | UINTN Length; | |
88 | ||
89 | for (Length = 0; Destination[Length] != 0; Length++) | |
90 | ; | |
91 | ||
92 | // | |
93 | // We now have the length of the original string | |
94 | // We can safely assume for now that we are concatenating a narrow value to this string. | |
95 | // For instance, the string is "XYZ" and cat'ing ">" | |
96 | // If this assumption changes, we need to make this routine a bit more complex | |
97 | // | |
98 | Destination[Length] = NARROW_CHAR; | |
99 | Length++; | |
100 | ||
101 | StrCpy (Destination + Length, Source); | |
102 | } | |
103 | ||
104 | UINTN | |
105 | GetStringWidth ( | |
106 | CHAR16 *String | |
107 | ) | |
108 | { | |
109 | UINTN Index; | |
110 | UINTN Count; | |
111 | UINTN IncrementValue; | |
112 | ||
113 | Index = 0; | |
114 | Count = 0; | |
115 | IncrementValue = 1; | |
116 | ||
117 | do { | |
118 | // | |
119 | // Advance to the null-terminator or to the first width directive | |
120 | // | |
121 | for (; | |
122 | (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0); | |
123 | Index++, Count = Count + IncrementValue | |
124 | ) | |
125 | ; | |
126 | ||
127 | // | |
128 | // We hit the null-terminator, we now have a count | |
129 | // | |
130 | if (String[Index] == 0) { | |
131 | break; | |
132 | } | |
133 | // | |
134 | // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed | |
135 | // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2) | |
136 | // | |
137 | if (String[Index] == NARROW_CHAR) { | |
138 | // | |
139 | // Skip to the next character | |
140 | // | |
141 | Index++; | |
142 | IncrementValue = 1; | |
143 | } else { | |
144 | // | |
145 | // Skip to the next character | |
146 | // | |
147 | Index++; | |
148 | IncrementValue = 2; | |
149 | } | |
150 | } while (String[Index] != 0); | |
151 | ||
152 | // | |
153 | // Increment by one to include the null-terminator in the size | |
154 | // | |
155 | Count++; | |
156 | ||
157 | return Count * sizeof (CHAR16); | |
158 | } | |
159 | ||
160 | VOID | |
161 | DisplayPageFrame ( | |
162 | VOID | |
163 | ) | |
164 | { | |
165 | UINTN Index; | |
166 | UINT8 Line; | |
167 | UINT8 Alignment; | |
168 | CHAR16 Character; | |
169 | CHAR16 *Buffer; | |
170 | CHAR16 *StrFrontPageBanner; | |
171 | UINTN Row; | |
172 | EFI_SCREEN_DESCRIPTOR LocalScreen; | |
173 | ||
174 | ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR)); | |
175 | gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow); | |
176 | ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND); | |
177 | ||
178 | CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR)); | |
179 | ||
180 | // | |
181 | // For now, allocate an arbitrarily long buffer | |
182 | // | |
183 | Buffer = AllocateZeroPool (0x10000); | |
184 | ASSERT (Buffer != NULL); | |
185 | ||
186 | Character = BOXDRAW_HORIZONTAL; | |
187 | ||
188 | for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) { | |
189 | Buffer[Index] = Character; | |
190 | } | |
191 | ||
192 | if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) { | |
193 | // | |
194 | // ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND); | |
195 | // | |
196 | ClearLines ( | |
197 | LocalScreen.LeftColumn, | |
198 | LocalScreen.RightColumn, | |
199 | LocalScreen.TopRow, | |
200 | FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow, | |
201 | BANNER_TEXT | BANNER_BACKGROUND | |
202 | ); | |
203 | // | |
204 | // for (Line = 0; Line < BANNER_HEIGHT; Line++) { | |
205 | // | |
206 | for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) { | |
207 | // | |
208 | // for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) { | |
209 | // | |
210 | for (Alignment = (UINT8) LocalScreen.LeftColumn; | |
211 | Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn; | |
212 | Alignment++ | |
213 | ) { | |
214 | if (BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn] != 0x0000) { | |
215 | StrFrontPageBanner = GetToken ( | |
216 | BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn], | |
217 | FrontPageHandle | |
218 | ); | |
219 | } else { | |
220 | continue; | |
221 | } | |
222 | ||
223 | switch (Alignment - LocalScreen.LeftColumn) { | |
224 | case 0: | |
225 | // | |
226 | // Handle left column | |
227 | // | |
228 | PrintStringAt (LocalScreen.LeftColumn, Line, StrFrontPageBanner); | |
229 | break; | |
230 | ||
231 | case 1: | |
232 | // | |
233 | // Handle center column | |
234 | // | |
235 | PrintStringAt ( | |
236 | LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3, | |
237 | Line, | |
238 | StrFrontPageBanner | |
239 | ); | |
240 | break; | |
241 | ||
242 | case 2: | |
243 | // | |
244 | // Handle right column | |
245 | // | |
246 | PrintStringAt ( | |
247 | LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3, | |
248 | Line, | |
249 | StrFrontPageBanner | |
250 | ); | |
251 | break; | |
252 | } | |
253 | ||
254 | gBS->FreePool (StrFrontPageBanner); | |
255 | } | |
256 | } | |
257 | } | |
258 | ||
259 | ClearLines ( | |
260 | LocalScreen.LeftColumn, | |
261 | LocalScreen.RightColumn, | |
262 | LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, | |
263 | LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, | |
264 | KEYHELP_TEXT | KEYHELP_BACKGROUND | |
265 | ); | |
266 | ||
267 | if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) { | |
268 | ClearLines ( | |
269 | LocalScreen.LeftColumn, | |
270 | LocalScreen.RightColumn, | |
271 | LocalScreen.TopRow, | |
272 | LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, | |
273 | TITLE_TEXT | TITLE_BACKGROUND | |
274 | ); | |
275 | // | |
276 | // Print Top border line | |
277 | // +------------------------------------------------------------------------------+ | |
278 | // ? ? | |
279 | // +------------------------------------------------------------------------------+ | |
280 | // | |
281 | Character = BOXDRAW_DOWN_RIGHT; | |
282 | ||
283 | PrintChar (Character); | |
284 | PrintString (Buffer); | |
285 | ||
286 | Character = BOXDRAW_DOWN_LEFT; | |
287 | PrintChar (Character); | |
288 | ||
289 | Character = BOXDRAW_VERTICAL; | |
290 | for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) { | |
291 | PrintCharAt (LocalScreen.LeftColumn, Row, Character); | |
292 | PrintCharAt (LocalScreen.RightColumn - 1, Row, Character); | |
293 | } | |
294 | ||
295 | Character = BOXDRAW_UP_RIGHT; | |
296 | PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character); | |
297 | PrintString (Buffer); | |
298 | ||
299 | Character = BOXDRAW_UP_LEFT; | |
300 | PrintChar (Character); | |
301 | ||
302 | if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) { | |
303 | // | |
304 | // Print Bottom border line | |
305 | // +------------------------------------------------------------------------------+ | |
306 | // ? ? | |
307 | // +------------------------------------------------------------------------------+ | |
308 | // | |
309 | Character = BOXDRAW_DOWN_RIGHT; | |
310 | PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character); | |
311 | ||
312 | PrintString (Buffer); | |
313 | ||
314 | Character = BOXDRAW_DOWN_LEFT; | |
315 | PrintChar (Character); | |
316 | Character = BOXDRAW_VERTICAL; | |
317 | for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT + 1; | |
318 | Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2; | |
319 | Row++ | |
320 | ) { | |
321 | PrintCharAt (LocalScreen.LeftColumn, Row, Character); | |
322 | PrintCharAt (LocalScreen.RightColumn - 1, Row, Character); | |
323 | } | |
324 | ||
325 | Character = BOXDRAW_UP_RIGHT; | |
326 | PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character); | |
327 | ||
328 | PrintString (Buffer); | |
329 | ||
330 | Character = BOXDRAW_UP_LEFT; | |
331 | PrintChar (Character); | |
332 | } | |
333 | } | |
334 | ||
335 | gBS->FreePool (Buffer); | |
336 | ||
337 | } | |
338 | ||
339 | ||
340 | /** | |
341 | Evaluate all expressions in a Form. | |
342 | ||
343 | @param FormSet FormSet this Form belongs to. | |
344 | @param Form The Form. | |
345 | ||
346 | @retval EFI_SUCCESS The expression evaluated successfuly | |
347 | ||
348 | **/ | |
349 | EFI_STATUS | |
350 | EvaluateFormExpressions ( | |
351 | IN FORM_BROWSER_FORMSET *FormSet, | |
352 | IN FORM_BROWSER_FORM *Form | |
353 | ) | |
354 | { | |
355 | EFI_STATUS Status; | |
356 | LIST_ENTRY *Link; | |
357 | FORM_EXPRESSION *Expression; | |
358 | ||
359 | Link = GetFirstNode (&Form->ExpressionListHead); | |
360 | while (!IsNull (&Form->ExpressionListHead, Link)) { | |
361 | Expression = FORM_EXPRESSION_FROM_LINK (Link); | |
362 | Link = GetNextNode (&Form->ExpressionListHead, Link); | |
363 | ||
364 | if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF || | |
365 | Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) { | |
366 | // | |
367 | // Postpone Form validation to Question editing or Form submiting | |
368 | // | |
369 | continue; | |
370 | } | |
371 | ||
372 | Status = EvaluateExpression (FormSet, Form, Expression); | |
373 | if (EFI_ERROR (Status)) { | |
374 | return Status; | |
375 | } | |
376 | } | |
377 | ||
378 | return EFI_SUCCESS; | |
379 | } | |
380 | ||
381 | /* | |
382 | +------------------------------------------------------------------------------+ | |
383 | ?F2=Previous Page Setup Page ? | |
384 | +------------------------------------------------------------------------------+ | |
385 | ||
386 | ||
387 | ||
388 | ||
389 | ||
390 | ||
391 | ||
392 | ||
393 | ||
394 | ||
395 | ||
396 | ||
397 | ||
398 | ||
399 | ||
400 | ||
401 | ||
402 | +------------------------------------------------------------------------------+ | |
403 | ?F1=Scroll Help F9=Reset to Defaults F10=Save and Exit ? | |
404 | | ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Discard Changes | | |
405 | +------------------------------------------------------------------------------+ | |
406 | */ | |
407 | EFI_STATUS | |
408 | DisplayForm ( | |
409 | IN OUT UI_MENU_SELECTION *Selection | |
410 | ) | |
411 | { | |
412 | CHAR16 *StringPtr; | |
413 | UINT16 MenuItemCount; | |
414 | EFI_HII_HANDLE Handle; | |
415 | BOOLEAN Suppress; | |
416 | EFI_SCREEN_DESCRIPTOR LocalScreen; | |
417 | UINT16 Width; | |
418 | UINTN ArrayEntry; | |
419 | CHAR16 *OutputString; | |
420 | LIST_ENTRY *Link; | |
421 | FORM_BROWSER_STATEMENT *Statement; | |
422 | UINT16 NumberOfLines; | |
423 | EFI_STATUS Status; | |
424 | ||
425 | Handle = Selection->Handle; | |
426 | MenuItemCount = 0; | |
427 | ArrayEntry = 0; | |
428 | OutputString = NULL; | |
429 | ||
430 | UiInitMenu (); | |
431 | ||
432 | CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR)); | |
433 | ||
434 | StringPtr = GetToken (Selection->FormSet->FormSetTitle, Handle); | |
435 | ||
436 | if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) { | |
437 | gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND); | |
438 | PrintStringAt ( | |
439 | (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2, | |
440 | LocalScreen.TopRow + 1, | |
441 | StringPtr | |
442 | ); | |
443 | } | |
444 | ||
445 | if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) { | |
446 | gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND); | |
447 | ||
448 | // | |
449 | // Display the infrastructure strings | |
450 | // | |
451 | if (!IsListEmpty (&gMenuList)) { | |
452 | PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.TopRow + 1, gFunctionTwoString); | |
453 | } | |
454 | ||
455 | PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 4, gFunctionOneString); | |
456 | PrintStringAt ( | |
457 | LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3, | |
458 | LocalScreen.BottomRow - 4, | |
459 | gFunctionNineString | |
460 | ); | |
461 | PrintStringAt ( | |
462 | LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3, | |
463 | LocalScreen.BottomRow - 4, | |
464 | gFunctionTenString | |
465 | ); | |
466 | PrintAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 3, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
467 | PrintStringAt ( | |
468 | LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3, | |
469 | LocalScreen.BottomRow - 3, | |
470 | gEscapeString | |
471 | ); | |
472 | } | |
473 | // | |
474 | // Remove Buffer allocated for StringPtr after it has been used. | |
475 | // | |
476 | gBS->FreePool (StringPtr); | |
477 | ||
478 | // | |
479 | // Evaluate all the Expressions in this Form | |
480 | // | |
481 | Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form); | |
482 | if (EFI_ERROR (Status)) { | |
483 | return Status; | |
484 | } | |
485 | ||
486 | Link = GetFirstNode (&Selection->Form->StatementListHead); | |
487 | while (!IsNull (&Selection->Form->StatementListHead, Link)) { | |
488 | Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link); | |
489 | ||
490 | if (Statement->SuppressExpression != NULL) { | |
491 | Suppress = Statement->SuppressExpression->Result.Value.b; | |
492 | } else { | |
493 | Suppress = FALSE; | |
494 | } | |
495 | ||
496 | if (!Suppress) { | |
497 | StringPtr = GetToken (Statement->Prompt, Handle); | |
498 | ||
499 | Width = GetWidth (Statement, Handle); | |
500 | ||
501 | NumberOfLines = 1; | |
502 | ArrayEntry = 0; | |
503 | for (; GetLineByWidth (StringPtr, Width, &ArrayEntry, &OutputString) != 0x0000;) { | |
504 | // | |
505 | // If there is more string to process print on the next row and increment the Skip value | |
506 | // | |
507 | if (StrLen (&StringPtr[ArrayEntry])) { | |
508 | NumberOfLines++; | |
509 | } | |
510 | ||
511 | gBS->FreePool (OutputString); | |
512 | } | |
513 | ||
514 | // | |
515 | // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do | |
516 | // it in UiFreeMenu. | |
517 | // | |
518 | UiAddMenuOption (StringPtr, Selection->Handle, Statement, NumberOfLines, MenuItemCount); | |
519 | MenuItemCount++; | |
520 | } | |
521 | ||
522 | Link = GetNextNode (&Selection->Form->StatementListHead, Link); | |
523 | } | |
524 | ||
525 | Status = UiDisplayMenu (Selection); | |
526 | ||
527 | UiFreeMenu (); | |
528 | ||
529 | return Status; | |
530 | } | |
531 | ||
532 | VOID | |
533 | InitializeBrowserStrings ( | |
534 | VOID | |
535 | ) | |
536 | { | |
537 | gFunctionOneString = GetToken (STRING_TOKEN (FUNCTION_ONE_STRING), gHiiHandle); | |
538 | gFunctionTwoString = GetToken (STRING_TOKEN (FUNCTION_TWO_STRING), gHiiHandle); | |
539 | gFunctionNineString = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle); | |
540 | gFunctionTenString = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle); | |
541 | gEnterString = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle); | |
542 | gEnterCommitString = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle); | |
543 | gEscapeString = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle); | |
544 | gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle); | |
545 | gMoveHighlight = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle); | |
546 | gMakeSelection = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle); | |
547 | gDecNumericInput = GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), gHiiHandle); | |
548 | gHexNumericInput = GetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), gHiiHandle); | |
549 | gToggleCheckBox = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle); | |
550 | gPromptForData = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle); | |
551 | gPromptForPassword = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle); | |
552 | gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle); | |
553 | gConfirmPassword = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle); | |
554 | gConfirmError = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle); | |
555 | gPassowordInvalid = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle); | |
556 | gPressEnter = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle); | |
557 | gEmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle); | |
558 | gAreYouSure = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle); | |
559 | gYesResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle); | |
560 | gNoResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle); | |
561 | gMiniString = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle); | |
562 | gPlusString = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle); | |
563 | gMinusString = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle); | |
564 | gAdjustNumber = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle); | |
565 | return ; | |
566 | } | |
567 | ||
568 | VOID | |
569 | FreeBrowserStrings ( | |
570 | VOID | |
571 | ) | |
572 | { | |
573 | SafeFreePool (gFunctionOneString); | |
574 | SafeFreePool (gFunctionTwoString); | |
575 | SafeFreePool (gFunctionNineString); | |
576 | SafeFreePool (gFunctionTenString); | |
577 | SafeFreePool (gEnterString); | |
578 | SafeFreePool (gEnterCommitString); | |
579 | SafeFreePool (gEscapeString); | |
580 | SafeFreePool (gMoveHighlight); | |
581 | SafeFreePool (gMakeSelection); | |
582 | SafeFreePool (gDecNumericInput); | |
583 | SafeFreePool (gHexNumericInput); | |
584 | SafeFreePool (gToggleCheckBox); | |
585 | SafeFreePool (gPromptForData); | |
586 | SafeFreePool (gPromptForPassword); | |
587 | SafeFreePool (gPromptForNewPassword); | |
588 | SafeFreePool (gConfirmPassword); | |
589 | SafeFreePool (gPassowordInvalid); | |
590 | SafeFreePool (gConfirmError); | |
591 | SafeFreePool (gPressEnter); | |
592 | SafeFreePool (gEmptyString); | |
593 | SafeFreePool (gAreYouSure); | |
594 | SafeFreePool (gYesResponse); | |
595 | SafeFreePool (gNoResponse); | |
596 | SafeFreePool (gMiniString); | |
597 | SafeFreePool (gPlusString); | |
598 | SafeFreePool (gMinusString); | |
599 | SafeFreePool (gAdjustNumber); | |
600 | return ; | |
601 | } | |
602 | ||
603 | ||
604 | /** | |
605 | Update key's help imformation | |
606 | ||
607 | @param MenuOption The Menu option | |
608 | @param Selected Whether or not a tag be selected | |
609 | ||
610 | @return None | |
611 | ||
612 | **/ | |
613 | VOID | |
614 | UpdateKeyHelp ( | |
615 | IN UI_MENU_OPTION *MenuOption, | |
616 | IN BOOLEAN Selected | |
617 | ) | |
618 | { | |
619 | UINTN SecCol; | |
620 | UINTN ThdCol; | |
621 | UINTN LeftColumnOfHelp; | |
622 | UINTN RightColumnOfHelp; | |
623 | UINTN TopRowOfHelp; | |
624 | UINTN BottomRowOfHelp; | |
625 | UINTN StartColumnOfHelp; | |
626 | EFI_SCREEN_DESCRIPTOR LocalScreen; | |
627 | FORM_BROWSER_STATEMENT *Statement; | |
628 | ||
629 | CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR)); | |
630 | ||
631 | SecCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3; | |
632 | ThdCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3; | |
633 | ||
634 | StartColumnOfHelp = LocalScreen.LeftColumn + 2; | |
635 | LeftColumnOfHelp = LocalScreen.LeftColumn + 1; | |
636 | RightColumnOfHelp = LocalScreen.RightColumn - 2; | |
637 | TopRowOfHelp = LocalScreen.BottomRow - 4; | |
638 | BottomRowOfHelp = LocalScreen.BottomRow - 3; | |
639 | ||
640 | if (gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS) { | |
641 | return ; | |
642 | } | |
643 | ||
644 | gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND); | |
645 | ||
646 | Statement = MenuOption->ThisTag; | |
647 | switch (Statement->Operand) { | |
648 | case EFI_IFR_ORDERED_LIST_OP: | |
649 | case EFI_IFR_ONE_OF_OP: | |
650 | case EFI_IFR_NUMERIC_OP: | |
651 | case EFI_IFR_TIME_OP: | |
652 | case EFI_IFR_DATE_OP: | |
653 | ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND); | |
654 | ||
655 | if (!Selected) { | |
656 | if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) { | |
657 | PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString); | |
658 | PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString); | |
659 | PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString); | |
660 | PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); | |
661 | } | |
662 | ||
663 | if ((Statement->Operand == EFI_IFR_DATE_OP) || | |
664 | (Statement->Operand == EFI_IFR_TIME_OP) || | |
665 | (Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0)) { | |
666 | PrintAt ( | |
667 | StartColumnOfHelp, | |
668 | BottomRowOfHelp, | |
669 | L"%c%c%c%c%s", | |
670 | ARROW_UP, | |
671 | ARROW_DOWN, | |
672 | ARROW_RIGHT, | |
673 | ARROW_LEFT, | |
674 | gMoveHighlight | |
675 | ); | |
676 | PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber); | |
677 | } else { | |
678 | PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
679 | PrintStringAt (SecCol, BottomRowOfHelp, gEnterString); | |
680 | } | |
681 | } else { | |
682 | PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString); | |
683 | ||
684 | // | |
685 | // If it is a selected numeric with manual input, display different message | |
686 | // | |
687 | if ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step == 0)) { | |
688 | PrintStringAt ( | |
689 | SecCol, | |
690 | TopRowOfHelp, | |
691 | (Statement->Flags & EFI_IFR_DISPLAY_UINT_HEX) ? gHexNumericInput : gDecNumericInput | |
692 | ); | |
693 | } else if (Statement->Operand != EFI_IFR_ORDERED_LIST_OP) { | |
694 | PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
695 | } | |
696 | ||
697 | if (Statement->Operand == EFI_IFR_ORDERED_LIST_OP) { | |
698 | PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString); | |
699 | PrintStringAt (ThdCol, TopRowOfHelp, gMinusString); | |
700 | } | |
701 | ||
702 | PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); | |
703 | } | |
704 | break; | |
705 | ||
706 | case EFI_IFR_CHECKBOX_OP: | |
707 | ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND); | |
708 | ||
709 | if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) { | |
710 | PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString); | |
711 | PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString); | |
712 | PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString); | |
713 | PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); | |
714 | } | |
715 | ||
716 | PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
717 | PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox); | |
718 | break; | |
719 | ||
720 | case EFI_IFR_REF_OP: | |
721 | case EFI_IFR_PASSWORD_OP: | |
722 | case EFI_IFR_STRING_OP: | |
723 | case EFI_IFR_TEXT_OP: | |
724 | case EFI_IFR_ACTION_OP: | |
725 | case EFI_IFR_RESET_BUTTON_OP: | |
726 | ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND); | |
727 | ||
728 | if (!Selected) { | |
729 | if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) { | |
730 | PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString); | |
731 | PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString); | |
732 | PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString); | |
733 | PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); | |
734 | } | |
735 | ||
736 | PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight); | |
737 | if (Statement->Operand != EFI_IFR_TEXT_OP) { | |
738 | PrintStringAt (SecCol, BottomRowOfHelp, gEnterString); | |
739 | } | |
740 | } else { | |
741 | if (Statement->Operand != EFI_IFR_REF_OP) { | |
742 | PrintStringAt ( | |
743 | (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2, | |
744 | BottomRowOfHelp, | |
745 | gEnterCommitString | |
746 | ); | |
747 | PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString); | |
748 | } | |
749 | } | |
750 | break; | |
751 | ||
752 | default: | |
753 | break; | |
754 | } | |
755 | } | |
756 | ||
757 | EFI_STATUS | |
758 | FormUpdateNotify ( | |
759 | IN UINT8 PackageType, | |
760 | IN CONST EFI_GUID *PackageGuid, | |
761 | IN CONST EFI_HII_PACKAGE_HEADER *Package, | |
762 | IN EFI_HII_HANDLE Handle, | |
763 | IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType | |
764 | ) | |
765 | { | |
766 | mHiiPackageListUpdated = TRUE; | |
767 | ||
768 | return EFI_SUCCESS; | |
769 | } | |
770 | ||
771 | EFI_STATUS | |
772 | SetupBrowser ( | |
773 | IN OUT UI_MENU_SELECTION *Selection | |
774 | ) | |
775 | { | |
776 | EFI_STATUS Status; | |
777 | LIST_ENTRY *Link; | |
778 | EFI_BROWSER_ACTION_REQUEST ActionRequest; | |
779 | EFI_HANDLE NotifyHandle; | |
780 | EFI_HII_VALUE *HiiValue; | |
781 | FORM_BROWSER_STATEMENT *Statement; | |
782 | EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; | |
783 | ||
784 | gMenuRefreshHead = NULL; | |
785 | gResetRequired = FALSE; | |
786 | gNvUpdateRequired = FALSE; | |
787 | ||
788 | UiInitMenuList (); | |
789 | ||
790 | // | |
791 | // Register notify for Form package update | |
792 | // | |
793 | Status = mHiiDatabase->RegisterPackageNotify ( | |
794 | mHiiDatabase, | |
795 | EFI_HII_PACKAGE_FORM, | |
796 | NULL, | |
797 | FormUpdateNotify, | |
798 | EFI_HII_DATABASE_NOTIFY_REMOVE_PACK, | |
799 | &NotifyHandle | |
800 | ); | |
801 | if (EFI_ERROR (Status)) { | |
802 | return Status; | |
803 | } | |
804 | ||
805 | do { | |
806 | // | |
807 | // Displays the Header and Footer borders | |
808 | // | |
809 | DisplayPageFrame (); | |
810 | ||
811 | // | |
812 | // Initialize Selection->Form | |
813 | // | |
814 | if (Selection->FormId == 0) { | |
815 | // | |
816 | // Zero FormId indicates display the first Form in a FormSet | |
817 | // | |
818 | Link = GetFirstNode (&Selection->FormSet->FormListHead); | |
819 | ||
820 | Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link); | |
821 | Selection->FormId = Selection->Form->FormId; | |
822 | } else { | |
823 | Selection->Form = IdToForm (Selection->FormSet, Selection->FormId); | |
824 | } | |
825 | ||
826 | // | |
827 | // Load Questions' Value for display | |
828 | // | |
829 | Status = LoadFormConfig (Selection->FormSet, Selection->Form); | |
830 | if (EFI_ERROR (Status)) { | |
831 | return Status; | |
832 | } | |
833 | ||
834 | // | |
835 | // Display form | |
836 | // | |
837 | Status = DisplayForm (Selection); | |
838 | if (EFI_ERROR (Status)) { | |
839 | return Status; | |
840 | } | |
841 | ||
842 | // | |
843 | // Check Selected Statement (if press ESC, Selection->Statement will be NULL) | |
844 | // | |
845 | Statement = Selection->Statement; | |
846 | if (Statement != NULL) { | |
847 | if (Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) { | |
848 | gResetRequired = TRUE; | |
849 | } | |
850 | ||
851 | // | |
852 | // Reset FormPackage update flag | |
853 | // | |
854 | mHiiPackageListUpdated = FALSE; | |
855 | ||
856 | if (Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK && Statement->Operand != EFI_IFR_PASSWORD_OP) { | |
857 | ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; | |
858 | ||
859 | HiiValue = &Statement->HiiValue; | |
860 | if (HiiValue->Type == EFI_IFR_TYPE_STRING) { | |
861 | // | |
862 | // Create String in HII database for Configuration Driver to retrieve | |
863 | // | |
864 | HiiValue->Value.string = NewString ((CHAR16 *) Statement->BufferValue, Selection->FormSet->HiiHandle); | |
865 | } | |
866 | ||
867 | ConfigAccess = Selection->FormSet->ConfigAccess; | |
868 | if (ConfigAccess == NULL) { | |
869 | return EFI_UNSUPPORTED; | |
870 | } | |
871 | Status = ConfigAccess->Callback ( | |
872 | ConfigAccess, | |
873 | EFI_BROWSER_ACTION_CHANGING, | |
874 | Statement->QuestionId, | |
875 | HiiValue->Type, | |
876 | &HiiValue->Value, | |
877 | &ActionRequest | |
878 | ); | |
879 | ||
880 | if (HiiValue->Type == EFI_IFR_TYPE_STRING) { | |
881 | // | |
882 | // Clean the String in HII Database | |
883 | // | |
884 | DeleteString (HiiValue->Value.string, Selection->FormSet->HiiHandle); | |
885 | } | |
886 | ||
887 | if (!EFI_ERROR (Status)) { | |
888 | switch (ActionRequest) { | |
889 | case EFI_BROWSER_ACTION_REQUEST_RESET: | |
890 | gResetRequired = TRUE; | |
891 | break; | |
892 | ||
893 | case EFI_BROWSER_ACTION_REQUEST_SUBMIT: | |
894 | SubmitForm (Selection->FormSet, Selection->Form); | |
895 | break; | |
896 | ||
897 | case EFI_BROWSER_ACTION_REQUEST_EXIT: | |
898 | Selection->Action = UI_ACTION_EXIT; | |
899 | gNvUpdateRequired = FALSE; | |
900 | break; | |
901 | ||
902 | default: | |
903 | break; | |
904 | } | |
905 | } | |
906 | } | |
907 | ||
908 | // | |
909 | // Check whether Form Package has been updated during Callback | |
910 | // | |
911 | if (mHiiPackageListUpdated && (Selection->Action == UI_ACTION_REFRESH_FORM)) { | |
912 | // | |
913 | // Force to reparse IFR binary of target Formset | |
914 | // | |
915 | Selection->Action = UI_ACTION_REFRESH_FORMSET; | |
916 | } | |
917 | } | |
918 | } while (Selection->Action == UI_ACTION_REFRESH_FORM); | |
919 | ||
920 | // | |
921 | // Unregister notify for Form package update | |
922 | // | |
923 | Status = mHiiDatabase->UnregisterPackageNotify ( | |
924 | mHiiDatabase, | |
925 | NotifyHandle | |
926 | ); | |
927 | return Status; | |
928 | } |