mirror of https://github.com/acidanthera/audk.git
Enable new "ref5" opcode in browser.
Signed-off-by:ydong10 Reviewed-by:lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11913 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
2ed77d0de5
commit
8ca6180f21
|
@ -1143,6 +1143,10 @@ ParseOpCodes (
|
|||
ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_TIME);
|
||||
break;
|
||||
|
||||
case EFI_IFR_TYPE_REF:
|
||||
ExpressionOpCode->ValueWidth = (UINT8) sizeof (EFI_IFR_REF);
|
||||
break;
|
||||
|
||||
case EFI_IFR_TYPE_OTHER:
|
||||
case EFI_IFR_TYPE_UNDEFINED:
|
||||
case EFI_IFR_TYPE_ACTION:
|
||||
|
@ -1548,19 +1552,25 @@ ParseOpCodes (
|
|||
case EFI_IFR_REF_OP:
|
||||
CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);
|
||||
ASSERT (CurrentStatement != NULL);
|
||||
CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_UNDEFINED;
|
||||
CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
|
||||
if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
|
||||
CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
|
||||
Value = &CurrentStatement->HiiValue;
|
||||
Value->Type = EFI_IFR_TYPE_REF;
|
||||
if (OpCodeLength >= sizeof (EFI_IFR_REF)) {
|
||||
CopyMem (&Value->Value.ref.FormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));
|
||||
|
||||
if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
|
||||
CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
|
||||
if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {
|
||||
CopyMem (&Value->Value.ref.QuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));
|
||||
|
||||
if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
|
||||
CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
|
||||
if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {
|
||||
CopyMem (&Value->Value.ref.FormSetGuid, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));
|
||||
|
||||
if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {
|
||||
CopyMem (&Value->Value.ref.DevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_REF);
|
||||
InitializeRequestElement (FormSet, CurrentStatement, CurrentForm);
|
||||
break;
|
||||
|
||||
case EFI_IFR_ONE_OF_OP:
|
||||
|
|
|
@ -1162,6 +1162,14 @@ ProcessCallBackFunction (
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// According the spec, return value from call back of "changing" and
|
||||
// "retrieve" should update to the question's temp buffer.
|
||||
//
|
||||
if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {
|
||||
SetQuestionValue(Selection->FormSet,Selection->Form, Question,TRUE);
|
||||
}
|
||||
} else if (Status == EFI_UNSUPPORTED) {
|
||||
//
|
||||
// If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
|
||||
|
@ -1384,11 +1392,18 @@ SetupBrowser (
|
|||
(Statement->Operand != EFI_IFR_PASSWORD_OP)) {
|
||||
|
||||
Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
|
||||
if ((EFI_ERROR (Status)) && (Status != EFI_UNSUPPORTED)) {
|
||||
if (Statement->Operand == EFI_IFR_REF_OP && Selection->Action != UI_ACTION_EXIT) {
|
||||
//
|
||||
// Callback return error status other than EFI_UNSUPPORTED
|
||||
// Process dynamic update ref opcode.
|
||||
//
|
||||
if (Statement->Operand == EFI_IFR_REF_OP) {
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = ProcessGotoOpCode(Statement, Selection, NULL, NULL);
|
||||
}
|
||||
|
||||
//
|
||||
// Callback return error status or status return from process goto opcode.
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Cross reference will not be taken
|
||||
//
|
||||
|
|
|
@ -2643,6 +2643,16 @@ LoadFormConfig (
|
|||
HiiSetString (FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);
|
||||
}
|
||||
|
||||
//
|
||||
// According the spec, ref opcode try to get value from call back with "retrieve" type.
|
||||
//
|
||||
if ((Question->Operand == EFI_IFR_REF_OP) && (FormSet->ConfigAccess != NULL)) {
|
||||
Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Check whether EfiVarstore with CallBack can be got.
|
||||
//
|
||||
|
|
|
@ -372,10 +372,6 @@ typedef struct {
|
|||
UINT64 Step;
|
||||
|
||||
EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON
|
||||
EFI_FORM_ID RefFormId; // for EFI_IFR_REF
|
||||
EFI_QUESTION_ID RefQuestionId; // for EFI_IFR_REF2
|
||||
EFI_GUID RefFormSetId; // for EFI_IFR_REF3
|
||||
EFI_STRING_ID RefDevicePath; // for EFI_IFR_REF4
|
||||
EFI_GUID RefreshGuid; // for EFI_IFR_REFRESH_ID
|
||||
|
||||
//
|
||||
|
|
|
@ -1649,6 +1649,175 @@ DevicePathToHiiHandle (
|
|||
return HiiHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
Process the goto op code, update the info in the selection structure.
|
||||
|
||||
@param Statement The statement belong to goto op code.
|
||||
@param Selection The selection info.
|
||||
@param Repaint Whether need to repaint the menu.
|
||||
@param NewLine Whether need to create new line.
|
||||
|
||||
@retval EFI_SUCCESS The menu process successfully.
|
||||
@return Other value if the process failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ProcessGotoOpCode (
|
||||
IN OUT FORM_BROWSER_STATEMENT *Statement,
|
||||
IN OUT UI_MENU_SELECTION *Selection,
|
||||
OUT BOOLEAN *Repaint,
|
||||
OUT BOOLEAN *NewLine
|
||||
)
|
||||
{
|
||||
CHAR16 *StringPtr;
|
||||
UINTN BufferSize;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
CHAR16 TemStr[2];
|
||||
UINT8 *DevicePathBuffer;
|
||||
UINTN Index;
|
||||
UINT8 DigitUint8;
|
||||
FORM_BROWSER_FORM *RefForm;
|
||||
EFI_INPUT_KEY Key;
|
||||
EFI_STATUS Status;
|
||||
UI_MENU_LIST *MenuList;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
if (Statement->HiiValue.Value.ref.DevicePath != 0) {
|
||||
if (Selection->Form->ModalForm) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Goto another Hii Package list
|
||||
//
|
||||
Selection->Action = UI_ACTION_REFRESH_FORMSET;
|
||||
|
||||
StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);
|
||||
if (StringPtr == NULL) {
|
||||
//
|
||||
// No device path string not found, exit
|
||||
//
|
||||
Selection->Action = UI_ACTION_EXIT;
|
||||
Selection->Statement = NULL;
|
||||
return Status;
|
||||
}
|
||||
BufferSize = StrLen (StringPtr) / 2;
|
||||
DevicePath = AllocatePool (BufferSize);
|
||||
ASSERT (DevicePath != NULL);
|
||||
|
||||
//
|
||||
// Convert from Device Path String to DevicePath Buffer in the reverse order.
|
||||
//
|
||||
DevicePathBuffer = (UINT8 *) DevicePath;
|
||||
for (Index = 0; StringPtr[Index] != L'\0'; Index ++) {
|
||||
TemStr[0] = StringPtr[Index];
|
||||
DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
|
||||
if (DigitUint8 == 0 && TemStr[0] != L'0') {
|
||||
//
|
||||
// Invalid Hex Char as the tail.
|
||||
//
|
||||
break;
|
||||
}
|
||||
if ((Index & 1) == 0) {
|
||||
DevicePathBuffer [Index/2] = DigitUint8;
|
||||
} else {
|
||||
DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);
|
||||
}
|
||||
}
|
||||
|
||||
Selection->Handle = DevicePathToHiiHandle (DevicePath);
|
||||
if (Selection->Handle == NULL) {
|
||||
//
|
||||
// If target Hii Handle not found, exit
|
||||
//
|
||||
Selection->Action = UI_ACTION_EXIT;
|
||||
Selection->Statement = NULL;
|
||||
return Status;
|
||||
}
|
||||
|
||||
FreePool (StringPtr);
|
||||
FreePool (DevicePath);
|
||||
|
||||
CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
|
||||
Selection->FormId = Statement->HiiValue.Value.ref.FormId;
|
||||
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
|
||||
} else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {
|
||||
if (Selection->Form->ModalForm) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Goto another Formset, check for uncommitted data
|
||||
//
|
||||
Selection->Action = UI_ACTION_REFRESH_FORMSET;
|
||||
|
||||
CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
|
||||
Selection->FormId = Statement->HiiValue.Value.ref.FormId;
|
||||
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
|
||||
} else if (Statement->HiiValue.Value.ref.FormId != 0) {
|
||||
//
|
||||
// Check whether target From is suppressed.
|
||||
//
|
||||
RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);
|
||||
|
||||
if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
|
||||
Status = EvaluateExpression (Selection->FormSet, RefForm, RefForm->SuppressExpression);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RefForm->SuppressExpression->Result.Value.b) {
|
||||
//
|
||||
// Form is suppressed.
|
||||
//
|
||||
do {
|
||||
CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);
|
||||
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
|
||||
if (Repaint != NULL) {
|
||||
*Repaint = TRUE;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Goto another form inside this formset,
|
||||
//
|
||||
Selection->Action = UI_ACTION_REFRESH_FORM;
|
||||
|
||||
//
|
||||
// Link current form so that we can always go back when someone hits the ESC
|
||||
//
|
||||
MenuList = UiFindMenuList (&Selection->FormSetGuid, Statement->HiiValue.Value.ref.FormId);
|
||||
if (MenuList == NULL && Selection->CurrentMenu != NULL) {
|
||||
MenuList = UiAddMenuList (Selection->CurrentMenu, &Selection->FormSetGuid, Statement->HiiValue.Value.ref.FormId);
|
||||
}
|
||||
|
||||
Selection->FormId = Statement->HiiValue.Value.ref.FormId;
|
||||
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
|
||||
} else if (Statement->HiiValue.Value.ref.QuestionId != 0) {
|
||||
//
|
||||
// Goto another Question
|
||||
//
|
||||
Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
|
||||
|
||||
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
|
||||
Selection->Action = UI_ACTION_REFRESH_FORM;
|
||||
} else {
|
||||
if (Repaint != NULL) {
|
||||
*Repaint = TRUE;
|
||||
}
|
||||
if (NewLine != NULL) {
|
||||
*NewLine = TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
|
||||
Selection->Action = UI_ACTION_REFRESH_FORM;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Display menu and wait for user to select one menu option, then return it.
|
||||
If AutoBoot is enabled, then if user doesn't select any option,
|
||||
|
@ -1704,16 +1873,9 @@ UiDisplayMenu (
|
|||
MENU_REFRESH_ENTRY *MenuUpdateEntry;
|
||||
UI_SCREEN_OPERATION ScreenOperation;
|
||||
UINT8 MinRefreshInterval;
|
||||
UINTN BufferSize;
|
||||
UINT16 DefaultId;
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
FORM_BROWSER_STATEMENT *Statement;
|
||||
CHAR16 TemStr[2];
|
||||
UINT8 *DevicePathBuffer;
|
||||
UINT8 DigitUint8;
|
||||
UI_MENU_LIST *CurrentMenu;
|
||||
UI_MENU_LIST *MenuList;
|
||||
FORM_BROWSER_FORM *RefForm;
|
||||
UINTN ModalSkipColumn;
|
||||
|
||||
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
|
||||
|
@ -1736,7 +1898,6 @@ UiDisplayMenu (
|
|||
NextMenuOption = NULL;
|
||||
PreviousMenuOption = NULL;
|
||||
SavedMenuOption = NULL;
|
||||
RefForm = NULL;
|
||||
ModalSkipColumn = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 6;
|
||||
|
||||
ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
|
||||
|
@ -2613,130 +2774,7 @@ UiDisplayMenu (
|
|||
|
||||
switch (Statement->Operand) {
|
||||
case EFI_IFR_REF_OP:
|
||||
if (Statement->RefDevicePath != 0) {
|
||||
if (Selection->Form->ModalForm) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Goto another Hii Package list
|
||||
//
|
||||
Selection->Action = UI_ACTION_REFRESH_FORMSET;
|
||||
|
||||
StringPtr = GetToken (Statement->RefDevicePath, Selection->FormSet->HiiHandle);
|
||||
if (StringPtr == NULL) {
|
||||
//
|
||||
// No device path string not found, exit
|
||||
//
|
||||
Selection->Action = UI_ACTION_EXIT;
|
||||
Selection->Statement = NULL;
|
||||
break;
|
||||
}
|
||||
BufferSize = StrLen (StringPtr) / 2;
|
||||
DevicePath = AllocatePool (BufferSize);
|
||||
ASSERT (DevicePath != NULL);
|
||||
|
||||
//
|
||||
// Convert from Device Path String to DevicePath Buffer in the reverse order.
|
||||
//
|
||||
DevicePathBuffer = (UINT8 *) DevicePath;
|
||||
for (Index = 0; StringPtr[Index] != L'\0'; Index ++) {
|
||||
TemStr[0] = StringPtr[Index];
|
||||
DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
|
||||
if (DigitUint8 == 0 && TemStr[0] != L'0') {
|
||||
//
|
||||
// Invalid Hex Char as the tail.
|
||||
//
|
||||
break;
|
||||
}
|
||||
if ((Index & 1) == 0) {
|
||||
DevicePathBuffer [Index/2] = DigitUint8;
|
||||
} else {
|
||||
DevicePathBuffer [Index/2] = (UINT8) ((DevicePathBuffer [Index/2] << 4) + DigitUint8);
|
||||
}
|
||||
}
|
||||
|
||||
Selection->Handle = DevicePathToHiiHandle (DevicePath);
|
||||
if (Selection->Handle == NULL) {
|
||||
//
|
||||
// If target Hii Handle not found, exit
|
||||
//
|
||||
Selection->Action = UI_ACTION_EXIT;
|
||||
Selection->Statement = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
FreePool (StringPtr);
|
||||
FreePool (DevicePath);
|
||||
|
||||
CopyMem (&Selection->FormSetGuid, &Statement->RefFormSetId, sizeof (EFI_GUID));
|
||||
Selection->FormId = Statement->RefFormId;
|
||||
Selection->QuestionId = Statement->RefQuestionId;
|
||||
} else if (!CompareGuid (&Statement->RefFormSetId, &gZeroGuid)) {
|
||||
if (Selection->Form->ModalForm) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Goto another Formset, check for uncommitted data
|
||||
//
|
||||
Selection->Action = UI_ACTION_REFRESH_FORMSET;
|
||||
|
||||
CopyMem (&Selection->FormSetGuid, &Statement->RefFormSetId, sizeof (EFI_GUID));
|
||||
Selection->FormId = Statement->RefFormId;
|
||||
Selection->QuestionId = Statement->RefQuestionId;
|
||||
} else if (Statement->RefFormId != 0) {
|
||||
//
|
||||
// Check whether target From is suppressed.
|
||||
//
|
||||
RefForm = IdToForm (Selection->FormSet, Statement->RefFormId);
|
||||
|
||||
if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
|
||||
Status = EvaluateExpression (Selection->FormSet, RefForm, RefForm->SuppressExpression);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (RefForm->SuppressExpression->Result.Value.b) {
|
||||
//
|
||||
// Form is suppressed.
|
||||
//
|
||||
do {
|
||||
CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);
|
||||
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
|
||||
|
||||
Repaint = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Goto another form inside this formset,
|
||||
//
|
||||
Selection->Action = UI_ACTION_REFRESH_FORM;
|
||||
|
||||
//
|
||||
// Link current form so that we can always go back when someone hits the ESC
|
||||
//
|
||||
MenuList = UiFindMenuList (&Selection->FormSetGuid, Statement->RefFormId);
|
||||
if (MenuList == NULL) {
|
||||
MenuList = UiAddMenuList (CurrentMenu, &Selection->FormSetGuid, Statement->RefFormId);
|
||||
}
|
||||
|
||||
Selection->FormId = Statement->RefFormId;
|
||||
Selection->QuestionId = Statement->RefQuestionId;
|
||||
} else if (Statement->RefQuestionId != 0) {
|
||||
//
|
||||
// Goto another Question
|
||||
//
|
||||
Selection->QuestionId = Statement->RefQuestionId;
|
||||
|
||||
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
|
||||
Selection->Action = UI_ACTION_REFRESH_FORM;
|
||||
} else {
|
||||
Repaint = TRUE;
|
||||
NewLine = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ProcessGotoOpCode(Statement, Selection, &Repaint, &NewLine);
|
||||
break;
|
||||
|
||||
case EFI_IFR_ACTION_OP:
|
||||
|
|
|
@ -331,6 +331,26 @@ FreeBrowserStrings (
|
|||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Process the goto op code, update the info in the selection structure.
|
||||
|
||||
@param Statement The statement belong to goto op code.
|
||||
@param Selection The selection info.
|
||||
@param Repaint Whether need to repaint the menu.
|
||||
@param NewLine Whether need to create new line.
|
||||
|
||||
@retval EFI_SUCCESS The menu process successfully.
|
||||
@return Other value if the process failed.
|
||||
**/
|
||||
EFI_STATUS
|
||||
ProcessGotoOpCode (
|
||||
IN OUT FORM_BROWSER_STATEMENT *Statement,
|
||||
IN OUT UI_MENU_SELECTION *Selection,
|
||||
OUT BOOLEAN *Repaint,
|
||||
OUT BOOLEAN *NewLine
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
The worker function that send the displays to the screen. On output,
|
||||
the selection made by user is returned.
|
||||
|
|
Loading…
Reference in New Issue