]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
1) Cleanup HiiLib, IfrSupportLib.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Presentation.c
CommitLineData
93e3992d 1/** @file
2Copyright (c) 2004 - 2007, Intel Corporation
3All rights reserved. This program and the accompanying materials
4are licensed and made available under the terms and conditions of the BSD License
5which accompanies this distribution. The full text of the license may be found at
6http://opensource.org/licenses/bsd-license.php
7
8THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10
11Module Name:
12 Presentation.c
13
14Abstract:
15
16 Some presentation routines.
17
18
19**/
20
21#include "Setup.h"
22#include "Ui.h"
23
24BOOLEAN mHiiPackageListUpdated;
25UI_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**/
40VOID
41ClearLines (
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
81VOID
82NewStrCat (
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
104UINTN
105GetStringWidth (
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
160VOID
161DisplayPageFrame (
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**/
349EFI_STATUS
350EvaluateFormExpressions (
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*/
407EFI_STATUS
408DisplayForm (
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
532VOID
533InitializeBrowserStrings (
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
568VOID
569FreeBrowserStrings (
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**/
613VOID
614UpdateKeyHelp (
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
757EFI_STATUS
758FormUpdateNotify (
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
771EFI_STATUS
772SetupBrowser (
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}