From 1c0d306fe026cb1f9527585ec037e6d44a00877f Mon Sep 17 00:00:00 2001 From: Eric Dong Date: Wed, 4 Sep 2013 04:15:10 +0000 Subject: Enable warningif opcode in browser. Signed-off-by: Eric Dong Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14625 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/DisplayEngineDxe/ProcessOptions.c | 147 ++++++++++++++++++++- MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c | 32 +++++ .../Universal/SetupBrowserDxe/Presentation.c | 50 ++++++- MdeModulePkg/Universal/SetupBrowserDxe/Setup.h | 4 + 4 files changed, 226 insertions(+), 7 deletions(-) (limited to 'MdeModulePkg/Universal') diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c index aca043a8c2..cf9f6836b3 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c @@ -15,6 +15,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "FormDisplay.h" +typedef struct { + EFI_EVENT SyncEvent; + UINT8 *TimeOut; + CHAR16 *ErrorInfo; +} WARNING_IF_CONTEXT; + +#define MAX_TIME_OUT_LEN 0x10 + /** Concatenate a narrow string to another string. @@ -560,6 +568,136 @@ CreateMultiStringPopUp ( VA_END (Marker); } +/** + Process nothing. + + @param Event The Event need to be process + @param Context The context of the event. + +**/ +VOID +EFIAPI +EmptyEventProcess ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ +} + +/** + Process for the refresh interval statement. + + @param Event The Event need to be process + @param Context The context of the event. + +**/ +VOID +EFIAPI +RefreshTimeOutProcess ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + WARNING_IF_CONTEXT *EventInfo; + CHAR16 TimeOutString[MAX_TIME_OUT_LEN]; + + EventInfo = (WARNING_IF_CONTEXT *) Context; + + if (*(EventInfo->TimeOut) == 0) { + gBS->CloseEvent (Event); + + gBS->SignalEvent (EventInfo->SyncEvent); + return; + } + + UnicodeSPrint(TimeOutString, MAX_TIME_OUT_LEN, L"%d", *(EventInfo->TimeOut)); + + CreateDialog (NULL, gEmptyString, EventInfo->ErrorInfo, gPressEnter, gEmptyString, TimeOutString, NULL); + + *(EventInfo->TimeOut) -= 1; +} + +/** + Show the warning message. + + @param RetInfo The input warning string and timeout info. + +**/ +VOID +WarningIfCheck ( + IN STATEMENT_ERROR_INFO *RetInfo + ) +{ + CHAR16 *ErrorInfo; + EFI_EVENT WaitList[2]; + EFI_EVENT RefreshIntervalEvent; + EFI_EVENT TimeOutEvent; + UINT8 TimeOut; + EFI_STATUS Status; + UINTN Index; + WARNING_IF_CONTEXT EventContext; + EFI_INPUT_KEY Key; + + TimeOutEvent = NULL; + RefreshIntervalEvent = NULL; + + ASSERT (RetInfo->StringId != 0); + ErrorInfo = GetToken (RetInfo->StringId, gFormData->HiiHandle); + TimeOut = RetInfo->TimeOut; + if (RetInfo->TimeOut == 0) { + do { + CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + } else { + Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent); + ASSERT_EFI_ERROR (Status); + + EventContext.SyncEvent = TimeOutEvent; + EventContext.TimeOut = &TimeOut; + EventContext.ErrorInfo = ErrorInfo; + + Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent); + ASSERT_EFI_ERROR (Status); + + // + // Show the dialog first to avoid long time not reaction. + // + gBS->SignalEvent (RefreshIntervalEvent); + + Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND); + ASSERT_EFI_ERROR (Status); + + while (TRUE) { + Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + break; + } + + if (Status != EFI_NOT_READY) { + continue; + } + + WaitList[0] = TimeOutEvent; + WaitList[1] = gST->ConIn->WaitForKey; + + Status = gBS->WaitForEvent (2, WaitList, &Index); + ASSERT_EFI_ERROR (Status); + + if (Index == 0) { + // + // Timeout occur, close the hoot time out event. + // + break; + } + } + } + + gBS->CloseEvent (TimeOutEvent); + gBS->CloseEvent (RefreshIntervalEvent); + + FreePool (ErrorInfo); +} + /** Process validate for one question. @@ -600,7 +738,14 @@ ValidateQuestion ( FreePool (ErrorInfo); Status = EFI_INVALID_PARAMETER; - break; + break; + + case WARNING_IF_TRUE: + // + // Condition meet, show up warning message + // + WarningIfCheck (&RetInfo); + break; default: break; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c index 11839ad6ce..ac7dce694b 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c @@ -54,6 +54,7 @@ CreateStatement ( InitializeListHead (&Statement->OptionListHead); InitializeListHead (&Statement->InconsistentListHead); InitializeListHead (&Statement->NoSubmitListHead); + InitializeListHead (&Statement->WarningListHead); Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE; @@ -816,6 +817,17 @@ DestroyStatement ( DestroyExpression (Expression); } + // + // Free WarningIf List + // + while (!IsListEmpty (&Statement->WarningListHead)) { + Link = GetFirstNode (&Statement->WarningListHead); + Expression = FORM_EXPRESSION_FROM_LINK (Link); + RemoveEntryList (&Expression->Link); + + DestroyExpression (Expression); + } + if (Statement->Expression != NULL) { FreePool (Statement->Expression); } @@ -2020,6 +2032,25 @@ ParseOpCodes ( } break; + case EFI_IFR_WARNING_IF_OP: + // + // Create an Expression node + // + CurrentExpression = CreateExpression (CurrentForm); + CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID)); + CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut; + CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF; + InsertTailList (&CurrentStatement->WarningListHead, &CurrentExpression->Link); + + // + // Take a look at next OpCode to see whether current expression consists + // of single OpCode + // + if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) { + SingleOpCodeExpression = TRUE; + } + break; + case EFI_IFR_SUPPRESS_IF_OP: // // Question and Option will appear in scope of this OpCode @@ -2327,6 +2358,7 @@ ParseOpCodes ( case EFI_IFR_NO_SUBMIT_IF_OP: case EFI_IFR_INCONSISTENT_IF_OP: + case EFI_IFR_WARNING_IF_OP: // // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF // diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c index def18fd9f9..a5caf4426c 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c @@ -52,6 +52,7 @@ EvaluateFormExpressions ( if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF || Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF || + Expression->Type == EFI_HII_EXPRESSION_WARNING_IF || Expression->Type == EFI_HII_EXPRESSION_WRITE || (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) { // @@ -228,13 +229,15 @@ CreateRefreshEvent ( Perform value check for a question. @param Question The question need to do check. + @param Type Condition type need to check. @param ErrorInfo Return info about the error. @retval The check result. **/ UINT32 -InConsistentIfCheck ( +ConditionCheck ( IN FORM_BROWSER_STATEMENT *Question, + IN UINT8 Type, OUT STATEMENT_ERROR_INFO *ErrorInfo ) { @@ -245,8 +248,23 @@ InConsistentIfCheck ( UINT32 RetVal; RetVal = STATEMENT_VALID; - ListHead = &Question->InconsistentListHead; + ListHead = NULL; + switch (Type) { + case EFI_HII_EXPRESSION_INCONSISTENT_IF: + ListHead = &Question->InconsistentListHead; + break; + + case EFI_HII_EXPRESSION_WARNING_IF: + ListHead = &Question->WarningListHead; + break; + + default: + ASSERT (FALSE); + return RetVal; + } + + ASSERT (ListHead != NULL); Link = GetFirstNode (ListHead); while (!IsNull (ListHead, Link)) { Expression = FORM_EXPRESSION_FROM_LINK (Link); @@ -262,8 +280,21 @@ InConsistentIfCheck ( if ((Expression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && Expression->Result.Value.b) { ErrorInfo->StringId = Expression->Error; - ErrorInfo->TimeOut = 0; - RetVal = INCOSISTENT_IF_TRUE; + switch (Type) { + case EFI_HII_EXPRESSION_INCONSISTENT_IF: + ErrorInfo->TimeOut = 0; + RetVal = INCOSISTENT_IF_TRUE; + break; + + case EFI_HII_EXPRESSION_WARNING_IF: + ErrorInfo->TimeOut = Expression->TimeOut; + RetVal = WARNING_IF_TRUE; + break; + + default: + ASSERT (FALSE); + break; + } break; } } @@ -324,7 +355,14 @@ QuestionCheck ( // Do the inconsistentif check. // if (!IsListEmpty (&Question->InconsistentListHead)) { - RetVal = InConsistentIfCheck(Question, ErrorInfo); + RetVal = ConditionCheck(Question, EFI_HII_EXPRESSION_INCONSISTENT_IF, ErrorInfo); + } + + // + // Do the warningif check. + // + if (RetVal == STATEMENT_VALID && !IsListEmpty (&Question->WarningListHead)) { + RetVal = ConditionCheck(Question, EFI_HII_EXPRESSION_WARNING_IF, ErrorInfo); } // @@ -456,7 +494,7 @@ InitializeDisplayStatement ( // // Save the validate check question for later use. // - if (!IsListEmpty (&Statement->InconsistentListHead)) { + if (!IsListEmpty (&Statement->InconsistentListHead) || !IsListEmpty (&Statement->WarningListHead)) { DisplayStatement->ValidateQuestion = QuestionCheck; } diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h index e5f9d18b5b..99418543df 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h @@ -106,6 +106,7 @@ typedef struct { #define EFI_HII_EXPRESSION_RULE 6 #define EFI_HII_EXPRESSION_READ 7 #define EFI_HII_EXPRESSION_WRITE 8 +#define EFI_HII_EXPRESSION_WARNING_IF 9 #define EFI_HII_VARSTORE_BUFFER 0 #define EFI_HII_VARSTORE_NAME_VALUE 1 @@ -224,6 +225,8 @@ typedef struct { EFI_HII_VALUE Result; // Expression evaluation result + UINT8 TimeOut; // For EFI_IFR_WARNING_IF + LIST_ENTRY OpCodeListHead; // OpCodes consist of this expression (EXPRESSION_OPCODE) } FORM_EXPRESSION; @@ -351,6 +354,7 @@ typedef struct { LIST_ENTRY InconsistentListHead;// nested inconsistent expression list (FORM_EXPRESSION) LIST_ENTRY NoSubmitListHead; // nested nosubmit expression list (FORM_EXPRESSION) + LIST_ENTRY WarningListHead; // nested warning expression list (FORM_EXPRESSION) FORM_EXPRESSION_LIST *Expression; // nesting inside of GrayOutIf/DisableIf/SuppressIf FORM_EXPRESSION *ReadExpression; // nested EFI_IFR_READ, provide this question value by read expression. -- cgit v1.2.3