presentation.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,477 行 · 第 1/4 页
C
1,477 行
Selection - The current selection of the form.
CallbackData - The pointer to host the data passed back by the callback function.
FileFormTagsHead - Prompt string token of the one-of box
IdValue - The current page number.
FormHandle - Output the the handle of the form.
TitleToken - Output the TitleToken of the new page.
FormTags - Output the FormFags of the new page.
Returns:
VOID
--*/
{
UINTN Index;
UINTN BackupIndex;
EFI_FILE_FORM_TAGS *FileFormTags;
EFI_FORM_TAGS *LocalTags;
EFI_FORM_CALLBACK_PROTOCOL *FormCallback;
EFI_STATUS Status;
UINTN Length;
UINT8 *Buffer;
EFI_PHYSICAL_ADDRESS CallbackHandle;
EFI_GUID TagGuid;
UINT16 TargetPage;
EFI_HII_CALLBACK_PACKET *Packet;
UINTN ScreenSize;
CHAR16 NullCharacter;
EFI_INPUT_KEY Key;
UINT16 ConsistencyId;
UINT16 CurrentVariable;
EFI_VARIABLE_DEFINITION *VariableDefinition;
VariableDefinition = NULL;
NullCharacter = CHAR_NULL;
CurrentVariable = 0;
FileFormTags = FileFormTagsHead;
Length = 0;
CallbackHandle = 0;
TargetPage = (UINT16) IdValue;
Packet = NULL;
ConsistencyId = 0;
//
// 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;
//
// Advance Index to the FormOp with the correct ID value
//
for (; LocalTags->Next != NULL; LocalTags = LocalTags->Next) {
if ((LocalTags->Tags[0].CallbackHandle != 0) && (CallbackHandle == 0)) {
CallbackHandle = LocalTags->Tags[0].CallbackHandle;
EfiCopyMem (&TagGuid, &LocalTags->Tags[0].GuidValue, sizeof (EFI_GUID));
}
for (Index = 0; LocalTags->Tags[Index].Operand != EFI_IFR_FORM_OP; Index++)
;
if (LocalTags->Tags[Index].Id == IdValue) {
break;
}
}
//
// If we are going to callback on a non-goto opcode, make sure we don't change pages
//
if (Selection->ThisTag->Operand != EFI_IFR_REF_OP) {
TargetPage = Selection->FormId;
}
//
// The first tag below should be the form op-code. We need to store away the
// current variable setting to ensure if we have to reload the page, that we
// can correctly restore the values for the active variable
//
CurrentVariable = Selection->Tags[0].VariableNumber;
//
// Remember that dynamic pages in an environment where all pages are not
// dynamic require us to call back to the user to give them an opportunity
// to register fresh information in the HII database so that we can extract it.
//
Status = gBS->HandleProtocol (
(VOID *) (UINTN) CallbackHandle,
&gEfiFormCallbackProtocolGuid,
&FormCallback
);
if (EFI_ERROR (Status)) {
gBS->FreePool (LocalTags->Tags);
return ;
}
ExtractRequestedNvMap (FileFormTags, CurrentVariable, &VariableDefinition);
if (Selection->ThisTag->Flags & (EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS)) {
((EFI_IFR_DATA_ARRAY *) CallbackData)->NvRamMap = VariableDefinition->NvRamMap;
} else {
((EFI_IFR_DATA_ARRAY *) CallbackData)->NvRamMap = NULL;
}
if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
Status = FormCallback->Callback (
FormCallback,
Selection->ThisTag->Key,
(EFI_IFR_DATA_ARRAY *) CallbackData,
&Packet
);
}
if (EFI_ERROR (Status)) {
//
// Restore Previous Value
//
EfiCopyMem (
&VariableDefinition->NvRamMap[Selection->ThisTag->StorageStart],
gPreviousValue,
Selection->ThisTag->StorageWidth
);
if (Packet != NULL) {
//
// Upon error, we will likely receive a string to print out
//
ScreenSize = GetStringWidth (Packet->String) / 2;
//
// Display error popup
//
CreatePopUp (ScreenSize, 3, &NullCharacter, Packet->String, &NullCharacter);
do {
Status = WaitForKeyStroke (&Key);
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
} else {
UpdateStatusBar (INPUT_ERROR, (UINT8) 0, TRUE);
}
} else {
if (Packet != NULL) {
//
// We need to on a non-error, look in the outbound Packet for information and update the NVRAM
// location associated with the op-code specified there. This is used on single op-code instances
// and not for when a hyperlink sent us a whole page of data.
//
if (Packet->DataArray.EntryCount == 1) {
switch (Packet->DataArray.Data->OpCode) {
case EFI_IFR_STRING_OP:
case EFI_IFR_NUMERIC_OP:
case EFI_IFR_ORDERED_LIST_OP:
case EFI_IFR_ONE_OF_OP:
case EFI_IFR_CHECKBOX_OP:
EfiCopyMem (
&VariableDefinition->NvRamMap[Selection->ThisTag->StorageStart],
&Packet->DataArray.Data[0].Data,
Selection->ThisTag->StorageWidth
);
break;
case EFI_IFR_NV_ACCESS_COMMAND:
EfiCopyMem (
&VariableDefinition->NvRamMap[((EFI_IFR_NV_DATA *) Packet)->QuestionId],
((EFI_IFR_NV_DATA *) Packet)->Data,
((EFI_IFR_NV_DATA *) Packet)->StorageWidth
);
break;
}
if (Packet->DataArray.Data->Flags & RESET_REQUIRED) {
gResetRequired = TRUE;
}
if (Packet->DataArray.Data->Flags & EXIT_REQUIRED) {
gExitRequired = TRUE;
}
if (Packet->DataArray.Data->Flags & SAVE_REQUIRED) {
gSaveRequired = TRUE;
}
if (Packet->DataArray.Data->Flags & NV_CHANGED) {
gNvUpdateRequired = TRUE;
}
if (Packet->DataArray.Data->Flags & NV_NOT_CHANGED) {
gNvUpdateRequired = FALSE;
}
}
}
}
if (Packet != NULL) {
gBS->FreePool (Packet);
}
for (BackupIndex = 0; LocalTags->Tags[BackupIndex].Operand != EFI_IFR_END_FORM_OP; BackupIndex++) {
switch (LocalTags->Tags[BackupIndex].Operand) {
case EFI_IFR_EQ_VAR_VAL_OP:
case EFI_IFR_EQ_ID_VAL_OP:
case EFI_IFR_EQ_ID_ID_OP:
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:
case EFI_IFR_EQ_ID_LIST_OP:
//
// If we encountered a ConsistencyId value, on this page they will be incremental
// So register the first value we encounter. We will pass this in when we re-create this page
//
if ((LocalTags->Tags[BackupIndex].ConsistencyId != 0) && (ConsistencyId == 0)) {
ConsistencyId = (UINT16) (LocalTags->Tags[BackupIndex].ConsistencyId - 1);
}
break;
}
}
//
// Delete the buffer associated with previous dynamic page
// We will re-allocate a buffer....
//
gBS->FreePool (LocalTags->Tags);
Length = 0xF000;
Buffer = EfiLibAllocateZeroPool (Length);
ASSERT (Buffer != NULL);
//
// Get the form that was updated by the callback
//
Hii->GetForms (
Hii,
Selection->Handle,
TargetPage,
&Length,
Buffer
);
//
// Ok, we have the new page.....now we must purge the old page and re-allocate
// the tag page with the new data
//
UpdateNewTagData (
Buffer,
ConsistencyId,
CurrentVariable,
LocalTags,
FileFormTags
);
//
// return the Form Id, Text, and the File's FormTags structure
//
*FormHandle = LocalTags->Tags[0].Id;
*TitleToken = LocalTags->Tags[0].Text;
*FormTags = *LocalTags;
FormTags->Tags[0].CallbackHandle = CallbackHandle;
EfiCopyMem (&FormTags->Tags[0].GuidValue, &TagGuid, sizeof (EFI_GUID));
return ;
}
UI_MENU_OPTION *
SetupBrowser (
IN UI_MENU_OPTION *Selection,
IN BOOLEAN Callback,
IN EFI_FILE_FORM_TAGS *FileFormTagsHead,
IN UINT8 *CallbackData
)
{
UINT16 FormHandle;
UINT16 TitleToken;
EFI_FORM_TAGS FormTags;
gEntryNumber = -1;
gLastOpr = FALSE;
//
// Displays the Header and Footer borders
//
DisplayPageFrame ();
//
// Id of 0 yields the getting of the top form whatever the ID is. Usually the first form in the IFR
//
ExtractFormHandle (Selection, FileFormTagsHead, 0, &FormHandle, &TitleToken, &FormTags);
Selection = DisplayForm (Selection, FormHandle, TitleToken, FormTags, FileFormTagsHead, CallbackData);
//
// If selection is null use the former selection
//
if (Selection == NULL) {
return Selection;
}
if (Callback) {
return Selection;
}
while (Selection->Tags != NULL) {
if (Selection->Previous) {
ExtractFormHandle (Selection, FileFormTagsHead, Selection->FormId, &FormHandle, &TitleToken, &FormTags);
} else {
//
// True if a hyperlink/jump is selected
//
if (Selection->ThisTag->Operand == EFI_IFR_REF_OP && Selection->ThisTag->Id != 0x0000) {
if (Selection->ThisTag->Flags & EFI_IFR_FLAG_INTERACTIVE) {
ExtractDynamicFormHandle (
Selection,
CallbackData,
FileFormTagsHead,
Selection->ThisTag->Id,
&FormHandle,
&TitleToken,
&FormTags
);
goto DisplayPage;
} else {
ExtractFormHandle (Selection, FileFormTagsHead, Selection->ThisTag->Id, &FormHandle, &TitleToken, &FormTags);
goto DisplayPage;
}
}
if ((Selection->ThisTag->Flags & EFI_IFR_FLAG_INTERACTIVE) &&
(Selection->ThisTag->Operand != EFI_IFR_PASSWORD_OP)
) {
ExtractDynamicFormHandle (
Selection,
CallbackData,
FileFormTagsHead,
Selection->FormId,
&FormHandle,
&TitleToken,
&FormTags
);
} else {
ExtractFormHandle (Selection, FileFormTagsHead, Selection->FormId, &FormHandle, &TitleToken, &FormTags);
}
}
DisplayPage:
//
// Displays the Header and Footer borders
//
DisplayPageFrame ();
Selection = DisplayForm (Selection, FormHandle, TitleToken, FormTags, FileFormTagsHead, CallbackData);
if (Selection == NULL) {
break;
}
};
return Selection;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?