\r
#include "FormDisplay.h"\r
\r
+typedef struct {\r
+ EFI_EVENT SyncEvent;\r
+ UINT8 *TimeOut;\r
+ CHAR16 *ErrorInfo;\r
+} WARNING_IF_CONTEXT;\r
+\r
+#define MAX_TIME_OUT_LEN 0x10\r
+\r
/**\r
Concatenate a narrow string to another string.\r
\r
VA_END (Marker);\r
}\r
\r
+/**\r
+ Process nothing.\r
+\r
+ @param Event The Event need to be process\r
+ @param Context The context of the event.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EmptyEventProcess (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Process for the refresh interval statement.\r
+\r
+ @param Event The Event need to be process\r
+ @param Context The context of the event.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RefreshTimeOutProcess (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ WARNING_IF_CONTEXT *EventInfo;\r
+ CHAR16 TimeOutString[MAX_TIME_OUT_LEN];\r
+\r
+ EventInfo = (WARNING_IF_CONTEXT *) Context;\r
+\r
+ if (*(EventInfo->TimeOut) == 0) {\r
+ gBS->CloseEvent (Event);\r
+\r
+ gBS->SignalEvent (EventInfo->SyncEvent);\r
+ return;\r
+ }\r
+\r
+ UnicodeSPrint(TimeOutString, MAX_TIME_OUT_LEN, L"%d", *(EventInfo->TimeOut));\r
+\r
+ CreateDialog (NULL, gEmptyString, EventInfo->ErrorInfo, gPressEnter, gEmptyString, TimeOutString, NULL);\r
+\r
+ *(EventInfo->TimeOut) -= 1;\r
+}\r
+\r
+/**\r
+ Show the warning message.\r
+\r
+ @param RetInfo The input warning string and timeout info.\r
+\r
+**/\r
+VOID\r
+WarningIfCheck (\r
+ IN STATEMENT_ERROR_INFO *RetInfo\r
+ )\r
+{\r
+ CHAR16 *ErrorInfo;\r
+ EFI_EVENT WaitList[2];\r
+ EFI_EVENT RefreshIntervalEvent;\r
+ EFI_EVENT TimeOutEvent;\r
+ UINT8 TimeOut;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ WARNING_IF_CONTEXT EventContext;\r
+ EFI_INPUT_KEY Key;\r
+\r
+ TimeOutEvent = NULL;\r
+ RefreshIntervalEvent = NULL;\r
+\r
+ ASSERT (RetInfo->StringId != 0);\r
+ ErrorInfo = GetToken (RetInfo->StringId, gFormData->HiiHandle);\r
+ TimeOut = RetInfo->TimeOut;\r
+ if (RetInfo->TimeOut == 0) {\r
+ do {\r
+ CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+ } else {\r
+ Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ EventContext.SyncEvent = TimeOutEvent;\r
+ EventContext.TimeOut = &TimeOut;\r
+ EventContext.ErrorInfo = ErrorInfo;\r
+\r
+ Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Show the dialog first to avoid long time not reaction.\r
+ //\r
+ gBS->SignalEvent (RefreshIntervalEvent);\r
+\r
+ Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ while (TRUE) {\r
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
+ break;\r
+ }\r
+\r
+ if (Status != EFI_NOT_READY) {\r
+ continue;\r
+ }\r
+\r
+ WaitList[0] = TimeOutEvent;\r
+ WaitList[1] = gST->ConIn->WaitForKey;\r
+\r
+ Status = gBS->WaitForEvent (2, WaitList, &Index);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ if (Index == 0) {\r
+ //\r
+ // Timeout occur, close the hoot time out event.\r
+ //\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ gBS->CloseEvent (TimeOutEvent);\r
+ gBS->CloseEvent (RefreshIntervalEvent);\r
+\r
+ FreePool (ErrorInfo);\r
+}\r
+\r
/**\r
Process validate for one question.\r
\r
FreePool (ErrorInfo);\r
\r
Status = EFI_INVALID_PARAMETER;\r
- break;\r
+ break;\r
+\r
+ case WARNING_IF_TRUE:\r
+ //\r
+ // Condition meet, show up warning message\r
+ //\r
+ WarningIfCheck (&RetInfo);\r
+ break;\r
\r
default:\r
break;\r
InitializeListHead (&Statement->OptionListHead);\r
InitializeListHead (&Statement->InconsistentListHead);\r
InitializeListHead (&Statement->NoSubmitListHead);\r
+ InitializeListHead (&Statement->WarningListHead);\r
\r
Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
\r
DestroyExpression (Expression);\r
}\r
\r
+ //\r
+ // Free WarningIf List\r
+ //\r
+ while (!IsListEmpty (&Statement->WarningListHead)) {\r
+ Link = GetFirstNode (&Statement->WarningListHead);\r
+ Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
+ RemoveEntryList (&Expression->Link);\r
+\r
+ DestroyExpression (Expression);\r
+ }\r
+\r
if (Statement->Expression != NULL) {\r
FreePool (Statement->Expression);\r
}\r
}\r
break;\r
\r
+ case EFI_IFR_WARNING_IF_OP:\r
+ //\r
+ // Create an Expression node\r
+ //\r
+ CurrentExpression = CreateExpression (CurrentForm);\r
+ CopyMem (&CurrentExpression->Error, &((EFI_IFR_WARNING_IF *) OpCodeData)->Warning, sizeof (EFI_STRING_ID));\r
+ CurrentExpression->TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeData)->TimeOut;\r
+ CurrentExpression->Type = EFI_HII_EXPRESSION_WARNING_IF;\r
+ InsertTailList (&CurrentStatement->WarningListHead, &CurrentExpression->Link);\r
+\r
+ //\r
+ // Take a look at next OpCode to see whether current expression consists\r
+ // of single OpCode\r
+ //\r
+ if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
+ SingleOpCodeExpression = TRUE;\r
+ }\r
+ break;\r
+\r
case EFI_IFR_SUPPRESS_IF_OP:\r
//\r
// Question and Option will appear in scope of this OpCode\r
\r
case EFI_IFR_NO_SUBMIT_IF_OP:\r
case EFI_IFR_INCONSISTENT_IF_OP:\r
+ case EFI_IFR_WARNING_IF_OP:\r
//\r
// Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
//\r
\r
if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||\r
Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF ||\r
+ Expression->Type == EFI_HII_EXPRESSION_WARNING_IF ||\r
Expression->Type == EFI_HII_EXPRESSION_WRITE ||\r
(Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {\r
//\r
Perform value check for a question.\r
\r
@param Question The question need to do check.\r
+ @param Type Condition type need to check.\r
@param ErrorInfo Return info about the error.\r
\r
@retval The check result.\r
**/\r
UINT32\r
-InConsistentIfCheck (\r
+ConditionCheck (\r
IN FORM_BROWSER_STATEMENT *Question,\r
+ IN UINT8 Type,\r
OUT STATEMENT_ERROR_INFO *ErrorInfo\r
)\r
{\r
UINT32 RetVal;\r
\r
RetVal = STATEMENT_VALID;\r
- ListHead = &Question->InconsistentListHead;\r
+ ListHead = NULL;\r
\r
+ switch (Type) {\r
+ case EFI_HII_EXPRESSION_INCONSISTENT_IF:\r
+ ListHead = &Question->InconsistentListHead;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_WARNING_IF:\r
+ ListHead = &Question->WarningListHead;\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ return RetVal;\r
+ }\r
+\r
+ ASSERT (ListHead != NULL);\r
Link = GetFirstNode (ListHead);\r
while (!IsNull (ListHead, Link)) {\r
Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
\r
if ((Expression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && Expression->Result.Value.b) {\r
ErrorInfo->StringId = Expression->Error;\r
- ErrorInfo->TimeOut = 0;\r
- RetVal = INCOSISTENT_IF_TRUE;\r
+ switch (Type) {\r
+ case EFI_HII_EXPRESSION_INCONSISTENT_IF:\r
+ ErrorInfo->TimeOut = 0;\r
+ RetVal = INCOSISTENT_IF_TRUE;\r
+ break;\r
+\r
+ case EFI_HII_EXPRESSION_WARNING_IF:\r
+ ErrorInfo->TimeOut = Expression->TimeOut;\r
+ RetVal = WARNING_IF_TRUE;\r
+ break;\r
+\r
+ default:\r
+ ASSERT (FALSE);\r
+ break;\r
+ }\r
break;\r
}\r
}\r
// Do the inconsistentif check.\r
//\r
if (!IsListEmpty (&Question->InconsistentListHead)) {\r
- RetVal = InConsistentIfCheck(Question, ErrorInfo);\r
+ RetVal = ConditionCheck(Question, EFI_HII_EXPRESSION_INCONSISTENT_IF, ErrorInfo);\r
+ }\r
+\r
+ //\r
+ // Do the warningif check.\r
+ //\r
+ if (RetVal == STATEMENT_VALID && !IsListEmpty (&Question->WarningListHead)) {\r
+ RetVal = ConditionCheck(Question, EFI_HII_EXPRESSION_WARNING_IF, ErrorInfo);\r
}\r
\r
//\r
//\r
// Save the validate check question for later use.\r
//\r
- if (!IsListEmpty (&Statement->InconsistentListHead)) {\r
+ if (!IsListEmpty (&Statement->InconsistentListHead) || !IsListEmpty (&Statement->WarningListHead)) {\r
DisplayStatement->ValidateQuestion = QuestionCheck;\r
}\r
\r
#define EFI_HII_EXPRESSION_RULE 6\r
#define EFI_HII_EXPRESSION_READ 7\r
#define EFI_HII_EXPRESSION_WRITE 8\r
+#define EFI_HII_EXPRESSION_WARNING_IF 9\r
\r
#define EFI_HII_VARSTORE_BUFFER 0\r
#define EFI_HII_VARSTORE_NAME_VALUE 1\r
\r
EFI_HII_VALUE Result; // Expression evaluation result\r
\r
+ UINT8 TimeOut; // For EFI_IFR_WARNING_IF\r
+\r
LIST_ENTRY OpCodeListHead; // OpCodes consist of this expression (EXPRESSION_OPCODE)\r
} FORM_EXPRESSION;\r
\r
\r
LIST_ENTRY InconsistentListHead;// nested inconsistent expression list (FORM_EXPRESSION)\r
LIST_ENTRY NoSubmitListHead; // nested nosubmit expression list (FORM_EXPRESSION)\r
+ LIST_ENTRY WarningListHead; // nested warning expression list (FORM_EXPRESSION)\r
FORM_EXPRESSION_LIST *Expression; // nesting inside of GrayOutIf/DisableIf/SuppressIf\r
\r
FORM_EXPRESSION *ReadExpression; // nested EFI_IFR_READ, provide this question value by read expression.\r