]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Presentation.c
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 }