presentation.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,477 行 · 第 1/4 页

C
1,477
字号
  UINT16              Width;
  UINTN               ArrayEntry;
  CHAR16              *OutputString;

  Handle        = Selection->Handle;
  FormId        = 0;
  String        = 0;
  MenuItemCount = 0;
  ArrayEntry    = 0;
  OutputString  = NULL;

  EfiCopyMem (&LocalScreen, &gScreenDimensions, sizeof (SCREEN_DESCRIPTOR));

  //
  // If we hit a F2 (previous) we already nuked the menu and are simply carrying around what information we need
  //
  if (Selection->Previous) {
    Selection->Previous = FALSE;
  } else {
    UiFreeMenu ();
    UiInitMenu ();
  }

  StringPtr = GetToken (TitleToken, 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);

  for (Index = 0; FormTags.Tags[Index].Operand != EFI_IFR_END_FORM_OP; Index++) {
    GrayOut       = FALSE;
    Suppress      = FALSE;
    SuppressIf    = FALSE;
    Conditional   = FALSE;
    FileFormTags  = FileFormTagsHead;

    if (FormTags.Tags[Index].Operand == EFI_IFR_FORM_OP) {
      FormId = FormTags.Tags[Index].Id;
    }
    //
    // This gives us visibility to the FileFormTags->NvRamMap to check things
    // ActiveIfr is a global maintained by the menuing code to ensure that we
    // are pointing to the correct formset's file data.
    //
    for (Count = 0; Count < gActiveIfr; Count++) {
      FileFormTags = FileFormTags->NextFile;
    }
    //
    //  GrayoutIf [SuppressIf]
    //    <BOOLEANS>
    //      OpCode(s)
    //  EndIf
    //
    //  SuppressIf [GrayoutIf]
    //    <BOOLEANS>
    //      OpCode(s)
    //  EndIf
    //
    Count = 0;

    do {
      switch (FormTags.Tags[Index].Operand) {
      case EFI_IFR_SUPPRESS_IF_OP:
        SuppressIf = TRUE;

      case EFI_IFR_GRAYOUT_IF_OP:

        Conditional = TRUE;

        //
        // Advance to the next op-code
        //
        Index++;

        //
        // We are now pointing to the beginning of the consistency checking.  Let's fast forward
        // through the AND/OR/NOT data to come up with some meaningful ID data.
        //
        for (;
             FormTags.Tags[Index].Operand == EFI_IFR_AND_OP   ||
             FormTags.Tags[Index].Operand == EFI_IFR_OR_OP    ||
             FormTags.Tags[Index].Operand == EFI_IFR_GT_OP    ||
             FormTags.Tags[Index].Operand == EFI_IFR_GE_OP    ||
             FormTags.Tags[Index].Operand == EFI_IFR_NOT_OP;
           Index++
            )
          ;

        //
        // We need to walk through the consistency checks until we hit the end of the consistency
        // FALSE means evaluate this single expression
        // The ConsistencyId refers to which expression in the Consistency database to use
        //
        if (SuppressIf) {
          Suppress = ValueIsNotValid (
                      FALSE,
                      FormTags.Tags[Index].ConsistencyId,
                      &FormTags.Tags[Index],
                      FileFormTags,
                      &String
                      );
          SuppressIf = FALSE;
        } else {
          GrayOut = ValueIsNotValid (
                      FALSE,
                      FormTags.Tags[Index].ConsistencyId,
                      &FormTags.Tags[Index],
                      FileFormTags,
                      &String
                      );
        }
        //
        // Advance to the end of the expression (Will land us at a grayoutif/suppressif or the op-code being affected)
        //
        for (;
             FormTags.Tags[Index].Operand == EFI_IFR_EQ_ID_VAL_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_EQ_VAR_VAL_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_EQ_ID_ID_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_EQ_ID_LIST_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_NOT_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_AND_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_OR_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_TRUE_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_FALSE_OP ||
             FormTags.Tags[Index].Operand == EFI_IFR_GT_OP    ||
             FormTags.Tags[Index].Operand == EFI_IFR_GE_OP    ||
             FormTags.Tags[Index].Operand == EFI_IFR_LABEL_OP;
           Index++
            )
          ;
        break;

      default:
        goto GetOut;
      }
      //
      // Do this two times (at most will see a suppress and grayout combination
      //
      Count++;
    } while (Count < 2);

GetOut:
    do {
      if (GrayOut) {
        FormTags.Tags[Index].GrayOut = TRUE;
      } else {
        FormTags.Tags[Index].GrayOut = FALSE;
      }
      if (Suppress && FormTags.Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
        //
        // Only need .Suppress field when the tag is a one_of_option. For other cases, omit them directly.
        //
        FormTags.Tags[Index].Suppress = TRUE;
      } else {
        FormTags.Tags[Index].Suppress = FALSE;
      }

      if ((
            FormTags.Tags[Index].NumberOfLines > 0 ||
            FormTags.Tags[Index].Operand == EFI_IFR_DATE_OP ||
            FormTags.Tags[Index].Operand == EFI_IFR_TIME_OP
          ) &&
          !Suppress
          ) {

        StringPtr = GetToken (FormTags.Tags[Index].Text, Handle);

        Width     = GetWidth (&FormTags.Tags[Index], Handle);

        //
        // This data can be retrieved over and over again.  Therefore, reset to original values
        // before processing otherwise things will start growing linearly
        //
        if (FormTags.Tags[Index].NumberOfLines > 1) {
          FormTags.Tags[Index].NumberOfLines = 1;
        }

        for (Count = 0; GetLineByWidth (StringPtr, Width, &ArrayEntry, &OutputString) != 0x0000;) {
          //
          // If there is more string to process print on the next row and increment the Skip value
          //
          if (EfiStrLen (&StringPtr[ArrayEntry])) {
            FormTags.Tags[Index].NumberOfLines++;
          }

          gBS->FreePool (OutputString);
        }

        ArrayEntry = 0;

        //
        // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
        // it in UiFreeMenu.
        //
        UiAddSubMenuOption (StringPtr, Handle, FormTags.Tags, Index, FormId, MenuItemCount);
        MenuItemCount++;
      }
      //
      // Keep processing menu entries based on the resultant suppress/grayout results until we hit an end-if
      //
      Index++;
    } while (FormTags.Tags[Index].Operand != EFI_IFR_END_IF_OP && Conditional);

    //
    // We advanced the index for the above conditional, rewind it to keep harmony with the for loop logic
    //
    Index--;
  }

  Selection = UiDisplayMenu (TRUE, FileFormTagsHead, (EFI_IFR_DATA_ARRAY *) CallbackData);

  return Selection;
}

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);
  gMoveHighlight        = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);
  gMakeSelection        = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);
  gNumericInput         = GetToken (STRING_TOKEN (NUMERIC_INPUT), gHiiHandle);
  gToggleCheckBox       = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), 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);
  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
UpdateKeyHelp (
  IN  UI_MENU_OPTION              *Selection,
  IN  BOOLEAN                     Selected
  )
/*++
Routine Description:
  Update key's help imformation

Arguments:
  Selection C The form that current display
  Selected C  Whether or not a tag be selected

Returns:
  None
--*/
{
  UINTN             SecCol;
  UINTN             ThdCol;
  UINTN             LeftColumnOfHelp;
  UINTN             RightColumnOfHelp;
  UINTN             TopRowOfHelp;
  UINTN             BottomRowOfHelp;
  UINTN             StartColumnOfHelp;
  SCREEN_DESCRIPTOR LocalScreen;

  EfiCopyMem (&LocalScreen, &gScreenDimensions, sizeof (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);

  switch (Selection->ThisTag->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 ((Selection->ThisTag->Operand == EFI_IFR_DATE_OP) || (Selection->ThisTag->Operand == EFI_IFR_TIME_OP)) {
        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 ((Selection->ThisTag->Operand == EFI_IFR_NUMERIC_OP) && (Selection->ThisTag->Step == 0)) {
        PrintStringAt (SecCol, TopRowOfHelp, gNumericInput);
      } else if (Selection->ThisTag->Operand != EFI_IFR_ORDERED_LIST_OP) {
        PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?