git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4599 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			929 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			929 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| Copyright (c) 2004 - 2007, Intel Corporation
 | |
| All rights reserved. This program and the accompanying materials
 | |
| are licensed and made available under the terms and conditions of the BSD License
 | |
| which accompanies this distribution.  The full text of the license may be found at
 | |
| http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| Module Name:
 | |
|   Presentation.c
 | |
| 
 | |
| Abstract:
 | |
| 
 | |
|   Some presentation routines.
 | |
| 
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "Setup.h"
 | |
| #include "Ui.h"
 | |
| 
 | |
| BOOLEAN            mHiiPackageListUpdated;
 | |
| UI_MENU_SELECTION  *gCurrentSelection;
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Clear retangle with specified text attribute.
 | |
| 
 | |
|   @param  LeftColumn     Left column of retangle.
 | |
|   @param  RightColumn    Right column of retangle.
 | |
|   @param  TopRow         Start row of retangle.
 | |
|   @param  BottomRow      End row of retangle.
 | |
|   @param  TextAttribute  The character foreground and background.
 | |
| 
 | |
|   @return None.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| ClearLines (
 | |
|   UINTN                                       LeftColumn,
 | |
|   UINTN                                       RightColumn,
 | |
|   UINTN                                       TopRow,
 | |
|   UINTN                                       BottomRow,
 | |
|   UINTN                                       TextAttribute
 | |
|   )
 | |
| {
 | |
|   CHAR16  *Buffer;
 | |
|   UINTN   Row;
 | |
| 
 | |
|   //
 | |
|   // For now, allocate an arbitrarily long buffer
 | |
|   //
 | |
|   Buffer = AllocateZeroPool (0x10000);
 | |
|   ASSERT (Buffer != NULL);
 | |
| 
 | |
|   //
 | |
|   // Set foreground and background as defined
 | |
|   //
 | |
|   gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);
 | |
| 
 | |
|   //
 | |
|   // Much faster to buffer the long string instead of print it a character at a time
 | |
|   //
 | |
|   SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');
 | |
| 
 | |
|   //
 | |
|   // Clear the desired area with the appropriate foreground/background
 | |
|   //
 | |
|   for (Row = TopRow; Row <= BottomRow; Row++) {
 | |
|     PrintStringAt (LeftColumn, Row, Buffer);
 | |
|   }
 | |
| 
 | |
|   gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);
 | |
| 
 | |
|   gBS->FreePool (Buffer);
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| NewStrCat (
 | |
|   CHAR16                                      *Destination,
 | |
|   CHAR16                                      *Source
 | |
|   )
 | |
| {
 | |
|   UINTN Length;
 | |
| 
 | |
|   for (Length = 0; Destination[Length] != 0; Length++)
 | |
|     ;
 | |
| 
 | |
|   //
 | |
|   // We now have the length of the original string
 | |
|   // We can safely assume for now that we are concatenating a narrow value to this string.
 | |
|   // For instance, the string is "XYZ" and cat'ing ">"
 | |
|   // If this assumption changes, we need to make this routine a bit more complex
 | |
|   //
 | |
|   Destination[Length] = NARROW_CHAR;
 | |
|   Length++;
 | |
| 
 | |
|   StrCpy (Destination + Length, Source);
 | |
| }
 | |
| 
 | |
| UINTN
 | |
| GetStringWidth (
 | |
|   CHAR16                                      *String
 | |
|   )
 | |
| {
 | |
|   UINTN Index;
 | |
|   UINTN Count;
 | |
|   UINTN IncrementValue;
 | |
| 
 | |
|   Index           = 0;
 | |
|   Count           = 0;
 | |
|   IncrementValue  = 1;
 | |
| 
 | |
|   do {
 | |
|     //
 | |
|     // Advance to the null-terminator or to the first width directive
 | |
|     //
 | |
|     for (;
 | |
|          (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
 | |
|          Index++, Count = Count + IncrementValue
 | |
|         )
 | |
|       ;
 | |
| 
 | |
|     //
 | |
|     // We hit the null-terminator, we now have a count
 | |
|     //
 | |
|     if (String[Index] == 0) {
 | |
|       break;
 | |
|     }
 | |
|     //
 | |
|     // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
 | |
|     // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
 | |
|     //
 | |
|     if (String[Index] == NARROW_CHAR) {
 | |
|       //
 | |
|       // Skip to the next character
 | |
|       //
 | |
|       Index++;
 | |
|       IncrementValue = 1;
 | |
|     } else {
 | |
|       //
 | |
|       // Skip to the next character
 | |
|       //
 | |
|       Index++;
 | |
|       IncrementValue = 2;
 | |
|     }
 | |
|   } while (String[Index] != 0);
 | |
| 
 | |
|   //
 | |
|   // Increment by one to include the null-terminator in the size
 | |
|   //
 | |
|   Count++;
 | |
| 
 | |
|   return Count * sizeof (CHAR16);
 | |
| }
 | |
| 
 | |
| VOID
 | |
| DisplayPageFrame (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   UINTN                  Index;
 | |
|   UINT8                  Line;
 | |
|   UINT8                  Alignment;
 | |
|   CHAR16                 Character;
 | |
|   CHAR16                 *Buffer;
 | |
|   CHAR16                 *StrFrontPageBanner;
 | |
|   UINTN                  Row;
 | |
|   EFI_SCREEN_DESCRIPTOR  LocalScreen;
 | |
| 
 | |
|   ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR));
 | |
|   gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow);
 | |
|   ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND);
 | |
| 
 | |
|   CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | |
| 
 | |
|   //
 | |
|   // For now, allocate an arbitrarily long buffer
 | |
|   //
 | |
|   Buffer = AllocateZeroPool (0x10000);
 | |
|   ASSERT (Buffer != NULL);
 | |
| 
 | |
|   Character = BOXDRAW_HORIZONTAL;
 | |
| 
 | |
|   for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {
 | |
|     Buffer[Index] = Character;
 | |
|   }
 | |
| 
 | |
|   if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {
 | |
|     //
 | |
|     //    ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
 | |
|     //
 | |
|     ClearLines (
 | |
|       LocalScreen.LeftColumn,
 | |
|       LocalScreen.RightColumn,
 | |
|       LocalScreen.TopRow,
 | |
|       FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,
 | |
|       BANNER_TEXT | BANNER_BACKGROUND
 | |
|       );
 | |
|     //
 | |
|     //    for (Line = 0; Line < BANNER_HEIGHT; Line++) {
 | |
|     //
 | |
|     for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) {
 | |
|       //
 | |
|       //      for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
 | |
|       //
 | |
|       for (Alignment = (UINT8) LocalScreen.LeftColumn;
 | |
|            Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;
 | |
|            Alignment++
 | |
|           ) {
 | |
|         if (BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn] != 0x0000) {
 | |
|           StrFrontPageBanner = GetToken (
 | |
|                                 BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn],
 | |
|                                 FrontPageHandle
 | |
|                                 );
 | |
|         } else {
 | |
|           continue;
 | |
|         }
 | |
| 
 | |
|         switch (Alignment - LocalScreen.LeftColumn) {
 | |
|         case 0:
 | |
|           //
 | |
|           // Handle left column
 | |
|           //
 | |
|           PrintStringAt (LocalScreen.LeftColumn, Line, StrFrontPageBanner);
 | |
|           break;
 | |
| 
 | |
|         case 1:
 | |
|           //
 | |
|           // Handle center column
 | |
|           //
 | |
|           PrintStringAt (
 | |
|             LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
 | |
|             Line,
 | |
|             StrFrontPageBanner
 | |
|             );
 | |
|           break;
 | |
| 
 | |
|         case 2:
 | |
|           //
 | |
|           // Handle right column
 | |
|           //
 | |
|           PrintStringAt (
 | |
|             LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
 | |
|             Line,
 | |
|             StrFrontPageBanner
 | |
|             );
 | |
|           break;
 | |
|         }
 | |
| 
 | |
|         gBS->FreePool (StrFrontPageBanner);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   ClearLines (
 | |
|     LocalScreen.LeftColumn,
 | |
|     LocalScreen.RightColumn,
 | |
|     LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT,
 | |
|     LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,
 | |
|     KEYHELP_TEXT | KEYHELP_BACKGROUND
 | |
|     );
 | |
| 
 | |
|   if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
 | |
|     ClearLines (
 | |
|       LocalScreen.LeftColumn,
 | |
|       LocalScreen.RightColumn,
 | |
|       LocalScreen.TopRow,
 | |
|       LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1,
 | |
|       TITLE_TEXT | TITLE_BACKGROUND
 | |
|       );
 | |
|     //
 | |
|     // Print Top border line
 | |
|     // +------------------------------------------------------------------------------+
 | |
|     // ?                                                                             ?
 | |
|     // +------------------------------------------------------------------------------+
 | |
|     //
 | |
|     Character = BOXDRAW_DOWN_RIGHT;
 | |
| 
 | |
|     PrintChar (Character);
 | |
|     PrintString (Buffer);
 | |
| 
 | |
|     Character = BOXDRAW_DOWN_LEFT;
 | |
|     PrintChar (Character);
 | |
| 
 | |
|     Character = BOXDRAW_VERTICAL;
 | |
|     for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {
 | |
|       PrintCharAt (LocalScreen.LeftColumn, Row, Character);
 | |
|       PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
 | |
|     }
 | |
| 
 | |
|     Character = BOXDRAW_UP_RIGHT;
 | |
|     PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);
 | |
|     PrintString (Buffer);
 | |
| 
 | |
|     Character = BOXDRAW_UP_LEFT;
 | |
|     PrintChar (Character);
 | |
| 
 | |
|     if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | |
|       //
 | |
|       // Print Bottom border line
 | |
|       // +------------------------------------------------------------------------------+
 | |
|       // ?                                                                             ?
 | |
|       // +------------------------------------------------------------------------------+
 | |
|       //
 | |
|       Character = BOXDRAW_DOWN_RIGHT;
 | |
|       PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character);
 | |
| 
 | |
|       PrintString (Buffer);
 | |
| 
 | |
|       Character = BOXDRAW_DOWN_LEFT;
 | |
|       PrintChar (Character);
 | |
|       Character = BOXDRAW_VERTICAL;
 | |
|       for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT + 1;
 | |
|            Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
 | |
|            Row++
 | |
|           ) {
 | |
|         PrintCharAt (LocalScreen.LeftColumn, Row, Character);
 | |
|         PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
 | |
|       }
 | |
| 
 | |
|       Character = BOXDRAW_UP_RIGHT;
 | |
|       PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);
 | |
| 
 | |
|       PrintString (Buffer);
 | |
| 
 | |
|       Character = BOXDRAW_UP_LEFT;
 | |
|       PrintChar (Character);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   gBS->FreePool (Buffer);
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Evaluate all expressions in a Form.
 | |
| 
 | |
|   @param  FormSet        FormSet this Form belongs to.
 | |
|   @param  Form           The Form.
 | |
| 
 | |
|   @retval EFI_SUCCESS    The expression evaluated successfuly
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EvaluateFormExpressions (
 | |
|   IN FORM_BROWSER_FORMSET  *FormSet,
 | |
|   IN FORM_BROWSER_FORM     *Form
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS       Status;
 | |
|   LIST_ENTRY       *Link;
 | |
|   FORM_EXPRESSION  *Expression;
 | |
| 
 | |
|   Link = GetFirstNode (&Form->ExpressionListHead);
 | |
|   while (!IsNull (&Form->ExpressionListHead, Link)) {
 | |
|     Expression = FORM_EXPRESSION_FROM_LINK (Link);
 | |
|     Link = GetNextNode (&Form->ExpressionListHead, Link);
 | |
| 
 | |
|     if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||
 | |
|         Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {
 | |
|       //
 | |
|       // Postpone Form validation to Question editing or Form submiting
 | |
|       //
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     Status = EvaluateExpression (FormSet, Form, Expression);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /*
 | |
| +------------------------------------------------------------------------------+
 | |
| ?F2=Previous Page                 Setup Page                                  ?
 | |
| +------------------------------------------------------------------------------+
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| +------------------------------------------------------------------------------+
 | |
| ?F1=Scroll Help                 F9=Reset to Defaults        F10=Save and Exit ?
 | |
| | ^"=Move Highlight          <Spacebar> Toggles Checkbox   Esc=Discard Changes |
 | |
| +------------------------------------------------------------------------------+
 | |
| */
 | |
| EFI_STATUS
 | |
| DisplayForm (
 | |
|   IN OUT UI_MENU_SELECTION           *Selection
 | |
|   )
 | |
| {
 | |
|   CHAR16                 *StringPtr;
 | |
|   UINT16                 MenuItemCount;
 | |
|   EFI_HII_HANDLE         Handle;
 | |
|   BOOLEAN                Suppress;
 | |
|   EFI_SCREEN_DESCRIPTOR  LocalScreen;
 | |
|   UINT16                 Width;
 | |
|   UINTN                  ArrayEntry;
 | |
|   CHAR16                 *OutputString;
 | |
|   LIST_ENTRY             *Link;
 | |
|   FORM_BROWSER_STATEMENT *Statement;
 | |
|   UINT16                 NumberOfLines;
 | |
|   EFI_STATUS             Status;
 | |
| 
 | |
|   Handle        = Selection->Handle;
 | |
|   MenuItemCount = 0;
 | |
|   ArrayEntry    = 0;
 | |
|   OutputString  = NULL;
 | |
| 
 | |
|   UiInitMenu ();
 | |
| 
 | |
|   CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | |
| 
 | |
|   StringPtr = GetToken (Selection->FormSet->FormSetTitle, Handle);
 | |
| 
 | |
|   if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
 | |
|     gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);
 | |
|     PrintStringAt (
 | |
|       (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,
 | |
|       LocalScreen.TopRow + 1,
 | |
|       StringPtr
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | |
|     gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | |
| 
 | |
|     //
 | |
|     // Display the infrastructure strings
 | |
|     //
 | |
|     if (!IsListEmpty (&gMenuList)) {
 | |
|       PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.TopRow + 1, gFunctionTwoString);
 | |
|     }
 | |
| 
 | |
|     PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 4, gFunctionOneString);
 | |
|     PrintStringAt (
 | |
|       LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
 | |
|       LocalScreen.BottomRow - 4,
 | |
|       gFunctionNineString
 | |
|       );
 | |
|     PrintStringAt (
 | |
|       LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
 | |
|       LocalScreen.BottomRow - 4,
 | |
|       gFunctionTenString
 | |
|       );
 | |
|     PrintAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 3, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | |
|     PrintStringAt (
 | |
|       LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
 | |
|       LocalScreen.BottomRow - 3,
 | |
|       gEscapeString
 | |
|       );
 | |
|   }
 | |
|   //
 | |
|   // Remove Buffer allocated for StringPtr after it has been used.
 | |
|   //
 | |
|   gBS->FreePool (StringPtr);
 | |
| 
 | |
|   //
 | |
|   // Evaluate all the Expressions in this Form
 | |
|   //
 | |
|   Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Link = GetFirstNode (&Selection->Form->StatementListHead);
 | |
|   while (!IsNull (&Selection->Form->StatementListHead, Link)) {
 | |
|     Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
 | |
| 
 | |
|     if (Statement->SuppressExpression != NULL) {
 | |
|       Suppress = Statement->SuppressExpression->Result.Value.b;
 | |
|     } else {
 | |
|       Suppress = FALSE;
 | |
|     }
 | |
| 
 | |
|     if (!Suppress) {
 | |
|       StringPtr = GetToken (Statement->Prompt, Handle);
 | |
| 
 | |
|       Width     = GetWidth (Statement, Handle);
 | |
| 
 | |
|       NumberOfLines = 1;
 | |
|       ArrayEntry = 0;
 | |
|       for (; GetLineByWidth (StringPtr, Width, &ArrayEntry, &OutputString) != 0x0000;) {
 | |
|         //
 | |
|         // If there is more string to process print on the next row and increment the Skip value
 | |
|         //
 | |
|         if (StrLen (&StringPtr[ArrayEntry])) {
 | |
|           NumberOfLines++;
 | |
|         }
 | |
| 
 | |
|         gBS->FreePool (OutputString);
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
 | |
|       // it in UiFreeMenu.
 | |
|       //
 | |
|       UiAddMenuOption (StringPtr, Selection->Handle, Statement, NumberOfLines, MenuItemCount);
 | |
|       MenuItemCount++;
 | |
|     }
 | |
| 
 | |
|     Link = GetNextNode (&Selection->Form->StatementListHead, Link);
 | |
|   }
 | |
| 
 | |
|   Status = UiDisplayMenu (Selection);
 | |
| 
 | |
|   UiFreeMenu ();
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| InitializeBrowserStrings (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   gFunctionOneString    = GetToken (STRING_TOKEN (FUNCTION_ONE_STRING), gHiiHandle);
 | |
|   gFunctionTwoString    = GetToken (STRING_TOKEN (FUNCTION_TWO_STRING), gHiiHandle);
 | |
|   gFunctionNineString   = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);
 | |
|   gFunctionTenString    = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);
 | |
|   gEnterString          = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);
 | |
|   gEnterCommitString    = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);
 | |
|   gEscapeString         = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);
 | |
|   gSaveFailed           = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
 | |
|   gMoveHighlight        = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);
 | |
|   gMakeSelection        = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);
 | |
|   gDecNumericInput      = GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), gHiiHandle);
 | |
|   gHexNumericInput      = GetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), gHiiHandle);
 | |
|   gToggleCheckBox       = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle);
 | |
|   gPromptForData        = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);
 | |
|   gPromptForPassword    = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
 | |
|   gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
 | |
|   gConfirmPassword      = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
 | |
|   gConfirmError         = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
 | |
|   gPassowordInvalid     = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);
 | |
|   gPressEnter           = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
 | |
|   gEmptyString          = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
 | |
|   gAreYouSure           = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle);
 | |
|   gYesResponse          = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);
 | |
|   gNoResponse           = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);
 | |
|   gMiniString           = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
 | |
|   gPlusString           = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle);
 | |
|   gMinusString          = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle);
 | |
|   gAdjustNumber         = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| FreeBrowserStrings (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   SafeFreePool (gFunctionOneString);
 | |
|   SafeFreePool (gFunctionTwoString);
 | |
|   SafeFreePool (gFunctionNineString);
 | |
|   SafeFreePool (gFunctionTenString);
 | |
|   SafeFreePool (gEnterString);
 | |
|   SafeFreePool (gEnterCommitString);
 | |
|   SafeFreePool (gEscapeString);
 | |
|   SafeFreePool (gMoveHighlight);
 | |
|   SafeFreePool (gMakeSelection);
 | |
|   SafeFreePool (gDecNumericInput);
 | |
|   SafeFreePool (gHexNumericInput);
 | |
|   SafeFreePool (gToggleCheckBox);
 | |
|   SafeFreePool (gPromptForData);
 | |
|   SafeFreePool (gPromptForPassword);
 | |
|   SafeFreePool (gPromptForNewPassword);
 | |
|   SafeFreePool (gConfirmPassword);
 | |
|   SafeFreePool (gPassowordInvalid);
 | |
|   SafeFreePool (gConfirmError);
 | |
|   SafeFreePool (gPressEnter);
 | |
|   SafeFreePool (gEmptyString);
 | |
|   SafeFreePool (gAreYouSure);
 | |
|   SafeFreePool (gYesResponse);
 | |
|   SafeFreePool (gNoResponse);
 | |
|   SafeFreePool (gMiniString);
 | |
|   SafeFreePool (gPlusString);
 | |
|   SafeFreePool (gMinusString);
 | |
|   SafeFreePool (gAdjustNumber);
 | |
|   return ;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Update key's help imformation
 | |
| 
 | |
|   @param  MenuOption     The Menu option
 | |
|   @param  Selected       Whether or not a tag be selected
 | |
| 
 | |
|   @return None
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| UpdateKeyHelp (
 | |
|   IN  UI_MENU_OPTION              *MenuOption,
 | |
|   IN  BOOLEAN                     Selected
 | |
|   )
 | |
| {
 | |
|   UINTN                  SecCol;
 | |
|   UINTN                  ThdCol;
 | |
|   UINTN                  LeftColumnOfHelp;
 | |
|   UINTN                  RightColumnOfHelp;
 | |
|   UINTN                  TopRowOfHelp;
 | |
|   UINTN                  BottomRowOfHelp;
 | |
|   UINTN                  StartColumnOfHelp;
 | |
|   EFI_SCREEN_DESCRIPTOR  LocalScreen;
 | |
|   FORM_BROWSER_STATEMENT *Statement;
 | |
| 
 | |
|   CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
 | |
| 
 | |
|   SecCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
 | |
|   ThdCol            = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3;
 | |
| 
 | |
|   StartColumnOfHelp = LocalScreen.LeftColumn + 2;
 | |
|   LeftColumnOfHelp  = LocalScreen.LeftColumn + 1;
 | |
|   RightColumnOfHelp = LocalScreen.RightColumn - 2;
 | |
|   TopRowOfHelp      = LocalScreen.BottomRow - 4;
 | |
|   BottomRowOfHelp   = LocalScreen.BottomRow - 3;
 | |
| 
 | |
|   if (gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS) {
 | |
|     return ;
 | |
|   }
 | |
| 
 | |
|   gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | |
| 
 | |
|   Statement = MenuOption->ThisTag;
 | |
|   switch (Statement->Operand) {
 | |
|   case EFI_IFR_ORDERED_LIST_OP:
 | |
|   case EFI_IFR_ONE_OF_OP:
 | |
|   case EFI_IFR_NUMERIC_OP:
 | |
|   case EFI_IFR_TIME_OP:
 | |
|   case EFI_IFR_DATE_OP:
 | |
|     ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | |
| 
 | |
|     if (!Selected) {
 | |
|       if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | |
|         PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
 | |
|         PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
 | |
|         PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
 | |
|         PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | |
|       }
 | |
| 
 | |
|       if ((Statement->Operand == EFI_IFR_DATE_OP) ||
 | |
|           (Statement->Operand == EFI_IFR_TIME_OP) ||
 | |
|           (Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0)) {
 | |
|         PrintAt (
 | |
|           StartColumnOfHelp,
 | |
|           BottomRowOfHelp,
 | |
|           L"%c%c%c%c%s",
 | |
|           ARROW_UP,
 | |
|           ARROW_DOWN,
 | |
|           ARROW_RIGHT,
 | |
|           ARROW_LEFT,
 | |
|           gMoveHighlight
 | |
|           );
 | |
|         PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber);
 | |
|       } else {
 | |
|         PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | |
|         PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
 | |
|       }
 | |
|     } else {
 | |
|       PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);
 | |
| 
 | |
|       //
 | |
|       // If it is a selected numeric with manual input, display different message
 | |
|       //
 | |
|       if ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step == 0)) {
 | |
|         PrintStringAt (
 | |
|           SecCol,
 | |
|           TopRowOfHelp,
 | |
|           (Statement->Flags & EFI_IFR_DISPLAY_UINT_HEX) ? gHexNumericInput : gDecNumericInput
 | |
|           );
 | |
|       } else if (Statement->Operand != EFI_IFR_ORDERED_LIST_OP) {
 | |
|         PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | |
|       }
 | |
| 
 | |
|       if (Statement->Operand == EFI_IFR_ORDERED_LIST_OP) {
 | |
|         PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);
 | |
|         PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);
 | |
|       }
 | |
| 
 | |
|       PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | |
|     }
 | |
|     break;
 | |
| 
 | |
|   case EFI_IFR_CHECKBOX_OP:
 | |
|     ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | |
| 
 | |
|     if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | |
|       PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
 | |
|       PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
 | |
|       PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
 | |
|       PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | |
|     }
 | |
| 
 | |
|     PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | |
|     PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);
 | |
|     break;
 | |
| 
 | |
|   case EFI_IFR_REF_OP:
 | |
|   case EFI_IFR_PASSWORD_OP:
 | |
|   case EFI_IFR_STRING_OP:
 | |
|   case EFI_IFR_TEXT_OP:
 | |
|   case EFI_IFR_ACTION_OP:
 | |
|   case EFI_IFR_RESET_BUTTON_OP:
 | |
|     ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
 | |
| 
 | |
|     if (!Selected) {
 | |
|       if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
 | |
|         PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
 | |
|         PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
 | |
|         PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
 | |
|         PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | |
|       }
 | |
| 
 | |
|       PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
 | |
|       if (Statement->Operand != EFI_IFR_TEXT_OP) {
 | |
|         PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
 | |
|       }
 | |
|     } else {
 | |
|       if (Statement->Operand != EFI_IFR_REF_OP) {
 | |
|         PrintStringAt (
 | |
|           (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,
 | |
|           BottomRowOfHelp,
 | |
|           gEnterCommitString
 | |
|           );
 | |
|         PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
 | |
|       }
 | |
|     }
 | |
|     break;
 | |
| 
 | |
|   default:
 | |
|     break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| FormUpdateNotify (
 | |
|   IN UINT8                              PackageType,
 | |
|   IN CONST EFI_GUID                     *PackageGuid,
 | |
|   IN CONST EFI_HII_PACKAGE_HEADER       *Package,
 | |
|   IN EFI_HII_HANDLE                     Handle,
 | |
|   IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType
 | |
|   )
 | |
| {
 | |
|   mHiiPackageListUpdated = TRUE;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| SetupBrowser (
 | |
|   IN OUT UI_MENU_SELECTION    *Selection
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                      Status;
 | |
|   LIST_ENTRY                      *Link;
 | |
|   EFI_BROWSER_ACTION_REQUEST      ActionRequest;
 | |
|   EFI_HANDLE                      NotifyHandle;
 | |
|   EFI_HII_VALUE                   *HiiValue;
 | |
|   FORM_BROWSER_STATEMENT          *Statement;
 | |
|   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
 | |
| 
 | |
|   gMenuRefreshHead = NULL;
 | |
|   gResetRequired = FALSE;
 | |
|   gNvUpdateRequired = FALSE;
 | |
| 
 | |
|   UiInitMenuList ();
 | |
| 
 | |
|   //
 | |
|   // Register notify for Form package update
 | |
|   //
 | |
|   Status = mHiiDatabase->RegisterPackageNotify (
 | |
|                            mHiiDatabase,
 | |
|                            EFI_HII_PACKAGE_FORM,
 | |
|                            NULL,
 | |
|                            FormUpdateNotify,
 | |
|                            EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
 | |
|                            &NotifyHandle
 | |
|                            );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   do {
 | |
|     //
 | |
|     // Displays the Header and Footer borders
 | |
|     //
 | |
|     DisplayPageFrame ();
 | |
| 
 | |
|     //
 | |
|     // Initialize Selection->Form
 | |
|     //
 | |
|     if (Selection->FormId == 0) {
 | |
|       //
 | |
|       // Zero FormId indicates display the first Form in a FormSet
 | |
|       //
 | |
|       Link = GetFirstNode (&Selection->FormSet->FormListHead);
 | |
| 
 | |
|       Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link);
 | |
|       Selection->FormId = Selection->Form->FormId;
 | |
|     } else {
 | |
|       Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Load Questions' Value for display
 | |
|     //
 | |
|     Status = LoadFormConfig (Selection->FormSet, Selection->Form);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Display form
 | |
|     //
 | |
|     Status = DisplayForm (Selection);
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
 | |
|     //
 | |
|     Statement = Selection->Statement;
 | |
|     if (Statement != NULL) {
 | |
|       if (Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) {
 | |
|         gResetRequired = TRUE;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Reset FormPackage update flag
 | |
|       //
 | |
|       mHiiPackageListUpdated = FALSE;
 | |
| 
 | |
|       if (Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK && Statement->Operand != EFI_IFR_PASSWORD_OP) {
 | |
|         ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
 | |
| 
 | |
|         HiiValue = &Statement->HiiValue;
 | |
|         if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
 | |
|           //
 | |
|           // Create String in HII database for Configuration Driver to retrieve
 | |
|           //
 | |
|           HiiValue->Value.string = NewString ((CHAR16 *) Statement->BufferValue, Selection->FormSet->HiiHandle);
 | |
|         }
 | |
| 
 | |
|         ConfigAccess = Selection->FormSet->ConfigAccess;
 | |
|         if (ConfigAccess == NULL) {
 | |
|           return EFI_UNSUPPORTED;
 | |
|         }
 | |
|         Status = ConfigAccess->Callback (
 | |
|                                  ConfigAccess,
 | |
|                                  EFI_BROWSER_ACTION_CHANGING,
 | |
|                                  Statement->QuestionId,
 | |
|                                  HiiValue->Type,
 | |
|                                  &HiiValue->Value,
 | |
|                                  &ActionRequest
 | |
|                                  );
 | |
| 
 | |
|         if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
 | |
|           //
 | |
|           // Clean the String in HII Database
 | |
|           //
 | |
|           DeleteString (HiiValue->Value.string, Selection->FormSet->HiiHandle);
 | |
|         }
 | |
| 
 | |
|         if (!EFI_ERROR (Status)) {
 | |
|           switch (ActionRequest) {
 | |
|           case EFI_BROWSER_ACTION_REQUEST_RESET:
 | |
|             gResetRequired = TRUE;
 | |
|             break;
 | |
| 
 | |
|           case EFI_BROWSER_ACTION_REQUEST_SUBMIT:
 | |
|             SubmitForm (Selection->FormSet, Selection->Form);
 | |
|             break;
 | |
| 
 | |
|           case EFI_BROWSER_ACTION_REQUEST_EXIT:
 | |
|             Selection->Action = UI_ACTION_EXIT;
 | |
|             gNvUpdateRequired = FALSE;
 | |
|             break;
 | |
| 
 | |
|           default:
 | |
|             break;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Check whether Form Package has been updated during Callback
 | |
|       //
 | |
|       if (mHiiPackageListUpdated && (Selection->Action == UI_ACTION_REFRESH_FORM)) {
 | |
|         //
 | |
|         // Force to reparse IFR binary of target Formset
 | |
|         //
 | |
|         Selection->Action = UI_ACTION_REFRESH_FORMSET;
 | |
|       }
 | |
|     }
 | |
|   } while (Selection->Action == UI_ACTION_REFRESH_FORM);
 | |
| 
 | |
|   //
 | |
|   // Unregister notify for Form package update
 | |
|   //
 | |
|   Status = mHiiDatabase->UnregisterPackageNotify (
 | |
|                            mHiiDatabase,
 | |
|                            NotifyHandle
 | |
|                            );
 | |
|   return Status;
 | |
| }
 |