presentation.c

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

C
1,477
字号
      }

      if (Selection->ThisTag->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:
    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);
      PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
    } else {
      if (Selection->ThisTag->Operand != EFI_IFR_REF_OP) {
        PrintStringAt (
          (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,
          BottomRowOfHelp,
          gEnterCommitString
          );
        PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
      }
    }
    break;
  }

}

VOID
ExtractFormHandle (
  IN  UI_MENU_OPTION              *Selection,
  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,
  IN  UINTN                       IdValue,
  OUT UINT16                      *FormHandle,
  OUT UINT16                      *TitleToken,
  OUT EFI_FORM_TAGS               *FormTags
  )
{
  UINTN               Index;
  EFI_FILE_FORM_TAGS  *FileFormTags;
  EFI_FORM_TAGS       LocalTags;

  FileFormTags = FileFormTagsHead;

  //
  // Advance FileFormTags to the correct file's tag information.
  // For instance, if Selection->IfrNumber is 3, that means the 4th
  // file (0-based) in the FileFormTags linked-list contains the tag
  // information.
  //
  for (Index = 0; Index < Selection->IfrNumber; Index++) {
    FileFormTags = FileFormTags->NextFile;
  }

  LocalTags = FileFormTags->FormTags;

  if (IdValue == 0) {
    //
    // Advance Index to the first FormOp tag information
    //
    for (Index = 0; FileFormTags->FormTags.Tags[Index].Operand != EFI_IFR_FORM_OP; Index++)
      ;
  } else {
    //
    // Advance Index to the FormOp with the correct ID value
    //
    for (; LocalTags.Next != NULL; LocalTags = *LocalTags.Next) {
      for (Index = 0; LocalTags.Tags[Index].Operand != EFI_IFR_FORM_OP; Index++)
        ;
      if (LocalTags.Tags[Index].Id == IdValue) {
        break;
      }
    }
  }
  //
  // return the Form Id, Text, and the File's FormTags structure
  //
  *FormHandle = LocalTags.Tags[Index].Id;
  *TitleToken = LocalTags.Tags[Index].Text;
  *FormTags   = LocalTags;
  return ;
}

EFI_STATUS
UpdateNewTagData (
  IN  UINT8                                     *FormData,
  IN  UINT16                                    ConsistencyId,
  IN  UINT16                                    CurrentVariable,
  IN  EFI_FORM_TAGS                             *FormTags,
  OUT EFI_FILE_FORM_TAGS                        *FileFormTags
  )
{
  EFI_STATUS  Status;
  UINT16      Index;
  UINT16      QuestionIndex;
  UINT16      NumberOfTags;
  INT16       CurrTag;
  UINT8       TagLength;
  UINTN       Count;
  BOOLEAN     Finished;

  //
  // Initialize some Index variable and Status
  //
  Count         = 0;
  QuestionIndex = 0;
  NumberOfTags  = 1;
  Index         = 0;
  Status        = EFI_SUCCESS;
  Finished      = FALSE;

  //
  // Determine the number of tags for the first form
  //
  GetTagCount (&FormData[Index], &NumberOfTags);

  //
  // Allocate memory for our tags on the first form
  //
  FormTags->Tags = EfiLibAllocateZeroPool (NumberOfTags * sizeof (EFI_TAG));
  ASSERT (FormTags->Tags != NULL);

  for (CurrTag = 0; FormData[Index] != EFI_IFR_END_FORM_SET_OP; CurrTag++) {
    //
    // Operand = IFR OpCode
    //
    FormTags->Tags[CurrTag].Operand = FormData[Index];

    //
    // Assume for now 0 lines occupied by this OpCode
    //
    FormTags->Tags[CurrTag].NumberOfLines = 0;

    //
    // Determine the length of the Tag so we can later skip to the next tag in the form
    //
    //
    // get the length
    //
    TagLength = FormData[Index + 1];
    //
    // Operate on the Found OpCode
    //
    switch (FormData[Index]) {

    case EFI_IFR_FORM_OP:
    case EFI_IFR_SUBTITLE_OP:
    case EFI_IFR_TEXT_OP:
    case EFI_IFR_REF_OP:
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      break;

    case EFI_IFR_VARSTORE_SELECT_OP:
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      EfiCopyMem (&CurrentVariable, &((EFI_IFR_VARSTORE_SELECT *) &FormData[Index])->VarId, sizeof (UINT16));
      break;

    case EFI_IFR_END_FORM_OP:
      FormTags->Tags[CurrTag].Operand       = FormData[Index];
      FormTags->Tags[CurrTag].NumberOfLines = 0;

      Finished = TRUE;
      break;

    case EFI_IFR_ORDERED_LIST_OP:
    case EFI_IFR_ONE_OF_OP:
      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, Index, FileFormTags, CurrentVariable);

      //
      // Store away the CurrTag since what follows will be the answer that we
      // need to place into the appropriate location in the tag array
      //
      //
      // record for setting default later
      //
      QuestionIndex = (UINT16) CurrTag;
      break;

    case EFI_IFR_ONE_OF_OPTION_OP:
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      FormTags->Tags[QuestionIndex].Key = ((EFI_IFR_ONE_OF_OPTION *) &FormData[Index])->Key;
      FormTags->Tags[QuestionIndex].ResetRequired = (BOOLEAN) (FormTags->Tags[QuestionIndex].Flags & EFI_IFR_FLAG_RESET_REQUIRED);
      break;

    case EFI_IFR_CHECKBOX_OP:
      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, Index, FileFormTags, CurrentVariable);
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      break;

    case EFI_IFR_NUMERIC_OP:
      GetNumericHeader (&FormTags->Tags[CurrTag], FormData, Index, (UINT16) 1, FileFormTags, CurrentVariable);
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      break;

    case EFI_IFR_DATE_OP:
      //
      // Date elements come in as a Year, Month, Day.  We need to process them as a country-based
      // Order.  It is much easier to do it here than anywhere else.
      //
      // For US standards - we want Month/Day/Year, thus we advance "i" +1, +2, +0 while CurrTag is +0, +1, +2
      //
      GetNumericHeader (
        &FormTags->Tags[CurrTag],
        FormData,
        (UINT16) (Index + TagLength),
        (UINT16) 0,
        FileFormTags,
        CurrentVariable
        );

      //
      // The current language selected + the Date operand
      //
      FormTags->Tags[CurrTag + 1].Operand = FormData[Index];
      GetNumericHeader (
        &FormTags->Tags[CurrTag + 1],
        FormData,
        (UINT16) (Index + TagLength + FormData[Index + TagLength + 1]),
        (UINT16) 0,
        FileFormTags,
        CurrentVariable
        );

      //
      // The current language selected + the Date operand
      //
      FormTags->Tags[CurrTag + 2].Operand = FormData[Index];
      GetNumericHeader (&FormTags->Tags[CurrTag + 2], FormData, Index, (UINT16) 1, FileFormTags, CurrentVariable);

      CurrTag   = (INT16) (CurrTag + 2);

      Index     = (UINT16) (Index + TagLength);
      //
      // get the length
      //
      TagLength = FormData[Index + 1];
      Index     = (UINT16) (Index + TagLength);
      //
      // get the length
      //
      TagLength = FormData[Index + 1];
      break;

    case EFI_IFR_TIME_OP:
      GetNumericHeader (&FormTags->Tags[CurrTag], FormData, Index, (UINT16) 0, FileFormTags, CurrentVariable);

      if (Count == 2) {
        //
        // Override the GetQuestionHeader information - date/time are treated very differently
        //
        FormTags->Tags[CurrTag].NumberOfLines = 1;
        Count = 0;
      } else {
        //
        // The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines
        // associated with them, and the third has 1 line to allow to space beyond the choice.
        //
        Count++;
      }
      break;

    case EFI_IFR_PASSWORD_OP:
    case EFI_IFR_STRING_OP:
      GetQuestionHeader (&FormTags->Tags[CurrTag], FormData, Index, FileFormTags, CurrentVariable);
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      break;

    case EFI_IFR_INCONSISTENT_IF_OP:
    case EFI_IFR_SUPPRESS_IF_OP:
    case EFI_IFR_GRAYOUT_IF_OP:
      ConsistencyId++;
      break;

    case EFI_IFR_EQ_ID_VAL_OP:
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
      break;

    case EFI_IFR_EQ_VAR_VAL_OP:
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
      break;

    case EFI_IFR_EQ_ID_ID_OP:
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
      break;

    case EFI_IFR_AND_OP:
    case EFI_IFR_OR_OP:
    case EFI_IFR_NOT_OP:
    case EFI_IFR_TRUE_OP:
    case EFI_IFR_FALSE_OP:
    case EFI_IFR_GT_OP:
    case EFI_IFR_GE_OP:
      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
      break;

    case EFI_IFR_EQ_ID_LIST_OP:
      IfrToFormTag (FormData[Index], &FormTags->Tags[CurrTag], (VOID *) &FormData[Index], NULL);

      FormTags->Tags[CurrTag].ConsistencyId = ConsistencyId;
      break;

    default:
      break;
    }
    //
    // End of switch
    //
    if (Finished) {
      break;
    }
    //
    // Per spec., we ignore ops that we don't know how to deal with.  Skip to next tag
    //
    Index = (UINT16) (Index + TagLength);
  }
  //
  // End of Index
  //
  return Status;
}

VOID
ExtractDynamicFormHandle (
  IN  UI_MENU_OPTION              *Selection,
  IN  UINT8                       *CallbackData,
  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,
  IN  UINTN                       IdValue,
  OUT UINT16                      *FormHandle,
  OUT UINT16                      *TitleToken,
  OUT EFI_FORM_TAGS               *FormTags
  )
/*++

Routine Description:

  The function does the most of the works when the EFI_TAG that
  user selects on is EFI_IFR_FLAG_INTERACTIVE or EFI_IFR_PASSWORD_OP:
  invoke CallBack, update the new form data.
  
Arguments:

⌨️ 快捷键说明

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